1 #include <stdint.h>
2 #include <inttypes.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include "opcodes.h"
7
8 #ifndef M3
9 #define M3 0
10 #endif
11
12 /* The abstracted result of an CU12 insn */
13 typedef struct {
14 uint64_t addr1; // target
15 uint64_t len1;
16 uint64_t addr2; // source
17 uint64_t len2;
18 uint32_t cc;
19 } cu12_t;
20
21 /* Define various input buffers. */
22
23 /* 1-byte UTF-8 character */
24 uint8_t pattern1[] = {
25 0x00, 0x01, 0x02, 0x03
26 };
27
28 /* 2-byte UTF-8 character */
29 uint8_t pattern2[] = {
30 0xc2, 0x80,
31 0xc2, 0x81,
32 0xc2, 0x82,
33 0xc2, 0x83,
34 };
35
36 /* 3-byte UTF-8 character */
37 uint8_t pattern3[] = {
38 0xe1, 0x80, 0x80,
39 0xe1, 0x80, 0x81,
40 0xe1, 0x80, 0x82,
41 0xe1, 0x80, 0x83,
42 };
43
44 /* 4-byte UTF-8 character */
45 uint8_t pattern4[] = {
46 0xf4, 0x80, 0x80, 0x80,
47 0xf4, 0x80, 0x80, 0x81,
48 0xf4, 0x80, 0x80, 0x82,
49 0xf4, 0x80, 0x80, 0x83,
50 };
51
52
53 /* Mixed bytes */
54 uint8_t mixed[] = {
55 0x01, // 1 byte
56 0xc3, 0x80, // 2 bytes
57 0x12, // 1 byte
58 0xe1, 0x90, 0x93, // 3 bytes
59 0x23, // 1 byte
60 0xf4, 0x80, 0x90, 0x8a, // 4 bytes
61 0x34, // 1 byte
62 0xc4, 0x8c, // 2 bytes
63 0xe1, 0x91, 0x94, // 3 bytes
64 0xc5, 0x8a, // 2 bytes
65 0xf4, 0x80, 0x90, 0x8a, // 4 bytes
66 0xc5, 0x8a, // 2 bytes
67 0xe1, 0x91, 0x94, // 3 bytes
68 0xf4, 0x80, 0x90, 0x8a, // 4 bytes
69 0xe1, 0x91, 0x94, // 3 bytes
70 };
71
72 /* This is the buffer for the converted bytes. */
73 uint16_t buff[1000]; /* Large so we con'don't have to worry about it */
74
75
76 static cu12_t
do_cu12(uint16_t * dst,uint64_t dst_len,uint8_t * src,uint64_t src_len)77 do_cu12(uint16_t *dst, uint64_t dst_len, uint8_t *src, uint64_t src_len)
78 {
79 int cc = 42;
80 cu12_t regs;
81
82 /* build up the register pairs */
83 register uint8_t *source asm("4") = src;
84 register uint64_t source_len asm("5") = src_len;
85 register uint16_t *dest asm("2") = dst;
86 register uint64_t dest_len asm("3") = dst_len;
87
88 asm volatile(
89 CU12(M3,2,4)
90 "ipm %2\n\t"
91 "srl %2,28\n\t"
92 : "+d"(dest), "+d"(source), "=d"(cc),
93 "+d"(source_len), "+d"(dest_len)
94 :
95 : "memory", "cc");
96
97 /* Capture register contents at end of cu12 */
98 regs.addr1 = (uint64_t)dest;
99 regs.len1 = dest_len;
100 regs.addr2 = (uint64_t)source;
101 regs.len2 = source_len;
102 regs.cc = cc;
103
104 return regs;
105 }
106
107 void
run_test(uint16_t * dst,uint64_t dst_len,uint8_t * src,uint64_t src_len)108 run_test(uint16_t *dst, uint64_t dst_len, uint8_t *src, uint64_t src_len)
109 {
110 int i;
111 cu12_t result;
112
113 printf("UTF8: ");
114 if (src_len == 0)
115 printf(" <none>");
116 else {
117 for(i = 0; i < src_len; ++i)
118 printf(" %02x", src[i]);
119 }
120 printf("\n");
121
122 result = do_cu12(dst, dst_len, src, src_len);
123
124 // Write out the converted byte, if any
125 printf("UTF16: ");
126 if (dst_len - result.len1 == 0)
127 printf(" <none>");
128 else {
129 uint64_t num_bytes = dst_len - result.len1;
130
131 /* The number of bytes that were written must be divisible by 2 */
132 if (num_bytes % 2 != 0)
133 fprintf(stderr, "*** number of bytes is not a multiple of 2\n");
134
135 for (i = 0; i < num_bytes / 2; i++) {
136 printf(" %04x", dst[i]);
137 }
138 }
139 printf("\n");
140
141 printf(" cc = %d\n", result.cc);
142 if (dst != NULL)
143 printf(" dst address difference: %"PRId64, result.addr1 - (uint64_t)dst);
144 printf(" dst len: %"PRId64"\n", result.len1);
145
146 if (src != NULL)
147 printf(" src address difference: %"PRId64, result.addr2 - (uint64_t)src);
148 printf(" src len: %"PRId64"\n", result.len2);
149 }
150
151 // Test conversion of a one-byte character
convert_1_byte(void)152 void convert_1_byte(void)
153 {
154 int i;
155
156 printf("===== Conversion of a one-byte character =====\n");
157
158 printf("\n----- Valid characters -----\n");
159 uint8_t valid[] = {
160 0x00, 0x7f, // corner cases
161 0x01, 0x10, 0x7e, 0x5d // misc
162 };
163 run_test(buff, sizeof buff, valid, sizeof valid);
164
165 // As conversion stops upon encountering an invalid character, we
166 // need to test each invalid character separately, to make sure it
167 // is recognized as invalid.
168
169 printf("\n----- Invalid characters -----\n");
170 uint8_t always_invalid[] = {
171 0x80, 0xbf, // corner cases
172 0xf8, 0xff, // corner cases
173 0x81, 0xbe, 0x95, 0xab // misc
174 };
175 for (i = 0; i < sizeof always_invalid; ++i) {
176 uint8_t invalid_char[1];
177 invalid_char[0] = always_invalid[i];
178 run_test(buff, sizeof buff, invalid_char, sizeof invalid_char);
179 }
180
181 // In case of m3 == 0 we get cc=0 indicating exhaustion of source
182 printf("\n----- Invalid characters if m3 == 1 -----\n");
183 uint8_t invalid_if_m3[] = { // contains all such invalid characters
184 0xc0, 0xc1,
185 0xf5, 0xf6, 0xf7
186 };
187 for (i = 0; i < sizeof invalid_if_m3; ++i) {
188 uint8_t invalid_char[1];
189 invalid_char[0] = invalid_if_m3[i];
190 run_test(buff, sizeof buff, invalid_char, sizeof invalid_char);
191 }
192
193 printf("\n----- 1st char valid, 2nd char invalid -----\n");
194 uint8_t valid_invalid[] = {
195 0x10, // valid
196 0xaa // invalid
197 };
198 run_test(buff, sizeof buff, valid_invalid, sizeof valid_invalid);
199 }
200
201 // Test conversion of a two-byte character
convert_2_bytes(void)202 void convert_2_bytes(void)
203 {
204 int i;
205
206 printf("\n===== Conversion of a two-byte character =====\n");
207
208 printf("\n----- Valid characters -----\n");
209 uint8_t valid[] = {
210 0xc2, 0x80, // corner case
211 0xc2, 0xbf, // corner case
212 0xdf, 0x80, // corner case
213 0xdf, 0xbf, // corner case
214 0xc3, 0xbe, 0xda, 0xbc // misc
215 };
216 run_test(buff, sizeof buff, valid, sizeof valid);
217
218 printf("\n----- Valid characters if m3 == 0 -----\n");
219 // First char is 0xc0 or 0xc1
220 uint8_t valid_if_not_m3[] = {
221 0xc0, 0x80,
222 0xc0, 0xbf,
223 0xc1, 0x80,
224 0xc0, 0xbf
225 };
226 run_test(buff, sizeof buff, valid_if_not_m3, sizeof valid_if_not_m3);
227
228 // Test for invalid two-byte characters where the 1st byte is valid
229 // The 2nd byte is invalid if not in range 0x80..0xbf, inclusive
230
231 // As conversion stops upon encountering an invalid character, we
232 // need to test each invalid character separately, to make sure it
233 // is recognized as invalid.
234
235 printf("\n----- Invalid characters if m3 == 1 -----\n");
236 uint8_t always_invalid[] = {
237 0xc2, 0x00,
238 0xc2, 0x7f,
239 0xc2, 0xc0,
240 0xc2, 0xff
241 };
242 for (i = 0; i < sizeof always_invalid; i += 2) {
243 uint8_t invalid_char[2];
244 invalid_char[0] = always_invalid[i];
245 invalid_char[1] = always_invalid[i+1];
246 run_test(buff, sizeof buff, invalid_char, sizeof invalid_char);
247 }
248
249 /* Nb: for a two-byte character we need not test the case where
250 invalidity of the character (cc=2) takes precedence over exhaustion
251 of the 1st operand (cc=1). Invalidity of the character has already
252 been tested when testing the 1st byte. */
253
254 printf("\n----- 1st char valid, 2nd char invalid -----\n");
255 uint8_t valid_invalid[] = {
256 0xc3, 0x81, // valid
257 0xc4, 0x00 // invalid
258 };
259 run_test(buff, sizeof buff, valid_invalid, sizeof valid_invalid);
260 }
261
262 // Test conversion of a three-byte character
263 void
convert_3_bytes(void)264 convert_3_bytes(void)
265 {
266 int i;
267
268 printf("\n===== Conversion of a three-byte character =====\n");
269
270 /* Exhaustively test the 1st byte E0 - EF, and the interval boundaries for
271 the 2nd and 3rd bytes */
272 printf("\n----- Valid characters -----\n");
273 uint8_t e0[] = {
274 0xe0, 0xa0, 0x80,
275 0xe0, 0xbf, 0x80,
276 0xe0, 0xa0, 0xbf,
277 0xe0, 0xbf, 0xbf,
278 0xe0, 0xaa, 0xbb, // random e0 .. ..
279 };
280 run_test(buff, sizeof buff, e0, sizeof e0);
281
282 uint8_t ed[] = {
283 0xed, 0x80, 0x80,
284 0xed, 0x9f, 0x80,
285 0xed, 0x80, 0xbf,
286 0xed, 0x9f, 0xbf,
287 0xed, 0x8a, 0xbb, // random ed .. ..
288 };
289 run_test(buff, sizeof buff, ed, sizeof ed);
290
291 for (i = 0; i <= 0xf; ++i) {
292 uint8_t exxx_1[3] = { 0x0, 0x80, 0x80 };
293 uint8_t exxx_2[3] = { 0x0, 0xbf, 0x80 };
294 uint8_t exxx_3[3] = { 0x0, 0x80, 0xbf };
295 uint8_t exxx_4[3] = { 0x0, 0xbf, 0xbf };
296
297 if (i == 0x00) continue; // special case e0
298 if (i == 0x0d) continue; // special case ed
299
300 exxx_1[0] = 0xe0 | i;
301 exxx_2[0] = 0xe0 | i;
302 exxx_3[0] = 0xe0 | i;
303 exxx_4[0] = 0xe0 | i;
304 run_test(buff, sizeof buff, exxx_1, sizeof exxx_1);
305 run_test(buff, sizeof buff, exxx_2, sizeof exxx_2);
306 run_test(buff, sizeof buff, exxx_3, sizeof exxx_3);
307 run_test(buff, sizeof buff, exxx_4, sizeof exxx_4);
308 };
309
310 printf("\n----- Invalid characters (2nd byte is invalid) -----\n");
311 // Test for invalid three-byte characters where the 1st byte is valid
312 // The 2nd byte is invalid.
313
314 // As conversion stops upon encountering an invalid character, we
315 // need to test each invalid character separately, to make sure it
316 // is recognized as invalid.
317
318 e0[0] = 0xe0; // valid
319 e0[1] = 0x9f; // invalid because outside [0xa0 .. 0xbf]
320 e0[2] = 0x80; // valid
321 run_test(buff, sizeof buff, e0, sizeof e0);
322 e0[1] = 0xc0; // invalid because outside [0xa0 .. 0xbf]
323 run_test(buff, sizeof buff, e0, sizeof e0);
324
325 ed[0] = 0xed; // valid
326 ed[1] = 0x7f; // invalid because outside [0x80 .. 0x9f]
327 ed[2] = 0x80; // valid
328 run_test(buff, sizeof buff, ed, sizeof ed);
329 ed[1] = 0xa0; // invalid because outside [0x80 .. 0x9f]
330 run_test(buff, sizeof buff, ed, sizeof ed);
331
332 for (i = 0; i <= 0xf; ++i) {
333 uint8_t exxx_1[3] = { 0x0, 0x7f, 0x80 };
334 uint8_t exxx_2[3] = { 0x0, 0xc0, 0x80 };
335
336 if (i == 0x00) continue; // special case e0
337 if (i == 0x0d) continue; // special case ed
338
339 exxx_1[0] = 0xe0 | i;
340 exxx_2[0] = 0xe0 | i;
341 run_test(buff, sizeof buff, exxx_1, sizeof exxx_1);
342 run_test(buff, sizeof buff, exxx_2, sizeof exxx_2);
343 };
344
345 printf("\n----- Invalid characters (3rd byte is invalid) -----\n");
346 // For all 1st bytes 0xe0 .. 0xef the 3rd bytes must be in [0x80 .. 0xbf]
347 // No need to special case 0xe0 and 0xed
348 for (i = 0; i <= 0xf; ++i) {
349 uint8_t exxx_1[3] = { 0x0, 0xab, 0x7f };
350 uint8_t exxx_2[3] = { 0x0, 0xab, 0xc0 };
351
352 exxx_1[0] = 0xe0 | i;
353 exxx_2[0] = 0xe0 | i;
354 run_test(buff, sizeof buff, exxx_1, sizeof exxx_1);
355 run_test(buff, sizeof buff, exxx_2, sizeof exxx_2);
356 };
357
358 printf("\n----- Invalid 2nd char AND output exhausted -----\n");
359 /* The character is invalid in its 2nd byte AND the output buffer is
360 exhausted (2 bytes are needed) */
361 uint8_t pat1[] = {
362 0xe0, 0x00, 0x80
363 };
364 run_test(buff, 1, pat1, 3);
365
366 printf("\n----- Invalid 3rd char AND output exhausted -----\n");
367 /* The character is invalid in its 3rd byte AND the output buffer is
368 exhausted (2 bytes are needed) */
369 uint8_t pat2[] = {
370 0xe4, 0x84, 0x00
371 };
372 run_test(buff, 1, pat2, 3);
373
374 printf("\n----- 1st char valid, 2nd char invalid -----\n");
375 uint8_t valid_invalid[] = {
376 0xe1, 0x90, 0x90, // valid
377 0xe1, 0x00, 0x90 // invalid
378 };
379 run_test(buff, sizeof buff, valid_invalid, sizeof valid_invalid);
380 }
381
382 // Test conversion of a four-byte character
383 void
convert_4_bytes(void)384 convert_4_bytes(void)
385 {
386 int i, j;
387
388 printf("\n===== Conversion of a four-byte character =====\n");
389
390 printf("\n----- Valid characters -----\n");
391 for (i = 0; i <= 4; ++i) {
392 uint8_t valid[4];
393
394 valid[0] = 0xf0 | i;
395
396 for (j = 0; j <= 1; ++j) {
397 // Byte 2
398 if (i == 0) {
399 valid[1] = j == 0 ? 0x90 : 0xbf; // 0xf0
400 } else if (i == 4) {
401 valid[1] = j == 0 ? 0x80 : 0x8f; // 0xf4
402 } else {
403 valid[1] = j == 0 ? 0x80 : 0xbf; // 0xf1 .. 0xf3
404 }
405 // Byte 3 and byte 4 have same interval 0x80 .. 0xbf
406 valid[2] = 0x80;
407 valid[3] = 0x80;
408 run_test(buff, sizeof buff, valid, sizeof valid);
409 valid[2] = 0x80;
410 valid[3] = 0xbf;
411 run_test(buff, sizeof buff, valid, sizeof valid);
412 valid[2] = 0xbf;
413 valid[3] = 0x80;
414 run_test(buff, sizeof buff, valid, sizeof valid);
415 valid[2] = 0xbf;
416 valid[3] = 0xbf;
417 run_test(buff, sizeof buff, valid, sizeof valid);
418 }
419 }
420
421 printf("\n----- Valid characters if m3 == 0 -----\n");
422 // First char is 0xf5 .. 0xf7
423 uint8_t valid_if_not_m3[] = {
424 0xf5, 0x00, 0x00, 0x00,
425 0xf6, 0x11, 0x22, 0x33,
426 0xf7, 0x44, 0x55, 0x66,
427 };
428 run_test(buff, sizeof buff, valid_if_not_m3, sizeof valid_if_not_m3);
429
430 // As conversion stops upon encountering an invalid character, we
431 // need to test each invalid character separately, to make sure it
432 // is recognized as invalid.
433
434 printf("\n----- Invalid characters (2nd byte is invalid) -----\n");
435 // Test for invalid four-byte characters where the 2nd byte is invalid.
436 // All other bytes are valid
437 uint8_t f0[4], f4[4];
438
439 f0[0] = 0xf0; // valid
440 f0[1] = 0x8f; // invalid because outside [0x90 .. 0xbf]
441 f0[2] = 0x80; // valid
442 f0[3] = 0x80; // valid
443 run_test(buff, sizeof buff, f0, sizeof f0);
444 f0[1] = 0xc0; // invalid because outside [0x90 .. 0xbf]
445 run_test(buff, sizeof buff, f0, sizeof f0);
446
447 f4[0] = 0xf4; // valid
448 f4[1] = 0x7f; // invalid because outside [0x80 .. 0x8f]
449 f4[2] = 0x80; // valid
450 f4[3] = 0x80; // valid
451 run_test(buff, sizeof buff, f4, sizeof f4);
452 f4[1] = 0x90; // invalid because outside [0x80 .. 0x9f]
453 run_test(buff, sizeof buff, f4, sizeof f4);
454
455 for (i = 0; i <= 0x4; ++i) {
456 uint8_t fxxx_1[4] = { 0x0, 0x7f, 0x80, 0x80 };
457 uint8_t fxxx_2[4] = { 0x0, 0xc0, 0x80, 0x80 };
458
459 if (i == 0) continue; // special case f0
460 if (i == 4) continue; // special case f4
461
462 fxxx_1[0] = 0xf0 | i;
463 fxxx_2[0] = 0xf0 | i;
464 run_test(buff, sizeof buff, fxxx_1, sizeof fxxx_1);
465 run_test(buff, sizeof buff, fxxx_2, sizeof fxxx_2);
466 };
467
468 printf("\n----- Invalid characters (3rd byte is invalid) -----\n");
469 // Test for invalid four-byte characters where the 3rd byte is invalid.
470 // All other bytes are valid
471 for (i = 0; i <= 0x4; ++i) {
472 uint8_t fxxx[4] = { 0x0, 0x0, 0x0, 0x80 };
473
474 fxxx[0] = 0xf0 | i;
475 fxxx[1] = (i == 0) ? 0x94 : 0x84;
476 fxxx[2] = 0x7f;
477 run_test(buff, sizeof buff, fxxx, sizeof fxxx);
478 fxxx[2] = 0xc0;
479 run_test(buff, sizeof buff, fxxx, sizeof fxxx);
480 };
481
482 printf("\n----- Invalid characters (4th byte is invalid) -----\n");
483 // Test for invalid four-byte characters where the 3rd byte is invalid.
484 // All other bytes are valid
485 for (i = 0; i <= 0x4; ++i) {
486 uint8_t fxxx[4] = { 0x0, 0x0, 0x80, 0x0 };
487
488 fxxx[0] = 0xf0 | i;
489 fxxx[1] = (i == 0) ? 0x94 : 0x84;
490 fxxx[3] = 0x7f;
491 run_test(buff, sizeof buff, fxxx, sizeof fxxx);
492 fxxx[3] = 0xc0;
493 run_test(buff, sizeof buff, fxxx, sizeof fxxx);
494 };
495
496 printf("\n----- Invalid 2nd char AND output exhausted -----\n");
497 /* The character is invalid in its 2nd byte AND the output buffer is
498 exhausted (4 bytes are needed) */
499 uint8_t pat1[] = {
500 0xf0, 0x00, 0x80, 0x80
501 };
502 run_test(buff, 1, pat1, 4);
503
504 printf("\n----- Invalid 3rd char AND output exhausted -----\n");
505 /* The character is invalid in its 3rd byte AND the output buffer is
506 exhausted (4 bytes are needed) */
507 uint8_t pat2[] = {
508 0xf0, 0xaa, 0x00, 0x80
509 };
510 run_test(buff, 3, pat2, 4);
511
512 printf("\n----- Invalid 4th char AND output exhausted -----\n");
513 /* The character is invalid in its 4th byte AND the output buffer is
514 exhausted (4 bytes are needed) */
515 uint8_t pat3[] = {
516 0xf0, 0xaa, 0xaa, 0x00
517 };
518 run_test(buff, 3, pat3, 4);
519
520 printf("\n----- 1st char valid, 2nd char invalid -----\n");
521 uint8_t valid_invalid[] = {
522 0xf0, 0xaa, 0xaa, 0xaa, // valid
523 0xf0, 0x00, 0x00, 0x00 // invalid
524 };
525 run_test(buff, sizeof buff, valid_invalid, sizeof valid_invalid);
526 }
527
528
main()529 int main()
530 {
531 convert_1_byte();
532 convert_2_bytes();
533 convert_3_bytes();
534 convert_4_bytes();
535
536 /* Length == 0, no memory should be read or written */
537 printf("\n------------- test1 ----------------\n");
538 run_test(NULL, 0, NULL, 0);
539
540 /* Test exhaustion of source length (source bytes are valid) */
541 printf("\n------------- test2.1 ----------------\n");
542
543 /* No character will be written to BUFF, i.e. loop in jitted code
544 is not iterated */
545 run_test(buff, sizeof buff, NULL, 0);
546 run_test(buff, sizeof buff, pattern1, 0);
547 run_test(buff, sizeof buff, pattern2, 0);
548 run_test(buff, sizeof buff, pattern2, 1);
549 run_test(buff, sizeof buff, pattern3, 0);
550 run_test(buff, sizeof buff, pattern3, 1);
551 run_test(buff, sizeof buff, pattern3, 2);
552 run_test(buff, sizeof buff, pattern4, 0);
553 run_test(buff, sizeof buff, pattern4, 1);
554 run_test(buff, sizeof buff, pattern4, 2);
555 run_test(buff, sizeof buff, pattern4, 3);
556
557 printf("\n------------- test2.2 ----------------\n");
558 /* At least one character will be written to BUFF, i.e. loop in jitted
559 code is iterated */
560 run_test(buff, sizeof buff, pattern1, 2);
561 run_test(buff, sizeof buff, pattern2, 5);
562 run_test(buff, sizeof buff, pattern3, 6);
563 run_test(buff, sizeof buff, pattern4, 9);
564
565 /* Test exhaustion of destination length (source bytes are valid) */
566 printf("\n------------- test3.1 ----------------\n");
567
568 /* No character will be written to BUFF, i.e. loop in jitted code
569 is not iterated */
570
571 /* Want to write 2 or 4 bytes at a time */
572 run_test(NULL, 0, pattern1, sizeof pattern1); // 2-byte result
573 run_test(NULL, 0, pattern2, sizeof pattern2); // 2-byte result
574 run_test(NULL, 1, pattern2, sizeof pattern2); // 2-byte result
575 run_test(NULL, 0, pattern3, sizeof pattern3); // 2-byte result
576 run_test(NULL, 1, pattern3, sizeof pattern3); // 2-byte result
577 run_test(NULL, 0, pattern4, sizeof pattern4); // 4-byte result
578 run_test(NULL, 1, pattern4, sizeof pattern4); // 4-byte result
579 run_test(NULL, 2, pattern4, sizeof pattern4); // 4-byte result
580 run_test(NULL, 3, pattern4, sizeof pattern4); // 4-byte result
581
582 printf("\n------------- test3.2 ----------------\n");
583 /* At least one character will be written to BUFF, i.e. loop in jitted
584 code is iterated */
585 run_test(buff, 4, pattern1, sizeof pattern1);
586 run_test(buff, 5, pattern1, sizeof pattern2);
587 run_test(buff, 6, pattern1, sizeof pattern3);
588 run_test(buff, 7, pattern1, sizeof pattern4);
589
590 /* Convert buffer with mixed characters */
591 printf("\n------------- test4 ----------------\n");
592 run_test(buff, sizeof buff, mixed, sizeof mixed);
593
594 return 0;
595 }
596