19fa1db4cSMartin Schwidefsky /* SPDX-License-Identifier: GPL-2.0 */
28bc1e4ecSHeiko Carstens /*
38bc1e4ecSHeiko Carstens  * Generate opcode table initializers for the in-kernel disassembler.
48bc1e4ecSHeiko Carstens  *
58bc1e4ecSHeiko Carstens  *    Copyright IBM Corp. 2017
68bc1e4ecSHeiko Carstens  *
78bc1e4ecSHeiko Carstens  */
88bc1e4ecSHeiko Carstens 
98bc1e4ecSHeiko Carstens #include <stdlib.h>
108bc1e4ecSHeiko Carstens #include <string.h>
118bc1e4ecSHeiko Carstens #include <ctype.h>
128bc1e4ecSHeiko Carstens #include <stdio.h>
138bc1e4ecSHeiko Carstens 
148bc1e4ecSHeiko Carstens #define STRING_SIZE_MAX 20
158bc1e4ecSHeiko Carstens 
168bc1e4ecSHeiko Carstens struct insn_type {
178bc1e4ecSHeiko Carstens 	unsigned char byte;
188bc1e4ecSHeiko Carstens 	unsigned char mask;
198bc1e4ecSHeiko Carstens 	char **format;
208bc1e4ecSHeiko Carstens };
218bc1e4ecSHeiko Carstens 
228bc1e4ecSHeiko Carstens struct insn {
238bc1e4ecSHeiko Carstens 	struct insn_type *type;
248bc1e4ecSHeiko Carstens 	char opcode[STRING_SIZE_MAX];
258bc1e4ecSHeiko Carstens 	char name[STRING_SIZE_MAX];
268bc1e4ecSHeiko Carstens 	char upper[STRING_SIZE_MAX];
278bc1e4ecSHeiko Carstens 	char format[STRING_SIZE_MAX];
288bc1e4ecSHeiko Carstens 	unsigned int name_len;
298bc1e4ecSHeiko Carstens };
308bc1e4ecSHeiko Carstens 
318bc1e4ecSHeiko Carstens struct insn_group {
328bc1e4ecSHeiko Carstens 	struct insn_type *type;
338bc1e4ecSHeiko Carstens 	int offset;
348bc1e4ecSHeiko Carstens 	int count;
358bc1e4ecSHeiko Carstens 	char opcode[2];
368bc1e4ecSHeiko Carstens };
378bc1e4ecSHeiko Carstens 
388bc1e4ecSHeiko Carstens struct insn_format {
398bc1e4ecSHeiko Carstens 	char *format;
408bc1e4ecSHeiko Carstens 	int type;
418bc1e4ecSHeiko Carstens };
428bc1e4ecSHeiko Carstens 
438bc1e4ecSHeiko Carstens struct gen_opcode {
448bc1e4ecSHeiko Carstens 	struct insn *insn;
458bc1e4ecSHeiko Carstens 	int nr;
468bc1e4ecSHeiko Carstens 	struct insn_group *group;
478bc1e4ecSHeiko Carstens 	int nr_groups;
488bc1e4ecSHeiko Carstens };
498bc1e4ecSHeiko Carstens 
508bc1e4ecSHeiko Carstens /*
518bc1e4ecSHeiko Carstens  * Table of instruction format types. Each opcode is defined with at
528bc1e4ecSHeiko Carstens  * least one byte (two nibbles), three nibbles, or two bytes (four
538bc1e4ecSHeiko Carstens  * nibbles).
548bc1e4ecSHeiko Carstens  * The byte member of each instruction format type entry defines
558bc1e4ecSHeiko Carstens  * within which byte of an instruction the third (and fourth) nibble
568bc1e4ecSHeiko Carstens  * of an opcode can be found. The mask member is the and-mask that
578bc1e4ecSHeiko Carstens  * needs to be applied on this byte in order to get the third (and
588bc1e4ecSHeiko Carstens  * fourth) nibble of the opcode.
598bc1e4ecSHeiko Carstens  * The format array defines all instruction formats (as defined in the
608bc1e4ecSHeiko Carstens  * Principles of Operation) which have the same position of the opcode
618bc1e4ecSHeiko Carstens  * nibbles.
628bc1e4ecSHeiko Carstens  * A special case are instruction formats with 1-byte opcodes. In this
638bc1e4ecSHeiko Carstens  * case the byte member always is zero, so that the mask is applied on
648bc1e4ecSHeiko Carstens  * the (only) byte that contains the opcode.
658bc1e4ecSHeiko Carstens  */
668bc1e4ecSHeiko Carstens static struct insn_type insn_type_table[] = {
678bc1e4ecSHeiko Carstens 	{
688bc1e4ecSHeiko Carstens 		.byte = 0,
698bc1e4ecSHeiko Carstens 		.mask = 0xff,
708bc1e4ecSHeiko Carstens 		.format = (char *[]) {
718bc1e4ecSHeiko Carstens 			"MII",
728bc1e4ecSHeiko Carstens 			"RR",
738bc1e4ecSHeiko Carstens 			"RS",
748bc1e4ecSHeiko Carstens 			"RSI",
758bc1e4ecSHeiko Carstens 			"RX",
768bc1e4ecSHeiko Carstens 			"SI",
778bc1e4ecSHeiko Carstens 			"SMI",
788bc1e4ecSHeiko Carstens 			"SS",
798bc1e4ecSHeiko Carstens 			NULL,
808bc1e4ecSHeiko Carstens 		},
818bc1e4ecSHeiko Carstens 	},
828bc1e4ecSHeiko Carstens 	{
838bc1e4ecSHeiko Carstens 		.byte = 1,
848bc1e4ecSHeiko Carstens 		.mask = 0x0f,
858bc1e4ecSHeiko Carstens 		.format = (char *[]) {
868bc1e4ecSHeiko Carstens 			"RI",
878bc1e4ecSHeiko Carstens 			"RIL",
888bc1e4ecSHeiko Carstens 			"SSF",
898bc1e4ecSHeiko Carstens 			NULL,
908bc1e4ecSHeiko Carstens 		},
918bc1e4ecSHeiko Carstens 	},
928bc1e4ecSHeiko Carstens 	{
938bc1e4ecSHeiko Carstens 		.byte = 1,
948bc1e4ecSHeiko Carstens 		.mask = 0xff,
958bc1e4ecSHeiko Carstens 		.format = (char *[]) {
968bc1e4ecSHeiko Carstens 			"E",
978bc1e4ecSHeiko Carstens 			"IE",
988bc1e4ecSHeiko Carstens 			"RRE",
998bc1e4ecSHeiko Carstens 			"RRF",
1008bc1e4ecSHeiko Carstens 			"RRR",
1018bc1e4ecSHeiko Carstens 			"S",
1028bc1e4ecSHeiko Carstens 			"SIL",
1038bc1e4ecSHeiko Carstens 			"SSE",
1048bc1e4ecSHeiko Carstens 			NULL,
1058bc1e4ecSHeiko Carstens 		},
1068bc1e4ecSHeiko Carstens 	},
1078bc1e4ecSHeiko Carstens 	{
1088bc1e4ecSHeiko Carstens 		.byte = 5,
1098bc1e4ecSHeiko Carstens 		.mask = 0xff,
1108bc1e4ecSHeiko Carstens 		.format = (char *[]) {
1118bc1e4ecSHeiko Carstens 			"RIE",
1128bc1e4ecSHeiko Carstens 			"RIS",
1138bc1e4ecSHeiko Carstens 			"RRS",
1148bc1e4ecSHeiko Carstens 			"RSE",
1158bc1e4ecSHeiko Carstens 			"RSL",
1168bc1e4ecSHeiko Carstens 			"RSY",
1178bc1e4ecSHeiko Carstens 			"RXE",
1188bc1e4ecSHeiko Carstens 			"RXF",
1198bc1e4ecSHeiko Carstens 			"RXY",
1208bc1e4ecSHeiko Carstens 			"SIY",
1218bc1e4ecSHeiko Carstens 			"VRI",
1228bc1e4ecSHeiko Carstens 			"VRR",
1238bc1e4ecSHeiko Carstens 			"VRS",
1248bc1e4ecSHeiko Carstens 			"VRV",
1258bc1e4ecSHeiko Carstens 			"VRX",
1268bc1e4ecSHeiko Carstens 			"VSI",
1278bc1e4ecSHeiko Carstens 			NULL,
1288bc1e4ecSHeiko Carstens 		},
1298bc1e4ecSHeiko Carstens 	},
1308bc1e4ecSHeiko Carstens };
1318bc1e4ecSHeiko Carstens 
insn_format_to_type(char * format)1328bc1e4ecSHeiko Carstens static struct insn_type *insn_format_to_type(char *format)
1338bc1e4ecSHeiko Carstens {
1348bc1e4ecSHeiko Carstens 	char tmp[STRING_SIZE_MAX];
1358bc1e4ecSHeiko Carstens 	char *base_format, **ptr;
1368bc1e4ecSHeiko Carstens 	int i;
1378bc1e4ecSHeiko Carstens 
1388bc1e4ecSHeiko Carstens 	strcpy(tmp, format);
1398bc1e4ecSHeiko Carstens 	base_format = tmp;
1408bc1e4ecSHeiko Carstens 	base_format = strsep(&base_format, "_");
1418bc1e4ecSHeiko Carstens 	for (i = 0; i < sizeof(insn_type_table) / sizeof(insn_type_table[0]); i++) {
1428bc1e4ecSHeiko Carstens 		ptr = insn_type_table[i].format;
1438bc1e4ecSHeiko Carstens 		while (*ptr) {
1448bc1e4ecSHeiko Carstens 			if (!strcmp(base_format, *ptr))
1458bc1e4ecSHeiko Carstens 				return &insn_type_table[i];
1468bc1e4ecSHeiko Carstens 			ptr++;
1478bc1e4ecSHeiko Carstens 		}
1488bc1e4ecSHeiko Carstens 	}
1498bc1e4ecSHeiko Carstens 	exit(EXIT_FAILURE);
1508bc1e4ecSHeiko Carstens }
1518bc1e4ecSHeiko Carstens 
read_instructions(struct gen_opcode * desc)1528bc1e4ecSHeiko Carstens static void read_instructions(struct gen_opcode *desc)
1538bc1e4ecSHeiko Carstens {
1548bc1e4ecSHeiko Carstens 	struct insn insn;
1558bc1e4ecSHeiko Carstens 	int rc, i;
1568bc1e4ecSHeiko Carstens 
1578bc1e4ecSHeiko Carstens 	while (1) {
1588bc1e4ecSHeiko Carstens 		rc = scanf("%s %s %s", insn.opcode, insn.name, insn.format);
1598bc1e4ecSHeiko Carstens 		if (rc == EOF)
1608bc1e4ecSHeiko Carstens 			break;
1618bc1e4ecSHeiko Carstens 		if (rc != 3)
1628bc1e4ecSHeiko Carstens 			exit(EXIT_FAILURE);
1638bc1e4ecSHeiko Carstens 		insn.type = insn_format_to_type(insn.format);
1648bc1e4ecSHeiko Carstens 		insn.name_len = strlen(insn.name);
1658bc1e4ecSHeiko Carstens 		for (i = 0; i <= insn.name_len; i++)
1668bc1e4ecSHeiko Carstens 			insn.upper[i] = toupper((unsigned char)insn.name[i]);
1678bc1e4ecSHeiko Carstens 		desc->nr++;
1688bc1e4ecSHeiko Carstens 		desc->insn = realloc(desc->insn, desc->nr * sizeof(*desc->insn));
1698bc1e4ecSHeiko Carstens 		if (!desc->insn)
1708bc1e4ecSHeiko Carstens 			exit(EXIT_FAILURE);
1718bc1e4ecSHeiko Carstens 		desc->insn[desc->nr - 1] = insn;
1728bc1e4ecSHeiko Carstens 	}
1738bc1e4ecSHeiko Carstens }
1748bc1e4ecSHeiko Carstens 
cmpformat(const void * a,const void * b)1758bc1e4ecSHeiko Carstens static int cmpformat(const void *a, const void *b)
1768bc1e4ecSHeiko Carstens {
1778bc1e4ecSHeiko Carstens 	return strcmp(((struct insn *)a)->format, ((struct insn *)b)->format);
1788bc1e4ecSHeiko Carstens }
1798bc1e4ecSHeiko Carstens 
print_formats(struct gen_opcode * desc)1808bc1e4ecSHeiko Carstens static void print_formats(struct gen_opcode *desc)
1818bc1e4ecSHeiko Carstens {
1828bc1e4ecSHeiko Carstens 	char *format;
1838bc1e4ecSHeiko Carstens 	int i, count;
1848bc1e4ecSHeiko Carstens 
1858bc1e4ecSHeiko Carstens 	qsort(desc->insn, desc->nr, sizeof(*desc->insn), cmpformat);
1868bc1e4ecSHeiko Carstens 	format = "";
1878bc1e4ecSHeiko Carstens 	count = 0;
1888bc1e4ecSHeiko Carstens 	printf("enum {\n");
1898bc1e4ecSHeiko Carstens 	for (i = 0; i < desc->nr; i++) {
1908bc1e4ecSHeiko Carstens 		if (!strcmp(format, desc->insn[i].format))
1918bc1e4ecSHeiko Carstens 			continue;
1928bc1e4ecSHeiko Carstens 		count++;
1938bc1e4ecSHeiko Carstens 		format = desc->insn[i].format;
1948bc1e4ecSHeiko Carstens 		printf("\tINSTR_%s,\n", format);
1958bc1e4ecSHeiko Carstens 	}
1968bc1e4ecSHeiko Carstens 	printf("}; /* %d */\n\n", count);
1978bc1e4ecSHeiko Carstens }
1988bc1e4ecSHeiko Carstens 
cmp_long_insn(const void * a,const void * b)1998bc1e4ecSHeiko Carstens static int cmp_long_insn(const void *a, const void *b)
2008bc1e4ecSHeiko Carstens {
2018bc1e4ecSHeiko Carstens 	return strcmp(((struct insn *)a)->name, ((struct insn *)b)->name);
2028bc1e4ecSHeiko Carstens }
2038bc1e4ecSHeiko Carstens 
print_long_insn(struct gen_opcode * desc)2048bc1e4ecSHeiko Carstens static void print_long_insn(struct gen_opcode *desc)
2058bc1e4ecSHeiko Carstens {
2068bc1e4ecSHeiko Carstens 	struct insn *insn;
2078bc1e4ecSHeiko Carstens 	int i, count;
2088bc1e4ecSHeiko Carstens 
2098bc1e4ecSHeiko Carstens 	qsort(desc->insn, desc->nr, sizeof(*desc->insn), cmp_long_insn);
2108bc1e4ecSHeiko Carstens 	count = 0;
2118bc1e4ecSHeiko Carstens 	printf("enum {\n");
2128bc1e4ecSHeiko Carstens 	for (i = 0; i < desc->nr; i++) {
2138bc1e4ecSHeiko Carstens 		insn = &desc->insn[i];
2148bc1e4ecSHeiko Carstens 		if (insn->name_len < 6)
2158bc1e4ecSHeiko Carstens 			continue;
2168bc1e4ecSHeiko Carstens 		printf("\tLONG_INSN_%s,\n", insn->upper);
2178bc1e4ecSHeiko Carstens 		count++;
2188bc1e4ecSHeiko Carstens 	}
2198bc1e4ecSHeiko Carstens 	printf("}; /* %d */\n\n", count);
2208bc1e4ecSHeiko Carstens 
2218bc1e4ecSHeiko Carstens 	printf("#define LONG_INSN_INITIALIZER { \\\n");
2228bc1e4ecSHeiko Carstens 	for (i = 0; i < desc->nr; i++) {
2238bc1e4ecSHeiko Carstens 		insn = &desc->insn[i];
2248bc1e4ecSHeiko Carstens 		if (insn->name_len < 6)
2258bc1e4ecSHeiko Carstens 			continue;
2268bc1e4ecSHeiko Carstens 		printf("\t[LONG_INSN_%s] = \"%s\", \\\n", insn->upper, insn->name);
2278bc1e4ecSHeiko Carstens 	}
2288bc1e4ecSHeiko Carstens 	printf("}\n\n");
2298bc1e4ecSHeiko Carstens }
2308bc1e4ecSHeiko Carstens 
print_opcode(struct insn * insn,int nr)2318bc1e4ecSHeiko Carstens static void print_opcode(struct insn *insn, int nr)
2328bc1e4ecSHeiko Carstens {
2338bc1e4ecSHeiko Carstens 	char *opcode;
2348bc1e4ecSHeiko Carstens 
2358bc1e4ecSHeiko Carstens 	opcode = insn->opcode;
2368bc1e4ecSHeiko Carstens 	if (insn->type->byte != 0)
2378bc1e4ecSHeiko Carstens 		opcode += 2;
2388bc1e4ecSHeiko Carstens 	printf("\t[%4d] = { .opfrag = 0x%s, .format = INSTR_%s, ", nr, opcode, insn->format);
2398bc1e4ecSHeiko Carstens 	if (insn->name_len < 6)
2408bc1e4ecSHeiko Carstens 		printf(".name = \"%s\" ", insn->name);
2418bc1e4ecSHeiko Carstens 	else
2428bc1e4ecSHeiko Carstens 		printf(".offset = LONG_INSN_%s ", insn->upper);
2438bc1e4ecSHeiko Carstens 	printf("}, \\\n");
2448bc1e4ecSHeiko Carstens }
2458bc1e4ecSHeiko Carstens 
add_to_group(struct gen_opcode * desc,struct insn * insn,int offset)2468bc1e4ecSHeiko Carstens static void add_to_group(struct gen_opcode *desc, struct insn *insn, int offset)
2478bc1e4ecSHeiko Carstens {
2488bc1e4ecSHeiko Carstens 	struct insn_group *group;
2498bc1e4ecSHeiko Carstens 
2508bc1e4ecSHeiko Carstens 	group = desc->group ? &desc->group[desc->nr_groups - 1] : NULL;
2518bc1e4ecSHeiko Carstens 	if (group && (!strncmp(group->opcode, insn->opcode, 2) || group->type->byte == 0)) {
2528bc1e4ecSHeiko Carstens 		group->count++;
2538bc1e4ecSHeiko Carstens 		return;
2548bc1e4ecSHeiko Carstens 	}
2558bc1e4ecSHeiko Carstens 	desc->nr_groups++;
2568bc1e4ecSHeiko Carstens 	desc->group = realloc(desc->group, desc->nr_groups * sizeof(*desc->group));
2578bc1e4ecSHeiko Carstens 	if (!desc->group)
2588bc1e4ecSHeiko Carstens 		exit(EXIT_FAILURE);
2598bc1e4ecSHeiko Carstens 	group = &desc->group[desc->nr_groups - 1];
260d053d639SVasily Gorbik 	memcpy(group->opcode, insn->opcode, 2);
2618bc1e4ecSHeiko Carstens 	group->type = insn->type;
2628bc1e4ecSHeiko Carstens 	group->offset = offset;
2638bc1e4ecSHeiko Carstens 	group->count = 1;
2648bc1e4ecSHeiko Carstens }
2658bc1e4ecSHeiko Carstens 
cmpopcode(const void * a,const void * b)2668bc1e4ecSHeiko Carstens static int cmpopcode(const void *a, const void *b)
2678bc1e4ecSHeiko Carstens {
2688bc1e4ecSHeiko Carstens 	return strcmp(((struct insn *)a)->opcode, ((struct insn *)b)->opcode);
2698bc1e4ecSHeiko Carstens }
2708bc1e4ecSHeiko Carstens 
print_opcode_table(struct gen_opcode * desc)2718bc1e4ecSHeiko Carstens static void print_opcode_table(struct gen_opcode *desc)
2728bc1e4ecSHeiko Carstens {
2738bc1e4ecSHeiko Carstens 	char opcode[2] = "";
2748bc1e4ecSHeiko Carstens 	struct insn *insn;
2758bc1e4ecSHeiko Carstens 	int i, offset;
2768bc1e4ecSHeiko Carstens 
2778bc1e4ecSHeiko Carstens 	qsort(desc->insn, desc->nr, sizeof(*desc->insn), cmpopcode);
2788bc1e4ecSHeiko Carstens 	printf("#define OPCODE_TABLE_INITIALIZER { \\\n");
2798bc1e4ecSHeiko Carstens 	offset = 0;
2808bc1e4ecSHeiko Carstens 	for (i = 0; i < desc->nr; i++) {
2818bc1e4ecSHeiko Carstens 		insn = &desc->insn[i];
2828bc1e4ecSHeiko Carstens 		if (insn->type->byte == 0)
2838bc1e4ecSHeiko Carstens 			continue;
2848bc1e4ecSHeiko Carstens 		add_to_group(desc, insn, offset);
2858bc1e4ecSHeiko Carstens 		if (strncmp(opcode, insn->opcode, 2)) {
286d053d639SVasily Gorbik 			memcpy(opcode, insn->opcode, 2);
2878bc1e4ecSHeiko Carstens 			printf("\t/* %.2s */ \\\n", opcode);
2888bc1e4ecSHeiko Carstens 		}
2898bc1e4ecSHeiko Carstens 		print_opcode(insn, offset);
2908bc1e4ecSHeiko Carstens 		offset++;
2918bc1e4ecSHeiko Carstens 	}
2928bc1e4ecSHeiko Carstens 	printf("\t/* 1-byte opcode instructions */ \\\n");
2938bc1e4ecSHeiko Carstens 	for (i = 0; i < desc->nr; i++) {
2948bc1e4ecSHeiko Carstens 		insn = &desc->insn[i];
2958bc1e4ecSHeiko Carstens 		if (insn->type->byte != 0)
2968bc1e4ecSHeiko Carstens 			continue;
2978bc1e4ecSHeiko Carstens 		add_to_group(desc, insn, offset);
2988bc1e4ecSHeiko Carstens 		print_opcode(insn, offset);
2998bc1e4ecSHeiko Carstens 		offset++;
3008bc1e4ecSHeiko Carstens 	}
3018bc1e4ecSHeiko Carstens 	printf("}\n\n");
3028bc1e4ecSHeiko Carstens }
3038bc1e4ecSHeiko Carstens 
print_opcode_table_offsets(struct gen_opcode * desc)3048bc1e4ecSHeiko Carstens static void print_opcode_table_offsets(struct gen_opcode *desc)
3058bc1e4ecSHeiko Carstens {
3068bc1e4ecSHeiko Carstens 	struct insn_group *group;
3078bc1e4ecSHeiko Carstens 	int i;
3088bc1e4ecSHeiko Carstens 
3098bc1e4ecSHeiko Carstens 	printf("#define OPCODE_OFFSET_INITIALIZER { \\\n");
3108bc1e4ecSHeiko Carstens 	for (i = 0; i < desc->nr_groups; i++) {
3118bc1e4ecSHeiko Carstens 		group = &desc->group[i];
3128bc1e4ecSHeiko Carstens 		printf("\t{ .opcode = 0x%.2s, .mask = 0x%02x, .byte = %d, .offset = %d, .count = %d }, \\\n",
3138bc1e4ecSHeiko Carstens 		       group->opcode, group->type->mask, group->type->byte, group->offset, group->count);
3148bc1e4ecSHeiko Carstens 	}
3158bc1e4ecSHeiko Carstens 	printf("}\n\n");
3168bc1e4ecSHeiko Carstens }
3178bc1e4ecSHeiko Carstens 
main(int argc,char ** argv)3188bc1e4ecSHeiko Carstens int main(int argc, char **argv)
3198bc1e4ecSHeiko Carstens {
3208bc1e4ecSHeiko Carstens 	struct gen_opcode _desc = { 0 };
3218bc1e4ecSHeiko Carstens 	struct gen_opcode *desc = &_desc;
3228bc1e4ecSHeiko Carstens 
3238bc1e4ecSHeiko Carstens 	read_instructions(desc);
3247fbf8315SHendrik Brueckner 	printf("#ifndef __S390_GENERATED_DIS_DEFS_H__\n");
3257fbf8315SHendrik Brueckner 	printf("#define __S390_GENERATED_DIS_DEFS_H__\n");
3268bc1e4ecSHeiko Carstens 	printf("/*\n");
3278bc1e4ecSHeiko Carstens 	printf(" * DO NOT MODIFY.\n");
3288bc1e4ecSHeiko Carstens 	printf(" *\n");
3298bc1e4ecSHeiko Carstens 	printf(" * This file was generated by %s\n", __FILE__);
3308bc1e4ecSHeiko Carstens 	printf(" */\n\n");
3318bc1e4ecSHeiko Carstens 	print_formats(desc);
3328bc1e4ecSHeiko Carstens 	print_long_insn(desc);
3338bc1e4ecSHeiko Carstens 	print_opcode_table(desc);
3348bc1e4ecSHeiko Carstens 	print_opcode_table_offsets(desc);
3358bc1e4ecSHeiko Carstens 	printf("#endif\n");
3368bc1e4ecSHeiko Carstens 	exit(EXIT_SUCCESS);
3378bc1e4ecSHeiko Carstens }
338