/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Generate opcode table initializers for the in-kernel disassembler.
 *
 *    Copyright IBM Corp. 2017
 *
 */

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>

#define STRING_SIZE_MAX 20

struct insn_type {
	unsigned char byte;
	unsigned char mask;
	char **format;
};

struct insn {
	struct insn_type *type;
	char opcode[STRING_SIZE_MAX];
	char name[STRING_SIZE_MAX];
	char upper[STRING_SIZE_MAX];
	char format[STRING_SIZE_MAX];
	unsigned int name_len;
};

struct insn_group {
	struct insn_type *type;
	int offset;
	int count;
	char opcode[2];
};

struct insn_format {
	char *format;
	int type;
};

struct gen_opcode {
	struct insn *insn;
	int nr;
	struct insn_group *group;
	int nr_groups;
};

/*
 * Table of instruction format types. Each opcode is defined with at
 * least one byte (two nibbles), three nibbles, or two bytes (four
 * nibbles).
 * The byte member of each instruction format type entry defines
 * within which byte of an instruction the third (and fourth) nibble
 * of an opcode can be found. The mask member is the and-mask that
 * needs to be applied on this byte in order to get the third (and
 * fourth) nibble of the opcode.
 * The format array defines all instruction formats (as defined in the
 * Principles of Operation) which have the same position of the opcode
 * nibbles.
 * A special case are instruction formats with 1-byte opcodes. In this
 * case the byte member always is zero, so that the mask is applied on
 * the (only) byte that contains the opcode.
 */
static struct insn_type insn_type_table[] = {
	{
		.byte = 0,
		.mask = 0xff,
		.format = (char *[]) {
			"MII",
			"RR",
			"RS",
			"RSI",
			"RX",
			"SI",
			"SMI",
			"SS",
			NULL,
		},
	},
	{
		.byte = 1,
		.mask = 0x0f,
		.format = (char *[]) {
			"RI",
			"RIL",
			"SSF",
			NULL,
		},
	},
	{
		.byte = 1,
		.mask = 0xff,
		.format = (char *[]) {
			"E",
			"IE",
			"RRE",
			"RRF",
			"RRR",
			"S",
			"SIL",
			"SSE",
			NULL,
		},
	},
	{
		.byte = 5,
		.mask = 0xff,
		.format = (char *[]) {
			"RIE",
			"RIS",
			"RRS",
			"RSE",
			"RSL",
			"RSY",
			"RXE",
			"RXF",
			"RXY",
			"SIY",
			"VRI",
			"VRR",
			"VRS",
			"VRV",
			"VRX",
			"VSI",
			NULL,
		},
	},
};

static struct insn_type *insn_format_to_type(char *format)
{
	char tmp[STRING_SIZE_MAX];
	char *base_format, **ptr;
	int i;

	strcpy(tmp, format);
	base_format = tmp;
	base_format = strsep(&base_format, "_");
	for (i = 0; i < sizeof(insn_type_table) / sizeof(insn_type_table[0]); i++) {
		ptr = insn_type_table[i].format;
		while (*ptr) {
			if (!strcmp(base_format, *ptr))
				return &insn_type_table[i];
			ptr++;
		}
	}
	exit(EXIT_FAILURE);
}

static void read_instructions(struct gen_opcode *desc)
{
	struct insn insn;
	int rc, i;

	while (1) {
		rc = scanf("%s %s %s", insn.opcode, insn.name, insn.format);
		if (rc == EOF)
			break;
		if (rc != 3)
			exit(EXIT_FAILURE);
		insn.type = insn_format_to_type(insn.format);
		insn.name_len = strlen(insn.name);
		for (i = 0; i <= insn.name_len; i++)
			insn.upper[i] = toupper((unsigned char)insn.name[i]);
		desc->nr++;
		desc->insn = realloc(desc->insn, desc->nr * sizeof(*desc->insn));
		if (!desc->insn)
			exit(EXIT_FAILURE);
		desc->insn[desc->nr - 1] = insn;
	}
}

static int cmpformat(const void *a, const void *b)
{
	return strcmp(((struct insn *)a)->format, ((struct insn *)b)->format);
}

static void print_formats(struct gen_opcode *desc)
{
	char *format;
	int i, count;

	qsort(desc->insn, desc->nr, sizeof(*desc->insn), cmpformat);
	format = "";
	count = 0;
	printf("enum {\n");
	for (i = 0; i < desc->nr; i++) {
		if (!strcmp(format, desc->insn[i].format))
			continue;
		count++;
		format = desc->insn[i].format;
		printf("\tINSTR_%s,\n", format);
	}
	printf("}; /* %d */\n\n", count);
}

