All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alessandro Di Federico via <qemu-devel@nongnu.org>
To: qemu-devel@nongnu.org
Cc: tsimpson@quicinc.com, bcain@quicinc.com, babush@rev.ng,
	nizzo@rev.ng, Alessandro Di Federico <ale@rev.ng>
Subject: [RFC PATCH 07/10] target/hexagon: import lexer for idef-parser
Date: Thu, 11 Feb 2021 22:50:48 +0100	[thread overview]
Message-ID: <20210211215051.2102435-8-ale.qemu@rev.ng> (raw)
In-Reply-To: <20210211215051.2102435-1-ale.qemu@rev.ng>

From: Paolo Montesel <babush@rev.ng>

Signed-off-by: Alessandro Di Federico <ale@rev.ng>
---
 target/hexagon/idef-parser/idef-lexer.lex | 648 ++++++++++++++++++++++
 target/hexagon/idef-parser/idef-parser.h  | 245 ++++++++
 target/hexagon/meson.build                |   4 +
 3 files changed, 897 insertions(+)
 create mode 100644 target/hexagon/idef-parser/idef-lexer.lex
 create mode 100644 target/hexagon/idef-parser/idef-parser.h

diff --git a/target/hexagon/idef-parser/idef-lexer.lex b/target/hexagon/idef-parser/idef-lexer.lex
new file mode 100644
index 0000000000..b0e460b4d4
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-lexer.lex
@@ -0,0 +1,648 @@
+%option noyywrap noinput nounput
+%option 8bit reentrant bison-bridge
+%option warn nodefault
+%option header-file="idef-parser.yy.h"
+%option bison-locations
+
+%{
+/*
+ * Copyright(c) 2019-2020 rev.ng Srls. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <stdbool.h>
+
+#include "idef-parser.h"
+#include "idef-parser.tab.h"
+
+/* Keep track of scanner position for error message printout */
+#define YY_USER_ACTION yylloc->first_column = yylloc->last_column; \
+    for (int i = 0; yytext[i] != '\0'; i++) {   \
+        yylloc->last_column++;                  \
+    }
+
+/* Global Error Counter */
+int error_count;
+
+%}
+
+/* Definitions */
+DIGIT                    [0-9]
+LOWER_ID                 [a-z]
+UPPER_ID                 [A-Z]
+ID                       LOWER_ID|UPPER_ID
+INST_NAME                [A-Z]+[0-9]_([A-Za-z]|[0-9]|_)+
+HEX_DIGIT                [0-9a-fA-F]
+REG_ID_32                e|s|d|t|u|v|x|y
+REG_ID_64                ee|ss|dd|tt|uu|vv|xx|yy
+SYS_ID_32                s|d
+SYS_ID_64                ss|dd
+LOWER_PRE                d|s|t|u|v|e|x|x
+ZERO_ONE                 0|1
+IMM_ID                   r|s|S|u|U
+VAR_ID                   [a-zA-Z_][a-zA-Z0-9_]*
+SIGN_ID                  s|u
+
+/* Tokens */
+%%
+
+[ \t\f\v]+                { /* Ignore whitespaces. */ }
+[\n\r]+                   { /* Ignore newlines. */ }
+
+{INST_NAME}               { yylval->string = strdup(yytext);
+                            return INAME; }
+"fFLOAT"                 |
+"fUNFLOAT"               |
+"fDOUBLE"                |
+"fUNDOUBLE"              |
+"0.0"                    |
+"0x1.0p52"               |
+"0x1.0p-52"              { return FAIL; }
+"R"{REG_ID_32}"V" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = GENERAL_PURPOSE;
+                           yylval->rvalue.reg.id = yytext[1];
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = false;
+                           return REG; }
+"R"{REG_ID_32}"N" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = DOTNEW;
+                           yylval->rvalue.reg.id = yytext[1];
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = true;
+                           return REG; }
+"R"{REG_ID_64}"V" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = GENERAL_PURPOSE;
+                           yylval->rvalue.reg.id = yytext[1];
+                           yylval->rvalue.reg.bit_width = 64;
+                           yylval->rvalue.bit_width = 64;
+                           yylval->rvalue.is_dotnew = false;
+                           return REG; }
+"R"{REG_ID_64}"N" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = DOTNEW;
+                           yylval->rvalue.reg.id = yytext[1];
+                           yylval->rvalue.reg.bit_width = 64;
+                           yylval->rvalue.bit_width = 64;
+                           yylval->rvalue.is_dotnew = true;
+                           return REG; }
+"MuV" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = MODIFIER;
+                           yylval->rvalue.reg.id = 'u';
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return REG; }
+"C"{REG_ID_32}"V" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = CONTROL;
+                           yylval->rvalue.reg.id = yytext[1];
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = false;
+                           return REG; }
+"C"{REG_ID_64}"V" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = CONTROL;
+                           yylval->rvalue.reg.id = yytext[1];
+                           yylval->rvalue.reg.bit_width = 64;
+                           yylval->rvalue.bit_width = 64;
+                           yylval->rvalue.is_dotnew = false;
+                           return REG; }
+{IMM_ID}"iV" {
+                           yylval->rvalue.type = IMMEDIATE;
+                           yylval->rvalue.is_unsigned = false;
+                           yylval->rvalue.imm.type = VARIABLE;
+                           yylval->rvalue.imm.id = yytext[0];
+                           yylval->rvalue.is_dotnew = false;
+                           return IMM; }
+"P"{LOWER_PRE}"V" {
+                           yylval->rvalue.type = PREDICATE;
+                           yylval->rvalue.pre.id = yytext[1];
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = false;
+                           return PRE; }
+"P"{LOWER_PRE}"N" {
+                           yylval->rvalue.type = PREDICATE;
+                           yylval->rvalue.pre.id = yytext[1];
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = true;
+                           return PRE; }
+"in R"{REG_ID_32}"V" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = GENERAL_PURPOSE;
+                           yylval->rvalue.reg.id = yytext[4];
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = false;
+                           return RREG; }
+"in R"{REG_ID_64}"V" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = GENERAL_PURPOSE;
+                           yylval->rvalue.reg.id = yytext[4];
+                           yylval->rvalue.reg.bit_width = 64;
+                           yylval->rvalue.bit_width = 64;
+                           yylval->rvalue.is_dotnew = false;
+                           return RREG; }
+"in N"{REG_ID_32}"N" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = DOTNEW;
+                           yylval->rvalue.reg.id = yytext[4];
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = true;
+                           return RREG; }
+"in N"{REG_ID_64}"N" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = DOTNEW;
+                           yylval->rvalue.reg.id = yytext[4];
+                           yylval->rvalue.reg.bit_width = 64;
+                           yylval->rvalue.bit_width = 64;
+                           yylval->rvalue.is_dotnew = true;
+                           return RREG; }
+"in P"{LOWER_PRE}"V" {
+                           yylval->rvalue.type = PREDICATE;
+                           yylval->rvalue.pre.id = yytext[4];
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = false;
+                           return RPRE; }
+"in P"{LOWER_PRE}"N" {
+                           yylval->rvalue.type = PREDICATE;
+                           yylval->rvalue.pre.id = yytext[4];
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = true;
+                           return RPRE; }
+"in MuV" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = MODIFIER;
+                           yylval->rvalue.reg.id = 'u';
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return RREG; }
+"in C"{REG_ID_32}"V" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = CONTROL;
+                           yylval->rvalue.reg.id = yytext[4];
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = false;
+                           return RREG; }
+"in C"{REG_ID_64}"V" {
+                           yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = CONTROL;
+                           yylval->rvalue.reg.id = yytext[4];
+                           yylval->rvalue.reg.bit_width = 64;
+                           yylval->rvalue.bit_width = 64;
+                           yylval->rvalue.is_dotnew = false;
+                           return RREG; }
+"fGEN_TCG_"{INST_NAME}"(" { return FWRAP; }
+"(unsigned int)"         { /* Skip c-style casts */ }
+"{"                      { return LBR; }
+"}"                      { return RBR; }
+"["                      { return LSQ; }
+"]"                      { return RSQ; }
+"("                      { return LPAR; }
+")"                      { return RPAR; }
+"IV1DEAD()"              |
+"fPAUSE(uiV);"           |
+";"                      { return SEMI; }
+":"                      { return COLON; }
+"+"                      { return PLUS; }
+"-"                      { return MINUS; }
+"*"                      { return MUL; }
+"**"                     { return POW; }
+"/"                      { return DIV; }
+"%"                      { return MOD; }
+"&"                      { return AND; }
+"|"                      { return OR; }
+"^"                      { return XOR; }
+"~"                      { return NOT; }
+"="                      { return ASSIGN; }
+"+="                     { return INC; }
+"-="                     { return DEC; }
+"++"                     { return PLUSPLUS; }
+"&="                     { return ANDA; }
+"|="                     { return ORA; }
+"^="                     { return XORA; }
+"<"                      { return LT; }
+">"                      { return GT; }
+"<<"                     { return ASL; }
+">>"                     { return ASR; }
+">>>"                    { return LSR; }
+"=="                     { return EQ; }
+"!="                     { return NEQ; }
+"<="                     { return LTE; }
+">="                     { return GTE; }
+"&&"                     { return ANDL; }
+"||"                     { return ORL; }
+"!"                      { return NOTL; }
+","                      { return COMMA; }
+"else"                   { return ELSE; }
+"for"                    { return FOR; }
+"fREAD_IREG"             { return ICIRC; }
+"fPART1"                 { return PART1; }
+"if"                     { return IF; }
+"fFRAME_SCRAMBLE"        { return FSCR; }
+"fFRAME_UNSCRAMBLE"      { return FSCR; }
+"fFRAMECHECK"            { return FCHK; }
+"Constant_extended"      { return CONSTEXT; }
+"fCL1_"{DIGIT}           { return LOCNT; }
+"fBREV_8"                { return BREV_8; }
+"fBREV_4"                { return BREV_4; }
+"fbrev"                  { return BREV; }
+"fSXTN"                  { return SXT; }
+"fZXTN"                  { return ZXT; }
+"fDF_MAX"                |
+"fSF_MAX"                |
+"fMAX"                   { return MAX; }
+"fDF_MIN"                |
+"fSF_MIN"                |
+"fMIN"                   { return MIN; }
+"fABS"                   { return ABS; }
+"fRNDN"                  { return ROUND; }
+"fCRND"                  { return CROUND; }
+"fCRNDN"                 { return CROUND; }
+"fPM_CIRI"               { return CIRCADD; }
+"fPM_CIRR"               { return CIRCADD; }
+"fCOUNTONES_"{DIGIT}     { return COUNTONES; }
+"fSATN"                  { yylval->sat.set_overflow = false;
+                           yylval->sat.is_unsigned = false;
+                           return SAT; }
+"fVSATN"                 { yylval->sat.set_overflow = true;
+                           yylval->sat.is_unsigned = false;
+                           return SAT; }
+"fSATUN"                 { yylval->sat.set_overflow = false;
+                           yylval->sat.is_unsigned = true;
+                           return SAT; }
+"fVSATUN"                { yylval->sat.set_overflow = true;
+                           yylval->sat.is_unsigned = true;
+                           return SAT; }
+"fSE32_64"               { yylval->cast.bit_width = 64;
+                           yylval->cast.is_unsigned = false;
+                           return CAST; }
+"fCAST4_4u"              { yylval->cast.bit_width = 32;
+                           yylval->cast.is_unsigned = true;
+                           return CAST; }
+"fCAST4_8s"              { yylval->cast.bit_width = 64;
+                           yylval->cast.is_unsigned = false;
+                           return CAST; }
+"fCAST4_8u"              { return CAST4_8U; }
+"fCAST4u"                { yylval->cast.bit_width = 32;
+                           yylval->cast.is_unsigned = true;
+                           return CAST; }
+"fCAST4s"                { yylval->cast.bit_width = 32;
+                           yylval->cast.is_unsigned = false;
+                           return CAST; }
+"fCAST8_8u"              { yylval->cast.bit_width = 64;
+                           yylval->cast.is_unsigned = true;
+                           return CAST; }
+"fCAST8u"                { yylval->cast.bit_width = 64;
+                           yylval->cast.is_unsigned = true;
+                           return CAST; }
+"fCAST8s"                { yylval->cast.bit_width = 64;
+                           yylval->cast.is_unsigned = false;
+                           return CAST; }
+"fGETBIT"                { yylval->extract.bit_width = 1;
+                           yylval->extract.storage_bit_width = 1;
+                           yylval->extract.is_unsigned = true;
+                           return EXTRACT; }
+"fGETBYTE"               { yylval->extract.bit_width = 8;
+                           yylval->extract.storage_bit_width = 8;
+                           yylval->extract.is_unsigned = false;
+                           return EXTRACT; }
+"fGETUBYTE"              { yylval->extract.bit_width = 8;
+                           yylval->extract.storage_bit_width = 8;
+                           yylval->extract.is_unsigned = true;
+                           return EXTRACT; }
+"fGETHALF"               { yylval->extract.bit_width = 16;
+                           yylval->extract.storage_bit_width = 16;
+                           yylval->extract.is_unsigned = false;
+                           return EXTRACT; }
+"fGETUHALF"              { yylval->extract.bit_width = 16;
+                           yylval->extract.storage_bit_width = 16;
+                           yylval->extract.is_unsigned = true;
+                           return EXTRACT; }
+"fGETWORD"               { yylval->extract.bit_width = 32;
+                           yylval->extract.storage_bit_width = 64;
+                           yylval->extract.is_unsigned = false;
+                           return EXTRACT; }
+"fGETUWORD"              { yylval->extract.bit_width = 32;
+                           yylval->extract.storage_bit_width = 64;
+                           yylval->extract.is_unsigned = true;
+                           return EXTRACT; }
+"fEXTRACTU_BITS"         { return EXTBITS; }
+"fEXTRACTU_RANGE"        { return EXTRANGE; }
+"fSETBIT"                { yylval->cast.bit_width = 1;
+                           yylval->cast.is_unsigned = false;
+                           return DEPOSIT; }
+"fSETBYTE"               { yylval->cast.bit_width = 8;
+                           yylval->cast.is_unsigned = false;
+                           return DEPOSIT; }
+"fSETHALF"               { yylval->cast.bit_width = 16;
+                           yylval->cast.is_unsigned = false;
+                           return SETHALF; }
+"fSETWORD"               { yylval->cast.bit_width = 32;
+                           yylval->cast.is_unsigned = false;
+                           return DEPOSIT; }
+"fINSERT_BITS"           { return INSBITS; }
+"fSETBITS"               { return SETBITS; }
+"fMPY8UU"                { yylval->mpy.first_bit_width = 8;
+                           yylval->mpy.second_bit_width = 8;
+                           yylval->mpy.first_unsigned = true;
+                           yylval->mpy.second_unsigned = true;
+                           return MPY; }
+"fMPY8US"                { yylval->mpy.first_bit_width = 8;
+                           yylval->mpy.second_bit_width = 8;
+                           yylval->mpy.first_unsigned = true;
+                           yylval->mpy.second_unsigned = false;
+                           return MPY; }
+"fMPY8SU"                { yylval->mpy.first_bit_width = 8;
+                           yylval->mpy.second_bit_width = 8;
+                           yylval->mpy.first_unsigned = false;
+                           yylval->mpy.second_unsigned = true;
+                           return MPY; }
+"fMPY8SS"                { yylval->mpy.first_bit_width = 8;
+                           yylval->mpy.second_bit_width = 8;
+                           yylval->mpy.first_unsigned = false;
+                           yylval->mpy.second_unsigned = false;
+                           return MPY; }
+"fMPY16UU"               { yylval->mpy.first_bit_width = 16;
+                           yylval->mpy.second_bit_width = 16;
+                           yylval->mpy.first_unsigned = true;
+                           yylval->mpy.second_unsigned = true;
+                           return MPY; }
+"fMPY16US"               { yylval->mpy.first_bit_width = 16;
+                           yylval->mpy.second_bit_width = 16;
+                           yylval->mpy.first_unsigned = true;
+                           yylval->mpy.second_unsigned = false;
+                           return MPY; }
+"fMPY16SU"               { yylval->mpy.first_bit_width = 16;
+                           yylval->mpy.second_bit_width = 16;
+                           yylval->mpy.first_unsigned = false;
+                           yylval->mpy.second_unsigned = true;
+                           return MPY; }
+"fMPY16SS"               { yylval->mpy.first_bit_width = 16;
+                           yylval->mpy.second_bit_width = 16;
+                           yylval->mpy.first_unsigned = false;
+                           yylval->mpy.second_unsigned = false;
+                           return MPY; }
+"fMPY32UU"               { yylval->mpy.first_bit_width = 32;
+                           yylval->mpy.second_bit_width = 32;
+                           yylval->mpy.first_unsigned = true;
+                           yylval->mpy.second_unsigned = true;
+                           return MPY; }
+"fMPY32US"               { yylval->mpy.first_bit_width = 32;
+                           yylval->mpy.second_bit_width = 32;
+                           yylval->mpy.first_unsigned = true;
+                           yylval->mpy.second_unsigned = false;
+                           return MPY; }
+"fMPY32SU"               { yylval->mpy.first_bit_width = 32;
+                           yylval->mpy.second_bit_width = 32;
+                           yylval->mpy.first_unsigned = false;
+                           yylval->mpy.second_unsigned = true;
+                           return MPY; }
+"fSFMPY"                 |
+"fMPY32SS"               { yylval->mpy.first_bit_width = 32;
+                           yylval->mpy.second_bit_width = 32;
+                           yylval->mpy.first_unsigned = false;
+                           yylval->mpy.second_unsigned = false;
+                           return MPY; }
+"fMPY3216SS"             { yylval->mpy.first_bit_width = 32;
+                           yylval->mpy.second_bit_width = 16;
+                           yylval->mpy.first_unsigned = false;
+                           yylval->mpy.second_unsigned = false;
+                           return MPY; }
+"fMPY3216SU"             { yylval->mpy.first_bit_width = 32;
+                           yylval->mpy.second_bit_width = 16;
+                           yylval->mpy.first_unsigned = false;
+                           yylval->mpy.second_unsigned = true;
+                           return MPY; }
+"fNEWREG"                |
+"fNEWREG_ST"             |
+"fIMMEXT"                |
+"fMUST_IMMEXT"           |
+"fCAST2_2s"              |
+"fCAST2_2u"              |
+"fCAST4_4s"              |
+"fCAST8_8s"              |
+"fZE8_16"                |
+"fSE8_16"                |
+"fZE16_32"               |
+"fSE16_32"               |
+"fZE32_64"               |
+"fPASS"                  |
+"fECHO"                  { return IDENTITY; }
+"(size8"[us]"_t)"        { yylval->cast.bit_width = 8;
+                           yylval->cast.is_unsigned = ((yytext[6]) == 'u');
+                           return CAST; }
+"(size16"[us]"_t)"       { yylval->cast.bit_width = 16;
+                           yylval->cast.is_unsigned = ((yytext[7]) == 'u');
+                           return CAST; }
+"(int)"                  { yylval->cast.bit_width = 32;
+                           yylval->cast.is_unsigned = false;
+                           return CAST; }
+"?"                      { return QMARK; }
+"fREAD_PC()"             |
+"PC"                     { return PC; }
+"fREAD_NPC()"            |
+"NPC"                    { return NPC; }
+"fGET_LPCFG"             |
+"USR.LPCFG"              { return LPCFG; }
+"LOAD_CANCEL(EA)"        |
+"STORE_CANCEL(EA)"       |
+"CANCEL"                 { return CANC; }
+"N"{LOWER_ID}            { yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = GENERAL_PURPOSE;
+                           yylval->rvalue.reg.id = yytext[1];
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return REG; }
+"N"{LOWER_ID}"N"         { yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = DOTNEW;
+                           yylval->rvalue.reg.id = yytext[1];
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return REG; }
+[rR]{DIGIT}+             { yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = GENERAL_PURPOSE;
+                           yylval->rvalue.reg.id = atoi(yytext + 1);
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return REG; }
+"fREAD_SP()"             |
+"SP"                     { yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = CONTROL;
+                           yylval->rvalue.reg.id = SP;
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return REG; }
+"fREAD_FP()"             |
+"FP"                     { yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = CONTROL;
+                           yylval->rvalue.reg.id = FP;
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return REG; }
+"fREAD_LR()"             |
+"LR"                     { yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = CONTROL;
+                           yylval->rvalue.reg.id = LR;
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return REG; }
+"GP"                     { yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = CONTROL;
+                           yylval->rvalue.reg.id = GP;
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return REG; }
+"fREAD_LC"{ZERO_ONE}     { yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = CONTROL;
+                           yylval->rvalue.reg.id = LC0 + atoi(yytext + 8);
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return REG; }
+"LC"{ZERO_ONE}           { yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = CONTROL;
+                           yylval->rvalue.reg.id = LC0 + atoi(yytext + 2);
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return REG; }
+"fREAD_SA"{ZERO_ONE}     { yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = CONTROL;
+                           yylval->rvalue.reg.id = SA0 + atoi(yytext + 8);
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return REG; }
+"SA"{ZERO_ONE}           { yylval->rvalue.type = REGISTER;
+                           yylval->rvalue.reg.type = CONTROL;
+                           yylval->rvalue.reg.id = SA0 + atoi(yytext + 2);
+                           yylval->rvalue.reg.bit_width = 32;
+                           yylval->rvalue.bit_width = 32;
+                           return REG; }
+"MuN"                    { return MUN; }
+"fREAD_P0()"             { yylval->rvalue.type = PREDICATE;
+                           yylval->rvalue.pre.id = '0';
+                           yylval->rvalue.bit_width = 32;
+                           return PRE; }
+[pP]{DIGIT}              { yylval->rvalue.type = PREDICATE;
+                           yylval->rvalue.pre.id = yytext[1];
+                           yylval->rvalue.bit_width = 32;
+                           return PRE; }
+"fLSBNEW(P"{LOWER_PRE}"N)" { yylval->rvalue.type = PREDICATE;
+                           yylval->rvalue.pre.id = yytext[9];
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = true;
+                           return PRE; }
+"fLSBNEW0"               { yylval->rvalue.type = PREDICATE;
+                           yylval->rvalue.pre.id = '0';
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = true;
+                           return PRE; }
+"fLSBNEW1"               { yylval->rvalue.type = PREDICATE;
+                           yylval->rvalue.pre.id = '1';
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = true;
+                           return PRE; }
+"fLSBNEW1NOT"            { yylval->rvalue.type = PREDICATE;
+                           yylval->rvalue.pre.id = '1';
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_dotnew = true;
+                           return PRE; }
+"N"                      { yylval->rvalue.type = IMMEDIATE;
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.imm.type = VARIABLE;
+                           yylval->rvalue.imm.id = 'N';
+                           return IMM; }
+"i"                      { yylval->rvalue.type = IMMEDIATE;
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.imm.type = I;
+                           return IMM; }
+{SIGN_ID}                { yylval->is_unsigned = (yytext[0] == 'u');
+                           return SIGN;
+                         }
+"fSF_BIAS()"             { yylval->rvalue.type = IMMEDIATE;
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_unsigned = false;
+                           yylval->rvalue.imm.type = VALUE;
+                           yylval->rvalue.imm.value = 127;
+                           return IMM; }
+{DIGIT}+                 { yylval->rvalue.type = IMMEDIATE;
+                           yylval->rvalue.bit_width = 64;
+                           yylval->rvalue.is_unsigned = false;
+                           yylval->rvalue.imm.type = VALUE;
+                           yylval->rvalue.imm.value = atoi(yytext);
+                           return IMM; }
+{DIGIT}+"LL"             { yylval->rvalue.type = IMMEDIATE;
+                           yylval->rvalue.bit_width = 64;
+                           yylval->rvalue.is_unsigned = false;
+                           yylval->rvalue.imm.type = VALUE;
+                           yylval->rvalue.imm.value = atoi(yytext);
+                           return IMM; }
+"0x"{HEX_DIGIT}+         { yylval->rvalue.type = IMMEDIATE;
+                           yylval->rvalue.bit_width = 32;
+                           yylval->rvalue.is_unsigned = false;
+                           yylval->rvalue.imm.type = VALUE;
+                           yylval->rvalue.imm.value = strtol(yytext, NULL, 16);
+                           return IMM; }
+"0x"{HEX_DIGIT}+"LL"     { yylval->rvalue.type = IMMEDIATE;
+                           yylval->rvalue.bit_width = 64;
+                           yylval->rvalue.is_unsigned = false;
+                           yylval->rvalue.imm.type = VALUE;
+                           yylval->rvalue.imm.value = strtol(yytext, NULL, 16);
+                           return IMM; }
+"0x"{HEX_DIGIT}+"ULL"    { yylval->rvalue.type = IMMEDIATE;
+                           yylval->rvalue.bit_width = 64;
+                           yylval->rvalue.is_unsigned = true;
+                           yylval->rvalue.imm.type = VALUE;
+                           yylval->rvalue.imm.value = strtoul(yytext, NULL, 16);
+                           return IMM; }
+"fCONSTLL"               { return CONSTLL; }
+"fCONSTULL"              { return CONSTULL; }
+"fLOAD"                  { return LOAD; }
+"fSTORE"                 { return STORE; }
+"fROTL"                  { return ROTL; }
+"fSET_OVERFLOW"          { return SETOVF; }
+"fDEINTERLEAVE"          { return DEINTERLEAVE; }
+"fINTERLEAVE"            { return INTERLEAVE; }
+{VAR_ID}                 { /* Variable name, we adopt the C names convention */
+                           yylval->rvalue.type = VARID;
+                           yylval->rvalue.var.name = strndup(yytext,
+                                                             ALLOC_NAME_SIZE);
+                           /* Default types are int */
+                           yylval->rvalue.bit_width = 32;
+                           if (yylval->rvalue.var.name == NULL) {
+                               fprintf(stderr,
+                                       "Error: failed to duplicate var name: "
+                                       "\"%s\"\n",
+                                       yytext);
+                               error_count++;
+                               return -1; /* invalid token */
+                           }
+                           return VAR; }
+"fHINTJR(RsV)"           { /* Emit no token */ }
+.                        { fprintf(stderr,
+                                   "Error: unexpected token \"%s\"\n",
+                                   yytext);
+                           error_count++;
+                           return -1; /* invalid token */
+                         }
+
+%%
diff --git a/target/hexagon/idef-parser/idef-parser.h b/target/hexagon/idef-parser/idef-parser.h
new file mode 100644
index 0000000000..d08b9c80ea
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright(c) 2019-2020 rev.ng Srls. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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 Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IDEF_PARSER_H
+#define IDEF_PARSER_H
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#define TCGV_NAME_SIZE 7
+#define MAX_WRITTEN_REGS 32
+#define OFFSET_STR_LEN 32
+#define ALLOC_LIST_LEN 32
+#define ALLOC_NAME_SIZE 32
+#define INIT_LIST_LEN 32
+#define OUT_BUF_LEN (1024 * 1024)
+#define SIGNATURE_BUF_LEN (128 * 1024)
+#define HEADER_BUF_LEN (128 * 1024)
+
+/* Variadic macros to wrap the buffer printing functions */
+#define EMIT(c, ...)                                                 \
+    do {                                                             \
+        (c)->out_c += snprintf((c)->out_buffer + (c)->out_c,         \
+                               OUT_BUF_LEN - (c)->out_c,             \
+                               __VA_ARGS__);                         \
+    } while (0)
+
+#define EMIT_SIG(c, ...)                                                       \
+    do {                                                                       \
+        (c)->signature_c += snprintf((c)->signature_buffer + (c)->signature_c, \
+                                     SIGNATURE_BUF_LEN - (c)->signature_c,     \
+                                     __VA_ARGS__);                             \
+    } while (0)
+
+#define EMIT_HEAD(c, ...)                                                      \
+    do {                                                                       \
+        (c)->header_c += snprintf((c)->header_buffer + (c)->header_c,          \
+                                     SIGNATURE_BUF_LEN - (c)->header_c,        \
+                                     __VA_ARGS__);                             \
+    } while (0)
+
+/**
+ * Type of register, assigned to the HexReg.type field
+ */
+typedef enum {GENERAL_PURPOSE, CONTROL, MODIFIER, DOTNEW} RegType;
+
+/**
+ * Types of control registers, assigned to the HexReg.id field
+ */
+typedef enum {SP, FP, LR, GP, LC0, LC1, SA0, SA1} CregType;
+
+/**
+ * Identifier string of the control registers, indexed by the CregType enum
+ */
+extern const char *creg_str[];
+
+/**
+ * Semantic record of the REG tokens, identifying registers
+ */
+typedef struct HexReg {
+    CregType id;            /**< Identifier of the register                  */
+    RegType type;           /**< Type of the register                        */
+    unsigned bit_width;     /**< Bit width of the reg, 32 or 64 bits         */
+} HexReg;
+
+/**
+ * Data structure, identifying a TCGv temporary value
+ */
+typedef struct HexTmp {
+    int index;              /**< Index of the TCGv temporary value    */
+} HexTmp;
+
+/**
+ * Enum of the possible immediated, an immediate is a value which is known
+ * at tinycode generation time, e.g. an integer value, not a TCGv
+ */
+enum ImmUnionTag {I, VARIABLE, VALUE, QEMU_TMP, IMM_PC, IMM_CONSTEXT};
+
+/**
+ * Semantic record of the IMM token, identifying an immediate constant
+ */
+typedef struct HexImm {
+    union {
+        char id;            /**< Identifier of the immediate                 */
+        uint64_t value;     /**< Immediate value (for VALUE type immediates) */
+        uint64_t index;     /**< Index of the immediate (for int temp vars)  */
+    };
+    enum ImmUnionTag type;  /**< Type of the immediate                      */
+} HexImm;
+
+/**
+ * Semantic record of the PRE token, identifying a predicate
+ */
+typedef struct HexPre {
+    char id;                /**< Identifier of the predicate                 */
+} HexPre;
+
+/**
+ * Semantic record of the SAT token, identifying the saturate operator
+ */
+typedef struct HexSat {
+    bool set_overflow;      /**< Set-overflow feature for the sat operator   */
+    bool is_unsigned;       /**< Unsigned flag for the saturate operator     */
+} HexSat;
+
+/**
+ * Semantic record of the CAST token, identifying the cast operator
+ */
+typedef struct HexCast {
+    int bit_width;          /**< Bit width of the cast operator              */
+    bool is_unsigned;       /**< Unsigned flag for the cast operator         */
+} HexCast;
+
+/**
+ * Semantic record of the EXTRACT token, identifying the cast operator
+ */
+typedef struct HexExtract {
+    int bit_width;          /**< Bit width of the extract operator           */
+    int storage_bit_width;  /**< Actual bit width of the extract operator    */
+    bool is_unsigned;       /**< Unsigned flag for the extract operator      */
+} HexExtract;
+
+/**
+ * Semantic record of the MPY token, identifying the fMPY multiplication
+ * operator
+ */
+typedef struct HexMpy {
+    int first_bit_width;    /**< Bit width of the first operand of fMPY op   */
+    int second_bit_width;   /**< Bit width of the second operand of fMPY     */
+    bool first_unsigned;    /**< Unsigned flag for the first operand of fMPY */
+    bool second_unsigned;   /**< Unsigned flag for second operand of fMPY    */
+} HexMpy;
+
+/**
+ * Semantic record of the VARID token, identifying automatic variables
+ * of the input language
+ */
+typedef struct HexVar {
+    char *name;             /**< Name of the VARID automatic variable        */
+} HexVar;
+
+/**
+ * Data structure uniquely identifying an automatic VARID variable, used for
+ * keeping track of declared variable, so that any variable is declared only
+ * once, and its properties are propagated through all the subsequent instances
+ * of that variable
+ */
+typedef struct Var {
+    char *name;             /**< Name of the VARID automatic variable        */
+    uint8_t bit_width;      /**< Bit width of the VARID automatic variable   */
+    bool is_unsigned;       /**< Unsigned flag for the VARID automatic var   */
+} Var;
+
+/**
+ * Enum of the possible rvalue types, used in the HexValue.type field
+ */
+enum RvalueUnionTag {REGISTER, TEMP, IMMEDIATE, PREDICATE, VARID};
+
+/**
+ * Semantic record of the rvalue token, identifying any numeric value,
+ * immediate or register based. The rvalue tokens are combined together
+ * through the use of several operators, to encode expressions
+ */
+typedef struct HexValue {
+    union {
+        HexReg reg;      /**< rvalue of register type                     */
+        HexTmp tmp;      /**< rvalue of temporary type                    */
+        HexImm imm;      /**< rvalue of immediate type                    */
+        HexPre pre;      /**< rvalue of predicate type                    */
+        HexVar var;      /**< rvalue of automatic variable type           */
+    };
+    enum RvalueUnionTag type; /**< Type of the rvalue                        */
+    unsigned bit_width;     /**< Bit width of the rvalue                     */
+    bool is_unsigned;       /**< Unsigned flag for the rvalue                */
+    bool is_dotnew;         /**< rvalue of predicate type is dotnew?         */
+    bool is_manual;         /**< Opt out of automatic freeing of params      */
+} HexValue;
+
+/**
+ * Operator type, used for referencing the correct operator when calling the
+ * gen_bin_op() function, which in turn will generate the correct code to
+ * execute the operation between the two rvalues
+ */
+enum OpType {ADD_OP, SUB_OP, MUL_OP, DIV_OP, ASL_OP, ASR_OP, LSR_OP, ANDB_OP,
+             ORB_OP, XORB_OP, ANDL_OP, MINI_OP, MAXI_OP, MOD_OP};
+
+/**
+ * Data structure including instruction specific information, to be cleared
+ * out after the compilation of each instruction
+ */
+typedef struct Inst {
+    char *name;                   /**< Name of the compiled instruction      */
+    char *code_begin;             /**< Beginning of instruction input code   */
+    char *code_end;               /**< End of instruction input code         */
+    int tmp_count;                /**< Index of the last declared TCGv temp  */
+    int qemu_tmp_count;           /**< Index of the last declared int temp   */
+    int if_count;                 /**< Index of the last declared if label   */
+    int error_count;              /**< Number of generated errors            */
+    Var allocated[ALLOC_LIST_LEN]; /**< Allocated VARID automatic vars       */
+    int allocated_count;          /**< Elements contained in allocated[]     */
+    HexValue init_list[INIT_LIST_LEN]; /**< List of initialized registers    */
+    int init_count;               /**< Number of members of init_list        */
+} Inst;
+
+/**
+ * Data structure representing the whole translation context, which in a
+ * reentrant flex/bison parser just like ours is passed between the scanner
+ * and the parser, holding all the necessary information to perform the
+ * parsing, this data structure survives between the compilation of different
+ * instructions
+ *
+ */
+typedef struct Context {
+    void *scanner;                /**< Reentrant parser state pointer        */
+    char *input_buffer;           /**< Buffer containing the input code      */
+    char *out_buffer;             /**< Buffer containing the output code     */
+    int out_c;                    /**< Characters emitted into out_buffer    */
+    char *signature_buffer;       /**< Buffer containing the signatures code */
+    int signature_c;              /**< Characters emitted into sig..._buffer */
+    char *header_buffer;          /**< Buffer containing the output code     */
+    int header_c;                 /**< Characters emitted into header buffer */
+    FILE *defines_file;           /**< FILE * of the generated header        */
+    FILE *output_file;            /**< FILE * of the C output file           */
+    FILE *enabled_file;           /**< FILE * of the list of enabled inst    */
+    int total_insn;               /**< Number of instructions in input file  */
+    int implemented_insn;         /**< Instruction compiled without errors   */
+    Inst inst;                  /**< Parsing data of the current inst      */
+} Context;
+
+#endif /* IDEF_PARSER_H */
diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build
index e2e6b64766..1a008e7e86 100644
--- a/target/hexagon/meson.build
+++ b/target/hexagon/meson.build
@@ -208,4 +208,8 @@ idef_parser_input_generated_prep = custom_target(
     command: [idef_parser_dir / 'prepare', '@INPUT@', '-I' + idef_parser_dir],
 )
 
