%{ ////////////////////////////////////////////////////////////////////////////// //Copyright 2008 // Andrew Gacek, Steven Holte, Gopalan Nadathur, Xiaochu Qi, Zach Snow ////////////////////////////////////////////////////////////////////////////// // This file is part of Teyjus. // // // // Teyjus is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // (at your option) any later version. // // // // Teyjus is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with Teyjus. If not, see . // ////////////////////////////////////////////////////////////////////////////// #include #include "instrgen-c.h" #include "instrgen-haskell.h" #include "../util/util.h" extern int yylex(); int yywrap() {return 1;} void yyerror(const char* str) { printf("%s\n", str); } %} %union{ char* name; char* text; struct { int ival; char* sval; } isval; } %token OPTYPES INSTRCAT INSTRUCTIONS OPCODE MAXOPERAND CALL_I1_LEN SEMICOLON ERROR LBRACKET RBRACKET %token ID %token NUM %token STRING STRING2 %start instr_format %type operand_name operand_tname operand_type instr_name instr_cat instr_head instr_length operand_comp_type %type comments compiler_include %type max_operand opcode operand_size %% instr_format : compiler_include operands instrcats instructions compiler_include : STRING2 { ocgenInclude($1);} operands : OPTYPES operand_decs opcode_type { cgenOpsH(); ocgenOps();} ; operand_decs : operand_dec operand_decs | operand_dec_last ; operand_dec : operand_name operand_tname operand_type operand_size operand_comp_type comments { cgenOpTypes($1, $2, $3, $6, 0); ocgenOpType($1, $4.ival, $5); } | operand_name comments { cgenOpTypes($1, NULL, NULL, $2, 0); } ; operand_dec_last : operand_name operand_tname operand_type operand_size operand_comp_type comments { cgenOpTypes($1, $2, $3, $6, 1); ocgenOpType($1, $4.ival, $5); } | operand_name comments { cgenOpTypes($1, NULL, NULL, $2, 1); } ; operand_name : ID { $$ = $1; } ; operand_tname : ID { $$ = $1; } ; operand_type : ID { $$ = $1; } ; operand_comp_type : ID { $$ = $1; } ; comments : STRING {$$ = $1; } ; operand_size : NUM { $$ = $1; } ; opcode_type : OPCODE ID operand_size { cgenOpCodeType($2); ocgenOpCodeType($3.ival);} ; instrcats : INSTRCAT max_operand instrcat_decs CALL_I1_LEN NUM { cgenInstrCatH($5.sval); cgenInstrCatC($2.sval); ocgenInstrCat(); } ; max_operand : MAXOPERAND NUM { $$ = $2; } ; instrcat_decs : instrcat_dec instrcat_decs | instrcat_dec_last ; instrcat_dec : ID LBRACKET instr_format RBRACKET instr_lengths { cgenOneInstrCatH($1, 0); cgenOneInstrCatC($1, 0); ocgenOneInstrCat($1); } ; instrcat_dec_last : ID LBRACKET instr_format RBRACKET instr_lengths { cgenOneInstrCatH($1, 1); cgenOneInstrCatC($1, 1); ocgenOneInstrCat($1); } ; instr_format : oneOp instr_format | lastOp ; oneOp : ID { cgenInstrFormat($1, 0); ocgenInstrFormat($1); } ; lastOp : ID { cgenInstrFormat($1, 1); ocgenInstrFormat($1); } ; instr_lengths : instr_len_first SEMICOLON instr_lengths_rest | instr_len_first ; instr_lengths_rest : instr_len SEMICOLON instr_lengths_rest | instr_len ; instr_len_first : ID NUM {cgenInstrLength($1, $2.sval); ocgenInstrLength($1, $2.sval);} ; instr_len : ID NUM { cgenInstrLength($1, $2.sval);} ; instructions : instr_head instrs { cgenInstrH($1); cgenInstrC(); cgenSimDispatch(); ocgenInstr(); } ; instr_head : INSTRUCTIONS NUM { cinitInstrC($2.ival); cinitSimDispatch($2.ival); $$ = $2.sval; } ; instrs : instr SEMICOLON instrs | last_instr ; instr : comments opcode instr_name instr_cat instr_length { cgenOneInstrH($1, $2.sval , $3); cgenOneInstrC($2.ival, $3, $4, $5, 0); cgenOneSimDispatch($2.ival, $3, 0); ocgenOneInstr($2.sval, $3, $4, $5, 0); } | opcode instr_name instr_cat instr_length { cgenOneInstrH(NULL, $1.sval , $2); cgenOneInstrC($1.ival, $2, $3, $4, 0); cgenOneSimDispatch($1.ival, $2, 0); ocgenOneInstr($1.sval, $2, $3, $4, 0); } ; last_instr : comments opcode instr_name instr_cat instr_length { cgenOneInstrH($1, $2.sval , $3); cgenOneInstrC($2.ival, $3, $4, $5, 1); cgenOneSimDispatch($2.ival, $3, 1); ocgenOneInstr($2.sval, $3, $4, $5, 1); } | opcode instr_name instr_cat instr_length { cgenOneInstrH(NULL, $1.sval , $2); cgenOneInstrC($1.ival, $2, $3, $4, 1); cgenOneSimDispatch($1.ival, $2, 1); ocgenOneInstr($1.sval, $2, $3, $4, 1); } ; opcode : NUM { $$ = $1; } ; instr_name : ID { $$ = $1; } ; instr_cat : ID { $$ = $1; } ; instr_length : ID { $$ = $1; } ; %% extern FILE* yyin; int main(argc, argv) int argc; char * argv[]; { char * root = NULL; int ret = 0; if(argc <= 1) { if (sizeof(void*) == 8) { //printf("No input file specified; using 'instrformats_64.in'.\n"); yyin = UTIL_fopenR("instrformats_64.in"); } else { //printf("No input file specified; using 'instrformats_32.in'.\n"); yyin = UTIL_fopenR("instrformats_32.in"); } } else { yyin = UTIL_fopenR(argv[1]); } if(argc > 2) { root = argv[2]; } else { //printf("Teyjus source root directory not specified; using '../../'.\n"); root = "../../"; } //printf("Generating instruction files...\n"); ret = yyparse(); UTIL_fclose(yyin); if(ret != 0) { printf("Generation failed.\n"); return -1; } cspitCInstructionsH(root); cspitCInstructionsC(root); cspitSimDispatch(root); ocSpitInstructionHS(root); //printf("Done.\n"); return 0; }