< prev index next >

test/jdk/java/foreign/callarranger/TestAarch64CallArranger.java

Print this page

140         });
141 
142         checkReturnBindings(callingSequence, new Binding[]{});
143     }
144 
145     @DataProvider
146     public static Object[][] structs() {
147         MemoryLayout struct2 = MemoryLayout.structLayout(C_INT, C_INT, C_DOUBLE, C_INT);
148         return new Object[][]{
149             // struct s { int32_t a, b; double c; };
150             { MemoryLayout.structLayout(C_INT, C_INT, C_DOUBLE), new Binding[] {
151                 dup(),
152                     // s.a & s.b
153                     bufferLoad(0, long.class), vmStore(r0, long.class),
154                     // s.c --> note AArch64 passes this in an *integer* register
155                     bufferLoad(8, long.class), vmStore(r1, long.class),
156             }},
157             // struct s { int32_t a, b; double c; int32_t d };
158             { struct2, new Binding[] {
159                 copy(struct2),
160                 baseAddress(),
161                 unboxAddress(),
162                 vmStore(r0, long.class)
163             }},
164             // struct s { int32_t a[2]; float b[2] };
165             { MemoryLayout.structLayout(C_INT, C_INT, C_FLOAT, C_FLOAT), new Binding[] {
166                 dup(),
167                     // s.a[0] & s.a[1]
168                     bufferLoad(0, long.class), vmStore(r0, long.class),
169                     // s.b[0] & s.b[1]
170                     bufferLoad(8, long.class), vmStore(r1, long.class),
171             }},
172             // struct s { float a; /* padding */ double b };
173             { MemoryLayout.structLayout(C_FLOAT, MemoryLayout.paddingLayout(32), C_DOUBLE),
174               new Binding[] {
175                 dup(),
176                 // s.a
177                 bufferLoad(0, long.class), vmStore(r0, long.class),
178                 // s.b
179                 bufferLoad(8, long.class), vmStore(r1, long.class),
180             }},
181         };
182     }
183 
184     @Test
185     public void testMultipleStructs() {
186         MemoryLayout struct1 = MemoryLayout.structLayout(C_INT, C_INT, C_DOUBLE, C_INT);
187         MemoryLayout struct2 = MemoryLayout.structLayout(C_LONG, C_LONG, C_LONG);
188 
189         MethodType mt = MethodType.methodType(void.class, MemorySegment.class, MemorySegment.class, int.class);
190         FunctionDescriptor fd = FunctionDescriptor.ofVoid(struct1, struct2, C_INT);
191         CallArranger.Bindings bindings = CallArranger.getBindings(mt, fd, false);
192 
193         assertFalse(bindings.isInMemoryReturn);
194         CallingSequence callingSequence = bindings.callingSequence;
195         assertEquals(callingSequence.methodType(), mt);
196         assertEquals(callingSequence.functionDesc(), fd);
197 
198         checkArgumentBindings(callingSequence, new Binding[][]{
199             {
200                 copy(struct1),
201                 baseAddress(),
202                 unboxAddress(),
203                 vmStore(r0, long.class)
204             },
205             {
206                 copy(struct2),
207                 baseAddress(),
208                 unboxAddress(),
209                 vmStore(r1, long.class)
210             },
211             { vmStore(r2, int.class) }
212         });
213 
214         checkReturnBindings(callingSequence, new Binding[]{});
215     }
216 
217     @Test
218     public void testReturnStruct1() {
219         MemoryLayout struct = MemoryLayout.structLayout(C_LONG, C_LONG, C_FLOAT);
220 
221         MethodType mt = MethodType.methodType(MemorySegment.class);
222         FunctionDescriptor fd = FunctionDescriptor.of(struct);
223         CallArranger.Bindings bindings = CallArranger.getBindings(mt, fd, false);
224 
225         assertTrue(bindings.isInMemoryReturn);
226         CallingSequence callingSequence = bindings.callingSequence;
227         assertEquals(callingSequence.methodType(), MethodType.methodType(void.class, MemoryAddress.class));
228         assertEquals(callingSequence.functionDesc(), FunctionDescriptor.ofVoid(C_POINTER));

349     public void testStructStackSpill() {
350         // A large (> 16 byte) struct argument that is spilled to the
351         // stack should be passed as a pointer to a copy and occupy one
352         // stack slot.
353 
354         MemoryLayout struct = MemoryLayout.structLayout(C_INT, C_INT, C_DOUBLE, C_INT);
355 
356         MethodType mt = MethodType.methodType(
357             void.class, MemorySegment.class, MemorySegment.class, int.class, int.class,
358             int.class, int.class, int.class, int.class, MemorySegment.class, int.class);
359         FunctionDescriptor fd = FunctionDescriptor.ofVoid(
360             struct, struct, C_INT, C_INT, C_INT, C_INT, C_INT, C_INT, struct, C_INT);
361         CallArranger.Bindings bindings = CallArranger.getBindings(mt, fd, false);
362 
363         assertFalse(bindings.isInMemoryReturn);
364         CallingSequence callingSequence = bindings.callingSequence;
365         assertEquals(callingSequence.methodType(), mt);
366         assertEquals(callingSequence.functionDesc(), fd);
367 
368         checkArgumentBindings(callingSequence, new Binding[][]{
369             { copy(struct), baseAddress(), unboxAddress(), vmStore(r0, long.class) },
370             { copy(struct), baseAddress(), unboxAddress(), vmStore(r1, long.class) },
371             { vmStore(r2, int.class) },
372             { vmStore(r3, int.class) },
373             { vmStore(r4, int.class) },
374             { vmStore(r5, int.class) },
375             { vmStore(r6, int.class) },
376             { vmStore(r7, int.class) },
377             { copy(struct), baseAddress(), unboxAddress(), vmStore(stackStorage(0), long.class) },
378             { vmStore(stackStorage(1), int.class) },
379         });
380 
381         checkReturnBindings(callingSequence, new Binding[]{});
382     }
383 }