+flex = generator(find_program('flex'),
+                 output: '@PLAINNAME@.yy.c',
+                 arguments: ['-o', '@OUTPUT@', '@INPUT@'])
+
 target_arch += {'hexagon': hexagon_ss}
-- 
2.30.0



  parent reply	other threads:[~2021-02-11 21:56 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-11 21:50 [RFC PATCH 00/10] target/hexagon: introduce idef-parser Alessandro Di Federico via
2021-02-11 21:50 ` [RFC PATCH 01/10] target/hexagon: update MAINTAINERS for idef-parser Alessandro Di Federico via
2021-02-11 21:50 ` [RFC PATCH 02/10] target/hexagon: import README " Alessandro Di Federico via
2021-02-11 21:50 ` [RFC PATCH 03/10] target/hexagon: make helper functions non-static Alessandro Di Federico via
2021-02-11 23:04   ` Philippe Mathieu-Daudé
2021-02-11 23:23     ` Philippe Mathieu-Daudé
2021-02-11 21:50 ` [RFC PATCH 04/10] target/hexagon: introduce new helper functions Alessandro Di Federico via
2021-02-11 23:22   ` Philippe Mathieu-Daudé
2021-02-11 21:50 ` [RFC PATCH 05/10] target/hexagon: expose next PC in DisasContext Alessandro Di Federico via
2021-02-11 21:50 ` [RFC PATCH 06/10] target/hexagon: prepare input for the idef-parser Alessandro Di Federico via
2021-02-11 21:50 ` Alessandro Di Federico via [this message]
2021-02-11 21:50 ` [RFC PATCH 08/10] target/hexagon: import parser for idef-parser Alessandro Di Federico via
2021-02-14 16:56   ` Richard Henderson
2021-02-25 15:24     ` Alessandro Di Federico via
2021-02-11 21:50 ` [RFC PATCH 09/10] target/hexagon: call idef-parser functions Alessandro Di Federico via
2021-02-11 21:50 ` [RFC PATCH 10/10] target/hexagon: import additional tests Alessandro Di Federico via
2021-02-15  1:34   ` Richard Henderson
2021-02-14 21:52 ` [RFC PATCH 00/10] target/hexagon: introduce idef-parser Richard Henderson
2021-02-25 15:24   ` Alessandro Di Federico via

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210211215051.2102435-8-ale.qemu@rev.ng \
    --to=qemu-devel@nongnu.org \
    --cc=ale.qemu@rev.ng \
    --cc=ale@rev.ng \
    --cc=babush@rev.ng \
    --cc=bcain@quicinc.com \
    --cc=nizzo@rev.ng \
    --cc=tsimpson@quicinc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.