static int cmp_long_insn(const void *a, const void *b)
{
	return strcmp(((struct insn *)a)->name, ((struct insn *)b)->name);
}

static void print_long_insn(struct gen_opcode *desc)
{
	struct insn *insn;
	int i, count;

	qsort(desc->insn, desc->nr, sizeof(*desc->insn), cmp_long_insn);
	count = 0;
	printf("enum {\n");
	for (i = 0; i < desc->nr; i++) {
		insn = &desc->insn[i];
		if (insn->name_len < 6)
			continue;
		printf("\tLONG_INSN_%s,\n", insn->upper);
		count++;
	}
	printf("}; /* %d */\n\n", count);

	printf("#define LONG_INSN_INITIALIZER { \\\n");
	for (i = 0; i < desc->nr; i++) {
		insn = &desc->insn[i];
		if (insn->name_len < 6)
			continue;
		printf("\t[LONG_INSN_%s] = \"%s\", \\\n", insn->upper, insn->name);
	}
	printf("}\n\n");
}

static void print_opcode(struct insn *insn, int nr)
{
	char *opcode;

	opcode = insn->opcode;
	if (insn->type->byte != 0)
		opcode += 2;
	printf("\t[%4d] = { .opfrag = 0x%s, .format = INSTR_%s, ", nr, opcode, insn->format);
	if (insn->name_len < 6)
		printf(".name = \"%s\" ", insn->name);
	else
		printf(".offset = LONG_INSN_%s ", insn->upper);
	printf("}, \\\n");
}

static void add_to_group(struct gen_opcode *desc, struct insn *insn, int offset)
{
	struct insn_group *group;

	group = desc->group ? &desc->group[desc->nr_groups - 1] : NULL;
	if (group && (!strncmp(group->opcode, insn->opcode, 2) || group->type->byte == 0)) {
		group->count++;
		return;
	}
	desc->nr_groups++;
	desc->group = realloc(desc->group, desc->nr_groups * sizeof(*desc->group));
	if (!desc->group)
		exit(EXIT_FAILURE);
	group = &desc->group[desc->nr_groups - 1];
	memcpy(group->opcode, insn->opcode, 2);
	group->type = insn->type;
	group->offset = offset;
	group->count = 1;
}

static int cmpopcode(const void *a, const void *b)
{
	return strcmp(((struct insn *)a)->opcode, ((struct insn *)b)->opcode);
}

static void print_opcode_table(struct gen_opcode *desc)
{
	char opcode[2] = "";
	struct insn *insn;
	int i, offset;

	qsort(desc->insn, desc->nr, sizeof(*desc->insn), cmpopcode);
	printf("#define OPCODE_TABLE_INITIALIZER { \\\n");
	offset = 0;
	for (i = 0; i < desc->nr; i++) {
		insn = &desc->insn[i];
		if (insn->type->byte == 0)
			continue;
		add_to_group(desc, insn, offset);
		if (strncmp(opcode, insn->opcode, 2)) {
			memcpy(opcode, insn->opcode, 2);
			printf("\t/* %.2s */ \\\n", opcode);
		}
		print_opcode(insn, offset);
		offset++;
	}
	printf("\t/* 1-byte opcode instructions */ \\\n");
	for (i = 0; i < desc->nr; i++) {
		insn = &desc->insn[i];
		if (insn->type->byte != 0)
			continue;
		add_to_group(desc, insn, offset);
		print_opcode(insn, offset);
		offset++;
	}
	printf("}\n\n");
}

static void print_opcode_table_offsets(struct gen_opcode *desc)
{
	struct insn_group *group;
	int i;

	printf("#define OPCODE_OFFSET_INITIALIZER { \\\n");
	for (i = 0; i < desc->nr_groups; i++) {
		group = &desc->group[i];
		printf("\t{ .opcode = 0x%.2s, .mask = 0x%02x, .byte = %d, .offset = %d, .count = %d }, \\\n",
		       group->opcode, group->type->mask, group->type->byte, group->offset, group->count);
	}
	printf("}\n\n");
}

int main(int argc, char **argv)
{
	struct gen_opcode _desc = { 0 };
	struct gen_opcode *desc = &_desc;

	read_instructions(desc);
	printf("#ifndef __S390_GENERATED_DIS_DEFS_H__\n");
	printf("#define __S390_GENERATED_DIS_DEFS_H__\n");
	printf("/*\n");
	printf(" * DO NOT MODIFY.\n");
	printf(" *\n");
	printf(" * This file was generated by %s\n", __FILE__);
	printf(" */\n\n");
	print_formats(desc);
	print_long_insn(desc);
	print_opcode_table(desc);
	print_opcode_table_offsets(desc);
	printf("#endif\n");
	exit(EXIT_SUCCESS);
}
