6 /* The golden logs were obtained by running this test natively. */
8 /* The abstracted result of a CLCL insn */
18 /* Register contents after CLCL insn */
27 /* Run a single CLCL insn and return its raw result. */
29 do_clcl(uint64_t r1
, uint64_t r1p1
, uint64_t r2
, uint64_t r2p1
)
33 register uint64_t a1
asm ("2") = r1
;
34 register uint64_t l1
asm ("3") = r1p1
;
35 register uint64_t a2
asm ("4") = r2
;
36 register uint64_t l2
asm ("5") = r2p1
;
37 register uint32_t cc
asm ("7");
39 asm volatile( "0: clcl 2,4\n\t"
43 :"=d" (cc
), "+d" (a1
),"+d" (l1
), "+d" (a2
), "+d" (l2
)
56 result_from_regs(clcl_regs regs
)
60 result
.addr1
= regs
.r1
;
61 result
.len1
= regs
.r1p1
& 0xFFFFFF;
62 result
.addr2
= regs
.r2
;
63 result
.len2
= regs
.r2p1
& 0xFFFFFF;
64 result
.pad
= (regs
.r2p1
& 0xFF000000u
) >> 24;
70 /* Run CLCL twice using different fill bits for unused register bits.
71 Results ought to be the same */
73 clcl(void *addr1
, uint32_t len1
,
74 void *addr2
, uint32_t len2
, uint32_t pad
)
76 clcl_t result1
, result2
;
78 uint64_t r1
, r1p1
, r2
, r2p1
;
80 /* Check input arguments */
81 assert((pad
& 0xFF) == pad
); /* an 8-byte value */
82 assert((len1
& 0xFFFFFF) == len1
);
83 assert((len2
& 0xFFFFFF) == len2
);
85 /* Build up register contents setting unused bits to 0 */
89 r2p1
= len2
| (pad
<< 24);
92 regs
= do_clcl(r1
, r1p1
, r2
, r2p1
);
93 result1
= result_from_regs(regs
);
95 /* Check unused bits */
96 if ((regs
.r1p1
>> 24) != 0)
97 printf("FAIL: r1[0:39] modified (unused bits 0)\n");
98 if ((regs
.r2p1
>> 32) != 0)
99 printf("FAIL: r2[0:31] modified (unused bits 0)\n");
101 /* Check pad value */
102 if (result1
.pad
!= pad
)
103 printf("FAIL: pad byte modified (unused bits 0)\n");
105 /* Build up register contents setting unused bits to 1 */
106 r1p1
|= 0xFFFFFFFFFFull
<< 24;
107 r2p1
|= ((uint64_t)0xFFFFFFFF) << 32;
110 regs
= do_clcl(r1
, r1p1
, r2
, r2p1
);
111 result2
= result_from_regs(regs
);
113 /* Check unused bits */
114 if ((regs
.r1p1
>> 24) != 0xFFFFFFFFFFull
)
115 printf("FAIL: r1[0:39] modified (unused bits 1)\n");
116 if ((regs
.r2p1
>> 32) != 0xFFFFFFFFu
)
117 printf("FAIL: r2[0:31] modified (unused bits 1)\n");
119 /* Check pad value */
120 if (result2
.pad
!= pad
)
121 printf("FAIL: pad byte modified (unused bits 1)\n");
123 /* Compare results */
124 if (result1
.addr1
!= result2
.addr1
)
125 printf("FAIL: addr1 result is different\n");
126 if (result1
.addr2
!= result2
.addr2
)
127 printf("FAIL: addr2 result is different\n");
128 if (result1
.len1
!= result2
.len1
)
129 printf("FAIL: len1 result is different\n");
130 if (result1
.len2
!= result2
.len2
)
131 printf("FAIL: len2 result is different\n");
132 if (result1
.pad
!= result2
.pad
)
133 printf("FAIL: pad result is different\n");
134 if (result1
.cc
!= result2
.cc
)
135 printf("FAIL: cc result is different\n");
141 run_test(void *addr1
, uint32_t len1
, void *addr2
, uint32_t len2
, uint32_t pad
)
145 result
= clcl(addr1
, len1
, addr2
, len2
, pad
);
147 printf("cc: %"PRIu32
", len1: %"PRIu32
", len2: %"PRIu32
148 ", addr1 diff: %"PRId64
", addr2 diff: %"PRId64
"\n", result
.cc
,
149 result
.len1
, result
.len2
, (int64_t)result
.addr1
- (int64_t)addr1
,
150 (int64_t)result
.addr2
- (int64_t)addr2
);
155 uint8_t byte
, byte1
, byte2
;
157 /* Test 1: both lengths are 0; nothing loaded from memory */
158 printf("--- test 1 ---\n");
159 run_test(NULL
, 0, NULL
, 0, 0x00);
160 run_test(NULL
, 0, NULL
, 0, 0xff);
162 /* Test 2: Compare two single bytes */
163 printf("--- test 2 ---\n");
166 run_test(&byte1
, 1, &byte2
, 1, 0x00); // first operand low
167 run_test(&byte1
, 1, &byte1
, 1, 0x00); // equal
168 run_test(&byte2
, 1, &byte1
, 1, 0x00); // first operand high
169 run_test(&byte1
, 1, &byte2
, 1, 0xFF); // first operand low
170 run_test(&byte1
, 1, &byte1
, 1, 0xFF); // equal
171 run_test(&byte2
, 1, &byte1
, 1, 0xFF); // first operand high
173 /* Test 3: Compare a single byte against the pad byte */
174 printf("--- test 3 ---\n");
176 run_test(NULL
, 0, &byte
, 1, 10); // equal
177 run_test(NULL
, 0, &byte
, 1, 9); // first operand low
178 run_test(NULL
, 0, &byte
, 1, 11); // first operand high
180 run_test(&byte
, 1, NULL
, 0, 10); // equal
181 run_test(&byte
, 1, NULL
, 0, 9); // first operand high
182 run_test(&byte
, 1, NULL
, 0, 11); // first operand low
184 /* Test 4: Make sure pad byte is interpreted as unsigned value */
185 printf("--- test 4 ---\n");
187 run_test(&byte
, 1, NULL
, 0, 0xFF); // first operand low
189 run_test(&byte
, 1, NULL
, 0, 0xFF); // equal
191 /* Test 5: Compare a buffer against the pad byte */
192 printf("--- test 5 ---\n");
193 uint8_t buf1
[4] = "yyyy";
194 run_test(buf1
, 4, NULL
, 0, 'y'); // equal
195 run_test(buf1
, 4, NULL
, 0, 'x'); // greater
196 run_test(buf1
, 4, NULL
, 0, 'z'); // less
198 /* Test 6: Compare two buffers of same size (difference in 1st byte) */
200 printf("--- test 6 ---\n");
201 uint8_t x
[5] = "pqrst";
202 uint8_t y
[5] = "abcde";
203 uint8_t z
[5] = "abcde";
204 run_test(x
, 5, y
, 5, 'a'); // first operand low
205 run_test(y
, 5, x
, 5, 'a'); // first operand high
206 run_test(y
, 5, z
, 5, 'q'); // equal
209 /* Test 7: Compare two buffers of same size (difference in last byte) */
211 printf("--- test 7 ---\n");
212 uint8_t x
[5] = "abcdd";
213 uint8_t y
[5] = "abcde";
214 uint8_t z
[5] = "abcdf";
215 run_test(x
, 5, y
, 5, 'a'); // first operand low
216 run_test(z
, 5, z
, 5, 'a'); // first operand high
219 /* Test 8: Compare two buffers of different size. The difference
220 is past the end of the shorter string. */
222 printf("--- test 8 ---\n");
223 uint8_t x
[5] = "abcde";
224 uint8_t y
[7] = "abcdeff";
225 run_test(x
, 5, y
, 7, 0); // first operand low
226 run_test(y
, 7, x
, 5, 0); // first operand high
227 run_test(x
, 5, y
, 7, 'f'); // equal
228 run_test(y
, 7, x
, 5, 'f'); // equal
231 /* Test 9: Compare two buffers of different size. The difference
232 is before the end of the shorter string. */
234 printf("--- test 9 ---\n");
235 uint8_t x
[5] = "abcab";
236 uint8_t y
[7] = "abcdeff";
237 run_test(x
, 5, y
, 7, 0); // first operand low
238 run_test(y
, 7, x
, 5, 0); // first operand high
239 run_test(x
, 5, y
, 7, 'f'); // first operand low
240 run_test(y
, 7, x
, 5, 'f'); // first operand high