aboutsummaryrefslogtreecommitdiff
path: root/target/hexagon/idef-parser/idef-parser.lex
diff options
context:
space:
mode:
authorPaolo Montesel <babush@rev.ng>2022-09-23 19:38:28 +0200
committerTaylor Simpson <tsimpson@quicinc.com>2022-12-16 11:36:57 -0800
commitfd8171fe52b5e56b2052e51b3f9e82acab58d87f (patch)
tree7dafde1beeabb8dca8b876a1475c6a292f34271e /target/hexagon/idef-parser/idef-parser.lex
parent7c19dcc5646aef8ef31d453adf81becdcfb43c19 (diff)
downloadqemu-fd8171fe52b5e56b2052e51b3f9e82acab58d87f.zip
qemu-fd8171fe52b5e56b2052e51b3f9e82acab58d87f.tar.gz
qemu-fd8171fe52b5e56b2052e51b3f9e82acab58d87f.tar.bz2
target/hexagon: import lexer for idef-parser
Signed-off-by: Alessandro Di Federico <ale@rev.ng> Signed-off-by: Paolo Montesel <babush@rev.ng> Signed-off-by: Anton Johansson <anjo@rev.ng> Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Reviewed-by: Taylor Simpson <tsimpson@quicinc.com> Message-Id: <20220923173831.227551-9-anjo@rev.ng>
Diffstat (limited to 'target/hexagon/idef-parser/idef-parser.lex')
-rw-r--r--target/hexagon/idef-parser/idef-parser.lex471
1 files changed, 471 insertions, 0 deletions
diff --git a/target/hexagon/idef-parser/idef-parser.lex b/target/hexagon/idef-parser/idef-parser.lex
new file mode 100644
index 0000000..ff87a02
--- /dev/null
+++ b/target/hexagon/idef-parser/idef-parser.lex
@@ -0,0 +1,471 @@
+%option noyywrap noinput nounput
+%option 8bit reentrant bison-bridge
+%option warn nodefault
+%option bison-locations
+
+%{
+/*
+ * Copyright(c) 2019-2022 rev.ng Labs Srl. All Rights Reserved.
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <stdbool.h>
+
+#include "hex_regs.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
+PRED_ID d|s|t|u|v|e|x|x
+IMM_ID r|s|S|u|U
+VAR_ID [a-zA-Z_][a-zA-Z0-9_]*
+SIGN_ID s|u
+STRING_LIT \"(\\.|[^"\\])*\"
+
+/* Tokens */
+%%
+
+[ \t\f\v]+ { /* Ignore whitespaces. */ }
+[\n\r]+ { /* Ignore newlines. */ }
+^#.*$ { /* Ignore linemarkers. */ }
+
+{INST_NAME} { yylval->string = g_string_new(yytext);
+ return INAME; }
+"fFLOAT" |
+"fUNFLOAT" |
+"fDOUBLE" |
+"fUNDOUBLE" |
+"0.0" |
+"0x1.0p52" |
+"0x1.0p-52" { return FAIL; }
+"in" { return IN; }
+"R"{REG_ID_32}"V" {
+ yylval->rvalue.type = REGISTER_ARG;
+ 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;
+ yylval->rvalue.signedness = SIGNED;
+ return REG; }
+"R"{REG_ID_64}"V" {
+ yylval->rvalue.type = REGISTER_ARG;
+ 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;
+ yylval->rvalue.signedness = SIGNED;
+ return REG; }
+"MuV" {
+ yylval->rvalue.type = REGISTER_ARG;
+ yylval->rvalue.reg.type = MODIFIER;
+ yylval->rvalue.reg.id = 'u';
+ yylval->rvalue.reg.bit_width = 32;
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.signedness = SIGNED;
+ return REG; }
+"C"{REG_ID_32}"V" {
+ yylval->rvalue.type = REGISTER_ARG;
+ 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;
+ yylval->rvalue.signedness = SIGNED;
+ return REG; }
+"C"{REG_ID_64}"V" {
+ yylval->rvalue.type = REGISTER_ARG;
+ 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;
+ yylval->rvalue.signedness = SIGNED;
+ return REG; }
+{IMM_ID}"iV" {
+ yylval->rvalue.type = IMMEDIATE;
+ yylval->rvalue.signedness = SIGNED;
+ yylval->rvalue.imm.type = VARIABLE;
+ yylval->rvalue.imm.id = yytext[0];
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.is_dotnew = false;
+ return IMM; }
+"P"{PRED_ID}"V" {
+ yylval->rvalue.type = PREDICATE;
+ yylval->rvalue.pred.id = yytext[1];
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.is_dotnew = false;
+ yylval->rvalue.signedness = SIGNED;
+ return PRED; }
+"P"{PRED_ID}"N" {
+ yylval->rvalue.type = PREDICATE;
+ yylval->rvalue.pred.id = yytext[1];
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.is_dotnew = true;
+ yylval->rvalue.signedness = SIGNED;
+ return PRED; }
+"IV1DEAD()" |
+"fPAUSE(uiV);" { return ';'; }
+"+=" { return INC; }
+"-=" { return DEC; }
+"++" { return PLUSPLUS; }
+"&=" { return ANDA; }
+"|=" { return ORA; }
+"^=" { return XORA; }
+"<<" { return ASL; }
+">>" { return ASR; }
+">>>" { return LSR; }
+"==" { return EQ; }
+"!=" { return NEQ; }
+"<=" { return LTE; }
+">=" { return GTE; }
+"&&" { return ANDL; }
+"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" { 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.signedness = SIGNED;
+ return SAT; }
+"fSATUN" { yylval->sat.signedness = UNSIGNED;
+ return SAT; }
+"fCONSTLL" { yylval->cast.bit_width = 64;
+ yylval->cast.signedness = SIGNED;
+ return CAST; }
+"fSE32_64" { yylval->cast.bit_width = 64;
+ yylval->cast.signedness = SIGNED;
+ return CAST; }
+"fCAST4_4u" { yylval->cast.bit_width = 32;
+ yylval->cast.signedness = UNSIGNED;
+ return CAST; }
+"fCAST4_8s" { yylval->cast.bit_width = 64;
+ yylval->cast.signedness = SIGNED;
+ return CAST; }
+"fCAST4_8u" { return CAST4_8U; }
+"fCAST4u" { yylval->cast.bit_width = 32;
+ yylval->cast.signedness = UNSIGNED;
+ return CAST; }
+"fNEWREG" |
+"fCAST4_4s" |
+"fCAST4s" { yylval->cast.bit_width = 32;
+ yylval->cast.signedness = SIGNED;
+ return CAST; }
+"fCAST8_8u" { yylval->cast.bit_width = 64;
+ yylval->cast.signedness = UNSIGNED;
+ return CAST; }
+"fCAST8u" { yylval->cast.bit_width = 64;
+ yylval->cast.signedness = UNSIGNED;
+ return CAST; }
+"fCAST8_8s" |
+"fCAST8s" { yylval->cast.bit_width = 64;
+ yylval->cast.signedness = SIGNED;
+ return CAST; }
+"fGETBIT" { yylval->extract.bit_width = 1;
+ yylval->extract.storage_bit_width = 1;
+ yylval->extract.signedness = UNSIGNED;
+ return EXTRACT; }
+"fGETBYTE" { yylval->extract.bit_width = 8;
+ yylval->extract.storage_bit_width = 8;
+ yylval->extract.signedness = SIGNED;
+ return EXTRACT; }
+"fGETUBYTE" { yylval->extract.bit_width = 8;
+ yylval->extract.storage_bit_width = 8;
+ yylval->extract.signedness = UNSIGNED;
+ return EXTRACT; }
+"fGETHALF" { yylval->extract.bit_width = 16;
+ yylval->extract.storage_bit_width = 16;
+ yylval->extract.signedness = SIGNED;
+ return EXTRACT; }
+"fGETUHALF" { yylval->extract.bit_width = 16;
+ yylval->extract.storage_bit_width = 16;
+ yylval->extract.signedness = UNSIGNED;
+ return EXTRACT; }
+"fGETWORD" { yylval->extract.bit_width = 32;
+ yylval->extract.storage_bit_width = 64;
+ yylval->extract.signedness = SIGNED;
+ return EXTRACT; }
+"fGETUWORD" { yylval->extract.bit_width = 32;
+ yylval->extract.storage_bit_width = 64;
+ yylval->extract.signedness = UNSIGNED;
+ return EXTRACT; }
+"fEXTRACTU_RANGE" { return EXTRANGE; }
+"fSETBIT" { yylval->cast.bit_width = 1;
+ yylval->cast.signedness = SIGNED;
+ return DEPOSIT; }
+"fSETBYTE" { yylval->cast.bit_width = 8;
+ yylval->cast.signedness = SIGNED;
+ return DEPOSIT; }
+"fSETHALF" { yylval->cast.bit_width = 16;
+ yylval->cast.signedness = SIGNED;
+ return SETHALF; }
+"fSETWORD" { yylval->cast.bit_width = 32;
+ yylval->cast.signedness = SIGNED;
+ return DEPOSIT; }
+"fINSERT_BITS" { return INSBITS; }
+"fSETBITS" { return SETBITS; }
+"fMPY16UU" { yylval->mpy.first_bit_width = 16;
+ yylval->mpy.second_bit_width = 16;
+ yylval->mpy.first_signedness = UNSIGNED;
+ yylval->mpy.second_signedness = UNSIGNED;
+ return MPY; }
+"fMPY16SU" { yylval->mpy.first_bit_width = 16;
+ yylval->mpy.second_bit_width = 16;
+ yylval->mpy.first_signedness = SIGNED;
+ yylval->mpy.second_signedness = UNSIGNED;
+ return MPY; }
+"fMPY16SS" { yylval->mpy.first_bit_width = 16;
+ yylval->mpy.second_bit_width = 16;
+ yylval->mpy.first_signedness = SIGNED;
+ yylval->mpy.second_signedness = SIGNED;
+ return MPY; }
+"fMPY32UU" { yylval->mpy.first_bit_width = 32;
+ yylval->mpy.second_bit_width = 32;
+ yylval->mpy.first_signedness = UNSIGNED;
+ yylval->mpy.second_signedness = UNSIGNED;
+ return MPY; }
+"fMPY32SU" { yylval->mpy.first_bit_width = 32;
+ yylval->mpy.second_bit_width = 32;
+ yylval->mpy.first_signedness = SIGNED;
+ yylval->mpy.second_signedness = UNSIGNED;
+ return MPY; }
+"fSFMPY" |
+"fMPY32SS" { yylval->mpy.first_bit_width = 32;
+ yylval->mpy.second_bit_width = 32;
+ yylval->mpy.first_signedness = SIGNED;
+ yylval->mpy.second_signedness = SIGNED;
+ return MPY; }
+"fMPY3216SS" { yylval->mpy.first_bit_width = 32;
+ yylval->mpy.second_bit_width = 16;
+ yylval->mpy.first_signedness = SIGNED;
+ yylval->mpy.second_signedness = SIGNED;
+ return MPY; }
+"fMPY3216SU" { yylval->mpy.first_bit_width = 32;
+ yylval->mpy.second_bit_width = 16;
+ yylval->mpy.first_signedness = SIGNED;
+ yylval->mpy.second_signedness = UNSIGNED;
+ return MPY; }
+"fNEWREG_ST" |
+"fIMMEXT" |
+"fMUST_IMMEXT" |
+"fPASS" |
+"fECHO" { return IDENTITY; }
+"(size8u_t)" { yylval->cast.bit_width = 64;
+ yylval->cast.signedness = UNSIGNED;
+ return CAST; }
+"(unsigned int)" { yylval->cast.bit_width = 32;
+ yylval->cast.signedness = UNSIGNED;
+ return CAST; }
+"fREAD_PC()" |
+"PC" { return PC; }
+"fREAD_NPC()" |
+"NPC" { return NPC; }
+"fGET_LPCFG" |
+"USR.LPCFG" { return LPCFG; }
+"LOAD_CANCEL(EA)" { return LOAD_CANCEL; }
+"STORE_CANCEL(EA)" |
+"CANCEL" { return CANCEL; }
+"N"{LOWER_ID}"N" { yylval->rvalue.type = REGISTER_ARG;
+ yylval->rvalue.reg.type = DOTNEW;
+ yylval->rvalue.reg.id = yytext[1];
+ yylval->rvalue.reg.bit_width = 32;
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.signedness = UNSIGNED;
+ return REG; }
+"fREAD_SP()" |
+"SP" { yylval->rvalue.type = REGISTER;
+ yylval->rvalue.reg.type = GENERAL_PURPOSE;
+ yylval->rvalue.reg.id = HEX_REG_SP;
+ yylval->rvalue.reg.bit_width = 32;
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.signedness = UNSIGNED;
+ return REG; }
+"fREAD_FP()" |
+"FP" { yylval->rvalue.type = REGISTER;
+ yylval->rvalue.reg.type = GENERAL_PURPOSE;
+ yylval->rvalue.reg.id = HEX_REG_FP;
+ yylval->rvalue.reg.bit_width = 32;
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.signedness = UNSIGNED;
+ return REG; }
+"fREAD_LR()" |
+"LR" { yylval->rvalue.type = REGISTER;
+ yylval->rvalue.reg.type = GENERAL_PURPOSE;
+ yylval->rvalue.reg.id = HEX_REG_LR;
+ yylval->rvalue.reg.bit_width = 32;
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.signedness = UNSIGNED;
+ return REG; }
+"fREAD_GP()" |
+"GP" { yylval->rvalue.type = REGISTER;
+ yylval->rvalue.reg.type = CONTROL;
+ yylval->rvalue.reg.id = HEX_REG_GP;
+ yylval->rvalue.reg.bit_width = 32;
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.signedness = UNSIGNED;
+ return REG; }
+"fREAD_LC"[01] { yylval->rvalue.type = REGISTER;
+ yylval->rvalue.reg.type = CONTROL;
+ yylval->rvalue.reg.id = HEX_REG_LC0
+ + (yytext[8] - '0') * 2;
+ yylval->rvalue.reg.bit_width = 32;
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.signedness = UNSIGNED;
+ return REG; }
+"LC"[01] { yylval->rvalue.type = REGISTER;
+ yylval->rvalue.reg.type = CONTROL;
+ yylval->rvalue.reg.id = HEX_REG_LC0
+ + (yytext[2] - '0') * 2;
+ yylval->rvalue.reg.bit_width = 32;
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.signedness = UNSIGNED;
+ return REG; }
+"fREAD_SA"[01] { yylval->rvalue.type = REGISTER;
+ yylval->rvalue.reg.type = CONTROL;
+ yylval->rvalue.reg.id = HEX_REG_SA0
+ + (yytext[8] - '0') * 2;
+ yylval->rvalue.reg.bit_width = 32;
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.signedness = UNSIGNED;
+ return REG; }
+"SA"[01] { yylval->rvalue.type = REGISTER;
+ yylval->rvalue.reg.type = CONTROL;
+ yylval->rvalue.reg.id = HEX_REG_SA0
+ + (yytext[2] - '0') * 2;
+ yylval->rvalue.reg.bit_width = 32;
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.signedness = UNSIGNED;
+ return REG; }
+"fREAD_P0()" { yylval->rvalue.type = PREDICATE;
+ yylval->rvalue.pred.id = '0';
+ yylval->rvalue.bit_width = 32;
+ return PRED; }
+[pP]{DIGIT} { yylval->rvalue.type = PREDICATE;
+ yylval->rvalue.pred.id = yytext[1];
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.is_dotnew = false;
+ return PRED; }
+[pP]{DIGIT}[nN] { yylval->rvalue.type = PREDICATE;
+ yylval->rvalue.pred.id = yytext[1];
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.is_dotnew = true;
+ return PRED; }
+"fLSBNEW" { return LSBNEW; }
+"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.signedness = SIGNED;
+ yylval->rvalue.imm.type = I;
+ return IMM; }
+{SIGN_ID} { if (yytext[0] == 'u') {
+ yylval->signedness = UNSIGNED;
+ } else {
+ yylval->signedness = SIGNED;
+ }
+ return SIGN;
+ }
+"0x"{HEX_DIGIT}+ |
+{DIGIT}+ { yylval->rvalue.type = IMMEDIATE;
+ yylval->rvalue.bit_width = 32;
+ yylval->rvalue.signedness = SIGNED;
+ yylval->rvalue.imm.type = VALUE;
+ yylval->rvalue.imm.value = strtoull(yytext, NULL, 0);
+ return IMM; }
+"0x"{HEX_DIGIT}+"ULL" |
+{DIGIT}+"ULL" { yylval->rvalue.type = IMMEDIATE;
+ yylval->rvalue.bit_width = 64;
+ yylval->rvalue.signedness = UNSIGNED;
+ yylval->rvalue.imm.type = VALUE;
+ yylval->rvalue.imm.value = strtoull(yytext, NULL, 0);
+ return IMM; }
+"fLOAD" { return LOAD; }
+"fSTORE" { return STORE; }
+"fROTL" { return ROTL; }
+"fCARRY_FROM_ADD" { return CARRY_FROM_ADD; }
+"fADDSAT64" { return ADDSAT64; }
+"size"[1248][us]"_t" { /* Handles "size_t" variants of int types */
+ const unsigned int bits_per_byte = 8;
+ const unsigned int bytes = yytext[4] - '0';
+ yylval->rvalue.bit_width = bits_per_byte * bytes;
+ if (yytext[5] == 'u') {
+ yylval->rvalue.signedness = UNSIGNED;
+ } else {
+ yylval->rvalue.signedness = SIGNED;
+ }
+ return TYPE_SIZE_T; }
+"unsigned" { return TYPE_UNSIGNED; }
+"long" { return TYPE_LONG; }
+"int" { return TYPE_INT; }
+"const" { /* Emit no token */ }
+{VAR_ID} { /* Variable name, we adopt the C names convention */
+ yylval->rvalue.type = VARID;
+ yylval->rvalue.var.name = g_string_new(yytext);
+ /* Default to an unknown signedness and 0 width. */
+ yylval->rvalue.bit_width = 0;
+ yylval->rvalue.signedness = UNKNOWN_SIGNEDNESS;
+ return VAR; }
+"fatal("{STRING_LIT}")" { /* Emit no token */ }
+"fHINTJR(RsV)" { /* Emit no token */ }
+. { return yytext[0]; }
+
+%%