URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [gen_or1k_isa/] [sources/] [gen_or1k_isa.c] - Rev 1780
Go to most recent revision | Compare with Previous | Blame | View Log
/* * $Log: not supported by cvs2svn $ * Revision 1.10 2003/01/28 03:49:24 lampret * Added cvs log keywords * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define NO_RELOC 20 #define RELOC_32 1 #define RELOC_8 2 #define RELOC_CONST 3 #define RELOC_CONSTH 4 #define EX_NONE "None" #define EX_NA_N "N" #define EX_NA_A "A" #define EX_RANGE "Range Exception" #define EX_TRAP "Trap Exception" #define EX_TLB "TLB miss" #define EX_PAGE "Page fault" #define EX_BUSER "Bus error" #include "opcode/or32.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) { /* printf("\n\ninput: %s\n", input); */ while (*input != '\0') { if (strncmp(input, "vector/floating-point", strlen("vector/floating-point")) == 0) { strcpy(output, "general-purpose"); output += strlen("general-purpose"); input += strlen("vector/floating-point") - 1; } else if (strncmp(input, "vfr", 3) == 0) { *output++ = 'r'; input += 2; } else 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 if (*input == '<') { *output++ = '$'; *output++ = '<'; *output++ = '$'; } else if (*input == '&' && *(input + 1) == '&') { *output++ = '\\';*output++ = '&'; *output++ = '\\';*output++ = '&'; /**output++ = 'v';*output++ = 'e';*output++ = 'r';*output++ = 'b'; *output++ = '*';*output++ = '&';*output++ = '&';*output++ = '*';*/ input++; } else *output++ = *input; input++; } *output = '\0'; /* printf("output: %s\n\n", output); */ } void eliminate_slash(char *input, char *output) { while (*input != '\0') { if (*input == '\\') { *output++ = '\n'; *output++ = '\n'; } else *output++ = *input; input++; } *output = '\0'; } void eliminate_crcr(char *input, char *output) { while (*input != '\0') { if (*input == '\\') { /* *output++ = '{'; *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("{\\footnotesize\\hspace{-0.5mm}\\hfil%d\\hfil}&\n", i); else printf("{\\footnotesize\\hspace{-1.5mm}\\hfil.\\hfil}&\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|}{\\small{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|}{\\small{%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|}{\\small{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|}{\\small{%d bits}}&\n", (i == 1 ? "|":""), decoded.field[i].bitsize); } printf("\\multicolumn{%d}", decoded.field[i].bitsize); printf("{%sc|}{\\small{%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 transform_except(char *input, char *output) { char *pTmp = NULL; pTmp = (char*)strtok(input, "\\"); while (pTmp) { if (strcmp(pTmp, EX_RANGE) == 0) *output++ = 'R'; if (strcmp(pTmp, EX_NA_N) == 0) *output++ = '-'; if (strcmp(pTmp, EX_NA_A) == 0) *output++ = '-'; if (strcmp(pTmp, EX_TRAP) == 0) *output++ = 'T'; if (strcmp(pTmp, EX_TLB) == 0) *output++ = 'M'; if (strcmp(pTmp, EX_PAGE) == 0) *output++ = 'P'; if (strcmp(pTmp, EX_BUSER) == 0) *output++ = 'B'; pTmp = (char*)strtok(NULL, "\\"); } *output = '\0'; } void print_reference(int newtable, struct or32_opcode *insn, struct or1k_isa *info) { char tmp[2000]; char tmp2[2000]; int i,j; if (newtable) { printf("\\footnotesize\n"); printf("\\begin{longtable}[t]{|p{2.3cm}|p{2cm}|p{6cm}|p{6cm}|p{0.6cm}|}\n"); printf("\\hline\n"); printf("\\normalsize ISN &\n"); printf("\\normalsize Name &\n"); printf("\\normalsize Description &\n"); /*printf("\\normalsize Usage &\n");*/ printf("\\normalsize Action &\n"); printf("\\normalsize ex. \\\\\n"); printf("\\hline\n"); printf("\\endhead\n"); printf("\\hline\n"); printf("\\endfoot\n"); } else { transform_tex(insn->name, tmp); transform_tex(insn->args, tmp2); printf("{\n\n\\raggedright %s %s} &\n", tmp, tmp2); transform_tex(info->title, tmp); printf("\\raggedright %s &\n", tmp); transform_tex(info->desc, tmp); printf("%s &\n", tmp); /* transform_tex(insn->args, tmp); transform_tex(insn->name, tmp2); printf("%s %s &\n", tmp2, tmp); */ eliminate_slash(info->oper32, tmp); transform_tex(tmp, tmp2); printf("{\n"); printf("%s} &\n", tmp2); /* transform_tex(info->oper64, tmp); printf("{\n"); printf("%s} &\n", tmp); */ tmp[0] = 0; strcpy(tmp2, info->except); transform_except(tmp2, tmp); printf("%s \\\\\n", tmp); printf("\\hline\n"); } } void print_summary(int newtable, struct or32_opcode *insn, struct or1k_isa *info) { char tmp[2000]; char tmp2[2000]; int i, j, k; if (newtable) { printf("{\\centering \\begin{tabular}{|l"); /* 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"); printf("Insn&\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("%d&\n"); printf("0\\\\\n"); } else { printf("\\multicolumn{1}{|c}{}&\n"); k = 31; for(i = 1; i <= decoded.fldcnt; i++) { for(j = 0; j < decoded.field[i].bitsize; j++) { if (j == 0) printf("\\multicolumn{1}{|l"); else if (j+1 == decoded.field[i].bitsize) printf("\\multicolumn{1}{|r"); else printf("\\multicolumn{1}{|c"); if (k) printf("}{%d}&\n", k); else printf("}{%d}\\\\\n", k); k--; } } } printf("\\multicolumn{1}{|l|}{"); transform_tex(info->name, tmp); printf("%s}&\n", tmp); /* 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"); /* print third row of the table */ /* printf("\\multicolumn{10}{|c|}{"); transform_tex(info->name, tmp); printf("%s ", tmp); transform_tex(insn->args, tmp); printf("%s}&\n", tmp); printf("\\multicolumn{22}{c|}{"); eliminate_crcr(info->desc, tmp2); transform_tex(tmp2, tmp); printf("%s}\\\\\n", tmp); */ } 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 "); printf("Middle Middle Middle Middle "); printf("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 = (struct or32_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}{cc}\n"); printf("Instruction Class&\n"); printf(" \\\\\n"); transform_tex(or1k_isa_classes[info->class].table, tmp); printf("%s\n", tmp); printf("\\end{tabular}\\par}\n"); /* printf("\\vfill\n"); printf("{\\centering \\begin{tabular}{|c|c|}\n"); printf("\\hline\n"); printf("Instruction Class&\n"); printf(" \\\\\n"); printf("\\hline\n"); transform_tex(or1k_isa_classes[info->class].table, tmp); printf("%s\\hline\n", tmp); printf("\\end{tabular}\\par}\n"); */ printf("\n"); } int main(int argc, char *argv[]) { int i, j; int mode = 0; long classes = -1; if ((argc >= 2) && (strcmp(argv[1], "-s") == 0)) mode = 1; if ((argc >= 2) && (strcmp(argv[1], "-r") == 0)) mode = 2; if (argc == 3) classes = strtol(argv[2], NULL, 0); cross_ref_check(); switch (mode) { case 0: case 1: printf("\n\\begin{document}\n\\vspace{50mm}"); break; case 2: printf("\\documentclass[10pt,a4paper,onepage]{article}\n"); printf("\\setlength{\\topmargin}{-0.5in}\n"); printf("\\setlength{\\textheight}{9.5in}\n"); printf("\\setlength{\\evensidemargin}{-1.5cm}\n"); printf("\\setlength{\\oddsidemargin}{-1.5cm}\n"); printf("\\usepackage{longtable}\n"); printf("\\begin{document}\n"); printf("\\pagestyle{empty}\n"); printf("\\hspace{-3cm}\\noindent\n"); } for(i = 0; strlen(or1k_order[i].title); i++) { printf("\\section{%s}\n \n \n", or1k_order[i].title); j= 0; while (get_or1k_isa(or1k_order[i].classes, &info)) { if (((1 << info.desc->class) & classes) == 0) continue; switch (mode) { case 1: decode(info.opcode); if (j && ((j % 100) == 0)) printf("\\end{tabular}\\par}\n"); print_summary(((j % 100) == 0), info.opcode, info.desc); break; case 2: decode(info.opcode); print_reference((j == 0), info.opcode, info.desc); break; case 0: print_header(info.opcode, info.desc); decode(info.opcode); print_encoding(); print_body(info.opcode, info.desc); } j++; } if ( (mode == 1) && j) printf("\\end{tabular}\\par}\n"); if ( (mode == 2) && j) printf("\\end{longtable}\n"); } printf("\n\\end{document}\n"); return 0; }
Go to most recent revision | Compare with Previous | Blame | View Log