OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gen_or1k_isa/] [sources/] [gen_or1k_isa.c] - Rev 89

Go to most recent revision | Compare with Previous | Blame | View Log

 
#include <stdio.h>
 
#define NO_RELOC 20
#define RELOC_32 1
#define RELOC_8 2
#define RELOC_CONST 3
#define RELOC_CONSTH 4
 
#include "or1.h"
#include "or1k_isadesc.h"
 
/* types of data in encoding field. */
typedef enum { opcode, reserved, operand } encfld_types;
 
/* encoding transformed for TeX output */
struct {
	int bitpos[33];
	int fldcnt;
	int insn_size;
	struct {
		encfld_types type;
		int value;
		int bitsize;
	} field[50];
} decoded;
 
struct info {
	struct or1k_isa *desc;
	struct or32_opcode *opcode;
} info;
 
void transform_tex(char *input, char *output)
{
	while (*input != '\0') {
		if (*input == '[') {
			*output++ = '{';
			*output++ = '[';
			*output++ = '}';
		} else if (*input == ']') {
			*output++ = '{';
			*output++ = ']';
			*output++ = '}';
		} else if (*input == '%') {
			*output++ = '\\';
			*output++ = '%';
		} else if (*input == '\\') {
			*output++ = '\\';
			*output++ = '\\';
		} else if (*input == '_') {
			*output++ = '\\';
			*output++ = '_';
		} else if (*input == '\t') {
			*output++ = '\\';
			*output++ = 'i';
			*output++ = 'n';
			*output++ = 'd';
			*output++ = 'e';
			*output++ = 'n';
			*output++ = 't';
			*output++ = ' ';
		} else
			*output++ = *input;
		input++;
	}
	*output = '\0';
}
 
void print_encoding()
{
	int i, j;
 
	printf("\\vspace{10mm}\n");
	printf("{\\centering \\begin{tabular}{");
 
	/* organization of the table */
	for(i = 1; i <= decoded.fldcnt; i++) {
		printf("|");
		for(j = 0; j < decoded.field[i].bitsize; j++)
			if (j == 0)
				printf("l");
			else if (j+1 == decoded.field[i].bitsize)
				printf("r");
			else
				printf("c");
	}
	printf("|}\n\\hline\n");
 
	/* print first row of the table */
	for(i = decoded.insn_size - 1; i > 0; i--)
		if (decoded.bitpos[i])
			printf("%d&\n", i);
		else
			printf(".&\n");
	printf("0\\\\\n\\hline\n");
 
	/* print second row of the table */
	for(i = 1; i <= decoded.fldcnt; i++) {
		if (decoded.field[i].type == opcode) {
			printf("\\multicolumn{%d}{", decoded.field[i].bitsize);
			printf("%s", (i == 1 ? "|":""));
			printf("c|}{opcode 0x%x}", decoded.field[i].value);
		} else if (decoded.field[i].type == operand) {
			printf("\\multicolumn{%d}{", decoded.field[i].bitsize);
			printf("%s", (i == 1 ? "|":""));
			printf("c|}{%c}", decoded.field[i].value);
		} else if (decoded.field[i].type == reserved) {
			printf("\\multicolumn{%d}{", decoded.field[i].bitsize);
			printf("%s", (i == 1 ? "|":""));
			printf("c|}{reserved}", decoded.field[i].value);
		}
		if (i == decoded.fldcnt)
			printf("\\\\\n");
		else
			printf("&\n");
	}
	printf("\n\\hline\n");
 
	/* print third row of the table */
	for(i = 1; i < decoded.fldcnt; i++) {
		printf("\\multicolumn{%d}", decoded.field[i].bitsize);
		printf("{%sc|}{%d bits}&\n", (i == 1 ? "|":""), decoded.field[i].bitsize);
	}
        printf("\\multicolumn{%d}", decoded.field[i].bitsize);
        printf("{%sc|}{%d bits}\\\\\n", (i == 1 ? "|":""), decoded.field[i].bitsize);
/*	printf("\n\\hline\n");
/*	printf("\\multicolumn{32}");
/*	printf("{|c|}{\\textcolor{white}{XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX ");
	printf("XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX}}\\\\\n");*/
        printf("\\end{tabular}\\par}\n");	
}
 
