diff --git a/.gitignore b/.gitignore
index 2e18d89..c41c81b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -104,9 +104,7 @@ celerybeat.pid
# Environments
.env
.venv
-env/
venv/
-ENV/
env.bak/
venv.bak/
diff --git a/doc/friscv.drawio b/doc/friscv.drawio
index 8d77274..71baa77 100644
--- a/doc/friscv.drawio
+++ b/doc/friscv.drawio
@@ -1 +1 @@
-7Vxbd6I6FP41rnXOg12Em/ioVju9zPTizHScl7MQotIisTHe5tefIKECiZRWENqOs9aUBIiwv72/fWFjTelM12fYnE2+Ihu6NVmy1zXltCbLTVWn//sTm2BCl7VgYowdO5gCu4m+8weySYnNLhwbzmMHEoRc4szikxbyPGiR2JyJMVrFDxshN/6tM3MMuYm+Zbr87L1jk0kwa8iN3fwX6Iwn4TcDvRnsmZrhwexO5hPTRqvIlNKtKR2MEAm2pusOdH3ZhXIJzuvt2ft8YRh6JMsJd/LwAj/ddjeXV8vVVP9Sd3rf63KwytJ0F+yGl9IJXUc3p7Oa0vaGc/8PuwGyCaWC0cKzob+wRHevJg6B/Zlp+XtXVA3o3IRMXToCdHNOMHp8lh697/bIcd0OchHerqaMNP/f85GRPfr245+BPBKZDz50fgkxcShaLdcZe3QfQf6Xm2yEA2C2ZzPVAuFqfXY3Ci9HJlp/bbiOTDG5nkE0hQRv6CFsr6wxjJmSyxIbr3Yqo4V6MImoixaeaDI1HT+vvUOSbjAwxcC2rurtVf/yZuqA1d1le75xBqu6xgHLgQhtqulsiDCZoDHyTLe7m23HYd4dc4V8MW/BfYCEbJhszQVBSehNTFq+GdIJyzXnc8cKp3uOGx5GJY83v/yvOdHC4YB963Zwuo6NNuFo7ZDIaXQ0CFek27uT/EF4zl6452iBLSYa9Gc9Uc96lt5yZG1cXw6a64u6yujHxGNIUkQPmOx9+aZqD4auSZxlnGlEmsBOvUEOveZnrdPCL2Ja1wAJZQruiJ0VZYYXFtKTCwW3zC20Vczn+8mkq/WlstkoP52f2v3qstsBA4y7daUM1XyL7rxVTzOaQZSm1KyqKlZBXlWFkgd5a2pWzqKe8HGx7j7eP/TIoH7tGr8v6qGB7dED6A7Rar8KzB8hsSZs8LCYzsLzPOTBPFVESlWRhKOS6GfrwDjXJm0/eaMsPk4tC+a0y464phuMLEiNwhsfFmkk4oohsO2RJI5Asppa9iBAU+STOI+qgjAAiMIAo6goQKleFMDMMcp9Uq7cJ2e1irKMQhhcVBCpYzgqAVhC8VTLUWl/HVUxJlktR8Unxx0qNIz8E394DsnVWfV6Xb3TOZazkpvxjLV8V6WXkgQcMfHMyK2ZrCyNI6NWJqz55M6l4qxSkePRkKZp8SWypqfJhQpMT8WsxAesZejqXsUoGkhdSnBFI1udITf5q5z8z/stOnEHx86cQDzPlYhtExojqywiVgRErOgCIlaLImLAlw5PTWLSmeGCSlr6p3XT/peTOL1dIir7hoJlwU1U1mwqLNZaVIgQC2q6U8e2tyYkwjGOdLSw+6pANTtgqhEHzBAA1igIrzQ6j1qHR2W/sIiDvAhqv87VuksF+ImxUxKFztKx45mtgzCkM53+3QciNcpqfHTZLEjQabHRXiPpmNYE5irxoWkZtlKWxHX1iPG8MEdOL+p/6hw569OlapXs066ajxXeu0GpWiLpOKZBwea0/dBqg99f5PNvV9c319f/WQIK6xOTvOfYV5NedhNFeYk024qImMa6fqKBFn54k6ekR6ORbB1N0klt1nRe0nJDK0bUPVAf4x9fPb3nXT2BM6zfT+7LeeablGzB7Ql7gYuSvFA6ct4kL87snzsGwg4COVtmT0VmbiKHzfwD5pxOvC73F0YR6VXB9xFFRNQHNEBUgcCJJKkvlRr90Q3EDhWln2IVGZiISVGgtEKsSotMUi87QuY/Wnffa7Lu+snuEMfUSn9aoLBTrD7fou9XmIA6W+920q0xqQna4SqUQEfYLZ5QH+5EdPnlyodakLtOY8kIwmc359d8RPRJ4MlQmCqqkCjkA/kDcHdBRJvGn9XNANOuOmGENZ8rdkwb8GZ/MazPN3MCp7mG0hDYGmwcK5ROsqAwMQQFJYaj1WRozK6f1t8G4Ndpu2eqt5cCBJbgPfVwJ7uzX9HTHe/h5kAUQL0X16aeSEbDdCjq3QwBrkryuWZuwPL+LZVRP1sPd4IAXyRdsfE0edYVHygfyLLiFAwoarJtkHu+nfVBuWAtrbhn5UIpvZtW7oM63XLRPC2r4jWPpXha8sF+wcrymfu9j6tCx4oQ066ygv3eBwUMQDa4hm9wxIcEQlnr1QsZXtXwnYtZZHXpWplW0ageUqW4wczxl1EmWsZfV5UDzPkHMSBR9FKSL9QWHMI0OSuuUov4Yf4NJCod5Xu38AL+NonnmAAbWQlYKciEE8+m1bf2iXMrHTv5FTxyqlSjcr50oAjoQBYVyPJ4wJBSkknrVP4YPa+H4aZIjWSBqckjJ2p71QsDjn/b8SP3LB9qd1nwA5Kge6c4ANNLNwXX+cLtQcy5ZnCoGVPRncOPufud90/t98nHKzeyemW9IK/ciLM9SAZ1+b30I76v9HdsK6Rhb9WWEkI9PaNSHZqsHcYtfA2r9LchDmNwKfkCnSByEvnf4vIovvh08b119nmdrJH4AS9V0Ilc1ItBqVlZBCGnAi31+WYQWtae+uLiGL5+Y797MfPPJcoXtFxO5aZ6v/GVozuX5WPFiIdBD94L9FlyhcPeBcgHdyUj7oGC5J8bSEqcXjg3WHBuECp+rHxAwwy8mPmXyTcespq8m/M7PK9uPDysQa2ZpHVRBc4o6CWeVE2MAnF3+3nDSC7SF/0QbE5xJB3ufjs4sKzdDzAr3f8B7V3rd5u4Ev9rcvbuB+fwfnx0nKTNnvZuN2lvt/ulB4Nsk2JweTTJ/vVXEg+DJDC2EeDE6TlNEFgWmpnfjEYzowt5tn5+F1qb1cfAAd6FJDjPF/L1hSSJim7CX6jlJW1RZDFtWIaukz20bXhw/wVZo5C1Jq4DosqDcRB4sbupNtqB7wM7rrRZYRg8VR9bBF71WzfWElAND7bl0a1fXSdepa2GpG/b3wN3ucq/WdSyF15b+cPZm0QrywmeSk3yzYU8C4MgTv9aP8+AhyYvn5fPT+ufjyv7s/XvNPLB90/P7r/vJmlnt/t8pHiFEPhxx11Lad+/LC/JJix72fgln8EwSHwHoF6EC/nqaeXG4GFj2ejuE+QZ2LaK1x68EuGfURwGP4qZhnN01XLw2Uv+AmEMnkuky17mHQjWIA5f4CPZ3YIuGWOKenb9tCVz8cyqRGJFzhqtjLWWRd/b6YN/ZDO4x2zquycTOJA7s8sgjFfBMvAt72bbelWd7u0zH4Jgk03yI4jjl0zUrCQOSBJYYTxFogMb/MAHeduti14Hdwue3fhv9PelKmaX3/ClaSrZ9fVz6dnrl/zChxOVfTK//Fa+t/0YvnopdfIJhC6caBBmbftxBnyDJWh6Tk6fQzNcEf0oSEI7a1qK2nTy5fvS+WMD/krAx7vJ9YeJobIZLQSeFbu/qr2xmCb76KfAhS9SMKgsozkqs6ikEpyXDi37HMF8xUAO50fjZPhxP1YoU7SJFXayjMZkmSM44Sj4ME+GXFsUqGDAFhJqUGAgMotq13RmS7ymVFWSLBLyno6Um7zLFAPd+VAhJ3bsBj68cQ1saN+Fx2n4BWSDWeAFIf6s7Ag2ABJT8y8CP87YTFR4WgI6BbQGbQuILFtA68AUWAfi6noVXv98Ur9svt+Fi+dNQYp+Rbek1UtKPb/TrUKvwITtWVHk2gRSiN1LvEZLPHP6xaGAnTkafVhmkA7gBnE/YCdFfdzcMS61r1Go/QB+JsC3O0bqueg4C2FkSK0IPSJ1bH/R/phEj++1H+/Ff97fqbeKVTDX6SD1nrLZsZDVGFNtre3Oja6CgwoHVTuji7beyI6Udqs1CHPWS+mxDXogqh+wqqrMAW+ZOO3xUNNw83j/Rbj/+jX+9vj9dhEpU+XqWyGq5bWF5sUIDTaWX+F/7WeCXFoYFCYR5uApfECUNs/wF2YoYW7ZP5ZYCiZ2ijDokXA5/4+kGOgpCQ5TkBRz+7cq/L7tG/61RL9DYDkv+Ujgi6WDSe8x5fKDNQdeVZYsz136SM1A/ka+hSuER65tedPsxtp1nFRsAXwda477Qy+SUQp2rl5dqNe1QEgBXOGuzDq7KBxNZTGrh5tagJwIl4JpaBX+yGl3pJxMJKXSLdFBsFhE4NhVCVPbKkMCbNW7pTYCbD9A2TkA6vKwq878PUvY8ikMbABtPn9J0R4KUtxopixU9G8vuWbZQVUOIuUaX2eDErPr0hjSH6aplLaUnhXwD0ejSSX0kqTpuRFVNppEhtFkqJxsVpE2Wt2tqyFqQfXqPGZ+pjIrZE1dcgEvCsmk30ejjVpTo8kj8dqIEAdecbY3att4G49bnfCGX1k3LhVz+0NYd7LRzoo8ut/uUP5h5QS35rvpl/f/fLajXzeqZMkTiWFAjtM5TbLLMVtW6cf09vzcsQ3B8GgwqTOYv4u9oUYzy6fZEOb8UeZ7vRjUKgLhUqya7lJHprtJdCtxMN6bGKt2S2HqOJAMY1X4zWYfL2sAAncVqzVFYlhsBsNgIzeIDxHJzTv5a3g/sZ2/4v+py83P9eOfVhYbwlr/J952wZ22eC7ZUl6Wz+AchgH6wsR3EZO6UZSACHO55eBfP+E1umP56PrJwo8tIJGR4K03HkiZp2bVnzbPQ7IFPkiPrHmsVV69n37cjgCPOF4BxriRu2ITwOXL3HvBJIMUk4T/RJD93AXkRD/+HV5DiQa+Xe+8aDXoOx8OBy+ThKr9LEC2hP87eMfOwbehLoTNuNGBo4hx8zpwEsjOeMyLxMMDhl3OXd+Kg9C1vPQWFBUbvYQTgMj/LU77C+FnbcB8lX0nmmKKebJYgHA7x9MPX36Lqm+Jr9BwrQg9Ydk2BhIBv6djxehV12AdYNmKPKjy0fif/KLPTbHKvDyOCtToS9OEmGUN/JSd8exa9iqlmG1trLnrubGLmKnhm2BjWco6h0oPLOJugZLbWpYI2lJMeqWkslayImnudrY5R2u42cM9RaRjNl4Kj0adl2GXd6LHoDpRrmoumeVrMFmaqwNXQ9NmXdkCeUDO5nuwdKMYY0zvtCI8R9Wdz75oNVFqNj52UErsIv6RaffTRsYWWb9gZNWsNZp/fx5tWFC4H+VKM8/21eX4GKYvTwHkPIjjYE0QVa6hQ1sS1tNLktFWfJlkJsNRpGgMmslduIqYNBtm+7PYyrwUBK2yKL+UBHnXwhxdkcGkZW7QaPktvLTtwtscOnYBNlKRC9Qe6CHBrGyyGGxeOnIlqarE0kTUTAK4u4tJZb4Y7RpAS0jYIlCMeDAabHGYzQFU+ENVB9ze3mizWZP74Egk0GWKCozgdZXT+pBJFjp0MCMLjQ+vliyiPD66KHV0od2vr5cu5vjoQu95ZnRR3w5d5BHiGGO1cIEsirdDFGIFJxqMZUGvJKGzou7eFn5BORkZSViJQdWl2d3bUv2KPDYS0clAd2/LSFbMsZFEpP0bluO4FEnGt/fFWBAr16ZZClviQT+jSj+TEeqtMOjHz9VBu3rncNrP5GMj4ujIR7sOgvAsfbWb0GMjH+1isPxTRc/bWw3+cKSfpI6OfrWuCDrA+9UaJXB1NbolLyP+OiPMG1r2SuoICaNR8z9Y5oOe7qrUxi32vH1SXw7k4C2VnWU+ettSMci98O5Cc9kvxvawjAmWZzPe0k+QYPC1Iu1imf59p0w8OOcXSEeTUW44OK0remnH0Uu/mWo3Ao0Ct/gn/65qHCWH/XJRUyhMZ9CVmS7MccOc9sw8ojC7UzRj+S9DxLGZsRLtxEFgOaZtG85gKZoSpbGGhkuJds2c7Nqe+9pQNKsJwiMQKmmH+HSWTVYYrodYsQXcdWTFUlKuaRnp63KOiuCnxloN/GxgiVEyq8Fb07mxLJFbYSZZZIGzrSzRXqg03tyNbCt0ThNxCrYr22W5t7R7Yzt3xBY0ZARx6yoNPySpu4OfXUudA+BngAXxvmj3iuGHU64u5EHS9DEPLRcj5sYQJQZ9RVLusll7VLos84diT0NA/8bMnnpL9tT5aEdRPZg9O2Mq2md5ZqqemErhw1TC8ExFOyhv3RCniGLjK8EJgIvA84InnFrHSAElEkeyJ/IH/ph+KCXbzTnm2r06c86sWnOSoLaz5rpIyGNzizEeCDovJpsIZbZENpGPNadAdSkrigHZ09AkQSdAru+VJat8NwFTV/+9YcOU4KLM54XlRVku9zYD2V5Z/hLhY5r0vMCJ0CcBax4q7nFVVAosZ1nin6GRTxEoRyhrKSvmcWO9oF+umms2jTOydQeIZTjcUR+vrgCp1K4CKT8gkqWWQCQfa7cfR1rayT29h9czKOE+OnZnR3Zsz/UvGXXxCq9HO/lsU2WnQQhqBVe4FIjoxGwMx27lV/rMUxU7LbLTyL9EvSRhBqU87rgK9M4E97oEdg77GIJJJkSLgtRyg5ebM1FmpEKed+733blvlere8869PGgl2n2WHseV+uaoaI22ilYaVNHSEZFWGhGJ+sUfPuvaqlQ06FpF07hUtSOObOlN2Q4alXmQvb1n4codjEXEJ4wALZRh0YL2Ti68JFqdMYKQmXp9D9eAskDWqOwEJKrI0x9I0OGbHR3KstOEWywWkm1zNLslQ6DMbrHtMSz8zG6zEZa79nvsfy4AP5xU2rovlGNPUDmuFEmzZ6rfdIa2mnM/+7nOHcldU7aNixhWUyq0A+v++uzAqpWVRoUpKnonGpJcLvNTijlOlbdx727/PE4fEtqv2M6vc2D0554yFFpNMlLKdIaW7OKwMjYJBj1Xch+lORSUHq0ja/YaDe1SJ7ihKMfR0w6jQmfg4vCJTem0HaEA4fR/hM6McrY9I7E8IBLXbPkU7g1VkLm4N0SRvSDqAafpwMATA4l6D/hYYyEUxkkdDSvLzvFJVmh8Ekk1xBufGMXXyuXeyY2TTo6jHsF6WhDoqWccQG0WpbR7WVArh5wBZSfhLzzz4lBOz7Zqg4KIK/yvD1HnJMEaLcECv0OeGl5t72NCppApXqLSiRpu3bEWaFc7Ah7U5NnD6/TlJMEL8OPwm/HuTKvDMxbwA/PQ8vMDGXwAnOIEiTk+IgKEiyBco6My8AkZqV83G2V6RsVFfk4JEWh1d/0aznQoDCtG/CL6xxEXFc0kGdpkwGJxckA/9XQZdfWQC4P2bY0npq5+GcWhNDV5dhEz5b7X5NKcF84kqytbbYyNYrSf8EwxwmIcnZTRzr0zzco0yxdT46EYHah2plil9og5NorRDrwzxapFK8eHi3Qs2ZlmTWV+jaGLkagMN9SZYiWKyebYKMYoYHemWAUXx0Yx2lF0plhT3bPhKXZ2fDRSjCq4PDjFNJo0I97Gq1a/66YmzhBZEJ379TWFXuy3PHOPUWt2d1+ctwg02rfzKQyWoYU8+XZNwloP4Qa1uHBw5IC2M4ZLVNVqJb58D+lIljGIImnVz/MLHNCkU0ScsZ/2yQFRxENLTjMQZXdfnOtYabQf6zPawKseFe/UBAucJrRIjdACub8oOtBpgrOhsTrtAVjOjq9GglMVXYc3PmsPlZhSNHu1h0ooecbwaI6U0Gp8WyJFlLcpSArD2B7ag6yxj2d4Q3IkyuOrOK7VeLDOkpTTTKdoNrhSon1YmVKiI7BerTAp5tiUUv79Z1Gqo9jYNqJ1RoDO25Ii+ujywTWSLp3FqJFkVHDA4ApJp10XXnKix5ZwPwuIYVEMfnCJTjsmTvdQUu4UpCVweALSfoo/kyhGRMQpASGq2hHhbIMo2WyCMM4a3RDAsUyZtaZrWppSID7jnIHbh4/w/zi07B9R9cvnaBp3pBQQmQ2PyXqDXwLXg83PJ9mVYSH4yHe6DkL0VBKBReJdopGFkFcmACc6FHkPdL4EWG9iF2VLZDkR5c4Qc+NbiR+7XjES8LwBdoxvYHXlpm9uAxdlEh2WybHfG7uL4qFyNggeiA9QaqyFOK19MgfJAHh4lclCtEmHmQ9uk8Tlqd2O3kqZuHb01dnEU5hlouDs3bTZhtQLAzj/IZY13CUjXyVlMzeOgIeGHPj29n465HRWsozhLX227+pS75rOafltK6PBOTVR/UzUJtd0DrE1KTMx2oc6hXwZgy6HKTESZhSWVUrloneHsIfUS+OUR3hg9fZx5hHqOpsdjs87pysVkIsWzkECOu3y7DaPsJVWedidaFhRAU19zSy/guoRnKNc9RSKmix/szshsTyiHBlT/bm23PQbEYxChrs8ZyMeV5PWVCmxkBUaXZlrfpEfutKHXYwDXfM7J4uuJh90ZdRZEMSe0bX+pIkmdL2LogRjKzLfXD+BhimaEFQZF9qCeGos56JYtbQExnsQgdT6f1oBn20n3+Ym5BnBjvGfSFTdRoNxVk+/+dS5fXo+rGfkh/UY2YO7D+vhA5yyrA59DJlB73q0P0gMGqBu7FoxRlCrgLaT8BOO/SAeySSC3VhnkBk6DWvcTuExhi0SfqAlprUGuMMKi3PHqLZHJRoqJ4yidgVJxck5Ftag3dmdl9ici46zqNmFJXZwuQm8ZhITLTE2EtjHg3ATeUaYVjkCefRIrxBwLXKjnq6RYiIyqCdoNPUO2AeCl2EQxGU5gzOx+hg4KOb75v8=7R1bc5u4+tdkpvtAhrvhMb5ts6fZtE273e7LGYIVmwYbL8aN04fz248EEgZJBmxLQNK6M42RQcB313fThTFa7n6PvfXiJpqB8EJXZ7sLY3yh69pgYMA/aOSZjLhmNjKPgxke2w/cBT8AHlTx6DaYgU3pxCSKwiRYlwf9aLUCflIa8+I4eiqf9hCF5buuvTlgBu58L2RHvwSzZJGNOvpgP/4WBPMFubNmu9kvS4+cjN9ks/Bm0VNhyJhcGKM4ipLs23I3AiGCHoFLPB+P53/95zZ+DxZKbN6+fXKBkk02PeaS/BVisEpOnnr0+/r+j9vx7frefjuxl/7Odq8UE7/bdy/cYoBNQeIvQHyh295yfWEMV/cb9AfDIHkmgI2j7WoG0OQq/PlpESTgbu356NcnSEtwbJEsQ3ikwa+bJI4ecwRA0A29MJiv4Pc4g/3wO4iTAKLtCo8nEZriIVold/ieBjnOaEwz86eqhQyGILoH2BXoAkPqdxAtQRI/w1Pwry5BOiZ728DHT3saMh08tijQj2njQQ/T7Tyfe48b+AWjh4+qjx9HwX+/etsvS200vNWB4n+7VlhMBSMPYgqOfYKw0tV34DtiXvFoG0VhFKdXG2r6ORehGIEGg2BJ2NSMMjYNnYNNnYNNXQQ2ue9gMNgkyHwXrKC8FMxtNN88BGFYQOt0OrFcVyI/6Q6FAYvFgMbDgDQEWAwCGJiDGdQk+DCKk0U0j1ZeONmPDstY2Z/zLkLEnuLiG0iSZwx6b5tENKa8OLlCag4O+KG32QQ+GZ4GITkNYiN+/hvfJj34ig4udYscj3fFX8fP5GgXJOl1lwMLH34lc8Lv+6vQQX7RakYeaRWtQDaCn0Y9mkg20Tb2QcV5mBXgK89B1XzY7kBYqSS5GIReEnwv6/9z6Ofx2/XjByX8/KDdfLjdxe5d8GWs6AcZOIQMDP98iSGPsuLYDpFwvEf6dY6+vYmBN0vtn+U6BEkQreAB5Eto6oTbzeI3LlW+8+6hqC9REhG/PkQK1N6s/F0Gs1lGtGAT/PDu0/kQOtdRsEpS8FjDC2vcHMGEhWgpkBtz+CYle4knHRRIyY5hlCQEnqkxMvHk79HL7Gd23NKkikbNED08bCDR0cSQP+Lp8sXuQpwQdtcKvK5eWpXcXhJBmN+L8ketkD914kewpDAbSgpHtKTgE5dFGYmWRimr7EHxVeJJzGRE0A1YRumbsXJmBC2AOApDZNm3aluMrybOdCTRtjDVMhpyu7wz28LtD+/r1cy/Z+yCLZFbCBWc3dhwadWUGDQUEEavTAl2LUDYdxsS9iUjYUBG3gZQqExvgs2G/AYP9z+zF1yvIO9u/czEqLgCDhbve5z5EYIH3uJPvPHhijI+1EvbMBwh1oaiURrBlWBtcElI5eKpE4kzaCpxyqbEoGVboqmo6NeqgyjHvaj4mC0fYvDvFmySfqwWqkhUyGpB1e2BEI7VS+yqWW2tDgYMHnO3a8uOn9HEnUo0zjS7b8aZw4D+6u9rE4mCCP5HLGgKC/BtkyrXKDZuitDFQ805jYfbMvZlIclmLGiLQRLP2W3JwpFm9EefnabO6rRZk1W3YI2n6Q1V3qArlVf52BTDKmHqXlMf4mgJ/+DlLfz2eRWwavB186+i1QtZt00Zq7He9avZDJoScK2CZA2cVbUQYtEXTdXN7Nvl5eV5+q/1sAYVWFK0AQt53eSAXpcGersC9BoBvZGD3no1oOeElFoGPWvV7UGvE9CbOejtVwN6TnS8ZdBzrLoc9Jam5TAnhG8Zrwb6ndM9mfhwLIx1T7xuhUwnHHD1As+ilocj1nNA4Uj76XHEYaR2ccRauhSO9J8eRxxN0y6ODifuYBz9qfz0nMRhJN7yQwSSuK5GNjB6noqfeZtFeq7WqlWltajYuXBskCP1AuDodg1GdkX2EsHY5so2/OfLX4v5zZ2+u//jQ3wTxu+H7zlitUWfIHH8icqo8bfx9xyHTJqtnX7OcgFyQYhRIzsxxjDLtGPIS4ypes0jA+pkZLP2VmRsHMTAT5Slt15DbEFMhJAplyB92XUUBv5zIWpevJBNwGkYpX/vxR56fxx001UfmxczsIZ8d+Yk2EbJeFhX3wTFnAB1jeJP6Tm/nZEhcL6xU5dEUG/qFNPKSRiswF/mGP2TKD3pnCSdo8sNnvR0ZEnPUyIqJSElNtf5gFhsTRLq7UhCc2CW6MCiXe6SJSG7omwiCW+8lTdHRQgqDo3i7AI0kkZJ0Wok9tDdlzhe2kgsfYq91eYhipd4ZhLDSefMbtVMvMWRn7n2Yir7QQ0eCtJumSZHqckCIOn2lCVkl2Rh09wpOssCToKmfEBBe3SjLSpoC4+ddQ/n6eTP0eQS/qDeI6oDsbcJVnNEJymO6Ufm5pT/EtUniWqLKk2xOcVBeaSsKKrzZa9wWW11Lqv3dSPNy0Z6Jd+Fp23x5btGEQ9T/ndAvkMwec+F03BW1cH7KJRFbepWcbr65yqfD79kTyBU2fDcLvXKBotWSsSpqUHq51H9bRrVLyiiZimvrDYY7bUG0V2Q01NrOD/2C7nyDdVDso1X+5mLxTyNJnjrraC8RO+dVv0gyt0Bf4vt8jdYPfyyys/NkxhQZjnPN8SV9aosWc86h+4Am79yXkRyNJocL2KPACtd3akM2PyxVl1FbCD+kzcXCtSZBZyZKRWoZj1QuZmT0qDKxtgLJQVnlixT4B3Bz1RmXiqTqt89eF0GvOXIknCB3ueYkqJTHhRFMzkI0tpEECkerXLkbxbeGn2F5nj4PIw9/xGlWtZR/x6m1V0XGMmOPun1iZfaCsbYlZtoaFFYyaVUUYPykDKQhhU2IvvihL1Fg5UX587H2iF21pq/hgDcnQnYssWXfXiELTmJyqYtljYTC/jwZoOtt/vykxejVwd27wBblRCLVnpZNCf1Qd5vgxCt35IFx1H4U+lfm7Y+NV7hTrsSibXqm/gXMBcZV8iLsEmjeCmuNyBE/cYIssuRsAD95+WmF3IahNFcf0PFz9AL0Zemv1Wv1Is1uUikMs8G8bkBh+gwf5hSZLDpHZFuTO8Xg6UXrDIv883dMCXuKE6fIX179t7ZrYvPOQcrEHupV32RliNjj/tD6M2rfTSvx1mxgZMgKGZnSbMQGmS1cAOKrjR25C8HL3jZvoKajrWtzOg8Bh7QrTZFIFlwsDDnZR2+UKib9Mq8c6i/ghVGD91JusmAsPdFnpenN0kRXuTJByq2dtvva8APRLllqmPyH7IXYuJjbEDLrplIdiLF4BexdkesnVUkVz52sXsDjtp9BP+i2Kr/KMGk7fNyka5AtgxWu8iqQObjiPWmv7i4WpNM9lbDauR5XrIhpA/qgTqQBFRuC26NXS61oVlO1BL8xKBcCXE10ulagw8wndUa3BNbynbXNCpUpalmMyvnBOPkH+f78/DO+Dz59OHmevlVN4bhA69FRjmZvUBc9r9b1LB+6Gc8l3qC5vdv4AOrmX+n8O23/enEVePlrtPM93U9PpgAzyFqyZ2oKBcNWr8eyC2r5EQRPeWweX0qaRHh5JSvENKQiv/u3VbXHCFNii0rjUFJdl2qZq38QkfvQRxAgCFykyGg1IbySe/KquU+jVGth0B4Hz0dRv7mMU2F7ogSilRQ33vp23a5Jq9FupKit4OHiygOfkAp4oXiyaKp2tKFr3ZOSjnVNMsqqbUBNosOLtFpe5XEAg9eoFE+Kad8h7OzVLngtVhlyVNq7WuvhlrKEKalFPUS4qzcdp1Q87mtsQfcWeXrMatajx0jxThi4izBpp+m40rmuVoj2hgv/mhk22qHOk7riSwzyrLMscVKGq5ZrveUFI/xJh4yqRlCG+q2fUJYqL+EdpYxxXGURMoUV4uxtcHT6+ktQyzndn6lvVXjydCQ6FjRVMpF73A8K7zMHxERav7mZpX816MljWCWkSNzOfYe5fR16II4cTEZ7ns6XeL3pJBMvjpt2iSWE5M/s1quimLaX7Geps0NyuHmGjXVcPQFjia2HI4LLDYC8T+wXCdsc+n+e8ZIqo+Q3u2uKXbJkU9DSR+JzjIGs2gbjky/p8lxr0Kf08VynevzTrfU6lCfN3UcWb0ygTkFBFSnvKxYtreOFhLlF+JnMW0pfhYyDSnzlrGBRRVNUkn1cCrkO8v7Yew4G1qQCqkEyjzwI0J3Ga4LDvl8vOClrw8i7wDZe7qR9BylH6mrIaqkx1FZ6anzytdEdJXgM+QpbSVe1KYKguWu1VDuai3tN6iZdKsSuqhO8oKLLVEaVZbIiLZ4JBeFaapb9hJanOJGaZvVcF2IbiXLduBCPDFtpPn6owqVRU7kgqu7jA96K5wDGR/HLnVdl76RWh1TYy8wWvB0cyqj+xJDq2IrMTsXG2K2IlOMcqs4hU4ikrieZa250maReZ+zQ7vM9SO5tVyx1ZZht49iF7WEKklLVBogBfwRjBU7Ef3ESKM71OTlA21Uv/AXUHqlam/Vm1Hd163/wWjNZe2DTjNCVYrcnIaG+rnmgVOXccM8mOA4OJ/U2XXDeosu69wPXkGQlUwrxnAwNUrji/EJlV1CeTqZfDPCqA64dpl7010stqloInlYHcfWaIlCOtNIFRBGtWPhgu3z24eVRSUPCPIaW/Z5IoH0OWzNL0zovVR3BZG28iXsbVz2D03soevILEx3qYRYm7MlBq90SETrK36CS3UGRF8EbmPzcnCUT0mwpNY5O8L3OaVRp5yVmqrXGH8GHZJw6hK6HdqZVHsLOqO77hY1zyTJXcU2dPhVL3V8VogpLC0EyguVbG6X261CjGGFXsBLDImy/amm07FkpSc/kGnQVR2cQCavCllaHNOozgN5cVrvKJ8KKVQiXC9eD5KFyAtLNzFY7qPWEHj/D3rzjP4uJUQmoJiWJkW+lifVqOsl+hr6avoek+fQFeeabe2OQRuQBp0bKDlhwWANvRveJg9SVfT4auJM5eYaUUsBk6OiudENeStTNvmP3UKJ2USKQsPPHKDKm+DVtVsVYWbxF0mvQMC2Wb1WlZDSfmDqLNSz1WtZQjuncu0juI+iM/sq1Xv2LMktJ13KC+FytmvkpbrTWT/CMKCzKOgZOzaPpJ3FQFpjr5zbKxaqaFaNIJfaHwR4e59RKqFcl3Uj1bqn0KTKJkUWclFp2nrHzqJcZKUpm3QKL9luDjqjKnavzZ5f5HM1gYwPP8is4b0TWegVe1BXPm6d760P/adDtAgdev7jPB2nby2E/c5Ie7KdZh3+6Cw2cSKyWiLK75umH9lek7Pz4Qko6yg8wcmBZTJNaVdr496u9FRuw2Xi4ZiJ6A5rnBbQ5W0FO3feu/BzgJwq2UeE894e0LGoCxG+Jaq2yShff4pvCR7GyFwtnA5F7+ImmiFMTf4P7Vtbd9o4EP41PNIj+e5Hmlt3kzZpaXdLX3q0trDVGosjRID99StjGV+kUrLFdlsnL0FjeSTP981FgxmZF4vtDUPL+DUNcTIyQLgdmZcjwzBMwxb/Mskul/i+mwsiRsJcBEvBlPyLpRBI6ZqEeFWbyClNOFnWhQFNUxzwmgwxRjf1aXOa1FddoggrgmmAElX6Nwl5nEs9wy3lrzCJ4mJl6Pj5lQUqJssnWcUopJuKyLwamReMUp5/WmwvcJIZr7DLB/b5TZiOAXx3Q9bO9P3tn7dsnCu7fsoth0dgOOXnVS2tsOK7wl44FOaTQ8p4TCOaouSqlL5kdJ2GONMKxKicc0fpUgihEH7BnO8kF9CaUyGK+SKRV/GW8I+Vz7NM1Qtbji63UvN+sJODFUeMTzI+CEFKU1zIrkmSyDlzmnK5KLQyBSlnu4+FtmxQWSkblkvtR8VaJ5pbwrKiaxbgI/McyXrEInxUn1SYIVDhrkTzBtMFFrsUExhOECePdYIj6SfRYd7h1gdKxIMYQPq07UlCS482fbuuIt+pvKtklPhQ2UYp2vPsCZzz++RcybNZlWYtcK6k2azYw0/IOdAN5yxY5xz0Qaeck/Z4RMlaPoJCwjrFNjHheLpEeytvRGqs06kJ+4oz+vWQYIwnA/qIGcfbowgUGdmtW9IovHlTZjcDSFlcyWyGBb6NWs3eTzWuqRj3j5TjCDMhvBdp/qyWRgmJUjEIhF3FCmKCcMYLmlC2V26GCHvzoFNITNAIqIYKCbQ0kDhtIWIpiLzGC7rf8x1FodA55ZThwSFj9Y6M10fy+4WLJ2icmMmcbhKZ4usnFk+KokM4PiiyXjRU5cZRVAkg0a4ybZlNWLWRNYukXY3s04kQvMMRWQknV2O7cEzeCBP1KDCfz40g0IWLzK2JOLhN5IUFCcM9/3VxqO4TTfLux3JT8BBxKrsA+79uY1GzBIKaWGRoYpHXViwqDhwVeC8RR0JSZIvvgls3rAwtVcSlqDuwW0LPtpvuqkEP6squ1tAzNGWXwGMdcEJTceHl+hT3HAyC7gkA6tzvHACOP20j9BcYT/+JLz/AGTTB7PMYKOg8915+oHzQ2lhTPWjned1UD7ZfJ6EPW2u9aB8T9km536/1coxyrReiTp1KLmyto3LsMX+DjgpsWtI1ikq8khssXU/lcBo4e3I43lM5r6l/xoN7o0ftep6ards6uGsBUVsq1w/DxMLTdBy7xcJWsJhwuiDBMPHw3b7xcPooK37hqtQ/sSrtqpSA/68qVXtadlNRrz2tY5X+c8/j+4HGcZtw6gqj1roex1znuelxGoRj6yQIO+176LrKg6ptG00A1++7ttU0ggdT3DbA8HRtwW7BUE/Wg6pumy2y3k8bcOBncavxlacHeo9Xwz2MN8HwQe/uMezTuAJI/wlEfdltGsQ4XCdZxOoSDgxDG7udwtH8mk8XrHwNGoZptwWHeuJ8IEuckLTj9696QAM2W4caNNy20HgLANhM3t/N7mf3AXhz93Z66xRfuj6/0dLC23WO2d4bLWJY/tIi7wWVv1cxr/4D7VjbctowFPwaHtPxHfwIBlJmmpkMJDQ8ClvYSoRFhQgmX98jLOMbSUnLJZkUZkBndSxLu2dlRMP05sk1R4vohgWYNgwtSBpmt2EYruXApwQ2KeAYdgqEnAQppOfAiLxgBWoKXZEAL0uJgjEqyKIM+iyOsS9KGOKcrctpM0bLd12gENeAkY9oHf1JAhGlaMto5vh3TMIou7PuuGnPHGXJaiXLCAVsXYDMXsP0OGMibc0TD1PJXcbLJOS9x8ndo2tMxngQTO+9dXKVDtZ/zyW7JXAci+MO3UqHfkZ0pfhSaxWbjEAcAJ8qZFxELGQxor0c7XC2igMsb6NBlOf8YGwBoA7gIxZio4oDrQQDKBJzqnqXAnHRlmID4FO0XBI/g/uEZmkH0qDoWrIV9/EbeWqpcJMQvzWeqhTJQ6GkFMnXmM2x4BtI4JgiQZ7LdYdU+Ya7vFwiaCiV3qGYUVOsPxyMvHFD1qRDYSGdKS8p6PxayRLtzFgsrpZbDdqQoFuLZEtq1g+tUH4Px6ZBIMFjHNeqoaz1OiICjxZoy/Ma9o+qrpw97WxnyDmAmh6jjG9HM/v9nu26am6qPHTr3VI/Yy5w8qY4qtfMzKx2M0tT8TrfG/QsJyruC452IkGtD2FB4JlvHtT122Aig2+w26u4mxR7uxsVHdmU5oGmND6UKc2ahoMYin/lC8Ji6Bi2b/7NSRXfzGz5Vr4p4Olrv/PO5DDdqjhMP9BhJzOYcxE/JUQ8FNqpm2wV5V6SQWal1zzYPLMH7U/pQbvmwS4S6Iubz720+dzPYr4Df4O+5tEzW7R5oEWzzfd4HlWX3jICC9kVntOqFF6rUlDpTNVVlZraTePvy6xZM/99e3gHyPh2UKvAP9i9XH4V8wcIt2b+RU1uaxWu7UubPKuyAv133i0AI+Y/YVETABYq9p0UMp5jFuMK9QpClISxNChwigHvSNoInPbbqmNOgmC7iewTuaKs1EtNyjiVWDVjNOtiuXu0Mk6mVf0AOYiJIMDsC1BjaFM5+/YInpn9MeaEsvBL61eRz6zLZ51Vvn1HjaJ8awLzMrQXzNl/3Xa62XtOIUfSDcL8P8D0eZb/kWr2fgM=
\ No newline at end of file
+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
\ No newline at end of file
diff --git a/doc/traps.md b/doc/traps.md
new file mode 100644
index 0000000..ff44a21
--- /dev/null
+++ b/doc/traps.md
@@ -0,0 +1,219 @@
+# Volume 1 (Exception Occurences)
+
+Exceptions, Traps, and Interrupts (specs v1.6) :
+
+- We use the term exception to refer to an unusual condition occurring at run
+ time associated with an instruction in the current RISC-V hart.
+
+- We use the term interrupt to refer to an external asynchronous event that may
+ cause a RISC-V hart to experience an unexpected transfer of control.
+
+- We use the term trap to refer to the transfer of control to a trap handler
+ caused by either an exception or an interrupt.
+
+ The general behavior of most RISC-V EEIs is that a trap to some handler
+ occurs when an exception is signaled on an instruction
+
+
+Misc. :
+
+An instruction-address-misaligned exception is generated on a taken branch or
+unconditional jump if the target address is not four-byte aligned. This
+exception is reported on the branch or jump instruction, not on the target
+instruction
+
+Ordinarily, if an instruction attempts to access memory at an inaccessible
+address, an exception is raised for the instruction.
+
+No integer computational instructions cause arithmetic exceptions.
+
+The JAL and JALR instructions will generate an instruction-address-misaligned
+exception if the target address is not aligned to a four-byte boundary.
+
+Loads with a destination of x0 must still raise any exceptions and cause any
+other side effects even though the load value is discarded.
+
+Loads and stores where the effective address is not naturally aligned to the
+referenced datatype (i.e., on a four-byte boundary for 32-bit accesses, and a
+two-byte boundary for 16-bit accesses) have behavior dependent on the EEI. An
+EEI may not guarantee misaligned loads and stores are handled invisibly. In
+this case, loads and stores that are not naturally aligned may either complete
+execution successfully or raise an exception. The exception raised can be
+either an address-misaligned exception or an access-fault exception
+
+
+No special mentions to take in account for interrupts in this volume
+
+
+# Volume 2 (Exception Occruences, to be continued... )
+
+## Misc.
+
+CSR Chapter:
+
+Attempts to access a non-existent CSR raise an illegal instruction exception.
+Attempts to access a CSR without appropriate privilege level or to write a
+read-only register also raise illegal instruction exceptions.
+
+Machine-mode standard read-write CSRs 0x7A0–0x7BF are reserved for use by the
+debug system. Implementations should raise illegal instruction exceptions on
+machine-mode access to the latter set of registers.
+
+Implementations are permitted but not required to raise an illegal instruction
+exception if an instruction attempts to write a non-supported value to a WLRL
+field.
+
+MSTATUS Chapter:
+
+The mstatus register keeps track of and controls the hart’s current operating state.
+
+Virtual memory, N/A
+
+Extension Context Status in mstatus Register
+
+When an extension’s status is set to off, any instruction that attempts to read
+or write the corresponding state will cause an illegal instruction exception
+
+MTVEC:
+
+The mtvec register is an MXLEN-bit read/write register that holds trap vector configuration,
+consisting of a vector base address (BASE) and a vector mode (MODE).
+
+Vectored mode: Asynchronous interrupts set pc to BASE+4×cause, else BASE
+
+MEDELEG / MIDELEG
+
+To indicate that certain exceptions and interrupts should be processed directly by a lower privilege level
+
+
+MIP / MIE
+
+
+Synchronous exceptions are of lower priority than all interrupts.
+
+MEPC
+
+When a trap is taken into M-mode, mepc is written with the virtual address of
+the instruction that was interrupted or that encountered the exception
+
+MCAUSE
+
+Machine exception code
+
+MTVAL
+
+When a trap is taken into M-mode, mtval is either set to zero or written with
+exception-specific information to assist software in handling the trap.
+Otherwise, mtval is never written by the implementation, though it may be
+explicitly written by software. The hardware platform will specify which excep-
+tions must set mtval informatively and which may unconditionally set it to
+zero.
+
+mtval is written with the faulting virtual address when:
+
+- a hardware breakpoint is triggered
+- an instruction-fetch, load, or store address-misaligned, access
+- a page-fault exception occurs
+
+ mtval may be written with the first XLEN or ILEN bits of the faulting instruction on:
+- an illegal instruction trap
+
+else setup to 0
+
+ECALL:
+
+The ECALL instruction is used to make a request to the supporting execution environment.
+It generates an environment-call-from-x-mode exception
+
+MRET
+
+To return after handling a trap, there are separate trap return instructions
+per privilege level: MRET, SRET, and URET. MRET is always provided. SRET must
+be provided if supervisor mode is supported, and should raise an illegal
+instruction exception otherwise. SRET should also raise an illegal instruction
+exception when TSR=1 in mstatus
+
+WFI
+
+The Wait for Interrupt instruction (WFI) provides a hint to the implementation
+that the current hart can be stalled until an interrupt might need servicing
+
+This instruction may raise an illegal instruction exception when TW=1 in mstatus
+
+
+If an enabled interrupt is present or later becomes present while the hart is
+stalled, the interrupt exception will be taken on the following instruction,
+i.e., execution resumes in the trap handler and mepc = pc + 4.
+
+
+Mentions in Virtual Memory, Atomic operations and Supervisor mode
+
+
+# Trap Management:
+
+xCAUSE: store the trap cause
+xEPC: address of the instruction triggering the trap
+xTVAL: written with exception specific datum
+xPP in STATUS: active privilege mode at the moment of the trap
+xPIE: written with the current xIE value
+xIE: cleared
+
+# Clint from other IPS:
+
+https://riscv.org/wp-content/uploads/2018/05/riscv-privileged-BCN.v7-2.pdf
+
+Armleo:
+
+https://github.com/armleo/ArmleoCPU/blob/main-development/src/armleosoc_axi_clint.sv
+
+out: software interrupt s-mode (ssip)
+out: software interrupt m-mode (msip)
+out: timer interrupt
+in: timer increment
+
+Pulp-Platform:
+
+https://github.com/pulp-platform/clint/blob/master/src/clint.sv
+
+out: software interrupt m-mode (msip)
+out: timer interrupt
+in: timer increment
+
+Hazard 3:
+
+https://github.com/Wren6991/Hazard3/blob/master/hdl/peri/hazard3_riscv_timer.v
+
+out: timer interrupt
+in: timer increment
+
+How are they connected in a SOC based on these IPs?
+
+# Notes
+
+3 interrupts:
+
+- external: Simple IO or from PLIC (?)
+- timer: memory-mapped peripheral, shared across a multi core architecture
+- sotware: ecrire dans mip qui est une sortie, mais peut elle rentrer ensuite?
+ Peut etre par une IRQ externe?
+
+
+Stackoverflow thread about software interrupts:
+
+https://stackoverflow.com/questions/64863737/risc-v-software-interrupts
+
+
+# RISCV Esperanto slides
+
+https://riscv.org/wp-content/uploads/2018/05/riscv-privileged-BCN.v7-2.pdf
+
+PLIC:
+- gathers external interrupt and route them to the different harts
+- Interrupts can target multiple harts simultaneously
+
+Sotfware interrupts:
+
+Software interrupt are how harts interrupt each other
+- Mechanism for inter-hart interrupts (IPIs)
+- Setting the appropriate SIP bit in another hart is performed by a MMIO write
+- But a hart can set its own SIP bit if currmode >=
diff --git a/rtl/friscv_clint.sv b/rtl/friscv_clint.sv
new file mode 100644
index 0000000..c920f71
--- /dev/null
+++ b/rtl/friscv_clint.sv
@@ -0,0 +1,42 @@
+// distributed under the mit license
+// https://opensource.org/licenses/mit-license.php
+
+`timescale 1 ns / 1 ps
+`default_nettype none
+
+`include "svlogger.sv"
+`include "friscv_h.sv"
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Clint controller (Core Local Interrupt Controller), implementing next CSRs:
+// - mtime / mtimecmp (machine time registers)
+// - mie / mip (machine interrupt registers)
+///////////////////////////////////////////////////////////////////////////////
+
+
+module friscv_clint
+
+ #(
+ // Architecture setup
+ parameter XLEN = 32
+ )(
+ // clock & reset
+ input logic aclk,
+ input logic aresetn,
+ input logic srst,
+ // real-time clock, shared across the harts
+ input logic rtc,
+ // software interrupt
+ output logic sw_irq,
+ // timer interrupt
+ output logic timer_irq
+ );
+
+ assign sw_irq = 1'b0;
+ assign timer_irq = 1'b0;
+
+endmodule
+
+`resetall
+
diff --git a/rtl/friscv_control.sv b/rtl/friscv_control.sv
index 912a27a..3883ebe 100644
--- a/rtl/friscv_control.sv
+++ b/rtl/friscv_control.sv
@@ -34,7 +34,6 @@ module friscv_control
input logic aclk,
input logic aresetn,
input logic srst,
- input logic irq,
output logic [5 -1:0] traps,
// Flush control
output logic flush_req,
@@ -77,6 +76,8 @@ module friscv_control
output logic [XLEN -1:0] mstatus,
output logic mcause_wr,
output logic [XLEN -1:0] mcause,
+ output logic mtval_wr,
+ output logic [XLEN -1:0] mtval,
// CSR shared bus
input logic [`CSR_SB_W -1:0] csr_sb
);
@@ -114,7 +115,7 @@ module friscv_control
logic [6 -1:0] sys;
// Flag raised when receiving an unsupported/undefined instruction
- logic inst_error;
+ logic dec_error;
// Control fsm
typedef enum logic[3:0] {
@@ -158,6 +159,7 @@ module friscv_control
logic fifo_full;
logic pull_inst;
logic fifo_empty;
+ logic [XLEN -1:0] mtvec;
logic [XLEN -1:0] sb_mepc;
logic [XLEN -1:0] sb_mtvec;
@@ -167,10 +169,13 @@ module friscv_control
logic csr_ro_wr;
logic inst_addr_misaligned;
logic [XLEN -1:0] mcause_code;
+ logic [XLEN -1:0] mtval_info;
logic [XLEN -1:0] data_addr;
logic load_misaligned;
logic store_misaligned;
logic trap_occuring;
+ logic sync_trap_occuring;
+ logic async_trap_occuring;
// Logger setup
svlogger log;
@@ -214,6 +219,14 @@ module friscv_control
csr));
endtask
+ task print_mcause(
+ input string msg,
+ input logic [XLEN-1:0] mcause
+ );
+ string mcause_str;
+ $sformat(mcause_str, "%x", mcause);
+ log.debug({msg, mcause_str});
+ endtask
///////////////////////////////////////////////////////////////////////////
// CSR Shared bus extraction
@@ -256,7 +269,7 @@ module friscv_control
);
assign pull_inst = (csr_ready && ~cant_branch_now && ~cant_process_now &&
- cfsm==FETCH && ~fifo_empty) ? 1'b1 : 1'b0;
+ cfsm==FETCH && ~fifo_empty && ~trap_occuring) ? 1'b1 : 1'b0;
///////////////////////////////////////////////////////////////////////////
//
@@ -310,7 +323,7 @@ module friscv_control
.branching (branching),
.sys (sys),
.processing (processing),
- .inst_error (inst_error),
+ .dec_error (dec_error),
.pred (pred),
.succ (succ)
);
@@ -420,8 +433,8 @@ module friscv_control
///////////////////////////////////////////////////////////////////////////
//
- // Control flow FSM: the FSM updating the program counter, managing the
- // incoming instructions and the processing unit
+ // Control flow: the FSM updating the program counter, managing the
+ // incoming instructions, the CSR & processing unit and all traps
//
///////////////////////////////////////////////////////////////////////////
@@ -444,6 +457,8 @@ module friscv_control
mstatus <= {XLEN{1'b0}};
mcause_wr <= 1'b0;
mcause <= {XLEN{1'b0}};
+ mtval_wr <= 1'b0;
+ mtval <= {XLEN{1'b0}};
end else if (srst == 1'b1) begin
cfsm <= BOOT;
arvalid <= 1'b0;
@@ -461,11 +476,15 @@ module friscv_control
mstatus <= {XLEN{1'b0}};
mcause_wr <= 1'b0;
mcause <= {XLEN{1'b0}};
+ mtval_wr <= 1'b0;
+ mtval <= {XLEN{1'b0}};
end else begin
case (cfsm)
+ ///////////////////////////////////////////////////////////////
// Start to boot the RAM after reset.
+ ///////////////////////////////////////////////////////////////
default: begin
arvalid <= 1'b1;
@@ -478,50 +497,64 @@ module friscv_control
end
end
+ ///////////////////////////////////////////////////////////////
// Fetch instructions from the cache (or the memory)
+ ///////////////////////////////////////////////////////////////
FETCH: begin
+ ///////////////////////////////////////////////////////////
// Manages read outstanding requests to fetch
// new instruction from memory:
//
- // - if fifo is filled with instruction, need a jump
- // and can branch and CSR are ready, stop the addr
- // issuer and load it with correct address to use
+ // - if fifo is filled with instruction, need a jump or
+ // manage a trap, stop the addr issuer and load the
+ // right branch
//
if (~fifo_empty &&
- (jump_branch || sys[`IS_ECALL] || sys[`IS_MRET] || fence[`IS_FENCEI]) &&
+ (jump_branch || sys[`IS_ECALL] || sys[`IS_MRET] ||
+ fence[`IS_FENCEI] || trap_occuring) &&
~cant_branch_now && csr_ready) begin
- // ECALL
- if (sys[`IS_ECALL]) araddr <= sb_mtvec;
+
+ // ECALL / Trap handling
+ if (sys[`IS_ECALL] || trap_occuring) araddr <= mtvec;
+ // MRET
else if (sys[`IS_MRET]) araddr <= sb_mepc;
// All other jumps
else araddr <= pc;
//
- // - else continue to simply increment by instruction width
- // TODO: don't continue to increment if need to jump?
+ // - else continue to simply increment by ILEN
//
end else if (arready) begin
araddr <= araddr + ILEN/8;
end
+ ///////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////
// Manages the PC vs the different instructions to execute
if (~fifo_empty) begin
- // Stop the execution when a unsupported instruction or
- // a decoding error has been issued
- if (inst_error) begin
- log.error("Decoding error, received an unsupported instruction");
- print_instruction(instruction, pc_reg, opcode, funct3,
- funct7, rs1, rs2, rd, imm12, imm20, csr);
+ // Need to branch/process but ALU/memfy/CSR didn't finish
+ // to execute last instruction, so store it.
+ if (~csr_ready || cant_branch_now || cant_process_now) begin
+ pc_jal_saved <= pc_plus4;
+ pc_auipc_saved <= pc_reg;
+ end
+
+ // Move to the trap handling when received an
+ // interrupt, a wrong instruction, ...
+ if (trap_occuring) begin
+ print_mcause("Handling a trap: ", mcause_code);
traps[3] <= 1'b1;
flush_fifo <= 1'b1;
arvalid <= 1'b0;
arid <= arid + 1;
- pc_reg <= sb_mtvec;
+ pc_reg <= mtvec;
mepc_wr <= 1'b1;
mepc <= pc_reg;
mcause_wr <= 1'b1;
mcause <= mcause_code;
+ mtval_wr <= 1'b1;
+ mtval <= mtval_info;
cfsm <= RELOAD;
end
@@ -548,9 +581,11 @@ module friscv_control
flush_fifo <= 1'b1;
arvalid <= 1'b0;
arid <= arid + 1;
- pc_reg <= sb_mtvec;
+ pc_reg <= mtvec;
mepc_wr <= 1'b1;
mepc <= pc_reg;
+ mtval_wr <= 1'b1;
+ mtval <= mtval_info;
cfsm <= RELOAD;
// Reach an EBREAK instruction, need to stall the core
@@ -591,16 +626,8 @@ module friscv_control
arid <= arid + 1;
pc_reg <= pc;
cfsm <= FENCE_I;
- end
-
- // Need to branch/process but ALU/memfy/CSR didn't finish
- // to execute last instruction, so store it.
- else if (~csr_ready || cant_branch_now || cant_process_now) begin
- pc_jal_saved <= pc_plus4;
- pc_auipc_saved <= pc_reg;
-
- // Process as long instructions are available
+ // All other instructions
end else if (csr_ready &&
~cant_branch_now && ~cant_process_now) begin
print_instruction(instruction, pc_reg, opcode, funct3,
@@ -608,25 +635,31 @@ module friscv_control
pc_reg <= pc;
end
end
+ ///////////////////////////////////////////////////////////
end
+
+ ///////////////////////////////////////////////////////////////
// Stop operations to reload new oustanding requests. Used to
// reboot the cache and continue to fetch the addresses from
// a new origin
+ ///////////////////////////////////////////////////////////////
RELOAD: begin
traps <= 5'b0;
mepc_wr <= 1'b0;
mstatus_wr <= 1'b0;
mcause_wr <= 1'b0;
+ mtval_wr <= 1'b0;
arvalid <= 1'b1;
flush_fifo <= 1'b0;
cfsm <= FETCH;
end
+
+ ///////////////////////////////////////////////////////////////
// Launch a cache flush, req starts the flush and is kept
// high as long ack is not asserted.
- // TODO: ensure the instruction pipeline is empty before
- // moving back to execution
+ ///////////////////////////////////////////////////////////////
FENCE_I: begin
flush_req <= 1'b1;
if (flush_ack) begin
@@ -638,8 +671,10 @@ module friscv_control
end
end
- // EBREAK completly stops the processor and wait for a reboot
- // TODO: Understand how to manage EBREAK when software needs
+
+ ///////////////////////////////////////////////////////////////
+ // EBREAK completely stops the processor and wait for a reboot
+ ///////////////////////////////////////////////////////////////
EBREAK: begin
traps <= 5'b0;
arvalid <= 1'b0;
@@ -662,7 +697,7 @@ module friscv_control
assign cant_branch_now = ((jal || jalr || branching) &&
~proc_ready) ? 1'b1 :
- 1'b0;
+ 1'b0 ;
assign cant_process_now = (processing && ~proc_ready) ? 1'b1 : 1'b0;
@@ -687,13 +722,13 @@ module friscv_control
((jal || jalr) && pull_inst) ? pc_plus4 :
(lui) ? {imm20, 12'b0} :
(auipc && ~pull_inst) ? pc_auipc_saved :
- (auipc && pull_inst) ? pc_auipc :
+ (auipc && pull_inst) ? pc_auipc :
pc;
///////////////////////////////////////////////////////////////////////////
//
- // Prepare CSR registers content to store during exceptions and traps
+ // Prepare CSR registers content to use or modify
//
///////////////////////////////////////////////////////////////////////////
@@ -711,12 +746,19 @@ module friscv_control
1'b0, // SIE
1'b0}; // UIE
+ // MTVEC computation: on async exception occurence, pc uses mtvec + 4*cause
+ // else set it up to mtvec.
+ assign mtvec = (async_trap_occuring && sb_mtvec[1:0]!=2'b0) ? // Vectored mode
+ {sb_mtvec[XLEN-1:2], 2'b0} + (mcause_code << 2) :
+ {sb_mtvec[XLEN-1:2], 2'b0} ; // Direct mode
+
+
///////////////////////////////////////////////////////////////////////////
- // Mause Register management, indicating to software the trap in
+ // Mcause CSR management, indicating to software the trap in
// machine-mode
///////////////////////////////////////////////////////////////////////////
- // The access tries to modify a read-only register
+ // The instruction tries to modify a read-only register
assign csr_ro_wr = (csr[11:10]==2'b11 &&
// only rs1=x0 and these opcodes can be legal, else
// it modifies the targeted CSR
@@ -728,60 +770,110 @@ module friscv_control
) ? 1'b1 : 1'b0;
// PC is not aligned with 32 bits
- assign inst_addr_misaligned = (pc[1:0] != 2'b0) ? 1'b1 : 1'b0;
+ assign inst_addr_misaligned = (pc[1:0]!=2'b0) ? 1'b1 : 1'b0;
- // The address to access during a LOAD or a STORE
+ // The address used to access during a LOAD or a STORE
assign data_addr = $signed({{(XLEN-12){imm12[11]}}, imm12}) + $signed(ctrl_rs1_val);
- // LOAD is not boundary aligned
- assign load_misaligned = (opcode==`LOAD && funct3==`LH && data_addr[1:0]==2'h3) ? 1'b1 :
- (opcode==`LOAD && funct3==`LHU && data_addr[1:0]==2'h3) ? 1'b1 :
+ // LOAD is not boundary aligned, must be aligned on data type
+ assign load_misaligned = (opcode==`LOAD && (funct3==`LH || funct3==`LHU) &&
+ (data_addr[1:0]==2'h3 || data_addr[1:0]==2'h1)) ? 1'b1 :
(opcode==`LOAD && funct3==`LW && data_addr[1:0]!=2'b0) ? 1'b1 :
1'b0 ;
// STORE is not boundary aligned
- assign store_misaligned = (opcode==`STORE && funct3==`SH && ^data_addr[1:0]==2'h3) ? 1'b1 :
- 1'b0 ;
+ assign store_misaligned = (opcode==`STORE && funct3==`SH &&
+ (data_addr[1:0]==2'h3 || data_addr[1:0]==2'h1)) ? 1'b1 :
+ (opcode==`STORE && funct3==`SW && data_addr[1:0]!=2'b0) ? 1'b1 :
+ 1'b0 ;
///////////////////////////////////////////////////////////////////////////
//
+ // Asynchronous exceptions code:
+ // ---------------------------
+ //
+ // Exception Code | Description
+ // ----------------|------------------------------------------
+ // 0 | User software interrupt
+ // 1 | Supervisor software interrupt
+ // 2 | Reserved for future standard use
+ // 3 | Machine software interrupt
+ // -----------------------------------------------------------
+ // 4 | User timer interrupt
+ // 5 | Supervisor timer interrupt
+ // 6 | Reserved for future standard use
+ // 7 | Machine timer interrupt
+ // -----------------------------------------------------------
+ // 8 | User external interrupt
+ // 9 | Supervisor external interrupt
+ // 10 | Reserved for future standard use
+ // 11 | Machine external interrupt
+ // -----------------------------------------------------------
+ // 12-15 | Reserved for future standard use
+ // ≥16 | Reserved for platform use
+ // -----------------------------------------------------------
+ //
+ //
// Synchronous exception priority in decreasing priority order:
+ // -----------------------------------------------------------
+ //
//
// Priority | Exception Code | Description
// ----------|------------------|------------------------------------------
// Highest | 3 | Instruction address breakpoint
+ // ------------------------------------------------------------------------
// | 12 | Instruction page fault
+ // ------------------------------------------------------------------------
// | 1 | Instruction access fault
+ // ------------------------------------------------------------------------
// | 2 | Illegal instruction
// | 0 | Instruction address misaligned
// | 8,9,11 | Environment call (U/S/M modes)
// | 3 | Environment break
// | 3 | Load/Store/AMO address breakpoint
+ // ------------------------------------------------------------------------
// | 6 | Store/AMO address misaligned
// | 4 | Load address misaligned
+ // ------------------------------------------------------------------------
// | 15 | Store/AMO page fault
// | 13 | Load page fault
- // | 7 | Store/AMO access fault
- // Lowest | 5 | Load access fault
+ // ------------------------------------------------------------------------
+ // Lowest | 7 | Store/AMO access fault
+ // | 5 | Load access fault
+ // ------------------------------------------------------------------------
//
///////////////////////////////////////////////////////////////////////////
- // MCAUSE switching logic based on priority
- assign mcause_code = (inst_addr_misaligned) ? {XLEN{1'b0}} :
+ // MCAUSE switching logic based on above listed priorities
+ assign mcause_code = // aync exceptions have highest priority
+ (csr_sb[`MEIRQ]) ? {1'b1, {XLEN-5{1'b0}}, 4'hB} :
+ // then follow sync exceptions
+ (inst_addr_misaligned) ? {XLEN{1'b0}} :
(csr_ro_wr) ? {{XLEN-4{1'b0}}, 4'h1} :
- (inst_error) ? {{XLEN-4{1'b0}}, 4'h2} :
+ (dec_error) ? {{XLEN-4{1'b0}}, 4'h2} :
(sys[`IS_ECALL]) ? {{XLEN-4{1'b0}}, 4'hB} :
(sys[`IS_EBREAK]) ? {{XLEN-4{1'b0}}, 4'h3} :
(store_misaligned) ? {{XLEN-4{1'b0}}, 4'h6} :
(load_misaligned) ? {{XLEN-4{1'b0}}, 4'h4} :
{XLEN{1'b0}};
- // Triggers the trap execution
- assign trap_occuring = csr_ro_wr |
- inst_addr_misaligned |
- load_misaligned |
- store_misaligned |
- inst_error;
+ // Exception-specific information
+ assign mtval_info = (dec_error) ? instruction :
+ (inst_addr_misaligned) ? data_addr :
+ (sys[`IS_ECALL]) ? pc_reg :
+ (sys[`IS_EBREAK]) ? pc_reg :
+ {XLEN{1'b0}};
+
+ // Trigger the trap handling execution in main FSM
+ assign async_trap_occuring = csr_sb[`MEIRQ];
+
+ assign sync_trap_occuring = csr_ro_wr |
+ inst_addr_misaligned |
+ load_misaligned |
+ store_misaligned |
+ dec_error;
+
+ assign trap_occuring = async_trap_occuring | sync_trap_occuring;
endmodule
diff --git a/rtl/friscv_csr.sv b/rtl/friscv_csr.sv
index 1273fc5..a7bb30a 100644
--- a/rtl/friscv_csr.sv
+++ b/rtl/friscv_csr.sv
@@ -13,15 +13,17 @@ module friscv_csr
parameter MHART_ID = 0,
parameter XLEN = 32
)(
- // clock/reset interface
+ // Clock/reset interface
input logic aclk,
input logic aresetn,
input logic srst,
+ // External interrupt pin
+ input logic eirq,
// Instruction bus
input logic valid,
output logic ready,
input logic [`INST_BUS_W-1:0] instbus,
- // register source 1 query interface
+ // Register source 1 query interface
output logic [5 -1:0] rs1_addr,
input logic [XLEN -1:0] rs1_val,
output logic rd_wr_en,
@@ -34,6 +36,8 @@ module friscv_csr
input logic [XLEN -1:0] ctrl_mstatus,
input logic ctrl_mcause_wr,
input logic [XLEN -1:0] ctrl_mcause,
+ input logic ctrl_mtval_wr,
+ input logic [XLEN -1:0] ctrl_mtval,
// CSR shared bus
output logic [`CSR_SB_W -1:0] csr_sb
);
@@ -75,10 +79,11 @@ module friscv_csr
logic [5 -1:0] rs1_addr_r;
logic [XLEN -1:0] rs1_val_r;
+ logic [2 -1:0] eirq_cdc;
- // -------------------
+ //////////////////////////////////////////////////////////////////////////
// Machine-level CSRs:
- // -------------------
+ //////////////////////////////////////////////////////////////////////////
// Machine Information Status
// logic [XLEN-1:0] mvendorid; // 0xF11 MRO (not implemented)
@@ -110,17 +115,17 @@ module friscv_csr
logic [XLEN-1:0] pmpaddr0; // 0x3B0 MRW
- // ----------------------
+ //////////////////////////////////////////////////////////////////////////
// Supervisor-level CSRs:
- // ----------------------
+ //////////////////////////////////////////////////////////////////////////
// Supervisor Protection and Translation
logic [XLEN-1:0] satp; // 0x180
- // ----------------
+ //////////////////////////////////////////////////////////////////////////
// User-level CSRs:
- // ----------------
+ //////////////////////////////////////////////////////////////////////////
// User Counter/Timers
logic [XLEN-1:0] cycle; // 0xC00
@@ -132,9 +137,9 @@ module friscv_csr
`CSR_VERBOSITY,
`CSR_ROUTE);
- // ------------------------------------------------------------------------
+ //////////////////////////////////////////////////////////////////////////
// Decompose the instruction bus
- // ------------------------------------------------------------------------
+ //////////////////////////////////////////////////////////////////////////
assign opcode = instbus[`OPCODE +: `OPCODE_W];
assign funct3 = instbus[`FUNCT3 +: `FUNCT3_W];
@@ -146,9 +151,9 @@ module friscv_csr
assign rs1_addr = rs1;
- // ------------------------------------------------------------------------
+ //////////////////////////////////////////////////////////////////////////
// CSR execution machine
- // ------------------------------------------------------------------------
+ //////////////////////////////////////////////////////////////////////////
always @ (posedge aclk or negedge aresetn) begin
if (aresetn==1'b0) begin
@@ -276,14 +281,23 @@ module friscv_csr
end
- // ------------------------------------------------------------------------
+ //////////////////////////////////////////////////////////////////////////
// CSRs description
- // ------------------------------------------------------------------------
+ //
+ // WPRI: Reserved Writes Preserve Values, Reads Ignore Values
+ // WARL: Write Any, Read legal
+ //
+ //////////////////////////////////////////////////////////////////////////
- // HARTID - Read-only
+
+ ///////////////////////////////////////////////////////////////////////////
+ // HARTID - 0xF14 (RO)
+ ///////////////////////////////////////////////////////////////////////////
assign mhartid = MHART_ID;
- // ISA Description: supposed to be RW, is RO in this implementation
+ ///////////////////////////////////////////////////////////////////////////
+ // MISA - 0x301 (RO)
+ ///////////////////////////////////////////////////////////////////////////
// Supported extensions
assign misa[0] = 1'b0; // A Atomic extension
@@ -313,7 +327,6 @@ module friscv_csr
assign misa[24] = 1'b0; // Y Reserved
assign misa[25] = 1'b0; // Z Reserved
-
// MXLEN field encoding
generate
if (XLEN==32) begin : MXLEN_32
@@ -325,32 +338,32 @@ module friscv_csr
end
endgenerate
- // TODO: take in account current privilege mode check if rw is applicable
-
- // MSTATUS (WPRI - Reserved Writes Preserve Values, Reads Ignore Values)
-
- // 31 SD related to XS FS, 0 for the moment
- // 30-23 WPRI
- // 22 TSR Supervisor mode, 0 for the moment
- // 21 TW Timeout Wait, 0 for the moment
- // 20 TVM Virtualization, 0 N/A
- // 19 MXR Virtual Mem, 0 N/A
- // 18 SUM Virtual Mem, 0 N/A
- // 17 MPRV Virtual Mem, 0 N/A
- // 16:15 XS FP, 0 N/A
- // 14:13 FS FP, 0 N/A
- // 12:11 MPP
- // 10:9 WPRI
- // 8 SPP Supervisor mode, 0 for the moment
- // 7 MPIE
- // 6 WPRI
- // 5 SPIE Supervisor mode, 0 for the moment
- // 4 UPIE User mode, 0 for the moment
- // 3 MIE
- // 2 WPRI
- // 1 SIE Supervisor mode, 0 for the moment
- // 0 UIE User mode, 0 for the moment
-
+ ///////////////////////////////////////////////////////////////////////////
+ // MSTATUS - 0x300
+ //
+ // 31: SD related to XS FS, 0 for the moment
+ // 30:23: (WPRI)
+ // 22: TSR Supervisor mode, 0 N/A
+ // 21: TW Timeout Wait, 0 N/A
+ // 20: TVM Virtualization, 0 N/A
+ // 19: MXR Virtual Mem, 0 N/A
+ // 18: SUM Virtual Mem, 0 N/A
+ // 17: MPRV Virtual Mem, 0 N/A
+ // 16:15: XS FP, 0 N/A
+ // 14:13: FS FP, 0 N/A
+ // 12:11: MPP: Machine-mode, previous priviledge mode, 0 N/A
+ // 10:9: (WPRI)
+ // 8: SPP Supervisor mode, 0 N/A
+ // 7: MPIE: Machine-mode, Interrupt enable (prior to the trap)
+ // 6: (WPRI)
+ // 5: SPIE Supervisor mode, 0 N/A
+ // 4: UPIE User mode, 0 N/A
+ // 3: MIE: Machine-mode, Interrupt enable
+ // 2: (WPRI)
+ // 1: SIE Supervisor mode, 0 N/A
+ // 0: UIE User mode, 0 N/A
+ //
+ ///////////////////////////////////////////////////////////////////////////
always @ (posedge aclk or negedge aresetn) begin
if (~aresetn) begin
mstatus <= {XLEN{1'b0}};
@@ -371,7 +384,26 @@ module friscv_csr
end
end
- // MTVEC (WARL - Write Any Values, Reads Legal Values)
+ ///////////////////////////////////////////////////////////////////////////
+ // MIE - 0x304
+ ///////////////////////////////////////////////////////////////////////////
+ always @ (posedge aclk or negedge aresetn) begin
+ if (~aresetn) begin
+ mie <= {XLEN{1'b0}};
+ end else if (srst) begin
+ mie <= {XLEN{1'b0}};
+ end else begin
+ if (csr_wren) begin
+ if (csr_r==12'h304) begin
+ mie <= newval;
+ end
+ end
+ end
+ end
+
+ ///////////////////////////////////////////////////////////////////////////
+ // MTVEC - 0x305
+ ///////////////////////////////////////////////////////////////////////////
always @ (posedge aclk or negedge aresetn) begin
if (~aresetn) begin
mtvec <= {XLEN{1'b0}};
@@ -386,7 +418,9 @@ module friscv_csr
end
end
- // MSCRATCH
+ ///////////////////////////////////////////////////////////////////////////
+ // MSCRATCH - 0x340
+ ///////////////////////////////////////////////////////////////////////////
always @ (posedge aclk or negedge aresetn) begin
if (~aresetn) begin
mscratch <= {XLEN{1'b0}};
@@ -401,7 +435,9 @@ module friscv_csr
end
end
- // MEPC, only support IALIGN=32
+ ///////////////////////////////////////////////////////////////////////////
+ // MEPC, only support IALIGN=32 - 0x341
+ ///////////////////////////////////////////////////////////////////////////
always @ (posedge aclk or negedge aresetn) begin
if (~aresetn) begin
mepc <= {XLEN{1'b0}};
@@ -418,7 +454,9 @@ module friscv_csr
end
end
- // MCAUSE
+ ///////////////////////////////////////////////////////////////////////////
+ // MCAUSE - 0x342
+ ///////////////////////////////////////////////////////////////////////////
always @ (posedge aclk or negedge aresetn) begin
if (~aresetn) begin
mcause <= {XLEN{1'b0}};
@@ -435,14 +473,18 @@ module friscv_csr
end
end
- // MTVAL
+ ///////////////////////////////////////////////////////////////////////////
+ // MTVAL - 0x343
+ ///////////////////////////////////////////////////////////////////////////
always @ (posedge aclk or negedge aresetn) begin
if (~aresetn) begin
mtval <= {XLEN{1'b0}};
end else if (srst) begin
mtval <= {XLEN{1'b0}};
end else begin
- if (csr_wren) begin
+ if (ctrl_mtval_wr) begin
+ mtval <= ctrl_mtval;
+ end else if (csr_wren) begin
if (csr_r==12'h343) begin
mtval <= newval;
end
@@ -450,6 +492,22 @@ module friscv_csr
end
end
+ ///////////////////////////////////////////////////////////////////////////
+ // MIP - 0x344
+ ///////////////////////////////////////////////////////////////////////////
+ always @ (posedge aclk or negedge aresetn) begin
+ if (~aresetn) begin
+ mip <= {XLEN{1'b0}};
+ end else if (srst) begin
+ mip <= {XLEN{1'b0}};
+ end else begin
+ if (csr_wren) begin
+ if (csr_r==12'h344) begin
+ mip <= newval;
+ end
+ end
+ end
+ end
//////////////////////////////////////////////////////////////////////////
// Read circuit
@@ -466,6 +524,8 @@ module friscv_csr
oldval <= mstatus;
end else if (csr==12'h301) begin
oldval <= misa;
+ end else if (csr==12'h304) begin
+ oldval <= mie;
end else if (csr==12'h305) begin
oldval <= mtvec;
end else if (csr==12'h340) begin
@@ -476,6 +536,8 @@ module friscv_csr
oldval <= mcause;
end else if (csr==12'h343) begin
oldval <= mtval;
+ end else if (csr==12'h344) begin
+ oldval <= mip;
end else if (csr==12'hF14) begin
oldval <= mhartid;
end else begin
@@ -494,6 +556,17 @@ module friscv_csr
assign csr_sb[`MEPC+:XLEN] = mepc;
assign csr_sb[`MSTATUS+:XLEN] = mstatus;
+ // Synchronize the external IRQ in the core's clock domain
+ always @ (posedge aclk or negedge aresetn) begin
+ if (aresetn) eirq_cdc <= 2'b0;
+ else if (srst) eirq_cdc <= 2'b0;
+ else eirq_cdc <= {eirq_cdc[0], eirq};
+ end
+
+ assign csr_sb[`MEIRQ] = mstatus[3] & // global interrupt enable
+ mie[11] & // external interrupt enable
+ eirq_cdc[1]; // external interrupt pin
+
endmodule
diff --git a/rtl/friscv_decoder.sv b/rtl/friscv_decoder.sv
index 0cd5710..8855fc3 100644
--- a/rtl/friscv_decoder.sv
+++ b/rtl/friscv_decoder.sv
@@ -29,7 +29,7 @@ module friscv_decoder
output logic branching,
output logic [6 -1:0] sys,
output logic processing,
- output logic inst_error,
+ output logic dec_error,
output logic [4 -1:0] pred,
output logic [4 -1:0] succ
);
@@ -49,7 +49,7 @@ module friscv_decoder
sys = 6'b0;
fence = 2'b0;
processing = 1'b0;
- inst_error = 1'b0;
+ dec_error = 1'b0;
imm12 = 12'b0;
imm20 = instruction[31:12];
end
@@ -64,7 +64,7 @@ module friscv_decoder
sys = 6'b0;
fence = 2'b0;
processing = 1'b0;
- inst_error = 1'b0;
+ dec_error = 1'b0;
imm12 = 12'b0;
imm20 = instruction[31:12];
end
@@ -79,7 +79,7 @@ module friscv_decoder
sys = 6'b0;
fence = 2'b0;
processing = 1'b0;
- inst_error = 1'b0;
+ dec_error = 1'b0;
imm12 = 12'b0;
imm20 = {instruction[31],
instruction[19:12],
@@ -97,7 +97,7 @@ module friscv_decoder
sys = 6'b0;
fence = 2'b0;
processing = 1'b0;
- inst_error = 1'b0;
+ dec_error = 1'b0;
imm12 = instruction[20+:12];
imm20 = 20'b0;
end
@@ -112,7 +112,7 @@ module friscv_decoder
sys = 6'b0;
fence = 2'b0;
processing = 1'b0;
- inst_error = 1'b0;
+ dec_error = 1'b0;
imm12 = {instruction[31],
instruction[7],
instruction[25+:6],
@@ -156,7 +156,7 @@ module friscv_decoder
end
fence = 2'b0;
processing = 1'b0;
- inst_error = 1'b0;
+ dec_error = 1'b0;
imm12 = 12'b0;
imm20 = 20'b0;
end
@@ -177,7 +177,7 @@ module friscv_decoder
fence = 2'b01;
end
processing = 1'b0;
- inst_error = 1'b0;
+ dec_error = 1'b0;
imm12 = 12'b0;
imm20 = 20'b0;
end
@@ -192,7 +192,7 @@ module friscv_decoder
sys = 6'b0;
fence = 2'b0;
processing = 1'b1;
- inst_error = 1'b0;
+ dec_error = 1'b0;
imm12 = instruction[20+:12];
imm20 = 20'b0;
end
@@ -207,7 +207,7 @@ module friscv_decoder
sys = 6'b0;
fence = 2'b0;
processing = 1'b1;
- inst_error = 1'b0;
+ dec_error = 1'b0;
imm12 = {instruction[25+:7], instruction[7+:5]};
imm20 = 20'b0;
end
@@ -222,7 +222,7 @@ module friscv_decoder
sys = 6'b0;
fence = 2'b0;
processing = 1'b1;
- inst_error = 1'b0;
+ dec_error = 1'b0;
imm12 = instruction[20+:12];
imm20 = 20'b0;
end
@@ -237,7 +237,7 @@ module friscv_decoder
sys = 6'b0;
fence = 2'b0;
processing = 1'b1;
- inst_error = 1'b0;
+ dec_error = 1'b0;
imm12 = 12'b0;
imm20 = 20'b0;
end
@@ -252,7 +252,7 @@ module friscv_decoder
sys = 6'b0;
fence = 2'b0;
processing = 1'b0;
- inst_error = 1'b1;
+ dec_error = 1'b1;
imm12 = 12'b0;
imm20 = 20'b0;
end
diff --git a/rtl/friscv_h.sv b/rtl/friscv_h.sv
index 64728e4..d433901 100644
--- a/rtl/friscv_h.sv
+++ b/rtl/friscv_h.sv
@@ -138,9 +138,10 @@
`define MTVEC 0
`define MEPC `MTVEC + `XLEN
`define MSTATUS `MEPC + `XLEN
+`define MEIRQ `MSTATUS + `XLEN
// CSR shared bus width
-`define CSR_SB_W `MSTATUS + `XLEN
+`define CSR_SB_W `MEIRQ + 1
//////////////////////////////////////////////////////////////////
diff --git a/rtl/friscv_rv32i.sv b/rtl/friscv_rv32i.sv
index a3f0535..0b14dbf 100644
--- a/rtl/friscv_rv32i.sv
+++ b/rtl/friscv_rv32i.sv
@@ -58,7 +58,7 @@ module friscv_rv32i
parameter ICACHE_DEPTH = 512
)(
- // clock/reset interface
+ // Clock/reset interface
input logic aclk,
input logic aresetn,
input logic srst,
@@ -66,7 +66,7 @@ module friscv_rv32i
input logic irq,
// Internal core status
output logic [8 -1:0] status,
- // instruction memory interface
+ // Instruction memory interface
output logic imem_arvalid,
input logic imem_arready,
output logic [AXI_ADDR_W -1:0] imem_araddr,
@@ -77,7 +77,7 @@ module friscv_rv32i
input logic [AXI_ID_W -1:0] imem_rid,
input logic [2 -1:0] imem_rresp,
input logic [AXI_IMEM_W -1:0] imem_rdata,
- // data memory interface
+ // Data memory interface
output logic dmem_awvalid,
input logic dmem_awready,
output logic [AXI_ADDR_W -1:0] dmem_awaddr,
@@ -174,6 +174,8 @@ module friscv_rv32i
logic [XLEN -1:0] ctrl_mstatus;
logic ctrl_mcause_wr;
logic [XLEN -1:0] ctrl_mcause;
+ logic ctrl_mtval_wr;
+ logic [XLEN -1:0] ctrl_mtval;
logic [`CSR_SB_W -1:0] csr_sb;
//////////////////////////////////////////////////////////////////////////
@@ -276,7 +278,6 @@ module friscv_rv32i
.aclk (aclk),
.aresetn (aresetn),
.srst (srst),
- .irq (irq),
.traps (traps),
.flush_req (flush_req),
.flush_ack (flush_ack),
@@ -311,6 +312,8 @@ module friscv_rv32i
.mstatus (ctrl_mstatus),
.mcause_wr (ctrl_mcause_wr),
.mcause (ctrl_mcause),
+ .mtval_wr (ctrl_mtval_wr),
+ .mtval (ctrl_mtval),
.csr_sb (csr_sb)
);
@@ -406,6 +409,7 @@ module friscv_rv32i
.aclk (aclk),
.aresetn (aresetn),
.srst (srst),
+ .eirq (irq),
.valid (csr_en),
.ready (csr_ready),
.instbus (csr_instbus),
@@ -420,6 +424,8 @@ module friscv_rv32i
.ctrl_mstatus (ctrl_mstatus),
.ctrl_mcause_wr (ctrl_mcause_wr),
.ctrl_mcause (ctrl_mcause),
+ .ctrl_mtval_wr (ctrl_mtval_wr),
+ .ctrl_mtval (ctrl_mtval),
.csr_sb (csr_sb)
);
diff --git a/test/asm_testsuite/tests/env/encoding.h b/test/asm_testsuite/tests/env/encoding.h
new file mode 100644
index 0000000..2aa895b
--- /dev/null
+++ b/test/asm_testsuite/tests/env/encoding.h
@@ -0,0 +1,2832 @@
+/* See LICENSE for license details. */
+
+#ifndef RISCV_CSR_ENCODING_H
+#define RISCV_CSR_ENCODING_H
+
+#define MSTATUS_UIE 0x00000001
+#define MSTATUS_SIE 0x00000002
+#define MSTATUS_HIE 0x00000004
+#define MSTATUS_MIE 0x00000008
+#define MSTATUS_UPIE 0x00000010
+#define MSTATUS_SPIE 0x00000020
+#define MSTATUS_HPIE 0x00000040
+#define MSTATUS_MPIE 0x00000080
+#define MSTATUS_SPP 0x00000100
+#define MSTATUS_VS 0x00000600
+#define MSTATUS_MPP 0x00001800
+#define MSTATUS_FS 0x00006000
+#define MSTATUS_XS 0x00018000
+#define MSTATUS_MPRV 0x00020000
+#define MSTATUS_SUM 0x00040000
+#define MSTATUS_MXR 0x00080000
+#define MSTATUS_TVM 0x00100000
+#define MSTATUS_TW 0x00200000
+#define MSTATUS_TSR 0x00400000
+#define MSTATUS32_SD 0x80000000
+#define MSTATUS_UXL 0x0000000300000000
+#define MSTATUS_SXL 0x0000000C00000000
+#define MSTATUS64_SD 0x8000000000000000
+
+#define SSTATUS_UIE 0x00000001
+#define SSTATUS_SIE 0x00000002
+#define SSTATUS_UPIE 0x00000010
+#define SSTATUS_SPIE 0x00000020
+#define SSTATUS_SPP 0x00000100
+#define SSTATUS_VS 0x00000600
+#define SSTATUS_FS 0x00006000
+#define SSTATUS_XS 0x00018000
+#define SSTATUS_SUM 0x00040000
+#define SSTATUS_MXR 0x00080000
+#define SSTATUS32_SD 0x80000000
+#define SSTATUS_UXL 0x0000000300000000
+#define SSTATUS64_SD 0x8000000000000000
+
+#define USTATUS_UIE 0x00000001
+#define USTATUS_UPIE 0x00000010
+
+#define DCSR_XDEBUGVER (3U<<30)
+#define DCSR_NDRESET (1<<29)
+#define DCSR_FULLRESET (1<<28)
+#define DCSR_EBREAKM (1<<15)
+#define DCSR_EBREAKH (1<<14)
+#define DCSR_EBREAKS (1<<13)
+#define DCSR_EBREAKU (1<<12)
+#define DCSR_STOPCYCLE (1<<10)
+#define DCSR_STOPTIME (1<<9)
+#define DCSR_CAUSE (7<<6)
+#define DCSR_DEBUGINT (1<<5)
+#define DCSR_HALT (1<<3)
+#define DCSR_STEP (1<<2)
+#define DCSR_PRV (3<<0)
+
+#define DCSR_CAUSE_NONE 0
+#define DCSR_CAUSE_SWBP 1
+#define DCSR_CAUSE_HWBP 2
+#define DCSR_CAUSE_DEBUGINT 3
+#define DCSR_CAUSE_STEP 4
+#define DCSR_CAUSE_HALT 5
+
+#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4))
+#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5))
+#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))
+
+#define MCONTROL_SELECT (1<<19)
+#define MCONTROL_TIMING (1<<18)
+#define MCONTROL_ACTION (0x3f<<12)
+#define MCONTROL_CHAIN (1<<11)
+#define MCONTROL_MATCH (0xf<<7)
+#define MCONTROL_M (1<<6)
+#define MCONTROL_H (1<<5)
+#define MCONTROL_S (1<<4)
+#define MCONTROL_U (1<<3)
+#define MCONTROL_EXECUTE (1<<2)
+#define MCONTROL_STORE (1<<1)
+#define MCONTROL_LOAD (1<<0)
+
+#define MCONTROL_TYPE_NONE 0
+#define MCONTROL_TYPE_MATCH 2
+
+#define MCONTROL_ACTION_DEBUG_EXCEPTION 0
+#define MCONTROL_ACTION_DEBUG_MODE 1
+#define MCONTROL_ACTION_TRACE_START 2
+#define MCONTROL_ACTION_TRACE_STOP 3
+#define MCONTROL_ACTION_TRACE_EMIT 4
+
+#define MCONTROL_MATCH_EQUAL 0
+#define MCONTROL_MATCH_NAPOT 1
+#define MCONTROL_MATCH_GE 2
+#define MCONTROL_MATCH_LT 3
+#define MCONTROL_MATCH_MASK_LOW 4
+#define MCONTROL_MATCH_MASK_HIGH 5
+
+#define MIP_USIP (1 << IRQ_U_SOFT)
+#define MIP_SSIP (1 << IRQ_S_SOFT)
+#define MIP_HSIP (1 << IRQ_H_SOFT)
+#define MIP_MSIP (1 << IRQ_M_SOFT)
+#define MIP_UTIP (1 << IRQ_U_TIMER)
+#define MIP_STIP (1 << IRQ_S_TIMER)
+#define MIP_HTIP (1 << IRQ_H_TIMER)
+#define MIP_MTIP (1 << IRQ_M_TIMER)
+#define MIP_UEIP (1 << IRQ_U_EXT)
+#define MIP_SEIP (1 << IRQ_S_EXT)
+#define MIP_HEIP (1 << IRQ_H_EXT)
+#define MIP_MEIP (1 << IRQ_M_EXT)
+
+#define SIP_SSIP MIP_SSIP
+#define SIP_STIP MIP_STIP
+
+#define PRV_U 0
+#define PRV_S 1
+#define PRV_H 2
+#define PRV_M 3
+
+#define SATP32_MODE 0x80000000
+#define SATP32_ASID 0x7FC00000
+#define SATP32_PPN 0x003FFFFF
+#define SATP64_MODE 0xF000000000000000
+#define SATP64_ASID 0x0FFFF00000000000
+#define SATP64_PPN 0x00000FFFFFFFFFFF
+
+#define SATP_MODE_OFF 0
+#define SATP_MODE_SV32 1
+#define SATP_MODE_SV39 8
+#define SATP_MODE_SV48 9
+#define SATP_MODE_SV57 10
+#define SATP_MODE_SV64 11
+
+#define PMP_R 0x01
+#define PMP_W 0x02
+#define PMP_X 0x04
+#define PMP_A 0x18
+#define PMP_L 0x80
+#define PMP_SHIFT 2
+
+#define PMP_TOR 0x08
+#define PMP_NA4 0x10
+#define PMP_NAPOT 0x18
+
+#define IRQ_U_SOFT 0
+#define IRQ_S_SOFT 1
+#define IRQ_H_SOFT 2
+#define IRQ_M_SOFT 3
+#define IRQ_U_TIMER 4
+#define IRQ_S_TIMER 5
+#define IRQ_H_TIMER 6
+#define IRQ_M_TIMER 7
+#define IRQ_U_EXT 8
+#define IRQ_S_EXT 9
+#define IRQ_H_EXT 10
+#define IRQ_M_EXT 11
+#define IRQ_COP 12
+#define IRQ_HOST 13
+
+#define DEFAULT_RSTVEC 0x00001000
+#define CLINT_BASE 0x02000000
+#define CLINT_SIZE 0x000c0000
+#define EXT_IO_BASE 0x40000000
+#define DRAM_BASE 0x80000000
+
+/* page table entry (PTE) fields */
+#define PTE_V 0x001 /* Valid */
+#define PTE_R 0x002 /* Read */
+#define PTE_W 0x004 /* Write */
+#define PTE_X 0x008 /* Execute */
+#define PTE_U 0x010 /* User */
+#define PTE_G 0x020 /* Global */
+#define PTE_A 0x040 /* Accessed */
+#define PTE_D 0x080 /* Dirty */
+#define PTE_SOFT 0x300 /* Reserved for Software */
+#define PTE_RSVD 0x1FC0000000000000 /* Reserved for future standard use */
+#define PTE_PBMT 0x6000000000000000 /* Svpbmt: Page-based memory types */
+#define PTE_N 0x8000000000000000 /* Svnapot: NAPOT translation contiguity */
+#define PTE_ATTR 0xFFC0000000000000 /* All attributes and reserved bits */
+
+#define PTE_PPN_SHIFT 10
+
+#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
+
+#ifdef __riscv
+
+#if __riscv_xlen == 64
+# define MSTATUS_SD MSTATUS64_SD
+# define SSTATUS_SD SSTATUS64_SD
+# define RISCV_PGLEVEL_BITS 9
+# define SATP_MODE SATP64_MODE
+#else
+# define MSTATUS_SD MSTATUS32_SD
+# define SSTATUS_SD SSTATUS32_SD
+# define RISCV_PGLEVEL_BITS 10
+# define SATP_MODE SATP32_MODE
+#endif
+#define RISCV_PGSHIFT 12
+#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
+
+#ifndef __ASSEMBLER__
+
+#ifdef __GNUC__
+
+#define read_csr(reg) ({ unsigned long __tmp; \
+ asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+
+#define write_csr(reg, val) ({ \
+ asm volatile ("csrw " #reg ", %0" :: "rK"(val)); })
+
+#define swap_csr(reg, val) ({ unsigned long __tmp; \
+ asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "rK"(val)); \
+ __tmp; })
+
+#define set_csr(reg, bit) ({ unsigned long __tmp; \
+ asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
+ __tmp; })
+
+#define clear_csr(reg, bit) ({ unsigned long __tmp; \
+ asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
+ __tmp; })
+
+#define rdtime() read_csr(time)
+#define rdcycle() read_csr(cycle)
+#define rdinstret() read_csr(instret)
+
+#endif
+
+#endif
+
+#endif
+
+#endif
+/* Automatically generated by parse_opcodes. */
+#ifndef RISCV_ENCODING_H
+#define RISCV_ENCODING_H
+#define MATCH_SLLI_RV32 0x1013
+#define MASK_SLLI_RV32 0xfe00707f
+#define MATCH_SRLI_RV32 0x5013
+#define MASK_SRLI_RV32 0xfe00707f
+#define MATCH_SRAI_RV32 0x40005013
+#define MASK_SRAI_RV32 0xfe00707f
+#define MATCH_FRFLAGS 0x102073
+#define MASK_FRFLAGS 0xfffff07f
+#define MATCH_FSFLAGS 0x101073
+#define MASK_FSFLAGS 0xfff0707f
+#define MATCH_FSFLAGSI 0x105073
+#define MASK_FSFLAGSI 0xfff0707f
+#define MATCH_FRRM 0x202073
+#define MASK_FRRM 0xfffff07f
+#define MATCH_FSRM 0x201073
+#define MASK_FSRM 0xfff0707f
+#define MATCH_FSRMI 0x205073
+#define MASK_FSRMI 0xfff0707f
+#define MATCH_FSCSR 0x301073
+#define MASK_FSCSR 0xfff0707f
+#define MATCH_FRCSR 0x302073
+#define MASK_FRCSR 0xfffff07f
+#define MATCH_RDCYCLE 0xc0002073
+#define MASK_RDCYCLE 0xfffff07f
+#define MATCH_RDTIME 0xc0102073
+#define MASK_RDTIME 0xfffff07f
+#define MATCH_RDINSTRET 0xc0202073
+#define MASK_RDINSTRET 0xfffff07f
+#define MATCH_RDCYCLEH 0xc8002073
+#define MASK_RDCYCLEH 0xfffff07f
+#define MATCH_RDTIMEH 0xc8102073
+#define MASK_RDTIMEH 0xfffff07f
+#define MATCH_RDINSTRETH 0xc8202073
+#define MASK_RDINSTRETH 0xfffff07f
+#define MATCH_SCALL 0x73
+#define MASK_SCALL 0xffffffff
+#define MATCH_SBREAK 0x100073
+#define MASK_SBREAK 0xffffffff
+#define MATCH_FMV_X_S 0xe0000053
+#define MASK_FMV_X_S 0xfff0707f
+#define MATCH_FMV_S_X 0xf0000053
+#define MASK_FMV_S_X 0xfff0707f
+#define MATCH_FENCE_TSO 0x8330000f
+#define MASK_FENCE_TSO 0xfff0707f
+#define MATCH_PAUSE 0x100000f
+#define MASK_PAUSE 0xffffffff
+#define MATCH_BEQ 0x63
+#define MASK_BEQ 0x707f
+#define MATCH_BNE 0x1063
+#define MASK_BNE 0x707f
+#define MATCH_BLT 0x4063
+#define MASK_BLT 0x707f
+#define MATCH_BGE 0x5063
+#define MASK_BGE 0x707f
+#define MATCH_BLTU 0x6063
+#define MASK_BLTU 0x707f
+#define MATCH_BGEU 0x7063
+#define MASK_BGEU 0x707f
+#define MATCH_JALR 0x67
+#define MASK_JALR 0x707f
+#define MATCH_JAL 0x6f
+#define MASK_JAL 0x7f
+#define MATCH_LUI 0x37
+#define MASK_LUI 0x7f
+#define MATCH_AUIPC 0x17
+#define MASK_AUIPC 0x7f
+#define MATCH_ADDI 0x13
+#define MASK_ADDI 0x707f
+#define MATCH_SLLI 0x1013
+#define MASK_SLLI 0xfc00707f
+#define MATCH_SLTI 0x2013
+#define MASK_SLTI 0x707f
+#define MATCH_SLTIU 0x3013
+#define MASK_SLTIU 0x707f
+#define MATCH_XORI 0x4013
+#define MASK_XORI 0x707f
+#define MATCH_SRLI 0x5013
+#define MASK_SRLI 0xfc00707f
+#define MATCH_SRAI 0x40005013
+#define MASK_SRAI 0xfc00707f
+#define MATCH_ORI 0x6013
+#define MASK_ORI 0x707f
+#define MATCH_ANDI 0x7013
+#define MASK_ANDI 0x707f
+#define MATCH_ADD 0x33
+#define MASK_ADD 0xfe00707f
+#define MATCH_SUB 0x40000033
+#define MASK_SUB 0xfe00707f
+#define MATCH_SLL 0x1033
+#define MASK_SLL 0xfe00707f
+#define MATCH_SLT 0x2033
+#define MASK_SLT 0xfe00707f
+#define MATCH_SLTU 0x3033
+#define MASK_SLTU 0xfe00707f
+#define MATCH_XOR 0x4033
+#define MASK_XOR 0xfe00707f
+#define MATCH_SRL 0x5033
+#define MASK_SRL 0xfe00707f
+#define MATCH_SRA 0x40005033
+#define MASK_SRA 0xfe00707f
+#define MATCH_OR 0x6033
+#define MASK_OR 0xfe00707f
+#define MATCH_AND 0x7033
+#define MASK_AND 0xfe00707f
+#define MATCH_LB 0x3
+#define MASK_LB 0x707f
+#define MATCH_LH 0x1003
+#define MASK_LH 0x707f
+#define MATCH_LW 0x2003
+#define MASK_LW 0x707f
+#define MATCH_LBU 0x4003
+#define MASK_LBU 0x707f
+#define MATCH_LHU 0x5003
+#define MASK_LHU 0x707f
+#define MATCH_SB 0x23
+#define MASK_SB 0x707f
+#define MATCH_SH 0x1023
+#define MASK_SH 0x707f
+#define MATCH_SW 0x2023
+#define MASK_SW 0x707f
+#define MATCH_FENCE 0xf
+#define MASK_FENCE 0x707f
+#define MATCH_FENCE_I 0x100f
+#define MASK_FENCE_I 0x707f
+#define MATCH_ADDIW 0x1b
+#define MASK_ADDIW 0x707f
+#define MATCH_SLLIW 0x101b
+#define MASK_SLLIW 0xfe00707f
+#define MATCH_SRLIW 0x501b
+#define MASK_SRLIW 0xfe00707f
+#define MATCH_SRAIW 0x4000501b
+#define MASK_SRAIW 0xfe00707f
+#define MATCH_ADDW 0x3b
+#define MASK_ADDW 0xfe00707f
+#define MATCH_SUBW 0x4000003b
+#define MASK_SUBW 0xfe00707f
+#define MATCH_SLLW 0x103b
+#define MASK_SLLW 0xfe00707f
+#define MATCH_SRLW 0x503b
+#define MASK_SRLW 0xfe00707f
+#define MATCH_SRAW 0x4000503b
+#define MASK_SRAW 0xfe00707f
+#define MATCH_LD 0x3003
+#define MASK_LD 0x707f
+#define MATCH_LWU 0x6003
+#define MASK_LWU 0x707f
+#define MATCH_SD 0x3023
+#define MASK_SD 0x707f
+#define MATCH_MUL 0x2000033
+#define MASK_MUL 0xfe00707f
+#define MATCH_MULH 0x2001033
+#define MASK_MULH 0xfe00707f
+#define MATCH_MULHSU 0x2002033
+#define MASK_MULHSU 0xfe00707f
+#define MATCH_MULHU 0x2003033
+#define MASK_MULHU 0xfe00707f
+#define MATCH_DIV 0x2004033
+#define MASK_DIV 0xfe00707f
+#define MATCH_DIVU 0x2005033
+#define MASK_DIVU 0xfe00707f
+#define MATCH_REM 0x2006033
+#define MASK_REM 0xfe00707f
+#define MATCH_REMU 0x2007033
+#define MASK_REMU 0xfe00707f
+#define MATCH_MULW 0x200003b
+#define MASK_MULW 0xfe00707f
+#define MATCH_DIVW 0x200403b
+#define MASK_DIVW 0xfe00707f
+#define MATCH_DIVUW 0x200503b
+#define MASK_DIVUW 0xfe00707f
+#define MATCH_REMW 0x200603b
+#define MASK_REMW 0xfe00707f
+#define MATCH_REMUW 0x200703b
+#define MASK_REMUW 0xfe00707f
+#define MATCH_AMOADD_W 0x202f
+#define MASK_AMOADD_W 0xf800707f
+#define MATCH_AMOXOR_W 0x2000202f
+#define MASK_AMOXOR_W 0xf800707f
+#define MATCH_AMOOR_W 0x4000202f
+#define MASK_AMOOR_W 0xf800707f
+#define MATCH_AMOAND_W 0x6000202f
+#define MASK_AMOAND_W 0xf800707f
+#define MATCH_AMOMIN_W 0x8000202f
+#define MASK_AMOMIN_W 0xf800707f
+#define MATCH_AMOMAX_W 0xa000202f
+#define MASK_AMOMAX_W 0xf800707f
+#define MATCH_AMOMINU_W 0xc000202f
+#define MASK_AMOMINU_W 0xf800707f
+#define MATCH_AMOMAXU_W 0xe000202f
+#define MASK_AMOMAXU_W 0xf800707f
+#define MATCH_AMOSWAP_W 0x800202f
+#define MASK_AMOSWAP_W 0xf800707f
+#define MATCH_LR_W 0x1000202f
+#define MASK_LR_W 0xf9f0707f
+#define MATCH_SC_W 0x1800202f
+#define MASK_SC_W 0xf800707f
+#define MATCH_AMOADD_D 0x302f
+#define MASK_AMOADD_D 0xf800707f
+#define MATCH_AMOXOR_D 0x2000302f
+#define MASK_AMOXOR_D 0xf800707f
+#define MATCH_AMOOR_D 0x4000302f
+#define MASK_AMOOR_D 0xf800707f
+#define MATCH_AMOAND_D 0x6000302f
+#define MASK_AMOAND_D 0xf800707f
+#define MATCH_AMOMIN_D 0x8000302f
+#define MASK_AMOMIN_D 0xf800707f
+#define MATCH_AMOMAX_D 0xa000302f
+#define MASK_AMOMAX_D 0xf800707f
+#define MATCH_AMOMINU_D 0xc000302f
+#define MASK_AMOMINU_D 0xf800707f
+#define MATCH_AMOMAXU_D 0xe000302f
+#define MASK_AMOMAXU_D 0xf800707f
+#define MATCH_AMOSWAP_D 0x800302f
+#define MASK_AMOSWAP_D 0xf800707f
+#define MATCH_LR_D 0x1000302f
+#define MASK_LR_D 0xf9f0707f
+#define MATCH_SC_D 0x1800302f
+#define MASK_SC_D 0xf800707f
+#define MATCH_FADD_S 0x53
+#define MASK_FADD_S 0xfe00007f
+#define MATCH_FSUB_S 0x8000053
+#define MASK_FSUB_S 0xfe00007f
+#define MATCH_FMUL_S 0x10000053
+#define MASK_FMUL_S 0xfe00007f
+#define MATCH_FDIV_S 0x18000053
+#define MASK_FDIV_S 0xfe00007f
+#define MATCH_FSGNJ_S 0x20000053
+#define MASK_FSGNJ_S 0xfe00707f
+#define MATCH_FSGNJN_S 0x20001053
+#define MASK_FSGNJN_S 0xfe00707f
+#define MATCH_FSGNJX_S 0x20002053
+#define MASK_FSGNJX_S 0xfe00707f
+#define MATCH_FMIN_S 0x28000053
+#define MASK_FMIN_S 0xfe00707f
+#define MATCH_FMAX_S 0x28001053
+#define MASK_FMAX_S 0xfe00707f
+#define MATCH_FSQRT_S 0x58000053
+#define MASK_FSQRT_S 0xfff0007f
+#define MATCH_FLE_S 0xa0000053
+#define MASK_FLE_S 0xfe00707f
+#define MATCH_FLT_S 0xa0001053
+#define MASK_FLT_S 0xfe00707f
+#define MATCH_FEQ_S 0xa0002053
+#define MASK_FEQ_S 0xfe00707f
+#define MATCH_FCVT_W_S 0xc0000053
+#define MASK_FCVT_W_S 0xfff0007f
+#define MATCH_FCVT_WU_S 0xc0100053
+#define MASK_FCVT_WU_S 0xfff0007f
+#define MATCH_FMV_X_W 0xe0000053
+#define MASK_FMV_X_W 0xfff0707f
+#define MATCH_FCLASS_S 0xe0001053
+#define MASK_FCLASS_S 0xfff0707f
+#define MATCH_FCVT_S_W 0xd0000053
+#define MASK_FCVT_S_W 0xfff0007f
+#define MATCH_FCVT_S_WU 0xd0100053
+#define MASK_FCVT_S_WU 0xfff0007f
+#define MATCH_FMV_W_X 0xf0000053
+#define MASK_FMV_W_X 0xfff0707f
+#define MATCH_FLW 0x2007
+#define MASK_FLW 0x707f
+#define MATCH_FSW 0x2027
+#define MASK_FSW 0x707f
+#define MATCH_FMADD_S 0x43
+#define MASK_FMADD_S 0x600007f
+#define MATCH_FMSUB_S 0x47
+#define MASK_FMSUB_S 0x600007f
+#define MATCH_FNMSUB_S 0x4b
+#define MASK_FNMSUB_S 0x600007f
+#define MATCH_FNMADD_S 0x4f
+#define MASK_FNMADD_S 0x600007f
+#define MATCH_FCVT_L_S 0xc0200053
+#define MASK_FCVT_L_S 0xfff0007f
+#define MATCH_FCVT_LU_S 0xc0300053
+#define MASK_FCVT_LU_S 0xfff0007f
+#define MATCH_FCVT_S_L 0xd0200053
+#define MASK_FCVT_S_L 0xfff0007f
+#define MATCH_FCVT_S_LU 0xd0300053
+#define MASK_FCVT_S_LU 0xfff0007f
+#define MATCH_FADD_D 0x2000053
+#define MASK_FADD_D 0xfe00007f
+#define MATCH_FSUB_D 0xa000053
+#define MASK_FSUB_D 0xfe00007f
+#define MATCH_FMUL_D 0x12000053
+#define MASK_FMUL_D 0xfe00007f
+#define MATCH_FDIV_D 0x1a000053
+#define MASK_FDIV_D 0xfe00007f
+#define MATCH_FSGNJ_D 0x22000053
+#define MASK_FSGNJ_D 0xfe00707f
+#define MATCH_FSGNJN_D 0x22001053
+#define MASK_FSGNJN_D 0xfe00707f
+#define MATCH_FSGNJX_D 0x22002053
+#define MASK_FSGNJX_D 0xfe00707f
+#define MATCH_FMIN_D 0x2a000053
+#define MASK_FMIN_D 0xfe00707f
+#define MATCH_FMAX_D 0x2a001053
+#define MASK_FMAX_D 0xfe00707f
+#define MATCH_FCVT_S_D 0x40100053
+#define MASK_FCVT_S_D 0xfff0007f
+#define MATCH_FCVT_D_S 0x42000053
+#define MASK_FCVT_D_S 0xfff0007f
+#define MATCH_FSQRT_D 0x5a000053
+#define MASK_FSQRT_D 0xfff0007f
+#define MATCH_FLE_D 0xa2000053
+#define MASK_FLE_D 0xfe00707f
+#define MATCH_FLT_D 0xa2001053
+#define MASK_FLT_D 0xfe00707f
+#define MATCH_FEQ_D 0xa2002053
+#define MASK_FEQ_D 0xfe00707f
+#define MATCH_FCVT_W_D 0xc2000053
+#define MASK_FCVT_W_D 0xfff0007f
+#define MATCH_FCVT_WU_D 0xc2100053
+#define MASK_FCVT_WU_D 0xfff0007f
+#define MATCH_FCLASS_D 0xe2001053
+#define MASK_FCLASS_D 0xfff0707f
+#define MATCH_FCVT_D_W 0xd2000053
+#define MASK_FCVT_D_W 0xfff0007f
+#define MATCH_FCVT_D_WU 0xd2100053
+#define MASK_FCVT_D_WU 0xfff0007f
+#define MATCH_FLD 0x3007
+#define MASK_FLD 0x707f
+#define MATCH_FSD 0x3027
+#define MASK_FSD 0x707f
+#define MATCH_FMADD_D 0x2000043
+#define MASK_FMADD_D 0x600007f
+#define MATCH_FMSUB_D 0x2000047
+#define MASK_FMSUB_D 0x600007f
+#define MATCH_FNMSUB_D 0x200004b
+#define MASK_FNMSUB_D 0x600007f
+#define MATCH_FNMADD_D 0x200004f
+#define MASK_FNMADD_D 0x600007f
+#define MATCH_FCVT_L_D 0xc2200053
+#define MASK_FCVT_L_D 0xfff0007f
+#define MATCH_FCVT_LU_D 0xc2300053
+#define MASK_FCVT_LU_D 0xfff0007f
+#define MATCH_FMV_X_D 0xe2000053
+#define MASK_FMV_X_D 0xfff0707f
+#define MATCH_FCVT_D_L 0xd2200053
+#define MASK_FCVT_D_L 0xfff0007f
+#define MATCH_FCVT_D_LU 0xd2300053
+#define MASK_FCVT_D_LU 0xfff0007f
+#define MATCH_FMV_D_X 0xf2000053
+#define MASK_FMV_D_X 0xfff0707f
+#define MATCH_FADD_Q 0x6000053
+#define MASK_FADD_Q 0xfe00007f
+#define MATCH_FSUB_Q 0xe000053
+#define MASK_FSUB_Q 0xfe00007f
+#define MATCH_FMUL_Q 0x16000053
+#define MASK_FMUL_Q 0xfe00007f
+#define MATCH_FDIV_Q 0x1e000053
+#define MASK_FDIV_Q 0xfe00007f
+#define MATCH_FSGNJ_Q 0x26000053
+#define MASK_FSGNJ_Q 0xfe00707f
+#define MATCH_FSGNJN_Q 0x26001053
+#define MASK_FSGNJN_Q 0xfe00707f
+#define MATCH_FSGNJX_Q 0x26002053
+#define MASK_FSGNJX_Q 0xfe00707f
+#define MATCH_FMIN_Q 0x2e000053
+#define MASK_FMIN_Q 0xfe00707f
+#define MATCH_FMAX_Q 0x2e001053
+#define MASK_FMAX_Q 0xfe00707f
+#define MATCH_FCVT_S_Q 0x40300053
+#define MASK_FCVT_S_Q 0xfff0007f
+#define MATCH_FCVT_Q_S 0x46000053
+#define MASK_FCVT_Q_S 0xfff0007f
+#define MATCH_FCVT_D_Q 0x42300053
+#define MASK_FCVT_D_Q 0xfff0007f
+#define MATCH_FCVT_Q_D 0x46100053
+#define MASK_FCVT_Q_D 0xfff0007f
+#define MATCH_FSQRT_Q 0x5e000053
+#define MASK_FSQRT_Q 0xfff0007f
+#define MATCH_FLE_Q 0xa6000053
+#define MASK_FLE_Q 0xfe00707f
+#define MATCH_FLT_Q 0xa6001053
+#define MASK_FLT_Q 0xfe00707f
+#define MATCH_FEQ_Q 0xa6002053
+#define MASK_FEQ_Q 0xfe00707f
+#define MATCH_FCVT_W_Q 0xc6000053
+#define MASK_FCVT_W_Q 0xfff0007f
+#define MATCH_FCVT_WU_Q 0xc6100053
+#define MASK_FCVT_WU_Q 0xfff0007f
+#define MATCH_FCLASS_Q 0xe6001053
+#define MASK_FCLASS_Q 0xfff0707f
+#define MATCH_FCVT_Q_W 0xd6000053
+#define MASK_FCVT_Q_W 0xfff0007f
+#define MATCH_FCVT_Q_WU 0xd6100053
+#define MASK_FCVT_Q_WU 0xfff0007f
+#define MATCH_FLQ 0x4007
+#define MASK_FLQ 0x707f
+#define MATCH_FSQ 0x4027
+#define MASK_FSQ 0x707f
+#define MATCH_FMADD_Q 0x6000043
+#define MASK_FMADD_Q 0x600007f
+#define MATCH_FMSUB_Q 0x6000047
+#define MASK_FMSUB_Q 0x600007f
+#define MATCH_FNMSUB_Q 0x600004b
+#define MASK_FNMSUB_Q 0x600007f
+#define MATCH_FNMADD_Q 0x600004f
+#define MASK_FNMADD_Q 0x600007f
+#define MATCH_FCVT_L_Q 0xc6200053
+#define MASK_FCVT_L_Q 0xfff0007f
+#define MATCH_FCVT_LU_Q 0xc6300053
+#define MASK_FCVT_LU_Q 0xfff0007f
+#define MATCH_FCVT_Q_L 0xd6200053
+#define MASK_FCVT_Q_L 0xfff0007f
+#define MATCH_FCVT_Q_LU 0xd6300053
+#define MASK_FCVT_Q_LU 0xfff0007f
+#define MATCH_FMV_X_Q 0xe6000053
+#define MASK_FMV_X_Q 0xfff0707f
+#define MATCH_FMV_Q_X 0xf6000053
+#define MASK_FMV_Q_X 0xfff0707f
+#define MATCH_ECALL 0x73
+#define MASK_ECALL 0xffffffff
+#define MATCH_EBREAK 0x100073
+#define MASK_EBREAK 0xffffffff
+#define MATCH_URET 0x200073
+#define MASK_URET 0xffffffff
+#define MATCH_SRET 0x10200073
+#define MASK_SRET 0xffffffff
+#define MATCH_MRET 0x30200073
+#define MASK_MRET 0xffffffff
+#define MATCH_DRET 0x7b200073
+#define MASK_DRET 0xffffffff
+#define MATCH_SFENCE_VMA 0x12000073
+#define MASK_SFENCE_VMA 0xfe007fff
+#define MATCH_WFI 0x10500073
+#define MASK_WFI 0xffffffff
+#define MATCH_CSRRW 0x1073
+#define MASK_CSRRW 0x707f
+#define MATCH_CSRRS 0x2073
+#define MASK_CSRRS 0x707f
+#define MATCH_CSRRC 0x3073
+#define MASK_CSRRC 0x707f
+#define MATCH_CSRRWI 0x5073
+#define MASK_CSRRWI 0x707f
+#define MATCH_CSRRSI 0x6073
+#define MASK_CSRRSI 0x707f
+#define MATCH_CSRRCI 0x7073
+#define MASK_CSRRCI 0x707f
+#define MATCH_HFENCE_VVMA 0x22000073
+#define MASK_HFENCE_VVMA 0xfe007fff
+#define MATCH_HFENCE_GVMA 0x62000073
+#define MASK_HFENCE_GVMA 0xfe007fff
+#define MATCH_C_NOP 0x1
+#define MASK_C_NOP 0xffff
+#define MATCH_C_ADDI16SP 0x6101
+#define MASK_C_ADDI16SP 0xef83
+#define MATCH_C_JR 0x8002
+#define MASK_C_JR 0xf07f
+#define MATCH_C_JALR 0x9002
+#define MASK_C_JALR 0xf07f
+#define MATCH_C_EBREAK 0x9002
+#define MASK_C_EBREAK 0xffff
+#define MATCH_C_ADDI4SPN 0x0
+#define MASK_C_ADDI4SPN 0xe003
+#define MATCH_C_FLD 0x2000
+#define MASK_C_FLD 0xe003
+#define MATCH_C_LW 0x4000
+#define MASK_C_LW 0xe003
+#define MATCH_C_FLW 0x6000
+#define MASK_C_FLW 0xe003
+#define MATCH_C_FSD 0xa000
+#define MASK_C_FSD 0xe003
+#define MATCH_C_SW 0xc000
+#define MASK_C_SW 0xe003
+#define MATCH_C_FSW 0xe000
+#define MASK_C_FSW 0xe003
+#define MATCH_C_ADDI 0x1
+#define MASK_C_ADDI 0xe003
+#define MATCH_C_JAL 0x2001
+#define MASK_C_JAL 0xe003
+#define MATCH_C_LI 0x4001
+#define MASK_C_LI 0xe003
+#define MATCH_C_LUI 0x6001
+#define MASK_C_LUI 0xe003
+#define MATCH_C_SRLI 0x8001
+#define MASK_C_SRLI 0xec03
+#define MATCH_C_SRAI 0x8401
+#define MASK_C_SRAI 0xec03
+#define MATCH_C_ANDI 0x8801
+#define MASK_C_ANDI 0xec03
+#define MATCH_C_SUB 0x8c01
+#define MASK_C_SUB 0xfc63
+#define MATCH_C_XOR 0x8c21
+#define MASK_C_XOR 0xfc63
+#define MATCH_C_OR 0x8c41
+#define MASK_C_OR 0xfc63
+#define MATCH_C_AND 0x8c61
+#define MASK_C_AND 0xfc63
+#define MATCH_C_J 0xa001
+#define MASK_C_J 0xe003
+#define MATCH_C_BEQZ 0xc001
+#define MASK_C_BEQZ 0xe003
+#define MATCH_C_BNEZ 0xe001
+#define MASK_C_BNEZ 0xe003
+#define MATCH_C_SLLI 0x2
+#define MASK_C_SLLI 0xe003
+#define MATCH_C_FLDSP 0x2002
+#define MASK_C_FLDSP 0xe003
+#define MATCH_C_LWSP 0x4002
+#define MASK_C_LWSP 0xe003
+#define MATCH_C_FLWSP 0x6002
+#define MASK_C_FLWSP 0xe003
+#define MATCH_C_MV 0x8002
+#define MASK_C_MV 0xf003
+#define MATCH_C_ADD 0x9002
+#define MASK_C_ADD 0xf003
+#define MATCH_C_FSDSP 0xa002
+#define MASK_C_FSDSP 0xe003
+#define MATCH_C_SWSP 0xc002
+#define MASK_C_SWSP 0xe003
+#define MATCH_C_FSWSP 0xe002
+#define MASK_C_FSWSP 0xe003
+#define MATCH_C_SRLI_RV32 0x8001
+#define MASK_C_SRLI_RV32 0xfc03
+#define MATCH_C_SRAI_RV32 0x8401
+#define MASK_C_SRAI_RV32 0xfc03
+#define MATCH_C_SLLI_RV32 0x2
+#define MASK_C_SLLI_RV32 0xf003
+#define MATCH_C_LD 0x6000
+#define MASK_C_LD 0xe003
+#define MATCH_C_SD 0xe000
+#define MASK_C_SD 0xe003
+#define MATCH_C_SUBW 0x9c01
+#define MASK_C_SUBW 0xfc63
+#define MATCH_C_ADDW 0x9c21
+#define MASK_C_ADDW 0xfc63
+#define MATCH_C_ADDIW 0x2001
+#define MASK_C_ADDIW 0xe003
+#define MATCH_C_LDSP 0x6002
+#define MASK_C_LDSP 0xe003
+#define MATCH_C_SDSP 0xe002
+#define MASK_C_SDSP 0xe003
+#define MATCH_C_LQ 0x2000
+#define MASK_C_LQ 0xe003
+#define MATCH_C_SQ 0xa000
+#define MASK_C_SQ 0xe003
+#define MATCH_C_LQSP 0x2002
+#define MASK_C_LQSP 0xe003
+#define MATCH_C_SQSP 0xa002
+#define MASK_C_SQSP 0xe003
+#define MATCH_CUSTOM0 0xb
+#define MASK_CUSTOM0 0x707f
+#define MATCH_CUSTOM0_RS1 0x200b
+#define MASK_CUSTOM0_RS1 0x707f
+#define MATCH_CUSTOM0_RS1_RS2 0x300b
+#define MASK_CUSTOM0_RS1_RS2 0x707f
+#define MATCH_CUSTOM0_RD 0x400b
+#define MASK_CUSTOM0_RD 0x707f
+#define MATCH_CUSTOM0_RD_RS1 0x600b
+#define MASK_CUSTOM0_RD_RS1 0x707f
+#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b
+#define MASK_CUSTOM0_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM1 0x2b
+#define MASK_CUSTOM1 0x707f
+#define MATCH_CUSTOM1_RS1 0x202b
+#define MASK_CUSTOM1_RS1 0x707f
+#define MATCH_CUSTOM1_RS1_RS2 0x302b
+#define MASK_CUSTOM1_RS1_RS2 0x707f
+#define MATCH_CUSTOM1_RD 0x402b
+#define MASK_CUSTOM1_RD 0x707f
+#define MATCH_CUSTOM1_RD_RS1 0x602b
+#define MASK_CUSTOM1_RD_RS1 0x707f
+#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b
+#define MASK_CUSTOM1_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM2 0x5b
+#define MASK_CUSTOM2 0x707f
+#define MATCH_CUSTOM2_RS1 0x205b
+#define MASK_CUSTOM2_RS1 0x707f
+#define MATCH_CUSTOM2_RS1_RS2 0x305b
+#define MASK_CUSTOM2_RS1_RS2 0x707f
+#define MATCH_CUSTOM2_RD 0x405b
+#define MASK_CUSTOM2_RD 0x707f
+#define MATCH_CUSTOM2_RD_RS1 0x605b
+#define MASK_CUSTOM2_RD_RS1 0x707f
+#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b
+#define MASK_CUSTOM2_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM3 0x7b
+#define MASK_CUSTOM3 0x707f
+#define MATCH_CUSTOM3_RS1 0x207b
+#define MASK_CUSTOM3_RS1 0x707f
+#define MATCH_CUSTOM3_RS1_RS2 0x307b
+#define MASK_CUSTOM3_RS1_RS2 0x707f
+#define MATCH_CUSTOM3_RD 0x407b
+#define MASK_CUSTOM3_RD 0x707f
+#define MATCH_CUSTOM3_RD_RS1 0x607b
+#define MASK_CUSTOM3_RD_RS1 0x707f
+#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b
+#define MASK_CUSTOM3_RD_RS1_RS2 0x707f
+#define MATCH_VSETVLI 0x7057
+#define MASK_VSETVLI 0x8000707f
+#define MATCH_VSETVL 0x80007057
+#define MASK_VSETVL 0xfe00707f
+#define MATCH_VLB_V 0x10000007
+#define MASK_VLB_V 0x1df0707f
+#define MATCH_VLH_V 0x10005007
+#define MASK_VLH_V 0x1df0707f
+#define MATCH_VLW_V 0x10006007
+#define MASK_VLW_V 0x1df0707f
+#define MATCH_VLE_V 0x7007
+#define MASK_VLE_V 0x1df0707f
+#define MATCH_VLBU_V 0x7
+#define MASK_VLBU_V 0x1df0707f
+#define MATCH_VLHU_V 0x5007
+#define MASK_VLHU_V 0x1df0707f
+#define MATCH_VLWU_V 0x6007
+#define MASK_VLWU_V 0x1df0707f
+#define MATCH_VSB_V 0x27
+#define MASK_VSB_V 0x1df0707f
+#define MATCH_VSH_V 0x5027
+#define MASK_VSH_V 0x1df0707f
+#define MATCH_VSW_V 0x6027
+#define MASK_VSW_V 0x1df0707f
+#define MATCH_VSE_V 0x7027
+#define MASK_VSE_V 0x1df0707f
+#define MATCH_VLSB_V 0x18000007
+#define MASK_VLSB_V 0x1c00707f
+#define MATCH_VLSH_V 0x18005007
+#define MASK_VLSH_V 0x1c00707f
+#define MATCH_VLSW_V 0x18006007
+#define MASK_VLSW_V 0x1c00707f
+#define MATCH_VLSE_V 0x8007007
+#define MASK_VLSE_V 0x1c00707f
+#define MATCH_VLSBU_V 0x8000007
+#define MASK_VLSBU_V 0x1c00707f
+#define MATCH_VLSHU_V 0x8005007
+#define MASK_VLSHU_V 0x1c00707f
+#define MATCH_VLSWU_V 0x8006007
+#define MASK_VLSWU_V 0x1c00707f
+#define MATCH_VSSB_V 0x8000027
+#define MASK_VSSB_V 0x1c00707f
+#define MATCH_VSSH_V 0x8005027
+#define MASK_VSSH_V 0x1c00707f
+#define MATCH_VSSW_V 0x8006027
+#define MASK_VSSW_V 0x1c00707f
+#define MATCH_VSSE_V 0x8007027
+#define MASK_VSSE_V 0x1c00707f
+#define MATCH_VLXB_V 0x1c000007
+#define MASK_VLXB_V 0x1c00707f
+#define MATCH_VLXH_V 0x1c005007
+#define MASK_VLXH_V 0x1c00707f
+#define MATCH_VLXW_V 0x1c006007
+#define MASK_VLXW_V 0x1c00707f
+#define MATCH_VLXE_V 0xc007007
+#define MASK_VLXE_V 0x1c00707f
+#define MATCH_VLXBU_V 0xc000007
+#define MASK_VLXBU_V 0x1c00707f
+#define MATCH_VLXHU_V 0xc005007
+#define MASK_VLXHU_V 0x1c00707f
+#define MATCH_VLXWU_V 0xc006007
+#define MASK_VLXWU_V 0x1c00707f
+#define MATCH_VSXB_V 0xc000027
+#define MASK_VSXB_V 0x1c00707f
+#define MATCH_VSXH_V 0xc005027
+#define MASK_VSXH_V 0x1c00707f
+#define MATCH_VSXW_V 0xc006027
+#define MASK_VSXW_V 0x1c00707f
+#define MATCH_VSXE_V 0xc007027
+#define MASK_VSXE_V 0x1c00707f
+#define MATCH_VSUXB_V 0x1c000027
+#define MASK_VSUXB_V 0xfc00707f
+#define MATCH_VSUXH_V 0x1c005027
+#define MASK_VSUXH_V 0xfc00707f
+#define MATCH_VSUXW_V 0x1c006027
+#define MASK_VSUXW_V 0xfc00707f
+#define MATCH_VSUXE_V 0x1c007027
+#define MASK_VSUXE_V 0xfc00707f
+#define MATCH_VLBFF_V 0x11000007
+#define MASK_VLBFF_V 0x1df0707f
+#define MATCH_VLHFF_V 0x11005007
+#define MASK_VLHFF_V 0x1df0707f
+#define MATCH_VLWFF_V 0x11006007
+#define MASK_VLWFF_V 0x1df0707f
+#define MATCH_VLEFF_V 0x1007007
+#define MASK_VLEFF_V 0x1df0707f
+#define MATCH_VLBUFF_V 0x1000007
+#define MASK_VLBUFF_V 0x1df0707f
+#define MATCH_VLHUFF_V 0x1005007
+#define MASK_VLHUFF_V 0x1df0707f
+#define MATCH_VLWUFF_V 0x1006007
+#define MASK_VLWUFF_V 0x1df0707f
+#define MATCH_VL1R_V 0x2807007
+#define MASK_VL1R_V 0xfff0707f
+#define MATCH_VS1R_V 0x2807027
+#define MASK_VS1R_V 0xfff0707f
+#define MATCH_VFADD_VF 0x5057
+#define MASK_VFADD_VF 0xfc00707f
+#define MATCH_VFSUB_VF 0x8005057
+#define MASK_VFSUB_VF 0xfc00707f
+#define MATCH_VFMIN_VF 0x10005057
+#define MASK_VFMIN_VF 0xfc00707f
+#define MATCH_VFMAX_VF 0x18005057
+#define MASK_VFMAX_VF 0xfc00707f
+#define MATCH_VFSGNJ_VF 0x20005057
+#define MASK_VFSGNJ_VF 0xfc00707f
+#define MATCH_VFSGNJN_VF 0x24005057
+#define MASK_VFSGNJN_VF 0xfc00707f
+#define MATCH_VFSGNJX_VF 0x28005057
+#define MASK_VFSGNJX_VF 0xfc00707f
+#define MATCH_VFSLIDE1UP_VF 0x38005057
+#define MASK_VFSLIDE1UP_VF 0xfc00707f
+#define MATCH_VFSLIDE1DOWN_VF 0x3c005057
+#define MASK_VFSLIDE1DOWN_VF 0xfc00707f
+#define MATCH_VFMV_S_F 0x42005057
+#define MASK_VFMV_S_F 0xfff0707f
+#define MATCH_VFMERGE_VFM 0x5c005057
+#define MASK_VFMERGE_VFM 0xfe00707f
+#define MATCH_VFMV_V_F 0x5e005057
+#define MASK_VFMV_V_F 0xfff0707f
+#define MATCH_VMFEQ_VF 0x60005057
+#define MASK_VMFEQ_VF 0xfc00707f
+#define MATCH_VMFLE_VF 0x64005057
+#define MASK_VMFLE_VF 0xfc00707f
+#define MATCH_VMFLT_VF 0x6c005057
+#define MASK_VMFLT_VF 0xfc00707f
+#define MATCH_VMFNE_VF 0x70005057
+#define MASK_VMFNE_VF 0xfc00707f
+#define MATCH_VMFGT_VF 0x74005057
+#define MASK_VMFGT_VF 0xfc00707f
+#define MATCH_VMFGE_VF 0x7c005057
+#define MASK_VMFGE_VF 0xfc00707f
+#define MATCH_VFDIV_VF 0x80005057
+#define MASK_VFDIV_VF 0xfc00707f
+#define MATCH_VFRDIV_VF 0x84005057
+#define MASK_VFRDIV_VF 0xfc00707f
+#define MATCH_VFMUL_VF 0x90005057
+#define MASK_VFMUL_VF 0xfc00707f
+#define MATCH_VFRSUB_VF 0x9c005057
+#define MASK_VFRSUB_VF 0xfc00707f
+#define MATCH_VFMADD_VF 0xa0005057
+#define MASK_VFMADD_VF 0xfc00707f
+#define MATCH_VFNMADD_VF 0xa4005057
+#define MASK_VFNMADD_VF 0xfc00707f
+#define MATCH_VFMSUB_VF 0xa8005057
+#define MASK_VFMSUB_VF 0xfc00707f
+#define MATCH_VFNMSUB_VF 0xac005057
+#define MASK_VFNMSUB_VF 0xfc00707f
+#define MATCH_VFMACC_VF 0xb0005057
+#define MASK_VFMACC_VF 0xfc00707f
+#define MATCH_VFNMACC_VF 0xb4005057
+#define MASK_VFNMACC_VF 0xfc00707f
+#define MATCH_VFMSAC_VF 0xb8005057
+#define MASK_VFMSAC_VF 0xfc00707f
+#define MATCH_VFNMSAC_VF 0xbc005057
+#define MASK_VFNMSAC_VF 0xfc00707f
+#define MATCH_VFWADD_VF 0xc0005057
+#define MASK_VFWADD_VF 0xfc00707f
+#define MATCH_VFWSUB_VF 0xc8005057
+#define MASK_VFWSUB_VF 0xfc00707f
+#define MATCH_VFWADD_WF 0xd0005057
+#define MASK_VFWADD_WF 0xfc00707f
+#define MATCH_VFWSUB_WF 0xd8005057
+#define MASK_VFWSUB_WF 0xfc00707f
+#define MATCH_VFWMUL_VF 0xe0005057
+#define MASK_VFWMUL_VF 0xfc00707f
+#define MATCH_VFWMACC_VF 0xf0005057
+#define MASK_VFWMACC_VF 0xfc00707f
+#define MATCH_VFWNMACC_VF 0xf4005057
+#define MASK_VFWNMACC_VF 0xfc00707f
+#define MATCH_VFWMSAC_VF 0xf8005057
+#define MASK_VFWMSAC_VF 0xfc00707f
+#define MATCH_VFWNMSAC_VF 0xfc005057
+#define MASK_VFWNMSAC_VF 0xfc00707f
+#define MATCH_VFADD_VV 0x1057
+#define MASK_VFADD_VV 0xfc00707f
+#define MATCH_VFREDSUM_VS 0x4001057
+#define MASK_VFREDSUM_VS 0xfc00707f
+#define MATCH_VFSUB_VV 0x8001057
+#define MASK_VFSUB_VV 0xfc00707f
+#define MATCH_VFREDOSUM_VS 0xc001057
+#define MASK_VFREDOSUM_VS 0xfc00707f
+#define MATCH_VFMIN_VV 0x10001057
+#define MASK_VFMIN_VV 0xfc00707f
+#define MATCH_VFREDMIN_VS 0x14001057
+#define MASK_VFREDMIN_VS 0xfc00707f
+#define MATCH_VFMAX_VV 0x18001057
+#define MASK_VFMAX_VV 0xfc00707f
+#define MATCH_VFREDMAX_VS 0x1c001057
+#define MASK_VFREDMAX_VS 0xfc00707f
+#define MATCH_VFSGNJ_VV 0x20001057
+#define MASK_VFSGNJ_VV 0xfc00707f
+#define MATCH_VFSGNJN_VV 0x24001057
+#define MASK_VFSGNJN_VV 0xfc00707f
+#define MATCH_VFSGNJX_VV 0x28001057
+#define MASK_VFSGNJX_VV 0xfc00707f
+#define MATCH_VFMV_F_S 0x42001057
+#define MASK_VFMV_F_S 0xfe0ff07f
+#define MATCH_VMFEQ_VV 0x60001057
+#define MASK_VMFEQ_VV 0xfc00707f
+#define MATCH_VMFLE_VV 0x64001057
+#define MASK_VMFLE_VV 0xfc00707f
+#define MATCH_VMFLT_VV 0x6c001057
+#define MASK_VMFLT_VV 0xfc00707f
+#define MATCH_VMFNE_VV 0x70001057
+#define MASK_VMFNE_VV 0xfc00707f
+#define MATCH_VFDIV_VV 0x80001057
+#define MASK_VFDIV_VV 0xfc00707f
+#define MATCH_VFMUL_VV 0x90001057
+#define MASK_VFMUL_VV 0xfc00707f
+#define MATCH_VFMADD_VV 0xa0001057
+#define MASK_VFMADD_VV 0xfc00707f
+#define MATCH_VFNMADD_VV 0xa4001057
+#define MASK_VFNMADD_VV 0xfc00707f
+#define MATCH_VFMSUB_VV 0xa8001057
+#define MASK_VFMSUB_VV 0xfc00707f
+#define MATCH_VFNMSUB_VV 0xac001057
+#define MASK_VFNMSUB_VV 0xfc00707f
+#define MATCH_VFMACC_VV 0xb0001057
+#define MASK_VFMACC_VV 0xfc00707f
+#define MATCH_VFNMACC_VV 0xb4001057
+#define MASK_VFNMACC_VV 0xfc00707f
+#define MATCH_VFMSAC_VV 0xb8001057
+#define MASK_VFMSAC_VV 0xfc00707f
+#define MATCH_VFNMSAC_VV 0xbc001057
+#define MASK_VFNMSAC_VV 0xfc00707f
+#define MATCH_VFCVT_XU_F_V 0x88001057
+#define MASK_VFCVT_XU_F_V 0xfc0ff07f
+#define MATCH_VFCVT_X_F_V 0x88009057
+#define MASK_VFCVT_X_F_V 0xfc0ff07f
+#define MATCH_VFCVT_F_XU_V 0x88011057
+#define MASK_VFCVT_F_XU_V 0xfc0ff07f
+#define MATCH_VFCVT_F_X_V 0x88019057
+#define MASK_VFCVT_F_X_V 0xfc0ff07f
+#define MATCH_VFCVT_RTZ_XU_F_V 0x88031057
+#define MASK_VFCVT_RTZ_XU_F_V 0xfc0ff07f
+#define MATCH_VFCVT_RTZ_X_F_V 0x88039057
+#define MASK_VFCVT_RTZ_X_F_V 0xfc0ff07f
+#define MATCH_VFWCVT_XU_F_V 0x88041057
+#define MASK_VFWCVT_XU_F_V 0xfc0ff07f
+#define MATCH_VFWCVT_X_F_V 0x88049057
+#define MASK_VFWCVT_X_F_V 0xfc0ff07f
+#define MATCH_VFWCVT_F_XU_V 0x88051057
+#define MASK_VFWCVT_F_XU_V 0xfc0ff07f
+#define MATCH_VFWCVT_F_X_V 0x88059057
+#define MASK_VFWCVT_F_X_V 0xfc0ff07f
+#define MATCH_VFWCVT_F_F_V 0x88061057
+#define MASK_VFWCVT_F_F_V 0xfc0ff07f
+#define MATCH_VFWCVT_RTZ_XU_F_V 0x88071057
+#define MASK_VFWCVT_RTZ_XU_F_V 0xfc0ff07f
+#define MATCH_VFWCVT_RTZ_X_F_V 0x88079057
+#define MASK_VFWCVT_RTZ_X_F_V 0xfc0ff07f
+#define MATCH_VFNCVT_XU_F_W 0x88081057
+#define MASK_VFNCVT_XU_F_W 0xfc0ff07f
+#define MATCH_VFNCVT_X_F_W 0x88089057
+#define MASK_VFNCVT_X_F_W 0xfc0ff07f
+#define MATCH_VFNCVT_F_XU_W 0x88091057
+#define MASK_VFNCVT_F_XU_W 0xfc0ff07f
+#define MATCH_VFNCVT_F_X_W 0x88099057
+#define MASK_VFNCVT_F_X_W 0xfc0ff07f
+#define MATCH_VFNCVT_F_F_W 0x880a1057
+#define MASK_VFNCVT_F_F_W 0xfc0ff07f
+#define MATCH_VFNCVT_ROD_F_F_W 0x880a9057
+#define MASK_VFNCVT_ROD_F_F_W 0xfc0ff07f
+#define MATCH_VFNCVT_RTZ_XU_F_W 0x880b1057
+#define MASK_VFNCVT_RTZ_XU_F_W 0xfc0ff07f
+#define MATCH_VFNCVT_RTZ_X_F_W 0x880b9057
+#define MASK_VFNCVT_RTZ_X_F_W 0xfc0ff07f
+#define MATCH_VFSQRT_V 0x8c001057
+#define MASK_VFSQRT_V 0xfc0ff07f
+#define MATCH_VFCLASS_V 0x8c081057
+#define MASK_VFCLASS_V 0xfc0ff07f
+#define MATCH_VFWADD_VV 0xc0001057
+#define MASK_VFWADD_VV 0xfc00707f
+#define MATCH_VFWREDSUM_VS 0xc4001057
+#define MASK_VFWREDSUM_VS 0xfc00707f
+#define MATCH_VFWSUB_VV 0xc8001057
+#define MASK_VFWSUB_VV 0xfc00707f
+#define MATCH_VFWREDOSUM_VS 0xcc001057
+#define MASK_VFWREDOSUM_VS 0xfc00707f
+#define MATCH_VFWADD_WV 0xd0001057
+#define MASK_VFWADD_WV 0xfc00707f
+#define MATCH_VFWSUB_WV 0xd8001057
+#define MASK_VFWSUB_WV 0xfc00707f
+#define MATCH_VFWMUL_VV 0xe0001057
+#define MASK_VFWMUL_VV 0xfc00707f
+#define MATCH_VFDOT_VV 0xe4001057
+#define MASK_VFDOT_VV 0xfc00707f
+#define MATCH_VFWMACC_VV 0xf0001057
+#define MASK_VFWMACC_VV 0xfc00707f
+#define MATCH_VFWNMACC_VV 0xf4001057
+#define MASK_VFWNMACC_VV 0xfc00707f
+#define MATCH_VFWMSAC_VV 0xf8001057
+#define MASK_VFWMSAC_VV 0xfc00707f
+#define MATCH_VFWNMSAC_VV 0xfc001057
+#define MASK_VFWNMSAC_VV 0xfc00707f
+#define MATCH_VADD_VX 0x4057
+#define MASK_VADD_VX 0xfc00707f
+#define MATCH_VSUB_VX 0x8004057
+#define MASK_VSUB_VX 0xfc00707f
+#define MATCH_VRSUB_VX 0xc004057
+#define MASK_VRSUB_VX 0xfc00707f
+#define MATCH_VMINU_VX 0x10004057
+#define MASK_VMINU_VX 0xfc00707f
+#define MATCH_VMIN_VX 0x14004057
+#define MASK_VMIN_VX 0xfc00707f
+#define MATCH_VMAXU_VX 0x18004057
+#define MASK_VMAXU_VX 0xfc00707f
+#define MATCH_VMAX_VX 0x1c004057
+#define MASK_VMAX_VX 0xfc00707f
+#define MATCH_VAND_VX 0x24004057
+#define MASK_VAND_VX 0xfc00707f
+#define MATCH_VOR_VX 0x28004057
+#define MASK_VOR_VX 0xfc00707f
+#define MATCH_VXOR_VX 0x2c004057
+#define MASK_VXOR_VX 0xfc00707f
+#define MATCH_VRGATHER_VX 0x30004057
+#define MASK_VRGATHER_VX 0xfc00707f
+#define MATCH_VSLIDEUP_VX 0x38004057
+#define MASK_VSLIDEUP_VX 0xfc00707f
+#define MATCH_VSLIDEDOWN_VX 0x3c004057
+#define MASK_VSLIDEDOWN_VX 0xfc00707f
+#define MATCH_VADC_VXM 0x40004057
+#define MASK_VADC_VXM 0xfe00707f
+#define MATCH_VMADC_VXM 0x44004057
+#define MASK_VMADC_VXM 0xfc00707f
+#define MATCH_VSBC_VXM 0x48004057
+#define MASK_VSBC_VXM 0xfe00707f
+#define MATCH_VMSBC_VXM 0x4c004057
+#define MASK_VMSBC_VXM 0xfc00707f
+#define MATCH_VMERGE_VXM 0x5c004057
+#define MASK_VMERGE_VXM 0xfe00707f
+#define MATCH_VMV_V_X 0x5e004057
+#define MASK_VMV_V_X 0xfff0707f
+#define MATCH_VMSEQ_VX 0x60004057
+#define MASK_VMSEQ_VX 0xfc00707f
+#define MATCH_VMSNE_VX 0x64004057
+#define MASK_VMSNE_VX 0xfc00707f
+#define MATCH_VMSLTU_VX 0x68004057
+#define MASK_VMSLTU_VX 0xfc00707f
+#define MATCH_VMSLT_VX 0x6c004057
+#define MASK_VMSLT_VX 0xfc00707f
+#define MATCH_VMSLEU_VX 0x70004057
+#define MASK_VMSLEU_VX 0xfc00707f
+#define MATCH_VMSLE_VX 0x74004057
+#define MASK_VMSLE_VX 0xfc00707f
+#define MATCH_VMSGTU_VX 0x78004057
+#define MASK_VMSGTU_VX 0xfc00707f
+#define MATCH_VMSGT_VX 0x7c004057
+#define MASK_VMSGT_VX 0xfc00707f
+#define MATCH_VSADDU_VX 0x80004057
+#define MASK_VSADDU_VX 0xfc00707f
+#define MATCH_VSADD_VX 0x84004057
+#define MASK_VSADD_VX 0xfc00707f
+#define MATCH_VSSUBU_VX 0x88004057
+#define MASK_VSSUBU_VX 0xfc00707f
+#define MATCH_VSSUB_VX 0x8c004057
+#define MASK_VSSUB_VX 0xfc00707f
+#define MATCH_VSLL_VX 0x94004057
+#define MASK_VSLL_VX 0xfc00707f
+#define MATCH_VSMUL_VX 0x9c004057
+#define MASK_VSMUL_VX 0xfc00707f
+#define MATCH_VSRL_VX 0xa0004057
+#define MASK_VSRL_VX 0xfc00707f
+#define MATCH_VSRA_VX 0xa4004057
+#define MASK_VSRA_VX 0xfc00707f
+#define MATCH_VSSRL_VX 0xa8004057
+#define MASK_VSSRL_VX 0xfc00707f
+#define MATCH_VSSRA_VX 0xac004057
+#define MASK_VSSRA_VX 0xfc00707f
+#define MATCH_VNSRL_WX 0xb0004057
+#define MASK_VNSRL_WX 0xfc00707f
+#define MATCH_VNSRA_WX 0xb4004057
+#define MASK_VNSRA_WX 0xfc00707f
+#define MATCH_VNCLIPU_WX 0xb8004057
+#define MASK_VNCLIPU_WX 0xfc00707f
+#define MATCH_VNCLIP_WX 0xbc004057
+#define MASK_VNCLIP_WX 0xfc00707f
+#define MATCH_VQMACCU_VX 0xf0004057
+#define MASK_VQMACCU_VX 0xfc00707f
+#define MATCH_VQMACC_VX 0xf4004057
+#define MASK_VQMACC_VX 0xfc00707f
+#define MATCH_VQMACCUS_VX 0xf8004057
+#define MASK_VQMACCUS_VX 0xfc00707f
+#define MATCH_VQMACCSU_VX 0xfc004057
+#define MASK_VQMACCSU_VX 0xfc00707f
+#define MATCH_VADD_VV 0x57
+#define MASK_VADD_VV 0xfc00707f
+#define MATCH_VSUB_VV 0x8000057
+#define MASK_VSUB_VV 0xfc00707f
+#define MATCH_VMINU_VV 0x10000057
+#define MASK_VMINU_VV 0xfc00707f
+#define MATCH_VMIN_VV 0x14000057
+#define MASK_VMIN_VV 0xfc00707f
+#define MATCH_VMAXU_VV 0x18000057
+#define MASK_VMAXU_VV 0xfc00707f
+#define MATCH_VMAX_VV 0x1c000057
+#define MASK_VMAX_VV 0xfc00707f
+#define MATCH_VAND_VV 0x24000057
+#define MASK_VAND_VV 0xfc00707f
+#define MATCH_VOR_VV 0x28000057
+#define MASK_VOR_VV 0xfc00707f
+#define MATCH_VXOR_VV 0x2c000057
+#define MASK_VXOR_VV 0xfc00707f
+#define MATCH_VRGATHER_VV 0x30000057
+#define MASK_VRGATHER_VV 0xfc00707f
+#define MATCH_VADC_VVM 0x40000057
+#define MASK_VADC_VVM 0xfe00707f
+#define MATCH_VMADC_VVM 0x44000057
+#define MASK_VMADC_VVM 0xfc00707f
+#define MATCH_VSBC_VVM 0x48000057
+#define MASK_VSBC_VVM 0xfe00707f
+#define MATCH_VMSBC_VVM 0x4c000057
+#define MASK_VMSBC_VVM 0xfc00707f
+#define MATCH_VMERGE_VVM 0x5c000057
+#define MASK_VMERGE_VVM 0xfe00707f
+#define MATCH_VMV_V_V 0x5e000057
+#define MASK_VMV_V_V 0xfff0707f
+#define MATCH_VMSEQ_VV 0x60000057
+#define MASK_VMSEQ_VV 0xfc00707f
+#define MATCH_VMSNE_VV 0x64000057
+#define MASK_VMSNE_VV 0xfc00707f
+#define MATCH_VMSLTU_VV 0x68000057
+#define MASK_VMSLTU_VV 0xfc00707f
+#define MATCH_VMSLT_VV 0x6c000057
+#define MASK_VMSLT_VV 0xfc00707f
+#define MATCH_VMSLEU_VV 0x70000057
+#define MASK_VMSLEU_VV 0xfc00707f
+#define MATCH_VMSLE_VV 0x74000057
+#define MASK_VMSLE_VV 0xfc00707f
+#define MATCH_VSADDU_VV 0x80000057
+#define MASK_VSADDU_VV 0xfc00707f
+#define MATCH_VSADD_VV 0x84000057
+#define MASK_VSADD_VV 0xfc00707f
+#define MATCH_VSSUBU_VV 0x88000057
+#define MASK_VSSUBU_VV 0xfc00707f
+#define MATCH_VSSUB_VV 0x8c000057
+#define MASK_VSSUB_VV 0xfc00707f
+#define MATCH_VSLL_VV 0x94000057
+#define MASK_VSLL_VV 0xfc00707f
+#define MATCH_VSMUL_VV 0x9c000057
+#define MASK_VSMUL_VV 0xfc00707f
+#define MATCH_VSRL_VV 0xa0000057
+#define MASK_VSRL_VV 0xfc00707f
+#define MATCH_VSRA_VV 0xa4000057
+#define MASK_VSRA_VV 0xfc00707f
+#define MATCH_VSSRL_VV 0xa8000057
+#define MASK_VSSRL_VV 0xfc00707f
+#define MATCH_VSSRA_VV 0xac000057
+#define MASK_VSSRA_VV 0xfc00707f
+#define MATCH_VNSRL_WV 0xb0000057
+#define MASK_VNSRL_WV 0xfc00707f
+#define MATCH_VNSRA_WV 0xb4000057
+#define MASK_VNSRA_WV 0xfc00707f
+#define MATCH_VNCLIPU_WV 0xb8000057
+#define MASK_VNCLIPU_WV 0xfc00707f
+#define MATCH_VNCLIP_WV 0xbc000057
+#define MASK_VNCLIP_WV 0xfc00707f
+#define MATCH_VWREDSUMU_VS 0xc0000057
+#define MASK_VWREDSUMU_VS 0xfc00707f
+#define MATCH_VWREDSUM_VS 0xc4000057
+#define MASK_VWREDSUM_VS 0xfc00707f
+#define MATCH_VDOTU_VV 0xe0000057
+#define MASK_VDOTU_VV 0xfc00707f
+#define MATCH_VDOT_VV 0xe4000057
+#define MASK_VDOT_VV 0xfc00707f
+#define MATCH_VQMACCU_VV 0xf0000057
+#define MASK_VQMACCU_VV 0xfc00707f
+#define MATCH_VQMACC_VV 0xf4000057
+#define MASK_VQMACC_VV 0xfc00707f
+#define MATCH_VQMACCSU_VV 0xfc000057
+#define MASK_VQMACCSU_VV 0xfc00707f
+#define MATCH_VADD_VI 0x3057
+#define MASK_VADD_VI 0xfc00707f
+#define MATCH_VRSUB_VI 0xc003057
+#define MASK_VRSUB_VI 0xfc00707f
+#define MATCH_VAND_VI 0x24003057
+#define MASK_VAND_VI 0xfc00707f
+#define MATCH_VOR_VI 0x28003057
+#define MASK_VOR_VI 0xfc00707f
+#define MATCH_VXOR_VI 0x2c003057
+#define MASK_VXOR_VI 0xfc00707f
+#define MATCH_VRGATHER_VI 0x30003057
+#define MASK_VRGATHER_VI 0xfc00707f
+#define MATCH_VSLIDEUP_VI 0x38003057
+#define MASK_VSLIDEUP_VI 0xfc00707f
+#define MATCH_VSLIDEDOWN_VI 0x3c003057
+#define MASK_VSLIDEDOWN_VI 0xfc00707f
+#define MATCH_VADC_VIM 0x40003057
+#define MASK_VADC_VIM 0xfe00707f
+#define MATCH_VMADC_VIM 0x44003057
+#define MASK_VMADC_VIM 0xfc00707f
+#define MATCH_VMERGE_VIM 0x5c003057
+#define MASK_VMERGE_VIM 0xfe00707f
+#define MATCH_VMV_V_I 0x5e003057
+#define MASK_VMV_V_I 0xfff0707f
+#define MATCH_VMSEQ_VI 0x60003057
+#define MASK_VMSEQ_VI 0xfc00707f
+#define MATCH_VMSNE_VI 0x64003057
+#define MASK_VMSNE_VI 0xfc00707f
+#define MATCH_VMSLEU_VI 0x70003057
+#define MASK_VMSLEU_VI 0xfc00707f
+#define MATCH_VMSLE_VI 0x74003057
+#define MASK_VMSLE_VI 0xfc00707f
+#define MATCH_VMSGTU_VI 0x78003057
+#define MASK_VMSGTU_VI 0xfc00707f
+#define MATCH_VMSGT_VI 0x7c003057
+#define MASK_VMSGT_VI 0xfc00707f
+#define MATCH_VSADDU_VI 0x80003057
+#define MASK_VSADDU_VI 0xfc00707f
+#define MATCH_VSADD_VI 0x84003057
+#define MASK_VSADD_VI 0xfc00707f
+#define MATCH_VSLL_VI 0x94003057
+#define MASK_VSLL_VI 0xfc00707f
+#define MATCH_VMV1R_V 0x9e003057
+#define MASK_VMV1R_V 0xfe0ff07f
+#define MATCH_VMV2R_V 0x9e00b057
+#define MASK_VMV2R_V 0xfe0ff07f
+#define MATCH_VMV4R_V 0x9e01b057
+#define MASK_VMV4R_V 0xfe0ff07f
+#define MATCH_VMV8R_V 0x9e03b057
+#define MASK_VMV8R_V 0xfe0ff07f
+#define MATCH_VSRL_VI 0xa0003057
+#define MASK_VSRL_VI 0xfc00707f
+#define MATCH_VSRA_VI 0xa4003057
+#define MASK_VSRA_VI 0xfc00707f
+#define MATCH_VSSRL_VI 0xa8003057
+#define MASK_VSSRL_VI 0xfc00707f
+#define MATCH_VSSRA_VI 0xac003057
+#define MASK_VSSRA_VI 0xfc00707f
+#define MATCH_VNSRL_WI 0xb0003057
+#define MASK_VNSRL_WI 0xfc00707f
+#define MATCH_VNSRA_WI 0xb4003057
+#define MASK_VNSRA_WI 0xfc00707f
+#define MATCH_VNCLIPU_WI 0xb8003057
+#define MASK_VNCLIPU_WI 0xfc00707f
+#define MATCH_VNCLIP_WI 0xbc003057
+#define MASK_VNCLIP_WI 0xfc00707f
+#define MATCH_VREDSUM_VS 0x2057
+#define MASK_VREDSUM_VS 0xfc00707f
+#define MATCH_VREDAND_VS 0x4002057
+#define MASK_VREDAND_VS 0xfc00707f
+#define MATCH_VREDOR_VS 0x8002057
+#define MASK_VREDOR_VS 0xfc00707f
+#define MATCH_VREDXOR_VS 0xc002057
+#define MASK_VREDXOR_VS 0xfc00707f
+#define MATCH_VREDMINU_VS 0x10002057
+#define MASK_VREDMINU_VS 0xfc00707f
+#define MATCH_VREDMIN_VS 0x14002057
+#define MASK_VREDMIN_VS 0xfc00707f
+#define MATCH_VREDMAXU_VS 0x18002057
+#define MASK_VREDMAXU_VS 0xfc00707f
+#define MATCH_VREDMAX_VS 0x1c002057
+#define MASK_VREDMAX_VS 0xfc00707f
+#define MATCH_VAADDU_VV 0x20002057
+#define MASK_VAADDU_VV 0xfc00707f
+#define MATCH_VAADD_VV 0x24002057
+#define MASK_VAADD_VV 0xfc00707f
+#define MATCH_VASUBU_VV 0x28002057
+#define MASK_VASUBU_VV 0xfc00707f
+#define MATCH_VASUB_VV 0x2c002057
+#define MASK_VASUB_VV 0xfc00707f
+#define MATCH_VMV_X_S 0x42002057
+#define MASK_VMV_X_S 0xfe0ff07f
+#define MATCH_VCOMPRESS_VM 0x5e002057
+#define MASK_VCOMPRESS_VM 0xfe00707f
+#define MATCH_VMANDNOT_MM 0x60002057
+#define MASK_VMANDNOT_MM 0xfc00707f
+#define MATCH_VMAND_MM 0x64002057
+#define MASK_VMAND_MM 0xfc00707f
+#define MATCH_VMOR_MM 0x68002057
+#define MASK_VMOR_MM 0xfc00707f
+#define MATCH_VMXOR_MM 0x6c002057
+#define MASK_VMXOR_MM 0xfc00707f
+#define MATCH_VMORNOT_MM 0x70002057
+#define MASK_VMORNOT_MM 0xfc00707f
+#define MATCH_VMNAND_MM 0x74002057
+#define MASK_VMNAND_MM 0xfc00707f
+#define MATCH_VMNOR_MM 0x78002057
+#define MASK_VMNOR_MM 0xfc00707f
+#define MATCH_VMXNOR_MM 0x7c002057
+#define MASK_VMXNOR_MM 0xfc00707f
+#define MATCH_VMSBF_M 0x5000a057
+#define MASK_VMSBF_M 0xfc0ff07f
+#define MATCH_VMSOF_M 0x50012057
+#define MASK_VMSOF_M 0xfc0ff07f
+#define MATCH_VMSIF_M 0x5001a057
+#define MASK_VMSIF_M 0xfc0ff07f
+#define MATCH_VIOTA_M 0x50082057
+#define MASK_VIOTA_M 0xfc0ff07f
+#define MATCH_VID_V 0x5008a057
+#define MASK_VID_V 0xfdfff07f
+#define MATCH_VPOPC_M 0x40082057
+#define MASK_VPOPC_M 0xfc0ff07f
+#define MATCH_VFIRST_M 0x4008a057
+#define MASK_VFIRST_M 0xfc0ff07f
+#define MATCH_VDIVU_VV 0x80002057
+#define MASK_VDIVU_VV 0xfc00707f
+#define MATCH_VDIV_VV 0x84002057
+#define MASK_VDIV_VV 0xfc00707f
+#define MATCH_VREMU_VV 0x88002057
+#define MASK_VREMU_VV 0xfc00707f
+#define MATCH_VREM_VV 0x8c002057
+#define MASK_VREM_VV 0xfc00707f
+#define MATCH_VMULHU_VV 0x90002057
+#define MASK_VMULHU_VV 0xfc00707f
+#define MATCH_VMUL_VV 0x94002057
+#define MASK_VMUL_VV 0xfc00707f
+#define MATCH_VMULHSU_VV 0x98002057
+#define MASK_VMULHSU_VV 0xfc00707f
+#define MATCH_VMULH_VV 0x9c002057
+#define MASK_VMULH_VV 0xfc00707f
+#define MATCH_VMADD_VV 0xa4002057
+#define MASK_VMADD_VV 0xfc00707f
+#define MATCH_VNMSUB_VV 0xac002057
+#define MASK_VNMSUB_VV 0xfc00707f
+#define MATCH_VMACC_VV 0xb4002057
+#define MASK_VMACC_VV 0xfc00707f
+#define MATCH_VNMSAC_VV 0xbc002057
+#define MASK_VNMSAC_VV 0xfc00707f
+#define MATCH_VWADDU_VV 0xc0002057
+#define MASK_VWADDU_VV 0xfc00707f
+#define MATCH_VWADD_VV 0xc4002057
+#define MASK_VWADD_VV 0xfc00707f
+#define MATCH_VWSUBU_VV 0xc8002057
+#define MASK_VWSUBU_VV 0xfc00707f
+#define MATCH_VWSUB_VV 0xcc002057
+#define MASK_VWSUB_VV 0xfc00707f
+#define MATCH_VWADDU_WV 0xd0002057
+#define MASK_VWADDU_WV 0xfc00707f
+#define MATCH_VWADD_WV 0xd4002057
+#define MASK_VWADD_WV 0xfc00707f
+#define MATCH_VWSUBU_WV 0xd8002057
+#define MASK_VWSUBU_WV 0xfc00707f
+#define MATCH_VWSUB_WV 0xdc002057
+#define MASK_VWSUB_WV 0xfc00707f
+#define MATCH_VWMULU_VV 0xe0002057
+#define MASK_VWMULU_VV 0xfc00707f
+#define MATCH_VWMULSU_VV 0xe8002057
+#define MASK_VWMULSU_VV 0xfc00707f
+#define MATCH_VWMUL_VV 0xec002057
+#define MASK_VWMUL_VV 0xfc00707f
+#define MATCH_VWMACCU_VV 0xf0002057
+#define MASK_VWMACCU_VV 0xfc00707f
+#define MATCH_VWMACC_VV 0xf4002057
+#define MASK_VWMACC_VV 0xfc00707f
+#define MATCH_VWMACCSU_VV 0xfc002057
+#define MASK_VWMACCSU_VV 0xfc00707f
+#define MATCH_VAADDU_VX 0x20006057
+#define MASK_VAADDU_VX 0xfc00707f
+#define MATCH_VAADD_VX 0x24006057
+#define MASK_VAADD_VX 0xfc00707f
+#define MATCH_VASUBU_VX 0x28006057
+#define MASK_VASUBU_VX 0xfc00707f
+#define MATCH_VASUB_VX 0x2c006057
+#define MASK_VASUB_VX 0xfc00707f
+#define MATCH_VMV_S_X 0x42006057
+#define MASK_VMV_S_X 0xfff0707f
+#define MATCH_VSLIDE1UP_VX 0x38006057
+#define MASK_VSLIDE1UP_VX 0xfc00707f
+#define MATCH_VSLIDE1DOWN_VX 0x3c006057
+#define MASK_VSLIDE1DOWN_VX 0xfc00707f
+#define MATCH_VDIVU_VX 0x80006057
+#define MASK_VDIVU_VX 0xfc00707f
+#define MATCH_VDIV_VX 0x84006057
+#define MASK_VDIV_VX 0xfc00707f
+#define MATCH_VREMU_VX 0x88006057
+#define MASK_VREMU_VX 0xfc00707f
+#define MATCH_VREM_VX 0x8c006057
+#define MASK_VREM_VX 0xfc00707f
+#define MATCH_VMULHU_VX 0x90006057
+#define MASK_VMULHU_VX 0xfc00707f
+#define MATCH_VMUL_VX 0x94006057
+#define MASK_VMUL_VX 0xfc00707f
+#define MATCH_VMULHSU_VX 0x98006057
+#define MASK_VMULHSU_VX 0xfc00707f
+#define MATCH_VMULH_VX 0x9c006057
+#define MASK_VMULH_VX 0xfc00707f
+#define MATCH_VMADD_VX 0xa4006057
+#define MASK_VMADD_VX 0xfc00707f
+#define MATCH_VNMSUB_VX 0xac006057
+#define MASK_VNMSUB_VX 0xfc00707f
+#define MATCH_VMACC_VX 0xb4006057
+#define MASK_VMACC_VX 0xfc00707f
+#define MATCH_VNMSAC_VX 0xbc006057
+#define MASK_VNMSAC_VX 0xfc00707f
+#define MATCH_VWADDU_VX 0xc0006057
+#define MASK_VWADDU_VX 0xfc00707f
+#define MATCH_VWADD_VX 0xc4006057
+#define MASK_VWADD_VX 0xfc00707f
+#define MATCH_VWSUBU_VX 0xc8006057
+#define MASK_VWSUBU_VX 0xfc00707f
+#define MATCH_VWSUB_VX 0xcc006057
+#define MASK_VWSUB_VX 0xfc00707f
+#define MATCH_VWADDU_WX 0xd0006057
+#define MASK_VWADDU_WX 0xfc00707f
+#define MATCH_VWADD_WX 0xd4006057
+#define MASK_VWADD_WX 0xfc00707f
+#define MATCH_VWSUBU_WX 0xd8006057
+#define MASK_VWSUBU_WX 0xfc00707f
+#define MATCH_VWSUB_WX 0xdc006057
+#define MASK_VWSUB_WX 0xfc00707f
+#define MATCH_VWMULU_VX 0xe0006057
+#define MASK_VWMULU_VX 0xfc00707f
+#define MATCH_VWMULSU_VX 0xe8006057
+#define MASK_VWMULSU_VX 0xfc00707f
+#define MATCH_VWMUL_VX 0xec006057
+#define MASK_VWMUL_VX 0xfc00707f
+#define MATCH_VWMACCU_VX 0xf0006057
+#define MASK_VWMACCU_VX 0xfc00707f
+#define MATCH_VWMACC_VX 0xf4006057
+#define MASK_VWMACC_VX 0xfc00707f
+#define MATCH_VWMACCUS_VX 0xf8006057
+#define MASK_VWMACCUS_VX 0xfc00707f
+#define MATCH_VWMACCSU_VX 0xfc006057
+#define MASK_VWMACCSU_VX 0xfc00707f
+#define MATCH_VAMOSWAPW_V 0x800602f
+#define MASK_VAMOSWAPW_V 0xf800707f
+#define MATCH_VAMOADDW_V 0x602f
+#define MASK_VAMOADDW_V 0xf800707f
+#define MATCH_VAMOXORW_V 0x2000602f
+#define MASK_VAMOXORW_V 0xf800707f
+#define MATCH_VAMOANDW_V 0x6000602f
+#define MASK_VAMOANDW_V 0xf800707f
+#define MATCH_VAMOORW_V 0x4000602f
+#define MASK_VAMOORW_V 0xf800707f
+#define MATCH_VAMOMINW_V 0x8000602f
+#define MASK_VAMOMINW_V 0xf800707f
+#define MATCH_VAMOMAXW_V 0xa000602f
+#define MASK_VAMOMAXW_V 0xf800707f
+#define MATCH_VAMOMINUW_V 0xc000602f
+#define MASK_VAMOMINUW_V 0xf800707f
+#define MATCH_VAMOMAXUW_V 0xe000602f
+#define MASK_VAMOMAXUW_V 0xf800707f
+#define MATCH_VAMOSWAPE_V 0x800702f
+#define MASK_VAMOSWAPE_V 0xf800707f
+#define MATCH_VAMOADDE_V 0x702f
+#define MASK_VAMOADDE_V 0xf800707f
+#define MATCH_VAMOXORE_V 0x2000702f
+#define MASK_VAMOXORE_V 0xf800707f
+#define MATCH_VAMOANDE_V 0x6000702f
+#define MASK_VAMOANDE_V 0xf800707f
+#define MATCH_VAMOORE_V 0x4000702f
+#define MASK_VAMOORE_V 0xf800707f
+#define MATCH_VAMOMINE_V 0x8000702f
+#define MASK_VAMOMINE_V 0xf800707f
+#define MATCH_VAMOMAXE_V 0xa000702f
+#define MASK_VAMOMAXE_V 0xf800707f
+#define MATCH_VAMOMINUE_V 0xc000702f
+#define MASK_VAMOMINUE_V 0xf800707f
+#define MATCH_VAMOMAXUE_V 0xe000702f
+#define MASK_VAMOMAXUE_V 0xf800707f
+#define MATCH_VMVNFR_V 0x9e003057
+#define MASK_VMVNFR_V 0xfe00707f
+#define CSR_FFLAGS 0x1
+#define CSR_FRM 0x2
+#define CSR_FCSR 0x3
+#define CSR_USTATUS 0x0
+#define CSR_UIE 0x4
+#define CSR_UTVEC 0x5
+#define CSR_VSTART 0x8
+#define CSR_VXSAT 0x9
+#define CSR_VXRM 0xa
+#define CSR_VCSR 0xf
+#define CSR_USCRATCH 0x40
+#define CSR_UEPC 0x41
+#define CSR_UCAUSE 0x42
+#define CSR_UTVAL 0x43
+#define CSR_UIP 0x44
+#define CSR_CYCLE 0xc00
+#define CSR_TIME 0xc01
+#define CSR_INSTRET 0xc02
+#define CSR_HPMCOUNTER3 0xc03
+#define CSR_HPMCOUNTER4 0xc04
+#define CSR_HPMCOUNTER5 0xc05
+#define CSR_HPMCOUNTER6 0xc06
+#define CSR_HPMCOUNTER7 0xc07
+#define CSR_HPMCOUNTER8 0xc08
+#define CSR_HPMCOUNTER9 0xc09
+#define CSR_HPMCOUNTER10 0xc0a
+#define CSR_HPMCOUNTER11 0xc0b
+#define CSR_HPMCOUNTER12 0xc0c
+#define CSR_HPMCOUNTER13 0xc0d
+#define CSR_HPMCOUNTER14 0xc0e
+#define CSR_HPMCOUNTER15 0xc0f
+#define CSR_HPMCOUNTER16 0xc10
+#define CSR_HPMCOUNTER17 0xc11
+#define CSR_HPMCOUNTER18 0xc12
+#define CSR_HPMCOUNTER19 0xc13
+#define CSR_HPMCOUNTER20 0xc14
+#define CSR_HPMCOUNTER21 0xc15
+#define CSR_HPMCOUNTER22 0xc16
+#define CSR_HPMCOUNTER23 0xc17
+#define CSR_HPMCOUNTER24 0xc18
+#define CSR_HPMCOUNTER25 0xc19
+#define CSR_HPMCOUNTER26 0xc1a
+#define CSR_HPMCOUNTER27 0xc1b
+#define CSR_HPMCOUNTER28 0xc1c
+#define CSR_HPMCOUNTER29 0xc1d
+#define CSR_HPMCOUNTER30 0xc1e
+#define CSR_HPMCOUNTER31 0xc1f
+#define CSR_VL 0xc20
+#define CSR_VTYPE 0xc21
+#define CSR_VLENB 0xc22
+#define CSR_SSTATUS 0x100
+#define CSR_SEDELEG 0x102
+#define CSR_SIDELEG 0x103
+#define CSR_SIE 0x104
+#define CSR_STVEC 0x105
+#define CSR_SCOUNTEREN 0x106
+#define CSR_SSCRATCH 0x140
+#define CSR_SEPC 0x141
+#define CSR_SCAUSE 0x142
+#define CSR_STVAL 0x143
+#define CSR_SIP 0x144
+#define CSR_SATP 0x180
+#define CSR_VSSTATUS 0x200
+#define CSR_VSIE 0x204
+#define CSR_VSTVEC 0x205
+#define CSR_VSSCRATCH 0x240
+#define CSR_VSEPC 0x241
+#define CSR_VSCAUSE 0x242
+#define CSR_VSTVAL 0x243
+#define CSR_VSIP 0x244
+#define CSR_VSATP 0x280
+#define CSR_HSTATUS 0x600
+#define CSR_HEDELEG 0x602
+#define CSR_HIDELEG 0x603
+#define CSR_HIE 0x604
+#define CSR_HTIMEDELTA 0x605
+#define CSR_HCOUNTEREN 0x606
+#define CSR_HGEIE 0x607
+#define CSR_HTVAL 0x643
+#define CSR_HIP 0x644
+#define CSR_HVIP 0x645
+#define CSR_HTINST 0x64a
+#define CSR_HGATP 0x680
+#define CSR_HGEIP 0xe12
+#define CSR_UTVT 0x7
+#define CSR_UNXTI 0x45
+#define CSR_UINTSTATUS 0x46
+#define CSR_USCRATCHCSW 0x48
+#define CSR_USCRATCHCSWL 0x49
+#define CSR_STVT 0x107
+#define CSR_SNXTI 0x145
+#define CSR_SINTSTATUS 0x146
+#define CSR_SSCRATCHCSW 0x148
+#define CSR_SSCRATCHCSWL 0x149
+#define CSR_MTVT 0x307
+#define CSR_MNXTI 0x345
+#define CSR_MINTSTATUS 0x346
+#define CSR_MSCRATCHCSW 0x348
+#define CSR_MSCRATCHCSWL 0x349
+#define CSR_MSTATUS 0x300
+#define CSR_MISA 0x301
+#define CSR_MEDELEG 0x302
+#define CSR_MIDELEG 0x303
+#define CSR_MIE 0x304
+#define CSR_MTVEC 0x305
+#define CSR_MCOUNTEREN 0x306
+#define CSR_MCOUNTINHIBIT 0x320
+#define CSR_MSCRATCH 0x340
+#define CSR_MEPC 0x341
+#define CSR_MCAUSE 0x342
+#define CSR_MTVAL 0x343
+#define CSR_MIP 0x344
+#define CSR_MTINST 0x34a
+#define CSR_MTVAL2 0x34b
+#define CSR_PMPCFG0 0x3a0
+#define CSR_PMPCFG1 0x3a1
+#define CSR_PMPCFG2 0x3a2
+#define CSR_PMPCFG3 0x3a3
+#define CSR_PMPADDR0 0x3b0
+#define CSR_PMPADDR1 0x3b1
+#define CSR_PMPADDR2 0x3b2
+#define CSR_PMPADDR3 0x3b3
+#define CSR_PMPADDR4 0x3b4
+#define CSR_PMPADDR5 0x3b5
+#define CSR_PMPADDR6 0x3b6
+#define CSR_PMPADDR7 0x3b7
+#define CSR_PMPADDR8 0x3b8
+#define CSR_PMPADDR9 0x3b9
+#define CSR_PMPADDR10 0x3ba
+#define CSR_PMPADDR11 0x3bb
+#define CSR_PMPADDR12 0x3bc
+#define CSR_PMPADDR13 0x3bd
+#define CSR_PMPADDR14 0x3be
+#define CSR_PMPADDR15 0x3bf
+#define CSR_TSELECT 0x7a0
+#define CSR_TDATA1 0x7a1
+#define CSR_TDATA2 0x7a2
+#define CSR_TDATA3 0x7a3
+#define CSR_DCSR 0x7b0
+#define CSR_DPC 0x7b1
+#define CSR_DSCRATCH0 0x7b2
+#define CSR_DSCRATCH1 0x7b3
+#define CSR_MCYCLE 0xb00
+#define CSR_MINSTRET 0xb02
+#define CSR_MHPMCOUNTER3 0xb03
+#define CSR_MHPMCOUNTER4 0xb04
+#define CSR_MHPMCOUNTER5 0xb05
+#define CSR_MHPMCOUNTER6 0xb06
+#define CSR_MHPMCOUNTER7 0xb07
+#define CSR_MHPMCOUNTER8 0xb08
+#define CSR_MHPMCOUNTER9 0xb09
+#define CSR_MHPMCOUNTER10 0xb0a
+#define CSR_MHPMCOUNTER11 0xb0b
+#define CSR_MHPMCOUNTER12 0xb0c
+#define CSR_MHPMCOUNTER13 0xb0d
+#define CSR_MHPMCOUNTER14 0xb0e
+#define CSR_MHPMCOUNTER15 0xb0f
+#define CSR_MHPMCOUNTER16 0xb10
+#define CSR_MHPMCOUNTER17 0xb11
+#define CSR_MHPMCOUNTER18 0xb12
+#define CSR_MHPMCOUNTER19 0xb13
+#define CSR_MHPMCOUNTER20 0xb14
+#define CSR_MHPMCOUNTER21 0xb15
+#define CSR_MHPMCOUNTER22 0xb16
+#define CSR_MHPMCOUNTER23 0xb17
+#define CSR_MHPMCOUNTER24 0xb18
+#define CSR_MHPMCOUNTER25 0xb19
+#define CSR_MHPMCOUNTER26 0xb1a
+#define CSR_MHPMCOUNTER27 0xb1b
+#define CSR_MHPMCOUNTER28 0xb1c
+#define CSR_MHPMCOUNTER29 0xb1d
+#define CSR_MHPMCOUNTER30 0xb1e
+#define CSR_MHPMCOUNTER31 0xb1f
+#define CSR_MHPMEVENT3 0x323
+#define CSR_MHPMEVENT4 0x324
+#define CSR_MHPMEVENT5 0x325
+#define CSR_MHPMEVENT6 0x326
+#define CSR_MHPMEVENT7 0x327
+#define CSR_MHPMEVENT8 0x328
+#define CSR_MHPMEVENT9 0x329
+#define CSR_MHPMEVENT10 0x32a
+#define CSR_MHPMEVENT11 0x32b
+#define CSR_MHPMEVENT12 0x32c
+#define CSR_MHPMEVENT13 0x32d
+#define CSR_MHPMEVENT14 0x32e
+#define CSR_MHPMEVENT15 0x32f
+#define CSR_MHPMEVENT16 0x330
+#define CSR_MHPMEVENT17 0x331
+#define CSR_MHPMEVENT18 0x332
+#define CSR_MHPMEVENT19 0x333
+#define CSR_MHPMEVENT20 0x334
+#define CSR_MHPMEVENT21 0x335
+#define CSR_MHPMEVENT22 0x336
+#define CSR_MHPMEVENT23 0x337
+#define CSR_MHPMEVENT24 0x338
+#define CSR_MHPMEVENT25 0x339
+#define CSR_MHPMEVENT26 0x33a
+#define CSR_MHPMEVENT27 0x33b
+#define CSR_MHPMEVENT28 0x33c
+#define CSR_MHPMEVENT29 0x33d
+#define CSR_MHPMEVENT30 0x33e
+#define CSR_MHPMEVENT31 0x33f
+#define CSR_MVENDORID 0xf11
+#define CSR_MARCHID 0xf12
+#define CSR_MIMPID 0xf13
+#define CSR_MHARTID 0xf14
+#define CSR_HTIMEDELTAH 0x615
+#define CSR_CYCLEH 0xc80
+#define CSR_TIMEH 0xc81
+#define CSR_INSTRETH 0xc82
+#define CSR_HPMCOUNTER3H 0xc83
+#define CSR_HPMCOUNTER4H 0xc84
+#define CSR_HPMCOUNTER5H 0xc85
+#define CSR_HPMCOUNTER6H 0xc86
+#define CSR_HPMCOUNTER7H 0xc87
+#define CSR_HPMCOUNTER8H 0xc88
+#define CSR_HPMCOUNTER9H 0xc89
+#define CSR_HPMCOUNTER10H 0xc8a
+#define CSR_HPMCOUNTER11H 0xc8b
+#define CSR_HPMCOUNTER12H 0xc8c
+#define CSR_HPMCOUNTER13H 0xc8d
+#define CSR_HPMCOUNTER14H 0xc8e
+#define CSR_HPMCOUNTER15H 0xc8f
+#define CSR_HPMCOUNTER16H 0xc90
+#define CSR_HPMCOUNTER17H 0xc91
+#define CSR_HPMCOUNTER18H 0xc92
+#define CSR_HPMCOUNTER19H 0xc93
+#define CSR_HPMCOUNTER20H 0xc94
+#define CSR_HPMCOUNTER21H 0xc95
+#define CSR_HPMCOUNTER22H 0xc96
+#define CSR_HPMCOUNTER23H 0xc97
+#define CSR_HPMCOUNTER24H 0xc98
+#define CSR_HPMCOUNTER25H 0xc99
+#define CSR_HPMCOUNTER26H 0xc9a
+#define CSR_HPMCOUNTER27H 0xc9b
+#define CSR_HPMCOUNTER28H 0xc9c
+#define CSR_HPMCOUNTER29H 0xc9d
+#define CSR_HPMCOUNTER30H 0xc9e
+#define CSR_HPMCOUNTER31H 0xc9f
+#define CSR_MSTATUSH 0x310
+#define CSR_MCYCLEH 0xb80
+#define CSR_MINSTRETH 0xb82
+#define CSR_MHPMCOUNTER3H 0xb83
+#define CSR_MHPMCOUNTER4H 0xb84
+#define CSR_MHPMCOUNTER5H 0xb85
+#define CSR_MHPMCOUNTER6H 0xb86
+#define CSR_MHPMCOUNTER7H 0xb87
+#define CSR_MHPMCOUNTER8H 0xb88
+#define CSR_MHPMCOUNTER9H 0xb89
+#define CSR_MHPMCOUNTER10H 0xb8a
+#define CSR_MHPMCOUNTER11H 0xb8b
+#define CSR_MHPMCOUNTER12H 0xb8c
+#define CSR_MHPMCOUNTER13H 0xb8d
+#define CSR_MHPMCOUNTER14H 0xb8e
+#define CSR_MHPMCOUNTER15H 0xb8f
+#define CSR_MHPMCOUNTER16H 0xb90
+#define CSR_MHPMCOUNTER17H 0xb91
+#define CSR_MHPMCOUNTER18H 0xb92
+#define CSR_MHPMCOUNTER19H 0xb93
+#define CSR_MHPMCOUNTER20H 0xb94
+#define CSR_MHPMCOUNTER21H 0xb95
+#define CSR_MHPMCOUNTER22H 0xb96
+#define CSR_MHPMCOUNTER23H 0xb97
+#define CSR_MHPMCOUNTER24H 0xb98
+#define CSR_MHPMCOUNTER25H 0xb99
+#define CSR_MHPMCOUNTER26H 0xb9a
+#define CSR_MHPMCOUNTER27H 0xb9b
+#define CSR_MHPMCOUNTER28H 0xb9c
+#define CSR_MHPMCOUNTER29H 0xb9d
+#define CSR_MHPMCOUNTER30H 0xb9e
+#define CSR_MHPMCOUNTER31H 0xb9f
+#define CAUSE_MISALIGNED_FETCH 0x0
+#define CAUSE_FETCH_ACCESS 0x1
+#define CAUSE_ILLEGAL_INSTRUCTION 0x2
+#define CAUSE_BREAKPOINT 0x3
+#define CAUSE_MISALIGNED_LOAD 0x4
+#define CAUSE_LOAD_ACCESS 0x5
+#define CAUSE_MISALIGNED_STORE 0x6
+#define CAUSE_STORE_ACCESS 0x7
+#define CAUSE_USER_ECALL 0x8
+#define CAUSE_SUPERVISOR_ECALL 0x9
+#define CAUSE_HYPERVISOR_ECALL 0xa
+#define CAUSE_MACHINE_ECALL 0xb
+#define CAUSE_FETCH_PAGE_FAULT 0xc
+#define CAUSE_LOAD_PAGE_FAULT 0xd
+#define CAUSE_STORE_PAGE_FAULT 0xf
+#endif
+#ifdef DECLARE_INSN
+DECLARE_INSN(slli_rv32, MATCH_SLLI_RV32, MASK_SLLI_RV32)
+DECLARE_INSN(srli_rv32, MATCH_SRLI_RV32, MASK_SRLI_RV32)
+DECLARE_INSN(srai_rv32, MATCH_SRAI_RV32, MASK_SRAI_RV32)
+DECLARE_INSN(frflags, MATCH_FRFLAGS, MASK_FRFLAGS)
+DECLARE_INSN(fsflags, MATCH_FSFLAGS, MASK_FSFLAGS)
+DECLARE_INSN(fsflagsi, MATCH_FSFLAGSI, MASK_FSFLAGSI)
+DECLARE_INSN(frrm, MATCH_FRRM, MASK_FRRM)
+DECLARE_INSN(fsrm, MATCH_FSRM, MASK_FSRM)
+DECLARE_INSN(fsrmi, MATCH_FSRMI, MASK_FSRMI)
+DECLARE_INSN(fscsr, MATCH_FSCSR, MASK_FSCSR)
+DECLARE_INSN(frcsr, MATCH_FRCSR, MASK_FRCSR)
+DECLARE_INSN(rdcycle, MATCH_RDCYCLE, MASK_RDCYCLE)
+DECLARE_INSN(rdtime, MATCH_RDTIME, MASK_RDTIME)
+DECLARE_INSN(rdinstret, MATCH_RDINSTRET, MASK_RDINSTRET)
+DECLARE_INSN(rdcycleh, MATCH_RDCYCLEH, MASK_RDCYCLEH)
+DECLARE_INSN(rdtimeh, MATCH_RDTIMEH, MASK_RDTIMEH)
+DECLARE_INSN(rdinstreth, MATCH_RDINSTRETH, MASK_RDINSTRETH)
+DECLARE_INSN(scall, MATCH_SCALL, MASK_SCALL)
+DECLARE_INSN(sbreak, MATCH_SBREAK, MASK_SBREAK)
+DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S)
+DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X)
+DECLARE_INSN(fence_tso, MATCH_FENCE_TSO, MASK_FENCE_TSO)
+DECLARE_INSN(pause, MATCH_PAUSE, MASK_PAUSE)
+DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
+DECLARE_INSN(bne, MATCH_BNE, MASK_BNE)
+DECLARE_INSN(blt, MATCH_BLT, MASK_BLT)
+DECLARE_INSN(bge, MATCH_BGE, MASK_BGE)
+DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU)
+DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU)
+DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR)
+DECLARE_INSN(jal, MATCH_JAL, MASK_JAL)
+DECLARE_INSN(lui, MATCH_LUI, MASK_LUI)
+DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC)
+DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI)
+DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI)
+DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI)
+DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU)
+DECLARE_INSN(xori, MATCH_XORI, MASK_XORI)
+DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI)
+DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI)
+DECLARE_INSN(ori, MATCH_ORI, MASK_ORI)
+DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI)
+DECLARE_INSN(add, MATCH_ADD, MASK_ADD)
+DECLARE_INSN(sub, MATCH_SUB, MASK_SUB)
+DECLARE_INSN(sll, MATCH_SLL, MASK_SLL)
+DECLARE_INSN(slt, MATCH_SLT, MASK_SLT)
+DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU)
+DECLARE_INSN(xor, MATCH_XOR, MASK_XOR)
+DECLARE_INSN(srl, MATCH_SRL, MASK_SRL)
+DECLARE_INSN(sra, MATCH_SRA, MASK_SRA)
+DECLARE_INSN(or, MATCH_OR, MASK_OR)
+DECLARE_INSN(and, MATCH_AND, MASK_AND)
+DECLARE_INSN(lb, MATCH_LB, MASK_LB)
+DECLARE_INSN(lh, MATCH_LH, MASK_LH)
+DECLARE_INSN(lw, MATCH_LW, MASK_LW)
+DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU)
+DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU)
+DECLARE_INSN(sb, MATCH_SB, MASK_SB)
+DECLARE_INSN(sh, MATCH_SH, MASK_SH)
+DECLARE_INSN(sw, MATCH_SW, MASK_SW)
+DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE)
+DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I)
+DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW)
+DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW)
+DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW)
+DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW)
+DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW)
+DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW)
+DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW)
+DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW)
+DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW)
+DECLARE_INSN(ld, MATCH_LD, MASK_LD)
+DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU)
+DECLARE_INSN(sd, MATCH_SD, MASK_SD)
+DECLARE_INSN(mul, MATCH_MUL, MASK_MUL)
+DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH)
+DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU)
+DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU)
+DECLARE_INSN(div, MATCH_DIV, MASK_DIV)
+DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU)
+DECLARE_INSN(rem, MATCH_REM, MASK_REM)
+DECLARE_INSN(remu, MATCH_REMU, MASK_REMU)
+DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW)
+DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)
+DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)
+DECLARE_INSN(remw, MATCH_REMW, MASK_REMW)
+DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)
+DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
+DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
+DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)
+DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W)
+DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W)
+DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W)
+DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W)
+DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W)
+DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W)
+DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W)
+DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W)
+DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D)
+DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D)
+DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D)
+DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D)
+DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D)
+DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D)
+DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D)
+DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D)
+DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D)
+DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)
+DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D)
+DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S)
+DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S)
+DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S)
+DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S)
+DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S)
+DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S)
+DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S)
+DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S)
+DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S)
+DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S)
+DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S)
+DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S)
+DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S)
+DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S)
+DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S)
+DECLARE_INSN(fmv_x_w, MATCH_FMV_X_W, MASK_FMV_X_W)
+DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S)
+DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W)
+DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU)
+DECLARE_INSN(fmv_w_x, MATCH_FMV_W_X, MASK_FMV_W_X)
+DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)
+DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW)
+DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S)
+DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S)
+DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S)
+DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S)
+DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S)
+DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S)
+DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L)
+DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU)
+DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D)
+DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D)
+DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D)
+DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D)
+DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D)
+DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D)
+DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D)
+DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D)
+DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D)
+DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D)
+DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S)
+DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D)
+DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D)
+DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D)
+DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D)
+DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D)
+DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D)
+DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D)
+DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W)
+DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU)
+DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)
+DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD)
+DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D)
+DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D)
+DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D)
+DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D)
+DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D)
+DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D)
+DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D)
+DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L)
+DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU)
+DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X)
+DECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q)
+DECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q)
+DECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q)
+DECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q)
+DECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q)
+DECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q)
+DECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q)
+DECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q)
+DECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q)
+DECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q)
+DECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S)
+DECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q)
+DECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D)
+DECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q)
+DECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q)
+DECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q)
+DECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q)
+DECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q)
+DECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q)
+DECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q)
+DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W)
+DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU)
+DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ)
+DECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ)
+DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q)
+DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q)
+DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q)
+DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q)
+DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q)
+DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q)
+DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L)
+DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU)
+DECLARE_INSN(fmv_x_q, MATCH_FMV_X_Q, MASK_FMV_X_Q)
+DECLARE_INSN(fmv_q_x, MATCH_FMV_Q_X, MASK_FMV_Q_X)
+DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL)
+DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK)
+DECLARE_INSN(uret, MATCH_URET, MASK_URET)
+DECLARE_INSN(sret, MATCH_SRET, MASK_SRET)
+DECLARE_INSN(mret, MATCH_MRET, MASK_MRET)
+DECLARE_INSN(dret, MATCH_DRET, MASK_DRET)
+DECLARE_INSN(sfence_vma, MATCH_SFENCE_VMA, MASK_SFENCE_VMA)
+DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI)
+DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)
+DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS)
+DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC)
+DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI)
+DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI)
+DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI)
+DECLARE_INSN(hfence_vvma, MATCH_HFENCE_VVMA, MASK_HFENCE_VVMA)
+DECLARE_INSN(hfence_gvma, MATCH_HFENCE_GVMA, MASK_HFENCE_GVMA)
+DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP)
+DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP)
+DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR)
+DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR)
+DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK)
+DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN)
+DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD)
+DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW)
+DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW)
+DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD)
+DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW)
+DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW)
+DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI)
+DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL)
+DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI)
+DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI)
+DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI)
+DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI)
+DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI)
+DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB)
+DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR)
+DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR)
+DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND)
+DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J)
+DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ)
+DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ)
+DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI)
+DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP)
+DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP)
+DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP)
+DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV)
+DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD)
+DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP)
+DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP)
+DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP)
+DECLARE_INSN(c_srli_rv32, MATCH_C_SRLI_RV32, MASK_C_SRLI_RV32)
+DECLARE_INSN(c_srai_rv32, MATCH_C_SRAI_RV32, MASK_C_SRAI_RV32)
+DECLARE_INSN(c_slli_rv32, MATCH_C_SLLI_RV32, MASK_C_SLLI_RV32)
+DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD)
+DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD)
+DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW)
+DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW)
+DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW)
+DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP)
+DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP)
+DECLARE_INSN(c_lq, MATCH_C_LQ, MASK_C_LQ)
+DECLARE_INSN(c_sq, MATCH_C_SQ, MASK_C_SQ)
+DECLARE_INSN(c_lqsp, MATCH_C_LQSP, MASK_C_LQSP)
+DECLARE_INSN(c_sqsp, MATCH_C_SQSP, MASK_C_SQSP)
+DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0)
+DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1)
+DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2)
+DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD)
+DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1)
+DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2)
+DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1)
+DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1)
+DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2)
+DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD)
+DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1)
+DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2)
+DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2)
+DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1)
+DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2)
+DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD)
+DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1)
+DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2)
+DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3)
+DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1)
+DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2)
+DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD)
+DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1)
+DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2)
+DECLARE_INSN(vsetvli, MATCH_VSETVLI, MASK_VSETVLI)
+DECLARE_INSN(vsetvl, MATCH_VSETVL, MASK_VSETVL)
+DECLARE_INSN(vlb_v, MATCH_VLB_V, MASK_VLB_V)
+DECLARE_INSN(vlh_v, MATCH_VLH_V, MASK_VLH_V)
+DECLARE_INSN(vlw_v, MATCH_VLW_V, MASK_VLW_V)
+DECLARE_INSN(vle_v, MATCH_VLE_V, MASK_VLE_V)
+DECLARE_INSN(vlbu_v, MATCH_VLBU_V, MASK_VLBU_V)
+DECLARE_INSN(vlhu_v, MATCH_VLHU_V, MASK_VLHU_V)
+DECLARE_INSN(vlwu_v, MATCH_VLWU_V, MASK_VLWU_V)
+DECLARE_INSN(vsb_v, MATCH_VSB_V, MASK_VSB_V)
+DECLARE_INSN(vsh_v, MATCH_VSH_V, MASK_VSH_V)
+DECLARE_INSN(vsw_v, MATCH_VSW_V, MASK_VSW_V)
+DECLARE_INSN(vse_v, MATCH_VSE_V, MASK_VSE_V)
+DECLARE_INSN(vlsb_v, MATCH_VLSB_V, MASK_VLSB_V)
+DECLARE_INSN(vlsh_v, MATCH_VLSH_V, MASK_VLSH_V)
+DECLARE_INSN(vlsw_v, MATCH_VLSW_V, MASK_VLSW_V)
+DECLARE_INSN(vlse_v, MATCH_VLSE_V, MASK_VLSE_V)
+DECLARE_INSN(vlsbu_v, MATCH_VLSBU_V, MASK_VLSBU_V)
+DECLARE_INSN(vlshu_v, MATCH_VLSHU_V, MASK_VLSHU_V)
+DECLARE_INSN(vlswu_v, MATCH_VLSWU_V, MASK_VLSWU_V)
+DECLARE_INSN(vssb_v, MATCH_VSSB_V, MASK_VSSB_V)
+DECLARE_INSN(vssh_v, MATCH_VSSH_V, MASK_VSSH_V)
+DECLARE_INSN(vssw_v, MATCH_VSSW_V, MASK_VSSW_V)
+DECLARE_INSN(vsse_v, MATCH_VSSE_V, MASK_VSSE_V)
+DECLARE_INSN(vlxb_v, MATCH_VLXB_V, MASK_VLXB_V)
+DECLARE_INSN(vlxh_v, MATCH_VLXH_V, MASK_VLXH_V)
+DECLARE_INSN(vlxw_v, MATCH_VLXW_V, MASK_VLXW_V)
+DECLARE_INSN(vlxe_v, MATCH_VLXE_V, MASK_VLXE_V)
+DECLARE_INSN(vlxbu_v, MATCH_VLXBU_V, MASK_VLXBU_V)
+DECLARE_INSN(vlxhu_v, MATCH_VLXHU_V, MASK_VLXHU_V)
+DECLARE_INSN(vlxwu_v, MATCH_VLXWU_V, MASK_VLXWU_V)
+DECLARE_INSN(vsxb_v, MATCH_VSXB_V, MASK_VSXB_V)
+DECLARE_INSN(vsxh_v, MATCH_VSXH_V, MASK_VSXH_V)
+DECLARE_INSN(vsxw_v, MATCH_VSXW_V, MASK_VSXW_V)
+DECLARE_INSN(vsxe_v, MATCH_VSXE_V, MASK_VSXE_V)
+DECLARE_INSN(vsuxb_v, MATCH_VSUXB_V, MASK_VSUXB_V)
+DECLARE_INSN(vsuxh_v, MATCH_VSUXH_V, MASK_VSUXH_V)
+DECLARE_INSN(vsuxw_v, MATCH_VSUXW_V, MASK_VSUXW_V)
+DECLARE_INSN(vsuxe_v, MATCH_VSUXE_V, MASK_VSUXE_V)
+DECLARE_INSN(vlbff_v, MATCH_VLBFF_V, MASK_VLBFF_V)
+DECLARE_INSN(vlhff_v, MATCH_VLHFF_V, MASK_VLHFF_V)
+DECLARE_INSN(vlwff_v, MATCH_VLWFF_V, MASK_VLWFF_V)
+DECLARE_INSN(vleff_v, MATCH_VLEFF_V, MASK_VLEFF_V)
+DECLARE_INSN(vlbuff_v, MATCH_VLBUFF_V, MASK_VLBUFF_V)
+DECLARE_INSN(vlhuff_v, MATCH_VLHUFF_V, MASK_VLHUFF_V)
+DECLARE_INSN(vlwuff_v, MATCH_VLWUFF_V, MASK_VLWUFF_V)
+DECLARE_INSN(vl1r_v, MATCH_VL1R_V, MASK_VL1R_V)
+DECLARE_INSN(vs1r_v, MATCH_VS1R_V, MASK_VS1R_V)
+DECLARE_INSN(vfadd_vf, MATCH_VFADD_VF, MASK_VFADD_VF)
+DECLARE_INSN(vfsub_vf, MATCH_VFSUB_VF, MASK_VFSUB_VF)
+DECLARE_INSN(vfmin_vf, MATCH_VFMIN_VF, MASK_VFMIN_VF)
+DECLARE_INSN(vfmax_vf, MATCH_VFMAX_VF, MASK_VFMAX_VF)
+DECLARE_INSN(vfsgnj_vf, MATCH_VFSGNJ_VF, MASK_VFSGNJ_VF)
+DECLARE_INSN(vfsgnjn_vf, MATCH_VFSGNJN_VF, MASK_VFSGNJN_VF)
+DECLARE_INSN(vfsgnjx_vf, MATCH_VFSGNJX_VF, MASK_VFSGNJX_VF)
+DECLARE_INSN(vfslide1up_vf, MATCH_VFSLIDE1UP_VF, MASK_VFSLIDE1UP_VF)
+DECLARE_INSN(vfslide1down_vf, MATCH_VFSLIDE1DOWN_VF, MASK_VFSLIDE1DOWN_VF)
+DECLARE_INSN(vfmv_s_f, MATCH_VFMV_S_F, MASK_VFMV_S_F)
+DECLARE_INSN(vfmerge_vfm, MATCH_VFMERGE_VFM, MASK_VFMERGE_VFM)
+DECLARE_INSN(vfmv_v_f, MATCH_VFMV_V_F, MASK_VFMV_V_F)
+DECLARE_INSN(vmfeq_vf, MATCH_VMFEQ_VF, MASK_VMFEQ_VF)
+DECLARE_INSN(vmfle_vf, MATCH_VMFLE_VF, MASK_VMFLE_VF)
+DECLARE_INSN(vmflt_vf, MATCH_VMFLT_VF, MASK_VMFLT_VF)
+DECLARE_INSN(vmfne_vf, MATCH_VMFNE_VF, MASK_VMFNE_VF)
+DECLARE_INSN(vmfgt_vf, MATCH_VMFGT_VF, MASK_VMFGT_VF)
+DECLARE_INSN(vmfge_vf, MATCH_VMFGE_VF, MASK_VMFGE_VF)
+DECLARE_INSN(vfdiv_vf, MATCH_VFDIV_VF, MASK_VFDIV_VF)
+DECLARE_INSN(vfrdiv_vf, MATCH_VFRDIV_VF, MASK_VFRDIV_VF)
+DECLARE_INSN(vfmul_vf, MATCH_VFMUL_VF, MASK_VFMUL_VF)
+DECLARE_INSN(vfrsub_vf, MATCH_VFRSUB_VF, MASK_VFRSUB_VF)
+DECLARE_INSN(vfmadd_vf, MATCH_VFMADD_VF, MASK_VFMADD_VF)
+DECLARE_INSN(vfnmadd_vf, MATCH_VFNMADD_VF, MASK_VFNMADD_VF)
+DECLARE_INSN(vfmsub_vf, MATCH_VFMSUB_VF, MASK_VFMSUB_VF)
+DECLARE_INSN(vfnmsub_vf, MATCH_VFNMSUB_VF, MASK_VFNMSUB_VF)
+DECLARE_INSN(vfmacc_vf, MATCH_VFMACC_VF, MASK_VFMACC_VF)
+DECLARE_INSN(vfnmacc_vf, MATCH_VFNMACC_VF, MASK_VFNMACC_VF)
+DECLARE_INSN(vfmsac_vf, MATCH_VFMSAC_VF, MASK_VFMSAC_VF)
+DECLARE_INSN(vfnmsac_vf, MATCH_VFNMSAC_VF, MASK_VFNMSAC_VF)
+DECLARE_INSN(vfwadd_vf, MATCH_VFWADD_VF, MASK_VFWADD_VF)
+DECLARE_INSN(vfwsub_vf, MATCH_VFWSUB_VF, MASK_VFWSUB_VF)
+DECLARE_INSN(vfwadd_wf, MATCH_VFWADD_WF, MASK_VFWADD_WF)
+DECLARE_INSN(vfwsub_wf, MATCH_VFWSUB_WF, MASK_VFWSUB_WF)
+DECLARE_INSN(vfwmul_vf, MATCH_VFWMUL_VF, MASK_VFWMUL_VF)
+DECLARE_INSN(vfwmacc_vf, MATCH_VFWMACC_VF, MASK_VFWMACC_VF)
+DECLARE_INSN(vfwnmacc_vf, MATCH_VFWNMACC_VF, MASK_VFWNMACC_VF)
+DECLARE_INSN(vfwmsac_vf, MATCH_VFWMSAC_VF, MASK_VFWMSAC_VF)
+DECLARE_INSN(vfwnmsac_vf, MATCH_VFWNMSAC_VF, MASK_VFWNMSAC_VF)
+DECLARE_INSN(vfadd_vv, MATCH_VFADD_VV, MASK_VFADD_VV)
+DECLARE_INSN(vfredsum_vs, MATCH_VFREDSUM_VS, MASK_VFREDSUM_VS)
+DECLARE_INSN(vfsub_vv, MATCH_VFSUB_VV, MASK_VFSUB_VV)
+DECLARE_INSN(vfredosum_vs, MATCH_VFREDOSUM_VS, MASK_VFREDOSUM_VS)
+DECLARE_INSN(vfmin_vv, MATCH_VFMIN_VV, MASK_VFMIN_VV)
+DECLARE_INSN(vfredmin_vs, MATCH_VFREDMIN_VS, MASK_VFREDMIN_VS)
+DECLARE_INSN(vfmax_vv, MATCH_VFMAX_VV, MASK_VFMAX_VV)
+DECLARE_INSN(vfredmax_vs, MATCH_VFREDMAX_VS, MASK_VFREDMAX_VS)
+DECLARE_INSN(vfsgnj_vv, MATCH_VFSGNJ_VV, MASK_VFSGNJ_VV)
+DECLARE_INSN(vfsgnjn_vv, MATCH_VFSGNJN_VV, MASK_VFSGNJN_VV)
+DECLARE_INSN(vfsgnjx_vv, MATCH_VFSGNJX_VV, MASK_VFSGNJX_VV)
+DECLARE_INSN(vfmv_f_s, MATCH_VFMV_F_S, MASK_VFMV_F_S)
+DECLARE_INSN(vmfeq_vv, MATCH_VMFEQ_VV, MASK_VMFEQ_VV)
+DECLARE_INSN(vmfle_vv, MATCH_VMFLE_VV, MASK_VMFLE_VV)
+DECLARE_INSN(vmflt_vv, MATCH_VMFLT_VV, MASK_VMFLT_VV)
+DECLARE_INSN(vmfne_vv, MATCH_VMFNE_VV, MASK_VMFNE_VV)
+DECLARE_INSN(vfdiv_vv, MATCH_VFDIV_VV, MASK_VFDIV_VV)
+DECLARE_INSN(vfmul_vv, MATCH_VFMUL_VV, MASK_VFMUL_VV)
+DECLARE_INSN(vfmadd_vv, MATCH_VFMADD_VV, MASK_VFMADD_VV)
+DECLARE_INSN(vfnmadd_vv, MATCH_VFNMADD_VV, MASK_VFNMADD_VV)
+DECLARE_INSN(vfmsub_vv, MATCH_VFMSUB_VV, MASK_VFMSUB_VV)
+DECLARE_INSN(vfnmsub_vv, MATCH_VFNMSUB_VV, MASK_VFNMSUB_VV)
+DECLARE_INSN(vfmacc_vv, MATCH_VFMACC_VV, MASK_VFMACC_VV)
+DECLARE_INSN(vfnmacc_vv, MATCH_VFNMACC_VV, MASK_VFNMACC_VV)
+DECLARE_INSN(vfmsac_vv, MATCH_VFMSAC_VV, MASK_VFMSAC_VV)
+DECLARE_INSN(vfnmsac_vv, MATCH_VFNMSAC_VV, MASK_VFNMSAC_VV)
+DECLARE_INSN(vfcvt_xu_f_v, MATCH_VFCVT_XU_F_V, MASK_VFCVT_XU_F_V)
+DECLARE_INSN(vfcvt_x_f_v, MATCH_VFCVT_X_F_V, MASK_VFCVT_X_F_V)
+DECLARE_INSN(vfcvt_f_xu_v, MATCH_VFCVT_F_XU_V, MASK_VFCVT_F_XU_V)
+DECLARE_INSN(vfcvt_f_x_v, MATCH_VFCVT_F_X_V, MASK_VFCVT_F_X_V)
+DECLARE_INSN(vfcvt_rtz_xu_f_v, MATCH_VFCVT_RTZ_XU_F_V, MASK_VFCVT_RTZ_XU_F_V)
+DECLARE_INSN(vfcvt_rtz_x_f_v, MATCH_VFCVT_RTZ_X_F_V, MASK_VFCVT_RTZ_X_F_V)
+DECLARE_INSN(vfwcvt_xu_f_v, MATCH_VFWCVT_XU_F_V, MASK_VFWCVT_XU_F_V)
+DECLARE_INSN(vfwcvt_x_f_v, MATCH_VFWCVT_X_F_V, MASK_VFWCVT_X_F_V)
+DECLARE_INSN(vfwcvt_f_xu_v, MATCH_VFWCVT_F_XU_V, MASK_VFWCVT_F_XU_V)
+DECLARE_INSN(vfwcvt_f_x_v, MATCH_VFWCVT_F_X_V, MASK_VFWCVT_F_X_V)
+DECLARE_INSN(vfwcvt_f_f_v, MATCH_VFWCVT_F_F_V, MASK_VFWCVT_F_F_V)
+DECLARE_INSN(vfwcvt_rtz_xu_f_v, MATCH_VFWCVT_RTZ_XU_F_V, MASK_VFWCVT_RTZ_XU_F_V)
+DECLARE_INSN(vfwcvt_rtz_x_f_v, MATCH_VFWCVT_RTZ_X_F_V, MASK_VFWCVT_RTZ_X_F_V)
+DECLARE_INSN(vfncvt_xu_f_w, MATCH_VFNCVT_XU_F_W, MASK_VFNCVT_XU_F_W)
+DECLARE_INSN(vfncvt_x_f_w, MATCH_VFNCVT_X_F_W, MASK_VFNCVT_X_F_W)
+DECLARE_INSN(vfncvt_f_xu_w, MATCH_VFNCVT_F_XU_W, MASK_VFNCVT_F_XU_W)
+DECLARE_INSN(vfncvt_f_x_w, MATCH_VFNCVT_F_X_W, MASK_VFNCVT_F_X_W)
+DECLARE_INSN(vfncvt_f_f_w, MATCH_VFNCVT_F_F_W, MASK_VFNCVT_F_F_W)
+DECLARE_INSN(vfncvt_rod_f_f_w, MATCH_VFNCVT_ROD_F_F_W, MASK_VFNCVT_ROD_F_F_W)
+DECLARE_INSN(vfncvt_rtz_xu_f_w, MATCH_VFNCVT_RTZ_XU_F_W, MASK_VFNCVT_RTZ_XU_F_W)
+DECLARE_INSN(vfncvt_rtz_x_f_w, MATCH_VFNCVT_RTZ_X_F_W, MASK_VFNCVT_RTZ_X_F_W)
+DECLARE_INSN(vfsqrt_v, MATCH_VFSQRT_V, MASK_VFSQRT_V)
+DECLARE_INSN(vfclass_v, MATCH_VFCLASS_V, MASK_VFCLASS_V)
+DECLARE_INSN(vfwadd_vv, MATCH_VFWADD_VV, MASK_VFWADD_VV)
+DECLARE_INSN(vfwredsum_vs, MATCH_VFWREDSUM_VS, MASK_VFWREDSUM_VS)
+DECLARE_INSN(vfwsub_vv, MATCH_VFWSUB_VV, MASK_VFWSUB_VV)
+DECLARE_INSN(vfwredosum_vs, MATCH_VFWREDOSUM_VS, MASK_VFWREDOSUM_VS)
+DECLARE_INSN(vfwadd_wv, MATCH_VFWADD_WV, MASK_VFWADD_WV)
+DECLARE_INSN(vfwsub_wv, MATCH_VFWSUB_WV, MASK_VFWSUB_WV)
+DECLARE_INSN(vfwmul_vv, MATCH_VFWMUL_VV, MASK_VFWMUL_VV)
+DECLARE_INSN(vfdot_vv, MATCH_VFDOT_VV, MASK_VFDOT_VV)
+DECLARE_INSN(vfwmacc_vv, MATCH_VFWMACC_VV, MASK_VFWMACC_VV)
+DECLARE_INSN(vfwnmacc_vv, MATCH_VFWNMACC_VV, MASK_VFWNMACC_VV)
+DECLARE_INSN(vfwmsac_vv, MATCH_VFWMSAC_VV, MASK_VFWMSAC_VV)
+DECLARE_INSN(vfwnmsac_vv, MATCH_VFWNMSAC_VV, MASK_VFWNMSAC_VV)
+DECLARE_INSN(vadd_vx, MATCH_VADD_VX, MASK_VADD_VX)
+DECLARE_INSN(vsub_vx, MATCH_VSUB_VX, MASK_VSUB_VX)
+DECLARE_INSN(vrsub_vx, MATCH_VRSUB_VX, MASK_VRSUB_VX)
+DECLARE_INSN(vminu_vx, MATCH_VMINU_VX, MASK_VMINU_VX)
+DECLARE_INSN(vmin_vx, MATCH_VMIN_VX, MASK_VMIN_VX)
+DECLARE_INSN(vmaxu_vx, MATCH_VMAXU_VX, MASK_VMAXU_VX)
+DECLARE_INSN(vmax_vx, MATCH_VMAX_VX, MASK_VMAX_VX)
+DECLARE_INSN(vand_vx, MATCH_VAND_VX, MASK_VAND_VX)
+DECLARE_INSN(vor_vx, MATCH_VOR_VX, MASK_VOR_VX)
+DECLARE_INSN(vxor_vx, MATCH_VXOR_VX, MASK_VXOR_VX)
+DECLARE_INSN(vrgather_vx, MATCH_VRGATHER_VX, MASK_VRGATHER_VX)
+DECLARE_INSN(vslideup_vx, MATCH_VSLIDEUP_VX, MASK_VSLIDEUP_VX)
+DECLARE_INSN(vslidedown_vx, MATCH_VSLIDEDOWN_VX, MASK_VSLIDEDOWN_VX)
+DECLARE_INSN(vadc_vxm, MATCH_VADC_VXM, MASK_VADC_VXM)
+DECLARE_INSN(vmadc_vxm, MATCH_VMADC_VXM, MASK_VMADC_VXM)
+DECLARE_INSN(vsbc_vxm, MATCH_VSBC_VXM, MASK_VSBC_VXM)
+DECLARE_INSN(vmsbc_vxm, MATCH_VMSBC_VXM, MASK_VMSBC_VXM)
+DECLARE_INSN(vmerge_vxm, MATCH_VMERGE_VXM, MASK_VMERGE_VXM)
+DECLARE_INSN(vmv_v_x, MATCH_VMV_V_X, MASK_VMV_V_X)
+DECLARE_INSN(vmseq_vx, MATCH_VMSEQ_VX, MASK_VMSEQ_VX)
+DECLARE_INSN(vmsne_vx, MATCH_VMSNE_VX, MASK_VMSNE_VX)
+DECLARE_INSN(vmsltu_vx, MATCH_VMSLTU_VX, MASK_VMSLTU_VX)
+DECLARE_INSN(vmslt_vx, MATCH_VMSLT_VX, MASK_VMSLT_VX)
+DECLARE_INSN(vmsleu_vx, MATCH_VMSLEU_VX, MASK_VMSLEU_VX)
+DECLARE_INSN(vmsle_vx, MATCH_VMSLE_VX, MASK_VMSLE_VX)
+DECLARE_INSN(vmsgtu_vx, MATCH_VMSGTU_VX, MASK_VMSGTU_VX)
+DECLARE_INSN(vmsgt_vx, MATCH_VMSGT_VX, MASK_VMSGT_VX)
+DECLARE_INSN(vsaddu_vx, MATCH_VSADDU_VX, MASK_VSADDU_VX)
+DECLARE_INSN(vsadd_vx, MATCH_VSADD_VX, MASK_VSADD_VX)
+DECLARE_INSN(vssubu_vx, MATCH_VSSUBU_VX, MASK_VSSUBU_VX)
+DECLARE_INSN(vssub_vx, MATCH_VSSUB_VX, MASK_VSSUB_VX)
+DECLARE_INSN(vsll_vx, MATCH_VSLL_VX, MASK_VSLL_VX)
+DECLARE_INSN(vsmul_vx, MATCH_VSMUL_VX, MASK_VSMUL_VX)
+DECLARE_INSN(vsrl_vx, MATCH_VSRL_VX, MASK_VSRL_VX)
+DECLARE_INSN(vsra_vx, MATCH_VSRA_VX, MASK_VSRA_VX)
+DECLARE_INSN(vssrl_vx, MATCH_VSSRL_VX, MASK_VSSRL_VX)
+DECLARE_INSN(vssra_vx, MATCH_VSSRA_VX, MASK_VSSRA_VX)
+DECLARE_INSN(vnsrl_wx, MATCH_VNSRL_WX, MASK_VNSRL_WX)
+DECLARE_INSN(vnsra_wx, MATCH_VNSRA_WX, MASK_VNSRA_WX)
+DECLARE_INSN(vnclipu_wx, MATCH_VNCLIPU_WX, MASK_VNCLIPU_WX)
+DECLARE_INSN(vnclip_wx, MATCH_VNCLIP_WX, MASK_VNCLIP_WX)
+DECLARE_INSN(vqmaccu_vx, MATCH_VQMACCU_VX, MASK_VQMACCU_VX)
+DECLARE_INSN(vqmacc_vx, MATCH_VQMACC_VX, MASK_VQMACC_VX)
+DECLARE_INSN(vqmaccus_vx, MATCH_VQMACCUS_VX, MASK_VQMACCUS_VX)
+DECLARE_INSN(vqmaccsu_vx, MATCH_VQMACCSU_VX, MASK_VQMACCSU_VX)
+DECLARE_INSN(vadd_vv, MATCH_VADD_VV, MASK_VADD_VV)
+DECLARE_INSN(vsub_vv, MATCH_VSUB_VV, MASK_VSUB_VV)
+DECLARE_INSN(vminu_vv, MATCH_VMINU_VV, MASK_VMINU_VV)
+DECLARE_INSN(vmin_vv, MATCH_VMIN_VV, MASK_VMIN_VV)
+DECLARE_INSN(vmaxu_vv, MATCH_VMAXU_VV, MASK_VMAXU_VV)
+DECLARE_INSN(vmax_vv, MATCH_VMAX_VV, MASK_VMAX_VV)
+DECLARE_INSN(vand_vv, MATCH_VAND_VV, MASK_VAND_VV)
+DECLARE_INSN(vor_vv, MATCH_VOR_VV, MASK_VOR_VV)
+DECLARE_INSN(vxor_vv, MATCH_VXOR_VV, MASK_VXOR_VV)
+DECLARE_INSN(vrgather_vv, MATCH_VRGATHER_VV, MASK_VRGATHER_VV)
+DECLARE_INSN(vadc_vvm, MATCH_VADC_VVM, MASK_VADC_VVM)
+DECLARE_INSN(vmadc_vvm, MATCH_VMADC_VVM, MASK_VMADC_VVM)
+DECLARE_INSN(vsbc_vvm, MATCH_VSBC_VVM, MASK_VSBC_VVM)
+DECLARE_INSN(vmsbc_vvm, MATCH_VMSBC_VVM, MASK_VMSBC_VVM)
+DECLARE_INSN(vmerge_vvm, MATCH_VMERGE_VVM, MASK_VMERGE_VVM)
+DECLARE_INSN(vmv_v_v, MATCH_VMV_V_V, MASK_VMV_V_V)
+DECLARE_INSN(vmseq_vv, MATCH_VMSEQ_VV, MASK_VMSEQ_VV)
+DECLARE_INSN(vmsne_vv, MATCH_VMSNE_VV, MASK_VMSNE_VV)
+DECLARE_INSN(vmsltu_vv, MATCH_VMSLTU_VV, MASK_VMSLTU_VV)
+DECLARE_INSN(vmslt_vv, MATCH_VMSLT_VV, MASK_VMSLT_VV)
+DECLARE_INSN(vmsleu_vv, MATCH_VMSLEU_VV, MASK_VMSLEU_VV)
+DECLARE_INSN(vmsle_vv, MATCH_VMSLE_VV, MASK_VMSLE_VV)
+DECLARE_INSN(vsaddu_vv, MATCH_VSADDU_VV, MASK_VSADDU_VV)
+DECLARE_INSN(vsadd_vv, MATCH_VSADD_VV, MASK_VSADD_VV)
+DECLARE_INSN(vssubu_vv, MATCH_VSSUBU_VV, MASK_VSSUBU_VV)
+DECLARE_INSN(vssub_vv, MATCH_VSSUB_VV, MASK_VSSUB_VV)
+DECLARE_INSN(vsll_vv, MATCH_VSLL_VV, MASK_VSLL_VV)
+DECLARE_INSN(vsmul_vv, MATCH_VSMUL_VV, MASK_VSMUL_VV)
+DECLARE_INSN(vsrl_vv, MATCH_VSRL_VV, MASK_VSRL_VV)
+DECLARE_INSN(vsra_vv, MATCH_VSRA_VV, MASK_VSRA_VV)
+DECLARE_INSN(vssrl_vv, MATCH_VSSRL_VV, MASK_VSSRL_VV)
+DECLARE_INSN(vssra_vv, MATCH_VSSRA_VV, MASK_VSSRA_VV)
+DECLARE_INSN(vnsrl_wv, MATCH_VNSRL_WV, MASK_VNSRL_WV)
+DECLARE_INSN(vnsra_wv, MATCH_VNSRA_WV, MASK_VNSRA_WV)
+DECLARE_INSN(vnclipu_wv, MATCH_VNCLIPU_WV, MASK_VNCLIPU_WV)
+DECLARE_INSN(vnclip_wv, MATCH_VNCLIP_WV, MASK_VNCLIP_WV)
+DECLARE_INSN(vwredsumu_vs, MATCH_VWREDSUMU_VS, MASK_VWREDSUMU_VS)
+DECLARE_INSN(vwredsum_vs, MATCH_VWREDSUM_VS, MASK_VWREDSUM_VS)
+DECLARE_INSN(vdotu_vv, MATCH_VDOTU_VV, MASK_VDOTU_VV)
+DECLARE_INSN(vdot_vv, MATCH_VDOT_VV, MASK_VDOT_VV)
+DECLARE_INSN(vqmaccu_vv, MATCH_VQMACCU_VV, MASK_VQMACCU_VV)
+DECLARE_INSN(vqmacc_vv, MATCH_VQMACC_VV, MASK_VQMACC_VV)
+DECLARE_INSN(vqmaccsu_vv, MATCH_VQMACCSU_VV, MASK_VQMACCSU_VV)
+DECLARE_INSN(vadd_vi, MATCH_VADD_VI, MASK_VADD_VI)
+DECLARE_INSN(vrsub_vi, MATCH_VRSUB_VI, MASK_VRSUB_VI)
+DECLARE_INSN(vand_vi, MATCH_VAND_VI, MASK_VAND_VI)
+DECLARE_INSN(vor_vi, MATCH_VOR_VI, MASK_VOR_VI)
+DECLARE_INSN(vxor_vi, MATCH_VXOR_VI, MASK_VXOR_VI)
+DECLARE_INSN(vrgather_vi, MATCH_VRGATHER_VI, MASK_VRGATHER_VI)
+DECLARE_INSN(vslideup_vi, MATCH_VSLIDEUP_VI, MASK_VSLIDEUP_VI)
+DECLARE_INSN(vslidedown_vi, MATCH_VSLIDEDOWN_VI, MASK_VSLIDEDOWN_VI)
+DECLARE_INSN(vadc_vim, MATCH_VADC_VIM, MASK_VADC_VIM)
+DECLARE_INSN(vmadc_vim, MATCH_VMADC_VIM, MASK_VMADC_VIM)
+DECLARE_INSN(vmerge_vim, MATCH_VMERGE_VIM, MASK_VMERGE_VIM)
+DECLARE_INSN(vmv_v_i, MATCH_VMV_V_I, MASK_VMV_V_I)
+DECLARE_INSN(vmseq_vi, MATCH_VMSEQ_VI, MASK_VMSEQ_VI)
+DECLARE_INSN(vmsne_vi, MATCH_VMSNE_VI, MASK_VMSNE_VI)
+DECLARE_INSN(vmsleu_vi, MATCH_VMSLEU_VI, MASK_VMSLEU_VI)
+DECLARE_INSN(vmsle_vi, MATCH_VMSLE_VI, MASK_VMSLE_VI)
+DECLARE_INSN(vmsgtu_vi, MATCH_VMSGTU_VI, MASK_VMSGTU_VI)
+DECLARE_INSN(vmsgt_vi, MATCH_VMSGT_VI, MASK_VMSGT_VI)
+DECLARE_INSN(vsaddu_vi, MATCH_VSADDU_VI, MASK_VSADDU_VI)
+DECLARE_INSN(vsadd_vi, MATCH_VSADD_VI, MASK_VSADD_VI)
+DECLARE_INSN(vsll_vi, MATCH_VSLL_VI, MASK_VSLL_VI)
+DECLARE_INSN(vmv1r_v, MATCH_VMV1R_V, MASK_VMV1R_V)
+DECLARE_INSN(vmv2r_v, MATCH_VMV2R_V, MASK_VMV2R_V)
+DECLARE_INSN(vmv4r_v, MATCH_VMV4R_V, MASK_VMV4R_V)
+DECLARE_INSN(vmv8r_v, MATCH_VMV8R_V, MASK_VMV8R_V)
+DECLARE_INSN(vsrl_vi, MATCH_VSRL_VI, MASK_VSRL_VI)
+DECLARE_INSN(vsra_vi, MATCH_VSRA_VI, MASK_VSRA_VI)
+DECLARE_INSN(vssrl_vi, MATCH_VSSRL_VI, MASK_VSSRL_VI)
+DECLARE_INSN(vssra_vi, MATCH_VSSRA_VI, MASK_VSSRA_VI)
+DECLARE_INSN(vnsrl_wi, MATCH_VNSRL_WI, MASK_VNSRL_WI)
+DECLARE_INSN(vnsra_wi, MATCH_VNSRA_WI, MASK_VNSRA_WI)
+DECLARE_INSN(vnclipu_wi, MATCH_VNCLIPU_WI, MASK_VNCLIPU_WI)
+DECLARE_INSN(vnclip_wi, MATCH_VNCLIP_WI, MASK_VNCLIP_WI)
+DECLARE_INSN(vredsum_vs, MATCH_VREDSUM_VS, MASK_VREDSUM_VS)
+DECLARE_INSN(vredand_vs, MATCH_VREDAND_VS, MASK_VREDAND_VS)
+DECLARE_INSN(vredor_vs, MATCH_VREDOR_VS, MASK_VREDOR_VS)
+DECLARE_INSN(vredxor_vs, MATCH_VREDXOR_VS, MASK_VREDXOR_VS)
+DECLARE_INSN(vredminu_vs, MATCH_VREDMINU_VS, MASK_VREDMINU_VS)
+DECLARE_INSN(vredmin_vs, MATCH_VREDMIN_VS, MASK_VREDMIN_VS)
+DECLARE_INSN(vredmaxu_vs, MATCH_VREDMAXU_VS, MASK_VREDMAXU_VS)
+DECLARE_INSN(vredmax_vs, MATCH_VREDMAX_VS, MASK_VREDMAX_VS)
+DECLARE_INSN(vaaddu_vv, MATCH_VAADDU_VV, MASK_VAADDU_VV)
+DECLARE_INSN(vaadd_vv, MATCH_VAADD_VV, MASK_VAADD_VV)
+DECLARE_INSN(vasubu_vv, MATCH_VASUBU_VV, MASK_VASUBU_VV)
+DECLARE_INSN(vasub_vv, MATCH_VASUB_VV, MASK_VASUB_VV)
+DECLARE_INSN(vmv_x_s, MATCH_VMV_X_S, MASK_VMV_X_S)
+DECLARE_INSN(vcompress_vm, MATCH_VCOMPRESS_VM, MASK_VCOMPRESS_VM)
+DECLARE_INSN(vmandnot_mm, MATCH_VMANDNOT_MM, MASK_VMANDNOT_MM)
+DECLARE_INSN(vmand_mm, MATCH_VMAND_MM, MASK_VMAND_MM)
+DECLARE_INSN(vmor_mm, MATCH_VMOR_MM, MASK_VMOR_MM)
+DECLARE_INSN(vmxor_mm, MATCH_VMXOR_MM, MASK_VMXOR_MM)
+DECLARE_INSN(vmornot_mm, MATCH_VMORNOT_MM, MASK_VMORNOT_MM)
+DECLARE_INSN(vmnand_mm, MATCH_VMNAND_MM, MASK_VMNAND_MM)
+DECLARE_INSN(vmnor_mm, MATCH_VMNOR_MM, MASK_VMNOR_MM)
+DECLARE_INSN(vmxnor_mm, MATCH_VMXNOR_MM, MASK_VMXNOR_MM)
+DECLARE_INSN(vmsbf_m, MATCH_VMSBF_M, MASK_VMSBF_M)
+DECLARE_INSN(vmsof_m, MATCH_VMSOF_M, MASK_VMSOF_M)
+DECLARE_INSN(vmsif_m, MATCH_VMSIF_M, MASK_VMSIF_M)
+DECLARE_INSN(viota_m, MATCH_VIOTA_M, MASK_VIOTA_M)
+DECLARE_INSN(vid_v, MATCH_VID_V, MASK_VID_V)
+DECLARE_INSN(vpopc_m, MATCH_VPOPC_M, MASK_VPOPC_M)
+DECLARE_INSN(vfirst_m, MATCH_VFIRST_M, MASK_VFIRST_M)
+DECLARE_INSN(vdivu_vv, MATCH_VDIVU_VV, MASK_VDIVU_VV)
+DECLARE_INSN(vdiv_vv, MATCH_VDIV_VV, MASK_VDIV_VV)
+DECLARE_INSN(vremu_vv, MATCH_VREMU_VV, MASK_VREMU_VV)
+DECLARE_INSN(vrem_vv, MATCH_VREM_VV, MASK_VREM_VV)
+DECLARE_INSN(vmulhu_vv, MATCH_VMULHU_VV, MASK_VMULHU_VV)
+DECLARE_INSN(vmul_vv, MATCH_VMUL_VV, MASK_VMUL_VV)
+DECLARE_INSN(vmulhsu_vv, MATCH_VMULHSU_VV, MASK_VMULHSU_VV)
+DECLARE_INSN(vmulh_vv, MATCH_VMULH_VV, MASK_VMULH_VV)
+DECLARE_INSN(vmadd_vv, MATCH_VMADD_VV, MASK_VMADD_VV)
+DECLARE_INSN(vnmsub_vv, MATCH_VNMSUB_VV, MASK_VNMSUB_VV)
+DECLARE_INSN(vmacc_vv, MATCH_VMACC_VV, MASK_VMACC_VV)
+DECLARE_INSN(vnmsac_vv, MATCH_VNMSAC_VV, MASK_VNMSAC_VV)
+DECLARE_INSN(vwaddu_vv, MATCH_VWADDU_VV, MASK_VWADDU_VV)
+DECLARE_INSN(vwadd_vv, MATCH_VWADD_VV, MASK_VWADD_VV)
+DECLARE_INSN(vwsubu_vv, MATCH_VWSUBU_VV, MASK_VWSUBU_VV)
+DECLARE_INSN(vwsub_vv, MATCH_VWSUB_VV, MASK_VWSUB_VV)
+DECLARE_INSN(vwaddu_wv, MATCH_VWADDU_WV, MASK_VWADDU_WV)
+DECLARE_INSN(vwadd_wv, MATCH_VWADD_WV, MASK_VWADD_WV)
+DECLARE_INSN(vwsubu_wv, MATCH_VWSUBU_WV, MASK_VWSUBU_WV)
+DECLARE_INSN(vwsub_wv, MATCH_VWSUB_WV, MASK_VWSUB_WV)
+DECLARE_INSN(vwmulu_vv, MATCH_VWMULU_VV, MASK_VWMULU_VV)
+DECLARE_INSN(vwmulsu_vv, MATCH_VWMULSU_VV, MASK_VWMULSU_VV)
+DECLARE_INSN(vwmul_vv, MATCH_VWMUL_VV, MASK_VWMUL_VV)
+DECLARE_INSN(vwmaccu_vv, MATCH_VWMACCU_VV, MASK_VWMACCU_VV)
+DECLARE_INSN(vwmacc_vv, MATCH_VWMACC_VV, MASK_VWMACC_VV)
+DECLARE_INSN(vwmaccsu_vv, MATCH_VWMACCSU_VV, MASK_VWMACCSU_VV)
+DECLARE_INSN(vaaddu_vx, MATCH_VAADDU_VX, MASK_VAADDU_VX)
+DECLARE_INSN(vaadd_vx, MATCH_VAADD_VX, MASK_VAADD_VX)
+DECLARE_INSN(vasubu_vx, MATCH_VASUBU_VX, MASK_VASUBU_VX)
+DECLARE_INSN(vasub_vx, MATCH_VASUB_VX, MASK_VASUB_VX)
+DECLARE_INSN(vmv_s_x, MATCH_VMV_S_X, MASK_VMV_S_X)
+DECLARE_INSN(vslide1up_vx, MATCH_VSLIDE1UP_VX, MASK_VSLIDE1UP_VX)
+DECLARE_INSN(vslide1down_vx, MATCH_VSLIDE1DOWN_VX, MASK_VSLIDE1DOWN_VX)
+DECLARE_INSN(vdivu_vx, MATCH_VDIVU_VX, MASK_VDIVU_VX)
+DECLARE_INSN(vdiv_vx, MATCH_VDIV_VX, MASK_VDIV_VX)
+DECLARE_INSN(vremu_vx, MATCH_VREMU_VX, MASK_VREMU_VX)
+DECLARE_INSN(vrem_vx, MATCH_VREM_VX, MASK_VREM_VX)
+DECLARE_INSN(vmulhu_vx, MATCH_VMULHU_VX, MASK_VMULHU_VX)
+DECLARE_INSN(vmul_vx, MATCH_VMUL_VX, MASK_VMUL_VX)
+DECLARE_INSN(vmulhsu_vx, MATCH_VMULHSU_VX, MASK_VMULHSU_VX)
+DECLARE_INSN(vmulh_vx, MATCH_VMULH_VX, MASK_VMULH_VX)
+DECLARE_INSN(vmadd_vx, MATCH_VMADD_VX, MASK_VMADD_VX)
+DECLARE_INSN(vnmsub_vx, MATCH_VNMSUB_VX, MASK_VNMSUB_VX)
+DECLARE_INSN(vmacc_vx, MATCH_VMACC_VX, MASK_VMACC_VX)
+DECLARE_INSN(vnmsac_vx, MATCH_VNMSAC_VX, MASK_VNMSAC_VX)
+DECLARE_INSN(vwaddu_vx, MATCH_VWADDU_VX, MASK_VWADDU_VX)
+DECLARE_INSN(vwadd_vx, MATCH_VWADD_VX, MASK_VWADD_VX)
+DECLARE_INSN(vwsubu_vx, MATCH_VWSUBU_VX, MASK_VWSUBU_VX)
+DECLARE_INSN(vwsub_vx, MATCH_VWSUB_VX, MASK_VWSUB_VX)
+DECLARE_INSN(vwaddu_wx, MATCH_VWADDU_WX, MASK_VWADDU_WX)
+DECLARE_INSN(vwadd_wx, MATCH_VWADD_WX, MASK_VWADD_WX)
+DECLARE_INSN(vwsubu_wx, MATCH_VWSUBU_WX, MASK_VWSUBU_WX)
+DECLARE_INSN(vwsub_wx, MATCH_VWSUB_WX, MASK_VWSUB_WX)
+DECLARE_INSN(vwmulu_vx, MATCH_VWMULU_VX, MASK_VWMULU_VX)
+DECLARE_INSN(vwmulsu_vx, MATCH_VWMULSU_VX, MASK_VWMULSU_VX)
+DECLARE_INSN(vwmul_vx, MATCH_VWMUL_VX, MASK_VWMUL_VX)
+DECLARE_INSN(vwmaccu_vx, MATCH_VWMACCU_VX, MASK_VWMACCU_VX)
+DECLARE_INSN(vwmacc_vx, MATCH_VWMACC_VX, MASK_VWMACC_VX)
+DECLARE_INSN(vwmaccus_vx, MATCH_VWMACCUS_VX, MASK_VWMACCUS_VX)
+DECLARE_INSN(vwmaccsu_vx, MATCH_VWMACCSU_VX, MASK_VWMACCSU_VX)
+DECLARE_INSN(vamoswapw_v, MATCH_VAMOSWAPW_V, MASK_VAMOSWAPW_V)
+DECLARE_INSN(vamoaddw_v, MATCH_VAMOADDW_V, MASK_VAMOADDW_V)
+DECLARE_INSN(vamoxorw_v, MATCH_VAMOXORW_V, MASK_VAMOXORW_V)
+DECLARE_INSN(vamoandw_v, MATCH_VAMOANDW_V, MASK_VAMOANDW_V)
+DECLARE_INSN(vamoorw_v, MATCH_VAMOORW_V, MASK_VAMOORW_V)
+DECLARE_INSN(vamominw_v, MATCH_VAMOMINW_V, MASK_VAMOMINW_V)
+DECLARE_INSN(vamomaxw_v, MATCH_VAMOMAXW_V, MASK_VAMOMAXW_V)
+DECLARE_INSN(vamominuw_v, MATCH_VAMOMINUW_V, MASK_VAMOMINUW_V)
+DECLARE_INSN(vamomaxuw_v, MATCH_VAMOMAXUW_V, MASK_VAMOMAXUW_V)
+DECLARE_INSN(vamoswape_v, MATCH_VAMOSWAPE_V, MASK_VAMOSWAPE_V)
+DECLARE_INSN(vamoadde_v, MATCH_VAMOADDE_V, MASK_VAMOADDE_V)
+DECLARE_INSN(vamoxore_v, MATCH_VAMOXORE_V, MASK_VAMOXORE_V)
+DECLARE_INSN(vamoande_v, MATCH_VAMOANDE_V, MASK_VAMOANDE_V)
+DECLARE_INSN(vamoore_v, MATCH_VAMOORE_V, MASK_VAMOORE_V)
+DECLARE_INSN(vamomine_v, MATCH_VAMOMINE_V, MASK_VAMOMINE_V)
+DECLARE_INSN(vamomaxe_v, MATCH_VAMOMAXE_V, MASK_VAMOMAXE_V)
+DECLARE_INSN(vamominue_v, MATCH_VAMOMINUE_V, MASK_VAMOMINUE_V)
+DECLARE_INSN(vamomaxue_v, MATCH_VAMOMAXUE_V, MASK_VAMOMAXUE_V)
+DECLARE_INSN(vmvnfr_v, MATCH_VMVNFR_V, MASK_VMVNFR_V)
+#endif
+#ifdef DECLARE_CSR
+DECLARE_CSR(fflags, CSR_FFLAGS)
+DECLARE_CSR(frm, CSR_FRM)
+DECLARE_CSR(fcsr, CSR_FCSR)
+DECLARE_CSR(ustatus, CSR_USTATUS)
+DECLARE_CSR(uie, CSR_UIE)
+DECLARE_CSR(utvec, CSR_UTVEC)
+DECLARE_CSR(vstart, CSR_VSTART)
+DECLARE_CSR(vxsat, CSR_VXSAT)
+DECLARE_CSR(vxrm, CSR_VXRM)
+DECLARE_CSR(vcsr, CSR_VCSR)
+DECLARE_CSR(uscratch, CSR_USCRATCH)
+DECLARE_CSR(uepc, CSR_UEPC)
+DECLARE_CSR(ucause, CSR_UCAUSE)
+DECLARE_CSR(utval, CSR_UTVAL)
+DECLARE_CSR(uip, CSR_UIP)
+DECLARE_CSR(cycle, CSR_CYCLE)
+DECLARE_CSR(time, CSR_TIME)
+DECLARE_CSR(instret, CSR_INSTRET)
+DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3)
+DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4)
+DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5)
+DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6)
+DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7)
+DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8)
+DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9)
+DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10)
+DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11)
+DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12)
+DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13)
+DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14)
+DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15)
+DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16)
+DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17)
+DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18)
+DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19)
+DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20)
+DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21)
+DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22)
+DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23)
+DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24)
+DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25)
+DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26)
+DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27)
+DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28)
+DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29)
+DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30)
+DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31)
+DECLARE_CSR(vl, CSR_VL)
+DECLARE_CSR(vtype, CSR_VTYPE)
+DECLARE_CSR(vlenb, CSR_VLENB)
+DECLARE_CSR(sstatus, CSR_SSTATUS)
+DECLARE_CSR(sedeleg, CSR_SEDELEG)
+DECLARE_CSR(sideleg, CSR_SIDELEG)
+DECLARE_CSR(sie, CSR_SIE)
+DECLARE_CSR(stvec, CSR_STVEC)
+DECLARE_CSR(scounteren, CSR_SCOUNTEREN)
+DECLARE_CSR(sscratch, CSR_SSCRATCH)
+DECLARE_CSR(sepc, CSR_SEPC)
+DECLARE_CSR(scause, CSR_SCAUSE)
+DECLARE_CSR(stval, CSR_STVAL)
+DECLARE_CSR(sip, CSR_SIP)
+DECLARE_CSR(satp, CSR_SATP)
+DECLARE_CSR(vsstatus, CSR_VSSTATUS)
+DECLARE_CSR(vsie, CSR_VSIE)
+DECLARE_CSR(vstvec, CSR_VSTVEC)
+DECLARE_CSR(vsscratch, CSR_VSSCRATCH)
+DECLARE_CSR(vsepc, CSR_VSEPC)
+DECLARE_CSR(vscause, CSR_VSCAUSE)
+DECLARE_CSR(vstval, CSR_VSTVAL)
+DECLARE_CSR(vsip, CSR_VSIP)
+DECLARE_CSR(vsatp, CSR_VSATP)
+DECLARE_CSR(hstatus, CSR_HSTATUS)
+DECLARE_CSR(hedeleg, CSR_HEDELEG)
+DECLARE_CSR(hideleg, CSR_HIDELEG)
+DECLARE_CSR(hie, CSR_HIE)
+DECLARE_CSR(htimedelta, CSR_HTIMEDELTA)
+DECLARE_CSR(hcounteren, CSR_HCOUNTEREN)
+DECLARE_CSR(hgeie, CSR_HGEIE)
+DECLARE_CSR(htval, CSR_HTVAL)
+DECLARE_CSR(hip, CSR_HIP)
+DECLARE_CSR(hvip, CSR_HVIP)
+DECLARE_CSR(htinst, CSR_HTINST)
+DECLARE_CSR(hgatp, CSR_HGATP)
+DECLARE_CSR(hgeip, CSR_HGEIP)
+DECLARE_CSR(utvt, CSR_UTVT)
+DECLARE_CSR(unxti, CSR_UNXTI)
+DECLARE_CSR(uintstatus, CSR_UINTSTATUS)
+DECLARE_CSR(uscratchcsw, CSR_USCRATCHCSW)
+DECLARE_CSR(uscratchcswl, CSR_USCRATCHCSWL)
+DECLARE_CSR(stvt, CSR_STVT)
+DECLARE_CSR(snxti, CSR_SNXTI)
+DECLARE_CSR(sintstatus, CSR_SINTSTATUS)
+DECLARE_CSR(sscratchcsw, CSR_SSCRATCHCSW)
+DECLARE_CSR(sscratchcswl, CSR_SSCRATCHCSWL)
+DECLARE_CSR(mtvt, CSR_MTVT)
+DECLARE_CSR(mnxti, CSR_MNXTI)
+DECLARE_CSR(mintstatus, CSR_MINTSTATUS)
+DECLARE_CSR(mscratchcsw, CSR_MSCRATCHCSW)
+DECLARE_CSR(mscratchcswl, CSR_MSCRATCHCSWL)
+DECLARE_CSR(mstatus, CSR_MSTATUS)
+DECLARE_CSR(misa, CSR_MISA)
+DECLARE_CSR(medeleg, CSR_MEDELEG)
+DECLARE_CSR(mideleg, CSR_MIDELEG)
+DECLARE_CSR(mie, CSR_MIE)
+DECLARE_CSR(mtvec, CSR_MTVEC)
+DECLARE_CSR(mcounteren, CSR_MCOUNTEREN)
+DECLARE_CSR(mcountinhibit, CSR_MCOUNTINHIBIT)
+DECLARE_CSR(mscratch, CSR_MSCRATCH)
+DECLARE_CSR(mepc, CSR_MEPC)
+DECLARE_CSR(mcause, CSR_MCAUSE)
+DECLARE_CSR(mtval, CSR_MTVAL)
+DECLARE_CSR(mip, CSR_MIP)
+DECLARE_CSR(mtinst, CSR_MTINST)
+DECLARE_CSR(mtval2, CSR_MTVAL2)
+DECLARE_CSR(pmpcfg0, CSR_PMPCFG0)
+DECLARE_CSR(pmpcfg1, CSR_PMPCFG1)
+DECLARE_CSR(pmpcfg2, CSR_PMPCFG2)
+DECLARE_CSR(pmpcfg3, CSR_PMPCFG3)
+DECLARE_CSR(pmpaddr0, CSR_PMPADDR0)
+DECLARE_CSR(pmpaddr1, CSR_PMPADDR1)
+DECLARE_CSR(pmpaddr2, CSR_PMPADDR2)
+DECLARE_CSR(pmpaddr3, CSR_PMPADDR3)
+DECLARE_CSR(pmpaddr4, CSR_PMPADDR4)
+DECLARE_CSR(pmpaddr5, CSR_PMPADDR5)
+DECLARE_CSR(pmpaddr6, CSR_PMPADDR6)
+DECLARE_CSR(pmpaddr7, CSR_PMPADDR7)
+DECLARE_CSR(pmpaddr8, CSR_PMPADDR8)
+DECLARE_CSR(pmpaddr9, CSR_PMPADDR9)
+DECLARE_CSR(pmpaddr10, CSR_PMPADDR10)
+DECLARE_CSR(pmpaddr11, CSR_PMPADDR11)
+DECLARE_CSR(pmpaddr12, CSR_PMPADDR12)
+DECLARE_CSR(pmpaddr13, CSR_PMPADDR13)
+DECLARE_CSR(pmpaddr14, CSR_PMPADDR14)
+DECLARE_CSR(pmpaddr15, CSR_PMPADDR15)
+DECLARE_CSR(tselect, CSR_TSELECT)
+DECLARE_CSR(tdata1, CSR_TDATA1)
+DECLARE_CSR(tdata2, CSR_TDATA2)
+DECLARE_CSR(tdata3, CSR_TDATA3)
+DECLARE_CSR(dcsr, CSR_DCSR)
+DECLARE_CSR(dpc, CSR_DPC)
+DECLARE_CSR(dscratch0, CSR_DSCRATCH0)
+DECLARE_CSR(dscratch1, CSR_DSCRATCH1)
+DECLARE_CSR(mcycle, CSR_MCYCLE)
+DECLARE_CSR(minstret, CSR_MINSTRET)
+DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3)
+DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4)
+DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5)
+DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6)
+DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7)
+DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8)
+DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9)
+DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10)
+DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11)
+DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12)
+DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13)
+DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14)
+DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15)
+DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16)
+DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17)
+DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18)
+DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19)
+DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20)
+DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21)
+DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22)
+DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23)
+DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24)
+DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25)
+DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26)
+DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27)
+DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28)
+DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29)
+DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30)
+DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31)
+DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3)
+DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4)
+DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5)
+DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6)
+DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7)
+DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8)
+DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9)
+DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10)
+DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11)
+DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12)
+DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13)
+DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14)
+DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15)
+DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16)
+DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17)
+DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18)
+DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19)
+DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20)
+DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21)
+DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22)
+DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23)
+DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24)
+DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25)
+DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26)
+DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27)
+DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28)
+DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29)
+DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30)
+DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31)
+DECLARE_CSR(mvendorid, CSR_MVENDORID)
+DECLARE_CSR(marchid, CSR_MARCHID)
+DECLARE_CSR(mimpid, CSR_MIMPID)
+DECLARE_CSR(mhartid, CSR_MHARTID)
+DECLARE_CSR(htimedeltah, CSR_HTIMEDELTAH)
+DECLARE_CSR(cycleh, CSR_CYCLEH)
+DECLARE_CSR(timeh, CSR_TIMEH)
+DECLARE_CSR(instreth, CSR_INSTRETH)
+DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H)
+DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H)
+DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H)
+DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H)
+DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H)
+DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H)
+DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H)
+DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H)
+DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H)
+DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H)
+DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H)
+DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H)
+DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H)
+DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H)
+DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H)
+DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H)
+DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H)
+DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H)
+DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H)
+DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H)
+DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H)
+DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H)
+DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H)
+DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H)
+DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H)
+DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H)
+DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H)
+DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H)
+DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H)
+DECLARE_CSR(mstatush, CSR_MSTATUSH)
+DECLARE_CSR(mcycleh, CSR_MCYCLEH)
+DECLARE_CSR(minstreth, CSR_MINSTRETH)
+DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H)
+DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H)
+DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H)
+DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H)
+DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H)
+DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H)
+DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H)
+DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H)
+DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H)
+DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H)
+DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H)
+DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H)
+DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H)
+DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H)
+DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H)
+DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H)
+DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H)
+DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H)
+DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H)
+DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H)
+DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H)
+DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H)
+DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H)
+DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H)
+DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H)
+DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H)
+DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H)
+DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H)
+DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H)
+#endif
+#ifdef DECLARE_CAUSE
+DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH)
+DECLARE_CAUSE("fetch access", CAUSE_FETCH_ACCESS)
+DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION)
+DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT)
+DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD)
+DECLARE_CAUSE("load access", CAUSE_LOAD_ACCESS)
+DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE)
+DECLARE_CAUSE("store access", CAUSE_STORE_ACCESS)
+DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL)
+DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL)
+DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL)
+DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL)
+DECLARE_CAUSE("fetch page fault", CAUSE_FETCH_PAGE_FAULT)
+DECLARE_CAUSE("load page fault", CAUSE_LOAD_PAGE_FAULT)
+DECLARE_CAUSE("store page fault", CAUSE_STORE_PAGE_FAULT)
+#endif
diff --git a/test/asm_testsuite/tests/env/p/link.ld b/test/asm_testsuite/tests/env/p/link.ld
new file mode 100644
index 0000000..c30b941
--- /dev/null
+++ b/test/asm_testsuite/tests/env/p/link.ld
@@ -0,0 +1,17 @@
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+SECTIONS
+{
+ . = 0x00010000;
+ .text.init : { *(.text.init) }
+ . = ALIGN(0x1000);
+ .tohost : { *(.tohost) }
+ . = ALIGN(0x1000);
+ .text : { *(.text) }
+ . = ALIGN(0x1000);
+ .data : { *(.data) }
+ .bss : { *(.bss) }
+ _end = .;
+}
+
diff --git a/test/asm_testsuite/tests/env/p/riscv_test.h b/test/asm_testsuite/tests/env/p/riscv_test.h
new file mode 100644
index 0000000..19a9b73
--- /dev/null
+++ b/test/asm_testsuite/tests/env/p/riscv_test.h
@@ -0,0 +1,271 @@
+// See LICENSE for license details.
+
+#ifndef _ENV_PHYSICAL_SINGLE_CORE_H
+#define _ENV_PHYSICAL_SINGLE_CORE_H
+
+#include "../encoding.h"
+
+//-----------------------------------------------------------------------
+// Begin Macro
+//-----------------------------------------------------------------------
+
+#define RVTEST_RV64U \
+ .macro init; \
+ .endm
+
+#define RVTEST_RV64UF \
+ .macro init; \
+ RVTEST_FP_ENABLE; \
+ .endm
+
+#define RVTEST_RV64UV \
+ .macro init; \
+ RVTEST_VECTOR_ENABLE; \
+ .endm
+
+#define RVTEST_RV32U \
+ .macro init; \
+ .endm
+
+#define RVTEST_RV32UF \
+ .macro init; \
+ RVTEST_FP_ENABLE; \
+ .endm
+
+#define RVTEST_RV32UV \
+ .macro init; \
+ RVTEST_VECTOR_ENABLE; \
+ .endm
+
+#define RVTEST_RV64M \
+ .macro init; \
+ RVTEST_ENABLE_MACHINE; \
+ .endm
+
+#define RVTEST_RV64S \
+ .macro init; \
+ RVTEST_ENABLE_SUPERVISOR; \
+ .endm
+
+#define RVTEST_RV32M \
+ .macro init; \
+ RVTEST_ENABLE_MACHINE; \
+ .endm
+
+#define RVTEST_RV32S \
+ .macro init; \
+ RVTEST_ENABLE_SUPERVISOR; \
+ .endm
+
+#if __riscv_xlen == 64
+# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bgez a0, 1f; RVTEST_PASS; 1:
+#else
+# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bltz a0, 1f; RVTEST_PASS; 1:
+#endif
+
+#define INIT_XREG \
+ li x1, 0; \
+ li x2, 0; \
+ li x3, 0; \
+ li x4, 0; \
+ li x5, 0; \
+ li x6, 0; \
+ li x7, 0; \
+ li x8, 0; \
+ li x9, 0; \
+ li x10, 0; \
+ li x11, 0; \
+ li x12, 0; \
+ li x13, 0; \
+ li x14, 0; \
+ li x15, 0; \
+ li x16, 0; \
+ li x17, 0; \
+ li x18, 0; \
+ li x19, 0; \
+ li x20, 0; \
+ li x21, 0; \
+ li x22, 0; \
+ li x23, 0; \
+ li x24, 0; \
+ li x25, 0; \
+ li x26, 0; \
+ li x27, 0; \
+ li x28, 0; \
+ li x29, 0; \
+ li x30, 0; \
+ li x31, 0;
+
+#define INIT_PMP \
+ la t0, 1f; \
+ csrw mtvec, t0; \
+ /* Set up a PMP to permit all accesses */ \
+ li t0, (1 << (31 + (__riscv_xlen / 64) * (53 - 31))) - 1; \
+ csrw pmpaddr0, t0; \
+ li t0, PMP_NAPOT | PMP_R | PMP_W | PMP_X; \
+ csrw pmpcfg0, t0; \
+ .align 2; \
+1:
+
+#define INIT_SATP \
+ la t0, 1f; \
+ csrw mtvec, t0; \
+ csrwi satp, 0; \
+ .align 2; \
+1:
+
+#define DELEGATE_NO_TRAPS \
+ csrwi mie, 0; \
+ la t0, 1f; \
+ csrw mtvec, t0; \
+ csrwi medeleg, 0; \
+ csrwi mideleg, 0; \
+ .align 2; \
+1:
+
+#define RVTEST_ENABLE_SUPERVISOR \
+ li a0, MSTATUS_MPP & (MSTATUS_MPP >> 1); \
+ csrs mstatus, a0; \
+ li a0, SIP_SSIP | SIP_STIP; \
+ csrs mideleg, a0; \
+
+#define RVTEST_ENABLE_MACHINE \
+ li a0, MSTATUS_MPP; \
+ csrs mstatus, a0; \
+
+#define RVTEST_FP_ENABLE \
+ li a0, MSTATUS_FS & (MSTATUS_FS >> 1); \
+ csrs mstatus, a0; \
+ csrwi fcsr, 0
+
+#define RVTEST_VECTOR_ENABLE \
+ li a0, (MSTATUS_VS & (MSTATUS_VS >> 1)) | \
+ (MSTATUS_FS & (MSTATUS_FS >> 1)); \
+ csrs mstatus, a0; \
+ csrwi fcsr, 0; \
+ csrwi vcsr, 0;
+
+#define RISCV_MULTICORE_DISABLE \
+ csrr a0, mhartid; \
+ 1: bnez a0, 1b
+
+#define EXTRA_TVEC_USER
+#define EXTRA_TVEC_MACHINE
+#define EXTRA_INIT
+#define EXTRA_INIT_TIMER
+
+#define INTERRUPT_HANDLER j other_exception /* No interrupts should occur */
+
+#define RVTEST_CODE_BEGIN \
+ .section .text.init; \
+ .align 6; \
+ .weak stvec_handler; \
+ .weak mtvec_handler; \
+ .globl _start; \
+_start: \
+ /* reset vector */ \
+ j reset_vector; \
+ .align 2; \
+trap_vector: \
+ /* test whether the test came from pass/fail */ \
+ csrr t5, mcause; \
+ li t6, CAUSE_USER_ECALL; \
+ beq t5, t6, write_tohost; \
+ li t6, CAUSE_SUPERVISOR_ECALL; \
+ beq t5, t6, write_tohost; \
+ li t6, CAUSE_MACHINE_ECALL; \
+ beq t5, t6, write_tohost; \
+ /* if an mtvec_handler is defined, jump to it */ \
+ la t5, mtvec_handler; \
+ beqz t5, 1f; \
+ jr t5; \
+ /* was it an interrupt or an exception? */ \
+ 1: csrr t5, mcause; \
+ bgez t5, handle_exception; \
+ INTERRUPT_HANDLER; \
+handle_exception: \
+ /* we don't know how to handle whatever the exception was */ \
+ other_exception: \
+ /* some unhandlable exception occurred */ \
+ 1: ori TESTNUM, TESTNUM, 1337; \
+ write_tohost: \
+ sw TESTNUM, tohost, t5; \
+ j write_tohost; \
+reset_vector: \
+ INIT_XREG; \
+ RISCV_MULTICORE_DISABLE; \
+ INIT_SATP; \
+ INIT_PMP; \
+ DELEGATE_NO_TRAPS; \
+ li TESTNUM, 0; \
+ la t0, trap_vector; \
+ csrw mtvec, t0; \
+ CHECK_XLEN; \
+ /* if an stvec_handler is defined, delegate exceptions to it */ \
+ la t0, stvec_handler; \
+ beqz t0, 1f; \
+ csrw stvec, t0; \
+ li t0, (1 << CAUSE_LOAD_PAGE_FAULT) | \
+ (1 << CAUSE_STORE_PAGE_FAULT) | \
+ (1 << CAUSE_FETCH_PAGE_FAULT) | \
+ (1 << CAUSE_MISALIGNED_FETCH) | \
+ (1 << CAUSE_USER_ECALL) | \
+ (1 << CAUSE_BREAKPOINT); \
+ csrw medeleg, t0; \
+1: csrwi mstatus, 0; \
+ init; \
+ EXTRA_INIT; \
+ EXTRA_INIT_TIMER; \
+ la t0, 1f; \
+ csrw mepc, t0; \
+ csrr a0, mhartid; \
+ mret; \
+1:
+
+//-----------------------------------------------------------------------
+// End Macro
+//-----------------------------------------------------------------------
+
+#define RVTEST_CODE_END \
+ ebreak; \
+ unimp
+
+//-----------------------------------------------------------------------
+// Pass/Fail Macro
+//-----------------------------------------------------------------------
+
+#define RVTEST_PASS \
+ fence; \
+ li TESTNUM, 1; \
+ li a7, 93; \
+ li a0, 0; \
+ ebreak
+
+#define TESTNUM gp
+#define RVTEST_FAIL \
+ fence; \
+1: beqz TESTNUM, 1b; \
+ sll TESTNUM, TESTNUM, 1; \
+ or TESTNUM, TESTNUM, 1; \
+ li a7, 93; \
+ addi a0, TESTNUM, 0; \
+ add x31, x31, 1; \
+ ebreak
+
+//-----------------------------------------------------------------------
+// Data Section Macro
+//-----------------------------------------------------------------------
+
+#define EXTRA_DATA
+
+#define RVTEST_DATA_BEGIN \
+ EXTRA_DATA \
+ .pushsection .tohost,"aw",@progbits; \
+ .align 6; .global tohost; tohost: .dword 0; \
+ .align 6; .global fromhost; fromhost: .dword 0; \
+ .popsection; \
+ .align 4; .global begin_signature; begin_signature:
+
+#define RVTEST_DATA_END .align 4; .global end_signature; end_signature:
+
+#endif
diff --git a/test/asm_testsuite/tests/env/pm/link.ld b/test/asm_testsuite/tests/env/pm/link.ld
new file mode 100644
index 0000000..b3e315e
--- /dev/null
+++ b/test/asm_testsuite/tests/env/pm/link.ld
@@ -0,0 +1,17 @@
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+SECTIONS
+{
+ . = 0x80000000;
+ .text.init : { *(.text.init) }
+ . = ALIGN(0x1000);
+ .tohost : { *(.tohost) }
+ . = ALIGN(0x1000);
+ .text : { *(.text) }
+ . = ALIGN(0x1000);
+ .data : { *(.data) }
+ .bss : { *(.bss) }
+ _end = .;
+}
+
diff --git a/test/asm_testsuite/tests/env/pm/riscv_test.h b/test/asm_testsuite/tests/env/pm/riscv_test.h
new file mode 100644
index 0000000..38a0e86
--- /dev/null
+++ b/test/asm_testsuite/tests/env/pm/riscv_test.h
@@ -0,0 +1,11 @@
+// See LICENSE for license details.
+
+#ifndef _ENV_PHYSICAL_MULTI_CORE_H
+#define _ENV_PHYSICAL_MULTI_CORE_H
+
+#include "../p/riscv_test.h"
+
+#undef RISCV_MULTICORE_DISABLE
+#define RISCV_MULTICORE_DISABLE
+
+#endif
diff --git a/test/asm_testsuite/tests/env/pt/link.ld b/test/asm_testsuite/tests/env/pt/link.ld
new file mode 100644
index 0000000..b3e315e
--- /dev/null
+++ b/test/asm_testsuite/tests/env/pt/link.ld
@@ -0,0 +1,17 @@
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+SECTIONS
+{
+ . = 0x80000000;
+ .text.init : { *(.text.init) }
+ . = ALIGN(0x1000);
+ .tohost : { *(.tohost) }
+ . = ALIGN(0x1000);
+ .text : { *(.text) }
+ . = ALIGN(0x1000);
+ .data : { *(.data) }
+ .bss : { *(.bss) }
+ _end = .;
+}
+
diff --git a/test/asm_testsuite/tests/env/pt/riscv_test.h b/test/asm_testsuite/tests/env/pt/riscv_test.h
new file mode 100644
index 0000000..34c2a33
--- /dev/null
+++ b/test/asm_testsuite/tests/env/pt/riscv_test.h
@@ -0,0 +1,69 @@
+// See LICENSE for license details.
+
+#ifndef _ENV_PHYSICAL_SINGLE_CORE_TIMER_H
+#define _ENV_PHYSICAL_SINGLE_CORE_TIMER_H
+
+#include "../p/riscv_test.h"
+
+#define TIMER_INTERVAL 2
+
+#undef EXTRA_INIT_TIMER
+#define EXTRA_INIT_TIMER \
+ li a0, MIP_MTIP; \
+ csrs mie, a0; \
+ csrr a0, mtime; \
+ addi a0, a0, TIMER_INTERVAL; \
+ csrw mtimecmp, a0; \
+
+#if SSTATUS_XS != 0x18000
+# error
+#endif
+#define XS_SHIFT 15
+
+#undef INTERRUPT_HANDLER
+#define INTERRUPT_HANDLER \
+ slli t5, t5, 1; \
+ srli t5, t5, 1; \
+ add t5, t5, -IRQ_M_TIMER; \
+ bnez t5, other_exception; /* other interrups shouldn't happen */\
+ csrr t5, mtime; \
+ addi t5, t5, TIMER_INTERVAL; \
+ csrw mtimecmp, t5; \
+ mret; \
+
+//-----------------------------------------------------------------------
+// Data Section Macro
+//-----------------------------------------------------------------------
+
+#undef EXTRA_DATA
+#define EXTRA_DATA \
+ .align 3; \
+regspill: \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+ .dword 0xdeadbeefcafebabe; \
+evac: \
+ .skip 32768; \
+
+#endif
diff --git a/test/asm_testsuite/tests/env/v/entry.S b/test/asm_testsuite/tests/env/v/entry.S
new file mode 100644
index 0000000..49b2d3e
--- /dev/null
+++ b/test/asm_testsuite/tests/env/v/entry.S
@@ -0,0 +1,162 @@
+#include "riscv_test.h"
+
+#if __riscv_xlen == 64
+# define STORE sd
+# define LOAD ld
+# define REGBYTES 8
+#else
+# define STORE sw
+# define LOAD lw
+# define REGBYTES 4
+#endif
+
+#define STACK_TOP (_end + 4096)
+
+ .section ".text.init","ax",@progbits
+ .globl _start
+ .align 2
+_start:
+ j handle_reset
+
+ /* NMI vector */
+ .align 2
+nmi_vector:
+ j wtf
+
+ .align 2
+trap_vector:
+ j wtf
+
+handle_reset:
+ li x1, 0
+ li x2, 0
+ li x3, 0
+ li x4, 0
+ li x5, 0
+ li x6, 0
+ li x7, 0
+ li x8, 0
+ li x9, 0
+ li x10, 0
+ li x11, 0
+ li x12, 0
+ li x13, 0
+ li x14, 0
+ li x15, 0
+ li x16, 0
+ li x17, 0
+ li x18, 0
+ li x19, 0
+ li x20, 0
+ li x21, 0
+ li x22, 0
+ li x23, 0
+ li x24, 0
+ li x25, 0
+ li x26, 0
+ li x27, 0
+ li x28, 0
+ li x29, 0
+ li x30, 0
+ li x31, 0
+
+ la t0, trap_vector
+ csrw mtvec, t0
+ la sp, STACK_TOP - SIZEOF_TRAPFRAME_T
+ csrr t0, mhartid
+ slli t0, t0, 12
+ add sp, sp, t0
+ csrw mscratch, sp
+ call extra_boot
+ la a0, userstart
+ j vm_boot
+
+ .globl pop_tf
+pop_tf:
+ LOAD t0,33*REGBYTES(a0)
+ csrw sepc,t0
+ LOAD x1,1*REGBYTES(a0)
+ LOAD x2,2*REGBYTES(a0)
+ LOAD x3,3*REGBYTES(a0)
+ LOAD x4,4*REGBYTES(a0)
+ LOAD x5,5*REGBYTES(a0)
+ LOAD x6,6*REGBYTES(a0)
+ LOAD x7,7*REGBYTES(a0)
+ LOAD x8,8*REGBYTES(a0)
+ LOAD x9,9*REGBYTES(a0)
+ LOAD x11,11*REGBYTES(a0)
+ LOAD x12,12*REGBYTES(a0)
+ LOAD x13,13*REGBYTES(a0)
+ LOAD x14,14*REGBYTES(a0)
+ LOAD x15,15*REGBYTES(a0)
+ LOAD x16,16*REGBYTES(a0)
+ LOAD x17,17*REGBYTES(a0)
+ LOAD x18,18*REGBYTES(a0)
+ LOAD x19,19*REGBYTES(a0)
+ LOAD x20,20*REGBYTES(a0)
+ LOAD x21,21*REGBYTES(a0)
+ LOAD x22,22*REGBYTES(a0)
+ LOAD x23,23*REGBYTES(a0)
+ LOAD x24,24*REGBYTES(a0)
+ LOAD x25,25*REGBYTES(a0)
+ LOAD x26,26*REGBYTES(a0)
+ LOAD x27,27*REGBYTES(a0)
+ LOAD x28,28*REGBYTES(a0)
+ LOAD x29,29*REGBYTES(a0)
+ LOAD x30,30*REGBYTES(a0)
+ LOAD x31,31*REGBYTES(a0)
+ LOAD a0,10*REGBYTES(a0)
+ sret
+
+ .global trap_entry
+ .align 2
+trap_entry:
+ csrrw sp, sscratch, sp
+
+ # save gprs
+ STORE x1,1*REGBYTES(sp)
+ STORE x3,3*REGBYTES(sp)
+ STORE x4,4*REGBYTES(sp)
+ STORE x5,5*REGBYTES(sp)
+ STORE x6,6*REGBYTES(sp)
+ STORE x7,7*REGBYTES(sp)
+ STORE x8,8*REGBYTES(sp)
+ STORE x9,9*REGBYTES(sp)
+ STORE x10,10*REGBYTES(sp)
+ STORE x11,11*REGBYTES(sp)
+ STORE x12,12*REGBYTES(sp)
+ STORE x13,13*REGBYTES(sp)
+ STORE x14,14*REGBYTES(sp)
+ STORE x15,15*REGBYTES(sp)
+ STORE x16,16*REGBYTES(sp)
+ STORE x17,17*REGBYTES(sp)
+ STORE x18,18*REGBYTES(sp)
+ STORE x19,19*REGBYTES(sp)
+ STORE x20,20*REGBYTES(sp)
+ STORE x21,21*REGBYTES(sp)
+ STORE x22,22*REGBYTES(sp)
+ STORE x23,23*REGBYTES(sp)
+ STORE x24,24*REGBYTES(sp)
+ STORE x25,25*REGBYTES(sp)
+ STORE x26,26*REGBYTES(sp)
+ STORE x27,27*REGBYTES(sp)
+ STORE x28,28*REGBYTES(sp)
+ STORE x29,29*REGBYTES(sp)
+ STORE x30,30*REGBYTES(sp)
+ STORE x31,31*REGBYTES(sp)
+
+ csrrw t0,sscratch,sp
+ STORE t0,2*REGBYTES(sp)
+
+ # get sr, epc, badvaddr, cause
+ csrr t0,sstatus
+ STORE t0,32*REGBYTES(sp)
+ csrr t0,sepc
+ STORE t0,33*REGBYTES(sp)
+ csrr t0,stval
+ STORE t0,34*REGBYTES(sp)
+ csrr t0,scause
+ STORE t0,35*REGBYTES(sp)
+
+ move a0, sp
+ j handle_trap
diff --git a/test/asm_testsuite/tests/env/v/link.ld b/test/asm_testsuite/tests/env/v/link.ld
new file mode 100644
index 0000000..b3e315e
--- /dev/null
+++ b/test/asm_testsuite/tests/env/v/link.ld
@@ -0,0 +1,17 @@
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+SECTIONS
+{
+ . = 0x80000000;
+ .text.init : { *(.text.init) }
+ . = ALIGN(0x1000);
+ .tohost : { *(.tohost) }
+ . = ALIGN(0x1000);
+ .text : { *(.text) }
+ . = ALIGN(0x1000);
+ .data : { *(.data) }
+ .bss : { *(.bss) }
+ _end = .;
+}
+
diff --git a/test/asm_testsuite/tests/env/v/riscv_test.h b/test/asm_testsuite/tests/env/v/riscv_test.h
new file mode 100644
index 0000000..c74e05d
--- /dev/null
+++ b/test/asm_testsuite/tests/env/v/riscv_test.h
@@ -0,0 +1,80 @@
+// See LICENSE for license details.
+
+#ifndef _ENV_VIRTUAL_SINGLE_CORE_H
+#define _ENV_VIRTUAL_SINGLE_CORE_H
+
+#include "../p/riscv_test.h"
+
+//-----------------------------------------------------------------------
+// Begin Macro
+//-----------------------------------------------------------------------
+
+#undef RVTEST_FP_ENABLE
+#define RVTEST_FP_ENABLE fssr x0
+
+#undef RVTEST_VECTOR_ENABLE
+#define RVTEST_VECTOR_ENABLE \
+ csrwi fcsr, 0; \
+ csrwi vcsr, 0;
+
+#undef RVTEST_CODE_BEGIN
+#define RVTEST_CODE_BEGIN \
+ .text; \
+ .global extra_boot; \
+extra_boot: \
+ EXTRA_INIT \
+ ret; \
+ .global userstart; \
+userstart: \
+ init
+
+//-----------------------------------------------------------------------
+// Pass/Fail Macro
+//-----------------------------------------------------------------------
+
+#undef RVTEST_PASS
+#define RVTEST_PASS li a0, 1; scall
+
+#undef RVTEST_FAIL
+#define RVTEST_FAIL sll a0, TESTNUM, 1; 1:beqz a0, 1b; or a0, a0, 1; scall;
+
+//-----------------------------------------------------------------------
+// Data Section Macro
+//-----------------------------------------------------------------------
+
+#undef RVTEST_DATA_END
+#define RVTEST_DATA_END
+
+//-----------------------------------------------------------------------
+// Supervisor mode definitions and macros
+//-----------------------------------------------------------------------
+
+#define MAX_TEST_PAGES 63 // this must be the period of the LFSR below
+#define LFSR_NEXT(x) (((((x)^((x)>>1)) & 1) << 5) | ((x) >> 1))
+
+#define PGSHIFT 12
+#define PGSIZE (1UL << PGSHIFT)
+
+#define SIZEOF_TRAPFRAME_T ((__riscv_xlen / 8) * 36)
+
+#ifndef __ASSEMBLER__
+
+typedef unsigned long pte_t;
+#define LEVELS (sizeof(pte_t) == sizeof(uint64_t) ? 3 : 2)
+#define PTIDXBITS (PGSHIFT - (sizeof(pte_t) == 8 ? 3 : 2))
+#define VPN_BITS (PTIDXBITS * LEVELS)
+#define VA_BITS (VPN_BITS + PGSHIFT)
+#define PTES_PER_PT (1UL << RISCV_PGLEVEL_BITS)
+#define MEGAPAGE_SIZE (PTES_PER_PT * PGSIZE)
+
+typedef struct
+{
+ long gpr[32];
+ long sr;
+ long epc;
+ long badvaddr;
+ long cause;
+} trapframe_t;
+#endif
+
+#endif
diff --git a/test/asm_testsuite/tests/env/v/string.c b/test/asm_testsuite/tests/env/v/string.c
new file mode 100644
index 0000000..4ffedc0
--- /dev/null
+++ b/test/asm_testsuite/tests/env/v/string.c
@@ -0,0 +1,114 @@
+#include
+#include
+#include
+
+void* memcpy(void* dest, const void* src, size_t len)
+{
+ if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t)-1)) == 0) {
+ const uintptr_t* s = src;
+ uintptr_t *d = dest;
+ while (d < (uintptr_t*)(dest + len))
+ *d++ = *s++;
+ } else {
+ const char* s = src;
+ char *d = dest;
+ while (d < (char*)(dest + len))
+ *d++ = *s++;
+ }
+ return dest;
+}
+
+void* memset(void* dest, int byte, size_t len)
+{
+ if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) {
+ uintptr_t word = byte & 0xFF;
+ word |= word << 8;
+ word |= word << 16;
+ word |= word << 16 << 16;
+
+ uintptr_t *d = dest;
+ while (d < (uintptr_t*)(dest + len))
+ *d++ = word;
+ } else {
+ char *d = dest;
+ while (d < (char*)(dest + len))
+ *d++ = byte;
+ }
+ return dest;
+}
+
+size_t strlen(const char *s)
+{
+ const char *p = s;
+ while (*p)
+ p++;
+ return p - s;
+}
+
+int strcmp(const char* s1, const char* s2)
+{
+ unsigned char c1, c2;
+
+ do {
+ c1 = *s1++;
+ c2 = *s2++;
+ } while (c1 != 0 && c1 == c2);
+
+ return c1 - c2;
+}
+
+int memcmp(const void* s1, const void* s2, size_t n)
+{
+ if ((((uintptr_t)s1 | (uintptr_t)s2) & (sizeof(uintptr_t)-1)) == 0) {
+ const uintptr_t* u1 = s1;
+ const uintptr_t* u2 = s2;
+ const uintptr_t* end = u1 + (n / sizeof(uintptr_t));
+ while (u1 < end) {
+ if (*u1 != *u2)
+ break;
+ u1++;
+ u2++;
+ }
+ n -= (const void*)u1 - s1;
+ s1 = u1;
+ s2 = u2;
+ }
+
+ while (n--) {
+ unsigned char c1 = *(const unsigned char*)s1++;
+ unsigned char c2 = *(const unsigned char*)s2++;
+ if (c1 != c2)
+ return c1 - c2;
+ }
+
+ return 0;
+}
+
+char* strcpy(char* dest, const char* src)
+{
+ char* d = dest;
+ while ((*d++ = *src++))
+ ;
+ return dest;
+}
+
+long atol(const char* str)
+{
+ long res = 0;
+ int sign = 0;
+
+ while (*str == ' ')
+ str++;
+
+ if (*str == '-' || *str == '+') {
+ sign = *str == '-';
+ str++;
+ }
+
+ while (*str) {
+ res *= 10;
+ res += *str++ - '0';
+ }
+
+ return sign ? -res : res;
+}
diff --git a/test/asm_testsuite/tests/env/v/vm.c b/test/asm_testsuite/tests/env/v/vm.c
new file mode 100644
index 0000000..9802fb7
--- /dev/null
+++ b/test/asm_testsuite/tests/env/v/vm.c
@@ -0,0 +1,300 @@
+// See LICENSE for license details.
+
+#include
+#include
+#include
+
+#include "riscv_test.h"
+
+#if __riscv_xlen == 32
+# define SATP_MODE_CHOICE SATP_MODE_SV32
+#elif defined(Sv48)
+# define SATP_MODE_CHOICE SATP_MODE_SV48
+#else
+# define SATP_MODE_CHOICE SATP_MODE_SV39
+#endif
+
+void trap_entry();
+void pop_tf(trapframe_t*);
+
+extern volatile uint64_t tohost;
+extern volatile uint64_t fromhost;
+
+static void do_tohost(uint64_t tohost_value)
+{
+ while (tohost)
+ fromhost = 0;
+ tohost = tohost_value;
+}
+
+#define pa2kva(pa) ((void*)(pa) - DRAM_BASE - MEGAPAGE_SIZE)
+#define uva2kva(pa) ((void*)(pa) - MEGAPAGE_SIZE)
+
+#define flush_page(addr) asm volatile ("sfence.vma %0" : : "r" (addr) : "memory")
+
+static uint64_t lfsr63(uint64_t x)
+{
+ uint64_t bit = (x ^ (x >> 1)) & 1;
+ return (x >> 1) | (bit << 62);
+}
+
+static void cputchar(int x)
+{
+ do_tohost(0x0101000000000000 | (unsigned char)x);
+}
+
+static void cputstring(const char* s)
+{
+ while (*s)
+ cputchar(*s++);
+}
+
+static void terminate(int code)
+{
+ do_tohost(code);
+ while (1);
+}
+
+void wtf()
+{
+ terminate(841);
+}
+
+#define stringify1(x) #x
+#define stringify(x) stringify1(x)
+#define assert(x) do { \
+ if (x) break; \
+ cputstring("Assertion failed: " stringify(x) "\n"); \
+ terminate(3); \
+} while(0)
+
+#define l1pt pt[0]
+#define user_l2pt pt[1]
+#if SATP_MODE_CHOICE == SATP_MODE_SV48
+# define NPT 6
+# define kernel_l2pt pt[2]
+# define kernel_l3pt pt[3]
+# define user_l3pt pt[4]
+# define user_llpt pt[5]
+#elif SATP_MODE_CHOICE == SATP_MODE_SV39
+# define NPT 4
+# define kernel_l2pt pt[2]
+# define user_llpt pt[3]
+#elif SATP_MODE_CHOICE == SATP_MODE_SV32
+# define NPT 2
+# define user_llpt user_l2pt
+#else
+# error Unknown SATP_MODE_CHOICE
+#endif
+pte_t pt[NPT][PTES_PER_PT] __attribute__((aligned(PGSIZE)));
+
+typedef struct { pte_t addr; void* next; } freelist_t;
+
+freelist_t user_mapping[MAX_TEST_PAGES];
+freelist_t freelist_nodes[MAX_TEST_PAGES];
+freelist_t *freelist_head, *freelist_tail;
+
+void printhex(uint64_t x)
+{
+ char str[17];
+ for (int i = 0; i < 16; i++)
+ {
+ str[15-i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a'-10);
+ x >>= 4;
+ }
+ str[16] = 0;
+
+ cputstring(str);
+}
+
+static void evict(unsigned long addr)
+{
+ assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
+ addr = addr/PGSIZE*PGSIZE;
+
+ freelist_t* node = &user_mapping[addr/PGSIZE];
+ if (node->addr)
+ {
+ // check accessed and dirty bits
+ assert(user_llpt[addr/PGSIZE] & PTE_A);
+ uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM);
+ if (memcmp((void*)addr, uva2kva(addr), PGSIZE)) {
+ assert(user_llpt[addr/PGSIZE] & PTE_D);
+ memcpy((void*)addr, uva2kva(addr), PGSIZE);
+ }
+ write_csr(sstatus, sstatus);
+
+ user_mapping[addr/PGSIZE].addr = 0;
+
+ if (freelist_tail == 0)
+ freelist_head = freelist_tail = node;
+ else
+ {
+ freelist_tail->next = node;
+ freelist_tail = node;
+ }
+ }
+}
+
+void handle_fault(uintptr_t addr, uintptr_t cause)
+{
+ assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
+ addr = addr/PGSIZE*PGSIZE;
+
+ if (user_llpt[addr/PGSIZE]) {
+ if (!(user_llpt[addr/PGSIZE] & PTE_A)) {
+ user_llpt[addr/PGSIZE] |= PTE_A;
+ } else {
+ assert(!(user_llpt[addr/PGSIZE] & PTE_D) && cause == CAUSE_STORE_PAGE_FAULT);
+ user_llpt[addr/PGSIZE] |= PTE_D;
+ }
+ flush_page(addr);
+ return;
+ }
+
+ freelist_t* node = freelist_head;
+ assert(node);
+ freelist_head = node->next;
+ if (freelist_head == freelist_tail)
+ freelist_tail = 0;
+
+ uintptr_t new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X;
+ user_llpt[addr/PGSIZE] = new_pte | PTE_A | PTE_D;
+ flush_page(addr);
+
+ assert(user_mapping[addr/PGSIZE].addr == 0);
+ user_mapping[addr/PGSIZE] = *node;
+
+ uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM);
+ memcpy((void*)addr, uva2kva(addr), PGSIZE);
+ write_csr(sstatus, sstatus);
+
+ user_llpt[addr/PGSIZE] = new_pte;
+ flush_page(addr);
+
+ asm volatile ("fence.i");
+}
+
+void handle_trap(trapframe_t* tf)
+{
+ if (tf->cause == CAUSE_USER_ECALL)
+ {
+ int n = tf->gpr[10];
+
+ for (long i = 1; i < MAX_TEST_PAGES; i++)
+ evict(i*PGSIZE);
+
+ terminate(n);
+ }
+ else if (tf->cause == CAUSE_ILLEGAL_INSTRUCTION)
+ {
+ assert(tf->epc % 4 == 0);
+
+ int* fssr;
+ asm ("jal %0, 1f; fssr x0; 1:" : "=r"(fssr));
+
+ if (*(int*)tf->epc == *fssr)
+ terminate(1); // FP test on non-FP hardware. "succeed."
+ else
+ assert(!"illegal instruction");
+ tf->epc += 4;
+ }
+ else if (tf->cause == CAUSE_FETCH_PAGE_FAULT || tf->cause == CAUSE_LOAD_PAGE_FAULT || tf->cause == CAUSE_STORE_PAGE_FAULT)
+ handle_fault(tf->badvaddr, tf->cause);
+ else
+ assert(!"unexpected exception");
+
+ pop_tf(tf);
+}
+
+static void coherence_torture()
+{
+ // cause coherence misses without affecting program semantics
+ uint64_t random = ENTROPY;
+ while (1) {
+ uintptr_t paddr = DRAM_BASE + ((random % (2 * (MAX_TEST_PAGES + 1) * PGSIZE)) & -4);
+#ifdef __riscv_atomic
+ if (random & 1) // perform a no-op write
+ asm volatile ("amoadd.w zero, zero, (%0)" :: "r"(paddr));
+ else // perform a read
+#endif
+ asm volatile ("lw zero, (%0)" :: "r"(paddr));
+ random = lfsr63(random);
+ }
+}
+
+void vm_boot(uintptr_t test_addr)
+{
+ uint64_t random = ENTROPY;
+ if (read_csr(mhartid) > 0)
+ coherence_torture();
+
+ _Static_assert(SIZEOF_TRAPFRAME_T == sizeof(trapframe_t), "???");
+
+#if (MAX_TEST_PAGES > PTES_PER_PT) || (DRAM_BASE % MEGAPAGE_SIZE) != 0
+# error
+#endif
+ // map user to lowermost megapage
+ l1pt[0] = ((pte_t)user_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+ // map kernel to uppermost megapage
+#if SATP_MODE_CHOICE == SATP_MODE_SV48
+ l1pt[PTES_PER_PT-1] = ((pte_t)kernel_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+ kernel_l2pt[PTES_PER_PT-1] = ((pte_t)kernel_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+ kernel_l3pt[PTES_PER_PT-1] = (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D;
+ user_l2pt[0] = ((pte_t)user_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+ user_l3pt[0] = ((pte_t)user_llpt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+#elif SATP_MODE_CHOICE == SATP_MODE_SV39
+ l1pt[PTES_PER_PT-1] = ((pte_t)kernel_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+ kernel_l2pt[PTES_PER_PT-1] = (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D;
+ user_l2pt[0] = ((pte_t)user_llpt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
+#elif SATP_MODE_CHOICE == SATP_MODE_SV32
+ l1pt[PTES_PER_PT-1] = (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D;
+#else
+# error
+#endif
+ uintptr_t vm_choice = SATP_MODE_CHOICE;
+ uintptr_t satp_value = ((uintptr_t)l1pt >> PGSHIFT)
+ | (vm_choice * (SATP_MODE & ~(SATP_MODE<<1)));
+ write_csr(satp, satp_value);
+ if (read_csr(satp) != satp_value)
+ assert(!"unsupported satp mode");
+
+ // Set up PMPs if present, ignoring illegal instruction trap if not.
+ uintptr_t pmpc = PMP_NAPOT | PMP_R | PMP_W | PMP_X;
+ uintptr_t pmpa = ((uintptr_t)1 << (__riscv_xlen == 32 ? 31 : 53)) - 1;
+ asm volatile ("la t0, 1f\n\t"
+ "csrrw t0, mtvec, t0\n\t"
+ "csrw pmpaddr0, %1\n\t"
+ "csrw pmpcfg0, %0\n\t"
+ ".align 2\n\t"
+ "1: csrw mtvec, t0"
+ : : "r" (pmpc), "r" (pmpa) : "t0");
+
+ // set up supervisor trap handling
+ write_csr(stvec, pa2kva(trap_entry));
+ write_csr(sscratch, pa2kva(read_csr(mscratch)));
+ write_csr(medeleg,
+ (1 << CAUSE_USER_ECALL) |
+ (1 << CAUSE_FETCH_PAGE_FAULT) |
+ (1 << CAUSE_LOAD_PAGE_FAULT) |
+ (1 << CAUSE_STORE_PAGE_FAULT));
+ // FPU on; accelerator on; vector unit on
+ write_csr(mstatus, MSTATUS_FS | MSTATUS_XS | MSTATUS_VS);
+ write_csr(mie, 0);
+
+ random = 1 + (random % MAX_TEST_PAGES);
+ freelist_head = pa2kva((void*)&freelist_nodes[0]);
+ freelist_tail = pa2kva(&freelist_nodes[MAX_TEST_PAGES-1]);
+ for (long i = 0; i < MAX_TEST_PAGES; i++)
+ {
+ freelist_nodes[i].addr = DRAM_BASE + (MAX_TEST_PAGES + random)*PGSIZE;
+ freelist_nodes[i].next = pa2kva(&freelist_nodes[i+1]);
+ random = LFSR_NEXT(random);
+ }
+ freelist_nodes[MAX_TEST_PAGES-1].next = 0;
+
+ trapframe_t tf;
+ memset(&tf, 0, sizeof(tf));
+ tf.epc = test_addr - DRAM_BASE;
+ pop_tf(&tf);
+}