URL
https://opencores.org/ocsvn/scarts/scarts/trunk
Subversion Repositories scarts
[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [cgen/] [opc-itab.scm] - Rev 17
Go to most recent revision | Compare with Previous | Blame | View Log
; Opcode table support. ; Copyright (C) 2000, 2005, 2009 Red Hat, Inc. ; This file is part of CGEN. ; Append code here to be run before insn parsing/etc. ; These are for internal use and aren't intended to appear in .cpu files. ; ??? Nothing currently uses them but that might change. """"""""; Define CGEN_INIT_{PARSE,INSERT,EXTRACT,PRINT} macros. ; ??? These were early escape hatches. Not currently used. "Generating init macros ...\n""#define CGEN_INIT_PARSE(od) \\ {\\\n""}\n""#define CGEN_INIT_INSERT(od) \\ {\\\n""}\n""#define CGEN_INIT_EXTRACT(od) \\ {\\\n""}\n""#define CGEN_INIT_PRINT(od) \\ {\\\n""}\n"; Instruction field support. ; Return C code to declare various ifield types,decls. "Generating instruction field decls ...\n""/* This struct records data prior to insertion or after extraction. */\n""struct cgen_fields\n{\n"; A special member `length' is used to record the length. " int length;\n""};\n\n"; Instruction syntax support. ; Extract the operand fields in SYNTAX-STRING. ; The result is a list of operand names. ; ??? Not currently used, but keep awhile. "missing char after '\\'"; Extract the symbol from the string, which will be the name of ; an operand. Append it to the result. "missing operand name"; Note that 'n' includes the leading ${. "empty operand name""missing '}'""empty or invalid operand name"; Strip the mnemonic part from SYNTAX. ; (ie: everything up to but not including the first space or '$') ; If STRIP-MNEM-OPERANDS?, strip them too. """"; Compute the sequence of syntax bytes for SYNTAX. ; STRIP-MNEMONIC? is #t if the mnemonic part is to be stripped off. ; STRIP-MNEM-OPERANDS? is #t if any mnemonic operands are to be stripped off. ; SYNTAX is a string of text and operands. ; OP-MACRO is the macro to call that computes an operand's value. ; The resulting syntax is expressed as a sequence of bytes. ; Values < 128 are characters that must be matched. ; Values >= 128 are 128 + the index into the operand table. "syntax computation""""0""missing char after '\\'""'\\\\', ""'""', "; Extract the symbol from the string, which will be the name of ; an operand. Append it to the result. "missing operand name"; Is it $foo or ${foo}? ; Note that 'n' includes the leading ${. ; FIXME: \} not implemented yet. "empty operand name""missing '}'"" (""), ""empty or invalid operand name""undefined operand "" (""), "; Append the character to the result. "'""', "; Return C code to define the syntax string for SYNTAX ; MNEM is the C value to use to represent the instruction's mnemonic. ; OP is the C macro to use to compute an operand's syntax value. "{ { "", "; `mnem' is used to represent the mnemonic, so we always want to strip it ; from the syntax string, regardless of the setting of `strip-mnemonic?'. " } }"; Instruction format table support. ; Return the table for IFMT, an <iformat> object. ; sanitize based on the example insn "static const CGEN_IFMT "" ATTRIBUTE_UNUSED = {\n"" "", "", ""0x"", ""{ ""{ F ("") }, ""{ 0 } }\n};\n\n"; Generate the insn format table. "/* Instruction formats. */\n\n""F(f) & @arch@_cgen_ifld_table[@ARCH@_""f]""#undef F\n\n"; Parse/insert/extract/print handlers. ; Each handler type is recorded in the assembler/disassembler as an array of ; pointers to functions. The value recorded in the operand table is the index ; into this array. The first element in the array is reserved as index 0 is ; special (the "default"). ; ; The handlers are recorded here as associative lists in case we ever want ; to record more than just the name. ; ; Adding a new handler involves ; - specifying its name in the .cpu file ; - getting its name appended to these tables ; - writing the C code ; ; ??? It might be useful to define the handler in Scheme. Later. ; FIXME: There currently isn't a spot for specifying special handlers for ; each instruction. For now assume we always use the same ones. ", "", "", "; Return C code to define the cgen_opcode_handler struct for INSN. ; This is intended to be the ultimate escape hatch for the parse/insert/ ; extract/print handlers. Each entry is an index into a table of handlers. ; The escape hatch isn't used yet. "{ "" }"; Handler table support. ; There are tables for each of parse/insert/extract/print. ; Return C code to define the handler table for NAME with values VALUES. "cgen_""_fn * const @arch@_cgen_""_handlers[] = \n{\n"" ""_"",\n""};\n\n"; Instruction table support. ; Return a declaration of an enum for all insns. "Generating instruction enum ...\n""@arch@ instruction types""@ARCH@_INSN_""/* Index of `invalid' insn place holder. */\n""#define CGEN_INSN_INVALID @ARCH@_INSN_INVALID\n\n""/* Total number of insns in table. */\n""#define MAX_INSNS ((int) @ARCH@_INSN_"" + 1)\n\n"; Return a reference to the format table entry of INSN. "& "; Return the definition of an instruction value entry. "{ ""0x"; (ifmt-opcodes-beyond-base? (insn-ifmt insn)) ", { "; ??? wip: opcode values beyond the base insn "0 }"""" }"; Generate an insn opcode entry for INSN. ; ALL-ATTRS is a list of all instruction attributes. ; NUM-NON-BOOLS is the number of non-boolean insn attributes. "/* "" */\n"" {\n"" "",\n"" ""MNEM""OP"",\n"; ??? 'twould save space to put a pointer here and record format separately " "", ";"0x" (number->string (insn-value insn) 16) ",\n" "\n"" },\n"; Generate insn table. "Generating instruction opcode table ...\n""A(a) (1 << CGEN_INSN_""a)""OPERAND(op) @ARCH@_OPERAND_""op""\ #define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */ #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) /* The instruction table. */ static const CGEN_OPCODE @arch@_cgen_insn_opcode_table[MAX_INSNS] = { /* Special null first entry. A `num' value of zero is thus invalid. Also, the special `invalid' insn resides here. */ { { 0, 0, 0, 0 }, {{0}}, 0, {0}},\n""Generating insn opcode entry for "" ...\n""\ }; #undef A #undef OPERAND #undef MNEM #undef OP "; Return assembly/disassembly hashing support. "\ #ifndef CGEN_ASM_HASH_P #define CGEN_ASM_HASH_P(insn) 1 #endif #ifndef CGEN_DIS_HASH_P #define CGEN_DIS_HASH_P(insn) 1 #endif /* Return non-zero if INSN is to be added to the hash table. Targets are free to override CGEN_{ASM,DIS}_HASH_P in the .opc file. */ static int asm_hash_insn_p (insn) const CGEN_INSN *insn ATTRIBUTE_UNUSED; { return CGEN_ASM_HASH_P (insn); } static int dis_hash_insn_p (insn) const CGEN_INSN *insn; { /* If building the hash table and the NO-DIS attribute is present, ignore. */ if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_NO_DIS)) return 0; return CGEN_DIS_HASH_P (insn); } #ifndef CGEN_ASM_HASH #define CGEN_ASM_HASH_SIZE 127 #ifdef CGEN_MNEMONIC_OPERANDS #define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) #else #define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) /*FIXME*/ #endif #endif /* It doesn't make much sense to provide a default here, but while this is under development we do. BUFFER is a pointer to the bytes of the insn, target order. VALUE is the first base_insn_bitsize bits as an int in host order. */ #ifndef CGEN_DIS_HASH #define CGEN_DIS_HASH_SIZE 256 #define CGEN_DIS_HASH(buf, value) (*(unsigned char *) (buf)) #endif /* The result is the hash value of the insn. Targets are free to override CGEN_{ASM,DIS}_HASH in the .opc file. */ static unsigned int asm_hash_insn (mnem) const char * mnem; { return CGEN_ASM_HASH (mnem); } /* BUF is a pointer to the bytes of the insn, target order. VALUE is the first base_insn_bitsize bits as an int in host order. */ static unsigned int dis_hash_insn (buf, value) const char * buf ATTRIBUTE_UNUSED; CGEN_INSN_INT value ATTRIBUTE_UNUSED; { return CGEN_DIS_HASH (buf, value); } \n"; Hash support decls. "\ /* The hash functions are recorded here to help keep assembler code out of the disassembler and vice versa. */ static int asm_hash_insn_p (const CGEN_INSN *); static unsigned int asm_hash_insn (const char *); static int dis_hash_insn_p (const CGEN_INSN *); static unsigned int dis_hash_insn (const char *, CGEN_INSN_INT); \n"; Macro insn support. ; Return a macro-insn expansion entry. ; FIXME: wip "0, "; Return a macro-insn table entry. ; ??? wip, not currently used. " /* "" */\n"" {\n"" ""-1, "; macro-insns are not currently enumerated, no current need to "\"""\", ""\"""\",\n"" ""MNEM""OP"",\n"" (PTR) & macro_""_expansions[0],\n"" ""\n"" },\n"; Return a macro-insn opcode table entry. ; ??? wip, not currently used. " /* "" */\n"" {\n"" ""-1, "; macro-insns are not currently enumerated, no current need to "\"""\", ""\"""\",\n"" ""MNEM""OP"",\n"" (PTR) & macro_""_expansions[0],\n"" ""\n"" },\n"; Macro insn expansion has one basic form, but we optimize the common case ; of unconditionally expanding the input text to one instruction. ; The general form is a Scheme expression that is interpreted at runtime to ; decide how to perform the expansion. Yes, that means having a (perhaps ; minimal) Scheme interpreter in the assembler. ; Another thing to do is have a builder for each real insn so instead of ; expanding to text, the macro-expansion could invoke the builder for each ; expanded-to insn. "Generating macro-instruction table ...\n""gen-macro-insn-table""/* Formats for ALIAS macro-insns. */\n\n""F(f) & @arch@_cgen_ifld_table[@ARCH@_""f]""#undef F\n\n""/* Each non-simple macro entry points to an array of expansion possibilities. */\n\n""""static const CGEN_MINSN_EXPANSION macro_""_expansions[] =\n""{\n"" { 0, 0 }\n};\n\n""A(a) (1 << CGEN_INSN_""a)""OPERAND(op) @ARCH@_OPERAND_""op""\ #define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */ #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) /* The macro instruction table. */ static const CGEN_IBASE @arch@_cgen_macro_insn_table[] = { ""Generating macro-insn table entry for "" ...\n"; Simple macro-insns are emitted as aliases of real insns. "\ }; /* The macro instruction opcode table. */ static const CGEN_OPCODE @arch@_cgen_macro_insn_opcode_table[] = {\n""Generating macro-insn table entry for "" ...\n"; Simple macro-insns are emitted as aliases of real insns. "\ }; #undef A #undef OPERAND #undef MNEM #undef OP \n"; Emit a function to call to initialize the opcode table. "\ /* Set the recorded length of the insn in the CGEN_FIELDS struct. */ static void set_fields_bitsize (CGEN_FIELDS *fields, int size) { CGEN_FIELDS_BITSIZE (fields) = size; } /* Function to call before using the operand instance table. This plugs the opcode entries and macro instructions into the cpu table. */ void @arch@_cgen_init_opcode_table (CGEN_CPU_DESC cd) { int i; int num_macros = (sizeof (@arch@_cgen_macro_insn_table) / sizeof (@arch@_cgen_macro_insn_table[0])); const CGEN_IBASE *ib = & @arch@_cgen_macro_insn_table[0]; const CGEN_OPCODE *oc = & @arch@_cgen_macro_insn_opcode_table[0]; CGEN_INSN *insns = xmalloc (num_macros * sizeof (CGEN_INSN)); /* This test has been added to avoid a warning generated if memset is called with a third argument of value zero. */ if (num_macros >= 1) memset (insns, 0, num_macros * sizeof (CGEN_INSN)); for (i = 0; i < num_macros; ++i) { insns[i].base = &ib[i]; insns[i].opcode = &oc[i]; @arch@_cgen_build_insn_regex (& insns[i]); } cd->macro_insn_table.init_entries = insns; cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE); cd->macro_insn_table.num_init_entries = num_macros; oc = & @arch@_cgen_insn_opcode_table[0]; insns = (CGEN_INSN *) cd->insn_table.init_entries; for (i = 0; i < MAX_INSNS; ++i) { insns[i].opcode = &oc[i]; @arch@_cgen_build_insn_regex (& insns[i]); } cd->sizeof_fields = sizeof (CGEN_FIELDS); cd->set_fields_bitsize = set_fields_bitsize; cd->asm_hash_p = asm_hash_insn_p; cd->asm_hash = asm_hash_insn; cd->asm_hash_size = CGEN_ASM_HASH_SIZE; cd->dis_hash_p = dis_hash_insn_p; cd->dis_hash = dis_hash_insn; cd->dis_hash_size = CGEN_DIS_HASH_SIZE; } "; Top level C code generators ; FIXME: Create enum objects for all the enums we explicitly declare here. ; Then they'd be usable and we wouldn't have to special case them here. "Generating ""-opc.h ...\n""Instruction opcode header for @arch@.""\ #ifndef @ARCH@_OPC_H #define @ARCH@_OPC_H "" #endif /* @ARCH@_OPC_H */ "; This file contains the instruction opcode table. "Generating ""-opc.c ...\n""Instruction opcode table for @arch@.""\ #include \"sysdep.h\" #include \"ansidecl.h\" #include \"bfd.h\" #include \"symcat.h\" #include \"@prefix@-desc.h\" #include \"@prefix@-opc.h\" #include \"libiberty.h\" \n"
Go to most recent revision | Compare with Previous | Blame | View Log