void decode(struct or32_opcode *insn)
{
        int opc_pos = 0;
        char *enc;
        encfld_types last;
        char lastoperand;
        int tmp;
 
	if (!insn) {
		printf("internal error: insn pointer NULL\n");
		return;
	}
 
	memset(&decoded, 0, sizeof(decoded));
 
	if ((insn->name[0] == 'h') && (insn->name[1] == '.'))
	        decoded.insn_size = opc_pos = 16;
	else
		decoded.insn_size = opc_pos = 32;
 
	last = -1;
 
        for (enc = insn->encoding; *enc != '\0'; )
                if ((*enc == '0') && (*(enc+1) == 'x')) {
                        int tmp = strtol(enc, NULL, 16);
                        if (last != opcode) {
                        	decoded.bitpos[opc_pos] = 1;
                        	decoded.bitpos[opc_pos - 1] = 1;
                        	decoded.field[++decoded.fldcnt].type = opcode;
			}
                       	decoded.field[decoded.fldcnt].value <<= 4;
                       	decoded.field[decoded.fldcnt].value += tmp;
                        decoded.field[decoded.fldcnt].bitsize += 4;
                        opc_pos -= 4;
                        enc += 3;
                        last = opcode;
                }
                else if (*enc == '0') {
                       if (last != opcode) {
                        	decoded.bitpos[opc_pos] = 1;
                        	decoded.bitpos[opc_pos - 1] = 1;
                        	decoded.field[++decoded.fldcnt].type = opcode;
			}
                       	decoded.field[decoded.fldcnt].value <<= 1;
                        decoded.field[decoded.fldcnt].bitsize += 1;
                	opc_pos--;
                        enc++;
                        last = opcode;
                }
                else if (*enc == '-') {
                       if (last != reserved) {
                        	decoded.bitpos[opc_pos] = 1;
                        	decoded.bitpos[opc_pos - 1] = 1;
                        	decoded.field[++decoded.fldcnt].type = reserved;
                        }
                       	decoded.field[decoded.fldcnt].value <<= 1;
                        decoded.field[decoded.fldcnt].bitsize += 1;
                        opc_pos--;
                        enc++;
                        last = reserved;
                }
                else if (*enc == '1') {
                       if (last != opcode) {
                        	decoded.bitpos[opc_pos] = 1;
                        	decoded.bitpos[opc_pos - 1] = 1;
                        	decoded.field[++decoded.fldcnt].type = opcode;
                        }
                       	decoded.field[decoded.fldcnt].value <<= 1;
                       	decoded.field[decoded.fldcnt].value += 1;
                        decoded.field[decoded.fldcnt].bitsize += 1;                
                        opc_pos--;
                        enc++;
                        last = opcode;
                }
                else if (isalpha(*enc)) {
                       if ((last != operand) || (lastoperand != *enc)) {
                        	decoded.bitpos[opc_pos] = 1;
                        	decoded.bitpos[opc_pos - 1] = 1;
                        	decoded.field[++decoded.fldcnt].type = operand;
                        }
                        decoded.field[decoded.fldcnt].value = *enc;
                        decoded.field[decoded.fldcnt].bitsize += 1;                
                        opc_pos--;
                        lastoperand = *enc;
                        enc++;
                        last = operand;
                }
                else
                        enc++;
}
 
void print_header(struct or32_opcode *insn, struct or1k_isa *info)
{
	char tmp[2000];
 
	printf("\n\n\\pagebreak\n");
	printf("\\vspace{10mm}\n");
	/* printf("\\section{Appendix A}\n"); */
	printf("\\lyxline{\\small}\\vspace{-1\\parskip}\n");
	printf("\\vspace{10mm}\n");	
	printf("{\\centering \\begin{tabular}{ccc}\n");
	printf("\\textbf{\\textcolor{white}{\\small Left}}\\textcolor{white}{\\small }&\n");
	printf("\\textcolor{white}{\\small }\\textbf{\\textcolor{white}{\\small Middle \n");
	printf("Middle Middle Middle Middle Middle Middle ");
	printf("Middle Middle Middle Middle Middle Middle ");
	printf("Middle Middle Middle}} \\textcolor{white}{\\small }&\n");
	printf("\\textcolor{white}{\\small }\\textbf{\\textcolor{white}{\\small Right}}\\\\\n");
	transform_tex(insn->name, tmp);
	printf("\\textbf{\\Large %s}&\n", tmp);
	transform_tex(info->title, tmp);
	printf("\\multicolumn{1}{c}{\\textbf{\\Large %s}}&\n", tmp);
	transform_tex(insn->name, tmp);
	printf("\\textbf{\\Large %s}\\\\\n", tmp);
	printf("\\end{tabular}\\par}\n\\bigskip{}\n\n");
}
 
struct or1k_isa *get_or1k_isa(unsigned long classes, struct info *info)
{
	int i;
	struct or1k_isa	*tmp;
 
	while (1) {
		/* Pick first instruction that wasn't printed yet and meets current class constraint */
		for (i = 0; strlen(or1k_isa_info[i].name); i++)
			if ((!or1k_isa_info[i].printed) && ((1<<or1k_isa_info[i].class)>>1 & classes))
				break;
 
		/* Don't return any instruction if they were all already processed or don't meet
		   class constraint. */
		if (strlen(or1k_isa_info[i].name) == 0) {
			fprintf(stderr, "All instructions that meet class constraint %x were processed.\n", classes);
			return NULL;
		}
 
		tmp = &or1k_isa_info[i];
 
		/* Check if tmp instruction is first in order to be processed. If preceeding
		   instructions are found, they are used instead. */
		for (i = 0; strlen(or1k_isa_info[i].name); i++)
			if ((!or1k_isa_info[i].printed) && ((1<<or1k_isa_info[i].class)>>1 & classes) &&
			    (strcmp(or1k_isa_info[i].name, tmp->name) < 0))
				tmp = &or1k_isa_info[i];
 
		tmp->printed = 1;
 
		/* Find matching encoding. */
		for (i = 0; strlen(or32_opcodes[i].name); i++)
			if (strcmp(tmp->name, or32_opcodes[i].name) == 0) {
				fprintf(stderr, "PROCESSING: %s\n", tmp->name);
				info->desc = tmp;
				info->opcode = &or32_opcodes[i];
				return tmp;
			}
	}
 
