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

Subversion Repositories or1k

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

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;
 
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++)
			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("\\end{tabular}\\par}\n");
 
}
 
void decode(struct or1_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 or1_opcode *insn, struct or1k_isa *info)
{
	printf("\n\n\\newpage\n");
	printf("\\vspace{10mm}\n");
	/* printf("\\section{Appendix A}\n"); */
	printf("\\lyxline{\\small}\\vspace{-1\\parskip}\n");
	printf("\\vspace{10mm}\n");	
	printf("{\\raggedright \\begin{tabular}{ccc}\n");
	printf("\\textbf{\\textcolor{white}{\\small Left}}\\textcolor{white}{\\small }&\n");
	printf("\\textcolor{white}{\\small }\\textbf{\\textcolor{white}{\\small Middle Middle\n");
	printf("Middle Middle Middle Middle Middle Middle}} \\textcolor{white}{\\small }&\n");
	printf("\\textcolor{white}{\\small }\\textbf{\\textcolor{white}{\\small Right}}\\\\\n");
	printf("\\textbf{\\huge %s}&\n", insn->name);
	printf("\\multicolumn{1}{c}{\\textbf{\\huge %s}}&\n", info->title);
	printf("\\textbf{\\huge %s}\\\\\n", insn->name);
	printf("\\end{tabular}\\par}\n\\bigskip{}\n\n");
}
 
struct or1k_isa *get_or1k_isa(char *name)
{
	int i;
 
	for (i = 0; strlen(or1k_isa_info[i].name); i++)
		if (strcmp(or1k_isa_info[i].name, name) == 0)
			break;
 
	return &or1k_isa_info[i];
}
 
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
			*output++ = *input;
		input++;
	}
	*output = '\0';
}
 
void print_body(struct or1_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");
	printf("\\texttt{\\large %s\\ %s}{\\large \\par}\n", insn->name, insn->args);
	printf("\\end{quotation}\n");
	printf("\\vspace{10mm}\n");
 
	printf("\\textbf{\\LARGE Description:}{\\LARGE \\par}\n");
	printf("\\vspace{5mm}\n");
	printf("\\begin{quotation}\n");
	printf("\\texttt{\\large %s}{\\large \\par}\n", info->desc);
	printf("\\end{quotation}\n");
	printf("\\vspace{10mm}\n");
 
	printf("\\textbf{\\LARGE Operation:}{\\LARGE \\par}\n");
	printf("\\vspace{5mm}\n");
	printf("\\begin{quotation}\n");
	transform_tex(info->oper, tmp);
	printf("%s\n", tmp);
	printf("\\end{quotation}\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("%s: \n", or1k_isa_classes[info->class].title);
	printf("{\\centering \\begin{tabular}{|c|c|c|}\n");
	printf("\\hline\n");
	printf("Architecture Level&\n");
	printf("Execution Mode&\n");
	printf("Implementation\\\\\n");
	printf("\\hline\n");
	printf("%s\n", or1k_isa_classes[info->class].table);
	printf("\\hline\n");
	printf("\\end{tabular}\\par}\n");
 
	printf("\n");
}
 
int main()
{
	int i;
	struct or1k_isa *info;
 
	printf("\n\\begin{document}\n\\vspace{50mm}");
	printf("\\section{OpenRISC 1000 Instruction Set}\n");
	printf("Draft, Do not distribute\n");
 
	for(i = 0; strlen(or1_opcodes[i].name); i++) {
 
		info = get_or1k_isa(or1_opcodes[i].name);
 
		print_header(&or1_opcodes[i], info);
		decode(&or1_opcodes[i]);
		print_encoding();
		print_body(&or1_opcodes[i], info);
	}
	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.