8 /* The abstracted result of an MVCL insn */
18 /* Register contents after executing an MVCL insn */
28 /* Run a single MVCL insn and return its raw result. */
30 do_mvcl(uint64_t r1
, uint64_t r1p1
, uint64_t r2
, uint64_t r2p1
)
34 register uint64_t a1
asm ("2") = r1
;
35 register uint64_t l1
asm ("3") = r1p1
;
36 register uint64_t a2
asm ("4") = r2
;
37 register uint64_t l2
asm ("5") = r2p1
;
38 register uint32_t cc
asm ("7");
40 asm volatile( "mvcl %1,%3\n\t"
43 :"=d"(cc
), "+d"(a1
), "+d"(l1
), "+d"(a2
), "+d"(l2
)
57 result_from_regs(mvcl_regs regs
)
61 result
.addr1
= regs
.r1
;
62 result
.len1
= regs
.r1p1
& 0xFFFFFF;
63 result
.addr2
= regs
.r2
;
64 result
.len2
= regs
.r2p1
& 0xFFFFFF;
65 result
.pad
= (regs
.r2p1
& 0xFF000000u
) >> 24;
71 /* Run MVCL twice using different fill bits for unused register bits.
72 Results ought to be the same */
74 mvcl(void *addr1
, uint32_t len1
,
75 void *addr2
, uint32_t len2
, uint32_t pad
)
77 mvcl_t result1
, result2
;
79 uint64_t r1
, r1p1
, r2
, r2p1
;
81 /* Check input arguments */
82 assert((pad
& 0xFF) == pad
); /* an 8-byte value */
83 assert((len1
& 0xFFFFFF) == len1
);
84 assert((len2
& 0xFFFFFF) == len2
);
86 /* Make a copy of the input buffer */
87 void *copy
= memcpy(malloc(len1
), addr1
, len1
);
89 /* Build up register contents setting unused bits to 0 */
93 r2p1
= len2
| (pad
<< 24);
96 regs
= do_mvcl(r1
, r1p1
, r2
, r2p1
);
97 result1
= result_from_regs(regs
);
99 /* Check unused bits */
100 if ((regs
.r1p1
>> 24) != 0)
101 printf("FAIL: r1[0:39] modified (unused bits 0)\n");
102 if ((regs
.r2p1
>> 32) != 0)
103 printf("FAIL: r2[0:31] modified (unused bits 0)\n");
105 /* Check pad value */
106 if (result1
.pad
!= pad
)
107 printf("FAIL: pad byte modified (unused bits 0)\n");
109 /* Build up register contents setting unused bits to 1 */
110 memcpy(addr1
, copy
, len1
);
111 r1p1
|= 0xFFFFFFFFFFULL
<< 24;
112 r2p1
|= ((uint64_t)0xFFFFFFFF) << 32;
115 regs
= do_mvcl(r1
, r1p1
, r2
, r2p1
);
116 result2
= result_from_regs(regs
);
118 /* Check unused bits */
119 if ((regs
.r1p1
>> 24) != 0xFFFFFFFFFFull
)
120 printf("FAIL: r1[0:39] modified (unused bits 1)\n");
121 if ((regs
.r2p1
>> 32) != 0xFFFFFFFFu
)
122 printf("FAIL: r2[0:31] modified (unused bits 1)\n");
124 /* Check pad value */
125 if (result2
.pad
!= pad
)
126 printf("FAIL: pad byte modified (unused bits 1)\n");
128 /* Compare results */
129 if (result1
.addr1
!= result2
.addr1
)
130 printf("FAIL: addr1 result is different\n");
131 if (result1
.addr2
!= result2
.addr2
)
132 printf("FAIL: addr2 result is different\n");
133 if (result1
.len1
!= result2
.len1
)
134 printf("FAIL: len1 result is different\n");
135 if (result1
.len2
!= result2
.len2
)
136 printf("FAIL: len2 result is different\n");
137 if (result1
.pad
!= result2
.pad
)
138 printf("FAIL: pad result is different\n");
139 if (result1
.cc
!= result2
.cc
)
140 printf("FAIL: cc result is different\n");
146 print_buf(const char *prefix
, char *buf
, uint32_t len
)
151 printf("%s |", prefix
);
152 for (i
= 0; i
< len
; ++i
)
159 run_test(void *dst
, uint32_t dst_len
, void *src
, uint32_t src_len
, uint32_t pad
)
163 result
= mvcl(dst
, dst_len
, src
, src_len
, pad
);
165 printf("cc: %"PRIu32
", len1: %"PRIu32
", len2: %"PRIu32
166 ", addr1 diff: %"PRId64
", addr2 diff: %"PRId64
"\n", result
.cc
,
167 result
.len1
, result
.len2
, (int64_t)result
.addr1
- (int64_t)dst
,
168 (int64_t)result
.addr2
- (int64_t)src
);
169 print_buf("dst buffer:", dst
, dst_len
);
174 uint8_t byte
, buf
[10], small
[5], i
;
175 uint32_t dst_offset
, dst_len
, src_offset
, src_len
;
177 /* Test 1: len1 == 0 */
178 printf("--- test 1 ---\n");
179 run_test(NULL
, 0, NULL
, 0, 0x00);
180 run_test(NULL
, 0, NULL
, 0, 0xFF);
181 run_test(NULL
, 0, NULL
, 5, 0x00);
182 run_test(NULL
, 0, NULL
, 5, 0xFF);
183 run_test(NULL
, 0, buf
, sizeof buf
, 0x00);
184 run_test(NULL
, 0, buf
, sizeof buf
, 0xFF);
186 /* Test 2: len1 != 0, len2 == 0 */
187 printf("--- test 2 ---\n");
188 run_test(&byte
, 1, NULL
, 0, 'a');
189 memset(buf
, 'x', sizeof buf
);
190 run_test(buf
, sizeof buf
, NULL
, 0, 'a');
192 /* In the following: len1 != 0, len2 != 0 */
194 /* Test 3: src == dst */
195 printf("--- test 3 ---\n");
197 run_test(&byte
, 1, &byte
, 1, 'a');
198 memset(buf
, 'x', sizeof buf
);
199 for (i
= 0; i
<= sizeof buf
; ++i
)
200 run_test(buf
, i
, buf
, sizeof buf
, 'a');
202 /* Test 4: len1 > len2, no buffer overlap */
203 printf("--- test 4 ---\n");
204 memset(buf
, 'b', sizeof buf
);
205 memset(small
, 's', sizeof small
);
206 run_test(buf
, sizeof buf
, small
, sizeof small
, 'a');
208 /* Test 5: len1 < len2, no buffer overlap */
209 printf("--- test 5 ---\n");
210 memset(buf
, 'b', sizeof buf
);
211 memset(small
, 's', sizeof small
);
212 run_test(small
, sizeof small
, buf
, sizeof buf
, 'a');
214 /* Test 6: len1 > len2, non-destructive overlap */
215 printf("--- test 6 ---\n");
216 memcpy(buf
, "0123456789", 10);
217 run_test(buf
, sizeof buf
, buf
+ 5, 5, 'x');
219 /* Test 7: len1 < len2, non-destructive overlap */
220 printf("--- test 7 ---\n");
221 memcpy(buf
, "0123456789", 10);
222 run_test(buf
, 5, buf
+ 4, 3, 'x');
224 /* Test 8: Misc checks for testing destructive overlap
226 printf("--- test 8 ---\n");
227 memcpy(buf
, "0123456789", 10);
228 run_test(buf
+ 3, 1, buf
, 10, 'x'); // non-destructive
229 memcpy(buf
, "0123456789", 10);
230 run_test(buf
+ 3, 2, buf
, 10, 'x'); // non-destructive
231 memcpy(buf
, "0123456789", 10);
232 run_test(buf
+ 3, 3, buf
, 10, 'x'); // non-destructive
233 memcpy(buf
, "0123456789", 10);
234 run_test(buf
+ 3, 4, buf
, 10, 'x'); // destructive
235 memcpy(buf
, "0123456789", 10);
236 run_test(buf
+ 3, 5, buf
, 10, 'x'); // destructive
237 memcpy(buf
, "0123456789", 10);
238 run_test(buf
+ 3, 6, buf
, 10, 'x'); // destructive
239 memcpy(buf
, "0123456789", 10);
240 run_test(buf
+ 3, 7, buf
, 10, 'x'); // destructive
242 /* Test 9: More checks for testing destructive overlap
243 Pad byte used; len2 == 0 */
244 printf("--- test 9 ---\n");
245 memcpy(buf
, "0123456789", 10);
246 run_test(buf
+ 3, 1, buf
, 0, 'x'); // non-destructive
247 memcpy(buf
, "0123456789", 10);
248 run_test(buf
+ 3, 2, buf
, 0, 'x'); // non-destructive
249 memcpy(buf
, "0123456789", 10);
250 run_test(buf
+ 3, 3, buf
, 0, 'x'); // non-destructive
251 memcpy(buf
, "0123456789", 10);
252 run_test(buf
+ 3, 4, buf
, 0, 'x'); // non-destructive
253 memcpy(buf
, "0123456789", 10);
254 run_test(buf
+ 3, 4, buf
, 0, 'x'); // non-destructive
255 memcpy(buf
, "0123456789", 10);
256 run_test(buf
+ 3, 5, buf
, 0, 'x'); // non-destructive
257 memcpy(buf
, "0123456789", 10);
258 run_test(buf
+ 3, 6, buf
, 0, 'x'); // non-destructive
259 memcpy(buf
, "0123456789", 10);
260 run_test(buf
+ 3, 7, buf
, 0, 'x'); // non-destructive
262 /* Test 10; what the heck... Just try all combinations. */
263 printf("--- test 9 ---\n");
264 for (dst_offset
= 0; dst_offset
< sizeof buf
; ++dst_offset
)
265 for (dst_len
= 0; dst_len
<= sizeof buf
- dst_offset
; ++dst_len
)
266 for (src_offset
= 0; src_offset
< sizeof buf
; ++src_offset
)
267 for (src_len
= 0; src_len
<= sizeof buf
- src_offset
; ++src_len
)
268 run_test(buf
+ dst_offset
, dst_len
, buf
+ src_offset
, src_len
, 'x');