	return NULL;
}
 
void cross_ref_check()
{
	int i, j;
 
	for (i = 0; strlen(or32_opcodes[i].name); i++) {
		for (j = 0; strlen(or1k_isa_info[j].name); j++)
			if (strcmp(or32_opcodes[i].name, or1k_isa_info[j].name) == 0)
				break;
		if (strlen(or1k_isa_info[j].name) == 0)
			fprintf(stderr, "Description for %s missing.\n", or32_opcodes[i].name);
	}
 
	for (i = 0; strlen(or1k_isa_info[i].name); i++) {
		for (j = 0; strlen(or32_opcodes[j].name); j++)
			if (strcmp(or1k_isa_info[i].name, or32_opcodes[j].name) == 0)
				break;
		if (strlen(or32_opcodes[j].name) == 0)
			fprintf(stderr, "Encoding for %s missing.\n", or1k_isa_info[i].name);
	}
}
 
void print_body(struct or32_opcode *insn, struct or1k_isa *info)
{
	char tmp[2000];
 
	printf("\\vspace{15mm}\n");
 
	printf("{\\par \\raggedright \\textbf{\\Large Format:}\\Large \\par}\n");
	printf("\\vspace{5mm}\n");
	printf("\\begin{quotation}\n");
	transform_tex(info->name, tmp);
	printf("\\texttt{\\large %s\\ ", tmp);
	transform_tex(insn->args, tmp);
	printf("%s}{\\large \\par}\n", tmp);
	printf("\\end{quotation}\n");
	printf("\\vspace{10mm}\n");
 
	printf("\\textbf{\\Large Description:}{\\Large \\par}\n");
	printf("\\vspace{5mm}\n");
	printf("\\begin{quotation}\n");
	transform_tex(info->desc, tmp);
	printf("%s\n", tmp);
	printf("\\end{quotation}\n");
	printf("\\vspace{10mm}\n");
 
	printf("\\textbf{\\Large 32-bit Implementation:}{\\Large \\par}\n");
	printf("\\vspace{5mm}\n");
	printf("\\begin{flushleft}\n");
	printf("\\begin{quotation}\n");
	transform_tex(info->oper32, tmp);
	printf("\\texttt{\\large %s}{\\large \\par}\n", tmp);
	printf("\\end{quotation}\n");
	printf("\\end{flushleft}\n");
	printf("\\vspace{10mm}\n");
 
	printf("\\textbf{\\Large 64-bit Implementation:}{\\Large \\par}\n");
	printf("\\vspace{5mm}\n");
	printf("\\begin{flushleft}\n");
	printf("\\begin{quotation}\n");
	transform_tex(info->oper64, tmp);
	printf("\\texttt{\\large %s}{\\large \\par}\n", tmp);
	printf("\\end{quotation}\n");
	printf("\\end{flushleft}\n");
	printf("\\vspace{10mm}\n");
 
	printf("\\textbf{\\Large Exceptions:}{\\Large \\par}\n");
	printf("\\vspace{5mm}\n");
	printf("\\begin{flushleft}\n");
	printf("\\begin{quotation}\n");
	transform_tex(info->except, tmp);
	printf("\\texttt{\\large %s}{\\large \\par}\n",tmp);
	printf("\\end{quotation}\n");
	printf("\\end{flushleft}\n");
	printf("\\vspace{10mm}\n");
 
	printf("\\textbf{\\Large Notes:}{\\Large \\par}\n");
	printf("\\vspace{5mm}\n");
	printf("\\begin{quotation}\n");
	printf("\n");
	printf("\\end{quotation}\n");
	printf("\\vspace{10mm}\n");
 
	printf("\\vfill\n");
	printf("{\\centering \\begin{tabular}{|c|c|}\n");
	printf("\\hline\n");
	printf("Instruction Class&\n");
	printf("Implementation\\\\\n");
	printf("\\hline\n");
	transform_tex(or1k_isa_classes[info->class].table, tmp);
	printf("%s\n", tmp);
	printf("\\end{tabular}\\par}\n");
 
	printf("\n");
}
 
int main()
{
	int i;
 
	cross_ref_check();
	printf("\n\\begin{document}\n\\vspace{50mm}");
 
	for(i = 0; strlen(or1k_order[i].title); i++) {
		printf("\\section{%s}\n", or1k_order[i].title);
 
		while (get_or1k_isa(or1k_order[i].classes, &info)) {
 
			print_header(info.opcode, info.desc);
			decode(info.opcode);
			print_encoding();
			print_body(info.opcode, info.desc);
		}
	}
 
	printf("\n\\end{document}\n");
	return 0;
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.