• 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: 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          java.lang.String[] fstr
46          java.lang.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 java.lang.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 java.lang.AbstractMethodError <external>
64      .record java.lang.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 Java
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']
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: restore_register
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        header-template: [r_A]
500        description: >
501          Invoke virtual method and check if registers after calling is restored.
502        code-template: |
503          .function void A.foo(A a0) {
504              %s
505              lda.null
506              sta.obj v0
507              mov.obj v256, v0
508              return.void
509          }
510
511          .function i32 main() {
512              initobj.short A.constructor
513              sta.obj v0
514              %s
515              mov%s v256, %s
516              call.virt.short A.foo, v0
517              mov%s v100, v256
518              lda%s v100
519              %s
520        cases:
521          - values:
522            - 'movi v1, 123'
523            - 'movi v1, 321'
524            - ''
525            - 'v1'
526            - ''
527            - ''
528            - |
529              #
530                  jne v1, set_failure
531                  ldai 0
532                  jmp done
533              set_failure:
534                  ldai 1
535              done:
536          - values:
537            - 'movi.64 v8, 123'
538            - 'movi v8, 321'
539            - ''
540            - 'v8'
541            - ''
542            - ''
543            - |
544              #
545                  jne v8, set_failure
546                  ldai 0
547                  jmp done
548              set_failure:
549                  ldai 1
550              done:
551          - values:
552            - 'fmovi.64 v16, 123'
553            - 'movi v16, 321'
554            - ''
555            - 'v16'
556            - ''
557            - ''
558            - |
559              #
560                  jne v16, set_failure
561                  ldai 0
562                  jmp done
563              set_failure:
564                  ldai 1
565              done:
566          - values:
567            - 'mov.null v128'
568            - 'movi v128, 321'
569            - ''
570            - 'v128'
571            - ''
572            - ''
573            - |
574              #
575                  jne v128, set_failure
576                  ldai 0
577                  jmp done
578              set_failure:
579                  ldai 1
580              done:
581          - values:
582            - |
583              #
584                  lda.str "123"
585                  sta.obj v255
586            - 'movi v255, 321'
587            - ''
588            - 'v255'
589            - ''
590            - ''
591            - |
592              #
593                  jne v255, set_failure
594                  ldai 0
595                  jmp done
596              set_failure:
597                  ldai 1
598              done:
599          - values: ['movi v1, 123',   'movi.64 v1, 321', '.64', 'v1', '.64', '.64', 'cmp.64 v1']
600          - values: ['movi.64 v8, 123',   'movi.64 v8, 321', '.64', 'v8', '.64', '.64', 'cmp.64 v8']
601          - values: ['fmovi.64 v16, 123',  'movi.64 v16, 321', '.64', 'v16', '.64', '.64', 'cmp.64 v16']
602          - values: ['mov.null v128', 'movi.64 v128, 321', '.64', 'v128', '.64', '.64', 'cmp.64 v128']
603          - values:
604              - |
605                #
606                    lda.str "123"
607                    sta.obj v255
608              - 'movi.64 v255, 321'
609              - '.64'
610              - 'v255'
611              - '.64'
612              - '.64'
613              - 'cmp.64 v255'
614          - values: ['movi v1, 123',   'fmovi.64 v1, 321', '.64', 'v1', '.64', '.64', 'fcmpg.64 v1']
615          - values: ['movi.64 v8, 123',   'fmovi.64 v8, 321', '.64', 'v8', '.64', '.64', 'fcmpg.64 v8']
616          - values: ['fmovi.64 v16, 123',  'fmovi.64 v16, 321', '.64', 'v16', '.64', '.64', 'fcmpg.64 v16']
617          - values: ['mov.null v128', 'fmovi.64 v128, 321', '.64', 'v128', '.64', '.64', 'fcmpg.64 v128']
618          - values:
619              - |
620                #
621                    lda.str "123"
622                    sta.obj v255
623              - 'fmovi.64 v255, 321'
624              - '.64'
625              - 'v255'
626              - '.64'
627              - '.64'
628              - 'fcmpg.64 v255'
629
630      - file-name: regs
631        isa:
632          instructions:
633            - sig: call.virt.short method_id, v1:in:top, v2:in:top
634              acc: out:top
635              format: [op_v1_4_v2_4_id_16]
636        header-template: [r_A]
637        description: >
638          Check available registers number and registers width.
639        code-template: |
640            .function void A.foo(A a0%s) {
641                return.void
642            }
643
644            .function i32 main() {
645                call.virt.short A.foo, %s
646            }
647        check-type: empty
648        runner-options: [compile-only]
649        cases:
650          - values: ['', 'v0']
651          - values: ['', 'v8']
652          - values: ['', 'v15']
653          - values: ['', 'v16']
654            runner-options: [compile-failure]
655          - values: ['', '0']
656            runner-options: [compile-failure]
657          - values: [',i32 a1', 'v0, v0']
658          - values: [',i32 a1', 'v0, v8']
659          - values: [',i32 a1', 'v0, v15']
660          - values: [',i32 a1', 'v0, v16']
661            runner-options: [compile-failure]
662          - values: [',i32 a1', 'v0, 0']
663            runner-options: [compile-failure]
664          - values: [',i32 a1', 'v16, v0']
665            runner-options: [compile-failure]
666          - values: [',i32 a1', 'v16, v8']
667            runner-options: [compile-failure]
668          - values: [',i32 a1', 'v16, v15']
669            runner-options: [compile-failure]
670          - values: [',i32 a1', 'v16, v16']
671            runner-options: [compile-failure]
672          - values: [',i32 a1', 'v16, 0']
673            runner-options: [compile-failure]
674          - values: [',i32 a1', 'v15, v15']
675          - values: [',i32 a1', 'v15, v16']
676            runner-options: [compile-failure]
677          - values: [',i32 a1', 'v15, 0']
678            runner-options: [compile-failure]
679          - values: [',i32 a1', '0, 0']
680            runner-options: [compile-failure]
681          - values: [',i32 a1, i32 a2', 'v0, v0, v0']
682            runner-options: [compile-failure]
683          - values: [',i32 a1, i32 a2', 'v0, v0, v15']
684            runner-options: [compile-failure]
685          - values: [',i32 a1, i32 a2', 'v0, v15, v16']
686            runner-options: [compile-failure]
687          - values: [',i32 a1, i32 a2', 'v15, v16, v16']
688            runner-options: [compile-failure]
689          - values: [',i32 a1, i32 a2', 'v16, v16, 0']
690            runner-options: [compile-failure]
691          - values: [',i32 a1, i32 a2', 'v16, 0, 0']
692            runner-options: [compile-failure]
693          - values: [',i32 a1, i32 a2', '0, 0, 0']
694            runner-options: [compile-failure]
695
696      - file-name: panda_npe
697        isa:
698          instructions:
699            - sig: call.virt.short method_id, v1:in:top, v2:in:top
700              acc: out:top
701              format: [op_v1_4_v2_4_id_16]
702          exceptions:
703            - x_null
704        header-template: [NPE]
705        description: >
706              Check incorrect usage of `call.virt.short` instruction.
707              Null reference usage causes to panda.NullPointerException. Method_id points to virtual method of base class. Use PandaAssembly language context.
708        code-template: |
709          %s
710          .record B {}
711
712          .function void B.constructor(B a0) <ctor> {
713              return.void
714          }
715
716          .function i32 B.func(B a0%s) <noimpl>
717
718          .function i32 main() {
719              mov.null v0
720              %s
721          begin:
722              call.virt.short B.func, v0%s
723          end:
724              ldai 1
725              return
726
727          catch_NPE:
728              ldai 0 # Expected panda.NullPointerException
729              return
730
731          catch_all:
732              ldai 2 # Unexpected exception, test failed
733              return
734
735          .catch panda.NullPointerException, begin, end, catch_NPE
736          .catchall begin, end, catch_all
737
738        check-type: none
739        cases:
740          - values:
741            - ''
742            - ''
743            - ''
744            - ''
745          - values:
746            - ''
747            - ', i32 a1'
748            - 'movi v1, 0'
749            - ', v1'
750          - values:
751            - ''
752            - ', i64 a1'
753            - 'movi.64 v1, 0'
754            - ', v1'
755          - values:
756            - ''
757            - ', f64 a1'
758            - 'fmovi.64 v1, 0'
759            - ', v1'
760          - values:
761            - ''
762            - ', B a1'
763            - |
764              initobj B.constructor
765                  sta.obj v1
766            - ', v1'
767          - values:
768            - '.record panda.String <external>'
769            - ', panda.String a1'
770            - |
771              lda.str "some string"
772                  sta.obj v1
773            - ', v1'
774
775          - values:
776              - '.record panda.Class <external>'
777              - ', panda.Class a1'
778              - |
779                #
780                    lda.type B
781                    sta.obj v1
782              - ', v1'
783
784      - file-name: panda_ame
785        isa:
786          instructions:
787            - sig: call.virt.short method_id, v1:in:top, v2:in:top
788              acc: out:top
789              format: [op_v1_4_v2_4_id_16]
790          exceptions:
791            - x_abstract
792        header-template: [AME]
793        description: >
794          Check incorrect usage of `call.virt.short` instruction. Call of abstract method, check if panda.AbstractMethodError is thrown.
795          Use PandaAssembly language context.
796        tags: ['tsan']
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              initobj.short B.constructor
809              sta.obj v0
810              %s
811          begin:
812              call.virt.short B.func, v0%s
813          end:
814              ldai 1
815              return
816
817          catch_AME:
818              ldai 0 # Expected panda.AbstractMethodError
819              return
820
821          catch_all:
822              ldai 2 # Unexpected exception, test failed
823              return
824
825          .catch panda.AbstractMethodError, begin, end, catch_AME
826          .catchall begin, end, catch_all
827
828        check-type: none
829        cases:
830          - values:
831            - ''
832            - ''
833            - ''
834            - ''
835          - values:
836            - ''
837            - ', i32 a1'
838            - 'movi v1, 0'
839            - ', v1'
840          - values:
841            - ''
842            - ', i64 a1'
843            - 'movi.64 v1, 0'
844            - ', v1'
845          - values:
846            - ''
847            - ', f64 a1'
848            - 'fmovi.64 v1, 0'
849            - ', v1'
850          - values:
851            - ''
852            - ', B a1'
853            - |
854              initobj.short B.constructor
855                  sta.obj v1
856            - ', v1'
857          - values:
858            - '.record panda.String <external>'
859            - ', panda.String a1'
860            - |
861              lda.str "some string"
862                  sta.obj v1
863            - ', v1'
864
865          - values:
866              - ''
867              - ', panda.Class a1'
868              - |
869                #
870                    lda.type B
871                    sta.obj v1
872              - ', v1'
873
874      - file-name: unused_regs
875        isa:
876          description: >
877            Unused register slot values will be discarded and corresponding registers will not be
878            passed to the callee).
879        header-template: []
880        description: Verifier should ignore unused register slots.
881        code-template: |
882            .record A {}
883            .function void A.ctor(A a0) <ctor> {
884                return.void
885            }
886            .function i32 A.foo(A a0) {
887                ldai 0
888                return
889            }
890            .function i32 main() {
891                initobj A.ctor
892                sta.obj v5
893                call.virt.short A.foo, v5, v4
894        check-type: no-check
895