140         });
141 
142         checkReturnBindings(callingSequence, new Binding[]{});
143     }
144 
145     @DataProvider
146     public static Object[][] structs() {
147         MemoryLayout struct2 = MemoryLayout.structLayout(C_INT, C_INT, C_DOUBLE, C_INT);
148         return new Object[][]{
149             // struct s { int32_t a, b; double c; };
150             { MemoryLayout.structLayout(C_INT, C_INT, C_DOUBLE), new Binding[] {
151                 dup(),
152                     // s.a & s.b
153                     bufferLoad(0, long.class), vmStore(r0, long.class),
154                     // s.c --> note AArch64 passes this in an *integer* register
155                     bufferLoad(8, long.class), vmStore(r1, long.class),
156             }},
157             // struct s { int32_t a, b; double c; int32_t d };
158             { struct2, new Binding[] {
159                 copy(struct2),
160                 unboxAddress(MemorySegment.class),

161                 vmStore(r0, long.class)
162             }},
163             // struct s { int32_t a[2]; float b[2] };
164             { MemoryLayout.structLayout(C_INT, C_INT, C_FLOAT, C_FLOAT), new Binding[] {
165                 dup(),
166                     // s.a[0] & s.a[1]
167                     bufferLoad(0, long.class), vmStore(r0, long.class),
168                     // s.b[0] & s.b[1]
169                     bufferLoad(8, long.class), vmStore(r1, long.class),
170             }},
171             // struct s { float a; /* padding */ double b };
172             { MemoryLayout.structLayout(C_FLOAT, MemoryLayout.paddingLayout(32), C_DOUBLE),
173               new Binding[] {
174                 dup(),
175                 // s.a
176                 bufferLoad(0, long.class), vmStore(r0, long.class),
177                 // s.b
178                 bufferLoad(8, long.class), vmStore(r1, long.class),
179             }},
180         };
181     }
182 
183     @Test
184     public void testMultipleStructs() {
185         MemoryLayout struct1 = MemoryLayout.structLayout(C_INT, C_INT, C_DOUBLE, C_INT);
186         MemoryLayout struct2 = MemoryLayout.structLayout(C_LONG, C_LONG, C_LONG);
187 
188         MethodType mt = MethodType.methodType(void.class, MemorySegment.class, MemorySegment.class, int.class);
189         FunctionDescriptor fd = FunctionDescriptor.ofVoid(struct1, struct2, C_INT);
190         CallArranger.Bindings bindings = CallArranger.getBindings(mt, fd, false);
191 
192         assertFalse(bindings.isInMemoryReturn);
193         CallingSequence callingSequence = bindings.callingSequence;
194         assertEquals(callingSequence.methodType(), mt);
195         assertEquals(callingSequence.functionDesc(), fd);
196 
197         checkArgumentBindings(callingSequence, new Binding[][]{
198             {
199                 copy(struct1),
200                 unboxAddress(MemorySegment.class),

201                 vmStore(r0, long.class)
202             },
203             {
204                 copy(struct2),
205                 unboxAddress(MemorySegment.class),

206                 vmStore(r1, long.class)
207             },
208             { vmStore(r2, int.class) }
209         });
210 
211         checkReturnBindings(callingSequence, new Binding[]{});
212     }
213 
214     @Test
215     public void testReturnStruct1() {
216         MemoryLayout struct = MemoryLayout.structLayout(C_LONG, C_LONG, C_FLOAT);
217 
218         MethodType mt = MethodType.methodType(MemorySegment.class);
219         FunctionDescriptor fd = FunctionDescriptor.of(struct);
220         CallArranger.Bindings bindings = CallArranger.getBindings(mt, fd, false);
221 
222         assertTrue(bindings.isInMemoryReturn);
223         CallingSequence callingSequence = bindings.callingSequence;
224         assertEquals(callingSequence.methodType(), MethodType.methodType(void.class, MemoryAddress.class));
225         assertEquals(callingSequence.functionDesc(), FunctionDescriptor.ofVoid(C_POINTER));

346     public void testStructStackSpill() {
347         // A large (> 16 byte) struct argument that is spilled to the
348         // stack should be passed as a pointer to a copy and occupy one
349         // stack slot.
350 
351         MemoryLayout struct = MemoryLayout.structLayout(C_INT, C_INT, C_DOUBLE, C_INT);
352 
353         MethodType mt = MethodType.methodType(
354             void.class, MemorySegment.class, MemorySegment.class, int.class, int.class,
355             int.class, int.class, int.class, int.class, MemorySegment.class, int.class);
356         FunctionDescriptor fd = FunctionDescriptor.ofVoid(
357             struct, struct, C_INT, C_INT, C_INT, C_INT, C_INT, C_INT, struct, C_INT);
358         CallArranger.Bindings bindings = CallArranger.getBindings(mt, fd, false);
359 
360         assertFalse(bindings.isInMemoryReturn);
361         CallingSequence callingSequence = bindings.callingSequence;
362         assertEquals(callingSequence.methodType(), mt);
363         assertEquals(callingSequence.functionDesc(), fd);
364 
365         checkArgumentBindings(callingSequence, new Binding[][]{
366             { copy(struct), unboxAddress(MemorySegment.class), vmStore(r0, long.class) },
367             { copy(struct), unboxAddress(MemorySegment.class), vmStore(r1, long.class) },
368             { vmStore(r2, int.class) },
369             { vmStore(r3, int.class) },
370             { vmStore(r4, int.class) },
371             { vmStore(r5, int.class) },
372             { vmStore(r6, int.class) },
373             { vmStore(r7, int.class) },
374             { copy(struct), unboxAddress(MemorySegment.class), vmStore(stackStorage(0), long.class) },
375             { vmStore(stackStorage(1), int.class) },
376         });
377 
378         checkReturnBindings(callingSequence, new Binding[]{});
379     }
380 }
< prev index next >