URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [gen_or1k_isa/] [sources/] [gen_or1k_isa.c] - Rev 95
Go to most recent revision | Compare with Previous | Blame | View Log
#include <stdio.h> #include <stdlib.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 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("%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 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 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 argc, char *argv[]) { int i, j; int summary = 0; long classes = -1; if ((argc >= 2) && (strcmp(argv[1], "-s") == 0)) summary = 1; if (argc == 3) classes = strtol(argv[2], NULL, 0); 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); j= 0; while (get_or1k_isa(or1k_order[i].classes, &info)) { if (((1 << info.desc->class) & classes) == 0) continue; if (summary) { decode(info.opcode); if (j && ((j % 100) == 0)) printf("\\end{tabular}\\par}\n"); print_summary(((j % 100) == 0), info.opcode, info.desc); } else { print_header(info.opcode, info.desc); decode(info.opcode); print_encoding(); print_body(info.opcode, info.desc); } j++; } if (summary && j) printf("\\end{tabular}\\par}\n"); } printf("\n\\end{document}\n"); return 0; }
Go to most recent revision | Compare with Previous | Blame | View Log