[
  {
    "path": ".clang-format",
    "content": "﻿---\nBasedOnStyle: Google\nColumnLimit: '120'\nAllowShortCaseLabelsOnASingleLine: 'false'\nAllowShortFunctionsOnASingleLine: Empty\nAllowShortIfStatementsOnASingleLine: 'false'\nIndentWidth: '4'\nTabWidth: '4'\nUseTab: ForIndentation\n...\n"
  },
  {
    "path": ".gitignore",
    "content": ".cproject\n.project\n.settings/\nmain\nbuild/\nvp/dependencies/systemc-dist/\n*.bin\nsystemc-*\n*.asm\n**/nbproject/private/\n**/nbproject/Makefile-*.mk\n**/nbproject/Package-*.bash\nbuild/\nnbbuild/\ndist/\nnbdist/\n.nb-gradle/\nnbproject/\nsw/basic-gcov/main.*\nsw/**/*.o\n"
  },
  {
    "path": ".gitlab-ci.yml",
    "content": "image: alpine:3.19\n\nvariables:\n  GIT_SUBMODULE_STRATEGY: recursive\n\ncache:\n  key: $CI_COMMIT_REF_SLUG\n  paths:\n    - vp/build\n\ndefault:\n  before_script:\n    - apk update && apk add --no-cache build-base git boost-dev cmake git gdb-multiarch g++-riscv-none-elf gcc-riscv-none-elf newlib-riscv-none-elf valgrind socat\n    - export RISCV_PREFIX=riscv-none-elf-\n\nbuild-vp:\n  stage: build\n  script:\n    - sh -c 'env MAKEFLAGS=-j$(nproc) make'\n  artifacts:\n    paths:\n      - vp/build/bin\n    expire_in: 24h\n  only:\n    - master\n    - merge_requests\n\ntest-vp:\n  stage: test\n  script:\n    - cd vp/build\n    - ctest -V\n  only:\n    - master\n    - merge_requests\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"vp/src/core/common/gdb-mc/parser/mpc\"]\n\tpath = vp/src/core/common/gdb-mc/libgdb/mpc\n\turl = https://github.com/orangeduck/mpc\n[submodule \"tests/integration\"]\n\tpath = vp/tests\n\turl = https://github.com/agra-uni-bremen/vp-integration-tests.git\n[submodule \"vp/src/platform/hwitl/virtual-bus\"]\n\tpath = vp/src/platform/hwitl/virtual-bus\n\turl = https://github.com/agra-uni-bremen/virtual-bus\n[submodule \"vp/src/platform/hifive/vbb-protocol\"]\n\tpath = vp/src/platform/hifive/vbb-protocol\n\turl = https://github.com/agra-uni-bremen/virtual-breadboard-protocol.git\n[submodule \"vp/src/vendor/systemc\"]\n\tpath = vp/src/vendor/systemc\n\turl = https://github.com/accellera-official/systemc.git\n"
  },
  {
    "path": "CITATION.cff",
    "content": "# This CITATION.cff file was generated with cffinit.\n# Visit https://bit.ly/cffinit to generate yours today!\n\ncff-version: 1.2.0\ntitle: RISC-V VP\nmessage: >-\n  If you want to cite this software, please use the metadata from this file.\ntype: software\nauthors:\n  - given-names: Vladimir\n    family-names: Herdt\n    email: riscv@informatik.uni-bremen.de\n    affiliation: University of Bremen\n    orcid: 'https://orcid.org/0000-0002-4481-057X'\n  - given-names: Group of Computer Architecture\n    email: riscv@informatik.uni-bremen.de\n    affiliation: University of Bremen\n  - given-names: Rolf\n    family-names: Drechsler\n    email: drechsler@uni-bremen.de\n    affiliation: University of Bremen\n    orcid: 'https://orcid.org/0000-0002-9872-1740'\nidentifiers:\n  - type: doi\n    value: 10.1016/j.sysarc.2020.101756\n    description: >-\n      RISC-V based virtual prototype: An extensible and configurable platform for the system-level\nrepository-code: 'hhttps://github.com/agra-uni-bremen/riscv-vp'\nabstract: >-\n  RISC-V based virtual prototype: An extensible and configurable platform for the system-level \nlicense: MIT\n"
  },
  {
    "path": "Dockerfile",
    "content": "# XXX: Need Alpine Linux Edge since the latest release (3.19)\n# only ships SystemC 2.3.3 and does hence not support aarch64.\nFROM alpine:edge\n\nRUN apk update && apk add --no-cache  build-base cmake boost-dev \\\n\tsystemc-dev systemc-static git gcc-riscv-none-elf \\\n\tg++-riscv-none-elf newlib-riscv-none-elf gdb-multiarch\n\nRUN adduser -G users -g 'RISC-V VP User' -D riscv-vp\nADD --chown=riscv-vp:users . /home/riscv-vp/riscv-vp\nRUN su - riscv-vp -c 'env USE_SYSTEM_SYSTEMC=ON MAKEFLAGS=\"-j$(nproc)\" make -C /home/riscv-vp/riscv-vp'\nRUN su - riscv-vp -c 'echo export RISCV_PREFIX=\\\"riscv-none-elf-\\\" >> /home/riscv-vp/.profile'\nRUN su - riscv-vp -c 'echo export PATH=\\\"$PATH:/home/riscv-vp/riscv-vp/vp/build/bin\\\" >> /home/riscv-vp/.profile'\nCMD su - riscv-vp\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2017-2018 Group of Computer Architecture, University of Bremen <riscv@systemc-verification.org>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": "MAKEFLAGS += --no-print-directory\n\n# Whether to use a system-wide SystemC library instead of the vendored one.\nUSE_SYSTEM_SYSTEMC ?= OFF\n\nvps: vp/src/core/common/gdb-mc/libgdb/mpc/mpc.c vp/build/Makefile\n\t$(MAKE) install -C vp/build\n\nvp/src/core/common/gdb-mc/libgdb/mpc/mpc.c:\n\tgit submodule update --init vp/src/core/common/gdb-mc/libgdb/mpc\n\nall: vps vp-display\n\nvp/build/Makefile:\n\tmkdir -p vp/build\n\tcd vp/build && cmake -DUSE_SYSTEM_SYSTEMC=$(USE_SYSTEM_SYSTEMC) ..\n\nvp-eclipse:\n\tmkdir -p vp-eclipse\n\tcd vp-eclipse && cmake ../vp/ -G \"Eclipse CDT4 - Unix Makefiles\"\n\nenv/basic/vp-display/build/Makefile:\n\tmkdir -p env/basic/vp-display/build\n\tcd env/basic/vp-display/build && cmake ..\n\nvp-display: env/basic/vp-display/build/Makefile\n\t$(MAKE) -C env/basic/vp-display/build\n\nvp-clean:\n\trm -rf vp/build\n\nqt-clean:\n\trm -rf env/basic/vp-display/build\n\nclean-all: vp-clean qt-clean\n\nclean: vp-clean\n\ncodestyle:\n\tfind . -type d \\( -name .git -o -name dependencies \\) -prune -o -name '*.h' -o -name '*.hpp' -o -name '*.cpp' -print | xargs clang-format -i -style=file\n"
  },
  {
    "path": "README.md",
    "content": "# RISC-V based Virtual Prototype (VP)\n\n<p align=\"center\">\n  <img src=\"./img/riscv-vp_logo.png\" alt=\"RISC-V based Virtual Prototype (VP)\" width=\"250\"/>\n</p>\n\n### Key features of our VP:\n\n - RV32GC and RV64GC core support (i.e. RV32IMAFDC and RV64IMAFDC)\n - Implemented in SystemC TLM-2.0\n - SW debug capabilities (GDB RSP interface) with Eclipse\n - Virtual Breadboard GUI (interactive IO) featuring C++ and Lua modeled digital devices (separate repository)\n - FreeRTOS, RIOT, Zephyr, Linux support\n - Generic and configurable bus\n - CLINT and PLIC-based interrupt controller + additional peripherals\n - Instruction-based timing model + annotated TLM 2.0 transaction delays\n - Peripherals, e.g. display, flash controller, preliminary ethernet\n - Example configuration for the SiFive HiFive1 (currently only Rev. A) board available\n - Support for simulation of multi-core platforms\n - Machine-, Supervisor- and User-mode (including user traps) privilege levels and CSRs\n - Virtual memory support (Sv32, Sv39, Sv48)\n\nFor related information, e.g. verification, please visit https://www.informatik.uni-bremen.de/agra/projects/risc-v/ or contact <riscv@informatik.uni-bremen.de>. \nWe accept pull requests and in general contributions are very welcome.\nIf you are using the RISC-V VP in a scientific paper, please cite https://doi.org/10.1016/j.sysarc.2020.101756. For the Virtual Breadboard GUI, please refer to https://www.mdpi.com/2079-9268/12/4/52.\n\n\nIn the following we provide build instructions and how to compile and run software on the VP.\n\n\n#### 1) Build requirements\n\nMainly the usual build tools and boost is required:\n\nOn Ubuntu 20, install these:\n```bash\nsudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo libgoogle-perftools-dev libtool patchutils bc zlib1g-dev libexpat-dev libboost-iostreams-dev libboost-program-options-dev libboost-log-dev qt5-default\n```\n\nOn Fedora, following actions are required:\n```bash\nsudo dnf install autoconf automake curl libmpc-devel mpfr-devel gmp-devel gawk bison flex texinfo gperf libtool patchutils bc zlib-devel expat-devel cmake boost-devel qt5-qtbase qt5-qtbase-devel\nsudo dnf groupinstall \"C Development Tools and Libraries\"\n#optional debuginfo\nsudo dnf debuginfo-install boost-iostreams boost-program-options boost-regex bzip2-libs glibc libgcc libicu libstdc++ zlib\n```\n\n#### 2) Build this RISC-V Virtual Prototype:\n\n\nCheck out all submodules (`git submodule update --init --recursive`), and type `make all`. This script does the following for you:\n\n>\n>i) in *vp/dependencies* folder (will download and compile SystemC, and build a local version of the softfloat library):\n>\n>```bash\n>./build_systemc_233.sh\n>./build_softfloat.sh\n>```\n>\n>\n>ii) in *vp* folder (requires the *boost* C++ library):\n> \n>```bash\n>mkdir build\n>cd build\n>cmake ..\n>make install\n>```\n\n#### 3) Building the interactive environment GUI (`vp-breadboard`)\n\nThe GUI for interacting with the VP has moved to [https://github.com/agra-uni-bremen/virtual-breadboard](https://github.com/agra-uni-bremen/virtual-breadboard).\n\n#### 3) Building SW examples using the GNU toolchain\n\n##### Requirements\n\nIn order to test the software examples, a configured RISC-V GNU toolchain is required in your `$PATH`.\nSeveral standard packages are required to build the toolchain.\nFor more information on prerequisites for the RISC-V GNU toolchain visit https://github.com/riscv/riscv-gnu-toolchain.\nWith the packages installed, the toolchain can be build as follows:\n\n```bash\n# in some source folder\ngit clone https://github.com/riscv/riscv-gnu-toolchain.git\ncd riscv-gnu-toolchain\ngit submodule update --init --recursive # this may take a while\n./configure --prefix=$(pwd)/../riscv-gnu-toolchain-dist-rv32imac-ilp32 --with-arch=rv32imac --with-abi=ilp32\nmake -j$(nproc)\n```\n\nIf wanted, move the `riscv-gnu-toolchain-dist-rv32imac-ilp32` folder to your `/opt/` folder and add it to your path in your `~/.bashrc`\n(e.g. `PATH=$PATH:/opt/riscv-gnu-toolchain-dist-rv32imac-ilp32/bin`)\n\n##### Running the examples\n\nIn *sw*:\n\n```bash\ncd simple-sensor    # can be replaced with different example\nmake                # (requires RISC-V GNU toolchain in PATH)\nmake sim            # (requires *riscv-vp*, i.e. *vp/build/bin/riscv-vp*, executable in PATH)\n```\n\nPlease note, if *make* is called without the *install* argument in step 2, then the *riscv-vp* executable is available in *vp/build/src/platform/basic/riscv-vp*.\n\n\n\nThis will also copy the VP binaries into the *vp/build/bin* folder.\n\n#### Alternative Setup: Docker\n\nInstead of compiling the riscv-vp manually, a `Dockerfile` is also\nprovided which eases this process. In order to build a Docker image from\nthis file run the following command:\n\n\t$ docker build -t riscv-vp .\n\nAfterwards, start a new Docker container using:\n\n\t$ docker run --rm -it riscv-vp\n\nWithin this Docker container, the riscv-vp source tree is available in\n`/home/riscv-vp/riscv-vp/`. A RISC-V cross compiler toolchain is also\npart of the container. As such, it is possible to compile and run any of\nthe examples from the `./sw` subdirectory in this container. For\nexample:\n\n\t$ cd /home/riscv-vp/riscv-vp/sw/basic-c/\n\t$ make\n\t$ make sim\n\n#### FAQ\n\n**Q:** How do I exit the VP?\n\n**A:** All VPs use the input TTY in raw mode and forward all control\ncharacters to the guest. For this reason, one cannot use Ctrl-c to exit\nthe VP. Instead, press Ctrl-a to enter command mode and press Ctrl-x to\nexit the VP.\n\n**Q:** How do I emit a Ctrl-a control character?\n\n**A:** Enter control mode using Ctrl-a and press Ctrl-a again to send a\nliteral Ctrl-a control character to the guest.\n\n#### Acknowledgements:\n\nThis work was supported in part by the German Federal Ministry of Education and Research (BMBF) within the project CONFIRM under contract no. 16ES0565 and within the project SATiSFy under contract no. 16KIS0821K and within the project VerSys under contract no. 01IW19001 and within the project Scale4Edge under contract no. 16ME0127, and by the University of Bremen’s graduate school SyDe, funded by the German Excellence Initiative.\n"
  },
  {
    "path": "env/basic/vp-display/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.1.0)\nproject(vp-display) # Your project name\n\nset(CMAKE_CXX_STANDARD 11) # This is equal to QMAKE_CXX_FLAGS += -std=c++0x\n\n\n# Find includes in corresponding build directories\nset(CMAKE_INCLUDE_CURRENT_DIR ON)\nset(CMAKE_AUTOMOC ON)\nset(CMAKE_AUTOUIC ON)\n\n\nfind_package(Qt5Widgets CONFIG REQUIRED)\n\nset(SOURCES\n\tmain.cpp\n\tmainwindow.cpp\n    vpdisplayserver.cpp\n)\n\nset(HEADERS\n\tmainwindow.h\n\tvpdisplayserver.h\n\tframebuffer.h\n)\n\nset(UI mainwindow.ui)\n\nadd_executable(vp-display ${SOURCES} ${HEADERS} ${UI})\n\ntarget_link_libraries(vp-display Qt5::Widgets pthread)\n\n"
  },
  {
    "path": "env/basic/vp-display/VP-Display.pro",
    "content": "#-------------------------------------------------\n#\n# Project created by QtCreator 2018-09-10T15:30:06\n#\n#-------------------------------------------------\n\nQT       += core gui\n\ngreaterThan(QT_MAJOR_VERSION, 4): QT += widgets\n\nTARGET = VP-Display\nTEMPLATE = app\nCONFIG += c++11\n\n# The following define makes your compiler emit warnings if you use\n# any feature of Qt which has been marked as deprecated (the exact warnings\n# depend on your compiler). Please consult the documentation of the\n# deprecated API in order to know how to port your code away from it.\nDEFINES += QT_DEPRECATED_WARNINGS\n\n# You can also make your code fail to compile if you use deprecated APIs.\n# In order to do so, uncomment the following line.\n# You can also select to disable deprecated APIs only up to a certain version of Qt.\n#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0\n\n\nSOURCES += \\\n        main.cpp \\\n        mainwindow.cpp \\\n    vpdisplayserver.cpp\n\nHEADERS += \\\n        mainwindow.h \\\n    vpdisplayserver.h \\\n    framebuffer.h\n\nFORMS += \\\n        mainwindow.ui\n"
  },
  {
    "path": "env/basic/vp-display/framebuffer.h",
    "content": "#pragma once\n#include <inttypes.h>\n#include <cassert>\n#include <cstring>\n\n#define SHMKEY 1338\n\nstruct Framebuffer {\n\tstatic constexpr uint16_t screenWidth = 800;\n\tstatic constexpr uint16_t screenHeight = 600;\n\n\ttypedef uint16_t Color;\n\n\tstruct Point {\n\t\tuint32_t x;\n\t\tuint32_t y;\n\t\tinline Point() : x(0), y(0){};\n\t\tinline Point(uint32_t x, uint32_t y) : x(x), y(y){};\n\t};\n\n\tstruct PointF {\n\t\tfloat x;\n\t\tfloat y;\n\t\tinline PointF() : x(0), y(0){};\n\t\tinline PointF(float x, float y) : x(x), y(y){};\n\t\tinline PointF(Point p) : x(p.x), y(p.y){};\n\t};\n\n\tstruct Frame {\n\t\tColor raw[screenHeight][screenWidth];  // Notice: Screen is on side\n\t};\n\n\tenum class Type : uint8_t { foreground, background };\n\tuint8_t activeFrame;\n\tenum class Command : uint8_t {\n\t\tnone = 0,\n\t\tclearAll,\n\t\tfillFrame,\n\t\tapplyFrame,\n\t\tdrawLine,\n\t} volatile command;\n\tunion Parameter {\n\t\tstruct {\n\t\t\t//fillframe\n\t\t\tType frame;\n\t\t\tColor color;\n\t\t} fill;\n\t\tstruct {\n\t\t\t//drawLine\n\t\t\tType frame;\n\t\t\tPointF from;\n\t\t\tPointF to;\n\t\t\tColor color;\n\t\t} line;\n\t\tinline Parameter(){};\n\t} parameter;\n\tFrame frames[2];\n\tFrame background;\n\n\tFramebuffer() : activeFrame(0), command(Command::none){};\n\n\tFrame& getActiveFrame() {\n\t\treturn frames[activeFrame % 2];\n\t}\n\tFrame& getInactiveFrame() {\n\t\treturn frames[(activeFrame + 1) % 2];\n\t}\n\tFrame& getBackground() {\n\t\treturn background;\n\t}\n\tFrame& getFrame(Type type) {\n\t\tif (type == Type::foreground)\n\t\t\treturn getInactiveFrame();\n\t\telse if (type == Type::background)\n\t\t\treturn getBackground();\n\n\t\tassert(false && \"Get invalid frame type\");\n\t\treturn background;\n\t}\n};\n\n\ninline Framebuffer::PointF operator+(const Framebuffer::PointF l, Framebuffer::PointF const r) {\n\treturn Framebuffer::PointF(l.x + r.x, l.y + r.y);\n}\n"
  },
  {
    "path": "env/basic/vp-display/main.cpp",
    "content": "#include <QApplication>\n#include \"mainwindow.h\"\n\nint main(int argc, char *argv[]) {\n\tQApplication a(argc, argv);\n\tVPDisplay w;\n\tw.show();\n\n\treturn a.exec();\n}\n"
  },
  {
    "path": "env/basic/vp-display/mainwindow.cpp",
    "content": "#include \"mainwindow.h\"\n#include <qpainter.h>\n#include <cassert>\n#include \"framebuffer.h\"\n#include \"ui_mainwindow.h\"\n\nVPDisplay::VPDisplay(QWidget* mparent) : QWidget(mparent) {\n\tframebuffer = server.createSM();\n\tframe = new QImage(Framebuffer::screenWidth, Framebuffer::screenHeight,\n\t                   QImage::Format_RGB444);  // two bytes per pixel\n\tresize(Framebuffer::screenWidth, Framebuffer::screenHeight);\n\tsetFixedSize(size());\n\tserver.startListening(std::bind(&VPDisplay::notifyChange, this, std::placeholders::_1));\n}\n\nVPDisplay::~VPDisplay() {\n\tdelete frame;\n}\n\nvoid VPDisplay::drawMainPage(QImage* mem) {\n\tFramebuffer::Frame activeFrame = framebuffer->getActiveFrame();\n\tFramebuffer::Frame background = framebuffer->getBackground();\n\tfor (int row = 0; row < mem->height(); row++) {\n\t\tuint16_t* line = reinterpret_cast<uint16_t*>(mem->scanLine(row));  // Two bytes per pixel\n\t\tfor (int x = 0; x < mem->width(); x++) {\n\t\t\tline[x] = activeFrame.raw[row][x] == 0 ? background.raw[row][x] : activeFrame.raw[row][x];\n\t\t}\n\t}\n}\n\nvoid VPDisplay::paintEvent(QPaintEvent*) {\n\tQPainter painter(this);\n\n\t// painter.scale(size_factor, size_factor);\n\n\t// Draw Header\n\t// QPainter mempaint(&memory);\n\n\tdrawMainPage(frame);\n\tpainter.drawImage(QPoint(0, 0), *frame);\n\tpainter.end();\n}\n\nvoid VPDisplay::notifyChange(bool success) {\n\tassert(success);\n\tupdate();\n}\n"
  },
  {
    "path": "env/basic/vp-display/mainwindow.h",
    "content": "#pragma once\n#include <QMainWindow>\n#include <cassert>\n#include \"vpdisplayserver.h\"\n\nnamespace Ui {\nclass VPDisplay;\n}\n\nclass VPDisplay : public QWidget {\n\tQ_OBJECT\n\tFramebuffer* framebuffer;\n\tQImage* frame;\n\tVPDisplayserver server;\n\n   public:\n\tVPDisplay(QWidget* mparent = 0);\n\t~VPDisplay();\n\tvoid paintEvent(QPaintEvent*);\n\t// void keyPressEvent(QKeyEvent *e);\n\tvoid drawMainPage(QImage* mem);\n\n\tvoid notifyChange(bool success);\n};\n"
  },
  {
    "path": "env/basic/vp-display/mainwindow.ui",
    "content": "<ui version=\"4.0\">\n <class>MainWindow</class>\n <widget class=\"QMainWindow\" name=\"MainWindow\" >\n  <property name=\"geometry\" >\n   <rect>\n    <x>0</x>\n    <y>0</y>\n    <width>400</width>\n    <height>300</height>\n   </rect>\n  </property>\n  <property name=\"windowTitle\" >\n   <string>MainWindow</string>\n  </property>\n  <widget class=\"QMenuBar\" name=\"menuBar\" />\n  <widget class=\"QToolBar\" name=\"mainToolBar\" />\n  <widget class=\"QWidget\" name=\"centralWidget\" />\n  <widget class=\"QStatusBar\" name=\"statusBar\" />\n </widget>\n <layoutDefault spacing=\"6\" margin=\"11\" />\n <pixmapfunction></pixmapfunction>\n <resources/>\n <connections/>\n</ui>\n"
  },
  {
    "path": "env/basic/vp-display/vpdisplayserver.cpp",
    "content": "#include \"vpdisplayserver.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/ipc.h>\n#include <sys/shm.h>\n#include <sys/types.h>\n#include <iostream>\n\nVPDisplayserver::VPDisplayserver(unsigned int sharedMemoryKey) : mSharedMemoryKey(sharedMemoryKey), stop(false) {}\n\nVPDisplayserver::~VPDisplayserver() {\n\tstop.store(true);\n\tactive_watch.join();\n}\n\nFramebuffer* VPDisplayserver::createSM() {\n\tint shmid;\n\t// TODO: Dont create, but check if exists\n\tif ((shmid = shmget(mSharedMemoryKey, sizeof(Framebuffer), 0666)) < 0) {\n\t\tperror(\"shmget\");\n\t\texit(1);\n\t}\n\tstd::cout << \"SHMID: \" << shmid << std::endl;\n\tframebuffer = reinterpret_cast<Framebuffer*>(shmat(shmid, nullptr, 0));\n\tif (framebuffer == (Framebuffer*)-1) {\n\t\tperror(\"shmat\");\n\t\texit(1);\n\t}\n\treturn framebuffer;\n}\n\nvoid VPDisplayserver::startListening(std::function<void(bool)> notifyChange) {\n\t// TODO: While loop around buffer changer\n\tactive_watch = std::thread([=]() {\n\t\tuint8_t lastFrame = -1;\n\t\twhile (!stop.load()) {\n\t\t\tif (framebuffer->activeFrame != lastFrame) {\n\t\t\t\tnotifyChange(true);\n\t\t\t\tlastFrame = framebuffer->activeFrame;\n\t\t\t}\n\t\t\t// std::this_thread::sleep_for(std::chrono::milliseconds(100));\n\t\t}\n\t});\n\tnotifyChange(true);\n}\n"
  },
  {
    "path": "env/basic/vp-display/vpdisplayserver.h",
    "content": "#pragma once\n#include <atomic>\n#include <functional>\n#include <thread>\n#include \"framebuffer.h\"\n\nclass VPDisplayserver {\n\tunsigned int mSharedMemoryKey;\n\tFramebuffer* framebuffer;\n\tstd::atomic<bool> stop;\n\tstd::thread active_watch;\n\n   public:\n\tVPDisplayserver(unsigned int sharedMemoryKey = 1338);\n\t~VPDisplayserver();\n\tFramebuffer* createSM();\n\tvoid startListening(std::function<void(bool)> notifyChange);\n};\n"
  },
  {
    "path": "sw/.gitignore",
    "content": "main\n"
  },
  {
    "path": "sw/Makefile",
    "content": "all:\n\tfind . -maxdepth 1 -type d \\( ! -name . \\) -exec bash -c \"cd '{}' && make\" \\;\n\nclean:\n\tfind . -maxdepth 1 -type d \\( ! -name . \\) -exec bash -c \"cd '{}' && make clean\" \\;\n"
  },
  {
    "path": "sw/Makefile.common",
    "content": "RISCV_PREFIX ?= riscv32-unknown-elf-\n\noverride CC = $(RISCV_PREFIX)gcc\noverride CXX = $(RISCV_PREFIX)g++\noverride LD = $(RISCV_PREFIX)gcc\n\nASFLAGS ?= $(CFLAGS)\nSIM_TARGET ?= sim-default\n\n# ISA Version 2.2 is the last version where zicsr is still\n# supported as part of the base ISA. Use that for now until\n# _zicsr is widely supported by existing cross-compilers.\nSUPPORTS_MISA ?= $(shell echo \"typedef int dont_be_pedantic;\" | $(RISCV_PREFIX)gcc -march=rv32imac -mabi=ilp32 -misa-spec=2.2 -E - > /dev/null 2>&1 && echo 1 || echo 0)\nifeq (1,$(SUPPORTS_MISA))\n  CFLAGS += -misa-spec=2.2\n  CXXFLAGS += -misa-spec=2.2\nendif\n\nVP ?= riscv-vp\nVP_FLAGS ?= --intercept-syscalls --error-on-zero-traphandler=true\n\nEXECUTABLE ?= main\nOBJECTS ?= main.o\n\n########################################################################\n\n$(EXECUTABLE): $(OBJECTS)\n\t$(LD) $(CXXFLAGS) $(CFLAGS) -o $@ $(LDFLAGS) $^ $(LDLIBS)\n\n%.o: %.S\n\t$(CC) $(CPPFLAGS) $(ASFLAGS) -c $<\n%.o: %.c\n\t$(CC) $(CPPFLAGS) $(CFLAGS) -c $<\n%.o: %.cpp\n\t$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<\n\n########################################################################\n\nsim: $(SIM_TARGET)\nsim-default: $(EXECUTABLE)\n\t$(VP) $(VP_FLAGS) $<\n\ndump-elf: $(EXECUTABLE)\n\t$(RISCV_PREFIX)readelf -a main\n\ndump-code: $(EXECUTABLE)\n\t$(RISCV_PREFIX)objdump -D main\n\nclean:\n\trm -f $(OBJECTS) $(EXECUTABLE) $(CLEAN_EXTRA)\n\n.PHONY: sim sim-default dump-elf dump-code clean\n.DEFAULT_GOAL := $(EXECUTABLE)\n"
  },
  {
    "path": "sw/README.md",
    "content": "These SW examples demonstrate basic bare-metal applications and applications that use the C-library. In particular, the  applications using the C-library require support for system calls (syscalls). Syscalls are handled in one of two ways in the VP:\n\n 1) By default the VP will trigger a trap and thus jump to the trap/interrupt handler. The handler will detect that the reason is a syscall and re-direct the syscall to the syscall handler (or some other peripheral) through memory mapped I/O. This requires to provide and setup a trap handler. This can be done by providing a custom entry-point that performs the required setup and then jumps to the crt0.S entry code of the C-library (which in turn will call the main function). The *printf* SW example demonstrates this case.\n\n 2) With the \"--intercept-syscalls\" command line argument, the VP will directly intercept and handle syscalls, hence it is not necessary to setup a trap handler. Thus, no designated startup code (i.e. bootstrap.S) is required to run applications that use the C-library. For example see the *c++-lib* SW example.\n\nThe provided SW examples demonstrate both approaches for dealing with syscalls.\n\nThe VP also supports the FreeRTOS (see https://github.com/agra-uni-bremen/riscv-freertos) and Zephyr (see https://www.zephyrproject.org/ - use the Zephyr *hifive* board option when building Zephyr applications and use the *hifive-vp* configuration for executing them) operating systems.\n"
  },
  {
    "path": "sw/basic-asm/Makefile",
    "content": "OBJECTS  = sum.o\nCFLAGS   = -march=rv32i -mabi=ilp32\nLDFLAGS  = -nostartfiles -Wl,--no-relax\nVP_FLAGS = --error-on-zero-traphandler=true\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/basic-asm/sum.S",
    "content": ".globl _start\n.equ SYSCALL_ADDR, 0x02010000\n\n.macro SYS_EXIT, exit_code\nli   a7, 93\nli   a0, \\exit_code\nli   t0, SYSCALL_ADDR\ncsrr a6, mhartid\nsw   a6, 0(t0)\n.endm\n\n\n# program entry-point\n_start:\n\nli a0,50\nli a1,100\n\nli a2,0\nloop:\nbgt a0,a1,end\nadd a2,a2,a0\naddi a0,a0,1\nj loop\nend:\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\nSYS_EXIT 0\n"
  },
  {
    "path": "sw/basic-c/Makefile",
    "content": "OBJECTS  = main.o sum.o bootstrap.o\nCFLAGS   = -march=rv32i -mabi=ilp32\nLDFLAGS  = -nostartfiles -Wl,--no-relax\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/basic-c/bootstrap.S",
    "content": ".globl _start\n.globl main\n\n_start:\njal main\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\nli a7,93\nli a0,0\necall\n"
  },
  {
    "path": "sw/basic-c/main.c",
    "content": "int sum(int end);\n\nint x = 5;\nint y;\n\nint main() {\n\tint a = 6;\n\tint b = 7;\n\ta = a + b + x + y;\n\ta = sum(a);\n\treturn a;\n}\n"
  },
  {
    "path": "sw/basic-c/sum.c",
    "content": "int sum(int end) {\n\tint ans = end;\n\tfor (int i=1; i<end; ++i) {\n\t\tans += i;\n\t}\n\treturn ans;\n}\n"
  },
  {
    "path": "sw/basic-debug/Makefile",
    "content": "OBJECTS  = main.o bootstrap.o\nCFLAGS   = -g3 -march=rv32im -mabi=ilp32\nLDFLAGS  = -nostartfiles -Wl,--no-relax\nVP_FLAGS = --intercept-syscalls --error-on-zero-traphandler=true --debug-mode\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/basic-debug/bootstrap.S",
    "content": ".align 6\n.globl _start\n.globl main\n\n_start:\njal main\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\nli a7,93\nli a0,0\necall\n"
  },
  {
    "path": "sw/basic-debug/eclipse-remote-debug-readme.txt",
    "content": "Start Eclipse\n\nFile -> New -> Makefile Project with Existing Code\n\n    Select the software folder containing the Makefile\n\nRun -> Debug Configurations ...\n\n    C/C++ Remote Application (List Entry on the left side): Click \"New\" Button\n\n    Main Tab\n        - C/C++ Application Name: Enter name, typically \"main\"\n        - Using GDB (DSF) Automatic Remote Launcher: Click \"Select other\"\n            -> Use configuration specific settings\n            -> GDB (DSF) Manual Remote Debug Launcher\n\n    Debugger Tab\n        - GDB debugger: riscv32-unknown-elf-gdb   [Sub-tab Main]\n        - Connection: Port Number 5005            [Sub-tab Connection]\n\n    Click \"Debug\" Button (lower right corner) to start debugging\n        -> Launch the VP in debug mode first: riscv-vp --debug-mode main\n        -> Perhaps it is necessary to refresh the Eclipse project view in case the executable (typically main) cannot be found (the \"Debug\" button is greyed out in this case)\n"
  },
  {
    "path": "sw/basic-debug/main.c",
    "content": "int x = 5;\nint y;\n\nint f(int a, int b) {\n\tif (a > 0) {\n\t\tint ans = a + b;\n\t\treturn ans;\n\t}\n\ta = -a;\n\treturn b + a;\n}\n\nint main() {\n\tint a = 5;\n\tint b = 3;\n\tb--;\n\ta = a / b;\n\ta = a * 2;\n\ta = f(x, y);\n\treturn a;\n}\n"
  },
  {
    "path": "sw/basic-debug/remote-debug-readme.txt",
    "content": "In the first terminal run our VP in debug mode (wraps the core iss in a debug stub):\n\n\triscv-vp --debug-mode --intercept-syscalls main\n\n\nIn the other terminal run:\n\n\triscv32-unknown-elf-gdb\n\nInside of gdb then (for example):\n\n\tfile main\n\ttarget remote :5005\n\tb main.c:14\n\tcontinue\n\tp x\n\tp y\n\tstep\n\tcontinue\n\nThis will load the symbols from the *main* elf file (note: this one should match the one loaded in our VP). The *target remote* command is passed host and port number. In this case localhost is used.\n\nNote: you can use 'set debug remote 1' in gdb to observe the packets send and received by gdb (might be useful for debugging).\n"
  },
  {
    "path": "sw/basic-debug/test-ignore",
    "content": ""
  },
  {
    "path": "sw/basic-dma/Makefile",
    "content": "OBJECTS  = main.o irq.o bootstrap.o\nCFLAGS   = -march=rv32imac -mabi=ilp32\nLDFLAGS  = -nostartfiles -Wl,--no-relax\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/basic-dma/bootstrap.S",
    "content": ".globl _start\n.globl init\n.globl main\n.globl level_1_interrupt_handler\n\n.equ PLIC_ENABLED_IRQ_ADDR, 0x40002000\n\n_start:\njal init\nla t0, level_0_interrupt_handler\ncsrw mtvec, t0\nli t1, 0x888\ncsrw mie, t1\ncsrwi mstatus, 8\nli t0, PLIC_ENABLED_IRQ_ADDR\nli t1, -1\nsw t1, 0(t0)\nsw t1, 4(t0)\njal main\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\nli a7,93\nli a0,0\necall\n\n\n/*\n * Interrupt handler for non-nested interrupts. Only selected registers are stored/re-stored, i.e. those not preserved on function calls.\n */\n#define STORE    sw\n#define LOAD     lw\n#define REGBYTES 4\n\n.align 4\nlevel_0_interrupt_handler:\n// store execution context on the stack (register content)\naddi    sp, sp, -REGBYTES * 32\nSTORE\tx1, 0x0(sp)\nSTORE\tx4, 3 * REGBYTES(sp)\nSTORE\tx5, 4 * REGBYTES(sp)\nSTORE\tx6, 5 * REGBYTES(sp)\nSTORE\tx7, 6 * REGBYTES(sp)\nSTORE\tx10, 9 * REGBYTES(sp)\nSTORE\tx11, 10 * REGBYTES(sp)\nSTORE\tx12, 11 * REGBYTES(sp)\nSTORE\tx13, 12 * REGBYTES(sp)\nSTORE\tx14, 13 * REGBYTES(sp)\nSTORE\tx15, 14 * REGBYTES(sp)\nSTORE\tx16, 15 * REGBYTES(sp)\nSTORE\tx17, 16 * REGBYTES(sp)\nSTORE\tx28, 27 * REGBYTES(sp)\nSTORE\tx29, 28 * REGBYTES(sp)\nSTORE\tx30, 29 * REGBYTES(sp)\nSTORE\tx31, 30 * REGBYTES(sp)\n\n// load interrupt/trap reason and call external C function to handle it\ncsrr    a0, mcause\njal     level_1_interrupt_handler\n\n// re-store the saved context\nLOAD\tx1, 0x0(sp)\nLOAD\tx4, 3 * REGBYTES(sp)\nLOAD\tx5, 4 * REGBYTES(sp)\nLOAD\tx6, 5 * REGBYTES(sp)\nLOAD\tx7, 6 * REGBYTES(sp)\nLOAD\tx10, 9 * REGBYTES(sp)\nLOAD\tx11, 10 * REGBYTES(sp)\nLOAD\tx12, 11 * REGBYTES(sp)\nLOAD\tx13, 12 * REGBYTES(sp)\nLOAD\tx14, 13 * REGBYTES(sp)\nLOAD\tx15, 14 * REGBYTES(sp)\nLOAD\tx16, 15 * REGBYTES(sp)\nLOAD\tx17, 16 * REGBYTES(sp)\nLOAD\tx28, 27 * REGBYTES(sp)\nLOAD\tx29, 28 * REGBYTES(sp)\nLOAD\tx30, 29 * REGBYTES(sp)\nLOAD\tx31, 30 * REGBYTES(sp)\naddi\tsp, sp, REGBYTES * 32\nmret\n\n"
  },
  {
    "path": "sw/basic-dma/irq.c",
    "content": "#include \"irq.h\"\n#include \"assert.h\"\n\n\n#define RISCV_MACHINE_SOFTWARE_INTERRUPT 3\n#define RISCV_MACHINE_TIMER_INTERRUPT 7\n#define RISCV_MACHINE_EXTERNAL_INTERRUPT 11\n\n\n#define PLIC_BASE 0x40000000\n#define IRQ_TABLE_NUM_ENTRIES 64\nstatic volatile uint32_t * const PLIC_INTERRUPT_ENABLE_START = (uint32_t * const)(PLIC_BASE + 0x2000);\nstatic volatile uint32_t * const PLIC_CLAIM_AND_RESPONSE_REGISTER = (uint32_t * const)(PLIC_BASE + 0x200004);\n\n\nstatic void irq_empty_handler() {}\nstatic irq_handler_t irq_handler_table[IRQ_TABLE_NUM_ENTRIES] = { [ 0 ... IRQ_TABLE_NUM_ENTRIES-1 ] = irq_empty_handler };\n\n\n#define CLINT_BASE 0x2000000\n\nvolatile uint64_t* mtime =   (uint64_t*)(CLINT_BASE + 0xbff8);\nvolatile uint64_t* mtimecmp = (uint64_t*)(CLINT_BASE + 0x4000);\n\nstatic irq_handler_t timer_irq_handler = 0;\n\n\nvoid level_1_interrupt_handler(uint32_t cause) {\n\n\tswitch (cause & 0xf) {\n\t\tcase RISCV_MACHINE_EXTERNAL_INTERRUPT: {\n\t\t\tasm volatile (\"csrc mip, %0\" : : \"r\" (0x800));\n\n\t\t\tuint32_t irq_id = *PLIC_CLAIM_AND_RESPONSE_REGISTER;\n\n\t\t\tirq_handler_table[irq_id]();\n\n\t\t\t*PLIC_CLAIM_AND_RESPONSE_REGISTER = 1;\n\n\t\t\treturn;\n\t\t}\n\n\t\tcase RISCV_MACHINE_TIMER_INTERRUPT: {\n\t\t\t// Note: the pending timer interrupt bit will be automatically cleared when writing to the *mtimecmp* register of this hart\n\t\t\tif (timer_irq_handler) {\n\t\t\t\t// let the user registered handler clear the timer interrupt bit\n\t\t\t\ttimer_irq_handler();\n\t\t\t} else {\n\t\t\t\t// reset the *mtimecmp* register to zero to clear the pending bit\n\t\t\t\t*mtimecmp = 0;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\t}\n\n\tassert (0 && \"unsupported cause\");\n}\n\nvoid register_interrupt_handler(uint32_t irq_id, irq_handler_t fn) {\n\tassert (irq_id < IRQ_TABLE_NUM_ENTRIES);\n\t// enable interrupt\n\tvolatile uint32_t* const reg = (PLIC_INTERRUPT_ENABLE_START + irq_id/32);\n\t*reg |= 1 << (irq_id%32);\n\t// set a prio different to zero (which means do-not-interrupt)\n\t*((uint32_t*) (PLIC_BASE + irq_id*sizeof(uint32_t))) = 1;\n\tirq_handler_table[irq_id] = fn;\n}\n\nvoid register_timer_interrupt_handler(irq_handler_t fn) {\n\ttimer_irq_handler = fn;\n}\n"
  },
  {
    "path": "sw/basic-dma/irq.h",
    "content": "#ifndef __RISCV_IRQ_H__\n#define __RISCV_IRQ_H__\n\n#include \"stdint.h\"\n\ntypedef void (*irq_handler_t)(void);\n\nvoid register_interrupt_handler(uint32_t irq_id, irq_handler_t fn);\n\nvoid register_timer_interrupt_handler(irq_handler_t fn);\n\nextern volatile uint64_t* mtime;\nextern volatile uint64_t* mtimecmp;\n\n#endif\n"
  },
  {
    "path": "sw/basic-dma/main.c",
    "content": "#include \"stdint.h\"\n\n#include \"irq.h\"\n\n\nstatic volatile char * const TERMINAL_ADDR = (char * const)0x20000000;\n\nstatic volatile uint32_t * const DMA_SRC_ADDR  = (uint32_t * const)0x70000000;\nstatic volatile uint32_t * const DMA_DST_ADDR  = (uint32_t * const)0x70000004;\nstatic volatile uint32_t * const DMA_LEN_ADDR  = (uint32_t * const)0x70000008;\nstatic volatile uint32_t * const DMA_OP_ADDR   = (uint32_t * const)0x7000000C;\nstatic volatile uint32_t * const DMA_STAT_ADDR = (uint32_t * const)0x70000010;\n\nstatic const uint32_t DMA_OP_NOP = 0;\nstatic const uint32_t DMA_OP_MEMCPY = 1;\n\n\nvolatile _Bool dma_completed = 0;\n\nvoid dma_irq_handler() {\n\tdma_completed = 1;\n}\n\nvoid init() {\n\tregister_interrupt_handler(4, dma_irq_handler);\n}\n\nint main() {\n\tuint8_t src[32] = { [ 0 ... 31 ] = 70 };\n\tuint8_t dst[32] = { 0 };\n\n\tdma_completed = 0;\n\t*DMA_SRC_ADDR = (uint32_t)(&src[0]);\n\t*DMA_DST_ADDR = (uint32_t)(&dst[0]);\n\t*DMA_LEN_ADDR = sizeof(src);\n\t*DMA_OP_ADDR  = DMA_OP_MEMCPY;\n\n\twhile (!dma_completed) {\n\t\tasm volatile (\"wfi\");\n\t}\n\n\tfor (int i=0; i<32; ++i) {\n\t\t*TERMINAL_ADDR = dst[i];\n\t}\n\t*TERMINAL_ADDR = '\\n';\n\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/basic-e/Makefile",
    "content": "OBJECTS  = sum.o\nCFLAGS   = -march=rv32e -mabi=ilp32e\nLDFLAGS  = -nostartfiles -Wl,--no-relax\nVP_FLAGS = --use-E-base-isa --error-on-zero-traphandler=true\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/basic-e/sum.S",
    "content": ".globl _start\n.equ SYSCALL_ADDR, 0x02010000\n\n.macro SYS_EXIT, exit_code\nli   a5, 93\nli   a0, \\exit_code\nli   t0, SYSCALL_ADDR\ncsrr t1, mhartid\nsw   t1, 0(t0)\n.endm\n\n\n# program entry-point\n_start:\n\nli a0,50\nli a1,100\n\nli a2,0\nloop:\nbgt a0,a1,end\nadd a2,a2,a0\naddi a0,a0,1\nj loop\nend:\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\nSYS_EXIT 0\n"
  },
  {
    "path": "sw/basic-gcov/Makefile",
    "content": "OBJECTS  = main.o\nCFLAGS   = --coverage -march=rv32ima -mabi=ilp32\nLDFLAGS  = --coverage\nVP_FLAGS = --error-on-zero-traphandler=true\n\nCLEAN_EXTRA = main.c.gcov main.gcda main.gcno cov*.html\n\nmain.gcda: main\n\triscv-vp --intercept-syscalls --error-on-zero-traphandler=true main\n\n# use -b option to display branch coverage too\ndump-coverage: main.gcda\n\t$(RISCV_PREFIX)gcov main.c\n\ndump-html-coverage: main.gcda\n\tgcovr --gcov-executable $(RISCV_PREFIX)gcov -b -r . --html-details -o cov.html\n\ninclude ../Makefile.common\n.DEFAULT_GOAL := main.gcda\n"
  },
  {
    "path": "sw/basic-gcov/test-ignore",
    "content": ""
  },
  {
    "path": "sw/basic-gpio/Makefile",
    "content": "OBJECTS  = bootstrap.o main.o uart.o\nCFLAGS   = -g3 -march=rv32i -mabi=ilp32\nLDLIBS   = -Tlink.ld -nostartfiles -Wl,--no-relax\n\nVP       = microrv32-vp\nVP_FLAGS =\n\nhex: $(EXECUTABLE)\n\t../elf2bin.py ./main gpio.hex 0x4020\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/basic-gpio/bootstrap.S",
    "content": ".globl _start\n.globl main\n\n.equ SYSCALL_ADDR, 0x02010000\n\n.macro INIT_HW_PLATFORM\nand x1,x0,x0\nand x2,x0,x0\nand x3,x0,x0\nand x4,x0,x0\nand x5,x0,x0\nand x6,x0,x0\nand x7,x0,x0\nand x8,x0,x0\nand x9,x0,x0\nand x10,x0,x0\nand x11,x0,x0\nand x12,x0,x0\nand x13,x0,x0\nand x14,x0,x0\nand x15,x0,x0\nand x16,x0,x0\nand x17,x0,x0\nand x18,x0,x0\nand x19,x0,x0\nand x20,x0,x0\nand x21,x0,x0\nand x22,x0,x0\nand x23,x0,x0\nand x24,x0,x0\nand x25,x0,x0\nand x26,x0,x0\nand x27,x0,x0\nand x28,x0,x0\nand x29,x0,x0\nand x30,x0,x0\nand x31,x0,x0\n.endm\n\n.macro SYS_EXIT, exit_code\nli   a7, 93\nli   a0, \\exit_code\nli   t0, SYSCALL_ADDR\ncsrr a6, mhartid\nsw   a6, 0(t0)\n.endm\n\n# .macro SYS_EXIT, exit_code\n# li   a7, 93\n# li   a0, \\exit_code\n# li   t0, SYSCALL_ADDR\n# sw   a7, 0(t0)\n# .endm\n\n_start:\n# initialize hw-platform\nINIT_HW_PLATFORM\nla sp, stack_end\njal main\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\nSYS_EXIT 0\n\n.align 4\nstack_begin:\n.zero 1024\nstack_end:\n"
  },
  {
    "path": "sw/basic-gpio/gpio.h",
    "content": "#ifndef GPIO_H\n#define GPIO_H\n\n\n#endif /* GPIO_H */"
  },
  {
    "path": "sw/basic-gpio/link.ld",
    "content": "OUTPUT_ARCH( \"riscv\" )\nENTRY(_start)\n\nSECTIONS\n{\n  . = 0x80000000;\n  .text.init : { *(.text.init) }\n  . = ALIGN(0x1000);\n  .tohost : { *(.tohost) }\n  . = ALIGN(0x1000);\n  .text : { *(.text) }\n  . = ALIGN(0x1000);\n  .data : { *(.data) }\n  .bss : { *(.bss) }\n  _end = .;\n}\n\n"
  },
  {
    "path": "sw/basic-gpio/main.c",
    "content": "#include <stdint.h>\n#include <stdio.h>\n#include \"platform.h\"\n#include \"uart.h\"\n#include \"util.h\"\n//#include \"gpio.h\"\nvoid wait(uint32_t nOps) {\n\t/*\n\t * TODO correlate nOps to clocks/time waited\n\t */\n\tfor(uint32_t i = 0; i < nOps; i++) {\n\t\tasm(\"nop\");\n\t}\n}\n\nint main(int argc, char **argv) {\n\tuint8_t val = 1;\n\n\t*GPIO_BANK_A_DIRECTION_ADDR = 0x000000ff; // set all pins to output\n\t*GPIO_BANK_A_OUTPUT_ADDR = 0x01; // output 0x01 to all 8 pins of gpio bank A\n\twait(10);\n\t*LED_ADDR = 0x05;\n\twait(10);\n\t*LED_ADDR = 0x0A;\n\twait(10);\n\t// bit shift pattern until only 0x55 and 0xAA are present\n\tfor(uint8_t i=0; i<10; i++) {\n\t\t*GPIO_BANK_A_OUTPUT_ADDR = val;\n\t\twait(10);\n\t\tval = (val << 1) | (i & 1);\n\t}\n\t*LED_ADDR = 0x0A;\n\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/basic-gpio/platform.h",
    "content": "#ifndef PLATFORM_H\n#define PLATFORM_H\n\n//#define MICRORV\n\n#ifdef MICRORV\n// LED\nstatic volatile uint32_t *LED_ADDR = (uint32_t *)0x81000000;\n// UART\nstatic volatile uint32_t *UART_TX_DATA_ADDR = (uint32_t *)0x82000000;\nstatic volatile uint32_t *UART_TX_CTRL_ADDR = (uint32_t *)0x82000004;\nstatic volatile uint32_t *UART_RX_DATA_ADDR = (uint32_t *)0x82000008;\n// CLIC\nstatic volatile uint64_t *MTIMECMP_REG = (uint64_t *)0x02004000;\nstatic volatile uint64_t *MTIME_REG = (uint64_t *)0x0200bff8;\n// GPIO\nstatic volatile uint32_t *GPIO_BANK_A_DIRECTION_ADDR = (uint32_t *)0x83000000;\nstatic volatile uint32_t *GPIO_BANK_A_OUTPUT_ADDR = (uint32_t *)0x83000004;\nstatic volatile uint32_t *GPIO_BANK_A_INPUT_ADDR = (uint32_t *)0x83000008;\n#else\n// LED\nstatic volatile uint32_t *LED_ADDR = (uint32_t *)0x81000000;\n// UART\nstatic volatile uint32_t *UART_TX_DATA_ADDR = (uint32_t *)0x82000000;\nstatic volatile uint32_t *UART_TX_CTRL_ADDR = (uint32_t *)0x82000004;\nstatic volatile uint32_t *UART_RX_DATA_ADDR = (uint32_t *)0x82000008;\n// CLIC\nstatic volatile uint64_t *MTIMECMP_REG = (uint64_t *)0x02004000;\nstatic volatile uint64_t *MTIME_REG = (uint64_t *)0x0200bff8;\n// GPIO\nstatic volatile uint32_t *GPIO_BANK_A_DIRECTION_ADDR = (uint32_t *)0x83000000;\nstatic volatile uint32_t *GPIO_BANK_A_OUTPUT_ADDR = (uint32_t *)0x83000004;\nstatic volatile uint32_t *GPIO_BANK_A_INPUT_ADDR = (uint32_t *)0x83000008;\n#endif\n\n#endif /* PLATFORM_H */"
  },
  {
    "path": "sw/basic-gpio/uart.c",
    "content": "#include \"uart.h\"\n#include \"platform.h\"\n#include <stdint.h>\n\nint sendString(char* str, long len) {\n\tlong cnt = len;\n\tconst char *s = (const char *)str;\n\twhile (cnt > 0) {\n\t\t--cnt;\n\t\tputChr(*s);\n\t\ts++;\n\t}\n\treturn len;\n}\n\nvoid putChr(char chr) {\n#ifdef MICRORV\n\tuint32_t tx_rdy = 0;\n\t*UART_TX_DATA_ADDR = chr;\n\t// send character stored in uart_tx_addr\n\t*UART_TX_CTRL_ADDR = 1;\n\t// wait until tx is ready again for sening another character\n\tdo {\n\t\t// read uart tx status\n\t\ttx_rdy = *UART_TX_CTRL_ADDR;\n\t\tasm volatile (\"nop\");\n\t} while(!tx_rdy);\n#else\n\tuint32_t tx_rdy = 0;\n\t*UART_TX_DATA_ADDR = chr;\n\t// send character stored in uart_tx_addr\n\t*UART_TX_CTRL_ADDR = 1;\n\t// wait until tx is ready again for sening another character\n\tdo {\n\t\t// read uart tx status\n\t\ttx_rdy = *UART_TX_CTRL_ADDR;\n\t\tasm volatile (\"nop\");\n\t} while(!tx_rdy);\n#endif\n\treturn;\n}"
  },
  {
    "path": "sw/basic-gpio/uart.h",
    "content": "#ifndef  UART_H\n\n#include <stdint.h>\n\nint sendString(char* str, long len);\nvoid putChr(char chr);\n\n#endif /* UART_H */"
  },
  {
    "path": "sw/basic-gpio/util.c",
    "content": "/*\n* utility functions for embedded usage where c-libs are too big\n*/\n\n//----------------------------\n// integer to ascii (itoa) with util functions\n//----------------------------\n\n// function to swap two numbers\nvoid swap(char *x, char *y) {\n\tchar t = *x;\n\t*x = *y;\n\t*y = t;\n}\n\n// function to reverse buffer[i..j]\nchar* reverse(char *buffer, int i, int j) {\n\twhile (i < j)\n\t\tswap(&buffer[i++], &buffer[j--]);\n\treturn buffer;\n}\n\n// Iterative function to implement itoa() function in C\nchar* itoa(int value, char* buffer, int base) {\n\t// invalid input\n\tif (base < 2 || base > 32)\n\t\treturn buffer;\n\t// consider absolute value of number\n\tint n = (value < 0) ? -value : value;\n\tint i = 0;\n\twhile (n) {\n\t\tint r = n % base;\n\t\tif (r >= 10)\n\t\t\tbuffer[i++] = 65 + (r - 10);\n\t\telse\n\t\t\tbuffer[i++] = 48 + r;\n\t\tn = n / base;\n\t}\n\n\t// if number is 0\n\tif (i == 0)\n\t\tbuffer[i++] = '0';\n\n\t// If base is 10 and value is negative, the resulting string\n\t// is preceded with a minus sign (-)\n\t// With any other base, value is always considered unsigned\n\tif (value < 0 && base == 10)\n\t\tbuffer[i++] = '-';\n\n\tbuffer[i] = '\\0'; // null terminate string\n\n\t// reverse the string and return it\n\treturn reverse(buffer, 0, i - 1);\n}\n"
  },
  {
    "path": "sw/basic-gpio/util.h",
    "content": "#ifndef  UTIL_H\n\nvoid swap(char *x, char *y);\nchar* reverse(char *buffer, int i, int j);\nchar* itoa(int value, char* buffer, int base);\n\n#endif /* UTIL_H */"
  },
  {
    "path": "sw/basic-multicore/Makefile",
    "content": "OBJECTS  = main.o bootstrap.o\nCFLAGS   = -march=rv32ima -mabi=ilp32\nLDFLAGS  = -nostartfiles -Wl,--no-relax\n\nVP       = tiny32-mc\nVP_FLAGS = --error-on-zero-traphandler=true\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/basic-multicore/bootstrap.S",
    "content": ".globl _start\n.globl main\n\n.equ SYSCALL_ADDR, 0x02010000\n\n# NOTE: this will exit the whole simulation, i.e. stop all harts\n.macro SYS_EXIT, exit_code\nli   a7, 93\nli   a0, \\exit_code\nli   t0, SYSCALL_ADDR\ncsrr a6, mhartid\nsw   a6, 0(t0)\n.endm\n\n\n# NOTE: each core will start here with execution\n_start:\n\n# initialize global pointer (see crt0.S of the RISC-V newlib C-library port)\n.option push\n.option norelax\n1:auipc gp, %pcrel_hi(__global_pointer$)\n  addi  gp, gp, %pcrel_lo(1b)\n.option pop\n\ncsrr a0, mhartid   # return a core specific number 0 or 1\nli t0, 0\nbeq a0, t0, core0\nli t0, 1\nbeq a0, t0, core1\ncore0:\nla sp, stack0_end  # code executed only by core0\nj end\ncore1:\nla sp, stack1_end  # code executed only by core1\nj end\nend:\n\njal main\n\n# wait until all two cores have finished\nla t0, exit_counter\nli t1, 1\nli t2, 1\namoadd.w a0, t1, 0(t0)\n1:\nblt a0, t2, 1b\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\nSYS_EXIT 0\n\n.align 8\nstack0_begin:\n.zero 32768\nstack0_end:\n\n.align 8\nstack1_begin:\n.zero 32768\nstack1_end:\nexit_counter:\n.word 0\n"
  },
  {
    "path": "sw/basic-multicore/main.c",
    "content": "int main(unsigned hart_id) {\n\t// behave differently based on the core (i.e. hart) id\n\tfor (unsigned i=0; i<100*hart_id; ++i)\n\t\t;\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/blocking-sleep/Makefile",
    "content": "OBJECTS  = main.o irq.o bootstrap.o\nCFLAGS   = -march=rv32imac -mabi=ilp32\nLDFLAGS  = -nostartfiles -Wl,--no-relax\n\nVP       = tiny32-vp\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/blocking-sleep/bootstrap.S",
    "content": ".globl _start\n.globl register_handler\n.globl main\n\n_start:\ncall register_handler\njal main\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\nli a7,93\nli a0,0\necall\n"
  },
  {
    "path": "sw/blocking-sleep/irq.S",
    "content": ".globl register_handler\n.globl lvl0_handler\n\n.align 4\nlvl0_handler:\n    # Store all register values on the stack\n    addi sp, sp, -4 * 32\n    sw x1, 0x0(sp)\n    sw x4, 3 * 4(sp)\n    sw x5, 4 * 4(sp)\n    sw x6, 5 * 4(sp)\n    sw x7, 6 * 4(sp)\n    sw x10, 9 * 4(sp)\n    sw x11, 10 * 4(sp)\n    sw x12, 11 * 4(sp)\n    sw x13, 12 * 4(sp)\n    sw x14, 13 * 4(sp)\n    sw x15, 14 * 4(sp)\n    sw x16, 15 * 4(sp)\n    sw x17, 16 * 4(sp)\n    sw x28, 27 * 4(sp)\n    sw x29, 28 * 4(sp)\n    sw x30, 29 * 4(sp)\n    sw x31, 30 * 4(sp)\n\n    jal irq_handler\n\n    # Load all register values from the stack and return\n    lw x1, 0x0(sp)\n    lw x4, 3 * 4(sp)\n    lw x5, 4 * 4(sp)\n    lw x6, 5 * 4(sp)\n    lw x7, 6 * 4(sp)\n    lw x10, 9 * 4(sp)\n    lw x11, 10 * 4(sp)\n    lw x12, 11 * 4(sp)\n    lw x13, 12 * 4(sp)\n    lw x14, 13 * 4(sp)\n    lw x15, 14 * 4(sp)\n    lw x16, 15 * 4(sp)\n    lw x17, 16 * 4(sp)\n    lw x28, 27 * 4(sp)\n    lw x29, 28 * 4(sp)\n    lw x30, 29 * 4(sp)\n    lw x31, 30 * 4(sp)\n    addi sp, sp, 4 * 32\n    mret\n\nregister_handler:\n    # Use lvl0_handler as the trap handler\n    la t0, lvl0_handler\n    csrw mtvec, t0\n\n    # Enable machine external interrupts (MIE bit)\n    li t1, 0x888\n    csrw mie, t1\n\n    # Globally enable machine mode interrupts (MIE bit)\n    li t1, 8\n    csrw mstatus, t1\n\n    # Return\n    ret\n"
  },
  {
    "path": "sw/blocking-sleep/main.c",
    "content": "#include <stdint.h>\n#include <stdbool.h>\n\nenum {\n\tSLEEP_TIME = 5, // In seconds\n\tUS_PER_SEC = 1000000,\n};\n\n/* This is used to quantize a 1MHz value to the closest 32768Hz value */\n#define DIVIDEND ((uint64_t)15625/(uint64_t)512)\n\n/* Bitmask to extract exception code from mcause register */\n#define MCAUSE_CAUSE 0x7FFFFFFF\n\n/* Exception code for timer interrupts */\n#define MACHINE_TIMER 7\n\n/* Set after timer interrupt was received */\nstatic volatile bool terminate = false;\n\nstatic volatile uint64_t *MTIMECMP_REG = (uint64_t *)0x2004000;\nstatic volatile uint64_t *MTIME_REG = (uint64_t *)0x200bff8;\n\nvoid irq_handler(void) {\n\tuint32_t mcause;\n\tuint32_t code;\n\n\tmcause = 0;\n\t__asm__ volatile (\"csrr %[ret], mcause\"\n\t                  : [ret] \"=r\" (mcause));\n\n\tcode = mcause & MCAUSE_CAUSE;\n\tif (code != MACHINE_TIMER || terminate)\n\t\t__asm__ volatile (\"ebreak\");\n\n\t// Attempt to clear timer interrupt\n\t*MTIMECMP_REG = UINT64_MAX;\n\n\tterminate = true;\n\treturn;\n}\n\nint main() {\n\tuint64_t usec = SLEEP_TIME * US_PER_SEC;\n\tuint64_t ticks = usec / DIVIDEND;\n\n\tuint64_t target = *MTIME_REG + ticks;\n\t*MTIMECMP_REG = target;\n\n\twhile (!terminate)\n\t\t__asm__ volatile (\"wfi\");\n\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/busy-wait-sleep/Makefile",
    "content": "OBJECTS  = main.o bootstrap.o\nCFLAGS   = -march=rv32i -mabi=ilp32\nLDFLAGS  = -nostartfiles -Wl,--no-relax\n\nVP       = tiny32-vp\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/busy-wait-sleep/bootstrap.S",
    "content": ".globl _start\n.globl main\n\n_start:\njal main\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\nli a7,93\nli a0,0\necall\n"
  },
  {
    "path": "sw/busy-wait-sleep/main.c",
    "content": "#include <stdint.h>\n\nstatic volatile uint64_t *MTIMECMP_REG = (uint64_t *)0x2004000;\nstatic volatile uint64_t *MTIME_REG = (uint64_t *)0x200bff8;\n\nenum {\n\tSLEEP_TIME = 5, // In seconds\n\tUS_PER_SEC = 1000000,\n};\n\n/* This is used to quantize a 1MHz value to the closest 32768Hz value */\n#define DIVIDEND ((uint64_t)15625/(uint64_t)512)\n\nint main() {\n\tuint64_t usec = SLEEP_TIME * US_PER_SEC;\n\tuint64_t ticks = usec / DIVIDEND;\n\n\tuint64_t target = *MTIME_REG + ticks;\n\twhile (*MTIME_REG < target)\n\t\t;\n\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/c++-lib/Makefile",
    "content": "LD       = $(CXX)\nOBJECTS  = main.o\nCXXFLAGS = -std=c++14 -march=rv32imac -mabi=ilp32\n\ninclude ../Makefile.common\noverride LD = $(CXX)\n"
  },
  {
    "path": "sw/c++-lib/main.cpp",
    "content": "#include <iostream>\n#include <list>\n#include <map>\n#include <vector>\n\nstruct A {\n\tint a;\n\tint b;\n\n\tA(int a, int b) : a(a), b(b) {}\n\n\tvirtual int foo() = 0;\n\n\tvirtual int bar() {\n\t\treturn a + b;\n\t}\n};\n\nstruct B : public A {\n\tusing A::A;\n\n\tvirtual int foo() override {\n\t\treturn a - b;\n\t}\n};\n\nint main() {\n\tstd::cout << \"Hello World\\n\";\n\tB x(5, 2);\n\tauto a = x.foo();\n\tauto b = x.bar();\n\tstd::cout << a << \"\\n\";\n\tstd::cout << b << \"\\n\";\n\tstd::vector<int> v;\n\tv.push_back(1);\n\tv.push_back(2);\n\tfor (auto e : v) std::cout << e << std::endl;\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/clock-ticks/Makefile",
    "content": "OBJECTS  = main.o irq.o bootstrap.o\nCFLAGS   = -march=rv32imac -mabi=ilp32\nLDFLAGS  = -nostartfiles -Wl,--no-relax\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/clock-ticks/bootstrap.S",
    "content": ".globl _start\n.globl main\n.globl level_1_interrupt_handler\n\n_start:\nla t0, level_0_interrupt_handler\ncsrw mtvec, t0\nli t1, 0x888\ncsrw mie, t1\ncsrwi mstatus, 8\njal main\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\nli a7,93\nli a0,0\necall\n\n\n/*\n * Interrupt handler for non-nested interrupts. Only selected registers are stored/re-stored, i.e. those not preserved on function calls.\n */\n#define STORE    sw\n#define LOAD     lw\n#define REGBYTES 4\n\n.align 4\nlevel_0_interrupt_handler:\n// store execution context on the stack (register content)\naddi    sp, sp, -REGBYTES * 32\nSTORE\tx1, 0x0(sp)\nSTORE\tx4, 3 * REGBYTES(sp)\nSTORE\tx5, 4 * REGBYTES(sp)\nSTORE\tx6, 5 * REGBYTES(sp)\nSTORE\tx7, 6 * REGBYTES(sp)\nSTORE\tx10, 9 * REGBYTES(sp)\nSTORE\tx11, 10 * REGBYTES(sp)\nSTORE\tx12, 11 * REGBYTES(sp)\nSTORE\tx13, 12 * REGBYTES(sp)\nSTORE\tx14, 13 * REGBYTES(sp)\nSTORE\tx15, 14 * REGBYTES(sp)\nSTORE\tx16, 15 * REGBYTES(sp)\nSTORE\tx17, 16 * REGBYTES(sp)\nSTORE\tx28, 27 * REGBYTES(sp)\nSTORE\tx29, 28 * REGBYTES(sp)\nSTORE\tx30, 29 * REGBYTES(sp)\nSTORE\tx31, 30 * REGBYTES(sp)\n\n// load interrupt/trap reason and call external C function to handle it\ncsrr    a0, mcause\njal     level_1_interrupt_handler\n\n// re-store the saved context\nLOAD\tx1, 0x0(sp)\nLOAD\tx4, 3 * REGBYTES(sp)\nLOAD\tx5, 4 * REGBYTES(sp)\nLOAD\tx6, 5 * REGBYTES(sp)\nLOAD\tx7, 6 * REGBYTES(sp)\nLOAD\tx10, 9 * REGBYTES(sp)\nLOAD\tx11, 10 * REGBYTES(sp)\nLOAD\tx12, 11 * REGBYTES(sp)\nLOAD\tx13, 12 * REGBYTES(sp)\nLOAD\tx14, 13 * REGBYTES(sp)\nLOAD\tx15, 14 * REGBYTES(sp)\nLOAD\tx16, 15 * REGBYTES(sp)\nLOAD\tx17, 16 * REGBYTES(sp)\nLOAD\tx28, 27 * REGBYTES(sp)\nLOAD\tx29, 28 * REGBYTES(sp)\nLOAD\tx30, 29 * REGBYTES(sp)\nLOAD\tx31, 30 * REGBYTES(sp)\naddi\tsp, sp, REGBYTES * 32\nmret\n\n"
  },
  {
    "path": "sw/clock-ticks/irq.c",
    "content": "#include \"irq.h\"\n#include \"assert.h\"\n\n\n#define RISCV_MACHINE_SOFTWARE_INTERRUPT 3\n#define RISCV_MACHINE_TIMER_INTERRUPT 7\n#define RISCV_MACHINE_EXTERNAL_INTERRUPT 11\n\n\n#define PLIC_BASE 0x40000000\n#define IRQ_TABLE_NUM_ENTRIES 64\nstatic volatile uint32_t * const PLIC_INTERRUPT_ENABLE_START = (uint32_t * const)(PLIC_BASE + 0x2000);\nstatic volatile uint32_t * const PLIC_CLAIM_AND_RESPONSE_REGISTER = (uint32_t * const)(PLIC_BASE + 0x200004);\n\n\nstatic void irq_empty_handler() {}\nstatic irq_handler_t irq_handler_table[IRQ_TABLE_NUM_ENTRIES] = { [ 0 ... IRQ_TABLE_NUM_ENTRIES-1 ] = irq_empty_handler };\n\n\n#define CLINT_BASE 0x2000000\n\nvolatile uint64_t* mtime =   (uint64_t*)(CLINT_BASE + 0xbff8);\nvolatile uint64_t* mtimecmp = (uint64_t*)(CLINT_BASE + 0x4000);\n\nstatic irq_handler_t timer_irq_handler = 0;\n\n\nvoid level_1_interrupt_handler(uint32_t cause) {\n\n\tswitch (cause & 0xf) {\n\t\tcase RISCV_MACHINE_EXTERNAL_INTERRUPT: {\n\t\t\tasm volatile (\"csrc mip, %0\" : : \"r\" (0x800));\n\n\t\t\tuint32_t irq_id = *PLIC_CLAIM_AND_RESPONSE_REGISTER;\n\n\t\t\tirq_handler_table[irq_id]();\n\n\t\t\t*PLIC_CLAIM_AND_RESPONSE_REGISTER = 1;\n\n\t\t\treturn;\n\t\t}\n\n\t\tcase RISCV_MACHINE_TIMER_INTERRUPT: {\n\t\t\t// Note: the pending timer interrupt bit will be automatically cleared when writing to the *mtimecmp* register of this hart\n\t\t\tif (timer_irq_handler) {\n\t\t\t\t// let the user registered handler clear the timer interrupt bit\n\t\t\t\ttimer_irq_handler();\n\t\t\t} else {\n\t\t\t\t// reset the *mtimecmp* register to zero to clear the pending bit\n\t\t\t\t*mtimecmp = 0;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\t}\n\n\tassert (0 && \"unsupported cause\");\n}\n\nvoid register_interrupt_handler(uint32_t irq_id, irq_handler_t fn) {\n\tassert (irq_id < IRQ_TABLE_NUM_ENTRIES);\n\t// enable interrupt\n\tvolatile uint32_t* const reg = (PLIC_INTERRUPT_ENABLE_START + irq_id/32);\n\t*reg |= 1 << (irq_id%32);\n\t// set a prio different to zero (which means do-not-interrupt)\n\t*((uint32_t*) (PLIC_BASE + irq_id*sizeof(uint32_t))) = 1;\n\tirq_handler_table[irq_id] = fn;\n}\n\nvoid register_timer_interrupt_handler(irq_handler_t fn) {\n\ttimer_irq_handler = fn;\n}\n"
  },
  {
    "path": "sw/clock-ticks/irq.h",
    "content": "#ifndef __RISCV_IRQ_H__\n#define __RISCV_IRQ_H__\n\n#include \"stdint.h\"\n\ntypedef void (*irq_handler_t)(void);\n\nvoid register_interrupt_handler(uint32_t irq_id, irq_handler_t fn);\n\nvoid register_timer_interrupt_handler(irq_handler_t fn);\n\nextern volatile uint64_t* mtime;\nextern volatile uint64_t* mtimecmp;\n\n#endif\n"
  },
  {
    "path": "sw/clock-ticks/main.c",
    "content": "#include \"stdint.h\"\n#include \"irq.h\"\n#include \"stdio.h\"\n#include \"assert.h\"\n\nstatic void set_next_timer_interrupt() {\n\tassert (mtime && mtimecmp);\n\t*mtimecmp = *mtime + 1000;  // 1000 timer ticks, corresponds to 1 MS delay with current CLINT configuration\n}\n\nunsigned int num_ticks = 0;\n\nvoid timer_irq_handler() {\n\tset_next_timer_interrupt();\n\t++num_ticks;\n}\n\nint main() {\n\tprintf(\"num_ticks %d\\n\", num_ticks);\n\tregister_timer_interrupt_handler(timer_irq_handler);\n\tset_next_timer_interrupt();\n\twhile (num_ticks < 10) {\n\t\tprintf(\"num_ticks %d\\n\", num_ticks);\n\t}\n\tprintf(\"num_ticks %d\\n\", num_ticks);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/crc8/Makefile",
    "content": "OBJECTS  = main.o uart.o bootstrap.o\nCFLAGS   = -march=rv32i -mabi=ilp32\nLDFLAGS  = -nostartfiles -Wl,--no-relax -T link.ld\n\nVP       = microrv32-vp\nVP_FLAGS =\n\nhex: all\n\t../elf2bin.py ./main crc.hex 0x4020\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/crc8/bootstrap.S",
    "content": ".globl _start\n.globl main\n\n.equ SYSCALL_ADDR, 0x02010000\n\n.macro INIT_HW_PLATFORM\nand x1,x0,x0\nand x2,x0,x0\nand x3,x0,x0\nand x4,x0,x0\nand x5,x0,x0\nand x6,x0,x0\nand x7,x0,x0\nand x8,x0,x0\nand x9,x0,x0\nand x10,x0,x0\nand x11,x0,x0\nand x12,x0,x0\nand x13,x0,x0\nand x14,x0,x0\nand x15,x0,x0\nand x16,x0,x0\nand x17,x0,x0\nand x18,x0,x0\nand x19,x0,x0\nand x20,x0,x0\nand x21,x0,x0\nand x22,x0,x0\nand x23,x0,x0\nand x24,x0,x0\nand x25,x0,x0\nand x26,x0,x0\nand x27,x0,x0\nand x28,x0,x0\nand x29,x0,x0\nand x30,x0,x0\nand x31,x0,x0\n.endm\n\n.macro SYS_EXIT\nli   a7, 93\nli   t0, SYSCALL_ADDR\ncsrr a6, mhartid\nsw   a6, 0(t0)\n.endm\n\n_start:\n# initialize hw-platform\nINIT_HW_PLATFORM\nla sp, stack_end\njal main\n\n# call exit (SYS_EXIT=93) with exit code in a0\nSYS_EXIT\n\nstack_begin:\n.zero 1024\nstack_end:\n"
  },
  {
    "path": "sw/crc8/link.ld",
    "content": "OUTPUT_ARCH( \"riscv\" )\nENTRY(_start)\n\nSECTIONS\n{\n  . = 0x80000000;\n  .text.init : { *(.text.init) }\n  . = ALIGN(0x1000);\n  .tohost : { *(.tohost) }\n  . = ALIGN(0x1000);\n  .text : { *(.text) }\n  . = ALIGN(0x1000);\n  .data : { *(.data) }\n  .bss : { *(.bss) }\n  _end = .;\n}\n\n"
  },
  {
    "path": "sw/crc8/main.c",
    "content": "#include <stdint.h>\n#include <stdio.h>\n#include \"platform.h\"\n#include \"uart.h\"\n#include \"util.h\"\n\n// 8-bit SAE J1850 CRC\nunsigned char crc8(unsigned char *data, int length) {\n\t/*\n\t * 8-bit CRC calculation\n\t * polynomial     : 0x1D\n\t * initial value  : 0xFF\n\t * reflect input  : no\n\t * reflect result : no\n\t * XOR value      : 0xFF\n\t * check          : 0x4B\n\t * magic check    : 0xC4\n\t */\n\tunsigned long crc;\n\tint i,bit;\n\tcrc = 0xFF;\n\tfor(i=0; i<length; i++) {\n\t\tcrc ^= data[i];\n\t\tfor (bit=0; bit<8; bit++) {\n\t\t\tif((crc & 0x80)!=0) {\n\t\t\t\tcrc <<= 1;\n\t\t\t\tcrc ^= 0x1D;\n\t\t\t} else {\n\t\t\t\tcrc <<= 1;\n\t\t\t}\n\t\t}\n\t}\n\treturn (~crc)&0xFF; // xor value = 0xFF\n}\n\n\n\nint main(int argc, char **argv) {\n\t/*\n\t * test cases from AUTOSAR specification\n\t * 8-bit SAE J1850 CRC\n\t * see : https://www.autosar.org/fileadmin/user_upload/standards/classic/4-3/AUTOSAR_SWS_CRCLibrary.pdf (page 22/50)\n\t * \t\t7.2.1 8-bit CRC calculation\n\t * \t\t7.2.1.1 8-bit SAE J1850 CRC Calculation\n\t*/\n\t// NOTE idea: calculate all 6 test cases in one main loop, see if it makes a good benchmark?\n\t// unsigned char crcData[] = {0x00,0xC0,0xDF,0xAC,0xAA,0x07,0x40}; // 0x6C\n\t// unsigned char crcData[] = {0x00,0x00,0x00,0x00}; // 0x59\n\t// unsigned char crcData[] = {0xF2,0x01,0x83}; // 0x37\n\tconst unsigned char crcData[] = {0x33,0x22,0x55,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}; // 0xCB\n\t// unsigned char crcData[] = {0x92,0x6B,0x55}; // 0x8C\n\t//unsigned char crcData[] = {0xFF,0xFF,0xFF,0xFF}; // 0x74\n\tconst unsigned char crcTrueResult = 0xCB;\n\tchar buf[3];\n\tchar buf2[3];\n\tchar *txt1 = \"crc8 of:\\n\";\n\tchar *txt2 = \"result:\\n\";\n\tsendString(txt1,10);\n\tfor(int i=0; i<sizeof(crcData); i++) {\n\t\titoa(crcData[i], buf, 16);\n\t\tsendString(buf, 3);\n\t}\n\tputChr('\\n');\n\tconst unsigned char crcResult = crc8((unsigned char*)crcData,sizeof(crcData));\n\titoa(crcResult, buf2, 16);\n\tsendString(txt2,9);\n\tsendString(buf2, 3);\n\tputChr('\\n');\n\n\tif(crcResult != crcTrueResult) {\n\t\tsendString(\"CRC wrong!!!!111!!\", 19);\n\t\treturn -1;\n\t} else {\n\t\tsendString(\"CRC correct\\n\", 13);\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/crc8/platform.h",
    "content": "#ifndef PLATFORM_H\n#define PLATFORM_H\n\n//#define MICRORV\n\n#ifdef MICRORV\n// LED\nstatic volatile uint32_t *LED_ADDR = (uint32_t *)0x81000000;\n// UART\nstatic volatile uint32_t *UART_TX_DATA_ADDR = (uint32_t *)0x82000000;\nstatic volatile uint32_t *UART_TX_CTRL_ADDR = (uint32_t *)0x82000004;\nstatic volatile uint32_t *UART_RX_DATA_ADDR = (uint32_t *)0x82000008;\n// CLIC\nstatic volatile uint64_t *MTIMECMP_REG = (uint64_t *)0x02004000;\nstatic volatile uint64_t *MTIME_REG = (uint64_t *)0x0200bff8;\n#else\n// UART\nstatic volatile uint32_t *UART_TX_DATA_ADDR = (uint32_t *)0x82000000;\nstatic volatile uint32_t *UART_TX_CTRL_ADDR = (uint32_t *)0x82000004;\nstatic volatile uint32_t *UART_RX_DATA_ADDR = (uint32_t *)0x82000008;\n// CLIC\nstatic volatile uint64_t *MTIMECMP_REG = (uint64_t *)0x02004000;\nstatic volatile uint64_t *MTIME_REG = (uint64_t *)0x0200bff8;\n#endif\n\n#endif /* PLATFORM_H */"
  },
  {
    "path": "sw/crc8/uart.c",
    "content": "#include \"uart.h\"\n#include \"platform.h\"\n#include <stdint.h>\n\nint sendString(char* str, long len) {\n\tlong cnt = len;\n\tconst char *s = (const char *)str;\n\twhile (cnt > 0) {\n\t\t--cnt;\n\t\tputChr(*s);\n\t\ts++;\n\t}\n\treturn len;\n}\n\nvoid putChr(char chr) {\n#ifdef MICRORV\n\tuint32_t tx_rdy = 0;\n\t*UART_TX_ADDR = chr;\n\t// send character stored in uart_tx_addr\n\t*UART_TX_CTRL = 1;\n\t// wait until tx is ready again for sening another character\n\tdo {\n\t\t// read uart tx status\n\t\ttx_rdy = *UART_TX_CTRL;\n\t\tasm volatile (\"nop\");\n\t} while(!tx_rdy);\n#else\n\tuint32_t tx_rdy = 0;\n\t*UART_TX_DATA_ADDR = chr;\n\t// send character stored in uart_tx_addr\n\t*UART_TX_CTRL_ADDR = 1;\n\t// wait until tx is ready again for sening another character\n\tdo {\n\t\t// read uart tx status\n\t\ttx_rdy = *UART_TX_CTRL_ADDR;\n\t\tasm volatile (\"nop\");\n\t} while(!tx_rdy);\n#endif\n\treturn;\n}"
  },
  {
    "path": "sw/crc8/uart.h",
    "content": "#ifndef  UART_H\n\n#include <stdint.h>\n\nint sendString(char* str, long len);\nvoid putChr(char chr);\n\n#endif /* UART_H */"
  },
  {
    "path": "sw/crc8/util.c",
    "content": "/*\n* utility functions for embedded usage where c-libs are too big\n*/\n\n//----------------------------\n// integer to ascii (itoa) with util functions\n//----------------------------\n\n// function to swap two numbers\nvoid swap(char *x, char *y) {\n\tchar t = *x;\n\t*x = *y;\n\t*y = t;\n}\n\n// function to reverse buffer[i..j]\nchar* reverse(char *buffer, int i, int j) {\n\twhile (i < j)\n\t\tswap(&buffer[i++], &buffer[j--]);\n\treturn buffer;\n}\n\n// Iterative function to implement itoa() function in C\nchar* itoa(int value, char* buffer, int base) {\n\t// invalid input\n\tif (base < 2 || base > 32)\n\t\treturn buffer;\n\t// consider absolute value of number\n\tint n = (value < 0) ? -value : value;\n\tint i = 0;\n\twhile (n) {\n\t\tint r = n % base;\n\t\tif (r >= 10)\n\t\t\tbuffer[i++] = 65 + (r - 10);\n\t\telse\n\t\t\tbuffer[i++] = 48 + r;\n\t\tn = n / base;\n\t}\n\n\t// if number is 0\n\tif (i == 0)\n\t\tbuffer[i++] = '0';\n\n\t// If base is 10 and value is negative, the resulting string\n\t// is preceded with a minus sign (-)\n\t// With any other base, value is always considered unsigned\n\tif (value < 0 && base == 10)\n\t\tbuffer[i++] = '-';\n\n\tbuffer[i] = '\\0'; // null terminate string\n\n\t// reverse the string and return it\n\treturn reverse(buffer, 0, i - 1);\n}\n"
  },
  {
    "path": "sw/crc8/util.h",
    "content": "#ifndef  UTIL_H\n\nvoid swap(char *x, char *y);\nchar* reverse(char *buffer, int i, int j);\nchar* itoa(int value, char* buffer, int base);\n\n#endif /* UTIL_H */"
  },
  {
    "path": "sw/flashTest/Makefile",
    "content": "OBJECTS  = main.o\nCXXFLAGS = -ggdb -std=c++14 -march=rv32ima -mabi=ilp32\n\ninclude ../Makefile.common\noverride LD = $(CXX)\n"
  },
  {
    "path": "sw/flashTest/main.cpp",
    "content": "#include <inttypes.h>\n#include <string.h>\n#include <iostream>\n\n// From flash.h\nstatic constexpr unsigned int BLOCKSIZE = 512;\nstatic constexpr unsigned int FLASH_ADDR_REG = 0;\nstatic constexpr unsigned int FLASH_SIZE_REG = sizeof(uint64_t);\nstatic constexpr unsigned int DATA_ADDR = FLASH_SIZE_REG + sizeof(uint64_t);\n// static constexpr unsigned int ADDR_SPACE = DATA_ADDR + BLOCKSIZE;\n\nstatic uint8_t* volatile const FLASH_CONTROLLER = (uint8_t * volatile const)(0x71000000);\n\nusing namespace std;\n\nvoid setTargetBlock(uint64_t addr);\nvoid readFlash(char* dst, uint64_t addr, size_t len);\nvoid writeFlash(const char* src, uint64_t addr, size_t len);\n\nint main() {\n\tunsigned long counter = 0;\n\tuint64_t flashNumOfBlocks = 0;\n\tmemcpy(&flashNumOfBlocks, FLASH_CONTROLLER + FLASH_SIZE_REG, sizeof(uint64_t));\n\n\tcout << \"Flash size: \" << flashNumOfBlocks * BLOCKSIZE << \" (\" << flashNumOfBlocks << \" Blocks)\" << endl;\n\n\treadFlash(reinterpret_cast<char*>(&counter), 0, sizeof(unsigned long));\n\n\tcout << \" Counter before: \" << counter << endl;\n\n\twriteFlash(reinterpret_cast<char*>(&++counter), 0, sizeof(unsigned long));\n\n\tcout << \" Counter after: \" << counter << endl;\n}\n\nvoid setTargetBlock(uint64_t addr) {\n\tuint64_t targetBlock = addr % BLOCKSIZE;\n\tmemcpy(FLASH_CONTROLLER + FLASH_ADDR_REG, &targetBlock, sizeof(uint64_t));\n}\n\nvoid readFlash(char* dst, uint64_t addr, size_t len) {\n\tif (addr / BLOCKSIZE != (addr + len) / BLOCKSIZE) {\n\t\tcerr << \"Unaligned read, currently not supported\" << endl;\n\t\treturn;\n\t}\n\tsetTargetBlock(addr);\n\tmemcpy(dst, FLASH_CONTROLLER + DATA_ADDR, len);\n}\n\nvoid writeFlash(const char* src, uint64_t addr, size_t len) {\n\tif (addr / BLOCKSIZE != (addr + len) / BLOCKSIZE) {\n\t\tcerr << \"Unaligned read, currently not supported\" << endl;\n\t\treturn;\n\t}\n\tsetTargetBlock(addr);\n\tmemcpy(FLASH_CONTROLLER + DATA_ADDR, src, len);\n}\n"
  },
  {
    "path": "sw/flashTest/test-ignore",
    "content": ""
  },
  {
    "path": "sw/mramTest/Makefile",
    "content": "OBJECTS  = main.o\nCXXFLAGS = -ggdb -std=c++14 -march=rv32ima -mabi=ilp32\n\ninclude ../Makefile.common\noverride LD = $(CXX)\n"
  },
  {
    "path": "sw/mramTest/main.cpp",
    "content": "#include <string.h>\n#include \"stdio.h\"\n\nstatic char* const MRAM_START_ADDR = reinterpret_cast<char* const>(0x60000000);\nstatic const unsigned int MRAM_SIZE = 0x0FFFFFFF;\n\nint main() {\n\tunsigned long counter = 0;\n\tchar buffer[10] = {0};\n\n\tmemcpy(&counter, MRAM_START_ADDR, sizeof(unsigned long));\n\tmemcpy(buffer, MRAM_START_ADDR + 10, 10);\n\n\tprintf(\"Before:\\n\");\n\tprintf(\"%lu, %0.*s\\n\", counter, 10, buffer);\n\n\tmemcpy(MRAM_START_ADDR, &(++counter), sizeof(unsigned long));\n\tmemcpy(MRAM_START_ADDR + 10, \"Kokosnuss\", 10);\n\n\tmemcpy(&counter, MRAM_START_ADDR, sizeof(unsigned long));\n\tmemcpy(buffer, MRAM_START_ADDR + 10, 10);\n\n\tprintf(\"After:\\n\");\n\tprintf(\"%lu, %0.*s\\n\", counter, 10, buffer);\n}\n"
  },
  {
    "path": "sw/mrv32-uart/Makefile",
    "content": "rvArch?=rv32i\n\nOBJECTS  = bootstrap.o main.o uart.o util.o\nCFLAGS   = -march=$(rvArch) -mabi=ilp32 -mno-strict-align\nLDFLAGS  = -nostartfiles -Wl,--no-relax,--print-memory-usage  -T link.ld\n\nVP       = microrv32-vp\nVP_FLAGS =\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/mrv32-uart/bootstrap.S",
    "content": ".globl _start\n.globl main\n\n.equ SYSCALL_ADDR, 0x02010000\n\n.macro INIT_HW_PLATFORM\nand x1,x0,x0\nand x2,x0,x0\nand x3,x0,x0\nand x4,x0,x0\nand x5,x0,x0\nand x6,x0,x0\nand x7,x0,x0\nand x8,x0,x0\nand x9,x0,x0\nand x10,x0,x0\nand x11,x0,x0\nand x12,x0,x0\nand x13,x0,x0\nand x14,x0,x0\nand x15,x0,x0\nand x16,x0,x0\nand x17,x0,x0\nand x18,x0,x0\nand x19,x0,x0\nand x20,x0,x0\nand x21,x0,x0\nand x22,x0,x0\nand x23,x0,x0\nand x24,x0,x0\nand x25,x0,x0\nand x26,x0,x0\nand x27,x0,x0\nand x28,x0,x0\nand x29,x0,x0\nand x30,x0,x0\nand x31,x0,x0\n.endm\n\n.macro SYS_EXIT, exit_code\nli   a7, 93\nli   a0, \\exit_code\nli   t0, SYSCALL_ADDR\ncsrr a6, mhartid\nsw   a6, 0(t0)\nsw   a7, 0(t0)\n.endm\n\n.align 4\n_start:\n# initialize hw-platform\nINIT_HW_PLATFORM\nla sp, stack_end\njal main\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\n1: SYS_EXIT 0\nj 1b\n\n.align 4\nstack_begin:\n.zero 2048\nstack_end:\n"
  },
  {
    "path": "sw/mrv32-uart/link.ld",
    "content": "OUTPUT_ARCH( \"riscv\" )\nENTRY(_start)\n\nMEMORY {\n  RAM (rwx): ORIGIN = 0x80000000, LENGTH = 8k\n}\n\nSECTIONS\n{\n  . = 0x80000000;\n  .text.init : { *(.text.init) } > RAM\n  . = ALIGN(0x1000);\n  .tohost : { *(.tohost) } > RAM\n  . = ALIGN(0x1000);\n  .text : { *(.text) } > RAM\n  . = ALIGN(0x1000);\n  .data : { *(.data) } > RAM\n  .bss : { *(.bss) } > RAM\n  _end = .;\n}\n\n"
  },
  {
    "path": "sw/mrv32-uart/main.c",
    "content": "#include <stdint.h>\n#include <stdio.h>\n// #include <string.h>\n#include \"platform.h\"\n#include \"uart.h\"\n#include \"util.h\"\n\nvoid delay(uint32_t loops) {\n\tfor(uint32_t i = 0; i < loops; i++) {\n\t\tasm volatile(\"nop\");\n\t}\n}\n\nint main() {\n\tdelay(10000);\n\tchar buf[3];\n\tchar *txt1 = \"uart rx failed?!\\n\";\n\tdelay(5000);\n\t// delay(7000);\n\t// delay(2000);\n\t// delay(10000);\n\n\tchar rxBuf[5];\n\tint rxEmpty = 1;\n\tint maxCnt = 30;\n\tint cnt = 0;\n\trxEmpty = UART->RXEMPT;\n\tint occ;\n\tif(!rxEmpty) {\n\t\t// read rx data register from uart peripheral\n\t\tdo {\n\t\t\trxBuf[0] = UART->RXDATA;\n\t\t\tputChr(rxBuf[0]);\n\t\t\tcnt++;\n\t\t\tocc = UART->RXOCCU;\n\t\t\t// sendString()\n\t\t} while(UART->RXEMPT || cnt <= maxCnt);\n\t\tputChr('\\n');\n\t\tputChr('\\n');\n\t} else {\n\t\tsendString(txt1,1600);\n\t\tputChr('\\n');\n\t}\n\n\treturn 0;\n}"
  },
  {
    "path": "sw/mrv32-uart/platform.h",
    "content": "#ifndef PLATFORM_H\n#define PLATFORM_H\n\n/* #define MICRORV\n\n// #ifdef MICRORV */\n// LED\nstatic volatile uint32_t *LED_ADDR = (uint32_t *)0x81000000;\n// UART\nstatic volatile uint32_t *UART_TX_DATA_ADDR = (uint32_t *)0x82000000;\nstatic volatile uint32_t *UART_TX_CTRL_ADDR = (uint32_t *)0x82000004;\nstatic volatile uint32_t *UART_RX_DATA_ADDR = (uint32_t *)0x82000008;\n// CLIC\nstatic volatile uint64_t *MTIMECMP_REG = (uint64_t *)0x02004000;\nstatic volatile uint64_t *MTIME_REG = (uint64_t *)0x0200bff8;\n\ntypedef struct {\n\tvolatile uint32_t TXDATA;\n\tvolatile uint32_t TXCTRL;\n\tvolatile uint32_t RXDATA;\n\tvolatile uint32_t RXOCCU;\n\tvolatile uint32_t RXALEM;\n\tvolatile uint32_t RXEMPT;\n} UART_REGS;\n\n#define UART        ((UART_REGS *)0x82000000)\n\n/* #else\n// // UART\n// static volatile uint32_t *UART_TX_DATA_ADDR = (uint32_t *)0x82000000;\n// static volatile uint32_t *UART_TX_CTRL_ADDR = (uint32_t *)0x82000004;\n// static volatile uint32_t *UART_RX_DATA_ADDR = (uint32_t *)0x82000008;\n// static volatile uint32_t *UART_RX_FIFO_OCC_ADDR = (uint32_t *)0x8200000c;\n// static volatile uint32_t *UART_RX_FIFO_ALMOST_EMPTY_ADDR = (uint32_t *)0x82000010;\n// static volatile uint32_t *UART_RX_FIFO_EMPTY_ADDR = (uint32_t *)0x82000014;\n\n// // CLIC\n// static volatile uint64_t *MTIMECMP_REG = (uint64_t *)0x02004000;\n// static volatile uint64_t *MTIME_REG = (uint64_t *)0x0200bff8;\n// #endif */\n\n#endif /* PLATFORM_H */"
  },
  {
    "path": "sw/mrv32-uart/uart.c",
    "content": "#include \"uart.h\"\n#include \"platform.h\"\n#include <stdint.h>\n\nint sendString(char* str, long len) {\n\tlong cnt = len;\n\tconst char *s = (const char *)str;\n\twhile (cnt > 0) {\n\t\t--cnt;\n\t\tputChr(*s);\n\t\ts++;\n\t}\n\treturn len;\n}\n\nvoid putChr(char chr) {\n\tuint32_t tx_rdy = 0;\n\tUART->TXDATA = chr;\n\t// send character stored in uart_tx_addr\n\tUART->TXCTRL = 1;\n\t// wait until tx is ready again for sening another character\n\tdo {\n\t\t// read uart tx status\n\t\ttx_rdy = UART->TXCTRL;\n\t\tasm volatile (\"nop\");\n\t} while(!tx_rdy);\n\treturn;\n}"
  },
  {
    "path": "sw/mrv32-uart/uart.h",
    "content": "#ifndef  UART_H\n\n#include <stdint.h>\n\nint sendString(char* str, long len);\nvoid putChr(char chr);\n\n#endif /* UART_H */"
  },
  {
    "path": "sw/mrv32-uart/util.c",
    "content": "/*\n* utility functions for embedded usage where c-libs are too big\n*/\n\n//----------------------------\n// integer to ascii (itoa) with util functions\n//----------------------------\n\n// function to swap two numbers\nvoid swap(char *x, char *y) {\n\tchar t = *x;\n\t*x = *y;\n\t*y = t;\n}\n\n// function to reverse buffer[i..j]\nchar* reverse(char *buffer, int i, int j) {\n\twhile (i < j)\n\t\tswap(&buffer[i++], &buffer[j--]);\n\treturn buffer;\n}\n\n// Iterative function to implement itoa() function in C\nchar* itoa(int value, char* buffer, int base) {\n\t// invalid input\n\tif (base < 2 || base > 32)\n\t\treturn buffer;\n\t// consider absolute value of number\n\tint n = (value < 0) ? -value : value;\n\tint i = 0;\n\twhile (n) {\n\t\tint r = n % base;\n\t\tif (r >= 10)\n\t\t\tbuffer[i++] = 65 + (r - 10);\n\t\telse\n\t\t\tbuffer[i++] = 48 + r;\n\t\tn = n / base;\n\t}\n\n\t// if number is 0\n\tif (i == 0)\n\t\tbuffer[i++] = '0';\n\n\t// If base is 10 and value is negative, the resulting string\n\t// is preceded with a minus sign (-)\n\t// With any other base, value is always considered unsigned\n\tif (value < 0 && base == 10)\n\t\tbuffer[i++] = '-';\n\n\tbuffer[i] = '\\0'; // null terminate string\n\n\t// reverse the string and return it\n\treturn reverse(buffer, 0, i - 1);\n}\n"
  },
  {
    "path": "sw/mrv32-uart/util.h",
    "content": "#ifndef  UTIL_H\n\nvoid swap(char *x, char *y);\nchar* reverse(char *buffer, int i, int j);\nchar* itoa(int value, char* buffer, int base);\n\n#endif /* UTIL_H */"
  },
  {
    "path": "sw/peripheral-in-the-loop/Makefile",
    "content": "OBJECTS = main.o irq.o bootstrap.o\nCFLAGS  = -march=rv32i -mabi=ilp32\nLDFLAGS = -nostartfiles -Wl,--no-relax\n\nvirtual-bus-path=../../vp/src/platform/hwitl/virtual-bus\nsimple-sensor-path=../simple-sensor\ntty=/dev/ttyUSB2\n\n$(virtual-bus-path)/responder-cli:\n\tmake -C $(virtual-bus-path) responder-cli\n\nsim-bus: $(EXECUTABLE) $(virtual-bus-path)/responder-cli\n\tmake -C $(virtual-bus-path) pipe_left\n\tsleep 1 #needed sometimes as pipe is not immediately there\n\t$(virtual-bus-path)/responder-cli $(virtual-bus-path)/pipe_right &\n\thwitl-vp $(EXECUTABLE) --error-on-zero-traphandler=true --virtual-bus-device $(virtual-bus-path)/pipe_left\n\tkillall responder-cli\n\tkillall socat\n\nreal: $(EXECUTABLE)\n\thwitl-vp $(EXECUTABLE) --error-on-zero-traphandler=true --virtual-bus-device $(tty)\n\nclearpipes:\n\tkillall responder-cli || true\n\tkillall socat || true\n\nSIM_TARGET = sim-bus\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/peripheral-in-the-loop/main.c",
    "content": "#include <stdint.h>\n#include \"../simple-sensor/irq.h\"\n\ntypedef uint32_t BUS_BRIDGE_TYPE;\nstatic volatile BUS_BRIDGE_TYPE * const BUS_BRIDGE_START = (BUS_BRIDGE_TYPE * const) 0x50000000;\nstatic volatile BUS_BRIDGE_TYPE * const BUS_BRIDGE_END   = (BUS_BRIDGE_TYPE * const) 0x5000000F; // INCLUSIVE\nstatic const unsigned BUS_BRIDGE_ITR = 2;\nstatic volatile char * const TERMINAL_ADDR = (char * const)0x20000000;\n\nstatic const unsigned num_words = (BUS_BRIDGE_END - BUS_BRIDGE_START) + 1;\t\t// INCLUSIVE\n\nvoid read_stuff() {\n\tfor (int i = 0; i < num_words; i++) {\n\t\tconst BUS_BRIDGE_TYPE datum = BUS_BRIDGE_START[i];\n\t\tfor(int c = 0; c < sizeof(BUS_BRIDGE_TYPE); c++) {\n\t\t\t*TERMINAL_ADDR = ((uint8_t*)&datum)[c];\n\t\t}\n\t\t*TERMINAL_ADDR = '\\n';\n\t}\n}\n\nvoid write_stuff() {\n\tfor (int i = 0; i < num_words; i++) {\n\t\tBUS_BRIDGE_TYPE datum;\n\t\tfor(int c = 0; c < sizeof(BUS_BRIDGE_TYPE); c++) {\n\t\t\t((uint8_t*)&datum)[c] = 'a' + (i+c);\n\t\t\t*TERMINAL_ADDR = ((uint8_t*)&datum)[c];\n\t\t}\n\t\tBUS_BRIDGE_START[i] = datum;\n\t\t*TERMINAL_ADDR = '\\n';\n\t}\n}\n\nvolatile int was_itr_triggered = 0;\nvoid virtual_bus_irq_handler() {\n\tstatic const char* hi = \"Interrupt was triggered\\n\";\n\twas_itr_triggered = 1;\n\tfor(int i = 0; hi[i]; i++)\n\t\t*TERMINAL_ADDR = hi[i];\n}\n\nint main() {\n\tregister_interrupt_handler(BUS_BRIDGE_ITR, virtual_bus_irq_handler);\n\n\tread_stuff();\n\n\t/*\n\twhile(!was_itr_triggered)\n\t\tasm volatile (\"wfi\");\n\t*/\n\n\twrite_stuff();\n\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/printf/Makefile",
    "content": "OBJECTS  = main.o entry.o\nCFLAGS   = -march=rv32i -mabi=ilp32\nLDFLAGS  = -Wl,-e_reset_vector\nVP_FLAGS = --error-on-zero-traphandler=true\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/printf/entry.S",
    "content": ".globl _start\n.globl _reset_vector\n.equ SYSCALL_ADDR, 0x02010000\n\ntrap_handler:\n\tli   t0, SYSCALL_ADDR\n\tcsrr t1, mhartid\n\tsw   t1, 0(t0)\n\tcsrr t0, mepc\n\taddi t0, t0, 4\n\tcsrw mepc, t0\n\tmret\n\n_reset_vector:\nla t0, trap_handler\ncsrw mtvec, t0\nj _start\n"
  },
  {
    "path": "sw/printf/main.c",
    "content": "#include \"stdio.h\"\n#include \"errno.h\"\n#include \"string.h\"\n#include \"unistd.h\"\n\nint main(int argc, char **argv) {\n\tint n = printf(\"ABCDEFX %s\\n\", \"Done\");\n\tint e = errno;\n\tputs(strerror(e));\n\n\tputs (\"Hello World!\");\n\tputs (\"  Hello World!\");\n\tputs (\" X A \");\n\tputchar('a');\n\tputchar('b');\n\tputchar('c');\n\tputchar('\\n');\n\tprintf(\"  X Test\\n\");\n\tprintf(\"%d\\n\", 12);\n\n\tprintf(\"Should print 1.2: %f\\n\", 1.2f);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/simple-display/Makefile",
    "content": "OBJECTS  = main.o libDisplay.o\nCXXFLAGS = -std=c++14 -march=rv32ima -mabi=ilp32\n\nremoveSHMEM:\n\tipcrm --shmem-key 0x0000053a || true\n\ninclude ../Makefile.common\noverride LD = $(CXX)\n"
  },
  {
    "path": "sw/simple-display/libDisplay.cpp",
    "content": "/*\n * libDisplay.cpp\n *\n *  Created on: Oct 5, 2018\n *      Author: dwd\n */\n\n#include \"libDisplay.hpp\"\n#include <math.h>\n#include <algorithm>\n\ntypedef Framebuffer::Point Point;\ntypedef Framebuffer::PointF PointF;\ntypedef Framebuffer::Color Color;\n\n\nnamespace display {\n\nvoid setPixel(Framebuffer::Type frame, Point pixel, Color color) {\n\tframebuffer->getFrame(frame).raw[pixel.y][pixel.x] = color;\n}\n\nvoid drawLine(Framebuffer::Type frame, PointF from, PointF to, Color color) {\n\tframebuffer->parameter.line.frame = frame;\n\tframebuffer->parameter.line.from = from;\n\tframebuffer->parameter.line.to = to;\n\tframebuffer->parameter.line.color = color;\n\tframebuffer->command = Framebuffer::Command::drawLine;\n}\n\nvoid drawRect(Framebuffer::Type frame, PointF ol, PointF ur, Color color) {\n\tif (ol.x > ur.x) {\n\t\tstd::swap(ol.x, ur.x);\n\t}\n\tif (ol.y > ur.y) {\n\t\tstd::swap(ol.y, ur.y);\n\t}\n\tdrawLine(frame, ol, PointF(ur.x, ol.y), color);\n\tdrawLine(frame, PointF(ur.x, ol.y), ur, color);\n\tdrawLine(frame, ur, PointF(ol.x, ur.y), color);\n\tdrawLine(frame, PointF(ol.x, ur.y), ol, color);\n}\n\nvoid fillRect(Framebuffer::Type frame, PointF ol, PointF ur, Color color) {\n\tif (ol.x == ur.x || ol.y == ur.y) {  // No dimension\n\t\treturn;\n\t}\n\tif (ol.x > ur.x) {\n\t\tstd::swap(ol.x, ur.x);\n\t}\n\tif (ol.y > ur.y) {\n\t\tstd::swap(ol.y, ur.y);\n\t}\n\tif (ur.x - ol.x > ur.y - ol.y) {\n\t\t// Horizontal\n\t\tfor (uint16_t y = ol.y; y <= ur.y; y++) {\n\t\t\tdrawLine(frame, PointF(ol.x, y), PointF(ur.x, y), color);\n\t\t}\n\t} else {\n\t\t// Vertical\n\t\tfor (uint16_t x = ol.x; x <= ur.x; x++) {\n\t\t\tdrawLine(frame, PointF(x, ol.y), PointF(x, ur.y), color);\n\t\t}\n\t}\n}\n\nvoid applyFrame() {\n\tframebuffer->command = Framebuffer::Command::applyFrame;\n}\n\nvoid fillFrame(Framebuffer::Type frame, Color color) {\n\tframebuffer->parameter.fill.frame = frame;\n\tframebuffer->parameter.fill.color = color;\n\tframebuffer->command = Framebuffer::Command::fillFrame;\n}\n\n}  // namespace display\n"
  },
  {
    "path": "sw/simple-display/libDisplay.hpp",
    "content": "/*\n * libDisplay.hpp\n *\n *  Created on: Oct 5, 2018\n *      Author: dwd\n */\n\n#pragma once\n\n#include \"../../env/basic/vp-display/framebuffer.h\"\n\nextern Framebuffer* volatile const framebuffer;\n\ninline Framebuffer::Color fromRGB(uint8_t r, uint8_t g, uint8_t b) {\n\tFramebuffer::Color ret = 0;\n\tret |= (b & 0x0F);\n\tret |= (g & 0x0F) << 4;\n\tret |= (r & 0x0F) << 8;\n\treturn ret;\n}\n\nnamespace display {\nvoid setPixel(Framebuffer::Type frame, Framebuffer::Point pixel, Framebuffer::Color color);\n\nvoid drawLine(Framebuffer::Type frame, Framebuffer::PointF from, Framebuffer::PointF to, Framebuffer::Color color);\n\nvoid drawRect(Framebuffer::Type frame, Framebuffer::PointF ol, Framebuffer::PointF ur, Framebuffer::Color color);\n\nvoid fillRect(Framebuffer::Type frame, Framebuffer::PointF ol, Framebuffer::PointF ur, Framebuffer::Color color);\n\nvoid applyFrame();\n\nvoid fillFrame(Framebuffer::Type frame = Framebuffer::Type::foreground, Framebuffer::Color color = 0);\n};  // namespace display\n"
  },
  {
    "path": "sw/simple-display/main.cpp",
    "content": "#include \"libDisplay.hpp\"\n\n#include <math.h>\n#include <climits>\n#include <cstring>\n#include <iostream>\n\nFramebuffer* volatile const framebuffer = (Framebuffer * volatile const)(0x72000000);\n\ntypedef Framebuffer::Point Point;\ntypedef Framebuffer::PointF PointF;\ntypedef Framebuffer::Color Color;\nstatic constexpr auto screenWidth = Framebuffer::screenWidth;\nstatic constexpr auto screenHeight = Framebuffer::screenHeight;\n\nvoid activeWait(float factor = 0.5) {\n\tfor (uint16_t i = 0; i < UINT16_MAX * factor; i++) {\n\t};\n}\n\nPoint getRandomPoint() {\n\treturn Point(rand() % screenWidth, rand() % screenHeight);\n}\n\nColor getRandomColor() {\n\treturn rand() % SHRT_MAX;\n}\n\nvoid drawBackground() {\n\tfor (uint32_t i = 0; i < screenHeight - 1; i++) {\n\t\tdisplay::drawLine(Framebuffer::Type::background, Point(0, i), Point(screenWidth, i),\n\t\t                  fromRGB(i & 0x7, 0, i >> 3));\n\t\tif (i % 5 == 0)\n\t\t\tdisplay::applyFrame();\n\t}\n}\n\nvoid drawFunnyRects() {\n\tstatic uint32_t m = 0;\n\tfor (uint16_t i = 0; i < 400; i++) {\n\t\t// drawLine(framebuffer->getInactiveFrame(), getRandomPoint(),\n\t\t// getRandomPoint(), getRandomColor());\n\t\tdisplay::drawRect(Framebuffer::Type::foreground, Point(m % screenWidth, m % screenHeight),\n\t\t                  Point(\n\t\t\t\t   (screenWidth - (m + 1) % screenWidth), (screenHeight - (m + 1) % screenHeight)\n\t\t\t\t  ),\n\t\t                  fromRGB(255 - (m % 255), (m % 255), i % 255));\n\t\tdisplay::applyFrame();\n\t\tactiveWait(.005);\n\t\tm += 17;\n\t}\n}\n\n/**\n * @param completion Values between 0..1\n */\nvoid progressBar(bool horizontal, Framebuffer::PointF base, Framebuffer::PointF extent, Color fg, Color bg, float completion) {\n\tPointF progress = horizontal ? PointF(extent.x * completion, extent.y) : PointF(extent.x, extent.y * completion);\n\n\tdisplay::fillRect(Framebuffer::Type::foreground, base, base + progress, fg);\n\tdisplay::fillRect(Framebuffer::Type::foreground, base + progress, base + extent, bg);\n}\n\nvoid drawFunnyBar(bool horizontal = false) {\n\tColor bgColor = fromRGB(0, 0, 1);\n\tColor progressColor = fromRGB(126, 255, 10);\n\tPoint baseOL;\n\tPoint baseUR;\n\tuint16_t stepsize = 1;\n\tif (horizontal) {\n\t\tbaseOL = Point(100, 250);\n\t\tbaseUR = Point(700, 350);\n\t} else {\n\t\tbaseOL = Point(350, 50);\n\t\tbaseUR = Point(450, 550);\n\t}\n\n\tdisplay::fillRect(Framebuffer::Type::foreground, baseOL, baseUR, bgColor);\n\tdisplay::applyFrame();\n\tPoint barBase(baseOL.x + 10, baseOL.y + 10);\n\tPoint barExtent((baseUR.x - baseOL.x) - 20, (baseUR.y - baseOL.y) - 20);\n\n\tfor (float progress = 0; progress <= 1; progress += 0.01) {\n\t\tdisplay::fillRect(Framebuffer::Type::foreground, baseOL, baseUR, bgColor);\n\t\tprogressBar(horizontal, barBase, barExtent, progressColor, bgColor, progress);\n\t\tdisplay::applyFrame();\n\t\tactiveWait(.005);\n\t}\n\tfor (float progress = 1; progress >= 0; progress -= 0.01) {\n\t\tdisplay::fillRect(Framebuffer::Type::foreground, baseOL, baseUR, bgColor);\n\t\tprogressBar(horizontal, barBase, barExtent, progressColor, bgColor, progress);\n\t\tdisplay::applyFrame();\n\t\tactiveWait(.005);\n\t}\n}\n\nusing namespace std;\n\nint main() {\n\tcout << \"draw background\" << endl;\n\tdrawBackground();\n\twhile (true) {\n\t\tcout << \"Draw H-bar\" << endl;\n\t\tdrawFunnyBar(true);\n\t\tdisplay::fillFrame(Framebuffer::Type::foreground);\n\t\tdisplay::applyFrame();\n\t\tcout << \"Draw V-bar\" << endl;\n\t\tdrawFunnyBar(false);\n\t\tdisplay::fillFrame(Framebuffer::Type::foreground);\n\t\tdisplay::applyFrame();\n\t\tcout << \"Draw Rects\" << endl;\n\t\tdrawFunnyRects();\n\t\tdisplay::fillFrame(Framebuffer::Type::foreground);\n\t\tdisplay::applyFrame();\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/simple-display/test-ignore",
    "content": ""
  },
  {
    "path": "sw/simple-scheduler/Makefile",
    "content": "OBJECTS  = main.o cor.o\nCFLAGS   = -march=rv32imac -mabi=ilp32\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/simple-scheduler/cor.S",
    "content": ".globl contextswitch\n.globl coroutine_entry\n.globl launch_coroutine\n\n\ncoroutine_entry:\n\t// move the launch argument to the a0 register (i.e. first argument of the following function)\n\tmv    a0,s0\n\tcall  launch_coroutine\n\n\t// the above call should not return\t(i.e the scheduler should not call a finished coroutine)\n\tebreak\n\n\n/*\n * registers a0 and a1 point to the current and next context, respectively\n *\n * 1) store all current registers and pc in the current context\n * 2) load register values from next context\n * 3) jump to pc in the next context\n */\ncontextswitch:\n\t// store registers\n\tsw    x1,4(a0)\t    // ra\n\tsw    x2,8(a0)\t\t// sp\n\tsw    x8,32(a0)\t\t// s0\n\tsw    x9,36(a0)\t\t// s1\n\tsw    x18,72(a0)\t// s2\n\tsw    x19,76(a0)\t// s3\n\tsw    x20,80(a0)\t// s4\n\tsw    x21,84(a0)\t// s5\n\tsw    x22,88(a0)\t// s6\n\tsw    x23,92(a0)\t// s7\n\tsw    x24,96(a0)\t// s8\n\tsw    x25,100(a0)\t// s9\n\tsw    x26,104(a0)\t// s10\n\tsw    x27,108(a0)\t// s11\n\n\t// store pc\n\tla    t0,_resume\n\tsw    t0,0(a0)\n\n\t// restore other registers (NOTE: callee saved only + ra)\n\tlw    x1,4(a1)\t\t// ra\n\tlw    x2,8(a1)\t\t// sp\n\tlw    x8,32(a1)\t\t// s0\n\tlw    x9,36(a1)\t\t// s1\n\tlw    x18,72(a1)\t// s2\n\tlw    x19,76(a1)\t// s3\n\tlw    x20,80(a1)\t// s4\n\tlw    x21,84(a1)\t// s5\n\tlw    x22,88(a1)\t// s6\n\tlw    x23,92(a1)\t// s7\n\tlw    x24,96(a1)\t// s8\n\tlw    x25,100(a1)\t// s9\n\tlw    x26,104(a1)\t// s10\n\tlw    x27,108(a1)\t// s11\n\n\t// load new program counter and perform context switch\n\tlw\t  t0,0(a1)\n\tjr    t0\n\n\t_resume:\n\n\tret\n\n"
  },
  {
    "path": "sw/simple-scheduler/main.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <assert.h>\n#include <stdint.h>\n\n#define REG_SP 1\n#define REG_S0 7\n\ntypedef void (*entrypoint_t)(void *);\n\nenum state_t {\n\tUNKNOWN,\n\tSTART,\n\tACTIVE,\n\tFINISHED\n};\n\ntypedef struct {\n\tuint32_t pc;\n\tuint32_t regs[31];\n} context_t;\n\ntypedef struct {\n\tuint8_t stack[16384];\n\tcontext_t ctx;\n\tentrypoint_t entry;\n\tvoid *arg;\n\tenum state_t stat;\n} coroutine_t;\n\n\ncontext_t main_context;\ncontext_t *active_context;\n\nextern void contextswitch(context_t *current, context_t *next);\n\nextern void coroutine_entry();\n\n\nvoid switch_to_scheduler() {\n\tcontextswitch(active_context, &main_context);\n}\n\nvoid switch_to_coroutine(coroutine_t *cor) {\n\tactive_context = &cor->ctx;\n\tcontextswitch(&main_context, &cor->ctx);\n}\n\n\nvoid launch_coroutine(coroutine_t *cor) {\n\tcor->stat = ACTIVE;\n\tcor->entry(cor->arg);\n\tcor->stat = FINISHED;\n\tassert (active_context == &cor->ctx);\n\tswitch_to_scheduler();\n}\n\n\nvoid function_A(void *arg) {\n\tprintf(\"A fn: 1\\n\");\n\tswitch_to_scheduler();\n\tprintf(\"A fn: 2\\n\");\n}\n\nvoid function_B(void *arg) {\n\tprintf(\"B fn: 1\\n\");\n\tswitch_to_scheduler();\n\tprintf(\"B fn: 2\\n\");\n\tswitch_to_scheduler();\n\tprintf(\"B fn: 3\\n\");\n}\n\n\ncoroutine_t *create_coroutine(entrypoint_t fn, void *arg) {\n\tcoroutine_t *cor = (coroutine_t *)malloc(sizeof(coroutine_t));\n\n\tfor (int i=0; i<31; ++i)\n\t\tcor->ctx.regs[i] = 0;\n\n\tcor->ctx.regs[REG_SP] = (uint32_t)(&cor->stack[16384]);\n\tcor->ctx.regs[REG_S0] = (uint32_t)cor;\n\n\tcor->entry = fn;\n\tcor->arg = arg;\n\tcor->stat = START;\n\n\tcor->ctx.pc = (uint32_t)coroutine_entry;\n\n\treturn cor;\n}\n\nvoid free_coroutine(coroutine_t *cor) {\n\tfree(cor);\n}\n\nint main() {\n\tcoroutine_t *A_cor = create_coroutine(function_A, 0);\n\tcoroutine_t *B_cor = create_coroutine(function_B, 0);\n\n\t_Bool done = 0;\n\twhile (!done) {\n\t\tdone = 1;\n\n\t\tif (A_cor->stat != FINISHED) {\n\t\t\tswitch_to_coroutine(A_cor);\n\t\t\tdone = 0;\n\t\t}\n\n\t\tif (B_cor->stat != FINISHED) {\n\t\t\tswitch_to_coroutine(B_cor);\n\t\t\tdone = 0;\n\t\t}\n\t}\n\n\tfree_coroutine(A_cor);\n\tfree_coroutine(B_cor);\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/simple-scheduler/no-clib/Makefile",
    "content": "all : main.c\n\triscv32-unknown-elf-gcc main.c cor.S bootstrap.S -o main -march=rv32ima -mabi=ilp32 -nostartfiles\n\nsim: all\n\triscv-vp --intercept-syscalls main\n\ndump-elf: all\n\triscv32-unknown-elf-readelf -a main\n\ndump-code: all\n\triscv32-unknown-elf-objdump -D main\n\nclean:\n\trm -f main\n"
  },
  {
    "path": "sw/simple-scheduler/no-clib/bootstrap.S",
    "content": ".globl _start\n.globl main\n\n\n_start:\n\n# Initialize global pointer\n.option push\n.option norelax\n1:auipc gp, %pcrel_hi(__global_pointer$)\n  addi  gp, gp, %pcrel_lo(1b)\n.option pop\n\nli sp, 8000000\n\njal main\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\nli a7,93\nli a0,0\necall\n"
  },
  {
    "path": "sw/simple-scheduler/no-clib/cor.S",
    "content": ".globl contextswitch\n.globl coroutine_entry\n.globl launch_coroutine\n\n\ncoroutine_entry:\n\t// move the launch argument to the a0 register (i.e. first argument of the following function)\n\tmv    a0,s0\n\tcall  launch_coroutine\n\n\t// the above call should not return\t(i.e the scheduler should not call a finished coroutine)\n\tebreak\n\n\n/*\n * registers a0 and a1 point to the current and next context, respectively\n *\n * 1) store all current registers and pc in the current context\n * 2) load register values from next context\n * 3) jump to pc in the next context\n */\ncontextswitch:\n\t// store registers\n\tsw    x1,4(a0)\t    // ra\n\tsw    x2,8(a0)\t\t// sp\n\t//sw    x3,12(a0)\t// gp\n\t//sw    x4,16(a0)\t// tp\n\t//sw    x5,20(a0)\t// t0\n\t//sw    x6,24(a0)\t// t1\n\t//sw    x7,28(a0)\t// t2\n\tsw    x8,32(a0)\t\t// s0\n\tsw    x9,36(a0)\t\t// s1\n\t//sw    x10,40(a0)\t// a0\n\t//sw    x11,44(a0)\t// a1\n\t//sw    x12,48(a0)\t// a2\n\t//sw    x13,52(a0)\t// a3\n\t//sw    x14,56(a0)\t// a4\n\t//sw    x15,60(a0)\t// a5\n\t//sw    x16,64(a0)\t// a6\n\t//sw    x17,68(a0)\t// a7\n\tsw    x18,72(a0)\t// s2\n\tsw    x19,76(a0)\t// s3\n\tsw    x20,80(a0)\t// s4\n\tsw    x21,84(a0)\t// s5\n\tsw    x22,88(a0)\t// s6\n\tsw    x23,92(a0)\t// s7\n\tsw    x24,96(a0)\t// s8\n\tsw    x25,100(a0)\t// s9\n\tsw    x26,104(a0)\t// s10\n\tsw    x27,108(a0)\t// s11\n\t//sw    x28,112(a0)\t// t3\n\t//sw    x29,116(a0)\t// t4\n\t//sw    x30,120(a0)\t// t5\n\t//sw    x31,124(a0)\t// t6\n\n\t// store pc\n\tla    t0,_resume\n\tsw    t0,0(a0)\n\n\t// restore other registers (NOTE: callee saved only + ra)\n\tlw    x1,4(a1)\t\t// ra\n\tlw    x2,8(a1)\t\t// sp\n\tlw    x8,32(a1)\t\t// s0\n\tlw    x9,36(a1)\t\t// s1\n\tlw    x18,72(a1)\t// s2\n\tlw    x19,76(a1)\t// s3\n\tlw    x20,80(a1)\t// s4\n\tlw    x21,84(a1)\t// s5\n\tlw    x22,88(a1)\t// s6\n\tlw    x23,92(a1)\t// s7\n\tlw    x24,96(a1)\t// s8\n\tlw    x25,100(a1)\t// s9\n\tlw    x26,104(a1)\t// s10\n\tlw    x27,108(a1)\t// s11\n\n\t// load new program counter and perform context switch\n\tlw\t  t0,0(a1)\n\tjr    t0\n\n\t_resume:\n\n\tret\n\n"
  },
  {
    "path": "sw/simple-scheduler/no-clib/main.c",
    "content": "#include \"stdlib.h\"\n#include \"stdio.h\"\n#include \"assert.h\"\n\n\n#define REG_SP 1\n#define REG_S0 7\n\ntypedef void (*entrypoint_t)(void *);\n\nenum state_t {\n\tUNKNOWN,\n\tSTART,\n\tACTIVE,\n\tFINISHED\n};\n\ntypedef struct {\n\tuint32_t pc;\n\tuint32_t regs[31];\n} context_t;\n\ntypedef struct {\n\tuint8_t stack[16384];\n\tcontext_t ctx;\n\tentrypoint_t entry;\n\tvoid *arg;\n\tenum state_t stat;\n} coroutine_t;\n\n\ncontext_t main_context;\ncontext_t *active_context;\n\nextern void contextswitch(context_t *current, context_t *next);\n\nextern void coroutine_entry();\n\n\nvoid switch_to_scheduler() {\n\tcontextswitch(active_context, &main_context);\n}\n\nvoid switch_to_coroutine(coroutine_t *cor) {\n\tactive_context = &cor->ctx;\n\tcontextswitch(&main_context, &cor->ctx);\n}\n\n\nvoid launch_coroutine(coroutine_t *cor) {\n\tcor->stat = ACTIVE;\n\tcor->entry(cor->arg);\n\tcor->stat = FINISHED;\n\tassert (active_context == &cor->ctx);\n\tswitch_to_scheduler();\n}\n\n\nvoid function_A(void *arg) {\n\tprintf(\"A fn: 1\\n\");\n\tswitch_to_scheduler();\n\tprintf(\"A fn: 2\\n\");\n}\n\nvoid function_B(void *arg) {\n\tprintf(\"B fn: 1\\n\");\n\tswitch_to_scheduler();\n\tprintf(\"B fn: 2\\n\");\n\tswitch_to_scheduler();\n\tprintf(\"B fn: 3\\n\");\n}\n\n\ncoroutine_t *create_coroutine(entrypoint_t fn, void *arg) {\n\tcoroutine_t *cor = (coroutine_t *)malloc(sizeof(coroutine_t));\n\n\tfor (int i=0; i<31; ++i)\n\t\tcor->ctx.regs[i] = 0;\n\n\tcor->ctx.regs[REG_SP] = (uint32_t)(&cor->stack[16384]);\n\tcor->ctx.regs[REG_S0] = (uint32_t)cor;\n\n\tcor->entry = fn;\n\tcor->arg = arg;\n\tcor->stat = START;\n\n\tcor->ctx.pc = (uint32_t)coroutine_entry;\n\n\treturn cor;\n}\n\nvoid free_coroutine(coroutine_t *cor) {\n\tfree(cor);\n}\n\nint main() {\n\tcoroutine_t *A_cor = create_coroutine(function_A, 0);\n\tcoroutine_t *B_cor = create_coroutine(function_B, 0);\n\n\t_Bool done = 0;\n\twhile (!done) {\n\t\tdone = 1;\n\n\t\tif (A_cor->stat != FINISHED) {\n\t\t\tswitch_to_coroutine(A_cor);\n\t\t\tdone = 0;\n\t\t}\n\n\t\tif (B_cor->stat != FINISHED) {\n\t\t\tswitch_to_coroutine(B_cor);\n\t\t\tdone = 0;\n\t\t}\n\t}\n\n\tfree_coroutine(A_cor);\n\tfree_coroutine(B_cor);\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/simple-sensor/Makefile",
    "content": "OBJECTS  = main.o irq.o bootstrap.o\nCFLAGS   = -march=rv32i -mabi=ilp32\nLDFLAGS  = -nostartfiles -Wl,--no-relax\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/simple-sensor/bootstrap.S",
    "content": ".globl _start\n.globl main\n.globl level_1_interrupt_handler\n\n.equ SYSCALL_ADDR, 0x02010000\n.equ PLIC_ENABLED_IRQ_ADDR, 0x40002000\n\n.macro SYS_EXIT, exit_code\nli   a7, 93\nli   a0, \\exit_code\nli   t0, SYSCALL_ADDR\ncsrr a6, mhartid\nsw   a6, 0(t0)\n.endm\n\n\n_start:\nla t0, level_0_interrupt_handler\ncsrw mtvec, t0\nli t1, 0x888\ncsrw mie, t1\ncsrsi mstatus, 8\nli t0, PLIC_ENABLED_IRQ_ADDR\nli t1, -1\nsw t1, 0(t0)\nsw t1, 4(t0)\njal main\n\n# call exit (SYS_EXIT=93) with exit code 0 (argument in a0)\nSYS_EXIT 0\n\n\n/*\n * Interrupt handler for non-nested interrupts. Only selected registers are stored/re-stored, i.e. those not preserved on function calls.\n */\n#define STORE    sw\n#define LOAD     lw\n#define REGBYTES 4\n\nlevel_0_interrupt_handler:\n// store execution context on the stack (register content)\naddi    sp, sp, -REGBYTES * 32\nSTORE\tx1, 0x0(sp)\nSTORE\tx4, 3 * REGBYTES(sp)\nSTORE\tx5, 4 * REGBYTES(sp)\nSTORE\tx6, 5 * REGBYTES(sp)\nSTORE\tx7, 6 * REGBYTES(sp)\nSTORE\tx10, 9 * REGBYTES(sp)\nSTORE\tx11, 10 * REGBYTES(sp)\nSTORE\tx12, 11 * REGBYTES(sp)\nSTORE\tx13, 12 * REGBYTES(sp)\nSTORE\tx14, 13 * REGBYTES(sp)\nSTORE\tx15, 14 * REGBYTES(sp)\nSTORE\tx16, 15 * REGBYTES(sp)\nSTORE\tx17, 16 * REGBYTES(sp)\nSTORE\tx28, 27 * REGBYTES(sp)\nSTORE\tx29, 28 * REGBYTES(sp)\nSTORE\tx30, 29 * REGBYTES(sp)\nSTORE\tx31, 30 * REGBYTES(sp)\n\n// load interrupt/trap reason and call external C function to handle it\ncsrr    t2, mcause\nsrli    t3, t2, 31\nbnez    t3, handle_irq\n\nli      t0, SYSCALL_ADDR\ncsrr    t1, mhartid\ncsrr    a7, mcause\nsw      t1, 0(t0)\ncsrr    t0, mepc\naddi    t0, t0, 4\ncsrw    mepc, t0\nsw      a0, 9 * REGBYTES(sp)\n\nj       done_trap\nhandle_irq:\nmv      a0, t2\njal     level_1_interrupt_handler\ndone_trap:\n\n// re-store the saved context\nLOAD\tx1, 0x0(sp)\nLOAD\tx4, 3 * REGBYTES(sp)\nLOAD\tx5, 4 * REGBYTES(sp)\nLOAD\tx6, 5 * REGBYTES(sp)\nLOAD\tx7, 6 * REGBYTES(sp)\nLOAD\tx10, 9 * REGBYTES(sp)\nLOAD\tx11, 10 * REGBYTES(sp)\nLOAD\tx12, 11 * REGBYTES(sp)\nLOAD\tx13, 12 * REGBYTES(sp)\nLOAD\tx14, 13 * REGBYTES(sp)\nLOAD\tx15, 14 * REGBYTES(sp)\nLOAD\tx16, 15 * REGBYTES(sp)\nLOAD\tx17, 16 * REGBYTES(sp)\nLOAD\tx28, 27 * REGBYTES(sp)\nLOAD\tx29, 28 * REGBYTES(sp)\nLOAD\tx30, 29 * REGBYTES(sp)\nLOAD\tx31, 30 * REGBYTES(sp)\naddi\tsp, sp, REGBYTES * 32\nmret\n\n"
  },
  {
    "path": "sw/simple-sensor/irq.c",
    "content": "#include \"irq.h\"\n#include \"assert.h\"\n\n\n#define RISCV_MACHINE_SOFTWARE_INTERRUPT 3\n#define RISCV_MACHINE_TIMER_INTERRUPT 7\n#define RISCV_MACHINE_EXTERNAL_INTERRUPT 11\n\n\n#define PLIC_BASE 0x40000000\n#define IRQ_TABLE_NUM_ENTRIES 64\nstatic volatile uint32_t * const PLIC_INTERRUPT_ENABLE_START = (uint32_t * const)(PLIC_BASE + 0x2000);\nstatic volatile uint32_t * const PLIC_CLAIM_AND_RESPONSE_REGISTER = (uint32_t * const)(PLIC_BASE + 0x200004);\n\n\nstatic void irq_empty_handler() {}\nstatic irq_handler_t irq_handler_table[IRQ_TABLE_NUM_ENTRIES] = { [ 0 ... IRQ_TABLE_NUM_ENTRIES-1 ] = irq_empty_handler };\n\n\n#define CLINT_BASE 0x2000000\n\nvolatile uint64_t* mtime =   (uint64_t*)(CLINT_BASE + 0xbff8);\nvolatile uint64_t* mtimecmp = (uint64_t*)(CLINT_BASE + 0x4000);\n\nstatic irq_handler_t timer_irq_handler = 0;\n\n\nvoid level_1_interrupt_handler(uint32_t cause) {\n\n\tswitch (cause & 0xf) {\n\t\tcase RISCV_MACHINE_EXTERNAL_INTERRUPT: {\n\t\t\tasm volatile (\"csrc mip, %0\" : : \"r\" (0x800));\n\n\t\t\tuint32_t irq_id = *PLIC_CLAIM_AND_RESPONSE_REGISTER;\n\n\t\t\tirq_handler_table[irq_id]();\n\n\t\t\t*PLIC_CLAIM_AND_RESPONSE_REGISTER = 1;\n\n\t\t\treturn;\n\t\t}\n\n\t\tcase RISCV_MACHINE_TIMER_INTERRUPT: {\n\t\t\t// Note: the pending timer interrupt bit will be automatically cleared when writing to the *mtimecmp* register of this hart\n\t\t\tif (timer_irq_handler) {\n\t\t\t\t// let the user registered handler clear the timer interrupt bit\n\t\t\t\ttimer_irq_handler();\n\t\t\t} else {\n\t\t\t\t// reset the *mtimecmp* register to zero to clear the pending bit\n\t\t\t\t*mtimecmp = 0;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\t}\n\n\tassert (0 && \"unsupported cause\");\n}\n\nvoid register_interrupt_handler(uint32_t irq_id, irq_handler_t fn) {\n\tassert (irq_id < IRQ_TABLE_NUM_ENTRIES);\n\t// enable interrupt\n\tvolatile uint32_t* const reg = (PLIC_INTERRUPT_ENABLE_START + irq_id/32);\n\t*reg |= 1 << (irq_id%32);\n\t// set a prio different to zero (which means do-not-interrupt)\n\t*((uint32_t*) (PLIC_BASE + irq_id*sizeof(uint32_t))) = 1;\n\tirq_handler_table[irq_id] = fn;\n}\n\nvoid register_timer_interrupt_handler(irq_handler_t fn) {\n\ttimer_irq_handler = fn;\n}\n"
  },
  {
    "path": "sw/simple-sensor/irq.h",
    "content": "#ifndef __RISCV_IRQ_H__\n#define __RISCV_IRQ_H__\n\n#include \"stdint.h\"\n\ntypedef void (*irq_handler_t)(void);\n\nvoid register_interrupt_handler(uint32_t irq_id, irq_handler_t fn);\n\nvoid register_timer_interrupt_handler(irq_handler_t fn);\n\nextern volatile uint64_t* mtime;\nextern volatile uint64_t* mtimecmp;\n\n#endif\n"
  },
  {
    "path": "sw/simple-sensor/main.c",
    "content": "#include <stdint.h>\n#include \"irq.h\"\n\nstatic volatile char * const TERMINAL_ADDR = (char * const)0x20000000;\nstatic volatile char * const SENSOR_INPUT_ADDR = (char * const)0x50000000;\nstatic volatile uint32_t * const SENSOR_SCALER_REG_ADDR = (uint32_t * const)0x50000080;\nstatic volatile uint32_t * const SENSOR_FILTER_REG_ADDR = (uint32_t * const)0x50000084;\n\nvolatile _Bool has_sensor_data = 0;\n\nvoid sensor_irq_handler() {\n\thas_sensor_data = 1;\n}\n\nvoid dump_sensor_data() {\n\twhile (!has_sensor_data) {\n\t\tasm volatile (\"wfi\");\n\t}\n\thas_sensor_data = 0;\n\n\tfor (int i=0; i<64; ++i) {\n\t\t*TERMINAL_ADDR = *(SENSOR_INPUT_ADDR + i) % 92 + 32;\n\t}\n\t*TERMINAL_ADDR = '\\n';\n}\n\nint main() {\n\tregister_interrupt_handler(2, sensor_irq_handler);\n\n\t*SENSOR_SCALER_REG_ADDR = 5;\n\t*SENSOR_FILTER_REG_ADDR = 2;\n\n\tfor (int i=0; i<3; ++i)\n\t\tdump_sensor_data();\n\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/sys-read/Makefile",
    "content": "OBJECTS  = main.o\nCFLAGS   = -march=rv32ima -mabi=ilp32\n\ninclude ../Makefile.common\n"
  },
  {
    "path": "sw/sys-read/main.c",
    "content": "#include \"stdio.h\"\n\nint main(int argc, char **argv) {\n\tprintf(\"Enter a number: \");\n\n\tint c,n = 0;\n\twhile (!scanf(\"%d\", &n)) {\n\t\tprintf(\"Error: unable to parse number\\n\");\n\t\twhile((c = getchar()) != '\\n' && c != EOF);\n\t\tprintf(\"Enter a number: \");\n\t}\n\n\tprintf(\"Success, you entered %i\\n\", n);\n\treturn 0;\n}\n"
  },
  {
    "path": "sw/sys-read/test-ignore",
    "content": ""
  },
  {
    "path": "sw/test.sh",
    "content": "#!/bin/sh\n\nexport SYSTEMC_DISABLE_COPYRIGHT_MESSAGE=1\n\nhandle_exit() {\n\t[ $# -eq 1 ] || exit 1\n\n\tif [ \"${1}\" -eq 0 ]; then\n\t\tprintf \"OK.\\n\"\n\telse\n\t\tprintf \"FAIL.\\n\"\n\t\texit 1\n\tfi\n}\n\nfor test in *; do\n\t[ -e \"${test}/test-ignore\" -o -f \"${test}\" ] && continue\n\n\tname=${test##*/}\n\n\tprintf \"Building sw '%s': \" \"${name}\"\n\tmake -C \"${test}\" >/dev/null\n\thandle_exit $?\n\n\tprintf \"Running sw '%s': \" \"${name}\"\n\tmake -C \"${test}\" sim >/dev/null\n\thandle_exit $?\ndone\n"
  },
  {
    "path": "vp/.gitignore",
    "content": "build\n"
  },
  {
    "path": "vp/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.18)\nproject(riscv-vp\n\tVERSION 1.2.2\n)\n\noption(USE_SYSTEM_SYSTEMC \"use systemc version provided by the system\" OFF)\n\nif(NOT CMAKE_BUILD_TYPE)\n  set(CMAKE_BUILD_TYPE Debug)\nendif()\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_FLAGS \"-Wall -Wextra -Wno-unused-parameter -Wpedantic\")\nset(CMAKE_CXX_FLAGS_DEBUG \"-g3\")        #\"-fsanitize=address -fno-omit-frame-pointer\"\nset(CMAKE_CXX_FLAGS_RELEASE \"-O3\")\n\n# Allows running tests without invoking `make install` first.\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"${CMAKE_BINARY_DIR}/bin\")\n\nset(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR})\n\ninclude(cmake/AddGitSubmodule.cmake)\n\nfind_package( Boost REQUIRED COMPONENTS iostreams program_options log)\n\nif(USE_SYSTEM_SYSTEMC)\n\tfind_library(SystemC libsystemc.a)\nendif()\n\nsubdirs(src)\n\nenable_testing()\nlist(APPEND CMAKE_CTEST_ARGUMENTS \"--verbose\")\n\nadd_test(NAME libgdb\n\tCOMMAND ./test.sh\n\tWORKING_DIRECTORY \"${CMAKE_SOURCE_DIR}/tests/libgdb\")\nadd_test(NAME gdb\n\tCOMMAND ./test.sh\n\tWORKING_DIRECTORY \"${CMAKE_SOURCE_DIR}/tests/gdb\")\nadd_test(NAME integration\n\tCOMMAND ./test.sh\n\tWORKING_DIRECTORY \"${CMAKE_SOURCE_DIR}/tests/integration\")\nadd_test(NAME sw\n\tCOMMAND ./test.sh\n\tWORKING_DIRECTORY \"${CMAKE_SOURCE_DIR}/../sw\")\n\nset_tests_properties(gdb integration sw PROPERTIES ENVIRONMENT\n\tPATH=$ENV{PATH}:${CMAKE_RUNTIME_OUTPUT_DIRECTORY})\nset_tests_properties(libgdb PROPERTIES ENVIRONMENT\n\tRISCV_VP_BASE=${CMAKE_CURRENT_SOURCE_DIR}/..)\n"
  },
  {
    "path": "vp/cmake/AddGitSubmodule.cmake",
    "content": "#thanks @ https://gist.github.com/scivision/bb1d47a9529e153617414e91ff5390af\n\ncmake_minimum_required(VERSION 3.16)\n\nfunction(add_git_submodule dir)\n# add a Git submodule directory to CMake, assuming the\n# Git submodule directory is a CMake project.\n#\n# Usage: in CMakeLists.txt\n# \n# include(AddGitSubmodule.cmake)\n# add_git_submodule(mysubmod_dir)\n\nfind_package(Git REQUIRED)\nif(NOT EXISTS ${dir})\n    set(dir ${CMAKE_CURRENT_SOURCE_DIR}/${dir})\nendif()\n\nif(NOT EXISTS \"${dir}/CMakeLists.txt\")\n  message(\"checking out submodule ${dir}\")\n  execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive -- ${abs_dir}\n    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}\n    #COMMAND_ERROR_IS_FATAL\t\t# cmake 3.19+\n    #ANY\t\t\t\t\t\t# cmake 3.19+\n   )\nendif()\n\nadd_subdirectory(${dir})\n\nendfunction(add_git_submodule)"
  },
  {
    "path": "vp/src/CMakeLists.txt",
    "content": "include_directories(.)\n\nsubdirs(vendor)\nsubdirs(core)\nsubdirs(platform)\n"
  },
  {
    "path": "vp/src/core/CMakeLists.txt",
    "content": "subdirs(common)\nsubdirs(rv32)\nsubdirs(rv64)\n"
  },
  {
    "path": "vp/src/core/common/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_library(core-common\n\t\ttimer.cpp\n\t\treal_clint.cpp\n\t\tinstr.cpp\n\t\tdebug_memory.cpp\n\t\trawmode.cpp\n\t\t${HEADERS})\n\ntarget_include_directories(core-common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\ntarget_link_libraries(core-common PRIVATE pthread systemc)\n\nadd_subdirectory(gdb-mc)\n"
  },
  {
    "path": "vp/src/core/common/bus_lock_if.h",
    "content": "#pragma once\n\nstruct bus_lock_if {\n    virtual ~bus_lock_if() {}\n\n\tvirtual void lock(unsigned hart_id) = 0;\n\n\tvirtual void unlock(unsigned hart_id) = 0;\n\n\tvirtual bool is_locked() = 0;  // by any hart\n\n\tvirtual bool is_locked(unsigned hart_id) = 0;\n\n\tvirtual void wait_until_unlocked() = 0;\n\n\tinline void wait_for_access_rights(unsigned hart_id) {\n\t\tif (is_locked() && !is_locked(hart_id))\n\t\t\twait_until_unlocked();\n\t}\n};"
  },
  {
    "path": "vp/src/core/common/clint.h",
    "content": "#ifndef RISCV_ISA_CLINT_H\n#define RISCV_ISA_CLINT_H\n\n#include \"clint_if.h\"\n#include \"irq_if.h\"\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n\n#include \"util/memory_map.h\"\n\ntemplate <unsigned NumberOfCores>\nstruct CLINT : public clint_if, public sc_core::sc_module {\n\t//\n\t// core local interrupt controller (provides local timer interrupts with\n\t// memory mapped configuration)\n\t//\n\t// send out interrupt if: *mtime >= mtimecmp* and *mtimecmp != 0*\n\t//\n\t// *mtime* is a read-only 64 bit timer register shared by all CPUs (accessed\n\t// by MMIO and also mapped into the CSR address space of each CPU)\n\t//\n\t// for every CPU a *mtimecmp* register (read/write 64 bit) is available\n\t//\n\t//\n\t// Note: the software is responsible to ensure that no overflow occurs when\n\t// writing *mtimecmp* (see RISC-V privileged ISA spec.):\n\t//\n\t// # New comparand is in a1:a0.\n\t// li t0, -1\n\t// sw t0, mtimecmp    # No smaller than old value.\n\t// sw a1, mtimecmp+4  # No smaller than new value.\n\t// sw a0, mtimecmp    # New value.\n\t//\n\n\tstatic_assert(NumberOfCores < 4096, \"out of bound\");  // stay within the allocated address range\n\n\tstatic constexpr uint64_t scaler = 1000000;  // scale from PS resolution (default in SystemC) to US\n\t                                             // resolution (apparently required by FreeRTOS)\n\n\ttlm_utils::simple_target_socket<CLINT> tsock;\n\n\tsc_core::sc_time clock_cycle = sc_core::sc_time(10, sc_core::SC_NS);\n\tsc_core::sc_event irq_event;\n\n\tRegisterRange regs_mtime{0xBFF8, 8};\n\tIntegerView<uint64_t> mtime{regs_mtime};\n\n\tRegisterRange regs_mtimecmp{0x4000, 8 * NumberOfCores};\n\tArrayView<uint64_t> mtimecmp{regs_mtimecmp};\n\n\tRegisterRange regs_msip{0x0, 4 * NumberOfCores};\n\tArrayView<uint32_t> msip{regs_msip};\n\n\tstd::vector<RegisterRange *> register_ranges{&regs_mtime, &regs_mtimecmp, &regs_msip};\n\n\tstd::array<clint_interrupt_target *, NumberOfCores> target_harts{};\n\n\tSC_HAS_PROCESS(CLINT);\n\n\tCLINT(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &CLINT::transport);\n\n\t\tregs_mtimecmp.alignment = 4;\n\t\tregs_msip.alignment = 4;\n\t\tregs_mtime.alignment = 4;\n\n\t\tregs_mtime.pre_read_callback = std::bind(&CLINT::pre_read_mtime, this, std::placeholders::_1);\n\t\tregs_mtimecmp.post_write_callback = std::bind(&CLINT::post_write_mtimecmp, this, std::placeholders::_1);\n\t\tregs_msip.post_write_callback = std::bind(&CLINT::post_write_msip, this, std::placeholders::_1);\n\n\t\tSC_THREAD(run);\n\t}\n\n\tuint64_t update_and_get_mtime() override {\n\t\tauto now = sc_core::sc_time_stamp().value() / scaler;\n\t\tif (now > mtime)\n\t\t\tmtime = now;  // do not update backward in time (e.g. due to local quantums in tlm transaction processing)\n\t\treturn mtime;\n\t}\n\n\tvoid run() {\n\t\twhile (true) {\n\t\t\tsc_core::wait(irq_event);\n\n\t\t\tupdate_and_get_mtime();\n\n\t\t\tfor (unsigned i = 0; i < NumberOfCores; ++i) {\n\t\t\t\tauto cmp = mtimecmp[i];\n\t\t\t\t// std::cout << \"[vp::clint] process mtimecmp[\" << i << \"]=\" << cmp << \", mtime=\" << mtime << std::endl;\n\t\t\t\tif (cmp > 0 && mtime >= cmp) {\n\t\t\t\t\t// std::cout << \"[vp::clint] set timer interrupt for core \" << i << std::endl;\n\t\t\t\t\ttarget_harts[i]->trigger_timer_interrupt(true);\n\t\t\t\t} else {\n\t\t\t\t\t// std::cout << \"[vp::clint] unset timer interrupt for core \" << i << std::endl;\n\t\t\t\t\ttarget_harts[i]->trigger_timer_interrupt(false);\n\t\t\t\t\tif (cmp > 0 && cmp < UINT64_MAX) {\n\t\t\t\t\t\tauto time = sc_core::sc_time::from_value(mtime * scaler);\n\t\t\t\t\t\tauto goal = sc_core::sc_time::from_value(cmp * scaler);\n\t\t\t\t\t\t// std::cout << \"[vp::clint] time=\" << time << std::endl;\n\t\t\t\t\t\t// std::cout << \"[vp::clint] goal=\" << goal << std::endl;\n\t\t\t\t\t\t// std::cout << \"[vp::clint] goal-time=delay=\" << goal-time << std::endl;\n\t\t\t\t\t\tirq_event.notify(goal - time);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tbool pre_read_mtime(RegisterRange::ReadInfo t) {\n\t\tsc_core::sc_time now = sc_core::sc_time_stamp() + t.delay;\n\n\t\tmtime.write(now.value() / scaler);\n\n\t\treturn true;\n\t}\n\n\tvoid post_write_mtimecmp(RegisterRange::WriteInfo t) {\n\t\t// std::cout << \"[vp::clint] write mtimecmp[addr=\" << t.addr << \"]=\" << mtimecmp[t.addr / 8] << \", mtime=\" <<\n\t\t// mtime << std::endl;\n\t\tirq_event.notify(t.delay);\n\t}\n\n\tvoid post_write_msip(RegisterRange::WriteInfo t) {\n\t\tassert(t.addr % 4 == 0);\n\t\tunsigned idx = t.addr / 4;\n\t\tmsip[idx] &= 0x1;\n\t\ttarget_harts[idx]->trigger_software_interrupt(msip[idx] != 0);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tdelay += 2 * clock_cycle;\n\n\t\tvp::mm::route(\"CLINT\", register_ranges, trans, delay);\n\t}\n};\n\n#endif  // RISCV_ISA_CLINT_H\n"
  },
  {
    "path": "vp/src/core/common/clint_if.h",
    "content": "#pragma once\n\n#include <stdint.h>\n\nstruct clint_if {\n\tvirtual ~clint_if() {}\n\n\tvirtual uint64_t update_and_get_mtime() = 0;\n};"
  },
  {
    "path": "vp/src/core/common/core_defs.h",
    "content": "#pragma once\n\nenum Architecture {\n\tRV32 = 1,\n\tRV64 = 2,\n\tRV128 = 3,\n};\n\nenum class CoreExecStatus {\n\tRunnable,\n\tHitBreakpoint,\n\tTerminated,\n};\n\nconstexpr unsigned SATP_MODE_BARE = 0;\nconstexpr unsigned SATP_MODE_SV32 = 1;\nconstexpr unsigned SATP_MODE_SV39 = 8;\nconstexpr unsigned SATP_MODE_SV48 = 9;\nconstexpr unsigned SATP_MODE_SV57 = 10;\nconstexpr unsigned SATP_MODE_SV64 = 11;"
  },
  {
    "path": "vp/src/core/common/debug.h",
    "content": "#ifndef RISCV_DEBUG\n#define RISCV_DEBUG\n\n#include <stdint.h>\n\n#include <unordered_set>\n#include <vector>\n\n#include \"core_defs.h\"\n\n\nstruct debug_target_if {\n\tvirtual ~debug_target_if() {}\n\n\tvirtual void enable_debug(void) = 0;\n\tvirtual CoreExecStatus get_status(void) = 0;\n\tvirtual void set_status(CoreExecStatus) = 0;\n\tvirtual void block_on_wfi(bool) = 0;\n\n\tvirtual void insert_breakpoint(uint64_t) = 0;\n\tvirtual void remove_breakpoint(uint64_t) = 0;\n\n\tvirtual Architecture get_architecture(void) = 0;\n\tvirtual uint64_t get_hart_id(void) = 0;\n\n\tvirtual uint64_t get_progam_counter(void) = 0;\n\tvirtual std::vector<uint64_t> get_registers(void) = 0;\n\tvirtual uint64_t read_register(unsigned) = 0;\n\n\tvirtual void run(void) = 0;\n\tvirtual void run_step(void) = 0;\n};\n\n#endif\n"
  },
  {
    "path": "vp/src/core/common/debug_memory.cpp",
    "content": "#include \"debug_memory.h\"\n\n#include <assert.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <errno.h>\n\n#include <arpa/inet.h>\n#include <byteswap.h>\n#include <netinet/in.h>\n#include <netinet/ip.h>\n#include <sys/socket.h>\n#include <sys/types.h>\n\n#include <cassert>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n#include <iomanip>\n#include <iostream>\n#include <sstream>\n#include <string>\n\n#include <boost/algorithm/string.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n#include <boost/lexical_cast.hpp>\n\nunsigned DebugMemoryInterface::_do_dbg_transaction(tlm::tlm_command cmd, uint64_t addr, uint8_t *data,\n                                                   unsigned num_bytes) {\n\ttlm::tlm_generic_payload trans;\n\ttrans.set_command(cmd);\n\ttrans.set_address(addr);\n\ttrans.set_data_ptr(data);\n\ttrans.set_data_length(num_bytes);\n\ttrans.set_response_status(tlm::TLM_OK_RESPONSE);\n\n\tunsigned nbytes = isock->transport_dbg(trans);\n\tif (trans.is_response_error())\n\t\tthrow std::runtime_error(\"debug transaction failed\");\n\n\treturn nbytes;\n}\n\nstd::string DebugMemoryInterface::read_memory(uint64_t start, unsigned nbytes) {\n\tstd::vector<uint8_t> buf(nbytes);  // NOTE: every element is zero-initialized by default\n\n\tunsigned nbytes_read = _do_dbg_transaction(tlm::TLM_READ_COMMAND, start, buf.data(), buf.size());\n\tassert(nbytes_read == nbytes && \"not all bytes read\");\n\n\tstd::stringstream stream;\n\tstream << std::setfill('0') << std::hex;\n\tfor (uint8_t byte : buf) {\n\t\tstream << std::setw(2) << (unsigned)byte;\n\t}\n\n\treturn stream.str();\n}\n\nvoid DebugMemoryInterface::write_memory(uint64_t start, unsigned nbytes, const std::string &data) {\n\tunsigned i, j;\n\tstd::vector<uint8_t> buf(data.length() / 2);\n\n\tassert(data.length() % 2 == 0);\n\tassert(buf.size() == nbytes);\n\n\tfor (j = 0, i = 0; i + 1 < nbytes; j++, i += 2) {\n\t\tlong num;\n\t\tchar hex[3];\n\n\t\thex[0] = data.at(i);\n\t\thex[1] = data.at(i+1);\n\t\thex[2] = '\\0';\n\n\t\terrno = 0;\n\t\tnum = strtol(hex, NULL, 16);\n\t\tif (num == 0 && errno != 0)\n\t\t\tthrow std::system_error(errno, std::generic_category());\n\n\t\tassert(num >= 0 && num <= UINT8_MAX);\n\t\tbuf.at(j) = (uint8_t)num;\n\t}\n\n\tunsigned nbytes_write = _do_dbg_transaction(tlm::TLM_WRITE_COMMAND, start, buf.data(), buf.size());\n\tassert(nbytes_write == nbytes && \"not all data written\");\n}\n"
  },
  {
    "path": "vp/src/core/common/debug_memory.h",
    "content": "#ifndef RISCV_ISA_DEBUG_MEMORY_H\n#define RISCV_ISA_DEBUG_MEMORY_H\n\n#include <string>\n#include <type_traits>\n\n#include <tlm_utils/simple_initiator_socket.h>\n#include <systemc>\n\n#include \"core_defs.h\"\n#include \"trap.h\"\n\nstruct DebugMemoryInterface : public sc_core::sc_module {\n\ttlm_utils::simple_initiator_socket<DebugMemoryInterface> isock;\n\n\tDebugMemoryInterface(sc_core::sc_module_name) {}\n\n\tunsigned _do_dbg_transaction(tlm::tlm_command cmd, uint64_t addr, uint8_t *data, unsigned num_bytes);\n\n\tstd::string read_memory(uint64_t start, unsigned nbytes);\n\n\tvoid write_memory(uint64_t start, unsigned nbytes, const std::string &data);\n};\n\n#endif  // RISCV_ISA_GDB_STUB_H\n"
  },
  {
    "path": "vp/src/core/common/dmi.h",
    "content": "#pragma once\n\n#include <stdint.h>\n\nclass MemoryDMI {\n\tuint8_t *mem;\n\tuint64_t start;\n\tuint64_t size;\n\tuint64_t end;\n\n\tMemoryDMI(uint8_t *mem, uint64_t start, uint64_t size) : mem(mem), start(start), size(size), end(start + size) {}\n\n   public:\n\tstatic MemoryDMI create_start_end_mapping(uint8_t *mem, uint64_t start, uint64_t end) {\n\t\tassert(end > start);\n\t\treturn create_start_size_mapping(mem, start, end - start);\n\t}\n\n\tstatic MemoryDMI create_start_size_mapping(uint8_t *mem, uint64_t start, uint64_t size) {\n\t\tassert(start + size > start);\n\t\treturn MemoryDMI(mem, start, size);\n\t}\n\n\tuint8_t *get_raw_mem_ptr() {\n\t\treturn mem;\n\t}\n\n\ttemplate <typename T>\n\tT *get_mem_ptr_to_global_addr(uint64_t addr) {\n\t\tassert(contains(addr));\n\t\tassert((addr + sizeof(T)) <= end);\n\t\t// assert ((addr % sizeof(T)) == 0 && \"unaligned access\");   //NOTE: due to compressed instructions, fetching\n\t\t// can be unaligned\n\t\treturn reinterpret_cast<T *>(mem + (addr - start));\n\t}\n\n\ttemplate <typename T>\n\tT load(uint64_t addr) {\n\t\tstatic_assert(std::is_integral<T>::value, \"integer type required\");\n\t\tT ans;\n\t\tT *src = get_mem_ptr_to_global_addr<T>(addr);\n\t\t// use memcpy to avoid problems with unaligned loads into standard C++ data types\n\t\t// see: https://blog.quarkslab.com/unaligned-accesses-in-cc-what-why-and-solutions-to-do-it-properly.html\n\t\tmemcpy(&ans, src, sizeof(T));\n\t\treturn ans;\n\t}\n\n\ttemplate <typename T>\n\tvoid store(uint64_t addr, T value) {\n\t\tstatic_assert(std::is_integral<T>::value, \"integer type required\");\n\t\tT *dst = get_mem_ptr_to_global_addr<T>(addr);\n\t\tmemcpy(dst, &value, sizeof(value));\n\t}\n\n\tuint64_t get_start() {\n\t\treturn start;\n\t}\n\n\tuint64_t get_end() {\n\t\treturn start + size;\n\t}\n\n\tuint64_t get_size() {\n\t\treturn size;\n\t}\n\n\tbool contains(uint64_t addr) {\n\t\treturn addr >= start && addr < end;\n\t}\n};"
  },
  {
    "path": "vp/src/core/common/elf_loader.h",
    "content": "#pragma once\n\n#include <boost/iostreams/device/mapped_file.hpp>\n#include <exception>\n#include <cstdint>\n#include <vector>\n\n#include \"load_if.h\"\n\ntemplate <typename T>\nstruct GenericElfLoader {\n\ttypedef typename T::addr_t addr_t;\n\ttypedef typename T::Elf_Ehdr Elf_Ehdr;\n\ttypedef typename T::Elf_Phdr Elf_Phdr;\n\ttypedef typename T::Elf_Shdr Elf_Shdr;\n\ttypedef typename T::Elf_Sym Elf_Sym;\n\tstatic_assert(sizeof(addr_t) == sizeof(Elf_Ehdr::e_entry), \"architecture mismatch\");\n\n\tconst char *filename;\n\tboost::iostreams::mapped_file_source elf;\n\tconst Elf_Ehdr *hdr;\n\n\tstruct load_executable_exception : public std::exception {\n\t\tconst char * what () const throw () {\n\t\t\treturn \"Tried loading invalid elf layout\";\n\t\t}\n\t};\n\n\tGenericElfLoader(const char *filename) : filename(filename), elf(filename) {\n\t\tassert(elf.is_open() && \"file not open\");\n\n\t\thdr = reinterpret_cast<const Elf_Ehdr *>(elf.data());\n\t}\n\n\tstd::vector<const Elf_Phdr *> get_load_sections() {\n\t\tstd::vector<const Elf_Phdr *> sections;\n\n\t\tfor (int i = 0; i < hdr->e_phnum; ++i) {\n\t\t\tconst Elf_Phdr *p =\n\t\t\t    reinterpret_cast<const typename T::Elf_Phdr *>(elf.data() + hdr->e_phoff + hdr->e_phentsize * i);\n\n\t\t\tif (p->p_type != T::PT_LOAD)\n\t\t\t\tcontinue;\n\n\t\t\tif ((p->p_filesz == 0) && (p->p_memsz == 0))\n\t\t\t\tcontinue;\n\n\t\t\t//If p_memsz is greater than p_filesz, the extra bytes are NOBITS.\n\t\t\t// -> still, the memory needs to be zero initialized in this case!\n//\t\t\tif (p->p_memsz > p->p_filesz)\n//\t\t\t\tcontinue;\n\n\t\t\tsections.push_back(p);\n\t\t}\n\n\t\treturn sections;\n\t}\n\n\tstd::ostream& print_phdr(std::ostream& os, const Elf_Phdr& h, unsigned tabs = 0)\n\t{\n\t\tstd::string tab(tabs, '\\t');\n\t\tos << tab << \"p_type \"  << h.p_type   << std::endl;\n\t\tos << tab << \"p_offset \"<< h.p_offset << std::endl;\n\t\tos << tab << \"p_vaddr \" << h.p_vaddr  << std::endl;\n\t\tos << tab << \"p_paddr \" << h.p_paddr  << std::endl;\n\t\tos << tab << \"p_filesz \"<< h.p_filesz << std::endl;\n\t\tos << tab << \"p_memsz \" << h.p_memsz  << std::endl;\n\t\tos << tab << \"p_flags \" << h.p_flags  << std::endl;\n\t\tos << tab << \"p_align \" << h.p_align  << std::endl;\n\t    return os;\n\t}\n\n\tvoid load_executable_image(load_if &load_if, addr_t size, addr_t offset, bool use_vaddr = true) {\n\t\tfor (auto p : get_load_sections()) {\n\t\t\tauto addr = p->p_paddr;\n\t\t\tif (use_vaddr)\n\t\t\t\taddr = p->p_vaddr;\n\n\t\t\t// If the modeled virtual platform separates Flash and DRAM\n\t\t\t// (like the hifive-vp does) we call load_executable_image\n\t\t\t// once for each memory segment (i.e. once for the Flash and\n\t\t\t// once for the DRAM). As such, we must skip all ELF regions\n\t\t\t// which are not covered by the passed memory segment.\n\t\t\tif (!(addr >= offset && addr < (offset + size)))\n\t\t\t\tcontinue;\n\n\t\t\tif (addr < offset) {\n\t\t\t\tstd::cerr << \"[elf_loader] \";\n\t\t\t\tstd::cerr << \"Offset overlaps into section:\" << std::endl;\n\t\t\t\tstd::cerr << \"\\t0x\" << std::hex << +addr << \" < \" << +offset << std::endl;\n\t\t\t\tprint_phdr(std::cerr, *p, 2);\n\t\t\t\tthrow load_executable_exception();\n\t\t\t}\n\n\t\t\tif (addr + p->p_memsz >= offset + size) {\n\t\t\t\tstd::cerr << \"[elf_loader] \";\n\t\t\t\tstd::cerr << \"Section does not fit in target memory\" << std::endl;\n\t\t\t\tstd::cerr << \"\\t0x\" << std::hex << +addr << \" + size 0x\" << +p->p_memsz;\n\t\t\t\tstd::cerr << \" would overflow offset 0x\" << +offset << \" + size 0x\" << +size << std::endl;\n\t\t\t\tprint_phdr(std::cerr, *p, 2);\n\t\t\t\tthrow load_executable_exception();\n\t\t\t}\n\n\t\t\tauto idx = addr - offset;\n\t\t\tconst char *src = elf.data() + p->p_offset;\n\t\t\tauto to_copy = p->p_filesz;\n\n\t\t\tload_if.load_data(src, idx, to_copy);\n\n\t\t\tassert (p->p_memsz >= p->p_filesz);\n\t\t\tidx = idx + p->p_filesz;\n\t\t\tto_copy = p->p_memsz - p->p_filesz;\n\n\t\t\tload_if.load_zero(idx, to_copy);\n\t\t}\n\t}\n\n\taddr_t get_memory_end() {\n\t\tconst Elf_Phdr *last =\n\t\t    reinterpret_cast<const Elf_Phdr *>(elf.data() + hdr->e_phoff + hdr->e_phentsize * (hdr->e_phnum - 1));\n\n\t\treturn last->p_vaddr + last->p_memsz;\n\t}\n\n\taddr_t get_heap_addr() {\n\t\t// return first 8 byte aligned address after the memory image\n\t\tauto s = get_memory_end();\n\t\treturn s + s % 8;\n\t}\n\n\taddr_t get_entrypoint() {\n\t\treturn hdr->e_entry;\n\t}\n\n\tconst char *get_section_string_table() {\n\t\tassert(hdr->e_shoff != 0 && \"string table section not available\");\n\n\t\tconst Elf_Shdr *s =\n\t\t    reinterpret_cast<const Elf_Shdr *>(elf.data() + hdr->e_shoff + hdr->e_shentsize * hdr->e_shstrndx);\n\t\tconst char *start = elf.data() + s->sh_offset;\n\t\treturn start;\n\t}\n\n\tconst char *get_symbol_string_table() {\n\t\tauto s = get_section(\".strtab\");\n\t\treturn elf.data() + s->sh_offset;\n\t}\n\n\tconst Elf_Sym *get_symbol(const char *symbol_name) {\n\t\tconst Elf_Shdr *s = get_section(\".symtab\");\n\t\tconst char *strings = get_symbol_string_table();\n\n\t\tassert(s->sh_size % sizeof(Elf_Sym) == 0);\n\n\t\tauto num_entries = s->sh_size / sizeof(typename T::Elf_Sym);\n\t\tfor (unsigned i = 0; i < num_entries; ++i) {\n\t\t\tconst Elf_Sym *p = reinterpret_cast<const Elf_Sym *>(elf.data() + s->sh_offset + i * sizeof(Elf_Sym));\n\n\t\t\t// std::cout << \"check symbol: \" << strings + p->st_name << std::endl;\n\n\t\t\tif (!strcmp(strings + p->st_name, symbol_name)) {\n\t\t\t\treturn p;\n\t\t\t}\n\t\t}\n\n\t\tthrow std::runtime_error(\"unable to find symbol in the symbol table \" + std::string(symbol_name));\n\t}\n\n\taddr_t get_begin_signature_address() {\n\t\tauto p = get_symbol(\"begin_signature\");\n\t\treturn p->st_value;\n\t}\n\n\taddr_t get_end_signature_address() {\n\t\tauto p = get_symbol(\"end_signature\");\n\t\treturn p->st_value;\n\t}\n\n    addr_t get_to_host_address() {\n        auto p = get_symbol(\"tohost\");\n        return p->st_value;\n    }\n\n\tstd::vector<const Elf_Shdr *> get_sections(void) {\n\t\tif (hdr->e_shoff == 0) {\n\t\t\tthrow std::runtime_error(\"unable to find section address, section table not available\");\n\t\t}\n\n\t\tstd::vector<const Elf_Shdr *> sections;\n\t\tfor (unsigned i = 0; i < hdr->e_shnum; ++i) {\n\t\t\tconst Elf_Shdr *s = reinterpret_cast<const Elf_Shdr *>(elf.data() + hdr->e_shoff + hdr->e_shentsize * i);\n\t\t\tsections.push_back(s);\n\t\t}\n\n\t\treturn sections;\n\t}\n\n\tconst Elf_Shdr *get_section(const char *section_name) {\n\t\tconst char *strings = get_section_string_table();\n\n\t\tfor (auto s : get_sections()) {\n\t\t\tif (!strcmp(strings + s->sh_name, section_name)) {\n\t\t\t\treturn s;\n\t\t\t}\n\t\t}\n\n\t\tthrow std::runtime_error(\"unable to find section address, section seems not available: \" +\n\t\t                         std::string(section_name));\n\t}\n};\n"
  },
  {
    "path": "vp/src/core/common/fp.h",
    "content": "#pragma once\n\n#include <softfloat/softfloat.hpp>\n\n// floating-point rounding modes\nconstexpr unsigned FRM_RNE = 0b000;  // Round to Nearest, ties to Even\nconstexpr unsigned FRM_RTZ = 0b001;  // Round towards Zero\nconstexpr unsigned FRM_RDN = 0b010;  // Round Down (towards -inf)\nconstexpr unsigned FRM_RUP = 0b011;  // Round Down (towards +inf)\nconstexpr unsigned FRM_RMM = 0b100;  // Round to Nearest, ties to Max Magnitude\nconstexpr unsigned FRM_DYN =\n    0b111;  // In instruction’s rm field, selects dynamic rounding mode; In Rounding Mode register, Invalid\n\n// NaN values\nconstexpr uint32_t defaultNaNF32UI = 0x7fc00000;\nconstexpr uint64_t defaultNaNF64UI = 0x7FF8000000000000;\n\nconstexpr float32_t f32_defaultNaN = {defaultNaNF32UI};\nconstexpr float64_t f64_defaultNaN = {defaultNaNF64UI};\n\nconstexpr uint32_t F32_SIGN_BIT = 1 << 31;\nconstexpr uint64_t F64_SIGN_BIT = 1ul << 63;\n\ninline bool f32_isNegative(float32_t x) {\n\treturn x.v & F32_SIGN_BIT;\n}\n\ninline bool f64_isNegative(float64_t x) {\n\treturn x.v & F64_SIGN_BIT;\n}\n\ninline float32_t f32_neg(float32_t x) {\n\treturn float32_t{x.v ^ F32_SIGN_BIT};\n}\n\ninline float64_t f64_neg(float64_t x) {\n\treturn float64_t{x.v ^ F64_SIGN_BIT};\n}\n\ninline bool f32_isNaN(float32_t x) {\n\t// f32 NaN:\n\t// - sign bit can be 0 or 1\n\t// - all exponent bits set\n\t// - at least one fraction bit set\n\treturn ((~x.v & 0x7F800000) == 0) && (x.v & 0x007FFFFF);\n}\n\ninline bool f64_isNaN(float64_t x) {\n\t// similar to f32 NaN\n\treturn ((~x.v & 0x7FF0000000000000) == 0) && (x.v & 0x000FFFFFFFFFFFFF);\n}\n\nstruct FpRegs {\n   private:\n\tstd::array<float64_t, 32> regs;\n\n\tbool is_boxed_f32(float64_t x) {\n\t\treturn (x.v >> 32) == (uint32_t)-1;\n\t}\n\n\tfloat32_t unbox_f32(float64_t x) {\n\t\treturn float32_t{(uint32_t)x.v};\n\t}\n\n\tfloat64_t box_f32(float32_t x) {\n\t\treturn float64_t{(uint64_t)x.v | 0xFFFFFFFF00000000};\n\t}\n\n   public:\n\tvoid write(unsigned idx, float32_t x) {\n\t\twrite(idx, box_f32(x));\n\t}\n\n\tvoid write(unsigned idx, float64_t x) {\n\t\tregs[idx] = x;\n\t}\n\n\tuint32_t u32(unsigned idx) {\n\t\t// access raw data, e.g. to store to memory\n\t\treturn regs[idx].v;\n\t}\n\n\tfloat32_t f32(unsigned idx) {\n\t\tif (is_boxed_f32(regs[idx]))\n\t\t\treturn unbox_f32(regs[idx]);\n\t\telse\n\t\t\treturn f32_defaultNaN;\n\t}\n\n\tfloat64_t f64(unsigned idx) {\n\t\treturn regs[idx];\n\t}\n};"
  },
  {
    "path": "vp/src/core/common/gdb-mc/CMakeLists.txt",
    "content": "add_subdirectory(libgdb)\n\nadd_library(gdb-mc\n\tgdb_server.cpp\n\tgdb_runner.cpp\n\tregister_format.cpp\n\thandler.cpp)\n\ntarget_link_libraries(gdb-mc gdb core-common systemc)\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/gdb_runner.cpp",
    "content": "#include \"gdb_runner.h\"\n\nGDBServerRunner::GDBServerRunner(sc_core::sc_module_name name, GDBServer *server, debug_target_if *hart) {\n\t(void)name;\n\n\tthis->hart = hart;\n\tthis->server = server;\n\n\tthis->stop_event = server->get_stop_event(hart);\n\tserver->set_run_event(hart, &this->run_event);\n\n\thart->enable_debug();\n\tSC_THREAD(run);\n}\n\nvoid GDBServerRunner::run(void) {\n\tfor (;;) {\n\t\tsc_core::wait(run_event);\n\t\tif (server->single_run) {\n\t\t\thart->run_step();\n\t\t\tif (hart->get_status() == CoreExecStatus::Runnable)\n\t\t\t\thart->set_status(CoreExecStatus::HitBreakpoint);\n\t\t} else {\n\t\t\thart->run();\n\t\t}\n\t\tstop_event->notify();\n\n\t\tif (hart->get_status() == CoreExecStatus::Terminated)\n\t\t\tbreak;\n\t}\n}\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/gdb_runner.h",
    "content": "#ifndef RISCV_GDB_RUNNER\n#define RISCV_GDB_RUNNER\n\n#include <systemc>\n\n#include \"debug.h\"\n#include \"gdb_server.h\"\n\nSC_MODULE(GDBServerRunner) {\npublic:\n\tSC_HAS_PROCESS(GDBServerRunner);\n\n\tGDBServerRunner(sc_core::sc_module_name, GDBServer *, debug_target_if *);\nprivate:\n\tGDBServer *server;\n\tdebug_target_if *hart;\n\tsc_core::sc_event run_event;\n\tsc_core::sc_event *stop_event;\n\n\tvoid run(void);\n};\n\n#endif\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/gdb_server.cpp",
    "content": "#include <err.h>\n#include <assert.h>\n#include <stdio.h>\n#include <string.h>\n#include <unistd.h>\n#include <stdint.h>\n#include <stdlib.h>\n\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <netinet/tcp.h>\n#include <libgdb/parser2.h>\n#include <libgdb/response.h>\n\n#include <systemc>\n\n#include \"gdb_server.h\"\n#include \"platform/common/async_event.h\"\n\nextern std::map<std::string, GDBServer::packet_handler> handlers;\n\nGDBServer::GDBServer(sc_core::sc_module_name name,\n                     std::vector<debug_target_if*> targets,\n                     DebugMemoryInterface *mm,\n                     uint16_t port,\n                     std::vector<mmu_memory_if*> mmus) {\n        (void)name;\n\n\tif (targets.size() <= 0)\n\t\tthrow std::invalid_argument(\"no harts specified\");\n\tif (mmus.size() > 0 && mmus.size() != targets.size())\n\t\tthrow std::invalid_argument(\"invalid amount of MMUs specified\");\n\n\tfor (size_t i = 0; i < targets.size(); i++) {\n\t\tdebug_target_if *target = targets.at(i);\n\t\tharts.push_back(target);\n\n\t\tevents[target] = std::make_tuple(new sc_core::sc_event, (sc_core::sc_event *)NULL);\n\t\tif (mmus.size() > 0)\n\t\t\tmmu[target] = mmus.at(i);\n\n\t\t/* Don't block on WFI, otherwise the run_threads method\n\t\t * does not work correctly. Allowing blocking WFI would\n\t\t * likely increase the performance */\n\t\ttarget->block_on_wfi(false);\n\t}\n\n\tmemory = mm;\n\tarch = harts.at(0)->get_architecture(); // assuming all harts use the same\n\tprevpkt = NULL;\n\tcreate_sock(port);\n\n\tSC_THREAD(run);\n\n\tthr = std::thread(&GDBServer::serve, this);\n\tthr.detach();\n}\n\nsc_core::sc_event *GDBServer::get_stop_event(debug_target_if *hart) {\n\treturn std::get<0>(events.at(hart));\n}\n\nvoid GDBServer::set_run_event(debug_target_if *hart, sc_core::sc_event *event) {\n\tstd::get<1>(events.at(hart)) = event;\n}\n\nvoid GDBServer::create_sock(uint16_t port) {\n\tstruct sockaddr_in addr;\n\tint reuse;\n\n\tsockfd = socket(AF_INET, SOCK_STREAM, 0);\n\tif (sockfd == -1)\n\t\tthrow std::system_error(errno, std::generic_category());\n\n\treuse = 1;\n\tif (setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &reuse, sizeof(reuse)) == -1)\n\t\tgoto err;\n\tif (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse)) == -1)\n\t\tgoto err;\n\n\tmemset(&addr, 0, sizeof(addr));\n\taddr.sin_family = AF_INET;\n\taddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);\n\taddr.sin_port = htons(port);\n\n\tif (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)\n\t\tgoto err;\n\tif (listen(sockfd, 0) == -1)\n\t\tgoto err;\n\n\treturn;\nerr:\n\tclose(sockfd);\n\tthrow std::system_error(errno, std::generic_category());\n}\n\nstd::vector<debug_target_if *> GDBServer::get_threads(int id) {\n\tif (id == GDB_THREAD_ANY)\n\t\tid = 1; /* pick the first thread */\n\n\tif (id == GDB_THREAD_ALL)\n\t\treturn harts;\n\n\tif (id < 1) /* thread ids should start at index 1 */\n\t\tthrow std::out_of_range(\"Thread id is too small\");\n\telse\n\t\tid--;\n\n\tstd::vector<debug_target_if *> v;\n\tv.push_back(harts.at(id));\n\treturn v;\n}\n\nuint64_t GDBServer::translate_addr(debug_target_if *hart, uint64_t addr, MemoryAccessType type) {\n\tmmu_memory_if *mmu_if;\n\ttry {\n\t\tmmu_if = mmu.at(hart);\n\t} catch (const std::out_of_range&) {\n\t\tmmu_if = NULL;\n\t}\n\n\tif (!mmu_if) {\n\t\treturn addr;\n\t} else {\n\t\treturn mmu_if->v2p(addr, type);\n\t}\n}\n\nvoid GDBServer::exec_thread(thread_func fn, char op) {\n\tint thread;\n\tstd::vector<debug_target_if *> threads;\n\n\ttry {\n\t\tthread = thread_ops.at(op);\n\t} catch (const std::out_of_range&) {\n\t\tthread = GDB_THREAD_ANY;\n\t}\n\n\tthreads = get_threads(thread);\n\tfor (debug_target_if *thread : threads)\n\t\tfn(thread);\n}\n\nstd::vector<debug_target_if *> GDBServer::run_threads(std::vector<debug_target_if *> hartsrun, bool single) {\n\tif (hartsrun.empty()) {\n\t\treturn hartsrun;\n\t}\n\tthis->single_run = single;\n\n\t/* invoke all selected harts */\n\tsc_core::sc_event_or_list allharts;\n\tfor (debug_target_if *hart : hartsrun) {\n\t\tsc_core::sc_event *stop_event, *run_event;\n\t\tstd::tie (stop_event, run_event) = this->events.at(hart);\n\n\t\trun_event->notify();\n\t\tallharts |= *stop_event;\n\t}\n\n\t/* wait until the first hart finishes execution */\n\tsc_core::wait(allharts);\n\n\t/* ensure that all running harts are stopped */\n\tstd::vector<CoreExecStatus> orig_status;\n\tfor (debug_target_if *hart : hartsrun) {\n\t\tCoreExecStatus status = hart->get_status();\n\t\torig_status.push_back(status);\n\n\t\tif (status != CoreExecStatus::Runnable)\n\t\t\tcontinue;\n\t\thart->set_status(CoreExecStatus::HitBreakpoint);\n\n\t\tsc_core::sc_event &stopev = *get_stop_event(hart);\n\t\tsc_core::wait(stopev);\n\t}\n\n\t/* restore original hart status */\n\tassert(orig_status.size() == hartsrun.size());\n\tfor (size_t i = 0; i < hartsrun.size(); i++)\n\t\thartsrun[i]->set_status(orig_status[i]);\n\n\treturn hartsrun;\n}\n\nvoid GDBServer::writeall(int fd, char *data, size_t len) {\n\tssize_t ret, w;\n\n\tw = 0;\n\tdo {\n\t\tassert(len >= (size_t)w);\n\t\tret = write(fd, &data[w], len - (size_t)w);\n\t\tif (ret < 0)\n\t\t\tthrow std::system_error(errno, std::generic_category());\n\n\t\tw += ret;\n\t} while ((size_t)w < len);\n}\n\nvoid GDBServer::send_packet(int conn, const char *data, gdb_kind_t kind) {\n\tchar *serialized;\n\n\tserialized = gdb_serialize(kind, data);\n\n\ttry {\n\t\twriteall(conn, serialized, strlen(serialized));\n\t} catch (const std::system_error& e) {\n\t\twarnx(\"writeall failed: %s\", e.what());\n\t\tgoto ret;\n\t}\n\n\t/* acknowledgment are only used for GDB packets */\n\tif (kind != GDB_KIND_PACKET)\n\t\tgoto ret;\n\n\tfree(prevpkt);\n\tif (!(prevpkt = strdup(serialized))) {\n\t\tprevpkt = NULL;\n\t\tfree(serialized);\n\t\tthrow std::system_error(errno, std::generic_category());\n\t}\n\nret:\n\tfree(serialized);\n}\n\nvoid GDBServer::retransmit(int conn) {\n\tif (!prevpkt)\n\t\treturn;\n\n\ttry {\n\t\twriteall(conn, prevpkt, strlen(prevpkt));\n\t} catch (const std::system_error& e) {\n\t\twarnx(\"writeall failed: %s\", e.what());\n\t}\n\n\t/* memory for prevpkt is freed on next successfull\n\t * packet transmit in the send_packet function */\n}\n\nvoid GDBServer::dispatch(int conn) {\n\tFILE *stream;\n\tgdb_packet_t *pkt;\n\n\tif (!(stream = fdopen(conn, \"r\")))\n\t\tthrow std::system_error(errno, std::generic_category());\n\n\tfor (;;) {\n\t\tmtx.lock();\n\t\tif (!(pkt = gdb_parse_pkt(stream))) {\n\t\t\tmtx.unlock();\n\t\t\tbreak;\n\t\t}\n\n\t\tpktq.push(std::make_tuple(conn, pkt));\n\t\tasyncEvent.notify();\n\n\t\t/* further processing is performed in the SystemC run()\n\t\t * thread which interacts with the ISS objects and\n\t\t * unlocks the mutex after finishing all operations. */\n\t}\n\n\tfclose(stream);\n}\n\nvoid GDBServer::serve(void) {\n\tint conn;\n\n\tfor (;;) {\n\t\tif ((conn = accept(sockfd, NULL, NULL)) == -1) {\n\t\t\twarn(\"accept failed\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tdispatch(conn);\n\t\tclose(conn);\n\n\t\tfree(prevpkt);\n\t\tprevpkt = NULL;\n\t}\n}\n\nvoid GDBServer::run(void) {\n\tint conn;\n\tgdb_command_t *cmd;\n\tgdb_packet_t *pkt;\n\tpacket_handler handler;\n\n\tfor (;;) {\n\t\tsc_core::wait(asyncEvent);\n\n\t\tauto ctx = pktq.front();\n\t\tstd::tie (conn, pkt) = ctx;\n\n\t\tswitch (pkt->kind) {\n\t\tcase GDB_KIND_NACK:\n\t\t\tretransmit(conn);\n\t\t\t/* fall through */\n\t\tcase GDB_KIND_ACK:\n\t\t\tgoto next1;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!(cmd = gdb_parse_cmd(pkt))) {\n\t\t\tsend_packet(conn, NULL, GDB_KIND_NACK);\n\t\t\tgoto next1;\n\t\t}\n\n\t\tsend_packet(conn, NULL, GDB_KIND_ACK);\n\t\ttry {\n\t\t\thandler = handlers.at(cmd->name);\n\t\t} catch (const std::out_of_range&) {\n\t\t\t// For any command not supported by the stub, an\n\t\t\t// empty response (‘$#00’) should be returned.\n\t\t\tsend_packet(conn, \"\");\n\t\t\tgoto next2;\n\t\t}\n\n\t\t(this->*handler)(conn, cmd);\n\nnext2:\n\t\tgdb_free_cmd(cmd);\nnext1:\n\t\tgdb_free_packet(pkt);\n\t\tpktq.pop();\n\t\tmtx.unlock();\n\t}\n}\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/gdb_server.h",
    "content": "#ifndef RISCV_GDB_NG\n#define RISCV_GDB_NG\n\n#include <stdint.h>\n#include <stddef.h>\n#include <stdbool.h>\n\n#include <queue>\n#include <mutex>\n#include <systemc>\n#include <thread>\n#include <map>\n#include <tuple>\n#include <functional>\n\n#include <core/common/mmu_mem_if.h>\n#include <libgdb/parser2.h>\n\n#include \"debug.h\"\n#include \"core_defs.h\"\n#include \"platform/common/async_event.h\"\n#include \"debug_memory.h\" // DebugMemoryInterface\n\nSC_MODULE(GDBServer) {\npublic:\n\ttypedef void (GDBServer::*packet_handler)(int, gdb_command_t *);\n\n\tvoid haltReason(int, gdb_command_t *);\n\tvoid getRegisters(int, gdb_command_t *);\n\tvoid setThread(int, gdb_command_t *);\n\tvoid killServer(int, gdb_command_t *);\n\tvoid readMemory(int, gdb_command_t *);\n\tvoid writeMemory(int, gdb_command_t *);\n\tvoid readRegister(int, gdb_command_t *);\n\tvoid qAttached(int, gdb_command_t *);\n\tvoid qSupported(int, gdb_command_t *);\n\tvoid threadInfo(int, gdb_command_t *);\n\tvoid threadInfoEnd(int, gdb_command_t *);\n\tvoid vCont(int, gdb_command_t *);\n\tvoid vContSupported(int, gdb_command_t *);\n\tvoid removeBreakpoint(int, gdb_command_t *);\n\tvoid setBreakpoint(int, gdb_command_t *);\n\tvoid isAlive(int, gdb_command_t *);\n\n\tSC_HAS_PROCESS(GDBServer);\n\n\tGDBServer(sc_core::sc_module_name,\n\t          std::vector<debug_target_if*>,\n\t          DebugMemoryInterface*,\n\t          uint16_t,\n\t          std::vector<mmu_memory_if*> mmus = {});\n\n\t/* Used by GDBRunner to determine whether run() or run_step()\n\t * should be used when receiving a run event for a debug_target_if.\n\t *\n\t * TODO: Pass this on a per-event basis instead. */\n\tbool single_run = false;\n\n\tsc_core::sc_event *get_stop_event(debug_target_if *);\n\tvoid set_run_event(debug_target_if *, sc_core::sc_event *);\n\nprivate:\n\ttypedef std::function<void(debug_target_if *)> thread_func;\n\ttypedef std::tuple<int, gdb_packet_t *> ctx;\n\ttypedef std::tuple<sc_core::sc_event *, sc_core::sc_event *> hart_event;\n\n\tDebugMemoryInterface *memory;\n\tAsyncEvent asyncEvent;\n\tArchitecture arch;\n\tstd::vector<debug_target_if*> harts;\n\tstd::thread thr;\n\tchar *prevpkt;\n\tstd::queue<ctx> pktq;\n\tstd::mutex mtx;\n\tint sockfd;\n\n\t/* operation → thread id */\n\tstd::map<char, int> thread_ops;\n\n\t/* hart → events */\n\tstd::map<debug_target_if *, hart_event> events;\n\n\t/* hart → mmu */\n\tstd::map<debug_target_if *, mmu_memory_if *> mmu;\n\n\tvoid create_sock(uint16_t);\n\tstd::vector<debug_target_if *> get_threads(int);\n\tuint64_t translate_addr(debug_target_if *, uint64_t, MemoryAccessType type);\n\tvoid exec_thread(thread_func, char = 'g');\n\tstd::vector<debug_target_if *> run_threads(std::vector<debug_target_if *>, bool = false);\n\tvoid writeall(int, char *, size_t);\n\tvoid send_packet(int, const char *, gdb_kind_t = GDB_KIND_PACKET);\n\tvoid retransmit(int);\n\tvoid dispatch(int conn);\n\tvoid serve(void);\n\tvoid run(void);\n};\n\n#endif\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/handler.cpp",
    "content": "#include <assert.h>\n#include <stdlib.h>\n#include <limits.h>\n\n#include <libgdb/parser2.h>\n\n#include \"debug.h\"\n#include \"gdb_server.h\"\n#include \"register_format.h\"\n\nenum {\n\tGDB_PKTSIZ = 4096,\n\tGDB_PC_REG = 32,\n};\n\nstd::map<std::string, GDBServer::packet_handler> handlers {\n\t{ \"?\", &GDBServer::haltReason },\n\t{ \"g\", &GDBServer::getRegisters },\n\t{ \"H\", &GDBServer::setThread },\n\t{ \"k\", &GDBServer::killServer },\n\t{ \"m\", &GDBServer::readMemory },\n\t{ \"M\", &GDBServer::writeMemory },\n\t{ \"p\", &GDBServer::readRegister },\n\t{ \"qAttached\", &GDBServer::qAttached },\n\t{ \"qSupported\", &GDBServer::qSupported },\n\t{ \"qfThreadInfo\", &GDBServer::threadInfo },\n\t{ \"qsThreadInfo\", &GDBServer::threadInfoEnd },\n\t{ \"T\", &GDBServer::isAlive },\n\t{ \"vCont\", &GDBServer::vCont },\n\t{ \"vCont?\", &GDBServer::vContSupported },\n\t{ \"z\", &GDBServer::removeBreakpoint },\n\t{ \"Z\", &GDBServer::setBreakpoint },\n};\n\nvoid GDBServer::haltReason(int conn, gdb_command_t *cmd) {\n\t(void)cmd;\n\n\t// If n is a recognized stop reason […]. The aa should be\n\t// ‘05’, the trap signal. At most one stop reason should be\n\t// present.\n\n\t// TODO: Only send create conditionally.\n\tsend_packet(conn, \"S05\");\n}\n\nvoid GDBServer::getRegisters(int conn, gdb_command_t *cmd) {\n\t(void)cmd;\n\n\tauto formatter = new RegisterFormater(arch);\n\tauto fn = [formatter] (debug_target_if *hart) {\n\t\tfor (uint64_t v : hart->get_registers())\n\t\t\tformatter->formatRegister(v);\n\t};\n\n\texec_thread(fn);\n\tsend_packet(conn, formatter->str().c_str());\n\tdelete formatter;\n}\n\nvoid GDBServer::setThread(int conn, gdb_command_t *cmd) {\n\tgdb_cmd_h_t *hcmd;\n\n\thcmd = &cmd->v.hcmd;\n\tthread_ops[hcmd->op] = hcmd->id.tid;\n\n\tsend_packet(conn, \"OK\");\n}\n\nvoid GDBServer::killServer(int conn, gdb_command_t *cmd) {\n\t(void)conn;\n\t(void)cmd;\n\n\t// TODO: Stop the System C simulation instead of\n\t// terminating the program. This would require interacting\n\t// with the GDBServerRunner directly to make it exit.\n\t//\n\t// This could be implemented by adding sys_exit to\n\t// debug_target_if, however, some SystemC modules, e.g. FU540_PLIC\n\t// also spawn threads which are not stopped at all. These\n\t// modules need to be fixed first.\n\texit(EXIT_SUCCESS);\n}\n\nvoid GDBServer::readMemory(int conn, gdb_command_t *cmd) {\n\tgdb_memory_t *mem;\n\n\tmem = &cmd->v.mem;\n\n\tassert(mem->addr <= UINT64_MAX);\n\tassert(mem->length <= UINT_MAX);\n\n\tstd::string retval;\n\tauto fn = [this, &retval, mem] (debug_target_if *hart) {\n\t\tuint64_t addr = translate_addr(hart, mem->addr, LOAD);\n\t\tretval += memory->read_memory(addr, (unsigned)mem->length);\n\t};\n\n\ttry {\n\t\texec_thread(fn);\n\t} catch (const std::runtime_error&) { /* exception raised in fn */\n\t\tsend_packet(conn, \"E01\");\n\t\treturn;\n\t}\n\n\tsend_packet(conn, retval.c_str());\n}\n\nvoid GDBServer::writeMemory(int conn, gdb_command_t *cmd) {\n\tgdb_memory_t *loc;\n\tgdb_memory_write_t *mem;\n\n\tmem = &cmd->v.memw;\n\tloc = &mem->location;\n\n\tassert(loc->addr <= UINT64_MAX);\n\tassert(loc->length <= UINT_MAX);\n\n\tauto fn = [this, loc, mem] (debug_target_if *hart) {\n\t\tuint64_t addr = translate_addr(hart, loc->addr, STORE);\n\t\tmemory->write_memory(addr, (unsigned)loc->length, mem->data);\n\t};\n\n\ttry {\n\t\texec_thread(fn);\n\t} catch (const std::runtime_error&) {\n\t\tsend_packet(conn, \"E01\");\n\t\treturn;\n\t}\n\n\tsend_packet(conn, \"OK\");\n}\n\nvoid GDBServer::readRegister(int conn, gdb_command_t *cmd) {\n\tint reg;\n\tauto formatter = new RegisterFormater(arch);\n\n\treg = cmd->v.ival;\n\tauto fn = [formatter, reg] (debug_target_if *hart) {\n\t\tuint64_t regval;\n\t\tif (reg == GDB_PC_REG) {\n\t\t\tregval = hart->get_progam_counter();\n\t\t} else {\n\t\t\tregval = hart->read_register(reg);\n\t\t}\n\n\t\t/* TODO: handle CSRs? */\n\n\t\tformatter->formatRegister(regval);\n\t};\n\n\ttry {\n\t\texec_thread(fn);\n\t} catch (const std::out_of_range&) { /* exception raised in fn */\n\t\tsend_packet(conn, \"E01\");\n\t\tgoto ret;\n\t}\n\n\tsend_packet(conn, formatter->str().c_str());\nret:\n\tdelete formatter;\n}\n\nvoid GDBServer::threadInfo(int conn, gdb_command_t *cmd) {\n\t(void)cmd;\n\n\tstd::string thrlist = \"m\";\n\n\t/* TODO: refactor this to make it always output hex digits,\n\t * preferablly move it to the protocol code/ */\n\tfor (size_t i = 0; i < harts.size(); i++) {\n\t\tdebug_target_if *hart = harts.at(i);\n\t\tif (hart->get_status() == CoreExecStatus::Terminated)\n\t\t\tcontinue;\n\n\t\tthrlist += std::to_string(hart->get_hart_id() + 1);\n\t\tif (i + 1 < harts.size())\n\t\t\tthrlist += \",\";\n\t}\n\n\tsend_packet(conn, thrlist.c_str());\n}\n\nvoid GDBServer::threadInfoEnd(int conn, gdb_command_t *cmd) {\n\t(void)cmd;\n\n\t// GDB will respond to each reply with a request for more thread\n\t// ids (using the ‘qs’ form of the query), until the target\n\t// responds with ‘l’ (lower-case ell, for last).\n\t//\n\t// Since the GDBServer::threadInfo sends all threads in one\n\t// response we always terminate the list here.\n\tsend_packet(conn, \"l\");\n}\n\nvoid GDBServer::qAttached(int conn, gdb_command_t *cmd) {\n\t(void)cmd;\n\n\t// 0 process started, 1 attached to process\n\tsend_packet(conn, \"0\");\n}\n\nvoid GDBServer::qSupported(int conn, gdb_command_t *cmd) {\n\t(void)cmd;\n\n\tsend_packet(conn, (\"vContSupported+;PacketSize=\" + std::to_string(GDB_PKTSIZ)).c_str());\n}\n\nvoid GDBServer::isAlive(int conn, gdb_command_t *cmd) {\n\tgdb_thread_t *thr;\n\n\tthr = &cmd->v.tval;\n\ttry {\n\t\tget_threads(thr->tid);\n\t} catch (const std::out_of_range&) {\n\t\tsend_packet(conn, \"E01\");\n\t\treturn;\n\t}\n\n\tsend_packet(conn, \"OK\");\n}\n\nvoid GDBServer::vCont(int conn, gdb_command_t *cmd) {\n\tgdb_vcont_t *vcont;\n\tint stopped_thread = -1;\n\tconst char *stop_reason = NULL;\n\tstd::map<debug_target_if *, bool> matched;\n\n\t/* This handler attempts to implement the all-stop mode.\n\t * See: https://sourceware.org/gdb/onlinedocs/gdb/All_002dStop-Mode.html */\n\n\tvcont = cmd->v.vval;\n\tfor (vcont = cmd->v.vval; vcont; vcont = vcont->next) {\n\t\tbool single = false;\n\t\tif (vcont->action == 's')\n\t\t\tsingle = true;\n\t\telse if (vcont->action != 'c')\n\t\t\tthrow std::invalid_argument(\"Unimplemented vCont action\"); /* TODO */\n\n\t\tstd::vector<debug_target_if *> selected_harts;\n\t\ttry {\n\t\t\tauto run = get_threads(vcont->thread.tid);\n\t\t\tfor (auto i = run.begin(); i != run.end();) {\n\t\t\t\tdebug_target_if *hart = *i;\n\t\t\t\tif (matched.count(hart))\n\t\t\t\t\ti = run.erase(i); /* already matched */\n\t\t\t\telse\n\t\t\t\t\ti++;\n\t\t\t}\n\n\t\t\tselected_harts = run_threads(run, single);\n\t\t} catch (const std::out_of_range&) {\n\t\t\tsend_packet(conn, \"E01\");\n\t\t\treturn;\n\t\t}\n\n\t\tfor (debug_target_if *hart : selected_harts) {\n\t\t\tswitch (hart->get_status()) {\n\t\t\tcase CoreExecStatus::HitBreakpoint:\n\t\t\t\tstop_reason = \"05\";\n\t\t\t\tstopped_thread = hart->get_hart_id() + 1;\n\n\t\t\t\t/* mark runnable again */\n\t\t\t\thart->set_status(CoreExecStatus::Runnable);\n\n\t\t\t\tbreak;\n\t\t\tcase CoreExecStatus::Terminated:\n\t\t\t\tstop_reason = \"03\";\n\t\t\t\tstopped_thread = hart->get_hart_id() + 1;\n\t\t\t\tbreak;\n\t\t\tcase CoreExecStatus::Runnable:\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t/* The vCont specification mandates that only the leftmost action with\n\t\t * a matching thread-id is applied. Unfortunately, the specification\n\t\t * is a bit unclear in regards to handling two actions with no thread\n\t\t * id (i.e. GDB_THREAD_ALL). */\n\t\tif (vcont->thread.tid > 0) {\n\t\t\tauto threads = get_threads(vcont->thread.tid);\n\t\t\tassert(threads.size() == 1);\n\t\t\tmatched[threads.front()] = true;\n\t\t}\n\t}\n\n\tassert(stop_reason && stopped_thread >= 1);\n\n\t/* This sets the current thread for various follow-up\n\t * operations, most importantly readRegister. Without this\n\t * change gdb reads the registers of the previously selected\n\t * thread and doesn't switch threads properly if a thread other\n\t * than the currently selected hits a breakpoint.\n\t *\n\t * XXX: No idea if the stub is really required to do this. */\n\tthread_ops['g'] = stopped_thread;\n\n\tconst std::string msg = std::string(\"T\") + stop_reason + \"thread:\" +\n\t                        std::to_string(stopped_thread) + \";\";\n\tsend_packet(conn, msg.c_str());\n}\n\nvoid GDBServer::vContSupported(int conn, gdb_command_t *cmd) {\n\t(void)cmd;\n\n\t// We need to support both c and C otherwise GDB doesn't use vCont\n\t// This is documented in the remote_vcont_probe function in the GDB source.\n\tsend_packet(conn, \"vCont;c;C\");\n}\n\nvoid GDBServer::removeBreakpoint(int conn, gdb_command_t *cmd) {\n\tgdb_breakpoint_t *bpoint;\n\n\tbpoint = &cmd->v.bval;\n\tif (bpoint->type != GDB_ZKIND_SOFT) {\n\t\tsend_packet(conn, \"\"); /* not supported */\n\t\treturn;\n\t}\n\n\tfor (debug_target_if *hart : harts)\n\t\thart->remove_breakpoint(bpoint->address);\n\tsend_packet(conn, \"OK\");\n}\n\nvoid GDBServer::setBreakpoint(int conn, gdb_command_t *cmd) {\n\tgdb_breakpoint_t *bpoint;\n\n\tbpoint = &cmd->v.bval;\n\tif (bpoint->type != GDB_ZKIND_SOFT) {\n\t\tsend_packet(conn, \"\"); /* not supported */\n\t\treturn;\n\t}\n\n\tfor (debug_target_if *hart : harts)\n\t\thart->insert_breakpoint(bpoint->address);\n\tsend_packet(conn, \"OK\");\n}\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/libgdb/CMakeLists.txt",
    "content": "add_library(gdb\n\tmpc/mpc.c\n\tparser1.c\n\tparser2.c\n\tresponse.c\n\tutil.c)\n\ntarget_compile_options(gdb PRIVATE\n\t-Wpedantic -Wall -Wextra -Wconversion -Wmissing-prototypes\n\t-Wpointer-arith -Wstrict-prototypes -Wshadow -Wcast-align)\n\nset_source_files_properties(mpc/mpc.c\n\tPROPERTIES COMPILE_FLAGS \"-w -ansi\")\ntarget_include_directories(gdb PRIVATE\n\t${CMAKE_CURRENT_SOURCE_DIR}/mpc)\ntarget_include_directories(gdb PUBLIC\n\t${CMAKE_CURRENT_SOURCE_DIR}/include)\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/libgdb/README.md",
    "content": "# libgdb\n\nUtility library for implementing the [GDB protocol][gdb protocol].\n\n## Design\n\nUnfortunately, the GDB protocol doesn't use delimiters for protocol\nmessages. For this reason, a state machine is required to read packets\nfrom a stream. This library implements such a state machine using a\nparser combinator library. This state machine only returns a generic\npackage structure and doesn't perform any further canonicalization.\n\nSince proper canonicalization of GDB packets is desirable this utility\nlibrary provides two parser stages. The first stage is the\naforementioned state machine, the second parser stages performs packet\nspecific validations and uses the most restrictive input definition on a\nper packet basis.\n\nThis library attempts to follow some of the [langsec][langsec website]\nprinciples outlined in [\\[1\\]][curing the vulnerable parsers].\nUnfortunately, the second stage parser is unfinished at the moment and\nhas a fallback for accepting arbitrary inputs currently, thereby\ncircumventing the \"most restrictive input definition\".\n\nAdditionally, some utility functions for creating responses to received\nGDB packets are provided by `libgdb/response.h`. However, this part of\nthe library is in very early stages of development.\n\n[gdb protocol]: https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html\n[langsec website]: http://langsec.org/\n[curing the vulnerable parsers]: https://www.usenix.org/publications/login/spring2017/bratus\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/libgdb/include/libgdb/parser1.h",
    "content": "#ifndef LIBGDB_PARSER1_H\n#define LIBGDB_PARSER1_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdio.h>\n#include <stddef.h>\n#include <stdbool.h>\n\n#define GDB_CSUM_LEN 2\n\ntypedef enum {\n\tGDB_KIND_NOTIFY,\n\tGDB_KIND_PACKET,\n\tGDB_KIND_NACK,\n\tGDB_KIND_ACK,\n} gdb_kind_t;\n\ntypedef struct {\n\tgdb_kind_t kind;\n\tchar *data;\n\tchar csum[GDB_CSUM_LEN];\n} gdb_packet_t;\n\nvoid gdb_free_packet(gdb_packet_t *);\ngdb_packet_t *gdb_parse_pkt(FILE *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/libgdb/include/libgdb/parser2.h",
    "content": "#ifndef LIBGDB_PARSER2_H\n#define LIBGDB_PARSER2_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stddef.h>\n#include <stdint.h>\n#include <inttypes.h>\n\n#include <libgdb/parser1.h>\n\n#ifndef LIBGDB_ADDR_TYPE\n#define LIBGDB_ADDR_TYPE uint64_t\n#endif\n#ifndef LIBGDB_ADDR_FORMAT\n#define LIBGDB_ADDR_FORMAT SCNx64\n#endif\n\ntypedef LIBGDB_ADDR_TYPE gdb_addr_t;\n#undef LIBGDB_ADDR_TYPE\n\nenum {\n\tGDB_THREAD_UNSET = -2,\n\tGDB_THREAD_ANY = 0,\n\tGDB_THREAD_ALL = -1,\n};\n\ntypedef struct {\n\tint pid; /* requires multiprocess feature */\n\tint tid;\n} gdb_thread_t;\n\ntypedef enum {\n\tGDB_ZKIND_SOFT = 0,\n\tGDB_ZKIND_HARD,\n\tGDB_ZKIND_WATCHW,\n\tGDB_ZKIND_WATCHR,\n\tGDB_ZKIND_WATCHA,\n} gdb_ztype_t;\n\ntypedef struct {\n\tgdb_ztype_t type;\n\tgdb_addr_t address;\n\tsize_t kind;\n} gdb_breakpoint_t;\n\ntypedef struct {\n\tgdb_addr_t addr;\n\tsize_t length;\n} gdb_memory_t;\n\ntypedef struct {\n\tgdb_memory_t location;\n\tchar *data; /* null-terminated hexstring */\n} gdb_memory_write_t;\n\ntypedef struct {\n\tchar op;\n\tgdb_thread_t id;\n} gdb_cmd_h_t;\n\ntypedef struct _gdb_vcont_t gdb_vcont_t;\n\nstruct _gdb_vcont_t {\n\tchar action;\n\tint sig; /* -1 if unset */\n\tgdb_thread_t thread;\n\n\tgdb_vcont_t *next; /* NULL on end */\n};\n\ntypedef enum {\n\tGDB_ARG_NONE,\n\tGDB_ARG_VCONT,\n\tGDB_ARG_H,\n\tGDB_ARG_INT,\n\tGDB_ARG_MEMORY,\n\tGDB_ARG_MEMORYW,\n\tGDB_ARG_BREAK,\n\tGDB_ARG_THREAD,\n} gdb_argument_t;\n\ntypedef struct {\n\tchar *name;\n\tgdb_argument_t type;\n\n\tunion {\n\t\tgdb_vcont_t *vval;\n\t\tgdb_cmd_h_t hcmd;\n\t\tint ival;\n\t\tgdb_memory_t mem;\n\t\tgdb_memory_write_t memw;\n\t\tgdb_breakpoint_t bval;\n\t\tgdb_thread_t tval;\n\t} v;\n} gdb_command_t;\n\nvoid gdb_free_cmd(gdb_command_t *);\ngdb_command_t *gdb_parse_cmd(gdb_packet_t *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/libgdb/include/libgdb/response.h",
    "content": "#ifndef LIBGDB_RESPONSE_H\n#define LIBGDB_RESPONSE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Copied from QEMU\n * See: https://github.com/qemu/qemu/blob/d37147997/gdbstub.c#L103-L113 */\ntypedef enum {\n\tGDB_SIGNAL_0 = 0,\n\tGDB_SIGNAL_INT = 2,\n\tGDB_SIGNAL_QUIT = 3,\n\tGDB_SIGNAL_TRAP = 5,\n\tGDB_SIGNAL_ABRT = 6,\n\tGDB_SIGNAL_ALRM = 14,\n\tGDB_SIGNAL_IO = 23,\n\tGDB_SIGNAL_XCPU = 24,\n\tGDB_SIGNAL_UNKNOWN = 143\n} gdb_signal_t;\n\nchar *gdb_serialize(gdb_kind_t, const char *);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/libgdb/internal.h",
    "content": "#ifndef GDB_PROTOCOL_FNS\n#define GDB_PROTOCOL_FNS\n\n#include <assert.h>\n#include <stddef.h>\n\n#include <libgdb/parser2.h>\n\n#ifdef NDEBUG\n#define xassert(X) ((void)(X)) /* prevent -Wunused-parameter warning */\n#else\n#define xassert(X) (assert(X))\n#endif\n\nvoid *xrealloc(void *, size_t);\nvoid *xmalloc(size_t);\nchar *xstrdup(char *);\n\ngdb_command_t *gdb_new_cmd(char *, gdb_argument_t);\n\nint calc_csum(const char *);\nbool gdb_is_valid(gdb_packet_t *);\nchar *gdb_unescape(char *);\nchar *gdb_decode_runlen(char *);\n\n#endif\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/libgdb/parser1.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n\n#include <libgdb/parser1.h>\n\n#include \"mpc.h\"\n#include \"internal.h\"\n\nstatic mpc_val_t *\ngdbf_packet(int n, mpc_val_t** xs)\n{\n\tgdb_packet_t *pkt;\n\tchar *start, *csum;\n\n\txassert(n == 3);\n\n\tpkt = xmalloc(sizeof(*pkt));\n\tpkt->data = (char*)xs[1];\n\n\tstart = (char*)xs[0];\n\tswitch (*start) {\n\tcase '%':\n\t\tpkt->kind = GDB_KIND_NOTIFY;\n\t\tbreak;\n\tcase '$':\n\t\tpkt->kind = GDB_KIND_PACKET;\n\t\tbreak;\n\tdefault:\n\t\txassert(0);\n\t}\n\n\tcsum = (char*)xs[2];\n\tcsum++; /* skip leading '#' */\n\tmemcpy(pkt->csum, csum, GDB_CSUM_LEN);\n\n\t/* data (xs[1]) is still used in struct, don't free it */\n\tfree(xs[0]);\n\tfree(xs[2]);\n\n\treturn pkt;\n}\n\nstatic mpc_val_t *\ngdbf_acknowledge(mpc_val_t* xs)\n{\n\tgdb_packet_t *pkt;\n\tchar *str;\n\n\tpkt = xmalloc(sizeof(*pkt));\n\tpkt->data = NULL;\n\tmemset(pkt->csum, 0, GDB_CSUM_LEN);\n\n\tstr = (char*)xs;\n\tswitch (*str) {\n\tcase '+':\n\t\tpkt->kind = GDB_KIND_ACK;\n\t\tbreak;\n\tcase '-':\n\t\tpkt->kind = GDB_KIND_NACK;\n\t\tbreak;\n\tdefault:\n\t\txassert(0);\n\t}\n\n\tfree(xs);\n\treturn pkt;\n}\n\nstatic mpc_parser_t *\ngdb_csum(void)\n{\n\tmpc_parser_t *csum;\n\n\tcsum = mpc_and(2, mpcf_strfold, mpc_any(), mpc_any(), free);\n\treturn mpc_and(2, mpcf_strfold, mpc_char('#'), csum, free);\n}\n\nstatic mpc_parser_t *\ngdb_packet(void)\n{\n\tmpc_parser_t *data;\n\n\tdata = mpc_many(mpcf_strfold, mpc_noneof(\"#$\"));\n\treturn mpc_and(3, gdbf_packet, mpc_char('$'),\n\t               data, gdb_csum(), free, free);\n}\n\nstatic mpc_parser_t *\ngdb_notification(void)\n{\n\tmpc_parser_t *data;\n\n\tdata = mpc_many(mpcf_strfold, mpc_noneof(\"#$%\"));\n\treturn mpc_and(3, gdbf_packet, mpc_char('%'),\n\t               data, gdb_csum(), free, free);\n}\n\nstatic mpc_parser_t *\ngdb_acknowledge(void)\n{\n\treturn mpc_apply(mpc_oneof(\"+-\"), gdbf_acknowledge);\n}\n\nstatic mpc_parser_t *\ngdb_parse_stage1(void)\n{\n\treturn mpc_or(3, gdb_acknowledge(),\n\t              gdb_packet(),\n\t              gdb_notification());\n}\n\ngdb_packet_t *\ngdb_parse_pkt(FILE *stream)\n{\n\tgdb_packet_t *pkt;\n\tmpc_parser_t *par;\n\tmpc_result_t r;\n\n\tpkt = NULL;\n\tpar = mpc_predictive(gdb_parse_stage1());\n\n\tif (mpc_parse_pipe(\"<stream>\", stream, par, &r)) {\n\t\tpkt = (gdb_packet_t *)r.output;\n\t} else {\n#ifdef GDB_PARSER_DEBUG\n\t\tmpc_err_print(r.error);\n#endif\n\t\tmpc_err_delete(r.error);\n\t}\n\n\tmpc_cleanup(1, par);\n\treturn pkt;\n}\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/libgdb/parser2.c",
    "content": "#include <errno.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include <libgdb/parser1.h>\n#include <libgdb/parser2.h>\n\n#include \"mpc.h\"\n#include \"parser2.h\"\n#include \"internal.h\"\n\nstatic mpc_val_t *\ngdbf_ignarg(mpc_val_t* xs)\n{\n\tchar *str, *sep;\n\tgdb_command_t *cmd;\n\n\tstr = (char *)xs;\n\tif ((sep = strchr(str, ':')))\n\t\t*sep = '\\0';\n\n\tcmd = gdb_new_cmd(xstrdup(str), GDB_ARG_NONE);\n\tfree(xs);\n\n\treturn cmd;\n}\n\nstatic mpc_val_t *\ngdbf_address(mpc_val_t *x)\n{\n\tint r;\n\tgdb_addr_t *v;\n\n\tv = xmalloc(sizeof(*v));\n\n\tr = sscanf((char *)x, \"%\"LIBGDB_ADDR_FORMAT, v);\n\txassert(r == 1);\n\n\tfree(x);\n\treturn v;\n}\n\nstatic mpc_parser_t *\ngdb_address(void)\n{\n\treturn mpc_expect(mpc_apply(mpc_hexdigits(), gdbf_address), \"hexadecimal address\");\n}\n\nstatic mpc_val_t *\ngdbf_uhex(mpc_val_t *x)\n{\n\tint r;\n\tsize_t *v;\n\n\tv = xmalloc(sizeof(*v));\n\n\tr = sscanf((char *)x, \"%zx\", v);\n\txassert(r == 1);\n\t\n\tfree(x);\n\treturn v;\n}\n\nstatic mpc_parser_t *\ngdb_uhex(void)\n{\n\treturn mpc_apply(mpc_hexdigits(), gdbf_uhex);\n}\n\nstatic mpc_val_t *\ngdbf_negative(mpc_val_t *val)\n{\n\tint *neg;\n\n\txassert(!strcmp((char*)val, \"-1\"));\n\tneg = xmalloc(sizeof(*neg));\n\t*neg = -1;\n\n\tfree(val);\n\treturn neg;\n}\n\nstatic mpc_val_t *\ngdbf_memory(int n, mpc_val_t **xs)\n{\n\tgdb_memory_t *mem;\n\n\txassert(n == 3);\n\txassert(*(char *)xs[1] == ',');\n\n\tmem = xmalloc(sizeof(*mem));\n\tmem->addr = *((gdb_addr_t *)xs[0]);\n\tmem->length = *((size_t *)xs[2]);\n\n\tfree(xs[0]);\n\tfree(xs[1]);\n\tfree(xs[2]);\n\n\treturn mem;\n}\n\nstatic mpc_parser_t *\ngdb_memory(void)\n{\n\treturn mpc_and(3, gdbf_memory, gdb_address(),\n\t               mpc_char(','), gdb_uhex(),\n\t               free, free);\n}\n\nstatic mpc_val_t *\ngdbf_thread_id(int n, mpc_val_t** xs)\n{\n\tint *arg1, *arg2;\n\tgdb_thread_t *id;\n\n\txassert(n == 2);\n\n\tid = xmalloc(sizeof(*id));\n\targ1 = (int*)xs[0];\n\targ2 = (int*)xs[1];\n\n\tif (arg1 != NULL)\n\t\tid->pid = *arg1;\n\telse\n\t\tid->pid = GDB_THREAD_UNSET;\n\tid->tid = *arg2;\n\n\tfree(xs[0]);\n\tfree(xs[1]);\n\n\treturn id;\n}\n\nstatic mpc_parser_t *\ngdb_hexid(void)\n{\n\t/* Positive numbers with a target-specific interpretation,\n\t * formatted as big-endian hex strings. Can also be a literal\n\t * '-1' to indicate all threads, or '0' to pick any thread. */\n\treturn mpc_or(2, mpc_hex(),\n\t              mpc_apply(mpc_string(\"-1\"), gdbf_negative));\n}\n\nstatic mpc_parser_t *\ngdb_thread_id(void)\n{\n\tmpc_parser_t *pid, *tid;\n\n\ttid = gdb_hexid();\n\tpid = mpc_and(3, mpcf_snd_free, mpc_char('p'),\n\t              gdb_hexid(), mpc_char('.'), free, free);\n\n\treturn mpc_and(2, gdbf_thread_id, mpc_maybe(pid), tid, free);\n}\n\ngdbf_fold(h, GDB_ARG_H, GDBF_ARG_HCMD)\n\nstatic mpc_parser_t *\ngdb_packet_h(void)\n{\n\tmpc_parser_t *op, *id;\n\n\top = mpc_any(); /* (‘m’, ‘M’, ‘g’, ‘G’, et.al.). */\n\tid = gdb_thread_id();\n\n\treturn mpc_and(3, gdbf_packet_h, mpc_char('H'), op, id, free, free);\n}\n\ngdbf_fold(p, GDB_ARG_INT, GDBF_ARG_INT)\n\nstatic mpc_parser_t *\ngdb_packet_p(void)\n{\n\treturn mpc_and(2, gdbf_packet_p, mpc_char('p'), mpc_hex(), free);\n}\n\nstatic mpc_val_t *\ngdbf_vcont_action(int n, mpc_val_t **xs)\n{\n\tchar *actstr;\n\tsize_t actlen;\n\tgdb_vcont_t *vcont;\n\n\txassert(n == 2);\n\n\tactstr = (char *)xs[0];\n\tactlen = strlen(actstr);\n\n\tvcont = xmalloc(sizeof(*vcont));\n\tvcont->action = *actstr;\n\tvcont->next = NULL;\n\n\tif (actlen == 1)\n\t\tvcont->sig = -1;\n\telse if (actlen == 3)\n\t\tvcont->sig = (int)strtol(actstr + 1, NULL, 16);\n\telse\n\t\txassert(0);\n\n\t/* An action with no thread-id matches all threads. */\n\tif (!xs[1]) {\n\t\tvcont->thread.pid = GDB_THREAD_UNSET;\n\t\tvcont->thread.tid = GDB_THREAD_ALL;\n\t} else {\n\t\tvcont->thread = *((gdb_thread_t *)xs[1]);\n\t}\n\n\tfree(xs[0]);\n\tfree(xs[1]);\n\n\treturn vcont;\n}\n\nstatic mpc_val_t *\ngdbf_vcont(int n, mpc_val_t **xs)\n{\n\tsize_t i;\n\tgdb_vcont_t *vcont;\n\n\txassert(n >= 1);\n\n\tfor (vcont = (gdb_vcont_t *)xs[0], i = 1; i < (size_t)n; i++, vcont = vcont->next)\n\t\tvcont->next = (gdb_vcont_t *)xs[i];\n\tvcont->next = NULL;\n\n\treturn (gdb_vcont_t *)xs[0];\n}\n\ngdbf_fold(vcont, GDB_ARG_VCONT, GDBF_ARG_VCONT)\n\nstatic mpc_parser_t *\ngdb_packet_vcont(void)\n{\n\tmpc_parser_t *action0, *action1, *action, *args, *thread;\n\n\t/* TODO: add support for r command */\n\n\taction0 = mpc_oneof(\"cst\");\n\taction1 = mpc_and(2, mpcf_strfold, mpc_oneof(\"CS\"), mpc_hexdigits());\n\n\tthread = mpc_and(2, mpcf_snd_free, mpc_char(':'), gdb_thread_id(), free);\n\taction = mpc_and(2, gdbf_vcont_action, mpc_or(2, action0, action1),\n\t                 mpc_maybe(thread), free); /* destructor incorrect but unused */\n\n\targs = mpc_many1(gdbf_vcont, mpc_and(2, mpcf_snd_free, mpc_char(';'), action, free));\n\treturn mpc_and(2, gdbf_packet_vcont, mpc_string(\"vCont\"), args, free);\n}\n\ngdbf_fold(m, GDB_ARG_MEMORY, GDBF_ARG_MEMORY)\n\nstatic mpc_parser_t *\ngdb_packet_m(void)\n{\n\treturn mpc_and(2, gdbf_packet_m, mpc_char('m'), gdb_memory(), free);\n}\n\ngdbf_fold(M, GDB_ARG_MEMORYW, GDBF_ARG_MEMORYW)\n\nstatic mpc_parser_t *\ngdb_packet_M(void)\n{\n\treturn mpc_and(4, gdbf_packet_M, mpc_char('M'),\n\t               gdb_memory(), mpc_char(':'), mpc_hexdigits(),\n\t               free, free, free);\n}\n\nstatic mpc_parser_t *\ngdb_arg(mpc_parser_t *par)\n{\n\treturn mpc_and(2, mpcf_fst_free, par, mpc_char(','), free);\n}\n\ngdbf_fold(z, GDB_ARG_BREAK, GDBF_ARG_BREAK)\n\nstatic mpc_parser_t *\ngdb_packet_z(void)\n{\n\tmpc_parser_t *name, *type;\n\n\t/* TODO: parse cond_list */\n\n\tname = mpc_or(2, mpc_char('z'), mpc_char('Z'));\n\ttype = mpc_apply(mpc_re(\"[0-4]\"), mpcf_int);\n\n\treturn mpc_and(4, gdbf_packet_z, name,\n\t               gdb_arg(type), gdb_arg(gdb_address()),\n\t               gdb_uhex(), free, free, free);\n}\n\ngdbf_fold(T, GDB_ARG_THREAD, GDBF_ARG_THREAD)\n\nstatic mpc_parser_t *\ngdb_packet_T(void)\n{\n\treturn mpc_and(2, gdbf_packet_T, mpc_char('T'),\n\t               gdb_thread_id(), free);\n}\n\nstatic mpc_parser_t *\ngdb_any(void)\n{\n\treturn mpc_apply(mpc_many1(mpcf_strfold, mpc_any()), gdbf_ignarg);\n}\n\nstatic mpc_parser_t *\ngdb_cmd(mpc_parser_t *cmd)\n{\n\treturn mpc_and(2, mpcf_fst_free, cmd, mpc_eoi(), gdb_free_cmd);\n}\n\nstatic mpc_parser_t *\ngdb_parse_stage2(void)\n{\n\treturn mpc_or(8,\n\t              gdb_cmd(gdb_packet_h()),\n\t              gdb_cmd(gdb_packet_p()),\n\t              gdb_cmd(gdb_packet_vcont()),\n\t              gdb_cmd(gdb_packet_m()),\n\t              gdb_cmd(gdb_packet_M()),\n\t              gdb_cmd(gdb_packet_z()),\n\t              gdb_cmd(gdb_packet_T()),\n\t              gdb_any());\n}\n\ngdb_command_t *\ngdb_parse_cmd(gdb_packet_t *pkt)\n{\n\tmpc_result_t r;\n\tmpc_parser_t *par;\n\tchar *data, *unesc;\n\tgdb_command_t *cmd;\n\n\tcmd = NULL;\n\tpar = gdb_parse_stage2();\n\n\tif (pkt->kind != GDB_KIND_PACKET) {\n\t\terrno = EINVAL;\n\t\treturn NULL;\n\t}\n\n\tif (!gdb_is_valid(pkt)) {\n\t\terrno = EILSEQ;\n\t\treturn NULL;\n\t}\n\n\tif (!(data = gdb_decode_runlen(pkt->data))) {\n\t\terrno = EBADMSG;\n\t\treturn NULL;\n\t}\n\n\tunesc = gdb_unescape(data);\n\tfree(data);\n\n\tif (mpc_parse(\"<packet>\", unesc, par, &r)) {\n\t\tcmd = (gdb_command_t *)r.output;\n\t} else {\n#ifdef GDB_PARSER_DEBUG\n\t\tmpc_err_print(r.error);\n#endif\n\t\tmpc_err_delete(r.error);\n\t}\n\n\tfree(unesc);\n\tmpc_cleanup(1, par);\n\n\tif (!cmd)\n\t\terrno = EBADMSG; /* mpc_parse failed */\n\n\treturn cmd;\n}\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/libgdb/parser2.h",
    "content": "#define gdbf_fold(I, TYPE, FUNC)                                               \\\n\tstatic mpc_val_t *gdbf_packet_##I(int n, mpc_val_t **xs)               \\\n\t{                                                                      \\\n\t\tint j;                                                         \\\n\t\tgdb_command_t *cmd;                                            \\\n                                                                               \\\n\t\t/* Remove optional mpc_maybe() arguments */                    \\\n\t\tfor (j = n - 1; j >= 0; j--)                                   \\\n\t\t\tif (!xs[j])                                            \\\n\t\t\t\t--n;                                           \\\n                                                                               \\\n\t\txassert(n > 0);                                                \\\n\t\tcmd = gdb_new_cmd(xs[0], TYPE);                                \\\n\t\tFUNC;                                                          \\\n                                                                               \\\n\t\treturn cmd;                                                    \\\n\t}\n\n#define GDBF_ARG_HCMD                                                          \\\n\tdo {                                                                   \\\n\t\txassert(n == 3);                                               \\\n\t\t                                                               \\\n\t\tcmd->v.hcmd.op = *((char*)xs[1]);                              \\\n\t\tcmd->v.hcmd.id = *((gdb_thread_t*)xs[2]);                      \\\n                                                                               \\\n\t\tfree(xs[1]);                                                   \\\n\t\tfree(xs[2]);                                                   \\\n\t} while (0)\n\n#define GDBF_ARG_INT                                                           \\\n\tdo {                                                                   \\\n\t\txassert(n == 2);                                               \\\n\t\t                                                               \\\n\t\tcmd->v.ival = *((int*)xs[1]);                                  \\\n\t\tfree(xs[1]);                                                   \\\n\t} while (0)\n\n#define GDBF_ARG_VCONT                                                         \\\n\tdo {                                                                   \\\n\t\txassert(n == 2);                                               \\\n\t\tcmd->v.vval = (gdb_vcont_t *)xs[1];                            \\\n\t} while (0)\n\n#define GDBF_ARG_MEMORY                                                        \\\n\tdo {                                                                   \\\n\t\txassert(n == 2);                                               \\\n\t\tcmd->v.mem = *((gdb_memory_t *)xs[1]);                         \\\n\t\tfree(xs[1]);                                                   \\\n\t} while (0)\n\n#define GDBF_ARG_MEMORYW                                                       \\\n\tdo {                                                                   \\\n\t\txassert(n == 4);                                               \\\n\t\tcmd->v.memw.location = *((gdb_memory_t *)xs[1]);               \\\n\t\tcmd->v.memw.data = (char *)xs[3];                              \\\n\t\tfree(xs[1]);                                                   \\\n\t\tfree(xs[2]);                                                   \\\n\t} while (0)\n\n#define GDBF_ARG_BREAK                                                         \\\n\tdo {                                                                   \\\n\t\tint type;                                                      \\\n\t\t                                                               \\\n\t\txassert(n == 4);                                               \\\n\t\ttype = *(int *)(xs[1]);                                        \\\n\t\txassert(type >= GDB_ZKIND_SOFT && type <= GDB_ZKIND_WATCHA);   \\\n\t\t                                                               \\\n\t\tcmd->v.bval.type = (gdb_ztype_t)type;                          \\\n\t\tcmd->v.bval.address = *((gdb_addr_t *)xs[2]);                  \\\n\t\tcmd->v.bval.kind = *(size_t *)(xs[3]);                         \\\n\t\tfree(xs[1]);                                                   \\\n\t\tfree(xs[2]);                                                   \\\n\t\tfree(xs[3]);                                                   \\\n\t} while (0)\n\n#define GDBF_ARG_THREAD                                                        \\\n\tdo {                                                                   \\\n\t\txassert(n == 2);                                               \\\n\t\tcmd->v.tval = *((gdb_thread_t *)xs[1]);                        \\\n\t\tfree(xs[1]);                                                   \\\n\t} while (0)\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/libgdb/response.c",
    "content": "#include <err.h>\n#include <stdlib.h>\n#include <stddef.h>\n#include <string.h>\n#include <stdio.h>\n\n#include <libgdb/parser1.h>\n#include <libgdb/response.h>\n\n#include \"internal.h\"\n\nstatic char\nkind_to_char(gdb_kind_t kind)\n{\n\tswitch (kind) {\n\tcase GDB_KIND_NOTIFY:\n\t\treturn '#';\n\tcase GDB_KIND_PACKET:\n\t\treturn '$';\n\tcase GDB_KIND_NACK:\n\t\treturn '-';\n\tcase GDB_KIND_ACK:\n\t\treturn '+';\n\tdefault:\n\t\txassert(0);\n\t\treturn -1;\n\t}\n}\n\nchar *\ngdb_serialize(gdb_kind_t kind, const char *data)\n{\n\tsize_t pktlen;\n\tchar *serialized;\n\tchar pktkind;\n\tint csum, ret;\n\n\tpktkind = kind_to_char(kind);\n\tif (kind == GDB_KIND_NACK || kind == GDB_KIND_ACK) {\n\t\txassert(data == NULL);\n\t\tserialized = xmalloc(2); /* kind + nullbyte */\n\n\t\tserialized[0] = pktkind;\n\t\tserialized[1] = '\\0';\n\n\t\treturn serialized;\n\t}\n\n\tcsum = calc_csum(data);\n\n\t/* + 3 → nullbyte, checksum delimiter, kind */\n\tpktlen = strlen(data) + GDB_CSUM_LEN + 3;\n\tserialized = xmalloc(pktlen);\n\n\tret = snprintf(serialized, pktlen, \"%c%s#%.2x\", pktkind, data, csum);\n\tif (ret < 0)\n\t\terr(EXIT_FAILURE, \"snprintf failed\");\n\telse if ((size_t)ret >= pktlen)\n\t\terrx(EXIT_FAILURE, \"insufficient snprintf buffer size\");\n\n\treturn serialized;\n}\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/libgdb/util.c",
    "content": "#include <err.h>\n#include <limits.h>\n#include <stdio.h>\n#include <string.h>\n#include <stddef.h>\n#include <stdbool.h>\n#include <stdlib.h>\n#include <stdbool.h>\n\n#include <libgdb/parser1.h>\n#include <libgdb/parser2.h>\n\n#include \"internal.h\"\n\n#define GDB_RUNLEN_CHAR '*'\n#define GDB_RUNLEN_OFF 29\n#define GDB_RUNLEN_STEP 32\n#define GDB_ESCAPE_CHAR '}'\n#define GDB_ESCAPE_BYTE 0x20\n\nint\ncalc_csum(const char *data)\n{\n\tsize_t i;\n\tint csum = 0;\n\n\tfor (i = 0; i < strlen(data); i++)\n\t\tcsum += (int)data[i];\n\n\treturn csum % 256;\n}\n\nchar *\ngdb_decode_runlen(char *data)\n{\n\tint rcount, j;\n\tsize_t i, nlen, nrem;\n\tint runlen;\n\tchar *ndat;\n\n\tnlen = 0;\n\tnrem = strlen(data);\n\tndat = xmalloc(nrem);\n\n\tfor (runlen = -1, i = 0; i < strlen(data); i++) {\n\t\tif (data[i] == GDB_RUNLEN_CHAR) {\n\t\t\tif (i <= 0)\n\t\t\t\tgoto err;\n\t\t\trunlen = data[i - 1];\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (runlen == -1) {\n\t\t\trunlen = data[i];\n\t\t\trcount = 1;\n\t\t} else {\n\t\t\trcount = (int)data[i] - GDB_RUNLEN_OFF;\n\t\t\tif (rcount <= 0)\n\t\t\t\tgoto err;\n\t\t}\n\n\t\tfor (j = 0; j < rcount; j++) {\n\t\t\tif (nrem-- == 0) {\n\t\t\t\tndat = xrealloc(ndat, nlen + GDB_RUNLEN_STEP);\n\t\t\t\tnrem += GDB_RUNLEN_STEP;\n\t\t\t}\n\n\t\t\txassert(runlen >= 0 && runlen <= CHAR_MAX);\n\t\t\tndat[nlen++] = (char)runlen;\n\t\t}\n\n\t\trunlen = -1;\n\t}\n\n\t/* shrink to actual size */\n\tndat = xrealloc(ndat, nlen + 1);\n\tndat[nlen] = '\\0';\n\n\treturn ndat;\nerr:\n\tfree(ndat);\n\treturn NULL;\n}\n\nchar *\ngdb_unescape(char *data)\n{\n\tsize_t i, nlen;\n\tchar *ndat;\n\tbool esc;\n\n\tndat = xmalloc(strlen(data));\n\tnlen = 0;\n\n\tfor (esc = false, i = 0; i < strlen(data); i++) {\n\t\tif (data[i] == GDB_ESCAPE_CHAR) {\n\t\t\tesc = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tndat[nlen++] = (esc) ? data[i] ^ GDB_ESCAPE_BYTE : data[i];\n\t\tesc = false;\n\t}\n\n\t/* shrink to actual size */\n\tndat = xrealloc(ndat, nlen + 1);\n\tndat[nlen] = '\\0';\n\n\treturn ndat;\n}\n\nbool\ngdb_is_valid(gdb_packet_t *pkt)\n{\n\tint ret;\n\tint expcsum;\n\tchar strcsum[GDB_CSUM_LEN + 1]; /* +1 for snprintf nullbyte */\n\n\tif (!pkt->data)\n\t\treturn true;\n\texpcsum = calc_csum(pkt->data);\n\n\tret = snprintf(strcsum, sizeof(strcsum), \"%.2x\", expcsum);\n\txassert(ret == GDB_CSUM_LEN);\n\n\treturn !strncmp(pkt->csum, strcsum, GDB_CSUM_LEN);\n}\n\ngdb_command_t *\ngdb_new_cmd(char *name, gdb_argument_t type)\n{\n\tgdb_command_t *cmd;\n\n\tcmd = xmalloc(sizeof(*cmd));\n\tcmd->name = name;\n\tcmd->type = type;\n\n\treturn cmd;\n}\n\nvoid\ngdb_free_cmd(gdb_command_t *cmd)\n{\n\tgdb_vcont_t *parent, *next;\n\n\tif (cmd->type == GDB_ARG_MEMORYW)\n\t\tfree(cmd->v.memw.data);\n\n\tif (cmd->type == GDB_ARG_VCONT) {\n\t\tparent = cmd->v.vval;\n\t\twhile (parent) {\n\t\t\tnext = parent->next;\n\t\t\tfree(parent);\n\t\t\tparent = next;\n\t\t}\n\t}\n\n\tfree(cmd->name);\n\tfree(cmd);\n}\n\nvoid *\nxrealloc(void *ptr, size_t size)\n{\n\tvoid *r;\n\n\tif (!(r = realloc(ptr, size)))\n\t\terr(EXIT_FAILURE, \"realloc failed\");\n\n\treturn r;\n}\n\nvoid *\nxmalloc(size_t size)\n{\n\tvoid *r;\n\n\tif (!(r = malloc(size)))\n\t\terr(EXIT_FAILURE, \"malloc failed\");\n\n\treturn r;\n}\n\nchar *\nxstrdup(char *s)\n{\n\tchar *r;\n\n\tif (!(r = strdup(s)))\n\t\terr(EXIT_FAILURE, \"strdup failed\");\n\n\treturn r;\n}\n\nvoid\ngdb_free_packet(gdb_packet_t *pkt)\n{\n\tif (pkt->data)\n\t\tfree(pkt->data);\n\tfree(pkt);\n}\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/register_format.cpp",
    "content": "#include <iomanip>\n\n#include <byteswap.h>\n\n#include \"register_format.h\"\n\nRegisterFormater::RegisterFormater(Architecture arch) {\n\tthis->arch = arch;\n\tthis->stream << std::setfill('0') << std::hex;\n}\n\nvoid RegisterFormater::formatRegister(uint64_t value) {\n\tswitch (arch) {\n\tcase RV32:\n\t\tstream << std::setw(8) << bswap_32(value);\n\t\tbreak;\n\tcase RV64:\n\t\tstream << std::setw(16) << bswap_64(value);\n\t\tbreak;\n\tdefault:\n\t\tthrow std::invalid_argument(\"Architecture not implemented\");\n\t}\n}\n\nstd::string RegisterFormater::str(void) {\n\treturn this->stream.str();\n}\n"
  },
  {
    "path": "vp/src/core/common/gdb-mc/register_format.h",
    "content": "#ifndef RISCV_GDB_REGISTER\n#define RISCV_GDB_REGISTER\n\n#include <sstream>\n\n#include <stdint.h>\n\n#include \"core_defs.h\"\n\nclass RegisterFormater {\n  private:\n\tArchitecture arch;\n\tstd::ostringstream stream;\n\n  public:\n\tRegisterFormater(Architecture);\n\tvoid formatRegister(uint64_t);\n\tstd::string str(void);\n};\n\n#endif\n"
  },
  {
    "path": "vp/src/core/common/instr.cpp",
    "content": "#include \"instr.h\"\n#include \"trap.h\"\n#include \"util/common.h\"\n\n#include <cassert>\n#include <stdexcept>\n\nconstexpr uint32_t LUI_MASK = 0b00000000000000000000000001111111;\nconstexpr uint32_t LUI_ENCODING = 0b00000000000000000000000000110111;\nconstexpr uint32_t AUIPC_MASK = 0b00000000000000000000000001111111;\nconstexpr uint32_t AUIPC_ENCODING = 0b00000000000000000000000000010111;\nconstexpr uint32_t JAL_MASK = 0b00000000000000000000000001111111;\nconstexpr uint32_t JAL_ENCODING = 0b00000000000000000000000001101111;\nconstexpr uint32_t JALR_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t JALR_ENCODING = 0b00000000000000000000000001100111;\nconstexpr uint32_t BEQ_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t BEQ_ENCODING = 0b00000000000000000000000001100011;\nconstexpr uint32_t BNE_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t BNE_ENCODING = 0b00000000000000000001000001100011;\nconstexpr uint32_t BLT_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t BLT_ENCODING = 0b00000000000000000100000001100011;\nconstexpr uint32_t BGE_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t BGE_ENCODING = 0b00000000000000000101000001100011;\nconstexpr uint32_t BLTU_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t BLTU_ENCODING = 0b00000000000000000110000001100011;\nconstexpr uint32_t BGEU_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t BGEU_ENCODING = 0b00000000000000000111000001100011;\nconstexpr uint32_t LB_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t LB_ENCODING = 0b00000000000000000000000000000011;\nconstexpr uint32_t LH_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t LH_ENCODING = 0b00000000000000000001000000000011;\nconstexpr uint32_t LW_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t LW_ENCODING = 0b00000000000000000010000000000011;\nconstexpr uint32_t LBU_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t LBU_ENCODING = 0b00000000000000000100000000000011;\nconstexpr uint32_t LHU_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t LHU_ENCODING = 0b00000000000000000101000000000011;\nconstexpr uint32_t SB_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t SB_ENCODING = 0b00000000000000000000000000100011;\nconstexpr uint32_t SH_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t SH_ENCODING = 0b00000000000000000001000000100011;\nconstexpr uint32_t SW_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t SW_ENCODING = 0b00000000000000000010000000100011;\nconstexpr uint32_t ADDI_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t ADDI_ENCODING = 0b00000000000000000000000000010011;\nconstexpr uint32_t SLTI_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t SLTI_ENCODING = 0b00000000000000000010000000010011;\nconstexpr uint32_t SLTIU_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t SLTIU_ENCODING = 0b00000000000000000011000000010011;\nconstexpr uint32_t XORI_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t XORI_ENCODING = 0b00000000000000000100000000010011;\nconstexpr uint32_t ORI_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t ORI_ENCODING = 0b00000000000000000110000000010011;\nconstexpr uint32_t ANDI_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t ANDI_ENCODING = 0b00000000000000000111000000010011;\n//-- RV64 special case (one less mask bit compared to RV32)\nconstexpr uint32_t SLLI_MASK = 0b11111100000000000111000001111111;\nconstexpr uint32_t SLLI_ENCODING = 0b00000000000000000001000000010011;\nconstexpr uint32_t SRLI_MASK = 0b11111100000000000111000001111111;\nconstexpr uint32_t SRLI_ENCODING = 0b00000000000000000101000000010011;\nconstexpr uint32_t SRAI_MASK = 0b11111100000000000111000001111111;\nconstexpr uint32_t SRAI_ENCODING = 0b01000000000000000101000000010011;\n//-- RV32 case\nconstexpr uint32_t SLLI_32_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SLLI_32_ENCODING = 0b00000000000000000001000000010011;\nconstexpr uint32_t SRLI_32_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SRLI_32_ENCODING = 0b00000000000000000101000000010011;\nconstexpr uint32_t SRAI_32_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SRAI_32_ENCODING = 0b01000000000000000101000000010011;\n//--\nconstexpr uint32_t ADD_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t ADD_ENCODING = 0b00000000000000000000000000110011;\nconstexpr uint32_t SUB_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SUB_ENCODING = 0b01000000000000000000000000110011;\nconstexpr uint32_t SLL_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SLL_ENCODING = 0b00000000000000000001000000110011;\nconstexpr uint32_t SLT_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SLT_ENCODING = 0b00000000000000000010000000110011;\nconstexpr uint32_t SLTU_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SLTU_ENCODING = 0b00000000000000000011000000110011;\nconstexpr uint32_t XOR_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t XOR_ENCODING = 0b00000000000000000100000000110011;\nconstexpr uint32_t SRL_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SRL_ENCODING = 0b00000000000000000101000000110011;\nconstexpr uint32_t SRA_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SRA_ENCODING = 0b01000000000000000101000000110011;\nconstexpr uint32_t OR_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t OR_ENCODING = 0b00000000000000000110000000110011;\nconstexpr uint32_t AND_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t AND_ENCODING = 0b00000000000000000111000000110011;\nconstexpr uint32_t FENCE_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t FENCE_ENCODING = 0b00000000000000000000000000001111;\nconstexpr uint32_t FENCE_I_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t FENCE_I_ENCODING = 0b00000000000000000001000000001111;\nconstexpr uint32_t ECALL_MASK = 0b11111111111111111111111111111111;\nconstexpr uint32_t ECALL_ENCODING = 0b00000000000000000000000001110011;\nconstexpr uint32_t EBREAK_MASK = 0b11111111111111111111111111111111;\nconstexpr uint32_t EBREAK_ENCODING = 0b00000000000100000000000001110011;\nconstexpr uint32_t CSRRW_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t CSRRW_ENCODING = 0b00000000000000000001000001110011;\nconstexpr uint32_t CSRRS_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t CSRRS_ENCODING = 0b00000000000000000010000001110011;\nconstexpr uint32_t CSRRC_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t CSRRC_ENCODING = 0b00000000000000000011000001110011;\nconstexpr uint32_t CSRRWI_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t CSRRWI_ENCODING = 0b00000000000000000101000001110011;\nconstexpr uint32_t CSRRSI_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t CSRRSI_ENCODING = 0b00000000000000000110000001110011;\nconstexpr uint32_t CSRRCI_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t CSRRCI_ENCODING = 0b00000000000000000111000001110011;\nconstexpr uint32_t MUL_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t MUL_ENCODING = 0b00000010000000000000000000110011;\nconstexpr uint32_t MULH_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t MULH_ENCODING = 0b00000010000000000001000000110011;\nconstexpr uint32_t MULHSU_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t MULHSU_ENCODING = 0b00000010000000000010000000110011;\nconstexpr uint32_t MULHU_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t MULHU_ENCODING = 0b00000010000000000011000000110011;\nconstexpr uint32_t DIV_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t DIV_ENCODING = 0b00000010000000000100000000110011;\nconstexpr uint32_t DIVU_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t DIVU_ENCODING = 0b00000010000000000101000000110011;\nconstexpr uint32_t REM_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t REM_ENCODING = 0b00000010000000000110000000110011;\nconstexpr uint32_t REMU_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t REMU_ENCODING = 0b00000010000000000111000000110011;\nconstexpr uint32_t LR_W_MASK = 0b11111001111100000111000001111111;\nconstexpr uint32_t LR_W_ENCODING = 0b00010000000000000010000000101111;\nconstexpr uint32_t SC_W_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t SC_W_ENCODING = 0b00011000000000000010000000101111;\nconstexpr uint32_t AMOSWAP_W_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOSWAP_W_ENCODING = 0b00001000000000000010000000101111;\nconstexpr uint32_t AMOADD_W_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOADD_W_ENCODING = 0b00000000000000000010000000101111;\nconstexpr uint32_t AMOXOR_W_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOXOR_W_ENCODING = 0b00100000000000000010000000101111;\nconstexpr uint32_t AMOAND_W_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOAND_W_ENCODING = 0b01100000000000000010000000101111;\nconstexpr uint32_t AMOOR_W_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOOR_W_ENCODING = 0b01000000000000000010000000101111;\nconstexpr uint32_t AMOMIN_W_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOMIN_W_ENCODING = 0b10000000000000000010000000101111;\nconstexpr uint32_t AMOMAX_W_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOMAX_W_ENCODING = 0b10100000000000000010000000101111;\nconstexpr uint32_t AMOMINU_W_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOMINU_W_ENCODING = 0b11000000000000000010000000101111;\nconstexpr uint32_t AMOMAXU_W_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOMAXU_W_ENCODING = 0b11100000000000000010000000101111;\nconstexpr uint32_t URET_MASK = 0b11111111111111111111111111111111;\nconstexpr uint32_t URET_ENCODING = 0b00000000001000000000000001110011;\nconstexpr uint32_t SRET_MASK = 0b11111111111111111111111111111111;\nconstexpr uint32_t SRET_ENCODING = 0b00010000001000000000000001110011;\nconstexpr uint32_t MRET_MASK = 0b11111111111111111111111111111111;\nconstexpr uint32_t MRET_ENCODING = 0b00110000001000000000000001110011;\nconstexpr uint32_t WFI_MASK = 0b11111111111111111111111111111111;\nconstexpr uint32_t WFI_ENCODING = 0b00010000010100000000000001110011;\nconstexpr uint32_t SFENCE_VMA_MASK = 0b11111110000000000111111111111111;\nconstexpr uint32_t SFENCE_VMA_ENCODING = 0b00010010000000000000000001110011;\n\n//-- RV64IMA Extension\nconstexpr uint32_t LWU_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t LWU_ENCODING = 0b00000000000000000110000000000011;\nconstexpr uint32_t LD_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t LD_ENCODING = 0b00000000000000000011000000000011;\nconstexpr uint32_t SD_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t SD_ENCODING = 0b00000000000000000011000000100011;\nconstexpr uint32_t ADDIW_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t ADDIW_ENCODING = 0b00000000000000000000000000011011;\nconstexpr uint32_t SLLIW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SLLIW_ENCODING = 0b00000000000000000001000000011011;\nconstexpr uint32_t SRLIW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SRLIW_ENCODING = 0b00000000000000000101000000011011;\nconstexpr uint32_t SRAIW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SRAIW_ENCODING = 0b01000000000000000101000000011011;\nconstexpr uint32_t ADDW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t ADDW_ENCODING = 0b00000000000000000000000000111011;\nconstexpr uint32_t SUBW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SUBW_ENCODING = 0b01000000000000000000000000111011;\nconstexpr uint32_t SLLW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SLLW_ENCODING = 0b00000000000000000001000000111011;\nconstexpr uint32_t SRLW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SRLW_ENCODING = 0b00000000000000000101000000111011;\nconstexpr uint32_t SRAW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t SRAW_ENCODING = 0b01000000000000000101000000111011;\nconstexpr uint32_t MULW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t MULW_ENCODING = 0b00000010000000000000000000111011;\nconstexpr uint32_t DIVW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t DIVW_ENCODING = 0b00000010000000000100000000111011;\nconstexpr uint32_t DIVUW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t DIVUW_ENCODING = 0b00000010000000000101000000111011;\nconstexpr uint32_t REMW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t REMW_ENCODING = 0b00000010000000000110000000111011;\nconstexpr uint32_t REMUW_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t REMUW_ENCODING = 0b00000010000000000111000000111011;\nconstexpr uint32_t LR_D_MASK = 0b11111001111100000111000001111111;\nconstexpr uint32_t LR_D_ENCODING = 0b00010000000000000011000000101111;\nconstexpr uint32_t SC_D_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t SC_D_ENCODING = 0b00011000000000000011000000101111;\nconstexpr uint32_t AMOSWAP_D_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOSWAP_D_ENCODING = 0b00001000000000000011000000101111;\nconstexpr uint32_t AMOADD_D_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOADD_D_ENCODING = 0b00000000000000000011000000101111;\nconstexpr uint32_t AMOXOR_D_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOXOR_D_ENCODING = 0b00100000000000000011000000101111;\nconstexpr uint32_t AMOAND_D_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOAND_D_ENCODING = 0b01100000000000000011000000101111;\nconstexpr uint32_t AMOOR_D_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOOR_D_ENCODING = 0b01000000000000000011000000101111;\nconstexpr uint32_t AMOMIN_D_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOMIN_D_ENCODING = 0b10000000000000000011000000101111;\nconstexpr uint32_t AMOMAX_D_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOMAX_D_ENCODING = 0b10100000000000000011000000101111;\nconstexpr uint32_t AMOMINU_D_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOMINU_D_ENCODING = 0b11000000000000000011000000101111;\nconstexpr uint32_t AMOMAXU_D_MASK = 0b11111000000000000111000001111111;\nconstexpr uint32_t AMOMAXU_D_ENCODING = 0b11100000000000000011000000101111;\n\n// RV32/64FD Extension\nconstexpr uint32_t FLW_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t FLW_ENCODING = 0b00000000000000000010000000000111;\nconstexpr uint32_t FSW_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t FSW_ENCODING = 0b00000000000000000010000000100111;\nconstexpr uint32_t FMADD_S_MASK = 0b00000110000000000000000001111111;\nconstexpr uint32_t FMADD_S_ENCODING = 0b00000000000000000000000001000011;\nconstexpr uint32_t FMSUB_S_MASK = 0b00000110000000000000000001111111;\nconstexpr uint32_t FMSUB_S_ENCODING = 0b00000000000000000000000001000111;\nconstexpr uint32_t FNMADD_S_MASK = 0b00000110000000000000000001111111;\nconstexpr uint32_t FNMADD_S_ENCODING = 0b00000000000000000000000001001111;\nconstexpr uint32_t FNMSUB_S_MASK = 0b00000110000000000000000001111111;\nconstexpr uint32_t FNMSUB_S_ENCODING = 0b00000000000000000000000001001011;\nconstexpr uint32_t FADD_S_MASK = 0b11111110000000000000000001111111;\nconstexpr uint32_t FADD_S_ENCODING = 0b00000000000000000000000001010011;\nconstexpr uint32_t FSUB_S_MASK = 0b11111110000000000000000001111111;\nconstexpr uint32_t FSUB_S_ENCODING = 0b00001000000000000000000001010011;\nconstexpr uint32_t FMUL_S_MASK = 0b11111110000000000000000001111111;\nconstexpr uint32_t FMUL_S_ENCODING = 0b00010000000000000000000001010011;\nconstexpr uint32_t FDIV_S_MASK = 0b11111110000000000000000001111111;\nconstexpr uint32_t FDIV_S_ENCODING = 0b00011000000000000000000001010011;\nconstexpr uint32_t FSQRT_S_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FSQRT_S_ENCODING = 0b01011000000000000000000001010011;\nconstexpr uint32_t FSGNJ_S_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FSGNJ_S_ENCODING = 0b00100000000000000000000001010011;\nconstexpr uint32_t FSGNJN_S_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FSGNJN_S_ENCODING = 0b00100000000000000001000001010011;\nconstexpr uint32_t FSGNJX_S_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FSGNJX_S_ENCODING = 0b00100000000000000010000001010011;\nconstexpr uint32_t FMIN_S_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FMIN_S_ENCODING = 0b00101000000000000000000001010011;\nconstexpr uint32_t FMAX_S_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FMAX_S_ENCODING = 0b00101000000000000001000001010011;\nconstexpr uint32_t FCVT_W_S_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_W_S_ENCODING = 0b11000000000000000000000001010011;\nconstexpr uint32_t FCVT_WU_S_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_WU_S_ENCODING = 0b11000000000100000000000001010011;\nconstexpr uint32_t FMV_X_W_MASK = 0b11111111111100000111000001111111;\nconstexpr uint32_t FMV_X_W_ENCODING = 0b11100000000000000000000001010011;\nconstexpr uint32_t FEQ_S_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FEQ_S_ENCODING = 0b10100000000000000010000001010011;\nconstexpr uint32_t FLT_S_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FLT_S_ENCODING = 0b10100000000000000001000001010011;\nconstexpr uint32_t FLE_S_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FLE_S_ENCODING = 0b10100000000000000000000001010011;\nconstexpr uint32_t FCLASS_S_MASK = 0b11111111111100000111000001111111;\nconstexpr uint32_t FCLASS_S_ENCODING = 0b11100000000000000001000001010011;\nconstexpr uint32_t FCVT_S_W_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_S_W_ENCODING = 0b11010000000000000000000001010011;\nconstexpr uint32_t FCVT_S_WU_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_S_WU_ENCODING = 0b11010000000100000000000001010011;\nconstexpr uint32_t FMV_W_X_MASK = 0b11111111111100000111000001111111;\nconstexpr uint32_t FMV_W_X_ENCODING = 0b11110000000000000000000001010011;\nconstexpr uint32_t FCVT_L_S_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_L_S_ENCODING = 0b11000000001000000000000001010011;\nconstexpr uint32_t FCVT_LU_S_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_LU_S_ENCODING = 0b11000000001100000000000001010011;\nconstexpr uint32_t FCVT_S_L_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_S_L_ENCODING = 0b11010000001000000000000001010011;\nconstexpr uint32_t FCVT_S_LU_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_S_LU_ENCODING = 0b11010000001100000000000001010011;\nconstexpr uint32_t FLD_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t FLD_ENCODING = 0b00000000000000000011000000000111;\nconstexpr uint32_t FSD_MASK = 0b00000000000000000111000001111111;\nconstexpr uint32_t FSD_ENCODING = 0b00000000000000000011000000100111;\nconstexpr uint32_t FMADD_D_MASK = 0b00000110000000000000000001111111;\nconstexpr uint32_t FMADD_D_ENCODING = 0b00000010000000000000000001000011;\nconstexpr uint32_t FMSUB_D_MASK = 0b00000110000000000000000001111111;\nconstexpr uint32_t FMSUB_D_ENCODING = 0b00000010000000000000000001000111;\nconstexpr uint32_t FNMSUB_D_MASK = 0b00000110000000000000000001111111;\nconstexpr uint32_t FNMSUB_D_ENCODING = 0b00000010000000000000000001001011;\nconstexpr uint32_t FNMADD_D_MASK = 0b00000110000000000000000001111111;\nconstexpr uint32_t FNMADD_D_ENCODING = 0b00000010000000000000000001001111;\nconstexpr uint32_t FADD_D_MASK = 0b11111110000000000000000001111111;\nconstexpr uint32_t FADD_D_ENCODING = 0b00000010000000000000000001010011;\nconstexpr uint32_t FSUB_D_MASK = 0b11111110000000000000000001111111;\nconstexpr uint32_t FSUB_D_ENCODING = 0b00001010000000000000000001010011;\nconstexpr uint32_t FMUL_D_MASK = 0b11111110000000000000000001111111;\nconstexpr uint32_t FMUL_D_ENCODING = 0b00010010000000000000000001010011;\nconstexpr uint32_t FDIV_D_MASK = 0b11111110000000000000000001111111;\nconstexpr uint32_t FDIV_D_ENCODING = 0b00011010000000000000000001010011;\nconstexpr uint32_t FSQRT_D_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FSQRT_D_ENCODING = 0b01011010000000000000000001010011;\nconstexpr uint32_t FSGNJ_D_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FSGNJ_D_ENCODING = 0b00100010000000000000000001010011;\nconstexpr uint32_t FSGNJN_D_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FSGNJN_D_ENCODING = 0b00100010000000000001000001010011;\nconstexpr uint32_t FSGNJX_D_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FSGNJX_D_ENCODING = 0b00100010000000000010000001010011;\nconstexpr uint32_t FMIN_D_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FMIN_D_ENCODING = 0b00101010000000000000000001010011;\nconstexpr uint32_t FMAX_D_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FMAX_D_ENCODING = 0b00101010000000000001000001010011;\nconstexpr uint32_t FCVT_S_D_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_S_D_ENCODING = 0b01000000000100000000000001010011;\nconstexpr uint32_t FCVT_D_S_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_D_S_ENCODING = 0b01000010000000000000000001010011;\nconstexpr uint32_t FEQ_D_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FEQ_D_ENCODING = 0b10100010000000000010000001010011;\nconstexpr uint32_t FLT_D_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FLT_D_ENCODING = 0b10100010000000000001000001010011;\nconstexpr uint32_t FLE_D_MASK = 0b11111110000000000111000001111111;\nconstexpr uint32_t FLE_D_ENCODING = 0b10100010000000000000000001010011;\nconstexpr uint32_t FCLASS_D_MASK = 0b11111111111100000111000001111111;\nconstexpr uint32_t FCLASS_D_ENCODING = 0b11100010000000000001000001010011;\nconstexpr uint32_t FCVT_W_D_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_W_D_ENCODING = 0b11000010000000000000000001010011;\nconstexpr uint32_t FCVT_WU_D_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_WU_D_ENCODING = 0b11000010000100000000000001010011;\nconstexpr uint32_t FCVT_D_W_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_D_W_ENCODING = 0b11010010000000000000000001010011;\nconstexpr uint32_t FCVT_D_WU_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_D_WU_ENCODING = 0b11010010000100000000000001010011;\nconstexpr uint32_t FCVT_L_D_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_L_D_ENCODING = 0b11000010001000000000000001010011;\nconstexpr uint32_t FCVT_LU_D_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_LU_D_ENCODING = 0b11000010001100000000000001010011;\nconstexpr uint32_t FMV_X_D_MASK = 0b11111111111100000111000001111111;\nconstexpr uint32_t FMV_X_D_ENCODING = 0b11100010000000000000000001010011;\nconstexpr uint32_t FCVT_D_L_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_D_L_ENCODING = 0b11010010001000000000000001010011;\nconstexpr uint32_t FCVT_D_LU_MASK = 0b11111111111100000000000001111111;\nconstexpr uint32_t FCVT_D_LU_ENCODING = 0b11010010001100000000000001010011;\nconstexpr uint32_t FMV_D_X_MASK = 0b11111111111100000111000001111111;\nconstexpr uint32_t FMV_D_X_ENCODING = 0b11110010000000000000000001010011;\n\n#define MATCH_AND_RETURN_INSTR2(instr, result)                     \\\n\tif (unlikely((data() & (instr##_MASK)) != (instr##_ENCODING))) \\\n\t\treturn UNDEF;                                              \\\n\treturn result;\n\n#define MATCH_AND_RETURN_INSTR(instr) MATCH_AND_RETURN_INSTR2(instr, instr)\n\nnamespace Compressed {\nenum Opcode {\n\t// quadrant zero\n\tC_Illegal,\n\tC_Reserved,\n\tC_ADDI4SPN,\n\tC_FLD,\n\tC_LQ,  // RV128\n\tC_LW,\n\tC_FLW,\n\tC_LD,\n\n\tC_FSD,\n\tC_SQ,  // RV128\n\tC_SW,\n\tC_FSW,\n\tC_SD,\n\n\t// quadrant one\n\tC_NOP,\n\tC_ADDI,\n\tC_JAL,\n\tC_ADDIW,\n\tC_LI,\n\tC_ADDI16SP,\n\tC_LUI,\n\tC_SRLI,\n\tC_SRAI,\n\tC_ANDI,\n\tC_SUB,\n\tC_XOR,\n\tC_OR,\n\tC_AND,\n\tC_SUBW,\n\tC_ADDW,\n\tC_J,\n\tC_BEQZ,\n\tC_BNEZ,\n\n\t// quadrant two\n\tC_SLLI,\n\tC_FLDSP,\n\tC_LQSP,  // RV128\n\tC_LWSP,\n\tC_FLWSP,\n\tC_LDSP,\n\tC_JR,\n\tC_MV,\n\tC_EBREAK,\n\tC_JALR,\n\tC_ADD,\n\tC_FSDSP,\n\tC_SQSP,  // RV128\n\tC_SWSP,\n\tC_FSWSP,\n\tC_SDSP,\n};\n}\n\nstd::array<const char*, 32> Opcode::regnamePrettyStr = {\n\t\"zero\", \"ra\", \"sp\", \"gp\", \"tp\", \"t0\", \"t1\", \"t2\",\n\t\"s0/fp\", \"s1\", \"a0\", \"a1\", \"a2\", \"a3\", \"a4\", \"a5\",\n\t\"a6\", \"a7\", \"s2\", \"s3\", \"s4\", \"s5\", \"s6\", \"s7\",\n\t\"s8\", \"s9\", \"s10\", \"s11\", \"t3\", \"t4\", \"t5\", \"t6\"\n};\n\n/*\nPython snippet to generate the \"mappingStr\":\n\nfor e in [e.strip().replace(\",\", \"\") for e in s.strip().split(\"\\n\")]:\n    if \"//\" in e or len(e) == 0:\n        print(e)\n    else:\n        print('\"{}\",'.format(e))\n */\nstd::array<const char *, Opcode::NUMBER_OF_INSTRUCTIONS> Opcode::mappingStr = {\n    \"ZERO-INVALID\",\n\n    // RV32I base instruction set\n    \"LUI\",\n    \"AUIPC\",\n    \"JAL\",\n    \"JALR\",\n    \"BEQ\",\n    \"BNE\",\n    \"BLT\",\n    \"BGE\",\n    \"BLTU\",\n    \"BGEU\",\n    \"LB\",\n    \"LH\",\n    \"LW\",\n    \"LBU\",\n    \"LHU\",\n    \"SB\",\n    \"SH\",\n    \"SW\",\n    \"ADDI\",\n    \"SLTI\",\n    \"SLTIU\",\n    \"XORI\",\n    \"ORI\",\n    \"ANDI\",\n    \"SLLI\",\n    \"SRLI\",\n    \"SRAI\",\n    \"ADD\",\n    \"SUB\",\n    \"SLL\",\n    \"SLT\",\n    \"SLTU\",\n    \"XOR\",\n    \"SRL\",\n    \"SRA\",\n    \"OR\",\n    \"AND\",\n    \"FENCE\",\n    \"ECALL\",\n    \"EBREAK\",\n\n    // Zifencei standard extension\n    \"FENCE_I\",\n\n    // Zicsr standard extension\n    \"CSRRW\",\n    \"CSRRS\",\n    \"CSRRC\",\n    \"CSRRWI\",\n    \"CSRRSI\",\n    \"CSRRCI\",\n\n    // RV32M Standard Extension\n    \"MUL\",\n    \"MULH\",\n    \"MULHSU\",\n    \"MULHU\",\n    \"DIV\",\n    \"DIVU\",\n    \"REM\",\n    \"REMU\",\n\n    // RV32A Standard Extension\n    \"LR_W\",\n    \"SC_W\",\n    \"AMOSWAP_W\",\n    \"AMOADD_W\",\n    \"AMOXOR_W\",\n    \"AMOAND_W\",\n    \"AMOOR_W\",\n    \"AMOMIN_W\",\n    \"AMOMAX_W\",\n    \"AMOMINU_W\",\n    \"AMOMAXU_W\",\n\n    // RV64I base integer set (addition to RV32I)\n    \"LWU\",\n    \"LD\",\n    \"SD\",\n    \"ADDIW\",\n    \"SLLIW\",\n    \"SRLIW\",\n    \"SRAIW\",\n    \"ADDW\",\n    \"SUBW\",\n    \"SLLW\",\n    \"SRLW\",\n    \"SRAW\",\n\n    // RV64M standard extension (addition to RV32M)\n    \"MULW\",\n    \"DIVW\",\n    \"DIVUW\",\n    \"REMW\",\n    \"REMUW\",\n\n    // RV64A standard extension (addition to RV32A)\n    \"LR_D\",\n    \"SC_D\",\n    \"AMOSWAP_D\",\n    \"AMOADD_D\",\n    \"AMOXOR_D\",\n    \"AMOAND_D\",\n    \"AMOOR_D\",\n    \"AMOMIN_D\",\n    \"AMOMAX_D\",\n    \"AMOMINU_D\",\n    \"AMOMAXU_D\",\n\n    // RV32F standard extension\n    \"FLW\",\n    \"FSW\",\n    \"FMADD_S\",\n    \"FMSUB_S\",\n    \"FNMADD_S\",\n    \"FNMSUB_S\",\n    \"FADD_S\",\n    \"FSUB_S\",\n    \"FMUL_S\",\n    \"FDIV_S\",\n    \"FSQRT_S\",\n    \"FSGNJ_S\",\n    \"FSGNJN_S\",\n    \"FSGNJX_S\",\n    \"FMIN_S\",\n    \"FMAX_S\",\n    \"FCVT_W_S\",\n    \"FCVT_WU_S\",\n    \"FMV_X_W\",\n    \"FEQ_S\",\n    \"FLT_S\",\n    \"FLE_S\",\n    \"FCLASS_S\",\n    \"FCVT_S_W\",\n    \"FCVT_S_WU\",\n    \"FMV_W_X\",\n\n    // RV64F standard extension (addition to RV32F)\n    \"FCVT_L_S\",\n    \"FCVT_LU_S\",\n    \"FCVT_S_L\",\n    \"FCVT_S_LU\",\n\n    // RV32D standard extension\n    \"FLD\",\n    \"FSD\",\n    \"FMADD_D\",\n    \"FMSUB_D\",\n    \"FNMSUB_D\",\n    \"FNMADD_D\",\n    \"FADD_D\",\n    \"FSUB_D\",\n    \"FMUL_D\",\n    \"FDIV_D\",\n    \"FSQRT_D\",\n    \"FSGNJ_D\",\n    \"FSGNJN_D\",\n    \"FSGNJX_D\",\n    \"FMIN_D\",\n    \"FMAX_D\",\n    \"FCVT_S_D\",\n    \"FCVT_D_S\",\n    \"FEQ_D\",\n    \"FLT_D\",\n    \"FLE_D\",\n    \"FCLASS_D\",\n    \"FCVT_W_D\",\n    \"FCVT_WU_D\",\n    \"FCVT_D_W\",\n    \"FCVT_D_WU\",\n\n    // RV64D standard extension (addition to RV32D)\n    \"FCVT_L_D\",\n    \"FCVT_LU_D\",\n    \"FMV_X_D\",\n    \"FCVT_D_L\",\n    \"FCVT_D_LU\",\n    \"FMV_D_X\",\n\n    // privileged instructions\n    \"URET\",\n    \"SRET\",\n    \"MRET\",\n    \"WFI\",\n    \"SFENCE_VMA\",\n};\n\nOpcode::Type Opcode::getType(Opcode::Mapping mapping) {\n\tswitch (mapping) {\n\t\tcase SLLI:\n\t\tcase SRLI:\n\t\tcase SRAI:\n\t\tcase ADD:\n\t\tcase SUB:\n\t\tcase SLL:\n\t\tcase SLT:\n\t\tcase SLTU:\n\t\tcase XOR:\n\t\tcase SRL:\n\t\tcase SRA:\n\t\tcase OR:\n\t\tcase AND:\n\t\tcase MUL:\n\t\tcase MULH:\n\t\tcase MULHSU:\n\t\tcase MULHU:\n\t\tcase DIV:\n\t\tcase DIVU:\n\t\tcase REM:\n\t\tcase REMU:\n\t\tcase ADDW:\n\t\tcase SUBW:\n\t\tcase SLLW:\n\t\tcase SRLW:\n\t\tcase SRAW:\n\t\tcase MULW:\n\t\tcase DIVW:\n\t\tcase DIVUW:\n\t\tcase REMW:\n\t\tcase REMUW:\n\t\tcase LR_W:\n\t\tcase SC_W:\n\t\tcase AMOSWAP_W:\n\t\tcase AMOADD_W:\n\t\tcase AMOXOR_W:\n\t\tcase AMOAND_W:\n\t\tcase AMOOR_W:\n\t\tcase AMOMIN_W:\n\t\tcase AMOMAX_W:\n\t\tcase AMOMINU_W:\n\t\tcase AMOMAXU_W:\n\t\tcase LR_D:\n\t\tcase SC_D:\n\t\tcase AMOSWAP_D:\n\t\tcase AMOADD_D:\n\t\tcase AMOXOR_D:\n\t\tcase AMOAND_D:\n\t\tcase AMOOR_D:\n\t\tcase AMOMIN_D:\n\t\tcase AMOMAX_D:\n\t\tcase AMOMINU_D:\n\t\tcase AMOMAXU_D:\n\t\tcase FADD_S:\n\t\tcase FSUB_S:\n\t\tcase FMUL_S:\n\t\tcase FDIV_S:\n\t\tcase FSQRT_S:\n\t\tcase FSGNJ_S:\n\t\tcase FSGNJN_S:\n\t\tcase FSGNJX_S:\n\t\tcase FMIN_S:\n\t\tcase FMAX_S:\n\t\tcase FCVT_W_S:\n\t\tcase FCVT_WU_S:\n\t\tcase FMV_X_W:\n\t\tcase FEQ_S:\n\t\tcase FLT_S:\n\t\tcase FLE_S:\n\t\tcase FCLASS_S:\n\t\tcase FCVT_S_W:\n\t\tcase FCVT_S_WU:\n\t\tcase FMV_W_X:\n\t\tcase FCVT_L_S:\n\t\tcase FCVT_LU_S:\n\t\tcase FCVT_S_L:\n\t\tcase FCVT_S_LU:\n\t\tcase FADD_D:\n\t\tcase FSUB_D:\n\t\tcase FMUL_D:\n\t\tcase FDIV_D:\n\t\tcase FSQRT_D:\n\t\tcase FSGNJ_D:\n\t\tcase FSGNJN_D:\n\t\tcase FSGNJX_D:\n\t\tcase FMIN_D:\n\t\tcase FMAX_D:\n\t\tcase FCVT_S_D:\n\t\tcase FCVT_D_S:\n\t\tcase FEQ_D:\n\t\tcase FLT_D:\n\t\tcase FLE_D:\n\t\tcase FCLASS_D:\n\t\tcase FCVT_W_D:\n\t\tcase FCVT_WU_D:\n\t\tcase FCVT_D_W:\n\t\tcase FCVT_D_WU:\n\t\tcase FCVT_L_D:\n\t\tcase FCVT_LU_D:\n\t\tcase FMV_X_D:\n\t\tcase FCVT_D_L:\n\t\tcase FCVT_D_LU:\n\t\tcase FMV_D_X:\n\t\t\treturn Type::R;\n\t\tcase JALR:\n\t\tcase LB:\n\t\tcase LH:\n\t\tcase LW:\n\t\tcase LD:\n\t\tcase LBU:\n\t\tcase LHU:\n\t\tcase LWU:\n\t\tcase ADDI:\n\t\tcase SLTI:\n\t\tcase SLTIU:\n\t\tcase XORI:\n\t\tcase ORI:\n\t\tcase ANDI:\n\t\tcase ADDIW:\n\t\tcase SLLIW:\n\t\tcase SRLIW:\n\t\tcase SRAIW:\n\t\tcase FLW:\n\t\tcase FLD:\n\t\t\treturn Type::I;\n\t\tcase SB:\n\t\tcase SH:\n\t\tcase SW:\n\t\tcase SD:\n\t\tcase FSW:\n\t\tcase FSD:\n\t\t\treturn Type::S;\n\t\tcase BEQ:\n\t\tcase BNE:\n\t\tcase BLT:\n\t\tcase BGE:\n\t\tcase BLTU:\n\t\tcase BGEU:\n\t\t\treturn Type::B;\n\t\tcase LUI:\n\t\tcase AUIPC:\n\t\t\treturn Type::U;\n\t\tcase JAL:\n\t\t\treturn Type::J;\n\t\tcase FMADD_S:\n\t\tcase FMSUB_S:\n\t\tcase FNMSUB_S:\n\t\tcase FNMADD_S:\n\t\tcase FMADD_D:\n\t\tcase FMSUB_D:\n\t\tcase FNMSUB_D:\n\t\tcase FNMADD_D:\n\t\t\treturn Type::R4;\n\n\t\tdefault:\n\t\t\treturn Type::UNKNOWN;\n\t}\n}\n\nunsigned C_ADDI4SPN_NZUIMM(uint32_t n) {\n\treturn (BIT_SLICE(n, 12, 11) << 4) | (BIT_SLICE(n, 10, 7) << 6) | (BIT_SINGLE_P1(n, 6) << 2) |\n\t       (BIT_SINGLE_P1(n, 5) << 3);\n}\n\nunsigned C_LW_UIMM(uint32_t n) {\n\treturn (BIT_SLICE(n, 12, 10) << 3) | (BIT_SINGLE_P1(n, 6) << 2) | (BIT_SINGLE_P1(n, 5) << 6);\n}\n\nunsigned C_LD_UIMM(uint32_t n) {\n\treturn (BIT_SLICE(n, 12, 10) << 3) | (BIT_SLICE(n, 6, 5) << 6);\n}\n\nunsigned C_SW_UIMM(uint32_t n) {\n\treturn C_LW_UIMM(n);\n}\n\nunsigned C_SD_UIMM(uint32_t n) {\n\treturn C_LD_UIMM(n);\n}\n\nint32_t C_JAL_IMM(int32_t n) {\n\treturn EXTRACT_SIGN_BIT(n, 12, 11) | BIT_SINGLE_PN(n, 11, 4) | (BIT_SLICE(n, 10, 9) << 8) |\n\t       BIT_SINGLE_PN(n, 8, 10) | BIT_SINGLE_PN(n, 7, 6) | BIT_SINGLE_PN(n, 6, 7) | (BIT_SLICE(n, 5, 3) << 1) |\n\t       BIT_SINGLE_PN(n, 2, 5);\n}\n\nint32_t C_ADDI16SP_NZIMM(int32_t n) {\n\treturn EXTRACT_SIGN_BIT(n, 12, 9) | BIT_SINGLE_PN(n, 6, 4) | BIT_SINGLE_PN(n, 5, 6) | (BIT_SLICE(n, 4, 3) << 7) |\n\t       BIT_SINGLE_PN(n, 2, 5);\n}\n\nint32_t C_LUI_NZIMM(int32_t n) {\n\treturn EXTRACT_SIGN_BIT(n, 12, 17) | (BIT_SLICE(n, 6, 2) << 12);\n}\n\nint32_t C_J_IMM(int32_t n) {\n\treturn C_JAL_IMM(n);\n}\n\nint32_t C_BRANCH_IMM(int32_t n) {\n\treturn EXTRACT_SIGN_BIT(n, 12, 8) | (BIT_SLICE(n, 11, 10) << 3) | (BIT_SLICE(n, 6, 5) << 6) |\n\t       (BIT_SLICE(n, 4, 3) << 1) | BIT_SINGLE_PN(n, 2, 5);\n}\n\nuint32_t C_LWSP_UIMM(uint32_t n) {\n\treturn BIT_SINGLE_PN(n, 12, 5) | (BIT_SLICE(n, 6, 4) << 2) | (BIT_SLICE(n, 3, 2) << 6);\n}\n\nuint32_t C_SWSP_UIMM(uint32_t n) {\n\treturn (BIT_SLICE(n, 12, 9) << 2) | (BIT_SLICE(n, 8, 7) << 6);\n}\n\nuint32_t C_LDSP_UIMM(uint32_t n) {\n\treturn BIT_SINGLE_PN(n, 12, 5) | (BIT_SLICE(n, 6, 5) << 3) | (BIT_SLICE(n, 4, 2) << 6);\n}\n\nuint32_t C_SDSP_UIMM(uint32_t n) {\n\treturn (BIT_SLICE(n, 12, 10) << 3) | (BIT_SLICE(n, 9, 7) << 6);\n}\n\nstruct InstructionFactory {\n\ttypedef Instruction T;\n\n\tstatic T ADD(unsigned rd, unsigned rs1, unsigned rs2) {\n\t\treturn T(((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | ((rs2 & 0x1f) << 20) | 51 | (0 << 12) | (0 << 25));\n\t}\n\n\tstatic T AND(unsigned rd, unsigned rs1, unsigned rs2) {\n\t\treturn T(((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | ((rs2 & 0x1f) << 20) | 51 | (7 << 12) | (0 << 25));\n\t}\n\n\tstatic T OR(unsigned rd, unsigned rs1, unsigned rs2) {\n\t\treturn T(((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | ((rs2 & 0x1f) << 20) | 51 | (6 << 12) | (0 << 25));\n\t}\n\n\tstatic T XOR(unsigned rd, unsigned rs1, unsigned rs2) {\n\t\treturn T(((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | ((rs2 & 0x1f) << 20) | 51 | (4 << 12) | (0 << 25));\n\t}\n\n\tstatic T SUB(unsigned rd, unsigned rs1, unsigned rs2) {\n\t\treturn T(((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | ((rs2 & 0x1f) << 20) | 51 | (0 << 12) | (32 << 25));\n\t}\n\n\tstatic T LW(unsigned rd, unsigned rs1, int I_imm) {\n\t\treturn T(((I_imm & 4095) << 20) | ((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | 3 | (2 << 12));\n\t}\n\n\tstatic T LD(unsigned rd, unsigned rs1, int I_imm) {\n\t\treturn T(((I_imm & 4095) << 20) | ((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | 3 | (3 << 12));\n\t}\n\n\tstatic T FLW(unsigned rd, unsigned rs1, int I_imm) {\n\t\treturn T(((I_imm & 4095) << 20) | ((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | 7 | (2 << 12));\n\t}\n\n\tstatic T FLD(unsigned rd, unsigned rs1, int I_imm) {\n\t\treturn T(((I_imm & 4095) << 20) | ((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | 7 | (3 << 12));\n\t}\n\n\tstatic T SW(unsigned rs1, unsigned rs2, int S_imm) {\n\t\treturn T((((S_imm & 0b11111) << 7) | ((S_imm & (0b1111111 << 5)) << 20)) | ((rs1 & 0x1f) << 15) |\n\t\t         ((rs2 & 0x1f) << 20) | 35 | (2 << 12));\n\t}\n\n\tstatic T SD(unsigned rs1, unsigned rs2, int S_imm) {\n\t\treturn T((((S_imm & 0b11111) << 7) | ((S_imm & (0b1111111 << 5)) << 20)) | ((rs1 & 0x1f) << 15) |\n\t\t         ((rs2 & 0x1f) << 20) | 35 | (3 << 12));\n\t}\n\n\tstatic T FSW(unsigned rs1, unsigned rs2, int S_imm) {\n\t\treturn T((((S_imm & 0b11111) << 7) | ((S_imm & (0b1111111 << 5)) << 20)) | ((rs1 & 0x1f) << 15) |\n\t\t         ((rs2 & 0x1f) << 20) | 39 | (2 << 12));\n\t}\n\n\tstatic T FSD(unsigned rs1, unsigned rs2, int S_imm) {\n\t\treturn T((((S_imm & 0b11111) << 7) | ((S_imm & (0b1111111 << 5)) << 20)) | ((rs1 & 0x1f) << 15) |\n\t\t         ((rs2 & 0x1f) << 20) | 39 | (3 << 12));\n\t}\n\n\tstatic T LUI(unsigned rd, int U_imm) {\n\t\treturn T((U_imm & (1048575 << 12)) | ((rd & 0x1f) << 7) | 55);\n\t}\n\n\tstatic T ADDI(unsigned rd, unsigned rs1, int I_imm) {\n\t\treturn T(((I_imm & 4095) << 20) | ((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | 19 | (0 << 12));\n\t}\n\n\tstatic T ANDI(unsigned rd, unsigned rs1, int I_imm) {\n\t\treturn T(((I_imm & 4095) << 20) | ((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | 19 | (7 << 12));\n\t}\n\n\tstatic T SRLI(unsigned rd, unsigned rs1, unsigned shamt) {\n\t\treturn T(((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | ((shamt & 63) << 20) | 19 | (5 << 12) | (0 << 25));\n\t}\n\n\tstatic T SRAI(unsigned rd, unsigned rs1, unsigned shamt) {\n\t\treturn T(((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | ((shamt & 63) << 20) | 19 | (5 << 12) | (32 << 25));\n\t}\n\n\tstatic T SLLI(unsigned rd, unsigned rs1, unsigned shamt) {\n\t\treturn T(((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | ((shamt & 63) << 20) | 19 | (1 << 12) | (0 << 25));\n\t}\n\n\tstatic T JAL(unsigned rd, int J_imm) {\n\t\treturn T(111 | ((rd & 0x1f) << 7) |\n\t\t         ((J_imm & (0b11111111 << 12)) | ((J_imm & (1 << 11)) << 9) | ((J_imm & 0b11111111110) << 20) |\n\t\t          ((J_imm & (1 << 20)) << 11)));\n\t}\n\n\tstatic T JALR(unsigned rd, unsigned rs1, int I_imm) {\n\t\treturn T(((I_imm & 4095) << 20) | ((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | 103 | (0 << 12));\n\t}\n\n\tstatic T BEQ(unsigned rs1, unsigned rs2, int B_imm) {\n\t\treturn T(((((B_imm & 0b11110) << 7) | ((B_imm & (1 << 11)) >> 4)) |\n\t\t          (((B_imm & (0b111111 << 5)) << 20) | ((B_imm & (1 << 12)) << 19))) |\n\t\t         ((rs1 & 0x1f) << 15) | ((rs2 & 0x1f) << 20) | 99 | (0 << 12));\n\t}\n\n\tstatic T BNE(unsigned rs1, unsigned rs2, int B_imm) {\n\t\treturn T(((((B_imm & 0b11110) << 7) | ((B_imm & (1 << 11)) >> 4)) |\n\t\t          (((B_imm & (0b111111 << 5)) << 20) | ((B_imm & (1 << 12)) << 19))) |\n\t\t         ((rs1 & 0x1f) << 15) | ((rs2 & 0x1f) << 20) | 99 | (1 << 12));\n\t}\n\n\tstatic T EBREAK() {\n\t\treturn T(1048691);\n\t}\n\n\tstatic T ADDIW(unsigned rd, unsigned rs1, int I_imm) {\n\t\treturn T(((I_imm & 4095) << 20) | ((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | 0x1b);\n\t}\n\n\tstatic T ADDW(unsigned rd, unsigned rs1, unsigned rs2) {\n\t\treturn T(((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | ((rs2 & 0x1f) << 20) | 0x3b);\n\t}\n\n\tstatic T SUBW(unsigned rd, unsigned rs1, unsigned rs2) {\n\t\treturn T(((rd & 0x1f) << 7) | ((rs1 & 0x1f) << 15) | ((rs2 & 0x1f) << 20) | 0x3b | 0x40000000);\n\t}\n};\n\nCompressed::Opcode decode_compressed(Instruction &instr, Architecture arch) {\n\tusing namespace Compressed;\n\n\tswitch (instr.quadrant()) {\n\t\tcase 0:\n\t\t\tswitch (instr.c_opcode()) {\n\t\t\t\tcase 0b000:\n\t\t\t\t\tif (instr.c_format() == 0)\n\t\t\t\t\t\treturn C_Illegal;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn C_ADDI4SPN;\n\n\t\t\t\tcase 0b001:\n\t\t\t\t\treturn C_FLD;\n\n\t\t\t\tcase 0b010:\n\t\t\t\t\treturn C_LW;\n\n\t\t\t\tcase 0b011:\n\t\t\t\t\tif (arch == RV32)\n\t\t\t\t\t\treturn C_FLW;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn C_LD;\n\n\t\t\t\tcase 0b100:\n\t\t\t\t\treturn C_Reserved;\n\n\t\t\t\tcase 0b101:\n\t\t\t\t\treturn C_FSD;\n\n\t\t\t\tcase 0b110:\n\t\t\t\t\treturn C_SW;\n\n\t\t\t\tcase 0b111:\n\t\t\t\t\tif (arch == RV32)\n\t\t\t\t\t\treturn C_FSW;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn C_SD;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 1:\n\t\t\tswitch (instr.c_opcode()) {\n\t\t\t\tcase 0b000:\n\t\t\t\t\tif (instr.c_format() == 1)\n\t\t\t\t\t\treturn C_NOP;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn C_ADDI;\n\n\t\t\t\tcase 0b001:\n\t\t\t\t\tif (arch == RV32)\n\t\t\t\t\t\treturn C_JAL;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn C_ADDIW;\n\n\t\t\t\tcase 0b010:\n\t\t\t\t\treturn C_LI;\n\n\t\t\t\tcase 0b011:\n\t\t\t\t\tif (instr.c_rd() == 2)\n\t\t\t\t\t\treturn C_ADDI16SP;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn C_LUI;\n\n\t\t\t\tcase 0b100:\n\t\t\t\t\tswitch (instr.c_f2_high()) {\n\t\t\t\t\t\tcase 0b00:\n\t\t\t\t\t\t\treturn C_SRLI;\n\n\t\t\t\t\t\tcase 0b01:\n\t\t\t\t\t\t\treturn C_SRAI;\n\n\t\t\t\t\t\tcase 0b10:\n\t\t\t\t\t\t\treturn C_ANDI;\n\n\t\t\t\t\t\tcase 0b11:\n\t\t\t\t\t\t\tif (instr.c_b12()) {\n\t\t\t\t\t\t\t\tswitch (instr.c_f2_low()) {\n\t\t\t\t\t\t\t\t\tcase 0b00:\n\t\t\t\t\t\t\t\t\t\treturn C_SUBW;\n\t\t\t\t\t\t\t\t\tcase 0b01:\n\t\t\t\t\t\t\t\t\t\treturn C_ADDW;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn C_Reserved;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tswitch (instr.c_f2_low()) {\n\t\t\t\t\t\t\t\t\tcase 0b00:\n\t\t\t\t\t\t\t\t\t\treturn C_SUB;\n\t\t\t\t\t\t\t\t\tcase 0b01:\n\t\t\t\t\t\t\t\t\t\treturn C_XOR;\n\t\t\t\t\t\t\t\t\tcase 0b10:\n\t\t\t\t\t\t\t\t\t\treturn C_OR;\n\t\t\t\t\t\t\t\t\tcase 0b11:\n\t\t\t\t\t\t\t\t\t\treturn C_AND;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 0b101:\n\t\t\t\t\treturn C_J;\n\n\t\t\t\tcase 0b110:\n\t\t\t\t\treturn C_BEQZ;\n\n\t\t\t\tcase 0b111:\n\t\t\t\t\treturn C_BNEZ;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 2:\n\t\t\tswitch (instr.c_opcode()) {\n\t\t\t\tcase 0b000:\n\t\t\t\t\treturn C_SLLI;\n\n\t\t\t\tcase 0b001:\n\t\t\t\t\treturn C_FLDSP;\n\n\t\t\t\tcase 0b010:\n\t\t\t\t\treturn C_LWSP;\n\n\t\t\t\tcase 0b011:\n\t\t\t\t\tif (arch == RV32)\n\t\t\t\t\t\treturn C_FLWSP;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn C_LDSP;\n\n\t\t\t\tcase 0b100:\n\t\t\t\t\tif (instr.c_b12()) {\n\t\t\t\t\t\tif (instr.c_rd()) {\n\t\t\t\t\t\t\tif (instr.c_rs2()) {\n\t\t\t\t\t\t\t\treturn C_ADD;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn C_JALR;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn C_EBREAK;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (instr.c_rs2()) {\n\t\t\t\t\t\t\treturn C_MV;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn C_JR;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase 0b101:\n\t\t\t\t\treturn C_FSDSP;\n\n\t\t\t\tcase 0b110:\n\t\t\t\t\treturn C_SWSP;\n\n\t\t\t\tcase 0b111:\n\t\t\t\t\tif (arch == RV32)\n\t\t\t\t\t\treturn C_FSWSP;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn C_SDSP;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 3:\n\t\t\tthrow std::runtime_error(\"compressed instruction expected, but uncompressed found\");\n\t}\n\n\t// undefined/unsupported instruction\n\treturn C_Illegal;\n}\n\nOpcode::Mapping expand_compressed(Instruction &instr, Compressed::Opcode op, Architecture arch) {\n\tusing namespace Opcode;\n\tusing namespace Compressed;\n\n\tswitch (op) {\n\t\tcase C_Illegal:\n\t\t\treturn UNDEF;\n\n\t\t// RV128 currently not supported\n\t\tcase C_LQ:\n\t\tcase C_LQSP:\n\t\tcase C_SQ:\n\t\tcase C_SQSP:\n\t\t\treturn UNDEF;\n\n\t\tcase C_Reserved:\n\t\t    return UNDEF;   // reserved instructions should raise an illegal instruction exception\n\n\t\tcase C_NOP:\n\t\t\tinstr = InstructionFactory::ADD(0, 0, 0);\n\t\t\treturn ADD;\n\n\t\tcase C_ADD:\n\t\t\tinstr = InstructionFactory::ADD(instr.c_rd(), instr.c_rd(), instr.c_rs2());\n\t\t\treturn ADD;\n\n\t\tcase C_MV:\n\t\t\tinstr = InstructionFactory::ADD(instr.c_rd(), 0, instr.c_rs2());\n\t\t\treturn ADD;\n\n\t\tcase C_AND:\n\t\t\tinstr = InstructionFactory::AND(instr.c_rd_small(), instr.c_rd_small(), instr.c_rs2_small());\n\t\t\treturn AND;\n\n\t\tcase C_OR:\n\t\t\tinstr = InstructionFactory::OR(instr.c_rd_small(), instr.c_rd_small(), instr.c_rs2_small());\n\t\t\treturn OR;\n\n\t\tcase C_XOR:\n\t\t\tinstr = InstructionFactory::XOR(instr.c_rd_small(), instr.c_rd_small(), instr.c_rs2_small());\n\t\t\treturn XOR;\n\n\t\tcase C_SUB:\n\t\t\tinstr = InstructionFactory::SUB(instr.c_rd_small(), instr.c_rd_small(), instr.c_rs2_small());\n\t\t\treturn SUB;\n\n\t\tcase C_ADDW:\n\t\t\tinstr = InstructionFactory::ADDW(instr.c_rd_small(), instr.c_rd_small(), instr.c_rs2_small());\n\t\t\treturn ADDW;\n\n\t\tcase C_SUBW:\n\t\t\tinstr = InstructionFactory::SUBW(instr.c_rd_small(), instr.c_rd_small(), instr.c_rs2_small());\n\t\t\treturn SUBW;\n\n\t\tcase C_LW:\n\t\t\tinstr = InstructionFactory::LW(instr.c_rs2_small(), instr.c_rd_small(), C_LW_UIMM(instr.data()));\n\t\t\treturn LW;\n\n\t\tcase C_LD:\n\t\t\tinstr = InstructionFactory::LD(instr.c_rs2_small(), instr.c_rd_small(), C_LD_UIMM(instr.data()));\n\t\t\treturn LD;\n\n\t\tcase C_FLW:\n\t\t\tinstr = InstructionFactory::FLW(instr.c_rs2_small(), instr.c_rd_small(), C_LW_UIMM(instr.data()));\n\t\t\treturn FLW;\n\n\t\tcase C_FLD:\n\t\t\tinstr = InstructionFactory::FLD(instr.c_rs2_small(), instr.c_rd_small(), C_LD_UIMM(instr.data()));\n\t\t\treturn FLD;\n\n\t\tcase C_SW:\n\t\t\tinstr = InstructionFactory::SW(instr.c_rd_small(), instr.c_rs2_small(), C_SW_UIMM(instr.data()));\n\t\t\treturn SW;\n\n\t\tcase C_SD:\n\t\t\tinstr = InstructionFactory::SD(instr.c_rd_small(), instr.c_rs2_small(), C_SD_UIMM(instr.data()));\n\t\t\treturn SD;\n\n\t\tcase C_FSW:\n\t\t\tinstr = InstructionFactory::FSW(instr.c_rd_small(), instr.c_rs2_small(), C_SW_UIMM(instr.data()));\n\t\t\treturn FSW;\n\n\t\tcase C_FSD:\n\t\t\tinstr = InstructionFactory::FSD(instr.c_rd_small(), instr.c_rs2_small(), C_SD_UIMM(instr.data()));\n\t\t\treturn FSD;\n\n\t\tcase C_ADDI4SPN: {\n\t\t\tunsigned n = C_ADDI4SPN_NZUIMM(instr.data());\n\t\t\tif (n == 0)\n\t\t\t\treturn UNDEF;\n\t\t\tinstr = InstructionFactory::ADDI(instr.c_rs2_small(), 2, n);\n\t\t\treturn ADDI;\n\t\t}\n\n\t\tcase C_ADDI:\n\t\t\tinstr = InstructionFactory::ADDI(instr.c_rd(), instr.c_rd(), instr.c_imm());\n\t\t\treturn ADDI;\n\n\t\tcase C_JAL:\n\t\t\tinstr = InstructionFactory::JAL(1, C_JAL_IMM(instr.data()));\n\t\t\treturn JAL;\n\n\t\tcase C_ADDIW:\n            if (instr.c_rd() == 0)\n                return UNDEF;\t// reserved\n\t\t\tinstr = InstructionFactory::ADDI(instr.c_rd(), instr.c_rd(), instr.c_imm());\n\t\t\treturn ADDIW;\n\n\t\tcase C_LI:\n\t\t\tinstr = InstructionFactory::ADDI(instr.c_rd(), 0, instr.c_imm());\n\t\t\treturn ADDI;\n\n\t\tcase C_ADDI16SP: {\n\t\t\tauto n = C_ADDI16SP_NZIMM(instr.data());\n            if (n == 0)\n                return UNDEF;\t// reserved\n\t\t\tinstr = InstructionFactory::ADDI(2, 2, n);\n\t\t\treturn ADDI;\n\t\t}\n\n\t\tcase C_LUI: {\n\t\t\tauto n = C_LUI_NZIMM(instr.data());\n            if (n == 0)\n                return UNDEF;\t// reserved\n\t\t\tinstr = InstructionFactory::LUI(instr.c_rd(), n);\n\t\t\treturn LUI;\n\t\t}\n\n\t\tcase C_SLLI: {\n\t\t\tauto n = instr.c_uimm();\n\t\t\tif (arch == RV32 && n > 31)\n\t\t\t\treturn UNDEF;\n\t\t\tinstr = InstructionFactory::SLLI(instr.c_rd(), instr.c_rd(), n);\n\t\t\treturn SLLI;\n\t\t}\n\n\t\tcase C_SRLI: {\n\t\t\tauto n = instr.c_uimm();\n\t\t\tif (arch == RV32 && n > 31)\n\t\t\t\treturn UNDEF;\n\t\t\tinstr = InstructionFactory::SRLI(instr.c_rd_small(), instr.c_rd_small(), n);\n\t\t\treturn SRLI;\n\t\t}\n\n\t\tcase C_SRAI: {\n\t\t\tauto n = instr.c_uimm();\n\t\t\tif (arch == RV32 && n > 31)\n\t\t\t\treturn UNDEF;\n\t\t\tinstr = InstructionFactory::SRAI(instr.c_rd_small(), instr.c_rd_small(), n);\n\t\t\treturn SRAI;\n\t\t}\n\n\t\tcase C_ANDI:\n\t\t\tinstr = InstructionFactory::ANDI(instr.c_rd_small(), instr.c_rd_small(), instr.c_imm());\n\t\t\treturn ANDI;\n\n\t\tcase C_J:\n\t\t\tinstr = InstructionFactory::JAL(0, C_J_IMM(instr.data()));\n\t\t\treturn JAL;\n\n\t\tcase C_BEQZ:\n\t\t\tinstr = InstructionFactory::BEQ(instr.c_rd_small(), 0, C_BRANCH_IMM(instr.data()));\n\t\t\treturn BEQ;\n\n\t\tcase C_BNEZ:\n\t\t\tinstr = InstructionFactory::BNE(instr.c_rd_small(), 0, C_BRANCH_IMM(instr.data()));\n\t\t\treturn BNE;\n\n\t\tcase C_LWSP:\n            if (instr.c_rd() == 0)\n                return UNDEF;\t// reserved\n\t\t\tinstr = InstructionFactory::LW(instr.c_rd(), 2, C_LWSP_UIMM(instr.data()));\n\t\t\treturn LW;\n\n\t\tcase C_LDSP:\n            if (instr.c_rd() == 0)\n                return UNDEF;\t// reserved\n\t\t\tinstr = InstructionFactory::LD(instr.c_rd(), 2, C_LDSP_UIMM(instr.data()));\n\t\t\treturn LD;\n\n\t\tcase C_FLWSP:\n\t\t\tinstr = InstructionFactory::FLW(instr.c_rd(), 2, C_LWSP_UIMM(instr.data()));\n\t\t\treturn FLW;\n\n\t\tcase C_FLDSP:\n\t\t\tinstr = InstructionFactory::FLD(instr.c_rd(), 2, C_LDSP_UIMM(instr.data()));\n\t\t\treturn FLD;\n\n\t\tcase C_SWSP:\n\t\t\tinstr = InstructionFactory::SW(2, instr.c_rs2(), C_SWSP_UIMM(instr.data()));\n\t\t\treturn SW;\n\n\t\tcase C_SDSP:\n\t\t\tinstr = InstructionFactory::SD(2, instr.c_rs2(), C_SDSP_UIMM(instr.data()));\n\t\t\treturn SD;\n\n\t\tcase C_FSWSP:\n\t\t\tinstr = InstructionFactory::FSW(2, instr.c_rs2(), C_SWSP_UIMM(instr.data()));\n\t\t\treturn FSW;\n\n\t\tcase C_FSDSP:\n\t\t\tinstr = InstructionFactory::FSD(2, instr.c_rs2(), C_SDSP_UIMM(instr.data()));\n\t\t\treturn FSD;\n\n\t\tcase C_EBREAK:\n\t\t\tinstr = InstructionFactory::EBREAK();\n\t\t\treturn EBREAK;\n\n\t\tcase C_JR:\n            if (instr.c_rd() == 0)\n                return UNDEF;\t// reserved\n\t\t\tinstr = InstructionFactory::JALR(0, instr.c_rd(), 0);\n\t\t\treturn JALR;\n\n\t\tcase C_JALR:\n\t\t\tinstr = InstructionFactory::JALR(1, instr.c_rd(), 0);\n\t\t\treturn JALR;\n\t}\n\n\tthrow std::runtime_error(\"some compressed instruction not handled\");\n}\n\nOpcode::Mapping Instruction::decode_and_expand_compressed(Architecture arch) {\n\tauto c_op = decode_compressed(*this, arch);\n\treturn expand_compressed(*this, c_op, arch);\n}\n\nOpcode::Mapping Instruction::decode_normal(Architecture arch) {\n\tusing namespace Opcode;\n\n\tInstruction &instr = *this;\n\n\tswitch (instr.opcode()) {\n\t\tcase OP_LUI:\n\t\t\tMATCH_AND_RETURN_INSTR(LUI);\n\n\t\tcase OP_AUIPC:\n\t\t\tMATCH_AND_RETURN_INSTR(AUIPC);\n\n\t\tcase OP_JAL:\n\t\t\tMATCH_AND_RETURN_INSTR(JAL);\n\n\t\tcase OP_JALR: {\n\t\t\tMATCH_AND_RETURN_INSTR(JALR);\n\t\t}\n\n\t\tcase OP_BEQ: {\n\t\t\tswitch (instr.funct3()) {\n\t\t\t\tcase F3_BEQ:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(BEQ);\n\t\t\t\tcase F3_BNE:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(BNE);\n\t\t\t\tcase F3_BLT:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(BLT);\n\t\t\t\tcase F3_BGE:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(BGE);\n\t\t\t\tcase F3_BLTU:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(BLTU);\n\t\t\t\tcase F3_BGEU:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(BGEU);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase OP_LB: {\n\t\t\tswitch (instr.funct3()) {\n\t\t\t\tcase F3_LB:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(LB);\n\t\t\t\tcase F3_LH:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(LH);\n\t\t\t\tcase F3_LW:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(LW);\n\t\t\t\tcase F3_LBU:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(LBU);\n\t\t\t\tcase F3_LHU:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(LHU);\n\t\t\t\tcase F3_LWU:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(LWU);\n\t\t\t\tcase F3_LD:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(LD);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase OP_SB: {\n\t\t\tswitch (instr.funct3()) {\n\t\t\t\tcase F3_SB:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(SB);\n\t\t\t\tcase F3_SH:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(SH);\n\t\t\t\tcase F3_SW:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(SW);\n\t\t\t\tcase F3_SD:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(SD);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase OP_ADDI: {\n\t\t\tswitch (instr.funct3()) {\n\t\t\t\tcase F3_ADDI:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(ADDI);\n\t\t\t\tcase F3_SLTI:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(SLTI);\n\t\t\t\tcase F3_SLTIU:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(SLTIU);\n\t\t\t\tcase F3_XORI:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(XORI);\n\t\t\t\tcase F3_ORI:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(ORI);\n\t\t\t\tcase F3_ANDI:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(ANDI);\n\t\t\t\tcase F3_SLLI:\n\t\t\t\t\tif (arch == RV32) {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR2(SLLI_32, SLLI);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SLLI);\n\t\t\t\t\t}\n\t\t\t\tcase F3_SRLI: {\n\t\t\t\t\tswitch (instr.funct6()) {\n\t\t\t\t\t\tcase F6_SRLI:\n\t\t\t\t\t\t\tif (arch == RV32) {\n\t\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR2(SRLI_32, SRLI);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SRLI);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\tcase F6_SRAI:\n\t\t\t\t\t\t\tif (arch == RV32) {\n\t\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR2(SRAI_32, SRAI);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SRAI);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase OP_ADDIW: {\n\t\t\tswitch (instr.funct3()) {\n\t\t\t\tcase F3_ADDIW:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(ADDIW);\n\t\t\t\tcase F3_SLLIW:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(SLLIW);\n\t\t\t\tcase F3_SRLIW: {\n\t\t\t\t\tswitch (instr.funct7()) {\n\t\t\t\t\t\tcase F7_SRLIW:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SRLIW);\n\t\t\t\t\t\tcase F7_SRAIW:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SRAIW);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase OP_ADD: {\n\t\t\tswitch (instr.funct7()) {\n\t\t\t\tcase F7_ADD:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_ADD:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(ADD);\n\t\t\t\t\t\tcase F3_SLL:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SLL);\n\t\t\t\t\t\tcase F3_SLT:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SLT);\n\t\t\t\t\t\tcase F3_SLTU:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SLTU);\n\t\t\t\t\t\tcase F3_XOR:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(XOR);\n\t\t\t\t\t\tcase F3_SRL:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SRL);\n\t\t\t\t\t\tcase F3_OR:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(OR);\n\t\t\t\t\t\tcase F3_AND:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AND);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase F7_SUB:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_SUB:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SUB);\n\t\t\t\t\t\tcase F3_SRA:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SRA);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase F7_MUL:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_MUL:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(MUL);\n\t\t\t\t\t\tcase F3_MULH:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(MULH);\n\t\t\t\t\t\tcase F3_MULHSU:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(MULHSU);\n\t\t\t\t\t\tcase F3_MULHU:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(MULHU);\n\t\t\t\t\t\tcase F3_DIV:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(DIV);\n\t\t\t\t\t\tcase F3_DIVU:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(DIVU);\n\t\t\t\t\t\tcase F3_REM:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(REM);\n\t\t\t\t\t\tcase F3_REMU:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(REMU);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase OP_ADDW: {\n\t\t\tswitch (instr.funct7()) {\n\t\t\t\tcase F7_ADDW:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_ADDW:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(ADDW);\n\t\t\t\t\t\tcase F3_SLLW:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SLLW);\n\t\t\t\t\t\tcase F3_SRLW:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SRLW);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase F7_SUBW:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_SUBW:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SUBW);\n\t\t\t\t\t\tcase F3_SRAW:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SRAW);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase F7_MULW:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_MULW:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(MULW);\n\t\t\t\t\t\tcase F3_DIVW:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(DIVW);\n\t\t\t\t\t\tcase F3_DIVUW:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(DIVUW);\n\t\t\t\t\t\tcase F3_REMW:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(REMW);\n\t\t\t\t\t\tcase F3_REMUW:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(REMUW);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase OP_FENCE: {\n\t\t\tswitch (instr.funct3()) {\n\t\t\t\tcase F3_FENCE:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FENCE);\n\t\t\t\tcase F3_FENCE_I:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FENCE_I);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase OP_ECALL: {\n\t\t\tswitch (instr.funct3()) {\n\t\t\t\tcase F3_SYS: {\n\t\t\t\t\tswitch (instr.funct12()) {\n\t\t\t\t\t\tcase F12_ECALL:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(ECALL);\n\t\t\t\t\t\tcase F12_EBREAK:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(EBREAK);\n\t\t\t\t\t\tcase F12_URET:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(URET);\n\t\t\t\t\t\tcase F12_SRET:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SRET);\n\t\t\t\t\t\tcase F12_MRET:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(MRET);\n\t\t\t\t\t\tcase F12_WFI:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(WFI);\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SFENCE_VMA);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase F3_CSRRW:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(CSRRW);\n\t\t\t\tcase F3_CSRRS:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(CSRRS);\n\t\t\t\tcase F3_CSRRC:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(CSRRC);\n\t\t\t\tcase F3_CSRRWI:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(CSRRWI);\n\t\t\t\tcase F3_CSRRSI:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(CSRRSI);\n\t\t\t\tcase F3_CSRRCI:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(CSRRCI);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase OP_AMO: {\n\t\t\tswitch (instr.funct5()) {\n\t\t\t\tcase F5_LR_W:\n\t\t\t\t\tif (instr.funct3() == F3_AMO_D) {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(LR_D);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(LR_W);\n\t\t\t\t\t}\n\t\t\t\tcase F5_SC_W:\n\t\t\t\t\tif (instr.funct3() == F3_AMO_D) {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SC_D);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(SC_W);\n\t\t\t\t\t}\n\t\t\t\tcase F5_AMOSWAP_W:\n\t\t\t\t\tif (instr.funct3() == F3_AMO_D) {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOSWAP_D);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOSWAP_W);\n\t\t\t\t\t}\n\t\t\t\tcase F5_AMOADD_W:\n\t\t\t\t\tif (instr.funct3() == F3_AMO_D) {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOADD_D);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOADD_W);\n\t\t\t\t\t}\n\t\t\t\tcase F5_AMOXOR_W:\n\t\t\t\t\tif (instr.funct3() == F3_AMO_D) {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOXOR_D);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOXOR_W);\n\t\t\t\t\t}\n\t\t\t\tcase F5_AMOAND_W:\n\t\t\t\t\tif (instr.funct3() == F3_AMO_D) {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOAND_D);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOAND_W);\n\t\t\t\t\t}\n\t\t\t\tcase F5_AMOOR_W:\n\t\t\t\t\tif (instr.funct3() == F3_AMO_D) {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOOR_D);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOOR_W);\n\t\t\t\t\t}\n\t\t\t\tcase F5_AMOMIN_W:\n\t\t\t\t\tif (instr.funct3() == F3_AMO_D) {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOMIN_D);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOMIN_W);\n\t\t\t\t\t}\n\t\t\t\tcase F5_AMOMAX_W:\n\t\t\t\t\tif (instr.funct3() == F3_AMO_D) {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOMAX_D);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOMAX_W);\n\t\t\t\t\t}\n\t\t\t\tcase F5_AMOMINU_W:\n\t\t\t\t\tif (instr.funct3() == F3_AMO_D) {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOMINU_D);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOMINU_W);\n\t\t\t\t\t}\n\t\t\t\tcase F5_AMOMAXU_W:\n\t\t\t\t\tif (instr.funct3() == F3_AMO_D) {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOMAXU_D);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(AMOMAXU_W);\n\t\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\t// RV32/64 FD Extension\n\t\tcase OP_FMADD_S:\n\t\t\tswitch (instr.funct2()) {\n\t\t\t\tcase F2_FMADD_S:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMADD_S);\n\t\t\t\tcase F2_FMADD_D:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMADD_D);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase OP_FADD_S:\n\t\t\tswitch (instr.funct7()) {\n\t\t\t\tcase F7_FADD_S:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FADD_S);\n\t\t\t\tcase F7_FADD_D:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FADD_D);\n\t\t\t\tcase F7_FSUB_S:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FSUB_S);\n\t\t\t\tcase F7_FSUB_D:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FSUB_D);\n\t\t\t\tcase F7_FCVT_D_S:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_D_S);\n\t\t\t\tcase F7_FMUL_S:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMUL_S);\n\t\t\t\tcase F7_FMUL_D:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMUL_D);\n\t\t\t\tcase F7_FDIV_S:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FDIV_S);\n\t\t\t\tcase F7_FDIV_D:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FDIV_D);\n\t\t\t\tcase F7_FLE_S:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_FLE_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FLE_S);\n\t\t\t\t\t\tcase F3_FLT_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FLT_S);\n\t\t\t\t\t\tcase F3_FEQ_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FEQ_S);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase F7_FSGNJ_D:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_FSGNJ_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FSGNJ_D);\n\t\t\t\t\t\tcase F3_FSGNJN_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FSGNJN_D);\n\t\t\t\t\t\tcase F3_FSGNJX_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FSGNJX_D);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase F7_FMIN_S:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_FMIN_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMIN_S);\n\t\t\t\t\t\tcase F3_FMAX_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMAX_S);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase F7_FMIN_D:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_FMIN_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMIN_D);\n\t\t\t\t\t\tcase F3_FMAX_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMAX_D);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase F7_FCVT_S_D:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_S_D);\n\t\t\t\tcase F7_FSGNJ_S:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_FSGNJ_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FSGNJ_S);\n\t\t\t\t\t\tcase F3_FSGNJN_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FSGNJN_S);\n\t\t\t\t\t\tcase F3_FSGNJX_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FSGNJX_S);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase F7_FLE_D:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_FLE_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FLE_D);\n\t\t\t\t\t\tcase F3_FLT_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FLT_D);\n\t\t\t\t\t\tcase F3_FEQ_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FEQ_D);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase F7_FCVT_S_W:\n\t\t\t\t\tswitch (instr.rs2()) {\n\t\t\t\t\t\tcase RS2_FCVT_S_W:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_S_W);\n\t\t\t\t\t\tcase RS2_FCVT_S_WU:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_S_WU);\n\t\t\t\t\t\tcase RS2_FCVT_S_L:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_S_L);\n\t\t\t\t\t\tcase RS2_FCVT_S_LU:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_S_LU);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase F7_FCVT_D_W:\n\t\t\t\t\tswitch (instr.rs2()) {\n\t\t\t\t\t\tcase RS2_FCVT_D_W:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_D_W);\n\t\t\t\t\t\tcase RS2_FCVT_D_WU:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_D_WU);\n\t\t\t\t\t\tcase RS2_FCVT_D_L:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_D_L);\n\t\t\t\t\t\tcase RS2_FCVT_D_LU:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_D_LU);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase F7_FCVT_W_D:\n\t\t\t\t\tswitch (instr.rs2()) {\n\t\t\t\t\t\tcase RS2_FCVT_W_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_W_D);\n\t\t\t\t\t\tcase RS2_FCVT_WU_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_WU_D);\n\t\t\t\t\t\tcase RS2_FCVT_L_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_L_D);\n\t\t\t\t\t\tcase RS2_FCVT_LU_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_LU_D);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase F7_FSQRT_S:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FSQRT_S);\n\t\t\t\tcase F7_FSQRT_D:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FSQRT_D);\n\t\t\t\tcase F7_FCVT_W_S:\n\t\t\t\t\tswitch (instr.rs2()) {\n\t\t\t\t\t\tcase RS2_FCVT_W_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_W_S);\n\t\t\t\t\t\tcase RS2_FCVT_WU_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_WU_S);\n\t\t\t\t\t\tcase RS2_FCVT_L_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_L_S);\n\t\t\t\t\t\tcase RS2_FCVT_LU_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCVT_LU_S);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase F7_FMV_X_W:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_FMV_X_W:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMV_X_W);\n\t\t\t\t\t\tcase F3_FCLASS_S:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCLASS_S);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase F7_FMV_X_D:\n\t\t\t\t\tswitch (instr.funct3()) {\n\t\t\t\t\t\tcase F3_FMV_X_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMV_X_D);\n\t\t\t\t\t\tcase F3_FCLASS_D:\n\t\t\t\t\t\t\tMATCH_AND_RETURN_INSTR(FCLASS_D);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase F7_FMV_W_X:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMV_W_X);\n\t\t\t\tcase F7_FMV_D_X:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMV_D_X);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase OP_FLW:\n\t\t\tswitch (instr.funct3()) {\n\t\t\t\tcase F3_FLW:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FLW);\n\t\t\t\tcase F3_FLD:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FLD);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase OP_FSW:\n\t\t\tswitch (instr.funct3()) {\n\t\t\t\tcase F3_FSW:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FSW);\n\t\t\t\tcase F3_FSD:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FSD);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase OP_FMSUB_S:\n\t\t\tswitch (instr.funct2()) {\n\t\t\t\tcase F2_FMSUB_S:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMSUB_S);\n\t\t\t\tcase F2_FMSUB_D:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FMSUB_D);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase OP_FNMSUB_S:\n\t\t\tswitch (instr.funct2()) {\n\t\t\t\tcase F2_FNMSUB_S:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FNMSUB_S);\n\t\t\t\tcase F2_FNMSUB_D:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FNMSUB_D);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase OP_FNMADD_S:\n\t\t\tswitch (instr.funct2()) {\n\t\t\t\tcase F2_FNMADD_S:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FNMADD_S);\n\t\t\t\tcase F2_FNMADD_D:\n\t\t\t\t\tMATCH_AND_RETURN_INSTR(FNMADD_D);\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\treturn UNDEF;\n}\n"
  },
  {
    "path": "vp/src/core/common/instr.h",
    "content": "#ifndef RISCV_ISA_INSTR_H\n#define RISCV_ISA_INSTR_H\n\n#include <stdint.h>\n#include <array>\n#include <iostream>\n\n#include \"core_defs.h\"\n\nnamespace Opcode {\n// opcode masks used to decode an instruction\nenum Parts {\n\tOP_LUI = 0b0110111,\n\n\tOP_AUIPC = 0b0010111,\n\n\tOP_JAL = 0b1101111,\n\n\tOP_JALR = 0b1100111,\n\tF3_JALR = 0b000,\n\n\tOP_LB = 0b0000011,\n\tF3_LB = 0b000,\n\tF3_LH = 0b001,\n\tF3_LW = 0b010,\n\tF3_LBU = 0b100,\n\tF3_LHU = 0b101,\n\tF3_LWU = 0b110,\n\tF3_LD = 0b011,\n\n\tOP_SB = 0b0100011,\n\tF3_SB = 0b000,\n\tF3_SH = 0b001,\n\tF3_SW = 0b010,\n\tF3_SD = 0b011,\n\n\tOP_BEQ = 0b1100011,\n\tF3_BEQ = 0b000,\n\tF3_BNE = 0b001,\n\tF3_BLT = 0b100,\n\tF3_BGE = 0b101,\n\tF3_BLTU = 0b110,\n\tF3_BGEU = 0b111,\n\n\tOP_ADDI = 0b0010011,\n\tF3_ADDI = 0b000,\n\tF3_SLTI = 0b010,\n\tF3_SLTIU = 0b011,\n\tF3_XORI = 0b100,\n\tF3_ORI = 0b110,\n\tF3_ANDI = 0b111,\n\tF3_SLLI = 0b001,\n\tF3_SRLI = 0b101,\n\tF7_SRLI = 0b0000000,\n\tF7_SRAI = 0b0100000,\n\tF6_SRLI = 0b000000,  // RV64 special case\n\tF6_SRAI = 0b010000,  // RV64 special case\n\n\tOP_ADD = 0b0110011,\n\tF3_ADD = 0b000,\n\tF7_ADD = 0b0000000,\n\tF3_SUB = 0b000,\n\tF7_SUB = 0b0100000,\n\tF3_SLL = 0b001,\n\tF3_SLT = 0b010,\n\tF3_SLTU = 0b011,\n\tF3_XOR = 0b100,\n\tF3_SRL = 0b101,\n\tF3_SRA = 0b101,\n\tF3_OR = 0b110,\n\tF3_AND = 0b111,\n\n\tF3_MUL = 0b000,\n\tF7_MUL = 0b0000001,\n\tF3_MULH = 0b001,\n\tF3_MULHSU = 0b010,\n\tF3_MULHU = 0b011,\n\tF3_DIV = 0b100,\n\tF3_DIVU = 0b101,\n\tF3_REM = 0b110,\n\tF3_REMU = 0b111,\n\n\tOP_FENCE = 0b0001111,\n\tF3_FENCE = 0b000,\n\tF3_FENCE_I = 0b001,\n\n\tOP_ECALL = 0b1110011,\n\tF3_SYS = 0b000,\n\tF12_ECALL = 0b000000000000,\n\tF12_EBREAK = 0b000000000001,\n\t// begin:privileged-instructions\n\tF12_URET = 0b000000000010,\n\tF12_SRET = 0b000100000010,\n\tF12_MRET = 0b001100000010,\n\tF12_WFI = 0b000100000101,\n\tF7_SFENCE_VMA = 0b0001001,\n\t// end:privileged-instructions\n\tF3_CSRRW = 0b001,\n\tF3_CSRRS = 0b010,\n\tF3_CSRRC = 0b011,\n\tF3_CSRRWI = 0b101,\n\tF3_CSRRSI = 0b110,\n\tF3_CSRRCI = 0b111,\n\n\tOP_AMO = 0b0101111,\n\tF5_LR_W = 0b00010,\n\tF5_SC_W = 0b00011,\n\tF5_AMOSWAP_W = 0b00001,\n\tF5_AMOADD_W = 0b00000,\n\tF5_AMOXOR_W = 0b00100,\n\tF5_AMOAND_W = 0b01100,\n\tF5_AMOOR_W = 0b01000,\n\tF5_AMOMIN_W = 0b10000,\n\tF5_AMOMAX_W = 0b10100,\n\tF5_AMOMINU_W = 0b11000,\n\tF5_AMOMAXU_W = 0b11100,\n\n\tF3_AMO_W = 0b010,\n\tF3_AMO_D = 0b011,\n\n\tOP_ADDIW = 0b0011011,\n\tF3_ADDIW = 0b000,\n\tF3_SLLIW = 0b001,\n\tF3_SRLIW = 0b101,\n\tF7_SRLIW = 0b0000000,\n\tF7_SRAIW = 0b0100000,\n\n\tOP_ADDW = 0b0111011,\n\tF3_ADDW = 0b000,\n\tF7_ADDW = 0b0000000,\n\tF3_SUBW = 0b000,\n\tF7_SUBW = 0b0100000,\n\tF3_SLLW = 0b001,\n\tF3_SRLW = 0b101,\n\tF7_SRLW = 0b0000000,\n\tF3_SRAW = 0b101,\n\tF7_SRAW = 0b0100000,\n\tF7_MULW = 0b0000001,\n\tF3_MULW = 0b000,\n\tF3_DIVW = 0b100,\n\tF3_DIVUW = 0b101,\n\tF3_REMW = 0b110,\n\tF3_REMUW = 0b111,\n\n\t// F and D extension\n\tOP_FMADD_S = 0b1000011,\n\tF2_FMADD_S = 0b00,\n\tF2_FMADD_D = 0b01,\n\tOP_FADD_S = 0b1010011,\n\tF7_FADD_S = 0b0000000,\n\tF7_FADD_D = 0b0000001,\n\tF7_FSUB_S = 0b0000100,\n\tF7_FSUB_D = 0b0000101,\n\tF7_FCVT_D_S = 0b0100001,\n\tF7_FMUL_S = 0b0001000,\n\tF7_FMUL_D = 0b0001001,\n\tF7_FDIV_S = 0b0001100,\n\tF7_FDIV_D = 0b0001101,\n\tF7_FLE_S = 0b1010000,\n\tF3_FLE_S = 0b000,\n\tF3_FLT_S = 0b001,\n\tF3_FEQ_S = 0b010,\n\tF7_FSGNJ_D = 0b0010001,\n\tF3_FSGNJ_D = 0b000,\n\tF3_FSGNJN_D = 0b001,\n\tF3_FSGNJX_D = 0b010,\n\tF7_FMIN_S = 0b0010100,\n\tF3_FMIN_S = 0b000,\n\tF3_FMAX_S = 0b001,\n\tF7_FMIN_D = 0b0010101,\n\tF3_FMIN_D = 0b000,\n\tF3_FMAX_D = 0b001,\n\tF7_FCVT_S_D = 0b0100000,\n\tF7_FSGNJ_S = 0b0010000,\n\tF3_FSGNJ_S = 0b000,\n\tF3_FSGNJN_S = 0b001,\n\tF3_FSGNJX_S = 0b010,\n\tF7_FLE_D = 0b1010001,\n\tF3_FLE_D = 0b000,\n\tF3_FLT_D = 0b001,\n\tF3_FEQ_D = 0b010,\n\tF7_FCVT_S_W = 0b1101000,\n\tRS2_FCVT_S_W = 0b00000,\n\tRS2_FCVT_S_WU = 0b00001,\n\tRS2_FCVT_S_L = 0b00010,\n\tRS2_FCVT_S_LU = 0b00011,\n\tF7_FCVT_D_W = 0b1101001,\n\tRS2_FCVT_D_W = 0b00000,\n\tRS2_FCVT_D_WU = 0b00001,\n\tRS2_FCVT_D_L = 0b00010,\n\tRS2_FCVT_D_LU = 0b00011,\n\tF7_FCVT_W_D = 0b1100001,\n\tRS2_FCVT_W_D = 0b00000,\n\tRS2_FCVT_WU_D = 0b00001,\n\tRS2_FCVT_L_D = 0b00010,\n\tRS2_FCVT_LU_D = 0b00011,\n\tF7_FSQRT_S = 0b0101100,\n\tF7_FSQRT_D = 0b0101101,\n\tF7_FCVT_W_S = 0b1100000,\n\tRS2_FCVT_W_S = 0b00000,\n\tRS2_FCVT_WU_S = 0b00001,\n\tRS2_FCVT_L_S = 0b00010,\n\tRS2_FCVT_LU_S = 0b00011,\n\tF7_FMV_X_W = 0b1110000,\n\tF3_FMV_X_W = 0b000,\n\tF3_FCLASS_S = 0b001,\n\tF7_FMV_X_D = 0b1110001,\n\tF3_FMV_X_D = 0b000,\n\tF3_FCLASS_D = 0b001,\n\tF7_FMV_W_X = 0b1111000,\n\tF7_FMV_D_X = 0b1111001,\n\tOP_FLW = 0b0000111,\n\tF3_FLW = 0b010,\n\tF3_FLD = 0b011,\n\tOP_FSW = 0b0100111,\n\tF3_FSW = 0b010,\n\tF3_FSD = 0b011,\n\tOP_FMSUB_S = 0b1000111,\n\tF2_FMSUB_S = 0b00,\n\tF2_FMSUB_D = 0b01,\n\tOP_FNMSUB_S = 0b1001011,\n\tF2_FNMSUB_S = 0b00,\n\tF2_FNMSUB_D = 0b01,\n\tOP_FNMADD_S = 0b1001111,\n\tF2_FNMADD_S = 0b00,\n\tF2_FNMADD_D = 0b01,\n\n\t// reserved opcodes for custom instructions\n\tOP_CUST1 = 0b0101011,\n\tOP_CUST0 = 0b0001011,\n};\n\n// each instruction is mapped by the decoder to the following mapping\nenum Mapping {\n\tUNDEF = 0,\n\n\t// RV32I base instruction set\n\tLUI = 1,\n\tAUIPC,\n\tJAL,\n\tJALR,\n\tBEQ,\n\tBNE,\n\tBLT,\n\tBGE,\n\tBLTU,\n\tBGEU,\n\tLB,\n\tLH,\n\tLW,\n\tLBU,\n\tLHU,\n\tSB,\n\tSH,\n\tSW,\n\tADDI,\n\tSLTI,\n\tSLTIU,\n\tXORI,\n\tORI,\n\tANDI,\n\tSLLI,\n\tSRLI,\n\tSRAI,\n\tADD,\n\tSUB,\n\tSLL,\n\tSLT,\n\tSLTU,\n\tXOR,\n\tSRL,\n\tSRA,\n\tOR,\n\tAND,\n\tFENCE,\n\tECALL,\n\tEBREAK,\n\n\t// Zifencei standard extension\n\tFENCE_I,\n\n\t// Zicsr standard extension\n\tCSRRW,\n\tCSRRS,\n\tCSRRC,\n\tCSRRWI,\n\tCSRRSI,\n\tCSRRCI,\n\n\t// RV32M standard extension\n\tMUL,\n\tMULH,\n\tMULHSU,\n\tMULHU,\n\tDIV,\n\tDIVU,\n\tREM,\n\tREMU,\n\n\t// RV32A standard extension\n\tLR_W,\n\tSC_W,\n\tAMOSWAP_W,\n\tAMOADD_W,\n\tAMOXOR_W,\n\tAMOAND_W,\n\tAMOOR_W,\n\tAMOMIN_W,\n\tAMOMAX_W,\n\tAMOMINU_W,\n\tAMOMAXU_W,\n\n\t// RV64I base integer set (addition to RV32I)\n\tLWU,\n\tLD,\n\tSD,\n\tADDIW,\n\tSLLIW,\n\tSRLIW,\n\tSRAIW,\n\tADDW,\n\tSUBW,\n\tSLLW,\n\tSRLW,\n\tSRAW,\n\n\t// RV64M standard extension (addition to RV32M)\n\tMULW,\n\tDIVW,\n\tDIVUW,\n\tREMW,\n\tREMUW,\n\n\t// RV64A standard extension (addition to RV32A)\n\tLR_D,\n\tSC_D,\n\tAMOSWAP_D,\n\tAMOADD_D,\n\tAMOXOR_D,\n\tAMOAND_D,\n\tAMOOR_D,\n\tAMOMIN_D,\n\tAMOMAX_D,\n\tAMOMINU_D,\n\tAMOMAXU_D,\n\n\t// RV32F standard extension\n\tFLW,\n\tFSW,\n\tFMADD_S,\n\tFMSUB_S,\n\tFNMADD_S,\n\tFNMSUB_S,\n\tFADD_S,\n\tFSUB_S,\n\tFMUL_S,\n\tFDIV_S,\n\tFSQRT_S,\n\tFSGNJ_S,\n\tFSGNJN_S,\n\tFSGNJX_S,\n\tFMIN_S,\n\tFMAX_S,\n\tFCVT_W_S,\n\tFCVT_WU_S,\n\tFMV_X_W,\n\tFEQ_S,\n\tFLT_S,\n\tFLE_S,\n\tFCLASS_S,\n\tFCVT_S_W,\n\tFCVT_S_WU,\n\tFMV_W_X,\n\n\t// RV64F standard extension (addition to RV32F)\n\tFCVT_L_S,\n\tFCVT_LU_S,\n\tFCVT_S_L,\n\tFCVT_S_LU,\n\n\t// RV32D standard extension\n\tFLD,\n\tFSD,\n\tFMADD_D,\n\tFMSUB_D,\n\tFNMSUB_D,\n\tFNMADD_D,\n\tFADD_D,\n\tFSUB_D,\n\tFMUL_D,\n\tFDIV_D,\n\tFSQRT_D,\n\tFSGNJ_D,\n\tFSGNJN_D,\n\tFSGNJX_D,\n\tFMIN_D,\n\tFMAX_D,\n\tFCVT_S_D,\n\tFCVT_D_S,\n\tFEQ_D,\n\tFLT_D,\n\tFLE_D,\n\tFCLASS_D,\n\tFCVT_W_D,\n\tFCVT_WU_D,\n\tFCVT_D_W,\n\tFCVT_D_WU,\n\n\t// RV64D standard extension (addition to RV32D)\n\tFCVT_L_D,\n\tFCVT_LU_D,\n\tFMV_X_D,\n\tFCVT_D_L,\n\tFCVT_D_LU,\n\tFMV_D_X,\n\n\t// privileged instructions\n\tURET,\n\tSRET,\n\tMRET,\n\tWFI,\n\tSFENCE_VMA,\n\n\tNUMBER_OF_INSTRUCTIONS\n};\n\n// type denotes the instruction format\nenum class Type {\n\tUNKNOWN = 0,\n\tR,\n\tI,\n\tS,\n\tB,\n\tU,\n\tJ,\n\tR4,\n};\n\nextern std::array<const char*, NUMBER_OF_INSTRUCTIONS> mappingStr;\nextern std::array<const char*, 32> regnamePrettyStr;\n\nType getType(Mapping mapping);\n}  // namespace Opcode\n\n#define BIT_RANGE(instr, upper, lower) (instr & (((1 << (upper - lower + 1)) - 1) << lower))\n#define BIT_SLICE(instr, upper, lower) (BIT_RANGE(instr, upper, lower) >> lower)\n#define BIT_SINGLE(instr, pos) (instr & (1 << pos))\n#define BIT_SINGLE_P1(instr, pos) (BIT_SINGLE(instr, pos) >> pos)\n#define BIT_SINGLE_PN(instr, pos, new_pos) ((BIT_SINGLE(instr, pos) >> pos) << new_pos)\n#define EXTRACT_SIGN_BIT(instr, pos, new_pos) ((BIT_SINGLE_P1(instr, pos) << 31) >> (31 - new_pos))\n\nstruct Instruction {\n\tInstruction() : instr(0) {}\n\n\tInstruction(uint32_t instr) : instr(instr) {}\n\n\tinline uint32_t quadrant() {\n\t\treturn instr & 0x3;\n\t}\n\n\tinline bool is_compressed() {\n\t\treturn quadrant() < 3;\n\t}\n\n\tinline uint32_t c_format() {\n\t\treturn instr & 0xffff;\n\t}\n\n\tinline uint32_t c_opcode() {\n\t\treturn BIT_SLICE(instr, 15, 13);\n\t}\n\n\tinline uint32_t c_b12() {\n\t\treturn BIT_SINGLE_P1(instr, 12);\n\t}\n\n\tinline uint32_t c_rd() {\n\t\treturn rd();\n\t}\n\n\tinline uint32_t c_rd_small() {\n\t\treturn BIT_SLICE(instr, 9, 7) | 8;\n\t}\n\n\tinline uint32_t c_rs2_small() {\n\t\treturn BIT_SLICE(instr, 4, 2) | 8;\n\t}\n\n\tinline uint32_t c_rs2() {\n\t\treturn BIT_SLICE(instr, 6, 2);\n\t}\n\n\tinline uint32_t c_imm() {\n\t\treturn BIT_SLICE(instr, 6, 2) | EXTRACT_SIGN_BIT(instr, 12, 5);\n\t}\n\n\tinline uint32_t c_uimm() {\n\t\treturn BIT_SLICE(instr, 6, 2) | (BIT_SINGLE_P1(instr, 12) << 5);\n\t}\n\n\tinline uint32_t c_f2_high() {\n\t\treturn BIT_SLICE(instr, 11, 10);\n\t}\n\n\tinline uint32_t c_f2_low() {\n\t\treturn BIT_SLICE(instr, 6, 5);\n\t}\n\n\tOpcode::Mapping decode_normal(Architecture arch);\n\n\tOpcode::Mapping decode_and_expand_compressed(Architecture arch);\n\n\tinline uint32_t csr() {\n\t\t// cast to unsigned to avoid sign extension when shifting\n\t\treturn BIT_RANGE((uint32_t)instr, 31, 20) >> 20;\n\t}\n\n\tinline uint32_t zimm() {\n\t\treturn BIT_RANGE(instr, 19, 15) >> 15;\n\t}\n\n\tinline unsigned shamt() {\n\t\treturn (BIT_RANGE(instr, 25, 20) >> 20);\n\t}\n\n\tinline unsigned shamt_w() {\n\t\treturn (BIT_RANGE(instr, 24, 20) >> 20);\n\t}\n\n\tinline int32_t funct2() {\n\t\treturn (BIT_RANGE(instr, 26, 25) >> 25);\n\t}\n\n\tinline int32_t funct3() {\n\t\treturn (BIT_RANGE(instr, 14, 12) >> 12);\n\t}\n\n\tinline int32_t funct12() {\n\t\t// cast to unsigned to avoid sign extension when shifting\n\t\treturn (BIT_RANGE((uint32_t)instr, 31, 20) >> 20);\n\t}\n\n\tinline int32_t funct7() {\n\t\t// cast to unsigned to avoid sign extension when shifting\n\t\treturn (BIT_RANGE((uint32_t)instr, 31, 25) >> 25);\n\t}\n\n\tinline int32_t funct6() {\n\t\t// cast to unsigned to avoid sign extension when shifting\n\t\treturn (BIT_RANGE((uint32_t)instr, 31, 26) >> 26);\n\t}\n\n\tinline int32_t funct5() {\n\t\t// cast to unsigned to avoid sign extension when shifting\n\t\treturn (BIT_RANGE((uint32_t)instr, 31, 27) >> 27);\n\t}\n\n\tinline uint32_t frm() {\n\t\treturn BIT_SLICE(instr, 14, 12);\n\t}\n\n\tinline uint32_t fence_succ() {\n\t\treturn BIT_SLICE(instr, 23, 20);\n\t}\n\n\tinline uint32_t fence_pred() {\n\t\treturn BIT_SLICE(instr, 27, 24);\n\t}\n\n\tinline uint32_t fence_fm() {\n\t\treturn BIT_SLICE(instr, 31, 28);\n\t}\n\n\tinline bool aq() {\n\t\treturn BIT_SINGLE(instr, 26);\n\t}\n\n\tinline bool rl() {\n\t\treturn BIT_SINGLE(instr, 25);\n\t}\n\n\tinline int32_t opcode() {\n\t\treturn BIT_RANGE(instr, 6, 0);\n\t}\n\n\tinline int32_t J_imm() {\n\t\treturn (BIT_SINGLE(instr, 31) >> 11) | BIT_RANGE(instr, 19, 12) | (BIT_SINGLE(instr, 20) >> 9) |\n\t\t       (BIT_RANGE(instr, 30, 21) >> 20);\n\t}\n\n\tinline int32_t I_imm() {\n\t\treturn BIT_RANGE(instr, 31, 20) >> 20;\n\t}\n\n\tinline int32_t S_imm() {\n\t\treturn (BIT_RANGE(instr, 31, 25) >> 20) | (BIT_RANGE(instr, 11, 7) >> 7);\n\t}\n\n\tinline int32_t B_imm() {\n\t\treturn (BIT_SINGLE(instr, 31) >> 19) | (BIT_SINGLE(instr, 7) << 4) | (BIT_RANGE(instr, 30, 25) >> 20) |\n\t\t       (BIT_RANGE(instr, 11, 8) >> 7);\n\t}\n\n\tinline int32_t U_imm() {\n\t\treturn BIT_RANGE(instr, 31, 12);\n\t}\n\n\tinline uint32_t rs1() {\n\t\treturn BIT_RANGE(instr, 19, 15) >> 15;\n\t}\n\n\tinline uint32_t rs2() {\n\t\treturn BIT_RANGE(instr, 24, 20) >> 20;\n\t}\n\n\tinline uint32_t rs3() {\n\t\treturn BIT_RANGE((uint32_t)instr, 31, 27) >> 27;\n\t}\n\n\tinline uint32_t rd() {\n\t\treturn BIT_RANGE(instr, 11, 7) >> 7;\n\t}\n\n\tinline uint32_t data() {\n\t\treturn instr;\n\t}\n\n   private:\n\t// use signed variable to have correct sign extension in immediates\n\tint32_t instr;\n};\n\n#endif  // RISCV_ISA_INSTR_H\n"
  },
  {
    "path": "vp/src/core/common/irq_if.h",
    "content": "#ifndef RISCV_ISA_IRQ_IF_H\n#define RISCV_ISA_IRQ_IF_H\n\n#include <stdint.h>\n\ntypedef uint32_t PrivilegeLevel;\n\nconstexpr uint32_t MachineMode = 0b11;\nconstexpr uint32_t HypervisorMode = 0b10;\nconstexpr uint32_t SupervisorMode = 0b01;\nconstexpr uint32_t UserMode = 0b00;\nconstexpr uint32_t NoneMode = -1;  // invalid sentinel to avoid passing a boolean alongside a privilege level\n\nstruct external_interrupt_target {\n\tvirtual ~external_interrupt_target() {}\n\n\tvirtual void trigger_external_interrupt(PrivilegeLevel level) = 0;\n\tvirtual void clear_external_interrupt(PrivilegeLevel level) = 0;\n};\n\nstruct clint_interrupt_target {\n\tvirtual ~clint_interrupt_target() {}\n\n\tvirtual void trigger_timer_interrupt(bool status) = 0;\n\tvirtual void trigger_software_interrupt(bool status) = 0;\n};\n\nstruct interrupt_gateway {\n\tvirtual ~interrupt_gateway() {}\n\n\tvirtual void gateway_trigger_interrupt(uint32_t irq_id) = 0;\n};\n\n#endif  // RISCV_ISA_IRQ_IF_H\n"
  },
  {
    "path": "vp/src/core/common/load_if.h",
    "content": "#ifndef RISCV_VP_LOAD_IF_H\n#define RISCV_VP_LOAD_IF_H\n\n#include <stdint.h>\n#include <stddef.h>\n\nclass load_if {\n  public:\n\tvirtual void load_data(const char *src, uint64_t dst_addr, size_t n) = 0;\n\tvirtual void load_zero(uint64_t dst_addr, size_t n) = 0;\n};\n\n#endif\n"
  },
  {
    "path": "vp/src/core/common/mmu.h",
    "content": "#pragma once\n\n#include \"mmu_mem_if.h\"\n\nconstexpr unsigned PTE_PPN_SHIFT = 10;\nconstexpr unsigned PGSHIFT = 12;\nconstexpr unsigned PGSIZE = 1 << PGSHIFT;\nconstexpr unsigned PGMASK = PGSIZE - 1;\n\nconstexpr unsigned PTE_V = 1;\nconstexpr unsigned PTE_R = 1 << 1;\nconstexpr unsigned PTE_W = 1 << 2;\nconstexpr unsigned PTE_X = 1 << 3;\nconstexpr unsigned PTE_U = 1 << 4;\nconstexpr unsigned PTE_G = 1 << 5;\nconstexpr unsigned PTE_A = 1 << 6;\nconstexpr unsigned PTE_D = 1 << 7;\nconstexpr unsigned PTE_RSW = 0b11 << 8;\n\nstruct pte_t {\n    uint64_t value;\n\n    bool V() {\n        return value & PTE_V;\n    }\n    bool R() {\n        return value & PTE_R;\n    }\n    bool W() {\n        return value & PTE_W;\n    }\n    bool X() {\n        return value & PTE_X;\n    }\n    bool U() {\n        return value & PTE_U;\n    }\n    bool G() {\n        return value & PTE_G;\n    }\n    bool A() {\n        return value & PTE_A;\n    }\n    bool D() {\n        return value & PTE_D;\n    }\n\n    operator uint64_t() {\n        return value;\n    }\n};\n\nstruct vm_info {\n    int levels;\n    int idxbits;\n    int ptesize;\n    uint64_t ptbase;\n};\n\ntemplate <typename RVX_ISS>\nstruct GenericMMU {\n    RVX_ISS &core;\n    tlm_utils::tlm_quantumkeeper &quantum_keeper;\n    sc_core::sc_time clock_cycle = sc_core::sc_time(10, sc_core::SC_NS);\n    sc_core::sc_time mmu_access_delay = clock_cycle * 3;\n\n    mmu_memory_if *mem = nullptr;\n    bool page_fault_on_AD = false;\n\n    struct tlb_entry_t {\n        uint64_t ppn = -1;\n        uint64_t vpn = -1;\n    };\n\n    static constexpr unsigned TLB_ENTRIES = 256;\n    static constexpr unsigned NUM_MODES = 2;         // User and Supervisor\n    static constexpr unsigned NUM_ACCESS_TYPES = 3;  // FETCH, LOAD, STORE\n\n    tlb_entry_t tlb[NUM_MODES][NUM_ACCESS_TYPES][TLB_ENTRIES];\n\n    GenericMMU(RVX_ISS &core)\n        : core(core), quantum_keeper(core.quantum_keeper) {\n        flush_tlb();\n    }\n\n    void flush_tlb() {\n        memset(&tlb[0], -1, NUM_MODES * NUM_ACCESS_TYPES * TLB_ENTRIES * sizeof(tlb_entry_t));\n    }\n\n    uint64_t translate_virtual_to_physical_addr(uint64_t vaddr, MemoryAccessType type) {\n        if (core.csrs.satp.fields.mode == SATP_MODE_BARE)\n            return vaddr;\n\n        auto mode = core.prv;\n\n        if (type != FETCH) {\n            if (core.csrs.mstatus.fields.mprv)\n                mode = core.csrs.mstatus.fields.mpp;\n        }\n\n        if (mode == MachineMode)\n            return vaddr;\n\n        // optional timing\n        quantum_keeper.inc(mmu_access_delay);\n\n        // optimization only, to void page walk\n        assert(mode == 0 || mode == 1);\n        assert(type == 0 || type == 1 || type == 2);\n        auto vpn = (vaddr >> PGSHIFT);\n        auto idx = vpn % TLB_ENTRIES;\n        auto &x = tlb[mode][type][idx];\n        if (x.vpn == vpn)\n            return x.ppn | (vaddr & PGMASK);\n\n        uint64_t paddr = walk(vaddr, type, mode);\n\n        // optimization only, to void page walk\n        x.ppn = (paddr & ~PGMASK);\n        x.vpn = vpn;\n\n        return paddr;\n    }\n\n    vm_info decode_vm_info(PrivilegeLevel prv) {\n        assert(prv <= SupervisorMode);\n        uint64_t ptbase = (uint64_t)core.csrs.satp.fields.ppn << PGSHIFT;\n        unsigned mode = core.csrs.satp.fields.mode;\n        switch (mode) {\n            case SATP_MODE_SV32:\n                return {2, 10, 4, ptbase};\n            case SATP_MODE_SV39:\n                return {3, 9, 8, ptbase};\n            case SATP_MODE_SV48:\n                return {4, 9, 8, ptbase};\n            case SATP_MODE_SV57:\n                return {5, 9, 8, ptbase};\n            case SATP_MODE_SV64:\n                return {6, 9, 8, ptbase};\n            default:\n                throw std::runtime_error(\"unknown Sv (satp) mode \" + std::to_string(mode));\n        }\n    }\n\n    bool check_vaddr_extension(uint64_t vaddr, const vm_info &vm) {\n        int highbit = vm.idxbits * vm.levels + PGSHIFT - 1;\n        assert(highbit > 0);\n        uint64_t ext_mask = (uint64_t(1) << (core.xlen - highbit)) - 1;\n        uint64_t bits = (vaddr >> highbit) & ext_mask;\n        bool ok = (bits == 0) || (bits == ext_mask);\n        return ok;\n    }\n\n    uint64_t walk(uint64_t vaddr, MemoryAccessType type, PrivilegeLevel mode) {\n        bool s_mode = mode == SupervisorMode;\n        bool sum = core.csrs.mstatus.fields.sum;\n        bool mxr = core.csrs.mstatus.fields.mxr;\n\n        vm_info vm = decode_vm_info(mode);\n\n        if (!check_vaddr_extension(vaddr, vm))\n            vm.levels = 0;  // skip loop and raise page fault\n\n        uint64_t base = vm.ptbase;\n        for (int i = vm.levels - 1; i >= 0; --i) {\n            // obtain VPN field for current level, NOTE: all VPN fields have the same length for each separate VM\n            // implementation\n            int ptshift = i * vm.idxbits;\n            unsigned vpn_field = (vaddr >> (PGSHIFT + ptshift)) & ((1 << vm.idxbits) - 1);\n\n            auto pte_paddr = base + vpn_field * vm.ptesize;\n            // TODO: PMP checks for pte_paddr with (LOAD, PRV_S)\n\n            assert(vm.ptesize == 4 || vm.ptesize == 8);\n            assert(mem);\n            pte_t pte;\n            if (vm.ptesize == 4)\n                pte.value = mem->mmu_load_pte32(pte_paddr);\n            else\n                pte.value = mem->mmu_load_pte64(pte_paddr);\n\n            uint64_t ppn = pte >> PTE_PPN_SHIFT;\n\n            if (!pte.V() || (!pte.R() && pte.W())) {\n                // std::cout << \"[mmu] !pte.V() || (!pte.R() && pte.W())\" << std::endl;\n                break;\n            }\n\n            if (!pte.R() && !pte.X()) {\n                base = ppn << PGSHIFT;\n                continue;\n            }\n\n            assert(type == FETCH || type == LOAD || type == STORE);\n            if ((type == FETCH) && !pte.X()) {\n                // std::cout << \"[mmu] (type == FETCH) && !pte.X()\" << std::endl;\n                break;\n            }\n            if ((type == LOAD) && !pte.R() && !(mxr && pte.X())) {\n                // std::cout << \"[mmu] (type == LOAD) && !pte.R() && !(mxr && pte.X())\" << std::endl;\n                break;\n            }\n            if ((type == STORE) && !(pte.R() && pte.W())) {\n                // std::cout << \"[mmu] (type == STORE) && !(pte.R() && pte.W())\" << std::endl;\n                break;\n            }\n\n            if (pte.U()) {\n                if (s_mode && ((type == FETCH) || !sum))\n                    break;\n            } else {\n                if (!s_mode)\n                    break;\n            }\n\n            // NOTE: all PPN (except the highest one) have the same bitwidth as the VPNs, hence ptshift can be used\n            if ((ppn & ((uint64_t(1) << ptshift) - 1)) != 0)\n                break;  // misaligned superpage\n\n            uint64_t ad = PTE_A | ((type == STORE) * PTE_D);\n            if ((pte & ad) != ad) {\n                if (page_fault_on_AD) {\n                    break;  // let SW deal with this\n                } else {\n                    // TODO: PMP checks for pte_paddr with (STORE, PRV_S)\n\n                    // NOTE: the store has to be atomic with the above load of the PTE, i.e. lock the bus if required\n                    // NOTE: only need to update A / D flags, hence it is enough to store 32 bit (8 bit might be enough\n                    // too)\n                    mem->mmu_store_pte32(pte_paddr, pte | ad);\n                }\n            }\n\n            // translation successful, return physical address\n            uint64_t mask = ((uint64_t(1) << ptshift) - 1);\n            uint64_t vpn = vaddr >> PGSHIFT;\n            uint64_t pgoff = vaddr & (PGSIZE - 1);\n            uint64_t paddr = (((ppn & ~mask) | (vpn & mask)) << PGSHIFT) | pgoff;\n            return paddr;\n        }\n\n        switch (type) {\n            case FETCH:\n                raise_trap(EXC_INSTR_PAGE_FAULT, vaddr);\n                break;\n            case LOAD:\n                raise_trap(EXC_LOAD_PAGE_FAULT, vaddr);\n                break;\n            case STORE:\n                raise_trap(EXC_STORE_AMO_PAGE_FAULT, vaddr);\n                break;\n        }\n\n        throw std::runtime_error(\"[mmu] unknown access type \" + std::to_string(type));\n    }\n};\n"
  },
  {
    "path": "vp/src/core/common/mmu_mem_if.h",
    "content": "#ifndef RISCV_VP_MMU_MEM_IF_H\n#define RISCV_VP_MMU_MEM_IF_H\n\n#include <stdint.h>\n\nenum MemoryAccessType { FETCH, LOAD, STORE };\n\nstruct mmu_memory_if {\n    virtual ~mmu_memory_if() {}\n\n    virtual uint64_t v2p(uint64_t vaddr, MemoryAccessType type) = 0;\n    virtual uint64_t mmu_load_pte64(uint64_t addr) = 0;\n    virtual uint64_t mmu_load_pte32(uint64_t addr) = 0;\n    virtual void mmu_store_pte32(uint64_t addr, uint32_t value) = 0;\n};\n\n#endif //RISCV_VP_MMU_MEM_IF_H\n"
  },
  {
    "path": "vp/src/core/common/rawmode.cpp",
    "content": "/* Copied from linenoise <https://github.com/antirez/linenoise> with slight modifications.\n *\n * Copyright (c) 2019, Sören Tempel <tempel at uni-bremen dot de>\n * Copyright (c) 2010-2014, Salvatore Sanfilippo <antirez at gmail dot com>\n * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice,\n *   this list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n *   this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\n * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\n * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\n */\n\n#include <system_error>\n\n#include <stdlib.h>\n#include <errno.h>\n#include <termios.h>\n#include <unistd.h>\n#include <signal.h>\n#include <stddef.h>\n\n#include \"rawmode.h\"\n\nstatic int rawfd = -1;\nstatic struct termios orig_termios;\n\nstatic void reset_term(void) {\n\t// Signal might arrive before enableRawMode()\n\tif (rawfd < 0)\n\t\treturn;\n\n\tdisableRawMode(rawfd);\n}\n\nstatic void sighandler(int num) {\n\t(void)num;\n\treset_term();\n\texit(EXIT_FAILURE);\n}\n\nstatic void sethandler(void) {\n\tsize_t i;\n\tstruct sigaction act;\n\tint signals[] = {SIGINT, SIGTERM, SIGQUIT, SIGHUP};\n\n\tact.sa_flags = 0;\n\tact.sa_handler = sighandler;\n\tif (sigfillset(&act.sa_mask) == -1)\n\t\tthrow std::system_error(errno, std::generic_category());\n\n\tfor (i = 0; i < (sizeof(signals) / sizeof(signals[0])); i++) {\n\t\tif (sigaction(signals[i], &act, NULL))\n\t\t\tthrow std::system_error(errno, std::generic_category());\n\t}\n\n\t/* also make sure we cleanup on exit(3) */\n\tif (atexit(reset_term))\n\t\tthrow std::system_error(errno, std::generic_category());\n}\n\nvoid enableRawMode(int fd) {\n\tstruct termios raw;\n\n\t// Check if rawm ode was already activated\n\tif (rawfd >= 0)\n\t\treturn;\n\n\tif (!isatty(STDIN_FILENO))\n\t\treturn; // not a tty, nothing to do\n\n\tif (tcgetattr(fd, &orig_termios) == -1)\n\t\tgoto fatal;\n\n\traw = orig_termios; /* modify the original mode */\n\t/* input modes: no break, no CR to NL, no parity check, no strip char,\n\t * no start/stop output control. */\n\traw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);\n\t/* control modes - set 8 bit chars */\n\traw.c_cflag |= (CS8);\n\t/* local modes - choing off, canonical off, no extended functions,\n\t * no signal chars (^Z,^C) */\n\traw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);\n\t/* control chars - set return condition: min number of bytes and timer.\n\t * We want read to return every single byte, without timeout. */\n\traw.c_cc[VMIN] = 1;\n\traw.c_cc[VTIME] = 0; /* 1 byte, no timer */\n\n\t/* put terminal in raw mode after flushing */\n\tif (tcsetattr(fd, TCSAFLUSH, &raw) < 0)\n\t\tgoto fatal;\n\n\trawfd = fd;\n\tsethandler();\n\n\treturn;\nfatal:\n\tthrow std::system_error(errno, std::generic_category());\n}\n\nvoid disableRawMode(int fd) {\n\tif (rawfd < 0)\n\t\treturn;\n\n\tif (tcsetattr(fd, TCSAFLUSH, &orig_termios) == -1)\n\t\tthrow std::system_error(errno, std::generic_category());\n\n\trawfd = -1;\n}\n"
  },
  {
    "path": "vp/src/core/common/rawmode.h",
    "content": "#ifndef RISCV_VP_RAWMODE_H\n#define RISCV_VP_RAWMODE_H\n\nvoid enableRawMode(int);\nvoid disableRawMode(int);\n\n#endif\n"
  },
  {
    "path": "vp/src/core/common/real_clint.cpp",
    "content": "#include <assert.h>\n#include <stddef.h>\n\n#include \"real_clint.h\"\n\nenum {\n\tMSIP_BASE = 0,\n\tMSIP_SIZE = 4,\n\n\tMTIMECMP_BASE = 0x4000,\n\tMTIMECMP_SIZE = 8,\n\n\tMTIME_BASE = 0xBFF8,\n\tMTIME_SIZE = 8,\n};\n\nenum {\n\tMSIP_MASK = 0x1, // The upper MSIP bits are tied to zero\n};\n\n/* This is used to quantize a 1MHz value to the closest 32768Hz value */\n#define DIVIDEND (uint64_t(15625)/uint64_t(512))\n\nstatic void\ntimercb(void *arg) {\n\tAsyncEvent *event = (AsyncEvent *)arg;\n\tevent->notify();\n}\n\nRealCLINT::RealCLINT(sc_core::sc_module_name, std::vector<clint_interrupt_target*> &_harts)\n\t: regs_msip(MSIP_BASE, MSIP_SIZE * _harts.size()),\n\t  regs_mtimecmp(MTIMECMP_BASE, MTIMECMP_SIZE * _harts.size()),\n\t  regs_mtime(MTIME_BASE, MTIME_SIZE),\n\n\t  msip(regs_msip),\n\t  mtimecmp(regs_mtimecmp),\n\t  mtime(regs_mtime),\n\n\t  harts(_harts) {\n\tfor (size_t i = 0; i < harts.size(); i++) {\n\t\tTimer *timer = new Timer(timercb, &event);\n\t\ttimers.push_back(timer);\n\t}\n\n\tregister_ranges.insert(register_ranges.end(), {&regs_mtimecmp, &regs_msip, &regs_mtime});\n\tfor (auto reg : register_ranges)\n\t\treg->alignment = 4;\n\n\tregs_mtimecmp.post_write_callback = std::bind(&RealCLINT::post_write_mtimecmp, this, std::placeholders::_1);\n\tregs_msip.post_write_callback = std::bind(&RealCLINT::post_write_msip, this, std::placeholders::_1);\n\n\tregs_mtime.pre_read_callback = std::bind(&RealCLINT::pre_read_mtime, this, std::placeholders::_1);\n\tregs_mtime.post_write_callback = std::bind(&RealCLINT::post_write_mtime, this, std::placeholders::_1);\n\n\tfirst_mtime = std::chrono::high_resolution_clock::now();\n\ttsock.register_b_transport(this, &RealCLINT::transport);\n\n\tSC_METHOD(interrupt);\n\tsensitive << event;\n\tdont_initialize();\n}\n\nRealCLINT::~RealCLINT(void) {\n\tfor (auto timer : timers)\n\t\tdelete timer;\n}\n\nuint64_t RealCLINT::update_and_get_mtime(void) {\n\ttime_point now = std::chrono::high_resolution_clock::now();\n\tusecs duration = std::chrono::duration_cast<usecs>(now - first_mtime);\n\n\tmtime = usec_to_ticks(duration);\n\treturn mtime;\n}\n\nuint64_t RealCLINT::usec_to_ticks(usecs usec) {\n\t// This algorithm is inspired by the implementation provided by RIOT-OS.\n\t// https://github.com/RIOT-OS/RIOT/blob/d382bd656569599691c1a3e1c9b1662e07cf1a42/sys/include/xtimer/tick_conversion.h#L100-L106\n\n\tuint64_t microseconds = usec.count();\n\treturn microseconds / DIVIDEND;\n}\n\nRealCLINT::usecs RealCLINT::ticks_to_usec(uint64_t ticks) {\n\t// See comment in RealCLINT::usec_to_ticks\n\treturn usecs(ticks * DIVIDEND);\n}\n\nvoid RealCLINT::post_write_mtimecmp(RegisterRange::WriteInfo info) {\n\tassert(info.addr % 4 == 0);\n\tunsigned hart = info.addr / MTIMECMP_SIZE;\n\n\tuint64_t cmp = mtimecmp.at(hart);\n\tuint64_t time = update_and_get_mtime();\n\n\tTimer *timer = timers.at(hart);\n\ttimer->pause();\n\n\tif (time >= cmp) {\n\t\tharts.at(hart)->trigger_timer_interrupt(true);\n\t\treturn;\n\t}\n\tharts.at(hart)->trigger_timer_interrupt(false);\n\n\tuint64_t goal_ticks = cmp - time;\n\tusecs duration = ticks_to_usec(goal_ticks);\n\n\ttimer->start(duration);\n}\n\nvoid RealCLINT::post_write_msip(RegisterRange::WriteInfo info) {\n\tassert(info.addr % 4 == 0);\n\tunsigned hart = info.addr / MSIP_SIZE;\n\n\tmsip.at(hart) &= MSIP_MASK;\n\tharts.at(hart)->trigger_software_interrupt(msip.at(hart) != 0);\n}\n\nvoid RealCLINT::post_write_mtime(RegisterRange::WriteInfo info) {\n\t/* TODO:\n\t *  1. Adjust first_mtime to reflect new mtime register value.\n\t *  2. Notify asyncEvent to check if a timmer intr must be raised.\n\t *     Potentially requires stopping existing timers. */\n\t(void)info;\n}\n\nbool RealCLINT::pre_read_mtime(RegisterRange::ReadInfo info) {\n\t(void)info;\n\n\tupdate_and_get_mtime();\n\treturn true;\n}\n\nvoid RealCLINT::interrupt(void) {\n\tupdate_and_get_mtime();\n\n\tfor (size_t i = 0; i < harts.size(); i++) {\n\t\tauto cmp = mtimecmp.at(i);\n\t\tif (mtime >= cmp)\n\t\t\tharts.at(i)->trigger_timer_interrupt(true);\n\t}\n}\n\nvoid RealCLINT::transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\tvp::mm::route(\"RealCLINT\", register_ranges, trans, delay);\n}\n"
  },
  {
    "path": "vp/src/core/common/real_clint.h",
    "content": "#ifndef RISCV_VP_REAL_CLINT_H\n#define RISCV_VP_REAL_CLINT_H\n\n#include <stdint.h>\n\n#include <chrono>\n#include <systemc>\n#include <map>\n#include <tlm_utils/simple_target_socket.h>\n\n#include \"platform/common/async_event.h\"\n#include \"util/memory_map.h\"\n#include \"clint_if.h\"\n#include \"irq_if.h\"\n#include \"timer.h\"\n\n// This class implements a CLINT as specified in the FE310-G000 manual\n// and the RISC-V Privileged Specification. As per the FE310-G000\n// manual, this CLINT uses an input clock which runs at a frequency of\n// 32.768 kHz. Currently, this frequency cannot be configured.\n//\n// Contrary to the CLINT class, also provided in this directory, this\n// CLINT is based on \"real time\" instead of SystemC simulation time.\nclass RealCLINT : public clint_if, public sc_core::sc_module {\npublic:\n\tRealCLINT(sc_core::sc_module_name, std::vector<clint_interrupt_target*>&);\n\t~RealCLINT(void);\n\n\ttlm_utils::simple_target_socket<RealCLINT> tsock;\n\tuint64_t update_and_get_mtime(void) override;\n\n\tSC_HAS_PROCESS(RealCLINT);\npublic:\n\ttypedef std::chrono::high_resolution_clock::time_point time_point;\n\ttypedef Timer::usecs usecs;\n\n\tRegisterRange regs_msip;\n\tRegisterRange regs_mtimecmp;\n\tRegisterRange regs_mtime;\n\n\tArrayView<uint32_t> msip;\n\tArrayView<uint64_t> mtimecmp;\n\tIntegerView<uint64_t> mtime;\n\n\tstd::vector<RegisterRange*> register_ranges;\n\tstd::vector<clint_interrupt_target*> &harts;\n\n\tAsyncEvent event;\n\tstd::vector<Timer*> timers;\n\n\ttime_point first_mtime;\n\n\tvoid post_write_mtimecmp(RegisterRange::WriteInfo info);\n\tvoid post_write_msip(RegisterRange::WriteInfo info);\n\tvoid post_write_mtime(RegisterRange::WriteInfo info);\n\tbool pre_read_mtime(RegisterRange::ReadInfo info);\n\n\tuint64_t usec_to_ticks(usecs usec);\n\tusecs ticks_to_usec(uint64_t ticks);\n\n\tvoid interrupt(void);\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay);\n};\n\n#endif\n"
  },
  {
    "path": "vp/src/core/common/timer.cpp",
    "content": "#include <assert.h>\n#include <limits.h>\n#include <stdlib.h>\n#include <signal.h>\n#include <errno.h>\n#include <err.h>\n\n#include \"timer.h\"\n\n/* As defined in nanosleep(3) */\n#define NS_MAX 999999999UL\n#define US_MAX (NS_MAX / 1000)\n\n/* Signal used to unblock nanosleep in thread */\n#define SIGNUM SIGUSR1\n\nstatic int\nxnanosleep(const struct timespec *timespec) {\n\tif (nanosleep(timespec, NULL) == 0)\n\t\treturn 0; /* success */\n\n\tif (errno == EINTR)\n\t\treturn -1; /* received signal via pthread_kill, terminate */\n\n\terr(EXIT_FAILURE, \"nanosleep failed\"); /* EFAULT, EINVAL, … */\n}\n\nstatic void *\ncallback(void *arg)\n{\n\tstruct timespec timespec;\n\tTimer::Context *ctx = (Timer::Context*)arg;\n\n\t/* Initialize the seconds field, we use nanoseconds though */\n\ttimespec.tv_sec = 0;\n\n\tauto count = ctx->duration.count();\n\twhile (count > US_MAX) {\n\t\ttimespec.tv_nsec = NS_MAX;\n\t\tif (xnanosleep(&timespec))\n\t\t\treturn NULL; /* pthread_kill */\n\t\tcount -= US_MAX;\n\t}\n\n\t// Convert remaining us → ns with overflow check\n\tuint64_t ns = count * 1000;\n\tassert(ns > count);\n\n\tassert(ns <= LONG_MAX); // tv_nsec is a long\n\ttimespec.tv_nsec = ns;\n\tif (xnanosleep(&timespec))\n\t\treturn NULL; /* pthread_kill */\n\n\tctx->fn(ctx->arg);\n\treturn NULL;\n}\n\nTimer::Timer(Callback fn, void *arg)\n  : ctx(usecs(0), fn, arg) {\n\trunning = false;\n}\n\nTimer::~Timer(void) {\n\tpause();\n}\n\nvoid Timer::start(usecs duration) {\n\tif (running && (errno = pthread_join(thread, NULL)))\n\t\tthrow std::system_error(errno, std::generic_category());\n\n\t/* Update duration for new callback */\n\tctx.duration = duration;\n\n\tif ((errno = pthread_create(&thread, NULL, callback, &ctx)))\n\t\tthrow std::system_error(errno, std::generic_category());\n\trunning = true;\n}\n\nvoid Timer::pause(void) {\n\tstruct sigaction sa;\n\n\tif (!running)\n\t\treturn;\n\n\tsa.sa_handler = SIG_IGN;\n\tsa.sa_flags = SA_RESTART;\n\tif (sigemptyset(&sa.sa_mask) == -1)\n\t\tthrow std::system_error(errno, std::generic_category());\n\n\tif (sigaction(SIGNUM, &sa, NULL) == -1)\n\t\tthrow std::system_error(errno, std::generic_category());\n\n\t/* Signal is ignored in main thread, send it to background\n\t * thread and restore the default handler afterwards. */\n\tstop_thread();\n\n\tsa.sa_handler = SIG_DFL;\n\tif (sigaction(SIGNUM, &sa, NULL) == -1)\n\t\tthrow std::system_error(errno, std::generic_category());\n}\n\nvoid Timer::stop_thread(void) {\n\t/* Attempt to cancel thread first, for the event that it hasn't\n\t * invoked nanosleep yet. The nanosleep function is a\n\t * cancelation point, as per pthreads(7). If the thread is\n\t * blocked in nanosleep the signal should interrupt the\n\t * nanosleep system call and cause thread termination. */\n\n\tassert(running);\n\n\t// Either pthread_cancel or pthread_kill will stop the thread, in\n\t// which case the other one will error out thus the error is ignored.\n\tpthread_cancel(thread);\n\tpthread_kill(thread, SIGNUM);\n\n\tif ((errno = pthread_join(thread, NULL)))\n\t\tthrow std::system_error(errno, std::generic_category());\n\trunning = false;\n}\n"
  },
  {
    "path": "vp/src/core/common/timer.h",
    "content": "#ifndef RISCV_VP_TIMER_H\n#define RISCV_VP_TIMER_H\n\n#include <chrono>\n#include <system_error>\n\n#include <stdint.h>\n#include <pthread.h>\n#include <stdbool.h>\n\nclass Timer {\npublic:\n\ttypedef std::chrono::duration<uint64_t, std::micro> usecs;\n\n\ttypedef void (*Callback) (void*);\n\tclass Context {\n\tpublic:\n\t\tTimer::usecs duration;\n\t\tCallback fn;\n\t\tvoid *arg;\n\n\t\tContext(usecs _duration, Callback _fn, void *_arg)\n\t\t\t: duration(_duration), fn(_fn), arg(_arg) {};\n\t};\n\n\tTimer(Callback fn, void *arg);\n\t~Timer(void);\n\n\tvoid pause(void);\n\tvoid start(usecs duration);\n\nprivate:\n\tContext ctx;\n\tpthread_t thread;\n\tbool running;\n\n\tvoid stop_thread(void);\n};\n\n#endif\n"
  },
  {
    "path": "vp/src/core/common/trap.h",
    "content": "#pragma once\n\nenum ExceptionCode {\n\t// interrupt exception codes (mcause)\n\tEXC_U_SOFTWARE_INTERRUPT = 0,\n\tEXC_S_SOFTWARE_INTERRUPT = 1,\n\tEXC_M_SOFTWARE_INTERRUPT = 3,\n\n\tEXC_U_TIMER_INTERRUPT = 4,\n\tEXC_S_TIMER_INTERRUPT = 5,\n\tEXC_M_TIMER_INTERRUPT = 7,\n\n\tEXC_U_EXTERNAL_INTERRUPT = 8,\n\tEXC_S_EXTERNAL_INTERRUPT = 9,\n\tEXC_M_EXTERNAL_INTERRUPT = 11,\n\n\t// non-interrupt exception codes (mcause)\n\tEXC_INSTR_ADDR_MISALIGNED = 0,\n\tEXC_INSTR_ACCESS_FAULT = 1,\n\tEXC_ILLEGAL_INSTR = 2,\n\tEXC_BREAKPOINT = 3,\n\tEXC_LOAD_ADDR_MISALIGNED = 4,\n\tEXC_LOAD_ACCESS_FAULT = 5,\n\tEXC_STORE_AMO_ADDR_MISALIGNED = 6,\n\tEXC_STORE_AMO_ACCESS_FAULT = 7,\n\n\tEXC_ECALL_U_MODE = 8,\n\tEXC_ECALL_S_MODE = 9,\n\tEXC_ECALL_M_MODE = 11,\n\n\tEXC_INSTR_PAGE_FAULT = 12,\n\tEXC_LOAD_PAGE_FAULT = 13,\n\tEXC_STORE_AMO_PAGE_FAULT = 15,\n};\n\nstruct SimulationTrap {\n\tExceptionCode reason;\n\tunsigned long mtval;\n};\n\ninline void raise_trap(ExceptionCode exc, unsigned long mtval) {\n\tthrow SimulationTrap({exc, mtval});\n}\n"
  },
  {
    "path": "vp/src/core/rv32/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_library(rv32\n\t\tiss.cpp\n\t\tsyscall.cpp\n        ${HEADERS})\n\ntarget_link_libraries(rv32 systemc core-common softfloat)\n\n\nif(COLOR_THEME STREQUAL \"LIGHT\")\n\tmessage(\"> using color theme LIGHT\")\n\ttarget_compile_definitions(rv32 PRIVATE COLOR_THEME_LIGHT)\nelseif(COLOR_THEME STREQUAL \"DARK\")\n\tmessage(\"> using color theme DARK\")\n\ttarget_compile_definitions(rv32 PRIVATE COLOR_THEME_DARK)\nendif()\n\n\ntarget_include_directories(rv32 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\n"
  },
  {
    "path": "vp/src/core/rv32/csr.h",
    "content": "#pragma once\n\n#include <assert.h>\n#include <stdint.h>\n\n#include <stdexcept>\n#include <unordered_map>\n\n#include \"core/common/trap.h\"\n#include \"util/common.h\"\n\nnamespace rv32 {\n\nconstexpr unsigned FS_OFF = 0b00;\nconstexpr unsigned FS_INITIAL = 0b01;\nconstexpr unsigned FS_CLEAN = 0b10;\nconstexpr unsigned FS_DIRTY = 0b11;\n\ninline bool is_valid_privilege_level(PrivilegeLevel mode) {\n\treturn mode == MachineMode || mode == SupervisorMode || mode == UserMode;\n}\n\nstruct csr_32 {\n\tuint32_t reg = 0;\n};\n\nstruct csr_misa {\n\tcsr_misa() {\n\t\tinit();\n\t}\n\n\tunion {\n\t\tuint32_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned extensions : 26;\n\t\t\tunsigned wiri : 4;\n\t\t\tunsigned mxl : 2;\n\t\t} fields;\n\t};\n\n\tbool has_C_extension() {\n\t\treturn fields.extensions & C;\n\t}\n\n\tbool has_E_base_isa() {\n\t\treturn fields.extensions & E;\n\t}\n\n\tvoid select_E_base_isa() {\n\t\tfields.extensions &= ~I;\n\t\tfields.extensions |= E;\n\t}\n\n\tbool has_user_mode_extension() {\n\t\treturn fields.extensions & U;\n\t}\n\n\tbool has_supervisor_mode_extension() {\n\t\treturn fields.extensions & S;\n\t}\n\n\tenum {\n\t\tA = 1,\n\t\tC = 1 << 2,\n\t\tD = 1 << 3,\n\t\tE = 1 << 4,\n\t\tF = 1 << 5,\n\t\tI = 1 << 8,\n\t\tM = 1 << 12,\n\t\tN = 1 << 13,\n\t\tS = 1 << 18,\n\t\tU = 1 << 20,\n\t};\n\n\tvoid init() {\n\t\tfields.extensions = I | M | A | F | C | N | U | S;  // IMACF + NUS\n\t\tfields.wiri = 0;\n\t\tfields.mxl = 1;  // RV32\n\t}\n};\n\nconstexpr unsigned M_ISA_EXT = csr_misa::M;\nconstexpr unsigned A_ISA_EXT = csr_misa::A;\nconstexpr unsigned F_ISA_EXT = csr_misa::F;\nconstexpr unsigned D_ISA_EXT = csr_misa::D;\nconstexpr unsigned C_ISA_EXT = csr_misa::C;\n\nstruct csr_mvendorid {\n\tunion {\n\t\tuint32_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned offset : 7;\n\t\t\tunsigned bank : 25;\n\t\t} fields;\n\t};\n};\n\nstruct csr_mstatus {\n\tunion {\n\t\tuint32_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned uie : 1;\n\t\t\tunsigned sie : 1;\n\t\t\tunsigned wpri1 : 1;\n\t\t\tunsigned mie : 1;\n\t\t\tunsigned upie : 1;\n\t\t\tunsigned spie : 1;\n\t\t\tunsigned wpri2 : 1;\n\t\t\tunsigned mpie : 1;\n\t\t\tunsigned spp : 1;\n\t\t\tunsigned wpri3 : 2;\n\t\t\tunsigned mpp : 2;\n\t\t\tunsigned fs : 2;\n\t\t\tunsigned xs : 2;\n\t\t\tunsigned mprv : 1;\n\t\t\tunsigned sum : 1;\n\t\t\tunsigned mxr : 1;\n\t\t\tunsigned tvm : 1;\n\t\t\tunsigned tw : 1;\n\t\t\tunsigned tsr : 1;\n\t\t\tunsigned wpri4 : 8;\n\t\t\tunsigned sd : 1;\n\t\t} fields;\n\t};\n};\n\nstruct csr_mtvec {\n\tunion {\n\t\tuint32_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned mode : 2;   // WARL\n\t\t\tunsigned base : 30;  // WARL\n\t\t} fields;\n\t};\n\n\tuint32_t get_base_address() {\n\t\treturn fields.base << 2;\n\t}\n\n\tenum Mode { Direct = 0, Vectored = 1 };\n\n\tvoid checked_write(uint32_t val) {\n\t\treg = val;\n\t\tif (fields.mode >= 1)\n\t\t\tfields.mode = 0;\n\t}\n};\n\nstruct csr_mie {\n\tunion {\n\t\tuint32_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned usie : 1;\n\t\t\tunsigned ssie : 1;\n\t\t\tunsigned wpri1 : 1;\n\t\t\tunsigned msie : 1;\n\n\t\t\tunsigned utie : 1;\n\t\t\tunsigned stie : 1;\n\t\t\tunsigned wpri2 : 1;\n\t\t\tunsigned mtie : 1;\n\n\t\t\tunsigned ueie : 1;\n\t\t\tunsigned seie : 1;\n\t\t\tunsigned wpri3 : 1;\n\t\t\tunsigned meie : 1;\n\n\t\t\tunsigned wpri4 : 20;\n\t\t} fields;\n\t};\n};\n\nstruct csr_mip {\n\tunion {\n\t\tuint32_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned usip : 1;\n\t\t\tunsigned ssip : 1;\n\t\t\tunsigned wiri1 : 1;\n\t\t\tunsigned msip : 1;\n\n\t\t\tunsigned utip : 1;\n\t\t\tunsigned stip : 1;\n\t\t\tunsigned wiri2 : 1;\n\t\t\tunsigned mtip : 1;\n\n\t\t\tunsigned ueip : 1;\n\t\t\tunsigned seip : 1;\n\t\t\tunsigned wiri3 : 1;\n\t\t\tunsigned meip : 1;\n\n\t\t\tunsigned wiri4 : 20;\n\t\t} fields;\n\t};\n};\n\nstruct csr_mepc {\n\tunion {\n\t\tuint32_t reg = 0;\n\t};\n};\n\nstruct csr_mcause {\n\tunion {\n\t\tuint32_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned exception_code : 31;  // WLRL\n\t\t\tunsigned interrupt : 1;\n\t\t} fields;\n\t};\n};\n\nstruct csr_mcounteren {\n\tunion {\n\t\tuint32_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned CY : 1;\n\t\t\tunsigned TM : 1;\n\t\t\tunsigned IR : 1;\n\t\t\tunsigned reserved : 29;\n\t\t} fields;\n\t};\n};\n\nstruct csr_mcountinhibit {\n\tunion {\n\t\tuint32_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned CY : 1;\n\t\t\tunsigned zero : 1;\n\t\t\tunsigned IR : 1;\n\t\t\tunsigned reserved : 29;\n\t\t} fields;\n\t};\n};\n\nstruct csr_pmpcfg {\n\tunion {\n\t\tuint32_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned UNIMPLEMENTED : 24;  // WARL\n\t\t\tunsigned L0 : 1;              // WARL\n\t\t\tunsigned _wiri0 : 2;          // WIRI\n\t\t\tunsigned A0 : 2;              // WARL\n\t\t\tunsigned X0 : 1;              // WARL\n\t\t\tunsigned W0 : 1;              // WARL\n\t\t\tunsigned R0 : 1;              // WARL\n\t\t} fields;\n\t};\n};\n\nstruct csr_satp {\n\tunion {\n\t\tuint32_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned ppn : 22;  // WARL\n\t\t\tunsigned asid : 9;  // WARL\n\t\t\tunsigned mode : 1;  // WARL\n\t\t} fields;\n\t};\n};\n\nstruct csr_fcsr {\n\tunion {\n\t\tuint32_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned fflags : 5;\n\t\t\tunsigned frm : 3;\n\t\t\tunsigned reserved : 24;\n\t\t} fields;\n\t\t// fflags accessed separately\n\t\tstruct {\n\t\t\tunsigned NX : 1;  // invalid operation\n\t\t\tunsigned UF : 1;  // divide by zero\n\t\t\tunsigned OF : 1;  // overflow\n\t\t\tunsigned DZ : 1;  // underflow\n\t\t\tunsigned NV : 1;  // inexact\n\t\t\tunsigned _ : 27;\n\t\t} fflags;\n\t};\n};\n\n/*\n * Add new subclasses with specific consistency check (e.g. by adding virtual\n * write_low, write_high functions) if necessary.\n */\nstruct csr_64 {\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tint32_t low;\n\t\t\tint32_t high;\n\t\t} words;\n\t};\n\n\tvoid increment() {\n\t\t++reg;\n\t}\n};\n\nnamespace csr {\ntemplate <typename T>\ninline bool is_bitset(T &csr, unsigned bitpos) {\n\treturn csr.reg & (1 << bitpos);\n}\n\nconstexpr uint32_t MIE_MASK = 0b101110111011;\nconstexpr uint32_t SIE_MASK = 0b001100110011;\nconstexpr uint32_t UIE_MASK = 0b000100010001;\n\nconstexpr uint32_t MIP_WRITE_MASK = 0b001100110011;\nconstexpr uint32_t MIP_READ_MASK = MIE_MASK;\nconstexpr uint32_t SIP_MASK = 0b11;\nconstexpr uint32_t UIP_MASK = 0b1;\n\nconstexpr uint32_t MEDELEG_MASK = 0b1011101111111111;\nconstexpr uint32_t MIDELEG_MASK = MIE_MASK;\n\nconstexpr uint32_t MTVEC_MASK = ~2;\n\nconstexpr uint32_t MCOUNTEREN_MASK = 0b111;\nconstexpr uint32_t MCOUNTINHIBIT_MASK = 0b101;\n\nconstexpr uint32_t SEDELEG_MASK = 0b1011000111111111;\nconstexpr uint32_t SIDELEG_MASK = MIDELEG_MASK;\n\nconstexpr uint32_t MSTATUS_MASK = 0b10000000011111111111100110111011;\nconstexpr uint32_t SSTATUS_MASK = 0b10000000000011011110000100110011;\nconstexpr uint32_t USTATUS_MASK = 0b00000000000000000000000000010001;\n\nconstexpr uint32_t SATP_MASK = 0b10000000001111111111111111111111;\nconstexpr uint32_t SATP_MODE = 0b10000000000000000000000000000000;\n\nconstexpr uint32_t FCSR_MASK = 0b11111111;\n\n// 64 bit timer csrs\nconstexpr unsigned CYCLE_ADDR = 0xC00;\nconstexpr unsigned CYCLEH_ADDR = 0xC80;\nconstexpr unsigned TIME_ADDR = 0xC01;\nconstexpr unsigned TIMEH_ADDR = 0xC81;\nconstexpr unsigned INSTRET_ADDR = 0xC02;\nconstexpr unsigned INSTRETH_ADDR = 0xC82;\n\n// shadows for the above CSRs\nconstexpr unsigned MCYCLE_ADDR = 0xB00;\nconstexpr unsigned MCYCLEH_ADDR = 0xB80;\nconstexpr unsigned MTIME_ADDR = 0xB01;\nconstexpr unsigned MTIMEH_ADDR = 0xB81;\nconstexpr unsigned MINSTRET_ADDR = 0xB02;\nconstexpr unsigned MINSTRETH_ADDR = 0xB82;\n\n// debug CSRs\nconstexpr unsigned TSELECT_ADDR = 0x7A0;\nconstexpr unsigned TDATA1_ADDR = 0x7A1;\nconstexpr unsigned TDATA2_ADDR = 0x7A2;\nconstexpr unsigned TDATA3_ADDR = 0x7A3;\nconstexpr unsigned DCSR_ADDR = 0x7B0;\nconstexpr unsigned DPC_ADDR = 0x7B1;\nconstexpr unsigned DSCRATCH0_ADDR = 0x7B2;\nconstexpr unsigned DSCRATCH1_ADDR = 0x7B3;\n\n// 32 bit machine CSRs\nconstexpr unsigned MVENDORID_ADDR = 0xF11;\nconstexpr unsigned MARCHID_ADDR = 0xF12;\nconstexpr unsigned MIMPID_ADDR = 0xF13;\nconstexpr unsigned MHARTID_ADDR = 0xF14;\n\nconstexpr unsigned MSTATUS_ADDR = 0x300;\nconstexpr unsigned MISA_ADDR = 0x301;\nconstexpr unsigned MEDELEG_ADDR = 0x302;\nconstexpr unsigned MIDELEG_ADDR = 0x303;\nconstexpr unsigned MIE_ADDR = 0x304;\nconstexpr unsigned MTVEC_ADDR = 0x305;\nconstexpr unsigned MCOUNTEREN_ADDR = 0x306;\nconstexpr unsigned MCOUNTINHIBIT_ADDR = 0x320;\n\nconstexpr unsigned MSCRATCH_ADDR = 0x340;\nconstexpr unsigned MEPC_ADDR = 0x341;\nconstexpr unsigned MCAUSE_ADDR = 0x342;\nconstexpr unsigned MTVAL_ADDR = 0x343;\nconstexpr unsigned MIP_ADDR = 0x344;\n\nconstexpr unsigned PMPCFG0_ADDR = 0x3A0;\nconstexpr unsigned PMPCFG1_ADDR = 0x3A1;\nconstexpr unsigned PMPCFG2_ADDR = 0x3A2;\nconstexpr unsigned PMPCFG3_ADDR = 0x3A3;\n\nconstexpr unsigned PMPADDR0_ADDR = 0x3B0;\nconstexpr unsigned PMPADDR1_ADDR = 0x3B1;\nconstexpr unsigned PMPADDR2_ADDR = 0x3B2;\nconstexpr unsigned PMPADDR3_ADDR = 0x3B3;\nconstexpr unsigned PMPADDR4_ADDR = 0x3B4;\nconstexpr unsigned PMPADDR5_ADDR = 0x3B5;\nconstexpr unsigned PMPADDR6_ADDR = 0x3B6;\nconstexpr unsigned PMPADDR7_ADDR = 0x3B7;\nconstexpr unsigned PMPADDR8_ADDR = 0x3B8;\nconstexpr unsigned PMPADDR9_ADDR = 0x3B9;\nconstexpr unsigned PMPADDR10_ADDR = 0x3BA;\nconstexpr unsigned PMPADDR11_ADDR = 0x3BB;\nconstexpr unsigned PMPADDR12_ADDR = 0x3BC;\nconstexpr unsigned PMPADDR13_ADDR = 0x3BD;\nconstexpr unsigned PMPADDR14_ADDR = 0x3BE;\nconstexpr unsigned PMPADDR15_ADDR = 0x3BF;\n\n// 32 bit supervisor CSRs\nconstexpr unsigned SSTATUS_ADDR = 0x100;\nconstexpr unsigned SEDELEG_ADDR = 0x102;\nconstexpr unsigned SIDELEG_ADDR = 0x103;\nconstexpr unsigned SIE_ADDR = 0x104;\nconstexpr unsigned STVEC_ADDR = 0x105;\nconstexpr unsigned SCOUNTEREN_ADDR = 0x106;\nconstexpr unsigned SSCRATCH_ADDR = 0x140;\nconstexpr unsigned SEPC_ADDR = 0x141;\nconstexpr unsigned SCAUSE_ADDR = 0x142;\nconstexpr unsigned STVAL_ADDR = 0x143;\nconstexpr unsigned SIP_ADDR = 0x144;\nconstexpr unsigned SATP_ADDR = 0x180;\n\n// 32 bit user CSRs\nconstexpr unsigned USTATUS_ADDR = 0x000;\nconstexpr unsigned UIE_ADDR = 0x004;\nconstexpr unsigned UTVEC_ADDR = 0x005;\nconstexpr unsigned USCRATCH_ADDR = 0x040;\nconstexpr unsigned UEPC_ADDR = 0x041;\nconstexpr unsigned UCAUSE_ADDR = 0x042;\nconstexpr unsigned UTVAL_ADDR = 0x043;\nconstexpr unsigned UIP_ADDR = 0x044;\n\n// floating point CSRs\nconstexpr unsigned FFLAGS_ADDR = 0x001;\nconstexpr unsigned FRM_ADDR = 0x002;\nconstexpr unsigned FCSR_ADDR = 0x003;\n\n// performance counters\nconstexpr unsigned HPMCOUNTER3_ADDR = 0xC03;\nconstexpr unsigned HPMCOUNTER4_ADDR = 0xC04;\nconstexpr unsigned HPMCOUNTER5_ADDR = 0xC05;\nconstexpr unsigned HPMCOUNTER6_ADDR = 0xC06;\nconstexpr unsigned HPMCOUNTER7_ADDR = 0xC07;\nconstexpr unsigned HPMCOUNTER8_ADDR = 0xC08;\nconstexpr unsigned HPMCOUNTER9_ADDR = 0xC09;\nconstexpr unsigned HPMCOUNTER10_ADDR = 0xC0A;\nconstexpr unsigned HPMCOUNTER11_ADDR = 0xC0B;\nconstexpr unsigned HPMCOUNTER12_ADDR = 0xC0C;\nconstexpr unsigned HPMCOUNTER13_ADDR = 0xC0D;\nconstexpr unsigned HPMCOUNTER14_ADDR = 0xC0E;\nconstexpr unsigned HPMCOUNTER15_ADDR = 0xC0F;\nconstexpr unsigned HPMCOUNTER16_ADDR = 0xC10;\nconstexpr unsigned HPMCOUNTER17_ADDR = 0xC11;\nconstexpr unsigned HPMCOUNTER18_ADDR = 0xC12;\nconstexpr unsigned HPMCOUNTER19_ADDR = 0xC13;\nconstexpr unsigned HPMCOUNTER20_ADDR = 0xC14;\nconstexpr unsigned HPMCOUNTER21_ADDR = 0xC15;\nconstexpr unsigned HPMCOUNTER22_ADDR = 0xC16;\nconstexpr unsigned HPMCOUNTER23_ADDR = 0xC17;\nconstexpr unsigned HPMCOUNTER24_ADDR = 0xC18;\nconstexpr unsigned HPMCOUNTER25_ADDR = 0xC19;\nconstexpr unsigned HPMCOUNTER26_ADDR = 0xC1A;\nconstexpr unsigned HPMCOUNTER27_ADDR = 0xC1B;\nconstexpr unsigned HPMCOUNTER28_ADDR = 0xC1C;\nconstexpr unsigned HPMCOUNTER29_ADDR = 0xC1D;\nconstexpr unsigned HPMCOUNTER30_ADDR = 0xC1E;\nconstexpr unsigned HPMCOUNTER31_ADDR = 0xC1F;\n\nconstexpr unsigned HPMCOUNTER3H_ADDR = 0xC83;\nconstexpr unsigned HPMCOUNTER4H_ADDR = 0xC84;\nconstexpr unsigned HPMCOUNTER5H_ADDR = 0xC85;\nconstexpr unsigned HPMCOUNTER6H_ADDR = 0xC86;\nconstexpr unsigned HPMCOUNTER7H_ADDR = 0xC87;\nconstexpr unsigned HPMCOUNTER8H_ADDR = 0xC88;\nconstexpr unsigned HPMCOUNTER9H_ADDR = 0xC89;\nconstexpr unsigned HPMCOUNTER10H_ADDR = 0xC8A;\nconstexpr unsigned HPMCOUNTER11H_ADDR = 0xC8B;\nconstexpr unsigned HPMCOUNTER12H_ADDR = 0xC8C;\nconstexpr unsigned HPMCOUNTER13H_ADDR = 0xC8D;\nconstexpr unsigned HPMCOUNTER14H_ADDR = 0xC8E;\nconstexpr unsigned HPMCOUNTER15H_ADDR = 0xC8F;\nconstexpr unsigned HPMCOUNTER16H_ADDR = 0xC90;\nconstexpr unsigned HPMCOUNTER17H_ADDR = 0xC91;\nconstexpr unsigned HPMCOUNTER18H_ADDR = 0xC92;\nconstexpr unsigned HPMCOUNTER19H_ADDR = 0xC93;\nconstexpr unsigned HPMCOUNTER20H_ADDR = 0xC94;\nconstexpr unsigned HPMCOUNTER21H_ADDR = 0xC95;\nconstexpr unsigned HPMCOUNTER22H_ADDR = 0xC96;\nconstexpr unsigned HPMCOUNTER23H_ADDR = 0xC97;\nconstexpr unsigned HPMCOUNTER24H_ADDR = 0xC98;\nconstexpr unsigned HPMCOUNTER25H_ADDR = 0xC99;\nconstexpr unsigned HPMCOUNTER26H_ADDR = 0xC9A;\nconstexpr unsigned HPMCOUNTER27H_ADDR = 0xC9B;\nconstexpr unsigned HPMCOUNTER28H_ADDR = 0xC9C;\nconstexpr unsigned HPMCOUNTER29H_ADDR = 0xC9D;\nconstexpr unsigned HPMCOUNTER30H_ADDR = 0xC9E;\nconstexpr unsigned HPMCOUNTER31H_ADDR = 0xC9F;\n\nconstexpr unsigned MHPMCOUNTER3_ADDR = 0xB03;\nconstexpr unsigned MHPMCOUNTER4_ADDR = 0xB04;\nconstexpr unsigned MHPMCOUNTER5_ADDR = 0xB05;\nconstexpr unsigned MHPMCOUNTER6_ADDR = 0xB06;\nconstexpr unsigned MHPMCOUNTER7_ADDR = 0xB07;\nconstexpr unsigned MHPMCOUNTER8_ADDR = 0xB08;\nconstexpr unsigned MHPMCOUNTER9_ADDR = 0xB09;\nconstexpr unsigned MHPMCOUNTER10_ADDR = 0xB0A;\nconstexpr unsigned MHPMCOUNTER11_ADDR = 0xB0B;\nconstexpr unsigned MHPMCOUNTER12_ADDR = 0xB0C;\nconstexpr unsigned MHPMCOUNTER13_ADDR = 0xB0D;\nconstexpr unsigned MHPMCOUNTER14_ADDR = 0xB0E;\nconstexpr unsigned MHPMCOUNTER15_ADDR = 0xB0F;\nconstexpr unsigned MHPMCOUNTER16_ADDR = 0xB10;\nconstexpr unsigned MHPMCOUNTER17_ADDR = 0xB11;\nconstexpr unsigned MHPMCOUNTER18_ADDR = 0xB12;\nconstexpr unsigned MHPMCOUNTER19_ADDR = 0xB13;\nconstexpr unsigned MHPMCOUNTER20_ADDR = 0xB14;\nconstexpr unsigned MHPMCOUNTER21_ADDR = 0xB15;\nconstexpr unsigned MHPMCOUNTER22_ADDR = 0xB16;\nconstexpr unsigned MHPMCOUNTER23_ADDR = 0xB17;\nconstexpr unsigned MHPMCOUNTER24_ADDR = 0xB18;\nconstexpr unsigned MHPMCOUNTER25_ADDR = 0xB19;\nconstexpr unsigned MHPMCOUNTER26_ADDR = 0xB1A;\nconstexpr unsigned MHPMCOUNTER27_ADDR = 0xB1B;\nconstexpr unsigned MHPMCOUNTER28_ADDR = 0xB1C;\nconstexpr unsigned MHPMCOUNTER29_ADDR = 0xB1D;\nconstexpr unsigned MHPMCOUNTER30_ADDR = 0xB1E;\nconstexpr unsigned MHPMCOUNTER31_ADDR = 0xB1F;\n\nconstexpr unsigned MHPMCOUNTER3H_ADDR = 0xB83;\nconstexpr unsigned MHPMCOUNTER4H_ADDR = 0xB84;\nconstexpr unsigned MHPMCOUNTER5H_ADDR = 0xB85;\nconstexpr unsigned MHPMCOUNTER6H_ADDR = 0xB86;\nconstexpr unsigned MHPMCOUNTER7H_ADDR = 0xB87;\nconstexpr unsigned MHPMCOUNTER8H_ADDR = 0xB88;\nconstexpr unsigned MHPMCOUNTER9H_ADDR = 0xB89;\nconstexpr unsigned MHPMCOUNTER10H_ADDR = 0xB8A;\nconstexpr unsigned MHPMCOUNTER11H_ADDR = 0xB8B;\nconstexpr unsigned MHPMCOUNTER12H_ADDR = 0xB8C;\nconstexpr unsigned MHPMCOUNTER13H_ADDR = 0xB8D;\nconstexpr unsigned MHPMCOUNTER14H_ADDR = 0xB8E;\nconstexpr unsigned MHPMCOUNTER15H_ADDR = 0xB8F;\nconstexpr unsigned MHPMCOUNTER16H_ADDR = 0xB90;\nconstexpr unsigned MHPMCOUNTER17H_ADDR = 0xB91;\nconstexpr unsigned MHPMCOUNTER18H_ADDR = 0xB92;\nconstexpr unsigned MHPMCOUNTER19H_ADDR = 0xB93;\nconstexpr unsigned MHPMCOUNTER20H_ADDR = 0xB94;\nconstexpr unsigned MHPMCOUNTER21H_ADDR = 0xB95;\nconstexpr unsigned MHPMCOUNTER22H_ADDR = 0xB96;\nconstexpr unsigned MHPMCOUNTER23H_ADDR = 0xB97;\nconstexpr unsigned MHPMCOUNTER24H_ADDR = 0xB98;\nconstexpr unsigned MHPMCOUNTER25H_ADDR = 0xB99;\nconstexpr unsigned MHPMCOUNTER26H_ADDR = 0xB9A;\nconstexpr unsigned MHPMCOUNTER27H_ADDR = 0xB9B;\nconstexpr unsigned MHPMCOUNTER28H_ADDR = 0xB9C;\nconstexpr unsigned MHPMCOUNTER29H_ADDR = 0xB9D;\nconstexpr unsigned MHPMCOUNTER30H_ADDR = 0xB9E;\nconstexpr unsigned MHPMCOUNTER31H_ADDR = 0xB9F;\n\nconstexpr unsigned MHPMEVENT3_ADDR = 0x323;\nconstexpr unsigned MHPMEVENT4_ADDR = 0x324;\nconstexpr unsigned MHPMEVENT5_ADDR = 0x325;\nconstexpr unsigned MHPMEVENT6_ADDR = 0x326;\nconstexpr unsigned MHPMEVENT7_ADDR = 0x327;\nconstexpr unsigned MHPMEVENT8_ADDR = 0x328;\nconstexpr unsigned MHPMEVENT9_ADDR = 0x329;\nconstexpr unsigned MHPMEVENT10_ADDR = 0x32A;\nconstexpr unsigned MHPMEVENT11_ADDR = 0x32B;\nconstexpr unsigned MHPMEVENT12_ADDR = 0x32C;\nconstexpr unsigned MHPMEVENT13_ADDR = 0x32D;\nconstexpr unsigned MHPMEVENT14_ADDR = 0x32E;\nconstexpr unsigned MHPMEVENT15_ADDR = 0x32F;\nconstexpr unsigned MHPMEVENT16_ADDR = 0x330;\nconstexpr unsigned MHPMEVENT17_ADDR = 0x331;\nconstexpr unsigned MHPMEVENT18_ADDR = 0x332;\nconstexpr unsigned MHPMEVENT19_ADDR = 0x333;\nconstexpr unsigned MHPMEVENT20_ADDR = 0x334;\nconstexpr unsigned MHPMEVENT21_ADDR = 0x335;\nconstexpr unsigned MHPMEVENT22_ADDR = 0x336;\nconstexpr unsigned MHPMEVENT23_ADDR = 0x337;\nconstexpr unsigned MHPMEVENT24_ADDR = 0x338;\nconstexpr unsigned MHPMEVENT25_ADDR = 0x339;\nconstexpr unsigned MHPMEVENT26_ADDR = 0x33A;\nconstexpr unsigned MHPMEVENT27_ADDR = 0x33B;\nconstexpr unsigned MHPMEVENT28_ADDR = 0x33C;\nconstexpr unsigned MHPMEVENT29_ADDR = 0x33D;\nconstexpr unsigned MHPMEVENT30_ADDR = 0x33E;\nconstexpr unsigned MHPMEVENT31_ADDR = 0x33F;\n};  // namespace csr\n\nstruct csr_table {\n\tcsr_64 cycle;\n\tcsr_64 time;\n\tcsr_64 instret;\n\n\tcsr_mvendorid mvendorid;\n\tcsr_32 marchid;\n\tcsr_32 mimpid;\n\tcsr_32 mhartid;\n\n\tcsr_mstatus mstatus;\n\tcsr_misa misa;\n\tcsr_32 medeleg;\n\tcsr_32 mideleg;\n\tcsr_mie mie;\n\tcsr_mtvec mtvec;\n\tcsr_mcounteren mcounteren;\n\tcsr_mcountinhibit mcountinhibit;\n\n\tcsr_32 mscratch;\n\tcsr_mepc mepc;\n\tcsr_mcause mcause;\n\tcsr_32 mtval;\n\tcsr_mip mip;\n\n\t// pmp configuration\n\tstd::array<csr_32, 16> pmpaddr;\n\tstd::array<csr_pmpcfg, 4> pmpcfg;\n\n\t// supervisor csrs (please note: some are already covered by the machine mode csrs, i.e. sstatus, sie and sip, and\n\t// some are required but have the same fields, hence the machine mode classes are used)\n\tcsr_32 sedeleg;\n\tcsr_32 sideleg;\n\tcsr_mtvec stvec;\n\tcsr_mcounteren scounteren;\n\tcsr_32 sscratch;\n\tcsr_mepc sepc;\n\tcsr_mcause scause;\n\tcsr_32 stval;\n\tcsr_satp satp;\n\n\t// user csrs (see above comment)\n\tcsr_mtvec utvec;\n\tcsr_32 uscratch;\n\tcsr_mepc uepc;\n\tcsr_mcause ucause;\n\tcsr_32 utval;\n\n\tcsr_fcsr fcsr;\n\n\tstd::unordered_map<unsigned, uint32_t *> register_mapping;\n\n\tcsr_table() {\n\t\tusing namespace csr;\n\n\t\tregister_mapping[CYCLE_ADDR] = (uint32_t *)(&cycle.reg);\n\t\tregister_mapping[CYCLEH_ADDR] = (uint32_t *)(&cycle.reg) + 1;\n\t\tregister_mapping[TIME_ADDR] = (uint32_t *)(&time.reg);\n\t\tregister_mapping[TIMEH_ADDR] = (uint32_t *)(&time.reg) + 1;\n\t\tregister_mapping[INSTRET_ADDR] = (uint32_t *)(&instret.reg);\n\t\tregister_mapping[INSTRETH_ADDR] = (uint32_t *)(&instret.reg) + 1;\n\t\tregister_mapping[MCYCLE_ADDR] = (uint32_t *)(&cycle.reg);\n\t\tregister_mapping[MCYCLEH_ADDR] = (uint32_t *)(&cycle.reg) + 1;\n\t\tregister_mapping[MTIME_ADDR] = (uint32_t *)(&time.reg);\n\t\tregister_mapping[MTIMEH_ADDR] = (uint32_t *)(&time.reg) + 1;\n\t\tregister_mapping[MINSTRET_ADDR] = (uint32_t *)(&instret.reg);\n\t\tregister_mapping[MINSTRETH_ADDR] = (uint32_t *)(&instret.reg) + 1;\n\n\t\tregister_mapping[MVENDORID_ADDR] = &mvendorid.reg;\n\t\tregister_mapping[MARCHID_ADDR] = &marchid.reg;\n\t\tregister_mapping[MIMPID_ADDR] = &mimpid.reg;\n\t\tregister_mapping[MHARTID_ADDR] = &mhartid.reg;\n\n\t\tregister_mapping[MSTATUS_ADDR] = &mstatus.reg;\n\t\tregister_mapping[MISA_ADDR] = &misa.reg;\n\t\tregister_mapping[MEDELEG_ADDR] = &medeleg.reg;\n\t\tregister_mapping[MIDELEG_ADDR] = &mideleg.reg;\n\t\tregister_mapping[MIE_ADDR] = &mie.reg;\n\t\tregister_mapping[MTVEC_ADDR] = &mtvec.reg;\n\t\tregister_mapping[MCOUNTEREN_ADDR] = &mcounteren.reg;\n\t\tregister_mapping[MCOUNTINHIBIT_ADDR] = &mcountinhibit.reg;\n\n\t\tregister_mapping[MSCRATCH_ADDR] = &mscratch.reg;\n\t\tregister_mapping[MEPC_ADDR] = &mepc.reg;\n\t\tregister_mapping[MCAUSE_ADDR] = &mcause.reg;\n\t\tregister_mapping[MTVAL_ADDR] = &mtval.reg;\n\t\tregister_mapping[MIP_ADDR] = &mip.reg;\n\n\t\tfor (unsigned i = 0; i < 16; ++i) register_mapping[PMPADDR0_ADDR + i] = &pmpaddr[i].reg;\n\n\t\tfor (unsigned i = 0; i < 4; ++i) register_mapping[PMPCFG0_ADDR + i] = &pmpcfg[i].reg;\n\n\t\tregister_mapping[SEDELEG_ADDR] = &sedeleg.reg;\n\t\tregister_mapping[SIDELEG_ADDR] = &sideleg.reg;\n\t\tregister_mapping[STVEC_ADDR] = &stvec.reg;\n\t\tregister_mapping[SCOUNTEREN_ADDR] = &scounteren.reg;\n\t\tregister_mapping[SSCRATCH_ADDR] = &sscratch.reg;\n\t\tregister_mapping[SEPC_ADDR] = &sepc.reg;\n\t\tregister_mapping[SCAUSE_ADDR] = &scause.reg;\n\t\tregister_mapping[STVAL_ADDR] = &stval.reg;\n\t\tregister_mapping[SATP_ADDR] = &satp.reg;\n\n\t\tregister_mapping[UTVEC_ADDR] = &utvec.reg;\n\t\tregister_mapping[USCRATCH_ADDR] = &uscratch.reg;\n\t\tregister_mapping[UEPC_ADDR] = &uepc.reg;\n\t\tregister_mapping[UCAUSE_ADDR] = &ucause.reg;\n\t\tregister_mapping[UTVAL_ADDR] = &utval.reg;\n\n\t\tregister_mapping[FCSR_ADDR] = &fcsr.reg;\n\t}\n\n\tbool is_valid_csr32_addr(unsigned addr) {\n\t\treturn register_mapping.find(addr) != register_mapping.end();\n\t}\n\n\tvoid default_write32(unsigned addr, uint32_t value) {\n\t\tauto it = register_mapping.find(addr);\n\t\tensure((it != register_mapping.end()) && \"validate address before calling this function\");\n\t\t*it->second = value;\n\t}\n\n\tuint32_t default_read32(unsigned addr) {\n\t\tauto it = register_mapping.find(addr);\n\t\tensure((it != register_mapping.end()) && \"validate address before calling this function\");\n\t\treturn *it->second;\n\t}\n};\n\n#define SWITCH_CASE_MATCH_ANY_HPMCOUNTER_RV32 \\\n\tcase HPMCOUNTER3_ADDR:                    \\\n\tcase HPMCOUNTER4_ADDR:                    \\\n\tcase HPMCOUNTER5_ADDR:                    \\\n\tcase HPMCOUNTER6_ADDR:                    \\\n\tcase HPMCOUNTER7_ADDR:                    \\\n\tcase HPMCOUNTER8_ADDR:                    \\\n\tcase HPMCOUNTER9_ADDR:                    \\\n\tcase HPMCOUNTER10_ADDR:                   \\\n\tcase HPMCOUNTER11_ADDR:                   \\\n\tcase HPMCOUNTER12_ADDR:                   \\\n\tcase HPMCOUNTER13_ADDR:                   \\\n\tcase HPMCOUNTER14_ADDR:                   \\\n\tcase HPMCOUNTER15_ADDR:                   \\\n\tcase HPMCOUNTER16_ADDR:                   \\\n\tcase HPMCOUNTER17_ADDR:                   \\\n\tcase HPMCOUNTER18_ADDR:                   \\\n\tcase HPMCOUNTER19_ADDR:                   \\\n\tcase HPMCOUNTER20_ADDR:                   \\\n\tcase HPMCOUNTER21_ADDR:                   \\\n\tcase HPMCOUNTER22_ADDR:                   \\\n\tcase HPMCOUNTER23_ADDR:                   \\\n\tcase HPMCOUNTER24_ADDR:                   \\\n\tcase HPMCOUNTER25_ADDR:                   \\\n\tcase HPMCOUNTER26_ADDR:                   \\\n\tcase HPMCOUNTER27_ADDR:                   \\\n\tcase HPMCOUNTER28_ADDR:                   \\\n\tcase HPMCOUNTER29_ADDR:                   \\\n\tcase HPMCOUNTER30_ADDR:                   \\\n\tcase HPMCOUNTER31_ADDR:                   \\\n\tcase HPMCOUNTER3H_ADDR:                   \\\n\tcase HPMCOUNTER4H_ADDR:                   \\\n\tcase HPMCOUNTER5H_ADDR:                   \\\n\tcase HPMCOUNTER6H_ADDR:                   \\\n\tcase HPMCOUNTER7H_ADDR:                   \\\n\tcase HPMCOUNTER8H_ADDR:                   \\\n\tcase HPMCOUNTER9H_ADDR:                   \\\n\tcase HPMCOUNTER10H_ADDR:                  \\\n\tcase HPMCOUNTER11H_ADDR:                  \\\n\tcase HPMCOUNTER12H_ADDR:                  \\\n\tcase HPMCOUNTER13H_ADDR:                  \\\n\tcase HPMCOUNTER14H_ADDR:                  \\\n\tcase HPMCOUNTER15H_ADDR:                  \\\n\tcase HPMCOUNTER16H_ADDR:                  \\\n\tcase HPMCOUNTER17H_ADDR:                  \\\n\tcase HPMCOUNTER18H_ADDR:                  \\\n\tcase HPMCOUNTER19H_ADDR:                  \\\n\tcase HPMCOUNTER20H_ADDR:                  \\\n\tcase HPMCOUNTER21H_ADDR:                  \\\n\tcase HPMCOUNTER22H_ADDR:                  \\\n\tcase HPMCOUNTER23H_ADDR:                  \\\n\tcase HPMCOUNTER24H_ADDR:                  \\\n\tcase HPMCOUNTER25H_ADDR:                  \\\n\tcase HPMCOUNTER26H_ADDR:                  \\\n\tcase HPMCOUNTER27H_ADDR:                  \\\n\tcase HPMCOUNTER28H_ADDR:                  \\\n\tcase HPMCOUNTER29H_ADDR:                  \\\n\tcase HPMCOUNTER30H_ADDR:                  \\\n\tcase HPMCOUNTER31H_ADDR:                  \\\n\tcase MHPMCOUNTER3_ADDR:                   \\\n\tcase MHPMCOUNTER4_ADDR:                   \\\n\tcase MHPMCOUNTER5_ADDR:                   \\\n\tcase MHPMCOUNTER6_ADDR:                   \\\n\tcase MHPMCOUNTER7_ADDR:                   \\\n\tcase MHPMCOUNTER8_ADDR:                   \\\n\tcase MHPMCOUNTER9_ADDR:                   \\\n\tcase MHPMCOUNTER10_ADDR:                  \\\n\tcase MHPMCOUNTER11_ADDR:                  \\\n\tcase MHPMCOUNTER12_ADDR:                  \\\n\tcase MHPMCOUNTER13_ADDR:                  \\\n\tcase MHPMCOUNTER14_ADDR:                  \\\n\tcase MHPMCOUNTER15_ADDR:                  \\\n\tcase MHPMCOUNTER16_ADDR:                  \\\n\tcase MHPMCOUNTER17_ADDR:                  \\\n\tcase MHPMCOUNTER18_ADDR:                  \\\n\tcase MHPMCOUNTER19_ADDR:                  \\\n\tcase MHPMCOUNTER20_ADDR:                  \\\n\tcase MHPMCOUNTER21_ADDR:                  \\\n\tcase MHPMCOUNTER22_ADDR:                  \\\n\tcase MHPMCOUNTER23_ADDR:                  \\\n\tcase MHPMCOUNTER24_ADDR:                  \\\n\tcase MHPMCOUNTER25_ADDR:                  \\\n\tcase MHPMCOUNTER26_ADDR:                  \\\n\tcase MHPMCOUNTER27_ADDR:                  \\\n\tcase MHPMCOUNTER28_ADDR:                  \\\n\tcase MHPMCOUNTER29_ADDR:                  \\\n\tcase MHPMCOUNTER30_ADDR:                  \\\n\tcase MHPMCOUNTER31_ADDR:                  \\\n\tcase MHPMCOUNTER3H_ADDR:                  \\\n\tcase MHPMCOUNTER4H_ADDR:                  \\\n\tcase MHPMCOUNTER5H_ADDR:                  \\\n\tcase MHPMCOUNTER6H_ADDR:                  \\\n\tcase MHPMCOUNTER7H_ADDR:                  \\\n\tcase MHPMCOUNTER8H_ADDR:                  \\\n\tcase MHPMCOUNTER9H_ADDR:                  \\\n\tcase MHPMCOUNTER10H_ADDR:                 \\\n\tcase MHPMCOUNTER11H_ADDR:                 \\\n\tcase MHPMCOUNTER12H_ADDR:                 \\\n\tcase MHPMCOUNTER13H_ADDR:                 \\\n\tcase MHPMCOUNTER14H_ADDR:                 \\\n\tcase MHPMCOUNTER15H_ADDR:                 \\\n\tcase MHPMCOUNTER16H_ADDR:                 \\\n\tcase MHPMCOUNTER17H_ADDR:                 \\\n\tcase MHPMCOUNTER18H_ADDR:                 \\\n\tcase MHPMCOUNTER19H_ADDR:                 \\\n\tcase MHPMCOUNTER20H_ADDR:                 \\\n\tcase MHPMCOUNTER21H_ADDR:                 \\\n\tcase MHPMCOUNTER22H_ADDR:                 \\\n\tcase MHPMCOUNTER23H_ADDR:                 \\\n\tcase MHPMCOUNTER24H_ADDR:                 \\\n\tcase MHPMCOUNTER25H_ADDR:                 \\\n\tcase MHPMCOUNTER26H_ADDR:                 \\\n\tcase MHPMCOUNTER27H_ADDR:                 \\\n\tcase MHPMCOUNTER28H_ADDR:                 \\\n\tcase MHPMCOUNTER29H_ADDR:                 \\\n\tcase MHPMCOUNTER30H_ADDR:                 \\\n\tcase MHPMCOUNTER31H_ADDR:                 \\\n\tcase MHPMEVENT3_ADDR:                     \\\n\tcase MHPMEVENT4_ADDR:                     \\\n\tcase MHPMEVENT5_ADDR:                     \\\n\tcase MHPMEVENT6_ADDR:                     \\\n\tcase MHPMEVENT7_ADDR:                     \\\n\tcase MHPMEVENT8_ADDR:                     \\\n\tcase MHPMEVENT9_ADDR:                     \\\n\tcase MHPMEVENT10_ADDR:                    \\\n\tcase MHPMEVENT11_ADDR:                    \\\n\tcase MHPMEVENT12_ADDR:                    \\\n\tcase MHPMEVENT13_ADDR:                    \\\n\tcase MHPMEVENT14_ADDR:                    \\\n\tcase MHPMEVENT15_ADDR:                    \\\n\tcase MHPMEVENT16_ADDR:                    \\\n\tcase MHPMEVENT17_ADDR:                    \\\n\tcase MHPMEVENT18_ADDR:                    \\\n\tcase MHPMEVENT19_ADDR:                    \\\n\tcase MHPMEVENT20_ADDR:                    \\\n\tcase MHPMEVENT21_ADDR:                    \\\n\tcase MHPMEVENT22_ADDR:                    \\\n\tcase MHPMEVENT23_ADDR:                    \\\n\tcase MHPMEVENT24_ADDR:                    \\\n\tcase MHPMEVENT25_ADDR:                    \\\n\tcase MHPMEVENT26_ADDR:                    \\\n\tcase MHPMEVENT27_ADDR:                    \\\n\tcase MHPMEVENT28_ADDR:                    \\\n\tcase MHPMEVENT29_ADDR:                    \\\n\tcase MHPMEVENT30_ADDR:                    \\\n\tcase MHPMEVENT31_ADDR\n\n}  // namespace rv32\n"
  },
  {
    "path": "vp/src/core/rv32/elf_loader.h",
    "content": "#pragma once\n\n#include \"core/common/elf_loader.h\"\n\nnamespace rv32 {\n\n// see: http://wiki.osdev.org/ELF_Tutorial for ELF definitions\n\ntypedef uint16_t Elf32_Half;  // Unsigned half int\ntypedef uint32_t Elf32_Off;   // Unsigned offset\ntypedef uint32_t Elf32_Addr;  // Unsigned address\ntypedef uint32_t Elf32_Word;  // Unsigned int\ntypedef int32_t Elf32_Sword;  // Signed int\n\nconstexpr unsigned ELF_NIDENT = 16;\n\ntypedef struct {\n\tuint8_t e_ident[ELF_NIDENT];\n\tElf32_Half e_type;\n\tElf32_Half e_machine;\n\tElf32_Word e_version;\n\tElf32_Addr e_entry;\n\tElf32_Off e_phoff;\n\tElf32_Off e_shoff;\n\tElf32_Word e_flags;\n\tElf32_Half e_ehsize;\n\tElf32_Half e_phentsize;\n\tElf32_Half e_phnum;\n\tElf32_Half e_shentsize;\n\tElf32_Half e_shnum;\n\tElf32_Half e_shstrndx;\n} Elf32_Ehdr;\n\ntypedef struct {\n\tElf32_Word p_type;\n\tElf32_Off p_offset;\n\tElf32_Addr p_vaddr;\n\tElf32_Addr p_paddr;\n\tElf32_Word p_filesz;\n\tElf32_Word p_memsz;\n\tElf32_Word p_flags;\n\tElf32_Word p_align;\n} Elf32_Phdr;\n\ntypedef struct {\n\tElf32_Word sh_name;\n\tElf32_Word sh_type;\n\tElf32_Word sh_flags;\n\tElf32_Addr sh_addr;\n\tElf32_Off sh_offset;\n\tElf32_Word sh_size;\n\tElf32_Word sh_link;\n\tElf32_Word sh_info;\n\tElf32_Word sh_addralign;\n\tElf32_Word sh_entsize;\n} Elf32_Shdr;\n\ntypedef struct {\n\tElf32_Word st_name;\n\tElf32_Addr st_value;\n\tElf32_Word st_size;\n\tunsigned char st_info;\n\tunsigned char st_other;\n\tElf32_Half st_shndx;\n} Elf32_Sym;\n\nenum Elf32_PhdrType { PT_NULL = 0, PT_LOAD = 1, PT_DYNAMIC = 2, PT_INTERP = 3, PT_NOTE = 4, PT_SHLIB = 5, PT_PHDR = 6 };\n\nstruct Elf32Types {\n\ttypedef uint32_t addr_t;\n\ttypedef Elf32_Ehdr Elf_Ehdr;\n\ttypedef Elf32_Phdr Elf_Phdr;\n\ttypedef Elf32_Shdr Elf_Shdr;\n\ttypedef Elf32_Sym Elf_Sym;\n\tstatic constexpr unsigned PT_LOAD = Elf32_PhdrType::PT_LOAD;\n};\n\ntypedef GenericElfLoader<Elf32Types> ELFLoader;\n\n}  // namespace rv32\n"
  },
  {
    "path": "vp/src/core/rv32/iss.cpp",
    "content": "#include \"iss.h\"\n\n// to save *cout* format setting, see *ISS::show*\n#include <boost/io/ios_state.hpp>\n// for safe down-cast\n#include <boost/lexical_cast.hpp>\n\nusing namespace rv32;\n\n#define RAISE_ILLEGAL_INSTRUCTION() raise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\n#define REQUIRE_ISA(X)          \\\n    if (!(csrs.misa.reg & X))   \\\n        RAISE_ILLEGAL_INSTRUCTION()\n\n#define RD instr.rd()\n#define RS1 instr.rs1()\n#define RS2 instr.rs2()\n#define RS3 instr.rs3()\n\nconst char *regnames[] = {\n    \"zero (x0)\", \"ra   (x1)\", \"sp   (x2)\", \"gp   (x3)\", \"tp   (x4)\", \"t0   (x5)\", \"t1   (x6)\", \"t2   (x7)\",\n    \"s0/fp(x8)\", \"s1   (x9)\", \"a0  (x10)\", \"a1  (x11)\", \"a2  (x12)\", \"a3  (x13)\", \"a4  (x14)\", \"a5  (x15)\",\n    \"a6  (x16)\", \"a7  (x17)\", \"s2  (x18)\", \"s3  (x19)\", \"s4  (x20)\", \"s5  (x21)\", \"s6  (x22)\", \"s7  (x23)\",\n    \"s8  (x24)\", \"s9  (x25)\", \"s10 (x26)\", \"s11 (x27)\", \"t3  (x28)\", \"t4  (x29)\", \"t5  (x30)\", \"t6  (x31)\",\n};\n\nint regcolors[] = {\n#if defined(COLOR_THEME_DARK)\n    0,  1,  2,  3,  4,  5,  6,  52, 8,  9,  53, 54, 55, 56, 57, 58,\n    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n#elif defined(COLOR_THEME_LIGHT)\n    100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 153, 154, 155, 156, 157, 158,\n    116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,\n#else\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n#endif\n};\n\nRegFile::RegFile() {\n\tmemset(regs, 0, sizeof(regs));\n}\n\nRegFile::RegFile(const RegFile &other) {\n\tmemcpy(regs, other.regs, sizeof(regs));\n}\n\nvoid RegFile::write(uint32_t index, int32_t value) {\n\tassert(index <= x31);\n\tassert(index != x0);\n\tregs[index] = value;\n}\n\nint32_t RegFile::read(uint32_t index) {\n\tif (index > x31)\n\t\tthrow std::out_of_range(\"out-of-range register access\");\n\treturn regs[index];\n}\n\nuint32_t RegFile::shamt(uint32_t index) {\n\tassert(index <= x31);\n\treturn BIT_RANGE(regs[index], 4, 0);\n}\n\nint32_t &RegFile::operator[](const uint32_t idx) {\n\treturn regs[idx];\n}\n\n#if defined(COLOR_THEME_LIGHT) || defined(COLOR_THEME_DARK)\n#define COLORFRMT \"\\e[38;5;%um%s\\e[39m\"\n#define COLORPRINT(fmt, data) fmt, data\n#else\n#define COLORFRMT \"%s\"\n#define COLORPRINT(fmt, data) data\n#endif\n\nvoid RegFile::show() {\n\tfor (unsigned i = 0; i < NUM_REGS; ++i) {\n\t\tprintf(COLORFRMT \" = %8x\\n\", COLORPRINT(regcolors[i], regnames[i]), regs[i]);\n\t}\n}\n\nISS::ISS(uint32_t hart_id, bool use_E_base_isa) : systemc_name(\"Core-\" + std::to_string(hart_id)) {\n\tcsrs.mhartid.reg = hart_id;\n\tif (use_E_base_isa)\n\t\tcsrs.misa.select_E_base_isa();\n\n\tsc_core::sc_time qt = tlm::tlm_global_quantum::instance().get();\n\tcycle_time = sc_core::sc_time(10, sc_core::SC_NS);\n\n\tassert(qt >= cycle_time);\n\tassert(qt % cycle_time == sc_core::SC_ZERO_TIME);\n\n\tfor (int i = 0; i < Opcode::NUMBER_OF_INSTRUCTIONS; ++i) instr_cycles[i] = cycle_time;\n\n\tconst sc_core::sc_time memory_access_cycles = 4 * cycle_time;\n\tconst sc_core::sc_time mul_div_cycles = 8 * cycle_time;\n\n\tinstr_cycles[Opcode::LB] = memory_access_cycles;\n\tinstr_cycles[Opcode::LBU] = memory_access_cycles;\n\tinstr_cycles[Opcode::LH] = memory_access_cycles;\n\tinstr_cycles[Opcode::LHU] = memory_access_cycles;\n\tinstr_cycles[Opcode::LW] = memory_access_cycles;\n\tinstr_cycles[Opcode::SB] = memory_access_cycles;\n\tinstr_cycles[Opcode::SH] = memory_access_cycles;\n\tinstr_cycles[Opcode::SW] = memory_access_cycles;\n\tinstr_cycles[Opcode::MUL] = mul_div_cycles;\n\tinstr_cycles[Opcode::MULH] = mul_div_cycles;\n\tinstr_cycles[Opcode::MULHU] = mul_div_cycles;\n\tinstr_cycles[Opcode::MULHSU] = mul_div_cycles;\n\tinstr_cycles[Opcode::DIV] = mul_div_cycles;\n\tinstr_cycles[Opcode::DIVU] = mul_div_cycles;\n\tinstr_cycles[Opcode::REM] = mul_div_cycles;\n\tinstr_cycles[Opcode::REMU] = mul_div_cycles;\n\top = Opcode::UNDEF;\n}\n\nvoid ISS::exec_step() {\n\tassert(((pc & ~pc_alignment_mask()) == 0) && \"misaligned instruction\");\n\n\ttry {\n\t\tuint32_t mem_word = instr_mem->load_instr(pc);\n\t\tinstr = Instruction(mem_word);\n\t} catch (SimulationTrap &e) {\n\t\top = Opcode::UNDEF;\n\t\tinstr = Instruction(0);\n\t\tthrow;\n\t}\n\n\tif (instr.is_compressed()) {\n\t\top = instr.decode_and_expand_compressed(RV32);\n\t\tpc += 2;\n        if (op != Opcode::UNDEF)\n            REQUIRE_ISA(C_ISA_EXT);\n    } else {\n\t\top = instr.decode_normal(RV32);\n\t\tpc += 4;\n\t}\n\n\tif (trace) {\n\t\tprintf(\"core %2u: prv %1x: pc %8x: %s \", csrs.mhartid.reg, prv, last_pc, Opcode::mappingStr[op]);\n\t\tswitch (Opcode::getType(op)) {\n\t\t\tcase Opcode::Type::R:\n\t\t\t\tprintf(COLORFRMT \", \" COLORFRMT \", \" COLORFRMT, COLORPRINT(regcolors[instr.rd()], regnames[instr.rd()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs1()], regnames[instr.rs1()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs2()], regnames[instr.rs2()]));\n\t\t\t\tbreak;\n\t\t\tcase Opcode::Type::I:\n\t\t\t\tprintf(COLORFRMT \", \" COLORFRMT \", 0x%x\", COLORPRINT(regcolors[instr.rd()], regnames[instr.rd()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs1()], regnames[instr.rs1()]), instr.I_imm());\n\t\t\t\tbreak;\n\t\t\tcase Opcode::Type::S:\n\t\t\t\tprintf(COLORFRMT \", \" COLORFRMT \", 0x%x\", COLORPRINT(regcolors[instr.rs1()], regnames[instr.rs1()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs2()], regnames[instr.rs2()]), instr.S_imm());\n\t\t\t\tbreak;\n\t\t\tcase Opcode::Type::B:\n\t\t\t\tprintf(COLORFRMT \", \" COLORFRMT \", 0x%x\", COLORPRINT(regcolors[instr.rs1()], regnames[instr.rs1()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs2()], regnames[instr.rs2()]), instr.B_imm());\n\t\t\t\tbreak;\n\t\t\tcase Opcode::Type::U:\n\t\t\t\tprintf(COLORFRMT \", 0x%x\", COLORPRINT(regcolors[instr.rd()], regnames[instr.rd()]), instr.U_imm());\n\t\t\t\tbreak;\n\t\t\tcase Opcode::Type::J:\n\t\t\t\tprintf(COLORFRMT \", 0x%x\", COLORPRINT(regcolors[instr.rd()], regnames[instr.rd()]), instr.J_imm());\n\t\t\t\tbreak;\n\t\t\tdefault:;\n\t\t}\n\t\tputs(\"\");\n\t}\n\n\tswitch (op) {\n\t\tcase Opcode::UNDEF:\n\t\t\tif (trace)\n\t\t\t\tstd::cout << \"[ISS] WARNING: unknown instruction '\" << std::to_string(instr.data()) << \"' at address '\"\n\t\t\t\t          << std::to_string(last_pc) << \"'\" << std::endl;\n\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\t\t\tbreak;\n\n\t\tcase Opcode::ADDI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] + instr.I_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::SLTI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] < instr.I_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::SLTIU:\n\t\t\tregs[instr.rd()] = ((uint32_t)regs[instr.rs1()]) < ((uint32_t)instr.I_imm());\n\t\t\tbreak;\n\n\t\tcase Opcode::XORI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] ^ instr.I_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::ORI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] | instr.I_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::ANDI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] & instr.I_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::ADD:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] + regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::SUB:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] - regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::SLL:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] << regs.shamt(instr.rs2());\n\t\t\tbreak;\n\n\t\tcase Opcode::SLT:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] < regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::SLTU:\n\t\t\tregs[instr.rd()] = ((uint32_t)regs[instr.rs1()]) < ((uint32_t)regs[instr.rs2()]);\n\t\t\tbreak;\n\n\t\tcase Opcode::SRL:\n\t\t\tregs[instr.rd()] = ((uint32_t)regs[instr.rs1()]) >> regs.shamt(instr.rs2());\n\t\t\tbreak;\n\n\t\tcase Opcode::SRA:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] >> regs.shamt(instr.rs2());\n\t\t\tbreak;\n\n\t\tcase Opcode::XOR:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] ^ regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::OR:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] | regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::AND:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] & regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::SLLI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] << instr.shamt();\n\t\t\tbreak;\n\n\t\tcase Opcode::SRLI:\n\t\t\tregs[instr.rd()] = ((uint32_t)regs[instr.rs1()]) >> instr.shamt();\n\t\t\tbreak;\n\n\t\tcase Opcode::SRAI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] >> instr.shamt();\n\t\t\tbreak;\n\n\t\tcase Opcode::LUI:\n\t\t\tregs[instr.rd()] = instr.U_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::AUIPC:\n\t\t\tregs[instr.rd()] = last_pc + instr.U_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::JAL: {\n\t\t\tauto link = pc;\n\t\t\tpc = last_pc + instr.J_imm();\n\t\t\ttrap_check_pc_alignment();\n\t\t\tregs[instr.rd()] = link;\n\t\t} break;\n\n\t\tcase Opcode::JALR: {\n\t\t\tauto link = pc;\n\t\t\tpc = (regs[instr.rs1()] + instr.I_imm()) & ~1;\n\t\t\ttrap_check_pc_alignment();\n\t\t\tregs[instr.rd()] = link;\n\t\t} break;\n\n\t\tcase Opcode::SB: {\n\t\t\tuint32_t addr = regs[instr.rs1()] + instr.S_imm();\n\t\t\tmem->store_byte(addr, regs[instr.rs2()]);\n\t\t} break;\n\n\t\tcase Opcode::SH: {\n\t\t\tuint32_t addr = regs[instr.rs1()] + instr.S_imm();\n\t\t\ttrap_check_addr_alignment<2, false>(addr);\n\t\t\tmem->store_half(addr, regs[instr.rs2()]);\n\t\t} break;\n\n\t\tcase Opcode::SW: {\n\t\t\tuint32_t addr = regs[instr.rs1()] + instr.S_imm();\n\t\t\ttrap_check_addr_alignment<4, false>(addr);\n\t\t\tmem->store_word(addr, regs[instr.rs2()]);\n\t\t} break;\n\n\t\tcase Opcode::LB: {\n\t\t\tuint32_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\tregs[instr.rd()] = mem->load_byte(addr);\n\t\t} break;\n\n\t\tcase Opcode::LH: {\n\t\t\tuint32_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\ttrap_check_addr_alignment<2, true>(addr);\n\t\t\tregs[instr.rd()] = mem->load_half(addr);\n\t\t} break;\n\n\t\tcase Opcode::LW: {\n\t\t\tuint32_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\ttrap_check_addr_alignment<4, true>(addr);\n\t\t\tregs[instr.rd()] = mem->load_word(addr);\n\t\t} break;\n\n\t\tcase Opcode::LBU: {\n\t\t\tuint32_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\tregs[instr.rd()] = mem->load_ubyte(addr);\n\t\t} break;\n\n\t\tcase Opcode::LHU: {\n\t\t\tuint32_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\ttrap_check_addr_alignment<2, true>(addr);\n\t\t\tregs[instr.rd()] = mem->load_uhalf(addr);\n\t\t} break;\n\n\t\tcase Opcode::BEQ:\n\t\t\tif (regs[instr.rs1()] == regs[instr.rs2()]) {\n\t\t\t\tpc = last_pc + instr.B_imm();\n\t\t\t\ttrap_check_pc_alignment();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Opcode::BNE:\n\t\t\tif (regs[instr.rs1()] != regs[instr.rs2()]) {\n\t\t\t\tpc = last_pc + instr.B_imm();\n\t\t\t\ttrap_check_pc_alignment();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Opcode::BLT:\n\t\t\tif (regs[instr.rs1()] < regs[instr.rs2()]) {\n\t\t\t\tpc = last_pc + instr.B_imm();\n\t\t\t\ttrap_check_pc_alignment();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Opcode::BGE:\n\t\t\tif (regs[instr.rs1()] >= regs[instr.rs2()]) {\n\t\t\t\tpc = last_pc + instr.B_imm();\n\t\t\t\ttrap_check_pc_alignment();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Opcode::BLTU:\n\t\t\tif ((uint32_t)regs[instr.rs1()] < (uint32_t)regs[instr.rs2()]) {\n\t\t\t\tpc = last_pc + instr.B_imm();\n\t\t\t\ttrap_check_pc_alignment();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Opcode::BGEU:\n\t\t\tif ((uint32_t)regs[instr.rs1()] >= (uint32_t)regs[instr.rs2()]) {\n\t\t\t\tpc = last_pc + instr.B_imm();\n\t\t\t\ttrap_check_pc_alignment();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Opcode::FENCE:\n\t\tcase Opcode::FENCE_I: {\n\t\t\t// not using out of order execution so can be ignored\n\t\t} break;\n\n\t\tcase Opcode::ECALL: {\n\t\t\tif (sys) {\n\t\t\t\tsys->execute_syscall(this);\n\t\t\t} else {\n\t\t\t\tswitch (prv) {\n\t\t\t\t\tcase MachineMode:\n\t\t\t\t\t\traise_trap(EXC_ECALL_M_MODE, last_pc);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase SupervisorMode:\n\t\t\t\t\t\traise_trap(EXC_ECALL_S_MODE, last_pc);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase UserMode:\n\t\t\t\t\t\traise_trap(EXC_ECALL_U_MODE, last_pc);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow std::runtime_error(\"unknown privilege level \" + std::to_string(prv));\n\t\t\t\t}\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::EBREAK: {\n\t\t\t// TODO: also raise trap and let the SW deal with it?\n\t\t\tstatus = CoreExecStatus::HitBreakpoint;\n\t\t} break;\n\n\t\tcase Opcode::CSRRW: {\n\t\t\tauto addr = instr.csr();\n\t\t\tif (is_invalid_csr_access(addr, true)) {\n                RAISE_ILLEGAL_INSTRUCTION();\n\t\t\t} else {\n\t\t\t\tauto rd = instr.rd();\n\t\t\t\tauto rs1_val = regs[instr.rs1()];\n\t\t\t\tif (rd != RegFile::zero) {\n\t\t\t\t\tregs[instr.rd()] = get_csr_value(addr);\n\t\t\t\t}\n\t\t\t\tset_csr_value(addr, rs1_val);\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::CSRRS: {\n\t\t\tauto addr = instr.csr();\n\t\t\tauto rs1 = instr.rs1();\n\t\t\tauto write = rs1 != RegFile::zero;\n\t\t\tif (is_invalid_csr_access(addr, write)) {\n                RAISE_ILLEGAL_INSTRUCTION();\n\t\t\t} else {\n\t\t\t\tauto rd = instr.rd();\n\t\t\t\tauto rs1_val = regs[rs1];\n\t\t\t\tauto csr_val = get_csr_value(addr);\n\t\t\t\tif (rd != RegFile::zero)\n\t\t\t\t\tregs[rd] = csr_val;\n\t\t\t\tif (write)\n\t\t\t\t\tset_csr_value(addr, csr_val | rs1_val);\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::CSRRC: {\n\t\t\tauto addr = instr.csr();\n\t\t\tauto rs1 = instr.rs1();\n\t\t\tauto write = rs1 != RegFile::zero;\n\t\t\tif (is_invalid_csr_access(addr, write)) {\n                RAISE_ILLEGAL_INSTRUCTION();\n\t\t\t} else {\n\t\t\t\tauto rd = instr.rd();\n\t\t\t\tauto rs1_val = regs[rs1];\n\t\t\t\tauto csr_val = get_csr_value(addr);\n\t\t\t\tif (rd != RegFile::zero)\n\t\t\t\t\tregs[rd] = csr_val;\n\t\t\t\tif (write)\n\t\t\t\t\tset_csr_value(addr, csr_val & ~rs1_val);\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::CSRRWI: {\n\t\t\tauto addr = instr.csr();\n\t\t\tif (is_invalid_csr_access(addr, true)) {\n                RAISE_ILLEGAL_INSTRUCTION();\n\t\t\t} else {\n\t\t\t\tauto rd = instr.rd();\n\t\t\t\tif (rd != RegFile::zero) {\n\t\t\t\t\tregs[rd] = get_csr_value(addr);\n\t\t\t\t}\n\t\t\t\tset_csr_value(addr, instr.zimm());\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::CSRRSI: {\n\t\t\tauto addr = instr.csr();\n\t\t\tauto zimm = instr.zimm();\n\t\t\tauto write = zimm != 0;\n\t\t\tif (is_invalid_csr_access(addr, write)) {\n                RAISE_ILLEGAL_INSTRUCTION();\n\t\t\t} else {\n\t\t\t\tauto csr_val = get_csr_value(addr);\n\t\t\t\tauto rd = instr.rd();\n\t\t\t\tif (rd != RegFile::zero)\n\t\t\t\t\tregs[rd] = csr_val;\n\t\t\t\tif (write)\n\t\t\t\t\tset_csr_value(addr, csr_val | zimm);\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::CSRRCI: {\n\t\t\tauto addr = instr.csr();\n\t\t\tauto zimm = instr.zimm();\n\t\t\tauto write = zimm != 0;\n\t\t\tif (is_invalid_csr_access(addr, write)) {\n                RAISE_ILLEGAL_INSTRUCTION();\n\t\t\t} else {\n\t\t\t\tauto csr_val = get_csr_value(addr);\n\t\t\t\tauto rd = instr.rd();\n\t\t\t\tif (rd != RegFile::zero)\n\t\t\t\t\tregs[rd] = csr_val;\n\t\t\t\tif (write)\n\t\t\t\t\tset_csr_value(addr, csr_val & ~zimm);\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::MUL: {\n            REQUIRE_ISA(M_ISA_EXT);\n\t\t\tint64_t ans = (int64_t)regs[instr.rs1()] * (int64_t)regs[instr.rs2()];\n\t\t\tregs[instr.rd()] = ans & 0xFFFFFFFF;\n\t\t} break;\n\n\t\tcase Opcode::MULH: {\n            REQUIRE_ISA(M_ISA_EXT);\n\t\t\tint64_t ans = (int64_t)regs[instr.rs1()] * (int64_t)regs[instr.rs2()];\n\t\t\tregs[instr.rd()] = (ans & 0xFFFFFFFF00000000) >> 32;\n\t\t} break;\n\n\t\tcase Opcode::MULHU: {\n            REQUIRE_ISA(M_ISA_EXT);\n\t\t\tint64_t ans = ((uint64_t)(uint32_t)regs[instr.rs1()]) * (uint64_t)((uint32_t)regs[instr.rs2()]);\n\t\t\tregs[instr.rd()] = (ans & 0xFFFFFFFF00000000) >> 32;\n\t\t} break;\n\n\t\tcase Opcode::MULHSU: {\n            REQUIRE_ISA(M_ISA_EXT);\n\t\t\tint64_t ans = (int64_t)regs[instr.rs1()] * (uint64_t)((uint32_t)regs[instr.rs2()]);\n\t\t\tregs[instr.rd()] = (ans & 0xFFFFFFFF00000000) >> 32;\n\t\t} break;\n\n\t\tcase Opcode::DIV: {\n            REQUIRE_ISA(M_ISA_EXT);\n\t\t\tauto a = regs[instr.rs1()];\n\t\t\tauto b = regs[instr.rs2()];\n\t\t\tif (b == 0) {\n\t\t\t\tregs[instr.rd()] = -1;\n\t\t\t} else if (a == REG_MIN && b == -1) {\n\t\t\t\tregs[instr.rd()] = a;\n\t\t\t} else {\n\t\t\t\tregs[instr.rd()] = a / b;\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::DIVU: {\n            REQUIRE_ISA(M_ISA_EXT);\n\t\t\tauto a = regs[instr.rs1()];\n\t\t\tauto b = regs[instr.rs2()];\n\t\t\tif (b == 0) {\n\t\t\t\tregs[instr.rd()] = -1;\n\t\t\t} else {\n\t\t\t\tregs[instr.rd()] = (uint32_t)a / (uint32_t)b;\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::REM: {\n            REQUIRE_ISA(M_ISA_EXT);\n\t\t\tauto a = regs[instr.rs1()];\n\t\t\tauto b = regs[instr.rs2()];\n\t\t\tif (b == 0) {\n\t\t\t\tregs[instr.rd()] = a;\n\t\t\t} else if (a == REG_MIN && b == -1) {\n\t\t\t\tregs[instr.rd()] = 0;\n\t\t\t} else {\n\t\t\t\tregs[instr.rd()] = a % b;\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::REMU: {\n            REQUIRE_ISA(M_ISA_EXT);\n\t\t\tauto a = regs[instr.rs1()];\n\t\t\tauto b = regs[instr.rs2()];\n\t\t\tif (b == 0) {\n\t\t\t\tregs[instr.rd()] = a;\n\t\t\t} else {\n\t\t\t\tregs[instr.rd()] = (uint32_t)a % (uint32_t)b;\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::LR_W: {\n            REQUIRE_ISA(A_ISA_EXT);\n\t\t\tuint32_t addr = regs[instr.rs1()];\n\t\t\ttrap_check_addr_alignment<4, true>(addr);\n\t\t\tregs[instr.rd()] = mem->atomic_load_reserved_word(addr);\n\t\t\tif (lr_sc_counter == 0)\n\t\t\t    lr_sc_counter = 17;  // this instruction + 16 additional ones, (an over-approximation) to cover the RISC-V forward progress property\n\t\t} break;\n\n\t\tcase Opcode::SC_W: {\n            REQUIRE_ISA(A_ISA_EXT);\n\t\t\tuint32_t addr = regs[instr.rs1()];\n\t\t\ttrap_check_addr_alignment<4, false>(addr);\n\t\t\tuint32_t val = regs[instr.rs2()];\n\t\t\tregs[instr.rd()] = 1;  // failure by default (in case a trap is thrown)\n\t\t\tregs[instr.rd()] = mem->atomic_store_conditional_word(addr, val) ? 0 : 1;  // overwrite result (in case no trap is thrown)\n\t\t\tlr_sc_counter = 0;\n\t\t} break;\n\n\t\tcase Opcode::AMOSWAP_W: {\n            REQUIRE_ISA(A_ISA_EXT);\n\t\t\texecute_amo(instr, [](int32_t a, int32_t b) {\n\t\t\t\t(void)a;\n\t\t\t\treturn b;\n\t\t\t});\n\t\t} break;\n\n\t\tcase Opcode::AMOADD_W: {\n            REQUIRE_ISA(A_ISA_EXT);\n\t\t\texecute_amo(instr, [](int32_t a, int32_t b) { return a + b; });\n\t\t} break;\n\n\t\tcase Opcode::AMOXOR_W: {\n            REQUIRE_ISA(A_ISA_EXT);\n\t\t\texecute_amo(instr, [](int32_t a, int32_t b) { return a ^ b; });\n\t\t} break;\n\n\t\tcase Opcode::AMOAND_W: {\n            REQUIRE_ISA(A_ISA_EXT);\n\t\t\texecute_amo(instr, [](int32_t a, int32_t b) { return a & b; });\n\t\t} break;\n\n\t\tcase Opcode::AMOOR_W: {\n            REQUIRE_ISA(A_ISA_EXT);\n\t\t\texecute_amo(instr, [](int32_t a, int32_t b) { return a | b; });\n\t\t} break;\n\n\t\tcase Opcode::AMOMIN_W: {\n            REQUIRE_ISA(A_ISA_EXT);\n\t\t\texecute_amo(instr, [](int32_t a, int32_t b) { return std::min(a, b); });\n\t\t} break;\n\n\t\tcase Opcode::AMOMINU_W: {\n            REQUIRE_ISA(A_ISA_EXT);\n\t\t\texecute_amo(instr, [](int32_t a, int32_t b) { return std::min((uint32_t)a, (uint32_t)b); });\n\t\t} break;\n\n\t\tcase Opcode::AMOMAX_W: {\n            REQUIRE_ISA(A_ISA_EXT);\n\t\t\texecute_amo(instr, [](int32_t a, int32_t b) { return std::max(a, b); });\n\t\t} break;\n\n\t\tcase Opcode::AMOMAXU_W: {\n            REQUIRE_ISA(A_ISA_EXT);\n\t\t\texecute_amo(instr, [](int32_t a, int32_t b) { return std::max((uint32_t)a, (uint32_t)b); });\n\t\t} break;\n\n\t\t\t// RV32F Extension\n\n\t\tcase Opcode::FLW: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tuint32_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\ttrap_check_addr_alignment<4, true>(addr);\n\t\t\tfp_regs.write(RD, float32_t{(uint32_t)mem->load_word(addr)});\n\t\t} break;\n\n\t\tcase Opcode::FSW: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tuint32_t addr = regs[instr.rs1()] + instr.S_imm();\n\t\t\ttrap_check_addr_alignment<4, false>(addr);\n            mem->store_word(addr, fp_regs.u32(RS2));\n\t\t} break;\n\n\t\tcase Opcode::FADD_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_add(fp_regs.f32(RS1), fp_regs.f32(RS2)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FSUB_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_sub(fp_regs.f32(RS1), fp_regs.f32(RS2)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMUL_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_mul(fp_regs.f32(RS1), fp_regs.f32(RS2)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FDIV_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_div(fp_regs.f32(RS1), fp_regs.f32(RS2)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FSQRT_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_sqrt(fp_regs.f32(RS1)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMIN_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\n\t\t\tbool rs1_smaller = f32_lt_quiet(fp_regs.f32(RS1), fp_regs.f32(RS2)) ||\n\t\t\t                   (f32_eq(fp_regs.f32(RS1), fp_regs.f32(RS2)) && f32_isNegative(fp_regs.f32(RS1)));\n\n\t\t\tif (f32_isNaN(fp_regs.f32(RS1)) && f32_isNaN(fp_regs.f32(RS2))) {\n\t\t\t\tfp_regs.write(RD, f32_defaultNaN);\n\t\t\t} else {\n\t\t\t\tif (rs1_smaller)\n\t\t\t\t\tfp_regs.write(RD, fp_regs.f32(RS1));\n\t\t\t\telse\n\t\t\t\t\tfp_regs.write(RD, fp_regs.f32(RS2));\n\t\t\t}\n\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMAX_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\n\t\t\tbool rs1_greater = f32_lt_quiet(fp_regs.f32(RS2), fp_regs.f32(RS1)) ||\n\t\t\t                   (f32_eq(fp_regs.f32(RS2), fp_regs.f32(RS1)) && f32_isNegative(fp_regs.f32(RS2)));\n\n\t\t\tif (f32_isNaN(fp_regs.f32(RS1)) && f32_isNaN(fp_regs.f32(RS2))) {\n\t\t\t\tfp_regs.write(RD, f32_defaultNaN);\n\t\t\t} else {\n\t\t\t\tif (rs1_greater)\n\t\t\t\t\tfp_regs.write(RD, fp_regs.f32(RS1));\n\t\t\t\telse\n\t\t\t\t\tfp_regs.write(RD, fp_regs.f32(RS2));\n\t\t\t}\n\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMADD_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_mulAdd(fp_regs.f32(RS1), fp_regs.f32(RS2), fp_regs.f32(RS3)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMSUB_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_mulAdd(fp_regs.f32(RS1), fp_regs.f32(RS2), f32_neg(fp_regs.f32(RS3))));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FNMADD_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_mulAdd(f32_neg(fp_regs.f32(RS1)), fp_regs.f32(RS2), f32_neg(fp_regs.f32(RS3))));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FNMSUB_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_mulAdd(f32_neg(fp_regs.f32(RS1)), fp_regs.f32(RS2), fp_regs.f32(RS3)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_W_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tregs[RD] = f32_to_i32(fp_regs.f32(RS1), softfloat_roundingMode, true);\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_WU_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tregs[RD] = f32_to_ui32(fp_regs.f32(RS1), softfloat_roundingMode, true);\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_S_W: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, i32_to_f32(regs[RS1]));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_S_WU: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, ui32_to_f32(regs[RS1]));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FSGNJ_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tauto f1 = fp_regs.f32(RS1);\n\t\t\tauto f2 = fp_regs.f32(RS2);\n\t\t\tfp_regs.write(RD, float32_t{(f1.v & ~F32_SIGN_BIT) | (f2.v & F32_SIGN_BIT)});\n\t\t\tfp_set_dirty();\n\t\t} break;\n\n\t\tcase Opcode::FSGNJN_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tauto f1 = fp_regs.f32(RS1);\n\t\t\tauto f2 = fp_regs.f32(RS2);\n\t\t\tfp_regs.write(RD, float32_t{(f1.v & ~F32_SIGN_BIT) | (~f2.v & F32_SIGN_BIT)});\n\t\t\tfp_set_dirty();\n\t\t} break;\n\n\t\tcase Opcode::FSGNJX_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tauto f1 = fp_regs.f32(RS1);\n\t\t\tauto f2 = fp_regs.f32(RS2);\n\t\t\tfp_regs.write(RD, float32_t{f1.v ^ (f2.v & F32_SIGN_BIT)});\n\t\t\tfp_set_dirty();\n\t\t} break;\n\n\t\tcase Opcode::FMV_W_X: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tfp_regs.write(RD, float32_t{(uint32_t)regs[RS1]});\n\t\t\tfp_set_dirty();\n\t\t} break;\n\n\t\tcase Opcode::FMV_X_W: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = fp_regs.u32(RS1);\n\t\t} break;\n\n\t\tcase Opcode::FEQ_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = f32_eq(fp_regs.f32(RS1), fp_regs.f32(RS2));\n\t\t\tfp_update_exception_flags();\n\t\t} break;\n\n\t\tcase Opcode::FLT_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = f32_lt(fp_regs.f32(RS1), fp_regs.f32(RS2));\n\t\t\tfp_update_exception_flags();\n\t\t} break;\n\n\t\tcase Opcode::FLE_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = f32_le(fp_regs.f32(RS1), fp_regs.f32(RS2));\n\t\t\tfp_update_exception_flags();\n\t\t} break;\n\n\t\tcase Opcode::FCLASS_S: {\n            REQUIRE_ISA(F_ISA_EXT);\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = f32_classify(fp_regs.f32(RS1));\n\t\t} break;\n\n\t\t\t// RV32D Extension\n\n        case Opcode::FLD: {\n            REQUIRE_ISA(D_ISA_EXT);\n            uint32_t addr = regs[instr.rs1()] + instr.I_imm();\n            trap_check_addr_alignment<8, true>(addr);\n            fp_regs.write(RD, float64_t{(uint64_t)mem->load_double(addr)});\n        } break;\n\n        case Opcode::FSD: {\n            REQUIRE_ISA(D_ISA_EXT);\n            uint32_t addr = regs[instr.rs1()] + instr.S_imm();\n            trap_check_addr_alignment<8, false>(addr);\n            mem->store_double(addr, fp_regs.f64(RS2).v);\n        } break;\n\n        case Opcode::FADD_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, f64_add(fp_regs.f64(RS1), fp_regs.f64(RS2)));\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FSUB_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, f64_sub(fp_regs.f64(RS1), fp_regs.f64(RS2)));\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FMUL_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, f64_mul(fp_regs.f64(RS1), fp_regs.f64(RS2)));\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FDIV_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, f64_div(fp_regs.f64(RS1), fp_regs.f64(RS2)));\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FSQRT_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, f64_sqrt(fp_regs.f64(RS1)));\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FMIN_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n\n            bool rs1_smaller = f64_lt_quiet(fp_regs.f64(RS1), fp_regs.f64(RS2)) ||\n                               (f64_eq(fp_regs.f64(RS1), fp_regs.f64(RS2)) && f64_isNegative(fp_regs.f64(RS1)));\n\n            if (f64_isNaN(fp_regs.f64(RS1)) && f64_isNaN(fp_regs.f64(RS2))) {\n                fp_regs.write(RD, f64_defaultNaN);\n            } else {\n                if (rs1_smaller)\n                    fp_regs.write(RD, fp_regs.f64(RS1));\n                else\n                    fp_regs.write(RD, fp_regs.f64(RS2));\n            }\n\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FMAX_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n\n            bool rs1_greater = f64_lt_quiet(fp_regs.f64(RS2), fp_regs.f64(RS1)) ||\n                               (f64_eq(fp_regs.f64(RS2), fp_regs.f64(RS1)) && f64_isNegative(fp_regs.f64(RS2)));\n\n            if (f64_isNaN(fp_regs.f64(RS1)) && f64_isNaN(fp_regs.f64(RS2))) {\n                fp_regs.write(RD, f64_defaultNaN);\n            } else {\n                if (rs1_greater)\n                    fp_regs.write(RD, fp_regs.f64(RS1));\n                else\n                    fp_regs.write(RD, fp_regs.f64(RS2));\n            }\n\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FMADD_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, f64_mulAdd(fp_regs.f64(RS1), fp_regs.f64(RS2), fp_regs.f64(RS3)));\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FMSUB_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, f64_mulAdd(fp_regs.f64(RS1), fp_regs.f64(RS2), f64_neg(fp_regs.f64(RS3))));\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FNMADD_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, f64_mulAdd(f64_neg(fp_regs.f64(RS1)), fp_regs.f64(RS2), f64_neg(fp_regs.f64(RS3))));\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FNMSUB_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, f64_mulAdd(f64_neg(fp_regs.f64(RS1)), fp_regs.f64(RS2), fp_regs.f64(RS3)));\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FSGNJ_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            auto f1 = fp_regs.f64(RS1);\n            auto f2 = fp_regs.f64(RS2);\n            fp_regs.write(RD, float64_t{(f1.v & ~F64_SIGN_BIT) | (f2.v & F64_SIGN_BIT)});\n            fp_set_dirty();\n        } break;\n\n        case Opcode::FSGNJN_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            auto f1 = fp_regs.f64(RS1);\n            auto f2 = fp_regs.f64(RS2);\n            fp_regs.write(RD, float64_t{(f1.v & ~F64_SIGN_BIT) | (~f2.v & F64_SIGN_BIT)});\n            fp_set_dirty();\n        } break;\n\n        case Opcode::FSGNJX_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            auto f1 = fp_regs.f64(RS1);\n            auto f2 = fp_regs.f64(RS2);\n            fp_regs.write(RD, float64_t{f1.v ^ (f2.v & F64_SIGN_BIT)});\n            fp_set_dirty();\n        } break;\n\n        case Opcode::FCVT_S_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, f64_to_f32(fp_regs.f64(RS1)));\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FCVT_D_S: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, f32_to_f64(fp_regs.f32(RS1)));\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FEQ_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            regs[RD] = f64_eq(fp_regs.f64(RS1), fp_regs.f64(RS2));\n            fp_update_exception_flags();\n        } break;\n\n        case Opcode::FLT_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            regs[RD] = f64_lt(fp_regs.f64(RS1), fp_regs.f64(RS2));\n            fp_update_exception_flags();\n        } break;\n\n        case Opcode::FLE_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            regs[RD] = f64_le(fp_regs.f64(RS1), fp_regs.f64(RS2));\n            fp_update_exception_flags();\n        } break;\n\n        case Opcode::FCLASS_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            regs[RD] = (int64_t)f64_classify(fp_regs.f64(RS1));\n        } break;\n\n        case Opcode::FCVT_W_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            regs[RD] = f64_to_i32(fp_regs.f64(RS1), softfloat_roundingMode, true);\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FCVT_WU_D: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            regs[RD] = (int32_t)f64_to_ui32(fp_regs.f64(RS1), softfloat_roundingMode, true);\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FCVT_D_W: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, i32_to_f64((int32_t)regs[RS1]));\n            fp_finish_instr();\n        } break;\n\n        case Opcode::FCVT_D_WU: {\n            REQUIRE_ISA(D_ISA_EXT);\n            fp_prepare_instr();\n            fp_setup_rm();\n            fp_regs.write(RD, ui32_to_f64((int32_t)regs[RS1]));\n            fp_finish_instr();\n        } break;\n\n        // privileged instructions\n\n        case Opcode::WFI:\n            // NOTE: only a hint, can be implemented as NOP\n            // std::cout << \"[sim:wfi] CSR mstatus.mie \" << csrs.mstatus->mie << std::endl;\n            release_lr_sc_reservation();\n\n            if (s_mode() && csrs.mstatus.fields.tw)\n                raise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\n            if (u_mode() && csrs.misa.has_supervisor_mode_extension())\n                raise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\n            if (!ignore_wfi && !has_local_pending_enabled_interrupts())\n                sc_core::wait(wfi_event);\n            break;\n\n        case Opcode::SFENCE_VMA:\n            if (s_mode() && csrs.mstatus.fields.tvm)\n                raise_trap(EXC_ILLEGAL_INSTR, instr.data());\n            mem->flush_tlb();\n            break;\n\n        case Opcode::URET:\n            if (!csrs.misa.has_user_mode_extension())\n                raise_trap(EXC_ILLEGAL_INSTR, instr.data());\n            return_from_trap_handler(UserMode);\n            break;\n\n        case Opcode::SRET:\n            if (!csrs.misa.has_supervisor_mode_extension() || (s_mode() && csrs.mstatus.fields.tsr))\n                raise_trap(EXC_ILLEGAL_INSTR, instr.data());\n            return_from_trap_handler(SupervisorMode);\n            break;\n\n        case Opcode::MRET:\n            return_from_trap_handler(MachineMode);\n            break;\n\n            // instructions accepted by decoder but not by this RV32IMACF ISS -> do normal trap\n            // RV64I\n        case Opcode::LWU:\n        case Opcode::LD:\n        case Opcode::SD:\n        case Opcode::ADDIW:\n        case Opcode::SLLIW:\n        case Opcode::SRLIW:\n        case Opcode::SRAIW:\n        case Opcode::ADDW:\n        case Opcode::SUBW:\n        case Opcode::SLLW:\n        case Opcode::SRLW:\n        case Opcode::SRAW:\n            // RV64M\n        case Opcode::MULW:\n        case Opcode::DIVW:\n        case Opcode::DIVUW:\n        case Opcode::REMW:\n        case Opcode::REMUW:\n            // RV64A\n        case Opcode::LR_D:\n        case Opcode::SC_D:\n        case Opcode::AMOSWAP_D:\n        case Opcode::AMOADD_D:\n        case Opcode::AMOXOR_D:\n        case Opcode::AMOAND_D:\n        case Opcode::AMOOR_D:\n        case Opcode::AMOMIN_D:\n        case Opcode::AMOMAX_D:\n        case Opcode::AMOMINU_D:\n        case Opcode::AMOMAXU_D:\n            // RV64F\n        case Opcode::FCVT_L_S:\n        case Opcode::FCVT_LU_S:\n        case Opcode::FCVT_S_L:\n        case Opcode::FCVT_S_LU:\n            // RV64D\n        case Opcode::FCVT_L_D:\n        case Opcode::FCVT_LU_D:\n        case Opcode::FMV_X_D:\n        case Opcode::FCVT_D_L:\n        case Opcode::FCVT_D_LU:\n        case Opcode::FMV_D_X:\n            RAISE_ILLEGAL_INSTRUCTION();\n            break;\n\n        default:\n            throw std::runtime_error(\"unknown opcode\");\n\t}\n}\n\nuint64_t ISS::_compute_and_get_current_cycles() {\n\tassert(cycle_counter % cycle_time == sc_core::SC_ZERO_TIME);\n\tassert(cycle_counter.value() % cycle_time.value() == 0);\n\n\tuint64_t num_cycles = cycle_counter.value() / cycle_time.value();\n\n\treturn num_cycles;\n}\n\n\nbool ISS::is_invalid_csr_access(uint32_t csr_addr, bool is_write) {\n    if (csr_addr == csr::FFLAGS_ADDR || csr_addr == csr::FRM_ADDR || csr_addr == csr::FCSR_ADDR) {\n        REQUIRE_ISA(F_ISA_EXT);\n    }\n    PrivilegeLevel csr_prv = (0x300 & csr_addr) >> 8;\n    bool csr_readonly = ((0xC00 & csr_addr) >> 10) == 3;\n    bool s_invalid = (csr_prv == SupervisorMode) && !csrs.misa.has_supervisor_mode_extension();\n    bool u_invalid = (csr_prv == UserMode) && !csrs.misa.has_user_mode_extension();\n    return (is_write && csr_readonly) || (prv < csr_prv) || s_invalid || u_invalid;\n}\n\n\nvoid ISS::validate_csr_counter_read_access_rights(uint32_t addr) {\n\t// match against counter CSR addresses, see RISC-V privileged spec for the address definitions\n\tif ((addr >= 0xC00 && addr <= 0xC1F) || (addr >= 0xC80 && addr <= 0xC9F)) {\n\t\tauto cnt = addr & 0x1F;  // 32 counter in total, naturally aligned with the mcounteren and scounteren CSRs\n\n\t\tif (s_mode() && !csr::is_bitset(csrs.mcounteren, cnt))\n\t\t\tRAISE_ILLEGAL_INSTRUCTION();\n\n\t\tif (u_mode() && (!csr::is_bitset(csrs.mcounteren, cnt) || !csr::is_bitset(csrs.scounteren, cnt)))\n\t\t\tRAISE_ILLEGAL_INSTRUCTION();\n\t}\n}\n\nuint32_t ISS::get_csr_value(uint32_t addr) {\n\tvalidate_csr_counter_read_access_rights(addr);\n\n\tauto read = [=](auto &x, uint32_t mask) { return x.reg & mask; };\n\n\tusing namespace csr;\n\n\tswitch (addr) {\n\t\tcase TIME_ADDR:\n\t\tcase MTIME_ADDR: {\n\t\t\tuint64_t mtime = clint->update_and_get_mtime();\n\t\t\tcsrs.time.reg = mtime;\n\t\t\treturn csrs.time.words.low;\n\t\t}\n\n\t\tcase TIMEH_ADDR:\n\t\tcase MTIMEH_ADDR: {\n\t\t\tuint64_t mtime = clint->update_and_get_mtime();\n\t\t\tcsrs.time.reg = mtime;\n\t\t\treturn csrs.time.words.high;\n\t\t}\n\n\t\tcase MCYCLE_ADDR:\n\t\t\tcsrs.cycle.reg = _compute_and_get_current_cycles();\n\t\t\treturn csrs.cycle.words.low;\n\n\t\tcase MCYCLEH_ADDR:\n\t\t\tcsrs.cycle.reg = _compute_and_get_current_cycles();\n\t\t\treturn csrs.cycle.words.high;\n\n\t\tcase MINSTRET_ADDR:\n\t\t\treturn csrs.instret.words.low;\n\n\t\tcase MINSTRETH_ADDR:\n\t\t\treturn csrs.instret.words.high;\n\n\t\tSWITCH_CASE_MATCH_ANY_HPMCOUNTER_RV32:  // not implemented\n\t\t\treturn 0;\n\n\t\tcase MSTATUS_ADDR:\n\t\t\treturn read(csrs.mstatus, MSTATUS_MASK);\n\t\tcase SSTATUS_ADDR:\n\t\t\treturn read(csrs.mstatus, SSTATUS_MASK);\n\t\tcase USTATUS_ADDR:\n\t\t\treturn read(csrs.mstatus, USTATUS_MASK);\n\n\t\tcase MIP_ADDR:\n\t\t\treturn read(csrs.mip, MIP_READ_MASK);\n\t\tcase SIP_ADDR:\n\t\t\treturn read(csrs.mip, SIP_MASK);\n\t\tcase UIP_ADDR:\n\t\t\treturn read(csrs.mip, UIP_MASK);\n\n\t\tcase MIE_ADDR:\n\t\t\treturn read(csrs.mie, MIE_MASK);\n\t\tcase SIE_ADDR:\n\t\t\treturn read(csrs.mie, SIE_MASK);\n\t\tcase UIE_ADDR:\n\t\t\treturn read(csrs.mie, UIE_MASK);\n\n\t\tcase SATP_ADDR:\n\t\t\tif (csrs.mstatus.fields.tvm)\n\t\t\t\tRAISE_ILLEGAL_INSTRUCTION();\n\t\t\tbreak;\n\n\t\tcase FCSR_ADDR:\n\t\t\treturn read(csrs.fcsr, FCSR_MASK);\n\n\t\tcase FFLAGS_ADDR:\n\t\t\treturn csrs.fcsr.fields.fflags;\n\n\t\tcase FRM_ADDR:\n\t\t\treturn csrs.fcsr.fields.frm;\n\n        // debug CSRs not supported, thus hardwired\n        case TSELECT_ADDR:\n            return 1; // if a zero write by SW is preserved, then debug mode is supported (thus hardwire to non-zero)\n        case TDATA1_ADDR:\n        case TDATA2_ADDR:\n        case TDATA3_ADDR:\n        case DCSR_ADDR:\n        case DPC_ADDR:\n        case DSCRATCH0_ADDR:\n        case DSCRATCH1_ADDR:\n            return 0;\n\t}\n\n\tif (!csrs.is_valid_csr32_addr(addr))\n\t\tRAISE_ILLEGAL_INSTRUCTION();\n\n\treturn csrs.default_read32(addr);\n}\n\nvoid ISS::set_csr_value(uint32_t addr, uint32_t value) {\n\tauto write = [=](auto &x, uint32_t mask) { x.reg = (x.reg & ~mask) | (value & mask); };\n\n\tusing namespace csr;\n\n\tswitch (addr) {\n\t\tcase MISA_ADDR:                         // currently, read-only, thus cannot be changed at runtime\n\t\tSWITCH_CASE_MATCH_ANY_HPMCOUNTER_RV32:  // not implemented\n\t\t\tbreak;\n\n        case SATP_ADDR: {\n            if (csrs.mstatus.fields.tvm)\n                RAISE_ILLEGAL_INSTRUCTION();\n            write(csrs.satp, SATP_MASK);\n            // std::cout << \"[iss] satp=\" << boost::format(\"%x\") % csrs.satp.reg << std::endl;\n        } break;\n\n\t\tcase MTVEC_ADDR:\n\t\t\twrite(csrs.mtvec, MTVEC_MASK);\n\t\t\tbreak;\n\t\tcase STVEC_ADDR:\n\t\t\twrite(csrs.stvec, MTVEC_MASK);\n\t\t\tbreak;\n\t\tcase UTVEC_ADDR:\n\t\t\twrite(csrs.utvec, MTVEC_MASK);\n\t\t\tbreak;\n\n\t\tcase MEPC_ADDR:\n\t\t\twrite(csrs.mepc, pc_alignment_mask());\n\t\t\tbreak;\n\t\tcase SEPC_ADDR:\n\t\t\twrite(csrs.sepc, pc_alignment_mask());\n\t\t\tbreak;\n\t\tcase UEPC_ADDR:\n\t\t\twrite(csrs.uepc, pc_alignment_mask());\n\t\t\tbreak;\n\n\t\tcase MSTATUS_ADDR:\n\t\t\twrite(csrs.mstatus, MSTATUS_MASK);\n\t\t\tbreak;\n\t\tcase SSTATUS_ADDR:\n\t\t\twrite(csrs.mstatus, SSTATUS_MASK);\n\t\t\tbreak;\n\t\tcase USTATUS_ADDR:\n\t\t\twrite(csrs.mstatus, USTATUS_MASK);\n\t\t\tbreak;\n\n\t\tcase MIP_ADDR:\n\t\t\twrite(csrs.mip, MIP_WRITE_MASK);\n\t\t\tbreak;\n\t\tcase SIP_ADDR:\n\t\t\twrite(csrs.mip, SIP_MASK);\n\t\t\tbreak;\n\t\tcase UIP_ADDR:\n\t\t\twrite(csrs.mip, UIP_MASK);\n\t\t\tbreak;\n\n\t\tcase MIE_ADDR:\n\t\t\twrite(csrs.mie, MIE_MASK);\n\t\t\tbreak;\n\t\tcase SIE_ADDR:\n\t\t\twrite(csrs.mie, SIE_MASK);\n\t\t\tbreak;\n\t\tcase UIE_ADDR:\n\t\t\twrite(csrs.mie, UIE_MASK);\n\t\t\tbreak;\n\n\t\tcase MIDELEG_ADDR:\n\t\t\twrite(csrs.mideleg, MIDELEG_MASK);\n\t\t\tbreak;\n\n\t\tcase MEDELEG_ADDR:\n\t\t\twrite(csrs.medeleg, MEDELEG_MASK);\n\t\t\tbreak;\n\n\t\tcase SIDELEG_ADDR:\n\t\t\twrite(csrs.sideleg, SIDELEG_MASK);\n\t\t\tbreak;\n\n\t\tcase SEDELEG_ADDR:\n\t\t\twrite(csrs.sedeleg, SEDELEG_MASK);\n\t\t\tbreak;\n\n\t\tcase MCOUNTEREN_ADDR:\n\t\t\twrite(csrs.mcounteren, MCOUNTEREN_MASK);\n\t\t\tbreak;\n\n\t\tcase SCOUNTEREN_ADDR:\n\t\t\twrite(csrs.scounteren, MCOUNTEREN_MASK);\n\t\t\tbreak;\n\n\t\tcase MCOUNTINHIBIT_ADDR:\n\t\t\twrite(csrs.mcountinhibit, MCOUNTINHIBIT_MASK);\n\t\t\tbreak;\n\n\t\tcase FCSR_ADDR:\n\t\t\twrite(csrs.fcsr, FCSR_MASK);\n\t\t\tbreak;\n\n\t\tcase FFLAGS_ADDR:\n\t\t\tcsrs.fcsr.fields.fflags = value;\n\t\t\tbreak;\n\n\t\tcase FRM_ADDR:\n\t\t\tcsrs.fcsr.fields.frm = value;\n\t\t\tbreak;\n\n        // debug CSRs not supported, thus hardwired\n        case TSELECT_ADDR:\n        case TDATA1_ADDR:\n        case TDATA2_ADDR:\n        case TDATA3_ADDR:\n        case DCSR_ADDR:\n        case DPC_ADDR:\n        case DSCRATCH0_ADDR:\n        case DSCRATCH1_ADDR:\n            break;\n\n\t\tdefault:\n\t\t\tif (!csrs.is_valid_csr32_addr(addr))\n\t\t\t\tRAISE_ILLEGAL_INSTRUCTION();\n\n\t\t\tcsrs.default_write32(addr, value);\n\t}\n}\n\nvoid ISS::init(instr_memory_if *instr_mem, data_memory_if *data_mem, clint_if *clint, uint32_t entrypoint,\n               uint32_t sp) {\n\tthis->instr_mem = instr_mem;\n\tthis->mem = data_mem;\n\tthis->clint = clint;\n\tregs[RegFile::sp] = sp;\n\tpc = entrypoint;\n}\n\nvoid ISS::sys_exit() {\n\tshall_exit = true;\n}\n\nunsigned ISS::get_syscall_register_index() {\n\tif (csrs.misa.has_E_base_isa())\n\t\treturn RegFile::a5;\n\telse\n\t\treturn RegFile::a7;\n}\n\n\nuint64_t ISS::read_register(unsigned idx) {\n\treturn (uint32_t)regs.read(idx);    //NOTE: zero extend\n}\n\nvoid ISS::write_register(unsigned idx, uint64_t value) {\n\t// Since the value parameter in the function prototype is\n\t// a uint64_t, signed integer values (e.g. -1) get promoted\n\t// to values within this range. For example, -1 would be\n\t// promoted to (2**64)-1. As such, we cannot perform a\n\t// Boost lexical or numeric cast to uint32_t here as\n\t// these perform bounds checks. Instead, we perform a C\n\t// cast without bounds checks.\n\tregs.write(idx, (uint32_t)value);\n}\n\nuint64_t ISS::get_progam_counter(void) {\n    return pc;\n}\n\nvoid ISS::block_on_wfi(bool block) {\n    ignore_wfi = !block;\n}\n\nCoreExecStatus ISS::get_status(void) {\n    return status;\n}\n\nvoid ISS::set_status(CoreExecStatus s) {\n    status = s;\n}\n\nvoid ISS::enable_debug(void) {\n    debug_mode = true;\n}\n\nvoid ISS::insert_breakpoint(uint64_t addr) {\n    breakpoints.insert(addr);\n}\n\nvoid ISS::remove_breakpoint(uint64_t addr) {\n    breakpoints.erase(addr);\n}\n\nuint64_t ISS::get_hart_id() {\n    return csrs.mhartid.reg;\n}\n\nstd::vector<uint64_t> ISS::get_registers(void) {\n    std::vector<uint64_t> regvals;\n\n    for (auto v : regs.regs)\n        regvals.push_back((uint32_t)v); //NOTE: zero extend\n\n    return regvals;\n}\n\n\nvoid ISS::fp_finish_instr() {\n\tfp_set_dirty();\n\tfp_update_exception_flags();\n}\n\nvoid ISS::fp_prepare_instr() {\n\tassert(softfloat_exceptionFlags == 0);\n\tfp_require_not_off();\n}\n\nvoid ISS::fp_set_dirty() {\n\tcsrs.mstatus.fields.sd = 1;\n\tcsrs.mstatus.fields.fs = FS_DIRTY;\n}\n\nvoid ISS::fp_update_exception_flags() {\n\tif (softfloat_exceptionFlags) {\n\t\tfp_set_dirty();\n\t\tcsrs.fcsr.fields.fflags |= softfloat_exceptionFlags;\n\t\tsoftfloat_exceptionFlags = 0;\n\t}\n}\n\nvoid ISS::fp_setup_rm() {\n\tauto rm = instr.frm();\n\tif (rm == FRM_DYN)\n\t\trm = csrs.fcsr.fields.frm;\n\tif (rm >= FRM_RMM)\n\t\tRAISE_ILLEGAL_INSTRUCTION();\n\tsoftfloat_roundingMode = rm;\n}\n\nvoid ISS::fp_require_not_off() {\n\tif (csrs.mstatus.fields.fs == FS_OFF)\n\t\tRAISE_ILLEGAL_INSTRUCTION();\n}\n\nvoid ISS::return_from_trap_handler(PrivilegeLevel return_mode) {\n\tswitch (return_mode) {\n\t\tcase MachineMode:\n\t\t\tprv = csrs.mstatus.fields.mpp;\n\t\t\tcsrs.mstatus.fields.mie = csrs.mstatus.fields.mpie;\n\t\t\tcsrs.mstatus.fields.mpie = 1;\n\t\t\tpc = csrs.mepc.reg;\n\t\t\tif (csrs.misa.has_user_mode_extension())\n\t\t\t\tcsrs.mstatus.fields.mpp = UserMode;\n\t\t\telse\n\t\t\t\tcsrs.mstatus.fields.mpp = MachineMode;\n\t\t\tbreak;\n\n\t\tcase SupervisorMode:\n\t\t\tprv = csrs.mstatus.fields.spp;\n\t\t\tcsrs.mstatus.fields.sie = csrs.mstatus.fields.spie;\n\t\t\tcsrs.mstatus.fields.spie = 1;\n\t\t\tpc = csrs.sepc.reg;\n\t\t\tif (csrs.misa.has_user_mode_extension())\n\t\t\t\tcsrs.mstatus.fields.spp = UserMode;\n\t\t\telse\n\t\t\t\tcsrs.mstatus.fields.spp = SupervisorMode;\n\t\t\tbreak;\n\n\t\tcase UserMode:\n\t\t\tprv = UserMode;\n\t\t\tcsrs.mstatus.fields.uie = csrs.mstatus.fields.upie;\n\t\t\tcsrs.mstatus.fields.upie = 1;\n\t\t\tpc = csrs.uepc.reg;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"unknown privilege level \" + std::to_string(return_mode));\n\t}\n\n\tif (trace)\n\t\tprintf(\"[vp::iss] return from trap handler, time %s, pc %8x, prv %1x\\n\",\n\t\t       quantum_keeper.get_current_time().to_string().c_str(), pc, prv);\n}\n\nvoid ISS::trigger_external_interrupt(PrivilegeLevel level) {\n\tif (trace)\n\t\tstd::cout << \"[vp::iss] trigger external interrupt, \" << sc_core::sc_time_stamp() << std::endl;\n\n\tswitch (level) {\n\t\tcase UserMode:\n\t\t\tcsrs.mip.fields.ueip = true;\n\t\t\tbreak;\n\t\tcase SupervisorMode:\n\t\t\tcsrs.mip.fields.seip = true;\n\t\t\tbreak;\n\t\tcase MachineMode:\n\t\t\tcsrs.mip.fields.meip = true;\n\t\t\tbreak;\n\t}\n\n\twfi_event.notify(sc_core::SC_ZERO_TIME);\n}\n\nvoid ISS::clear_external_interrupt(PrivilegeLevel level) {\n\tif (trace)\n\t\tstd::cout << \"[vp::iss] clear external interrupt, \" << sc_core::sc_time_stamp() << std::endl;\n\n\tswitch (level) {\n\t\tcase UserMode:\n\t\t\tcsrs.mip.fields.ueip = false;\n\t\t\tbreak;\n\t\tcase SupervisorMode:\n\t\t\tcsrs.mip.fields.seip = false;\n\t\t\tbreak;\n\t\tcase MachineMode:\n\t\t\tcsrs.mip.fields.meip = false;\n\t\t\tbreak;\n\t}\n}\n\nvoid ISS::trigger_timer_interrupt(bool status) {\n\tif (trace)\n\t\tstd::cout << \"[vp::iss] trigger timer interrupt=\" << status << \", \" << sc_core::sc_time_stamp() << std::endl;\n\tcsrs.mip.fields.mtip = status;\n\twfi_event.notify(sc_core::SC_ZERO_TIME);\n}\n\nvoid ISS::trigger_software_interrupt(bool status) {\n\tif (trace)\n\t\tstd::cout << \"[vp::iss] trigger software interrupt=\" << status << \", \" << sc_core::sc_time_stamp() << std::endl;\n\tcsrs.mip.fields.msip = status;\n\twfi_event.notify(sc_core::SC_ZERO_TIME);\n}\n\nPrivilegeLevel ISS::prepare_trap(SimulationTrap &e) {\n\t// undo any potential pc update (for traps the pc should point to the originating instruction and not it's\n\t// successor)\n\tpc = last_pc;\n\tunsigned exc_bit = (1 << e.reason);\n\n\t// 1) machine mode execution takes any traps, independent of delegation setting\n\t// 2) non-delegated traps are processed in machine mode, independent of current execution mode\n\tif (prv == MachineMode || !(exc_bit & csrs.medeleg.reg)) {\n\t\tcsrs.mcause.fields.interrupt = 0;\n\t\tcsrs.mcause.fields.exception_code = e.reason;\n\t\tcsrs.mtval.reg = boost::lexical_cast<uint32_t>(e.mtval);\n\t\treturn MachineMode;\n\t}\n\n\t// see above machine mode comment\n\tif (prv == SupervisorMode || !(exc_bit & csrs.sedeleg.reg)) {\n\t\tcsrs.scause.fields.interrupt = 0;\n\t\tcsrs.scause.fields.exception_code = e.reason;\n\t\tcsrs.stval.reg = boost::lexical_cast<uint32_t>(e.mtval);\n\t\treturn SupervisorMode;\n\t}\n\n\tassert(prv == UserMode && (exc_bit & csrs.medeleg.reg) && (exc_bit & csrs.sedeleg.reg));\n\tcsrs.ucause.fields.interrupt = 0;\n\tcsrs.ucause.fields.exception_code = e.reason;\n\tcsrs.utval.reg = boost::lexical_cast<uint32_t>(e.mtval);\n\treturn UserMode;\n}\n\nvoid ISS::prepare_interrupt(const PendingInterrupts &e) {\n\tif (trace) {\n\t\tstd::cout << \"[vp::iss] prepare interrupt, pending=\" << e.pending << \", target-mode=\" << e.target_mode\n\t\t          << std::endl;\n\t}\n\n\tcsr_mip x{e.pending};\n\n\tExceptionCode exc;\n\tif (x.fields.meip)\n\t\texc = EXC_M_EXTERNAL_INTERRUPT;\n\telse if (x.fields.msip)\n\t\texc = EXC_M_SOFTWARE_INTERRUPT;\n\telse if (x.fields.mtip)\n\t\texc = EXC_M_TIMER_INTERRUPT;\n\telse if (x.fields.seip)\n\t\texc = EXC_S_EXTERNAL_INTERRUPT;\n\telse if (x.fields.ssip)\n\t\texc = EXC_S_SOFTWARE_INTERRUPT;\n\telse if (x.fields.stip)\n\t\texc = EXC_S_TIMER_INTERRUPT;\n\telse if (x.fields.ueip)\n\t\texc = EXC_U_EXTERNAL_INTERRUPT;\n\telse if (x.fields.usip)\n\t\texc = EXC_U_SOFTWARE_INTERRUPT;\n\telse if (x.fields.utip)\n\t\texc = EXC_U_TIMER_INTERRUPT;\n\telse\n\t\tthrow std::runtime_error(\"some pending interrupt must be available here\");\n\n\tswitch (e.target_mode) {\n\t\tcase MachineMode:\n\t\t\tcsrs.mcause.fields.exception_code = exc;\n\t\t\tcsrs.mcause.fields.interrupt = 1;\n\t\t\tbreak;\n\n\t\tcase SupervisorMode:\n\t\t\tcsrs.scause.fields.exception_code = exc;\n\t\t\tcsrs.scause.fields.interrupt = 1;\n\t\t\tbreak;\n\n\t\tcase UserMode:\n\t\t\tcsrs.ucause.fields.exception_code = exc;\n\t\t\tcsrs.ucause.fields.interrupt = 1;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"unknown privilege level \" + std::to_string(e.target_mode));\n\t}\n}\n\nPendingInterrupts ISS::compute_pending_interrupts() {\n\tuint32_t pending = csrs.mie.reg & csrs.mip.reg;\n\n\tif (!pending)\n\t\treturn {NoneMode, 0};\n\n\tauto m_pending = pending & ~csrs.mideleg.reg;\n\tif (m_pending && (prv < MachineMode || (prv == MachineMode && csrs.mstatus.fields.mie))) {\n\t\treturn {MachineMode, m_pending};\n\t}\n\n\tpending = pending & csrs.mideleg.reg;\n\tauto s_pending = pending & ~csrs.sideleg.reg;\n\tif (s_pending && (prv < SupervisorMode || (prv == SupervisorMode && csrs.mstatus.fields.sie))) {\n\t\treturn {SupervisorMode, s_pending};\n\t}\n\n\tauto u_pending = pending & csrs.sideleg.reg;\n\tif (u_pending && (prv == UserMode && csrs.mstatus.fields.uie)) {\n\t\treturn {UserMode, u_pending};\n\t}\n\n\treturn {NoneMode, 0};\n}\n\nvoid ISS::switch_to_trap_handler(PrivilegeLevel target_mode) {\n\tif (trace) {\n\t\tprintf(\"[vp::iss] switch to trap handler, time %s, last_pc %8x, pc %8x, irq %u, t-prv %1x\\n\",\n\t\t       quantum_keeper.get_current_time().to_string().c_str(), last_pc, pc, csrs.mcause.fields.interrupt, target_mode);\n\t}\n\n\t// free any potential LR/SC bus lock before processing a trap/interrupt\n\trelease_lr_sc_reservation();\n\n\tauto pp = prv;\n\tprv = target_mode;\n\n\tswitch (target_mode) {\n\t\tcase MachineMode:\n\t\t\tcsrs.mepc.reg = pc;\n\n\t\t\tcsrs.mstatus.fields.mpie = csrs.mstatus.fields.mie;\n\t\t\tcsrs.mstatus.fields.mie = 0;\n\t\t\tcsrs.mstatus.fields.mpp = pp;\n\n\t\t\tpc = csrs.mtvec.get_base_address();\n\n\t\t\tif(pc == 0) {\n\t\t\t\tif(error_on_zero_traphandler) {\n\t\t\t\t\tthrow std::runtime_error(\"[ISS] Took null trap handler in machine mode\");\n\t\t\t\t} else {\n\t\t\t\t\tstatic bool once = true;\n\t\t\t\t\tif (once)\n\t\t\t\t\t\tstd::cout << \"[ISS] Warn: Taking trap handler in machine mode to 0x0, this is probably an error.\" << std::endl;\n\t\t\t\t\tonce = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (csrs.mcause.fields.interrupt && csrs.mtvec.fields.mode == csr_mtvec::Mode::Vectored)\n\t\t\t\tpc += 4 * csrs.mcause.fields.exception_code;\n\t\t\tbreak;\n\n\t\tcase SupervisorMode:\n\t\t\tassert(prv == SupervisorMode || prv == UserMode);\n\n\t\t\tcsrs.sepc.reg = pc;\n\n\t\t\tcsrs.mstatus.fields.spie = csrs.mstatus.fields.sie;\n\t\t\tcsrs.mstatus.fields.sie = 0;\n\t\t\tcsrs.mstatus.fields.spp = pp;\n\n\t\t\tpc = csrs.stvec.get_base_address();\n\n\t\t\tif (csrs.scause.fields.interrupt && csrs.stvec.fields.mode == csr_mtvec::Mode::Vectored)\n\t\t\t\tpc += 4 * csrs.scause.fields.exception_code;\n\t\t\tbreak;\n\n\t\tcase UserMode:\n\t\t\tassert(prv == UserMode);\n\n\t\t\tcsrs.uepc.reg = pc;\n\n\t\t\tcsrs.mstatus.fields.upie = csrs.mstatus.fields.uie;\n\t\t\tcsrs.mstatus.fields.uie = 0;\n\n\t\t\tpc = csrs.utvec.get_base_address();\n\n\t\t\tif (csrs.ucause.fields.interrupt && csrs.utvec.fields.mode == csr_mtvec::Mode::Vectored)\n\t\t\t\tpc += 4 * csrs.ucause.fields.exception_code;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"unknown privilege level \" + std::to_string(target_mode));\n\t}\n}\n\nvoid ISS::performance_and_sync_update(Opcode::Mapping executed_op) {\n    ++total_num_instr;\n\n\tif (!csrs.mcountinhibit.fields.IR)\n\t\t++csrs.instret.reg;\n\n\tif (lr_sc_counter != 0) {\n\t\t--lr_sc_counter;\n\t\tassert (lr_sc_counter >= 0);\n\t\tif (lr_sc_counter == 0)\n            release_lr_sc_reservation();\n\t}\n\n\tauto new_cycles = instr_cycles[executed_op];\n\n\tif (!csrs.mcountinhibit.fields.CY)\n\t\tcycle_counter += new_cycles;\n\n\tquantum_keeper.inc(new_cycles);\n\tif (quantum_keeper.need_sync()) {\n\t    if (lr_sc_counter == 0) // match SystemC sync with bus unlocking in a tight LR_W/SC_W loop\n\t\t    quantum_keeper.sync();\n\t}\n}\n\nvoid ISS::run_step() {\n\tassert(regs.read(0) == 0);\n\n\t// speeds up the execution performance (non debug mode) significantly by\n\t// checking the additional flag first\n\tif (debug_mode && (breakpoints.find(pc) != breakpoints.end())) {\n\t\tstatus = CoreExecStatus::HitBreakpoint;\n\t\treturn;\n\t}\n\n\tlast_pc = pc;\n\ttry {\n\t\texec_step();\n\n\t\tauto x = compute_pending_interrupts();\n\t\tif (x.target_mode != NoneMode) {\n\t\t\tprepare_interrupt(x);\n\t\t\tswitch_to_trap_handler(x.target_mode);\n\t\t}\n\t} catch (SimulationTrap &e) {\n\t\tif (trace)\n\t\t\tstd::cout << \"take trap \" << e.reason << \", mtval=\" << e.mtval << std::endl;\n\t\tauto target_mode = prepare_trap(e);\n\t\tswitch_to_trap_handler(target_mode);\n\t}\n\n\t// NOTE: writes to zero register are supposedly allowed but must be ignored\n\t// (reset it after every instruction, instead of checking *rd != zero*\n\t// before every register write)\n\tregs.regs[regs.zero] = 0;\n\n\t// Do not use a check *pc == last_pc* here. The reason is that due to\n\t// interrupts *pc* can be set to *last_pc* accidentally (when jumping back\n\t// to *mepc*).\n\tif (shall_exit)\n\t\tstatus = CoreExecStatus::Terminated;\n\n\tperformance_and_sync_update(op);\n}\n\nvoid ISS::run() {\n\t// run a single step until either a breakpoint is hit or the execution\n\t// terminates\n\tdo {\n\t\trun_step();\n\t} while (status == CoreExecStatus::Runnable);\n\n\t// force sync to make sure that no action is missed\n\tquantum_keeper.sync();\n}\n\nvoid ISS::show() {\n\tboost::io::ios_flags_saver ifs(std::cout);\n\tstd::cout << \"=[ core : \" << csrs.mhartid.reg << \" ]===========================\" << std::endl;\n\tstd::cout << \"simulation time: \" << sc_core::sc_time_stamp() << std::endl;\n\tregs.show();\n\tstd::cout << \"pc = \" << std::hex << pc << std::endl;\n\tstd::cout << \"num-instr = \" << std::dec << csrs.instret.reg << std::endl;\n}\n"
  },
  {
    "path": "vp/src/core/rv32/iss.h",
    "content": "#pragma once\n\n#include \"core/common/bus_lock_if.h\"\n#include \"core/common/clint_if.h\"\n#include \"core/common/instr.h\"\n#include \"core/common/irq_if.h\"\n#include \"core/common/trap.h\"\n#include \"core/common/debug.h\"\n#include \"csr.h\"\n#include \"fp.h\"\n#include \"mem_if.h\"\n#include \"syscall_if.h\"\n#include \"util/common.h\"\n\n#include <assert.h>\n#include <stdint.h>\n#include <string.h>\n\n#include <functional>\n#include <iostream>\n#include <map>\n#include <memory>\n#include <stdexcept>\n#include <unordered_set>\n#include <vector>\n\n#include <tlm_utils/simple_initiator_socket.h>\n#include <tlm_utils/tlm_quantumkeeper.h>\n#include <systemc>\n\nnamespace rv32 {\n\nstruct RegFile {\n\tstatic constexpr unsigned NUM_REGS = 32;\n\n\tint32_t regs[NUM_REGS];\n\n\tRegFile();\n\n\tRegFile(const RegFile &other);\n\n\tvoid write(uint32_t index, int32_t value);\n\n\tint32_t read(uint32_t index);\n\n\tuint32_t shamt(uint32_t index);\n\n\tint32_t &operator[](const uint32_t idx);\n\n\tvoid show();\n\n\tenum e : uint16_t {\n\t\tx0 = 0,\n\t\tx1,\n\t\tx2,\n\t\tx3,\n\t\tx4,\n\t\tx5,\n\t\tx6,\n\t\tx7,\n\t\tx8,\n\t\tx9,\n\t\tx10,\n\t\tx11,\n\t\tx12,\n\t\tx13,\n\t\tx14,\n\t\tx15,\n\t\tx16,\n\t\tx17,\n\t\tx18,\n\t\tx19,\n\t\tx20,\n\t\tx21,\n\t\tx22,\n\t\tx23,\n\t\tx24,\n\t\tx25,\n\t\tx26,\n\t\tx27,\n\t\tx28,\n\t\tx29,\n\t\tx30,\n\t\tx31,\n\n\t\tzero = x0,\n\t\tra = x1,\n\t\tsp = x2,\n\t\tgp = x3,\n\t\ttp = x4,\n\t\tt0 = x5,\n\t\tt1 = x6,\n\t\tt2 = x7,\n\t\ts0 = x8,\n\t\tfp = x8,\n\t\ts1 = x9,\n\t\ta0 = x10,\n\t\ta1 = x11,\n\t\ta2 = x12,\n\t\ta3 = x13,\n\t\ta4 = x14,\n\t\ta5 = x15,\n\t\ta6 = x16,\n\t\ta7 = x17,\n\t\ts2 = x18,\n\t\ts3 = x19,\n\t\ts4 = x20,\n\t\ts5 = x21,\n\t\ts6 = x22,\n\t\ts7 = x23,\n\t\ts8 = x24,\n\t\ts9 = x25,\n\t\ts10 = x26,\n\t\ts11 = x27,\n\t\tt3 = x28,\n\t\tt4 = x29,\n\t\tt5 = x30,\n\t\tt6 = x31,\n\t};\n};\n\n// NOTE: on this branch, currently the *simple-timing* model is still directly\n// integrated in the ISS. Merge the *timedb* branch to use the timing_if.\nstruct ISS;\n\nstruct timing_if {\n\tvirtual ~timing_if() {}\n\n\tvirtual void update_timing(Instruction instr, Opcode::Mapping op, ISS &iss) = 0;\n};\n\n/* Buffer to be used between the ISS and instruction memory interface to cache compressed instructions.\n * In case the ISS does not support compressed instructions, then this buffer is not necessary and the ISS\n * can use the memory interface directly. */\nstruct InstructionBuffer {\n\tinstr_memory_if *instr_mem = nullptr;\n\tuint32_t last_fetch_addr = 0;\n\tuint32_t buffer = 0;\n\n\tuint32_t load_instr(uint64_t addr) {\n\t\tif (addr == (last_fetch_addr + 2))\n\t\t\treturn (buffer >> 16);\n\n\t\tlast_fetch_addr = addr;\n\t\tbuffer = instr_mem->load_instr(addr);\n\t\treturn buffer;\n\t}\n};\n\nstruct PendingInterrupts {\n\tPrivilegeLevel target_mode;\n\tuint32_t pending;\n};\n\nstruct ISS : public external_interrupt_target, public clint_interrupt_target, public iss_syscall_if, public debug_target_if {\n\tclint_if *clint = nullptr;\n\tinstr_memory_if *instr_mem = nullptr;\n\tdata_memory_if *mem = nullptr;\n\tsyscall_emulator_if *sys = nullptr;  // optional, if provided, the iss will intercept and handle syscalls directly\n\tRegFile regs;\n\tFpRegs fp_regs;\n\tuint32_t pc = 0;\n\tuint32_t last_pc = 0;\n\tbool trace = false;\n\tbool shall_exit = false;\n    bool ignore_wfi = false;\n    bool error_on_zero_traphandler = false;\n\tcsr_table csrs;\n\tPrivilegeLevel prv = MachineMode;\n\tint64_t lr_sc_counter = 0;\n\tuint64_t total_num_instr = 0;\n\n\t// last decoded and executed instruction and opcode\n\tInstruction instr;\n\tOpcode::Mapping op;\n\n\tCoreExecStatus status = CoreExecStatus::Runnable;\n\tstd::unordered_set<uint32_t> breakpoints;\n\tbool debug_mode = false;\n\n\tsc_core::sc_event wfi_event;\n\n\tstd::string systemc_name;\n\ttlm_utils::tlm_quantumkeeper quantum_keeper;\n\tsc_core::sc_time cycle_time;\n\tsc_core::sc_time cycle_counter;  // use a separate cycle counter, since cycle count can be inhibited\n\tstd::array<sc_core::sc_time, Opcode::NUMBER_OF_INSTRUCTIONS> instr_cycles;\n\n\tstatic constexpr int32_t REG_MIN = INT32_MIN;\n    static constexpr unsigned xlen = 32;\n\n\tISS(uint32_t hart_id, bool use_E_base_isa = false);\n\n\tvoid exec_step();\n\n\tuint64_t _compute_and_get_current_cycles();\n\n\tvoid init(instr_memory_if *instr_mem, data_memory_if *data_mem, clint_if *clint, uint32_t entrypoint, uint32_t sp);\n\n\tvoid trigger_external_interrupt(PrivilegeLevel level) override;\n\n\tvoid clear_external_interrupt(PrivilegeLevel level) override;\n\n\tvoid trigger_timer_interrupt(bool status) override;\n\n\tvoid trigger_software_interrupt(bool status) override;\n\n\n\tvoid sys_exit() override;\n\tunsigned get_syscall_register_index() override;\n\tuint64_t read_register(unsigned idx) override;\n\tvoid write_register(unsigned idx, uint64_t value) override;\n\n    std::vector<uint64_t> get_registers(void) override;\n\n    Architecture get_architecture(void) override {\n        return RV32;\n    }\n\n    uint64_t get_progam_counter(void) override;\n    void enable_debug(void) override;\n    CoreExecStatus get_status(void) override;\n    void set_status(CoreExecStatus) override;\n    void block_on_wfi(bool) override;\n\n    void insert_breakpoint(uint64_t) override;\n    void remove_breakpoint(uint64_t) override;\n\n\tuint64_t get_hart_id() override;\n\n\n\tvoid release_lr_sc_reservation() {\n\t\tlr_sc_counter = 0;\n\t\tmem->atomic_unlock();\n\t}\n\n\tvoid fp_prepare_instr();\n\tvoid fp_finish_instr();\n\tvoid fp_set_dirty();\n\tvoid fp_update_exception_flags();\n\tvoid fp_setup_rm();\n\tvoid fp_require_not_off();\n\n\tuint32_t get_csr_value(uint32_t addr);\n\tvoid set_csr_value(uint32_t addr, uint32_t value);\n\n\tbool is_invalid_csr_access(uint32_t csr_addr, bool is_write);\n\tvoid validate_csr_counter_read_access_rights(uint32_t addr);\n\n\tunsigned pc_alignment_mask() {\n\t\tif (csrs.misa.has_C_extension())\n\t\t\treturn ~0x1;\n\t\telse\n\t\t\treturn ~0x3;\n\t}\n\n\tinline void trap_check_pc_alignment() {\n\t\tassert(!(pc & 0x1) && \"not possible due to immediate formats and jump execution\");\n\n\t\tif (unlikely((pc & 0x3) && (!csrs.misa.has_C_extension()))) {\n\t\t\t// NOTE: misaligned instruction address not possible on machines supporting compressed instructions\n\t\t\traise_trap(EXC_INSTR_ADDR_MISALIGNED, pc);\n\t\t}\n\t}\n\n\ttemplate <unsigned Alignment, bool isLoad>\n\tinline void trap_check_addr_alignment(uint32_t addr) {\n\t\tif (unlikely(addr % Alignment)) {\n\t\t\traise_trap(isLoad ? EXC_LOAD_ADDR_MISALIGNED : EXC_STORE_AMO_ADDR_MISALIGNED, addr);\n\t\t}\n\t}\n\n\tinline void execute_amo(Instruction &instr, std::function<int32_t(int32_t, int32_t)> operation) {\n\t\tuint32_t addr = regs[instr.rs1()];\n\t\ttrap_check_addr_alignment<4, false>(addr);\n\t\tuint32_t data;\n\t\ttry {\n\t\t\tdata = mem->atomic_load_word(addr);\n\t\t} catch (SimulationTrap &e) {\n\t\t\tif (e.reason == EXC_LOAD_ACCESS_FAULT)\n\t\t\t\te.reason = EXC_STORE_AMO_ACCESS_FAULT;\n\t\t\tthrow e;\n\t\t}\n\t\tuint32_t val = operation(data, regs[instr.rs2()]);\n\t\tmem->atomic_store_word(addr, val);\n\t\tregs[instr.rd()] = data;\n\t}\n\n\tinline bool m_mode() {\n\t\treturn prv == MachineMode;\n\t}\n\n\tinline bool s_mode() {\n\t\treturn prv == SupervisorMode;\n\t}\n\n\tinline bool u_mode() {\n\t\treturn prv == UserMode;\n\t}\n\n\tPrivilegeLevel prepare_trap(SimulationTrap &e);\n\n\tvoid prepare_interrupt(const PendingInterrupts &x);\n\n\tPendingInterrupts compute_pending_interrupts();\n\n\tbool has_pending_enabled_interrupts() {\n\t\treturn compute_pending_interrupts().target_mode != NoneMode;\n\t}\n\n\tbool has_local_pending_enabled_interrupts() {\n\t\treturn csrs.mie.reg & csrs.mip.reg;\n\t}\n\n\tvoid return_from_trap_handler(PrivilegeLevel return_mode);\n\n\tvoid switch_to_trap_handler(PrivilegeLevel target_mode);\n\n\tvoid performance_and_sync_update(Opcode::Mapping executed_op);\n\n\tvoid run_step() override;\n\n\tvoid run() override;\n\n\tvoid show();\n};\n\n/* Do not call the run function of the ISS directly but use one of the Runner\n * wrappers. */\nstruct DirectCoreRunner : public sc_core::sc_module {\n\tISS &core;\n\tstd::string thread_name;\n\n\tSC_HAS_PROCESS(DirectCoreRunner);\n\n\tDirectCoreRunner(ISS &core) : sc_module(sc_core::sc_module_name(core.systemc_name.c_str())), core(core) {\n\t\tthread_name = \"run\" + std::to_string(core.get_hart_id());\n\t\tSC_NAMED_THREAD(run, thread_name.c_str());\n\t}\n\n\tvoid run() {\n\t\tcore.run();\n\n\t\tif (core.status == CoreExecStatus::HitBreakpoint) {\n\t\t\tthrow std::runtime_error(\n\t\t\t    \"Breakpoints are not supported in the direct runner, use the debug \"\n\t\t\t    \"runner instead.\");\n\t\t}\n\t\tassert(core.status == CoreExecStatus::Terminated);\n\n\t\tsc_core::sc_stop();\n\t}\n};\n\n}  // namespace rv32\n"
  },
  {
    "path": "vp/src/core/rv32/mem.h",
    "content": "#pragma once\n\n#include \"core/common/dmi.h\"\n#include \"iss.h\"\n#include \"mmu.h\"\n\nnamespace rv32 {\n\n/* For optimization, use DMI to fetch instructions */\nstruct InstrMemoryProxy : public instr_memory_if {\n\tMemoryDMI dmi;\n\n\ttlm_utils::tlm_quantumkeeper &quantum_keeper;\n\tsc_core::sc_time clock_cycle = sc_core::sc_time(10, sc_core::SC_NS);\n\tsc_core::sc_time access_delay = clock_cycle * 2;\n\n\tInstrMemoryProxy(const MemoryDMI &dmi, ISS &owner) : dmi(dmi), quantum_keeper(owner.quantum_keeper) {}\n\n\tvirtual uint32_t load_instr(uint64_t pc) override {\n\t\tquantum_keeper.inc(access_delay);\n\t\treturn dmi.load<uint32_t>(pc);\n\t}\n};\n\nstruct CombinedMemoryInterface : public sc_core::sc_module,\n                                 public instr_memory_if,\n                                 public data_memory_if,\n                                 public mmu_memory_if  {\n\tISS &iss;\n\tstd::shared_ptr<bus_lock_if> bus_lock;\n\tuint64_t lr_addr = 0;\n\n\ttlm_utils::simple_initiator_socket<CombinedMemoryInterface> isock;\n\ttlm_utils::tlm_quantumkeeper &quantum_keeper;\n\n\t// optionally add DMI ranges for optimization\n\tsc_core::sc_time clock_cycle = sc_core::sc_time(10, sc_core::SC_NS);\n\tsc_core::sc_time dmi_access_delay = clock_cycle * 4;\n\tstd::vector<MemoryDMI> dmi_ranges;\n\n    MMU *mmu;\n\n\tCombinedMemoryInterface(sc_core::sc_module_name, ISS &owner, MMU *mmu = nullptr)\n\t    : iss(owner), quantum_keeper(iss.quantum_keeper), mmu(mmu) {\n\t}\n\n    uint64_t v2p(uint64_t vaddr, MemoryAccessType type) override {\n\t    if (mmu == nullptr)\n\t        return vaddr;\n        return mmu->translate_virtual_to_physical_addr(vaddr, type);\n    }\n\n\tinline void _do_transaction(tlm::tlm_command cmd, uint64_t addr, uint8_t *data, unsigned num_bytes) {\n\t\ttlm::tlm_generic_payload trans;\n\t\ttrans.set_command(cmd);\n\t\ttrans.set_address(addr);\n\t\ttrans.set_data_ptr(data);\n\t\ttrans.set_data_length(num_bytes);\n\t\ttrans.set_response_status(tlm::TLM_OK_RESPONSE);\n\n\t\tsc_core::sc_time local_delay = quantum_keeper.get_local_time();\n\n\t\tisock->b_transport(trans, local_delay);\n\n\t\tassert(local_delay >= quantum_keeper.get_local_time());\n\t\tquantum_keeper.set(local_delay);\n\n\t\tif (trans.is_response_error()) {\n\t\t\tif (iss.trace || iss.sys)\t// if iss has syscall interface, it likely has no traphandler for this\n\t\t\t\tstd::cout << \"WARNING: core memory transaction failed for address 0x\" << std::hex << addr << std::dec << std::endl;\n\t\t\tif (cmd == tlm::TLM_READ_COMMAND)\n\t\t\t\traise_trap(EXC_LOAD_PAGE_FAULT, addr);\n\t\t\telse if (cmd == tlm::TLM_WRITE_COMMAND)\n\t\t\t\traise_trap(EXC_STORE_AMO_PAGE_FAULT, addr);\n\t\t\telse\n\t\t\t\tthrow std::runtime_error(\"TLM command must be read or write\");\n\t\t}\n\t}\n\n\ttemplate <typename T>\n\tinline T _raw_load_data(uint64_t addr) {\n\t\t// NOTE: a DMI load will not context switch (SystemC) and not modify the memory, hence should be able to\n\t\t// postpone the lock after the dmi access\n\t\tbus_lock->wait_for_access_rights(iss.get_hart_id());\n\n\t\tfor (auto &e : dmi_ranges) {\n\t\t\tif (e.contains(addr)) {\n\t\t\t\tquantum_keeper.inc(dmi_access_delay);\n\t\t\t\treturn e.load<T>(addr);\n\t\t\t}\n\t\t}\n\n\t\tT ans;\n\t\t_do_transaction(tlm::TLM_READ_COMMAND, addr, (uint8_t *)&ans, sizeof(T));\n\t\treturn ans;\n\t}\n\n\ttemplate <typename T>\n\tinline void _raw_store_data(uint64_t addr, T value) {\n\t\tbus_lock->wait_for_access_rights(iss.get_hart_id());\n\n\t\tbool done = false;\n\t\tfor (auto &e : dmi_ranges) {\n\t\t\tif (e.contains(addr)) {\n\t\t\t\tquantum_keeper.inc(dmi_access_delay);\n\t\t\t\te.store(addr, value);\n\t\t\t\tdone = true;\n\t\t\t}\n\t\t}\n\n\t\tif (!done)\n\t\t\t_do_transaction(tlm::TLM_WRITE_COMMAND, addr, (uint8_t *)&value, sizeof(T));\n\t\tatomic_unlock();\n\t}\n\n\n    template <typename T>\n    inline T _load_data(uint64_t addr) {\n        return _raw_load_data<T>(v2p(addr, LOAD));\n    }\n\n    template <typename T>\n    inline void _store_data(uint64_t addr, T value) {\n        _raw_store_data(v2p(addr, STORE), value);\n    }\n\n    uint64_t mmu_load_pte64(uint64_t addr) override {\n        return _raw_load_data<uint64_t>(addr);\n    }\n    uint64_t mmu_load_pte32(uint64_t addr) override {\n        return _raw_load_data<uint32_t>(addr);\n    }\n    void mmu_store_pte32(uint64_t addr, uint32_t value) override {\n        _raw_store_data(addr, value);\n    }\n\n    void flush_tlb() override {\n        mmu->flush_tlb();\n    }\n\n    uint32_t load_instr(uint64_t addr) override {\n        return _raw_load_data<uint32_t>(v2p(addr, FETCH));\n    }\n\n    int64_t load_double(uint64_t addr) override {\n        return _load_data<int64_t>(addr);\n    }\n\tint32_t load_word(uint64_t addr) override {\n\t\treturn _load_data<int32_t>(addr);\n\t}\n\tint32_t load_half(uint64_t addr) override {\n\t\treturn _load_data<int16_t>(addr);\n\t}\n\tint32_t load_byte(uint64_t addr) override {\n\t\treturn _load_data<int8_t>(addr);\n\t}\n\tuint32_t load_uhalf(uint64_t addr) override {\n\t\treturn _load_data<uint16_t>(addr);\n\t}\n\tuint32_t load_ubyte(uint64_t addr) override {\n\t\treturn _load_data<uint8_t>(addr);\n\t}\n\n    void store_double(uint64_t addr, uint64_t value) override {\n        _store_data(addr, value);\n    }\n\tvoid store_word(uint64_t addr, uint32_t value) override {\n\t\t_store_data(addr, value);\n\t}\n\tvoid store_half(uint64_t addr, uint16_t value) override {\n\t\t_store_data(addr, value);\n\t}\n\tvoid store_byte(uint64_t addr, uint8_t value) override {\n\t\t_store_data(addr, value);\n\t}\n\n\tvirtual int32_t atomic_load_word(uint64_t addr) override {\n\t\tbus_lock->lock(iss.get_hart_id());\n\t\treturn load_word(addr);\n\t}\n\tvirtual void atomic_store_word(uint64_t addr, uint32_t value) override {\n\t\tassert(bus_lock->is_locked(iss.get_hart_id()));\n\t\tstore_word(addr, value);\n\t}\n\tvirtual int32_t atomic_load_reserved_word(uint64_t addr) override {\n\t\tbus_lock->lock(iss.get_hart_id());\n\t\tlr_addr = addr;\n\t\treturn load_word(addr);\n\t}\n\tvirtual bool atomic_store_conditional_word(uint64_t addr, uint32_t value) override {\n\t\t/* According to the RISC-V ISA, an implementation can fail each LR/SC sequence that does not satisfy the forward\n\t\t * progress semantic.\n\t\t * The lock is established by the LR instruction and the lock is kept while forward progress is maintained. */\n\t\tif (bus_lock->is_locked(iss.get_hart_id())) {\n\t\t\tif (addr == lr_addr) {\n\t\t\t\tstore_word(addr, value);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tatomic_unlock();\n\t\t}\n\t\treturn false;\n\t}\n\tvirtual void atomic_unlock() override {\n\t\tbus_lock->unlock(iss.get_hart_id());\n\t}\n};\n\n}  // namespace rv32\n"
  },
  {
    "path": "vp/src/core/rv32/mem_if.h",
    "content": "#pragma once\n\n#include <stdint.h>\n\nnamespace rv32 {\n\nstruct instr_memory_if {\n\tvirtual ~instr_memory_if() {}\n\n\tvirtual uint32_t load_instr(uint64_t pc) = 0;\n};\n\n//NOTE: load/store double is used for floating point D extension\nstruct data_memory_if {\n\tvirtual ~data_memory_if() {}\n\n    virtual int64_t load_double(uint64_t addr) = 0;\n\tvirtual int32_t load_word(uint64_t addr) = 0;\n\tvirtual int32_t load_half(uint64_t addr) = 0;\n\tvirtual int32_t load_byte(uint64_t addr) = 0;\n\tvirtual uint32_t load_uhalf(uint64_t addr) = 0;\n\tvirtual uint32_t load_ubyte(uint64_t addr) = 0;\n\n    virtual void store_double(uint64_t addr, uint64_t value) = 0;\n\tvirtual void store_word(uint64_t addr, uint32_t value) = 0;\n\tvirtual void store_half(uint64_t addr, uint16_t value) = 0;\n\tvirtual void store_byte(uint64_t addr, uint8_t value) = 0;\n\n\tvirtual int32_t atomic_load_word(uint64_t addr) = 0;\n\tvirtual void atomic_store_word(uint64_t addr, uint32_t value) = 0;\n\tvirtual int32_t atomic_load_reserved_word(uint64_t addr) = 0;\n\tvirtual bool atomic_store_conditional_word(uint64_t addr, uint32_t value) = 0;\n\tvirtual void atomic_unlock() = 0;\n\n    virtual void flush_tlb() = 0;\n};\n\n}  // namespace rv32"
  },
  {
    "path": "vp/src/core/rv32/mmu.h",
    "content": "#pragma once\n\n#include \"iss.h\"\n#include \"core/common/mmu.h\"\n\nnamespace rv32 {\n\n    typedef GenericMMU<ISS> MMU;\n\n}  // namespace rv64"
  },
  {
    "path": "vp/src/core/rv32/syscall.cpp",
    "content": "#include \"syscall.h\"\n\n#include <assert.h>\n#include <sys/stat.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include <iostream>\n#include <stdexcept>\n\n#include <boost/lexical_cast.hpp>\n\nusing namespace rv32;\n\n// see: riscv-gnu-toolchain/riscv-newlib/libgloss/riscv/\n// for syscall implementation in the risc-v C lib (many are ignored and just return -1)\n\ntypedef int32_t rv32_long;\n\ntypedef int32_t rv32_time_t;\n\nstruct rv32_timeval {\n\trv32_time_t tv_sec;\n\trv32_time_t tv_usec;\n};\n\nstruct rv32_timespec {\n\trv32_time_t tv_sec;\n\trv32_time_t tv_nsec;\n};\n\nstruct rv32_stat {\n\tuint64_t st_dev;\n\tuint64_t st_ino;\n\tuint32_t st_mode;\n\tuint32_t st_nlink;\n\tuint32_t st_uid;\n\tuint32_t st_gid;\n\tuint64_t st_rdev;\n\tuint64_t __pad1;\n\tint64_t st_size;\n\tint32_t st_blksize;\n\tint32_t __pad2;\n\tint64_t st_blocks;\n\trv32_timespec st_atim;\n\trv32_timespec st_mtim;\n\trv32_timespec st_ctim;\n\tint32_t __glibc_reserved[2];\n};\n\nvoid _copy_timespec(rv32_timespec *dst, timespec *src) {\n\tdst->tv_sec = src->tv_sec;\n\tdst->tv_nsec = src->tv_nsec;\n}\n\nint sys_fstat(SyscallHandler *sys, int fd, rv32_stat *s_addr) {\n\tstruct stat x;\n\tint ans = fstat(fd, &x);\n\tif (ans == 0) {\n\t\trv32_stat *p = (rv32_stat *)sys->guest_to_host_pointer(s_addr);\n\t\tp->st_dev = x.st_dev;\n\t\tp->st_ino = x.st_ino;\n\t\tp->st_mode = x.st_mode;\n\t\tp->st_nlink = x.st_nlink;\n\t\tp->st_uid = x.st_uid;\n\t\tp->st_gid = x.st_gid;\n\t\tp->st_rdev = x.st_rdev;\n\t\tp->st_size = x.st_size;\n\t\tp->st_blksize = x.st_blksize;\n\t\tp->st_blocks = x.st_blocks;\n\t\t_copy_timespec(&p->st_atim, &x.st_atim);\n\t\t_copy_timespec(&p->st_mtim, &x.st_mtim);\n\t\t_copy_timespec(&p->st_ctim, &x.st_ctim);\n\t}\n\treturn ans;\n}\n\nint sys_gettimeofday(SyscallHandler *sys, rv32_timeval *tp, void *tzp) {\n\t/*\n\t * timeval is using a struct with two long arguments.\n\t * The second argument tzp currently is not used by riscv code.\n\t */\n\tassert(tzp == 0);\n\n\tstruct timeval x;\n\tint ans = gettimeofday(&x, 0);\n\n\trv32_timeval *p = (rv32_timeval *)sys->guest_to_host_pointer(tp);\n\tp->tv_sec = x.tv_sec;\n\tp->tv_usec = x.tv_usec;\n\treturn ans;\n}\n\nint sys_time(SyscallHandler *sys, rv32_time_t *tloc) {\n\ttime_t host_ans = time(0);\n\n\trv32_time_t guest_ans = boost::lexical_cast<rv32_time_t>(host_ans);\n\n\tif (tloc != 0) {\n\t\trv32_time_t *p = (rv32_time_t *)sys->guest_to_host_pointer(tloc);\n\t\t*p = guest_ans;\n\t}\n\n\treturn boost::lexical_cast<int>(guest_ans);\n}\n\nnamespace rv_sc {\n// see: riscv-gnu-toolchain/riscv/riscv32-unknown-elf/include/sys/_default_fcntl.h\nconstexpr uint32_t RDONLY = 0x0000; /* +1 == FREAD */\nconstexpr uint32_t WRONLY = 0x0001; /* +1 == FWRITE */\nconstexpr uint32_t RDWR = 0x0002;   /* +1 == FREAD|FWRITE */\nconstexpr uint32_t APPEND = 0x0008;\nconstexpr uint32_t CREAT = 0x0200;\nconstexpr uint32_t TRUNC = 0x0400;\n}  // namespace rv_sc\n\nint translateRVFlagsToHost(const int flags) {\n\tint ret = 0;\n\tret |= flags & rv_sc::RDONLY ? O_RDONLY : 0;\n\tret |= flags & rv_sc::WRONLY ? O_WRONLY : 0;\n\tret |= flags & rv_sc::RDWR ? O_RDWR : 0;\n\tret |= flags & rv_sc::APPEND ? O_APPEND : 0;\n\tret |= flags & rv_sc::CREAT ? O_CREAT : 0;\n\tret |= flags & rv_sc::TRUNC ? O_TRUNC : 0;\n\n\tif (ret == 0 && flags != 0) {\n\t\tthrow std::runtime_error(\"unsupported flag\");\n\t}\n\n\treturn ret;\n}\n\nint sys_brk(SyscallHandler *sys, void *addr) {\n\tif (addr == 0) {\n\t\t// riscv newlib expects brk to return current heap address when zero is passed in\n\t\treturn boost::lexical_cast<int>(sys->hp);\n\t} else {\n\t\t// NOTE: can also shrink again\n\t\tauto n = (uintptr_t)addr;\n\t\tsys->hp = n;\n\n\t\tif (sys->hp > sys->max_heap)\n\t\t\tsys->max_heap = sys->hp;\n\n\t\t// same for brk increase/decrease\n\t\treturn boost::lexical_cast<int>(n);\n\t}\n}\n\nint sys_write(SyscallHandler *sys, int fd, const void *buf, size_t count) {\n\tconst char *p = (const char *)sys->guest_to_host_pointer((void *)buf);\n\n\tauto ans = write(fd, p, count);\n\n\tif (ans < 0) {\n\t\tstd::cout << \"WARNING [sys-write error]: \" << strerror(errno) << std::endl;\n\t\tstd::cout << \"  fd = \" << fd << std::endl;\n\t\tstd::cout << \"  count = \" << count << std::endl;\n\t\tassert(false);\n\t}\n\n\treturn ans;\n}\n\nint sys_read(SyscallHandler *sys, int fd, void *buf, size_t count) {\n\tchar *p = (char *)sys->guest_to_host_pointer(buf);\n\n\tauto ans = read(fd, p, count);\n\n\tassert(ans >= 0);\n\n\treturn ans;\n}\n\nint sys_lseek(int fd, off_t offset, int whence) {\n\tauto ans = lseek(fd, offset, whence);\n\n\treturn ans;\n}\n\nint sys_open(SyscallHandler *sys, const char *pathname, int flags, mode_t mode) {\n\tconst char *host_pathname = (char *)sys->guest_to_host_pointer((void *)pathname);\n\n\tauto ans = open(host_pathname, translateRVFlagsToHost(flags), mode);\n\n\tstd::cout << \"[sys_open] \" << host_pathname << \", \" << flags << \" (translated to \" << translateRVFlagsToHost(flags)\n\t          << \"), \" << mode << std::endl;\n\n\treturn ans;\n}\n\nint sys_close(int fd) {\n\tif (fd == STDOUT_FILENO || fd == STDIN_FILENO || fd == STDERR_FILENO) {\n\t\t// ignore closing of std streams, just return success\n\t\treturn 0;\n\t} else {\n\t\treturn close(fd);\n\t}\n}\n\n/*\n *  TODO: Some parameters need to be aligned to the hosts word width (mostly 64 bit)\n *\tEspecially when coming from a 32 bit guest system.\n */\n\nint SyscallHandler::execute_syscall(uint64_t n, uint64_t _a0, uint64_t _a1, uint64_t _a2, uint64_t) {\n\t// NOTE: when linking with CRT, the most basic example only calls *gettimeofday* and finally *exit*\n\n\tswitch (n) {\n\t\tcase SYS_fstat:\n\t\t\treturn sys_fstat(this, _a0, (rv32_stat *)_a1);\n\n\t\tcase SYS_gettimeofday:\n\t\t\treturn sys_gettimeofday(this, (struct rv32_timeval *)_a0, (void *)_a1);\n\n\t\tcase SYS_brk:\n\t\t\treturn sys_brk(this, (void *)_a0);\n\n\t\tcase SYS_time:\n\t\t\treturn sys_time(this, (rv32_time_t *)_a0);\n\n\t\tcase SYS_write:\n\t\t\treturn sys_write(this, _a0, (void *)_a1, _a2);\n\n\t\tcase SYS_read:\n\t\t\treturn sys_read(this, _a0, (void *)_a1, _a2);\n\n\t\tcase SYS_lseek:\n\t\t\treturn sys_lseek(_a0, _a1, _a2);\n\n\t\tcase SYS_open:\n\t\t\treturn sys_open(this, (const char *)_a0, _a1, _a2);\n\n\t\tcase SYS_close:\n\t\t\treturn sys_close(_a0);\n\n\t\tcase SYS_exit:\n\t\t\t// If the software requested a non-zero exit code then terminate directly.\n\t\t\t// Otherwise, stop the SystemC simulation and exit with a zero exit code.\n\t\t\tif (_a0) exit(_a0);\n\n\t\t\tshall_exit = true;\n\t\t\treturn 0;\n\n\t\tcase SYS_host_error:\n\t\t\tthrow std::runtime_error(\"SYS_host_error\");\n\n\t\tcase SYS_host_test_pass:\n\t\t\tstd::cout << \"TEST_PASS\" << std::endl;\n\t\t\tshall_exit = true;\n\t\t\treturn 0;\n\n\t\tcase SYS_host_test_fail:\n\t\t\tstd::cout << \"TEST_FAIL (testnum = \" << _a0 << \")\" << std::endl;\n\t\t\tshall_exit = true;\n\t\t\treturn 0;\n\t}\n\n\tstd::cerr << \"unsupported syscall '\" << n << \"'\" << std::endl;\n\tstd::cerr << \"is this perhaps a trap ExceptionCode? \" << std::endl;\n\tthrow std::runtime_error(\"unsupported syscall '\" + std::to_string(n) + \"'\");\n}\n"
  },
  {
    "path": "vp/src/core/rv32/syscall.h",
    "content": "#pragma once\n\n#include <assert.h>\n#include <fcntl.h>\n#include <stdint.h>\n\n#include <boost/lexical_cast.hpp>\n\n// see: newlib/libgloss/riscv @\n// https://github.com/riscv/riscv-newlib/tree/riscv-newlib-2.5.0/libgloss/riscv\n\n#define SYS_exit 93\n#define SYS_exit_group 94\n#define SYS_getpid 172\n#define SYS_kill 129\n#define SYS_read 63\n#define SYS_write 64\n#define SYS_open 1024\n#define SYS_openat 56\n#define SYS_close 57\n#define SYS_lseek 62\n#define SYS_brk 214\n#define SYS_link 1025\n#define SYS_unlink 1026\n#define SYS_mkdir 1030\n#define SYS_chdir 49\n#define SYS_getcwd 17\n#define SYS_stat 1038\n#define SYS_fstat 80\n#define SYS_lstat 1039\n#define SYS_fstatat 79\n#define SYS_access 1033\n#define SYS_faccessat 48\n#define SYS_pread 67\n#define SYS_pwrite 68\n#define SYS_uname 160\n#define SYS_getuid 174\n#define SYS_geteuid 175\n#define SYS_getgid 176\n#define SYS_getegid 177\n#define SYS_mmap 222\n#define SYS_munmap 215\n#define SYS_mremap 216\n#define SYS_time 1062\n#define SYS_getmainvars 2011\n#define SYS_rt_sigaction 134\n#define SYS_writev 66\n#define SYS_gettimeofday 169\n#define SYS_times 153\n#define SYS_fcntl 25\n#define SYS_getdents 61\n#define SYS_dup 23\n\n// custom extensions\n#define SYS_host_error \\\n\t1  // indicate an error, i.e. this instruction should never be reached so something went wrong during exec.\n#define SYS_host_test_pass 2  // RISC-V test execution successfully completed\n#define SYS_host_test_fail 3  // RISC-V test execution failed\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n\n#include \"iss.h\"\n#include \"syscall_if.h\"\n\nnamespace rv32 {\n\nstruct SyscallHandler : public sc_core::sc_module, syscall_emulator_if {\n\ttlm_utils::simple_target_socket<SyscallHandler> tsock;\n\tstd::unordered_map<uint64_t, iss_syscall_if *> cores;\n\n\tvoid register_core(ISS *core) {\n\t\tassert(cores.find(core->get_hart_id()) == cores.end());\n\t\tcores[core->get_hart_id()] = core;\n\t}\n\n\tSyscallHandler(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &SyscallHandler::transport);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\t(void)delay;\n\n\t\tauto addr = trans.get_address();\n\t\tassert(addr % 4 == 0);\n\t\tassert(trans.get_data_length() == 4);\n\t\tauto hart_id = *((uint32_t *)trans.get_data_ptr());\n\n\t\tassert((cores.find(hart_id) != cores.end()) && \"core not registered in syscall handler\");\n\n\t\texecute_syscall(cores[hart_id]);\n\t}\n\n\tvirtual void execute_syscall(iss_syscall_if *core) override {\n\t\tauto syscall = core->read_register(core->get_syscall_register_index());\n\t\tauto a3 = core->read_register(RegFile::a3);\n\t\tauto a2 = core->read_register(RegFile::a2);\n\t\tauto a1 = core->read_register(RegFile::a1);\n\t\tauto a0 = core->read_register(RegFile::a0);\n\n\t\t// printf(\"a7=%u, a0=%u, a1=%u, a2=%u, a3=%u\\n\", a7, a0, a1, a2, a3);\n\n\t\tauto ans = execute_syscall(syscall, a0, a1, a2, a3);\n\n\t\tcore->write_register(RegFile::a0, boost::lexical_cast<int32_t>(ans));\n\n\t\tif (shall_exit)\n\t\t\tcore->sys_exit();\n\t}\n\n\tuint8_t *mem = 0;     // direct pointer to start of guest memory in host memory\n\tuint64_t mem_offset;  // start address of the memory as mapped into the\n\t                      // address space\n\tuint64_t hp = 0;      // heap pointer\n\tbool shall_exit = false;\n\tbool shall_break = false;\n\n\t// only for memory consumption evaluation\n\tuint64_t start_heap = 0;\n\tuint64_t max_heap = 0;\n\n\tuint64_t get_max_heap_memory_consumption() {\n\t\treturn max_heap - start_heap;\n\t}\n\n\tvoid init(uint8_t *host_memory_pointer, uint64_t mem_start_address, uint64_t heap_pointer_address) {\n\t\tmem = host_memory_pointer;\n\t\tmem_offset = mem_start_address;\n\t\thp = heap_pointer_address;\n\n\t\tstart_heap = hp;\n\t\tmax_heap = hp;\n\t}\n\n\tuint8_t *guest_address_to_host_pointer(uintptr_t addr) {\n\t\tassert(mem != nullptr);\n\n\t\treturn mem + (addr - mem_offset);\n\t}\n\n\tuint8_t *guest_to_host_pointer(void *p) {\n\t\treturn guest_address_to_host_pointer((uintptr_t)p);\n\t}\n\n\t/*\n\t * Syscalls are implemented to work directly on guest memory (represented in\n\t * host as byte array). Note: the data structures on the host system might\n\t * not be binary compatible with those on the guest system.\n\t */\n\tint execute_syscall(uint64_t n, uint64_t _a0, uint64_t _a1, uint64_t _a2, uint64_t _a3);\n};\n\n}  // namespace rv32"
  },
  {
    "path": "vp/src/core/rv32/syscall_if.h",
    "content": "#pragma once\n\n#include <stdint.h>\n\nnamespace rv32 {\n\n/* The syscall handler is using this interface to access and control the ISS. */\nstruct iss_syscall_if {\n\tvirtual ~iss_syscall_if() {}\n\n\tvirtual void sys_exit() = 0;\n\t// virtual void sys_break() = 0;\n\n\tvirtual unsigned get_syscall_register_index() = 0;\n\n\tvirtual uint64_t read_register(unsigned idx) = 0;\n\tvirtual void write_register(unsigned idx, uint64_t value) = 0;\n\n\t// virtual uint32_t get_hart_id() = 0;\n};\n\n/* Using this interface, the ISS supports to intercept and delegate syscalls. */\nstruct syscall_emulator_if {\n\tvirtual ~syscall_emulator_if() {}\n\n\tvirtual void execute_syscall(iss_syscall_if *core) = 0;\n};\n\n}  // namespace rv32"
  },
  {
    "path": "vp/src/core/rv32/timing/timing_external.h",
    "content": "#pragma once\n\n#include \"../iss.h\"\n\n#include <dlfcn.h>\n#include <boost/io/ios_state.hpp>\n#include <iomanip>\n\nstd::string RISCV_TIMING_SIM_LIB = \"riscv-timing-sim.so\";\nstd::string RISCV_TIMING_DB = \"riscv-timing-db.xml\";\n\n// NOTE: the interface inside the library has to match this one exactly, don't\n// forget the *virtual* attribute\nstruct SimTimingInterface {\n\tvirtual uint64_t get_cycles_for_instruction(uint64_t pc);\n\n\t// only to detect errors in loading the shared library\n\tvirtual uint64_t get_magic_number();\n};\n\nstruct ExternalTimingDecorator : public timing_if {\n\tSimTimingInterface *timing_sim = 0;\n\tvoid *lib_handle = 0;\n\tSimTimingInterface *(*create)(const char *) = 0;\n\tvoid (*destroy)(SimTimingInterface *) = 0;\n\n\tvoid initialize() {\n\t\tlib_handle = dlopen(RISCV_TIMING_SIM_LIB.c_str(), RTLD_LAZY);\n\t\tif (!lib_handle)\n\t\t\tthrow std::runtime_error(\"unable to open shared library '\" + RISCV_TIMING_SIM_LIB + \"'\");\n\n\t\tcreate = (SimTimingInterface * (*)(const char *)) dlsym(lib_handle, \"create_riscv_vp_timing_interface\");\n\t\tif (!create)\n\t\t\tthrow std::runtime_error(\"unable to load 'create_riscv_vp_timing_interface' function\");\n\n\t\tdestroy = (void (*)(SimTimingInterface *))dlsym(lib_handle, \"destroy_riscv_vp_timing_interface\");\n\t\tif (!destroy)\n\t\t\tthrow std::runtime_error(\"unable to load 'destroy_riscv_vp_timing_interface' function\");\n\n\t\ttiming_sim = (SimTimingInterface *)create(RISCV_TIMING_DB.c_str());\n\t}\n\n\tExternalTimingDecorator() {\n\t\tinitialize();\n\t}\n\n\t~ExternalTimingDecorator() {\n\t\tassert(timing_sim != 0);\n\t\tdestroy(timing_sim);\n\t\tassert(lib_handle != 0);\n\t\tdlclose(lib_handle);\n\t}\n\n\tvoid on_begin_exec_step(Instruction instr, Opcode::mapping op, ISS &iss) override {\n\t\tuint64_t cycles = timing_sim->get_cycles_for_instruction(iss.last_pc);\n\n\t\tassert(timing_sim->get_magic_number() == 0x5E5E5E5E5E5E5E5E);\n\n\t\tsc_core::sc_time delay = iss.cycle_time * cycles;\n\n\t\tiss.quantum_keeper.inc(delay);\n\t}\n};\n"
  },
  {
    "path": "vp/src/core/rv32/timing/timing_simple.h",
    "content": "#pragma once\n\n#include \"../iss.h\"\n\nstruct SimpleTimingDecorator : public timing_if {\n\tstd::array<sc_core::sc_time, Opcode::NUMBER_OF_INSTRUCTIONS> instr_cycles;\n\tsc_core::sc_time cycle_time = sc_core::sc_time(10, sc_core::SC_NS);\n\n\tSimpleTimingDecorator() {\n\t\tfor (int i = 0; i < Opcode::NUMBER_OF_INSTRUCTIONS; ++i) instr_cycles[i] = cycle_time;\n\n\t\tconst sc_core::sc_time memory_access_cycles = 4 * cycle_time;\n\t\tconst sc_core::sc_time mul_div_cycles = 8 * cycle_time;\n\n\t\tinstr_cycles[Opcode::LB] = memory_access_cycles;\n\t\tinstr_cycles[Opcode::LBU] = memory_access_cycles;\n\t\tinstr_cycles[Opcode::LH] = memory_access_cycles;\n\t\tinstr_cycles[Opcode::LHU] = memory_access_cycles;\n\t\tinstr_cycles[Opcode::LW] = memory_access_cycles;\n\t\tinstr_cycles[Opcode::SB] = memory_access_cycles;\n\t\tinstr_cycles[Opcode::SH] = memory_access_cycles;\n\t\tinstr_cycles[Opcode::SW] = memory_access_cycles;\n\t\tinstr_cycles[Opcode::MUL] = mul_div_cycles;\n\t\tinstr_cycles[Opcode::MULH] = mul_div_cycles;\n\t\tinstr_cycles[Opcode::MULHU] = mul_div_cycles;\n\t\tinstr_cycles[Opcode::MULHSU] = mul_div_cycles;\n\t\tinstr_cycles[Opcode::DIV] = mul_div_cycles;\n\t\tinstr_cycles[Opcode::DIVU] = mul_div_cycles;\n\t\tinstr_cycles[Opcode::REM] = mul_div_cycles;\n\t\tinstr_cycles[Opcode::REMU] = mul_div_cycles;\n\t}\n\n\tvoid on_begin_exec_step(Instruction instr, Opcode::mapping op, ISS &iss) override {\n\t\tauto new_cycles = instr_cycles[op];\n\n\t\tiss.quantum_keeper.inc(new_cycles);\n\t}\n};\n"
  },
  {
    "path": "vp/src/core/rv64/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_library(rv64\n\t\tiss.cpp\n\t\tsyscall.cpp\n        ${HEADERS})\n\ntarget_link_libraries(rv64 systemc core-common softfloat)\n\n\nif(COLOR_THEME STREQUAL \"LIGHT\")\n\tmessage(\"> using color theme LIGHT\")\n\ttarget_compile_definitions(rv64 PRIVATE COLOR_THEME_LIGHT)\nelseif(COLOR_THEME STREQUAL \"DARK\")\n\tmessage(\"> using color theme DARK\")\n\ttarget_compile_definitions(rv64 PRIVATE COLOR_THEME_DARK)\nendif()\n\n\ntarget_include_directories(rv64 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\n"
  },
  {
    "path": "vp/src/core/rv64/csr.h",
    "content": "#pragma once\n\n#include <assert.h>\n#include <stdint.h>\n\n#include <stdexcept>\n#include <unordered_map>\n\n#include \"core/common/trap.h\"\n#include \"util/common.h\"\n\nnamespace rv64 {\n\nconstexpr unsigned FS_OFF = 0b00;\nconstexpr unsigned FS_INITIAL = 0b01;\nconstexpr unsigned FS_CLEAN = 0b10;\nconstexpr unsigned FS_DIRTY = 0b11;\n\ninline bool is_valid_privilege_level(PrivilegeLevel mode) {\n\treturn mode == MachineMode || mode == SupervisorMode || mode == UserMode;\n}\n\nstruct csr_64 {\n\tuint64_t reg = 0;\n};\n\nstruct csr_misa {\n\tcsr_misa() {\n\t\tinit();\n\t}\n\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned extensions : 26;\n\t\t\tunsigned long wiri : 36;\n\t\t\tunsigned mxl : 2;\n\t\t} fields;\n\t};\n\n\tbool has_C_extension() {\n\t\treturn fields.extensions & C;\n\t}\n\n\tbool has_user_mode_extension() {\n\t\treturn fields.extensions & U;\n\t}\n\n\tbool has_supervisor_mode_extension() {\n\t\treturn fields.extensions & S;\n\t}\n\n\tenum {\n\t\tA = 1,\n\t\tC = 1 << 2,\n\t\tD = 1 << 3,\n\t\tE = 1 << 4,\n\t\tF = 1 << 5,\n\t\tI = 1 << 8,\n\t\tM = 1 << 12,\n\t\tN = 1 << 13,\n\t\tS = 1 << 18,\n\t\tU = 1 << 20,\n\t};\n\n\tvoid init() {\n\t\tfields.extensions = I | M | A | F | D | C | N | U | S;  // IMACFD + NUS\n\t\tfields.mxl = 2;                                         // RV64\n\t}\n};\n\nstruct csr_mvendorid {\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned offset : 7;\n\t\t\tunsigned bank : 25;\n\t\t\tunsigned _unused : 32;\n\t\t} fields;\n\t};\n};\n\nstruct csr_mstatus {\n\tcsr_mstatus() {\n\t\t// hardwire to 64 bit mode for now\n\t\tfields.sxl = 2;\n\t\tfields.uxl = 2;\n\t}\n\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned uie : 1;\n\t\t\tunsigned sie : 1;\n\t\t\tunsigned wpri1 : 1;\n\t\t\tunsigned mie : 1;\n\t\t\tunsigned upie : 1;\n\t\t\tunsigned spie : 1;\n\t\t\tunsigned wpri2 : 1;\n\t\t\tunsigned mpie : 1;\n\t\t\tunsigned spp : 1;\n\t\t\tunsigned wpri3 : 2;\n\t\t\tunsigned mpp : 2;\n\t\t\tunsigned fs : 2;\n\t\t\tunsigned xs : 2;\n\t\t\tunsigned mprv : 1;\n\t\t\tunsigned sum : 1;\n\t\t\tunsigned mxr : 1;\n\t\t\tunsigned tvm : 1;\n\t\t\tunsigned tw : 1;\n\t\t\tunsigned tsr : 1;\n\t\t\tunsigned wpri4 : 9;\n\t\t\tunsigned uxl : 2;\n\t\t\tunsigned sxl : 2;\n\t\t\tunsigned wpri5 : 27;\n\t\t\tunsigned sd : 1;\n\t\t} fields;\n\t};\n};\n\nstruct csr_mtvec {\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned mode : 2;        // WARL\n\t\t\tunsigned long base : 62;  // WARL\n\t\t} fields;\n\t};\n\n\tuint64_t get_base_address() {\n\t\treturn fields.base << 2;\n\t}\n\n\tenum Mode { Direct = 0, Vectored = 1 };\n\n\tvoid checked_write(uint64_t val) {\n\t\treg = val;\n\t\tif (fields.mode >= 1)\n\t\t\tfields.mode = 0;\n\t}\n};\n\nstruct csr_mie {\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned usie : 1;\n\t\t\tunsigned ssie : 1;\n\t\t\tunsigned wpri1 : 1;\n\t\t\tunsigned msie : 1;\n\n\t\t\tunsigned utie : 1;\n\t\t\tunsigned stie : 1;\n\t\t\tunsigned wpri2 : 1;\n\t\t\tunsigned mtie : 1;\n\n\t\t\tunsigned ueie : 1;\n\t\t\tunsigned seie : 1;\n\t\t\tunsigned wpri3 : 1;\n\t\t\tunsigned meie : 1;\n\n\t\t\tunsigned long wpri4 : 52;\n\t\t} fields;\n\t};\n};\n\nstruct csr_mip {\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned usip : 1;\n\t\t\tunsigned ssip : 1;\n\t\t\tunsigned wiri1 : 1;\n\t\t\tunsigned msip : 1;\n\n\t\t\tunsigned utip : 1;\n\t\t\tunsigned stip : 1;\n\t\t\tunsigned wiri2 : 1;\n\t\t\tunsigned mtip : 1;\n\n\t\t\tunsigned ueip : 1;\n\t\t\tunsigned seip : 1;\n\t\t\tunsigned wiri3 : 1;\n\t\t\tunsigned meip : 1;\n\n\t\t\tunsigned long wiri4 : 52;\n\t\t} fields;\n\t};\n};\n\nstruct csr_mepc {\n\tunion {\n\t\tuint64_t reg = 0;\n\t};\n};\n\nstruct csr_mcause {\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned long exception_code : 63;  // WLRL\n\t\t\tunsigned interrupt : 1;\n\t\t} fields;\n\t};\n};\n\nstruct csr_mcounteren {\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned CY : 1;\n\t\t\tunsigned TM : 1;\n\t\t\tunsigned IR : 1;\n\t\t\tunsigned long reserved : 61;\n\t\t} fields;\n\t};\n};\n\nstruct csr_mcountinhibit {\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned CY : 1;\n\t\t\tunsigned zero : 1;\n\t\t\tunsigned IR : 1;\n\t\t\tunsigned long reserved : 61;\n\t\t} fields;\n\t};\n};\n\nstruct csr_pmpcfg {\n\tunion {\n\t\tuint64_t reg = 0;\n\t};\n};\n\nstruct csr_pmpaddr {\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned long address : 54;\n\t\t\tunsigned zero : 10;\n\t\t} fields;\n\t};\n\n\tunsigned get_address() {\n\t\treturn fields.address << 2;\n\t}\n};\n\nstruct csr_satp {\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned long ppn : 44;  // WARL\n\t\t\tunsigned asid : 16;      // WARL\n\t\t\tunsigned mode : 4;       // WARL\n\t\t} fields;\n\t};\n};\n\n/* Actually 32 bit large, but use 64 value for consistency and simply set the read/write mask accordingly. */\nstruct csr_fcsr {\n\tunion {\n\t\tuint64_t reg = 0;\n\t\tstruct {\n\t\t\tunsigned fflags : 5;\n\t\t\tunsigned frm : 3;\n\t\t\tunsigned reserved : 24;\n\t\t\tunsigned _ : 32;\n\t\t} fields;\n\t\tstruct {\n\t\t\tunsigned NX : 1;  // invalid operation\n\t\t\tunsigned UF : 1;  // divide by zero\n\t\t\tunsigned OF : 1;  // overflow\n\t\t\tunsigned DZ : 1;  // underflow\n\t\t\tunsigned NV : 1;  // inexact\n\t\t} fflags;\n\t};\n};\n\nnamespace csr {\ntemplate <typename T>\ninline bool is_bitset(T &csr, unsigned bitpos) {\n\treturn csr.reg & (1 << bitpos);\n}\n\nconstexpr uint64_t MIE_MASK = 0b101110111011;\nconstexpr uint64_t SIE_MASK = 0b001100110011;\nconstexpr uint64_t UIE_MASK = 0b000100010001;\n\nconstexpr uint64_t MIP_WRITE_MASK = 0b001100110011;\nconstexpr uint64_t MIP_READ_MASK = MIE_MASK;\nconstexpr uint64_t SIP_MASK = 0b11;\nconstexpr uint64_t UIP_MASK = 0b1;\n\nconstexpr uint64_t MEDELEG_MASK = 0b1011101111111111;\nconstexpr uint64_t MIDELEG_MASK = MIE_MASK;\n\nconstexpr uint64_t MTVEC_MASK = ~2;\n\nconstexpr uint64_t MCOUNTEREN_MASK = 0b111;\nconstexpr uint64_t MCOUNTINHIBIT_MASK = 0b101;\n\nconstexpr uint64_t SEDELEG_MASK = 0b1011000111111111;\nconstexpr uint64_t SIDELEG_MASK = MIDELEG_MASK;\n\nconstexpr uint64_t MSTATUS_WRITE_MASK = 0b1000000000000000000000000000000000000000011111111111100110111011;\nconstexpr uint64_t MSTATUS_READ_MASK = 0b1000000000000000000000000000111100000000011111111111100110111011;\nconstexpr uint64_t SSTATUS_WRITE_MASK = 0b1000000000000000000000000000000000000000000011011110000100110011;\nconstexpr uint64_t SSTATUS_READ_MASK = 0b1000000000000000000000000000001100000000000011011110000100110011;\nconstexpr uint64_t USTATUS_MASK = 0b0000000000000000000000000000000000000000000000000000000000010001;\n\nconstexpr uint64_t PMPADDR_MASK = 0b0000000000111111111111111111111111111111111111111111111111111111;\n\nconstexpr uint64_t SATP_MASK = 0b1111000000000000000011111111111111111111111111111111111111111111;\nconstexpr uint64_t SATP_MODE = 0b1111000000000000000000000000000000000000000000000000000000000000;\n\nconstexpr uint64_t FCSR_MASK = 0b11111111;\n\n// 64 bit timer csrs\nconstexpr unsigned CYCLE_ADDR = 0xC00;\nconstexpr unsigned TIME_ADDR = 0xC01;\nconstexpr unsigned INSTRET_ADDR = 0xC02;\n\n// shadows for the above CSRs\nconstexpr unsigned MCYCLE_ADDR = 0xB00;\nconstexpr unsigned MTIME_ADDR = 0xB01;\nconstexpr unsigned MINSTRET_ADDR = 0xB02;\n\n// 32 bit machine CSRs\nconstexpr unsigned MVENDORID_ADDR = 0xF11;\nconstexpr unsigned MARCHID_ADDR = 0xF12;\nconstexpr unsigned MIMPID_ADDR = 0xF13;\nconstexpr unsigned MHARTID_ADDR = 0xF14;\n\nconstexpr unsigned MSTATUS_ADDR = 0x300;\nconstexpr unsigned MISA_ADDR = 0x301;\nconstexpr unsigned MEDELEG_ADDR = 0x302;\nconstexpr unsigned MIDELEG_ADDR = 0x303;\nconstexpr unsigned MIE_ADDR = 0x304;\nconstexpr unsigned MTVEC_ADDR = 0x305;\nconstexpr unsigned MCOUNTEREN_ADDR = 0x306;\nconstexpr unsigned MCOUNTINHIBIT_ADDR = 0x320;\n\nconstexpr unsigned MSCRATCH_ADDR = 0x340;\nconstexpr unsigned MEPC_ADDR = 0x341;\nconstexpr unsigned MCAUSE_ADDR = 0x342;\nconstexpr unsigned MTVAL_ADDR = 0x343;\nconstexpr unsigned MIP_ADDR = 0x344;\n\nconstexpr unsigned PMPCFG0_ADDR = 0x3A0;\nconstexpr unsigned PMPCFG1_ADDR = 0x3A1;\nconstexpr unsigned PMPCFG2_ADDR = 0x3A2;\nconstexpr unsigned PMPCFG3_ADDR = 0x3A3;\n\nconstexpr unsigned PMPADDR0_ADDR = 0x3B0;\nconstexpr unsigned PMPADDR1_ADDR = 0x3B1;\nconstexpr unsigned PMPADDR2_ADDR = 0x3B2;\nconstexpr unsigned PMPADDR3_ADDR = 0x3B3;\nconstexpr unsigned PMPADDR4_ADDR = 0x3B4;\nconstexpr unsigned PMPADDR5_ADDR = 0x3B5;\nconstexpr unsigned PMPADDR6_ADDR = 0x3B6;\nconstexpr unsigned PMPADDR7_ADDR = 0x3B7;\nconstexpr unsigned PMPADDR8_ADDR = 0x3B8;\nconstexpr unsigned PMPADDR9_ADDR = 0x3B9;\nconstexpr unsigned PMPADDR10_ADDR = 0x3BA;\nconstexpr unsigned PMPADDR11_ADDR = 0x3BB;\nconstexpr unsigned PMPADDR12_ADDR = 0x3BC;\nconstexpr unsigned PMPADDR13_ADDR = 0x3BD;\nconstexpr unsigned PMPADDR14_ADDR = 0x3BE;\nconstexpr unsigned PMPADDR15_ADDR = 0x3BF;\n\n// 32 bit supervisor CSRs\nconstexpr unsigned SSTATUS_ADDR = 0x100;\nconstexpr unsigned SEDELEG_ADDR = 0x102;\nconstexpr unsigned SIDELEG_ADDR = 0x103;\nconstexpr unsigned SIE_ADDR = 0x104;\nconstexpr unsigned STVEC_ADDR = 0x105;\nconstexpr unsigned SCOUNTEREN_ADDR = 0x106;\nconstexpr unsigned SSCRATCH_ADDR = 0x140;\nconstexpr unsigned SEPC_ADDR = 0x141;\nconstexpr unsigned SCAUSE_ADDR = 0x142;\nconstexpr unsigned STVAL_ADDR = 0x143;\nconstexpr unsigned SIP_ADDR = 0x144;\nconstexpr unsigned SATP_ADDR = 0x180;\n\n// 32 bit user CSRs\nconstexpr unsigned USTATUS_ADDR = 0x000;\nconstexpr unsigned UIE_ADDR = 0x004;\nconstexpr unsigned UTVEC_ADDR = 0x005;\nconstexpr unsigned USCRATCH_ADDR = 0x040;\nconstexpr unsigned UEPC_ADDR = 0x041;\nconstexpr unsigned UCAUSE_ADDR = 0x042;\nconstexpr unsigned UTVAL_ADDR = 0x043;\nconstexpr unsigned UIP_ADDR = 0x044;\n\n// floating point CSRs\nconstexpr unsigned FFLAGS_ADDR = 0x001;\nconstexpr unsigned FRM_ADDR = 0x002;\nconstexpr unsigned FCSR_ADDR = 0x003;\n\n// performance counters\nconstexpr unsigned HPMCOUNTER3_ADDR = 0xC03;\nconstexpr unsigned HPMCOUNTER4_ADDR = 0xC04;\nconstexpr unsigned HPMCOUNTER5_ADDR = 0xC05;\nconstexpr unsigned HPMCOUNTER6_ADDR = 0xC06;\nconstexpr unsigned HPMCOUNTER7_ADDR = 0xC07;\nconstexpr unsigned HPMCOUNTER8_ADDR = 0xC08;\nconstexpr unsigned HPMCOUNTER9_ADDR = 0xC09;\nconstexpr unsigned HPMCOUNTER10_ADDR = 0xC0A;\nconstexpr unsigned HPMCOUNTER11_ADDR = 0xC0B;\nconstexpr unsigned HPMCOUNTER12_ADDR = 0xC0C;\nconstexpr unsigned HPMCOUNTER13_ADDR = 0xC0D;\nconstexpr unsigned HPMCOUNTER14_ADDR = 0xC0E;\nconstexpr unsigned HPMCOUNTER15_ADDR = 0xC0F;\nconstexpr unsigned HPMCOUNTER16_ADDR = 0xC10;\nconstexpr unsigned HPMCOUNTER17_ADDR = 0xC11;\nconstexpr unsigned HPMCOUNTER18_ADDR = 0xC12;\nconstexpr unsigned HPMCOUNTER19_ADDR = 0xC13;\nconstexpr unsigned HPMCOUNTER20_ADDR = 0xC14;\nconstexpr unsigned HPMCOUNTER21_ADDR = 0xC15;\nconstexpr unsigned HPMCOUNTER22_ADDR = 0xC16;\nconstexpr unsigned HPMCOUNTER23_ADDR = 0xC17;\nconstexpr unsigned HPMCOUNTER24_ADDR = 0xC18;\nconstexpr unsigned HPMCOUNTER25_ADDR = 0xC19;\nconstexpr unsigned HPMCOUNTER26_ADDR = 0xC1A;\nconstexpr unsigned HPMCOUNTER27_ADDR = 0xC1B;\nconstexpr unsigned HPMCOUNTER28_ADDR = 0xC1C;\nconstexpr unsigned HPMCOUNTER29_ADDR = 0xC1D;\nconstexpr unsigned HPMCOUNTER30_ADDR = 0xC1E;\nconstexpr unsigned HPMCOUNTER31_ADDR = 0xC1F;\n\nconstexpr unsigned HPMCOUNTER3H_ADDR = 0xC83;\nconstexpr unsigned HPMCOUNTER4H_ADDR = 0xC84;\nconstexpr unsigned HPMCOUNTER5H_ADDR = 0xC85;\nconstexpr unsigned HPMCOUNTER6H_ADDR = 0xC86;\nconstexpr unsigned HPMCOUNTER7H_ADDR = 0xC87;\nconstexpr unsigned HPMCOUNTER8H_ADDR = 0xC88;\nconstexpr unsigned HPMCOUNTER9H_ADDR = 0xC89;\nconstexpr unsigned HPMCOUNTER10H_ADDR = 0xC8A;\nconstexpr unsigned HPMCOUNTER11H_ADDR = 0xC8B;\nconstexpr unsigned HPMCOUNTER12H_ADDR = 0xC8C;\nconstexpr unsigned HPMCOUNTER13H_ADDR = 0xC8D;\nconstexpr unsigned HPMCOUNTER14H_ADDR = 0xC8E;\nconstexpr unsigned HPMCOUNTER15H_ADDR = 0xC8F;\nconstexpr unsigned HPMCOUNTER16H_ADDR = 0xC90;\nconstexpr unsigned HPMCOUNTER17H_ADDR = 0xC91;\nconstexpr unsigned HPMCOUNTER18H_ADDR = 0xC92;\nconstexpr unsigned HPMCOUNTER19H_ADDR = 0xC93;\nconstexpr unsigned HPMCOUNTER20H_ADDR = 0xC94;\nconstexpr unsigned HPMCOUNTER21H_ADDR = 0xC95;\nconstexpr unsigned HPMCOUNTER22H_ADDR = 0xC96;\nconstexpr unsigned HPMCOUNTER23H_ADDR = 0xC97;\nconstexpr unsigned HPMCOUNTER24H_ADDR = 0xC98;\nconstexpr unsigned HPMCOUNTER25H_ADDR = 0xC99;\nconstexpr unsigned HPMCOUNTER26H_ADDR = 0xC9A;\nconstexpr unsigned HPMCOUNTER27H_ADDR = 0xC9B;\nconstexpr unsigned HPMCOUNTER28H_ADDR = 0xC9C;\nconstexpr unsigned HPMCOUNTER29H_ADDR = 0xC9D;\nconstexpr unsigned HPMCOUNTER30H_ADDR = 0xC9E;\nconstexpr unsigned HPMCOUNTER31H_ADDR = 0xC9F;\n\nconstexpr unsigned MHPMCOUNTER3_ADDR = 0xB03;\nconstexpr unsigned MHPMCOUNTER4_ADDR = 0xB04;\nconstexpr unsigned MHPMCOUNTER5_ADDR = 0xB05;\nconstexpr unsigned MHPMCOUNTER6_ADDR = 0xB06;\nconstexpr unsigned MHPMCOUNTER7_ADDR = 0xB07;\nconstexpr unsigned MHPMCOUNTER8_ADDR = 0xB08;\nconstexpr unsigned MHPMCOUNTER9_ADDR = 0xB09;\nconstexpr unsigned MHPMCOUNTER10_ADDR = 0xB0A;\nconstexpr unsigned MHPMCOUNTER11_ADDR = 0xB0B;\nconstexpr unsigned MHPMCOUNTER12_ADDR = 0xB0C;\nconstexpr unsigned MHPMCOUNTER13_ADDR = 0xB0D;\nconstexpr unsigned MHPMCOUNTER14_ADDR = 0xB0E;\nconstexpr unsigned MHPMCOUNTER15_ADDR = 0xB0F;\nconstexpr unsigned MHPMCOUNTER16_ADDR = 0xB10;\nconstexpr unsigned MHPMCOUNTER17_ADDR = 0xB11;\nconstexpr unsigned MHPMCOUNTER18_ADDR = 0xB12;\nconstexpr unsigned MHPMCOUNTER19_ADDR = 0xB13;\nconstexpr unsigned MHPMCOUNTER20_ADDR = 0xB14;\nconstexpr unsigned MHPMCOUNTER21_ADDR = 0xB15;\nconstexpr unsigned MHPMCOUNTER22_ADDR = 0xB16;\nconstexpr unsigned MHPMCOUNTER23_ADDR = 0xB17;\nconstexpr unsigned MHPMCOUNTER24_ADDR = 0xB18;\nconstexpr unsigned MHPMCOUNTER25_ADDR = 0xB19;\nconstexpr unsigned MHPMCOUNTER26_ADDR = 0xB1A;\nconstexpr unsigned MHPMCOUNTER27_ADDR = 0xB1B;\nconstexpr unsigned MHPMCOUNTER28_ADDR = 0xB1C;\nconstexpr unsigned MHPMCOUNTER29_ADDR = 0xB1D;\nconstexpr unsigned MHPMCOUNTER30_ADDR = 0xB1E;\nconstexpr unsigned MHPMCOUNTER31_ADDR = 0xB1F;\n\nconstexpr unsigned MHPMCOUNTER3H_ADDR = 0xB83;\nconstexpr unsigned MHPMCOUNTER4H_ADDR = 0xB84;\nconstexpr unsigned MHPMCOUNTER5H_ADDR = 0xB85;\nconstexpr unsigned MHPMCOUNTER6H_ADDR = 0xB86;\nconstexpr unsigned MHPMCOUNTER7H_ADDR = 0xB87;\nconstexpr unsigned MHPMCOUNTER8H_ADDR = 0xB88;\nconstexpr unsigned MHPMCOUNTER9H_ADDR = 0xB89;\nconstexpr unsigned MHPMCOUNTER10H_ADDR = 0xB8A;\nconstexpr unsigned MHPMCOUNTER11H_ADDR = 0xB8B;\nconstexpr unsigned MHPMCOUNTER12H_ADDR = 0xB8C;\nconstexpr unsigned MHPMCOUNTER13H_ADDR = 0xB8D;\nconstexpr unsigned MHPMCOUNTER14H_ADDR = 0xB8E;\nconstexpr unsigned MHPMCOUNTER15H_ADDR = 0xB8F;\nconstexpr unsigned MHPMCOUNTER16H_ADDR = 0xB90;\nconstexpr unsigned MHPMCOUNTER17H_ADDR = 0xB91;\nconstexpr unsigned MHPMCOUNTER18H_ADDR = 0xB92;\nconstexpr unsigned MHPMCOUNTER19H_ADDR = 0xB93;\nconstexpr unsigned MHPMCOUNTER20H_ADDR = 0xB94;\nconstexpr unsigned MHPMCOUNTER21H_ADDR = 0xB95;\nconstexpr unsigned MHPMCOUNTER22H_ADDR = 0xB96;\nconstexpr unsigned MHPMCOUNTER23H_ADDR = 0xB97;\nconstexpr unsigned MHPMCOUNTER24H_ADDR = 0xB98;\nconstexpr unsigned MHPMCOUNTER25H_ADDR = 0xB99;\nconstexpr unsigned MHPMCOUNTER26H_ADDR = 0xB9A;\nconstexpr unsigned MHPMCOUNTER27H_ADDR = 0xB9B;\nconstexpr unsigned MHPMCOUNTER28H_ADDR = 0xB9C;\nconstexpr unsigned MHPMCOUNTER29H_ADDR = 0xB9D;\nconstexpr unsigned MHPMCOUNTER30H_ADDR = 0xB9E;\nconstexpr unsigned MHPMCOUNTER31H_ADDR = 0xB9F;\n\nconstexpr unsigned MHPMEVENT3_ADDR = 0x323;\nconstexpr unsigned MHPMEVENT4_ADDR = 0x324;\nconstexpr unsigned MHPMEVENT5_ADDR = 0x325;\nconstexpr unsigned MHPMEVENT6_ADDR = 0x326;\nconstexpr unsigned MHPMEVENT7_ADDR = 0x327;\nconstexpr unsigned MHPMEVENT8_ADDR = 0x328;\nconstexpr unsigned MHPMEVENT9_ADDR = 0x329;\nconstexpr unsigned MHPMEVENT10_ADDR = 0x32A;\nconstexpr unsigned MHPMEVENT11_ADDR = 0x32B;\nconstexpr unsigned MHPMEVENT12_ADDR = 0x32C;\nconstexpr unsigned MHPMEVENT13_ADDR = 0x32D;\nconstexpr unsigned MHPMEVENT14_ADDR = 0x32E;\nconstexpr unsigned MHPMEVENT15_ADDR = 0x32F;\nconstexpr unsigned MHPMEVENT16_ADDR = 0x330;\nconstexpr unsigned MHPMEVENT17_ADDR = 0x331;\nconstexpr unsigned MHPMEVENT18_ADDR = 0x332;\nconstexpr unsigned MHPMEVENT19_ADDR = 0x333;\nconstexpr unsigned MHPMEVENT20_ADDR = 0x334;\nconstexpr unsigned MHPMEVENT21_ADDR = 0x335;\nconstexpr unsigned MHPMEVENT22_ADDR = 0x336;\nconstexpr unsigned MHPMEVENT23_ADDR = 0x337;\nconstexpr unsigned MHPMEVENT24_ADDR = 0x338;\nconstexpr unsigned MHPMEVENT25_ADDR = 0x339;\nconstexpr unsigned MHPMEVENT26_ADDR = 0x33A;\nconstexpr unsigned MHPMEVENT27_ADDR = 0x33B;\nconstexpr unsigned MHPMEVENT28_ADDR = 0x33C;\nconstexpr unsigned MHPMEVENT29_ADDR = 0x33D;\nconstexpr unsigned MHPMEVENT30_ADDR = 0x33E;\nconstexpr unsigned MHPMEVENT31_ADDR = 0x33F;\n};  // namespace csr\n\nstruct csr_table {\n\tcsr_64 cycle;\n\tcsr_64 time;\n\tcsr_64 instret;\n\n\tcsr_mvendorid mvendorid;\n\tcsr_64 marchid;\n\tcsr_64 mimpid;\n\tcsr_64 mhartid;\n\n\tcsr_mstatus mstatus;\n\tcsr_misa misa;\n\tcsr_64 medeleg;\n\tcsr_64 mideleg;\n\tcsr_mie mie;\n\tcsr_mtvec mtvec;\n\tcsr_mcounteren mcounteren;\n\tcsr_mcountinhibit mcountinhibit;\n\n\tcsr_64 mscratch;\n\tcsr_mepc mepc;\n\tcsr_mcause mcause;\n\tcsr_64 mtval;\n\tcsr_mip mip;\n\n\t// pmp configuration\n\tstd::array<csr_pmpaddr, 16> pmpaddr;\n\tstd::array<csr_pmpcfg, 2> pmpcfg;\n\n\t// supervisor csrs (please note: some are already covered by the machine mode csrs, i.e. sstatus, sie and sip, and\n\t// some are required but have the same fields, hence the machine mode classes are used)\n\tcsr_64 sedeleg;\n\tcsr_64 sideleg;\n\tcsr_mtvec stvec;\n\tcsr_mcounteren scounteren;\n\tcsr_64 sscratch;\n\tcsr_mepc sepc;\n\tcsr_mcause scause;\n\tcsr_64 stval;\n\tcsr_satp satp;\n\n\t// user csrs (see above comment)\n\tcsr_mtvec utvec;\n\tcsr_64 uscratch;\n\tcsr_mepc uepc;\n\tcsr_mcause ucause;\n\tcsr_64 utval;\n\n\tcsr_fcsr fcsr;\n\n\tstd::unordered_map<unsigned, uint64_t *> register_mapping;\n\n\tcsr_table() {\n\t\tusing namespace csr;\n\n\t\tregister_mapping[CYCLE_ADDR] = &cycle.reg;\n\t\tregister_mapping[TIME_ADDR] = &time.reg;\n\t\tregister_mapping[INSTRET_ADDR] = &instret.reg;\n\t\tregister_mapping[MCYCLE_ADDR] = &cycle.reg;\n\t\tregister_mapping[MTIME_ADDR] = &time.reg;\n\t\tregister_mapping[MINSTRET_ADDR] = &instret.reg;\n\n\t\tregister_mapping[MVENDORID_ADDR] = &mvendorid.reg;\n\t\tregister_mapping[MARCHID_ADDR] = &marchid.reg;\n\t\tregister_mapping[MIMPID_ADDR] = &mimpid.reg;\n\t\tregister_mapping[MHARTID_ADDR] = &mhartid.reg;\n\n\t\tregister_mapping[MSTATUS_ADDR] = &mstatus.reg;\n\t\tregister_mapping[MISA_ADDR] = &misa.reg;\n\t\tregister_mapping[MEDELEG_ADDR] = &medeleg.reg;\n\t\tregister_mapping[MIDELEG_ADDR] = &mideleg.reg;\n\t\tregister_mapping[MIE_ADDR] = &mie.reg;\n\t\tregister_mapping[MTVEC_ADDR] = &mtvec.reg;\n\t\tregister_mapping[MCOUNTEREN_ADDR] = &mcounteren.reg;\n\t\tregister_mapping[MCOUNTINHIBIT_ADDR] = &mcountinhibit.reg;\n\n\t\tregister_mapping[MSCRATCH_ADDR] = &mscratch.reg;\n\t\tregister_mapping[MEPC_ADDR] = &mepc.reg;\n\t\tregister_mapping[MCAUSE_ADDR] = &mcause.reg;\n\t\tregister_mapping[MTVAL_ADDR] = &mtval.reg;\n\t\tregister_mapping[MIP_ADDR] = &mip.reg;\n\n\t\tfor (unsigned i = 0; i < 16; ++i) register_mapping[PMPADDR0_ADDR + i] = &pmpaddr[i].reg;\n\n\t\tfor (unsigned i = 0; i < 4; ++i) register_mapping[PMPCFG0_ADDR + i] = &pmpcfg[i].reg;\n\n\t\tregister_mapping[SEDELEG_ADDR] = &sedeleg.reg;\n\t\tregister_mapping[SIDELEG_ADDR] = &sideleg.reg;\n\t\tregister_mapping[STVEC_ADDR] = &stvec.reg;\n\t\tregister_mapping[SCOUNTEREN_ADDR] = &scounteren.reg;\n\t\tregister_mapping[SSCRATCH_ADDR] = &sscratch.reg;\n\t\tregister_mapping[SEPC_ADDR] = &sepc.reg;\n\t\tregister_mapping[SCAUSE_ADDR] = &scause.reg;\n\t\tregister_mapping[STVAL_ADDR] = &stval.reg;\n\t\tregister_mapping[SATP_ADDR] = &satp.reg;\n\n\t\tregister_mapping[UTVEC_ADDR] = &utvec.reg;\n\t\tregister_mapping[USCRATCH_ADDR] = &uscratch.reg;\n\t\tregister_mapping[UEPC_ADDR] = &uepc.reg;\n\t\tregister_mapping[UCAUSE_ADDR] = &ucause.reg;\n\t\tregister_mapping[UTVAL_ADDR] = &utval.reg;\n\n\t\tregister_mapping[FCSR_ADDR] = &fcsr.reg;\n\t}\n\n\tbool is_valid_csr64_addr(unsigned addr) {\n\t\treturn register_mapping.find(addr) != register_mapping.end();\n\t}\n\n\tvoid default_write64(unsigned addr, uint64_t value) {\n\t\tauto it = register_mapping.find(addr);\n\t\tensure((it != register_mapping.end()) && \"validate address before calling this function\");\n\t\t*it->second = value;\n\t}\n\n\tuint64_t default_read64(unsigned addr) {\n\t\tauto it = register_mapping.find(addr);\n\t\tensure((it != register_mapping.end()) && \"validate address before calling this function\");\n\t\treturn *it->second;\n\t}\n};\n\n#define SWITCH_CASE_MATCH_ANY_HPMCOUNTER_RV64 \\\n\tcase HPMCOUNTER3_ADDR:                    \\\n\tcase HPMCOUNTER4_ADDR:                    \\\n\tcase HPMCOUNTER5_ADDR:                    \\\n\tcase HPMCOUNTER6_ADDR:                    \\\n\tcase HPMCOUNTER7_ADDR:                    \\\n\tcase HPMCOUNTER8_ADDR:                    \\\n\tcase HPMCOUNTER9_ADDR:                    \\\n\tcase HPMCOUNTER10_ADDR:                   \\\n\tcase HPMCOUNTER11_ADDR:                   \\\n\tcase HPMCOUNTER12_ADDR:                   \\\n\tcase HPMCOUNTER13_ADDR:                   \\\n\tcase HPMCOUNTER14_ADDR:                   \\\n\tcase HPMCOUNTER15_ADDR:                   \\\n\tcase HPMCOUNTER16_ADDR:                   \\\n\tcase HPMCOUNTER17_ADDR:                   \\\n\tcase HPMCOUNTER18_ADDR:                   \\\n\tcase HPMCOUNTER19_ADDR:                   \\\n\tcase HPMCOUNTER20_ADDR:                   \\\n\tcase HPMCOUNTER21_ADDR:                   \\\n\tcase HPMCOUNTER22_ADDR:                   \\\n\tcase HPMCOUNTER23_ADDR:                   \\\n\tcase HPMCOUNTER24_ADDR:                   \\\n\tcase HPMCOUNTER25_ADDR:                   \\\n\tcase HPMCOUNTER26_ADDR:                   \\\n\tcase HPMCOUNTER27_ADDR:                   \\\n\tcase HPMCOUNTER28_ADDR:                   \\\n\tcase HPMCOUNTER29_ADDR:                   \\\n\tcase HPMCOUNTER30_ADDR:                   \\\n\tcase HPMCOUNTER31_ADDR:                   \\\n\tcase MHPMCOUNTER3_ADDR:                   \\\n\tcase MHPMCOUNTER4_ADDR:                   \\\n\tcase MHPMCOUNTER5_ADDR:                   \\\n\tcase MHPMCOUNTER6_ADDR:                   \\\n\tcase MHPMCOUNTER7_ADDR:                   \\\n\tcase MHPMCOUNTER8_ADDR:                   \\\n\tcase MHPMCOUNTER9_ADDR:                   \\\n\tcase MHPMCOUNTER10_ADDR:                  \\\n\tcase MHPMCOUNTER11_ADDR:                  \\\n\tcase MHPMCOUNTER12_ADDR:                  \\\n\tcase MHPMCOUNTER13_ADDR:                  \\\n\tcase MHPMCOUNTER14_ADDR:                  \\\n\tcase MHPMCOUNTER15_ADDR:                  \\\n\tcase MHPMCOUNTER16_ADDR:                  \\\n\tcase MHPMCOUNTER17_ADDR:                  \\\n\tcase MHPMCOUNTER18_ADDR:                  \\\n\tcase MHPMCOUNTER19_ADDR:                  \\\n\tcase MHPMCOUNTER20_ADDR:                  \\\n\tcase MHPMCOUNTER21_ADDR:                  \\\n\tcase MHPMCOUNTER22_ADDR:                  \\\n\tcase MHPMCOUNTER23_ADDR:                  \\\n\tcase MHPMCOUNTER24_ADDR:                  \\\n\tcase MHPMCOUNTER25_ADDR:                  \\\n\tcase MHPMCOUNTER26_ADDR:                  \\\n\tcase MHPMCOUNTER27_ADDR:                  \\\n\tcase MHPMCOUNTER28_ADDR:                  \\\n\tcase MHPMCOUNTER29_ADDR:                  \\\n\tcase MHPMCOUNTER30_ADDR:                  \\\n\tcase MHPMCOUNTER31_ADDR:                  \\\n\tcase MHPMEVENT3_ADDR:                     \\\n\tcase MHPMEVENT4_ADDR:                     \\\n\tcase MHPMEVENT5_ADDR:                     \\\n\tcase MHPMEVENT6_ADDR:                     \\\n\tcase MHPMEVENT7_ADDR:                     \\\n\tcase MHPMEVENT8_ADDR:                     \\\n\tcase MHPMEVENT9_ADDR:                     \\\n\tcase MHPMEVENT10_ADDR:                    \\\n\tcase MHPMEVENT11_ADDR:                    \\\n\tcase MHPMEVENT12_ADDR:                    \\\n\tcase MHPMEVENT13_ADDR:                    \\\n\tcase MHPMEVENT14_ADDR:                    \\\n\tcase MHPMEVENT15_ADDR:                    \\\n\tcase MHPMEVENT16_ADDR:                    \\\n\tcase MHPMEVENT17_ADDR:                    \\\n\tcase MHPMEVENT18_ADDR:                    \\\n\tcase MHPMEVENT19_ADDR:                    \\\n\tcase MHPMEVENT20_ADDR:                    \\\n\tcase MHPMEVENT21_ADDR:                    \\\n\tcase MHPMEVENT22_ADDR:                    \\\n\tcase MHPMEVENT23_ADDR:                    \\\n\tcase MHPMEVENT24_ADDR:                    \\\n\tcase MHPMEVENT25_ADDR:                    \\\n\tcase MHPMEVENT26_ADDR:                    \\\n\tcase MHPMEVENT27_ADDR:                    \\\n\tcase MHPMEVENT28_ADDR:                    \\\n\tcase MHPMEVENT29_ADDR:                    \\\n\tcase MHPMEVENT30_ADDR:                    \\\n\tcase MHPMEVENT31_ADDR\n\n}  // namespace rv64\n"
  },
  {
    "path": "vp/src/core/rv64/elf_loader.h",
    "content": "#pragma once\n\n#include \"core/common/elf_loader.h\"\n\nnamespace rv64 {\n\n// see: \"ELF-64 Object File Format\" document for ELF64 type definitions\n\ntypedef uint64_t Elf64_Addr;\ntypedef uint64_t Elf64_Off;\ntypedef uint16_t Elf64_Half;\ntypedef uint32_t Elf64_Word;\ntypedef int32_t Elf64_Sword;\ntypedef uint64_t Elf64_Xword;\ntypedef int64_t Elf64_Sxword;\n\nconstexpr unsigned ELF_NIDENT = 16;\n\ntypedef struct {\n\tunsigned char e_ident[ELF_NIDENT]; /* ELF identification */\n\tElf64_Half e_type;                 /* Object file type */\n\tElf64_Half e_machine;              /* Machine type */\n\tElf64_Word e_version;              /* Object file version */\n\tElf64_Addr e_entry;                /* Entry point address */\n\tElf64_Off e_phoff;                 /* Program header offset */\n\tElf64_Off e_shoff;                 /* Section header offset */\n\tElf64_Word e_flags;                /* Processor-specific flags */\n\tElf64_Half e_ehsize;               /* ELF header size */\n\tElf64_Half e_phentsize;            /* Size of program header entry */\n\tElf64_Half e_phnum;                /* Number of program header entries */\n\tElf64_Half e_shentsize;            /* Size of section header entry */\n\tElf64_Half e_shnum;                /* Number of section header entries */\n\tElf64_Half e_shstrndx;             /* Section name string table index */\n} Elf64_Ehdr;\n\ntypedef struct {\n\tElf64_Word sh_name;       /* Section name */\n\tElf64_Word sh_type;       /* Section type */\n\tElf64_Xword sh_flags;     /* Section attributes */\n\tElf64_Addr sh_addr;       /* Virtual address in memory */\n\tElf64_Off sh_offset;      /* Offset in file */\n\tElf64_Xword sh_size;      /* Size of section */\n\tElf64_Word sh_link;       /* Link to other section */\n\tElf64_Word sh_info;       /* Miscellaneous information */\n\tElf64_Xword sh_addralign; /* Address alignment boundary */\n\tElf64_Xword sh_entsize;   /* Size of entries, if section has table */\n} Elf64_Shdr;\n\ntypedef struct {\n\tElf64_Word st_name;     /* Symbol name */\n\tunsigned char st_info;  /* Type and Binding attributes */\n\tunsigned char st_other; /* Reserved */\n\tElf64_Half st_shndx;    /* Section table index */\n\tElf64_Addr st_value;    /* Symbol value */\n\tElf64_Xword st_size;    /* Size of object (e.g., common) */\n} Elf64_Sym;\n\ntypedef struct {\n\tElf64_Word p_type;    /* Type of segment */\n\tElf64_Word p_flags;   /* Segment attributes */\n\tElf64_Off p_offset;   /* Offset in file */\n\tElf64_Addr p_vaddr;   /* Virtual address in memory */\n\tElf64_Addr p_paddr;   /* Reserved */\n\tElf64_Xword p_filesz; /* Size of segment in file */\n\tElf64_Xword p_memsz;  /* Size of segment in memory */\n\tElf64_Xword p_align;  /* Alignment of segment */\n} Elf64_Phdr;\n\nenum Elf64_PhdrType { PT_NULL = 0, PT_LOAD = 1, PT_DYNAMIC = 2, PT_INTERP = 3, PT_NOTE = 4, PT_SHLIB = 5, PT_PHDR = 6 };\n\nstruct Elf64Types {\n\ttypedef uint64_t addr_t;\n\ttypedef Elf64_Ehdr Elf_Ehdr;\n\ttypedef Elf64_Phdr Elf_Phdr;\n\ttypedef Elf64_Shdr Elf_Shdr;\n\ttypedef Elf64_Sym Elf_Sym;\n\tstatic constexpr unsigned PT_LOAD = Elf64_PhdrType::PT_LOAD;\n};\n\ntypedef GenericElfLoader<Elf64Types> ELFLoader;\n\n}  // namespace rv64"
  },
  {
    "path": "vp/src/core/rv64/iss.cpp",
    "content": "#include \"iss.h\"\n\n// to save *cout* format setting, see *ISS::show*\n#include <boost/format.hpp>\n#include <boost/io/ios_state.hpp>\n// for safe down-cast\n#include <boost/lexical_cast.hpp>\n\nusing namespace rv64;\n\n// GCC and clang support these types on x64 machines\n// perhaps use boost::multiprecision::int128_t instead\n// see: https://stackoverflow.com/questions/18439520/is-there-a-128-bit-integer-in-c\ntypedef __int128_t int128_t;\ntypedef __uint128_t uint128_t;\n\n#define RAISE_ILLEGAL_INSTRUCTION() raise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\n#define RD instr.rd()\n#define RS1 instr.rs1()\n#define RS2 instr.rs2()\n#define RS3 instr.rs3()\n\nconst char *regnames[] = {\n    \"zero (x0)\", \"ra   (x1)\", \"sp   (x2)\", \"gp   (x3)\", \"tp   (x4)\", \"t0   (x5)\", \"t1   (x6)\", \"t2   (x7)\",\n    \"s0/fp(x8)\", \"s1   (x9)\", \"a0  (x10)\", \"a1  (x11)\", \"a2  (x12)\", \"a3  (x13)\", \"a4  (x14)\", \"a5  (x15)\",\n    \"a6  (x16)\", \"a7  (x17)\", \"s2  (x18)\", \"s3  (x19)\", \"s4  (x20)\", \"s5  (x21)\", \"s6  (x22)\", \"s7  (x23)\",\n    \"s8  (x24)\", \"s9  (x25)\", \"s10 (x26)\", \"s11 (x27)\", \"t3  (x28)\", \"t4  (x29)\", \"t5  (x30)\", \"t6  (x31)\",\n};\n\nint regcolors[] = {\n#if defined(COLOR_THEME_DARK)\n    0,  1,  2,  3,  4,  5,  6,  52, 8,  9,  53, 54, 55, 56, 57, 58,\n    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n#elif defined(COLOR_THEME_LIGHT)\n    100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 153, 154, 155, 156, 157, 158,\n    116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,\n#else\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n#endif\n};\n\nRegFile::RegFile() {\n\tmemset(regs, 0, sizeof(regs));\n}\n\nRegFile::RegFile(const RegFile &other) {\n\tmemcpy(regs, other.regs, sizeof(regs));\n}\n\nvoid RegFile::write(uint64_t index, int64_t value) {\n\tassert(index <= x31);\n\tassert(index != x0);\n\tregs[index] = value;\n}\n\nint64_t RegFile::read(uint64_t index) {\n\tif (index > x31)\n\t\tthrow std::out_of_range(\"out-of-range register access\");\n\treturn regs[index];\n}\n\nuint64_t RegFile::shamt_w(uint64_t index) {\n\tassert(index <= x31);\n\treturn BIT_RANGE(regs[index], 4, 0);\n}\n\nuint64_t RegFile::shamt(uint64_t index) {\n\tassert(index <= x31);\n\treturn BIT_RANGE(regs[index], 5, 0);\n}\n\nint64_t &RegFile::operator[](const uint64_t idx) {\n\treturn regs[idx];\n}\n\n#if defined(COLOR_THEME_LIGHT) || defined(COLOR_THEME_DARK)\n#define COLORFRMT \"\\e[38;5;%um%s\\e[39m\"\n#define COLORPRINT(fmt, data) fmt, data\n#else\n#define COLORFRMT \"%s\"\n#define COLORPRINT(fmt, data) data\n#endif\n\nvoid RegFile::show() {\n\tfor (unsigned i = 0; i < NUM_REGS; ++i) {\n\t\tprintf(COLORFRMT \" = %16lx\\n\", COLORPRINT(regcolors[i], regnames[i]), regs[i]);\n\t}\n}\n\nISS::ISS(uint64_t hart_id) : systemc_name(\"Core-\" + std::to_string(hart_id)) {\n\tcsrs.mhartid.reg = hart_id;\n\top = Opcode::Mapping::UNDEF;\n\n\tsc_core::sc_time qt = tlm::tlm_global_quantum::instance().get();\n\tcycle_time = sc_core::sc_time(10, sc_core::SC_NS);\n\n\tassert(qt >= cycle_time);\n\tassert(qt % cycle_time == sc_core::SC_ZERO_TIME);\n\n\tfor (int i = 0; i < Opcode::NUMBER_OF_INSTRUCTIONS; ++i) instr_cycles[i] = cycle_time;\n\n\tconst sc_core::sc_time memory_access_cycles = 4 * cycle_time;\n\tconst sc_core::sc_time mul_div_cycles = 8 * cycle_time;\n\n\tinstr_cycles[Opcode::LB] = memory_access_cycles;\n\tinstr_cycles[Opcode::LBU] = memory_access_cycles;\n\tinstr_cycles[Opcode::LH] = memory_access_cycles;\n\tinstr_cycles[Opcode::LHU] = memory_access_cycles;\n\tinstr_cycles[Opcode::LW] = memory_access_cycles;\n\tinstr_cycles[Opcode::SB] = memory_access_cycles;\n\tinstr_cycles[Opcode::SH] = memory_access_cycles;\n\tinstr_cycles[Opcode::SW] = memory_access_cycles;\n\tinstr_cycles[Opcode::MUL] = mul_div_cycles;\n\tinstr_cycles[Opcode::MULH] = mul_div_cycles;\n\tinstr_cycles[Opcode::MULHU] = mul_div_cycles;\n\tinstr_cycles[Opcode::MULHSU] = mul_div_cycles;\n\tinstr_cycles[Opcode::DIV] = mul_div_cycles;\n\tinstr_cycles[Opcode::DIVU] = mul_div_cycles;\n\tinstr_cycles[Opcode::REM] = mul_div_cycles;\n\tinstr_cycles[Opcode::REMU] = mul_div_cycles;\n}\n\nvoid ISS::exec_step() {\n\tassert(((pc & ~pc_alignment_mask()) == 0) && \"misaligned instruction\");\n\n\tuint32_t mem_word;\n\ttry {\n\t\tmem_word = instr_mem->load_instr(pc);\n\t\tinstr = Instruction(mem_word);\n\t} catch (SimulationTrap &e) {\n\t\top = Opcode::UNDEF;\n\t\tinstr = Instruction(0);\n\t\tthrow;\n\t}\n\n\tif (instr.is_compressed()) {\n\t\top = instr.decode_and_expand_compressed(RV64);\n\t\tpc += 2;\n\t} else {\n\t\top = instr.decode_normal(RV64);\n\t\tpc += 4;\n\t}\n\n\tif (trace) {\n\t\tprintf(\"core %2lu: prv %1x: pc %16lx (%8x): %s \", csrs.mhartid.reg, prv, last_pc, mem_word,\n\t\t       Opcode::mappingStr.at(op));\n\t\tswitch (Opcode::getType(op)) {\n\t\t\tcase Opcode::Type::R:\n\t\t\t\tprintf(COLORFRMT \", \" COLORFRMT \", \" COLORFRMT, COLORPRINT(regcolors[instr.rd()], regnames[instr.rd()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs1()], regnames[instr.rs1()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs2()], regnames[instr.rs2()]));\n\t\t\t\tbreak;\n\t\t\tcase Opcode::Type::R4:\n\t\t\t\tprintf(COLORFRMT \", \" COLORFRMT \", \" COLORFRMT \", \" COLORFRMT,\n\t\t\t\t       COLORPRINT(regcolors[instr.rd()], regnames[instr.rd()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs1()], regnames[instr.rs1()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs2()], regnames[instr.rs2()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs3()], regnames[instr.rs3()]));\n\t\t\t\tbreak;\n\t\t\tcase Opcode::Type::I:\n\t\t\t\tprintf(COLORFRMT \", \" COLORFRMT \", 0x%x\", COLORPRINT(regcolors[instr.rd()], regnames[instr.rd()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs1()], regnames[instr.rs1()]), instr.I_imm());\n\t\t\t\tbreak;\n\t\t\tcase Opcode::Type::S:\n\t\t\t\tprintf(COLORFRMT \", \" COLORFRMT \", 0x%x\", COLORPRINT(regcolors[instr.rs1()], regnames[instr.rs1()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs2()], regnames[instr.rs2()]), instr.S_imm());\n\t\t\t\tbreak;\n\t\t\tcase Opcode::Type::B:\n\t\t\t\tprintf(COLORFRMT \", \" COLORFRMT \", 0x%x\", COLORPRINT(regcolors[instr.rs1()], regnames[instr.rs1()]),\n\t\t\t\t       COLORPRINT(regcolors[instr.rs2()], regnames[instr.rs2()]), instr.B_imm());\n\t\t\t\tbreak;\n\t\t\tcase Opcode::Type::U:\n\t\t\t\tprintf(COLORFRMT \", 0x%x\", COLORPRINT(regcolors[instr.rd()], regnames[instr.rd()]), instr.U_imm());\n\t\t\t\tbreak;\n\t\t\tcase Opcode::Type::J:\n\t\t\t\tprintf(COLORFRMT \", 0x%x\", COLORPRINT(regcolors[instr.rd()], regnames[instr.rd()]), instr.J_imm());\n\t\t\t\tbreak;\n\t\t\tdefault:;\n\t\t}\n\t\tputs(\"\");\n\t}\n\n\tswitch (op) {\n\t\tcase Opcode::UNDEF:\n\t\t\tif (trace)\n\t\t\t\tstd::cout << \"WARNING: unknown instruction '\" << std::to_string(instr.data()) << \"' at address '\"\n\t\t\t\t          << std::to_string(last_pc) << \"'\" << std::endl;\n\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\t\t\tbreak;\n\n\t\tcase Opcode::ADDI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] + instr.I_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::SLTI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] < instr.I_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::SLTIU:\n\t\t\tregs[instr.rd()] = ((uint64_t)regs[instr.rs1()]) < ((uint64_t)instr.I_imm());\n\t\t\tbreak;\n\n\t\tcase Opcode::XORI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] ^ instr.I_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::ORI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] | instr.I_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::ANDI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] & instr.I_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::ADD:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] + regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::SUB:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] - regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::SLL:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] << regs.shamt(instr.rs2());\n\t\t\tbreak;\n\n\t\tcase Opcode::SLT:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] < regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::SLTU:\n\t\t\tregs[instr.rd()] = ((uint64_t)regs[instr.rs1()]) < ((uint64_t)regs[instr.rs2()]);\n\t\t\tbreak;\n\n\t\tcase Opcode::SRL:\n\t\t\tregs[instr.rd()] = ((uint64_t)regs[instr.rs1()]) >> regs.shamt(instr.rs2());\n\t\t\tbreak;\n\n\t\tcase Opcode::SRA:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] >> regs.shamt(instr.rs2());\n\t\t\tbreak;\n\n\t\tcase Opcode::XOR:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] ^ regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::OR:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] | regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::AND:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] & regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::SLLI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] << instr.shamt();\n\t\t\tbreak;\n\n\t\tcase Opcode::SRLI:\n\t\t\tregs[instr.rd()] = ((uint64_t)regs[instr.rs1()]) >> instr.shamt();\n\t\t\tbreak;\n\n\t\tcase Opcode::SRAI:\n\t\t\tregs[instr.rd()] = regs[instr.rs1()] >> instr.shamt();\n\t\t\tbreak;\n\n\t\tcase Opcode::LUI:\n\t\t\tregs[instr.rd()] = instr.U_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::AUIPC:\n\t\t\tregs[instr.rd()] = last_pc + instr.U_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::JAL: {\n\t\t\tauto link = pc;\n\t\t\tpc = last_pc + instr.J_imm();\n\t\t\ttrap_check_pc_alignment();\n\t\t\tregs[instr.rd()] = link;\n\t\t} break;\n\n\t\tcase Opcode::JALR: {\n\t\t\tauto link = pc;\n\t\t\tpc = (regs[instr.rs1()] + instr.I_imm()) & ~1;\n\t\t\ttrap_check_pc_alignment();\n\t\t\tregs[instr.rd()] = link;\n\t\t} break;\n\n\t\tcase Opcode::SB: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.S_imm();\n\t\t\tmem->store_byte(addr, regs[instr.rs2()]);\n\t\t} break;\n\n\t\tcase Opcode::SH: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.S_imm();\n\t\t\ttrap_check_addr_alignment<2, false>(addr);\n\t\t\tmem->store_half(addr, regs[instr.rs2()]);\n\t\t} break;\n\n\t\tcase Opcode::SW: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.S_imm();\n\t\t\ttrap_check_addr_alignment<4, false>(addr);\n\t\t\tmem->store_word(addr, regs[instr.rs2()]);\n\t\t} break;\n\n\t\tcase Opcode::SD: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.S_imm();\n\t\t\ttrap_check_addr_alignment<8, false>(addr);\n\t\t\tmem->store_double(addr, regs[instr.rs2()]);\n\t\t} break;\n\n\t\tcase Opcode::LB: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\tregs[instr.rd()] = mem->load_byte(addr);\n\t\t} break;\n\n\t\tcase Opcode::LH: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\ttrap_check_addr_alignment<2, true>(addr);\n\t\t\tregs[instr.rd()] = mem->load_half(addr);\n\t\t} break;\n\n\t\tcase Opcode::LW: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\ttrap_check_addr_alignment<4, true>(addr);\n\t\t\tregs[instr.rd()] = mem->load_word(addr);\n\t\t} break;\n\n\t\tcase Opcode::LD: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\ttrap_check_addr_alignment<8, true>(addr);\n\t\t\tregs[instr.rd()] = mem->load_double(addr);\n\t\t} break;\n\n\t\tcase Opcode::LBU: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\tregs[instr.rd()] = mem->load_ubyte(addr);\n\t\t} break;\n\n\t\tcase Opcode::LHU: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\ttrap_check_addr_alignment<2, true>(addr);\n\t\t\tregs[instr.rd()] = mem->load_uhalf(addr);\n\t\t} break;\n\n\t\tcase Opcode::LWU: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\ttrap_check_addr_alignment<4, true>(addr);\n\t\t\tregs[instr.rd()] = mem->load_uword(addr);\n\t\t} break;\n\n\t\tcase Opcode::BEQ:\n\t\t\tif (regs[instr.rs1()] == regs[instr.rs2()]) {\n\t\t\t\tpc = last_pc + instr.B_imm();\n\t\t\t\ttrap_check_pc_alignment();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Opcode::BNE:\n\t\t\tif (regs[instr.rs1()] != regs[instr.rs2()]) {\n\t\t\t\tpc = last_pc + instr.B_imm();\n\t\t\t\ttrap_check_pc_alignment();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Opcode::BLT:\n\t\t\tif (regs[instr.rs1()] < regs[instr.rs2()]) {\n\t\t\t\tpc = last_pc + instr.B_imm();\n\t\t\t\ttrap_check_pc_alignment();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Opcode::BGE:\n\t\t\tif (regs[instr.rs1()] >= regs[instr.rs2()]) {\n\t\t\t\tpc = last_pc + instr.B_imm();\n\t\t\t\ttrap_check_pc_alignment();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Opcode::BLTU:\n\t\t\tif ((uint64_t)regs[instr.rs1()] < (uint64_t)regs[instr.rs2()]) {\n\t\t\t\tpc = last_pc + instr.B_imm();\n\t\t\t\ttrap_check_pc_alignment();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Opcode::BGEU:\n\t\t\tif ((uint64_t)regs[instr.rs1()] >= (uint64_t)regs[instr.rs2()]) {\n\t\t\t\tpc = last_pc + instr.B_imm();\n\t\t\t\ttrap_check_pc_alignment();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase Opcode::ADDIW:\n\t\t\tregs[instr.rd()] = (int32_t)regs[instr.rs1()] + (int32_t)instr.I_imm();\n\t\t\tbreak;\n\n\t\tcase Opcode::SLLIW:\n\t\t\tregs[instr.rd()] = (int32_t)((uint32_t)regs[instr.rs1()] << instr.shamt_w());\n\t\t\tbreak;\n\n\t\tcase Opcode::SRLIW:\n\t\t\tregs[instr.rd()] = (int32_t)(((uint32_t)regs[instr.rs1()]) >> instr.shamt_w());\n\t\t\tbreak;\n\n\t\tcase Opcode::SRAIW:\n\t\t\tregs[instr.rd()] = (int32_t)((int32_t)regs[instr.rs1()] >> instr.shamt_w());\n\t\t\tbreak;\n\n\t\tcase Opcode::ADDW:\n\t\t\tregs[instr.rd()] = (int32_t)regs[instr.rs1()] + (int32_t)regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::SUBW:\n\t\t\tregs[instr.rd()] = (int32_t)regs[instr.rs1()] - (int32_t)regs[instr.rs2()];\n\t\t\tbreak;\n\n\t\tcase Opcode::SLLW:\n\t\t\tregs[instr.rd()] = (int32_t)((uint32_t)regs[instr.rs1()] << regs.shamt_w(instr.rs2()));\n\t\t\tbreak;\n\n\t\tcase Opcode::SRLW:\n\t\t\tregs[instr.rd()] = (int32_t)(((uint32_t)regs[instr.rs1()]) >> regs.shamt_w(instr.rs2()));\n\t\t\tbreak;\n\n\t\tcase Opcode::SRAW:\n\t\t\tregs[instr.rd()] = (int32_t)((int32_t)regs[instr.rs1()] >> regs.shamt_w(instr.rs2()));\n\t\t\tbreak;\n\n\t\tcase Opcode::FENCE:\n\t\tcase Opcode::FENCE_I: {\n\t\t\t// not using out of order execution/caches so can be ignored\n\t\t} break;\n\n\t\tcase Opcode::ECALL: {\n\t\t\tif (sys) {\n\t\t\t\tsys->execute_syscall(this);\n\t\t\t} else {\n\t\t\t\tswitch (prv) {\n\t\t\t\t\tcase MachineMode:\n\t\t\t\t\t\traise_trap(EXC_ECALL_M_MODE, last_pc);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase SupervisorMode:\n\t\t\t\t\t\traise_trap(EXC_ECALL_S_MODE, last_pc);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase UserMode:\n\t\t\t\t\t\traise_trap(EXC_ECALL_U_MODE, last_pc);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow std::runtime_error(\"unknown privilege level \" + std::to_string(prv));\n\t\t\t\t}\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::EBREAK: {\n\t\t\t// TODO: also raise trap and let the SW deal with it?\n\t\t\tstatus = CoreExecStatus::HitBreakpoint;\n\t\t} break;\n\n\t\tcase Opcode::CSRRW: {\n\t\t\tauto addr = instr.csr();\n\t\t\tif (is_invalid_csr_access(addr, true)) {\n\t\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\t\t\t} else {\n\t\t\t\tauto rd = instr.rd();\n\t\t\t\tauto rs1_val = regs[instr.rs1()];\n\t\t\t\tif (rd != RegFile::zero) {\n\t\t\t\t\tregs[instr.rd()] = get_csr_value(addr);\n\t\t\t\t}\n\t\t\t\tset_csr_value(addr, rs1_val);\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::CSRRS: {\n\t\t\tauto addr = instr.csr();\n\t\t\tauto rs1 = instr.rs1();\n\t\t\tauto write = rs1 != RegFile::zero;\n\t\t\tif (is_invalid_csr_access(addr, write)) {\n\t\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\t\t\t} else {\n\t\t\t\tauto rd = instr.rd();\n\t\t\t\tauto rs1_val = regs[rs1];\n\t\t\t\tauto csr_val = get_csr_value(addr);\n\t\t\t\tif (rd != RegFile::zero)\n\t\t\t\t\tregs[rd] = csr_val;\n\t\t\t\tif (write)\n\t\t\t\t\tset_csr_value(addr, csr_val | rs1_val);\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::CSRRC: {\n\t\t\tauto addr = instr.csr();\n\t\t\tauto rs1 = instr.rs1();\n\t\t\tauto write = rs1 != RegFile::zero;\n\t\t\tif (is_invalid_csr_access(addr, write)) {\n\t\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\t\t\t} else {\n\t\t\t\tauto rd = instr.rd();\n\t\t\t\tauto rs1_val = regs[rs1];\n\t\t\t\tauto csr_val = get_csr_value(addr);\n\t\t\t\tif (rd != RegFile::zero)\n\t\t\t\t\tregs[rd] = csr_val;\n\t\t\t\tif (write)\n\t\t\t\t\tset_csr_value(addr, csr_val & ~rs1_val);\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::CSRRWI: {\n\t\t\tauto addr = instr.csr();\n\t\t\tif (is_invalid_csr_access(addr, true)) {\n\t\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\t\t\t} else {\n\t\t\t\tauto rd = instr.rd();\n\t\t\t\tif (rd != RegFile::zero) {\n\t\t\t\t\tregs[rd] = get_csr_value(addr);\n\t\t\t\t}\n\t\t\t\tset_csr_value(addr, instr.zimm());\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::CSRRSI: {\n\t\t\tauto addr = instr.csr();\n\t\t\tauto zimm = instr.zimm();\n\t\t\tauto write = zimm != 0;\n\t\t\tif (is_invalid_csr_access(addr, write)) {\n\t\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\t\t\t} else {\n\t\t\t\tauto csr_val = get_csr_value(addr);\n\t\t\t\tauto rd = instr.rd();\n\t\t\t\tif (rd != RegFile::zero)\n\t\t\t\t\tregs[rd] = csr_val;\n\t\t\t\tif (write)\n\t\t\t\t\tset_csr_value(addr, csr_val | zimm);\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::CSRRCI: {\n\t\t\tauto addr = instr.csr();\n\t\t\tauto zimm = instr.zimm();\n\t\t\tauto write = zimm != 0;\n\t\t\tif (is_invalid_csr_access(addr, write)) {\n\t\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\t\t\t} else {\n\t\t\t\tauto csr_val = get_csr_value(addr);\n\t\t\t\tauto rd = instr.rd();\n\t\t\t\tif (rd != RegFile::zero)\n\t\t\t\t\tregs[rd] = csr_val;\n\t\t\t\tif (write)\n\t\t\t\t\tset_csr_value(addr, csr_val & ~zimm);\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::MUL: {\n\t\t\tint128_t ans = (int128_t)regs[instr.rs1()] * (int128_t)regs[instr.rs2()];\n\t\t\tregs[instr.rd()] = (int64_t)ans;\n\t\t} break;\n\n\t\tcase Opcode::MULH: {\n\t\t\tint128_t ans = (int128_t)regs[instr.rs1()] * (int128_t)regs[instr.rs2()];\n\t\t\tregs[instr.rd()] = ans >> 64;\n\t\t} break;\n\n\t\tcase Opcode::MULHU: {\n\t\t\tint128_t ans = ((uint128_t)(uint64_t)regs[instr.rs1()]) * (uint128_t)((uint64_t)regs[instr.rs2()]);\n\t\t\tregs[instr.rd()] = ans >> 64;\n\t\t} break;\n\n\t\tcase Opcode::MULHSU: {\n\t\t\tint128_t ans = (int128_t)regs[instr.rs1()] * (uint128_t)((uint64_t)regs[instr.rs2()]);\n\t\t\tregs[instr.rd()] = ans >> 64;\n\t\t} break;\n\n\t\tcase Opcode::DIV: {\n\t\t\tauto a = regs[instr.rs1()];\n\t\t\tauto b = regs[instr.rs2()];\n\t\t\tif (b == 0) {\n\t\t\t\tregs[instr.rd()] = -1;\n\t\t\t} else if (a == REG_MIN && b == -1) {\n\t\t\t\tregs[instr.rd()] = a;\n\t\t\t} else {\n\t\t\t\tregs[instr.rd()] = a / b;\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::DIVU: {\n\t\t\tauto a = regs[instr.rs1()];\n\t\t\tauto b = regs[instr.rs2()];\n\t\t\tif (b == 0) {\n\t\t\t\tregs[instr.rd()] = -1;\n\t\t\t} else {\n\t\t\t\tregs[instr.rd()] = (uint64_t)a / (uint64_t)b;\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::REM: {\n\t\t\tauto a = regs[instr.rs1()];\n\t\t\tauto b = regs[instr.rs2()];\n\t\t\tif (b == 0) {\n\t\t\t\tregs[instr.rd()] = a;\n\t\t\t} else if (a == REG_MIN && b == -1) {\n\t\t\t\tregs[instr.rd()] = 0;\n\t\t\t} else {\n\t\t\t\tregs[instr.rd()] = a % b;\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::REMU: {\n\t\t\tauto a = regs[instr.rs1()];\n\t\t\tauto b = regs[instr.rs2()];\n\t\t\tif (b == 0) {\n\t\t\t\tregs[instr.rd()] = a;\n\t\t\t} else {\n\t\t\t\tregs[instr.rd()] = (uint64_t)a % (uint64_t)b;\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::MULW: {\n\t\t\tregs[instr.rd()] = (int32_t)(regs[instr.rs1()] * regs[instr.rs2()]);\n\t\t} break;\n\n\t\tcase Opcode::DIVW: {\n\t\t\tint32_t a = regs[instr.rs1()];\n\t\t\tint32_t b = regs[instr.rs2()];\n\t\t\tif (b == 0) {\n\t\t\t\tregs[instr.rd()] = -1;\n\t\t\t} else if (a == REG32_MIN && b == -1) {\n\t\t\t\tregs[instr.rd()] = a;\n\t\t\t} else {\n\t\t\t\tregs[instr.rd()] = a / b;\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::DIVUW: {\n\t\t\tint32_t a = regs[instr.rs1()];\n\t\t\tint32_t b = regs[instr.rs2()];\n\t\t\tif (b == 0) {\n\t\t\t\tregs[instr.rd()] = -1;\n\t\t\t} else {\n\t\t\t\tregs[instr.rd()] = (int32_t)((uint32_t)a / (uint32_t)b);\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::REMW: {\n\t\t\tint32_t a = regs[instr.rs1()];\n\t\t\tint32_t b = regs[instr.rs2()];\n\t\t\tif (b == 0) {\n\t\t\t\tregs[instr.rd()] = a;\n\t\t\t} else if (a == REG32_MIN && b == -1) {\n\t\t\t\tregs[instr.rd()] = 0;\n\t\t\t} else {\n\t\t\t\tregs[instr.rd()] = a % b;\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::REMUW: {\n\t\t\tint32_t a = regs[instr.rs1()];\n\t\t\tint32_t b = regs[instr.rs2()];\n\t\t\tif (b == 0) {\n\t\t\t\tregs[instr.rd()] = a;\n\t\t\t} else {\n\t\t\t\tregs[instr.rd()] = (int32_t)((uint32_t)a % (uint32_t)b);\n\t\t\t}\n\t\t} break;\n\n\t\tcase Opcode::LR_W: {\n\t\t\tuint64_t addr = regs[instr.rs1()];\n\t\t\ttrap_check_addr_alignment<4, true>(addr);\n\t\t\tregs[instr.rd()] = mem->atomic_load_reserved_word(addr);\n\t\t\tif (lr_sc_counter == 0)\n\t\t\t    lr_sc_counter = 17;  // this instruction + 16 additional ones, (an over-approximation) to cover the RISC-V forward progress property\n\t\t} break;\n\n\t\tcase Opcode::SC_W: {\n\t\t\tuint64_t addr = regs[instr.rs1()];\n\t\t\ttrap_check_addr_alignment<4, false>(addr);\n\t\t\tint32_t val = regs[instr.rs2()];\n\t\t\tregs[instr.rd()] = 1;  // failure by default (in case a trap is thrown)\n\t\t\tregs[instr.rd()] = mem->atomic_store_conditional_word(addr, val) ? 0 : 1;  // overwrite result (in case no trap is thrown)\n\t\t\tlr_sc_counter = 0;\n\t\t} break;\n\n\t\tcase Opcode::AMOSWAP_W: {\n\t\t\texecute_amo_w(instr, [](int32_t a, int32_t b) {\n\t\t\t\t(void)a;\n\t\t\t\treturn b;\n\t\t\t});\n\t\t} break;\n\n\t\tcase Opcode::AMOADD_W: {\n\t\t\texecute_amo_w(instr, [](int32_t a, int32_t b) { return a + b; });\n\t\t} break;\n\n\t\tcase Opcode::AMOXOR_W: {\n\t\t\texecute_amo_w(instr, [](int32_t a, int32_t b) { return a ^ b; });\n\t\t} break;\n\n\t\tcase Opcode::AMOAND_W: {\n\t\t\texecute_amo_w(instr, [](int32_t a, int32_t b) { return a & b; });\n\t\t} break;\n\n\t\tcase Opcode::AMOOR_W: {\n\t\t\texecute_amo_w(instr, [](int32_t a, int32_t b) { return a | b; });\n\t\t} break;\n\n\t\tcase Opcode::AMOMIN_W: {\n\t\t\texecute_amo_w(instr, [](int32_t a, int32_t b) { return std::min(a, b); });\n\t\t} break;\n\n\t\tcase Opcode::AMOMINU_W: {\n\t\t\texecute_amo_w(instr, [](int32_t a, int32_t b) { return std::min((uint32_t)a, (uint32_t)b); });\n\t\t} break;\n\n\t\tcase Opcode::AMOMAX_W: {\n\t\t\texecute_amo_w(instr, [](int32_t a, int32_t b) { return std::max(a, b); });\n\t\t} break;\n\n\t\tcase Opcode::AMOMAXU_W: {\n\t\t\texecute_amo_w(instr, [](int32_t a, int32_t b) { return std::max((uint32_t)a, (uint32_t)b); });\n\t\t} break;\n\n\t\tcase Opcode::LR_D: {\n\t\t\tuint64_t addr = regs[instr.rs1()];\n\t\t\ttrap_check_addr_alignment<8, true>(addr);\n\t\t\tregs[instr.rd()] = mem->atomic_load_reserved_double(addr);\n\t\t\tif (lr_sc_counter == 0)\n\t\t\t    lr_sc_counter = 17;  // this instruction + 16 additional ones, (an over-approximation) to cover the RISC-V forward progress property\n\t\t} break;\n\n\t\tcase Opcode::SC_D: {\n\t\t\tuint64_t addr = regs[instr.rs1()];\n\t\t\ttrap_check_addr_alignment<8, false>(addr);\n\t\t\tuint64_t val = regs[instr.rs2()];\n\t\t\tregs[instr.rd()] = 1;  // failure by default (in case a trap is thrown)\n\t\t\tregs[instr.rd()] = mem->atomic_store_conditional_double(addr, val)\n\t\t\t                       ? 0\n\t\t\t                       : 1;  // overwrite result (in case no trap is thrown)\n\t\t\tlr_sc_counter = 0;\n\t\t} break;\n\n\t\tcase Opcode::AMOSWAP_D: {\n\t\t\texecute_amo_d(instr, [](int64_t a, int64_t b) {\n\t\t\t\t(void)a;\n\t\t\t\treturn b;\n\t\t\t});\n\t\t} break;\n\n\t\tcase Opcode::AMOADD_D: {\n\t\t\texecute_amo_d(instr, [](int64_t a, int64_t b) { return a + b; });\n\t\t} break;\n\n\t\tcase Opcode::AMOXOR_D: {\n\t\t\texecute_amo_d(instr, [](int64_t a, int64_t b) { return a ^ b; });\n\t\t} break;\n\n\t\tcase Opcode::AMOAND_D: {\n\t\t\texecute_amo_d(instr, [](int64_t a, int64_t b) { return a & b; });\n\t\t} break;\n\n\t\tcase Opcode::AMOOR_D: {\n\t\t\texecute_amo_d(instr, [](int64_t a, int64_t b) { return a | b; });\n\t\t} break;\n\n\t\tcase Opcode::AMOMIN_D: {\n\t\t\texecute_amo_d(instr, [](int64_t a, int64_t b) { return std::min(a, b); });\n\t\t} break;\n\n\t\tcase Opcode::AMOMINU_D: {\n\t\t\texecute_amo_d(instr, [](int64_t a, int64_t b) { return std::min((uint64_t)a, (uint64_t)b); });\n\t\t} break;\n\n\t\tcase Opcode::AMOMAX_D: {\n\t\t\texecute_amo_d(instr, [](int64_t a, int64_t b) { return std::max(a, b); });\n\t\t} break;\n\n\t\tcase Opcode::AMOMAXU_D: {\n\t\t\texecute_amo_d(instr, [](int64_t a, int64_t b) { return std::max((uint64_t)a, (uint64_t)b); });\n\t\t} break;\n\n\t\t\t// RV64 F/D extension\n\n\t\tcase Opcode::FLW: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\ttrap_check_addr_alignment<4, true>(addr);\n\t\t\tfp_regs.write(RD, float32_t{(uint32_t)mem->load_uword(addr)});\n\t\t} break;\n\n\t\tcase Opcode::FSW: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.S_imm();\n\t\t\ttrap_check_addr_alignment<4, false>(addr);\n\t\t\tmem->store_word(addr, fp_regs.u32(RS2));\n\t\t} break;\n\n\t\tcase Opcode::FADD_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_add(fp_regs.f32(RS1), fp_regs.f32(RS2)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FSUB_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_sub(fp_regs.f32(RS1), fp_regs.f32(RS2)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMUL_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_mul(fp_regs.f32(RS1), fp_regs.f32(RS2)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FDIV_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_div(fp_regs.f32(RS1), fp_regs.f32(RS2)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FSQRT_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_sqrt(fp_regs.f32(RS1)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMIN_S: {\n\t\t\tfp_prepare_instr();\n\n\t\t\tbool rs1_smaller = f32_lt_quiet(fp_regs.f32(RS1), fp_regs.f32(RS2)) ||\n\t\t\t                   (f32_eq(fp_regs.f32(RS1), fp_regs.f32(RS2)) && f32_isNegative(fp_regs.f32(RS1)));\n\n\t\t\tif (f32_isNaN(fp_regs.f32(RS1)) && f32_isNaN(fp_regs.f32(RS2))) {\n\t\t\t\tfp_regs.write(RD, f32_defaultNaN);\n\t\t\t} else {\n\t\t\t\tif (rs1_smaller)\n\t\t\t\t\tfp_regs.write(RD, fp_regs.f32(RS1));\n\t\t\t\telse\n\t\t\t\t\tfp_regs.write(RD, fp_regs.f32(RS2));\n\t\t\t}\n\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMAX_S: {\n\t\t\tfp_prepare_instr();\n\n\t\t\tbool rs1_greater = f32_lt_quiet(fp_regs.f32(RS2), fp_regs.f32(RS1)) ||\n\t\t\t                   (f32_eq(fp_regs.f32(RS2), fp_regs.f32(RS1)) && f32_isNegative(fp_regs.f32(RS2)));\n\n\t\t\tif (f32_isNaN(fp_regs.f32(RS1)) && f32_isNaN(fp_regs.f32(RS2))) {\n\t\t\t\tfp_regs.write(RD, f32_defaultNaN);\n\t\t\t} else {\n\t\t\t\tif (rs1_greater)\n\t\t\t\t\tfp_regs.write(RD, fp_regs.f32(RS1));\n\t\t\t\telse\n\t\t\t\t\tfp_regs.write(RD, fp_regs.f32(RS2));\n\t\t\t}\n\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMADD_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_mulAdd(fp_regs.f32(RS1), fp_regs.f32(RS2), fp_regs.f32(RS3)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMSUB_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_mulAdd(fp_regs.f32(RS1), fp_regs.f32(RS2), f32_neg(fp_regs.f32(RS3))));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FNMADD_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_mulAdd(f32_neg(fp_regs.f32(RS1)), fp_regs.f32(RS2), f32_neg(fp_regs.f32(RS3))));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FNMSUB_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_mulAdd(f32_neg(fp_regs.f32(RS1)), fp_regs.f32(RS2), fp_regs.f32(RS3)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_W_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tregs[RD] = f32_to_i32(fp_regs.f32(RS1), softfloat_roundingMode, true);\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_WU_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tregs[RD] = (int32_t)f32_to_ui32(fp_regs.f32(RS1), softfloat_roundingMode, true);\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_S_W: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, i32_to_f32((int32_t)regs[RS1]));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_S_WU: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, ui32_to_f32((int32_t)regs[RS1]));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FSGNJ_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tauto f1 = fp_regs.f32(RS1);\n\t\t\tauto f2 = fp_regs.f32(RS2);\n\t\t\tfp_regs.write(RD, float32_t{(f1.v & ~F32_SIGN_BIT) | (f2.v & F32_SIGN_BIT)});\n\t\t\tfp_set_dirty();\n\t\t} break;\n\n\t\tcase Opcode::FSGNJN_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tauto f1 = fp_regs.f32(RS1);\n\t\t\tauto f2 = fp_regs.f32(RS2);\n\t\t\tfp_regs.write(RD, float32_t{(f1.v & ~F32_SIGN_BIT) | (~f2.v & F32_SIGN_BIT)});\n\t\t\tfp_set_dirty();\n\t\t} break;\n\n\t\tcase Opcode::FSGNJX_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tauto f1 = fp_regs.f32(RS1);\n\t\t\tauto f2 = fp_regs.f32(RS2);\n\t\t\tfp_regs.write(RD, float32_t{f1.v ^ (f2.v & F32_SIGN_BIT)});\n\t\t\tfp_set_dirty();\n\t\t} break;\n\n\t\tcase Opcode::FMV_W_X: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_regs.write(RD, float32_t{(uint32_t)((int32_t)regs[RS1])});\n\t\t\tfp_set_dirty();\n\t\t} break;\n\n\t\tcase Opcode::FMV_X_W: {\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = (int32_t)fp_regs.u32(RS1);\n\t\t} break;\n\n\t\tcase Opcode::FEQ_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = f32_eq(fp_regs.f32(RS1), fp_regs.f32(RS2));\n\t\t\tfp_update_exception_flags();\n\t\t} break;\n\n\t\tcase Opcode::FLT_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = f32_lt(fp_regs.f32(RS1), fp_regs.f32(RS2));\n\t\t\tfp_update_exception_flags();\n\t\t} break;\n\n\t\tcase Opcode::FLE_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = f32_le(fp_regs.f32(RS1), fp_regs.f32(RS2));\n\t\t\tfp_update_exception_flags();\n\t\t} break;\n\n\t\tcase Opcode::FCLASS_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = (int32_t)f32_classify(fp_regs.f32(RS1));\n\t\t} break;\n\n\t\tcase Opcode::FCVT_L_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tregs[RD] = f32_to_i64(fp_regs.f32(RS1), softfloat_roundingMode, true);\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_LU_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tregs[RD] = f32_to_ui64(fp_regs.f32(RS1), softfloat_roundingMode, true);\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_S_L: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, i64_to_f32(regs[RS1]));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_S_LU: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, ui64_to_f32(regs[RS1]));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FLD: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.I_imm();\n\t\t\ttrap_check_addr_alignment<8, true>(addr);\n\t\t\tfp_regs.write(RD, float64_t{(uint64_t)mem->load_double(addr)});\n\t\t} break;\n\n\t\tcase Opcode::FSD: {\n\t\t\tuint64_t addr = regs[instr.rs1()] + instr.S_imm();\n\t\t\ttrap_check_addr_alignment<8, false>(addr);\n\t\t\tmem->store_double(addr, fp_regs.f64(RS2).v);\n\t\t} break;\n\n\t\tcase Opcode::FADD_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f64_add(fp_regs.f64(RS1), fp_regs.f64(RS2)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FSUB_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f64_sub(fp_regs.f64(RS1), fp_regs.f64(RS2)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMUL_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f64_mul(fp_regs.f64(RS1), fp_regs.f64(RS2)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FDIV_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f64_div(fp_regs.f64(RS1), fp_regs.f64(RS2)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FSQRT_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f64_sqrt(fp_regs.f64(RS1)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMIN_D: {\n\t\t\tfp_prepare_instr();\n\n\t\t\tbool rs1_smaller = f64_lt_quiet(fp_regs.f64(RS1), fp_regs.f64(RS2)) ||\n\t\t\t                   (f64_eq(fp_regs.f64(RS1), fp_regs.f64(RS2)) && f64_isNegative(fp_regs.f64(RS1)));\n\n\t\t\tif (f64_isNaN(fp_regs.f64(RS1)) && f64_isNaN(fp_regs.f64(RS2))) {\n\t\t\t\tfp_regs.write(RD, f64_defaultNaN);\n\t\t\t} else {\n\t\t\t\tif (rs1_smaller)\n\t\t\t\t\tfp_regs.write(RD, fp_regs.f64(RS1));\n\t\t\t\telse\n\t\t\t\t\tfp_regs.write(RD, fp_regs.f64(RS2));\n\t\t\t}\n\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMAX_D: {\n\t\t\tfp_prepare_instr();\n\n\t\t\tbool rs1_greater = f64_lt_quiet(fp_regs.f64(RS2), fp_regs.f64(RS1)) ||\n\t\t\t                   (f64_eq(fp_regs.f64(RS2), fp_regs.f64(RS1)) && f64_isNegative(fp_regs.f64(RS2)));\n\n\t\t\tif (f64_isNaN(fp_regs.f64(RS1)) && f64_isNaN(fp_regs.f64(RS2))) {\n\t\t\t\tfp_regs.write(RD, f64_defaultNaN);\n\t\t\t} else {\n\t\t\t\tif (rs1_greater)\n\t\t\t\t\tfp_regs.write(RD, fp_regs.f64(RS1));\n\t\t\t\telse\n\t\t\t\t\tfp_regs.write(RD, fp_regs.f64(RS2));\n\t\t\t}\n\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMADD_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f64_mulAdd(fp_regs.f64(RS1), fp_regs.f64(RS2), fp_regs.f64(RS3)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FMSUB_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f64_mulAdd(fp_regs.f64(RS1), fp_regs.f64(RS2), f64_neg(fp_regs.f64(RS3))));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FNMADD_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f64_mulAdd(f64_neg(fp_regs.f64(RS1)), fp_regs.f64(RS2), f64_neg(fp_regs.f64(RS3))));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FNMSUB_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f64_mulAdd(f64_neg(fp_regs.f64(RS1)), fp_regs.f64(RS2), fp_regs.f64(RS3)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FSGNJ_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tauto f1 = fp_regs.f64(RS1);\n\t\t\tauto f2 = fp_regs.f64(RS2);\n\t\t\tfp_regs.write(RD, float64_t{(f1.v & ~F64_SIGN_BIT) | (f2.v & F64_SIGN_BIT)});\n\t\t\tfp_set_dirty();\n\t\t} break;\n\n\t\tcase Opcode::FSGNJN_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tauto f1 = fp_regs.f64(RS1);\n\t\t\tauto f2 = fp_regs.f64(RS2);\n\t\t\tfp_regs.write(RD, float64_t{(f1.v & ~F64_SIGN_BIT) | (~f2.v & F64_SIGN_BIT)});\n\t\t\tfp_set_dirty();\n\t\t} break;\n\n\t\tcase Opcode::FSGNJX_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tauto f1 = fp_regs.f64(RS1);\n\t\t\tauto f2 = fp_regs.f64(RS2);\n\t\t\tfp_regs.write(RD, float64_t{f1.v ^ (f2.v & F64_SIGN_BIT)});\n\t\t\tfp_set_dirty();\n\t\t} break;\n\n\t\tcase Opcode::FEQ_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = f64_eq(fp_regs.f64(RS1), fp_regs.f64(RS2));\n\t\t\tfp_update_exception_flags();\n\t\t} break;\n\n\t\tcase Opcode::FLT_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = f64_lt(fp_regs.f64(RS1), fp_regs.f64(RS2));\n\t\t\tfp_update_exception_flags();\n\t\t} break;\n\n\t\tcase Opcode::FLE_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = f64_le(fp_regs.f64(RS1), fp_regs.f64(RS2));\n\t\t\tfp_update_exception_flags();\n\t\t} break;\n\n\t\tcase Opcode::FCLASS_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = (int64_t)f64_classify(fp_regs.f64(RS1));\n\t\t} break;\n\n\t\tcase Opcode::FMV_D_X: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_regs.write(RD, float64_t{(uint64_t)regs[RS1]});\n\t\t\tfp_set_dirty();\n\t\t} break;\n\n\t\tcase Opcode::FMV_X_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tregs[RD] = fp_regs.f64(RS1).v;\n\t\t} break;\n\n\t\tcase Opcode::FCVT_W_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tregs[RD] = f64_to_i32(fp_regs.f64(RS1), softfloat_roundingMode, true);\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_WU_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tregs[RD] = (int32_t)f64_to_ui32(fp_regs.f64(RS1), softfloat_roundingMode, true);\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_D_W: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, i32_to_f64((int32_t)regs[RS1]));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_D_WU: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, ui32_to_f64((int32_t)regs[RS1]));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_S_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f64_to_f32(fp_regs.f64(RS1)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_D_S: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, f32_to_f64(fp_regs.f32(RS1)));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_L_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tregs[RD] = f64_to_i64(fp_regs.f64(RS1), softfloat_roundingMode, true);\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_LU_D: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tregs[RD] = f64_to_ui64(fp_regs.f64(RS1), softfloat_roundingMode, true);\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_D_L: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, i64_to_f64(regs[RS1]));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\tcase Opcode::FCVT_D_LU: {\n\t\t\tfp_prepare_instr();\n\t\t\tfp_setup_rm();\n\t\t\tfp_regs.write(RD, ui64_to_f64(regs[RS1]));\n\t\t\tfp_finish_instr();\n\t\t} break;\n\n\t\t\t// privileged instructions\n\n\t\tcase Opcode::WFI:\n\t\t\t// NOTE: only a hint, can be implemented as NOP\n\t\t\t// std::cout << \"[sim:wfi] CSR mstatus.fields.mie \" << csrs.mstatus->mie << std::endl;\n\t\t\trelease_lr_sc_reservation();\n\n\t\t\tif (s_mode() && csrs.mstatus.fields.tw)\n\t\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\n\t\t\tif (u_mode() && csrs.misa.has_supervisor_mode_extension())\n\t\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\n\t\t\tif (!ignore_wfi && !has_local_pending_enabled_interrupts())\n\t\t\t\tsc_core::wait(wfi_event);\n\t\t\tbreak;\n\n\t\tcase Opcode::SFENCE_VMA:\n\t\t\tif (s_mode() && csrs.mstatus.fields.tvm)\n\t\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\t\t\tmem->flush_tlb();\n\t\t\tbreak;\n\n\t\tcase Opcode::URET:\n\t\t\tif (!csrs.misa.has_user_mode_extension())\n\t\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\t\t\treturn_from_trap_handler(UserMode);\n\t\t\tbreak;\n\n\t\tcase Opcode::SRET:\n\t\t\tif (!csrs.misa.has_supervisor_mode_extension() || (s_mode() && csrs.mstatus.fields.tsr))\n\t\t\t\traise_trap(EXC_ILLEGAL_INSTR, instr.data());\n\t\t\treturn_from_trap_handler(SupervisorMode);\n\t\t\tbreak;\n\n\t\tcase Opcode::MRET:\n\t\t\treturn_from_trap_handler(MachineMode);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"unknown opcode\");\n\t}\n}\n\nuint64_t ISS::_compute_and_get_current_cycles() {\n\tassert(cycle_counter % cycle_time == sc_core::SC_ZERO_TIME);\n\tassert(cycle_counter.value() % cycle_time.value() == 0);\n\n\tuint64_t num_cycles = cycle_counter.value() / cycle_time.value();\n\n\treturn num_cycles;\n}\n\nvoid ISS::validate_csr_counter_read_access_rights(uint64_t addr) {\n\t// match against counter CSR addresses, see RISC-V privileged spec for the address definitions\n\tif ((addr >= 0xC00 && addr <= 0xC1F)) {\n\t\tauto cnt = addr & 0x1F;  // 32 counter in total, naturally aligned with the mcounteren and scounteren CSRs\n\n\t\tif (s_mode() && !csr::is_bitset(csrs.mcounteren, cnt))\n\t\t\tRAISE_ILLEGAL_INSTRUCTION();\n\n\t\tif (u_mode() && (!csr::is_bitset(csrs.mcounteren, cnt) || !csr::is_bitset(csrs.scounteren, cnt)))\n\t\t\tRAISE_ILLEGAL_INSTRUCTION();\n\t}\n}\n\nuint64_t ISS::get_csr_value(uint64_t addr) {\n\tvalidate_csr_counter_read_access_rights(addr);\n\n\tauto read = [=](auto &x, uint64_t mask) { return x.reg & mask; };\n\n\tusing namespace csr;\n\n\tswitch (addr) {\n\t\tcase TIME_ADDR:\n\t\tcase MTIME_ADDR: {\n\t\t\tuint64_t mtime = clint->update_and_get_mtime();\n\t\t\tcsrs.time.reg = mtime;\n\t\t\treturn csrs.time.reg;\n\t\t}\n\n\t\tcase MCYCLE_ADDR:\n\t\t\tcsrs.cycle.reg = _compute_and_get_current_cycles();\n\t\t\treturn csrs.cycle.reg;\n\n\t\tcase MINSTRET_ADDR:\n\t\t\treturn csrs.instret.reg;\n\n\t\tSWITCH_CASE_MATCH_ANY_HPMCOUNTER_RV64:  // not implemented\n\t\t\treturn 0;\n\n\t\t\t// TODO: SD should be updated as SD=XS|FS and SD should be read-only -> update mask\n\t\tcase MSTATUS_ADDR:\n\t\t\treturn read(csrs.mstatus, MSTATUS_READ_MASK);\n\t\tcase SSTATUS_ADDR:\n\t\t\treturn read(csrs.mstatus, SSTATUS_READ_MASK);\n\t\tcase USTATUS_ADDR:\n\t\t\treturn read(csrs.mstatus, USTATUS_MASK);\n\n\t\tcase MIP_ADDR:\n\t\t\treturn read(csrs.mip, MIP_READ_MASK);\n\t\tcase SIP_ADDR:\n\t\t\treturn read(csrs.mip, SIP_MASK);\n\t\tcase UIP_ADDR:\n\t\t\treturn read(csrs.mip, UIP_MASK);\n\n\t\tcase MIE_ADDR:\n\t\t\treturn read(csrs.mie, MIE_MASK);\n\t\tcase SIE_ADDR:\n\t\t\treturn read(csrs.mie, SIE_MASK);\n\t\tcase UIE_ADDR:\n\t\t\treturn read(csrs.mie, UIE_MASK);\n\n\t\tcase SATP_ADDR:\n\t\t\tif (csrs.mstatus.fields.tvm)\n\t\t\t\tRAISE_ILLEGAL_INSTRUCTION();\n\t\t\tbreak;\n\n\t\tcase FCSR_ADDR:\n\t\t\treturn read(csrs.fcsr, FCSR_MASK);\n\n\t\tcase FFLAGS_ADDR:\n\t\t\treturn csrs.fcsr.fields.fflags;\n\n\t\tcase FRM_ADDR:\n\t\t\treturn csrs.fcsr.fields.frm;\n\t}\n\n\tif (!csrs.is_valid_csr64_addr(addr))\n\t\tRAISE_ILLEGAL_INSTRUCTION();\n\n\treturn csrs.default_read64(addr);\n}\n\nvoid ISS::set_csr_value(uint64_t addr, uint64_t value) {\n\tauto write = [=](auto &x, uint64_t mask) { x.reg = (x.reg & ~mask) | (value & mask); };\n\n\tusing namespace csr;\n\n\tswitch (addr) {\n\t\tcase MISA_ADDR:                         // currently, read-only, thus cannot be changed at runtime\n\t\tSWITCH_CASE_MATCH_ANY_HPMCOUNTER_RV64:  // not implemented\n\t\t\tbreak;\n\n\t\tcase SATP_ADDR: {\n\t\t\tif (csrs.mstatus.fields.tvm)\n\t\t\t\tRAISE_ILLEGAL_INSTRUCTION();\n\t\t\tauto mode = csrs.satp.fields.mode;\n\t\t\twrite(csrs.satp, SATP_MASK);\n\t\t\tif (csrs.satp.fields.mode != SATP_MODE_BARE && csrs.satp.fields.mode != SATP_MODE_SV39 &&\n\t\t\t    csrs.satp.fields.mode != SATP_MODE_SV48)\n\t\t\t\tcsrs.satp.fields.mode = mode;\n\t\t\t// std::cout << \"[iss] satp=\" << boost::format(\"%x\") % csrs.satp.fields.reg << std::endl;\n\t\t} break;\n\n\t\tcase MTVEC_ADDR:\n\t\t\twrite(csrs.mtvec, MTVEC_MASK);\n\t\t\tbreak;\n\t\tcase STVEC_ADDR:\n\t\t\twrite(csrs.stvec, MTVEC_MASK);\n\t\t\tbreak;\n\t\tcase UTVEC_ADDR:\n\t\t\twrite(csrs.utvec, MTVEC_MASK);\n\t\t\tbreak;\n\n\t\tcase MEPC_ADDR:\n\t\t\twrite(csrs.mepc, pc_alignment_mask());\n\t\t\tbreak;\n\t\tcase SEPC_ADDR:\n\t\t\twrite(csrs.sepc, pc_alignment_mask());\n\t\t\tbreak;\n\t\tcase UEPC_ADDR:\n\t\t\twrite(csrs.uepc, pc_alignment_mask());\n\t\t\tbreak;\n\n\t\tcase MSTATUS_ADDR:\n\t\t\twrite(csrs.mstatus, MSTATUS_WRITE_MASK);\n\t\t\tbreak;\n\t\tcase SSTATUS_ADDR:\n\t\t\twrite(csrs.mstatus, SSTATUS_WRITE_MASK);\n\t\t\tbreak;\n\t\tcase USTATUS_ADDR:\n\t\t\twrite(csrs.mstatus, USTATUS_MASK);\n\t\t\tbreak;\n\n\t\tcase MIP_ADDR:\n\t\t\twrite(csrs.mip, MIP_WRITE_MASK);\n\t\t\tbreak;\n\t\tcase SIP_ADDR:\n\t\t\twrite(csrs.mip, SIP_MASK);\n\t\t\tbreak;\n\t\tcase UIP_ADDR:\n\t\t\twrite(csrs.mip, UIP_MASK);\n\t\t\tbreak;\n\n\t\tcase MIE_ADDR:\n\t\t\twrite(csrs.mie, MIE_MASK);\n\t\t\tbreak;\n\t\tcase SIE_ADDR:\n\t\t\twrite(csrs.mie, SIE_MASK);\n\t\t\tbreak;\n\t\tcase UIE_ADDR:\n\t\t\twrite(csrs.mie, UIE_MASK);\n\t\t\tbreak;\n\n\t\tcase MIDELEG_ADDR:\n\t\t\twrite(csrs.mideleg, MIDELEG_MASK);\n\t\t\tbreak;\n\n\t\tcase MEDELEG_ADDR:\n\t\t\twrite(csrs.medeleg, MEDELEG_MASK);\n\t\t\tbreak;\n\n\t\tcase SIDELEG_ADDR:\n\t\t\twrite(csrs.sideleg, SIDELEG_MASK);\n\t\t\tbreak;\n\n\t\tcase SEDELEG_ADDR:\n\t\t\twrite(csrs.sedeleg, SEDELEG_MASK);\n\t\t\tbreak;\n\n\t\tcase MCOUNTEREN_ADDR:\n\t\t\twrite(csrs.mcounteren, MCOUNTEREN_MASK);\n\t\t\tbreak;\n\n\t\tcase SCOUNTEREN_ADDR:\n\t\t\twrite(csrs.scounteren, MCOUNTEREN_MASK);\n\t\t\tbreak;\n\n\t\tcase MCOUNTINHIBIT_ADDR:\n\t\t\twrite(csrs.mcountinhibit, MCOUNTINHIBIT_MASK);\n\t\t\tbreak;\n\n\t\tcase FCSR_ADDR:\n\t\t\twrite(csrs.fcsr, FCSR_MASK);\n\t\t\tbreak;\n\n\t\tcase FFLAGS_ADDR:\n\t\t\tcsrs.fcsr.fields.fflags = value;\n\t\t\tbreak;\n\n\t\tcase FRM_ADDR:\n\t\t\tcsrs.fcsr.fields.frm = value;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tif (!csrs.is_valid_csr64_addr(addr))\n\t\t\t\tRAISE_ILLEGAL_INSTRUCTION();\n\n\t\t\tcsrs.default_write64(addr, value);\n\t}\n}\n\nvoid ISS::init(instr_memory_if *instr_mem, data_memory_if *data_mem, clint_if *clint, uint64_t entrypoint,\n               uint64_t sp) {\n\tthis->instr_mem = instr_mem;\n\tthis->mem = data_mem;\n\tthis->clint = clint;\n\tregs[RegFile::sp] = sp;\n\tpc = entrypoint;\n}\n\nvoid ISS::sys_exit() {\n\tshall_exit = true;\n}\n\nuint64_t ISS::read_register(unsigned idx) {\n\treturn regs.read(idx);\n}\n\nvoid ISS::write_register(unsigned idx, uint64_t value) {\n\tregs.write(idx, value);\n}\n\nuint64_t ISS::get_progam_counter(void) {\n\treturn pc;\n}\n\nvoid ISS::block_on_wfi(bool block) {\n\tignore_wfi = !block;\n}\n\nCoreExecStatus ISS::get_status(void) {\n\treturn status;\n}\n\nvoid ISS::set_status(CoreExecStatus s) {\n\tstatus = s;\n}\n\nvoid ISS::enable_debug(void) {\n\tdebug_mode = true;\n}\n\nvoid ISS::insert_breakpoint(uint64_t addr) {\n\tbreakpoints.insert(addr);\n}\n\nvoid ISS::remove_breakpoint(uint64_t addr) {\n\tbreakpoints.erase(addr);\n}\n\nuint64_t ISS::get_hart_id() {\n\treturn csrs.mhartid.reg;\n}\n\nstd::vector<uint64_t> ISS::get_registers(void) {\n\tstd::vector<uint64_t> regvals;\n\n\tfor (int64_t v : regs.regs)\n\t\tregvals.push_back(v);\n\n\treturn regvals;\n}\n\nvoid ISS::fp_finish_instr() {\n\tfp_set_dirty();\n\tfp_update_exception_flags();\n}\n\nvoid ISS::fp_prepare_instr() {\n\tassert(softfloat_exceptionFlags == 0);\n\tfp_require_not_off();\n}\n\nvoid ISS::fp_set_dirty() {\n\tcsrs.mstatus.fields.sd = 1;\n\tcsrs.mstatus.fields.fs = FS_DIRTY;\n}\n\nvoid ISS::fp_update_exception_flags() {\n\tif (softfloat_exceptionFlags) {\n\t\tfp_set_dirty();\n\t\tcsrs.fcsr.fields.fflags |= softfloat_exceptionFlags;\n\t\tsoftfloat_exceptionFlags = 0;\n\t}\n}\n\nvoid ISS::fp_setup_rm() {\n\tauto rm = instr.frm();\n\tif (rm == FRM_DYN)\n\t\trm = csrs.fcsr.fields.frm;\n\tif (rm >= FRM_RMM)\n\t\tRAISE_ILLEGAL_INSTRUCTION();\n\tsoftfloat_roundingMode = rm;\n}\n\nvoid ISS::fp_require_not_off() {\n\tif (csrs.mstatus.fields.fs == FS_OFF)\n\t\tRAISE_ILLEGAL_INSTRUCTION();\n}\n\nvoid ISS::return_from_trap_handler(PrivilegeLevel return_mode) {\n\tswitch (return_mode) {\n\t\tcase MachineMode:\n\t\t\tprv = csrs.mstatus.fields.mpp;\n\t\t\tcsrs.mstatus.fields.mie = csrs.mstatus.fields.mpie;\n\t\t\tcsrs.mstatus.fields.mpie = 1;\n\t\t\tpc = csrs.mepc.reg;\n\t\t\tif (csrs.misa.has_user_mode_extension())\n\t\t\t\tcsrs.mstatus.fields.mpp = UserMode;\n\t\t\telse\n\t\t\t\tcsrs.mstatus.fields.mpp = MachineMode;\n\t\t\tbreak;\n\n\t\tcase SupervisorMode:\n\t\t\tprv = csrs.mstatus.fields.spp;\n\t\t\tcsrs.mstatus.fields.sie = csrs.mstatus.fields.spie;\n\t\t\tcsrs.mstatus.fields.spie = 1;\n\t\t\tpc = csrs.sepc.reg;\n\t\t\tif (csrs.misa.has_user_mode_extension())\n\t\t\t\tcsrs.mstatus.fields.spp = UserMode;\n\t\t\telse\n\t\t\t\tcsrs.mstatus.fields.spp = SupervisorMode;\n\t\t\tbreak;\n\n\t\tcase UserMode:\n\t\t\tprv = UserMode;\n\t\t\tcsrs.mstatus.fields.uie = csrs.mstatus.fields.upie;\n\t\t\tcsrs.mstatus.fields.upie = 1;\n\t\t\tpc = csrs.uepc.reg;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"unknown privilege level \" + std::to_string(return_mode));\n\t}\n\n\tif (trace)\n\t\tprintf(\"[vp::iss] return from trap handler, time %s, pc %16lx, prv %1x\\n\",\n\t\t       quantum_keeper.get_current_time().to_string().c_str(), pc, prv);\n}\n\nvoid ISS::trigger_external_interrupt(PrivilegeLevel level) {\n\tif (trace)\n\t\tstd::cout << \"[vp::iss] trigger external interrupt, \" << sc_core::sc_time_stamp() << std::endl;\n\n\tswitch (level) {\n\t\tcase UserMode:\n\t\t\tcsrs.mip.fields.ueip = true;\n\t\t\tbreak;\n\t\tcase SupervisorMode:\n\t\t\tcsrs.mip.fields.seip = true;\n\t\t\tbreak;\n\t\tcase MachineMode:\n\t\t\tcsrs.mip.fields.meip = true;\n\t\t\tbreak;\n\t}\n\n\twfi_event.notify(sc_core::SC_ZERO_TIME);\n}\n\nvoid ISS::clear_external_interrupt(PrivilegeLevel level) {\n\tif (trace)\n\t\tstd::cout << \"[vp::iss] clear external interrupt, \" << sc_core::sc_time_stamp() << std::endl;\n\n\tswitch (level) {\n\t\tcase UserMode:\n\t\t\tcsrs.mip.fields.ueip = false;\n\t\t\tbreak;\n\t\tcase SupervisorMode:\n\t\t\tcsrs.mip.fields.seip = false;\n\t\t\tbreak;\n\t\tcase MachineMode:\n\t\t\tcsrs.mip.fields.meip = false;\n\t\t\tbreak;\n\t}\n}\n\nvoid ISS::trigger_timer_interrupt(bool status) {\n\tif (trace)\n\t\tstd::cout << \"[vp::iss] trigger timer interrupt=\" << status << \", \" << sc_core::sc_time_stamp() << std::endl;\n\tcsrs.mip.fields.mtip = status;\n\twfi_event.notify(sc_core::SC_ZERO_TIME);\n}\n\nvoid ISS::trigger_software_interrupt(bool status) {\n\tif (trace)\n\t\tstd::cout << \"[vp::iss] trigger software interrupt=\" << status << \", \" << sc_core::sc_time_stamp() << std::endl;\n\tcsrs.mip.fields.msip = status;\n\twfi_event.notify(sc_core::SC_ZERO_TIME);\n}\n\nPrivilegeLevel ISS::prepare_trap(SimulationTrap &e) {\n\t// undo any potential pc update (for traps the pc should point to the originating instruction and not it's\n\t// successor)\n\tpc = last_pc;\n\tunsigned exc_bit = (1 << e.reason);\n\n\t// 1) machine mode execution takes any traps, independent of delegation setting\n\t// 2) non-delegated traps are processed in machine mode, independent of current execution mode\n\tif (prv == MachineMode || !(exc_bit & csrs.medeleg.reg)) {\n\t\tcsrs.mcause.fields.interrupt = 0;\n\t\tcsrs.mcause.fields.exception_code = e.reason;\n\t\tcsrs.mtval.reg = e.mtval;\n\t\treturn MachineMode;\n\t}\n\n\t// see above machine mode comment\n\tif (prv == SupervisorMode || !(exc_bit & csrs.sedeleg.reg)) {\n\t\tcsrs.scause.fields.interrupt = 0;\n\t\tcsrs.scause.fields.exception_code = e.reason;\n\t\tcsrs.stval.reg = e.mtval;\n\t\treturn SupervisorMode;\n\t}\n\n\tassert(prv == UserMode && (exc_bit & csrs.medeleg.reg) && (exc_bit & csrs.sedeleg.reg));\n\tcsrs.ucause.fields.interrupt = 0;\n\tcsrs.ucause.fields.exception_code = e.reason;\n\tcsrs.utval.reg = e.mtval;\n\treturn UserMode;\n}\n\nvoid ISS::prepare_interrupt(const PendingInterrupts &e) {\n\tif (trace) {\n\t\tstd::cout << \"[vp::iss] prepare interrupt, pending=\" << e.pending << \", target-mode=\" << e.target_mode\n\t\t          << std::endl;\n\t}\n\n\tcsr_mip x{e.pending};\n\n\tExceptionCode exc;\n\tif (x.fields.meip)\n\t\texc = EXC_M_EXTERNAL_INTERRUPT;\n\telse if (x.fields.msip)\n\t\texc = EXC_M_SOFTWARE_INTERRUPT;\n\telse if (x.fields.mtip)\n\t\texc = EXC_M_TIMER_INTERRUPT;\n\telse if (x.fields.seip)\n\t\texc = EXC_S_EXTERNAL_INTERRUPT;\n\telse if (x.fields.ssip)\n\t\texc = EXC_S_SOFTWARE_INTERRUPT;\n\telse if (x.fields.stip)\n\t\texc = EXC_S_TIMER_INTERRUPT;\n\telse if (x.fields.ueip)\n\t\texc = EXC_U_EXTERNAL_INTERRUPT;\n\telse if (x.fields.usip)\n\t\texc = EXC_U_SOFTWARE_INTERRUPT;\n\telse if (x.fields.utip)\n\t\texc = EXC_U_TIMER_INTERRUPT;\n\telse\n\t\tthrow std::runtime_error(\"some pending interrupt must be available here\");\n\n\tswitch (e.target_mode) {\n\t\tcase MachineMode:\n\t\t\tcsrs.mcause.fields.exception_code = exc;\n\t\t\tcsrs.mcause.fields.interrupt = 1;\n\t\t\tbreak;\n\n\t\tcase SupervisorMode:\n\t\t\tcsrs.scause.fields.exception_code = exc;\n\t\t\tcsrs.scause.fields.interrupt = 1;\n\t\t\tbreak;\n\n\t\tcase UserMode:\n\t\t\tcsrs.ucause.fields.exception_code = exc;\n\t\t\tcsrs.ucause.fields.interrupt = 1;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"unknown privilege level \" + std::to_string(e.target_mode));\n\t}\n}\n\nPendingInterrupts ISS::compute_pending_interrupts() {\n\tuint64_t pending = csrs.mie.reg & csrs.mip.reg;\n\n\tif (!pending)\n\t\treturn {NoneMode, 0};\n\n\tauto m_pending = pending & ~csrs.mideleg.reg;\n\tif (m_pending && (prv < MachineMode || (prv == MachineMode && csrs.mstatus.fields.mie))) {\n\t\treturn {MachineMode, m_pending};\n\t}\n\n\tpending = pending & csrs.mideleg.reg;\n\tauto s_pending = pending & ~csrs.sideleg.reg;\n\tif (s_pending && (prv < SupervisorMode || (prv == SupervisorMode && csrs.mstatus.fields.sie))) {\n\t\treturn {SupervisorMode, s_pending};\n\t}\n\n\tauto u_pending = pending & csrs.sideleg.reg;\n\tif (u_pending && (prv == UserMode && csrs.mstatus.fields.uie)) {\n\t\treturn {UserMode, u_pending};\n\t}\n\n\treturn {NoneMode, 0};\n}\n\nvoid ISS::switch_to_trap_handler(PrivilegeLevel target_mode) {\n\tif (trace) {\n\t\tprintf(\"[vp::iss] switch to trap handler, time %s, last_pc %16lx, pc %16lx, irq %u, t-prv %1x\\n\",\n\t\t       quantum_keeper.get_current_time().to_string().c_str(), last_pc, pc, csrs.mcause.fields.interrupt, target_mode);\n\t}\n\n\t// free any potential LR/SC bus lock before processing a trap/interrupt\n\trelease_lr_sc_reservation();\n\n\tauto pp = prv;\n\tprv = target_mode;\n\n\tswitch (target_mode) {\n\t\tcase MachineMode:\n\t\t\tcsrs.mepc.reg = pc;\n\n\t\t\tcsrs.mstatus.fields.mpie = csrs.mstatus.fields.mie;\n\t\t\tcsrs.mstatus.fields.mie = 0;\n\t\t\tcsrs.mstatus.fields.mpp = pp;\n\n\t\t\tpc = csrs.mtvec.get_base_address();\n\n\t\t\tif (csrs.mcause.fields.interrupt && csrs.mtvec.fields.mode == csr_mtvec::Mode::Vectored)\n\t\t\t\tpc += 4 * csrs.mcause.fields.exception_code;\n\t\t\tbreak;\n\n\t\tcase SupervisorMode:\n\t\t\tassert(prv == SupervisorMode || prv == UserMode);\n\n\t\t\tcsrs.sepc.reg = pc;\n\n\t\t\tcsrs.mstatus.fields.spie = csrs.mstatus.fields.sie;\n\t\t\tcsrs.mstatus.fields.sie = 0;\n\t\t\tcsrs.mstatus.fields.spp = pp;\n\n\t\t\tpc = csrs.stvec.get_base_address();\n\n\t\t\tif (csrs.scause.fields.interrupt && csrs.stvec.fields.mode == csr_mtvec::Mode::Vectored)\n\t\t\t\tpc += 4 * csrs.scause.fields.exception_code;\n\t\t\tbreak;\n\n\t\tcase UserMode:\n\t\t\tassert(prv == UserMode);\n\n\t\t\tcsrs.uepc.reg = pc;\n\n\t\t\tcsrs.mstatus.fields.upie = csrs.mstatus.fields.uie;\n\t\t\tcsrs.mstatus.fields.uie = 0;\n\n\t\t\tpc = csrs.utvec.get_base_address();\n\n\t\t\tif (csrs.ucause.fields.interrupt && csrs.utvec.fields.mode == csr_mtvec::Mode::Vectored)\n\t\t\t\tpc += 4 * csrs.ucause.fields.exception_code;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"unknown privilege level \" + std::to_string(target_mode));\n\t}\n}\n\nvoid ISS::performance_and_sync_update(Opcode::Mapping executed_op) {\n\tif (!csrs.mcountinhibit.fields.IR)\n\t\t++csrs.instret.reg;\n\n\tif (lr_sc_counter != 0) {\n\t\t--lr_sc_counter;\n\t\tassert (lr_sc_counter >= 0);\n\t\tif (lr_sc_counter == 0)\n\t\t\trelease_lr_sc_reservation();\n\t}\n\n\tauto new_cycles = instr_cycles[executed_op];\n\n\tif (!csrs.mcountinhibit.fields.CY)\n\t\tcycle_counter += new_cycles;\n\n\tquantum_keeper.inc(new_cycles);\n\tif (quantum_keeper.need_sync()) {\n\t    if (lr_sc_counter == 0) // match SystemC sync with bus unlocking in a tight LR_W/SC_W loop\n\t\t    quantum_keeper.sync();\n\t}\n}\n\nvoid ISS::run_step() {\n\tassert(regs.read(0) == 0);\n\n\t// speeds up the execution performance (non debug mode) significantly by\n\t// checking the additional flag first\n\tif (debug_mode && (breakpoints.find(pc) != breakpoints.end())) {\n\t\tstatus = CoreExecStatus::HitBreakpoint;\n\t\treturn;\n\t}\n\n\tlast_pc = pc;\n\ttry {\n\t\texec_step();\n\n\t\tauto x = compute_pending_interrupts();\n\t\tif (x.target_mode != NoneMode) {\n\t\t\tprepare_interrupt(x);\n\t\t\tswitch_to_trap_handler(x.target_mode);\n\t\t}\n\t} catch (SimulationTrap &e) {\n\t\tif (trace)\n\t\t\tstd::cout << \"take trap \" << e.reason << \", mtval=\" << boost::format(\"%x\") % e.mtval\n\t\t\t          << \", pc=\" << boost::format(\"%x\") % last_pc << std::endl;\n\t\tauto target_mode = prepare_trap(e);\n\t\tswitch_to_trap_handler(target_mode);\n\t}\n\n\t// NOTE: writes to zero register are supposedly allowed but must be ignored\n\t// (reset it after every instruction, instead of checking *rd != zero*\n\t// before every register write)\n\tregs.regs[regs.zero] = 0;\n\n\t// Do not use a check *pc == last_pc* here. The reason is that due to\n\t// interrupts *pc* can be set to *last_pc* accidentally (when jumping back\n\t// to *mepc*).\n\tif (shall_exit)\n\t\tstatus = CoreExecStatus::Terminated;\n\n\tperformance_and_sync_update(op);\n}\n\nvoid ISS::run() {\n\t// run a single step until either a breakpoint is hit or the execution terminates\n\tdo {\n\t\trun_step();\n\t} while (status == CoreExecStatus::Runnable);\n\n\t// force sync to make sure that no action is missed\n\tquantum_keeper.sync();\n}\n\nvoid ISS::show() {\n\tboost::io::ios_flags_saver ifs(std::cout);\n\tstd::cout << \"=[ core : \" << csrs.mhartid.reg << \" ]===========================\" << std::endl;\n\tstd::cout << \"simulation time: \" << sc_core::sc_time_stamp() << std::endl;\n\tregs.show();\n\tstd::cout << \"pc = \" << std::hex << pc << std::endl;\n\tstd::cout << \"num-instr = \" << std::dec << csrs.instret.reg << std::endl;\n}\n"
  },
  {
    "path": "vp/src/core/rv64/iss.h",
    "content": "#pragma once\n\n#include \"core/common/bus_lock_if.h\"\n#include \"core/common/clint_if.h\"\n#include \"core/common/core_defs.h\"\n#include \"core/common/instr.h\"\n#include \"core/common/irq_if.h\"\n#include \"core/common/trap.h\"\n#include \"csr.h\"\n#include \"fp.h\"\n#include \"mem_if.h\"\n#include \"syscall_if.h\"\n#include \"util/common.h\"\n#include \"debug.h\"\n\n#include <assert.h>\n#include <stdint.h>\n#include <string.h>\n\n#include <functional>\n#include <iostream>\n#include <map>\n#include <memory>\n#include <stdexcept>\n#include <unordered_set>\n#include <vector>\n\n#include <tlm_utils/simple_initiator_socket.h>\n#include <tlm_utils/tlm_quantumkeeper.h>\n#include <systemc>\n\nnamespace rv64 {\n\nstruct RegFile {\n\tstatic constexpr unsigned NUM_REGS = 32;\n\n\tint64_t regs[NUM_REGS];\n\n\tRegFile();\n\n\tRegFile(const RegFile &other);\n\n\tvoid write(uint64_t index, int64_t value);\n\n\tint64_t read(uint64_t index);\n\n\tuint64_t shamt_w(uint64_t index);\n\n\tuint64_t shamt(uint64_t index);\n\n\tint64_t &operator[](const uint64_t idx);\n\n\tvoid show();\n\n\tenum e {\n\t\tx0 = 0,\n\t\tx1,\n\t\tx2,\n\t\tx3,\n\t\tx4,\n\t\tx5,\n\t\tx6,\n\t\tx7,\n\t\tx8,\n\t\tx9,\n\t\tx10,\n\t\tx11,\n\t\tx12,\n\t\tx13,\n\t\tx14,\n\t\tx15,\n\t\tx16,\n\t\tx17,\n\t\tx18,\n\t\tx19,\n\t\tx20,\n\t\tx21,\n\t\tx22,\n\t\tx23,\n\t\tx24,\n\t\tx25,\n\t\tx26,\n\t\tx27,\n\t\tx28,\n\t\tx29,\n\t\tx30,\n\t\tx31,\n\n\t\tzero = x0,\n\t\tra = x1,\n\t\tsp = x2,\n\t\tgp = x3,\n\t\ttp = x4,\n\t\tt0 = x5,\n\t\tt1 = x6,\n\t\tt2 = x7,\n\t\ts0 = x8,\n\t\tfp = x8,\n\t\ts1 = x9,\n\t\ta0 = x10,\n\t\ta1 = x11,\n\t\ta2 = x12,\n\t\ta3 = x13,\n\t\ta4 = x14,\n\t\ta5 = x15,\n\t\ta6 = x16,\n\t\ta7 = x17,\n\t\ts2 = x18,\n\t\ts3 = x19,\n\t\ts4 = x20,\n\t\ts5 = x21,\n\t\ts6 = x22,\n\t\ts7 = x23,\n\t\ts8 = x24,\n\t\ts9 = x25,\n\t\ts10 = x26,\n\t\ts11 = x27,\n\t\tt3 = x28,\n\t\tt4 = x29,\n\t\tt5 = x30,\n\t\tt6 = x31,\n\t};\n};\n\n// NOTE: on this branch, currently the *simple-timing* model is still directly\n// integrated in the ISS. Merge the *timedb* branch to use the timing_if.\nstruct ISS;\n\nstruct timing_if {\n\tvirtual ~timing_if() {}\n\n\tvirtual void update_timing(Instruction instr, Opcode::Mapping op, ISS &iss) = 0;\n};\n\nstruct PendingInterrupts {\n\tPrivilegeLevel target_mode;\n\tuint64_t pending;\n};\n\nstruct ISS : public external_interrupt_target, public clint_interrupt_target, public debug_target_if, public iss_syscall_if {\n\tclint_if *clint = nullptr;\n\tinstr_memory_if *instr_mem = nullptr;\n\tdata_memory_if *mem = nullptr;\n\tsyscall_emulator_if *sys = nullptr;  // optional, if provided, the iss will intercept and handle syscalls directly\n\tRegFile regs;\n\tFpRegs fp_regs;\n\tuint64_t pc = 0;\n\tuint64_t last_pc = 0;\n\tbool trace = false;\n\tbool shall_exit = false;\n\tbool ignore_wfi = false;\n\tcsr_table csrs;\n\tPrivilegeLevel prv = MachineMode;\n\tint64_t lr_sc_counter = 0;\n\n\t// last decoded and executed instruction and opcode\n\tInstruction instr;\n\tOpcode::Mapping op;\n\n\tCoreExecStatus status = CoreExecStatus::Runnable;\n\tstd::unordered_set<uint64_t> breakpoints;\n\tbool debug_mode = false;\n\n\tsc_core::sc_event wfi_event;\n\n\tstd::string systemc_name;\n\ttlm_utils::tlm_quantumkeeper quantum_keeper;\n\tsc_core::sc_time cycle_time;\n\tsc_core::sc_time cycle_counter;  // use a separate cycle counter, since cycle count can be inhibited\n\tstd::array<sc_core::sc_time, Opcode::NUMBER_OF_INSTRUCTIONS> instr_cycles;\n\n\tstatic constexpr int64_t REG_MIN = INT64_MIN;\n\tstatic constexpr int64_t REG32_MIN = INT32_MIN;\n\tstatic constexpr unsigned xlen = 64;\n\n\tISS(uint64_t hart_id);\n\n\tArchitecture get_architecture(void) override {\n\t\treturn RV64;\n\t}\n\n\tuint64_t get_progam_counter(void) override;\n\tvoid enable_debug(void) override;\n\tCoreExecStatus get_status(void) override;\n\tvoid set_status(CoreExecStatus) override;\n\tvoid block_on_wfi(bool) override;\n\n\tvoid insert_breakpoint(uint64_t) override;\n\tvoid remove_breakpoint(uint64_t) override;\n\n\tvoid exec_step();\n\n\tuint64_t _compute_and_get_current_cycles();\n\n\tvoid init(instr_memory_if *instr_mem, data_memory_if *data_mem, clint_if *clint, uint64_t entrypoint, uint64_t sp);\n\n\tvoid trigger_external_interrupt(PrivilegeLevel level) override;\n\n\tvoid clear_external_interrupt(PrivilegeLevel level) override;\n\n\tvoid trigger_timer_interrupt(bool status) override;\n\n\tvoid trigger_software_interrupt(bool status) override;\n\n\tvoid sys_exit() override;\n\n\tuint64_t read_register(unsigned idx) override;\n\n\tvoid write_register(unsigned idx, uint64_t value) override;\n\n\tuint64_t get_hart_id() override;\n\n\tstd::vector<uint64_t> get_registers(void) override;\n\n\tvoid release_lr_sc_reservation() {\n\t\tlr_sc_counter = 0;\n\t\tmem->atomic_unlock();\n\t}\n\n\tvoid fp_prepare_instr();\n\tvoid fp_finish_instr();\n\tvoid fp_set_dirty();\n\tvoid fp_update_exception_flags();\n\tvoid fp_setup_rm();\n\tvoid fp_require_not_off();\n\n\tuint64_t get_csr_value(uint64_t addr);\n\n\tvoid set_csr_value(uint64_t addr, uint64_t value);\n\n\tinline bool is_invalid_csr_access(uint64_t csr_addr, bool is_write) {\n\t\tPrivilegeLevel csr_prv = (0x300 & csr_addr) >> 8;\n\t\tbool csr_readonly = ((0xC00 & csr_addr) >> 10) == 3;\n\t\treturn (is_write && csr_readonly) || (prv < csr_prv);\n\t}\n\n\tvoid validate_csr_counter_read_access_rights(uint64_t addr);\n\n\tuint64_t pc_alignment_mask() {\n\t\tif (csrs.misa.has_C_extension())\n\t\t\treturn ~uint64_t(0x1);\n\t\telse\n\t\t\treturn ~uint64_t(0x3);\n\t}\n\n\tinline void trap_check_pc_alignment() {\n\t\tassert(!(pc & 0x1) && \"not possible due to immediate formats and jump execution\");\n\n\t\tif (unlikely((pc & 0x3) && (!csrs.misa.has_C_extension()))) {\n\t\t\t// NOTE: misaligned instruction address not possible on machines supporting compressed instructions\n\t\t\traise_trap(EXC_INSTR_ADDR_MISALIGNED, pc);\n\t\t}\n\t}\n\n\ttemplate <unsigned Alignment, bool isLoad>\n\tinline void trap_check_addr_alignment(uint64_t addr) {\n\t\tif (unlikely(addr % Alignment)) {\n\t\t\traise_trap(isLoad ? EXC_LOAD_ADDR_MISALIGNED : EXC_STORE_AMO_ADDR_MISALIGNED, addr);\n\t\t}\n\t}\n\n\tinline void execute_amo_w(Instruction &instr, std::function<int32_t(int32_t, int32_t)> operation) {\n\t\tuint64_t addr = regs[instr.rs1()];\n\t\ttrap_check_addr_alignment<4, false>(addr);\n\t\tint32_t data;\n\t\ttry {\n\t\t\tdata = mem->atomic_load_word(addr);\n\t\t} catch (SimulationTrap &e) {\n\t\t\tif (e.reason == EXC_LOAD_ACCESS_FAULT)\n\t\t\t\te.reason = EXC_STORE_AMO_ACCESS_FAULT;\n\t\t\tthrow e;\n\t\t}\n\t\tint32_t val = operation(data, (int32_t)regs[instr.rs2()]);\n\t\tmem->atomic_store_word(addr, val);\n\t\tregs[instr.rd()] = data;\n\t}\n\n\tinline void execute_amo_d(Instruction &instr, std::function<int64_t(int64_t, int64_t)> operation) {\n\t\tuint64_t addr = regs[instr.rs1()];\n\t\ttrap_check_addr_alignment<8, false>(addr);\n\t\tuint64_t data;\n\t\ttry {\n\t\t\tdata = mem->atomic_load_double(addr);\n\t\t} catch (SimulationTrap &e) {\n\t\t\tif (e.reason == EXC_LOAD_ACCESS_FAULT)\n\t\t\t\te.reason = EXC_STORE_AMO_ACCESS_FAULT;\n\t\t\tthrow e;\n\t\t}\n\t\tuint64_t val = operation(data, regs[instr.rs2()]);\n\t\tmem->atomic_store_double(addr, val);\n\t\tregs[instr.rd()] = data;\n\t}\n\n\tinline bool m_mode() {\n\t\treturn prv == MachineMode;\n\t}\n\n\tinline bool s_mode() {\n\t\treturn prv == SupervisorMode;\n\t}\n\n\tinline bool u_mode() {\n\t\treturn prv == UserMode;\n\t}\n\n\tPrivilegeLevel prepare_trap(SimulationTrap &e);\n\n\tvoid prepare_interrupt(const PendingInterrupts &x);\n\n\tPendingInterrupts compute_pending_interrupts();\n\n\tbool has_pending_enabled_interrupts() {\n\t\treturn compute_pending_interrupts().target_mode != NoneMode;\n\t}\n\n\tbool has_local_pending_enabled_interrupts() {\n\t\treturn csrs.mie.reg & csrs.mip.reg;\n\t}\n\n\tvoid return_from_trap_handler(PrivilegeLevel return_mode);\n\n\tvoid switch_to_trap_handler(PrivilegeLevel target_mode);\n\n\tvoid performance_and_sync_update(Opcode::Mapping executed_op);\n\n\tvoid run_step() override;\n\n\tvoid run() override;\n\n\tvoid show();\n};\n\n/* Do not call the run function of the ISS directly but use one of the Runner\n * wrappers. */\nstruct DirectCoreRunner : public sc_core::sc_module {\n\tISS &core;\n\tstd::string thread_name;\n\n\tSC_HAS_PROCESS(DirectCoreRunner);\n\n\tDirectCoreRunner(ISS &core) : sc_module(sc_core::sc_module_name(core.systemc_name.c_str())), core(core) {\n\t\tthread_name = \"run\" + std::to_string(core.get_hart_id());\n\t\tSC_NAMED_THREAD(run, thread_name.c_str());\n\t}\n\n\tvoid run() {\n\t\tcore.run();\n\n\t\tif (core.status == CoreExecStatus::HitBreakpoint) {\n\t\t\tthrow std::runtime_error(\n\t\t\t    \"Breakpoints are not supported in the direct runner, use the debug \"\n\t\t\t    \"runner instead.\");\n\t\t}\n\t\tassert(core.status == CoreExecStatus::Terminated);\n\n\t\tsc_core::sc_stop();\n\t}\n};\n\n}  // namespace rv64\n"
  },
  {
    "path": "vp/src/core/rv64/mem.h",
    "content": "#pragma once\n\n#include \"core/common/dmi.h\"\n#include \"iss.h\"\n#include \"mmu.h\"\n\nnamespace rv64 {\n\n/* For optimization, use DMI to fetch instructions */\nstruct InstrMemoryProxy : public instr_memory_if {\n\tMemoryDMI dmi;\n\n\tISS &core;\n\ttlm_utils::tlm_quantumkeeper &quantum_keeper;\n\tsc_core::sc_time clock_cycle = sc_core::sc_time(10, sc_core::SC_NS);\n\tsc_core::sc_time access_delay = clock_cycle * 2;\n\n\tInstrMemoryProxy(const MemoryDMI &dmi, ISS &owner) : dmi(dmi), core(owner), quantum_keeper(owner.quantum_keeper) {}\n\n\tvirtual uint32_t load_instr(uint64_t pc) override {\n\t\tassert((core.csrs.satp.fields.mode == SATP_MODE_BARE) && \"InstrMemoryProxy does not support virtual memory\");\n\t\tquantum_keeper.inc(access_delay);\n\t\treturn *(dmi.get_mem_ptr_to_global_addr<uint32_t>(pc));\n\t}\n};\n\nstruct CombinedMemoryInterface : public sc_core::sc_module,\n                                 public instr_memory_if,\n                                 public data_memory_if,\n                                 public mmu_memory_if {\n\tISS &iss;\n\tstd::shared_ptr<bus_lock_if> bus_lock;\n\tuint64_t lr_addr = 0;\n\n\ttlm_utils::simple_initiator_socket<CombinedMemoryInterface> isock;\n\ttlm_utils::tlm_quantumkeeper &quantum_keeper;\n\n\t// optionally add DMI ranges for optimization\n\tsc_core::sc_time clock_cycle = sc_core::sc_time(10, sc_core::SC_NS);\n\tsc_core::sc_time dmi_access_delay = clock_cycle * 4;\n\tstd::vector<MemoryDMI> dmi_ranges;\n\n\tMMU &mmu;\n\n\tCombinedMemoryInterface(sc_core::sc_module_name, ISS &owner, MMU &mmu)\n\t    : iss(owner), quantum_keeper(iss.quantum_keeper), mmu(mmu) {}\n\n\tuint64_t v2p(uint64_t vaddr, MemoryAccessType type) override {\n\t\treturn mmu.translate_virtual_to_physical_addr(vaddr, type);\n\t}\n\n\tinline void _do_transaction(tlm::tlm_command cmd, uint64_t addr, uint8_t *data, unsigned num_bytes) {\n\t\ttlm::tlm_generic_payload trans;\n\t\ttrans.set_command(cmd);\n\t\ttrans.set_address(addr);\n\t\ttrans.set_data_ptr(data);\n\t\ttrans.set_data_length(num_bytes);\n\t\ttrans.set_response_status(tlm::TLM_OK_RESPONSE);\n\n\t\tsc_core::sc_time local_delay = quantum_keeper.get_local_time();\n\n\t\tisock->b_transport(trans, local_delay);\n\n\t\tassert(local_delay >= quantum_keeper.get_local_time());\n\t\tquantum_keeper.set(local_delay);\n\n\t\tif (trans.is_response_error()) {\n\t\t\tif (iss.trace)\n\t\t\t\tstd::cout << \"WARNING: core memory transaction failed for address 0x\" << std::hex << addr << std::dec << \" -> raise trap\" << std::endl;\n\t\t\tif (cmd == tlm::TLM_READ_COMMAND)\n\t\t\t\traise_trap(EXC_LOAD_PAGE_FAULT, addr);\n\t\t\telse if (cmd == tlm::TLM_WRITE_COMMAND)\n\t\t\t\traise_trap(EXC_STORE_AMO_PAGE_FAULT, addr);\n\t\t\telse\n\t\t\t\tthrow std::runtime_error(\"TLM command must be read or write\");\n\t\t}\n\t}\n\n\ttemplate <typename T>\n\tinline T _raw_load_data(uint64_t addr) {\n\t\t// NOTE: a DMI load will not context switch (SystemC) and not modify the memory, hence should be able to\n\t\t// postpone the lock after the dmi access\n\t\tbus_lock->wait_for_access_rights(iss.get_hart_id());\n\n\t\tfor (auto &e : dmi_ranges) {\n\t\t\tif (e.contains(addr)) {\n\t\t\t\tquantum_keeper.inc(dmi_access_delay);\n\n\t\t\t\tT ans = *(e.get_mem_ptr_to_global_addr<T>(addr));\n\t\t\t\treturn ans;\n\t\t\t}\n\t\t}\n\n\t\tT ans;\n\t\t_do_transaction(tlm::TLM_READ_COMMAND, addr, (uint8_t *)&ans, sizeof(T));\n\t\treturn ans;\n\t}\n\n\ttemplate <typename T>\n\tinline void _raw_store_data(uint64_t addr, T value) {\n\t\tbus_lock->wait_for_access_rights(iss.get_hart_id());\n\n\t\tbool done = false;\n\t\tfor (auto &e : dmi_ranges) {\n\t\t\tif (e.contains(addr)) {\n\t\t\t\tquantum_keeper.inc(dmi_access_delay);\n\n\t\t\t\t*(e.get_mem_ptr_to_global_addr<T>(addr)) = value;\n\t\t\t\tdone = true;\n\t\t\t}\n\t\t}\n\n\t\tif (!done)\n\t\t\t_do_transaction(tlm::TLM_WRITE_COMMAND, addr, (uint8_t *)&value, sizeof(T));\n\t\tatomic_unlock();\n\t}\n\n\ttemplate <typename T>\n\tinline T _load_data(uint64_t addr) {\n\t\treturn _raw_load_data<T>(v2p(addr, LOAD));\n\t}\n\n\ttemplate <typename T>\n\tinline void _store_data(uint64_t addr, T value) {\n\t\t_raw_store_data(v2p(addr, STORE), value);\n\t}\n\n\tuint64_t mmu_load_pte64(uint64_t addr) override {\n\t\treturn _raw_load_data<uint64_t>(addr);\n\t}\n\tuint64_t mmu_load_pte32(uint64_t addr) override {\n\t\treturn _raw_load_data<uint32_t>(addr);\n\t}\n\tvoid mmu_store_pte32(uint64_t addr, uint32_t value) override {\n\t\t_raw_store_data(addr, value);\n\t}\n\n\tvoid flush_tlb() override {\n\t\tmmu.flush_tlb();\n\t}\n\n\tuint32_t load_instr(uint64_t addr) override {\n\t\treturn _raw_load_data<uint32_t>(v2p(addr, FETCH));\n\t}\n\n\ttemplate <typename T>\n\tT _atomic_load_data(uint64_t addr) {\n\t\tbus_lock->lock(iss.get_hart_id());\n\t\treturn _load_data<T>(addr);\n\t}\n\ttemplate <typename T>\n\tvoid _atomic_store_data(uint64_t addr, T value) {\n\t\tassert(bus_lock->is_locked(iss.get_hart_id()));\n\t\t_store_data(addr, value);\n\t}\n\ttemplate <typename T>\n\tT _atomic_load_reserved_data(uint64_t addr) {\n\t\tbus_lock->lock(iss.get_hart_id());\n\t\tlr_addr = addr;\n\t\treturn _load_data<T>(addr);\n\t}\n\ttemplate <typename T>\n\tbool _atomic_store_conditional_data(uint64_t addr, T value) {\n\t\t/* According to the RISC-V ISA, an implementation can fail each LR/SC sequence that does not satisfy the forward\n\t\t * progress semantic.\n\t\t * The lock is established by the LR instruction and the lock is kept while forward progress is maintained. */\n\t\tif (bus_lock->is_locked(iss.get_hart_id())) {\n\t\t\tif (addr == lr_addr) {\n\t\t\t\t_store_data(addr, value);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tatomic_unlock();\n\t\t}\n\t\treturn false;\n\t}\n\n\tint64_t load_double(uint64_t addr) override {\n\t\treturn _load_data<int64_t>(addr);\n\t}\n\tint64_t load_word(uint64_t addr) override {\n\t\treturn _load_data<int32_t>(addr);\n\t}\n\tint64_t load_half(uint64_t addr) override {\n\t\treturn _load_data<int16_t>(addr);\n\t}\n\tint64_t load_byte(uint64_t addr) override {\n\t\treturn _load_data<int8_t>(addr);\n\t}\n\tuint64_t load_uword(uint64_t addr) override {\n\t\treturn _load_data<uint32_t>(addr);\n\t}\n\tuint64_t load_uhalf(uint64_t addr) override {\n\t\treturn _load_data<uint16_t>(addr);\n\t}\n\tuint64_t load_ubyte(uint64_t addr) override {\n\t\treturn _load_data<uint8_t>(addr);\n\t}\n\n\tvoid store_double(uint64_t addr, uint64_t value) override {\n\t\t_store_data(addr, value);\n\t}\n\tvoid store_word(uint64_t addr, uint32_t value) override {\n\t\t_store_data(addr, value);\n\t}\n\tvoid store_half(uint64_t addr, uint16_t value) override {\n\t\t_store_data(addr, value);\n\t}\n\tvoid store_byte(uint64_t addr, uint8_t value) override {\n\t\t_store_data(addr, value);\n\t}\n\n\tint64_t atomic_load_word(uint64_t addr) override {\n\t\treturn _atomic_load_data<int32_t>(addr);\n\t}\n\tvoid atomic_store_word(uint64_t addr, uint32_t value) override {\n\t\t_atomic_store_data(addr, value);\n\t}\n\tint64_t atomic_load_reserved_word(uint64_t addr) override {\n\t\treturn _atomic_load_reserved_data<int32_t>(addr);\n\t}\n\tbool atomic_store_conditional_word(uint64_t addr, uint32_t value) override {\n\t\treturn _atomic_store_conditional_data(addr, value);\n\t}\n\n\tint64_t atomic_load_double(uint64_t addr) override {\n\t\treturn _atomic_load_data<int64_t>(addr);\n\t}\n\tvoid atomic_store_double(uint64_t addr, uint64_t value) override {\n\t\t_atomic_store_data(addr, value);\n\t}\n\tint64_t atomic_load_reserved_double(uint64_t addr) override {\n\t\treturn _atomic_load_reserved_data<int64_t>(addr);\n\t}\n\tbool atomic_store_conditional_double(uint64_t addr, uint64_t value) override {\n\t\treturn _atomic_store_conditional_data(addr, value);\n\t}\n\n\tvoid atomic_unlock() override {\n\t\tbus_lock->unlock(iss.get_hart_id());\n\t}\n};\n\n}  // namespace rv64\n"
  },
  {
    "path": "vp/src/core/rv64/mem_if.h",
    "content": "#pragma once\n\n#include <stdint.h>\n\nnamespace rv64 {\n\nstruct instr_memory_if {\n\tvirtual ~instr_memory_if() {}\n\n\tvirtual uint32_t load_instr(uint64_t pc) = 0;\n};\n\nstruct data_memory_if {\n\tvirtual ~data_memory_if() {}\n\n\tvirtual int64_t load_double(uint64_t addr) = 0;\n\tvirtual int64_t load_word(uint64_t addr) = 0;\n\tvirtual int64_t load_half(uint64_t addr) = 0;\n\tvirtual int64_t load_byte(uint64_t addr) = 0;\n\tvirtual uint64_t load_uword(uint64_t addr) = 0;\n\tvirtual uint64_t load_uhalf(uint64_t addr) = 0;\n\tvirtual uint64_t load_ubyte(uint64_t addr) = 0;\n\n\tvirtual void store_double(uint64_t addr, uint64_t value) = 0;\n\tvirtual void store_word(uint64_t addr, uint32_t value) = 0;\n\tvirtual void store_half(uint64_t addr, uint16_t value) = 0;\n\tvirtual void store_byte(uint64_t addr, uint8_t value) = 0;\n\n\tvirtual int64_t atomic_load_word(uint64_t addr) = 0;\n\tvirtual void atomic_store_word(uint64_t addr, uint32_t value) = 0;\n\tvirtual int64_t atomic_load_reserved_word(uint64_t addr) = 0;\n\tvirtual bool atomic_store_conditional_word(uint64_t addr, uint32_t value) = 0;\n\tvirtual void atomic_unlock() = 0;\n\n\tvirtual int64_t atomic_load_double(uint64_t addr) = 0;\n\tvirtual void atomic_store_double(uint64_t addr, uint64_t value) = 0;\n\tvirtual int64_t atomic_load_reserved_double(uint64_t addr) = 0;\n\tvirtual bool atomic_store_conditional_double(uint64_t addr, uint64_t value) = 0;\n\n\tvirtual void flush_tlb() = 0;\n};\n\n}  // namespace rv64"
  },
  {
    "path": "vp/src/core/rv64/mmu.h",
    "content": "#pragma once\n\n#include \"iss.h\"\n#include \"core/common/mmu.h\"\n\nnamespace rv64 {\n\n    typedef GenericMMU<ISS> MMU;\n\n}  // namespace rv64"
  },
  {
    "path": "vp/src/core/rv64/syscall.cpp",
    "content": "#include \"syscall.h\"\n\n#include <assert.h>\n#include <sys/stat.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include <iostream>\n#include <stdexcept>\n\n#include <boost/lexical_cast.hpp>\n\nusing namespace rv64;\n\n// see: riscv-gnu-toolchain/riscv-newlib/libgloss/riscv/\n// for syscall implementation in the risc-v C lib (many are ignored and just return -1)\n\ntypedef int64_t rv64_long;\n\ntypedef int64_t rv64_time_t;\n\nstruct rv64_timeval {\n\trv64_time_t tv_sec;\n\trv64_time_t tv_usec;\n};\n\nstruct rv64_timespec {\n\trv64_time_t tv_sec;\n\trv64_time_t tv_nsec;\n};\n\nstruct rv64_stat {\n\tuint64_t st_dev;\n\tuint64_t st_ino;\n\tuint32_t st_mode;\n\tuint32_t st_nlink;\n\tuint32_t st_uid;\n\tuint32_t st_gid;\n\tuint64_t st_rdev;\n\tuint64_t __pad1;\n\tint64_t st_size;\n\tint32_t st_blksize;\n\tint32_t __pad2;\n\tint64_t st_blocks;\n\trv64_timespec st_atim;\n\trv64_timespec st_mtim;\n\trv64_timespec st_ctim;\n\tint32_t __glibc_reserved[2];\n};\n\nvoid _copy_timespec(rv64_timespec *dst, timespec *src) {\n\tdst->tv_sec = src->tv_sec;\n\tdst->tv_nsec = src->tv_nsec;\n}\n\nint sys_fstat(SyscallHandler *sys, int fd, rv64_stat *s_addr) {\n\tstruct stat x;\n\tint ans = fstat(fd, &x);\n\tif (ans == 0) {\n\t\trv64_stat *p = (rv64_stat *)sys->guest_to_host_pointer(s_addr);\n\t\tp->st_dev = x.st_dev;\n\t\tp->st_ino = x.st_ino;\n\t\tp->st_mode = x.st_mode;\n\t\tp->st_nlink = x.st_nlink;\n\t\tp->st_uid = x.st_uid;\n\t\tp->st_gid = x.st_gid;\n\t\tp->st_rdev = x.st_rdev;\n\t\tp->st_size = x.st_size;\n\t\tp->st_blksize = x.st_blksize;\n\t\tp->st_blocks = x.st_blocks;\n\t\t_copy_timespec(&p->st_atim, &x.st_atim);\n\t\t_copy_timespec(&p->st_mtim, &x.st_mtim);\n\t\t_copy_timespec(&p->st_ctim, &x.st_ctim);\n\t}\n\treturn ans;\n}\n\nint sys_gettimeofday(SyscallHandler *sys, rv64_timeval *tp, void *tzp) {\n\t/*\n\t * timeval is using a struct with two long arguments.\n\t * The second argument tzp currently is not used by riscv code.\n\t */\n\tassert(tzp == 0);\n\n\tstruct timeval x;\n\tint ans = gettimeofday(&x, 0);\n\n\trv64_long *p = (rv64_long *)sys->guest_to_host_pointer(tp);\n\tp[0] = x.tv_sec;\n\tp[1] = x.tv_usec;\n\treturn ans;\n}\n\nint sys_time(SyscallHandler *sys, rv64_time_t *tloc) {\n\ttime_t host_ans = time(0);\n\n\trv64_time_t guest_ans = boost::lexical_cast<rv64_time_t>(host_ans);\n\n\tif (tloc != 0) {\n\t\trv64_time_t *p = (rv64_time_t *)sys->guest_to_host_pointer(tloc);\n\t\t*p = guest_ans;\n\t}\n\n\treturn boost::lexical_cast<int>(guest_ans);\n}\n\nnamespace rv_sc {\n// see: riscv-gnu-toolchain/riscv/riscv32-unknown-elf/include/sys/_default_fcntl.h\nconstexpr uint32_t RDONLY = 0x0000; /* +1 == FREAD */\nconstexpr uint32_t WRONLY = 0x0001; /* +1 == FWRITE */\nconstexpr uint32_t RDWR = 0x0002;   /* +1 == FREAD|FWRITE */\nconstexpr uint32_t APPEND = 0x0008;\nconstexpr uint32_t CREAT = 0x0200;\nconstexpr uint32_t TRUNC = 0x0400;\n}  // namespace rv_sc\n\nint translateRVFlagsToHost(const int flags) {\n\tint ret = 0;\n\tret |= flags & rv_sc::RDONLY ? O_RDONLY : 0;\n\tret |= flags & rv_sc::WRONLY ? O_WRONLY : 0;\n\tret |= flags & rv_sc::RDWR ? O_RDWR : 0;\n\tret |= flags & rv_sc::APPEND ? O_APPEND : 0;\n\tret |= flags & rv_sc::CREAT ? O_CREAT : 0;\n\tret |= flags & rv_sc::TRUNC ? O_TRUNC : 0;\n\n\tif (ret == 0 && flags != 0) {\n\t\tthrow std::runtime_error(\"unsupported flag\");\n\t}\n\n\treturn ret;\n}\n\nint sys_brk(SyscallHandler *sys, void *addr) {\n\tif (addr == 0) {\n\t\t// riscv newlib expects brk to return current heap address when zero is passed in\n\t\treturn boost::lexical_cast<int>(sys->hp);\n\t} else {\n\t\t// NOTE: can also shrink again\n\t\tauto n = (uintptr_t)addr;\n\t\tsys->hp = n;\n\n\t\tif (sys->hp > sys->max_heap)\n\t\t\tsys->max_heap = sys->hp;\n\n\t\t// same for brk increase/decrease\n\t\treturn boost::lexical_cast<int>(n);\n\t}\n}\n\nint sys_write(SyscallHandler *sys, int fd, const void *buf, size_t count) {\n\tconst char *p = (const char *)sys->guest_to_host_pointer((void *)buf);\n\n\tauto ans = write(fd, p, count);\n\n\tif (ans < 0) {\n\t\tstd::cout << \"WARNING [sys-write error]: \" << strerror(errno) << std::endl;\n\t\tstd::cout << \"  fd = \" << fd << std::endl;\n\t\tstd::cout << \"  count = \" << count << std::endl;\n\t\tassert(false);\n\t}\n\n\treturn ans;\n}\n\nint sys_read(SyscallHandler *sys, int fd, void *buf, size_t count) {\n\tchar *p = (char *)sys->guest_to_host_pointer(buf);\n\n\tauto ans = read(fd, p, count);\n\n\tassert(ans >= 0);\n\n\treturn ans;\n}\n\nint sys_lseek(int fd, off_t offset, int whence) {\n\tauto ans = lseek(fd, offset, whence);\n\n\treturn ans;\n}\n\nint sys_open(SyscallHandler *sys, const char *pathname, int flags, mode_t mode) {\n\tconst char *host_pathname = (char *)sys->guest_to_host_pointer((void *)pathname);\n\n\tauto ans = open(host_pathname, translateRVFlagsToHost(flags), mode);\n\n\tstd::cout << \"[sys_open] \" << host_pathname << \", \" << flags << \" (translated to \" << translateRVFlagsToHost(flags)\n\t          << \"), \" << mode << std::endl;\n\n\treturn ans;\n}\n\nint sys_close(int fd) {\n\tif (fd == STDOUT_FILENO || fd == STDIN_FILENO || fd == STDERR_FILENO) {\n\t\t// ignore closing of std streams, just return success\n\t\treturn 0;\n\t} else {\n\t\treturn close(fd);\n\t}\n}\n\n// TODO: add support for additional syscalls if necessary\nint SyscallHandler::execute_syscall(uint64_t n, uint64_t _a0, uint64_t _a1, uint64_t _a2, uint64_t) {\n\t// NOTE: when linking with CRT, the most basic example only calls *gettimeofday* and finally *exit*\n\n\tswitch (n) {\n\t\tcase SYS_fstat:\n\t\t\treturn sys_fstat(this, _a0, (rv64_stat *)_a1);\n\n\t\tcase SYS_gettimeofday:\n\t\t\treturn sys_gettimeofday(this, (rv64_timeval *)_a0, (void *)_a1);\n\n\t\tcase SYS_brk:\n\t\t\treturn sys_brk(this, (void *)_a0);\n\n\t\tcase SYS_time:\n\t\t\treturn sys_time(this, (rv64_time_t *)_a0);\n\n\t\tcase SYS_write:\n\t\t\treturn sys_write(this, _a0, (void *)_a1, _a2);\n\n\t\tcase SYS_read:\n\t\t\treturn sys_read(this, _a0, (void *)_a1, _a2);\n\n\t\tcase SYS_lseek:\n\t\t\treturn sys_lseek(_a0, _a1, _a2);\n\n\t\tcase SYS_open:\n\t\t\treturn sys_open(this, (const char *)_a0, _a1, _a2);\n\n\t\tcase SYS_close:\n\t\t\treturn sys_close(_a0);\n\n\t\tcase SYS_exit:\n\t\t\t// If the software requested a non-zero exit code then terminate directly.\n\t\t\t// Otherwise, stop the SystemC simulation and exit with a zero exit code.\n\t\t\tif (_a0) exit(_a0);\n\n\t\t\tshall_exit = true;\n\t\t\treturn 0;\n\n\t\tcase SYS_host_error:\n\t\t\tthrow std::runtime_error(\"SYS_host_error\");\n\n\t\tcase SYS_host_test_pass:\n\t\t\tstd::cout << \"TEST_PASS\" << std::endl;\n\t\t\tshall_exit = true;\n\t\t\treturn 0;\n\n\t\tcase SYS_host_test_fail:\n\t\t\tstd::cout << \"TEST_FAIL (testnum = \" << _a0 << \")\" << std::endl;\n\t\t\tshall_exit = true;\n\t\t\treturn 0;\n\t}\n\n\tstd::cerr << \"unsupported syscall '\" << n << \"'\" << std::endl;\n\tthrow std::runtime_error(\"unsupported syscall '\" + std::to_string(n) + \"'\");\n}\n"
  },
  {
    "path": "vp/src/core/rv64/syscall.h",
    "content": "#pragma once\n\n#include <assert.h>\n#include <fcntl.h>\n#include <stdint.h>\n\n// see: newlib/libgloss/riscv @\n// https://github.com/riscv/riscv-newlib/tree/riscv-newlib-2.5.0/libgloss/riscv\n\n#define SYS_exit 93\n#define SYS_exit_group 94\n#define SYS_getpid 172\n#define SYS_kill 129\n#define SYS_read 63\n#define SYS_write 64\n#define SYS_open 1024\n#define SYS_openat 56\n#define SYS_close 57\n#define SYS_lseek 62\n#define SYS_brk 214\n#define SYS_link 1025\n#define SYS_unlink 1026\n#define SYS_mkdir 1030\n#define SYS_chdir 49\n#define SYS_getcwd 17\n#define SYS_stat 1038\n#define SYS_fstat 80\n#define SYS_lstat 1039\n#define SYS_fstatat 79\n#define SYS_access 1033\n#define SYS_faccessat 48\n#define SYS_pread 67\n#define SYS_pwrite 68\n#define SYS_uname 160\n#define SYS_getuid 174\n#define SYS_geteuid 175\n#define SYS_getgid 176\n#define SYS_getegid 177\n#define SYS_mmap 222\n#define SYS_munmap 215\n#define SYS_mremap 216\n#define SYS_time 1062\n#define SYS_getmainvars 2011\n#define SYS_rt_sigaction 134\n#define SYS_writev 66\n#define SYS_gettimeofday 169\n#define SYS_times 153\n#define SYS_fcntl 25\n#define SYS_getdents 61\n#define SYS_dup 23\n\n// custom extensions\n#define SYS_host_error \\\n\t1  // indicate an error, i.e. this instruction should never be reached so something went wrong during exec.\n#define SYS_host_test_pass 2  // RISC-V test execution successfully completed\n#define SYS_host_test_fail 3  // RISC-V test execution failed\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n\n#include \"iss.h\"\n#include \"syscall_if.h\"\n\nnamespace rv64 {\n\nstruct SyscallHandler : public sc_core::sc_module, syscall_emulator_if {\n\ttlm_utils::simple_target_socket<SyscallHandler> tsock;\n\tstd::unordered_map<uint32_t, iss_syscall_if *> cores;\n\n\tvoid register_core(ISS *core) {\n\t\tassert(cores.find(core->get_hart_id()) == cores.end());\n\t\tcores[core->get_hart_id()] = core;\n\t}\n\n\tSyscallHandler(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &SyscallHandler::transport);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\t(void)delay;\n\n\t\tauto addr = trans.get_address();\n\t\tassert(addr % 4 == 0);\n\t\tassert(trans.get_data_length() == 4);\n\t\tauto hart_id = *((uint32_t *)trans.get_data_ptr());\n\n\t\tassert((cores.find(hart_id) != cores.end()) && \"core not registered in syscall handler\");\n\n\t\texecute_syscall(cores[hart_id]);\n\t}\n\n\tvirtual void execute_syscall(iss_syscall_if *core) override {\n\t\tauto a7 = core->read_register(RegFile::a7);\n\t\tauto a3 = core->read_register(RegFile::a3);\n\t\tauto a2 = core->read_register(RegFile::a2);\n\t\tauto a1 = core->read_register(RegFile::a1);\n\t\tauto a0 = core->read_register(RegFile::a0);\n\n\t\t// printf(\"a7=%u, a0=%u, a1=%u, a2=%u, a3=%u\\n\", a7, a0, a1, a2, a3);\n\n\t\tauto ans = execute_syscall(a7, a0, a1, a2, a3);\n\n\t\tcore->write_register(RegFile::a0, ans);\n\n\t\tif (shall_exit)\n\t\t\tcore->sys_exit();\n\t}\n\n\tuint8_t *mem = 0;     // direct pointer to start of guest memory in host memory\n\tuint64_t mem_offset;  // start address of the memory as mapped into the\n\t                      // address space\n\tuint64_t hp = 0;      // heap pointer\n\tbool shall_exit = false;\n\tbool shall_break = false;\n\n\t// only for memory consumption evaluation\n\tuint64_t start_heap = 0;\n\tuint64_t max_heap = 0;\n\n\tuint64_t get_max_heap_memory_consumption() {\n\t\treturn max_heap - start_heap;\n\t}\n\n\tvoid init(uint8_t *host_memory_pointer, uint64_t mem_start_address, uint64_t heap_pointer_address) {\n\t\tmem = host_memory_pointer;\n\t\tmem_offset = mem_start_address;\n\t\thp = heap_pointer_address;\n\n\t\tstart_heap = hp;\n\t\tmax_heap = hp;\n\t}\n\n\tuint8_t *guest_address_to_host_pointer(uintptr_t addr) {\n\t\tassert(mem != nullptr);\n\n\t\treturn mem + (addr - mem_offset);\n\t}\n\n\tuint8_t *guest_to_host_pointer(void *p) {\n\t\treturn guest_address_to_host_pointer((uintptr_t)p);\n\t}\n\n\t/*\n\t * Syscalls are implemented to work directly on guest memory (represented in\n\t * host as byte array). Note: the data structures on the host system might\n\t * not be binary compatible with those on the guest system.\n\t */\n\tint execute_syscall(uint64_t n, uint64_t _a0, uint64_t _a1, uint64_t _a2, uint64_t _a3);\n};\n\n}  // namespace rv64"
  },
  {
    "path": "vp/src/core/rv64/syscall_if.h",
    "content": "#pragma once\n\n#include <stdint.h>\n\nnamespace rv64 {\n\n/* The syscall handler is using this interface to access and control the ISS. */\nstruct iss_syscall_if {\n\tvirtual ~iss_syscall_if() {}\n\n\tvirtual void sys_exit() = 0;\n\n\tvirtual uint64_t read_register(unsigned idx) = 0;\n\tvirtual void write_register(unsigned idx, uint64_t value) = 0;\n};\n\n/* Using this interface, the ISS supports to intercept and delegate syscalls. */\nstruct syscall_emulator_if {\n\tvirtual ~syscall_emulator_if() {}\n\n\tvirtual void execute_syscall(iss_syscall_if *core) = 0;\n};\n\n}  // namespace rv64"
  },
  {
    "path": "vp/src/platform/CMakeLists.txt",
    "content": "file(GLOB sources_list LIST_DIRECTORIES true *)\nforeach(dir ${sources_list})\n    IF(IS_DIRECTORY ${dir})\n        add_subdirectory(${dir})\n    ELSE()\n        CONTINUE()\n    ENDIF()\nendforeach()"
  },
  {
    "path": "vp/src/platform/basic/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_library(platform-basic\nethernet.cpp\ndisplay.cpp\n${HEADERS})\n\ntarget_include_directories(platform-basic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\ntarget_link_libraries(platform-basic systemc)\n\nadd_executable(riscv-vp\n        main.cpp)\n\ntarget_link_libraries(riscv-vp rv32 platform-basic platform-common gdb-mc ${Boost_LIBRARIES} systemc pthread)\n\nINSTALL(TARGETS riscv-vp RUNTIME DESTINATION bin)\n"
  },
  {
    "path": "vp/src/platform/basic/basic_timer.h",
    "content": "#ifndef RISCV_ISA_BASIC_TIMER_H\n#define RISCV_ISA_BASIC_TIMER_H\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\n#include \"core/common/irq_if.h\"\n\nstruct BasicTimer : public sc_core::sc_module {\n\tinterrupt_gateway *plic = 0;\n\tuint32_t irq_number = 0;\n\n\tSC_HAS_PROCESS(BasicTimer);\n\n\tBasicTimer(sc_core::sc_module_name, uint32_t irq_number) : irq_number(irq_number) {\n\t\tSC_THREAD(run);\n\t}\n\n\tvoid run() {\n\t\twhile (true) {\n\t\t\tsc_core::wait(sc_core::sc_time(1, sc_core::SC_MS));\n\n\t\t\tplic->gateway_trigger_interrupt(irq_number);\n\t\t}\n\t}\n};\n\n#endif  // RISCV_ISA_BASIC_TIMER_H\n"
  },
  {
    "path": "vp/src/platform/basic/display.cpp",
    "content": "/*\n * display.cpp\n *\n *  Created on: Sep 11, 2018\n *      Author: dwd\n */\n\n#include \"display.hpp\"\n#include <math.h>\n#include <sys/ipc.h>\n#include <sys/shm.h>\n#include <sys/types.h>\n\ntypedef Framebuffer::Point Point;\ntypedef Framebuffer::PointF PointF;\ntypedef Framebuffer::Color Color;\ntypedef Framebuffer::Frame Frame;\n\n\nDisplay::Display(sc_module_name) {\n\ttsock.register_b_transport(this, &Display::transport);\n\tcreateSM();\n\tmemset(frame.raw, 0, sizeof(Framebuffer));\n}\n\nvoid Display::createSM() {\n\tint shmid;\n\tif ((shmid = shmget(SHMKEY, sizeof(Framebuffer), IPC_CREAT | 0666)) < 0) {\n\t\tstd::cerr << \"Could not get \" << sizeof(Framebuffer) << \" Byte of shared Memory \" << int(SHMKEY)\n\t\t          << \" for display\" << std::endl;\n\t\tperror(NULL);\n\t\texit(1);\n\t}\n\tframe.raw = reinterpret_cast<uint8_t *>(shmat(shmid, nullptr, 0));\n\tif (frame.raw == (uint8_t *)-1) {\n\t\tperror(\"shmat\");\n\t\texit(1);\n\t}\n}\n\nvoid Display::transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\ttlm::tlm_command cmd = trans.get_command();\n\tunsigned addr = trans.get_address();\n\tauto *ptr = trans.get_data_ptr();\n\tauto len = trans.get_data_length();\n\n\tassert((addr + len <= sizeof(Framebuffer)) && \"Access display out of bounds\");\n\n\tif (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\tif (addr == offsetof(Framebuffer, command) && len == sizeof(Framebuffer::Command)) {  // apply command\n\t\t\tswitch (*reinterpret_cast<Framebuffer::Command *>(ptr)) {\n\t\t\t\tcase Framebuffer::Command::clearAll:\n\t\t\t\t\tmemset(frame.raw, 0, sizeof(Framebuffer));\n\t\t\t\t\tframe.buf->activeFrame++;\n\t\t\t\t\tbreak;\n\t\t\t\tcase Framebuffer::Command::fillFrame:\n\t\t\t\t\tfillFrame(frame.buf->parameter.fill.frame, frame.buf->parameter.fill.color);\n\t\t\t\t\tbreak;\n\t\t\t\tcase Framebuffer::Command::applyFrame:\n\t\t\t\t\tframe.buf->activeFrame++;\n\t\t\t\t\tmemcpy(&frame.buf->getInactiveFrame(), &frame.buf->getActiveFrame(), sizeof(Frame));\n\t\t\t\t\tbreak;\n\t\t\t\tcase Framebuffer::Command::drawLine:\n\t\t\t\t\tdrawLine(frame.buf->parameter.line.frame, frame.buf->parameter.line.from,\n\t\t\t\t\t         frame.buf->parameter.line.to, frame.buf->parameter.line.color);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tcerr << \"unknown framebuffer command \" << *ptr << endl;\n\t\t\t\t\tsc_assert(false);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// reset parameter\n\t\t\tmemset(reinterpret_cast<void *>(&frame.buf->parameter), 0, sizeof(Framebuffer::Parameter));\n\t\t} else if (addr >= offsetof(Framebuffer, parameter) &&\n\t\t           addr + len < offsetof(Framebuffer, parameter) + sizeof(Framebuffer::Parameter)) {  // write the\n\t\t\t                                                                                          // parameter\n\t\t\tmemcpy(&frame.raw[addr], ptr, len);\n\t\t} else {  // Write the actual framebuffer\n\t\t\tmemcpy(&frame.raw[addr], ptr, len);\n\t\t}\n\n\t} else if (cmd == tlm::TLM_READ_COMMAND && addr < sizeof(Framebuffer)) {  // read whatever you like\n\t\tmemcpy(ptr, &frame.raw[addr], len);\n\t} else {\n\t\tsc_assert(false && \"unsupported tlm command\");\n\t}\n\tdelay += sc_core::sc_time(len * 5, sc_core::SC_NS);\n}\n\nvoid Display::fillFrame(Framebuffer::Type type, Color color) {\n\tassert(sizeof(Frame) % 8 == 0);\n\tassert(8 % sizeof(Color) == 0);\n\tuint64_t *rawFrame = reinterpret_cast<uint64_t *>(&frame.buf->getFrame(type).raw);\n\tuint_fast32_t steps = sizeof(Frame) / 8;\n\tuint64_t wideColor = 0;\n\tfor (uint_fast8_t i = 0; i * sizeof(Color) < 8; i++) {\n\t\treinterpret_cast<Color *>(&wideColor)[i] = color;\n\t}\n\tfor (uint_fast32_t i = 0; i < steps; i++) {\n\t\trawFrame[i] = wideColor;\n\t}\n}\n\nvoid Display::drawLine(Framebuffer::Type type, PointF from, PointF to, Color color) {\n\tFrame &local = frame.buf->getFrame(type);\n\tif (from.x == to.x) {  // vertical line\n\t\tif (from.y > to.y)\n\t\t\tswap(from.y, to.y);\n\t\tuint16_t intFromX = from.x;\n\t\tuint16_t intToY = to.y;\n\t\tfor (uint16_t y = from.y; y <= intToY; y++) {\n\t\t\tlocal.raw[y][intFromX] = color;\n\t\t}\n\t\treturn;\n\t}\n\tif (from.y == to.y) {  // horizontal line, the fastest\n\t\tif (from.x > to.x)\n\t\t\tswap(from.x, to.x);\n\t\tuint16_t intFromY = from.y;\n\t\tuint16_t intToX = to.x;\n\t\tfor (uint16_t x = from.x; x <= intToX; x++) {\n\t\t\tlocal.raw[intFromY][x] = color;\n\t\t}\n\t\treturn;\n\t}\n\n\t// Bresenham's line algorithm\n\tconst bool steep = (fabs(to.y - from.y) > fabs(to.x - from.x));\n\tif (steep) {\n\t\tswap(from.x, from.y);\n\t\tswap(to.x, to.y);\n\t}\n\n\tif (from.x > to.x) {\n\t\tswap(from.x, to.x);\n\t\tswap(from.y, to.y);\n\t}\n\n\tconst float dx = to.x - from.x;\n\tconst float dy = fabs(to.y - from.y);\n\n\tfloat error = dx / 2.0f;\n\tconst int ystep = (from.y < to.y) ? 1 : -1;\n\tint y = (int)from.y;\n\n\tconst int maxX = (int)to.x;\n\n\tfor (int x = (int)from.x; x < maxX; x++) {\n\t\tif (steep) {\n\t\t\tlocal.raw[x][y] = color;\n\t\t} else {\n\t\t\tlocal.raw[y][x] = color;\n\t\t}\n\n\t\terror -= dy;\n\t\tif (error < 0) {\n\t\t\ty += ystep;\n\t\t\terror += dx;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vp/src/platform/basic/display.hpp",
    "content": "/*\n * display.hpp\n *\n *  Created on: Sep 11, 2018\n *      Author: dwd\n */\n\n#pragma once\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n#include \"../../../../env/basic/vp-display/framebuffer.h\"\n\nusing namespace std;\nusing namespace sc_core;\nusing namespace tlm_utils;\n\nstruct Display : public sc_core::sc_module {\n\tstatic const size_t addressRange = sizeof(Framebuffer);\n\n\tsimple_target_socket<Display> tsock;\n\n\tunion {\n\t\tuint8_t* raw;\n\t\tFramebuffer* buf;\n\t} frame;\n\n\tvoid createSM();\n\n\tDisplay(sc_module_name);\n\tvoid transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay);\n\n\t// graphics acceleration functions\n\tvoid fillFrame(Framebuffer::Type frame, Framebuffer::Color color);\n\tvoid drawLine(Framebuffer::Type frame, Framebuffer::PointF from, Framebuffer::PointF to, Framebuffer::Color color);\n};\n"
  },
  {
    "path": "vp/src/platform/basic/dma.h",
    "content": "#ifndef RISCV_ISA_DMA_H\n#define RISCV_ISA_DMA_H\n\n#include <systemc>\n\n#include <tlm_utils/simple_initiator_socket.h>\n#include <tlm_utils/simple_target_socket.h>\n\n#include <unordered_map>\n#include <array>\n\nstruct SimpleDMA : public sc_core::sc_module {\n\ttlm_utils::simple_initiator_socket<SimpleDMA> isock;\n\ttlm_utils::simple_target_socket<SimpleDMA> tsock;\n\n\tinterrupt_gateway *plic = 0;\n\tuint32_t irq_number = 0;\n\n\tstd::array<uint8_t, 64> buffer;\n\n\tuint32_t src = 0;\n\tuint32_t dst = 0;\n\tuint32_t len = 0;\n\tuint32_t op = 0;\n\tuint32_t stat = 0;\n\n\tstd::unordered_map<uint64_t, uint32_t *> addr_to_reg;\n\n\tenum {\n\t\tOP_NOP = 0,\n\t\tOP_MEMCPY = 1,\n\t\tOP_MEMSET = 2,\n\t\tOP_MEMCMP = 3,\n\t\tOP_MEMCHR = 4,\n\t\tOP_MEMMOVE = 5,\n\t};\n\n\tenum {\n\t\tSRC_ADDR = 0,\n\t\tDST_ADDR = 4,\n\t\tLEN_ADDR = 8,\n\t\tOP_ADDR = 12,\n\t\tSTAT_ADDR = 16,\n\t};\n\n\tsc_core::sc_event run_event;\n\n\tSC_HAS_PROCESS(SimpleDMA);\n\n\tSimpleDMA(sc_core::sc_module_name, uint32_t irq_number) : irq_number(irq_number) {\n\t\ttsock.register_b_transport(this, &SimpleDMA::transport);\n\n\t\tSC_THREAD(run);\n\n\t\taddr_to_reg = {\n\t\t    {SRC_ADDR, &src},\n\t\t    {DST_ADDR, &dst},\n\t\t    {LEN_ADDR, &len},\n\t\t    {OP_ADDR, &op},\n\t\t};\n\t}\n\n\tvoid _copy_block(uint32_t off, uint32_t n) {\n\t\tdo_transaction(tlm::TLM_READ_COMMAND, src + off, &buffer[0], n);\n\t\tdo_transaction(tlm::TLM_WRITE_COMMAND, dst + off, &buffer[0], n);\n\t}\n\n\tvoid _perform_memcpy() {\n\t\tauto n = len;\n\t\tuint32_t off = 0;\n\n\t\twhile (n > buffer.size()) {\n\t\t\t_copy_block(off, buffer.size());\n\t\t\tn -= buffer.size();\n\t\t\toff += buffer.size();\n\t\t}\n\n\t\t_copy_block(off, n);\n\t}\n\n\tvoid run() {\n\t\twhile (true) {\n\t\t\tsc_core::wait(run_event);\n\n\t\t\tswitch (op) {\n\t\t\t\tcase OP_NOP:\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase OP_MEMCPY:\n\t\t\t\t\t_perform_memcpy();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase OP_MEMSET:\n\t\t\t\t\tassert(false && \"not implemented\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase OP_MEMCMP:\n\t\t\t\t\tassert(false && \"not implemented\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase OP_MEMCHR:\n\t\t\t\t\tassert(false && \"not implemented\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase OP_MEMMOVE:\n\t\t\t\t\tassert(false && \"not implemented\");\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tassert(false && \"unknown operation requested by software\");\n\t\t\t}\n\n\t\t\tplic->gateway_trigger_interrupt(irq_number);\n\t\t}\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tauto addr = trans.get_address();\n\t\tauto cmd = trans.get_command();\n\t\tauto len = trans.get_data_length();\n\t\tauto ptr = trans.get_data_ptr();\n\n\t\tassert(len == 4);  // NOTE: only allow to read/write whole register\n\n\t\tauto it = addr_to_reg.find(addr);\n\t\tassert(it != addr_to_reg.end());  // access to non-mapped address\n\n\t\t// actual read/write\n\t\tif (cmd == tlm::TLM_READ_COMMAND) {\n\t\t\t*((uint32_t *)ptr) = *it->second;\n\t\t} else if (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\t\t*it->second = *((uint32_t *)ptr);\n\t\t} else {\n\t\t\tassert(false && \"unsupported tlm command for dma access\");\n\t\t}\n\n\t\t// post read/write actions\n\t\tif ((cmd == tlm::TLM_WRITE_COMMAND) && (addr == OP_ADDR)) {\n\t\t\trun_event.notify(sc_core::sc_time(10, sc_core::SC_NS));\n\t\t}\n\n\t\t(void)delay;  // zero delay\n\t}\n\n\tvoid do_transaction(tlm::tlm_command cmd, uint64_t addr, uint8_t *data, unsigned num_bytes) {\n\t\tsc_core::sc_time delay = sc_core::SC_ZERO_TIME;\n\n\t\ttlm::tlm_generic_payload trans;\n\t\ttrans.set_command(cmd);\n\t\ttrans.set_address(addr);\n\t\ttrans.set_data_ptr(data);\n\t\ttrans.set_data_length(num_bytes);\n\n\t\tisock->b_transport(trans, delay);\n\n\t\tif (delay != sc_core::SC_ZERO_TIME)\n\t\t\tsc_core::wait(delay);\n\t}\n};\n\n#endif  // RISCV_ISA_DMA_H\n"
  },
  {
    "path": "vp/src/platform/basic/ethernet.cpp",
    "content": "#include \"ethernet.h\"\n\n#include <netinet/ether.h>\n#include <netinet/in.h>\n#include <sys/socket.h>\n#include <sys/types.h>\n// for debug\n#include <arpa/inet.h>\n#include <netinet/ip.h>\n#include <netinet/udp.h>\n\n#include <linux/if_packet.h>\n//#include <netpacket/packet.h>\n#include <net/if.h>\n//#include <linux/if_ether.h>\n#include <fcntl.h>\n#include <linux/if_tun.h>\n#include <sys/ioctl.h>\n\n#include <ifaddrs.h>\n#include <netdb.h>\n\nusing namespace std;\n\nstatic const char IF_NAME[] = \"tap0\";\n\n#define SYS_CHECK(arg, msg)           \\\n\tif ((arg) < 0) {                  \\\n\t\tperror(msg);                  \\\n\t\tthrow runtime_error(\"error\"); \\\n\t}\n\nvoid printHex(const unsigned char *buf, const uint32_t len) {\n\tfor (uint8_t i = 0; i < len; i++) {\n\t\tprintf(\"%s%02X\", i > 0 ? \":\" : \"\", buf[i]);\n\t}\n}\n\nvoid printDec(const unsigned char *buf, const uint32_t len) {\n\tfor (uint8_t i = 0; i < len; i++) {\n\t\tprintf(\"%s%d\", i > 0 ? \".\" : \"\", buf[i]);\n\t}\n}\n\nvoid dump_ethernet_frame(uint8_t *buf, size_t size, bool verbose = false) {\n\tuint8_t *readbuf = buf;\n\tstruct ether_header *eh = (struct ether_header *)readbuf;\n\n\tif (verbose) {\n\t\tcout << \"destination MAC: \";\n\t\tprintHex(reinterpret_cast<unsigned char *>(&eh->ether_dhost), 6);\n\t\tcout << endl;\n\t\tcout << \"source MAC     : \";\n\t\tprintHex(reinterpret_cast<unsigned char *>(&eh->ether_shost), 6);\n\t\tcout << endl;\n\t\tcout << \"type           : \" << ntohs(eh->ether_type) << endl;\n\t}\n\n\treadbuf += sizeof(struct ethhdr);\n\tswitch (ntohs(eh->ether_type)) {\n\t\tcase ETH_P_IP: {\n\t\t\tcout << \"IP \";\n\t\t\tstruct in_addr source;\n\t\t\tstruct in_addr dest;\n\t\t\tstruct iphdr *ip = (struct iphdr *)readbuf;\n\t\t\tmemset(&source, 0, sizeof(source));\n\t\t\tsource.s_addr = ip->saddr;\n\t\t\tmemset(&dest, 0, sizeof(dest));\n\t\t\tdest.s_addr = ip->daddr;\n\t\t\tif (verbose) {\n\t\t\t\tcout << endl;\n\t\t\t\tcout << \"\\t|-Version               : \" << ip->version << endl;\n\t\t\t\tcout << \"\\t|-Internet Header Length: \" << ip->ihl << \" DWORDS or \" << ip->ihl * 4 << \" Bytes\" << endl;\n\t\t\t\tcout << \"\\t|-Type Of Service       : \" << (unsigned int)ip->tos << endl;\n\t\t\t\tcout << \"\\t|-Total Length          : \" << ntohs(ip->tot_len) << \" Bytes\" << endl;\n\t\t\t\tcout << \"\\t|-Identification        : \" << ntohs(ip->id) << endl;\n\t\t\t\tcout << \"\\t|-Time To Live          : \" << (unsigned int)ip->ttl << endl;\n\t\t\t\tcout << \"\\t|-Protocol              : \" << (unsigned int)ip->protocol << endl;\n\t\t\t\tcout << \"\\t|-Header Checksum       : \" << ntohs(ip->check) << endl;\n\t\t\t\tcout << \"\\t|-Source IP             : \" << inet_ntoa(source) << endl;\n\t\t\t\tcout << \"\\t|-Destination IP        : \" << inet_ntoa(dest) << endl;\n\t\t\t}\n\t\t\treadbuf += ip->ihl * 4;\n\t\t\tswitch (ip->protocol) {\n\t\t\t\tcase IPPROTO_UDP: {\n\t\t\t\t\tcout << \"UDP \";\n\t\t\t\t\tstruct udphdr *udp = (struct udphdr *)readbuf;\n\t\t\t\t\tif (verbose) {\n\t\t\t\t\t\tcout << endl;\n\t\t\t\t\t\tcout << \"\\t|-Source port     : \" << ntohs(udp->source) << endl;\n\t\t\t\t\t\tcout << \"\\t|-Destination port: \" << ntohs(udp->dest) << endl;\n\t\t\t\t\t\tcout << \"\\t|-Length          : \" << ntohs(udp->len) << endl;\n\t\t\t\t\t\tcout << \"\\t|-Checksum        : \" << ntohs(udp->check) << endl;\n\t\t\t\t\t}\n\t\t\t\t\treadbuf += sizeof(udphdr);\n\t\t\t\t\tswitch (ntohs(udp->dest)) {\n\t\t\t\t\t\tcase 67:\n\t\t\t\t\t\tcase 68:\n\t\t\t\t\t\t\tcout << \"DHCP \";\n\t\t\t\t\t\t\tswitch (readbuf[0]) {\n\t\t\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\t\t\tcout << \"DISCOVER/REQUEST\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\tcout << \"ACK\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\tcout << \"UNKNOWN (\" << to_string(readbuf[0]) << \")\";\n\t\t\t\t\t\t\t\t\tgoto printHex;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tcase IPPROTO_TCP:\n\t\t\t\t\tcout << \"TCP \";\n\t\t\t\t\tif (verbose)\n\t\t\t\t\t\tcout << endl;\n\t\t\t\t\treturn;\n\t\t\t\tcase IPPROTO_ICMP:\n\t\t\t\t\tcout << \"ICMP \";\n\t\t\t\t\tswitch (readbuf[0]) {\n\t\t\t\t\t\tcase 0:\n\t\t\t\t\t\t\tcout << \"ECHO REPLY\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\tcout << \"DEST UNREACHABLE\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 8:\n\t\t\t\t\t\t\tcout << \"ECHO REQUEST\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tcout << \"Sonstiges\";\n\t\t\t\t\t}\n\t\t\t\t\tif (verbose)\n\t\t\t\t\t\tcout << endl;\n\t\t\t\tdefault:\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase ETH_P_ARP: {\n\t\t\tcout << \"ARP \";\n\t\t\tstruct arp_eth_header *arp = (struct arp_eth_header *)readbuf;\n\t\t\tif (verbose) {\n\t\t\t\tcout << endl;\n\t\t\t\tcout << \"\\t|-Sender MAC: \";\n\t\t\t\tprintHex((uint8_t *)&arp->sender_mac, 6);\n\t\t\t\tcout << endl;\n\t\t\t\tcout << \"\\t|-Sender IP : \";\n\t\t\t\tprintDec((uint8_t *)&arp->sender_ip, 4);\n\t\t\t\tcout << endl;\n\t\t\t\tcout << \"\\t|-DEST MAC  : \";\n\t\t\t\tprintHex((uint8_t *)&arp->target_mac, 6);\n\t\t\t\tcout << endl;\n\t\t\t\tcout << \"\\t|-DEST IP   : \";\n\t\t\t\tprintDec((uint8_t *)&arp->target_ip, 4);\n\t\t\t\tcout << endl;\n\t\t\t}\n\t\t\tcout << \"\\t|-Operation : \"\n\t\t\t     << (ntohs(arp->oper) == 1 ? \"REQUEST\" : ntohs(arp->oper) == 2 ? \"REPLY\" : \"INVALID\");\n\t\t\treturn;\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tcout << \"unknown protocol\";\n\t\t\treturn;\n\t}\nprintHex:\n\tios_base::fmtflags f(cout.flags());\n\tfor (unsigned i = 0; i < size; ++i) {\n\t\tcout << hex << setw(2) << setfill('0') << (int)buf[i] << \" \";\n\t}\n\tcout.flags(f);\n}\n\nEthernetDevice::EthernetDevice(sc_core::sc_module_name, uint32_t irq_number, uint8_t *mem, std::string clonedev)\n    : irq_number(irq_number), mem(mem) {\n\ttsock.register_b_transport(this, &EthernetDevice::transport);\n\tSC_THREAD(run);\n\n\trouter\n\t    .add_register_bank({\n\t        {STATUS_REG_ADDR, &status},\n\t        {RECEIVE_SIZE_REG_ADDR, &receive_size},\n\t        {RECEIVE_DST_REG_ADDR, &receive_dst},\n\t        {SEND_SRC_REG_ADDR, &send_src},\n\t        {SEND_SIZE_REG_ADDR, &send_size},\n\t        {MAC_HIGH_REG_ADDR, &mac[0]},\n\t        {MAC_LOW_REG_ADDR, &mac[1]},\n\t    })\n\t    .register_handler(this, &EthernetDevice::register_access_callback);\n\n\tdisabled = clonedev == string(\"\");\n\n\tif (!disabled) {\n\t\tinit_network(clonedev);\n\t}\n}\n\nvoid EthernetDevice::init_network(std::string clonedev) {\n\tstruct ifreq ifr;\n\tint err;\n\n\tif ((sockfd = open(clonedev.c_str(), O_RDWR)) < 0) {\n\t\tcerr << \"Error opening \" << clonedev << endl;\n\t\tperror(\"exiting\");\n\t\tassert(sockfd >= 0);\n\t}\n\n\tmemset(&ifr, 0, sizeof(ifr));\n\n\tifr.ifr_flags = IFF_TAP | IFF_NO_PI;\n\n\tstrncpy(ifr.ifr_name, IF_NAME, IFNAMSIZ);\n\n\tif ((err = ioctl(sockfd, TUNSETIFF, (void *)&ifr)) < 0) {\n\t\tperror(\"ioctl(TUNSETIFF)\");\n\t\tclose(sockfd);\n\t\tassert(err >= 0);\n\t}\n\n\t/* Get the MAC address of the interface to send on */\n\tstruct ifreq ifopts;\n\tmemset(&ifopts, 0, sizeof(struct ifreq));\n\tstrncpy(ifopts.ifr_name, IF_NAME, IFNAMSIZ - 1);\n\tif (ioctl(sockfd, SIOCGIFHWADDR, &ifopts) < 0) {\n\t\tperror(\"SIOCGIFHWADDR\");\n\t\tassert(sockfd >= 0);\n\t}\n\t// Save own MAC in register\n\tmemcpy(VIRTUAL_MAC_ADDRESS, ifopts.ifr_hwaddr.sa_data, 6);\n\n\tfcntl(sockfd, F_SETFL, O_NONBLOCK);\n}\n\nvoid EthernetDevice::send_raw_frame() {\n\tuint8_t sendbuf[send_size < 60 ? 60 : send_size];\n\tmemcpy(sendbuf, &mem[send_src - 0x80000000], send_size);\n\tif (send_size < 60) {\n\t\tmemset(&sendbuf[send_size], 0, 60 - send_size);\n\t\tsend_size = 60;\n\t}\n\n\tcout << \"SEND FRAME --->--->--->--->--->---> \";\n\tdump_ethernet_frame(sendbuf, send_size, true);\n\tcout << endl;\n\n\tstruct ether_header *eh = (struct ether_header *)sendbuf;\n\n\tassert(memcmp(eh->ether_shost, VIRTUAL_MAC_ADDRESS, ETH_ALEN) == 0);\n\n\tssize_t ans = write(sockfd, sendbuf, send_size);\n\tif (ans != send_size) {\n\t\tcout << strerror(errno) << endl;\n\t}\n\tassert(ans == send_size);\n}\n\nbool EthernetDevice::isPacketForUs(uint8_t *packet, ssize_t) {\n\tether_header *eh = reinterpret_cast<ether_header *>(packet);\n\tbool virtual_match = memcmp(eh->ether_dhost, VIRTUAL_MAC_ADDRESS, ETH_ALEN) == 0;\n\tbool broadcast_match = memcmp(eh->ether_dhost, BROADCAST_MAC_ADDRESS, ETH_ALEN) == 0;\n\tbool own_packet = memcmp(eh->ether_shost, VIRTUAL_MAC_ADDRESS, ETH_ALEN) == 0;\n\n\tif (!virtual_match && !(broadcast_match && !own_packet)) {\n\t\treturn false;\n\t}\n\n\tif (ntohs(eh->ether_type) != ETH_P_IP) {\n\t\tif (ntohs(eh->ether_type) != ETH_P_ARP) {  // Not ARP\n\t\t\t// cout << \" dumped non-ARP \" ;\n\t\t\t// FIXME change to true if you want other protocols than IP and ARP\n\t\t\treturn false;\n\t\t}\n\n\t\tarp_eth_header *arp = reinterpret_cast<arp_eth_header *>(packet + sizeof(ether_header));\n\n\t\tif (memcmp(arp->target_mac, VIRTUAL_MAC_ADDRESS,\n\t\t           6)) {  // not to us directly\n\t\t\t// cout << \" dumped ARP not targeted to US \";\n\t\t\t/**\n\t\t\t * FIXME comment out if you want to generate arp table automatically\n\t\t\t * \t\t instead of having to request every neighbor explicitly\n\t\t\t * \t\t also to reply to ARP requests\n\t\t\t */\n\t\t\treturn true;\n\t\t}\n\t} else {\n\t\t// is IP\n\t\treturn true;\n\n\t\tiphdr *ip = reinterpret_cast<iphdr *>(packet + sizeof(ether_header));\n\t\tif (ip->protocol != IPPROTO_UDP) {  // not UDP\n\t\t\t// cout << \" dumped non-UDP \";\n\t\t\t// FIXME change to true if you want to use TCP or ICMP\n\t\t\treturn false;\n\t\t}\n\n\t\tudphdr *udp = reinterpret_cast<udphdr *>(packet + sizeof(ether_header) + sizeof(iphdr));\n\t\tif (ntohs(udp->dest) != 67 && ntohs(udp->dest) != 68) {  // not DHCP\n\t\t\t// cout << \" dumped non-DHCP \";\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nbool EthernetDevice::try_recv_raw_frame() {\n\tssize_t ans;\n\n\tans = read(sockfd, recv_frame_buf, FRAME_SIZE);\n\tassert(ans <= FRAME_SIZE);\n\tif (ans == 0) {\n\t\tcerr << \"[ethernet] recv socket received zero bytes ... connection \"\n\t\t        \"closed?\"\n\t\t     << endl;\n\t\tthrow runtime_error(\"read failed\");\n\t} else if (ans == -1) {\n\t\tif (errno == EWOULDBLOCK || errno == EAGAIN) {\n\t\t\treturn true;\n\t\t} else\n\t\t\tthrow runtime_error(\"recvfrom failed\");\n\t}\n\tassert(ETH_ALEN == 6);\n\n\tif (!isPacketForUs(recv_frame_buf, ans)) {\n\t\treturn false;\n\t}\n\n\thas_frame = true;\n\treceive_size = ans;\n\tcout << \"RECEIVED FRAME <---<---<---<---<--- \";\n\tdump_ethernet_frame(recv_frame_buf, ans);\n\tcout << endl;\n\n\treturn true;\n}\n"
  },
  {
    "path": "vp/src/platform/basic/ethernet.h",
    "content": "#ifndef RISCV_VP_ETHERNET_H\n#define RISCV_VP_ETHERNET_H\n\n#include <unistd.h>\n#include <cstdlib>\n#include <cstring>\n#include <iomanip>\n#include <ios>\n#include <list>\n#include <map>\n#include <unordered_map>\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\n#include \"core/common/irq_if.h\"\n#include \"util/tlm_map.h\"\n\nstruct arp_eth_header {\n\tuint16_t htype;\n\tuint16_t ptype;\n\tuint8_t hlen;\n\tuint8_t plen;\n\tuint16_t oper;\n\tuint8_t sender_mac[6];\n\tuint8_t sender_ip[4];\n\tuint8_t target_mac[6];\n\tuint8_t target_ip[4];\n};\n\nstruct EthernetDevice : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<EthernetDevice> tsock;\n\n\tinterrupt_gateway *plic = 0;\n\tuint32_t irq_number = 0;\n\tsc_core::sc_event run_event;\n\n\t// memory mapped configuration registers\n\tuint32_t status = 0;\n\tuint32_t receive_size = 0;\n\tuint32_t receive_dst = 0;\n\tuint32_t send_src = 0;\n\tuint32_t send_size = 0;\n\tuint32_t mac[2];\n\n\tuint8_t *VIRTUAL_MAC_ADDRESS = reinterpret_cast<uint8_t *>(mac);\n\tuint8_t BROADCAST_MAC_ADDRESS[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\n\n\tuint8_t *mem = nullptr;\n\n\tvp::map::LocalRouter router;\n\n\tint sockfd = 0;\n\tint interfaceIdx = 0;\n\n\tstatic const uint16_t MTU_SIZE = 1500;\n\tstatic const uint16_t FRAME_SIZE = MTU_SIZE + 14;\n\n\tuint8_t recv_frame_buf[FRAME_SIZE];\n\tbool has_frame;\n\tbool disabled;\n\n\tstatic const uint16_t STATUS_REG_ADDR = 0x00;\n\tstatic const uint16_t RECEIVE_SIZE_REG_ADDR = STATUS_REG_ADDR + sizeof(uint32_t);\n\tstatic const uint16_t RECEIVE_DST_REG_ADDR = RECEIVE_SIZE_REG_ADDR + sizeof(uint32_t);\n\tstatic const uint16_t SEND_SRC_REG_ADDR = RECEIVE_DST_REG_ADDR + sizeof(uint32_t);\n\tstatic const uint16_t SEND_SIZE_REG_ADDR = SEND_SRC_REG_ADDR + sizeof(uint32_t);\n\tstatic const uint16_t MAC_HIGH_REG_ADDR = SEND_SIZE_REG_ADDR + sizeof(uint32_t);\n\tstatic const uint16_t MAC_LOW_REG_ADDR = MAC_HIGH_REG_ADDR + sizeof(uint32_t);\n\n\tenum : uint16_t {\n\t\tRECV_OPERATION = 1,\n\t\tSEND_OPERATION = 2,\n\t};\n\n\tSC_HAS_PROCESS(EthernetDevice);\n\n\tEthernetDevice(sc_core::sc_module_name, uint32_t irq_number, uint8_t *mem, std::string clonedev);\n\n\tvoid init_network(std::string clonedev);\n\tvoid add_all_if_ips();\n\n\tvoid send_raw_frame();\n\tbool try_recv_raw_frame();\n\tbool isPacketForUs(uint8_t *packet, ssize_t size);\n\n\tvoid register_access_callback(const vp::map::register_access_t &r) {\n\t\tassert(mem);\n\t\tassert(!disabled && \"Tried accessing disabled network device\");\n\n\t\tr.fn();\n\n\t\tif (r.write && r.vptr == &status) {\n\t\t\tif (r.nv == RECV_OPERATION) {\n\t\t\t\tassert(has_frame);\n\t\t\t\tmemcpy(&mem[receive_dst - 0x80000000], recv_frame_buf, receive_size);\n\t\t\t\thas_frame = false;\n\t\t\t\treceive_size = 0;\n\t\t\t} else if (r.nv == SEND_OPERATION) {\n\t\t\t\tsend_raw_frame();\n\t\t\t} else {\n\t\t\t\tthrow std::runtime_error(\"unsupported operation\");\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\trouter.transport(trans, delay);\n\t}\n\n\tvoid run() {\n\t\twhile (!disabled) {\n\t\t\trun_event.notify(sc_core::sc_time(10000, sc_core::SC_US));\n\t\t\tsc_core::wait(run_event);  // 10000 times per second by default\n\n\t\t\t// check if data is available on the socket, if yes store it in an\n\t\t\t// internal buffer\n\t\t\tif (!has_frame) {\n\t\t\t\twhile (!try_recv_raw_frame())\n\t\t\t\t\t;\n\t\t\t\tif (has_frame)\n\t\t\t\t\tplic->gateway_trigger_interrupt(irq_number);\n\t\t\t}\n\t\t}\n\t}\n};\n\n#endif  // RISCV_VP_ETHERNET_H\n"
  },
  {
    "path": "vp/src/platform/basic/flash.h",
    "content": "#pragma once\n\n#include <fcntl.h>\n#include <linux/fs.h>\n#include <stdint.h>\n#include <sys/ioctl.h>\n#include <unistd.h>  //truncate\n#include <fstream>   //file IO\n#include <iostream>\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n\n#include \"bus.h\"\n\nusing namespace std;\nusing namespace sc_core;\nusing namespace tlm_utils;\n\ntemplate <size_t width>\nstruct Blockbuffer {\n\tuint8_t buf[width];\n\tuint64_t offs;\n\tbool dirty;\n\tbool active;\n\tint fd;\n\tBlockbuffer(int fileDescriptor) : offs(0), dirty(false), active(false), fd(fileDescriptor){};\n\n\tvoid setPos(uint64_t blockOffset) {\n\t\tif (blockOffset != offs || !active) {\n\t\t\tif (dirty && active) {  // commit changes\n\t\t\t\twriteBlock(offs);\n\t\t\t}\n\t\t\toffs = blockOffset;\n\t\t\treadBlock(blockOffset);\n\t\t\tactive = true;\n\t\t}\n\t}\n\tvoid setData(const uint8_t* source, uint16_t pos, uint16_t length) {\n\t\tassert(active);\n\t\tmemcpy(&buf[pos], source, length);\n\t\tdirty = true;\n\t}\n\tvoid getData(uint8_t* target, uint16_t pos, uint16_t length) {\n\t\tassert(active);\n\t\tmemcpy(target, &buf[pos], length);\n\t}\n\n\tvoid writeBlock(uint64_t blockOffset) {\n\t\tif (lseek(fd, blockOffset * width, SEEK_SET) < 0) {\n\t\t\tcerr << \"Could not seek device: \" << strerror(errno) << endl;\n\t\t\treturn;\n\t\t}\n\t\tif (write(fd, buf, width) != width) {\n\t\t\tcerr << \"Could not write device: \" << strerror(errno) << endl;\n\t\t\treturn;\n\t\t}\n\t\tdirty = false;\n\t}\n\n\tvoid readBlock(uint64_t blockOffset) {\n\t\tif (lseek(fd, blockOffset * width, SEEK_SET) < 0) {\n\t\t\tcerr << \"Could not seek device: \" << strerror(errno) << endl;\n\t\t\treturn;\n\t\t}\n\t\tif (read(fd, buf, width) != width) {\n\t\t\tcerr << \"Could not read device: \" << strerror(errno) << endl;\n\t\t\treturn;\n\t\t}\n\t\tdirty = false;\n\t}\n\tvoid clear() {\n\t\tif (active && dirty) {\n\t\t\twriteBlock(offs);\n\t\t}\n\t\tactive = false;\n\t}\n};\n\nstruct Flashcontroller : public sc_core::sc_module {\n\tstatic const unsigned int BLOCKSIZE = 512;\n\tstatic const unsigned int FLASH_ADDR_REG = 0;\n\tstatic const unsigned int FLASH_SIZE_REG = sizeof(uint64_t);\n\tstatic const unsigned int DATA_ADDR = FLASH_SIZE_REG + sizeof(uint64_t);\n\tstatic const unsigned int ADDR_SPACE = DATA_ADDR + BLOCKSIZE;\n\n\tsimple_target_socket<Flashcontroller> tsock;\n\tuint8_t blockbufRaw[sizeof(Blockbuffer<BLOCKSIZE>)];\n\tBlockbuffer<BLOCKSIZE>* blockBuf;\n\n\tunion {\n\t\tuint64_t asInt;\n\t\tuint8_t asRaw[8];\n\t} mTargetBlock;\n\n\tunion {\n\t\tuint64_t asInt;\n\t\tuint8_t asRaw[8];\n\t} mDeviceNumBlocks;\n\n\tstring mFilepath;\n\tint mFiledescriptor;\n\n\tFlashcontroller(sc_module_name, string& filepath) : blockBuf(nullptr), mFilepath(filepath), mFiledescriptor(-1) {\n\t\ttsock.register_b_transport(this, &Flashcontroller::transport);\n\n\t\tif (filepath.length() == 0) {  // No file\n\t\t\treturn;\n\t\t}\n\n\t\tmFiledescriptor = open(mFilepath.c_str(), O_SYNC | O_RDWR);\n\t\tif (mFiledescriptor < 0) {\n\t\t\tcerr << \"Could not open device \" << mFilepath << \": \" << strerror(errno) << endl;\n\t\t\treturn;\n\t\t}\n\n\t\tif (ioctl(mFiledescriptor, BLKGETSIZE64, &mDeviceNumBlocks.asInt) < 0) {\n\t\t\tcerr << \"Could not get size of Device \" << mFilepath << \": \" << strerror(errno) << endl;\n\t\t\tmDeviceNumBlocks.asInt = lseek(mFiledescriptor, 0, SEEK_END);\n\t\t\tif (mDeviceNumBlocks.asInt <= 0) {\n\t\t\t\tclose(mFiledescriptor);\n\t\t\t\tmFiledescriptor = -1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcerr << \"Could get size of _file_ \" << mFilepath << \": \" << mDeviceNumBlocks.asInt << endl;\n\t\t\tmDeviceNumBlocks.asInt /= BLOCKSIZE;\n\t\t}\n\t\tmTargetBlock.asInt = 0;\n\t\tblockBuf = new (blockbufRaw) Blockbuffer<BLOCKSIZE>(mFiledescriptor);\n\t}\n\n\t~Flashcontroller() {\n\t\tif (blockBuf != nullptr) {\n\t\t\tblockBuf->clear();\n\t\t}\n\t\tclose(mFiledescriptor);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) {\n\t\ttlm::tlm_command cmd = trans.get_command();\n\t\tunsigned addr = trans.get_address();\n\t\tauto* ptr = trans.get_data_ptr();\n\t\tauto len = trans.get_data_length();\n\n\t\tassert((addr < DATA_ADDR + BLOCKSIZE) && \"Access flashcontroller out of bounds\");\n\t\tassert(mFiledescriptor >= 0);\n\n\t\tif (/*addr >= FLASH_ADDR_REG &&*/ addr < FLASH_SIZE_REG) {  // Address register\n\t\t\tif (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\t\t\tmemcpy(&mTargetBlock.asRaw[addr - FLASH_ADDR_REG], ptr, len);\n\t\t\t} else if (cmd == tlm::TLM_READ_COMMAND) {\n\t\t\t\tmemcpy(ptr, &mTargetBlock.asRaw[addr - FLASH_ADDR_REG], len);\n\t\t\t} else {\n\t\t\t\tsc_assert(false && \"unsupported tlm command\");\n\t\t\t}\n\t\t\tdelay += sc_core::sc_time(len * 30, sc_core::SC_NS);\n\t\t} else if (addr >= FLASH_SIZE_REG && addr < DATA_ADDR) {  // Size register\n\t\t\tif (cmd == tlm::TLM_READ_COMMAND) {\n\t\t\t\tmemcpy(ptr, &mDeviceNumBlocks.asRaw[addr - FLASH_SIZE_REG], len);\n\t\t\t} else {\n\t\t\t\tsc_assert(false && \"unsupported tlm command\");\n\t\t\t}\n\t\t\tdelay += sc_core::sc_time(len * 30, sc_core::SC_NS);\n\t\t} else {  // Data region\n\t\t\tassert(mTargetBlock.asInt < mDeviceNumBlocks.asInt && \"Access Flash out of bounds!\");\n\n\t\t\tblockBuf->setPos(mTargetBlock.asInt);  // Loads Block into buffer\n\t\t\tif (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\t\t\tblockBuf->setData(ptr, addr - DATA_ADDR, len);\n\t\t\t} else if (cmd == tlm::TLM_READ_COMMAND) {\n\t\t\t\tblockBuf->getData(ptr, addr - DATA_ADDR, len);\n\t\t\t} else {\n\t\t\t\tsc_assert(false && \"unsupported tlm command\");\n\t\t\t}\n\t\t\t// TODO: Add delay based on blockBuf cache\n\t\t\tdelay += sc_core::sc_time(len, sc_core::SC_US);\n\t\t}\n\t}\n};\n"
  },
  {
    "path": "vp/src/platform/basic/main.cpp",
    "content": "#include <cstdlib>\n#include <ctime>\n\n#include \"basic_timer.h\"\n#include \"core/common/clint.h\"\n#include \"display.hpp\"\n#include \"dma.h\"\n#include \"elf_loader.h\"\n#include \"ethernet.h\"\n#include \"fe310_plic.h\"\n#include \"flash.h\"\n#include \"debug_memory.h\"\n#include \"iss.h\"\n#include \"mem.h\"\n#include \"memory.h\"\n#include \"memory_mapped_file.h\"\n#include \"sensor.h\"\n#include \"sensor2.h\"\n#include \"syscall.h\"\n#include \"uart.h\"\n#include \"util/options.h\"\n#include \"platform/common/options.h\"\n#include \"platform/common/terminal.h\"\n#include \"gdb-mc/gdb_server.h\"\n#include \"gdb-mc/gdb_runner.h\"\n\n#include <boost/io/ios_state.hpp>\n#include <boost/program_options.hpp>\n#include <iomanip>\n#include <iostream>\n\n\nusing namespace rv32;\nnamespace po = boost::program_options;\n\nclass BasicOptions : public Options {\npublic:\n\ttypedef unsigned int addr_t;\n\n\tstd::string mram_image;\n\tstd::string flash_device;\n\tstd::string network_device;\n\tstd::string test_signature;\n\n\taddr_t mem_size = 1024 * 1024 * 32;  // 32 MB ram, to place it before the CLINT and run the base examples (assume\n\t                                     // memory start at zero) without modifications\n\taddr_t mem_start_addr = 0x00000000;\n\taddr_t mem_end_addr = mem_start_addr + mem_size - 1;\n\taddr_t clint_start_addr = 0x02000000;\n\taddr_t clint_end_addr = 0x0200ffff;\n\taddr_t sys_start_addr = 0x02010000;\n\taddr_t sys_end_addr = 0x020103ff;\n\taddr_t term_start_addr = 0x20000000;\n\taddr_t term_end_addr = term_start_addr + 16;\n\taddr_t uart_start_addr = 0x20010000;\n\taddr_t uart_end_addr = uart_start_addr + 0xfff;\n\taddr_t ethernet_start_addr = 0x30000000;\n\taddr_t ethernet_end_addr = ethernet_start_addr + 1500;\n\taddr_t plic_start_addr = 0x40000000;\n\taddr_t plic_end_addr = 0x41000000;\n\taddr_t sensor_start_addr = 0x50000000;\n\taddr_t sensor_end_addr = 0x50001000;\n\taddr_t sensor2_start_addr = 0x50002000;\n\taddr_t sensor2_end_addr = 0x50004000;\n\taddr_t mram_start_addr = 0x60000000;\n\taddr_t mram_size = 0x10000000;\n\taddr_t mram_end_addr = mram_start_addr + mram_size - 1;\n\taddr_t dma_start_addr = 0x70000000;\n\taddr_t dma_end_addr = 0x70001000;\n\taddr_t flash_start_addr = 0x71000000;\n\taddr_t flash_end_addr = flash_start_addr + Flashcontroller::ADDR_SPACE;  // Usually 528 Byte\n\taddr_t display_start_addr = 0x72000000;\n\taddr_t display_end_addr = display_start_addr + Display::addressRange;\n\n\tbool quiet = false;\n\tbool use_E_base_isa = false;\n\n\tOptionValue<unsigned long> entry_point;\n\n\tBasicOptions(void) {\n        \t// clang-format off\n\t\tadd_options()\n\t\t\t(\"quiet\", po::bool_switch(&quiet), \"do not output register values on exit\")\n\t\t\t(\"memory-start\", po::value<unsigned int>(&mem_start_addr),\"set memory start address\")\n\t\t\t(\"memory-size\", po::value<unsigned int>(&mem_size), \"set memory size\")\n\t\t\t(\"use-E-base-isa\", po::bool_switch(&use_E_base_isa), \"use the E instead of the I integer base ISA\")\n\t\t\t(\"entry-point\", po::value<std::string>(&entry_point.option),\"set entry point address (ISS program counter)\")\n\t\t\t(\"mram-image\", po::value<std::string>(&mram_image)->default_value(\"\"),\"MRAM image file for persistency\")\n\t\t\t(\"mram-image-size\", po::value<unsigned int>(&mram_size), \"MRAM image size\")\n\t\t\t(\"flash-device\", po::value<std::string>(&flash_device)->default_value(\"\"),\"blockdevice for flash emulation\")\n\t\t\t(\"network-device\", po::value<std::string>(&network_device)->default_value(\"\"),\"name of the tap network adapter, e.g. /dev/tap6\")\n\t\t\t(\"signature\", po::value<std::string>(&test_signature)->default_value(\"\"),\"output filename for the test execution signature\");\n        \t// clang-format on\n\t};\n\n\tvoid printValues(std::ostream& os) const override {\n\t\tos << std::hex;\n\t\tos << \"mem_start_addr:\\t\" << +mem_start_addr << std::endl;\n\t\tos << \"mem_end_addr:\\t\"   << +mem_end_addr   << std::endl;\n\t\tstatic_cast <const Options&>( *this ).printValues(os);\n\t}\n\n\tvoid parse(int argc, char **argv) override {\n\t\tOptions::parse(argc, argv);\n\n\t\tentry_point.finalize(parse_ulong_option);\n\t\tmem_end_addr = mem_start_addr + mem_size - 1;\n\t\tassert((mem_end_addr < clint_start_addr || mem_start_addr > display_end_addr) &&\n\t\t       \"RAM too big, would overlap memory\");\n\t\tmram_end_addr = mram_start_addr + mram_size - 1;\n\t\tassert(mram_end_addr < dma_start_addr && \"MRAM too big, would overlap memory\");\n\t}\n};\n\n\nint sc_main(int argc, char **argv) {\n\tBasicOptions opt;\n\topt.parse(argc, argv);\n\n\tstd::srand(std::time(nullptr));  // use current time as seed for random generator\n\n\ttlm::tlm_global_quantum::instance().set(sc_core::sc_time(opt.tlm_global_quantum, sc_core::SC_NS));\n\n\tISS core(0, opt.use_E_base_isa);\n\tSimpleMemory mem(\"SimpleMemory\", opt.mem_size);\n\tSimpleTerminal term(\"SimpleTerminal\");\n\tUART uart(\"Generic_UART\", 6);\n\tELFLoader loader(opt.input_program.c_str());\n\tSimpleBus<3, 13> bus(\"SimpleBus\");\n\tCombinedMemoryInterface iss_mem_if(\"MemoryInterface\", core);\n\tSyscallHandler sys(\"SyscallHandler\");\n\tFE310_PLIC<1, 64, 96, 32> plic(\"PLIC\");\n\tCLINT<1> clint(\"CLINT\");\n\tSimpleSensor sensor(\"SimpleSensor\", 2);\n\tSimpleSensor2 sensor2(\"SimpleSensor2\", 5);\n\tBasicTimer timer(\"BasicTimer\", 3);\n\tMemoryMappedFile mram(\"MRAM\", opt.mram_image, opt.mram_size);\n\tSimpleDMA dma(\"SimpleDMA\", 4);\n\tFlashcontroller flashController(\"Flashcontroller\", opt.flash_device);\n\tEthernetDevice ethernet(\"EthernetDevice\", 7, mem.data, opt.network_device);\n\tDisplay display(\"Display\");\n\tDebugMemoryInterface dbg_if(\"DebugMemoryInterface\");\n\n\tMemoryDMI dmi = MemoryDMI::create_start_size_mapping(mem.data, opt.mem_start_addr, mem.size);\n\tInstrMemoryProxy instr_mem(dmi, core);\n\n\tstd::shared_ptr<BusLock> bus_lock = std::make_shared<BusLock>();\n\tiss_mem_if.bus_lock = bus_lock;\n\n\tinstr_memory_if *instr_mem_if = &iss_mem_if;\n\tdata_memory_if *data_mem_if = &iss_mem_if;\n\tif (opt.use_instr_dmi)\n\t\tinstr_mem_if = &instr_mem;\n\tif (opt.use_data_dmi) {\n\t\tiss_mem_if.dmi_ranges.emplace_back(dmi);\n\t}\n\n\tuint64_t entry_point = loader.get_entrypoint();\n\tif (opt.entry_point.available)\n\t\tentry_point = opt.entry_point.value;\n\ttry {\n\t\tloader.load_executable_image(mem, mem.size, opt.mem_start_addr);\n\t} catch(ELFLoader::load_executable_exception& e) {\n\t\tstd::cerr << e.what() << std::endl;\n\t\tstd::cerr << \"Memory map: \" << std::endl;\n\t\topt.printValues(std::cerr);\n\t\treturn -1;\n\t}\n\t/*\n\t * The rv32 calling convention defaults to 32 bit, but as this Config is\n\t * mainly used together with the syscall handler, this helps for certain floats.\n\t * https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc\n\t */\n\tcore.init(instr_mem_if, data_mem_if, &clint, entry_point, rv64_align_address(opt.mem_end_addr));\n\tsys.init(mem.data, opt.mem_start_addr, loader.get_heap_addr());\n\tsys.register_core(&core);\n\n\tif (opt.intercept_syscalls)\n\t\tcore.sys = &sys;\n\tcore.error_on_zero_traphandler = opt.error_on_zero_traphandler;\n\n\t// address mapping\n\t{\n\t\tunsigned it = 0;\n\t\tbus.ports[it++] = new PortMapping(opt.mem_start_addr, opt.mem_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.clint_start_addr, opt.clint_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.plic_start_addr, opt.plic_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.term_start_addr, opt.term_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.uart_start_addr, opt.uart_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.sensor_start_addr, opt.sensor_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.dma_start_addr, opt.dma_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.sensor2_start_addr, opt.sensor2_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.mram_start_addr, opt.mram_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.flash_start_addr, opt.flash_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.ethernet_start_addr, opt.ethernet_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.display_start_addr, opt.display_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.sys_start_addr, opt.sys_end_addr);\n\t}\n\n\t// connect TLM sockets\n\tiss_mem_if.isock.bind(bus.tsocks[0]);\n\tdbg_if.isock.bind(bus.tsocks[2]);\n\n\tPeripheralWriteConnector dma_connector(\"SimpleDMA-Connector\");  // to respect ISS bus locking\n\tdma_connector.isock.bind(bus.tsocks[1]);\n\tdma.isock.bind(dma_connector.tsock);\n\tdma_connector.bus_lock = bus_lock;\n\n\t{\n\t\tunsigned it = 0;\n\t\tbus.isocks[it++].bind(mem.tsock);\n\t\tbus.isocks[it++].bind(clint.tsock);\n\t\tbus.isocks[it++].bind(plic.tsock);\n\t\tbus.isocks[it++].bind(term.tsock);\n\t\tbus.isocks[it++].bind(uart.tsock);\n\t\tbus.isocks[it++].bind(sensor.tsock);\n\t\tbus.isocks[it++].bind(dma.tsock);\n\t\tbus.isocks[it++].bind(sensor2.tsock);\n\t\tbus.isocks[it++].bind(mram.tsock);\n\t\tbus.isocks[it++].bind(flashController.tsock);\n\t\tbus.isocks[it++].bind(ethernet.tsock);\n\t\tbus.isocks[it++].bind(display.tsock);\n\t\tbus.isocks[it++].bind(sys.tsock);\n\t}\n\n\t// connect interrupt signals/communication\n\tplic.target_harts[0] = &core;\n\tclint.target_harts[0] = &core;\n\tsensor.plic = &plic;\n\tdma.plic = &plic;\n\ttimer.plic = &plic;\n\tsensor2.plic = &plic;\n\tethernet.plic = &plic;\n\n\tstd::vector<debug_target_if *> threads;\n\tthreads.push_back(&core);\n\n\tcore.trace = opt.trace_mode;  // switch for printing instructions\n\tif (opt.use_debug_runner) {\n\t\tauto server = new GDBServer(\"GDBServer\", threads, &dbg_if, opt.debug_port);\n\t\tnew GDBServerRunner(\"GDBRunner\", server, &core);\n\t} else {\n\t\tnew DirectCoreRunner(core);\n\t}\n\n\tif (opt.quiet)\n\t\tsc_core::sc_report_handler::set_verbosity_level(sc_core::SC_NONE);\n\tsc_core::sc_start();\n\tif (!opt.quiet)\n\t\tcore.show();\n\n\tif (opt.test_signature != \"\") {\n\t\tauto begin_sig = loader.get_begin_signature_address();\n\t\tauto end_sig = loader.get_end_signature_address();\n\n\t\t{\n\t\t\tboost::io::ios_flags_saver ifs(cout);\n\t\t\tstd::cout << std::hex;\n\t\t\tstd::cout << \"begin_signature: \" << begin_sig << std::endl;\n\t\t\tstd::cout << \"end_signature: \" << end_sig << std::endl;\n\t\t\tstd::cout << \"signature output file: \" << opt.test_signature << std::endl;\n\t\t}\n\n\t\tassert(end_sig >= begin_sig);\n\t\tassert(begin_sig >= opt.mem_start_addr);\n\n\t\tauto begin = begin_sig - opt.mem_start_addr;\n\t\tauto end = end_sig - opt.mem_start_addr;\n\n\t\tofstream sigfile(opt.test_signature, ios::out);\n\n\t\tauto n = begin;\n\t\twhile (n < end) {\n\t\t\tsigfile << std::hex << std::setw(2) << std::setfill('0') << (unsigned)mem.data[n];\n\t\t\t++n;\n\t\t}\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "vp/src/platform/basic/random_source.h",
    "content": "#ifndef RISCV_ISA_RANDOM_SOURCE_H\n#define RISCV_ISA_RANDOM_SOURCE_H\n\n#include <cstdlib>\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\nstruct RandomSource : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<RandomSource> tsock;\n\n\tRandomSource(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &RandomSource::transport);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tassert(trans.get_command() == tlm::TLM_READ_COMMAND);\n\n\t\tauto *p = trans.get_data_ptr();\n\t\tfor (unsigned i = 0; i < trans.get_data_length(); ++i) {\n\t\t\t*(p + i) = rand();\n\t\t}\n\t}\n};\n\n#endif  // RISCV_ISA_RANDOM_SOURCE_H\n"
  },
  {
    "path": "vp/src/platform/basic/sensor.h",
    "content": "#ifndef RISCV_ISA_SENSOR_H\n#define RISCV_ISA_SENSOR_H\n\n#include <cstdlib>\n#include <cstring>\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\n#include \"core/common/irq_if.h\"\n\nstruct SimpleSensor : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<SimpleSensor> tsock;\n\n\tinterrupt_gateway *plic = 0;\n\tuint32_t irq_number = 0;\n\tsc_core::sc_event run_event;\n\n\t// memory mapped data frame\n\tstd::array<uint8_t, 64> data_frame;\n\n\t// memory mapped configuration registers\n\tuint32_t scaler = 25;\n\tuint32_t filter = 0;\n\tstd::unordered_map<uint64_t, uint32_t *> addr_to_reg;\n\n\tenum {\n\t\tSCALER_REG_ADDR = 0x80,\n\t\tFILTER_REG_ADDR = 0x84,\n\t};\n\n\tSC_HAS_PROCESS(SimpleSensor);\n\n\tSimpleSensor(sc_core::sc_module_name, uint32_t irq_number) : irq_number(irq_number) {\n\t\ttsock.register_b_transport(this, &SimpleSensor::transport);\n\t\tSC_THREAD(run);\n\n\t\taddr_to_reg = {\n\t\t    {SCALER_REG_ADDR, &scaler},\n\t\t    {FILTER_REG_ADDR, &filter},\n\t\t};\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tauto addr = trans.get_address();\n\t\tauto cmd = trans.get_command();\n\t\tauto len = trans.get_data_length();\n\t\tauto ptr = trans.get_data_ptr();\n\n\t\tif (addr <= 63) {\n\t\t\t// access data frame\n\t\t\tassert(cmd == tlm::TLM_READ_COMMAND);\n\t\t\tassert((addr + len) <= data_frame.size());\n\n\t\t\t// return last generated random data at requested address\n\t\t\tmemcpy(ptr, &data_frame[addr], len);\n\t\t} else {\n\t\t\tassert(len == 4);  // NOTE: only allow to read/write whole register\n\n\t\t\tauto it = addr_to_reg.find(addr);\n\t\t\tassert(it != addr_to_reg.end());  // access to non-mapped address\n\n\t\t\t// trigger pre read/write actions\n\t\t\tif ((cmd == tlm::TLM_WRITE_COMMAND) && (addr == SCALER_REG_ADDR)) {\n\t\t\t\tuint32_t value = *((uint32_t *)ptr);\n\t\t\t\tif (value < 1 || value > 100)\n\t\t\t\t\treturn;  // ignore invalid values\n\t\t\t}\n\n\t\t\t// actual read/write\n\t\t\tif (cmd == tlm::TLM_READ_COMMAND) {\n\t\t\t\t*((uint32_t *)ptr) = *it->second;\n\t\t\t} else if (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\t\t\t*it->second = *((uint32_t *)ptr);\n\t\t\t} else {\n\t\t\t\tassert(false && \"unsupported tlm command for sensor access\");\n\t\t\t}\n\n\t\t\t// trigger post read/write actions\n\t\t\tif ((cmd == tlm::TLM_WRITE_COMMAND) && (addr == SCALER_REG_ADDR)) {\n\t\t\t\trun_event.cancel();\n\t\t\t\trun_event.notify(sc_core::sc_time(scaler, sc_core::SC_MS));\n\t\t\t}\n\t\t}\n\n\t\t(void)delay;  // zero delay\n\t}\n\n\tvoid run() {\n\t\twhile (true) {\n\t\t\trun_event.notify(sc_core::sc_time(scaler, sc_core::SC_MS));\n\t\t\tsc_core::wait(run_event);  // 40 times per second by default\n\n\t\t\t// fill with random data\n\t\t\tfor (auto &n : data_frame) {\n\t\t\t\tif (filter == 1) {\n\t\t\t\t\tn = rand() % 10 + 48;\n\t\t\t\t} else if (filter == 2) {\n\t\t\t\t\tn = rand() % 26 + 65;\n\t\t\t\t} else {\n\t\t\t\t\t// fallback for all other filter values\n\t\t\t\t\tn = rand() % 92 + 32;  // random printable char\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tplic->gateway_trigger_interrupt(irq_number);\n\t\t}\n\t}\n};\n\n#endif  // RISCV_ISA_SENSOR_H\n"
  },
  {
    "path": "vp/src/platform/basic/sensor2.h",
    "content": "#ifndef RISCV_ISA_SENSOR2_H\n#define RISCV_ISA_SENSOR2_H\n\n#include <cstdlib>\n#include <cstring>\n\n#include \"core/common/irq_if.h\"\n#include \"util/tlm_map.h\"\n\n/*\n * Provides the same functionality as sensor.h but uses the optional modelling\n * layer provided in util/tlm_map.h.\n */\n\nstruct SimpleSensor2 : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<SimpleSensor2> tsock;\n\n\tinterrupt_gateway *plic = 0;\n\tuint32_t irq_number = 0;\n\tsc_core::sc_event run_event;\n\n\t// memory mapped data frame\n\tstd::array<uint8_t, 64> data_frame;\n\n\t// memory mapped configuration registers\n\tuint32_t scaler = 25;\n\tuint32_t filter = 0;\n\n\tenum {\n\t\tSCALER_REG_ADDR = 0x80,\n\t\tFILTER_REG_ADDR = 0x84,\n\t};\n\n\tvp::map::LocalRouter router;\n\n\tSC_HAS_PROCESS(SimpleSensor2);\n\n\tSimpleSensor2(sc_core::sc_module_name, uint32_t irq_number) : irq_number(irq_number) {\n\t\ttsock.register_b_transport(this, &SimpleSensor2::transport);\n\t\tSC_THREAD(run);\n\n\t\trouter\n\t\t    .add_register_bank({\n\t\t        {SCALER_REG_ADDR, &scaler},\n\t\t        {FILTER_REG_ADDR, &filter},\n\t\t    })\n\t\t    .register_handler(this, &SimpleSensor2::register_access_callback);\n\n\t\trouter.add_start_size_mapping(0x00, data_frame.size(), vp::map::read_only)\n\t\t    .register_handler(this, &SimpleSensor2::data_frame_access_callback);\n\t}\n\n\tvoid data_frame_access_callback(tlm::tlm_generic_payload &trans, sc_core::sc_time) {\n\t\t// return last generated random data at requested address\n\t\tvp::map::execute_memory_access(trans, data_frame.data());\n\t}\n\n\tvoid register_access_callback(const vp::map::register_access_t &r) {\n\t\t// trigger pre read/write actions\n\t\tif (r.write && (r.vptr == &scaler)) {\n\t\t\tif (r.nv < 1 || r.nv > 100)\n\t\t\t\treturn;\n\t\t}\n\n\t\t// actual read/write\n\t\tr.fn();\n\n\t\t// trigger post read/write actions\n\t\tif (r.write && (r.vptr == &scaler)) {\n\t\t\trun_event.cancel();\n\t\t\trun_event.notify(sc_core::sc_time(scaler, sc_core::SC_MS));\n\t\t}\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\trouter.transport(trans, delay);\n\t}\n\n\tvoid run() {\n\t\twhile (true) {\n\t\t\trun_event.notify(sc_core::sc_time(scaler, sc_core::SC_MS));\n\t\t\tsc_core::wait(run_event);  // 40 times per second by default\n\n\t\t\t// fill with random data\n\t\t\tfor (auto &n : data_frame) {\n\t\t\t\tif (filter == 1) {\n\t\t\t\t\tn = rand() % 10 + 48;\n\t\t\t\t} else if (filter == 2) {\n\t\t\t\t\tn = rand() % 26 + 65;\n\t\t\t\t} else {\n\t\t\t\t\t// fallback for all other filter values\n\t\t\t\t\tn = rand();  // random char\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tplic->gateway_trigger_interrupt(irq_number);\n\t\t}\n\t}\n};\n\n#endif  // RISCV_ISA_SENSOR2_H\n"
  },
  {
    "path": "vp/src/platform/common/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_library(platform-common\n\t\tfe310_plic.cpp\n\t\tfu540_plic.cpp\n\t\tuart_if.cpp\n\t\tfd_abstract_uart.cpp\n\t\tslip.cpp\n\t\tuart.cpp\n\t\toptions.cpp\n\t\t${HEADERS})\n\ntarget_include_directories(platform-common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\ntarget_link_libraries(platform-common systemc)\n"
  },
  {
    "path": "vp/src/platform/common/async_event.h",
    "content": "/*****************************************************************************\n\n  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or\n  more contributor license agreements.  See the NOTICE file distributed\n  with this work for additional information regarding copyright ownership.\n  Accellera licenses this file to you under the Apache License, Version 2.0\n  (the \"License\"); you may not use this file except in compliance with the\n  License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n  implied.  See the License for the specific language governing\n  permissions and limitations under the License.\n\n *****************************************************************************/\n/*\n * thread_safe_event.h\n *\n * Copyright (C) 2017, GreenSocs Ltd.\n *\n * Developed by Mark Burton mark@greensocs.com\n */\n\n#pragma once\n#include <systemc>\n\nclass AsyncEvent : public sc_core::sc_prim_channel {\n\tsc_core::sc_time m_delay;\n\tsc_core::sc_event m_event;\n\n   public:\n\tAsyncEvent(const char* name = sc_core::sc_gen_unique_name(\"async_event\"))\n\t    : sc_core::sc_prim_channel(name), m_event((std::string(this->basename()) + \"_event\").c_str()) {\n\t\t// register this channel as \"suspending\", to not end the simulation\n\t\t// when we're running out of internal events\n\t\tasync_attach_suspending();\n\t}\n\n\t// THREADSAFE METHOD:\n\tvoid notify(sc_core::sc_time delay = sc_core::SC_ZERO_TIME) {\n\t\tm_delay = delay;\n\t\tasync_request_update();\n\t}\n\n\t// only allow waiting for the event\n\toperator const sc_core::sc_event&() const {\n\t\treturn m_event;\n\t}\n\n   protected:\n\tvoid update(void) {\n\t\t// we're in the update phase of the SystemC kernel (thread)\n\t\tm_event.notify(m_delay);\n\t}\n};\n"
  },
  {
    "path": "vp/src/platform/common/bus.h",
    "content": "#ifndef RISCV_ISA_BUS_H\n#define RISCV_ISA_BUS_H\n\n#include <tlm_utils/simple_initiator_socket.h>\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n\n#include <map>\n#include <stdexcept>\n#include <memory>\n\nstruct PortMapping {\n\tuint64_t start;\n\tuint64_t end;\n\n\tPortMapping(uint64_t start, uint64_t end) : start(start), end(end) {\n\t\tassert(end >= start);\n\t}\n\n\tbool contains(uint64_t addr) {\n\t\treturn addr >= start && addr <= end;\n\t}\n\n\tuint64_t global_to_local(uint64_t addr) {\n\t\treturn addr - start;\n\t}\n};\n\ntemplate <unsigned int NR_OF_INITIATORS, unsigned int NR_OF_TARGETS>\nstruct SimpleBus : sc_core::sc_module {\n\tstd::array<tlm_utils::simple_target_socket<SimpleBus>, NR_OF_INITIATORS> tsocks;\n\n\tstd::array<tlm_utils::simple_initiator_socket<SimpleBus>, NR_OF_TARGETS> isocks;\n\tstd::array<PortMapping *, NR_OF_TARGETS> ports;\n\n\tSimpleBus(sc_core::sc_module_name) {\n\t\tfor (auto &s : tsocks) {\n\t\t\ts.register_b_transport(this, &SimpleBus::transport);\n\t\t\ts.register_transport_dbg(this, &SimpleBus::transport_dbg);\n\t\t}\n\t}\n\n\tint decode(uint64_t addr) {\n\t\tfor (unsigned i = 0; i < NR_OF_TARGETS; ++i) {\n\t\t\tif (ports[i]->contains(addr))\n\t\t\t\treturn i;\n\t\t}\n\t\treturn -1;\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tauto addr = trans.get_address();\n\t\tauto id = decode(addr);\n\n\t\tif (id < 0) {\n\t\t\ttrans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);\n\t\t\treturn;\n\t\t}\n\n\t\ttrans.set_address(ports[id]->global_to_local(addr));\n\t\tisocks[id]->b_transport(trans, delay);\n\t}\n\n\tunsigned transport_dbg(tlm::tlm_generic_payload &trans) {\n\t\tauto addr = trans.get_address();\n\t\tauto id = decode(addr);\n\n\t\tif (id < 0) {\n\t\t\ttrans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);\n\t\t\treturn 0;\n\t\t}\n\n\t\ttrans.set_address(ports[id]->global_to_local(addr));\n\t\treturn isocks[id]->transport_dbg(trans);\n\t}\n};\n\n#include \"core/common/bus_lock_if.h\"\n\n/*\n * Use this adapter to attach peripherals with write access (e.g. DMA) to the bus.\n * This ensures that those peripherals do not violate the RISC-V LR/SC atomic semantic.\n */\nstruct PeripheralWriteConnector : sc_core::sc_module {\n\ttlm_utils::simple_target_socket<PeripheralWriteConnector> tsock;\n\ttlm_utils::simple_initiator_socket<PeripheralWriteConnector> isock;\n\tstd::shared_ptr<bus_lock_if> bus_lock;\n\n\tPeripheralWriteConnector(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &PeripheralWriteConnector::transport);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tbus_lock->wait_until_unlocked();\n\n\t\tisock->b_transport(trans, delay);\n\n\t\tif (trans.get_response_status() == tlm::TLM_ADDRESS_ERROR_RESPONSE)\n\t\t\tthrow std::runtime_error(\"unable to find target port for address \" + std::to_string(trans.get_address()));\n\t}\n};\n\nclass BusLock : public bus_lock_if {\n\tbool locked = false;\n\tunsigned owner = 0;\n\tsc_core::sc_event lock_event;\n\n   public:\n\tvirtual void lock(unsigned hart_id) override {\n\t\tif (locked && (hart_id != owner)) {\n\t\t\twait_until_unlocked();\n\t\t}\n\n\t\tassert(!locked || (hart_id == owner));\n\t\tlocked = true;\n\t\towner = hart_id;\n\t}\n\n\tvirtual void unlock(unsigned hart_id) override {\n\t\tif (locked && (owner == hart_id)) {\n\t\t\tlocked = false;\n\t\t\tlock_event.notify(sc_core::SC_ZERO_TIME);\n\t\t}\n\t}\n\n\tvirtual bool is_locked() override {\n\t\treturn locked;\n\t}\n\n\tvirtual bool is_locked(unsigned hart_id) override {\n\t\treturn locked && (owner == hart_id);\n\t}\n\n\tvirtual void wait_until_unlocked() override {\n\t\twhile (locked) sc_core::wait(lock_event);\n\t}\n};\n\n#endif  // RISCV_ISA_BUS_H\n"
  },
  {
    "path": "vp/src/platform/common/fd_abstract_uart.cpp",
    "content": "#include <fcntl.h>\n#include <poll.h>\n#include <semaphore.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <mutex>\n#include <queue>\n#include <thread>\n#include <err.h>\n\n#include \"fd_abstract_uart.h\"\n\n#define stop_fd (stop_pipe[0])\n#define newpollfd(FD) \\\n\t(struct pollfd){.fd = FD, .events = POLLIN | POLLERR, .revents = 0};\n\nFD_ABSTRACT_UART::FD_ABSTRACT_UART(sc_core::sc_module_name name, uint32_t irqsrc) : UART_IF(name, irqsrc) {\n\tstop = false;\n\tif (pipe(stop_pipe) == -1)\n\t\tthrow std::system_error(errno, std::generic_category());\n}\n\nFD_ABSTRACT_UART::~FD_ABSTRACT_UART(void) {\n\tclose(stop_pipe[0]);\n\tclose(stop_pipe[1]);\n}\n\nvoid FD_ABSTRACT_UART::start_threads(int fd, bool write_only) {\n\tfds[0] = newpollfd(stop_fd);\n\tfds[1] = newpollfd(fd);\n\n\tif (!write_only)\n\t\trcvthr = new std::thread(&FD_ABSTRACT_UART::receive, this);\n\ttxthr = new std::thread(&FD_ABSTRACT_UART::transmit, this);\n}\n\nvoid FD_ABSTRACT_UART::stop_threads(void) {\n\tstop = true;\n\n\tif (txthr) {\n\t\tspost(&txfull); // unblock transmit thread\n\t\ttxthr->join();\n\t\tdelete txthr;\n\t}\n\n\tif (rcvthr) {\n\t\tuint8_t byte = 0;\n\t\tif (write(stop_pipe[1], &byte, sizeof(byte)) == -1) // unblock receive thread\n\t\t\terr(EXIT_FAILURE, \"couldn't unblock uart receive thread\");\n\t\tspost(&rxempty); // unblock receive thread\n\t\trcvthr->join();\n\t\tdelete rcvthr;\n\t}\n}\n\nvoid FD_ABSTRACT_UART::transmit(void) {\n\tuint8_t data;\n\n\twhile (!stop) {\n\t\tdata = txpull();\n\t\tif(stop)\n\t\t\tbreak;\n\t\tasyncEvent.notify();\n\t\twrite_data(data);\n\t}\n}\n\nvoid FD_ABSTRACT_UART::receive(void) {\n\twhile (!stop) {\n\t\tif (poll(fds, (nfds_t)NFDS, -1) == -1)\n\t\t\tthrow std::system_error(errno, std::generic_category());\n\n\t\t/* stop_fd is checked first as it is fds[0] */\n\t\tfor (size_t i = 0; i < NFDS; i++) {\n\t\t\tint fd = fds[i].fd;\n\t\t\tshort ev = fds[i].revents;\n\n\t\t\tif (ev & POLLERR) {\n\t\t\t\tthrow std::runtime_error(\"received unexpected POLLERR\");\n\t\t\t} else if (ev & POLLIN) {\n\t\t\t\tif (fd == stop_fd)\n\t\t\t\t\tbreak;\n\t\t\t\telse\n\t\t\t\t\thandle_input(fd);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vp/src/platform/common/fd_abstract_uart.h",
    "content": "#pragma once\n\n#include <stdint.h>\n#include <poll.h>\n#include <semaphore.h>\n#include <stdbool.h>\n\n#include <thread>\n\n#include \"uart_if.h\"\n\nclass FD_ABSTRACT_UART : public UART_IF {\npublic:\n\tFD_ABSTRACT_UART(sc_core::sc_module_name, uint32_t);\n\tvirtual ~FD_ABSTRACT_UART(void);\n\nprotected:\n\tvoid start_threads(int fd, bool write_only = false);\n\tvoid stop_threads(void);\n\nprivate:\n\tvirtual void write_data(uint8_t) = 0;\n\tvirtual void handle_input(int fd) = 0;\n\n\tvoid transmit();\n\tvoid receive();\n\n\tstd::thread *rcvthr = NULL, *txthr = NULL;\n\n\tbool stop;\n\tint stop_pipe[2];\n\n\tenum {\n\t\tNFDS = 2,\n\t};\n\tstruct pollfd fds[NFDS];\n};\n"
  },
  {
    "path": "vp/src/platform/common/fe310_plic.cpp",
    "content": "#include \"fe310_plic.h\"\n"
  },
  {
    "path": "vp/src/platform/common/fe310_plic.h",
    "content": "#pragma once\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n\n#include \"core/common/irq_if.h\"\n#include \"util/memory_map.h\"\n#include \"util/tlm_map.h\"\n\nstatic constexpr bool trace_mode = false;\n\n/**\n * This class is supposed to implement the PLIC defined in Chapter 10\n * of the FE310-G000 manual. Currently, it still has various differences\n * from the version documented in the manual.\n */\ntemplate <unsigned NumberCores, unsigned NumberInterrupts, unsigned NumberInterruptEntries, uint32_t MaxPriority>\nstruct FE310_PLIC : public sc_core::sc_module, public interrupt_gateway {\n\tstatic_assert(NumberInterrupts <= 4096, \"out of bound\");\n\tstatic_assert(NumberCores <= 15360, \"out of bound\");\n\tstatic constexpr unsigned WORDS_FOR_INTERRUPT_ENTRIES = (NumberInterruptEntries+(32-1))/32;\n\n\ttlm_utils::simple_target_socket<FE310_PLIC> tsock;\n\n\tstd::array<external_interrupt_target *, NumberCores> target_harts{};\n\n\t// shared for all harts priority 1 is the lowest. Zero means do not interrupt\n\t// NOTE: addressing starts at 0x4 because interrupt 0 is reserved, however some example SW still writes to address\n\t// 0x0, hence we added it to the address map\n\tRegisterRange regs_interrupt_priorities{0x0, sizeof(uint32_t) * (NumberInterrupts + 1)};\n\tArrayView<uint32_t> interrupt_priorities{regs_interrupt_priorities};\n\n\tRegisterRange regs_pending_interrupts{0x1000, sizeof(uint32_t) * WORDS_FOR_INTERRUPT_ENTRIES};\n\tArrayView<uint32_t> pending_interrupts{regs_pending_interrupts};\n\n\tstruct HartConfig {\n\t\tuint32_t priority_threshold;\n\t\tuint32_t claim_response;\n\t};\n\tRegisterRange regs_hart_enabled_interrupts{0x2000, sizeof(uint32_t) * WORDS_FOR_INTERRUPT_ENTRIES * NumberCores};\n\tArrayView<uint32_t> hart_enabled_interrupts{regs_hart_enabled_interrupts};\n\n\tRegisterRange regs_hart_config{0x200000, sizeof(HartConfig) * NumberCores};\n\tArrayView<HartConfig> hart_config{regs_hart_config};\n\n\tstd::vector<RegisterRange *> register_ranges{&regs_interrupt_priorities,\n\t                                             &regs_pending_interrupts,\n\t                                             &regs_hart_enabled_interrupts,\n\t                                             &regs_hart_config\n\t};\n\n\tPrivilegeLevel irq_level;\n\tstd::array<bool, NumberCores> hart_eip{};\n\n\tsc_core::sc_event e_run;\n\tsc_core::sc_time clock_cycle;\n\n\tSC_HAS_PROCESS(FE310_PLIC);\n\n\tFE310_PLIC(sc_core::sc_module_name, PrivilegeLevel level = MachineMode) {\n\t\tclock_cycle = sc_core::sc_time(10, sc_core::SC_NS);\n\t\ttsock.register_b_transport(this, &FE310_PLIC::transport);\n\n\t\tregs_pending_interrupts.readonly = true;\n\t\tregs_hart_config.alignment = 4;\n\n\t\tregs_interrupt_priorities.post_write_callback =\n\t\t    std::bind(&FE310_PLIC::post_write_interrupt_priorities, this, std::placeholders::_1);\n\t\tregs_hart_config.post_write_callback = std::bind(&FE310_PLIC::post_write_hart_config, this, std::placeholders::_1);\n\t\tregs_hart_config.pre_read_callback = std::bind(&FE310_PLIC::pre_read_hart_config, this, std::placeholders::_1);\n\t\t\n\t\tif (trace_mode) {\n\t\t    regs_hart_enabled_interrupts.post_write_callback = [this](RegisterRange::WriteInfo t){\n\t\t\t    std::cout << \"[vp::plic] Wrote enabled_interrupts at offs +\" << std::dec << t.addr << \" value 0x\" << std::hex << *reinterpret_cast<uint32_t*>(t.trans.get_data_ptr()) << std::dec << std::endl;\n\t\t\t    for (unsigned n = 0; n < NumberCores; ++n) {\n\t\t\t\t    for (unsigned i = 0; i < WORDS_FOR_INTERRUPT_ENTRIES; ++i) {\n\t\t\t\t\t    const uint32_t itr_group = hart_enabled_interrupts(n, i);\n\t\t\t\t\t    if(itr_group) {\n\t\t\t\t\t\t    for(unsigned b = 0; b < 32; b++) {\n\t\t\t\t\t\t\t    if((1 << b) & itr_group) {\n        \t\t\t\t\t\t\tstd::cout << \"[vp::plic]\\t Hart \" << n << \" ITR \" << i*32 + b << \" enabled.\" << std::dec << std::endl;\n\t\t\t\t\t\t\t    }\n\t\t\t\t\t\t    }\n\t\t\t\t\t    }\n\t\t\t\t    }\n\t\t\t    }\n\t\t    };\n\t    }\n\t\t\n\t\tfor (unsigned i = 0; i < NumberInterrupts; ++i) {\n\t\t\tinterrupt_priorities[i] = 0;\n\t\t}\n\n\t\tfor (unsigned n = 0; n < NumberCores; ++n) {\n\t\t    target_harts[n] = nullptr;\n\t\t\thart_eip[n] = false;\n\t\t\tfor (unsigned i = 0; i < WORDS_FOR_INTERRUPT_ENTRIES; ++i) {\n\t\t\t\thart_enabled_interrupts(n, i) = 0;  // all interrupts disabled by default\n\t\t\t}\n\t\t}\n\n\t\tirq_level = level;\n\t\tSC_THREAD(run);\n\t}\n\n\tvoid gateway_trigger_interrupt(uint32_t irq_id) {\n\t\t// NOTE: can use different techniques for each gateway, in this case a\n\t\t// simple non queued edge trigger\n\t\tassert(irq_id > 0 && irq_id < NumberInterrupts);\n\t\t//std::cout << \"[vp::plic] incoming interrupt \" << irq_id << std::endl;\n\n\t\tunsigned idx = irq_id / 32;\n\t\tunsigned off = irq_id % 32;\n\n\t\tpending_interrupts[idx] |= 1 << off;\n\n\t\te_run.notify(clock_cycle);\n\t}\n\n\tvoid clear_pending_interrupt(unsigned irq_id) {\n\t\tassert(irq_id < NumberInterrupts);  // NOTE: ignore clear of zero interrupt (zero is not available)\n\t\tif (trace_mode)  std::cout << \"[vp::plic] clear pending interrupt \" << irq_id << std::endl;\n\n\t\tunsigned idx = irq_id / 32;\n\t\tunsigned off = irq_id % 32;\n\n\t\tpending_interrupts[idx] &= ~(1 << off);\n\t}\n\n\tunsigned hart_get_next_pending_interrupt(unsigned hart_id, bool consider_threshold) {\n\t\tunsigned min_id = 0;\n\t\tunsigned max_priority = 0;\n\n\t\tfor (unsigned i = 1; i < NumberInterrupts; ++i) {\n\t\t\tunsigned idx = i / 32;\n\t\t\tunsigned off = i % 32;\n\n\t\t\tif (hart_enabled_interrupts(hart_id, idx) & (1 << off)) {\n\t\t\t\tif (trace_mode) std::cout << \"[vp::plic] hart \" << hart_id << \" has enabled ITR \" << i << std::endl;\n\t\t\t\tif (pending_interrupts[idx] & (1 << off)) {\n\t\t\t\t\tauto prio = interrupt_priorities[i];\n\t\t\t\t\tif (trace_mode) std::cout << \"[vp::plic] .. and it is pending with priority \" << prio << std::endl;\n\t\t\t\t\tif (prio > 0 && (!consider_threshold || (prio > hart_config[hart_id].priority_threshold))) {\n\t\t\t\t\t\tif (trace_mode) std::cout << \"[vp::plic]   .. which is greater than the hart's threshold of \" << hart_config[hart_id].priority_threshold << std::endl;\n\t\t\t\t\t\tif (prio > max_priority) {\n\t\t\t\t\t\t\tmax_priority = prio;\n\t\t\t\t\t\t\tmin_id = i;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn min_id;\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tdelay += 4 * clock_cycle;\n\t\t//std::cout << \"[vp::plic] Writing at 0x\" << trans.get_address() << \" value 0x\" << *reinterpret_cast<uint32_t*>(trans.get_data_ptr()) << std::endl;\n\t\tvp::mm::route(\"FE310_PLIC\", register_ranges, trans, delay);\n\t}\n\n\tvoid post_write_interrupt_priorities(RegisterRange::WriteInfo) {\n\t\tif (trace_mode) std::cout << \"[vp::plic] wrote ITR priority:\" << std::endl;\n\t\tunsigned i = 0;\n\t\tfor (auto &x : interrupt_priorities) {\n\t\t\tx = std::min(x, MaxPriority);\n\t\t\tif (trace_mode) if(x) std::cout << \"[vp::plic]\\t Prio for ITR nr. \" << i << \": \" << x << std::endl;\n\t\t\ti++;\n\t\t}\n\t}\n\n\tbool pre_read_hart_config(RegisterRange::ReadInfo t) {\n\t\tassert(t.addr % 4 == 0);\n\t\tunsigned idx = t.addr / 4;\n\n\t\tif ((idx % 2) == 1) {\n\t\t\t// access is directed to claim response register\n\t\t\tassert(t.size == 4);\n\t\t\t--idx;\n\n\t\t\tunsigned min_id = hart_get_next_pending_interrupt(0, false);\n\t\t\thart_config[idx].claim_response = min_id;\n\t\t\tclear_pending_interrupt(min_id);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tvoid post_write_hart_config(RegisterRange::WriteInfo t) {\n\t\tassert(t.addr % 4 == 0);\n\t\tunsigned idx = t.addr / 4;\n\n\t\tif ((idx % 2) == 1) {\n\t\t\t// access is directed to claim response register\n\t\t\tassert(t.size == 4);\n\t\t\t--idx;\n\t\t\tif (trace_mode) std::cout << \"[vp::plic] wrote ITR claim/response\" << std::endl;\n\n\t\t\tif (hart_has_pending_enabled_interrupts(idx)) {\n\t\t\t\tassert(hart_eip[idx]);\n\t\t\t\t// trigger again to make this work even if the SW clears the harts interrupt pending bit\n\t\t\t\ttarget_harts[idx]->trigger_external_interrupt(irq_level);\n\t\t\t} else {\n\t\t\t\thart_eip[idx] = false;\n\t\t\t\ttarget_harts[idx]->clear_external_interrupt(irq_level);\n\t\t\t\t if (trace_mode) std::cout << \"[vp::plic] clear eip\" << std::endl;\n\t\t\t}\n\t\t} else {\n\t\t\tif (trace_mode) std::cout << \"[vp::plic] wrote ITR priority threshold 0x\" << std::hex << *reinterpret_cast<uint32_t*>(t.trans.get_data_ptr()) << \" for hart \" << idx/2 << std::dec << std::endl;\n\t\t}\n\t}\n\n\tbool hart_has_pending_enabled_interrupts(unsigned hart_id) {\n\t\treturn hart_get_next_pending_interrupt(hart_id, true) > 0;\n\t}\n\n\tvoid run() {\n\t\twhile (true) {\n\t\t\tsc_core::wait(e_run);\n\n\t\t\tfor (unsigned i = 0; i < NumberCores; ++i) {\n\t\t\t\tif (!hart_eip[i]) {\n\t\t\t\t\tif (hart_has_pending_enabled_interrupts(i)) {\n\t\t\t\t\t\tif (trace_mode) std::cout << \"[vp::plic] trigger interrupt \" << hart_get_next_pending_interrupt(i, true) << std::hex << std::endl;\n\t\t\t\t\t\thart_eip[i] = true;\n\t\t\t\t\t\ttarget_harts[i]->trigger_external_interrupt(irq_level);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n}\n};\n"
  },
  {
    "path": "vp/src/platform/common/fu540_plic.cpp",
    "content": "#include <assert.h>\n#include <stdint.h>\n#include <stddef.h>\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n\n#include \"core/common/irq_if.h\"\n#include \"util/memory_map.h\"\n#include \"util/tlm_map.h\"\n#include \"fu540_plic.h\"\n\ninline uint32_t GET_IDX(uint32_t& irq) { return irq / 32; }\ninline uint32_t GET_OFF(uint32_t& irq) { return 1 << irq % 32; }\n\n/**\n * TODO: Ensure that irq 0 is hardwired to zero\n * TODO: FE310 raises external interrupt during interrupt completion\n */\n\nstatic void assert_addr(size_t start, size_t end, RegisterRange *range) {\n\tassert(range->start == start && range->end + 1 == end + sizeof(uint32_t));\n}\n\nFU540_PLIC::FU540_PLIC(sc_core::sc_module_name, unsigned harts) {\n\ttarget_harts = std::vector<external_interrupt_target *>(harts, NULL);\n\n\t/* Values copied from FE310_PLIC */\n\tclock_cycle = sc_core::sc_time(10, sc_core::SC_NS);\n\n\tcreate_registers();\n\ttsock.register_b_transport(this, &FU540_PLIC::transport);\n\n\tSC_THREAD(run);\n};\n\nvoid FU540_PLIC::create_registers(void) {\n\tregs_interrupt_priorities.post_write_callback =\n\t\tstd::bind(&FU540_PLIC::write_irq_prios, this, std::placeholders::_1);\n\n\t/* make pending interrupts read-only */\n\tregs_pending_interrupts.pre_write_callback =\n\t\t[] (RegisterRange::WriteInfo) { return false; };\n\n\t/* The priorities end address, as documented in the FU540-C000\n\t * manual, is incorrect <https://github.com/riscv/opensbi/pull/138> */\n\tassert_addr(0x4, 0xD4, &regs_interrupt_priorities);\n\tassert_addr(0x1000, 0x1004, &regs_pending_interrupts);\n\n\tregister_ranges.push_back(&regs_interrupt_priorities);\n\tregister_ranges.push_back(&regs_pending_interrupts);\n\n\t/* create IRQ enable and context registers */\n\tcreate_hart_regs(ENABLE_BASE, ENABLE_PER_HART, enabled_irqs);\n\tcreate_hart_regs(CONTEXT_BASE, CONTEXT_PER_HART, hart_context);\n\n\t/* only supports \"naturally aligned 32-bit memory accesses\" */\n\tfor (size_t i = 0; i < register_ranges.size(); i++)\n\t\tregister_ranges[i]->alignment = sizeof(uint32_t);\n}\n\nvoid FU540_PLIC::create_hart_regs(uint64_t addr, uint64_t inc, hartmap &map) {\n\tauto add_reg = [this, addr] (unsigned int h, PrivilegeLevel l, uint64_t a) {\n\t\tRegisterRange *r = new RegisterRange(a, HART_REG_SIZE);\n\t\tif (addr == CONTEXT_BASE) {\n\t\t\tr->pre_read_callback = std::bind(&FU540_PLIC::read_hartctx, this, std::placeholders::_1, h, l);\n\t\t\tr->post_write_callback = std::bind(&FU540_PLIC::write_hartctx, this, std::placeholders::_1, h, l);\n\t\t}\n\n\t\tregister_ranges.push_back(r);\n\t\treturn r;\n\t};\n\n\tfor (size_t i = 0; i < target_harts.size(); i++) {\n\t\tRegisterRange *mreg, *sreg;\n\n\t\tmreg = add_reg(i, MachineMode, addr);\n\t\tsreg = mreg; /* for hart0 */\n\n\t\tif (i != 0) { /* hart 0 only supports m-mode interrupts */\n\t\t\taddr += inc;\n\t\t\tsreg = add_reg(i, SupervisorMode, addr);\n\t\t}\n\n\t\tmap[i] = new HartConfig(*mreg, *sreg);\n\t\taddr += inc;\n\t}\n}\n\nvoid FU540_PLIC::transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\tdelay += 4 * clock_cycle; /* copied from FE310_PLIC */\n\tvp::mm::route(\"FU540_PLIC\", register_ranges, trans, delay);\n};\n\nvoid FU540_PLIC::gateway_trigger_interrupt(uint32_t irq) {\n\tif (irq == 0 || irq > NUMIRQ)\n\t\tthrow std::invalid_argument(\"IRQ value is invalid\");\n\n\tpending_interrupts[GET_IDX(irq)] |= GET_OFF(irq);\n\te_run.notify(clock_cycle);\n};\n\nbool FU540_PLIC::read_hartctx(RegisterRange::ReadInfo t, unsigned int hart, PrivilegeLevel level) {\n\tassert(t.addr % sizeof(uint32_t) == 0);\n\tassert(t.size == sizeof(uint32_t));\n\n\tif (is_claim_access(t.addr)) {\n\t\tunsigned int irq = next_pending_irq(hart, level, true);\n\n\t\t/* if there is no pending irq zero needs to be written\n\t\t * to the claim register. next_pending_irq returns 0 in\n\t\t * this case so no special handling required. */\n\n\t\tswitch (level) {\n\t\tcase MachineMode:\n\t\t\thart_context[hart]->m_mode[1] = irq;\n\t\t\tbreak;\n\t\tcase SupervisorMode:\n\t\t\thart_context[hart]->s_mode[1] = irq;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tassert(0);\n\t\t\tbreak;\n\t\t}\n\n\t\t/* successful claim also clears the pending bit */\n\t\tif (irq != 0)\n\t\t\tclear_pending(irq);\n\t}\n\n\treturn true;\n}\n\nvoid FU540_PLIC::write_hartctx(RegisterRange::WriteInfo t, unsigned int hart, PrivilegeLevel level) {\n\tassert(t.addr % sizeof(uint32_t) == 0);\n\tassert(t.size == sizeof(uint32_t));\n\n\tif (is_claim_access(t.addr)) {\n\t\ttarget_harts[hart]->clear_external_interrupt(level);\n\t} else { /* access to priority threshold */\n\t\tuint32_t *thr;\n\n\t\tswitch (level) {\n\t\tcase MachineMode:\n\t\t\tthr = &hart_context[hart]->m_mode[0];\n\t\t\tbreak;\n\t\tcase SupervisorMode:\n\t\t\tthr = &hart_context[hart]->s_mode[0];\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tassert(0);\n\t\t\tbreak;\n\t\t}\n\n\t\t*thr = std::min(*thr, uint32_t(MAX_THR));\n\t}\n}\n\nvoid FU540_PLIC::write_irq_prios(RegisterRange::WriteInfo t) {\n\tsize_t idx = t.addr / sizeof(uint32_t);\n\tassert(idx <= NUMIRQ);\n\n\tauto &elem = interrupt_priorities[idx];\n\telem = std::min(elem, uint32_t(MAX_PRIO));\n}\n\nvoid FU540_PLIC::run(void) {\n\tfor (;;) {\n\t\tsc_core::wait(e_run);\n\n\t\tfor (size_t i = 0; i < target_harts.size(); i++) {\n\t\t\tPrivilegeLevel lvl;\n\t\t\tif (has_pending_irq(i, &lvl)) {\n\t\t\t\ttarget_harts[i]->trigger_external_interrupt(lvl);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/* Returns next enabled pending interrupt with highest priority */\nunsigned int FU540_PLIC::next_pending_irq(unsigned int hart, PrivilegeLevel lvl, bool ignth) {\n\tassert(!(hart == 0 && lvl == SupervisorMode));\n\n\tHartConfig *conf = enabled_irqs[hart];\n\tunsigned int selirq = 0, maxpri = 0;\n\n\tfor (unsigned irq = 1; irq <= NUMIRQ; irq++) {\n\t\tif (!conf->is_enabled(irq, lvl) || !is_pending(irq))\n\t\t\tcontinue;\n\n\t\tuint32_t prio = interrupt_priorities[irq - 1];\n\t\tif (!ignth && prio <= get_threshold(hart, lvl))\n\t\t\tcontinue;\n\n\t\tif (prio > maxpri) {\n\t\t\tmaxpri = prio;\n\t\t\tselirq = irq;\n\t\t}\n\t}\n\n\treturn selirq;\n}\n\nbool FU540_PLIC::has_pending_irq(unsigned int hart, PrivilegeLevel *level) {\n\tif (hart != 0 && next_pending_irq(hart, SupervisorMode, false) > 0) {\n\t\t*level = SupervisorMode;\n\t\treturn true;\n\t} else if (next_pending_irq(hart, MachineMode, false) > 0) {\n\t\t*level = MachineMode;\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n}\n\nuint32_t FU540_PLIC::get_threshold(unsigned int hart, PrivilegeLevel level) {\n\tif (hart == 0 && level == SupervisorMode)\n\t\tthrow std::invalid_argument(\"hart0 doesn't support SupervisorMode\");\n\n\tHartConfig *conf = hart_context[hart];\n\tswitch (level) {\n\tcase MachineMode:\n\t\treturn conf->m_mode[0];\n\t\tbreak;\n\tcase SupervisorMode:\n\t\treturn conf->s_mode[0];\n\t\tbreak;\n\tdefault:\n\t\tthrow std::invalid_argument(\"Invalid PrivilegeLevel\");\n\t}\n}\n\nvoid FU540_PLIC::clear_pending(unsigned int irq) {\n\tassert(irq > 0 && irq <= NUMIRQ);\n\tpending_interrupts[GET_IDX(irq)] &= ~(GET_OFF(irq));\n}\n\nbool FU540_PLIC::is_pending(unsigned int irq) {\n\tassert(irq > 0 && irq <= NUMIRQ);\n\treturn pending_interrupts[GET_IDX(irq)] & GET_OFF(irq);\n}\n\nbool FU540_PLIC::is_claim_access(uint64_t addr) {\n\tunsigned idx = addr / sizeof(uint32_t);\n\treturn (idx % 2) == 1;\n}\n\nbool FU540_PLIC::HartConfig::is_enabled(unsigned int irq, PrivilegeLevel level) {\n\tassert(irq > 0 && irq <= NUMIRQ);\n\n\tunsigned int idx = GET_IDX(irq);\n\tunsigned int off = GET_OFF(irq);\n\n\tswitch (level) {\n\tcase MachineMode:\n\t\treturn m_mode[idx] & off;\n\tcase SupervisorMode:\n\t\treturn s_mode[idx] & off;\n\tdefault:\n\t\tassert(0);\n\t}\n\n\treturn false;\n}\n"
  },
  {
    "path": "vp/src/platform/common/fu540_plic.h",
    "content": "#pragma once\n\n#include <stdint.h>\n#include <map>\n\n/**\n * This class implements a Platform-Level Interrupt Controller (PLIC) as\n * defined in chapter 10 of the SiFive FU540-C000 manual.\n */\nstruct FU540_PLIC : public sc_core::sc_module, public interrupt_gateway {\npublic:\n\tstatic constexpr int      NUMIRQ   = 53;\n\tstatic constexpr uint32_t MAX_THR  = 7;\n\tstatic constexpr uint32_t MAX_PRIO = 7;\n\n\tstatic constexpr uint32_t ENABLE_BASE = 0x2000;\n\tstatic constexpr uint32_t ENABLE_PER_HART = 0x80;\n\tstatic constexpr uint32_t CONTEXT_BASE = 0x200000;\n\tstatic constexpr uint32_t CONTEXT_PER_HART = 0x1000;\n\tstatic constexpr uint32_t HART_REG_SIZE = 2 * sizeof(uint32_t);\n\n\ttlm_utils::simple_target_socket<FU540_PLIC> tsock;\n\tstd::vector<external_interrupt_target *> target_harts{};\n\n\tFU540_PLIC(sc_core::sc_module_name, unsigned harts = 5);\n\tvoid gateway_trigger_interrupt(uint32_t);\n\n\tSC_HAS_PROCESS(FU540_PLIC);\n\nprivate:\n\tclass HartConfig {\n\t  public:\n\t\tArrayView<uint32_t> m_mode;\n\t\tArrayView<uint32_t> s_mode; /* same as m_mode for hart0 */\n\n\t\tHartConfig(RegisterRange &r1, RegisterRange &r2) : m_mode(r1), s_mode(r2) {\n\t\t\treturn;\n\t\t}\n\n\t\tbool is_enabled(unsigned int, PrivilegeLevel);\n\t};\n\n\tsc_core::sc_event e_run;\n\tsc_core::sc_time clock_cycle;\n\n\tstd::vector<RegisterRange*> register_ranges;\n\n\t/* hart_id (0..4) → hart_config */\n\ttypedef std::map<unsigned int, HartConfig*> hartmap;\n\thartmap enabled_irqs;\n\thartmap hart_context;\n\n\t/* See Section 10.3 */\n\tRegisterRange regs_interrupt_priorities{0x4, sizeof(uint32_t) * NUMIRQ};\n\tArrayView<uint32_t> interrupt_priorities{regs_interrupt_priorities};\n\n\t/* See Section 10.4 */\n\tRegisterRange regs_pending_interrupts{0x1000, sizeof(uint32_t) * 2};\n\tArrayView<uint32_t> pending_interrupts{regs_pending_interrupts};\n\t\n\tvoid create_registers(void);\n\tvoid create_hart_regs(uint64_t, uint64_t, hartmap&);\n\tvoid transport(tlm::tlm_generic_payload&, sc_core::sc_time&);\n\tbool read_hartctx(RegisterRange::ReadInfo, unsigned int, PrivilegeLevel);\n\tvoid write_hartctx(RegisterRange::WriteInfo, unsigned int, PrivilegeLevel);\n\tvoid write_irq_prios(RegisterRange::WriteInfo);\n\tvoid run(void);\n\tunsigned int next_pending_irq(unsigned int, PrivilegeLevel, bool);\n\tbool has_pending_irq(unsigned int, PrivilegeLevel*);\n\tuint32_t get_threshold(unsigned int, PrivilegeLevel);\n\tvoid clear_pending(unsigned int);\n\tbool is_pending(unsigned int);\n\tbool is_claim_access(uint64_t addr);\n};\n"
  },
  {
    "path": "vp/src/platform/common/memory.h",
    "content": "#ifndef RISCV_ISA_MEMORY_H\n#define RISCV_ISA_MEMORY_H\n\n#include <stdint.h>\n#include <boost/iostreams/device/mapped_file.hpp>\n#include <iostream>\n\n#include \"bus.h\"\n#include \"load_if.h\"\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n\nstruct SimpleMemory : public sc_core::sc_module, public load_if {\n\ttlm_utils::simple_target_socket<SimpleMemory> tsock;\n\n\tuint8_t *data;\n\tuint32_t size;\n\tbool read_only;\n\n\tSimpleMemory(sc_core::sc_module_name, uint32_t size, bool read_only = false)\n\t    : data(new uint8_t[size]()), size(size), read_only(read_only) {\n\t\ttsock.register_b_transport(this, &SimpleMemory::transport);\n\t\ttsock.register_get_direct_mem_ptr(this, &SimpleMemory::get_direct_mem_ptr);\n\t\ttsock.register_transport_dbg(this, &SimpleMemory::transport_dbg);\n\t}\n\n\t~SimpleMemory(void) {\n\t\tdelete[] data;\n\t}\n\n\tvoid load_data(const char *src, uint64_t dst_addr, size_t n) override {\n\t\tassert(dst_addr + n <= size);\n\t\tmemcpy(&data[dst_addr], src, n);\n\t}\n\n\tvoid load_zero(uint64_t dst_addr, size_t n) override {\n\t\tassert(dst_addr + n <= size);\n\t\tmemset(&data[dst_addr], 0, n);\n\t}\n\n\tvoid load_binary_file(const std::string &filename, unsigned addr) {\n\t\tboost::iostreams::mapped_file_source f(filename);\n\t\tassert(f.is_open());\n\t\twrite_data(addr, (const uint8_t *)f.data(), f.size());\n\t}\n\n\tvoid write_data(unsigned addr, const uint8_t *src, unsigned num_bytes) {\n\t\tassert(addr + num_bytes <= size);\n\n\t\tmemcpy(data + addr, src, num_bytes);\n\t}\n\n\tvoid read_data(unsigned addr, uint8_t *dst, unsigned num_bytes) {\n\t\tassert(addr + num_bytes <= size);\n\n\t\tmemcpy(dst, data + addr, num_bytes);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\ttransport_dbg(trans);\n\t\tdelay += sc_core::sc_time(10, sc_core::SC_NS);\n\t}\n\n\tunsigned transport_dbg(tlm::tlm_generic_payload &trans) {\n\t\ttlm::tlm_command cmd = trans.get_command();\n\t\tunsigned addr = trans.get_address();\n\t\tauto *ptr = trans.get_data_ptr();\n\t\tauto len = trans.get_data_length();\n\n\t\tassert(addr < size);\n\n\t\tif (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\t\twrite_data(addr, ptr, len);\n\t\t} else if (cmd == tlm::TLM_READ_COMMAND) {\n\t\t\tread_data(addr, ptr, len);\n\t\t} else {\n\t\t\tsc_assert(false && \"unsupported tlm command\");\n\t\t}\n\n\t\treturn len;\n\t}\n\n\tbool get_direct_mem_ptr(tlm::tlm_generic_payload &trans, tlm::tlm_dmi &dmi) {\n\t\t(void)trans;\n\t\tdmi.set_start_address(0);\n\t\tdmi.set_end_address(size);\n\t\tdmi.set_dmi_ptr(data);\n\t\tif (read_only)\n\t\t\tdmi.allow_read();\n\t\telse\n\t\t\tdmi.allow_read_write();\n\t\treturn true;\n\t}\n};\n\n#endif  // RISCV_ISA_MEMORY_H\n"
  },
  {
    "path": "vp/src/platform/common/memory_mapped_file.h",
    "content": "#pragma once\n\n#include <stdint.h>\n#include <unistd.h>  //truncate\n#include <fstream>   //file IO\n#include <iostream>\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n\n#include \"bus.h\"\n\nusing namespace std;\nusing namespace sc_core;\nusing namespace tlm_utils;\n\nstruct MemoryMappedFile : public sc_core::sc_module {\n\tsimple_target_socket<MemoryMappedFile> tsock;\n\n\tstring mFilepath;\n\tuint32_t mSize;\n\tfstream file;\n\n\tMemoryMappedFile(sc_module_name, string &filepath, uint32_t size) : mFilepath(filepath), mSize(size) {\n\t\ttsock.register_b_transport(this, &MemoryMappedFile::transport);\n\n\t\tif (filepath.size() == 0 || size == 0) {  // no file\n\t\t\treturn;\n\t\t}\n\t\tfile.open(mFilepath, ofstream::in | ofstream::out | ofstream::binary);\n\t\tif (!file.is_open() || !file.good()) {\n\t\t\t// cout << \"Failed to open \" << mFilepath << \": \" << strerror(errno)\n\t\t\t// << endl;\n\t\t\tfile.open(mFilepath, ofstream::in | ofstream::out | ofstream::binary | ios_base::trunc);\n\t\t}\n\t\tint stat = truncate(mFilepath.c_str(), mSize);\n\t\tassert(stat == 0 && \"truncate failed\");\n\t\tassert(file.is_open() && file.good() && \"File could not be opened\");\n\t}\n\n\t~MemoryMappedFile() {\n\t\tfile.close();\n\t}\n\n\tvoid write_data(unsigned addr, uint8_t *src, unsigned num_bytes) {\n\t\tassert(addr + num_bytes <= mSize);\n\t\tfile.seekg(addr, file.beg);\n\t\tfile.write(reinterpret_cast<char *>(src), num_bytes);\n\t\tif (!file.is_open() || !file.good()) {\n\t\t\tcout << \"Failed to write \" << mFilepath << \": \" << strerror(errno) << endl;\n\t\t}\n\t}\n\n\tvoid read_data(unsigned addr, uint8_t *dst, unsigned num_bytes) {\n\t\tassert(addr + num_bytes <= mSize);\n\t\tfile.seekg(addr, file.beg);\n\t\tfile.read(reinterpret_cast<char *>(dst), num_bytes);\n\t\tif (!file.is_open() || !file.good()) {\n\t\t\tcout << \"Failed to read \" << mFilepath << \": \" << strerror(errno) << endl;\n\t\t}\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\ttlm::tlm_command cmd = trans.get_command();\n\t\tunsigned addr = trans.get_address();\n\t\tauto *ptr = trans.get_data_ptr();\n\t\tauto len = trans.get_data_length();\n\n\t\tassert(addr < mSize);\n\n\t\tif (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\t\twrite_data(addr, ptr, len);\n\t\t} else if (cmd == tlm::TLM_READ_COMMAND) {\n\t\t\tread_data(addr, ptr, len);\n\t\t} else {\n\t\t\tsc_assert(false && \"unsupported tlm command\");\n\t\t}\n\n\t\tdelay += sc_core::sc_time(len * 30, sc_core::SC_NS);\n\t}\n};\n"
  },
  {
    "path": "vp/src/platform/common/options.cpp",
    "content": "#include \"options.h\"\n\n#include <iostream>\n#include <unistd.h>\n#include <boost/program_options.hpp>\n\nnamespace po = boost::program_options;\n\nOptions::Options(void) {\n\t// clang-format off\n\tadd_options()\n\t\t(\"help\", \"produce help message\")\n\t\t(\"intercept-syscalls\", po::bool_switch(&intercept_syscalls), \"directly intercept and handle syscalls in the ISS (testing mode)\")\n\t\t(\"error-on-zero-traphandler\", po::value<bool>(&error_on_zero_traphandler), \"Assume that taking an unset (zero) trap handler in machine mode is an error condition (which it usually is)\")\n\t\t(\"debug-mode\", po::bool_switch(&use_debug_runner), \"start execution in debugger (using gdb rsp interface)\")\n\t\t(\"debug-port\", po::value<unsigned int>(&debug_port), \"select port number to connect with GDB\")\n\t\t(\"trace-mode\", po::bool_switch(&trace_mode), \"enable instruction tracing\")\n\t\t(\"tlm-global-quantum\", po::value<unsigned int>(&tlm_global_quantum), \"set global tlm quantum (in NS)\")\n\t\t(\"use-instr-dmi\", po::bool_switch(&use_instr_dmi), \"use dmi to fetch instructions\")\n\t\t(\"use-data-dmi\", po::bool_switch(&use_data_dmi), \"use dmi to execute load/store operations\")\n\t\t(\"use-dmi\", po::bool_switch(), \"use instr and data dmi\")\n\t\t(\"input-file\", po::value<std::string>(&input_program)->required(), \"input file to use for execution\");\n\t// clang-format on\n\n\tpos.add(\"input-file\", 1);\n}\n\nOptions::~Options(){};\n\nvoid Options::parse(int argc, char **argv) {\n\ttry {\n\t\tauto parser = po::command_line_parser(argc, argv);\n\t\tparser.options(*this).positional(pos);\n\n\t\tpo::store(parser.run(), vm);\n\n\t\tif (vm.count(\"help\")) {\n\t\t\tstd::cout << *this << std::endl;\n\t\t\texit(0);\n\t\t}\n\n\t\tpo::notify(vm);\n\t\tif (vm[\"use-dmi\"].as<bool>()) {\n\t\t\tuse_data_dmi = true;\n\t\t\tuse_instr_dmi = true;\n\t\t}\n\t\tif (vm[\"intercept-syscalls\"].as<bool>() && vm.count(\"error-on-zero-traphandler\") == 0) {\n\t\t\t// intercept syscalls active, but no overriding error-on-zero-traphandler switch\n\t\t\tstd::cerr << \"[Options] Info: switch 'intercept-syscalls' also activates 'error-on-zero-traphandler' if unset.\" << std::endl;\n\t\t\terror_on_zero_traphandler = true;\n\t\t}\n\t} catch (po::error &e) {\n\t\tstd::cerr\n\t\t\t<< \"Error parsing command line options: \"\n\t\t\t<< e.what()\n\t\t\t<< std::endl;\n\n\t\tstd::cout << *this << std::endl;\n\t\texit(1);\n\t}\n}\n\nvoid Options::printValues(std::ostream& os) const {\n\tos << std::dec;\n\tos << \"intercept_syscalls: \" << intercept_syscalls << std::endl;\n\tos << \"error-on-zero-traphandler: \" << error_on_zero_traphandler << std::endl;\n\tos << \"use_debug_runner: \" << use_debug_runner << std::endl;\n\tos << \"debug_port: \" << debug_port << std::endl;\n\tos << \"trace_mode: \" << trace_mode << std::endl;\n\tos << \"tlm_global_quantum: \" << tlm_global_quantum << std::endl;\n\tos << \"use_instr_dmi: \" << use_instr_dmi << std::endl;\n\tos << \"use_data_dmi: \" << use_data_dmi << std::endl;\n}\n"
  },
  {
    "path": "vp/src/platform/common/options.h",
    "content": "#ifndef RISCV_VP_OPTIONS_H\n#define RISCV_VP_OPTIONS_H\n\n#include <boost/program_options.hpp>\n#include <iostream>\n\nclass Options : public boost::program_options::options_description {\npublic:\n\tOptions(void);\n\tvirtual ~Options();\n\tvirtual void parse(int argc, char **argv);\n\n\tstd::string input_program;\n\n\tbool intercept_syscalls = false;\n\tbool error_on_zero_traphandler = false;\n\tbool use_debug_runner = false;\n\tunsigned int debug_port = 5005;\n\tbool trace_mode = false;\n\tunsigned int tlm_global_quantum = 10;\n\tbool use_instr_dmi = false;\n\tbool use_data_dmi = false;\n\n\tvirtual void printValues(std::ostream& os = std::cout) const;\n\nprivate:\n\n\tboost::program_options::positional_options_description pos;\n\tboost::program_options::variables_map vm;\n};\n\n\n#endif\n"
  },
  {
    "path": "vp/src/platform/common/slip.cpp",
    "content": "#include <errno.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <termios.h>\n#include <unistd.h>\n#include <systemc>\n#include <fcntl.h>\n\n#include <sys/ioctl.h>\n#include <sys/socket.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n\n#include <linux/if.h>\n#include <linux/if_tun.h>\n\n#include \"slip.h\"\n\n// SLIP (as defined in RFC 1055) doesn't specify an MTU. We therefore\n// subsequently allocate memory for the packet buffer using realloc(3).\n#define SLIP_SNDBUF_STEP 1500\n\n#define SLIP_END 0300\n#define SLIP_ESC 0333\n#define SLIP_ESC_END 0334\n#define SLIP_ESC_ESC 0335\n\nSLIP::SLIP(const sc_core::sc_module_name &name, uint32_t irqsrc, std::string netdev) : FD_ABSTRACT_UART(name, irqsrc) {\n\ttunfd = open(\"/dev/net/tun\", O_RDWR);\n\tif (tunfd == -1)\n\t\tgoto err0;\n\n\tstruct ifreq ifr;\n\tmemset(&ifr, 0, sizeof(ifr));\n\tifr.ifr_flags = IFF_TUN | IFF_NO_PI; /* read/write raw IP packets */\n\tstrncpy(ifr.ifr_name, netdev.c_str(), IFNAMSIZ);\n\tif (ioctl(tunfd, TUNSETIFF, (void *)&ifr) == -1)\n\t\tgoto err1;\n\n\tsndsiz = 0;\n\tif (!(sndbuf = (uint8_t *)malloc(SLIP_SNDBUF_STEP * sizeof(uint8_t))))\n\t\tgoto err1;\n\trcvsiz = get_mtu(ifr.ifr_name);\n\tif (!(rcvbuf = (uint8_t *)malloc(rcvsiz * sizeof(uint8_t))))\n\t\tgoto err2;\n\n\tstart_threads(tunfd);\n\treturn;\nerr2:\n\tfree(sndbuf);\n\tsndbuf = NULL;\nerr1:\n\tclose(tunfd);\nerr0:\n\tstd::system_error(errno, std::generic_category());\n}\n\nSLIP::~SLIP(void) {\n\tstop_threads();\n\n\tif (sndbuf) {\n\t\tfree(sndbuf);\n\t\tsndbuf = NULL;\n\t}\n\tif (rcvbuf) {\n\t\tfree(rcvbuf);\n\t\trcvbuf = NULL;\n\t}\n\n\tif (tunfd > 0)\n\t\tclose(tunfd);\n}\n\nint SLIP::get_mtu(const char *dev) {\n\tstruct ifreq ifr;\n\n\tmemset(&ifr, 0, sizeof(ifr));\n\tstrncpy(ifr.ifr_name, dev, IFNAMSIZ);\n\n\tint fd = socket(AF_INET, SOCK_DGRAM, 0);\n\tif (fd == -1)\n\t\tthrow std::system_error(errno, std::generic_category());\n\n\tif (ioctl(fd, SIOCGIFMTU, (void *)&ifr) == -1) {\n\t\tclose(fd);\n\t\tthrow std::system_error(errno, std::generic_category());\n\t}\n\n\tclose(fd);\n\treturn ifr.ifr_mtu;\n}\n\nvoid SLIP::send_packet(void) {\n\tssize_t ret = write(tunfd, sndbuf, sndsiz);\n\tif (ret == -1) {\n\t\tthrow std::system_error(errno, std::generic_category());\n\t} else if ((size_t)ret != sndsiz) {\n\t\tthrow std::runtime_error(\"short write\");\n\t}\n\n\tif (sndsiz > SLIP_SNDBUF_STEP && !(sndbuf = (uint8_t *)realloc(sndbuf, SLIP_SNDBUF_STEP)))\n\t\tthrow std::system_error(errno, std::generic_category());\n\tsndsiz = 0;\n}\n\nvoid SLIP::handle_input(int fd) {\n\tssize_t ret = read(fd, rcvbuf, rcvsiz);\n\tif (ret <= -1)\n\t\tthrow std::system_error(errno, std::generic_category());\n\n\tfor (size_t i = 0; i < static_cast<size_t>(ret); i++) {\n\t\tswitch (rcvbuf[i]) {\n\t\t\tcase SLIP_END:\n\t\t\t\trxpush(SLIP_ESC);\n\t\t\t\trxpush(SLIP_ESC_END);\n\t\t\t\tbreak;\n\t\t\tcase SLIP_ESC:\n\t\t\t\trxpush(SLIP_ESC);\n\t\t\t\trxpush(SLIP_ESC_ESC);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\trxpush(rcvbuf[i]);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\trxpush(SLIP_END);\n}\n\nvoid SLIP::write_data(uint8_t data) {\n\tif (data == SLIP_END) {\n\t\tif (sndsiz > 0)\n\t\t\tsend_packet();\n\t\treturn;\n\t}\n\n\tif (sndsiz > 0 && sndbuf[sndsiz - 1] == SLIP_ESC) {\n\t\tswitch (data) {\n\t\t\tcase SLIP_ESC_END:\n\t\t\t\tsndbuf[sndsiz - 1] = SLIP_END;\n\t\t\t\treturn;\n\t\t\tcase SLIP_ESC_ESC:\n\t\t\t\tsndbuf[sndsiz - 1] = SLIP_ESC;\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\tif (sndsiz && sndsiz % SLIP_SNDBUF_STEP == 0) {\n\t\tsize_t newsiz = (sndsiz + SLIP_SNDBUF_STEP) * sizeof(uint8_t);\n\t\tif (!(sndbuf = (uint8_t *)realloc(sndbuf, newsiz)))\n\t\t\tthrow std::system_error(errno, std::generic_category());\n\t}\n\tsndbuf[sndsiz++] = data;\n}\n"
  },
  {
    "path": "vp/src/platform/common/slip.h",
    "content": "#ifndef RISCV_VP_SLIP_H\n#define RISCV_VP_SLIP_H\n\n#include <stdint.h>\n#include <fd_abstract_uart.h>\n#include <systemc>\n\nclass SLIP : public FD_ABSTRACT_UART {\npublic:\n\tSLIP(const sc_core::sc_module_name &, uint32_t, std::string);\n\t~SLIP(void);\n\nprivate:\n\tint get_mtu(const char *);\n\tvoid send_packet(void);\n\tvoid write_data(uint8_t) override;\n\tvoid handle_input(int fd) override;\n\n\tint tunfd;\n\n\tuint8_t *sndbuf = NULL, *rcvbuf = NULL;\n\tsize_t sndsiz, rcvsiz;\n\n};\n\n#endif  // RISCV_VP_SLIP_H\n"
  },
  {
    "path": "vp/src/platform/common/terminal.h",
    "content": "#ifndef RISCV_ISA_TERMINAL_H\n#define RISCV_ISA_TERMINAL_H\n\n#include <systemc>\n#include <tlm_utils/simple_target_socket.h>\n\nstruct SimpleTerminal : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<SimpleTerminal> tsock;\n\n\tSimpleTerminal(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &SimpleTerminal::transport);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tsc_assert(trans.get_command() == tlm::TLM_WRITE_COMMAND);\n\t\tsc_assert(trans.get_data_length() == 1);\n\n\t\tstd::cout << (char)*trans.get_data_ptr();\n\t\tdelay += (sc_core::sc_time(1, sc_core::sc_time_unit::SC_US));\n\t}\n};\n\n#endif  // RISCV_ISA_TERMINAL_H\n"
  },
  {
    "path": "vp/src/platform/common/uart.cpp",
    "content": "#include \"uart.h\"\n#include \"core/common/rawmode.h\"\n\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <systemc>\n\n#include <sys/types.h>\n\n/* character → control key */\n#define CTRL(c) ((c) & 0x1f)\n\n#define KEY_ESC  CTRL('a')  /* Ctrl-a (character to enter command mode) */\n#define KEY_EXIT 'x'        /* x (character to exit in command mode) */\n#define KEY_CEXIT CTRL(KEY_EXIT) /* Ctrl-x (character to exit in command mode) */\n\nUART::UART(const sc_core::sc_module_name& name, uint32_t irqsrc)\n\t\t: FD_ABSTRACT_UART(name, irqsrc) {\n\t// If stdin isn't a tty, it doesn't make much sense to poll from it.\n\t// In this case, we will run the UART in write-only mode.\n\tbool write_only = !isatty(STDIN_FILENO);\n\n\tenableRawMode(STDIN_FILENO);\n\tstart_threads(STDIN_FILENO, write_only);\n}\n\nUART::~UART(void) {\n\tstop_threads();\n\tdisableRawMode(STDIN_FILENO);\n}\n\nvoid UART::handle_input(int fd) {\n\tuint8_t buf;\n\tssize_t nread;\n\n\tnread = read(fd, &buf, sizeof(buf));\n\tif (nread == -1)\n\t\tthrow std::system_error(errno, std::generic_category());\n\telse if (nread != sizeof(buf))\n\t\tthrow std::runtime_error(\"short read\");\n\n\tswitch (state) {\n\tcase STATE_NORMAL:\n\t\tif(buf != KEY_ESC)\t// filter out first esc sequence\n\t\t\trxpush(buf);\n\t\tbreak;\n\tcase STATE_COMMAND:\n\t\thandle_cmd(buf);\n\t\tbreak;\n\t}\n\n\t/* update state of input state machine for next run */\n\tif (buf == KEY_ESC && state != STATE_COMMAND) {\n\t\tstate = STATE_COMMAND;\n\t} else {\n\t\tstate = STATE_NORMAL;\n\t}\n}\n\nvoid UART::handle_cmd(uint8_t cmd) {\n\tswitch (cmd) {\n\tcase KEY_ESC: /* double escape */\n\t\trxpush(cmd);\n\t\tbreak;\n\tcase KEY_EXIT:\n\tcase KEY_CEXIT:\n\t\texit(EXIT_SUCCESS);\n\t\tbreak;\n\tdefault:\n\t\treturn; /* unknown command → ignore */\n\t}\n}\n\nvoid UART::write_data(uint8_t data) {\n\tssize_t nwritten;\n\tnwritten = write(STDOUT_FILENO, &data, sizeof(data));\n\tif (nwritten == -1)\n\t\tthrow std::system_error(errno, std::generic_category());\n\telse if (nwritten != sizeof(data))\n\t\tthrow std::runtime_error(\"short write\");\n}\n"
  },
  {
    "path": "vp/src/platform/common/uart.h",
    "content": "#ifndef RISCV_VP_UART_H\n#define RISCV_VP_UART_H\n\n#include <stdint.h>\n#include <fd_abstract_uart.h>\n#include <systemc>\n\nclass UART : public FD_ABSTRACT_UART {\npublic:\n\tUART(const sc_core::sc_module_name&, uint32_t);\n\tvirtual ~UART(void);\n\nprivate:\n\ttypedef enum {\n\t\tSTATE_COMMAND,\n\t\tSTATE_NORMAL,\n\t} uart_state;\n\n\t/**\n\t * State of the input handling state machine. In normal mode\n\t * (STATE_NORMAL) the next input character is forwarded to the\n\t * guest. In command mode (STATE_COMMAND) the next input\n\t * character is interpreted by ::handle_cmd.\n\t */\n\tuart_state state = STATE_NORMAL;\n\tvoid handle_cmd(uint8_t);\n\n\tvoid handle_input(int fd) override;\n\tvoid write_data(uint8_t) override;\n};\n\n#endif  // RISCV_VP_UART_H\n"
  },
  {
    "path": "vp/src/platform/common/uart16550.h",
    "content": "#pragma once\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n\n#include \"util/memory_map.h\"\n\n#include <fcntl.h>\n#include <termios.h>\n#include <deque>\n\nstruct UART16550 : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<UART16550> tsock;\n\n\t// memory mapped configuration registers\n\tRegisterRange mm_regs{0x0, 8};\n\tArrayView<uint8_t> regs{mm_regs};\n\n\tstd::vector<RegisterRange *> register_ranges{&mm_regs};\n\n\tstd::deque<uint8_t> rx_fifo;\n\tbool initialized = false;\n\n\tstatic constexpr unsigned QUEUE_ADDR = 0;\n\tstatic constexpr unsigned LINESTAT_ADDR = 5;\n\tstatic constexpr unsigned STATUS_RX = 0x01;\n\tstatic constexpr unsigned STATUS_TX = 0x20;\n\n\tstruct termios orig_termios;\n\n\tUART16550(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &UART16550::transport);\n\n\t\tint flags = fcntl(0, F_GETFL, 0);\n\t\tfcntl(0, F_SETFL, flags | O_NONBLOCK);\n\t\ttcgetattr(STDIN_FILENO, &orig_termios);\n\t\tstruct termios raw = orig_termios;\n\t\traw.c_lflag &= ~(ICANON);  // Bytewise read\n\t\ttcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);\n\n\t\tmm_regs.pre_read_callback = std::bind(&UART16550::pre_read_regs, this, std::placeholders::_1);\n\t\tmm_regs.post_write_callback = std::bind(&UART16550::post_write_regs, this, std::placeholders::_1);\n\t}\n\n\t~UART16550() {\n\t\ttcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);\n\t}\n\n\tvoid try_receive_char() {\n\t\tif (rx_fifo.empty()) {\n\t\t\tchar c;\n\t\t\tif (read(0, &c, 1) >= 0) {\n\t\t\t\trx_fifo.push_back(c);\n\t\t\t}\n\t\t}\n\t}\n\n\tuint8_t take_next_char() {\n\t\ttry_receive_char();\n\t\tif (rx_fifo.empty())\n\t\t\treturn -1;\n\n\t\tuint8_t ans = rx_fifo.front();\n\t\trx_fifo.pop_front();\n\t\treturn ans;\n\t}\n\n\tbool pre_read_regs(RegisterRange::ReadInfo t) {\n\t\tif (t.addr == LINESTAT_ADDR) {\n\t\t\tregs[LINESTAT_ADDR] = 0;\n\t\t\tregs[LINESTAT_ADDR] |= STATUS_TX;\n\t\t\ttry_receive_char();\n\t\t\tif (!rx_fifo.empty())\n\t\t\t\tregs[LINESTAT_ADDR] |= STATUS_RX;\n\t\t} else if (t.addr == QUEUE_ADDR) {\n\t\t\tregs[QUEUE_ADDR] = take_next_char();\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tvoid post_write_regs(RegisterRange::WriteInfo t) {\n\t\tif (t.addr == QUEUE_ADDR) {\n\t\t\tuint8_t data = *t.trans.get_data_ptr();\n\t\t\tif (!initialized) {\n\t\t\t\tinitialized = true;\n\t\t\t\tif (data == 0)\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\tstd::cout << static_cast<char>(data);\n\t\t\tfflush(stdout);\n\t\t}\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tvp::mm::route(\"UART16550\", register_ranges, trans, delay);\n\t}\n};"
  },
  {
    "path": "vp/src/platform/common/uart_if.cpp",
    "content": "#include <semaphore.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <uart_if.h>\n#include <unistd.h>\n#include <mutex>\n#include <queue>\n\nUART_IF::UART_IF(sc_core::sc_module_name, uint32_t irqsrc) : plic(nullptr){\n\tirq = irqsrc;\n\ttsock.register_b_transport(this, &UART_IF::transport);\n\n\trouter.add_register_bank({\n\t\t{TXDATA_REG_ADDR, &txdata},\n\t\t{RXDATA_REG_ADDR, &rxdata},\n\t\t{TXCTRL_REG_ADDR, &txctrl},\n\t\t{RXCTRL_REG_ADDR, &rxctrl},\n\t\t{IE_REG_ADDR, &ie},\n\t\t{IP_REG_ADDR, &ip},\n\t\t{DIV_REG_ADDR, &div},\n\t    })\n\t    .register_handler(this, &UART_IF::register_access_callback);\n\n\tif (sem_init(&txfull, 0, 0))\n\t\tthrow std::system_error(errno, std::generic_category());\n\tif (sem_init(&rxempty, 0, UART_FIFO_DEPTH))\n\t\tthrow std::system_error(errno, std::generic_category());\n\n\tSC_METHOD(interrupt);\n\tsensitive << asyncEvent;\n\tdont_initialize();\n}\n\nUART_IF::~UART_IF(void) {\n\tsem_destroy(&txfull);\n\tsem_destroy(&rxempty);\n}\n\nvoid UART_IF::rxpush(uint8_t data) {\n\tswait(&rxempty);\n\trcvmtx.lock();\n\trx_fifo.push(data);\n\trcvmtx.unlock();\n\tasyncEvent.notify();\n}\n\nuint8_t UART_IF::txpull() {\n\tuint8_t data;\n\tswait(&txfull);\n\tif(tx_fifo.size() == 0) // Other thread will only increase count, not decrease\n\t\treturn 0;\n\ttxmtx.lock();\n\tdata = tx_fifo.front();\n\ttx_fifo.pop();\n\ttxmtx.unlock();\n\treturn data;\n}\n\nvoid UART_IF::register_access_callback(const vp::map::register_access_t &r) {\n\tif (r.read) {\n\t\tif (r.vptr == &txdata) {\n\t\t\ttxmtx.lock();\n\t\t\ttxdata = (tx_fifo.size() >= UART_FIFO_DEPTH) ? UART_FULL : 0;\n\t\t\ttxmtx.unlock();\n\t\t} else if (r.vptr == &rxdata) {\n\t\t\trcvmtx.lock();\n\t\t\tif (rx_fifo.empty()) {\n\t\t\t\trxdata = 1 << 31;\n\t\t\t} else {\n\t\t\t\trxdata = rx_fifo.front();\n\t\t\t\trx_fifo.pop();\n\t\t\t\tspost(&rxempty);\n\t\t\t}\n\t\t\trcvmtx.unlock();\n\t\t} else if (r.vptr == &txctrl) {\n\t\t\t// std::cout << \"TXctl\";\n\t\t} else if (r.vptr == &rxctrl) {\n\t\t\t// std::cout << \"RXctrl\";\n\t\t} else if (r.vptr == &ip) {\n\t\t\tuint32_t ret = 0;\n\t\t\ttxmtx.lock();\n\t\t\tif (tx_fifo.size() < UART_CTRL_CNT(txctrl)) {\n\t\t\t\tret |= UART_TXWM;\n\t\t\t}\n\t\t\ttxmtx.unlock();\n\t\t\trcvmtx.lock();\n\t\t\tif (rx_fifo.size() > UART_CTRL_CNT(rxctrl)) {\n\t\t\t\tret |= UART_RXWM;\n\t\t\t}\n\t\t\trcvmtx.unlock();\n\t\t\tip = ret;\n\t\t} else if (r.vptr == &ie) {\n\t\t\t// do nothing\n\t\t} else if (r.vptr == &div) {\n\t\t\t// just return the last set value\n\t\t} else {\n\t\t\tstd::cerr << \"invalid offset for UART \" << std::endl;\n\t\t}\n\t}\n\n\tbool notify = false;\n\tif (r.write) {\n\t\tif (r.vptr == &txctrl && UART_CTRL_CNT(r.nv) < UART_CTRL_CNT(txctrl))\n\t\t\tnotify = true;\n\t\telse if (r.vptr == &rxctrl && UART_CTRL_CNT(r.nv) < UART_CTRL_CNT(rxctrl))\n\t\t\tnotify = true;\n\t}\n\n\tr.fn();\n\n\tif (notify || (r.write && r.vptr == &ie))\n\t\tasyncEvent.notify();\n\n\tif (r.write && r.vptr == &txdata) {\n\t\t// from SoC to remote\n\t\ttxmtx.lock();\n\t\tif (tx_fifo.size() >= UART_FIFO_DEPTH) {\n\t\t\ttxmtx.unlock();\n\t\t\treturn; /* write is ignored */\n\t\t}\n\n\t\ttx_fifo.push(txdata);\n\t\ttxmtx.unlock();\n\t\tspost(&txfull);\n\t}\n}\n\nvoid UART_IF::transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\trouter.transport(trans, delay);\n}\n\nvoid UART_IF::interrupt(void) {\n\tbool trigger = false;\n\n\t/* XXX: Possible optimization would be to trigger the\n\t * interrupt from the background thread. However,\n\t * the PLIC methods are very likely not thread safe. */\n\n\tif (ie & UART_RXWM) {\n\t\trcvmtx.lock();\n\t\tif (rx_fifo.size() > UART_CTRL_CNT(rxctrl))\n\t\t\ttrigger = true;\n\t\trcvmtx.unlock();\n\t}\n\n\tif (ie & UART_TXWM) {\n\t\ttxmtx.lock();\n\t\tif (tx_fifo.size() < UART_CTRL_CNT(txctrl))\n\t\t\ttrigger = true;\n\t\ttxmtx.unlock();\n\t}\n\n\tif (trigger)\n\t\tplic->gateway_trigger_interrupt(irq);\n}\n\nvoid UART_IF::swait(sem_t *sem) {\n\tif (sem_wait(sem))\n\t\tthrow std::system_error(errno, std::generic_category());\n}\n\nvoid UART_IF::spost(sem_t *sem) {\n\tif (sem_post(sem))\n\t\tthrow std::system_error(errno, std::generic_category());\n}\n"
  },
  {
    "path": "vp/src/platform/common/uart_if.h",
    "content": "#pragma once\n\n#include <stdint.h>\n#include <poll.h>\n#include <semaphore.h>\n#include <stdbool.h>\n\n#include <systemc>\n#include <tlm_utils/simple_target_socket.h>\n\n#include <thread>\n#include <mutex>\n#include <queue>\n\n#include \"core/common/irq_if.h\"\n#include \"util/tlm_map.h\"\n#include \"platform/common/async_event.h\"\n\nclass UART_IF : public sc_core::sc_module {\npublic:\n\ttypedef uint32_t Register;\n\tstatic constexpr Register UART_TXWM = 1 << 0;\n\tstatic constexpr Register UART_RXWM = 1 << 1;\n\tstatic constexpr Register UART_FULL = 1 << 31;\n\n\t/* 8-entry transmit and receive FIFO buffers */\n\tstatic constexpr unsigned UART_FIFO_DEPTH = 8;\n\n\t/* Extracts the interrupt trigger threshold from a control register */\n\tstatic constexpr Register UART_CTRL_CNT(Register REG){ return REG >> 16;};\n\n\tstatic constexpr uint8_t TXDATA_REG_ADDR = 0x0;\n\tstatic constexpr uint8_t RXDATA_REG_ADDR = 0x4;\n\tstatic constexpr uint8_t TXCTRL_REG_ADDR = 0x8;\n\tstatic constexpr uint8_t RXCTRL_REG_ADDR = 0xC;\n\tstatic constexpr uint8_t IE_REG_ADDR = 0x10;\n\tstatic constexpr uint8_t IP_REG_ADDR = 0x14;\n\tstatic constexpr uint8_t DIV_REG_ADDR = 0x18;\n\n\tinterrupt_gateway *plic;\n\ttlm_utils::simple_target_socket<UART_IF> tsock;\n\n\tUART_IF(sc_core::sc_module_name, uint32_t irqsrc);\n\tvirtual ~UART_IF(void);\n\n\tSC_HAS_PROCESS(UART_IF);\t// interrupt\n\nprivate:\n\n\tvoid register_access_callback(const vp::map::register_access_t &);\n\tvoid transport(tlm::tlm_generic_payload &, sc_core::sc_time &);\n\tvoid interrupt(void);\n\n\tuint32_t irq;\n\n\t// memory mapped configuration registers\n\tuint32_t txdata = 0;\n\tuint32_t rxdata = 0;\n\tuint32_t txctrl = 0;\n\tuint32_t rxctrl = 0;\n\tuint32_t ie = 0;\n\tuint32_t ip = 0;\n\tuint32_t div = 0;\n\n\tvp::map::LocalRouter router = {\"UART\"};\n\nprotected:\n\tstd::queue<uint8_t> tx_fifo;\n\tsem_t txfull;\n\tstd::queue<uint8_t> rx_fifo;\n\tsem_t rxempty;\n\tstd::mutex rcvmtx, txmtx;\n\tAsyncEvent asyncEvent;\n\n\tvoid swait(sem_t *sem);\n\tvoid spost(sem_t *sem);\n\n\t// blocking push into SoC\n\tvoid rxpush(uint8_t data);\n\t// blocking pull from SoC to remote\n\tuint8_t txpull();\n};\n"
  },
  {
    "path": "vp/src/platform/common/util.h",
    "content": "#pragma once\n\n#include \"util/common.h\"\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n\n/* A simple memory block that provides arbitrary read/write access. */\nstruct BlankDevice : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<BlankDevice> tsock;\n\n\tunsigned size;\n\tuint8_t *data;\n\n\tBlankDevice(sc_core::sc_module_name, unsigned size) : size(size), data(new uint8_t[size]) {\n\t\ttsock.register_b_transport(this, &BlankDevice::transport);\n\t}\n\n\t~BlankDevice() {\n\t\tdelete[] data;\n\t\tdata = 0;\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tUNUSED(delay);\n\n\t\tassert(data);\n\t\tassert(trans.get_address() + trans.get_data_length() <= size);\n\n\t\tif (trans.get_command() == tlm::TLM_READ_COMMAND) {\n\t\t\tmemcpy(trans.get_data_ptr(), data + trans.get_address(), trans.get_data_length());\n\t\t} else if (trans.get_command() == tlm::TLM_WRITE_COMMAND) {\n\t\t\tmemcpy(data + trans.get_address(), trans.get_data_ptr(), trans.get_data_length());\n\t\t} else {\n\t\t\tthrow std::runtime_error(\"unsupported TLM command\");\n\t\t}\n\t}\n};\n\n/* Ignores all write accesses and always returns zero on any read access. */\nstruct ZeroDevice : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<ZeroDevice> tsock;\n\n\tZeroDevice(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &ZeroDevice::transport);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tUNUSED(delay);\n\n\t\tif (trans.get_command() == tlm::TLM_READ_COMMAND) {\n\t\t\tmemset(trans.get_data_ptr(), 0, trans.get_data_length());\n\t\t}\n\t}\n};\n\n/* Simple UART/terminal, e.g. this implementation matches the HiFive1 board write address and is already sufficient to\n * print characters in Zephyr OS examples. */\nstruct SimpleUART : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<SimpleUART> tsock;\n\n\tSimpleUART(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &SimpleUART::transport);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tUNUSED(delay);\n\n\t\tif (trans.get_command() == tlm::TLM_WRITE_COMMAND) {\n\t\t\tif (trans.get_address() == 0x0) {\n\t\t\t\tstd::cout << static_cast<char>(*trans.get_data_ptr());\n\t\t\t\tfflush(stdout);\n\t\t\t}\n\t\t}\n\t}\n};"
  },
  {
    "path": "vp/src/platform/hifive/CMakeLists.txt",
    "content": "add_executable(hifive-vp\n        hifive_main.cpp\n        can.cpp\n        oled/common.cpp\n        oled/oled.cpp\n        gpio.cpp\n        tunnel-uart.cpp\n        ../../util/elegantEnums.cpp #sorry :(\n        ${HEADERS})\n\nadd_git_submodule(vbb-protocol)\n\ntarget_link_libraries(hifive-vp virtual-breadboard-server rv32 platform-common gdb-mc ${Boost_LIBRARIES} systemc pthread)\n\nINSTALL(TARGETS hifive-vp RUNTIME DESTINATION bin)\n"
  },
  {
    "path": "vp/src/platform/hifive/aon.h",
    "content": "#ifndef RISCV_VP_AON_H\n#define RISCV_VP_AON_H\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\n#include \"core/common/irq_if.h\"\n#include \"util/tlm_map.h\"\n\nstruct AON : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<AON> tsock;\n\n\tuint32_t wdogcfg = 0;\n\tuint32_t wdogcount = 0;\n\tuint32_t wdogfeed = 0;\n\tuint32_t wdogkey = 0;\n\tuint32_t wdogcmp0 = 0;\n\n\tuint32_t lfrosccfg = 0;\n\tuint32_t pmucause = 1 << 8;\n\n\tuint32_t rtccfg = 0;\n\tuint32_t rtccountlo = 0;\n\tuint32_t rtccounthi = 0;\n\tuint32_t rtcs = 0;\n\tuint32_t rtccmp0 = 0;\n\n\tuint32_t backup0 = 0;\n\tuint32_t backup1 = 0;\n\tuint32_t backup2 = 0;\n\tuint32_t backup3 = 0;\n\tuint32_t backup4 = 0;\n\tuint32_t backup5 = 0;\n\tuint32_t backup6 = 0;\n\tuint32_t backup7 = 0;\n\tuint32_t backup8 = 0;\n\tuint32_t backup9 = 0;\n\tuint32_t backup10 = 0;\n\tuint32_t backup11 = 0;\n\tuint32_t backup12 = 0;\n\tuint32_t backup13 = 0;\n\tuint32_t backup14 = 0;\n\tuint32_t backup15 = 0;\n\tuint32_t backup16 = 0;\n\tuint32_t backup17 = 0;\n\tuint32_t backup18 = 0;\n\tuint32_t backup19 = 0;\n\tuint32_t backup20 = 0;\n\tuint32_t backup21 = 0;\n\tuint32_t backup22 = 0;\n\tuint32_t backup23 = 0;\n\tuint32_t backup24 = 0;\n\tuint32_t backup25 = 0;\n\tuint32_t backup26 = 0;\n\tuint32_t backup27 = 0;\n\tuint32_t backup28 = 0;\n\tuint32_t backup29 = 0;\n\tuint32_t backup30 = 0;\n\tuint32_t backup31 = 0;\n\n\tenum {\n\t\tWDOG_CFG_REG_ADDR = 0x000,\n\t\tWDOG_CNT_REG_ADDR = 0x010,\n\t\tWDOG_FEED_REG_ADDR = 0x018,\n\t\tWDOG_KEY_REG_ADDR = 0x01C,\n\t\tWDOG_CMP0_REG_ADDR = 0x020,\n\n\t\tRTC_CFG_REG_ADDR = 0x040,\n\t\tRTC_COUNT_LO_REG_ADDR = 0x048,\n\t\tRTC_COUNT_HI_REG_ADDR = 0x04C,\n\t\tRTC_S_REG_ADDR = 0x050,\n\t\tRTC_CMP0 =0x060,\n\n\t\tLFROSCCFG_REG_ADDR = 0x70,\n\n\t\tBACKUP0_REG_ADDR = 0x80,\n\t\tBACKUP1_REG_ADDR = 0x84,\n\t\tBACKUP2_REG_ADDR = 0x88,\n\t\tBACKUP3_REG_ADDR = 0x8C,\n\t\tBACKUP4_REG_ADDR = 0x90,\n\t\tBACKUP5_REG_ADDR = 0x94,\n\t\tBACKUP6_REG_ADDR = 0x98,\n\t\tBACKUP7_REG_ADDR = 0x9C,\n\t\tBACKUP8_REG_ADDR = 0xA0,\n\t\tBACKUP9_REG_ADDR = 0xA4,\n\t\tBACKUP10_REG_ADDR = 0xA8,\n\t\tBACKUP11_REG_ADDR = 0xAC,\n\t\tBACKUP12_REG_ADDR = 0xB0,\n\t\tBACKUP13_REG_ADDR = 0xB4,\n\t\tBACKUP14_REG_ADDR = 0xB8,\n\t\tBACKUP15_REG_ADDR = 0xBC,\n\t\tBACKUP16_REG_ADDR = 0xC0,\n\t\tBACKUP17_REG_ADDR = 0xC4,\n\t\tBACKUP18_REG_ADDR = 0xC8,\n\t\tBACKUP19_REG_ADDR = 0xCC,\n\t\tBACKUP20_REG_ADDR = 0xD0,\n\t\tBACKUP21_REG_ADDR = 0xD4,\n\t\tBACKUP22_REG_ADDR = 0xD8,\n\t\tBACKUP23_REG_ADDR = 0xDC,\n\t\tBACKUP24_REG_ADDR = 0xE0,\n\t\tBACKUP25_REG_ADDR = 0xE4,\n\t\tBACKUP26_REG_ADDR = 0xE8,\n\t\tBACKUP27_REG_ADDR = 0xEC,\n\t\tBACKUP28_REG_ADDR = 0xF0,\n\t\tBACKUP29_REG_ADDR = 0xF4,\n\t\tBACKUP30_REG_ADDR = 0xF8,\n\t\tBACKUP31_REG_ADDR = 0xFC,\n\n\t\tPMUCAUSE_REG_ADDR = 0x144,\n\t};\n\n\tvp::map::LocalRouter router = {\"AON\"};\n\n\tAON(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &AON::transport);\n\n\t\trouter\n\t\t    .add_register_bank({\n\t\t\t{WDOG_CFG_REG_ADDR, &wdogcfg},\n\t\t\t{WDOG_CNT_REG_ADDR, &wdogcount},\n\t\t\t{WDOG_FEED_REG_ADDR, &wdogfeed},\n\t\t\t{WDOG_KEY_REG_ADDR, &wdogkey},\n\t\t\t{WDOG_CMP0_REG_ADDR, &wdogcmp0},\n\n\t\t        {RTC_CFG_REG_ADDR, &rtccfg},\n\t\t        {RTC_COUNT_LO_REG_ADDR, &rtccountlo},\n\t\t\t{RTC_COUNT_HI_REG_ADDR, &rtccounthi},\n\t\t\t{RTC_S_REG_ADDR, &rtcs},\n\t\t\t{RTC_CMP0, &rtccmp0},\n\n\t\t        {LFROSCCFG_REG_ADDR, &lfrosccfg}, {PMUCAUSE_REG_ADDR, &pmucause},\n\n\t\t        {BACKUP0_REG_ADDR, &backup0},     {BACKUP1_REG_ADDR, &backup1},   {BACKUP2_REG_ADDR, &backup2},\n\t\t        {BACKUP3_REG_ADDR, &backup3},     {BACKUP4_REG_ADDR, &backup4},   {BACKUP5_REG_ADDR, &backup5},\n\t\t        {BACKUP6_REG_ADDR, &backup6},     {BACKUP7_REG_ADDR, &backup7},   {BACKUP8_REG_ADDR, &backup8},\n\t\t        {BACKUP9_REG_ADDR, &backup9},     {BACKUP10_REG_ADDR, &backup10}, {BACKUP11_REG_ADDR, &backup11},\n\t\t        {BACKUP12_REG_ADDR, &backup12},   {BACKUP13_REG_ADDR, &backup13}, {BACKUP14_REG_ADDR, &backup14},\n\t\t        {BACKUP15_REG_ADDR, &backup15},   {BACKUP16_REG_ADDR, &backup16}, {BACKUP17_REG_ADDR, &backup17},\n\t\t        {BACKUP18_REG_ADDR, &backup18},   {BACKUP19_REG_ADDR, &backup19}, {BACKUP20_REG_ADDR, &backup20},\n\t\t        {BACKUP21_REG_ADDR, &backup21},   {BACKUP22_REG_ADDR, &backup22}, {BACKUP23_REG_ADDR, &backup23},\n\t\t        {BACKUP24_REG_ADDR, &backup24},   {BACKUP25_REG_ADDR, &backup25}, {BACKUP26_REG_ADDR, &backup26},\n\t\t        {BACKUP27_REG_ADDR, &backup27},   {BACKUP28_REG_ADDR, &backup28}, {BACKUP29_REG_ADDR, &backup29},\n\t\t        {BACKUP30_REG_ADDR, &backup30},   {BACKUP31_REG_ADDR, &backup31},\n\t\t    })\n\t\t    .register_handler(this, &AON::register_access_callback);\n\t}\n\n\tvoid register_access_callback(const vp::map::register_access_t &r) {\n\t\tr.fn();\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\trouter.transport(trans, delay);\n\t}\n};\n\n#endif  // RISCV_VP_AON_H\n"
  },
  {
    "path": "vp/src/platform/hifive/can/90-slcan.rules",
    "content": " # Lawicel CANUSB module\n\nSUBSYSTEM==\"tty\", ATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6001\", ATTRS{product}==\"CANUSB\", SYMLINK+=\"ttyUSB_CAN\"\nACTION==\"add\",    ATTRS{product}==\"CANUSB\", RUN+=\"/usr/local/bin/slcan_add.sh\"\nACTION==\"remove\", ATTRS{product}==\"CANUSB\", RUN+=\"/usr/local/bin/slcan_remove.sh\"\n"
  },
  {
    "path": "vp/src/platform/hifive/can/CAN-Howto.md",
    "content": "```bash\nsudo apt-get install can-utils\n```\nCheck if the kernel modules „can“, „can_raw“ and „slcan“ are already loaded:\n\n```bash\nlsmod | grep can\n```\nif not, load them manually:\n\n```bash\nsudo modprobe can\nsudo modprobe can_raw\nsudo modprobe slcan\n````\n\nIf modprobe says „Module not found“ at this point, your linux distribution is missing the can modules. If modprobe says nothing, the modules exist.\nTo autoload these modules, insert into new file `/etc/modules-load.d/can` following lines:\n\n```\ncan\ncan_raw\nslcan\n```\n\n(perhaps test by restart, haha)\n\n\n```bash\nsudo cp 90-slcan.rules /etc/udev/rules.d/90-slcan.rules\nsudo cp slcan* /usr/local/bin/\n```\n\nYou may plug in the CAN-Controller now. *kiss*\n\n- If `ip link` does not show a _slcan0_, execute the `sudo slcan_add.sh`\n- To see can traffic, run `candump slcan0`\n"
  },
  {
    "path": "vp/src/platform/hifive/can/cantest.cpp",
    "content": "/*\n * cantest.cpp\n *\n *  Created on: 22 Mar 2019\n *      Author: dwd\n */\n#include <linux/can.h>\n#include <linux/can/raw.h>\n#include <cstring>\n#include <iostream>\n\n#include <endian.h>\n#include <net/if.h>\n#include <sys/ioctl.h>\n#include <sys/socket.h>\n#include <sys/types.h>\n#include <unistd.h>\n\nusing namespace std;\n\nint main(int argc, char* argv[]) {\n\tint s;\n\tstruct sockaddr_can addr;\n\tstruct ifreq ifr;\n\n\ts = socket(PF_CAN, SOCK_RAW, CAN_RAW);\n\tif (s < 0) {\n\t\tperror(\"Could not open socket!\");\n\t}\n\n\tmemset(&ifr, 0, sizeof(struct ifreq));\n\tstrcpy(ifr.ifr_name, \"slcan0\");\n\tif (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {\n\t\tperror(\"Could not ctl to device\");\n\t}\n\n\taddr.can_family = AF_CAN;\n\taddr.can_ifindex = ifr.ifr_ifindex;\n\n\tif (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {\n\t\tperror(\"Could not bind to can family\");\n\t}\n\n\t// while(true)\n\t{\n\t\tstruct can_frame frame;\n\n\t\tint nbytes = read(s, &frame, sizeof(struct can_frame));\n\n\t\tif (nbytes < 0) {\n\t\t\tperror(\"can raw socket read\");\n\t\t\treturn 1;\n\t\t}\n\n\t\t/* paranoid check ... */\n\t\tif (nbytes < sizeof(struct can_frame)) {\n\t\t\tfprintf(stderr, \"read: incomplete CAN frame\\n\");\n\t\t\treturn 1;\n\t\t}\n\n\t\t/* do something with the received CAN frame */\n\n\t\tcout << \"received id \" << frame.can_id << \" len \" << unsigned(frame.can_dlc) << endl;\n\n\t\tfor (uint8_t i = 0; i < frame.can_dlc; i++) {\n\t\t\tprintf(\"%s%02X\", i > 0 ? \" \" : \"\", frame.data[i]);\n\t\t}\n\t\tcout << endl;\n\n\t\tnbytes = write(s, &frame, sizeof(struct can_frame));\n\t}\n\tclose(s);\n}\n"
  },
  {
    "path": "vp/src/platform/hifive/can/mcp_can_dfs.h",
    "content": "/*\n  mcp_can_dfs.h\n  2012 Copyright (c) Seeed Technology Inc.  All right reserved.\n\n  Author:Loovee (loovee@seeed.cc)\n  2014-1-16\n\n  Contributor:\n\n  Cory J. Fowler\n  Latonita\n  Woodward1\n  Mehtajaghvi\n  BykeBlast\n  TheRo0T\n  Tsipizic\n  ralfEdmund\n  Nathancheek\n  BlueAndi\n  Adlerweb\n  Btetz\n  Hurvajs\n  xboxpro1\n  ttlappalainen\n\n  The MIT License (MIT)\n\n  Copyright (c) 2013 Seeed Technology Inc.\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE.\n*/\n#ifndef _MCP2515DFS_H_\n#define _MCP2515DFS_H_\n\n// Begin mt\n\n#define TIMEOUTVALUE 50\n#define MCP_SIDH 0\n#define MCP_SIDL 1\n#define MCP_EID8 2\n#define MCP_EID0 3\n\n#define MCP_TXB_EXIDE_M 0x08  // In TXBnSIDL\n#define MCP_DLC_MASK 0x0F     // 4 LSBits\n#define MCP_RTR_MASK 0x40     // (1<<6) Bit 6\n\n#define MCP_RXB_RX_ANY 0x60\n#define MCP_RXB_RX_EXT 0x40\n#define MCP_RXB_RX_STD 0x20\n#define MCP_RXB_RX_STDEXT 0x00\n#define MCP_RXB_RX_MASK 0x60\n#define MCP_RXB_BUKT_MASK (1 << 2)\n\n// Bits in the TXBnCTRL registers.\n\n#define MCP_TXB_TXBUFE_M 0x80\n#define MCP_TXB_ABTF_M 0x40\n#define MCP_TXB_MLOA_M 0x20\n#define MCP_TXB_TXERR_M 0x10\n#define MCP_TXB_TXREQ_M 0x08\n#define MCP_TXB_TXIE_M 0x04\n#define MCP_TXB_TXP10_M 0x03\n\n#define MCP_TXB_RTR_M 0x40  // In TXBnDLC\n#define MCP_RXB_IDE_M 0x08  // In RXBnSIDL\n#define MCP_RXB_RTR_M 0x40  // In RXBnDLC\n\n#define MCP_STAT_TX_PENDING_MASK (0x54)\n#define MCP_STAT_TX0_PENDING (0x04)\n#define MCP_STAT_TX1_PENDING (0x10)\n#define MCP_STAT_TX2_PENDING (0x40)\n#define MCP_STAT_TXIF_MASK (0xA8)\n#define MCP_STAT_TX0IF (0x08)\n#define MCP_STAT_TX1IF (0x20)\n#define MCP_STAT_TX2IF (0x80)\n#define MCP_STAT_RXIF_MASK (0x03)\n#define MCP_STAT_RX0IF (1 << 0)\n#define MCP_STAT_RX1IF (1 << 1)\n\n#define MCP_EFLG_RX1OVR (1 << 7)\n#define MCP_EFLG_RX0OVR (1 << 6)\n#define MCP_EFLG_TXBO (1 << 5)\n#define MCP_EFLG_TXEP (1 << 4)\n#define MCP_EFLG_RXEP (1 << 3)\n#define MCP_EFLG_TXWAR (1 << 2)\n#define MCP_EFLG_RXWAR (1 << 1)\n#define MCP_EFLG_EWARN (1 << 0)\n#define MCP_EFLG_ERRORMASK (0xF8)  // 5 MS-Bits\n\n// Define MCP2515 register addresses\n\n#define MCP_RXF0SIDH 0x00\n#define MCP_RXF0SIDL 0x01\n#define MCP_RXF0EID8 0x02\n#define MCP_RXF0EID0 0x03\n#define MCP_RXF1SIDH 0x04\n#define MCP_RXF1SIDL 0x05\n#define MCP_RXF1EID8 0x06\n#define MCP_RXF1EID0 0x07\n#define MCP_RXF2SIDH 0x08\n#define MCP_RXF2SIDL 0x09\n#define MCP_RXF2EID8 0x0A\n#define MCP_RXF2EID0 0x0B\n#define MCP_CANSTAT 0x0E\n#define MCP_CANCTRL 0x0F\n#define MCP_RXF3SIDH 0x10\n#define MCP_RXF3SIDL 0x11\n#define MCP_RXF3EID8 0x12\n#define MCP_RXF3EID0 0x13\n#define MCP_RXF4SIDH 0x14\n#define MCP_RXF4SIDL 0x15\n#define MCP_RXF4EID8 0x16\n#define MCP_RXF4EID0 0x17\n#define MCP_RXF5SIDH 0x18\n#define MCP_RXF5SIDL 0x19\n#define MCP_RXF5EID8 0x1A\n#define MCP_RXF5EID0 0x1B\n#define MCP_TEC 0x1C\n#define MCP_REC 0x1D\n#define MCP_RXM0SIDH 0x20\n#define MCP_RXM0SIDL 0x21\n#define MCP_RXM0EID8 0x22\n#define MCP_RXM0EID0 0x23\n#define MCP_RXM1SIDH 0x24\n#define MCP_RXM1SIDL 0x25\n#define MCP_RXM1EID8 0x26\n#define MCP_RXM1EID0 0x27\n#define MCP_CNF3 0x28\n#define MCP_CNF2 0x29\n#define MCP_CNF1 0x2A\n#define MCP_CANINTE 0x2B\n#define MCP_CANINTF 0x2C\n#define MCP_EFLG 0x2D\n#define MCP_TXB0CTRL 0x30\n#define MCP_TXB0SIDH 0x31\n#define MCP_TXB1CTRL 0x40\n#define MCP_TXB1SIDH 0x41\n#define MCP_TXB2CTRL 0x50\n#define MCP_TXB2SIDH 0x51\n#define MCP_RXB0CTRL 0x60\n#define MCP_RXB0SIDH 0x61\n#define MCP_RXB1CTRL 0x70\n#define MCP_RXB1SIDH 0x71\n\n#define MCP_TX_INT 0x1C    // Enable all transmit interrup ts\n#define MCP_TX01_INT 0x0C  // Enable TXB0 and TXB1 interru pts\n#define MCP_RX_INT 0x03    // Enable receive interrupts\n#define MCP_NO_INT 0x00    // Disable all interrupts\n\n#define MCP_TX01_MASK 0x14\n#define MCP_TX_MASK 0x54\n\n// Define SPI Instruction Set\n\n#define MCP_WRITE 0x02\n#define MCP_READ 0x03\n#define MCP_BITMOD 0x05\n#define MCP_LOAD_TX0 0x40\n#define MCP_LOAD_TX1 0x42\n#define MCP_LOAD_TX2 0x44\n\n#define MCP_RTS_TX0 0x81\n#define MCP_RTS_TX1 0x82\n#define MCP_RTS_TX2 0x84\n#define MCP_RTS_ALL 0x87\n#define MCP_READ_RX0 0x90\n#define MCP_READ_RX1 0x94\n#define MCP_READ_STATUS 0xA0\n#define MCP_RX_STATUS 0xB0\n#define MCP_RESET 0xC0\n\n// CANCTRL Register Values\n\n#define MODE_NORMAL 0x00\n#define MODE_SLEEP 0x20\n#define MODE_LOOPBACK 0x40\n#define MODE_LISTENONLY 0x60\n#define MODE_CONFIG 0x80\n#define MODE_POWERUP 0xE0\n#define MODE_MASK 0xE0\n#define ABORT_TX 0x10\n#define MODE_ONESHOT 0x08\n#define CLKOUT_ENABLE 0x04\n#define CLKOUT_DISABLE 0x00\n#define CLKOUT_PS1 0x00\n#define CLKOUT_PS2 0x01\n#define CLKOUT_PS4 0x02\n#define CLKOUT_PS8 0x03\n\n// CNF1 Register Values\n\n#define SJW1 0x00\n#define SJW2 0x40\n#define SJW3 0x80\n#define SJW4 0xC0\n\n//  CNF2 Register Values\n\n#define BTLMODE 0x80\n#define SAMPLE_1X 0x00\n#define SAMPLE_3X 0x40\n\n// CNF3 Register Values\n\n#define SOF_ENABLE 0x80\n#define SOF_DISABLE 0x00\n#define WAKFIL_ENABLE 0x40\n#define WAKFIL_DISABLE 0x00\n\n// CANINTF Register Bits\n\n#define MCP_RX0IF 0x01\n#define MCP_RX1IF 0x02\n#define MCP_TX0IF 0x04\n#define MCP_TX1IF 0x08\n#define MCP_TX2IF 0x10\n#define MCP_ERRIF 0x20\n#define MCP_WAKIF 0x40\n#define MCP_MERRF 0x80\n\n// clock\n\n#define MCP_16MHz 1\n#define MCP_8MHz 2\n\n// speed 16M\n\n#define MCP_16MHz_1000kBPS_CFG1 (0x00)\n#define MCP_16MHz_1000kBPS_CFG2 (0xD0)\n#define MCP_16MHz_1000kBPS_CFG3 (0x82)\n\n#define MCP_16MHz_500kBPS_CFG1 (0x00)\n#define MCP_16MHz_500kBPS_CFG2 (0xF0)\n#define MCP_16MHz_500kBPS_CFG3 (0x86)\n\n#define MCP_16MHz_250kBPS_CFG1 (0x41)\n#define MCP_16MHz_250kBPS_CFG2 (0xF1)\n#define MCP_16MHz_250kBPS_CFG3 (0x85)\n\n#define MCP_16MHz_200kBPS_CFG1 (0x01)\n#define MCP_16MHz_200kBPS_CFG2 (0xFA)\n#define MCP_16MHz_200kBPS_CFG3 (0x87)\n\n#define MCP_16MHz_125kBPS_CFG1 (0x03)\n#define MCP_16MHz_125kBPS_CFG2 (0xF0)\n#define MCP_16MHz_125kBPS_CFG3 (0x86)\n\n#define MCP_16MHz_100kBPS_CFG1 (0x03)\n#define MCP_16MHz_100kBPS_CFG2 (0xFA)\n#define MCP_16MHz_100kBPS_CFG3 (0x87)\n\n#define MCP_16MHz_95kBPS_CFG1 (0x03)\n#define MCP_16MHz_95kBPS_CFG2 (0xAD)\n#define MCP_16MHz_95kBPS_CFG3 (0x07)\n\n#define MCP_16MHz_83k3BPS_CFG1 (0x03)\n#define MCP_16MHz_83k3BPS_CFG2 (0xBE)\n#define MCP_16MHz_83k3BPS_CFG3 (0x07)\n\n#define MCP_16MHz_80kBPS_CFG1 (0x03)\n#define MCP_16MHz_80kBPS_CFG2 (0xFF)\n#define MCP_16MHz_80kBPS_CFG3 (0x87)\n\n#define MCP_16MHz_50kBPS_CFG1 (0x07)\n#define MCP_16MHz_50kBPS_CFG2 (0xFA)\n#define MCP_16MHz_50kBPS_CFG3 (0x87)\n\n#define MCP_16MHz_40kBPS_CFG1 (0x07)\n#define MCP_16MHz_40kBPS_CFG2 (0xFF)\n#define MCP_16MHz_40kBPS_CFG3 (0x87)\n\n#define MCP_16MHz_33kBPS_CFG1 (0x09)\n#define MCP_16MHz_33kBPS_CFG2 (0xBE)\n#define MCP_16MHz_33kBPS_CFG3 (0x07)\n\n#define MCP_16MHz_31k25BPS_CFG1 (0x0F)\n#define MCP_16MHz_31k25BPS_CFG2 (0xF1)\n#define MCP_16MHz_31k25BPS_CFG3 (0x85)\n\n#define MCP_16MHz_25kBPS_CFG1 (0X0F)\n#define MCP_16MHz_25kBPS_CFG2 (0XBA)\n#define MCP_16MHz_25kBPS_CFG3 (0X07)\n\n#define MCP_16MHz_20kBPS_CFG1 (0x0F)\n#define MCP_16MHz_20kBPS_CFG2 (0xFF)\n#define MCP_16MHz_20kBPS_CFG3 (0x87)\n\n#define MCP_16MHz_10kBPS_CFG1 (0x1F)\n#define MCP_16MHz_10kBPS_CFG2 (0xFF)\n#define MCP_16MHz_10kBPS_CFG3 (0x87)\n\n#define MCP_16MHz_5kBPS_CFG1 (0x3F)\n#define MCP_16MHz_5kBPS_CFG2 (0xFF)\n#define MCP_16MHz_5kBPS_CFG3 (0x87)\n\n#define MCP_16MHz_666kBPS_CFG1 (0x00)\n#define MCP_16MHz_666kBPS_CFG2 (0xA0)\n#define MCP_16MHz_666kBPS_CFG3 (0x04)\n\n// speed 8M\n\n#define MCP_8MHz_1000kBPS_CFG1 (0x00)\n#define MCP_8MHz_1000kBPS_CFG2 (0x80)\n#define MCP_8MHz_1000kBPS_CFG3 (0x00)\n\n#define MCP_8MHz_500kBPS_CFG1 (0x00)\n#define MCP_8MHz_500kBPS_CFG2 (0x90)\n#define MCP_8MHz_500kBPS_CFG3 (0x02)\n\n#define MCP_8MHz_250kBPS_CFG1 (0x00)\n#define MCP_8MHz_250kBPS_CFG2 (0xb1)\n#define MCP_8MHz_250kBPS_CFG3 (0x05)\n\n#define MCP_8MHz_200kBPS_CFG1 (0x00)\n#define MCP_8MHz_200kBPS_CFG2 (0xb4)\n#define MCP_8MHz_200kBPS_CFG3 (0x06)\n\n#define MCP_8MHz_125kBPS_CFG1 (0x01)\n#define MCP_8MHz_125kBPS_CFG2 (0xb1)\n#define MCP_8MHz_125kBPS_CFG3 (0x05)\n\n#define MCP_8MHz_100kBPS_CFG1 (0x01)\n#define MCP_8MHz_100kBPS_CFG2 (0xb4)\n#define MCP_8MHz_100kBPS_CFG3 (0x06)\n\n#define MCP_8MHz_80kBPS_CFG1 (0x01)\n#define MCP_8MHz_80kBPS_CFG2 (0xbf)\n#define MCP_8MHz_80kBPS_CFG3 (0x07)\n\n#define MCP_8MHz_50kBPS_CFG1 (0x03)\n#define MCP_8MHz_50kBPS_CFG2 (0xb4)\n#define MCP_8MHz_50kBPS_CFG3 (0x06)\n\n#define MCP_8MHz_40kBPS_CFG1 (0x03)\n#define MCP_8MHz_40kBPS_CFG2 (0xbf)\n#define MCP_8MHz_40kBPS_CFG3 (0x07)\n\n#define MCP_8MHz_31k25BPS_CFG1 (0x07)\n#define MCP_8MHz_31k25BPS_CFG2 (0xa4)\n#define MCP_8MHz_31k25BPS_CFG3 (0x04)\n\n#define MCP_8MHz_20kBPS_CFG1 (0x07)\n#define MCP_8MHz_20kBPS_CFG2 (0xbf)\n#define MCP_8MHz_20kBPS_CFG3 (0x07)\n\n#define MCP_8MHz_10kBPS_CFG1 (0x0f)\n#define MCP_8MHz_10kBPS_CFG2 (0xbf)\n#define MCP_8MHz_10kBPS_CFG3 (0x07)\n\n#define MCP_8MHz_5kBPS_CFG1 (0x1f)\n#define MCP_8MHz_5kBPS_CFG2 (0xbf)\n#define MCP_8MHz_5kBPS_CFG3 (0x07)\n\n#define MCPDEBUG (0)\n#define MCPDEBUG_TXBUF (0)\n#define MCP_N_TXBUFFERS (3)\n\n#define MCP_RXBUF_0 (MCP_RXB0SIDH)\n#define MCP_RXBUF_1 (MCP_RXB1SIDH)\n\n#define MCP2515_SELECT() digitalWrite(SPICS, LOW)\n#define MCP2515_UNSELECT() digitalWrite(SPICS, HIGH)\n\n#define MCP2515_OK (0)\n#define MCP2515_FAIL (1)\n#define MCP_ALLTXBUSY (2)\n\n#define CANDEBUG 1\n\n#define CANUSELOOP 0\n\n#define CANSENDTIMEOUT (200)  // milliseconds\n\n// initial value of gCANAutoProcess\n\n#define CANAUTOPROCESS (1)\n#define CANAUTOON (1)\n#define CANAUTOOFF (0)\n#define CAN_STDID (0)\n#define CAN_EXTID (1)\n#define CANDEFAULTIDENT (0x55CC)\n#define CANDEFAULTIDENTEXT (CAN_EXTID)\n\n#define CAN_5KBPS 1\n#define CAN_10KBPS 2\n#define CAN_20KBPS 3\n#define CAN_25KBPS 4\n#define CAN_31K25BPS 5\n#define CAN_33KBPS 6\n#define CAN_40KBPS 7\n#define CAN_50KBPS 8\n#define CAN_80KBPS 9\n#define CAN_83K3BPS 10\n#define CAN_95KBPS 11\n#define CAN_100KBPS 12\n#define CAN_125KBPS 13\n#define CAN_200KBPS 14\n#define CAN_250KBPS 15\n#define CAN_500KBPS 16\n#define CAN_666KBPS 17\n#define CAN_1000KBPS 18\n\n#define CAN_OK (0)\n#define CAN_FAILINIT (1)\n#define CAN_FAILTX (2)\n#define CAN_MSGAVAIL (3)\n#define CAN_NOMSG (4)\n#define CAN_CTRLERROR (5)\n#define CAN_GETTXBFTIMEOUT (6)\n#define CAN_SENDMSGTIMEOUT (7)\n#define CAN_FAIL (0xff)\n\n#define CAN_MAX_CHAR_IN_MESSAGE (8)\n\n#endif\n/*********************************************************************************************************\n  END FILE\n*********************************************************************************************************/\n"
  },
  {
    "path": "vp/src/platform/hifive/can/slcan_add.sh",
    "content": " #!/bin/sh\n# Bind the USBCAN device\nslcand -o -c -f -s6 /dev/ttyUSB_CAN slcan0\nsleep 1\nifconfig slcan0 up\n"
  },
  {
    "path": "vp/src/platform/hifive/can/slcan_remove.sh",
    "content": " #!/bin/sh\n# Remove the USBCAN device\npkill slcand\n"
  },
  {
    "path": "vp/src/platform/hifive/can.cpp",
    "content": "#include \"can.h\"\n#include <linux/can.h>\n#include <linux/can/raw.h>\n#include <unistd.h>\n\n#include <endian.h>\n#include <net/if.h>\n#include <sys/ioctl.h>\n#include <sys/socket.h>\n#include <sys/types.h>\n#include <unistd.h>\n#include <inttypes.h>\n\nCAN::CAN() {\n\tstate = State::init;\n\tstatus = 0;\n\tstop = false;\n\n\ts = socket(PF_CAN, SOCK_RAW, CAN_RAW);\n\tif (s < 0) {\n\t\tperror(\"Could not open socket!\");\n\t\treturn;\n\t}\n\n\tmemset(&ifr, 0, sizeof(struct ifreq));\n\tstrcpy(ifr.ifr_name, \"slcan0\");\n\tif (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {\n\t\tclose(s);\n\t\tperror(\"Could not ctl to device\");\n\t\treturn;\n\t}\n\n\taddr.can_family = AF_CAN;\n\taddr.can_ifindex = ifr.ifr_ifindex;\n\n\tif (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {\n\t\tclose(s);\n\t\tperror(\"Could not bind to can family\");\n\t\treturn;\n\t}\n\n\tlistener = std::thread(&CAN::listen, this);\n}\n\nCAN::~CAN() {\n\tstop = true;\n\tif (listener.joinable())\n\t\tlistener.join();\n}\n\nconst char* CAN::registerName(uint8_t id) {\n\tswitch (id) {\n\t\t/*..*/\n\t\tcase MCP_CANCTRL:\n\t\t\treturn \"MCP_CANCTRL\";\n\t\tcase MCP_RXF0SIDH:\n\t\t\treturn \"MCP_RXF0SIDH\";\n\t\t/*..*/\n\t\tcase MCP_CNF1:\n\t\t\treturn \"MCP_CNF1\";\n\t\tcase MCP_CNF2:\n\t\t\treturn \"MCP_CNF2\";\n\t\tcase MCP_CNF3:\n\t\t\treturn \"MCP_CNF3\";\n\t\t/*..*/\n\t\tcase MCP_CANINTF:\n\t\t\treturn \"MCP_CANINTF\";\n\n\t\tcase MCP_TXB1CTRL:\n\t\t\treturn \"MCP_TXB1CTRL\";\n\t\tcase MCP_TXB2CTRL:\n\t\t\treturn \"MCP_TXB2CTRL\";\n\n\t\tdefault:\n\t\t\treturn \"UNKNOWN-RegName\";\n\t}\n}\n\nconst char* CAN::regValueName(uint8_t id) {\n\tswitch (id) {\n\t\t/*..*/\n\t\tcase MODE_NORMAL:\n\t\t\treturn \"MODE_NORMAL\";\n\t\tcase MODE_SLEEP:\n\t\t\treturn \"MODE_SLEEP\";\n\n\t\tcase MODE_CONFIG:\n\t\t\treturn \"MODE_CONFIG\";\n\n\t\tcase MODE_ONESHOT:\n\t\t\treturn \"MODE_ONESHOT\";\n\n\t\tdefault:\n\t\t\treturn \"UNKNOWN-RegValue\";\n\t}\n}\n\nconst char* CAN::spiInstName(uint8_t id) {\n\tswitch (id) {\n\t\t/*..*/\n\t\tcase MCP_WRITE:\n\t\t\treturn \"MCP_WRITE\";\n\t\tcase MCP_READ:\n\t\t\treturn \"MCP_READ\";\n\t\tcase MCP_BITMOD:\n\t\t\treturn \"MCP_BITMOD\";\n\t\tcase MCP_LOAD_TX0:\n\t\t\treturn \"MCP_LOAD_TX0\";\n\t\tcase MCP_LOAD_TX1:\n\t\t\treturn \"MCP_LOAD_TX1\";\n\t\tcase MCP_LOAD_TX2:\n\t\t\treturn \"MCP_LOAD_TX2\";\n\t\tcase MCP_RTS_TX0:\n\t\t\treturn \"MCP_RTS_TX0\";\n\t\tcase MCP_RTS_TX1:\n\t\t\treturn \"MCP_RTS_TX1\";\n\t\tcase MCP_RTS_TX2:\n\t\t\treturn \"MCP_RTS_TX2\";\n\t\tcase MCP_RTS_ALL:\n\t\t\treturn \"MCP_RTS_ALL\";\n\t\tcase MCP_READ_RX0:\n\t\t\treturn \"MCP_READ_RX0\";\n\t\tcase MCP_READ_RX1:\n\t\t\treturn \"MCP_READ_RX1\";\n\t\tcase MCP_READ_STATUS:\n\t\t\treturn \"MCP_READ_STATUS\";\n\t\tcase MCP_RX_STATUS:\n\t\t\treturn \"MCP_RX_STATUS\";\n\t\tcase MCP_RESET:\n\t\t\treturn \"MCP_RESET\";\n\n\t\tdefault:\n\t\t\treturn \"UNKNOWN-SpiInst\";\n\t}\n}\n\nuint8_t CAN::write(uint8_t byte) {\n\tuint8_t ret = 0;\n\tuint8_t whichBuf = 0;\n\tswitch (state) {\n\t\tcase State::init:\n\t\t\tcommand(byte);\n\t\t\tret = 0;\n\t\t\tbreak;\n\t\tcase State::readRegister:\n\t\t\tret = readRegister(byte);\n\t\t\tbreak;\n\t\tcase State::writeRegister:\n\t\t\tret = writeRegister(byte);\n\t\t\tbreak;\n\t\tcase State::bitmod:\n\t\t\tret = modifyRegister(byte);\n\t\t\tbreak;\n\t\tcase State::loadTX2:\n\t\t\twhichBuf++;\n\t\t\t// fall-through\n\t\tcase State::loadTX1:\n\t\t\twhichBuf++;\n\t\t\t// fall-through\n\t\tcase State::loadTX0:\n\t\t\tret = loadTxBuf(whichBuf, byte);\n\t\t\tbreak;\n\t\tcase State::sendALL:\n\t\t\twhichBuf++;\n\t\t\t// fall-through\n\t\tcase State::sendTX2:\n\t\t\twhichBuf++;\n\t\t\t// fall-through\n\t\tcase State::sendTX1:\n\t\t\twhichBuf++;\n\t\t\t// fall-through\n\t\tcase State::sendTX0:\n\t\t\tret = sendTxBuf(whichBuf, byte);\n\t\t\tbreak;\n\t\tcase State::readRX1:\n\t\t\twhichBuf++;\n\t\t\t// fall-through\n\t\tcase State::readRX0:\n\t\t\tret = readRxBuf(whichBuf, byte);\n\t\t\tbreak;\n\t\tcase State::getStatus:\n\t\t\tret = status;  // short enough to be handled here\n\t\t\tstate = State::init;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tstd::cerr << \"[CAN] in unknown state!\" << std::endl;\n\t}\n\n\treturn ret;\n}\n\nvoid CAN::command(uint8_t byte) {\n\t// std::cout << \"[CAN] \" << spiInstName(byte);\n\tswitch (byte) {\n\t\tcase MCP_WRITE:\n\t\t\tstate = State::writeRegister;\n\t\t\tbreak;\n\t\tcase MCP_READ:\n\t\t\tstate = State::readRegister;\n\t\t\tbreak;\n\t\tcase MCP_BITMOD:\n\t\t\tstate = State::bitmod;\n\t\t\tbreak;\n\t\tcase MCP_LOAD_TX0:\n\t\t\tstate = State::loadTX0;\n\t\t\tbreak;\n\t\tcase MCP_LOAD_TX1:\n\t\t\tstate = State::loadTX1;\n\t\t\tbreak;\n\t\tcase MCP_LOAD_TX2:\n\t\t\tstate = State::loadTX2;\n\t\t\tbreak;\n\t\tcase MCP_RTS_TX0:\n\t\t\tstate = State::sendTX0;\n\t\t\tbreak;\n\t\tcase MCP_RTS_TX1:\n\t\t\tstate = State::sendTX1;\n\t\t\tbreak;\n\t\tcase MCP_RTS_TX2:\n\t\t\tstate = State::sendTX2;\n\t\t\tbreak;\n\t\tcase MCP_RTS_ALL:\n\t\t\tstate = State::sendALL;\n\t\t\tbreak;\n\t\tcase MCP_READ_RX0:\n\t\t\tstate = State::readRX0;\n\t\t\tbreak;\n\t\tcase MCP_READ_RX1:\n\t\t\tstate = State::readRX1;\n\t\t\tbreak;\n\t\tcase MCP_READ_STATUS:\n\t\t\tstate = State::getStatus;\n\t\t\tbreak;\n\t\tcase MCP_RX_STATUS:\n\t\t\tbreak;\n\t\tcase MCP_RESET:\n\t\t\t// do reset stuff\n\t\t\tstate = State::init;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tstd::cerr << std::hex << unsigned(byte) << \" is unknown command \" << std::endl;\n\t}\n\t// std::cout << std::endl;\n}\n\nuint8_t CAN::readRegister(uint8_t byte) {\n\tstatic int16_t selectedRegister = -1;\n\tuint8_t ret = 0;\n\n\tif (selectedRegister < 0) {\n\t\tselectedRegister = byte;\n\t\t// std::cout << \"\\t[CAN] read select Register \" << registerName(selectedRegister) << std::endl;\n\t\tret = 0;\n\t} else {\n\t\tif (byte != 0) {  // end \"auto increment\"\n\t\t\tselectedRegister = -1;\n\t\t\tcommand(byte);\n\t\t\treturn 0;\n\t\t}\n\t\t// std::cout << \"[CAN] Read on Register \" << registerName(selectedRegister) << std::endl;\n\t\tif (selectedRegister > MCP_RXB1SIDH) {\n\t\t\tstd::cerr << \"Read on Register too high! \";\n\t\t\tret = 0;\n\t\t} else {\n\t\t\tret = registers[selectedRegister];\n\t\t}\n\t\tselectedRegister++;\n\t}\n\treturn ret;\n}\n\nuint8_t CAN::writeRegister(uint8_t byte) {\n\tstatic int16_t selectedRegister = -1;\n\tif (selectedRegister < 0) {\n\t\tselectedRegister = byte;\n\t\t// std::cout << \"\\t[CAN] Write select Register \"  << registerName(selectedRegister) << std::endl;\n\t\treturn 0;\n\t} else {\n\t\t// std::cout << \"[CAN] Write on Register \" << registerName(selectedRegister) << std::endl;\n\n\t\tif (selectedRegister > MCP_RXB1SIDH) {\n\t\t\tstd::cerr << \"Write on Register too high! \";\n\t\t\treturn 0;\n\t\t} else {\n\t\t\tregisters[selectedRegister] = byte;\n\t\t}\n\t\tselectedRegister = -1;\n\t\tstate = State::init;\n\t}\n\treturn 0;\n}\n\nuint8_t CAN::modifyRegister(uint8_t byte) {\n\tstatic struct ModReg {\n\t\tenum : uint8_t { _address = 0, _mask, _data } state;\n\t\tuint8_t address;\n\t\tuint8_t mask;\n\t\tuint8_t data;\n\n\t\tModReg() : state(_address), address(0), mask(0), data(0){};\n\t} command;\n\n\t// std::cout << \"\\t[CAN] modReg \";\n\tswitch (command.state) {\n\t\tcase ModReg::_address:\n\t\t\tcommand.address = byte;\n\t\t\tcommand.state = ModReg::_mask;\n\t\t\t// std::cout << \"select \" << registerName(command.address) << std::endl;\n\t\t\tbreak;\n\t\tcase ModReg::_mask:\n\t\t\tcommand.mask = byte;\n\t\t\tcommand.state = ModReg::_data;\n\n\t\t\t// std::cout << \"mask \" << std::hex << unsigned(byte) << std::endl;\n\t\t\tbreak;\n\t\tcase ModReg::_data:\n\t\t\tcommand.data = byte;\n\t\t\tcommand.state = ModReg::_address;\n\t\t\tstate = State::init;\n\t\t\t// std::cout << \"setData \" << regValueName(command.data) << std::endl;\n\t\t\tregisters[command.address] &= ~command.mask;\n\t\t\tregisters[command.address] |= command.data;\n\t\t\tbreak;\n\t}\n\treturn 0;\n}\n\nuint8_t CAN::loadTxBuf(uint8_t no, uint8_t byte) {\n\tstatic struct LoadTX {\n\t\tenum {\n\t\t\tid,\n\t\t\tlength,\n\t\t\tpayload,\n\t\t} state = id;\n\t\tuint8_t payload_ptr = 0;\n\t} command;\n\n\tswitch (command.state) {\n\t\tcase LoadTX::id:\n\t\t\t// std::cout << \"\\t[CAN] ID: \" << std::hex << unsigned(byte) << std::endl;\n\t\t\ttxBuf[no].fields.id[command.payload_ptr++] = byte;\n\t\t\tif (command.payload_ptr == 4) {\n\t\t\t\tcommand.payload_ptr = 0;\n\t\t\t\tcommand.state = LoadTX::length;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase LoadTX::length:\n\t\t\t// std::cout << \"\\t[CAN] Length : \" << std::hex << unsigned(byte) << std::endl;\n\t\t\tcommand.state = LoadTX::payload;\n\t\t\ttxBuf[no].fields.length = byte;\n\t\t\tbreak;\n\t\tcase LoadTX::payload:\n\t\t\t// std::cout << \"\\t[CAN] PL : \" << std::hex << unsigned(byte) << std::endl;\n\t\t\ttxBuf[no].fields.payload[command.payload_ptr++] = byte;\n\t\t\tif (command.payload_ptr == txBuf[no].fields.length) {\n\t\t\t\tcommand = LoadTX();\n\t\t\t\tstate = State::init;\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\nuint8_t CAN::sendTxBuf(uint8_t no, uint8_t) {\n\tif (no == 4) {\n\t\t// todo: Special case to send all buffers\n\t\tno = 0;\n\t}\n\tstruct can_frame frame;\n\tbool extended;  // this is ignored\n\tmemset(&frame, 0, sizeof(struct can_frame));\n\tmcp2515_buf_to_id(frame.can_id, extended, txBuf[no].fields.id);\n\tframe.can_dlc = txBuf[no].fields.length;\n\tmemcpy(frame.data, txBuf[no].fields.payload, txBuf[no].fields.length);\n\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wunused-result\"\n\n\t::write(s, &frame, sizeof(struct can_frame));\n\t;\n\n#pragma GCC diagnostic pop\n\n\t// Set 'sent' status ok\n\tregisters[MCP_TXB0CTRL] = 0;\n\tstate = State::readRegister;\n\treturn 0;\n}\n\nuint8_t CAN::readRxBuf(uint8_t no, uint8_t) {\n\tstatic uint8_t payload_ptr = 0;\n\tuint8_t ret = rxBuf[no].raw[payload_ptr++];\n\tif (payload_ptr > rxBuf[no].fields.length + 4) {\n\t\tpayload_ptr = 0;\n\t\tstate = State::init;\n\t\tstatus &= ~(1 << no);  // MCP_STAT_RX0IF = 1 << 0\n\t}\n\t// std::cout << \"[CAN] readRxBuf\" << unsigned(no) << \" \" << unsigned(ret) << std::endl;\n\treturn ret;\n}\n\nvoid CAN::mcp2515_id_to_buf(const unsigned long id, uint8_t* idField, const bool extended) {\n\tuint16_t canid;\n\n\tcanid = (uint16_t)(id & 0x0FFFF);\n\n\tif (extended) {\n\t\tidField[MCP_EID0] = (uint8_t)(canid & 0xFF);\n\t\tidField[MCP_EID8] = (uint8_t)(canid >> 8);\n\t\tcanid = (uint16_t)(id >> 16);\n\t\tidField[MCP_SIDL] = (uint8_t)(canid & 0x03);\n\t\tidField[MCP_SIDL] += (uint8_t)((canid & 0x1C) << 3);\n\t\tidField[MCP_SIDL] |= MCP_TXB_EXIDE_M;\n\t\tidField[MCP_SIDH] = (uint8_t)(canid >> 5);\n\t} else {\n\t\tidField[MCP_SIDH] = (uint8_t)(canid >> 3);\n\t\tidField[MCP_SIDL] = (uint8_t)((canid & 0x07) << 5);\n\t\tidField[MCP_EID0] = 0;\n\t\tidField[MCP_EID8] = 0;\n\t}\n}\n\nvoid CAN::mcp2515_buf_to_id(unsigned& id, bool& extended, uint8_t* idField) {\n\textended = false;\n\tid = 0;\n\n\tid = (idField[MCP_SIDH] << 3) + (idField[MCP_SIDL] >> 5);\n\tif ((idField[MCP_SIDL] & MCP_TXB_EXIDE_M) == MCP_TXB_EXIDE_M) {\n\t\t// extended id\n\t\tid = (id << 2) + (idField[MCP_SIDL] & 0x03);\n\t\tid = (id << 8) + idField[MCP_EID8];\n\t\tid = (id << 8) + idField[MCP_EID0];\n\t\textended = true;\n\t}\n}\n\nvoid CAN::enqueueIncomingCanFrame(const struct can_frame& frame) {\n\tif ((status & 0b11) == 0b11) {\n\t\t// all buffers full\n\t\treturn;\n\t}\n\n\tfor (unsigned i = 0; i < 2; i++) {\n\t\tif (!(status & (1 << i)))  // Correnspond to MCP_STAT_RXnIF registers\n\t\t{\n\t\t\t// empty buffer\n\t\t\tmemset(&rxBuf[i], 0, sizeof(MCPFrame));\n\t\t\tmcp2515_id_to_buf(frame.can_id, rxBuf[i].fields.id);  // FIXME: This will break if extended frame or stuff happens\n\t\t\trxBuf[i].fields.length = frame.can_dlc;\n\t\t\tmemcpy(rxBuf[i].fields.payload, frame.data, frame.can_dlc);\n\t\t\tstatus |= 1 << i;\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nvoid CAN::listen() {\n\twhile (!stop) {\n\t\tstruct can_frame frame;\n\n\t\tint nbytes = read(s, &frame, sizeof(struct can_frame));\n\n\t\tif (nbytes < 0) {\n\t\t\tperror(\"can raw socket read\");\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* paranoid check ... */\n\t\tif (nbytes < static_cast<long>(sizeof(struct can_frame))) {\n\t\t\tfprintf(stderr, \"read: incomplete CAN frame\\n\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tenqueueIncomingCanFrame(frame);\n\t}\n}\n"
  },
  {
    "path": "vp/src/platform/hifive/can.h",
    "content": "#pragma once\n\n#include \"can/mcp_can_dfs.h\"\n#include \"spi.h\"\n\n#include <linux/can.h>\n#include <net/if.h>\n\n#include <functional>\n#include <thread>\n\nclass CAN  {\n\tenum class State {\n\t\tinit,\n\t\treadRegister,\n\t\twriteRegister,\n\t\tbitmod,\n\n\t\tloadTX0,\n\t\tloadTX1,\n\t\tloadTX2,\n\n\t\tsendTX0,\n\t\tsendTX1,\n\t\tsendTX2,\n\t\tsendALL,\n\n\t\treadRX0,\n\t\treadRX1,\n\n\t\tgetStatus,\n\n\t\tshit,\n\t\twank,\n\t\tfuck,\n\t\tarse,\n\t\tcrap,\n\t\tdick,\n\t} state;\n\n\tstd::thread listener;\n\n\tuint8_t registers[MCP_RXB1SIDH + 1];\n\n\tstruct MCPFrame {\n\t\tunion {\n\t\t\tuint8_t raw[5 + CANFD_MAX_DLEN];\n\t\t\tstruct {\n\t\t\t\tunion {\n\t\t\t\t\tuint8_t id[4];\n\t\t\t\t\tstruct {\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t    MCP_SIDH        0\n\t\t\t\t\t\t    MCP_SIDL        1\n\t\t\t\t\t\t    MCP_EID8        2\n\t\t\t\t\t\t    MCP_EID0        3\n\t\t\t\t\t\t */\n\t\t\t\t\t\tuint16_t sid;\n\t\t\t\t\t\tuint16_t eid;\n\t\t\t\t\t} fields;\n\t\t\t\t};\n\t\t\t\tuint8_t length;\n\t\t\t\tuint8_t payload[CANFD_MAX_DLEN];\n\t\t\t} fields;\n\t\t};\n\t};\n\n\tMCPFrame txBuf[3];\n\tMCPFrame rxBuf[2];\n\n\tuint8_t status;\n\n\tint s;\n\tstruct sockaddr_can addr;\n\tstruct ifreq ifr;\n\n\tvolatile bool stop;\n\npublic:\n\tCAN();\n\t~CAN();\n\n\tuint8_t write(uint8_t byte);\n\n\tconst char* registerName(uint8_t id);\n\tconst char* regValueName(uint8_t id);\n\tconst char* spiInstName(uint8_t id);\n\n\tvoid command(uint8_t byte);\n\tuint8_t readRegister(uint8_t byte);\n\tuint8_t writeRegister(uint8_t byte);\n\tuint8_t modifyRegister(uint8_t byte);\n\n\tuint8_t loadTxBuf(uint8_t no, uint8_t byte);\n\tuint8_t sendTxBuf(uint8_t no, uint8_t byte);\n\n\tuint8_t readRxBuf(uint8_t no, uint8_t byte);\n\n\tvoid mcp2515_id_to_buf(const unsigned long id, uint8_t* idField, const bool extended = false);\n\tvoid mcp2515_buf_to_id(unsigned& id, bool& extended, uint8_t* idField);\n\n\tvoid enqueueIncomingCanFrame(const struct can_frame& frame);\n\tvoid listen();\n};\n"
  },
  {
    "path": "vp/src/platform/hifive/gpio.cpp",
    "content": "#include \"gpio.h\"\n\nusing namespace std;\nusing namespace gpio;\n\nstatic Pinstate getIOF(PinNumber pin, bool iofsel) {\n\tswitch(pin) {\n\tcase 16:\t// UART0 RX\n\t\treturn !iofsel ? Pinstate::IOF_UART_RX : Pinstate::UNSET;\n\tcase 17:\t// UART0 TX\n\t\treturn !iofsel ? Pinstate::IOF_UART_TX : Pinstate::UNSET;\n\tcase 19:\t// PWM1_1\n\tcase 20:\t// PWM1_0\n\tcase 21:\t// PWM1_2\n\tcase 22:\t// PWM1_3\n\t\treturn !iofsel ? Pinstate::UNSET : Pinstate::IOF_PWM;\n\tcase  0:\t// PWM0_0\n\tcase  1:\t// PWM0_1\n\t\treturn !iofsel ? Pinstate::UNSET : Pinstate::IOF_PWM;\n\tcase  2:\t// SPI1 CS0, PWM0_2\n\tcase  3:\t// SPI1 OSI, PWM0_3\n\t\treturn !iofsel ? Pinstate::IOF_SPI : Pinstate::IOF_PWM;\n\tcase  4:\t// SPI1 MISO\n\tcase  5:\t// SPI1 SCK\n\t\treturn !iofsel ? Pinstate::IOF_SPI : Pinstate::UNSET;\n\tcase  9:\t// SPI1 CS2\n\t\treturn !iofsel ? Pinstate::IOF_SPI : Pinstate::UNSET;\n\tcase 10:\t// SPI1 CS3, PWM2_0\n\t\treturn !iofsel ? Pinstate::IOF_SPI : Pinstate::IOF_PWM;\n\tcase 11:\t// PWM2_1\n\tcase 12:\t// PWM2_2\n\tcase 13:\t// PWM2_3\n\t\treturn !iofsel ? Pinstate::UNSET : Pinstate::IOF_PWM;\n\tcase 18:\t// UART1 (RX?)\n\t\treturn !iofsel ? Pinstate::IOF_UART_RX : Pinstate::UNSET;\n\tcase 23:\t// UART1 (TX?)\n\t\treturn !iofsel ? Pinstate::IOF_UART_TX : Pinstate::UNSET;\n\tdefault:\n\t\treturn Pinstate::UNSET;\n\t}\n}\n\nstatic PinNumber getPinOffsFromSPIcs(PinNumber cs) {\n\tswitch (cs) {\n\tcase 0:\n\t\treturn 2;\n\tcase 1:\n\t\tassert(false && \"[GPIO] On Fe310, CS 1 is not routable\");\n\t\treturn max_num_pins;\n\tcase 2:\n\t\treturn 9;\n\tcase 3:\n\t\treturn 10;\n\tdefault:\n\t\tassert(false && \"[GPIO] Invalid CS pin given\");\n\t\treturn max_num_pins;\n\t}\n}\n\nGPIO::GPIO(sc_core::sc_module_name, unsigned int_gpio_base) : int_gpio_base(int_gpio_base) {\n\ttsock.register_b_transport(this, &GPIO::transport);\n\n\trouter\n\t    .add_register_bank({\n\t        {PIN_VALUE_ADDR, &value},\n\t        {INPUT_EN_REG_ADDR, &input_en},\n\t        {OUTPUT_EN_REG_ADDR, &output_en},\n\t        {PORT_REG_ADDR, &port},\n\t        {PULLUP_EN_ADDR, &pullup_en},\n\t        {PIN_DRIVE_STNGTH, &pin_drive_strength},\n\t        {RISE_INTR_EN, &rise_intr_en},\n\t        {RISE_INTR_PEND, &rise_intr_pending},\n\t        {FALL_INTR_EN, &fall_intr_en},\n\t        {FALL_INTR_PEND, &fall_intr_pending},\n\t        {HIGH_INTR_EN, &high_intr_en},\n\t        {HIGH_INTR_PEND, &high_intr_pending},\n\t        {LOW_INTR_EN, &low_intr_en},\n\t        {LOW_INTR_PEND, &low_intr_pending},\n\t        {IOF_EN_REG_ADDR, &iof_en},\n\t        {IOF_SEL_REG_ADDR, &iof_sel},\n\t        {OUT_XOR_REG_ADDR, &out_xor},\n\t    })\n\t    .register_handler(this, &GPIO::register_access_callback);\n\n\tSC_METHOD(synchronousChange);\n\tsensitive << asyncEvent;\n\tdont_initialize();\n\n\tserver.setupConnection(to_string(gpio::default_port).c_str());\n\tserver.registerOnChange(bind(&GPIO::asyncOnchange, this, placeholders::_1, placeholders::_2));\n\tserverThread = new thread(bind(&GpioServer::startAccepting, &server));\n}\n\nGPIO::~GPIO() {\n\tserver.quit();\n\tif (serverThread) {\n\t\tif(serverThread->joinable()){\n\t\t\tserverThread->join();\n\t\t}\n\t\tdelete serverThread;\n\t}\n}\n\nvoid GPIO::register_access_callback(const vp::map::register_access_t &r) {\n\tif (r.write) {\n\t\tswitch (r.addr) {\n\t\tcase PIN_VALUE_ADDR:\n\t\t\tcerr << \"[GPIO] write to value register is ignored!\" << endl;\n\t\t\treturn;\n\t\tcase PORT_REG_ADDR:\n\t\t\t// cout << \"[GPIO] new Port value: \";\n\t\t\t// bitPrint(reinterpret_cast<unsigned char*>(&r.nv), sizeof(uint32_t));\n\n\t\t\t// value and server.state might differ, if a bit is changed by\n\t\t\t// client and the synchronous_change was not fired yet.\n\t\t\t// Server wins in this scenario.\n\t\t\t{\n\t\t\t\tconst auto prv_output_enabled_port = (port & output_en) & ~iof_en;\n\t\t\t\tconst auto new_output_enabled_port = (r.nv & output_en) & ~iof_en;\n\t\t\t\tconst auto changed_output_pins = new_output_enabled_port ^ prv_output_enabled_port;\n\n\t\t\t\tif(!changed_output_pins)\n\t\t\t\t\tbreak;\n\n\t\t\t\tvalue = (value & ~output_en) | new_output_enabled_port;\n\n\t\t\t\tfor(PinNumber i = 0; i < available_pins; i++) {\n\t\t\t\t\tconst auto bitoffs = (1l << i);\n\t\t\t\t\tif(bitoffs & changed_output_pins) {\n\t\t\t\t\t\tserver.state.pins[i] = new_output_enabled_port & bitoffs ? Pinstate::HIGH : Pinstate::LOW;\n\t\t\t\t\t\tserver.pushPin(i, toTristate(server.state.pins[i]));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase PULLUP_EN_ADDR:\n\t\t\t// cout << \"[GPIO] pullup changed\" << endl;\n\t\t\t// bitPrint(reinterpret_cast<unsigned char*>(&pullup_en), sizeof(uint32_t));\n\t\t\t{\n\t\t\t\tconst auto newly_pulled_up_bits = (r.nv ^ pullup_en) & r.nv;\n\t\t\t\tvalue |= newly_pulled_up_bits;\n\t\t\t\tfor(PinNumber i = 0; i < available_pins; i++) {\n\t\t\t\t\tif((1l << i) & newly_pulled_up_bits) {\n\t\t\t\t\t\tserver.state.pins[i] = Pinstate::HIGH;\n\t\t\t\t\t\t// TODO: Notify pin subscriber\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase OUTPUT_EN_REG_ADDR:\n\t\t\t{\n\t\t\t\tconst auto& old_output_en = output_en;\n\t\t\t\tconst auto& new_output_en = r.nv;\n\n\t\t\t\tconst auto newly_output_disabled_bits =  old_output_en & ~new_output_en;\n\t\t\t\tconst auto newly_output_enabled_bits  = ~old_output_en &  new_output_en;\n\t\t\t\t// Implicit zero when output disabled\n\t\t\t\tvalue = (value & ~old_output_en) | (port & new_output_en);\n\n\t\t\t\tfor(PinNumber i = 0; i < available_pins; i++) {\n\t\t\t\t\tconst auto bitoffs = (1l << i);\n\t\t\t\t\tif(bitoffs & newly_output_disabled_bits) {\n\t\t\t\t\t\t// we can't differentiate between \"driven by server\" or \"by client\".\n\t\t\t\t\t\t// Server wins, so override.\n\t\t\t\t\t\tserver.state.pins[i] = Pinstate::UNSET;\n\t\t\t\t\t\tserver.pushPin(i, Tristate::UNSET);\n\t\t\t\t\t}\n\t\t\t\t\telse if (bitoffs & newly_output_enabled_bits) {\n\t\t\t\t\t\tserver.state.pins[i] = value & bitoffs ? Pinstate::HIGH : Pinstate::LOW;\n\t\t\t\t\t\tserver.pushPin(i, toTristate(server.state.pins[i]));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\tr.fn();\n\tif (r.write) {\n\t\tswitch (r.addr) {\n\t\tcase IOF_EN_REG_ADDR:\n\t\tcase IOF_SEL_REG_ADDR:\n\t\t\tfor (PinNumber i = 0; i < available_pins; i++) {\n\t\t\t\tif((1l << i) & iof_en) {\n\t\t\t\t\t{\n\t\t\t\t\tconst auto iof = getIOF(i, iof_sel & (1l << i));\n\t\t\t\t\t//cout << \"IOF for pin \" << (int)i << \" is \" << (int) iof << endl;\n\t\t\t\t\tif(iof == Pinstate::UNSET)\n\t\t\t\t\t\tcerr << \"[GPIO] Set invalid iof to pin \" << (int)i << endl;\n\t\t\t\t\telse\n\t\t\t\t\t\tserver.state.pins[i] = iof;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// TODO: Upon IOF disable, set value and state according to (port & output_en)\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FALL_INTR_EN:\n\t\t\t// cout << \"[GPIO] set fall_intr_en to \";\n\t\t\t// bitPrint(reinterpret_cast<unsigned char*>(&fall_intr_en), sizeof(uint32_t));\n\t\t\tbreak;\n\t\tcase FALL_INTR_PEND:\n\t\t\t// cout << \"[GPIO] set fall_intr_pending to \";\n\t\t\t// bitPrint(reinterpret_cast<unsigned char*>(&fall_intr_pending),sizeof(uint32_t));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nvoid GPIO::transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\trouter.transport(trans, delay);\n}\n\nbool GPIO::isServerConnected() {\n\treturn server.isConnected();\n}\n\nvoid GPIO::asyncOnchange(PinNumber bit, Tristate val) {\n\tconst auto state_prev = server.state.pins[bit];\n\n\tswitch(val){\n\tcase Tristate::UNSET:\n\t\t/*\n\t\t * TODO: Maybe do pullup/down decision here or emplace into a queue\n\t\t * Queue would be better for sync, but unsure about performance.\n\t\t * May be less overhead as only changed pins can be handled.\n\t\t * But moving a bitmask unconditionally for 32 Pins is pretty fast, too.\n\t\t */\n\n\tcase Tristate::LOW:\n\tcase Tristate::HIGH:\n\t\tserver.state.pins[bit] = toPinstate(val);\n\t\tbreak;\n\tdefault:\n\t\tcout << \"[GPIO] Invalid pin value \" << (int) val << \" on pin \" << bit << endl;\n\t}\n\n\tif(state_prev != server.state.pins[bit]){\n\t\t// cout << \"[GPIO] Bit \" << (unsigned) bit << \" changed to \" << (unsigned)\n\t\t// val << endl;\n\t\tasyncEvent.notify();\n\t}\n}\n\nvoid GPIO::synchronousChange() {\n\t// cout << \"[GPIO] might have changed!\" << endl;\n\n\tgpio::State serverSnapshot = server.state;\n\n\t// This is seriously more complicated just handling the last updated bit\n\t// from asyncChange. But because we have to wait until the update phase, and\n\t// until then there may fire multiple bits!\n\n\tfor (PinNumber i = 0; i < available_pins; i++) {\n\t\tconst auto bitmask = 1l << i;\n\t\tif (input_en & bitmask) {\n\n\t\t\t// Small optimization: If not set as input, unset will stay unset even if not pullup enabled.\n\t\t\tif (serverSnapshot.pins[i] == Pinstate::UNSET) {\n\t\t\t\tif(pullup_en & bitmask)\n\t\t\t\t\tserverSnapshot.pins[i] = Pinstate::HIGH;\n\t\t\t\telse\n\t\t\t\t\tserverSnapshot.pins[i] = Pinstate::LOW;\n\t\t\t}\n\n\t\t\t// cout << \"bit \" << (unsigned) i << \" is input enabled \";\n\t\t\tif (!(value & bitmask) && serverSnapshot.pins[i] == Pinstate::HIGH) {\n\t\t\t\t// cout << \" changed to 1 \";\n\t\t\t\tif (rise_intr_en & bitmask) {\n\t\t\t\t\t// cout << \"and interrupt is enabled \";\n\t\t\t\t\t// interrupt pending is inverted\n\t\t\t\t\tif (~rise_intr_pending & bitmask) {\n\t\t\t\t\t\t// cout << \"but not yet consumed\" << endl;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// cout << \"and is being fired at \" << int_gpio_base + i\n\t\t\t\t\t\t// << endl;\n\t\t\t\t\t\trise_intr_pending &= ~bitmask;\n\t\t\t\t\t\tplic->gateway_trigger_interrupt(int_gpio_base + i);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// cout << \"but no interrupt is registered.\" << endl;\n\t\t\t\t}\n\t\t\t\t// transfer to value register\n\t\t\t\tvalue |= bitmask;\n\t\t\t} else if ((value & bitmask) && serverSnapshot.pins[i] == Pinstate::LOW){\n\t\t\t\t// cout << \" changed to 0 \";\n\t\t\t\tif (fall_intr_en & bitmask) {\n\t\t\t\t\t// cout << \"and interrupt is enabled \";\n\t\t\t\t\t// interrupt pending is inverted\n\t\t\t\t\tif (~fall_intr_pending & bitmask) {\n\t\t\t\t\t\t// cout << \"but not yet consumed\" << endl;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// cout << \"and is being fired at \" << int_gpio_base + i\n\t\t\t\t\t\t// << endl;\n\t\t\t\t\t\tfall_intr_pending &= ~bitmask;\n\t\t\t\t\t\tplic->gateway_trigger_interrupt(int_gpio_base + i);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// cout << \"but no interrupt is registered.\" << endl;\n\t\t\t\t}\n\t\t\t\t// transfer to value register\n\t\t\t\tvalue &= ~bitmask;\n\t\t\t} else {\n\t\t\t\t// This pin did not change\n\t\t\t}\n\t\t}\n\t}\n\n\t// if something changed between snapshot and now, change is discarded. \"Yeet\"\n\tserver.state = serverSnapshot;\n}\n\nUartTXFunction GPIO::getUartTransmitFunction(const gpio::PinNumber tx){\n\treturn bind(&GpioServer::pushUART, &server, tx, placeholders::_1);\n}\nvoid GPIO::registerUartReceiveFunction(const gpio::PinNumber rx, UartRXFunction fun){\n\tserver.registerUARTRX(rx, fun);\n}\n\n\nSpiWriteFunction GPIO::getSPIwriteFunction(gpio::PinNumber cs) {\n\tconst auto pin = getPinOffsFromSPIcs(cs);\n\treturn bind(&GpioServer::pushSPI, &server, pin, placeholders::_1);\n}\n"
  },
  {
    "path": "vp/src/platform/hifive/gpio.h",
    "content": "#pragma once\n\n#include \"platform/common/async_event.h\"\n#include \"core/common/irq_if.h\"\n#include <gpio-server.hpp>\n#include \"util/tlm_map.h\"\n#include \"spi.h\"\n#include \"tunnel-uart.hpp\"\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n#include <thread>\n\nstruct GPIO : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<GPIO> tsock;\n\n\t// memory mapped configuration registers\n\tuint32_t value = 0;\t\t// Current state of pin, input or output\n\tuint32_t input_en = 0;\n\tuint32_t output_en = 0;\n\tuint32_t port = 0;\t\t// Desired output values of enabled pins\n\tuint32_t pullup_en = 0;\n\tuint32_t pin_drive_strength = 0;\n\tuint32_t rise_intr_en = 0;\n\tuint32_t rise_intr_pending = ~0l;\n\tuint32_t fall_intr_en = 0;\n\tuint32_t fall_intr_pending = ~0l;\n\tuint32_t high_intr_en = 0;\n\tuint32_t high_intr_pending = ~0l;\n\tuint32_t low_intr_en = 0;\n\tuint32_t low_intr_pending = ~0l;\n\tuint32_t iof_en = 0;\n\tuint32_t iof_sel = 0;\n\tuint32_t out_xor = 0;\n\n\tenum {\n\t\tPIN_VALUE_ADDR = 0x000,\n\t\tINPUT_EN_REG_ADDR = 0x004,\n\t\tOUTPUT_EN_REG_ADDR = 0x008,\n\t\tPORT_REG_ADDR = 0x00C,\n\t\tPULLUP_EN_ADDR = 0x010,\n\t\tPIN_DRIVE_STNGTH = 0x014,\n\t\tRISE_INTR_EN = 0x018,\n\t\tRISE_INTR_PEND = 0x01C,\n\t\tFALL_INTR_EN = 0x020,\n\t\tFALL_INTR_PEND = 0x024,\n\t\tHIGH_INTR_EN = 0x028,\n\t\tHIGH_INTR_PEND = 0x02C,\n\t\tLOW_INTR_EN = 0x030,\n\t\tLOW_INTR_PEND = 0x034,\n\t\tIOF_EN_REG_ADDR = 0x038,\n\t\tIOF_SEL_REG_ADDR = 0x03C,\n\t\tOUT_XOR_REG_ADDR = 0x040,\n\t};\n\n\tvp::map::LocalRouter router = {\"GPIO\"};\n\tinterrupt_gateway *plic = nullptr;\n\n\tstatic constexpr gpio::PinNumber available_pins = 32;\n\tconst unsigned int_gpio_base;\n\tGpioServer server;\n\tstd::thread *serverThread;\n\tAsyncEvent asyncEvent;\n\n\tSC_HAS_PROCESS(GPIO);\n\tGPIO(sc_core::sc_module_name, unsigned int_gpio_base);\n\t~GPIO();\n\n\tvoid register_access_callback(const vp::map::register_access_t &r);\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay);\n\n\tbool isServerConnected();\n\n\tvoid asyncOnchange(gpio::PinNumber bit, gpio::Tristate val);\n\tvoid synchronousChange();\n\n\tUartTXFunction getUartTransmitFunction(gpio::PinNumber tx);\n\tvoid registerUartReceiveFunction(gpio::PinNumber rx, UartRXFunction);\n\n\tSpiWriteFunction getSPIwriteFunction(gpio::PinNumber cs);\n};\n"
  },
  {
    "path": "vp/src/platform/hifive/hifive_main.cpp",
    "content": "#include <cstdlib>\n#include <ctime>\n\n#include \"aon.h\"\n#include \"can.h\"\n#include \"oled/oled.hpp\"\n#include \"core/common/clint.h\"\n#include \"core/rv32/syscall.h\"\n#include \"elf_loader.h\"\n#include \"fe310_plic.h\"\n#include \"debug_memory.h\"\n#include \"gpio.h\"\n#include \"iss.h\"\n#include \"maskROM.h\"\n#include \"mem.h\"\n#include \"memory.h\"\n#include \"prci.h\"\n#include \"slip.h\"\n#include \"spi.h\"\n#include \"uart.h\"\n#include \"platform/common/options.h\"\n\n#include \"gdb-mc/gdb_server.h\"\n#include \"gdb-mc/gdb_runner.h\"\n\n#include <boost/io/ios_state.hpp>\n#include <boost/program_options.hpp>\n#include <iomanip>\n#include <iostream>\n#include <memory>\n#include <functional>\n\n// Interrupt numbers\t(see platform.h)\n#define INT_RESERVED 0\n#define INT_WDOGCMP 1\n#define INT_RTCCMP 2\n#define INT_UART0_BASE 3\n#define INT_UART1_BASE 4\n#define INT_SPI0_BASE 5\n#define INT_SPI1_BASE 6\n#define INT_SPI2_BASE 7\n#define INT_GPIO_BASE 8\n#define INT_PWM0_BASE 40\n#define INT_PWM1_BASE 44\n#define INT_PWM2_BASE 48\n\nusing namespace rv32;\nnamespace po = boost::program_options;\n\nclass HifiveOptions : public Options {\npublic:\n\ttypedef unsigned int addr_t;\n\n\taddr_t maskROM_start_addr = 0x00001000;\n\taddr_t maskROM_end_addr = 0x00001FFF;\n\taddr_t clint_start_addr = 0x02000000;\n\taddr_t clint_end_addr = 0x0200FFFF;\n\taddr_t sys_start_addr = 0x02010000;\n\taddr_t sys_end_addr = 0x020103ff;\n\taddr_t plic_start_addr = 0x0C000000;\n\taddr_t plic_end_addr = 0x0FFFFFFF;\n\taddr_t aon_start_addr = 0x10000000;\n\taddr_t aon_end_addr = 0x10007FFF;\n\taddr_t prci_start_addr = 0x10008000;\n\taddr_t prci_end_addr = 0x1000FFFF;\n\taddr_t uart0_start_addr = 0x10013000;\n\taddr_t uart0_end_addr = 0x10013FFF;\n\taddr_t uart1_start_addr = 0x10023000;\n\taddr_t uart1_end_addr = 0x10023FFF;\t\t// not routed on Hifive1 Rev. A\n\taddr_t spi0_start_addr = 0x10014000;\n\taddr_t spi0_end_addr = 0x10014FFF;\n\taddr_t spi1_start_addr = 0x10024000;\n\taddr_t spi1_end_addr = 0x10024FFF;\n\taddr_t spi2_start_addr = 0x10034000;\n\taddr_t spi2_end_addr = 0x10034FFF;\n\taddr_t gpio0_start_addr = 0x10012000;\n\taddr_t gpio0_end_addr = 0x10012FFF;\n\taddr_t flash_size = 1024 * 1024 * 512;\t// 512 MB flash\n\taddr_t flash_start_addr = 0x20000000;\n\taddr_t flash_end_addr = flash_start_addr + flash_size - 1;\n\taddr_t dram_size = 1024 * 16;\t\t\t// 16 KB dram\n\taddr_t dram_start_addr = 0x80000000;\n\taddr_t dram_end_addr = dram_start_addr + dram_size - 1;\n\n\tbool enable_can = false;\n\tbool disable_inline_oled = false;\n\tbool wait_for_gpio_connection = false;\n\tbool forward_uart_0 = false;\n\tbool forward_uart_1 = false;\n\tstd::string tun_device = \"tun0\";\n\n\tHifiveOptions(void) {\n\t\t// clang-format off\n\t\tadd_options()\n\t\t\t(\"enable-inline-can\",  po::bool_switch(&enable_can), \"enable support for CAN SPI module\")\n\t\t\t(\"disable-inline-oled\", po::bool_switch(&disable_inline_oled), \"enable support for OLED SPI module\")\n\t\t\t(\"forward-uart0-to-vbb\", po::bool_switch(&forward_uart_0), \"forwards UART_0 TX/RX to virtual breadboard\")\n\t\t\t(\"forward-uart1-to-vbb\", po::bool_switch(&forward_uart_1), \"forwards UART_1 TX/RX to virtual breadboard\")\n\t\t\t(\"wait-for-gpio-connection\", po::bool_switch(&wait_for_gpio_connection), \"Waits for a GPIO-Connection before starting program\")\n\t\t\t(\"tun-device\", po::value<std::string>(&tun_device), \"tun device used by SLIP\");\n\t\t// clang-format on\n\t}\n\n\tvoid printValues(std::ostream& os) const override {\n\t\tos << std::hex;\n\t\tos << \"flash_start_addr:\\t\" << +flash_start_addr << std::endl;\n\t\tos << \"flash_end_addr:\\t\"   << +flash_end_addr   << std::endl;\n\t\tos << \"dram_start_addr:\\t\" << +dram_start_addr << std::endl;\n\t\tos << \"dram_end_addr:\\t\"   << +dram_end_addr   << std::endl;\n\t\tstatic_cast <const Options&>( *this ).printValues(os);\n\t}\n};\n\nint sc_main(int argc, char **argv) {\n\tHifiveOptions opt;\n\topt.parse(argc, argv);\n\n\tstd::srand(std::time(nullptr));  // use current time as seed for random generator\n\n\ttlm::tlm_global_quantum::instance().set(sc_core::sc_time(opt.tlm_global_quantum, sc_core::SC_NS));\n\n\tISS core(0);\n\tSimpleMemory dram(\"DRAM\", opt.dram_size);\n\tSimpleMemory flash(\"Flash\", opt.flash_size);\n\tELFLoader loader(opt.input_program.c_str());\n\tSimpleBus<2, 14> bus(\"SimpleBus\");\n\tCombinedMemoryInterface iss_mem_if(\"MemoryInterface\", core);\n\tSyscallHandler sys(\"SyscallHandler\");\n\n\tFE310_PLIC<1, 53, 64, 7> plic(\"PLIC\");\n\tCLINT<1> clint(\"CLINT\");\n\tAON aon(\"AON\");\n\tPRCI prci(\"PRCI\");\n\tGPIO gpio0(\"GPIO0\", INT_GPIO_BASE);\n\tSPI spi0(\"SPI0\");\n\tSPI spi1(\"SPI1\");\n\tstd::shared_ptr<CAN> can;\n\tif (opt.enable_can) {\n\t\tstd::cout << \"using internal CAN controller on SPI CS 0\" << std::endl;\n\t\tcan = std::make_shared<CAN>();\n\t\tspi1.connect(0, std::bind(&CAN::write, can, std::placeholders::_1));\n\t} else {\n\t\t// pass through to gpio server\n\t\tspi1.connect(0, gpio0.getSPIwriteFunction(0));\n\t}\n\tstd::shared_ptr<SS1106> oled;\n\tif(!opt.disable_inline_oled) {\n\t\tstd::cout << \"[hifive_main] using internal SS1106 oled controller on SPI CS 2 (with DC as Pin 16, Bit 10)\" << std::endl;\n\t\toled = std::make_shared<SS1106>([&gpio0]{return gpio0.value & (1 << 10);});\t\t// custom pin 16 is offset 10\n\t\tspi1.connect(2, std::bind(&SS1106::write, oled, std::placeholders::_1));\n\t} else {\n\t\t// pass through to gpio server\n\t\tspi1.connect(2, gpio0.getSPIwriteFunction(2));\n\t}\n\n\tspi1.connect(3, gpio0.getSPIwriteFunction(3));\n\tSPI spi2(\"SPI2\");\n\tstd::shared_ptr<UART> uart0;\n\tstd::shared_ptr<Tunnel_UART> uart0_tunnel;\n\tif(opt.forward_uart_0) {\n\t\tstd::cout << \"[hifive_main] tunneling UART0 over virtual breadboard protocol\" << std::endl;\n\t\tuart0_tunnel = std::make_shared<Tunnel_UART>(\"UART0\", 3);\n\t\tuart0_tunnel->register_transmit_function(gpio0.getUartTransmitFunction(17));\n\t\tgpio0.registerUartReceiveFunction(16, std::bind(&Tunnel_UART::nonblock_receive, uart0_tunnel, std::placeholders::_1));\n\t} else {\n\t\tuart0 = std::make_shared<UART>(\"UART0\", 3);\n\t}\n\tstd::shared_ptr<SLIP> slip;\n\tstd::shared_ptr<Tunnel_UART> uart1_tunnel;\n\tif(opt.forward_uart_1) {\n\t\tstd::cout << \"[hifive_main] tunneling UART1 over virtual breadboard protocol\" << std::endl;\n\t\tuart1_tunnel = std::make_shared<Tunnel_UART>(\"UART1\", 4);\n\t\t// following pins only connected on RevB\n\t\tuart1_tunnel->register_transmit_function(gpio0.getUartTransmitFunction(23));\n\t\tgpio0.registerUartReceiveFunction(18, std::bind(&Tunnel_UART::nonblock_receive, uart1_tunnel, std::placeholders::_1));\n\t} else {\n\t\tslip = std::make_shared<SLIP>(\"SLIP\", 4, opt.tun_device);\n\t}\n\tMaskROM maskROM(\"MASKROM\");\n\tDebugMemoryInterface dbg_if(\"DebugMemoryInterface\");\n\n\tMemoryDMI dram_dmi = MemoryDMI::create_start_size_mapping(dram.data, opt.dram_start_addr, dram.size);\n\tMemoryDMI flash_dmi = MemoryDMI::create_start_size_mapping(flash.data, opt.flash_start_addr, flash.size);\n\tInstrMemoryProxy instr_mem(flash_dmi, core);\n\n\tstd::shared_ptr<BusLock> bus_lock = std::make_shared<BusLock>();\n\tiss_mem_if.bus_lock = bus_lock;\n\n\tinstr_memory_if *instr_mem_if = &iss_mem_if;\n\tdata_memory_if *data_mem_if = &iss_mem_if;\n\tif (opt.use_instr_dmi)\n\t\tinstr_mem_if = &instr_mem;\n\tif (opt.use_data_dmi)\n\t\tiss_mem_if.dmi_ranges.emplace_back(dram_dmi);\n\n\tbus.ports[ 0] = new PortMapping(opt.flash_start_addr,  opt.flash_end_addr);\n\tbus.ports[ 1] = new PortMapping(opt.dram_start_addr,   opt.dram_end_addr);\n\tbus.ports[ 2] = new PortMapping(opt.plic_start_addr,   opt.plic_end_addr);\n\tbus.ports[ 3] = new PortMapping(opt.clint_start_addr,  opt.clint_end_addr);\n\tbus.ports[ 4] = new PortMapping(opt.aon_start_addr,    opt.aon_end_addr);\n\tbus.ports[ 5] = new PortMapping(opt.prci_start_addr,   opt.prci_end_addr);\n\tbus.ports[ 6] = new PortMapping(opt.spi0_start_addr,   opt.spi0_end_addr);\n\tbus.ports[ 7] = new PortMapping(opt.uart0_start_addr,  opt.uart0_end_addr);\n\tbus.ports[ 8] = new PortMapping(opt.maskROM_start_addr,opt.maskROM_end_addr);\n\tbus.ports[ 9] = new PortMapping(opt.gpio0_start_addr,  opt.gpio0_end_addr);\n\tbus.ports[10] = new PortMapping(opt.sys_start_addr,    opt.sys_end_addr);\n\tbus.ports[11] = new PortMapping(opt.spi1_start_addr,   opt.spi1_end_addr);\n\tbus.ports[12] = new PortMapping(opt.spi2_start_addr,   opt.spi2_end_addr);\n\tbus.ports[13] = new PortMapping(opt.uart1_start_addr,  opt.uart1_end_addr);\n\n\tloader.load_executable_image(flash, flash.size, opt.flash_start_addr, false);\n\tloader.load_executable_image(dram, dram.size, opt.dram_start_addr, false);\n\n\tcore.init(instr_mem_if, data_mem_if, &clint, loader.get_entrypoint(), rv32_align_address(opt.dram_end_addr));\n\tsys.init(dram.data, opt.dram_start_addr, loader.get_heap_addr());\n\tsys.register_core(&core);\n\n\tif (opt.intercept_syscalls)\n\t\tcore.sys = &sys;\n\n\t// connect TLM sockets\n\tiss_mem_if.isock.bind(bus.tsocks[0]);\n\tdbg_if.isock.bind(bus.tsocks[1]);\n\tbus.isocks[0].bind(flash.tsock);\n\tbus.isocks[1].bind(dram.tsock);\n\tbus.isocks[2].bind(plic.tsock);\n\tbus.isocks[3].bind(clint.tsock);\n\tbus.isocks[4].bind(aon.tsock);\n\tbus.isocks[5].bind(prci.tsock);\n\tbus.isocks[6].bind(spi0.tsock);\n\tif(uart0) {\n\t\tbus.isocks[7].bind(uart0->tsock);\n\t} else if (uart0_tunnel) {\n\t\tbus.isocks[7].bind(uart0_tunnel->tsock);\n\t}\n\tbus.isocks[8].bind(maskROM.tsock);\n\tbus.isocks[9].bind(gpio0.tsock);\n\tbus.isocks[10].bind(sys.tsock);\n\tbus.isocks[11].bind(spi1.tsock);\n\tbus.isocks[12].bind(spi2.tsock);\n\tif(slip) {\n\t\tbus.isocks[13].bind(slip->tsock);\n\t} else if (uart1_tunnel) {\n\t\tbus.isocks[13].bind(uart1_tunnel->tsock);\n\t}\n\n\t// connect interrupt signals/communication\n\tplic.target_harts[0] = &core;\n\tclint.target_harts[0] = &core;\n\tgpio0.plic = &plic;\n\tif(uart0)\n\t\tuart0->plic = &plic;\n\tif(uart0_tunnel)\n\t\tuart0_tunnel->plic = &plic;\n\tif(slip)\n\t\tslip->plic = &plic;\n\tif(uart1_tunnel)\n\t\tuart1_tunnel->plic = &plic;\n\n\tstd::vector<debug_target_if *> threads;\n\tthreads.push_back(&core);\n\n\tcore.trace = opt.trace_mode;  // switch for printing instructions\n\tif (opt.use_debug_runner) {\n\t\tauto server = new GDBServer(\"GDBServer\", threads, &dbg_if, opt.debug_port);\n\t\tnew GDBServerRunner(\"GDBRunner\", server, &core);\n\t} else {\n\t\tnew DirectCoreRunner(core);\n\t}\n\n\tif(opt.wait_for_gpio_connection) {\n\t\tstd::cout << \"[hifive_main] Waiting for virtual breadboard protocol connection\" << std::endl;\n\t\twhile(!gpio0.isServerConnected()) {\n\t\t\tusleep(2000);\n\t\t}\n\t}\n\n\tsc_core::sc_start();\n\n\tcore.show();\n\n\treturn 0;\n}\n"
  },
  {
    "path": "vp/src/platform/hifive/maskROM.h",
    "content": "#pragma once\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\n#include \"core/common/irq_if.h\"\n#include \"util/tlm_map.h\"\n\n#include <arpa/inet.h>\n\nstruct MaskROM : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<MaskROM> tsock;\n\n\tconst uint32_t baseAddr = 0x1000;\n\tconst uint32_t configStringOffs = 0x03b0;\n\tconst char *configString =\n\t    \"/cs-v1/;\"\n\t    \"/{\"\n\t    \"model = \\\"SiFive,FE310G-0000-Z0\\\";\"\n\t    \"compatible = \\\"sifive,fe300\\\";\"\n\t    \"/include/ 0x20004;\"\n\t    \"};\";\n\n\tMaskROM(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &MaskROM::transport);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\ttlm::tlm_command cmd = trans.get_command();\n\t\tunsigned addr = trans.get_address();\n\t\tauto *ptr = trans.get_data_ptr();\n\t\tauto len = trans.get_data_length();\n\n\t\tif (cmd != tlm::TLM_READ_COMMAND) {\n\t\t\tthrow(std::runtime_error(\"invalid write to MROM\"));\n\t\t}\n\n\t\tif (addr < 0x000C) {  // should contain jump to OTP\n\t\t\tmemset(ptr, 0, len);\n\t\t\treturn;\n\t\t}\n\n\t\tif (addr + len <= 0x000C + sizeof(uint32_t)) {\n\t\t\tuint32_t buf = baseAddr + configStringOffs;\n\t\t\tmemcpy(ptr, &buf, sizeof(uint32_t));\n\t\t\tdelay += sc_core::sc_time(len * 5, sc_core::SC_NS);\n\t\t\treturn;\n\t\t}\n\n\t\tif (addr < configStringOffs) {\n\t\t\tstd::cerr << \"invalid access to Mask-ROM at \" << std::hex << addr << std::endl;\n\t\t\tassert(false);\n\t\t\treturn;\n\t\t}\n\n\t\tif (addr < configStringOffs + strlen(configString)) {\n\t\t\tuint32_t offs = addr - configStringOffs;\n\t\t\tuint8_t cut = offs + len <= strlen(configString) ? len : (offs + len) - strlen(configString);\n\t\t\tmemcpy(ptr, &configString[offs], cut);\n\t\t\tif (cut != len) {\n\t\t\t\tmemset(&ptr[cut], 0, len - cut);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tmemset(ptr, 0, len);\n\t\tdelay += sc_core::sc_time(len * 5, sc_core::SC_NS);\n\n\t\treturn;\n\t}\n};\n"
  },
  {
    "path": "vp/src/platform/hifive/oled/common.cpp",
    "content": "/*\n * common.cpp\n *\n *  Created on: 24 Sep 2019\n *      Author: dwd\n */\n\n#include \"common.hpp\"\n#include <sys/ipc.h>\n#include <sys/shm.h>\n#include <sys/types.h>\n\nnamespace ss1106\n{\n\nIMPL_ENUM(Operator);\n\nState* getSharedState()\n{\n\tint shmid;\n\tfor(unsigned i = 0; i < 2; i++)\n\t{\n\t\tif ((shmid = shmget(shm_key, sizeof(State), IPC_CREAT | 0660)) >= 0)\n\t\t\tcontinue;\n\n\t\tstd::cerr << \"Could not get \" << sizeof(State) << \" Byte of shared Memory \" << int(shm_key)\n\t\t\t\t  << \" for oled display\" << std::endl;\n\t\tperror(\"shmget\");\n\t\tstd::cerr << \"Trying again...\\n\" << std::endl;\n\n\t\tif(-1 == (shmctl(shm_key, IPC_RMID, nullptr)))\n\t\t{\n\t\t\tstd::cerr << \"Could not destroy SHM\" << std::endl;\n\t\t\tperror(\"shmctl\");\n\t\t\treturn nullptr;\n\t\t}\n\t}\n\n\tvoid *addr = shmat(shmid, nullptr, 0);\n\tif (addr == nullptr) {\n\t\tperror(\"shmat\");\n\t\treturn nullptr;\n\t}\n\n\treturn reinterpret_cast<State*>(addr);\n}\n\n\n};\n\n\n"
  },
  {
    "path": "vp/src/platform/hifive/oled/common.hpp",
    "content": "/*\n * common.hpp\n *\n *  Created on: 24 Sep 2019\n *      Author: dwd\n */\n\n#pragma once\n#include <inttypes.h>\n#include \"util/elegantEnums.hpp\"\n\nnamespace ss1106\n{\n\nstatic constexpr uint8_t width  = 132;\nstatic constexpr uint8_t padding_lr  = 2;\nstatic constexpr uint8_t height = 64;\nstatic_assert(height%8 == 0, \"invalid height\");\nstatic constexpr uint16_t shm_key = 1339;\n\nstruct State\n{\n\tuint8_t changed:1;\t//beh, this is for syncing\n\n\tuint8_t column;\n\tuint8_t page;\n\tuint8_t pump_voltage:2;\n\tuint8_t display_startline:6;\n\tuint8_t contrast;\n\tuint8_t segment_remap:1;\n\tuint8_t entire_disp_on:1;\n\tuint8_t invert_color:1;\n\tuint8_t multiplex_whatever:6;\n\tuint8_t display_on:1;\n\tuint8_t frame[(height / 8)][width];\n};\n\nState* getSharedState();\n\nDECLARE_ENUM(Operator,\n\tCOL_LOW,\n\tCOL_HIGH,\n\tPUMP_VOLTAGE,\n\tDISPLAY_START_LINE,\n\tCONTRAST_MODE_SET,\t\t//Double Command\n\tSEGMENT_REMAP,\n\tENTIRE_DISPLAY,\n\tNORMAL_INVERSE,\n\tMULTIPLEX_RATIO,\t\t//Double command\n\tDC_DC_VOLTAGE,\n\tDISPLAY_ON,\n\tPAGE_ADDR,\n\tCOMMON_OUTPUT_DIR,\n\tDISPLAY_OFFSET,\t\t\t//Double command\n\tDISPLAY_DIVIDE_RATIO,\t//Double command\n\tDIS_PRE_CHARGE_PERIOD,\t//Double command\n\tCOMMON_PADS_STUFF,\t\t//DC\n\tVCOM_DESELECT,\t\t\t//DC\n\tRMW,\n\tRMW_END,\n\tNOP\n);\n\n}\n\n"
  },
  {
    "path": "vp/src/platform/hifive/oled/oled.cpp",
    "content": "/*\n * oled.cpp\n *\n *  Created on: 20 Sep 2019\n *      Author: dwd\n */\n\n\n#include <platform/hifive/oled/oled.hpp>\n#include <cstdio>\n#include <exception>\n#include <cstring>\n#include <sys/types.h>\n#include <sys/shm.h>\n\nusing namespace ss1106;\n\nconst std::map<ss1106::Operator, uint8_t> SS1106::opcode =\n{\n\t{ss1106::Operator::COL_LOW, 0x00},\n\t{ss1106::Operator::COL_HIGH, 0x10},\n\t{ss1106::Operator::PUMP_VOLTAGE, 0b00110000},\n\t{ss1106::Operator::DISPLAY_START_LINE, 0b01000000},\n\t{ss1106::Operator::CONTRAST_MODE_SET, 0b10000001},\n\t{ss1106::Operator::SEGMENT_REMAP, 0xA0},\n\t{ss1106::Operator::ENTIRE_DISPLAY, 0xA4},\n\t{ss1106::Operator::NORMAL_INVERSE, 0xA6},\n\t{ss1106::Operator::MULTIPLEX_RATIO, 0b10101000},\n\t{ss1106::Operator::DC_DC_VOLTAGE, 0x8B},\n\t{ss1106::Operator::DISPLAY_ON, 0xAE},\n\t{ss1106::Operator::PAGE_ADDR, 0xB0},\n\t{ss1106::Operator::COMMON_OUTPUT_DIR, 0xC0},\n\t{ss1106::Operator::DISPLAY_OFFSET, 0b11010011},\n\t{ss1106::Operator::DISPLAY_DIVIDE_RATIO, 0b11010101},\n\t{ss1106::Operator::DIS_PRE_CHARGE_PERIOD, 0b11011001},\n\t{ss1106::Operator::COMMON_PADS_STUFF, 0b11011010},\n\t{ss1106::Operator::VCOM_DESELECT, 0b11011011},\n\t{ss1106::Operator::RMW, 0b11100000},\n\t{ss1106::Operator::RMW_END, 0b11101110},\n\t{ss1106::Operator::NOP, 0b11100011},\n};\n\nuint8_t SS1106::mask(Operator op)\n{\n\tswitch(op)\n\t{\n\tcase Operator::DISPLAY_START_LINE:\n\t\treturn 0b11000000;\n\tcase Operator::COL_LOW:\n\tcase Operator::COL_HIGH:\n\tcase Operator::PAGE_ADDR:\n\tcase Operator::COMMON_OUTPUT_DIR:\n\t\treturn 0b11110000;\n\tcase Operator::PUMP_VOLTAGE:\n\t\treturn 0b11111100;\n\tcase Operator::SEGMENT_REMAP:\n\tcase Operator::ENTIRE_DISPLAY:\n\tcase Operator::NORMAL_INVERSE:\n\tcase Operator::DISPLAY_ON:\n\t\treturn 0b11111110;\n\tcase Operator::CONTRAST_MODE_SET:\n\tcase Operator::MULTIPLEX_RATIO:\n\tcase Operator::DC_DC_VOLTAGE:\n\tcase Operator::DISPLAY_OFFSET:\n\tcase Operator::DISPLAY_DIVIDE_RATIO:\n\tcase Operator::DIS_PRE_CHARGE_PERIOD:\n\tcase Operator::COMMON_PADS_STUFF:\n\tcase Operator::VCOM_DESELECT:\n\tcase Operator::RMW:\n\tcase Operator::RMW_END:\n\tcase Operator::NOP:\n\t\treturn 0b11111111;\n\t}\n\n\treturn 0xff;\n}\n\nSS1106::Command SS1106::match(uint8_t cmd)\n{\n\t//printf(\"CMD: %02X\\n\", cmd);\n\tfor(uint16_t opu = 0; opu < *Operator(); opu++)\n\t{\n\t\tOperator op = static_cast<Operator>(opu);\t\t//Bwah, ugly\n\t\t//printf(\"%d: \\tMask %02X, opcode %02X %s\\n\", opu, mask(op), opcode[op], (~Operator(op)).c_str());\n\t\tif(((cmd ^ opcode.at(op)) & mask(op)) == 0)\n\t\t\treturn Command{op, static_cast<uint8_t>(cmd & ~mask(op))};\n\t}\n\treturn Command{Operator::NOP, 0};\n}\n\nSS1106::SS1106(std::function<bool()> getDCPin, ss1106::State* state_memory_override) : getDCPin(getDCPin)\n{\n\tif(!state_memory_override) {\n\t\tsharedSegment = ss1106::getSharedState();\n\t\tif(sharedSegment == nullptr) {\n\t\t\tthrow std::runtime_error(\"[OLED] shared Memory unexpectedly NULL\");\n\t\t}\n\t\tstate = reinterpret_cast<State*>(sharedSegment);\n\t} else {\n\t\t// Memory is somewhere else\n\t\tstate = state_memory_override;\n\t}\n\tmemset(state, 0, sizeof(State));\n};\nSS1106::~SS1106(){\n\tif (sharedSegment && shmdt(sharedSegment))\n\t\tperror(\"shmdt\");\n};\n\n\nuint8_t SS1106::write(uint8_t byte)\n{\n\tif(getDCPin())\n\t{\n\t\t//Data\n\t\t//std::cout << \"Got Data \" << std::hex << (unsigned) byte << std::endl;\n\t\tif(state->column > width)\n\t\t{\n\t\t\tstd::cerr << \"OLED: Warning, exceeding column width (\" << (int)state->column << \" of \" << (int)width << \")\" << std::endl;\n\t\t\treturn -1;\t\t//this is not in spec.\n\t\t}\n\t\tif(state->page > height/8)\n\t\t{\n\t\t\tstd::cerr << \"OLED: Warning, exceeding page (\" << (int)state->page << \" of \" << (int)height/8 << \")\" << std::endl;\n\t\t\treturn -1;\t\t//this is not in spec.\n\t\t}\n\t\tstate->frame[state->page][state->column] = byte;\n\t\tstate->changed = 1;\n\t\tstate->column++;\n\t}\n\telse\n\t{\t//Command\n\t\tswitch(mode)\n\t\t{\n\t\tcase Mode::normal:\n\t\t\tlast_cmd = match(byte);\n\t\t\t//std::cout << \"OLED: \" << ~last_cmd.op << \" \" << std::hex << (unsigned)last_cmd.payload << std::endl;\n\t\t\tswitch(last_cmd.op)\n\t\t\t{\n\t\t\tcase Operator::COL_LOW:\n\t\t\t\tstate->column = (state->column & 0xf0) | last_cmd.payload;\n\t\t\t\tbreak;\n\t\t\tcase Operator::COL_HIGH:\n\t\t\t\tstate->column = (state->column & 0x0f) | (last_cmd.payload << 4);\n\t\t\t\tbreak;\n\t\t\tcase Operator::PUMP_VOLTAGE:\n\t\t\t\tstate->pump_voltage = last_cmd.payload;\n\t\t\t\tbreak;\n\t\t\tcase Operator::CONTRAST_MODE_SET:\n\t\t\t\tmode = Mode::second_arg;\n\t\t\t\tbreak;\n\t\t\tcase Operator::NORMAL_INVERSE:\n\t\t\t\tstate->invert_color = last_cmd.payload;\n\t\t\t\tbreak;\n\t\t\t//stuff inbetween...\n\t\t\tcase Operator::DISPLAY_ON:\n\t\t\t\tstate->display_on = last_cmd.payload;\n\t\t\t\tbreak;\n\t\t\tcase Operator::PAGE_ADDR:\n\t\t\t\tstate->page = last_cmd.payload;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tstd::cerr << \"OLED: Unhandled Operator \" << ~last_cmd.op << std::endl;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase Mode::second_arg:\n\t\t\t//std::cout << \"OLED: \" << ~last_cmd.op << \" \" << std::hex << (unsigned)byte << std::endl;\n\t\t\tswitch(last_cmd.op)\n\t\t\t{\n\t\t\tcase Operator::CONTRAST_MODE_SET:\n\t\t\t\tstate->contrast = byte;\n\t\t\t\tstate->changed = 1;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tstd::cerr << \"OLED: Unhandled Dual-command-Operator \" << ~last_cmd.op << std::endl;\n\t\t\t}\n\t\t\tmode = Mode::normal;\n\t\t\tbreak;\n\t\t}\n\t}\n\t//state->changed = 1;\t\t//This may be optimizable\n\treturn 0;\n}\n\n\n\n"
  },
  {
    "path": "vp/src/platform/hifive/oled/oled.hpp",
    "content": "/*\n * oled.hpp\n *\n *  Created on: 20 Sep 2019\n *      Author: dwd\n *\n * This class models the SH1106 oled Display driver.\n */\n\n#pragma once\n#include \"common.hpp\"\n\n#include <map>\n#include <functional>\n\nclass SS1106 {\npublic:\n\ttypedef std::function<bool()> GetDCPin_function;\nprivate:\n\n\tstatic const std::map<ss1106::Operator, uint8_t> opcode;\n\n\tstruct Command\n\t{\n\t\tss1106::Operator op;\n\t\tuint8_t payload;\n\t};\n\n\tenum class Mode : uint_fast8_t\n\t{\n\t\tnormal,\n\t\tsecond_arg\n\t} mode = Mode::normal;\n\n\tvoid *sharedSegment = nullptr;\n\tss1106::State* state;\n\n\tCommand last_cmd = Command{ss1106::Operator::NOP, 0};\n\n\tGetDCPin_function getDCPin;\n\n\n\tuint8_t mask(ss1106::Operator op);\n\tCommand match(uint8_t cmd);\n\npublic:\n\tSS1106(GetDCPin_function getDCPin, ss1106::State* state_memory_override = nullptr);\n\t~SS1106();\n\n\tuint8_t write(uint8_t byte);\n};\n"
  },
  {
    "path": "vp/src/platform/hifive/otp.h",
    "content": "#pragma once\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\n#include \"irq_if.h\"\n#include \"tlm_map.h\"\n\nstruct OTP : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<OTP> tsock;\n\n\tOTP(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &OTP::transport);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tassert(false && \"OTP not yet implemented\");\n\t\treturn;\n\t}\n};\n"
  },
  {
    "path": "vp/src/platform/hifive/prci.h",
    "content": "#ifndef RISCV_VP_PRCI_H\n#define RISCV_VP_PRCI_H\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\n#include \"core/common/irq_if.h\"\n#include \"util/tlm_map.h\"\n\nstruct PRCI : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<PRCI> tsock;\n\n\t// memory mapped configuration registers\n\tuint32_t hfrosccfg = 0;\n\tuint32_t hfxosccfg = 0;\n\tuint32_t pllcfg = 0;\n\tuint32_t plloutdiv = 0;\n\n\tenum {\n\t\tHFROSCCFG_REG_ADDR = 0x0,\n\t\tHFXOSCCFG_REG_ADDR = 0x4,\n\t\tPLLCFG_REG_ADDR = 0x8,\n\t\tPLLOUTDIV_REG_ADDR = 0xC,\n\t};\n\n\tvp::map::LocalRouter router = {\"PRCI\"};\n\n\tPRCI(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &PRCI::transport);\n\n\t\trouter\n\t\t    .add_register_bank({\n\t\t        {HFROSCCFG_REG_ADDR, &hfrosccfg},\n\t\t        {HFXOSCCFG_REG_ADDR, &hfxosccfg},\n\t\t        {PLLCFG_REG_ADDR, &pllcfg},\n\t\t        {PLLOUTDIV_REG_ADDR, &plloutdiv},\n\t\t    })\n\t\t    .register_handler(this, &PRCI::register_access_callback);\n\t}\n\n\tvoid register_access_callback(const vp::map::register_access_t &r) {\n\t\t/* Pretend that the crystal oscillator output is always ready. */\n\t\tif (r.read && r.vptr == &hfxosccfg)\n\t\t\thfxosccfg = 1 << 31;\n\n\t\tr.fn();\n\n\t\tif ((r.vptr == &hfrosccfg) && r.nv)\n\t\t\thfrosccfg |= 1 << 31;\n\n\t\tif ((r.vptr == &pllcfg) && r.nv)\n\t\t\tpllcfg |= 1 << 31;\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\trouter.transport(trans, delay);\n\t}\n};\n\n#endif  // RISCV_VP_PRCI_H\n"
  },
  {
    "path": "vp/src/platform/hifive/spi.h",
    "content": "#ifndef RISCV_VP_SPI_H\n#define RISCV_VP_SPI_H\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\n#include \"core/common/irq_if.h\"\n#include \"util/tlm_map.h\"\n\n#include <map>\n#include <queue>\n\ntypedef std::function<uint8_t(uint8_t)> SpiWriteFunction;\n\ntypedef uint32_t Pin;\n\nstruct SPI : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<SPI> tsock;\n\n\t//single queue for all targets\n\tstatic constexpr uint_fast8_t queue_size = 16;\n\tstd::queue<uint8_t> rxqueue;\n\tstd::map<Pin, SpiWriteFunction> targets;\n\n\t// memory mapped configuration registers\n\tuint32_t sckdiv = 0;\n\tuint32_t sckmode = 0;\n\tuint32_t csid = 0;\n\tuint32_t csdef = 1;\n\tuint32_t csmode = 0;\n\tuint32_t delay0 = 0;\n\tuint32_t delay1 = 0;\n\tuint32_t fmt = 0;\n\tuint32_t txdata = 0;\n\tuint32_t rxdata = 0;\n\tuint32_t txmark = 0;\n\tuint32_t rxmark = 0;\n\tuint32_t fctrl = 1;\n\tuint32_t ffmt = 0;\n\tuint32_t ie = 0;\n\tuint32_t ip = 0;\n\n\tenum {\n\t\tSCKDIV_REG_ADDR = 0x00,\n\t\tSCKMODE_REG_ADDR = 0x04,\n\t\tCSID_REG_ADDR = 0x10,\n\t\tCSDEF_REG_ADDR = 0x14,\n\t\tCSMODE_REG_ADDR = 0x18,\n\t\tDELAY0_REG_ADDR = 0x28,\n\t\tDELAY1_REG_ADDR = 0x2C,\n\t\tFMT_REG_ADDR = 0x40,\n\t\tTXDATA_REG_ADDR = 0x48,\n\t\tRXDATA_REG_ADDR = 0x4C,\n\t\tTXMARK_REG_ADDR = 0x50,\n\t\tRXMARK_REG_ADDR = 0x54,\n\t\tFCTRL_REG_ADDR = 0x60,\n\t\tFFMT_REG_ADDR = 0x64,\n\t\tIE_REG_ADDR = 0x70,\n\t\tIP_REG_ADDR = 0x74,\n\t};\n\n\tstatic constexpr uint_fast8_t SPI_IP_TXWM = 0x1;\n\tstatic constexpr uint_fast8_t SPI_IP_RXWM = 0x2;\n\n\n\tvp::map::LocalRouter router = {\"SPI\"};\n\n\tSPI(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &SPI::transport);\n\n\t\trouter\n\t\t    .add_register_bank({\n\t\t        {SCKDIV_REG_ADDR, &sckdiv},\n\t\t        {SCKMODE_REG_ADDR, &sckmode},\n\t\t        {CSID_REG_ADDR, &csid},\n\t\t        {CSDEF_REG_ADDR, &csdef},\n\t\t        {CSMODE_REG_ADDR, &csmode},\n\t\t        {DELAY0_REG_ADDR, &delay0},\n\t\t        {DELAY1_REG_ADDR, &delay1},\n\t\t        {FMT_REG_ADDR, &fmt},\n\t\t        {TXDATA_REG_ADDR, &txdata},\n\t\t        {RXDATA_REG_ADDR, &rxdata},\n\t\t        {TXMARK_REG_ADDR, &txmark},\n\t\t        {RXMARK_REG_ADDR, &rxmark},\n\t\t        {FCTRL_REG_ADDR, &fctrl},\n\t\t        {FFMT_REG_ADDR, &ffmt},\n\t\t        {IE_REG_ADDR, &ie},\n\t\t        {IP_REG_ADDR, &ip},\n\t\t    })\n\t\t    .register_handler(this, &SPI::register_access_callback);\n\t}\n\n\tvoid register_access_callback(const vp::map::register_access_t &r) {\n\t\tif (r.read) {\n\t\t\tif (r.vptr == &rxdata) {\n\t\t\t\tauto target = targets.find(csid);\n\t\t\t\tif (target == targets.end()) {\n\t\t\t\t\tstd::cerr << \"Read on unregistered Chip-Select \" << csid << std::endl;\n\t\t\t\t} else {\n\t\t\t\t\tif (rxqueue.empty()) {\n\t\t\t\t\t\trxdata = 1 << 31;\n\t\t\t\t\t} else {\n\t\t\t\t\t\trxdata = rxqueue.front();\n\t\t\t\t\t\trxqueue.pop();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tr.fn();\n\n\t\tif (r.write) {\n\t\t\tif (r.vptr == &csid) {\n\t\t\t\t//std::cout << \"Chip select \" << csid << std::endl;\n\t\t\t} else if (r.vptr == &txdata) {\n\t\t\t\t//std::cout << std::hex << txdata << \" \";\n\t\t\t\tauto target = targets.find(csid);\n\t\t\t\tif (target != targets.end()) {\n\t\t\t\t\trxqueue.push(target->second(txdata));\n\n\t\t\t\t\t//TODO: Model RX-Watermark IP\n\t\t\t\t\tif(rxqueue.size() > queue_size)\n\t\t\t\t\t\trxqueue.pop();\n\n\t\t\t\t\t//TODO: Model latency.\n\t\t\t\t\tif(txmark > 0 && (ie & SPI_IP_TXWM))\n\t\t\t\t\t\tip |= SPI_IP_TXWM;\n\t\t\t\t} else {\n\t\t\t\t\tstd::cerr << \"Write on unregistered Chip-Select \" << csid << std::endl;\n\t\t\t\t}\n\t\t\t\ttxdata = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\trouter.transport(trans, delay);\n\t}\n\n\tvoid connect(Pin cs, SpiWriteFunction interface) {\n\t\tif(cs == 1 || cs > 3)\n\t\t{\n\t\t\tstd::cerr << \"SPI: Unsupported chip select \" << cs  << std::endl;\n\t\t\treturn;\n\t\t}\n\t\ttargets.insert(std::pair<const Pin, SpiWriteFunction>(cs, interface));\n\t}\n};\n\n#endif  // RISCV_VP_SPI_H\n"
  },
  {
    "path": "vp/src/platform/hifive/tunnel-uart.cpp",
    "content": "#include \"tunnel-uart.hpp\"\n\n#include <semaphore.h>\n\nTunnel_UART::Tunnel_UART(sc_core::sc_module_name name, uint32_t irqsrc) : UART_IF(name, irqsrc)\n{\n\tstop = false;\n\trx_worker = std::thread(std::bind(&Tunnel_UART::rx_dequeue, this));\n};\n\nTunnel_UART::~Tunnel_UART(){\n\tstop = true;\n\tif(rx_worker.joinable()) {\n\t\tspost(&rxempty); // unblock receive thread\n\t\trx_worker.join();\n\t}\n\tif(tx_worker.joinable()) {\n\t\tspost(&txfull); // unblock transmit thread\n\t}\n}\n\nvoid Tunnel_UART::nonblock_receive(gpio::UART_Bytes bytes) {\n\tconst std::lock_guard<std::mutex> lock(nonblock_rx_mutex);\n\tif(nonblocking_rx_queue.size() > DROP_AT_FIFO_DEPTH - UART_FIFO_DEPTH) {\n\t\tstd::cerr << \"[tunnel-uart] Warn: pre-rx_queue growing to \" << nonblocking_rx_queue.size() << \" byte.\" << std::endl;\n\t\tstd::cerr << \"              The VP can probably not keep up with the remote.\" << std::endl;\n\t}\n\tif(nonblocking_rx_queue.size() > DROP_AT_FIFO_DEPTH) {\n\t\t// Dropping elements\n\t\treturn;\n\t}\n\tfor(const auto& byte : bytes) {\n\t\tnonblocking_rx_queue.push(byte);\n\t}\n}\n\nvoid Tunnel_UART::register_transmit_function(UartTXFunction fun) {\n\ttx_worker = std::thread(std::bind(&Tunnel_UART::tx_dequeue, this, fun));\n}\n\nvoid Tunnel_UART::rx_dequeue() {\n\twhile(!stop) {\n\t\tnonblock_rx_mutex.lock();\n\t\tif(!nonblocking_rx_queue.empty() && !stop){\n\t\t\tgpio::UART_Byte byte = nonblocking_rx_queue.front();\n\t\t\tnonblocking_rx_queue.pop();\n\t\t\tnonblock_rx_mutex.unlock();\n\t\t\trxpush(byte);\t// may block\n\t\t} else {\n\t\t\tnonblock_rx_mutex.unlock();\n\t\t}\n\t}\n}\n\nvoid Tunnel_UART::tx_dequeue(UartTXFunction fun) {\n\twhile(!stop) {\n\t\t// TODO: Perhaps make this a SysC-Thread for more realism?\n\t\tconst auto data = txpull(); // TODO: Optimize if more elems are in tx queue\n\t\tif(stop)\n\t\t\tbreak;\n\t\tfun(gpio::UART_Bytes{data});\n\t}\n}\n"
  },
  {
    "path": "vp/src/platform/hifive/tunnel-uart.hpp",
    "content": "#pragma once\n\n#include \"uart_if.h\"\n#include <gpio-common.hpp> // For UART_Byte types\n#include <functional>\n#include <inttypes.h>\n#include <queue>\n#include <mutex>\n\ntypedef std::function<void(gpio::UART_Bytes)> UartRXFunction;\t// from server to peripheral\ntypedef std::function<void(gpio::UART_Bytes)> UartTXFunction;\t// from peripheral to server\n\nclass Tunnel_UART : public UART_IF {\n\tstatic constexpr unsigned DROP_AT_FIFO_DEPTH = 1600;\npublic:\n\tTunnel_UART(sc_core::sc_module_name, uint32_t irqsrc);\n\tvirtual ~Tunnel_UART(void);\n\n\n\tvoid nonblock_receive(gpio::UART_Bytes bytes);\n\tvoid register_transmit_function(UartTXFunction fun);\n\nprivate:\n\tstd::queue<gpio::UART_Byte> nonblocking_rx_queue;\n\tstd::mutex nonblock_rx_mutex;\n\n\tbool stop;\n\tstd::thread rx_worker;\n\tvoid rx_dequeue();\n\n\tstd::thread tx_worker;\n\tvoid tx_dequeue(UartTXFunction fun);\n};\n\n\n"
  },
  {
    "path": "vp/src/platform/hwitl/CMakeLists.txt",
    "content": "file(GLOB HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h*)\nfile(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.c*)\n\nadd_git_submodule(virtual-bus)\n\nadd_executable(hwitl-vp\n\t${SOURCES}\n)\n\ntarget_link_libraries(hwitl-vp rv32 virtual-bus platform-common gdb-mc ${Boost_LIBRARIES} systemc pthread)\n\nINSTALL(TARGETS hwitl-vp RUNTIME DESTINATION bin)"
  },
  {
    "path": "vp/src/platform/hwitl/main.cpp",
    "content": "#include <cstdlib>\n#include <ctime>\n\n#include \"core/common/clint.h\"\n#include \"core/common/real_clint.h\"\n#include \"elf_loader.h\"\n#include \"fe310_plic.h\"\n#include \"debug_memory.h\"\n#include \"iss.h\"\n#include \"mem.h\"\n#include \"memory.h\"\n#include \"syscall.h\"\n#include \"util/options.h\"\n#include \"platform/common/options.h\"\n#include \"platform/common/terminal.h\"\n#include \"virtual_bus_tlm_connector.hpp\"\n\n#include \"gdb-mc/gdb_server.h\"\n#include \"gdb-mc/gdb_runner.h\"\n\n#include <boost/io/ios_state.hpp>\n#include <boost/program_options.hpp>\n#include <iomanip>\n#include <iostream>\n#include <fstream>\n#include <termios.h>\n\n\nusing namespace rv32;\nnamespace po = boost::program_options;\n\nclass HwitlOptions : public Options {\npublic:\n\ttypedef unsigned int addr_t;\n\n\tstd::string virtual_bus_device;\n\tunsigned virtual_bus_baudrate = 0;\n\tstd::string test_signature;\n\tbool use_real_clint = false;\n\n\taddr_t mem_size = 1024 * 1024 * 32;  // 32 MB ram, to place it before the CLINT and run the base examples (assume\n\t                                     // memory start at zero) without modifications\n\taddr_t mem_start_addr         = 0x00000000;\n\taddr_t mem_end_addr = mem_start_addr + mem_size - 1;\n\taddr_t clint_start_addr       = 0x02000000;\n\taddr_t clint_end_addr         = 0x0200ffff;\n\taddr_t sys_start_addr         = 0x02010000;\n\taddr_t sys_end_addr           = 0x020103ff;\n\taddr_t plic_start_addr        = 0x40000000;\n\taddr_t plic_end_addr          = 0x41000000;\n\taddr_t term_start_addr        = 0x20000000;\n\taddr_t term_end_addr          = term_start_addr + 16;\n\taddr_t virtual_bus_start_addr = 0x50000000;\n\taddr_t virtual_bus_end_addr   = 0x5FFFFFFF;\n\n\tOptionValue<unsigned long> entry_point;\n\n\tHwitlOptions(void) {\n        \t// clang-format off\n\t\tadd_options()\n\t\t\t(\"use-real-clint\", po::bool_switch(&use_real_clint),\"Lock clint to wall-clock time\")\n\t\t\t(\"memory-start\", po::value<unsigned int>(&mem_start_addr),\"set memory start address\")\n\t\t\t(\"memory-size\", po::value<unsigned int>(&mem_size), \"set memory size\")\n\t\t\t(\"entry-point\", po::value<std::string>(&entry_point.option),\"set entry point address (ISS program counter)\")\n\t\t\t(\"virtual-bus-device\",  po::value<std::string>(&virtual_bus_device)->required(),\"tty to virtual bus responder\")\n\t\t\t(\"virtual-bus-baudrate\",  po::value<unsigned int>(&virtual_bus_baudrate),\"If set, change baudrate of tty device\")\n\t\t\t(\"virtual-device-start\",  po::value<unsigned int>(&virtual_bus_start_addr),\"start of virtual peripheral\")\n\t\t\t(\"virtual-device-end\",  po::value<unsigned int>(&virtual_bus_end_addr),\"end of virtual peripheral\");\n        \t// clang-format on\n\t}\n\n\tvoid parse(int argc, char **argv) override {\n\t\tOptions::parse(argc, argv);\n\t\tentry_point.finalize(parse_ulong_option);\n\t}\n};\n\nstd::ostream& operator<<(std::ostream& os, const HwitlOptions& o) {\n\tos << \"virtual-bus-device:\\t\" << o.virtual_bus_device << std::endl;\n\tos << static_cast <const Options&>( o );\n\treturn os;\n}\n\n\nint sc_main(int argc, char **argv) {\n\tHwitlOptions opt;\n\topt.parse(argc, argv);\n\n\tstd::srand(std::time(nullptr));  // use current time as seed for random generator\n\n\ttlm::tlm_global_quantum::instance().set(sc_core::sc_time(opt.tlm_global_quantum, sc_core::SC_NS));\n\n\tISS core(0);\n\tSimpleMemory mem(\"SimpleMemory\", opt.mem_size);\n\tSimpleTerminal term(\"SimpleTerminal\");\n\tELFLoader loader(opt.input_program.c_str());\n\tSimpleBus<2, 6> bus(\"SimpleBus\");\n\tCombinedMemoryInterface iss_mem_if(\"MemoryInterface\", core);\n\tSyscallHandler sys(\"SyscallHandler\");\n\tFE310_PLIC<1, 64, 96, 32> plic(\"PLIC\");\n\tDebugMemoryInterface dbg_if(\"DebugMemoryInterface\");\n\n\tstd::shared_ptr<CLINT<1>> sim_clint;\n\tstd::shared_ptr<RealCLINT> real_clint;\n\tstd::vector<clint_interrupt_target*> real_clint_targets {&core};\n\tclint_if* one_clint;\n\tif(opt.use_real_clint) {\n\t\treal_clint = std::make_shared<RealCLINT>(\"REAL_CLINT\", real_clint_targets);\n\t\tone_clint = real_clint.get();\n\t} else {\n\t\tsim_clint = std::make_shared<CLINT<1>>(\"SIM_CLINT\");\n\t\tone_clint = sim_clint.get();\n\t}\n\n\n\tint virtual_bus_device_handle = -1;\n\tvirtual_bus_device_handle = open(opt.virtual_bus_device.c_str(), O_RDWR| O_NOCTTY);\n\tif(virtual_bus_device_handle < 0) {\n\t\tstd::cerr << \"[hwitl-vp] Device \" << opt.virtual_bus_device << \" could not be opened: \"\n\t\t\t\t<< strerror(errno) << std::endl;\n\t\treturn -1;\n\t}\n\tif(opt.virtual_bus_baudrate > 0) {\n\t\tif(!setBaudrate(virtual_bus_device_handle, opt.virtual_bus_baudrate)) {\n\t\t\tstd::cerr << \"[hwitl-vp] WARN: Could not set baudrate of \" << opt.virtual_bus_baudrate << \"!\" << std::endl;\n\t\t}\n\t}\n\tsetTTYRawmode(virtual_bus_device_handle);\t// ignore return\n\n\tInitiator virtual_bus_connector(virtual_bus_device_handle);\n\tVirtualBusMember virtual_bus_member(\"virtual_bus_member\", virtual_bus_connector, opt.virtual_bus_start_addr);\n\tvirtual_bus_member.setInterruptRoutine([&plic](){plic.gateway_trigger_interrupt(2);});\n\n\tMemoryDMI dmi = MemoryDMI::create_start_size_mapping(mem.data, opt.mem_start_addr, mem.size);\n\tInstrMemoryProxy instr_mem(dmi, core);\n\n\tstd::shared_ptr<BusLock> bus_lock = std::make_shared<BusLock>();\n\tiss_mem_if.bus_lock = bus_lock;\n\n\tinstr_memory_if *instr_mem_if = &iss_mem_if;\n\tdata_memory_if *data_mem_if = &iss_mem_if;\n\tif (opt.use_instr_dmi)\n\t\tinstr_mem_if = &instr_mem;\n\tif (opt.use_data_dmi) {\n\t\tiss_mem_if.dmi_ranges.emplace_back(dmi);\n\t}\n\n\tuint64_t entry_point = loader.get_entrypoint();\n\tif (opt.entry_point.available)\n\t\tentry_point = opt.entry_point.value;\n\ttry {\n\t\tloader.load_executable_image(mem, mem.size, opt.mem_start_addr);\n\t} catch(ELFLoader::load_executable_exception& e) {\n\t\tstd::cerr << e.what() << std::endl;\n\t\tstd::cerr << \"Memory map: \" << std::endl;\n\t\tstd::cerr << opt << std::endl;\n\t\treturn -1;\n\t}\n\t/*\n\t * The rv32 calling convention defaults to 32 bit, but as this Config is\n\t * mainly used together with the syscall handler, this helps for certain floats.\n\t * https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc\n\t */\n\tcore.init(instr_mem_if, data_mem_if, one_clint, entry_point, rv64_align_address(opt.mem_end_addr));\n\tsys.init(mem.data, opt.mem_start_addr, loader.get_heap_addr());\n\tsys.register_core(&core);\n\n\tif (opt.intercept_syscalls)\n\t\tcore.sys = &sys;\n\n\t// address mapping\n\t{\n\t\tunsigned it = 0;\n\t\tbus.ports[it++] = new PortMapping(opt.mem_start_addr, opt.mem_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.clint_start_addr, opt.clint_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.plic_start_addr, opt.plic_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.term_start_addr, opt.term_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.sys_start_addr, opt.sys_end_addr);\n\t\tbus.ports[it++] = new PortMapping(opt.virtual_bus_start_addr, opt.virtual_bus_end_addr);\n\t}\n\n\t// connect TLM sockets\n\tiss_mem_if.isock.bind(bus.tsocks[0]);\n\tdbg_if.isock.bind(bus.tsocks[1]);\n\n\t{\n\t\tunsigned it = 0;\n\t\tbus.isocks[it++].bind(mem.tsock);\n\t\tif(opt.use_real_clint)\n\t\t\tbus.isocks[it++].bind(real_clint->tsock);\n\t\telse\n\t\t\tbus.isocks[it++].bind(sim_clint->tsock);\n\t\tbus.isocks[it++].bind(plic.tsock);\n\t\tbus.isocks[it++].bind(term.tsock);\n\t\tbus.isocks[it++].bind(sys.tsock);\n\t\tbus.isocks[it++].bind(virtual_bus_member.tsock);\n\t}\n\n\t// connect interrupt signals/communication\n\tplic.target_harts[0] = &core;\n\tif(sim_clint)\n\t\tsim_clint->target_harts[0] = &core;\n\n\tstd::vector<debug_target_if *> threads;\n\tthreads.push_back(&core);\n\n\tcore.trace = opt.trace_mode;  // switch for printing instructions\n\tif (opt.use_debug_runner) {\n\t\tauto server = new GDBServer(\"GDBServer\", threads, &dbg_if, opt.debug_port);\n\t\tnew GDBServerRunner(\"GDBRunner\", server, &core);\n\t} else {\n\t\tnew DirectCoreRunner(core);\n\t}\n\n\tsc_core::sc_start();\n\n\tcore.show();\n\n\tif (opt.test_signature != \"\") {\n\t\tauto begin_sig = loader.get_begin_signature_address();\n\t\tauto end_sig = loader.get_end_signature_address();\n\n\t\t{\n\t\t\tstd::cout << std::hex;\n\t\t\tstd::cout << \"begin_signature: \" << begin_sig << std::endl;\n\t\t\tstd::cout << \"end_signature: \" << end_sig << std::endl;\n\t\t\tstd::cout << \"signature output file: \" << opt.test_signature << std::endl;\n\t\t\tstd::cout << std::dec;\n\t\t}\n\n\t\tassert(end_sig >= begin_sig);\n\t\tassert(begin_sig >= opt.mem_start_addr);\n\n\t\tauto begin = begin_sig - opt.mem_start_addr;\n\t\tauto end = end_sig - opt.mem_start_addr;\n\n\t\tstd::ofstream sigfile(opt.test_signature, std::ios::out);\n\n\t\tauto n = begin;\n\t\twhile (n < end) {\n\t\t\tsigfile << std::hex << std::setw(2) << std::setfill('0') << (unsigned)mem.data[n];\n\t\t\t++n;\n\t\t}\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "vp/src/platform/hwitl/virtual_bus_tlm_connector.cpp",
    "content": "/*\n * virtual_bus_tlm_connector.cpp\n *\n *  Created on: Oct 20, 2022\n *      Author: dwd\n */\n\n\n#include \"virtual_bus_tlm_connector.hpp\"\n\nusing namespace std;\nusing namespace sc_core;\nusing namespace tlm_utils;\nusing namespace tlm;\n\nVirtualBusMember::VirtualBusMember(sc_module_name name,\n\t\tInitiator& virtual_bus_connector,\n\t\thwitl::Address base_address)\n    : sc_module(name), virtual_bus(virtual_bus_connector), base_address(base_address)  {\n\ttsock.register_b_transport(this, &VirtualBusMember::transport);\n\tm_read_delay = sc_time(SC_ZERO_TIME);\n\tm_write_delay = sc_time(SC_ZERO_TIME);\n\n\t// TODO: Issue Reset command to remote device\n\n\t// Zero time: Special case, dont update\n\tm_interrupt_polling_delay = SC_ZERO_TIME;\n\tSC_THREAD(interrupt_service);\n}\n\nvoid VirtualBusMember::setDelayTimes(sc_time read_delay, sc_time write_delay) {\n\tm_read_delay = read_delay;\n\tm_write_delay = write_delay;\n}\n\nvoid VirtualBusMember::setInterruptRoutine(std::function<void(void)> trigger_target, sc_core::sc_time polling_time) {\n\ttrigger_interrupt_callback = trigger_target;\n\tm_interrupt_polling_delay = polling_time;\n\tm_interrupt_event.notify(m_interrupt_polling_delay);\n}\n\nvoid VirtualBusMember::transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\ttlm::tlm_command cmd = trans.get_command();\n\tunsigned addr = trans.get_address();\n\tauto len = trans.get_data_length();\n\n\tif(len > sizeof(hwitl::Payload)) {\n\t\tcerr << \"[virtual_bus_tlm_connector] accesses of length > \" << sizeof(hwitl::Payload) <<\n\t\t\t\t\" currently unsupported (was \" << len << \")\" << endl;\n\t\ttrans.set_response_status(tlm_response_status::TLM_ADDRESS_ERROR_RESPONSE);\n\t\treturn;\n\t}\n\n\thwitl::Payload temp;\n\thwitl::Payload* data = &temp;\n\tconst bool unaligned = len != sizeof(hwitl::Payload);\n\tif(!unaligned) {\n\t\tdata = reinterpret_cast<hwitl::Payload*>(trans.get_data_ptr());\n\t} else {\n\t\ttemp = 0;\n\t\tif(cmd == tlm::TLM_WRITE_COMMAND) {\n\t\t\t// This just ignores word size and writes to unaligned addresses.\n\t\t\t// WARN: This lets the actual peripheral handle this\n\t\t\tassert(len <= sizeof(hwitl::Payload));\t// should always be the case\n\t\t\tmemcpy(data, trans.get_data_ptr(), len);\n\t\t}\n\t}\n\n\tif (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\tconst auto response = virtual_bus.write(base_address + addr, *data);\n\t\tswitch(response) {\n\t\tcase hwitl::ResponseStatus::Ack::ok:\n\t\t\tbreak;\n\t\tcase hwitl::ResponseStatus::Ack::not_mapped:\n\t\t\ttrans.set_response_status(tlm_response_status::TLM_ADDRESS_ERROR_RESPONSE);\n\t\t\tcerr << \"[virtual_bus_tlm_connector] Write Address \" << showbase << hex << base_address + addr << dec << \" not mapped\" << endl;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\ttrans.set_response_status(tlm_response_status::TLM_GENERIC_ERROR_RESPONSE);\n\t\t\tcerr << \"[virtual_bus_tlm_connector] Write Error '\" << static_cast<unsigned>(response) << \"' at address \" << showbase << hex << base_address + addr << dec << endl;\n\t\t}\n\t\tdelay += m_write_delay;\n\t} else if (cmd == tlm::TLM_READ_COMMAND) {\n\t\tconst auto response = virtual_bus.read(base_address + addr);\n\t\tif(!response) {\n\t\t\ttrans.set_response_status(tlm_response_status::TLM_GENERIC_ERROR_RESPONSE);\n\t\t\tcerr << \"[virtual_bus_tlm_connector] Could not read from remote\" << endl;\n\t\t\treturn;\n\t\t}\n\t\tswitch(response->getStatus().ack) {\n\t\tcase hwitl::ResponseStatus::Ack::ok:\n\t\t\t*data = response->getPayload();\n\t\t\tbreak;\n\t\tcase hwitl::ResponseStatus::Ack::not_mapped:\n\t\t\ttrans.set_response_status(tlm_response_status::TLM_ADDRESS_ERROR_RESPONSE);\n\t\t\tcerr << \"[virtual_bus_tlm_connector] Read Address \" << showbase << hex << base_address + addr << dec << \" not mapped\" << endl;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\ttrans.set_response_status(tlm_response_status::TLM_GENERIC_ERROR_RESPONSE);\n\t\t\tcerr << \"[virtual_bus_tlm_connector] Read Error \" << static_cast<unsigned>(response->getStatus().ack) << \" at address \" << showbase << hex << base_address + addr << dec << endl;\n\t\t}\n\t\tif(unaligned) {\n\t\t\tassert(len <= sizeof(hwitl::Payload));\t// should always be the case\n\t\t\tmemcpy(trans.get_data_ptr(), data, len);\n\t\t}\n\t\tdelay += m_read_delay;\n\t} else {\n\t\tsc_assert(false && \"unsupported tlm command\");\n\t}\n\n}\n\nvoid VirtualBusMember::interrupt_service() {\n\twhile (true) {\n\t\tif(m_interrupt_polling_delay > SC_ZERO_TIME)\n\t\t\tm_interrupt_event.notify(m_interrupt_polling_delay);\n\t\tsc_core::wait(m_interrupt_event);\n\n\t\tif(trigger_interrupt_callback && virtual_bus.getInterrupt())\n\t\t\ttrigger_interrupt_callback();\n\t}\n}\n"
  },
  {
    "path": "vp/src/platform/hwitl/virtual_bus_tlm_connector.hpp",
    "content": "/*\n * virtual_bus_tlm_connector.cpp\n *\n *  Created on: Oct 20, 2022\n *      Author: dwd\n */\n\n\n#include <tlm_utils/simple_target_socket.h>\n#include <systemc>\n#include <functional>\n\n#include \"bus.h\"\n#include \"virtual-bus/initiator.hpp\"\n\nstruct VirtualBusMember : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<VirtualBusMember> tsock;\n\n\tInitiator& virtual_bus;\n\tconst hwitl::Address base_address;\n\tsc_core::sc_time m_read_delay;\n\tsc_core::sc_time m_write_delay;\n\n\t// interrupt stuff\n\tsc_core::sc_time m_interrupt_polling_delay;\n\tstd::function<void(void)> trigger_interrupt_callback;\n\tsc_core::sc_event m_interrupt_event;\n\n\t/**\n\t * @input base_address will be added to the local (!) address\n\t */\n\tVirtualBusMember(sc_core::sc_module_name, Initiator& virtual_bus_connector,\n\t\t\thwitl::Address base_address = 0);\n\n\tvoid setDelayTimes(sc_core::sc_time read_delay, sc_core::sc_time write_delay);\n\tvoid setInterruptRoutine(std::function<void(void)> trigger_target, sc_core::sc_time polling_time = sc_core::sc_time(10, sc_core::SC_MS));\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay);\n\n\tSC_HAS_PROCESS(VirtualBusMember);\n\tvoid interrupt_service();\n};\n"
  },
  {
    "path": "vp/src/platform/linux/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_executable(linux-vp\n        linux_main.cpp\n        ${HEADERS})\n\ntarget_link_libraries(linux-vp rv64 platform-common gdb-mc\n\t${Boost_LIBRARIES} systemc pthread)\n\nINSTALL(TARGETS linux-vp RUNTIME DESTINATION bin)\n"
  },
  {
    "path": "vp/src/platform/linux/linux_main.cpp",
    "content": "#include <cstdlib>\n#include <ctime>\n\n#include \"core/common/clint.h\"\n#include \"elf_loader.h\"\n#include \"fu540_plic.h\"\n#include \"debug_memory.h\"\n#include \"iss.h\"\n#include \"mem.h\"\n#include \"memory.h\"\n#include \"mmu.h\"\n#include \"platform/common/slip.h\"\n#include \"platform/common/uart.h\"\n#include \"prci.h\"\n#include \"syscall.h\"\n#include \"debug.h\"\n#include \"util/options.h\"\n#include \"platform/common/options.h\"\n\n#include \"gdb-mc/gdb_server.h\"\n#include \"gdb-mc/gdb_runner.h\"\n\n#include <boost/io/ios_state.hpp>\n#include <boost/program_options.hpp>\n#include <iomanip>\n#include <iostream>\n\n#include <termios.h>\n#include <unistd.h>\n\nenum {\n\tNUM_CORES = 5,\n};\n\nusing namespace rv64;\nnamespace po = boost::program_options;\n\nstruct LinuxOptions : public Options {\npublic:\n\ttypedef unsigned int addr_t;\n\n\taddr_t mem_size = 1024u * 1024u * 2048u;  // 2048 MB ram\n\taddr_t mem_start_addr = 0x80000000;\n\taddr_t mem_end_addr = mem_start_addr + mem_size - 1;\n\taddr_t clint_start_addr = 0x02000000;\n\taddr_t clint_end_addr = 0x0200ffff;\n\taddr_t sys_start_addr = 0x02010000;\n\taddr_t sys_end_addr = 0x020103ff;\n\taddr_t dtb_rom_start_addr = 0x00001000;\n\taddr_t dtb_rom_size = 0x2000;\n\taddr_t dtb_rom_end_addr = dtb_rom_start_addr + dtb_rom_size - 1;\n\taddr_t uart0_start_addr = 0x10010000;\n\taddr_t uart0_end_addr = 0x10010fff;\n\taddr_t uart1_start_addr = 0x10011000;\n\taddr_t uart1_end_addr = 0x10011fff;\n\taddr_t plic_start_addr = 0x0C000000;\n\taddr_t plic_end_addr = 0x10000000;\n\taddr_t prci_start_addr = 0x10000000;\n\taddr_t prci_end_addr = 0x1000FFFF;\n\n\tOptionValue<unsigned long> entry_point;\n\tstd::string dtb_file;\n\tstd::string tun_device = \"tun0\";\n\n\tLinuxOptions(void) {\n        \t// clang-format off\n\t\tadd_options()\n\t\t\t(\"memory-start\", po::value<unsigned int>(&mem_start_addr),\"set memory start address\")\n\t\t\t(\"memory-size\", po::value<unsigned int>(&mem_size), \"set memory size\")\n\t\t\t(\"entry-point\", po::value<std::string>(&entry_point.option),\"set entry point address (ISS program counter)\")\n\t\t\t(\"dtb-file\", po::value<std::string>(&dtb_file)->required(), \"dtb file for boot loading\")\n\t\t\t(\"tun-device\", po::value<std::string>(&tun_device), \"tun device used by SLIP\");\n        \t// clang-format on\n\t}\n\n\tvoid parse(int argc, char **argv) override {\n\t\tOptions::parse(argc, argv);\n\t\tentry_point.finalize(parse_ulong_option);\n\t\tmem_end_addr = mem_start_addr + mem_size - 1;\n\t}\n};\n\nclass Core {\n   public:\n\tISS iss;\n\tMMU mmu;\n\tCombinedMemoryInterface memif;\n\tInstrMemoryProxy imemif;\n\n\tCore(unsigned int id, MemoryDMI dmi)\n\t    : iss(id), mmu(iss), memif((\"MemoryInterface\" + std::to_string(id)).c_str(), iss, mmu), imemif(dmi, iss) {\n\t\treturn;\n\t}\n\n\tvoid init(bool use_data_dmi, bool use_instr_dmi, clint_if *clint, uint64_t entry, uint64_t addr) {\n\t\tif (use_data_dmi)\n\t\t\tmemif.dmi_ranges.emplace_back(imemif.dmi);\n\n\t\tiss.init(get_instr_memory_if(use_instr_dmi), &memif, clint, entry, addr);\n\t}\n\n   private:\n\tinstr_memory_if *get_instr_memory_if(bool use_instr_dmi) {\n\t\tif (use_instr_dmi)\n\t\t\treturn &imemif;\n\t\telse\n\t\t\treturn &memif;\n\t}\n};\n\nint sc_main(int argc, char **argv) {\n\tLinuxOptions opt;\n\topt.parse(argc, argv);\n\n\tstd::srand(std::time(nullptr));  // use current time as seed for random generator\n\n\ttlm::tlm_global_quantum::instance().set(sc_core::sc_time(opt.tlm_global_quantum, sc_core::SC_NS));\n\n\tSimpleMemory mem(\"SimpleMemory\", opt.mem_size);\n\tSimpleMemory dtb_rom(\"DBT_ROM\", opt.dtb_rom_size);\n\tELFLoader loader(opt.input_program.c_str());\n\tSimpleBus<NUM_CORES + 1, 8> bus(\"SimpleBus\");\n\tSyscallHandler sys(\"SyscallHandler\");\n\tFU540_PLIC plic(\"PLIC\", NUM_CORES);\n\tCLINT<NUM_CORES> clint(\"CLINT\");\n\tPRCI prci(\"PRCI\");\n\tUART uart0(\"UART0\", 3);\n\tSLIP slip(\"SLIP\", 4, opt.tun_device);\n\tDebugMemoryInterface dbg_if(\"DebugMemoryInterface\");\n\tMemoryDMI dmi = MemoryDMI::create_start_size_mapping(mem.data, opt.mem_start_addr, mem.size);\n\n\tCore *cores[NUM_CORES];\n\tfor (unsigned i = 0; i < NUM_CORES; i++) {\n\t\tcores[i] = new Core(i, dmi);\n\t}\n\n\tstd::shared_ptr<BusLock> bus_lock = std::make_shared<BusLock>();\n\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\tcores[i]->memif.bus_lock = bus_lock;\n\t\tcores[i]->mmu.mem = &cores[i]->memif;\n\t}\n\n\tuint64_t entry_point = loader.get_entrypoint();\n\tif (opt.entry_point.available)\n\t\tentry_point = opt.entry_point.value;\n\n\tloader.load_executable_image(mem, mem.size, opt.mem_start_addr);\n\tsys.init(mem.data, opt.mem_start_addr, loader.get_heap_addr());\n\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\tcores[i]->init(opt.use_data_dmi, opt.use_instr_dmi, &clint, entry_point, rv64_align_address(opt.mem_end_addr));\n\n\t\tsys.register_core(&cores[i]->iss);\n\t\tif (opt.intercept_syscalls)\n\t\t\tcores[i]->iss.sys = &sys;\n\t}\n\n\t// setup port mapping\n\tbus.ports[0] = new PortMapping(opt.mem_start_addr, opt.mem_end_addr);\n\tbus.ports[1] = new PortMapping(opt.clint_start_addr, opt.clint_end_addr);\n\tbus.ports[2] = new PortMapping(opt.sys_start_addr, opt.sys_end_addr);\n\tbus.ports[3] = new PortMapping(opt.dtb_rom_start_addr, opt.dtb_rom_end_addr);\n\tbus.ports[4] = new PortMapping(opt.uart0_start_addr, opt.uart0_end_addr);\n\tbus.ports[5] = new PortMapping(opt.uart1_start_addr, opt.uart1_end_addr);\n\tbus.ports[6] = new PortMapping(opt.plic_start_addr, opt.plic_end_addr);\n\tbus.ports[7] = new PortMapping(opt.prci_start_addr, opt.prci_end_addr);\n\n\t// connect TLM sockets\n\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\tcores[i]->memif.isock.bind(bus.tsocks[i]);\n\t}\n\tdbg_if.isock.bind(bus.tsocks[NUM_CORES]);\n\tbus.isocks[0].bind(mem.tsock);\n\tbus.isocks[1].bind(clint.tsock);\n\tbus.isocks[2].bind(sys.tsock);\n\tbus.isocks[3].bind(dtb_rom.tsock);\n\tbus.isocks[4].bind(uart0.tsock);\n\tbus.isocks[5].bind(slip.tsock);\n\tbus.isocks[6].bind(plic.tsock);\n\tbus.isocks[7].bind(prci.tsock);\n\n\t// connect interrupt signals/communication\n\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\tplic.target_harts[i] = &cores[i]->iss;\n\t\tclint.target_harts[i] = &cores[i]->iss;\n\t}\n\tuart0.plic = &plic;\n\tslip.plic = &plic;\n\n\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\t// switch for printing instructions\n\t\tcores[i]->iss.trace = opt.trace_mode;\n\n\t\t// ignore WFI instructions (handle them as a NOP, which is ok according to the RISC-V ISA) to avoid running too\n\t\t// fast ahead with simulation time when the CPU is idle\n\t\tcores[i]->iss.ignore_wfi = true;\n\n\t\t// emulate RISC-V core boot loader\n\t\tcores[i]->iss.regs[RegFile::a0] = cores[i]->iss.get_hart_id();\n\t\tcores[i]->iss.regs[RegFile::a1] = opt.dtb_rom_start_addr;\n\t}\n\n\t// OpenSBI boots all harts except hart 0 by default.\n\t//\n\t// To prevent this hart from being scheduled when stuck in\n\t// the OpenSBI `sbi_hart_hang()` function do not ignore WFI on\n\t// this hart.\n\t//\n\t// See: https://github.com/riscv/opensbi/commit/d70f8aab45d1e449b3b9be26e050b20ed76e12e9\n\tcores[0]->iss.ignore_wfi = false;\n\n\t// load DTB (Device Tree Binary) file\n\tdtb_rom.load_binary_file(opt.dtb_file, 0);\n\n\tstd::vector<mmu_memory_if*> mmus;\n\tstd::vector<debug_target_if*> dharts;\n\tif (opt.use_debug_runner) {\n\t\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\t\tdharts.push_back(&cores[i]->iss);\n\t\t\tmmus.push_back(&cores[i]->memif);\n\t\t}\n\n\t\tauto server = new GDBServer(\"GDBServer\", dharts, &dbg_if, opt.debug_port, mmus);\n\t\tfor (size_t i = 0; i < dharts.size(); i++)\n\t\t\tnew GDBServerRunner((\"GDBRunner\" + std::to_string(i)).c_str(), server, dharts[i]);\n\t} else {\n\t\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\t\tnew DirectCoreRunner(cores[i]->iss);\n\t\t}\n\t}\n\n\tsc_core::sc_start();\n\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\tcores[i]->iss.show();\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "vp/src/platform/linux/prci.h",
    "content": "#ifndef RISCV_VP_PRCI_H\n#define RISCV_VP_PRCI_H\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\n#include \"core/common/irq_if.h\"\n#include \"util/tlm_map.h\"\n\nstruct PRCI : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<PRCI> tsock;\n\n\t// memory mapped configuration registers\n\tuint32_t hfrosccfg = 0;\n\tuint32_t core_pllcfg0 = 0;\n\tuint32_t ddr_pllcfg0 = 0;\n\tuint32_t core_pllcfg1 = 0;\n\tuint32_t gemgxl_pllcfg0 = 0;\n\tuint32_t gemgxl_pllcfg1 = 0;\n\tuint32_t core_clksel = 0;\n\tuint32_t reset = 0;\n\tuint32_t clkmux_status = 0;\n\n\tenum {\n\t\tHFROSCCFG_REG_ADDR = 0x0,\n\t\tCORE_PLLCFG0_REG_ADDR = 0x4,\n\t\tDDR_PLLCFG0_REG_ADDR = 0x8,\n\t\tCORE_PLLCFG1_REG_ADDR = 0x10,\n\t\tGEMGXL_PLLCFG0_REG_ADDR = 0x1C,\n\t\tGEMGXL_PLLCFG1_REG_ADDR = 0x20,\n\t\tCORE_CLKSEL_REG_ADDR = 0x24,\n\t\tRESET_REG_ADDR = 0x28,\n\t\tCLKMUX_STATUS_REG_ADDR = 0x2C,\n\t};\n\n\tvp::map::LocalRouter router = {\"PRCI\"};\n\n\tPRCI(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &PRCI::transport);\n\n\t\trouter\n\t\t    .add_register_bank({\n\t\t        {HFROSCCFG_REG_ADDR, &hfrosccfg},\n\t\t\t{CORE_PLLCFG0_REG_ADDR, &core_pllcfg0},\n\t\t\t{DDR_PLLCFG0_REG_ADDR, &ddr_pllcfg0},\n\t\t\t{CORE_PLLCFG1_REG_ADDR, &core_pllcfg1},\n\t\t\t{GEMGXL_PLLCFG0_REG_ADDR, &gemgxl_pllcfg0},\n\t\t\t{GEMGXL_PLLCFG1_REG_ADDR, &gemgxl_pllcfg1},\n\t\t\t{CORE_CLKSEL_REG_ADDR, &core_clksel},\n\t\t\t{RESET_REG_ADDR, &reset},\n\t\t\t{CLKMUX_STATUS_REG_ADDR, &clkmux_status},\n\t\t    })\n\t\t    .register_handler(this, &PRCI::register_access_callback);\n\t}\n\n\tvoid register_access_callback(const vp::map::register_access_t &r) {\n\t\tr.fn();\n\n\t\t/* TODO: not implemented yet, this is a stub */\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\trouter.transport(trans, delay);\n\t}\n};\n\n#endif  // RISCV_VP_PRCI_H\n"
  },
  {
    "path": "vp/src/platform/linux32/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_executable(linux32-vp\n\t\tlinux32_main.cpp\n        ${HEADERS})\n\ntarget_link_libraries(linux32-vp rv32 platform-common gdb-mc\n\t${Boost_LIBRARIES} systemc pthread)\n\nINSTALL(TARGETS linux32-vp RUNTIME DESTINATION bin)\n"
  },
  {
    "path": "vp/src/platform/linux32/linux32_main.cpp",
    "content": "#include <cstdlib>\n#include <ctime>\n\n#include \"core/common/clint.h\"\n#include \"elf_loader.h\"\n#include \"fu540_plic.h\"\n#include \"debug_memory.h\"\n#include \"iss.h\"\n#include \"mem.h\"\n#include \"memory.h\"\n#include \"mmu.h\"\n#include \"platform/common/slip.h\"\n#include \"platform/common/uart.h\"\n#include \"prci.h\"\n#include \"syscall.h\"\n#include \"debug.h\"\n#include \"util/options.h\"\n#include \"platform/common/options.h\"\n\n#include \"gdb-mc/gdb_server.h\"\n#include \"gdb-mc/gdb_runner.h\"\n\n#include <boost/io/ios_state.hpp>\n#include <boost/program_options.hpp>\n#include <iomanip>\n#include <iostream>\n\n#include <termios.h>\n#include <unistd.h>\n\nenum {\n\tNUM_CORES = 5,\n};\n\nusing namespace rv32;\nnamespace po = boost::program_options;\n\nstruct LinuxOptions : public Options {\npublic:\n\ttypedef unsigned int addr_t;\n\n\taddr_t mem_size = 1024u * 1024u * 1024u;  // 1024 MB ram\n\taddr_t mem_start_addr = 0x80000000;\n\taddr_t mem_end_addr = mem_start_addr + mem_size - 1;\n\taddr_t clint_start_addr = 0x02000000;\n\taddr_t clint_end_addr = 0x0200ffff;\n\taddr_t sys_start_addr = 0x02010000;\n\taddr_t sys_end_addr = 0x020103ff;\n\taddr_t dtb_rom_start_addr = 0x00001000;\n\taddr_t dtb_rom_size = 0x2000;\n\taddr_t dtb_rom_end_addr = dtb_rom_start_addr + dtb_rom_size - 1;\n\taddr_t uart0_start_addr = 0x10010000;\n\taddr_t uart0_end_addr = 0x10010fff;\n\taddr_t uart1_start_addr = 0x10011000;\n\taddr_t uart1_end_addr = 0x10011fff;\n\taddr_t plic_start_addr = 0x0C000000;\n\taddr_t plic_end_addr = 0x10000000;\n\taddr_t prci_start_addr = 0x10000000;\n\taddr_t prci_end_addr = 0x1000FFFF;\n\n\tOptionValue<unsigned long> entry_point;\n\tstd::string dtb_file;\n\tstd::string tun_device = \"tun0\";\n\n\tLinuxOptions(void) {\n        \t// clang-format off\n\t\tadd_options()\n\t\t\t(\"memory-start\", po::value<unsigned int>(&mem_start_addr),\"set memory start address\")\n\t\t\t(\"memory-size\", po::value<unsigned int>(&mem_size), \"set memory size\")\n\t\t\t(\"entry-point\", po::value<std::string>(&entry_point.option),\"set entry point address (ISS program counter)\")\n\t\t\t(\"dtb-file\", po::value<std::string>(&dtb_file)->required(), \"dtb file for boot loading\")\n\t\t\t(\"tun-device\", po::value<std::string>(&tun_device), \"tun device used by SLIP\");\n        \t// clang-format on\n\t}\n\n\tvoid parse(int argc, char **argv) override {\n\t\tOptions::parse(argc, argv);\n\t\tentry_point.finalize(parse_ulong_option);\n\t\tmem_end_addr = mem_start_addr + mem_size - 1;\n\t}\n};\n\nclass Core {\n   public:\n\tISS iss;\n\tMMU mmu;\n\tCombinedMemoryInterface memif;\n\tInstrMemoryProxy imemif;\n\n\tCore(unsigned int id, MemoryDMI dmi)\n\t    : iss(id), mmu(iss), memif((\"MemoryInterface\" + std::to_string(id)).c_str(), iss, &mmu), imemif(dmi, iss) {\n\t\treturn;\n\t}\n\n\tvoid init(bool use_data_dmi, bool use_instr_dmi, clint_if *clint, uint64_t entry, uint64_t addr) {\n\t\tif (use_data_dmi)\n\t\t\tmemif.dmi_ranges.emplace_back(imemif.dmi);\n\n\t\tiss.init(get_instr_memory_if(use_instr_dmi), &memif, clint, entry, addr);\n\t}\n\n   private:\n\tinstr_memory_if *get_instr_memory_if(bool use_instr_dmi) {\n\t\tif (use_instr_dmi)\n\t\t\treturn &imemif;\n\t\telse\n\t\t\treturn &memif;\n\t}\n};\n\nint sc_main(int argc, char **argv) {\n\tLinuxOptions opt;\n\topt.parse(argc, argv);\n\n\tstd::srand(std::time(nullptr));  // use current time as seed for random generator\n\n\ttlm::tlm_global_quantum::instance().set(sc_core::sc_time(opt.tlm_global_quantum, sc_core::SC_NS));\n\n\tSimpleMemory mem(\"SimpleMemory\", opt.mem_size);\n\tSimpleMemory dtb_rom(\"DBT_ROM\", opt.dtb_rom_size);\n\tELFLoader loader(opt.input_program.c_str());\n\tSimpleBus<NUM_CORES + 1, 8> bus(\"SimpleBus\");\n\tSyscallHandler sys(\"SyscallHandler\");\n\tFU540_PLIC plic(\"PLIC\", NUM_CORES);\n\tCLINT<NUM_CORES> clint(\"CLINT\");\n\tPRCI prci(\"PRCI\");\n\tUART uart0(\"UART0\", 3);\n\tSLIP slip(\"SLIP\", 4, opt.tun_device);\n\tDebugMemoryInterface dbg_if(\"DebugMemoryInterface\");\n\tMemoryDMI dmi = MemoryDMI::create_start_size_mapping(mem.data, opt.mem_start_addr, mem.size);\n\n\tCore *cores[NUM_CORES];\n\tfor (unsigned i = 0; i < NUM_CORES; i++) {\n\t\tcores[i] = new Core(i, dmi);\n\t}\n\n\tstd::shared_ptr<BusLock> bus_lock = std::make_shared<BusLock>();\n\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\tcores[i]->memif.bus_lock = bus_lock;\n\t\tcores[i]->mmu.mem = &cores[i]->memif;\n\t}\n\n\tuint64_t entry_point = loader.get_entrypoint();\n\tif (opt.entry_point.available)\n\t\tentry_point = opt.entry_point.value;\n\n\tloader.load_executable_image(mem, mem.size, opt.mem_start_addr);\n\tsys.init(mem.data, opt.mem_start_addr, loader.get_heap_addr());\n\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\tcores[i]->init(opt.use_data_dmi, opt.use_instr_dmi, &clint, entry_point, rv64_align_address(opt.mem_end_addr));\n\n\t\tsys.register_core(&cores[i]->iss);\n\t\tif (opt.intercept_syscalls)\n\t\t\tcores[i]->iss.sys = &sys;\n\t}\n\n\t// setup port mapping\n\tbus.ports[0] = new PortMapping(opt.mem_start_addr, opt.mem_end_addr);\n\tbus.ports[1] = new PortMapping(opt.clint_start_addr, opt.clint_end_addr);\n\tbus.ports[2] = new PortMapping(opt.sys_start_addr, opt.sys_end_addr);\n\tbus.ports[3] = new PortMapping(opt.dtb_rom_start_addr, opt.dtb_rom_end_addr);\n\tbus.ports[4] = new PortMapping(opt.uart0_start_addr, opt.uart0_end_addr);\n\tbus.ports[5] = new PortMapping(opt.uart1_start_addr, opt.uart1_end_addr);\n\tbus.ports[6] = new PortMapping(opt.plic_start_addr, opt.plic_end_addr);\n\tbus.ports[7] = new PortMapping(opt.prci_start_addr, opt.prci_end_addr);\n\n\t// connect TLM sockets\n\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\tcores[i]->memif.isock.bind(bus.tsocks[i]);\n\t}\n\tdbg_if.isock.bind(bus.tsocks[NUM_CORES]);\n\tbus.isocks[0].bind(mem.tsock);\n\tbus.isocks[1].bind(clint.tsock);\n\tbus.isocks[2].bind(sys.tsock);\n\tbus.isocks[3].bind(dtb_rom.tsock);\n\tbus.isocks[4].bind(uart0.tsock);\n\tbus.isocks[5].bind(slip.tsock);\n\tbus.isocks[6].bind(plic.tsock);\n\tbus.isocks[7].bind(prci.tsock);\n\n\t// connect interrupt signals/communication\n\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\tplic.target_harts[i] = &cores[i]->iss;\n\t\tclint.target_harts[i] = &cores[i]->iss;\n\t}\n\tuart0.plic = &plic;\n\tslip.plic = &plic;\n\n\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\t// switch for printing instructions\n\t\tcores[i]->iss.trace = opt.trace_mode;\n\n\t\t// ignore WFI instructions (handle them as a NOP, which is ok according to the RISC-V ISA) to avoid running too\n\t\t// fast ahead with simulation time when the CPU is idle\n\t\tcores[i]->iss.ignore_wfi = true;\n\n\t\t// emulate RISC-V core boot loader\n\t\tcores[i]->iss.regs[RegFile::a0] = cores[i]->iss.get_hart_id();\n\t\tcores[i]->iss.regs[RegFile::a1] = opt.dtb_rom_start_addr;\n\n\t\t// configure supported instructions\n\t\tcores[i]->iss.csrs.misa.fields.extensions |= cores[i]->iss.csrs.misa.M | cores[i]->iss.csrs.misa.A |\n\t\t\tcores[i]->iss.csrs.misa.F | cores[i]->iss.csrs.misa.D;\n\t}\n\n\t// OpenSBI boots all harts except hart 0 by default.\n\t//\n\t// To prevent this hart from being scheduled when stuck in\n\t// the OpenSBI `sbi_hart_hang()` function do not ignore WFI on\n\t// this hart.\n\t//\n\t// See: https://github.com/riscv/opensbi/commit/d70f8aab45d1e449b3b9be26e050b20ed76e12e9\n\tcores[0]->iss.ignore_wfi = false;\n\n\t// load DTB (Device Tree Binary) file\n\tdtb_rom.load_binary_file(opt.dtb_file, 0);\n\n\tstd::vector<mmu_memory_if*> mmus;\n\tstd::vector<debug_target_if*> dharts;\n\tif (opt.use_debug_runner) {\n\t\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\t\tdharts.push_back(&cores[i]->iss);\n\t\t\tmmus.push_back(&cores[i]->memif);\n\t\t}\n\n\t\tauto server = new GDBServer(\"GDBServer\", dharts, &dbg_if, opt.debug_port, mmus);\n\t\tfor (size_t i = 0; i < dharts.size(); i++)\n\t\t\tnew GDBServerRunner((\"GDBRunner\" + std::to_string(i)).c_str(), server, dharts[i]);\n\t} else {\n\t\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\t\tnew DirectCoreRunner(cores[i]->iss);\n\t\t}\n\t}\n\n\tsc_core::sc_start();\n\tfor (size_t i = 0; i < NUM_CORES; i++) {\n\t\tcores[i]->iss.show();\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "vp/src/platform/linux32/prci.h",
    "content": "#ifndef RISCV_VP_PRCI_H\n#define RISCV_VP_PRCI_H\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\n#include \"core/common/irq_if.h\"\n#include \"util/tlm_map.h\"\n\nstruct PRCI : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<PRCI> tsock;\n\n\t// memory mapped configuration registers\n\tuint32_t hfrosccfg = 0;\n\tuint32_t core_pllcfg0 = 0;\n\tuint32_t ddr_pllcfg0 = 0;\n\tuint32_t core_pllcfg1 = 0;\n\tuint32_t gemgxl_pllcfg0 = 0;\n\tuint32_t gemgxl_pllcfg1 = 0;\n\tuint32_t core_clksel = 0;\n\tuint32_t reset = 0;\n\tuint32_t clkmux_status = 0;\n\n\tenum {\n\t\tHFROSCCFG_REG_ADDR = 0x0,\n\t\tCORE_PLLCFG0_REG_ADDR = 0x4,\n\t\tDDR_PLLCFG0_REG_ADDR = 0x8,\n\t\tCORE_PLLCFG1_REG_ADDR = 0x10,\n\t\tGEMGXL_PLLCFG0_REG_ADDR = 0x1C,\n\t\tGEMGXL_PLLCFG1_REG_ADDR = 0x20,\n\t\tCORE_CLKSEL_REG_ADDR = 0x24,\n\t\tRESET_REG_ADDR = 0x28,\n\t\tCLKMUX_STATUS_REG_ADDR = 0x2C,\n\t};\n\n\tvp::map::LocalRouter router = {\"PRCI\"};\n\n\tPRCI(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &PRCI::transport);\n\n\t\trouter\n\t\t    .add_register_bank({\n\t\t        {HFROSCCFG_REG_ADDR, &hfrosccfg},\n\t\t\t{CORE_PLLCFG0_REG_ADDR, &core_pllcfg0},\n\t\t\t{DDR_PLLCFG0_REG_ADDR, &ddr_pllcfg0},\n\t\t\t{CORE_PLLCFG1_REG_ADDR, &core_pllcfg1},\n\t\t\t{GEMGXL_PLLCFG0_REG_ADDR, &gemgxl_pllcfg0},\n\t\t\t{GEMGXL_PLLCFG1_REG_ADDR, &gemgxl_pllcfg1},\n\t\t\t{CORE_CLKSEL_REG_ADDR, &core_clksel},\n\t\t\t{RESET_REG_ADDR, &reset},\n\t\t\t{CLKMUX_STATUS_REG_ADDR, &clkmux_status},\n\t\t    })\n\t\t    .register_handler(this, &PRCI::register_access_callback);\n\t}\n\n\tvoid register_access_callback(const vp::map::register_access_t &r) {\n\t\tr.fn();\n\n\t\t/* TODO: not implemented yet, this is a stub */\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\trouter.transport(trans, delay);\n\t}\n};\n\n#endif  // RISCV_VP_PRCI_H\n"
  },
  {
    "path": "vp/src/platform/microrv32/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_executable(microrv32-vp\n        ${HEADERS}\n        main.cpp)\n\ntarget_link_libraries(microrv32-vp rv32 platform-common gdb-mc ${Boost_LIBRARIES} systemc pthread)\n\nINSTALL(TARGETS microrv32-vp RUNTIME DESTINATION bin)\n"
  },
  {
    "path": "vp/src/platform/microrv32/main.cpp",
    "content": "#include <cstdlib>\n#include <ctime>\n\n#include \"core/common/clint.h\"\n#include \"elf_loader.h\"\n#include \"debug_memory.h\"\n#include \"iss.h\"\n#include \"mem.h\"\n#include \"memory.h\"\n#include \"syscall.h\"\n#include \"microrv32_uart.h\"\n#include \"microrv32_led.h\"\n#include \"microrv32_gpio.h\"\n#include \"util/options.h\"\n#include \"platform/common/options.h\"\n\n#include \"gdb-mc/gdb_server.h\"\n#include \"gdb-mc/gdb_runner.h\"\n\n#include <boost/io/ios_state.hpp>\n#include <boost/program_options.hpp>\n#include <iomanip>\n#include <iostream>\n\nusing namespace rv32;\nnamespace po = boost::program_options;\n\nclass BasicOptions : public Options {\npublic:\n\ttypedef unsigned int addr_t;\n\n\taddr_t clint_start_addr = 0x2000000;\n\taddr_t clint_end_addr = 0x200ffff;\n\taddr_t sys_start_addr = 0x02010000;\n\taddr_t sys_end_addr = 0x020103ff;\n\taddr_t mem_start_addr = 0x80000000;\n\taddr_t mem_end_addr = 0x80ffffff;\n\taddr_t led_start_addr = 0x81000000;\n\taddr_t led_end_addr = 0x810000ff;\n\taddr_t uart_start_addr = 0x82000000;\n\taddr_t uart_end_addr = 0x820000ff;\n\taddr_t gpio_a_start_addr = 0x83000000;\n\taddr_t gpio_a_end_addr = 0x830000ff;\n\t\n\taddr_t mem_size = mem_end_addr - mem_start_addr;\n\n\tbool use_E_base_isa = false;\n\n\tOptionValue<unsigned long> entry_point;\n\n\tBasicOptions(void) {\n        \t// clang-format off\n\t\tadd_options()\n\t\t\t(\"use-E-base-isa\", po::bool_switch(&use_E_base_isa), \"use the E instead of the I integer base ISA\")\n\t\t\t(\"entry-point\", po::value<std::string>(&entry_point.option),\"set entry point address (ISS program counter)\");\n        \t// clang-format on\n\t}\n\n\tvoid parse(int argc, char **argv) override {\n\t\tOptions::parse(argc, argv);\n\n\t\tentry_point.finalize(parse_ulong_option);\n\t}\n};\n\nint sc_main(int argc, char **argv) {\n\tBasicOptions opt;\n\topt.parse(argc, argv);\n\n\tstd::srand(std::time(nullptr));  // use current time as seed for random generator\n\n\ttlm::tlm_global_quantum::instance().set(sc_core::sc_time(opt.tlm_global_quantum, sc_core::SC_NS));\n\n\tISS core(0, opt.use_E_base_isa);\n\tSimpleMemory mem(\"SimpleMemory\", opt.mem_size);\n\tELFLoader loader(opt.input_program.c_str());\n\tSimpleBus<2, 6> bus(\"SimpleBus\");\n\tCombinedMemoryInterface iss_mem_if(\"MemoryInterface\", core);\n\tSyscallHandler sys(\"SyscallHandler\");\n\tCLINT<1> clint(\"CLINT\");\n\tDebugMemoryInterface dbg_if(\"DebugMemoryInterface\");\n\tMicroRV32UART uart(\"MicroRV32UART\");\n\tMicroRV32LED led(\"MicroRV32LED\");\n\tMicroRV32GPIO gpio_a(\"MicroRV32GPIO\");\n\n\tMemoryDMI dmi = MemoryDMI::create_start_size_mapping(mem.data, opt.mem_start_addr, mem.size);\n\tInstrMemoryProxy instr_mem(dmi, core);\n\n\tstd::shared_ptr<BusLock> bus_lock = std::make_shared<BusLock>();\n\tiss_mem_if.bus_lock = bus_lock;\n\n\tinstr_memory_if *instr_mem_if = &iss_mem_if;\n\tdata_memory_if *data_mem_if = &iss_mem_if;\n\tif (opt.use_instr_dmi)\n\t\tinstr_mem_if = &instr_mem;\n\tif (opt.use_data_dmi) {\n\t\tiss_mem_if.dmi_ranges.emplace_back(dmi);\n\t}\n\n\tuint64_t entry_point = loader.get_entrypoint();\n\tif (opt.entry_point.available)\n\t\tentry_point = opt.entry_point.value;\n\n\tloader.load_executable_image(mem, mem.size, opt.mem_start_addr);\n\tcore.init(instr_mem_if, data_mem_if, &clint, entry_point, rv32_align_address(opt.mem_end_addr));\n\tsys.init(mem.data, opt.mem_start_addr, loader.get_heap_addr());\n\tsys.register_core(&core);\n\n\tif (opt.intercept_syscalls)\n\t\tcore.sys = &sys;\n\n\t// address mapping\n\tbus.ports[0] = new PortMapping(opt.mem_start_addr, opt.mem_end_addr);\n\tbus.ports[1] = new PortMapping(opt.clint_start_addr, opt.clint_end_addr);\n\tbus.ports[2] = new PortMapping(opt.uart_start_addr, opt.uart_end_addr);\n\tbus.ports[3] = new PortMapping(opt.sys_start_addr, opt.sys_end_addr);\n\tbus.ports[4] = new PortMapping(opt.led_start_addr, opt.led_end_addr);\n\tbus.ports[5] = new PortMapping(opt.gpio_a_start_addr, opt.gpio_a_end_addr);\n\n\t// connect TLM sockets\n\tiss_mem_if.isock.bind(bus.tsocks[0]);\n\tdbg_if.isock.bind(bus.tsocks[1]);\n\n\tbus.isocks[0].bind(mem.tsock);\n\tbus.isocks[1].bind(clint.tsock);\n\tbus.isocks[2].bind(uart.tsock);\n\tbus.isocks[3].bind(sys.tsock);\n\tbus.isocks[4].bind(led.tsock);\n\tbus.isocks[5].bind(gpio_a.tsock);\n\n\t// connect interrupt signals/communication\n\tclint.target_harts[0] = &core;\n\n\tstd::vector<debug_target_if *> threads;\n\tthreads.push_back(&core);\n\n\tcore.trace = opt.trace_mode;  // switch for printing instructions\n\tif (opt.use_debug_runner) {\n\t\tauto server = new GDBServer(\"GDBServer\", threads, &dbg_if, opt.debug_port);\n\t\tnew GDBServerRunner(\"GDBRunner\", server, &core);\n\t} else {\n\t\tnew DirectCoreRunner(core);\n\t}\n\n\tsc_core::sc_start();\n\n\tcore.show();\n\n\treturn 0;\n}\n"
  },
  {
    "path": "vp/src/platform/microrv32/microrv32_gpio.h",
    "content": "#pragma once\n\n#include <cstdlib>\n#include <cstring>\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\nstruct MicroRV32GPIO : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<MicroRV32GPIO> tsock;\n\n\tsc_core::sc_event run_event;\n\t// each bit represents a pin in each register\n\tuint8_t direction = 0; // direction of pins, 0: input (read pin), 1: output (write pin)\n\tuint8_t input = 0; // incomming, read pin values\n\tuint8_t output = 0; // outgoing pin values\n\n\tSC_HAS_PROCESS(MicroRV32GPIO);\n\n\tMicroRV32GPIO(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &MicroRV32GPIO::transport);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tauto addr = trans.get_address();\n\t\tauto cmd = trans.get_command();\n\t\t// auto len = trans.get_data_length();\n\t\tauto ptr = trans.get_data_ptr();\n\t\t\n\t\tif (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\t    if (addr == 0) {\n\t\t        direction = *ptr;\n\t\t\t\t// printf(\"\\n[TLM] GPIO direction write: %X\\n\", *ptr);\n\t\t    } else if (addr == 4) {\n\t\t        output = *ptr;\n\t\t\t\t// printf(\"\\n[TLM] GPIO output write: %X\\n\", *ptr);\n\t\t    }\n\t\t} else if (cmd == tlm::TLM_READ_COMMAND) {\n\t\t    if (addr == 0) {\n\t\t    \t*((uint32_t*)ptr) = direction;\n\t\t    } else if (addr == 4) {\n\t\t        *((uint32_t*)ptr) = output;\n\t\t    } else if (addr == 8) {\n\t\t        *((uint32_t*)ptr) = input;\n\t\t    }\n\t\t}\n\n\t\t(void)delay;  // zero delay\n\t}\n\t/*\n\t * TODO for future : generate data for GPIO input register \n\t * a) generate random data\n\t * b) read file with timestamp and value for input register\n\t * c) accept values for input register from socket/outside vp\n\t */\n};\n"
  },
  {
    "path": "vp/src/platform/microrv32/microrv32_led.h",
    "content": "#pragma once\n\n#include <cstdlib>\n#include <cstring>\n\n#include <systemc>\n\n#include <tlm_utils/simple_target_socket.h>\n\nstruct MicroRV32LED : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<MicroRV32LED> tsock;\n\n\tsc_core::sc_event run_event;\n\tuint8_t led_vals = 0;\n\n\tSC_HAS_PROCESS(MicroRV32LED);\n\n\tMicroRV32LED(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &MicroRV32LED::transport);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tauto addr = trans.get_address();\n\t\tauto cmd = trans.get_command();\n\t\t// auto len = trans.get_data_length();\n\t\tauto ptr = trans.get_data_ptr();\n\t\t\n\t\tif (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\t    if (addr == 0) {\n\t\t        led_vals = *ptr;\n\t\t\t\t// printf(\"\\n[TLM] LED write : %X \\n\", *ptr);\n\t\t    }\n\t\t} else if (cmd == tlm::TLM_READ_COMMAND) {\n\t\t    if (addr == 0) {\n\t\t    \t *((uint32_t*)ptr) = led_vals;\n\t\t    }\n\t\t}\n\n\t\t(void)delay;  // zero delay\n\t}\n};\n"
  },
  {
    "path": "vp/src/platform/microrv32/microrv32_uart.h",
    "content": "#pragma once\n\n#include <tlm_utils/simple_target_socket.h>\n\n#include <cstdlib>\n#include <cstring>\n#include <iostream>\n#include <queue>\n#include <systemc>\n\nstruct MicroRV32UART : public sc_core::sc_module {\n\ttlm_utils::simple_target_socket<MicroRV32UART> tsock;\n\n\tsc_core::sc_event run_event;\n\n\t// tx\n\tchar buf = 0;\n\t// rx\n\tstd::queue<unsigned char> rxFifo;\n\tuint8_t rxFifoDepth = 16;\n\n\tSC_HAS_PROCESS(MicroRV32UART);\n\n\tMicroRV32UART(sc_core::sc_module_name) {\n\t\ttsock.register_b_transport(this, &MicroRV32UART::transport);\n\t\tSC_THREAD(run);\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tauto addr = trans.get_address();\n\t\tauto cmd = trans.get_command();\n\t\t// auto len = trans.get_data_length();\n\t\tauto ptr = trans.get_data_ptr();\n\n\t\tif (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\t\tif (addr == 0) {\n\t\t\t\tbuf = *ptr;\n\t\t\t} else if (addr == 4) {\n\t\t\t\tstd::cout << buf;\n\t\t\t}\n\t\t} else if (cmd == tlm::TLM_READ_COMMAND) {\n\t\t\tif (addr == 0) {\n\t\t\t\t// ignore\n\t\t\t} else if (addr == 4) {\n\t\t\t\t*((uint32_t *)ptr) = 1;\n\t\t\t} else if (addr == 8) {\n\t\t\t\tif (rxFifo.size() > 0) {\n\t\t\t\t\t*((uint32_t *)ptr) = rxFifo.front();\n\t\t\t\t\t// printf(\"\\n[TLM] UART, transport, read RX: %2X\\n\", rxFifo.front());\n\t\t\t\t\t// std::cout << std::endl << \"[TLM] uart transport RX: \" << std::hex <<\n\t\t\t\t\t// static_cast<uint8_t>(rxFifo.front()) << std::endl;\n\t\t\t\t\trxFifo.pop();\n\t\t\t\t}\n\t\t\t} else if (addr == 12) {\n\t\t\t\t*((uint32_t *)ptr) = rxFifo.size();\n\t\t\t} else if (addr == 16) {\n\t\t\t\t*((uint32_t *)ptr) = rxFifo.size() == 1;\n\t\t\t}\n\t\t}\n\t\t// std::cout << \"sc_time: \" << sc_core::sc_time_stamp() << std::endl;\n\t\t// (void)delay;  // zero delay\n\t\t// wait(sc_core::sc_time(50, sc_core::SC_NS));\n\t\tdelay += sc_core::sc_time(50, sc_core::SC_NS);\n\t}\n\n\t// untested\n\tvoid run() {\n\t\twhile (true) {\n\t\t\t// 9600 baud ~= 1ms, 115200 ~= 87us\n\t\t\t// run_event.notify(sc_core::sc_time(1, sc_core::SC_MS));\n\t\t\trun_event.notify(sc_core::sc_time(87, sc_core::SC_US));\n\t\t\tsc_core::wait(run_event);  // 40 times per second by default\n\t\t\tunsigned char newRXChar = (rand() %('z'-'A')) + 'A';\n\t\t\tif (rxFifo.size() <= rxFifoDepth) {\n\t\t\t\trxFifo.push(newRXChar);\n\t\t\t\t// printf(\"\\n[TLM] UART, run: %X\\n\", newRXChar);\n\t\t\t\t// std::cout << std::endl << \"[TLM] uart run: \" << std::hex << (newRXChar & 0xff) << std::endl;\n\t\t\t}\n\t\t}\n\t}\n};\n"
  },
  {
    "path": "vp/src/platform/test32/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_executable(test32-vp\n        test32_main.cpp\n        ${HEADERS})\n\ntarget_link_libraries(test32-vp rv32 platform-common gdb-mc ${Boost_LIBRARIES} systemc pthread)\n\nINSTALL(TARGETS test32-vp RUNTIME DESTINATION bin)\n"
  },
  {
    "path": "vp/src/platform/test32/htif.h",
    "content": "#pragma once\n\n#include <systemc>\n\nstruct HTIF : public sc_core::sc_module {\n    uint64_t *to_host;\n    uint64_t *num_instr;\n    uint64_t max_instrs;\n    std::function<void(uint64_t)> to_host_callback;\n\n    SC_HAS_PROCESS(HTIF);\n    HTIF(sc_core::sc_module_name, uint64_t *to_host, uint64_t *num_instr, uint64_t max_instrs, std::function<void(uint64_t)> to_host_callback) {\n        this->to_host = to_host;\n        this->num_instr = num_instr;\n        this->max_instrs = max_instrs;\n        this->to_host_callback = to_host_callback;\n        SC_THREAD(run);\n    }\n\n    void run() {\n        while (true) {\n            sc_core::wait(10, sc_core::SC_US);\n            auto x = *to_host;\n            to_host_callback(x);\n            x = *num_instr;\n            if (x >= max_instrs)\n                throw std::runtime_error(\"reached >= max #instrs: \" + std::to_string(x));\n        }\n    }\n};\n"
  },
  {
    "path": "vp/src/platform/test32/test32_main.cpp",
    "content": "#include <cstdlib>\n#include <ctime>\n\n#include \"core/common/clint.h\"\n#include \"elf_loader.h\"\n#include \"debug_memory.h\"\n#include \"iss.h\"\n#include \"mem.h\"\n#include \"memory.h\"\n#include \"syscall.h\"\n#include \"platform/common/options.h\"\n\n#include \"gdb-mc/gdb_server.h\"\n#include \"gdb-mc/gdb_runner.h\"\n\n#include \"htif.h\"\n\n#include <boost/io/ios_state.hpp>\n#include <boost/program_options.hpp>\n#include <iomanip>\n#include <iostream>\n#include <fstream>\n\nusing namespace rv32;\nnamespace po = boost::program_options;\n\nclass TestOptions : public Options {\npublic:\n    typedef unsigned int addr_t;\n\n    std::string test_signature;\n    std::string isa;\n    unsigned int max_test_instrs = 1000000;\n\n    addr_t mem_size = 1024 * 1024 * 32;  // 32 MB ram, to place it before the CLINT and run the base examples (assume\n    // memory start at zero) without modifications\n    addr_t mem_start_addr = 0x00000000;\n    addr_t mem_end_addr = mem_start_addr + mem_size - 1;\n    addr_t clint_start_addr = 0x02000000;\n    addr_t clint_end_addr = 0x0200ffff;\n    addr_t sys_start_addr = 0x02010000;\n    addr_t sys_end_addr = 0x020103ff;\n\n    bool use_E_base_isa = false;\n\n\tTestOptions(void) {\n\t\t// clang-format off\n\t\tadd_options()\n\t\t\t(\"memory-start\", po::value<unsigned int>(&mem_start_addr),\"set memory start address\")\n\t\t\t(\"memory-size\", po::value<unsigned int>(&mem_size), \"set memory size\")\n\t\t\t(\"use-E-base-isa\", po::bool_switch(&use_E_base_isa), \"use the E instead of the I integer base ISA\")\n\t\t\t(\"max-instrs\", po::value<unsigned int>(&max_test_instrs), \"maximum number of instructions to execute (soft limit, checked periodically)\")\n\t\t\t(\"signature\", po::value<std::string>(&test_signature)->default_value(\"\"), \"output filename for the test execution signature\")\n\t\t\t(\"isa\", po::value<std::string>(&isa)->default_value(\"imacfnus\"), \"output filename for the test execution signature\");\n\t\t// clang-format on\n\t}\n\n\tvoid parse(int argc, char **argv) override {\n\t\tOptions::parse(argc, argv);\n\t\tmem_end_addr = mem_start_addr + mem_size - 1;\n\t}\n};\n\nvoid dump_test_signature(TestOptions &opt, uint8_t *mem, ELFLoader &loader) {\n    auto begin_sig = loader.get_begin_signature_address();\n    auto end_sig = loader.get_end_signature_address();\n\n    {\n        boost::io::ios_flags_saver ifs(std::cout);\n        std::cout << std::hex;\n        std::cout << \"begin_signature: \" << begin_sig << std::endl;\n        std::cout << \"end_signature: \" << end_sig << std::endl;\n        std::cout << \"signature output file: \" << opt.test_signature << std::endl;\n    }\n\n    assert (end_sig >= begin_sig);\n    assert (begin_sig >= opt.mem_start_addr);\n\n    auto begin = begin_sig - opt.mem_start_addr;\n    auto end = end_sig - opt.mem_start_addr;\n\n    std::ofstream sigfile(opt.test_signature, std::ios::out);\n\n    auto n = begin;\n    assert (n % 4 == 0);\n    while (n < end) {\n        uint32_t *p = ((uint32_t*)&mem[n]);\n        assert ((uintptr_t)p % 4 == 0);\n        sigfile << std::hex << std::setw(8) << std::setfill('0') << *p << std::endl;\n        n += 4;\n    }\n}\n\nint sc_main(int argc, char **argv) {\n\tTestOptions opt;\n\topt.parse(argc, argv);\n\n    std::srand(std::time(nullptr));  // use current time as seed for random generator\n\n    tlm::tlm_global_quantum::instance().set(sc_core::sc_time(opt.tlm_global_quantum, sc_core::SC_NS));\n\n    ISS core(0, opt.use_E_base_isa);\n    MMU mmu(core);\n    CombinedMemoryInterface core_mem_if(\"MemoryInterface0\", core, &mmu);\n    SimpleMemory mem(\"SimpleMemory\", opt.mem_size);\n    ELFLoader loader(opt.input_program.c_str());\n    SimpleBus<2, 3> bus(\"SimpleBus\");\n    SyscallHandler sys(\"SyscallHandler\");\n    CLINT<1> clint(\"CLINT\");\n    DebugMemoryInterface dbg_if(\"DebugMemoryInterface\");\n\n    MemoryDMI dmi = MemoryDMI::create_start_size_mapping(mem.data, opt.mem_start_addr, mem.size);\n    InstrMemoryProxy instr_mem(dmi, core);\n\n    std::shared_ptr<BusLock> bus_lock = std::make_shared<BusLock>();\n    core_mem_if.bus_lock = bus_lock;\n\n    instr_memory_if *instr_mem_if = &core_mem_if;\n    data_memory_if *data_mem_if = &core_mem_if;\n    if (opt.use_instr_dmi)\n        instr_mem_if = &instr_mem;\n    if (opt.use_data_dmi) {\n        core_mem_if.dmi_ranges.emplace_back(dmi);\n    }\n\n    loader.load_executable_image(mem, mem.size, opt.mem_start_addr);\n    core.init(instr_mem_if, data_mem_if, &clint, loader.get_entrypoint(), rv32_align_address(opt.mem_end_addr));\n    sys.init(mem.data, opt.mem_start_addr, loader.get_heap_addr());\n    sys.register_core(&core);\n\n    if (opt.intercept_syscalls)\n        core.sys = &sys;\n\n    // setup port mapping\n    bus.ports[0] = new PortMapping(opt.mem_start_addr, opt.mem_end_addr);\n    bus.ports[1] = new PortMapping(opt.clint_start_addr, opt.clint_end_addr);\n    bus.ports[2] = new PortMapping(opt.sys_start_addr, opt.sys_end_addr);\n\n    // connect TLM sockets\n    core_mem_if.isock.bind(bus.tsocks[0]);\n    dbg_if.isock.bind(bus.tsocks[1]);\n    bus.isocks[0].bind(mem.tsock);\n    bus.isocks[1].bind(clint.tsock);\n    bus.isocks[2].bind(sys.tsock);\n\n    // connect interrupt signals/communication\n    clint.target_harts[0] = &core;\n\n    // switch for printing instructions\n    core.trace = opt.trace_mode;\n\n    std::vector<debug_target_if *> threads;\n    threads.push_back(&core);\n\n    if (opt.use_debug_runner) {\n        auto server = new GDBServer(\"GDBServer\", threads, &dbg_if, opt.debug_port);\n        new GDBServerRunner(\"GDBRunner\", server, &core);\n    } else {\n        new DirectCoreRunner(core);\n    }\n\n    {\n        auto addr = loader.get_to_host_address();\n        uint8_t *p = &(mem.data[addr - opt.mem_start_addr]);\n        assert (((uintptr_t)p) % 8 == 0);  // correct alignment for uint64_t\n        auto to_host_callback = [&core](uint64_t x) {\n            if (x == 1) {\n                //NOTE: the \"scall\" benchmark (RISC-V compliance) still requires HTIF support for successful completion ...\n                core.sys_exit();\n            } else {\n                if (x != 0) {\n                    std::cout << \"to-host: \" << std::to_string(x) << std::endl;\n                    core.sys_exit();\n                }\n                //throw std::runtime_error(\"to-host: \" + std::to_string(x));\n            }\n        };\n        new HTIF(\"HTIF\", (uint64_t*)p, &core.total_num_instr, opt.max_test_instrs, to_host_callback);\n    }\n\n    {\n        std::transform(opt.isa.begin(), opt.isa.end(), opt.isa.begin(), ::toupper);\n        core.csrs.misa.fields.extensions = core.csrs.misa.I;\n        if (opt.isa.find('G') != std::string::npos)\n            core.csrs.misa.fields.extensions |= core.csrs.misa.M | core.csrs.misa.A | core.csrs.misa.F | core.csrs.misa.D;\n        if (opt.isa.find('M') != std::string::npos)\n            core.csrs.misa.fields.extensions |= core.csrs.misa.M;\n        if (opt.isa.find('A') != std::string::npos)\n            core.csrs.misa.fields.extensions |= core.csrs.misa.A;\n        if (opt.isa.find('C') != std::string::npos)\n            core.csrs.misa.fields.extensions |= core.csrs.misa.C;\n        if (opt.isa.find('F') != std::string::npos)\n            core.csrs.misa.fields.extensions |= core.csrs.misa.F;\n        if (opt.isa.find('D') != std::string::npos)\n            core.csrs.misa.fields.extensions |= core.csrs.misa.D;\n        if (opt.isa.find('N') != std::string::npos)\n            core.csrs.misa.fields.extensions |= core.csrs.misa.N;\n        if (opt.isa.find('U') != std::string::npos)\n            core.csrs.misa.fields.extensions |= core.csrs.misa.U;\n        if (opt.isa.find('S') != std::string::npos)\n            core.csrs.misa.fields.extensions |= core.csrs.misa.S | core.csrs.misa.U; // NOTE: S mode implies U mode\n    }\n\n    sc_core::sc_start();\n\n    core.show();\n\n    if (!opt.test_signature.empty()) {\n        dump_test_signature(opt, mem.data, loader);\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "vp/src/platform/tiny32/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_executable(tiny32-vp\n        tiny32_main.cpp\n        ${HEADERS})\n\ntarget_link_libraries(tiny32-vp rv32 platform-common gdb-mc\n\t${Boost_LIBRARIES} systemc pthread)\n\nINSTALL(TARGETS tiny32-vp RUNTIME DESTINATION bin)\n"
  },
  {
    "path": "vp/src/platform/tiny32/tiny32_main.cpp",
    "content": "#include <cstdlib>\n#include <ctime>\n\n#include \"core/common/real_clint.h\"\n#include \"elf_loader.h\"\n#include \"debug_memory.h\"\n#include \"iss.h\"\n#include \"mem.h\"\n#include \"memory.h\"\n#include \"syscall.h\"\n#include \"platform/common/options.h\"\n\n#include \"gdb-mc/gdb_server.h\"\n#include \"gdb-mc/gdb_runner.h\"\n\n#include <boost/io/ios_state.hpp>\n#include <boost/program_options.hpp>\n#include <iomanip>\n#include <iostream>\n\nusing namespace rv32;\nnamespace po = boost::program_options;\n\nstruct TinyOptions : public Options {\npublic:\n\ttypedef unsigned int addr_t;\n\n\taddr_t mem_size = 1024 * 1024 * 32;  // 32 MB ram, to place it before the CLINT and run the base examples (assume\n\t                                     // memory start at zero) without modifications\n\taddr_t mem_start_addr = 0x00000000;\n\taddr_t mem_end_addr = mem_start_addr + mem_size - 1;\n\taddr_t clint_start_addr = 0x02000000;\n\taddr_t clint_end_addr = 0x0200ffff;\n\taddr_t sys_start_addr = 0x02010000;\n\taddr_t sys_end_addr = 0x020103ff;\n\n\tbool quiet = false;\n\tbool use_E_base_isa = false;\n\n\tTinyOptions(void) {\n\t\t// clang-format off\n\t\tadd_options()\n\t\t\t(\"quiet\", po::bool_switch(&quiet), \"do not output register values on exit\")\n\t\t\t(\"memory-start\", po::value<unsigned int>(&mem_start_addr), \"set memory start address\")\n\t\t\t(\"memory-size\", po::value<unsigned int>(&mem_size), \"set memory size\")\n\t\t\t(\"use-E-base-isa\", po::bool_switch(&use_E_base_isa), \"use the E instead of the I integer base ISA\");\n        \t// clang-format on\n        }\n\n\tvoid parse(int argc, char **argv) override {\n\t\tOptions::parse(argc, argv);\n\t\tmem_end_addr = mem_start_addr + mem_size - 1;\n\t}\n};\n\nint sc_main(int argc, char **argv) {\n\tTinyOptions opt;\n\topt.parse(argc, argv);\n\n\tstd::srand(std::time(nullptr));  // use current time as seed for random generator\n\n\ttlm::tlm_global_quantum::instance().set(sc_core::sc_time(opt.tlm_global_quantum, sc_core::SC_NS));\n\n\tISS core(0, opt.use_E_base_isa);\n    MMU mmu(core);\n\tCombinedMemoryInterface core_mem_if(\"MemoryInterface0\", core, &mmu);\n\tSimpleMemory mem(\"SimpleMemory\", opt.mem_size);\n\tELFLoader loader(opt.input_program.c_str());\n\tSimpleBus<2, 3> bus(\"SimpleBus\");\n\tSyscallHandler sys(\"SyscallHandler\");\n\tDebugMemoryInterface dbg_if(\"DebugMemoryInterface\");\n\n\tstd::vector<clint_interrupt_target*> clint_targets {&core};\n\tRealCLINT clint(\"CLINT\", clint_targets);\n\n\tMemoryDMI dmi = MemoryDMI::create_start_size_mapping(mem.data, opt.mem_start_addr, mem.size);\n\tInstrMemoryProxy instr_mem(dmi, core);\n\n\tstd::shared_ptr<BusLock> bus_lock = std::make_shared<BusLock>();\n\tcore_mem_if.bus_lock = bus_lock;\n\n\tinstr_memory_if *instr_mem_if = &core_mem_if;\n\tdata_memory_if *data_mem_if = &core_mem_if;\n\tif (opt.use_instr_dmi)\n\t\tinstr_mem_if = &instr_mem;\n\tif (opt.use_data_dmi) {\n\t\tcore_mem_if.dmi_ranges.emplace_back(dmi);\n\t}\n\n\tloader.load_executable_image(mem, mem.size, opt.mem_start_addr);\n\tcore.init(instr_mem_if, data_mem_if, &clint, loader.get_entrypoint(), rv32_align_address(opt.mem_end_addr));\n\tsys.init(mem.data, opt.mem_start_addr, loader.get_heap_addr());\n\tsys.register_core(&core);\n\n\tif (opt.intercept_syscalls)\n\t\tcore.sys = &sys;\n\tcore.error_on_zero_traphandler = opt.error_on_zero_traphandler;\n\n\t// setup port mapping\n\tbus.ports[0] = new PortMapping(opt.mem_start_addr, opt.mem_end_addr);\n\tbus.ports[1] = new PortMapping(opt.clint_start_addr, opt.clint_end_addr);\n\tbus.ports[2] = new PortMapping(opt.sys_start_addr, opt.sys_end_addr);\n\n\t// connect TLM sockets\n\tcore_mem_if.isock.bind(bus.tsocks[0]);\n\tdbg_if.isock.bind(bus.tsocks[1]);\n\tbus.isocks[0].bind(mem.tsock);\n\tbus.isocks[1].bind(clint.tsock);\n\tbus.isocks[2].bind(sys.tsock);\n\n\t// switch for printing instructions\n\tcore.trace = opt.trace_mode;\n\n\tstd::vector<debug_target_if *> threads;\n\tthreads.push_back(&core);\n\n\tif (opt.use_debug_runner) {\n\t\tauto server = new GDBServer(\"GDBServer\", threads, &dbg_if, opt.debug_port);\n\t\tnew GDBServerRunner(\"GDBRunner\", server, &core);\n\t} else {\n\t\tnew DirectCoreRunner(core);\n\t}\n\n\tif (opt.quiet)\n\t\t sc_core::sc_report_handler::set_verbosity_level(sc_core::SC_NONE);\n\n\tsc_core::sc_start();\n\tif (!opt.quiet) {\n\t\tcore.show();\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "vp/src/platform/tiny32-mc/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_executable(tiny32-mc\n        mc_main.cpp\n        ${HEADERS})\n\ntarget_link_libraries(tiny32-mc rv32 platform-common gdb-mc\n\t${Boost_LIBRARIES} systemc pthread)\n\nINSTALL(TARGETS tiny32-mc RUNTIME DESTINATION bin)\n"
  },
  {
    "path": "vp/src/platform/tiny32-mc/mc_main.cpp",
    "content": "#include <cstdlib>\n#include <ctime>\n\n#include \"core/common/clint.h\"\n#include \"elf_loader.h\"\n#include \"iss.h\"\n#include \"mem.h\"\n#include \"memory.h\"\n#include \"syscall.h\"\n#include \"platform/common/options.h\"\n\n#include \"gdb-mc/gdb_server.h\"\n#include \"gdb-mc/gdb_runner.h\"\n\n#include <boost/io/ios_state.hpp>\n#include <boost/program_options.hpp>\n#include <iomanip>\n#include <iostream>\n\nusing namespace rv32;\nnamespace po = boost::program_options;\n\nstruct TinyOptions : public Options {\npublic:\n\ttypedef unsigned int addr_t;\n\n\taddr_t mem_size = 1024 * 1024 * 32;  // 32 MB ram, to place it before the CLINT and run the base examples (assume\n\t                                     // memory start at zero) without modifications\n\taddr_t mem_start_addr = 0x00000000;\n\taddr_t mem_end_addr = mem_start_addr + mem_size - 1;\n\taddr_t clint_start_addr = 0x02000000;\n\taddr_t clint_end_addr = 0x0200ffff;\n\taddr_t sys_start_addr = 0x02010000;\n\taddr_t sys_end_addr = 0x020103ff;\n\n\tbool quiet = false;\n\tbool use_E_base_isa = false;\n\n\tTinyOptions(void) {\n\t\t// clang-format off\n\t\tadd_options()\n\t\t\t(\"quiet\", po::bool_switch(&quiet), \"do not output register values on exit\")\n\t\t\t(\"memory-start\", po::value<unsigned int>(&mem_start_addr), \"set memory start address\")\n\t\t\t(\"memory-size\", po::value<unsigned int>(&mem_size), \"set memory size\")\n\t\t\t(\"use-E-base-isa\", po::bool_switch(&use_E_base_isa), \"use the E instead of the I integer base ISA\");\n        \t// clang-format on\n        }\n\n\tvoid parse(int argc, char **argv) override {\n\t\tOptions::parse(argc, argv);\n\t\tmem_end_addr = mem_start_addr + mem_size - 1;\n\t}\n};\n\nint sc_main(int argc, char **argv) {\n\tTinyOptions opt;\n\topt.parse(argc, argv);\n\n\tstd::srand(std::time(nullptr));  // use current time as seed for random generator\n\n\ttlm::tlm_global_quantum::instance().set(sc_core::sc_time(opt.tlm_global_quantum, sc_core::SC_NS));\n\n\tISS core0(0);\n\tISS core1(1);\n\tCombinedMemoryInterface core0_mem_if(\"MemoryInterface0\", core0);\n\tCombinedMemoryInterface core1_mem_if(\"MemoryInterface1\", core1);\n\n\tSimpleMemory mem(\"SimpleMemory\", opt.mem_size);\n\tELFLoader loader(opt.input_program.c_str());\n\tSimpleBus<3, 3> bus(\"SimpleBus\");\n\tSyscallHandler sys(\"SyscallHandler\");\n\tCLINT<2> clint(\"CLINT\");\n\tDebugMemoryInterface dbg_if(\"DebugMemoryInterface\");\n\n\tstd::shared_ptr<BusLock> bus_lock = std::make_shared<BusLock>();\n\tcore0_mem_if.bus_lock = bus_lock;\n\tcore1_mem_if.bus_lock = bus_lock;\n\n\tbus.ports[0] = new PortMapping(opt.mem_start_addr, opt.mem_end_addr);\n\tbus.ports[1] = new PortMapping(opt.clint_start_addr, opt.clint_end_addr);\n\tbus.ports[2] = new PortMapping(opt.sys_start_addr, opt.sys_end_addr);\n\n\tloader.load_executable_image(mem, mem.size, opt.mem_start_addr);\n\n\tcore0.init(&core0_mem_if, &core0_mem_if, &clint, loader.get_entrypoint(),\n\t           opt.mem_end_addr - 3);  // -3 to not overlap with the next region and stay 32 bit aligned\n\tcore1.init(&core1_mem_if, &core1_mem_if, &clint, loader.get_entrypoint(), opt.mem_end_addr - 32767);\n\n\tsys.init(mem.data, opt.mem_start_addr, loader.get_heap_addr());\n\tsys.register_core(&core0);\n\tsys.register_core(&core1);\n\n\tif (opt.intercept_syscalls) {\n\t\tcore0.sys = &sys;\n\t\tcore1.sys = &sys;\n\t}\n\tcore0.error_on_zero_traphandler = opt.error_on_zero_traphandler;\n\tcore1.error_on_zero_traphandler = opt.error_on_zero_traphandler;\n\n\t// connect TLM sockets\n\tcore0_mem_if.isock.bind(bus.tsocks[0]);\n\tcore1_mem_if.isock.bind(bus.tsocks[1]);\n\tdbg_if.isock.bind(bus.tsocks[2]);\n\tbus.isocks[0].bind(mem.tsock);\n\tbus.isocks[1].bind(clint.tsock);\n\tbus.isocks[2].bind(sys.tsock);\n\n\t// connect interrupt signals/communication\n\tclint.target_harts[0] = &core0;\n\tclint.target_harts[1] = &core1;\n\n\t// switch for printing instructions\n\tcore0.trace = opt.trace_mode;\n\tcore1.trace = opt.trace_mode;\n\n\tstd::vector<debug_target_if *> threads;\n\tthreads.push_back(&core0);\n\tthreads.push_back(&core1);\n\n\tif (opt.use_debug_runner) {\n\t\tauto server = new GDBServer(\"GDBServer\", threads, &dbg_if, opt.debug_port);\n\t\tnew GDBServerRunner(\"GDBRunner0\", server, &core0);\n\t\tnew GDBServerRunner(\"GDBRunner1\", server, &core1);\n\t} else {\n\t\tnew DirectCoreRunner(core0);\n\t\tnew DirectCoreRunner(core1);\n\t}\n\n\tif (opt.quiet)\n\t\tsc_core::sc_report_handler::set_verbosity_level(sc_core::SC_NONE);\n\n\tsc_core::sc_start();\n\tif (!opt.quiet) {\n\t\tcore0.show();\n\t\tcore1.show();\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "vp/src/platform/tiny64/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_executable(tiny64-vp\n        tiny64_main.cpp\n        ${HEADERS})\n\ntarget_link_libraries(tiny64-vp rv64 platform-common gdb-mc ${Boost_LIBRARIES} systemc pthread)\n\nINSTALL(TARGETS tiny64-vp RUNTIME DESTINATION bin)\n"
  },
  {
    "path": "vp/src/platform/tiny64/tiny64_main.cpp",
    "content": "#include <cstdlib>\n#include <ctime>\n\n#include \"core/common/real_clint.h\"\n#include \"elf_loader.h\"\n#include \"debug_memory.h\"\n#include \"iss.h\"\n#include \"mem.h\"\n#include \"memory.h\"\n#include \"mmu.h\"\n#include \"syscall.h\"\n#include \"platform/common/options.h\"\n\n#include \"gdb-mc/gdb_server.h\"\n#include \"gdb-mc/gdb_runner.h\"\n\n#include <boost/io/ios_state.hpp>\n#include <boost/program_options.hpp>\n#include <iomanip>\n#include <iostream>\n\nusing namespace rv64;\nnamespace po = boost::program_options;\n\nstruct TinyOptions : public Options {\npublic:\n\ttypedef unsigned int addr_t;\n\n\taddr_t mem_size = 1024 * 1024 * 32;  // 32 MB ram, to place it before the CLINT and run the base examples (assume\n\t                                     // memory start at zero) without modifications\n\taddr_t mem_start_addr = 0x00000000;\n\taddr_t mem_end_addr = mem_start_addr + mem_size - 1;\n\taddr_t clint_start_addr = 0x02000000;\n\taddr_t clint_end_addr = 0x0200ffff;\n\taddr_t sys_start_addr = 0x02010000;\n\taddr_t sys_end_addr = 0x020103ff;\n\n\tbool quiet = false;\n\tbool use_E_base_isa = false;\n\n\tTinyOptions(void) {\n\t\t// clang-format off\n\t\tadd_options()\n\t\t\t(\"quiet\", po::bool_switch(&quiet), \"do not output register values on exit\")\n\t\t\t(\"memory-start\", po::value<unsigned int>(&mem_start_addr), \"set memory start address\")\n\t\t\t(\"memory-size\", po::value<unsigned int>(&mem_size), \"set memory size\")\n\t\t\t(\"use-E-base-isa\", po::bool_switch(&use_E_base_isa), \"use the E instead of the I integer base ISA\");\n        \t// clang-format on\n        }\n\n\tvoid parse(int argc, char **argv) override {\n\t\tOptions::parse(argc, argv);\n\t\tmem_end_addr = mem_start_addr + mem_size - 1;\n\t}\n};\n\nint sc_main(int argc, char **argv) {\n\tTinyOptions opt;\n\topt.parse(argc, argv);\n\n\tstd::srand(std::time(nullptr));  // use current time as seed for random generator\n\n\ttlm::tlm_global_quantum::instance().set(sc_core::sc_time(opt.tlm_global_quantum, sc_core::SC_NS));\n\n\tISS core(0);\n\tMMU mmu(core);\n\tCombinedMemoryInterface core_mem_if(\"MemoryInterface0\", core, mmu);\n\tSimpleMemory mem(\"SimpleMemory\", opt.mem_size);\n\tELFLoader loader(opt.input_program.c_str());\n\tSimpleBus<2, 3> bus(\"SimpleBus\");\n\tSyscallHandler sys(\"SyscallHandler\");\n\tDebugMemoryInterface dbg_if(\"DebugMemoryInterface\");\n\n\tstd::vector<clint_interrupt_target*> clint_targets {&core};\n\tRealCLINT clint(\"CLINT\", clint_targets);\n\n\tMemoryDMI dmi = MemoryDMI::create_start_size_mapping(mem.data, opt.mem_start_addr, mem.size);\n\tInstrMemoryProxy instr_mem(dmi, core);\n\n\tstd::shared_ptr<BusLock> bus_lock = std::make_shared<BusLock>();\n\tcore_mem_if.bus_lock = bus_lock;\n\tmmu.mem = &core_mem_if;\n\n\tinstr_memory_if *instr_mem_if = &core_mem_if;\n\tdata_memory_if *data_mem_if = &core_mem_if;\n\tif (opt.use_instr_dmi)\n\t\tinstr_mem_if = &instr_mem;\n\tif (opt.use_data_dmi) {\n\t\tcore_mem_if.dmi_ranges.emplace_back(dmi);\n\t}\n\n\tloader.load_executable_image(mem, mem.size, opt.mem_start_addr);\n\tcore.init(instr_mem_if, data_mem_if, &clint, loader.get_entrypoint(), rv64_align_address(opt.mem_end_addr));\n\tsys.init(mem.data, opt.mem_start_addr, loader.get_heap_addr());\n\tsys.register_core(&core);\n\n\tif (opt.intercept_syscalls)\n\t\tcore.sys = &sys;\n\n\t// setup port mapping\n\tbus.ports[0] = new PortMapping(opt.mem_start_addr, opt.mem_end_addr);\n\tbus.ports[1] = new PortMapping(opt.clint_start_addr, opt.clint_end_addr);\n\tbus.ports[2] = new PortMapping(opt.sys_start_addr, opt.sys_end_addr);\n\n\t// connect TLM sockets\n\tcore_mem_if.isock.bind(bus.tsocks[0]);\n\tdbg_if.isock.bind(bus.tsocks[1]);\n\tbus.isocks[0].bind(mem.tsock);\n\tbus.isocks[1].bind(clint.tsock);\n\tbus.isocks[2].bind(sys.tsock);\n\n\t// switch for printing instructions\n\tcore.trace = opt.trace_mode;\n\n\tstd::vector<debug_target_if *> threads;\n\tthreads.push_back(&core);\n\n\tif (opt.use_debug_runner) {\n\t\tauto server = new GDBServer(\"GDBServer\", threads, &dbg_if, opt.debug_port);\n\t\tnew GDBServerRunner(\"GDBRunner\", server, &core);\n\t} else {\n\t\tnew DirectCoreRunner(core);\n\t}\n\n\tif (opt.quiet)\n\t\t sc_core::sc_report_handler::set_verbosity_level(sc_core::SC_NONE);\n\n\tsc_core::sc_start();\n\tif (!opt.quiet) {\n\t\tcore.show();\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "vp/src/platform/tiny64-mc/CMakeLists.txt",
    "content": "file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)\n\nadd_executable(tiny64-mc\n        mc_main.cpp\n        ${HEADERS})\n\ntarget_link_libraries(tiny64-mc rv64 platform-common gdb-mc\n\t${Boost_LIBRARIES} systemc pthread)\n\nINSTALL(TARGETS tiny64-mc RUNTIME DESTINATION bin)\n"
  },
  {
    "path": "vp/src/platform/tiny64-mc/mc_main.cpp",
    "content": "#include <cstdlib>\n#include <ctime>\n\n#include \"core/common/clint.h\"\n#include \"elf_loader.h\"\n#include \"iss.h\"\n#include \"mem.h\"\n#include \"memory.h\"\n#include \"syscall.h\"\n#include \"platform/common/options.h\"\n\n#include \"gdb-mc/gdb_server.h\"\n#include \"gdb-mc/gdb_runner.h\"\n\n#include <boost/io/ios_state.hpp>\n#include <boost/program_options.hpp>\n#include <iomanip>\n#include <iostream>\n\nusing namespace rv64;\nnamespace po = boost::program_options;\n\nstruct TinyOptions : public Options {\npublic:\n\ttypedef unsigned int addr_t;\n\n\taddr_t mem_size = 1024 * 1024 * 32;  // 32 MB ram, to place it before the CLINT and run the base examples (assume\n\t                                     // memory start at zero) without modifications\n\taddr_t mem_start_addr = 0x00000000;\n\taddr_t mem_end_addr = mem_start_addr + mem_size - 1;\n\taddr_t clint_start_addr = 0x02000000;\n\taddr_t clint_end_addr = 0x0200ffff;\n\taddr_t sys_start_addr = 0x02010000;\n\taddr_t sys_end_addr = 0x020103ff;\n\n\tbool quiet = false;\n\tbool use_E_base_isa = false;\n\n\tTinyOptions(void) {\n\t\t// clang-format off\n\t\tadd_options()\n\t\t\t(\"quiet\", po::bool_switch(&quiet), \"do not output register values on exit\")\n\t\t\t(\"memory-start\", po::value<unsigned int>(&mem_start_addr), \"set memory start address\")\n\t\t\t(\"memory-size\", po::value<unsigned int>(&mem_size), \"set memory size\")\n\t\t\t(\"use-E-base-isa\", po::bool_switch(&use_E_base_isa), \"use the E instead of the I integer base ISA\");\n        \t// clang-format on\n        }\n\n\tvoid parse(int argc, char **argv) override {\n\t\tOptions::parse(argc, argv);\n\t\tmem_end_addr = mem_start_addr + mem_size - 1;\n\t}\n};\n\nint sc_main(int argc, char **argv) {\n\tTinyOptions opt;\n\topt.parse(argc, argv);\n\n\tstd::srand(std::time(nullptr));  // use current time as seed for random generator\n\n\ttlm::tlm_global_quantum::instance().set(sc_core::sc_time(opt.tlm_global_quantum, sc_core::SC_NS));\n\n\tISS core0(0);\n\tMMU mmu0(core0);\n\tISS core1(1);\n\tMMU mmu1(core1);\n\n\tCombinedMemoryInterface core0_mem_if(\"MemoryInterface0\", core0, mmu0);\n\tCombinedMemoryInterface core1_mem_if(\"MemoryInterface1\", core1, mmu1);\n\n\tSimpleMemory mem(\"SimpleMemory\", opt.mem_size);\n\tELFLoader loader(opt.input_program.c_str());\n\tSimpleBus<3, 3> bus(\"SimpleBus\");\n\tSyscallHandler sys(\"SyscallHandler\");\n\tCLINT<2> clint(\"CLINT\");\n\tDebugMemoryInterface dbg_if(\"DebugMemoryInterface\");\n\n\tstd::shared_ptr<BusLock> bus_lock = std::make_shared<BusLock>();\n\tcore0_mem_if.bus_lock = bus_lock;\n\tcore1_mem_if.bus_lock = bus_lock;\n\n\tbus.ports[0] = new PortMapping(opt.mem_start_addr, opt.mem_end_addr);\n\tbus.ports[1] = new PortMapping(opt.clint_start_addr, opt.clint_end_addr);\n\tbus.ports[2] = new PortMapping(opt.sys_start_addr, opt.sys_end_addr);\n\n\tloader.load_executable_image(mem, mem.size, opt.mem_start_addr);\n\n\tcore0.init(&core0_mem_if, &core0_mem_if, &clint, loader.get_entrypoint(),\n\t           opt.mem_end_addr - 3);  // -3 to not overlap with the next region and stay 32 bit aligned\n\tcore1.init(&core1_mem_if, &core1_mem_if, &clint, loader.get_entrypoint(), opt.mem_end_addr - 32767);\n\n\tsys.init(mem.data, opt.mem_start_addr, loader.get_heap_addr());\n\tsys.register_core(&core0);\n\tsys.register_core(&core1);\n\n\tif (opt.intercept_syscalls) {\n\t\tcore0.sys = &sys;\n\t\tcore1.sys = &sys;\n\t}\n\n\t// connect TLM sockets\n\tcore0_mem_if.isock.bind(bus.tsocks[0]);\n\tcore1_mem_if.isock.bind(bus.tsocks[1]);\n\tdbg_if.isock.bind(bus.tsocks[2]);\n\tbus.isocks[0].bind(mem.tsock);\n\tbus.isocks[1].bind(clint.tsock);\n\tbus.isocks[2].bind(sys.tsock);\n\n\t// connect interrupt signals/communication\n\tclint.target_harts[0] = &core0;\n\tclint.target_harts[1] = &core1;\n\n\t// switch for printing instructions\n\tcore0.trace = opt.trace_mode;\n\tcore1.trace = opt.trace_mode;\n\n\tstd::vector<debug_target_if *> threads;\n\tthreads.push_back(&core0);\n\tthreads.push_back(&core1);\n\n\tif (opt.use_debug_runner) {\n\t\tauto server = new GDBServer(\"GDBServer\", threads, &dbg_if, opt.debug_port);\n\t\tnew GDBServerRunner(\"GDBRunner0\", server, &core0);\n\t\tnew GDBServerRunner(\"GDBRunner1\", server, &core1);\n\t} else {\n\t\tnew DirectCoreRunner(core0);\n\t\tnew DirectCoreRunner(core1);\n\t}\n\n\tif (opt.quiet)\n\t\t sc_core::sc_report_handler::set_verbosity_level(sc_core::SC_NONE);\n\n\tsc_core::sc_start();\n\tif (!opt.quiet) {\n\t\tcore0.show();\n\t\tcore1.show();\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "vp/src/util/common.h",
    "content": "#pragma once\n\n#include <stdexcept>\n\n#define likely(x) __builtin_expect((x), 1)\n#define unlikely(x) __builtin_expect((x), 0)\n\n#define UNUSED(x) (void)(x)\n\ninline void ensure(bool cond) {\n\tif (unlikely(!cond))\n\t\tthrow std::runtime_error(\"runtime assertion failed\");\n}\n\ninline void ensure(bool cond, const std::string &reason) {\n\tif (unlikely(!cond))\n\t\tthrow std::runtime_error(reason);\n}\n\ninline uint64_t rv64_align_address(uint64_t addr) {\n\treturn addr - addr % 8;\n}\n\ninline uint32_t rv32_align_address(uint32_t addr) {\n\treturn addr - addr % 4;\n}\n\n/* Allow to provide a custom function name for a SystemC thread to avoid duplicate name warning in case the same\n * SystemC module is instantiated multiple times. */\n#define SC_NAMED_THREAD(func, name) declare_thread_process(func##_handle, name, SC_CURRENT_USER_MODULE, func)\n"
  },
  {
    "path": "vp/src/util/elegantEnums.cpp",
    "content": "/*\n * elegantEnums.hpp\n *\n *  Created on: 14 Mar 2019\n *      Author: dwd\n */\n\n#include \"elegantEnums.hpp\"\n\nstd::vector<std::string> splitString(std::string str, char sep) {\n\tstd::vector<std::string> vecString;\n\tstd::string item;\n\n\tstd::stringstream stringStream(str);\n\n\twhile (std::getline(stringStream, item, sep)) {\n\t\tvecString.push_back(item);\n\t}\n\n\treturn vecString;\n}\n"
  },
  {
    "path": "vp/src/util/elegantEnums.hpp",
    "content": "/*\n * elegantEnums.hpp\n *\n *  Created on: 14 Mar 2019\n *      Author: dwd\n */\n\n#pragma once\n\n#include <algorithm>\n#include <iostream>\n#include <map>\n#include <sstream>\n#include <string>\n#include <vector>\n\n#define STRING_REMOVE_CHAR(str, ch) str.erase(std::remove(str.begin(), str.end(), ch), str.end())\n\nstd::vector<std::string> splitString(std::string str, char sep = ',');\n\n#define DECLARE_ENUM_WITH_TYPE(E, T, ...)                                         \\\n\tenum class E : T { __VA_ARGS__ };                                             \\\n\ttypedef T E##_underlying_type;                                                \\\n\tstatic std::map<T, std::string> E##MapName(generateEnumMap<T>(#__VA_ARGS__)); \\\n\tstd::ostream &operator<<(std::ostream &os, E enumTmp);                        \\\n\tsize_t operator*(E enumTmp);                                                  \\\n\tstd::string operator~(E enumTmp);                                             \\\n\tstd::string operator+(std::string &&str, E enumTmp);                          \\\n\tstd::string operator+(E enumTmp, std::string &&str);                          \\\n\tstd::string &operator+=(std::string &str, E enumTmp);                         \\\n\tE operator++(E &enumTmp);                                                     \\\n\tbool valid##E(T value);                                                       \\\n\tbool operator==(E left, E right);                                             \\\n\ttemplate<typename Other>                                                      \\\n\tbool operator<(E left, Other right) {                                         \\\n\t\treturn static_cast<T>(left) < right;                                      \\\n\t}\n\n#define DECLARE_ENUM(E, ...) DECLARE_ENUM_WITH_TYPE(E, uint16_t, __VA_ARGS__)\n\n#define IMPL_ENUM_WITH_TYPE(E, T)                                            \\\n\tstd::ostream &operator<<(std::ostream &os, E enumTmp) {                  \\\n\t\tos << E##MapName[static_cast<T>(enumTmp)];                           \\\n\t\treturn os;                                                           \\\n\t}                                                                        \\\n\tsize_t operator*(E enumTmp) {                                            \\\n\t\t(void)enumTmp;                                                       \\\n\t\treturn E##MapName.size();                                            \\\n\t}                                                                        \\\n\tstd::string operator~(E enumTmp) {                                       \\\n\t\treturn E##MapName[static_cast<T>(enumTmp)];                          \\\n\t}                                                                        \\\n\tstd::string operator+(std::string &&str, E enumTmp) {                    \\\n\t\treturn str + E##MapName[static_cast<T>(enumTmp)];                    \\\n\t}                                                                        \\\n\tstd::string operator+(E enumTmp, std::string &&str) {                    \\\n\t\treturn E##MapName[static_cast<T>(enumTmp)] + str;                    \\\n\t}                                                                        \\\n\tstd::string &operator+=(std::string &str, E enumTmp) {                   \\\n\t\tstr += E##MapName[static_cast<T>(enumTmp)];                          \\\n\t\treturn str;                                                          \\\n\t}                                                                        \\\n\tE operator++(E &enumTmp) {                                               \\\n\t\tauto iter = E##MapName.find(static_cast<T>(enumTmp));                \\\n\t\tif (iter == E##MapName.end() || std::next(iter) == E##MapName.end()) \\\n\t\t\titer = E##MapName.begin();                                       \\\n\t\telse {                                                               \\\n\t\t\t++iter;                                                          \\\n\t\t}                                                                    \\\n\t\tenumTmp = static_cast<E>(iter->first);                               \\\n\t\treturn enumTmp;                                                      \\\n\t}                                                                        \\\n\tbool valid##E(T value) {                                                 \\\n\t\treturn (E##MapName.find(value) != E##MapName.end());                 \\\n\t}                                                                        \\\n\tbool operator==(E left, E right) {                                       \\\n\t\treturn static_cast<T>(left) == static_cast<T>(right);                \\\n\t}\n\n\n#define IMPL_ENUM(E) IMPL_ENUM_WITH_TYPE(E, int32_t)\n\ntemplate <typename T>\nstd::map<T, std::string> generateEnumMap(std::string strMap) {\n\tSTRING_REMOVE_CHAR(strMap, ' ');\n\tSTRING_REMOVE_CHAR(strMap, '(');\n\n\tstd::vector<std::string> enumTokens(splitString(strMap));\n\tstd::map<T, std::string> retMap;\n\tT inxMap;\n\n\tinxMap = 0;\n\tfor (auto iter = enumTokens.begin(); iter != enumTokens.end(); ++iter) {\n\t\t// Token: [EnumName | EnumName=EnumValue]\n\t\tstd::string enumName;\n\t\t//T enumValue;\n\t\tif (iter->find('=') == std::string::npos) {\n\t\t\tenumName = *iter;\n\t\t} else {\n\t\t\tstd::vector<std::string> enumNameValue(splitString(*iter, '='));\n\t\t\tenumName = enumNameValue[0];\n\t\t\t// inxMap = static_cast<T>(enumNameValue[1]);\n\t\t\tif (std::is_unsigned<T>::value) {\n\t\t\t\tinxMap = static_cast<T>(std::stoull(enumNameValue[1], 0, 0));\n\t\t\t} else {\n\t\t\t\tinxMap = static_cast<T>(std::stoll(enumNameValue[1], 0, 0));\n\t\t\t}\n\t\t}\n\t\tretMap[inxMap++] = enumName;\n\t}\n\n\treturn retMap;\n}\n"
  },
  {
    "path": "vp/src/util/gtkwave_riscv-filter/.gitignore",
    "content": "build/\n"
  },
  {
    "path": "vp/src/util/gtkwave_riscv-filter/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.18)\nproject(GTKWAVE_RISCV_INSTR_FILTER CXX)\n\nSET(INSTR ${CMAKE_CURRENT_SOURCE_DIR}/../../core/common)\n\nadd_executable(gtkwave_riscv-filter\n\triscv-filter.cpp\n\t${INSTR}/instr.cpp\n)\ntarget_include_directories(gtkwave_riscv-filter PRIVATE\n\t${INSTR}\n\t${CMAKE_CURRENT_SOURCE_DIR}/../..\n)\ntarget_compile_features(gtkwave_riscv-filter PRIVATE cxx_std_20)"
  },
  {
    "path": "vp/src/util/gtkwave_riscv-filter/riscv-filter.cpp",
    "content": "#include <instr.h>\n\n#include <string>\n#include <iostream>\n#include <iterator>\n#include <sstream>\n#include <inttypes.h>\n#include <exception>\n\nstatic Architecture ARCH = Architecture::RV32;\nstatic bool USE_PRETTY_NAMES = false;\n\nusing namespace std;\n\nstring registerName(uint_fast16_t num) {\n\tif(USE_PRETTY_NAMES) {\n\t\treturn Opcode::regnamePrettyStr[num];\n\t} else {\n\t\treturn {\"x\" + to_string(num)};\n\t}\n}\n\nvoid printOpcode(Instruction& instr) {\n\tOpcode::Mapping op;\n\tif (instr.is_compressed()) {\n\t\top = instr.decode_and_expand_compressed(ARCH);\n\t} else {\n\t\top = instr.decode_normal(ARCH);\n\t}\n\n\tcout << Opcode::mappingStr.at(op) << \" \";\n\n\tswitch (Opcode::getType(op)) {\n\t\tcase Opcode::Type::R:\n\t\t\tcout <<  registerName(instr.rd()) << \", \" << registerName(instr.rs1()) << \", \" << registerName(instr.rs2());\n\t\t\tbreak;\n\t\tcase Opcode::Type::R4:\t// only >= rv64\n\t\t\tcout <<  registerName(instr.rd()) << \", \" << registerName(instr.rs1()) << \", \" << registerName(instr.rs2()) << \", \" << registerName(instr.rs3());\n\t\t\tbreak;\n\t\tcase Opcode::Type::I:\n\t\t\tcout <<  registerName(instr.rd()) << \", \" << registerName(instr.rs1()) << \", \" << instr.I_imm();\n\t\t\tbreak;\n\t\tcase Opcode::Type::S:\n\t\t\tcout <<  registerName(instr.rd()) << \", \" << registerName(instr.rs1()) << \", \" << instr.S_imm();\n\t\t\tbreak;\n\t\tcase Opcode::Type::B:\n\t\t\tcout <<  registerName(instr.rd()) << \", \" << registerName(instr.rs1()) << \", \" << instr.B_imm();\n\t\t\tbreak;\n\t\tcase Opcode::Type::U:\n\t\t\tcout <<  registerName(instr.rd()) << \", \" << instr.U_imm();\n\t\t\tbreak;\n\t\tcase Opcode::Type::J:\n\t\t\tcout <<  registerName(instr.rd()) << \", \" << instr.J_imm();\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tcout << \"Unknown Opcode Type \" << instr.opcode();\n\t}\n\n\tcout << endl;\n}\n\nint main(int argc, const char* argv[])\n{\n\tstring line;\n\tInstruction instr;\n\tcout << showbase << hex;\n\n\tfor(unsigned i = 1; i < argc; i++) {\n\t\tif(argv[i] == string{\"--use-pretty-names\"})\n\t\t\tUSE_PRETTY_NAMES = true;\n\t\telse if(argv[i] == string{\"--rv64\"})\n\t\t\tARCH = Architecture::RV64;\n\t\telse {\n\t\t\tcout << argv[0] << \" [--use-pretty-names] [--rv64]\" << endl;\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\twhile(std::getline(cin, line)) {\n\t\ttry {\n\t\t\tinstr = std::stoul(line, nullptr, 16);\t// Base 16\n\t\t} catch (std::invalid_argument&) {\n\t\t\tcerr << \"Not a parse-able hex number: '\" << line << \"'\" << endl;\n\t\t\tcontinue;\n\t\t}\n\t\tprintOpcode(instr);\n\t}\n}\n"
  },
  {
    "path": "vp/src/util/gtkwave_riscv-filter.py",
    "content": "#!/usr/bin/env python3\nimport sys\nimport tempfile\nimport subprocess\n\ndef main():\n    fh_in = sys.stdin\n    fh_out = sys.stdout\n\n    while True:\n        l = fh_in.readline()\n        if not l:\n            return 0\n\n        if \"x\" in l:\n            fh_out.write(l)\n            fh_out.flush()\n            continue\n\n        obj_temp = tempfile.NamedTemporaryFile(delete=False, mode='w')\n        with tempfile.NamedTemporaryFile(delete=False, mode='w') as asm_temp:\n            asm_temp.write(\".word 0x%s\\n\" % l)\n            asm_temp.flush()\n            subprocess.run([\"riscv64-unknown-elf-as\", \"-march=rv32i\", \"-o\", obj_temp.name, asm_temp.name])\n            result = subprocess.run([\"riscv64-unknown-elf-objdump\", \"-d\", obj_temp.name], capture_output=True)\n            lastline = result.stdout.splitlines()[-1]\n            chunks = lastline.decode().split('\\t')\n\n            opcodes = \" \".join(chunks[2:])\n\n            fh_out.write(\"%s\\n\" % opcodes)\n            fh_out.flush()\n\n\nif __name__ == '__main__':\n\tsys.exit(main())\n"
  },
  {
    "path": "vp/src/util/memory_map.h",
    "content": "#pragma once\n\n#include <functional>\n#include <vector>\n#include \"common.h\"\n\nstruct RegisterRange {\n\tstruct WriteInfo {\n\t\tuint64_t addr;\n\t\tsize_t size;\n\t\ttlm::tlm_generic_payload &trans;\n\t\tsc_core::sc_time &delay;\n\t};\n\n\tstruct ReadInfo {\n\t\tuint64_t addr;\n\t\tsize_t size;\n\t\ttlm::tlm_generic_payload &trans;\n\t\tsc_core::sc_time &delay;\n\t};\n\n\ttypedef std::function<bool(WriteInfo)> PreWriteCallback;\n\ttypedef std::function<void(WriteInfo)> PostWriteCallback;\n\ttypedef std::function<bool(ReadInfo)> PreReadCallback;\n\ttypedef std::function<void(ReadInfo)> PostReadCallback;\n\n\tuint64_t start;\n\tuint64_t end;\n\tstd::vector<uint8_t> mem;\n\tbool readonly = false;\n\tuint64_t alignment = 1;\n\n\tPreWriteCallback pre_write_callback;\n\tPostWriteCallback post_write_callback;\n\tPreReadCallback pre_read_callback;\n\tPostReadCallback post_read_callback;\n\n\tRegisterRange(uint64_t start, uint64_t size) : start(start) {\n\t\tassert(size > 0);\n\n\t\tend = start + size - 1;\n\t\tassert(end >= start);\n\n\t\tmem = std::vector<uint8_t>(size);\n\t}\n\n\tstatic RegisterRange make_start_end(uint64_t start, uint64_t end) {\n\t\tassert(end >= start);\n\t\treturn {start, end - start + 1};\n\t}\n\n\tstatic RegisterRange make_start_size(uint64_t start, uint64_t size) {\n\t\tassert(size > 0);\n\t\treturn {start, size};\n\t}\n\n\ttemplate <typename T>\n\tstatic RegisterRange make_array(uint64_t start, uint64_t num_elems) {\n\t\tstatic_assert(std::is_integral<T>::value, \"integer type required\");\n\n\t\tassert(num_elems > 0);\n\t\treturn {start, sizeof(T) * num_elems};\n\t}\n\n\tbool contains(uint64_t addr) {\n\t\treturn addr >= start && addr <= end;\n\t}\n\n\tuint64_t to_local(uint64_t addr) {\n\t\treturn addr - start;\n\t}\n\n\tvoid write(uint64_t addr, const uint8_t *src, size_t len, tlm::tlm_generic_payload &trans,\n\t           sc_core::sc_time &delay) {\n\t\tassert(contains(addr));\n\n\t\tauto local_addr = to_local(addr);\n\t\tassert(local_addr + len <= mem.size());\n\n\t\tif (pre_write_callback)\n\t\t\tif (!pre_write_callback({local_addr, len, trans, delay}))\n\t\t\t\treturn;\n\n\t\tmemcpy(mem.data() + local_addr, src, len);\n\n\t\tif (post_write_callback)\n\t\t\tpost_write_callback({local_addr, len, trans, delay});\n\t}\n\n\tvoid read(uint64_t addr, uint8_t *dst, size_t len, tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tassert(contains(addr));\n\n\t\tauto local_addr = to_local(addr);\n\t\tassert(local_addr + len <= mem.size());\n\n\t\tif (pre_read_callback)\n\t\t\tif (!pre_read_callback({local_addr, len, trans, delay}))\n\t\t\t\treturn;\n\n\t\tmemcpy(dst, mem.data() + local_addr, len);\n\n\t\tif (post_read_callback)\n\t\t\tpost_read_callback({local_addr, len, trans, delay});\n\t}\n\n\tbool match(tlm::tlm_generic_payload &trans) {\n\t\treturn contains(trans.get_address());\n\t}\n\n\tvoid process(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tauto addr = trans.get_address();\n\t\tauto cmd = trans.get_command();\n\t\tauto len = trans.get_data_length();\n\t\tauto ptr = trans.get_data_ptr();\n\n\t\tensure((addr % alignment == 0) && (len % alignment == 0));\n\n\t\tif (cmd == tlm::TLM_READ_COMMAND) {\n\t\t\tread(addr, ptr, len, trans, delay);\n\t\t} else if (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\t\tensure(!readonly);\n\t\t\twrite(addr, ptr, len, trans, delay);\n\t\t} else {\n\t\t\tthrow std::runtime_error(\"unsupported TLM command\");\n\t\t}\n\t}\n};\n\ntemplate <typename T>\nstruct IntegerView {\n\tstatic_assert(std::is_integral<T>::value, \"integer type required\");\n\n\tT *ptr;\n\n\tIntegerView(RegisterRange &r) {\n\t\tassert(((uintptr_t)r.mem.data()) % sizeof(T) == 0);\n\t\tassert(r.mem.size() >= sizeof(T));\n\t\tptr = reinterpret_cast<T *>(r.mem.data());\n\t}\n\n\tT read() const {\n\t\treturn *ptr;\n\t}\n\n\tvoid write(T value) {\n\t\t*ptr = value;\n\t}\n\n\toperator T() const {\n\t\treturn read();\n\t}\n\n\tIntegerView<T> &operator=(uint64_t value) {\n\t\twrite(value);\n\t\treturn *this;\n\t}\n};\n\ntemplate <typename T, unsigned RowSize = 1>\nstruct ArrayView {\n\tstatic_assert(std::is_integral<T>::value || std::is_pod<T>::value, \"integer or POD type required\");\n\n\tRegisterRange &regs;\n\tT *ptr;\n\tconst size_t size;\n\n\tArrayView(RegisterRange &r) : regs(r), size(r.mem.size() / sizeof(T)) {\n\t\tassert(r.mem.size() % sizeof(T) == 0);\n\t\tassert(size > 0);\n\n\t\tptr = reinterpret_cast<T *>(r.mem.data());\n\t}\n\n\tT &at(size_t idx) {\n\t\tif (idx >= size)\n\t\t\tthrow std::out_of_range(\"ArrayView index out-of-range\");\n\t\telse\n\t\t\treturn ptr[idx];\n\t}\n\n\tT &operator[](unsigned idx) {\n\t\tassert(idx < size);\n\t\treturn ptr[idx];\n\t}\n\n\t// use for 2d array access\n\tT &operator()(unsigned idx, unsigned row_idx) {\n\t\treturn ptr[idx * RowSize + row_idx];\n\t}\n\n\tT *begin() {\n\t\treturn &ptr[0];\n\t}\n\tconst T *begin() const {\n\t\treturn &ptr[0];\n\t}\n\tT *end() {\n\t\treturn &ptr[size - 1];\n\t}\n\tconst T *end() const {\n\t\treturn &ptr[size - 1];\n\t}\n};\n\nnamespace vp {\nnamespace mm {\n\ntemplate <typename Iter>\nvoid route(const char *name, Iter &iterable_mm, tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\tfor (auto e : iterable_mm) {\n\t\tif (e->match(trans)) {\n\t\t\te->process(trans, delay);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tthrow std::runtime_error(std::string(name) + \" unable to route address \" + std::to_string(trans.get_address()));\n}\n\n}  // namespace mm\n}  // namespace vp\n"
  },
  {
    "path": "vp/src/util/options.h",
    "content": "#pragma once\n\n#include <functional>\n#include <stdexcept>\n#include <string>\n\ntemplate <typename T>\nstruct OptionValue {\n\tbool available = false;\n\tT value{};\n\tstd::string option;\n\n\tbool finalize(std::function<T(const std::string &)> parser) {\n\t\tif (!option.empty()) {\n\t\t\tvalue = parser(option);\n\t\t\tavailable = true;\n\t\t}\n\t\treturn available;\n\t}\n};\n\nunsigned long parse_ulong_option(const std::string &s) {\n\tbool is_hex = false;\n\tif (s.size() >= 2) {\n\t\tif ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X')))\n\t\t\tis_hex = true;\n\t}\n\n\ttry {\n\t\tif (is_hex)\n\t\t\treturn stoul(s, 0, 16);\n\t\treturn stoul(s);\n\t} catch (std::exception &e) {\n\t\tthrow std::runtime_error(std::string(\"unable to parse option '\") + s + \"' into a number\");\n\t}\n}"
  },
  {
    "path": "vp/src/util/tlm_map.h",
    "content": "#ifndef RISCV_TLM_MAP_H\n#define RISCV_TLM_MAP_H\n\n#include <systemc>\n\n#include <tlm_utils/simple_initiator_socket.h>\n#include <tlm_utils/simple_target_socket.h>\n\n#include <boost/format.hpp>\n#include <functional>\n#include <unordered_map>\n\n/*\n * Optional modelling layer to simplify TLM register and memory access.\n * sensor2.h demonstrates how to use it.\n */\n\nnamespace vp {\nnamespace map {\n\nstruct access_mode {\n\tbool allow_read = true;\n\tbool allow_write = true;\n\n\tstatic access_mode make_writeonly() {\n\t\treturn access_mode({false, true});\n\t}\n\n\tstatic access_mode make_readonly() {\n\t\treturn access_mode({true, false});\n\t}\n\n\tbool can_read() {\n\t\treturn allow_read;\n\t}\n\n\tbool can_write() {\n\t\treturn allow_write;\n\t}\n\n\tbool is_readonly() {\n\t\treturn allow_read && !allow_write;\n\t}\n};\n\nconstexpr access_mode read_write = {true, true};\nconstexpr access_mode read_only = {true, false};\nconstexpr access_mode write_only = {false, true};\n\nstruct AbstractMapping {\n\tvirtual ~AbstractMapping() {}\n\n\tvirtual bool try_handle(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) = 0;\n};\n\ninline void execute_memory_access(tlm::tlm_generic_payload &trans, uint8_t *local_memory) {\n\tif (trans.get_command() == tlm::TLM_WRITE_COMMAND) {\n\t\tmemcpy(&local_memory[trans.get_address()], trans.get_data_ptr(), trans.get_data_length());\n\t} else if (trans.get_command() == tlm::TLM_READ_COMMAND) {\n\t\tmemcpy(trans.get_data_ptr(), &local_memory[trans.get_address()], trans.get_data_length());\n\t} else {\n\t\tthrow std::runtime_error(\"unsupported TLM command detected\");\n\t}\n}\n\nstruct AddressMapping : public AbstractMapping {\n\ttypedef std::function<void(tlm::tlm_generic_payload &, sc_core::sc_time &)> fn_transport_t;\n\n\tuint64_t start;\n\tuint64_t end;\n\taccess_mode mode;\n\tfn_transport_t handler;\n\n\ttemplate <typename Module, typename MemberFun>\n\tAddressMapping &register_handler(Module *this_, MemberFun fn) {\n\t\tassert(!handler);\n\t\thandler = std::bind(fn, this_, std::placeholders::_1, std::placeholders::_2);\n\t\treturn *this;\n\t}\n\n\tAddressMapping &register_handler(AddressMapping::fn_transport_t fn) {\n\t\tassert(!handler);\n\t\thandler = fn;\n\t\treturn *this;\n\t}\n\n\tbool try_handle(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tauto addr = trans.get_address();\n\t\tauto len = trans.get_data_length();\n\t\tauto cmd = trans.get_command();\n\n\t\tif (addr >= start && addr < end) {\n\t\t\tassert((addr + len <= end) && \"memory out of bounds access\");\n\t\t\tassert(mode.can_read() || cmd != tlm::TLM_READ_COMMAND);\n\t\t\tassert(mode.can_write() || cmd != tlm::TLM_WRITE_COMMAND);\n\n\t\t\ttrans.set_address(addr - start);\n\n\t\t\thandler(trans, delay);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n};\n\nstruct reg_mapping_t {\n\tuint64_t addr;\n\tuint32_t *vptr;\n\taccess_mode mode = read_write;\n\tuint32_t mask = 0xffffffff;\n\n\tuint32_t value() {\n\t\treturn *vptr;\n\t}\n\n\tvoid bus_write(uint32_t new_value) {\n\t\tassert(mode.can_write());\n\t\t*vptr = new_value & mask;\n\t}\n\n\tuint32_t bus_read() {\n\t\tassert(mode.can_read());\n\t\treturn *vptr;\n\t}\n};\n\nstruct register_access_t {\n\ttypedef std::function<void()> callback_t;\n\n\t/*\n\t * vptr points to the actual register.\n\t * nv is the new value that will be assigned to the register (only valid for\n\t * write access). calling fn will perform the actual read/write operation.\n\t */\n\tbool read;\n\tbool write;\n\tuint32_t *vptr;\n\tuint32_t nv;\n\tcallback_t fn;\n\tsc_core::sc_time &delay;\n\tuint64_t addr;\n};\n\nstruct RegisterMapping : public AbstractMapping {\n\ttypedef std::function<void()> callback_t;\n\ttypedef std::function<void(const register_access_t &)> handler_t;\n\n\tstd::unordered_map<uint64_t, reg_mapping_t> addr_to_reg;\n\thandler_t handler;\n\n\tRegisterMapping &add_register(reg_mapping_t m) {\n\t\taddr_to_reg.insert(std::make_pair(m.addr, m));\n\t\treturn *this;\n\t}\n\n\ttemplate <typename Module, typename MemberFun>\n\tRegisterMapping &register_handler(Module *this_, MemberFun fn) {\n\t\tassert(!handler);\n\t\thandler = std::bind(fn, this_, std::placeholders::_1);\n\t\treturn *this;\n\t}\n\n\tRegisterMapping &register_handler(RegisterMapping::handler_t fn) {\n\t\tassert(!handler);\n\t\thandler = fn;\n\t\treturn *this;\n\t}\n\n\tbool try_handle(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tauto addr = trans.get_address();\n\t\tauto new_vptr = (uint32_t *)trans.get_data_ptr();\n\t\tauto len = trans.get_data_length();\n\t\tauto cmd = trans.get_command();\n\n\t\tauto it = addr_to_reg.find(addr - addr % 4);  // clamp to nearest register\n\t\tif (it == addr_to_reg.end())\n\t\t\treturn false;\n\n\t\tassert(len + (addr % 4) <= 4);  // do not allow access beyond the register\n\t\tassert(cmd == tlm::TLM_READ_COMMAND || cmd == tlm::TLM_WRITE_COMMAND);\n\n\t\treg_mapping_t &r = it->second;\n\n\t\tassert(r.mode.can_read() || cmd != tlm::TLM_READ_COMMAND);\n\t\tassert(r.mode.can_write() || cmd != tlm::TLM_WRITE_COMMAND);\n\n\t\tauto fn = [cmd, &r, new_vptr, &trans]() {\n\t\t    (void) new_vptr;\n\t\t\tauto off = trans.get_address() % 4;\n\t\t\tif (cmd == tlm::TLM_READ_COMMAND) {\n\t\t\t\tuint32_t n = r.bus_read();\n\t\t\t\tmemcpy(trans.get_data_ptr(), ((uint8_t *)&n) + off, trans.get_data_length());\n\t\t\t\t//*new_vptr = r.bus_read();\n\t\t\t} else if (cmd == tlm::TLM_WRITE_COMMAND) {\n\t\t\t\tuint32_t n = r.value();\n\t\t\t\tmemcpy(((uint8_t *)&n) + off, trans.get_data_ptr(), trans.get_data_length());\n\t\t\t\tr.bus_write(n);\n\t\t\t\t// r.bus_write(*new_vptr);\n\t\t\t} else {\n\t\t\t\tthrow std::runtime_error(\"unsupported TLM command detected\");\n\t\t\t}\n\t\t};\n\n\t\tassert(handler && \"no callback function provided\");\n\n\t\t// introduce *nv* to get rid of \"use of uninitialized value\" warnings\n\t\tuint32_t nv = 0;\n\t\tif (cmd == tlm::TLM_WRITE_COMMAND)\n\t\t\tnv = *new_vptr;\n\n\t\thandler({cmd == tlm::TLM_READ_COMMAND, cmd == tlm::TLM_WRITE_COMMAND, r.vptr, nv, fn, delay, addr});\n\t\treturn true;\n\t}\n};\n\nstruct LocalRouter {\n\tstd::string name;\n\tstd::vector<AbstractMapping *> maps;\n\n\tLocalRouter(const std::string &name = \"unamed\") : name(name) {}\n\n\t~LocalRouter() {\n\t\tfor (auto p : maps) {\n\t\t\tassert(p);\n\t\t\tdelete p;\n\t\t}\n\t}\n\n\tvoid transport(tlm::tlm_generic_payload &trans, sc_core::sc_time &delay) {\n\t\tfor (auto &m : maps) {\n\t\t\tif (m->try_handle(trans, delay))\n\t\t\t\treturn;\n\t\t}\n\t\tthrow std::runtime_error(\"access of unmapped address (local TLM router): name=\" + name + \", addr=0x\" +\n\t\t                         (boost::format(\"%X\") % trans.get_address()).str());\n\t}\n\n\tRegisterMapping &add_register_bank(const std::vector<reg_mapping_t> &regs) {\n\t\tauto p = new RegisterMapping();\n\t\tfor (auto &m : regs) {\n\t\t\tassert(p->addr_to_reg.find(m.addr) == p->addr_to_reg.end() && \"register at this address already available\");\n\t\t\tp->addr_to_reg.insert(std::make_pair(m.addr, m));\n\t\t}\n\t\tmaps.push_back(p);\n\t\treturn *p;\n\t}\n\n\tAddressMapping &add_start_end_mapping(uint64_t start, uint64_t end, const access_mode &m) {\n\t\tauto p = new AddressMapping();\n\t\tp->start = start;\n\t\tp->end = end;\n\t\tp->mode = m;\n\t\tmaps.push_back(p);\n\t\treturn *p;\n\t}\n\n\tAddressMapping &add_start_size_mapping(uint64_t start, uint32_t size, const access_mode &m) {\n\t\treturn add_start_end_mapping(start, start + size, m);\n\t}\n};\n\n}  // namespace map\n}  // namespace vp\n\n#endif  // RISCV_TLM_MAP_H\n"
  },
  {
    "path": "vp/src/vendor/CMakeLists.txt",
    "content": "subdirs(softfloat)\nif(NOT USE_SYSTEM_SYSTEMC)\n    include(ExternalProject)\n    ExternalProject_Add(\n        systemc_project\n        URL ${CMAKE_CURRENT_SOURCE_DIR}/systemc\n        CMAKE_ARGS\n          -DCMAKE_CXX_FLAGS_NO_WARNINGS=\"-w\"\n          -DCMAKE_BUILD_TYPE=NO_WARNINGS\n          -DCMAKE_INSTALL_LIBDIR=lib #don't use lib64\n          -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}\n          -DBUILD_SHARED_LIBS=OFF\n        INSTALL_COMMAND \"\"\n        BINARY_DIR ${CMAKE_BINARY_DIR}/systemc\n        BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/systemc/src/libsystemc.a\n    )\n\n    add_library(systemc STATIC IMPORTED GLOBAL)\n    set_target_properties(systemc PROPERTIES\n        INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/systemc/src\n        IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/systemc/src/libsystemc.a)\n    add_dependencies(systemc systemc_project)\nendif()\n"
  },
  {
    "path": "vp/src/vendor/softfloat/CMakeLists.txt",
    "content": "add_library(softfloat\n\tf128_add.c\n\tf128_classify.c\n\tf128_div.c\n\tf128_eq.c\n\tf128_eq_signaling.c\n\tf128_isSignalingNaN.c\n\tf128_le.c\n\tf128_le_quiet.c\n\tf128_lt.c\n\tf128_lt_quiet.c\n\tf128_mul.c\n\tf128_mulAdd.c\n\tf128_rem.c\n\tf128_roundToInt.c\n\tf128_sqrt.c\n\tf128_sub.c\n\tf128_to_f16.c\n\tf128_to_f32.c\n\tf128_to_f64.c\n\tf128_to_i32.c\n\tf128_to_i32_r_minMag.c\n\tf128_to_i64.c\n\tf128_to_i64_r_minMag.c\n\tf128_to_ui32.c\n\tf128_to_ui32_r_minMag.c\n\tf128_to_ui64.c\n\tf128_to_ui64_r_minMag.c\n\tf16_add.c\n\tf16_div.c\n\tf16_eq.c\n\tf16_eq_signaling.c\n\tf16_isSignalingNaN.c\n\tf16_le.c\n\tf16_le_quiet.c\n\tf16_lt.c\n\tf16_lt_quiet.c\n\tf16_mul.c\n\tf16_mulAdd.c\n\tf16_rem.c\n\tf16_roundToInt.c\n\tf16_sqrt.c\n\tf16_sub.c\n\tf16_to_f128.c\n\tf16_to_f32.c\n\tf16_to_f64.c\n\tf16_to_i32.c\n\tf16_to_i32_r_minMag.c\n\tf16_to_i64.c\n\tf16_to_i64_r_minMag.c\n\tf16_to_ui32.c\n\tf16_to_ui32_r_minMag.c\n\tf16_to_ui64.c\n\tf16_to_ui64_r_minMag.c\n\tf32_add.c\n\tf32_classify.c\n\tf32_div.c\n\tf32_eq.c\n\tf32_eq_signaling.c\n\tf32_isSignalingNaN.c\n\tf32_le.c\n\tf32_le_quiet.c\n\tf32_lt.c\n\tf32_lt_quiet.c\n\tf32_mul.c\n\tf32_mulAdd.c\n\tf32_rem.c\n\tf32_roundToInt.c\n\tf32_sqrt.c\n\tf32_sub.c\n\tf32_to_f128.c\n\tf32_to_f16.c\n\tf32_to_f64.c\n\tf32_to_i32.c\n\tf32_to_i32_r_minMag.c\n\tf32_to_i64.c\n\tf32_to_i64_r_minMag.c\n\tf32_to_ui32.c\n\tf32_to_ui32_r_minMag.c\n\tf32_to_ui64.c\n\tf32_to_ui64_r_minMag.c\n\tf64_add.c\n\tf64_classify.c\n\tf64_div.c\n\tf64_eq.c\n\tf64_eq_signaling.c\n\tf64_isSignalingNaN.c\n\tf64_le.c\n\tf64_le_quiet.c\n\tf64_lt.c\n\tf64_lt_quiet.c\n\tf64_mul.c\n\tf64_mulAdd.c\n\tf64_rem.c\n\tf64_roundToInt.c\n\tf64_sqrt.c\n\tf64_sub.c\n\tf64_to_f128.c\n\tf64_to_f16.c\n\tf64_to_f32.c\n\tf64_to_i32.c\n\tf64_to_i32_r_minMag.c\n\tf64_to_i64.c\n\tf64_to_i64_r_minMag.c\n\tf64_to_ui32.c\n\tf64_to_ui32_r_minMag.c\n\tf64_to_ui64.c\n\tf64_to_ui64_r_minMag.c\n\ti32_to_f128.c\n\ti32_to_f16.c\n\ti32_to_f32.c\n\ti32_to_f64.c\n\ti64_to_f128.c\n\ti64_to_f16.c\n\ti64_to_f32.c\n\ti64_to_f64.c\n\ts_add128.c\n\ts_add256M.c\n\ts_addCarryM.c\n\ts_addComplCarryM.c\n\ts_addM.c\n\ts_addMagsF128.c\n\ts_addMagsF16.c\n\ts_addMagsF32.c\n\ts_addMagsF64.c\n\ts_approxRecip32_1.c\n\ts_approxRecipSqrt32_1.c\n\ts_approxRecipSqrt_1Ks.c\n\ts_approxRecip_1Ks.c\n\ts_commonNaNToF128UI.c\n\ts_commonNaNToF16UI.c\n\ts_commonNaNToF32UI.c\n\ts_commonNaNToF64UI.c\n\ts_compare128M.c\n\ts_compare96M.c\n\ts_countLeadingZeros16.c\n\ts_countLeadingZeros32.c\n\ts_countLeadingZeros64.c\n\ts_countLeadingZeros8.c\n\ts_eq128.c\n\ts_f128UIToCommonNaN.c\n\ts_f16UIToCommonNaN.c\n\ts_f32UIToCommonNaN.c\n\ts_f64UIToCommonNaN.c\n\ts_le128.c\n\ts_lt128.c\n\ts_mul128By32.c\n\ts_mul128MTo256M.c\n\ts_mul128To256M.c\n\ts_mul64ByShifted32To128.c\n\ts_mul64To128.c\n\ts_mul64To128M.c\n\ts_mulAddF128.c\n\ts_mulAddF16.c\n\ts_mulAddF32.c\n\ts_mulAddF64.c\n\ts_negXM.c\n\ts_normRoundPackToF128.c\n\ts_normRoundPackToF16.c\n\ts_normRoundPackToF32.c\n\ts_normRoundPackToF64.c\n\ts_normSubnormalF128Sig.c\n\ts_normSubnormalF16Sig.c\n\ts_normSubnormalF32Sig.c\n\ts_normSubnormalF64Sig.c\n\ts_propagateNaNF128UI.c\n\ts_propagateNaNF16UI.c\n\ts_propagateNaNF32UI.c\n\ts_propagateNaNF64UI.c\n\ts_remStepMBy32.c\n\ts_roundMToI64.c\n\ts_roundMToUI64.c\n\ts_roundPackMToI64.c\n\ts_roundPackMToUI64.c\n\ts_roundPackToF128.c\n\ts_roundPackToF16.c\n\ts_roundPackToF32.c\n\ts_roundPackToF64.c\n\ts_roundPackToI32.c\n\ts_roundPackToI64.c\n\ts_roundPackToUI32.c\n\ts_roundPackToUI64.c\n\ts_roundToI32.c\n\ts_roundToI64.c\n\ts_roundToUI32.c\n\ts_roundToUI64.c\n\ts_shiftRightJam128.c\n\ts_shiftRightJam128Extra.c\n\ts_shiftRightJam256M.c\n\ts_shiftRightJam32.c\n\ts_shiftRightJam64.c\n\ts_shiftRightJam64Extra.c\n\ts_shortShiftLeft128.c\n\ts_shortShiftLeft64To96M.c\n\ts_shortShiftRight128.c\n\ts_shortShiftRightExtendM.c\n\ts_shortShiftRightJam128.c\n\ts_shortShiftRightJam128Extra.c\n\ts_shortShiftRightJam64.c\n\ts_shortShiftRightJam64Extra.c\n\ts_shortShiftRightM.c\n\ts_sub128.c\n\ts_sub1XM.c\n\ts_sub256M.c\n\ts_subM.c\n\ts_subMagsF128.c\n\ts_subMagsF16.c\n\ts_subMagsF32.c\n\ts_subMagsF64.c\n\tsoftfloat_raiseFlags.c\n\tsoftfloat_state.c\n\tui32_to_f128.c\n\tui32_to_f16.c\n\tui32_to_f32.c\n\tui32_to_f64.c\n\tui64_to_f128.c\n\tui64_to_f16.c\n\tui64_to_f32.c\n\tui64_to_f64.c)\n\ntarget_compile_definitions(softfloat PRIVATE\n\tSOFTFLOAT_ROUND_ODD\n\tINLINE_LEVEL=5\n\tSOFTFLOAT_FAST_DIV32TO16\n\tSOFTFLOAT_FAST_DIV64TO32\n\tSOFTFLOAT_FAST_INT64)\n\ntarget_include_directories(softfloat PRIVATE\n\t${CMAKE_CURRENT_SOURCE_DIR}/include\n\t${CMAKE_CURRENT_SOURCE_DIR}/include/softfloat)\ntarget_include_directories(softfloat PUBLIC\n\t${CMAKE_CURRENT_SOURCE_DIR}/include)\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_add.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat128_t f128_add( float128_t a, float128_t b )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool signA;\n    union ui128_f128 uB;\n    uint_fast64_t uiB64, uiB0;\n    bool signB;\n#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2)\n    float128_t\n        (*magsFuncPtr)(\n            uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool );\n#endif\n\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    signA = signF128UI64( uiA64 );\n    uB.f = b;\n    uiB64 = uB.ui.v64;\n    uiB0  = uB.ui.v0;\n    signB = signF128UI64( uiB64 );\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\n    if ( signA == signB ) {\n        return softfloat_addMagsF128( uiA64, uiA0, uiB64, uiB0, signA );\n    } else {\n        return softfloat_subMagsF128( uiA64, uiA0, uiB64, uiB0, signA );\n    }\n#else\n    magsFuncPtr =\n        (signA == signB) ? softfloat_addMagsF128 : softfloat_subMagsF128;\n    return (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA );\n#endif\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_classify.c",
    "content": "\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast16_t f128_classify( float128_t a )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n\n    uint_fast16_t infOrNaN = expF128UI64( uiA64 ) == 0x7FFF;\n    uint_fast16_t subnormalOrZero = expF128UI64( uiA64 ) == 0;\n    bool sign = signF128UI64( uiA64 );\n    bool fracZero = fracF128UI64( uiA64 ) == 0 && uiA0 == 0;\n    bool isNaN = isNaNF128UI( uiA64, uiA0 );\n    bool isSNaN = softfloat_isSigNaNF128UI( uiA64, uiA0 );\n\n    return\n        (  sign && infOrNaN && fracZero )          << 0 |\n        (  sign && !infOrNaN && !subnormalOrZero ) << 1 |\n        (  sign && subnormalOrZero && !fracZero )  << 2 |\n        (  sign && subnormalOrZero && fracZero )   << 3 |\n        ( !sign && infOrNaN && fracZero )          << 7 |\n        ( !sign && !infOrNaN && !subnormalOrZero ) << 6 |\n        ( !sign && subnormalOrZero && !fracZero )  << 5 |\n        ( !sign && subnormalOrZero && fracZero )   << 4 |\n        ( isNaN &&  isSNaN )                       << 8 |\n        ( isNaN && !isSNaN )                       << 9;\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_div.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat128_t f128_div( float128_t a, float128_t b )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool signA;\n    int_fast32_t expA;\n    struct uint128 sigA;\n    union ui128_f128 uB;\n    uint_fast64_t uiB64, uiB0;\n    bool signB;\n    int_fast32_t expB;\n    struct uint128 sigB;\n    bool signZ;\n    struct exp32_sig128 normExpSig;\n    int_fast32_t expZ;\n    struct uint128 rem;\n    uint_fast32_t recip32;\n    int ix;\n    uint_fast64_t q64;\n    uint_fast32_t q;\n    struct uint128 term;\n    uint_fast32_t qs[3];\n    uint_fast64_t sigZExtra;\n    struct uint128 sigZ, uiZ;\n    union ui128_f128 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    signA = signF128UI64( uiA64 );\n    expA  = expF128UI64( uiA64 );\n    sigA.v64 = fracF128UI64( uiA64 );\n    sigA.v0  = uiA0;\n    uB.f = b;\n    uiB64 = uB.ui.v64;\n    uiB0  = uB.ui.v0;\n    signB = signF128UI64( uiB64 );\n    expB  = expF128UI64( uiB64 );\n    sigB.v64 = fracF128UI64( uiB64 );\n    sigB.v0  = uiB0;\n    signZ = signA ^ signB;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x7FFF ) {\n        if ( sigA.v64 | sigA.v0 ) goto propagateNaN;\n        if ( expB == 0x7FFF ) {\n            if ( sigB.v64 | sigB.v0 ) goto propagateNaN;\n            goto invalid;\n        }\n        goto infinity;\n    }\n    if ( expB == 0x7FFF ) {\n        if ( sigB.v64 | sigB.v0 ) goto propagateNaN;\n        goto zero;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expB ) {\n        if ( ! (sigB.v64 | sigB.v0) ) {\n            if ( ! (expA | sigA.v64 | sigA.v0) ) goto invalid;\n            softfloat_raiseFlags( softfloat_flag_infinite );\n            goto infinity;\n        }\n        normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    if ( ! expA ) {\n        if ( ! (sigA.v64 | sigA.v0) ) goto zero;\n        normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = expA - expB + 0x3FFE;\n    sigA.v64 |= UINT64_C( 0x0001000000000000 );\n    sigB.v64 |= UINT64_C( 0x0001000000000000 );\n    rem = sigA;\n    if ( softfloat_lt128( sigA.v64, sigA.v0, sigB.v64, sigB.v0 ) ) {\n        --expZ;\n        rem = softfloat_add128( sigA.v64, sigA.v0, sigA.v64, sigA.v0 );\n    }\n    recip32 = softfloat_approxRecip32_1( sigB.v64>>17 );\n    ix = 3;\n    for (;;) {\n        q64 = (uint_fast64_t) (uint32_t) (rem.v64>>19) * recip32;\n        q = (q64 + 0x80000000)>>32;\n        --ix;\n        if ( ix < 0 ) break;\n        rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );\n        term = softfloat_mul128By32( sigB.v64, sigB.v0, q );\n        rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );\n        if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {\n            --q;\n            rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 );\n        }\n        qs[ix] = q;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ((q + 1) & 7) < 2 ) {\n        rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );\n        term = softfloat_mul128By32( sigB.v64, sigB.v0, q );\n        rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );\n        if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {\n            --q;\n            rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 );\n        } else if ( softfloat_le128( sigB.v64, sigB.v0, rem.v64, rem.v0 ) ) {\n            ++q;\n            rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 );\n        }\n        if ( rem.v64 | rem.v0 ) q |= 1;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sigZExtra = (uint64_t) ((uint_fast64_t) q<<60);\n    term = softfloat_shortShiftLeft128( 0, qs[1], 54 );\n    sigZ =\n        softfloat_add128(\n            (uint_fast64_t) qs[2]<<19, ((uint_fast64_t) qs[0]<<25) + (q>>4),\n            term.v64, term.v0\n        );\n    return\n        softfloat_roundPackToF128( signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ.v64 = defaultNaNF128UI64;\n    uiZ.v0  = defaultNaNF128UI0;\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infinity:\n    uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 );\n    goto uiZ0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zero:\n    uiZ.v64 = packToF128UI64( signZ, 0, 0 );\n uiZ0:\n    uiZ.v0 = 0;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_eq.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f128_eq( float128_t a, float128_t b )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    union ui128_f128 uB;\n    uint_fast64_t uiB64, uiB0;\n\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    uB.f = b;\n    uiB64 = uB.ui.v64;\n    uiB0  = uB.ui.v0;\n    if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {\n        if (\n               softfloat_isSigNaNF128UI( uiA64, uiA0 )\n            || softfloat_isSigNaNF128UI( uiB64, uiB0 )\n        ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n        }\n        return false;\n    }\n    return\n           (uiA0 == uiB0)\n        && (   (uiA64 == uiB64)\n            || (! uiA0 && ! ((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )))\n           );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_eq_signaling.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nbool f128_eq_signaling( float128_t a, float128_t b )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    union ui128_f128 uB;\n    uint_fast64_t uiB64, uiB0;\n\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    uB.f = b;\n    uiB64 = uB.ui.v64;\n    uiB0  = uB.ui.v0;\n    if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return false;\n    }\n    return\n           (uiA0 == uiB0)\n        && (   (uiA64 == uiB64)\n            || (! uiA0 && ! ((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )))\n           );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_isSignalingNaN.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f128_isSignalingNaN( float128_t a )\n{\n    union ui128_f128 uA;\n\n    uA.f = a;\n    return softfloat_isSigNaNF128UI( uA.ui.v64, uA.ui.v0 );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_le.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nbool f128_le( float128_t a, float128_t b )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    union ui128_f128 uB;\n    uint_fast64_t uiB64, uiB0;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    uB.f = b;\n    uiB64 = uB.ui.v64;\n    uiB0  = uB.ui.v0;\n    if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return false;\n    }\n    signA = signF128UI64( uiA64 );\n    signB = signF128UI64( uiB64 );\n    return\n        (signA != signB)\n            ? signA\n                  || ! (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n                            | uiA0 | uiB0)\n            : ((uiA64 == uiB64) && (uiA0 == uiB0))\n                  || (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 ));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_le_quiet.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f128_le_quiet( float128_t a, float128_t b )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    union ui128_f128 uB;\n    uint_fast64_t uiB64, uiB0;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    uB.f = b;\n    uiB64 = uB.ui.v64;\n    uiB0  = uB.ui.v0;\n    if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {\n        if (\n               softfloat_isSigNaNF128UI( uiA64, uiA0 )\n            || softfloat_isSigNaNF128UI( uiB64, uiB0 )\n        ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n        }\n        return false;\n    }\n    signA = signF128UI64( uiA64 );\n    signB = signF128UI64( uiB64 );\n    return\n        (signA != signB)\n            ? signA\n                  || ! (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n                            | uiA0 | uiB0)\n            : ((uiA64 == uiB64) && (uiA0 == uiB0))\n                  || (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 ));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_lt.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nbool f128_lt( float128_t a, float128_t b )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    union ui128_f128 uB;\n    uint_fast64_t uiB64, uiB0;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    uB.f = b;\n    uiB64 = uB.ui.v64;\n    uiB0  = uB.ui.v0;\n    if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return false;\n    }\n    signA = signF128UI64( uiA64 );\n    signB = signF128UI64( uiB64 );\n    return\n        (signA != signB)\n            ? signA\n                  && (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n                          | uiA0 | uiB0)\n            : ((uiA64 != uiB64) || (uiA0 != uiB0))\n                  && (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 ));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_lt_quiet.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f128_lt_quiet( float128_t a, float128_t b )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    union ui128_f128 uB;\n    uint_fast64_t uiB64, uiB0;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    uB.f = b;\n    uiB64 = uB.ui.v64;\n    uiB0  = uB.ui.v0;\n    if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) {\n        if (\n               softfloat_isSigNaNF128UI( uiA64, uiA0 )\n            || softfloat_isSigNaNF128UI( uiB64, uiB0 )\n        ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n        }\n        return false;\n    }\n    signA = signF128UI64( uiA64 );\n    signB = signF128UI64( uiB64 );\n    return\n        (signA != signB)\n            ? signA\n                  && (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n                          | uiA0 | uiB0)\n            : ((uiA64 != uiB64) || (uiA0 != uiB0))\n                  && (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 ));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_mul.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat128_t f128_mul( float128_t a, float128_t b )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool signA;\n    int_fast32_t expA;\n    struct uint128 sigA;\n    union ui128_f128 uB;\n    uint_fast64_t uiB64, uiB0;\n    bool signB;\n    int_fast32_t expB;\n    struct uint128 sigB;\n    bool signZ;\n    uint_fast64_t magBits;\n    struct exp32_sig128 normExpSig;\n    int_fast32_t expZ;\n    uint64_t sig256Z[4];\n    uint_fast64_t sigZExtra;\n    struct uint128 sigZ;\n    struct uint128_extra sig128Extra;\n    struct uint128 uiZ;\n    union ui128_f128 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    signA = signF128UI64( uiA64 );\n    expA  = expF128UI64( uiA64 );\n    sigA.v64 = fracF128UI64( uiA64 );\n    sigA.v0  = uiA0;\n    uB.f = b;\n    uiB64 = uB.ui.v64;\n    uiB0  = uB.ui.v0;\n    signB = signF128UI64( uiB64 );\n    expB  = expF128UI64( uiB64 );\n    sigB.v64 = fracF128UI64( uiB64 );\n    sigB.v0  = uiB0;\n    signZ = signA ^ signB;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x7FFF ) {\n        if (\n            (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))\n        ) {\n            goto propagateNaN;\n        }\n        magBits = expB | sigB.v64 | sigB.v0;\n        goto infArg;\n    }\n    if ( expB == 0x7FFF ) {\n        if ( sigB.v64 | sigB.v0 ) goto propagateNaN;\n        magBits = expA | sigA.v64 | sigA.v0;\n        goto infArg;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! (sigA.v64 | sigA.v0) ) goto zero;\n        normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    if ( ! expB ) {\n        if ( ! (sigB.v64 | sigB.v0) ) goto zero;\n        normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = expA + expB - 0x4000;\n    sigA.v64 |= UINT64_C( 0x0001000000000000 );\n    sigB = softfloat_shortShiftLeft128( sigB.v64, sigB.v0, 16 );\n    softfloat_mul128To256M( sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z );\n    sigZExtra = sig256Z[indexWord( 4, 1 )] | (sig256Z[indexWord( 4, 0 )] != 0);\n    sigZ =\n        softfloat_add128(\n            sig256Z[indexWord( 4, 3 )], sig256Z[indexWord( 4, 2 )],\n            sigA.v64, sigA.v0\n        );\n    if ( UINT64_C( 0x0002000000000000 ) <= sigZ.v64 ) {\n        ++expZ;\n        sig128Extra =\n            softfloat_shortShiftRightJam128Extra(\n                sigZ.v64, sigZ.v0, sigZExtra, 1 );\n        sigZ = sig128Extra.v;\n        sigZExtra = sig128Extra.extra;\n    }\n    return\n        softfloat_roundPackToF128( signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infArg:\n    if ( ! magBits ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        uiZ.v64 = defaultNaNF128UI64;\n        uiZ.v0  = defaultNaNF128UI0;\n        goto uiZ;\n    }\n    uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 );\n    goto uiZ0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zero:\n    uiZ.v64 = packToF128UI64( signZ, 0, 0 );\n uiZ0:\n    uiZ.v0 = 0;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_mulAdd.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat128_t f128_mulAdd( float128_t a, float128_t b, float128_t c )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    union ui128_f128 uB;\n    uint_fast64_t uiB64, uiB0;\n    union ui128_f128 uC;\n    uint_fast64_t uiC64, uiC0;\n\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    uB.f = b;\n    uiB64 = uB.ui.v64;\n    uiB0  = uB.ui.v0;\n    uC.f = c;\n    uiC64 = uC.ui.v64;\n    uiC0  = uC.ui.v0;\n    return softfloat_mulAddF128( uiA64, uiA0, uiB64, uiB0, uiC64, uiC0, 0 );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_rem.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat128_t f128_rem( float128_t a, float128_t b )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool signA;\n    int_fast32_t expA;\n    struct uint128 sigA;\n    union ui128_f128 uB;\n    uint_fast64_t uiB64, uiB0;\n    int_fast32_t expB;\n    struct uint128 sigB;\n    struct exp32_sig128 normExpSig;\n    struct uint128 rem;\n    int_fast32_t expDiff;\n    uint_fast32_t q, recip32;\n    uint_fast64_t q64;\n    struct uint128 term, altRem, meanRem;\n    bool signRem;\n    struct uint128 uiZ;\n    union ui128_f128 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    signA = signF128UI64( uiA64 );\n    expA  = expF128UI64( uiA64 );\n    sigA.v64 = fracF128UI64( uiA64 );\n    sigA.v0  = uiA0;\n    uB.f = b;\n    uiB64 = uB.ui.v64;\n    uiB0  = uB.ui.v0;\n    expB  = expF128UI64( uiB64 );\n    sigB.v64 = fracF128UI64( uiB64 );\n    sigB.v0  = uiB0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x7FFF ) {\n        if (\n            (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))\n        ) {\n            goto propagateNaN;\n        }\n        goto invalid;\n    }\n    if ( expB == 0x7FFF ) {\n        if ( sigB.v64 | sigB.v0 ) goto propagateNaN;\n        return a;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expB ) {\n        if ( ! (sigB.v64 | sigB.v0) ) goto invalid;\n        normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    if ( ! expA ) {\n        if ( ! (sigA.v64 | sigA.v0) ) return a;\n        normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sigA.v64 |= UINT64_C( 0x0001000000000000 );\n    sigB.v64 |= UINT64_C( 0x0001000000000000 );\n    rem = sigA;\n    expDiff = expA - expB;\n    if ( expDiff < 1 ) {\n        if ( expDiff < -1 ) return a;\n        if ( expDiff ) {\n            --expB;\n            sigB = softfloat_add128( sigB.v64, sigB.v0, sigB.v64, sigB.v0 );\n            q = 0;\n        } else {\n            q = softfloat_le128( sigB.v64, sigB.v0, rem.v64, rem.v0 );\n            if ( q ) {\n                rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 );\n            }\n        }\n    } else {\n        recip32 = softfloat_approxRecip32_1( sigB.v64>>17 );\n        expDiff -= 30;\n        for (;;) {\n            q64 = (uint_fast64_t) (uint32_t) (rem.v64>>19) * recip32;\n            if ( expDiff < 0 ) break;\n            q = (q64 + 0x80000000)>>32;\n            rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );\n            term = softfloat_mul128By32( sigB.v64, sigB.v0, q );\n            rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );\n            if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {\n                rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 );\n            }\n            expDiff -= 29;\n        }\n        /*--------------------------------------------------------------------\n        | (`expDiff' cannot be less than -29 here.)\n        *--------------------------------------------------------------------*/\n        q = (uint32_t) (q64>>32)>>(~expDiff & 31);\n        rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, expDiff + 30 );\n        term = softfloat_mul128By32( sigB.v64, sigB.v0, q );\n        rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 );\n        if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {\n            altRem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 );\n            goto selectRem;\n        }\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    do {\n        altRem = rem;\n        ++q;\n        rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 );\n    } while ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) );\n selectRem:\n    meanRem = softfloat_add128( rem.v64, rem.v0, altRem.v64, altRem.v0 );\n    if (\n        (meanRem.v64 & UINT64_C( 0x8000000000000000 ))\n            || (! (meanRem.v64 | meanRem.v0) && (q & 1))\n    ) {\n        rem = altRem;\n    }\n    signRem = signA;\n    if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) {\n        signRem = ! signRem;\n        rem = softfloat_sub128( 0, 0, rem.v64, rem.v0 );\n    }\n    return softfloat_normRoundPackToF128( signRem, expB - 1, rem.v64, rem.v0 );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ.v64 = defaultNaNF128UI64;\n    uiZ.v0  = defaultNaNF128UI0;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_roundToInt.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat128_t\n f128_roundToInt( float128_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    int_fast32_t exp;\n    struct uint128 uiZ;\n    uint_fast64_t lastBitMask, roundBitsMask;\n    bool roundNearEven;\n    union ui128_f128 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    exp = expF128UI64( uiA64 );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( 0x402F <= exp ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( 0x406F <= exp ) {\n            if ( (exp == 0x7FFF) && (fracF128UI64( uiA64 ) | uiA0) ) {\n                uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, 0, 0 );\n                goto uiZ;\n            }\n            return a;\n        }\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        lastBitMask = (uint_fast64_t) 2<<(0x406E - exp);\n        roundBitsMask = lastBitMask - 1;\n        uiZ.v64 = uiA64;\n        uiZ.v0  = uiA0;\n        roundNearEven = (roundingMode == softfloat_round_near_even);\n        if ( roundNearEven || (roundingMode == softfloat_round_near_maxMag) ) {\n            if ( exp == 0x402F ) {\n                if ( UINT64_C( 0x8000000000000000 ) <= uiZ.v0 ) {\n                    ++uiZ.v64;\n                    if (\n                        roundNearEven\n                            && (uiZ.v0 == UINT64_C( 0x8000000000000000 ))\n                    ) {\n                        uiZ.v64 &= ~1;\n                    }\n                }\n            } else {\n                uiZ = softfloat_add128( uiZ.v64, uiZ.v0, 0, lastBitMask>>1 );\n                if ( roundNearEven && ! (uiZ.v0 & roundBitsMask) ) {\n                    uiZ.v0 &= ~lastBitMask;\n                }\n            }\n        } else if (\n            roundingMode\n                == (signF128UI64( uiZ.v64 ) ? softfloat_round_min\n                        : softfloat_round_max)\n        ) {\n            uiZ = softfloat_add128( uiZ.v64, uiZ.v0, 0, roundBitsMask );\n        }\n        uiZ.v0 &= ~roundBitsMask;\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( exp < 0x3FFF ) {\n            if ( ! ((uiA64 & UINT64_C( 0x7FFFFFFFFFFFFFFF )) | uiA0) ) {\n                return a;\n            }\n            if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact;\n            uiZ.v64 = uiA64 & packToF128UI64( 1, 0, 0 );\n            uiZ.v0  = 0;\n            switch ( roundingMode ) {\n             case softfloat_round_near_even:\n                if ( ! (fracF128UI64( uiA64 ) | uiA0) ) break;\n             case softfloat_round_near_maxMag:\n                if ( exp == 0x3FFE ) uiZ.v64 |= packToF128UI64( 0, 0x3FFF, 0 );\n                break;\n             case softfloat_round_min:\n                if ( uiZ.v64 ) uiZ.v64 = packToF128UI64( 1, 0x3FFF, 0 );\n                break;\n             case softfloat_round_max:\n                if ( ! uiZ.v64 ) uiZ.v64 = packToF128UI64( 0, 0x3FFF, 0 );\n                break;\n            }\n            goto uiZ;\n        }\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        uiZ.v64 = uiA64;\n        uiZ.v0  = 0;\n        lastBitMask = (uint_fast64_t) 1<<(0x402F - exp);\n        roundBitsMask = lastBitMask - 1;\n        if ( roundingMode == softfloat_round_near_maxMag ) {\n            uiZ.v64 += lastBitMask>>1;\n        } else if ( roundingMode == softfloat_round_near_even ) {\n            uiZ.v64 += lastBitMask>>1;\n            if ( ! ((uiZ.v64 & roundBitsMask) | uiA0) ) {\n                uiZ.v64 &= ~lastBitMask;\n            }\n        } else if (\n            roundingMode\n                == (signF128UI64( uiZ.v64 ) ? softfloat_round_min\n                        : softfloat_round_max)\n        ) {\n            uiZ.v64 = (uiZ.v64 | (uiA0 != 0)) + roundBitsMask;\n        }\n        uiZ.v64 &= ~roundBitsMask;\n    }\n    if ( exact && ((uiZ.v64 != uiA64) || (uiZ.v0 != uiA0)) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_sqrt.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat128_t f128_sqrt( float128_t a )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool signA;\n    int_fast32_t expA;\n    struct uint128 sigA, uiZ;\n    struct exp32_sig128 normExpSig;\n    int_fast32_t expZ;\n    uint_fast32_t sig32A, recipSqrt32, sig32Z;\n    struct uint128 rem;\n    uint32_t qs[3];\n    uint_fast32_t q;\n    uint_fast64_t x64, sig64Z;\n    struct uint128 y, term;\n    uint_fast64_t sigZExtra;\n    struct uint128 sigZ;\n    union ui128_f128 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    signA = signF128UI64( uiA64 );\n    expA  = expF128UI64( uiA64 );\n    sigA.v64 = fracF128UI64( uiA64 );\n    sigA.v0  = uiA0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x7FFF ) {\n        if ( sigA.v64 | sigA.v0 ) {\n            uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, 0, 0 );\n            goto uiZ;\n        }\n        if ( ! signA ) return a;\n        goto invalid;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( signA ) {\n        if ( ! (expA | sigA.v64 | sigA.v0) ) return a;\n        goto invalid;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! (sigA.v64 | sigA.v0) ) return a;\n        normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    | (`sig32Z' is guaranteed to be a lower bound on the square root of\n    | `sig32A', which makes `sig32Z' also a lower bound on the square root of\n    | `sigA'.)\n    *------------------------------------------------------------------------*/\n    expZ = ((expA - 0x3FFF)>>1) + 0x3FFE;\n    expA &= 1;\n    sigA.v64 |= UINT64_C( 0x0001000000000000 );\n    sig32A = sigA.v64>>17;\n    recipSqrt32 = softfloat_approxRecipSqrt32_1( expA, sig32A );\n    sig32Z = ((uint_fast64_t) sig32A * recipSqrt32)>>32;\n    if ( expA ) {\n        sig32Z >>= 1;\n        rem = softfloat_shortShiftLeft128( sigA.v64, sigA.v0, 12 );\n    } else {\n        rem = softfloat_shortShiftLeft128( sigA.v64, sigA.v0, 13 );\n    }\n    qs[2] = sig32Z;\n    rem.v64 -= (uint_fast64_t) sig32Z * sig32Z;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    q = ((uint32_t) (rem.v64>>2) * (uint_fast64_t) recipSqrt32)>>32;\n    x64 = (uint_fast64_t) sig32Z<<32;\n    sig64Z = x64 + ((uint_fast64_t) q<<3);\n    y = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );\n    /*------------------------------------------------------------------------\n    | (Repeating this loop is a rare occurrence.)\n    *------------------------------------------------------------------------*/\n    for (;;) {\n        term = softfloat_mul64ByShifted32To128( x64 + sig64Z, q );\n        rem = softfloat_sub128( y.v64, y.v0, term.v64, term.v0 );\n        if ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ) break;\n        --q;\n        sig64Z -= 1<<3;\n    }\n    qs[1] = q;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    q = ((rem.v64>>2) * recipSqrt32)>>32;\n    y = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 );\n    sig64Z <<= 1;\n    /*------------------------------------------------------------------------\n    | (Repeating this loop is a rare occurrence.)\n    *------------------------------------------------------------------------*/\n    for (;;) {\n        term = softfloat_shortShiftLeft128( 0, sig64Z, 32 );\n        term = softfloat_add128( term.v64, term.v0, 0, (uint_fast64_t) q<<6 );\n        term = softfloat_mul128By32( term.v64, term.v0, q );\n        rem = softfloat_sub128( y.v64, y.v0, term.v64, term.v0 );\n        if ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ) break;\n        --q;\n    }\n    qs[0] = q;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    q = (((rem.v64>>2) * recipSqrt32)>>32) + 2;\n    sigZExtra = (uint64_t) ((uint_fast64_t) q<<59);\n    term = softfloat_shortShiftLeft128( 0, qs[1], 53 );\n    sigZ =\n        softfloat_add128(\n            (uint_fast64_t) qs[2]<<18, ((uint_fast64_t) qs[0]<<24) + (q>>5),\n            term.v64, term.v0\n        );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( (q & 0xF) <= 2 ) {\n        q &= ~3;\n        sigZExtra = (uint64_t) ((uint_fast64_t) q<<59);\n        y = softfloat_shortShiftLeft128( sigZ.v64, sigZ.v0, 6 );\n        y.v0 |= sigZExtra>>58;\n        term = softfloat_sub128( y.v64, y.v0, 0, q );\n        y    = softfloat_mul64ByShifted32To128( term.v0,  q );\n        term = softfloat_mul64ByShifted32To128( term.v64, q );\n        term = softfloat_add128( term.v64, term.v0, 0, y.v64 );\n        rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 20 );\n        term = softfloat_sub128( term.v64, term.v0, rem.v64, rem.v0 );\n        /*--------------------------------------------------------------------\n        | The concatenation of `term' and `y.v0' is now the negative remainder\n        | (3 words altogether).\n        *--------------------------------------------------------------------*/\n        if ( term.v64 & UINT64_C( 0x8000000000000000 ) ) {\n            sigZExtra |= 1;\n        } else {\n            if ( term.v64 | term.v0 | y.v0 ) {\n                if ( sigZExtra ) {\n                    --sigZExtra;\n                } else {\n                    sigZ = softfloat_sub128( sigZ.v64, sigZ.v0, 0, 1 );\n                    sigZExtra = ~0;\n                }\n            }\n        }\n    }\n    return softfloat_roundPackToF128( 0, expZ, sigZ.v64, sigZ.v0, sigZExtra );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ.v64 = defaultNaNF128UI64;\n    uiZ.v0  = defaultNaNF128UI0;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_sub.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat128_t f128_sub( float128_t a, float128_t b )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool signA;\n    union ui128_f128 uB;\n    uint_fast64_t uiB64, uiB0;\n    bool signB;\n#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2)\n    float128_t\n        (*magsFuncPtr)(\n            uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool );\n#endif\n\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    signA = signF128UI64( uiA64 );\n    uB.f = b;\n    uiB64 = uB.ui.v64;\n    uiB0  = uB.ui.v0;\n    signB = signF128UI64( uiB64 );\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\n    if ( signA == signB ) {\n        return softfloat_subMagsF128( uiA64, uiA0, uiB64, uiB0, signA );\n    } else {\n        return softfloat_addMagsF128( uiA64, uiA0, uiB64, uiB0, signA );\n    }\n#else\n    magsFuncPtr =\n        (signA == signB) ? softfloat_subMagsF128 : softfloat_addMagsF128;\n    return (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA );\n#endif\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_to_f16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat16_t f128_to_f16( float128_t a )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool sign;\n    int_fast32_t exp;\n    uint_fast64_t frac64;\n    struct commonNaN commonNaN;\n    uint_fast16_t uiZ, frac16;\n    union ui16_f16 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    sign  = signF128UI64( uiA64 );\n    exp   = expF128UI64( uiA64 );\n    frac64 = fracF128UI64( uiA64 ) | (uiA0 != 0);\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x7FFF ) {\n        if ( frac64 ) {\n            softfloat_f128UIToCommonNaN( uiA64, uiA0, &commonNaN );\n            uiZ = softfloat_commonNaNToF16UI( &commonNaN );\n        } else {\n            uiZ = packToF16UI( sign, 0x1F, 0 );\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    frac16 = softfloat_shortShiftRightJam64( frac64, 34 );\n    if ( ! (exp | frac16) ) {\n        uiZ = packToF16UI( sign, 0, 0 );\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    exp -= 0x3FF1;\n    if ( sizeof (int_fast16_t) < sizeof (int_fast32_t) ) {\n        if ( exp < -0x40 ) exp = -0x40;\n    }\n    return softfloat_roundPackToF16( sign, exp, frac16 | 0x4000 );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_to_f32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat32_t f128_to_f32( float128_t a )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool sign;\n    int_fast32_t exp;\n    uint_fast64_t frac64;\n    struct commonNaN commonNaN;\n    uint_fast32_t uiZ, frac32;\n    union ui32_f32 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    sign  = signF128UI64( uiA64 );\n    exp   = expF128UI64( uiA64 );\n    frac64 = fracF128UI64( uiA64 ) | (uiA0 != 0);\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x7FFF ) {\n        if ( frac64 ) {\n            softfloat_f128UIToCommonNaN( uiA64, uiA0, &commonNaN );\n            uiZ = softfloat_commonNaNToF32UI( &commonNaN );\n        } else {\n            uiZ = packToF32UI( sign, 0xFF, 0 );\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    frac32 = softfloat_shortShiftRightJam64( frac64, 18 );\n    if ( ! (exp | frac32) ) {\n        uiZ = packToF32UI( sign, 0, 0 );\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    exp -= 0x3F81;\n    if ( sizeof (int_fast16_t) < sizeof (int_fast32_t) ) {\n        if ( exp < -0x1000 ) exp = -0x1000;\n    }\n    return softfloat_roundPackToF32( sign, exp, frac32 | 0x40000000 );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_to_f64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat64_t f128_to_f64( float128_t a )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool sign;\n    int_fast32_t exp;\n    uint_fast64_t frac64, frac0;\n    struct commonNaN commonNaN;\n    uint_fast64_t uiZ;\n    struct uint128 frac128;\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    sign  = signF128UI64( uiA64 );\n    exp   = expF128UI64( uiA64 );\n    frac64 = fracF128UI64( uiA64 );\n    frac0  = uiA0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x7FFF ) {\n        if ( frac64 | frac0 ) {\n            softfloat_f128UIToCommonNaN( uiA64, uiA0, &commonNaN );\n            uiZ = softfloat_commonNaNToF64UI( &commonNaN );\n        } else {\n            uiZ = packToF64UI( sign, 0x7FF, 0 );\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    frac128 = softfloat_shortShiftLeft128( frac64, frac0, 14 );\n    frac64 = frac128.v64 | (frac128.v0 != 0);\n    if ( ! (exp | frac64) ) {\n        uiZ = packToF64UI( sign, 0, 0 );\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    exp -= 0x3C01;\n    if ( sizeof (int_fast16_t) < sizeof (int_fast32_t) ) {\n        if ( exp < -0x1000 ) exp = -0x1000;\n    }\n    return\n        softfloat_roundPackToF64(\n            sign, exp, frac64 | UINT64_C( 0x4000000000000000 ) );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_to_i32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast32_t f128_to_i32( float128_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool sign;\n    int_fast32_t exp;\n    uint_fast64_t sig64, sig0;\n    int_fast32_t shiftDist;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    sign  = signF128UI64( uiA64 );\n    exp   = expF128UI64( uiA64 );\n    sig64 = fracF128UI64( uiA64 );\n    sig0  = uiA0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)\n    if ( (exp == 0x7FFF) && (sig64 | sig0) ) {\n#if (i32_fromNaN == i32_fromPosOverflow)\n        sign = 0;\n#elif (i32_fromNaN == i32_fromNegOverflow)\n        sign = 1;\n#else\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return i32_fromNaN;\n#endif\n    }\n#endif\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 );\n    sig64 |= (sig0 != 0);\n    shiftDist = 0x4023 - exp;\n    if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist );\n    return softfloat_roundToI32( sign, sig64, roundingMode, exact );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_to_i32_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast32_t f128_to_i32_r_minMag( float128_t a, bool exact )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    int_fast32_t exp;\n    uint_fast64_t sig64;\n    int_fast32_t shiftDist;\n    bool sign;\n    int_fast32_t absZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    exp   = expF128UI64( uiA64 );\n    sig64 = fracF128UI64( uiA64 ) | (uiA0 != 0);\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0x402F - exp;\n    if ( 49 <= shiftDist ) {\n        if ( exact && (exp | sig64) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF128UI64( uiA64 );\n    if ( shiftDist < 18 ) {\n        if (\n            sign && (shiftDist == 17)\n                && (sig64 < UINT64_C( 0x0000000000020000 ))\n        ) {\n            if ( exact && sig64 ) {\n                softfloat_exceptionFlags |= softfloat_flag_inexact;\n            }\n            return -0x7FFFFFFF - 1;\n        }\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0x7FFF) && sig64 ? i32_fromNaN\n                : sign ? i32_fromNegOverflow : i32_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig64 |= UINT64_C( 0x0001000000000000 );\n    absZ = sig64>>shiftDist;\n    if (\n        exact && ((uint_fast64_t) (uint_fast32_t) absZ<<shiftDist != sig64)\n    ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return sign ? -absZ : absZ;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_to_i64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast64_t f128_to_i64( float128_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool sign;\n    int_fast32_t exp;\n    uint_fast64_t sig64, sig0;\n    int_fast32_t shiftDist;\n    struct uint128 sig128;\n    struct uint64_extra sigExtra;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    sign  = signF128UI64( uiA64 );\n    exp   = expF128UI64( uiA64 );\n    sig64 = fracF128UI64( uiA64 );\n    sig0  = uiA0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0x402F - exp;\n    if ( shiftDist <= 0 ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( shiftDist < -15 ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n            return\n                (exp == 0x7FFF) && (sig64 | sig0) ? i64_fromNaN\n                    : sign ? i64_fromNegOverflow : i64_fromPosOverflow;\n        }\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        sig64 |= UINT64_C( 0x0001000000000000 );\n        if ( shiftDist ) {\n            sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftDist );\n            sig64 = sig128.v64;\n            sig0  = sig128.v0;\n        }\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 );\n        sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftDist );\n        sig64 = sigExtra.v;\n        sig0  = sigExtra.extra;\n    }\n    return softfloat_roundToI64( sign, sig64, sig0, roundingMode, exact );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_to_i64_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast64_t f128_to_i64_r_minMag( float128_t a, bool exact )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool sign;\n    int_fast32_t exp;\n    uint_fast64_t sig64, sig0;\n    int_fast32_t shiftDist;\n    int_fast8_t negShiftDist;\n    int_fast64_t absZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    sign  = signF128UI64( uiA64 );\n    exp   = expF128UI64( uiA64 );\n    sig64 = fracF128UI64( uiA64 );\n    sig0  = uiA0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0x402F - exp;\n    if ( shiftDist < 0 ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( shiftDist < -14 ) {\n            if (\n                   (uiA64 == UINT64_C( 0xC03E000000000000 ))\n                && (sig0 < UINT64_C( 0x0002000000000000 ))\n            ) {\n                if ( exact && sig0 ) {\n                    softfloat_exceptionFlags |= softfloat_flag_inexact;\n                }\n                return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1;\n            }\n            softfloat_raiseFlags( softfloat_flag_invalid );\n            return\n                (exp == 0x7FFF) && (sig64 | sig0) ? i64_fromNaN\n                    : sign ? i64_fromNegOverflow : i64_fromPosOverflow;\n        }\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        sig64 |= UINT64_C( 0x0001000000000000 );\n        negShiftDist = -shiftDist;\n        absZ = sig64<<negShiftDist | sig0>>(shiftDist & 63);\n        if ( exact && (uint64_t) (sig0<<negShiftDist) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( 49 <= shiftDist ) {\n            if ( exact && (exp | sig64 | sig0) ) {\n                softfloat_exceptionFlags |= softfloat_flag_inexact;\n            }\n            return 0;\n        }\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        sig64 |= UINT64_C( 0x0001000000000000 );\n        absZ = sig64>>shiftDist;\n        if ( exact && (sig0 || (absZ<<shiftDist != sig64)) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n    }\n    return sign ? -absZ : absZ;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_to_ui32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast32_t\n f128_to_ui32( float128_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool sign;\n    int_fast32_t exp;\n    uint_fast64_t sig64;\n    int_fast32_t shiftDist;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    sign  = signF128UI64( uiA64 );\n    exp   = expF128UI64( uiA64 );\n    sig64 = fracF128UI64( uiA64 ) | (uiA0 != 0);\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)\n    if ( (exp == 0x7FFF) && sig64 ) {\n#if (ui32_fromNaN == ui32_fromPosOverflow)\n        sign = 0;\n#elif (ui32_fromNaN == ui32_fromNegOverflow)\n        sign = 1;\n#else\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return ui32_fromNaN;\n#endif\n    }\n#endif\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 );\n    shiftDist = 0x4023 - exp;\n    if ( 0 < shiftDist ) {\n        sig64 = softfloat_shiftRightJam64( sig64, shiftDist );\n    }\n    return softfloat_roundToUI32( sign, sig64, roundingMode, exact );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_to_ui32_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast32_t f128_to_ui32_r_minMag( float128_t a, bool exact )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    int_fast32_t exp;\n    uint_fast64_t sig64;\n    int_fast32_t shiftDist;\n    bool sign;\n    uint_fast32_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    exp   = expF128UI64( uiA64 );\n    sig64 = fracF128UI64( uiA64 ) | (uiA0 != 0);\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0x402F - exp;\n    if ( 49 <= shiftDist ) {\n        if ( exact && (exp | sig64) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF128UI64( uiA64 );\n    if ( sign || (shiftDist < 17) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0x7FFF) && sig64 ? ui32_fromNaN\n                : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig64 |= UINT64_C( 0x0001000000000000 );\n    z = sig64>>shiftDist;\n    if ( exact && ((uint_fast64_t) z<<shiftDist != sig64) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return z;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_to_ui64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast64_t\n f128_to_ui64( float128_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool sign;\n    int_fast32_t exp;\n    uint_fast64_t sig64, sig0;\n    int_fast32_t shiftDist;\n    struct uint128 sig128;\n    struct uint64_extra sigExtra;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    sign  = signF128UI64( uiA64 );\n    exp   = expF128UI64( uiA64 );\n    sig64 = fracF128UI64( uiA64 );\n    sig0  = uiA0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0x402F - exp;\n    if ( shiftDist <= 0 ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( shiftDist < -15 ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n            return\n                (exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN\n                    : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;\n        }\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        sig64 |= UINT64_C( 0x0001000000000000 );\n        if ( shiftDist ) {\n            sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftDist );\n            sig64 = sig128.v64;\n            sig0  = sig128.v0;\n        }\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 );\n        sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftDist );\n        sig64 = sigExtra.v;\n        sig0  = sigExtra.extra;\n    }\n    return softfloat_roundToUI64( sign, sig64, sig0, roundingMode, exact );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f128_to_ui64_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast64_t f128_to_ui64_r_minMag( float128_t a, bool exact )\n{\n    union ui128_f128 uA;\n    uint_fast64_t uiA64, uiA0;\n    bool sign;\n    int_fast32_t exp;\n    uint_fast64_t sig64, sig0;\n    int_fast32_t shiftDist;\n    int_fast8_t negShiftDist;\n    uint_fast64_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA64 = uA.ui.v64;\n    uiA0  = uA.ui.v0;\n    sign  = signF128UI64( uiA64 );\n    exp   = expF128UI64( uiA64 );\n    sig64 = fracF128UI64( uiA64 );\n    sig0  = uiA0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0x402F - exp;\n    if ( shiftDist < 0 ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( sign || (shiftDist < -15) ) goto invalid;\n        sig64 |= UINT64_C( 0x0001000000000000 );\n        negShiftDist = -shiftDist;\n        z = sig64<<negShiftDist | sig0>>(shiftDist & 63);\n        if ( exact && (uint64_t) (sig0<<negShiftDist) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( 49 <= shiftDist ) {\n            if ( exact && (exp | sig64 | sig0) ) {\n                softfloat_exceptionFlags |= softfloat_flag_inexact;\n            }\n            return 0;\n        }\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( sign ) goto invalid;\n        sig64 |= UINT64_C( 0x0001000000000000 );\n        z = sig64>>shiftDist;\n        if ( exact && (sig0 || (z<<shiftDist != sig64)) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n    }\n    return z;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return\n        (exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN\n            : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_add.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat16_t f16_add( float16_t a, float16_t b )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    union ui16_f16 uB;\n    uint_fast16_t uiB;\n#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1)\n    float16_t (*magsFuncPtr)( uint_fast16_t, uint_fast16_t );\n#endif\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL)\n    if ( signF16UI( uiA ^ uiB ) ) {\n        return softfloat_subMagsF16( uiA, uiB );\n    } else {\n        return softfloat_addMagsF16( uiA, uiB );\n    }\n#else\n    magsFuncPtr =\n        signF16UI( uiA ^ uiB ) ? softfloat_subMagsF16 : softfloat_addMagsF16;\n    return (*magsFuncPtr)( uiA, uiB );\n#endif\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_div.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nextern const uint16_t softfloat_approxRecip_1k0s[];\nextern const uint16_t softfloat_approxRecip_1k1s[];\n\nfloat16_t f16_div( float16_t a, float16_t b )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    bool signA;\n    int_fast8_t expA;\n    uint_fast16_t sigA;\n    union ui16_f16 uB;\n    uint_fast16_t uiB;\n    bool signB;\n    int_fast8_t expB;\n    uint_fast16_t sigB;\n    bool signZ;\n    struct exp8_sig16 normExpSig;\n    int_fast8_t expZ;\n#ifdef SOFTFLOAT_FAST_DIV32TO16\n    uint_fast32_t sig32A;\n    uint_fast16_t sigZ;\n#else\n    int index;\n    uint16_t r0;\n    uint_fast16_t sigZ, rem;\n#endif\n    uint_fast16_t uiZ;\n    union ui16_f16 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF16UI( uiA );\n    expA  = expF16UI( uiA );\n    sigA  = fracF16UI( uiA );\n    uB.f = b;\n    uiB = uB.ui;\n    signB = signF16UI( uiB );\n    expB  = expF16UI( uiB );\n    sigB  = fracF16UI( uiB );\n    signZ = signA ^ signB;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x1F ) {\n        if ( sigA ) goto propagateNaN;\n        if ( expB == 0x1F ) {\n            if ( sigB ) goto propagateNaN;\n            goto invalid;\n        }\n        goto infinity;\n    }\n    if ( expB == 0x1F ) {\n        if ( sigB ) goto propagateNaN;\n        goto zero;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expB ) {\n        if ( ! sigB ) {\n            if ( ! (expA | sigA) ) goto invalid;\n            softfloat_raiseFlags( softfloat_flag_infinite );\n            goto infinity;\n        }\n        normExpSig = softfloat_normSubnormalF16Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    if ( ! expA ) {\n        if ( ! sigA ) goto zero;\n        normExpSig = softfloat_normSubnormalF16Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = expA - expB + 0xE;\n    sigA |= 0x0400;\n    sigB |= 0x0400;\n#ifdef SOFTFLOAT_FAST_DIV32TO16\n    if ( sigA < sigB ) {\n        --expZ;\n        sig32A = (uint_fast32_t) sigA<<15;\n    } else {\n        sig32A = (uint_fast32_t) sigA<<14;\n    }\n    sigZ = sig32A / sigB;\n    if ( ! (sigZ & 7) ) sigZ |= ((uint_fast32_t) sigB * sigZ != sig32A);\n#else\n    if ( sigA < sigB ) {\n        --expZ;\n        sigA <<= 5;\n    } else {\n        sigA <<= 4;\n    }\n    index = sigB>>6 & 0xF;\n    r0 = softfloat_approxRecip_1k0s[index]\n             - (((uint_fast32_t) softfloat_approxRecip_1k1s[index]\n                     * (sigB & 0x3F))\n                    >>10);\n    sigZ = ((uint_fast32_t) sigA * r0)>>16;\n    rem = (sigA<<10) - sigZ * sigB;\n    sigZ += (rem * (uint_fast32_t) r0)>>26;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    ++sigZ;\n    if ( ! (sigZ & 7) ) {\n        sigZ &= ~1;\n        rem = (sigA<<10) - sigZ * sigB;\n        if ( rem & 0x8000 ) {\n            sigZ -= 2;\n        } else {\n            if ( rem ) sigZ |= 1;\n        }\n    }\n#endif\n    return softfloat_roundPackToF16( signZ, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF16UI( uiA, uiB );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF16UI;\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infinity:\n    uiZ = packToF16UI( signZ, 0x1F, 0 );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zero:\n    uiZ = packToF16UI( signZ, 0, 0 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_eq.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f16_eq( float16_t a, float16_t b )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    union ui16_f16 uB;\n    uint_fast16_t uiB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) {\n        if (\n            softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB )\n        ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n        }\n        return false;\n    }\n    return (uiA == uiB) || ! (uint16_t) ((uiA | uiB)<<1);\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_eq_signaling.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nbool f16_eq_signaling( float16_t a, float16_t b )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    union ui16_f16 uB;\n    uint_fast16_t uiB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return false;\n    }\n    return (uiA == uiB) || ! (uint16_t) ((uiA | uiB)<<1);\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_isSignalingNaN.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f16_isSignalingNaN( float16_t a )\n{\n    union ui16_f16 uA;\n\n    uA.f = a;\n    return softfloat_isSigNaNF16UI( uA.ui );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_le.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nbool f16_le( float16_t a, float16_t b )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    union ui16_f16 uB;\n    uint_fast16_t uiB;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return false;\n    }\n    signA = signF16UI( uiA );\n    signB = signF16UI( uiB );\n    return\n        (signA != signB) ? signA || ! (uint16_t) ((uiA | uiB)<<1)\n            : (uiA == uiB) || (signA ^ (uiA < uiB));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_le_quiet.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f16_le_quiet( float16_t a, float16_t b )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    union ui16_f16 uB;\n    uint_fast16_t uiB;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) {\n        if (\n            softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB )\n        ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n        }\n        return false;\n    }\n    signA = signF16UI( uiA );\n    signB = signF16UI( uiB );\n    return\n        (signA != signB) ? signA || ! (uint16_t) ((uiA | uiB)<<1)\n            : (uiA == uiB) || (signA ^ (uiA < uiB));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_lt.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nbool f16_lt( float16_t a, float16_t b )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    union ui16_f16 uB;\n    uint_fast16_t uiB;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return false;\n    }\n    signA = signF16UI( uiA );\n    signB = signF16UI( uiB );\n    return\n        (signA != signB) ? signA && ((uint16_t) ((uiA | uiB)<<1) != 0)\n            : (uiA != uiB) && (signA ^ (uiA < uiB));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_lt_quiet.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f16_lt_quiet( float16_t a, float16_t b )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    union ui16_f16 uB;\n    uint_fast16_t uiB;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) {\n        if (\n            softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB )\n        ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n        }\n        return false;\n    }\n    signA = signF16UI( uiA );\n    signB = signF16UI( uiB );\n    return\n        (signA != signB) ? signA && ((uint16_t) ((uiA | uiB)<<1) != 0)\n            : (uiA != uiB) && (signA ^ (uiA < uiB));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_mul.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat16_t f16_mul( float16_t a, float16_t b )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    bool signA;\n    int_fast8_t expA;\n    uint_fast16_t sigA;\n    union ui16_f16 uB;\n    uint_fast16_t uiB;\n    bool signB;\n    int_fast8_t expB;\n    uint_fast16_t sigB;\n    bool signZ;\n    uint_fast16_t magBits;\n    struct exp8_sig16 normExpSig;\n    int_fast8_t expZ;\n    uint_fast32_t sig32Z;\n    uint_fast16_t sigZ, uiZ;\n    union ui16_f16 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF16UI( uiA );\n    expA  = expF16UI( uiA );\n    sigA  = fracF16UI( uiA );\n    uB.f = b;\n    uiB = uB.ui;\n    signB = signF16UI( uiB );\n    expB  = expF16UI( uiB );\n    sigB  = fracF16UI( uiB );\n    signZ = signA ^ signB;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x1F ) {\n        if ( sigA || ((expB == 0x1F) && sigB) ) goto propagateNaN;\n        magBits = expB | sigB;\n        goto infArg;\n    }\n    if ( expB == 0x1F ) {\n        if ( sigB ) goto propagateNaN;\n        magBits = expA | sigA;\n        goto infArg;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! sigA ) goto zero;\n        normExpSig = softfloat_normSubnormalF16Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    if ( ! expB ) {\n        if ( ! sigB ) goto zero;\n        normExpSig = softfloat_normSubnormalF16Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = expA + expB - 0xF;\n    sigA = (sigA | 0x0400)<<4;\n    sigB = (sigB | 0x0400)<<5;\n    sig32Z = (uint_fast32_t) sigA * sigB;\n    sigZ = sig32Z>>16;\n    if ( sig32Z & 0xFFFF ) sigZ |= 1;\n    if ( sigZ < 0x4000 ) {\n        --expZ;\n        sigZ <<= 1;\n    }\n    return softfloat_roundPackToF16( signZ, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF16UI( uiA, uiB );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infArg:\n    if ( ! magBits ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        uiZ = defaultNaNF16UI;\n    } else {\n        uiZ = packToF16UI( signZ, 0x1F, 0 );\n    }\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zero:\n    uiZ = packToF16UI( signZ, 0, 0 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_mulAdd.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat16_t f16_mulAdd( float16_t a, float16_t b, float16_t c )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    union ui16_f16 uB;\n    uint_fast16_t uiB;\n    union ui16_f16 uC;\n    uint_fast16_t uiC;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    uC.f = c;\n    uiC = uC.ui;\n    return softfloat_mulAddF16( uiA, uiB, uiC, 0 );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_rem.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat16_t f16_rem( float16_t a, float16_t b )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    bool signA;\n    int_fast8_t expA;\n    uint_fast16_t sigA;\n    union ui16_f16 uB;\n    uint_fast16_t uiB;\n    int_fast8_t expB;\n    uint_fast16_t sigB;\n    struct exp8_sig16 normExpSig;\n    uint16_t rem;\n    int_fast8_t expDiff;\n    uint_fast16_t q;\n    uint32_t recip32, q32;\n    uint16_t altRem, meanRem;\n    bool signRem;\n    uint_fast16_t uiZ;\n    union ui16_f16 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF16UI( uiA );\n    expA  = expF16UI( uiA );\n    sigA  = fracF16UI( uiA );\n    uB.f = b;\n    uiB = uB.ui;\n    expB = expF16UI( uiB );\n    sigB = fracF16UI( uiB );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x1F ) {\n        if ( sigA || ((expB == 0x1F) && sigB) ) goto propagateNaN;\n        goto invalid;\n    }\n    if ( expB == 0x1F ) {\n        if ( sigB ) goto propagateNaN;\n        return a;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expB ) {\n        if ( ! sigB ) goto invalid;\n        normExpSig = softfloat_normSubnormalF16Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    if ( ! expA ) {\n        if ( ! sigA ) return a;\n        normExpSig = softfloat_normSubnormalF16Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    rem = sigA | 0x0400;\n    sigB |= 0x0400;\n    expDiff = expA - expB;\n    if ( expDiff < 1 ) {\n        if ( expDiff < -1 ) return a;\n        sigB <<= 3;\n        if ( expDiff ) {\n            rem <<= 2;\n            q = 0;\n        } else {\n            rem <<= 3;\n            q = (sigB <= rem);\n            if ( q ) rem -= sigB;\n        }\n    } else {\n        recip32 = softfloat_approxRecip32_1( (uint_fast32_t) sigB<<21 );\n        /*--------------------------------------------------------------------\n        | Changing the shift of `rem' here requires also changing the initial\n        | subtraction from `expDiff'.\n        *--------------------------------------------------------------------*/\n        rem <<= 4;\n        expDiff -= 31;\n        /*--------------------------------------------------------------------\n        | The scale of `sigB' affects how many bits are obtained during each\n        | cycle of the loop.  Currently this is 29 bits per loop iteration,\n        | which is believed to be the maximum possible.\n        *--------------------------------------------------------------------*/\n        sigB <<= 3;\n        for (;;) {\n            q32 = (rem * (uint_fast64_t) recip32)>>16;\n            if ( expDiff < 0 ) break;\n            rem = -((uint_fast16_t) q32 * sigB);\n            expDiff -= 29;\n        }\n        /*--------------------------------------------------------------------\n        | (`expDiff' cannot be less than -30 here.)\n        *--------------------------------------------------------------------*/\n        q32 >>= ~expDiff & 31;\n        q = q32;\n        rem = (rem<<(expDiff + 30)) - q * sigB;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    do {\n        altRem = rem;\n        ++q;\n        rem -= sigB;\n    } while ( ! (rem & 0x8000) );\n    meanRem = rem + altRem;\n    if ( (meanRem & 0x8000) || (! meanRem && (q & 1)) ) rem = altRem;\n    signRem = signA;\n    if ( 0x8000 <= rem ) {\n        signRem = ! signRem;\n        rem = -rem;\n    }\n    return softfloat_normRoundPackToF16( signRem, expB, rem );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF16UI( uiA, uiB );\n    goto uiZ;\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF16UI;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_roundToInt.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat16_t f16_roundToInt( float16_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    int_fast8_t exp;\n    uint_fast16_t uiZ, lastBitMask, roundBitsMask;\n    union ui16_f16 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp = expF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp <= 0xE ) {\n        if ( ! (uint16_t) (uiA<<1) ) return a;\n        if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact;\n        uiZ = uiA & packToF16UI( 1, 0, 0 );\n        switch ( roundingMode ) {\n         case softfloat_round_near_even:\n            if ( ! fracF16UI( uiA ) ) break;\n         case softfloat_round_near_maxMag:\n            if ( exp == 0xE ) uiZ |= packToF16UI( 0, 0xF, 0 );\n            break;\n         case softfloat_round_min:\n            if ( uiZ ) uiZ = packToF16UI( 1, 0xF, 0 );\n            break;\n         case softfloat_round_max:\n            if ( ! uiZ ) uiZ = packToF16UI( 0, 0xF, 0 );\n            break;\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( 0x19 <= exp ) {\n        if ( (exp == 0x1F) && fracF16UI( uiA ) ) {\n            uiZ = softfloat_propagateNaNF16UI( uiA, 0 );\n            goto uiZ;\n        }\n        return a;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uiZ = uiA;\n    lastBitMask = (uint_fast16_t) 1<<(0x19 - exp);\n    roundBitsMask = lastBitMask - 1;\n    if ( roundingMode == softfloat_round_near_maxMag ) {\n        uiZ += lastBitMask>>1;\n    } else if ( roundingMode == softfloat_round_near_even ) {\n        uiZ += lastBitMask>>1;\n        if ( ! (uiZ & roundBitsMask) ) uiZ &= ~lastBitMask;\n    } else if (\n        roundingMode\n            == (signF16UI( uiZ ) ? softfloat_round_min : softfloat_round_max)\n    ) {\n        uiZ += roundBitsMask;\n    }\n    uiZ &= ~roundBitsMask;\n    if ( exact && (uiZ != uiA) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_sqrt.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nextern const uint16_t softfloat_approxRecipSqrt_1k0s[];\nextern const uint16_t softfloat_approxRecipSqrt_1k1s[];\n\nfloat16_t f16_sqrt( float16_t a )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    bool signA;\n    int_fast8_t expA;\n    uint_fast16_t sigA, uiZ;\n    struct exp8_sig16 normExpSig;\n    int_fast8_t expZ;\n    int index;\n    uint_fast16_t r0;\n    uint_fast32_t ESqrR0;\n    uint16_t sigma0;\n    uint_fast16_t recipSqrt16, sigZ, shiftedSigZ;\n    uint16_t negRem;\n    union ui16_f16 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF16UI( uiA );\n    expA  = expF16UI( uiA );\n    sigA  = fracF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x1F ) {\n        if ( sigA ) {\n            uiZ = softfloat_propagateNaNF16UI( uiA, 0 );\n            goto uiZ;\n        }\n        if ( ! signA ) return a;\n        goto invalid;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( signA ) {\n        if ( ! (expA | sigA) ) return a;\n        goto invalid;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! sigA ) return a;\n        normExpSig = softfloat_normSubnormalF16Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = ((expA - 0xF)>>1) + 0xE;\n    expA &= 1;\n    sigA |= 0x0400;\n    index = (sigA>>6 & 0xE) + expA;\n    r0 = softfloat_approxRecipSqrt_1k0s[index]\n             - (((uint_fast32_t) softfloat_approxRecipSqrt_1k1s[index]\n                     * (sigA & 0x7F))\n                    >>11);\n    ESqrR0 = ((uint_fast32_t) r0 * r0)>>1;\n    if ( expA ) ESqrR0 >>= 1;\n    sigma0 = ~(uint_fast16_t) ((ESqrR0 * sigA)>>16);\n    recipSqrt16 = r0 + (((uint_fast32_t) r0 * sigma0)>>25);\n    if ( ! (recipSqrt16 & 0x8000) ) recipSqrt16 = 0x8000;\n    sigZ = ((uint_fast32_t) (sigA<<5) * recipSqrt16)>>16;\n    if ( expA ) sigZ >>= 1;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    ++sigZ;\n    if ( ! (sigZ & 7) ) {\n        shiftedSigZ = sigZ>>1;\n        negRem = shiftedSigZ * shiftedSigZ;\n        sigZ &= ~1;\n        if ( negRem & 0x8000 ) {\n            sigZ |= 1;\n        } else {\n            if ( negRem ) --sigZ;\n        }\n    }\n    return softfloat_roundPackToF16( 0, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF16UI;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_sub.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat16_t f16_sub( float16_t a, float16_t b )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    union ui16_f16 uB;\n    uint_fast16_t uiB;\n#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1)\n    float16_t (*magsFuncPtr)( uint_fast16_t, uint_fast16_t );\n#endif\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL)\n    if ( signF16UI( uiA ^ uiB ) ) {\n        return softfloat_addMagsF16( uiA, uiB );\n    } else {\n        return softfloat_subMagsF16( uiA, uiB );\n    }\n#else\n    magsFuncPtr =\n        signF16UI( uiA ^ uiB ) ? softfloat_addMagsF16 : softfloat_subMagsF16;\n    return (*magsFuncPtr)( uiA, uiB );\n#endif\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_to_f128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat128_t f16_to_f128( float16_t a )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    bool sign;\n    int_fast8_t exp;\n    uint_fast16_t frac;\n    struct commonNaN commonNaN;\n    struct uint128 uiZ;\n    struct exp8_sig16 normExpSig;\n    union ui128_f128 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF16UI( uiA );\n    exp  = expF16UI( uiA );\n    frac = fracF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x1F ) {\n        if ( frac ) {\n            softfloat_f16UIToCommonNaN( uiA, &commonNaN );\n            uiZ = softfloat_commonNaNToF128UI( &commonNaN );\n        } else {\n            uiZ.v64 = packToF128UI64( sign, 0x7FFF, 0 );\n            uiZ.v0  = 0;\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! exp ) {\n        if ( ! frac ) {\n            uiZ.v64 = packToF128UI64( sign, 0, 0 );\n            uiZ.v0  = 0;\n            goto uiZ;\n        }\n        normExpSig = softfloat_normSubnormalF16Sig( frac );\n        exp = normExpSig.exp - 1;\n        frac = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uiZ.v64 = packToF128UI64( sign, exp + 0x3FF0, (uint_fast64_t) frac<<38 );\n    uiZ.v0  = 0;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_to_f32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat32_t f16_to_f32( float16_t a )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    bool sign;\n    int_fast8_t exp;\n    uint_fast16_t frac;\n    struct commonNaN commonNaN;\n    uint_fast32_t uiZ;\n    struct exp8_sig16 normExpSig;\n    union ui32_f32 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF16UI( uiA );\n    exp  = expF16UI( uiA );\n    frac = fracF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x1F ) {\n        if ( frac ) {\n            softfloat_f16UIToCommonNaN( uiA, &commonNaN );\n            uiZ = softfloat_commonNaNToF32UI( &commonNaN );\n        } else {\n            uiZ = packToF32UI( sign, 0xFF, 0 );\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! exp ) {\n        if ( ! frac ) {\n            uiZ = packToF32UI( sign, 0, 0 );\n            goto uiZ;\n        }\n        normExpSig = softfloat_normSubnormalF16Sig( frac );\n        exp = normExpSig.exp - 1;\n        frac = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uiZ = packToF32UI( sign, exp + 0x70, (uint_fast32_t) frac<<13 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_to_f64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat64_t f16_to_f64( float16_t a )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    bool sign;\n    int_fast8_t exp;\n    uint_fast16_t frac;\n    struct commonNaN commonNaN;\n    uint_fast64_t uiZ;\n    struct exp8_sig16 normExpSig;\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF16UI( uiA );\n    exp  = expF16UI( uiA );\n    frac = fracF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x1F ) {\n        if ( frac ) {\n            softfloat_f16UIToCommonNaN( uiA, &commonNaN );\n            uiZ = softfloat_commonNaNToF64UI( &commonNaN );\n        } else {\n            uiZ = packToF64UI( sign, 0x7FF, 0 );\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! exp ) {\n        if ( ! frac ) {\n            uiZ = packToF64UI( sign, 0, 0 );\n            goto uiZ;\n        }\n        normExpSig = softfloat_normSubnormalF16Sig( frac );\n        exp = normExpSig.exp - 1;\n        frac = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uiZ = packToF64UI( sign, exp + 0x3F0, (uint_fast64_t) frac<<42 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_to_i32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast32_t f16_to_i32( float16_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    bool sign;\n    int_fast8_t exp;\n    uint_fast16_t frac;\n    int_fast32_t sig32;\n    int_fast8_t shiftDist;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF16UI( uiA );\n    exp  = expF16UI( uiA );\n    frac = fracF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x1F ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            frac ? i32_fromNaN\n                : sign ? i32_fromNegOverflow : i32_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig32 = frac;\n    if ( exp ) {\n        sig32 |= 0x0400;\n        shiftDist = exp - 0x19;\n        if ( 0 <= shiftDist ) {\n            sig32 <<= shiftDist;\n            return sign ? -sig32 : sig32;\n        }\n        shiftDist = exp - 0x0D;\n        if ( 0 < shiftDist ) sig32 <<= shiftDist;\n    }\n    return\n        softfloat_roundToI32(\n            sign, (uint_fast32_t) sig32, roundingMode, exact );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_to_i32_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast32_t f16_to_i32_r_minMag( float16_t a, bool exact )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    int_fast8_t exp;\n    uint_fast16_t frac;\n    int_fast8_t shiftDist;\n    bool sign;\n    int_fast32_t alignedSig;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp  = expF16UI( uiA );\n    frac = fracF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = exp - 0x0F;\n    if ( shiftDist < 0 ) {\n        if ( exact && (exp | frac) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF16UI( uiA );\n    if ( exp == 0x1F ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0x1F) && frac ? i32_fromNaN\n                : sign ? i32_fromNegOverflow : i32_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    alignedSig = (int_fast32_t) (frac | 0x0400)<<shiftDist;\n    if ( exact && (alignedSig & 0x3FF) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    alignedSig >>= 10;\n    return sign ? -alignedSig : alignedSig;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_to_i64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast64_t f16_to_i64( float16_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    bool sign;\n    int_fast8_t exp;\n    uint_fast16_t frac;\n    int_fast32_t sig32;\n    int_fast8_t shiftDist;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF16UI( uiA );\n    exp  = expF16UI( uiA );\n    frac = fracF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x1F ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            frac ? i64_fromNaN\n                : sign ? i64_fromNegOverflow : i64_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig32 = frac;\n    if ( exp ) {\n        sig32 |= 0x0400;\n        shiftDist = exp - 0x19;\n        if ( 0 <= shiftDist ) {\n            sig32 <<= shiftDist;\n            return sign ? -sig32 : sig32;\n        }\n        shiftDist = exp - 0x0D;\n        if ( 0 < shiftDist ) sig32 <<= shiftDist;\n    }\n    return\n        softfloat_roundToI32(\n            sign, (uint_fast32_t) sig32, roundingMode, exact );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_to_i64_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast64_t f16_to_i64_r_minMag( float16_t a, bool exact )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    int_fast8_t exp;\n    uint_fast16_t frac;\n    int_fast8_t shiftDist;\n    bool sign;\n    int_fast32_t alignedSig;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp  = expF16UI( uiA );\n    frac = fracF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = exp - 0x0F;\n    if ( shiftDist < 0 ) {\n        if ( exact && (exp | frac) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF16UI( uiA );\n    if ( exp == 0x1F ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0x1F) && frac ? i64_fromNaN\n                : sign ? i64_fromNegOverflow : i64_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    alignedSig = (int_fast32_t) (frac | 0x0400)<<shiftDist;\n    if ( exact && (alignedSig & 0x3FF) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    alignedSig >>= 10;\n    return sign ? -alignedSig : alignedSig;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_to_ui32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast32_t f16_to_ui32( float16_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    bool sign;\n    int_fast8_t exp;\n    uint_fast16_t frac;\n    uint_fast32_t sig32;\n    int_fast8_t shiftDist;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF16UI( uiA );\n    exp  = expF16UI( uiA );\n    frac = fracF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x1F ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            frac ? ui32_fromNaN\n                : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig32 = frac;\n    if ( exp ) {\n        sig32 |= 0x0400;\n        shiftDist = exp - 0x19;\n        if ( (0 <= shiftDist) && ! sign ) {\n            return sig32<<shiftDist;\n        }\n        shiftDist = exp - 0x0D;\n        if ( 0 < shiftDist ) sig32 <<= shiftDist;\n    }\n    return softfloat_roundToUI32( sign, sig32, roundingMode, exact );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_to_ui32_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast32_t f16_to_ui32_r_minMag( float16_t a, bool exact )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    int_fast8_t exp;\n    uint_fast16_t frac;\n    int_fast8_t shiftDist;\n    bool sign;\n    uint_fast32_t alignedSig;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp  = expF16UI( uiA );\n    frac = fracF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = exp - 0x0F;\n    if ( shiftDist < 0 ) {\n        if ( exact && (exp | frac) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF16UI( uiA );\n    if ( sign || (exp == 0x1F) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0x1F) && frac ? ui32_fromNaN\n                : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    alignedSig = (uint_fast32_t) (frac | 0x0400)<<shiftDist;\n    if ( exact && (alignedSig & 0x3FF) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return alignedSig>>10;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_to_ui64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast64_t f16_to_ui64( float16_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    bool sign;\n    int_fast8_t exp;\n    uint_fast16_t frac;\n    uint_fast32_t sig32;\n    int_fast8_t shiftDist;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF16UI( uiA );\n    exp  = expF16UI( uiA );\n    frac = fracF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x1F ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            frac ? ui64_fromNaN\n                : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig32 = frac;\n    if ( exp ) {\n        sig32 |= 0x0400;\n        shiftDist = exp - 0x19;\n        if ( (0 <= shiftDist) && ! sign ) {\n            return sig32<<shiftDist;\n        }\n        shiftDist = exp - 0x0D;\n        if ( 0 < shiftDist ) sig32 <<= shiftDist;\n    }\n    return softfloat_roundToUI32( sign, sig32, roundingMode, exact );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f16_to_ui64_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast64_t f16_to_ui64_r_minMag( float16_t a, bool exact )\n{\n    union ui16_f16 uA;\n    uint_fast16_t uiA;\n    int_fast8_t exp;\n    uint_fast16_t frac;\n    int_fast8_t shiftDist;\n    bool sign;\n    uint_fast32_t alignedSig;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp  = expF16UI( uiA );\n    frac = fracF16UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = exp - 0x0F;\n    if ( shiftDist < 0 ) {\n        if ( exact && (exp | frac) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF16UI( uiA );\n    if ( sign || (exp == 0x1F) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0x1F) && frac ? ui64_fromNaN\n                : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    alignedSig = (uint_fast32_t) (frac | 0x0400)<<shiftDist;\n    if ( exact && (alignedSig & 0x3FF) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return alignedSig>>10;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_add.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat32_t f32_add( float32_t a, float32_t b )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    union ui32_f32 uB;\n    uint_fast32_t uiB;\n#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1)\n    float32_t (*magsFuncPtr)( uint_fast32_t, uint_fast32_t );\n#endif\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL)\n    if ( signF32UI( uiA ^ uiB ) ) {\n        return softfloat_subMagsF32( uiA, uiB );\n    } else {\n        return softfloat_addMagsF32( uiA, uiB );\n    }\n#else\n    magsFuncPtr =\n        signF32UI( uiA ^ uiB ) ? softfloat_subMagsF32 : softfloat_addMagsF32;\n    return (*magsFuncPtr)( uiA, uiB );\n#endif\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_classify.c",
    "content": "\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast16_t f32_classify( float32_t a )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n\n    uA.f = a;\n    uiA = uA.ui;\n\n    uint_fast16_t infOrNaN = expF32UI( uiA ) == 0xFF;\n    uint_fast16_t subnormalOrZero = expF32UI( uiA ) == 0;\n    bool sign = signF32UI( uiA );\n    bool fracZero = fracF32UI( uiA ) == 0;\n    bool isNaN = isNaNF32UI( uiA );\n    bool isSNaN = softfloat_isSigNaNF32UI( uiA );\n\n    return\n        (  sign && infOrNaN && fracZero )          << 0 |\n        (  sign && !infOrNaN && !subnormalOrZero ) << 1 |\n        (  sign && subnormalOrZero && !fracZero )  << 2 |\n        (  sign && subnormalOrZero && fracZero )   << 3 |\n        ( !sign && infOrNaN && fracZero )          << 7 |\n        ( !sign && !infOrNaN && !subnormalOrZero ) << 6 |\n        ( !sign && subnormalOrZero && !fracZero )  << 5 |\n        ( !sign && subnormalOrZero && fracZero )   << 4 |\n        ( isNaN &&  isSNaN )                       << 8 |\n        ( isNaN && !isSNaN )                       << 9;\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_div.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat32_t f32_div( float32_t a, float32_t b )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    bool signA;\n    int_fast16_t expA;\n    uint_fast32_t sigA;\n    union ui32_f32 uB;\n    uint_fast32_t uiB;\n    bool signB;\n    int_fast16_t expB;\n    uint_fast32_t sigB;\n    bool signZ;\n    struct exp16_sig32 normExpSig;\n    int_fast16_t expZ;\n#ifdef SOFTFLOAT_FAST_DIV64TO32\n    uint_fast64_t sig64A;\n    uint_fast32_t sigZ;\n#else\n    uint_fast32_t sigZ;\n    uint_fast64_t rem;\n#endif\n    uint_fast32_t uiZ;\n    union ui32_f32 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF32UI( uiA );\n    expA  = expF32UI( uiA );\n    sigA  = fracF32UI( uiA );\n    uB.f = b;\n    uiB = uB.ui;\n    signB = signF32UI( uiB );\n    expB  = expF32UI( uiB );\n    sigB  = fracF32UI( uiB );\n    signZ = signA ^ signB;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0xFF ) {\n        if ( sigA ) goto propagateNaN;\n        if ( expB == 0xFF ) {\n            if ( sigB ) goto propagateNaN;\n            goto invalid;\n        }\n        goto infinity;\n    }\n    if ( expB == 0xFF ) {\n        if ( sigB ) goto propagateNaN;\n        goto zero;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expB ) {\n        if ( ! sigB ) {\n            if ( ! (expA | sigA) ) goto invalid;\n            softfloat_raiseFlags( softfloat_flag_infinite );\n            goto infinity;\n        }\n        normExpSig = softfloat_normSubnormalF32Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    if ( ! expA ) {\n        if ( ! sigA ) goto zero;\n        normExpSig = softfloat_normSubnormalF32Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = expA - expB + 0x7E;\n    sigA |= 0x00800000;\n    sigB |= 0x00800000;\n#ifdef SOFTFLOAT_FAST_DIV64TO32\n    if ( sigA < sigB ) {\n        --expZ;\n        sig64A = (uint_fast64_t) sigA<<31;\n    } else {\n        sig64A = (uint_fast64_t) sigA<<30;\n    }\n    sigZ = sig64A / sigB;\n    if ( ! (sigZ & 0x3F) ) sigZ |= ((uint_fast64_t) sigB * sigZ != sig64A);\n#else\n    if ( sigA < sigB ) {\n        --expZ;\n        sigA <<= 8;\n    } else {\n        sigA <<= 7;\n    }\n    sigB <<= 8;\n    sigZ = ((uint_fast64_t) sigA * softfloat_approxRecip32_1( sigB ))>>32;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sigZ += 2;\n    if ( (sigZ & 0x3F) < 2 ) {\n        sigZ &= ~3;\n#ifdef SOFTFLOAT_FAST_INT64\n        rem = ((uint_fast64_t) sigA<<31) - (uint_fast64_t) sigZ * sigB;\n#else\n        rem = ((uint_fast64_t) sigA<<32) - (uint_fast64_t) (sigZ<<1) * sigB;\n#endif\n        if ( rem & UINT64_C( 0x8000000000000000 ) ) {\n            sigZ -= 4;\n        } else {\n            if ( rem ) sigZ |= 1;\n        }\n    }\n#endif\n    return softfloat_roundPackToF32( signZ, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF32UI( uiA, uiB );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF32UI;\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infinity:\n    uiZ = packToF32UI( signZ, 0xFF, 0 );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zero:\n    uiZ = packToF32UI( signZ, 0, 0 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_eq.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f32_eq( float32_t a, float32_t b )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    union ui32_f32 uB;\n    uint_fast32_t uiB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) {\n        if (\n            softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB )\n        ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n        }\n        return false;\n    }\n    return (uiA == uiB) || ! (uint32_t) ((uiA | uiB)<<1);\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_eq_signaling.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nbool f32_eq_signaling( float32_t a, float32_t b )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    union ui32_f32 uB;\n    uint_fast32_t uiB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return false;\n    }\n    return (uiA == uiB) || ! (uint32_t) ((uiA | uiB)<<1);\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_isSignalingNaN.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f32_isSignalingNaN( float32_t a )\n{\n    union ui32_f32 uA;\n\n    uA.f = a;\n    return softfloat_isSigNaNF32UI( uA.ui );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_le.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nbool f32_le( float32_t a, float32_t b )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    union ui32_f32 uB;\n    uint_fast32_t uiB;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return false;\n    }\n    signA = signF32UI( uiA );\n    signB = signF32UI( uiB );\n    return\n        (signA != signB) ? signA || ! (uint32_t) ((uiA | uiB)<<1)\n            : (uiA == uiB) || (signA ^ (uiA < uiB));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_le_quiet.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f32_le_quiet( float32_t a, float32_t b )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    union ui32_f32 uB;\n    uint_fast32_t uiB;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) {\n        if (\n            softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB )\n        ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n        }\n        return false;\n    }\n    signA = signF32UI( uiA );\n    signB = signF32UI( uiB );\n    return\n        (signA != signB) ? signA || ! (uint32_t) ((uiA | uiB)<<1)\n            : (uiA == uiB) || (signA ^ (uiA < uiB));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_lt.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nbool f32_lt( float32_t a, float32_t b )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    union ui32_f32 uB;\n    uint_fast32_t uiB;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return false;\n    }\n    signA = signF32UI( uiA );\n    signB = signF32UI( uiB );\n    return\n        (signA != signB) ? signA && ((uint32_t) ((uiA | uiB)<<1) != 0)\n            : (uiA != uiB) && (signA ^ (uiA < uiB));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_lt_quiet.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f32_lt_quiet( float32_t a, float32_t b )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    union ui32_f32 uB;\n    uint_fast32_t uiB;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) {\n        if (\n            softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB )\n        ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n        }\n        return false;\n    }\n    signA = signF32UI( uiA );\n    signB = signF32UI( uiB );\n    return\n        (signA != signB) ? signA && ((uint32_t) ((uiA | uiB)<<1) != 0)\n            : (uiA != uiB) && (signA ^ (uiA < uiB));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_mul.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat32_t f32_mul( float32_t a, float32_t b )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    bool signA;\n    int_fast16_t expA;\n    uint_fast32_t sigA;\n    union ui32_f32 uB;\n    uint_fast32_t uiB;\n    bool signB;\n    int_fast16_t expB;\n    uint_fast32_t sigB;\n    bool signZ;\n    uint_fast32_t magBits;\n    struct exp16_sig32 normExpSig;\n    int_fast16_t expZ;\n    uint_fast32_t sigZ, uiZ;\n    union ui32_f32 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF32UI( uiA );\n    expA  = expF32UI( uiA );\n    sigA  = fracF32UI( uiA );\n    uB.f = b;\n    uiB = uB.ui;\n    signB = signF32UI( uiB );\n    expB  = expF32UI( uiB );\n    sigB  = fracF32UI( uiB );\n    signZ = signA ^ signB;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0xFF ) {\n        if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN;\n        magBits = expB | sigB;\n        goto infArg;\n    }\n    if ( expB == 0xFF ) {\n        if ( sigB ) goto propagateNaN;\n        magBits = expA | sigA;\n        goto infArg;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! sigA ) goto zero;\n        normExpSig = softfloat_normSubnormalF32Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    if ( ! expB ) {\n        if ( ! sigB ) goto zero;\n        normExpSig = softfloat_normSubnormalF32Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = expA + expB - 0x7F;\n    sigA = (sigA | 0x00800000)<<7;\n    sigB = (sigB | 0x00800000)<<8;\n    sigZ = softfloat_shortShiftRightJam64( (uint_fast64_t) sigA * sigB, 32 );\n    if ( sigZ < 0x40000000 ) {\n        --expZ;\n        sigZ <<= 1;\n    }\n    return softfloat_roundPackToF32( signZ, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF32UI( uiA, uiB );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infArg:\n    if ( ! magBits ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        uiZ = defaultNaNF32UI;\n    } else {\n        uiZ = packToF32UI( signZ, 0xFF, 0 );\n    }\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zero:\n    uiZ = packToF32UI( signZ, 0, 0 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_mulAdd.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat32_t f32_mulAdd( float32_t a, float32_t b, float32_t c )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    union ui32_f32 uB;\n    uint_fast32_t uiB;\n    union ui32_f32 uC;\n    uint_fast32_t uiC;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    uC.f = c;\n    uiC = uC.ui;\n    return softfloat_mulAddF32( uiA, uiB, uiC, 0 );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_rem.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat32_t f32_rem( float32_t a, float32_t b )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    bool signA;\n    int_fast16_t expA;\n    uint_fast32_t sigA;\n    union ui32_f32 uB;\n    uint_fast32_t uiB;\n    int_fast16_t expB;\n    uint_fast32_t sigB;\n    struct exp16_sig32 normExpSig;\n    uint32_t rem;\n    int_fast16_t expDiff;\n    uint32_t q, recip32, altRem, meanRem;\n    bool signRem;\n    uint_fast32_t uiZ;\n    union ui32_f32 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF32UI( uiA );\n    expA  = expF32UI( uiA );\n    sigA  = fracF32UI( uiA );\n    uB.f = b;\n    uiB = uB.ui;\n    expB = expF32UI( uiB );\n    sigB = fracF32UI( uiB );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0xFF ) {\n        if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN;\n        goto invalid;\n    }\n    if ( expB == 0xFF ) {\n        if ( sigB ) goto propagateNaN;\n        return a;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expB ) {\n        if ( ! sigB ) goto invalid;\n        normExpSig = softfloat_normSubnormalF32Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    if ( ! expA ) {\n        if ( ! sigA ) return a;\n        normExpSig = softfloat_normSubnormalF32Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    rem = sigA | 0x00800000;\n    sigB |= 0x00800000;\n    expDiff = expA - expB;\n    if ( expDiff < 1 ) {\n        if ( expDiff < -1 ) return a;\n        sigB <<= 6;\n        if ( expDiff ) {\n            rem <<= 5;\n            q = 0;\n        } else {\n            rem <<= 6;\n            q = (sigB <= rem);\n            if ( q ) rem -= sigB;\n        }\n    } else {\n        recip32 = softfloat_approxRecip32_1( sigB<<8 );\n        /*--------------------------------------------------------------------\n        | Changing the shift of `rem' here requires also changing the initial\n        | subtraction from `expDiff'.\n        *--------------------------------------------------------------------*/\n        rem <<= 7;\n        expDiff -= 31;\n        /*--------------------------------------------------------------------\n        | The scale of `sigB' affects how many bits are obtained during each\n        | cycle of the loop.  Currently this is 29 bits per loop iteration,\n        | which is believed to be the maximum possible.\n        *--------------------------------------------------------------------*/\n        sigB <<= 6;\n        for (;;) {\n            q = (rem * (uint_fast64_t) recip32)>>32;\n            if ( expDiff < 0 ) break;\n            rem = -(q * (uint32_t) sigB);\n            expDiff -= 29;\n        }\n        /*--------------------------------------------------------------------\n        | (`expDiff' cannot be less than -30 here.)\n        *--------------------------------------------------------------------*/\n        q >>= ~expDiff & 31;\n        rem = (rem<<(expDiff + 30)) - q * (uint32_t) sigB;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    do {\n        altRem = rem;\n        ++q;\n        rem -= sigB;\n    } while ( ! (rem & 0x80000000) );\n    meanRem = rem + altRem;\n    if ( (meanRem & 0x80000000) || (! meanRem && (q & 1)) ) rem = altRem;\n    signRem = signA;\n    if ( 0x80000000 <= rem ) {\n        signRem = ! signRem;\n        rem = -rem;\n    }\n    return softfloat_normRoundPackToF32( signRem, expB, rem );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF32UI( uiA, uiB );\n    goto uiZ;\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF32UI;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_roundToInt.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat32_t f32_roundToInt( float32_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    int_fast16_t exp;\n    uint_fast32_t uiZ, lastBitMask, roundBitsMask;\n    union ui32_f32 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp = expF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp <= 0x7E ) {\n        if ( ! (uint32_t) (uiA<<1) ) return a;\n        if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact;\n        uiZ = uiA & packToF32UI( 1, 0, 0 );\n        switch ( roundingMode ) {\n         case softfloat_round_near_even:\n            if ( ! fracF32UI( uiA ) ) break;\n         case softfloat_round_near_maxMag:\n            if ( exp == 0x7E ) uiZ |= packToF32UI( 0, 0x7F, 0 );\n            break;\n         case softfloat_round_min:\n            if ( uiZ ) uiZ = packToF32UI( 1, 0x7F, 0 );\n            break;\n         case softfloat_round_max:\n            if ( ! uiZ ) uiZ = packToF32UI( 0, 0x7F, 0 );\n            break;\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( 0x96 <= exp ) {\n        if ( (exp == 0xFF) && fracF32UI( uiA ) ) {\n            uiZ = softfloat_propagateNaNF32UI( uiA, 0 );\n            goto uiZ;\n        }\n        return a;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uiZ = uiA;\n    lastBitMask = (uint_fast32_t) 1<<(0x96 - exp);\n    roundBitsMask = lastBitMask - 1;\n    if ( roundingMode == softfloat_round_near_maxMag ) {\n        uiZ += lastBitMask>>1;\n    } else if ( roundingMode == softfloat_round_near_even ) {\n        uiZ += lastBitMask>>1;\n        if ( ! (uiZ & roundBitsMask) ) uiZ &= ~lastBitMask;\n    } else if (\n        roundingMode\n            == (signF32UI( uiZ ) ? softfloat_round_min : softfloat_round_max)\n    ) {\n        uiZ += roundBitsMask;\n    }\n    uiZ &= ~roundBitsMask;\n    if ( exact && (uiZ != uiA) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_sqrt.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat32_t f32_sqrt( float32_t a )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    bool signA;\n    int_fast16_t expA;\n    uint_fast32_t sigA, uiZ;\n    struct exp16_sig32 normExpSig;\n    int_fast16_t expZ;\n    uint_fast32_t sigZ, shiftedSigZ;\n    uint32_t negRem;\n    union ui32_f32 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF32UI( uiA );\n    expA  = expF32UI( uiA );\n    sigA  = fracF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0xFF ) {\n        if ( sigA ) {\n            uiZ = softfloat_propagateNaNF32UI( uiA, 0 );\n            goto uiZ;\n        }\n        if ( ! signA ) return a;\n        goto invalid;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( signA ) {\n        if ( ! (expA | sigA) ) return a;\n        goto invalid;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! sigA ) return a;\n        normExpSig = softfloat_normSubnormalF32Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = ((expA - 0x7F)>>1) + 0x7E;\n    expA &= 1;\n    sigA = (sigA | 0x00800000)<<8;\n    sigZ =\n        ((uint_fast64_t) sigA * softfloat_approxRecipSqrt32_1( expA, sigA ))\n            >>32;\n    if ( expA ) sigZ >>= 1;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sigZ += 2;\n    if ( (sigZ & 0x3F) < 2 ) {\n        shiftedSigZ = sigZ>>2;\n        negRem = shiftedSigZ * shiftedSigZ;\n        sigZ &= ~3;\n        if ( negRem & 0x80000000 ) {\n            sigZ |= 1;\n        } else {\n            if ( negRem ) --sigZ;\n        }\n    }\n    return softfloat_roundPackToF32( 0, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF32UI;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_sub.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat32_t f32_sub( float32_t a, float32_t b )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    union ui32_f32 uB;\n    uint_fast32_t uiB;\n#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1)\n    float32_t (*magsFuncPtr)( uint_fast32_t, uint_fast32_t );\n#endif\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL)\n    if ( signF32UI( uiA ^ uiB ) ) {\n        return softfloat_addMagsF32( uiA, uiB );\n    } else {\n        return softfloat_subMagsF32( uiA, uiB );\n    }\n#else\n    magsFuncPtr =\n        signF32UI( uiA ^ uiB ) ? softfloat_addMagsF32 : softfloat_subMagsF32;\n    return (*magsFuncPtr)( uiA, uiB );\n#endif\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_to_f128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat128_t f32_to_f128( float32_t a )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast32_t frac;\n    struct commonNaN commonNaN;\n    struct uint128 uiZ;\n    struct exp16_sig32 normExpSig;\n    union ui128_f128 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF32UI( uiA );\n    exp  = expF32UI( uiA );\n    frac = fracF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0xFF ) {\n        if ( frac ) {\n            softfloat_f32UIToCommonNaN( uiA, &commonNaN );\n            uiZ = softfloat_commonNaNToF128UI( &commonNaN );\n        } else {\n            uiZ.v64 = packToF128UI64( sign, 0x7FFF, 0 );\n            uiZ.v0  = 0;\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! exp ) {\n        if ( ! frac ) {\n            uiZ.v64 = packToF128UI64( sign, 0, 0 );\n            uiZ.v0  = 0;\n            goto uiZ;\n        }\n        normExpSig = softfloat_normSubnormalF32Sig( frac );\n        exp = normExpSig.exp - 1;\n        frac = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uiZ.v64 = packToF128UI64( sign, exp + 0x3F80, (uint_fast64_t) frac<<25 );\n    uiZ.v0  = 0;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_to_f16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat16_t f32_to_f16( float32_t a )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast32_t frac;\n    struct commonNaN commonNaN;\n    uint_fast16_t uiZ, frac16;\n    union ui16_f16 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF32UI( uiA );\n    exp  = expF32UI( uiA );\n    frac = fracF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0xFF ) {\n        if ( frac ) {\n            softfloat_f32UIToCommonNaN( uiA, &commonNaN );\n            uiZ = softfloat_commonNaNToF16UI( &commonNaN );\n        } else {\n            uiZ = packToF16UI( sign, 0x1F, 0 );\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    frac16 = frac>>9 | ((frac & 0x1FF) != 0);\n    if ( ! (exp | frac16) ) {\n        uiZ = packToF16UI( sign, 0, 0 );\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    return softfloat_roundPackToF16( sign, exp - 0x71, frac16 | 0x4000 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_to_f64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat64_t f32_to_f64( float32_t a )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast32_t frac;\n    struct commonNaN commonNaN;\n    uint_fast64_t uiZ;\n    struct exp16_sig32 normExpSig;\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF32UI( uiA );\n    exp  = expF32UI( uiA );\n    frac = fracF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0xFF ) {\n        if ( frac ) {\n            softfloat_f32UIToCommonNaN( uiA, &commonNaN );\n            uiZ = softfloat_commonNaNToF64UI( &commonNaN );\n        } else {\n            uiZ = packToF64UI( sign, 0x7FF, 0 );\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! exp ) {\n        if ( ! frac ) {\n            uiZ = packToF64UI( sign, 0, 0 );\n            goto uiZ;\n        }\n        normExpSig = softfloat_normSubnormalF32Sig( frac );\n        exp = normExpSig.exp - 1;\n        frac = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uiZ = packToF64UI( sign, exp + 0x380, (uint_fast64_t) frac<<29 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_to_i32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast32_t f32_to_i32( float32_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast32_t sig;\n    uint_fast64_t sig64;\n    int_fast16_t shiftDist;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF32UI( uiA );\n    exp  = expF32UI( uiA );\n    sig  = fracF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)\n    if ( (exp == 0xFF) && sig ) {\n#if (i32_fromNaN == i32_fromPosOverflow)\n        sign = 0;\n#elif (i32_fromNaN == i32_fromNegOverflow)\n        sign = 1;\n#else\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return i32_fromNaN;\n#endif\n    }\n#endif\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp ) sig |= 0x00800000;\n    sig64 = (uint_fast64_t) sig<<32;\n    shiftDist = 0xAA - exp;\n    if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist );\n    return softfloat_roundToI32( sign, sig64, roundingMode, exact );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_to_i32_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast32_t f32_to_i32_r_minMag( float32_t a, bool exact )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    int_fast16_t exp;\n    uint_fast32_t sig;\n    int_fast16_t shiftDist;\n    bool sign;\n    int_fast32_t absZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp = expF32UI( uiA );\n    sig = fracF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0x9E - exp;\n    if ( 32 <= shiftDist ) {\n        if ( exact && (exp | sig) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF32UI( uiA );\n    if ( shiftDist <= 0 ) {\n        if ( uiA == packToF32UI( 1, 0x9E, 0 ) ) return -0x7FFFFFFF - 1;\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0xFF) && sig ? i32_fromNaN\n                : sign ? i32_fromNegOverflow : i32_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig = (sig | 0x00800000)<<8;\n    absZ = sig>>shiftDist;\n    if ( exact && ((uint_fast32_t) absZ<<shiftDist != sig) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return sign ? -absZ : absZ;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_to_i64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast64_t f32_to_i64( float32_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast32_t sig;\n    int_fast16_t shiftDist;\n#ifdef SOFTFLOAT_FAST_INT64\n    uint_fast64_t sig64, extra;\n    struct uint64_extra sig64Extra;\n#else\n    uint32_t extSig[3];\n#endif\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF32UI( uiA );\n    exp  = expF32UI( uiA );\n    sig  = fracF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0xBE - exp;\n    if ( shiftDist < 0 ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0xFF) && sig ? i64_fromNaN\n                : sign ? i64_fromNegOverflow : i64_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp ) sig |= 0x00800000;\n#ifdef SOFTFLOAT_FAST_INT64\n    sig64 = (uint_fast64_t) sig<<40;\n    extra = 0;\n    if ( shiftDist ) {\n        sig64Extra = softfloat_shiftRightJam64Extra( sig64, 0, shiftDist );\n        sig64 = sig64Extra.v;\n        extra = sig64Extra.extra;\n    }\n    return softfloat_roundToI64( sign, sig64, extra, roundingMode, exact );\n#else\n    extSig[indexWord( 3, 2 )] = sig<<8;\n    extSig[indexWord( 3, 1 )] = 0;\n    extSig[indexWord( 3, 0 )] = 0;\n    if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig );\n    return softfloat_roundMToI64( sign, extSig, roundingMode, exact );\n#endif\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_to_i64_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast64_t f32_to_i64_r_minMag( float32_t a, bool exact )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    int_fast16_t exp;\n    uint_fast32_t sig;\n    int_fast16_t shiftDist;\n    bool sign;\n    uint_fast64_t sig64;\n    int_fast64_t absZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp = expF32UI( uiA );\n    sig = fracF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0xBE - exp;\n    if ( 64 <= shiftDist ) {\n        if ( exact && (exp | sig) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF32UI( uiA );\n    if ( shiftDist <= 0 ) {\n        if ( uiA == packToF32UI( 1, 0xBE, 0 ) ) {\n            return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1;\n        }\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0xFF) && sig ? i64_fromNaN\n                : sign ? i64_fromNegOverflow : i64_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig |= 0x00800000;\n    sig64 = (uint_fast64_t) sig<<40;\n    absZ = sig64>>shiftDist;\n    shiftDist = 40 - shiftDist;\n    if ( exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31)) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return sign ? -absZ : absZ;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_to_ui32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast32_t f32_to_ui32( float32_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast32_t sig;\n    uint_fast64_t sig64;\n    int_fast16_t shiftDist;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF32UI( uiA );\n    exp  = expF32UI( uiA );\n    sig  = fracF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)\n    if ( (exp == 0xFF) && sig ) {\n#if (ui32_fromNaN == ui32_fromPosOverflow)\n        sign = 0;\n#elif (ui32_fromNaN == ui32_fromNegOverflow)\n        sign = 1;\n#else\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return ui32_fromNaN;\n#endif\n    }\n#endif\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp ) sig |= 0x00800000;\n    sig64 = (uint_fast64_t) sig<<32;\n    shiftDist = 0xAA - exp;\n    if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist );\n    return softfloat_roundToUI32( sign, sig64, roundingMode, exact );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_to_ui32_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast32_t f32_to_ui32_r_minMag( float32_t a, bool exact )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    int_fast16_t exp;\n    uint_fast32_t sig;\n    int_fast16_t shiftDist;\n    bool sign;\n    uint_fast32_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp = expF32UI( uiA );\n    sig = fracF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0x9E - exp;\n    if ( 32 <= shiftDist ) {\n        if ( exact && (exp | sig) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF32UI( uiA );\n    if ( sign || (shiftDist < 0) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0xFF) && sig ? ui32_fromNaN\n                : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig = (sig | 0x00800000)<<8;\n    z = sig>>shiftDist;\n    if ( exact && (z<<shiftDist != sig) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return z;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_to_ui64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast64_t f32_to_ui64( float32_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast32_t sig;\n    int_fast16_t shiftDist;\n#ifdef SOFTFLOAT_FAST_INT64\n    uint_fast64_t sig64, extra;\n    struct uint64_extra sig64Extra;\n#else\n    uint32_t extSig[3];\n#endif\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF32UI( uiA );\n    exp  = expF32UI( uiA );\n    sig  = fracF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0xBE - exp;\n    if ( shiftDist < 0 ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0xFF) && sig ? ui64_fromNaN\n                : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp ) sig |= 0x00800000;\n#ifdef SOFTFLOAT_FAST_INT64\n    sig64 = (uint_fast64_t) sig<<40;\n    extra = 0;\n    if ( shiftDist ) {\n        sig64Extra = softfloat_shiftRightJam64Extra( sig64, 0, shiftDist );\n        sig64 = sig64Extra.v;\n        extra = sig64Extra.extra;\n    }\n    return softfloat_roundToUI64( sign, sig64, extra, roundingMode, exact );\n#else\n    extSig[indexWord( 3, 2 )] = sig<<8;\n    extSig[indexWord( 3, 1 )] = 0;\n    extSig[indexWord( 3, 0 )] = 0;\n    if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig );\n    return softfloat_roundMToUI64( sign, extSig, roundingMode, exact );\n#endif\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f32_to_ui64_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast64_t f32_to_ui64_r_minMag( float32_t a, bool exact )\n{\n    union ui32_f32 uA;\n    uint_fast32_t uiA;\n    int_fast16_t exp;\n    uint_fast32_t sig;\n    int_fast16_t shiftDist;\n    bool sign;\n    uint_fast64_t sig64, z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp = expF32UI( uiA );\n    sig = fracF32UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0xBE - exp;\n    if ( 64 <= shiftDist ) {\n        if ( exact && (exp | sig) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF32UI( uiA );\n    if ( sign || (shiftDist < 0) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0xFF) && sig ? ui64_fromNaN\n                : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig |= 0x00800000;\n    sig64 = (uint_fast64_t) sig<<40;\n    z = sig64>>shiftDist;\n    shiftDist = 40 - shiftDist;\n    if ( exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31)) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return z;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_add.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat64_t f64_add( float64_t a, float64_t b )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool signA;\n    union ui64_f64 uB;\n    uint_fast64_t uiB;\n    bool signB;\n#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2)\n    float64_t (*magsFuncPtr)( uint_fast64_t, uint_fast64_t, bool );\n#endif\n\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF64UI( uiA );\n    uB.f = b;\n    uiB = uB.ui;\n    signB = signF64UI( uiB );\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\n    if ( signA == signB ) {\n        return softfloat_addMagsF64( uiA, uiB, signA );\n    } else {\n        return softfloat_subMagsF64( uiA, uiB, signA );\n    }\n#else\n    magsFuncPtr =\n        (signA == signB) ? softfloat_addMagsF64 : softfloat_subMagsF64;\n    return (*magsFuncPtr)( uiA, uiB, signA );\n#endif\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_classify.c",
    "content": "\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast16_t f64_classify( float64_t a )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n\n    uA.f = a;\n    uiA = uA.ui;\n\n    uint_fast16_t infOrNaN = expF64UI( uiA ) == 0x7FF;\n    uint_fast16_t subnormalOrZero = expF64UI( uiA ) == 0;\n    bool sign = signF64UI( uiA );\n    bool fracZero = fracF64UI( uiA ) == 0;\n    bool isNaN = isNaNF64UI( uiA );\n    bool isSNaN = softfloat_isSigNaNF64UI( uiA );\n\n    return\n        (  sign && infOrNaN && fracZero )          << 0 |\n        (  sign && !infOrNaN && !subnormalOrZero ) << 1 |\n        (  sign && subnormalOrZero && !fracZero )  << 2 |\n        (  sign && subnormalOrZero && fracZero )   << 3 |\n        ( !sign && infOrNaN && fracZero )          << 7 |\n        ( !sign && !infOrNaN && !subnormalOrZero ) << 6 |\n        ( !sign && subnormalOrZero && !fracZero )  << 5 |\n        ( !sign && subnormalOrZero && fracZero )   << 4 |\n        ( isNaN &&  isSNaN )                       << 8 |\n        ( isNaN && !isSNaN )                       << 9;\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_div.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat64_t f64_div( float64_t a, float64_t b )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool signA;\n    int_fast16_t expA;\n    uint_fast64_t sigA;\n    union ui64_f64 uB;\n    uint_fast64_t uiB;\n    bool signB;\n    int_fast16_t expB;\n    uint_fast64_t sigB;\n    bool signZ;\n    struct exp16_sig64 normExpSig;\n    int_fast16_t expZ;\n    uint32_t recip32, sig32Z, doubleTerm;\n    uint_fast64_t rem;\n    uint32_t q;\n    uint_fast64_t sigZ;\n    uint_fast64_t uiZ;\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF64UI( uiA );\n    expA  = expF64UI( uiA );\n    sigA  = fracF64UI( uiA );\n    uB.f = b;\n    uiB = uB.ui;\n    signB = signF64UI( uiB );\n    expB  = expF64UI( uiB );\n    sigB  = fracF64UI( uiB );\n    signZ = signA ^ signB;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x7FF ) {\n        if ( sigA ) goto propagateNaN;\n        if ( expB == 0x7FF ) {\n            if ( sigB ) goto propagateNaN;\n            goto invalid;\n        }\n        goto infinity;\n    }\n    if ( expB == 0x7FF ) {\n        if ( sigB ) goto propagateNaN;\n        goto zero;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expB ) {\n        if ( ! sigB ) {\n            if ( ! (expA | sigA) ) goto invalid;\n            softfloat_raiseFlags( softfloat_flag_infinite );\n            goto infinity;\n        }\n        normExpSig = softfloat_normSubnormalF64Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    if ( ! expA ) {\n        if ( ! sigA ) goto zero;\n        normExpSig = softfloat_normSubnormalF64Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = expA - expB + 0x3FE;\n    sigA |= UINT64_C( 0x0010000000000000 );\n    sigB |= UINT64_C( 0x0010000000000000 );\n    if ( sigA < sigB ) {\n        --expZ;\n        sigA <<= 11;\n    } else {\n        sigA <<= 10;\n    }\n    sigB <<= 11;\n    recip32 = softfloat_approxRecip32_1( sigB>>32 ) - 2;\n    sig32Z = ((uint32_t) (sigA>>32) * (uint_fast64_t) recip32)>>32;\n    doubleTerm = sig32Z<<1;\n    rem =\n        ((sigA - (uint_fast64_t) doubleTerm * (uint32_t) (sigB>>32))<<28)\n            - (uint_fast64_t) doubleTerm * ((uint32_t) sigB>>4);\n    q = (((uint32_t) (rem>>32) * (uint_fast64_t) recip32)>>32) + 4;\n    sigZ = ((uint_fast64_t) sig32Z<<32) + ((uint_fast64_t) q<<4);\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( (sigZ & 0x1FF) < 4<<4 ) {\n        q &= ~7;\n        sigZ &= ~(uint_fast64_t) 0x7F;\n        doubleTerm = q<<1;\n        rem =\n            ((rem - (uint_fast64_t) doubleTerm * (uint32_t) (sigB>>32))<<28)\n                - (uint_fast64_t) doubleTerm * ((uint32_t) sigB>>4);\n        if ( rem & UINT64_C( 0x8000000000000000 ) ) {\n            sigZ -= 1<<7;\n        } else {\n            if ( rem ) sigZ |= 1;\n        }\n    }\n    return softfloat_roundPackToF64( signZ, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF64UI( uiA, uiB );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF64UI;\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infinity:\n    uiZ = packToF64UI( signZ, 0x7FF, 0 );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zero:\n    uiZ = packToF64UI( signZ, 0, 0 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_eq.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f64_eq( float64_t a, float64_t b )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    union ui64_f64 uB;\n    uint_fast64_t uiB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) {\n        if (\n            softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB )\n        ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n        }\n        return false;\n    }\n    return (uiA == uiB) || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF ));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_eq_signaling.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nbool f64_eq_signaling( float64_t a, float64_t b )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    union ui64_f64 uB;\n    uint_fast64_t uiB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return false;\n    }\n    return (uiA == uiB) || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF ));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_isSignalingNaN.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f64_isSignalingNaN( float64_t a )\n{\n    union ui64_f64 uA;\n\n    uA.f = a;\n    return softfloat_isSigNaNF64UI( uA.ui );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_le.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nbool f64_le( float64_t a, float64_t b )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    union ui64_f64 uB;\n    uint_fast64_t uiB;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return false;\n    }\n    signA = signF64UI( uiA );\n    signB = signF64UI( uiB );\n    return\n        (signA != signB)\n            ? signA || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n            : (uiA == uiB) || (signA ^ (uiA < uiB));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_le_quiet.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f64_le_quiet( float64_t a, float64_t b )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    union ui64_f64 uB;\n    uint_fast64_t uiB;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) {\n        if (\n            softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB )\n        ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n        }\n        return false;\n    }\n    signA = signF64UI( uiA );\n    signB = signF64UI( uiB );\n    return\n        (signA != signB)\n            ? signA || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n            : (uiA == uiB) || (signA ^ (uiA < uiB));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_lt.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nbool f64_lt( float64_t a, float64_t b )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    union ui64_f64 uB;\n    uint_fast64_t uiB;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return false;\n    }\n    signA = signF64UI( uiA );\n    signB = signF64UI( uiB );\n    return\n        (signA != signB)\n            ? signA && ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n            : (uiA != uiB) && (signA ^ (uiA < uiB));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_lt_quiet.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nbool f64_lt_quiet( float64_t a, float64_t b )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    union ui64_f64 uB;\n    uint_fast64_t uiB;\n    bool signA, signB;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) {\n        if (\n            softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB )\n        ) {\n            softfloat_raiseFlags( softfloat_flag_invalid );\n        }\n        return false;\n    }\n    signA = signF64UI( uiA );\n    signB = signF64UI( uiB );\n    return\n        (signA != signB)\n            ? signA && ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n            : (uiA != uiB) && (signA ^ (uiA < uiB));\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_mul.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat64_t f64_mul( float64_t a, float64_t b )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool signA;\n    int_fast16_t expA;\n    uint_fast64_t sigA;\n    union ui64_f64 uB;\n    uint_fast64_t uiB;\n    bool signB;\n    int_fast16_t expB;\n    uint_fast64_t sigB;\n    bool signZ;\n    uint_fast64_t magBits;\n    struct exp16_sig64 normExpSig;\n    int_fast16_t expZ;\n#ifdef SOFTFLOAT_FAST_INT64\n    struct uint128 sig128Z;\n#else\n    uint32_t sig128Z[4];\n#endif\n    uint_fast64_t sigZ, uiZ;\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF64UI( uiA );\n    expA  = expF64UI( uiA );\n    sigA  = fracF64UI( uiA );\n    uB.f = b;\n    uiB = uB.ui;\n    signB = signF64UI( uiB );\n    expB  = expF64UI( uiB );\n    sigB  = fracF64UI( uiB );\n    signZ = signA ^ signB;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x7FF ) {\n        if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN;\n        magBits = expB | sigB;\n        goto infArg;\n    }\n    if ( expB == 0x7FF ) {\n        if ( sigB ) goto propagateNaN;\n        magBits = expA | sigA;\n        goto infArg;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! sigA ) goto zero;\n        normExpSig = softfloat_normSubnormalF64Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    if ( ! expB ) {\n        if ( ! sigB ) goto zero;\n        normExpSig = softfloat_normSubnormalF64Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = expA + expB - 0x3FF;\n    sigA = (sigA | UINT64_C( 0x0010000000000000 ))<<10;\n    sigB = (sigB | UINT64_C( 0x0010000000000000 ))<<11;\n#ifdef SOFTFLOAT_FAST_INT64\n    sig128Z = softfloat_mul64To128( sigA, sigB );\n    sigZ = sig128Z.v64 | (sig128Z.v0 != 0);\n#else\n    softfloat_mul64To128M( sigA, sigB, sig128Z );\n    sigZ =\n        (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 | sig128Z[indexWord( 4, 2 )];\n    if ( sig128Z[indexWord( 4, 1 )] || sig128Z[indexWord( 4, 0 )] ) sigZ |= 1;\n#endif\n    if ( sigZ < UINT64_C( 0x4000000000000000 ) ) {\n        --expZ;\n        sigZ <<= 1;\n    }\n    return softfloat_roundPackToF64( signZ, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF64UI( uiA, uiB );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infArg:\n    if ( ! magBits ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        uiZ = defaultNaNF64UI;\n    } else {\n        uiZ = packToF64UI( signZ, 0x7FF, 0 );\n    }\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zero:\n    uiZ = packToF64UI( signZ, 0, 0 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_mulAdd.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat64_t f64_mulAdd( float64_t a, float64_t b, float64_t c )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    union ui64_f64 uB;\n    uint_fast64_t uiB;\n    union ui64_f64 uC;\n    uint_fast64_t uiC;\n\n    uA.f = a;\n    uiA = uA.ui;\n    uB.f = b;\n    uiB = uB.ui;\n    uC.f = c;\n    uiC = uC.ui;\n    return softfloat_mulAddF64( uiA, uiB, uiC, 0 );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_rem.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat64_t f64_rem( float64_t a, float64_t b )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool signA;\n    int_fast16_t expA;\n    uint_fast64_t sigA;\n    union ui64_f64 uB;\n    uint_fast64_t uiB;\n    int_fast16_t expB;\n    uint_fast64_t sigB;\n    struct exp16_sig64 normExpSig;\n    uint64_t rem;\n    int_fast16_t expDiff;\n    uint32_t q, recip32;\n    uint_fast64_t q64;\n    uint64_t altRem, meanRem;\n    bool signRem;\n    uint_fast64_t uiZ;\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF64UI( uiA );\n    expA  = expF64UI( uiA );\n    sigA  = fracF64UI( uiA );\n    uB.f = b;\n    uiB = uB.ui;\n    expB = expF64UI( uiB );\n    sigB = fracF64UI( uiB );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x7FF ) {\n        if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN;\n        goto invalid;\n    }\n    if ( expB == 0x7FF ) {\n        if ( sigB ) goto propagateNaN;\n        return a;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA < expB - 1 ) return a;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expB ) {\n        if ( ! sigB ) goto invalid;\n        normExpSig = softfloat_normSubnormalF64Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    if ( ! expA ) {\n        if ( ! sigA ) return a;\n        normExpSig = softfloat_normSubnormalF64Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    rem = sigA | UINT64_C( 0x0010000000000000 );\n    sigB |= UINT64_C( 0x0010000000000000 );\n    expDiff = expA - expB;\n    if ( expDiff < 1 ) {\n        if ( expDiff < -1 ) return a;\n        sigB <<= 9;\n        if ( expDiff ) {\n            rem <<= 8;\n            q = 0;\n        } else {\n            rem <<= 9;\n            q = (sigB <= rem);\n            if ( q ) rem -= sigB;\n        }\n    } else {\n        recip32 = softfloat_approxRecip32_1( sigB>>21 );\n        /*--------------------------------------------------------------------\n        | Changing the shift of `rem' here requires also changing the initial\n        | subtraction from `expDiff'.\n        *--------------------------------------------------------------------*/\n        rem <<= 9;\n        expDiff -= 30;\n        /*--------------------------------------------------------------------\n        | The scale of `sigB' affects how many bits are obtained during each\n        | cycle of the loop.  Currently this is 29 bits per loop iteration,\n        | the maximum possible.\n        *--------------------------------------------------------------------*/\n        sigB <<= 9;\n        for (;;) {\n            q64 = (uint32_t) (rem>>32) * (uint_fast64_t) recip32;\n            if ( expDiff < 0 ) break;\n            q = (q64 + 0x80000000)>>32;\n#ifdef SOFTFLOAT_FAST_INT64\n            rem <<= 29;\n#else\n            rem = (uint_fast64_t) (uint32_t) (rem>>3)<<32;\n#endif\n            rem -= q * (uint64_t) sigB;\n            if ( rem & UINT64_C( 0x8000000000000000 ) ) rem += sigB;\n            expDiff -= 29;\n        }\n        /*--------------------------------------------------------------------\n        | (`expDiff' cannot be less than -29 here.)\n        *--------------------------------------------------------------------*/\n        q = (uint32_t) (q64>>32)>>(~expDiff & 31);\n        rem = (rem<<(expDiff + 30)) - q * (uint64_t) sigB;\n        if ( rem & UINT64_C( 0x8000000000000000 ) ) {\n            altRem = rem + sigB;\n            goto selectRem;\n        }\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    do {\n        altRem = rem;\n        ++q;\n        rem -= sigB;\n    } while ( ! (rem & UINT64_C( 0x8000000000000000 )) );\n selectRem:\n    meanRem = rem + altRem;\n    if (\n        (meanRem & UINT64_C( 0x8000000000000000 )) || (! meanRem && (q & 1))\n    ) {\n        rem = altRem;\n    }\n    signRem = signA;\n    if ( rem & UINT64_C( 0x8000000000000000 ) ) {\n        signRem = ! signRem;\n        rem = -rem;\n    }\n    return softfloat_normRoundPackToF64( signRem, expB, rem );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF64UI( uiA, uiB );\n    goto uiZ;\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF64UI;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_roundToInt.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat64_t f64_roundToInt( float64_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    int_fast16_t exp;\n    uint_fast64_t uiZ, lastBitMask, roundBitsMask;\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp = expF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp <= 0x3FE ) {\n        if ( ! (uiA & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) return a;\n        if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact;\n        uiZ = uiA & packToF64UI( 1, 0, 0 );\n        switch ( roundingMode ) {\n         case softfloat_round_near_even:\n            if ( ! fracF64UI( uiA ) ) break;\n         case softfloat_round_near_maxMag:\n            if ( exp == 0x3FE ) uiZ |= packToF64UI( 0, 0x3FF, 0 );\n            break;\n         case softfloat_round_min:\n            if ( uiZ ) uiZ = packToF64UI( 1, 0x3FF, 0 );\n            break;\n         case softfloat_round_max:\n            if ( ! uiZ ) uiZ = packToF64UI( 0, 0x3FF, 0 );\n            break;\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( 0x433 <= exp ) {\n        if ( (exp == 0x7FF) && fracF64UI( uiA ) ) {\n            uiZ = softfloat_propagateNaNF64UI( uiA, 0 );\n            goto uiZ;\n        }\n        return a;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uiZ = uiA;\n    lastBitMask = (uint_fast64_t) 1<<(0x433 - exp);\n    roundBitsMask = lastBitMask - 1;\n    if ( roundingMode == softfloat_round_near_maxMag ) {\n        uiZ += lastBitMask>>1;\n    } else if ( roundingMode == softfloat_round_near_even ) {\n        uiZ += lastBitMask>>1;\n        if ( ! (uiZ & roundBitsMask) ) uiZ &= ~lastBitMask;\n    } else if (\n        roundingMode\n            == (signF64UI( uiZ ) ? softfloat_round_min : softfloat_round_max)\n    ) {\n        uiZ += roundBitsMask;\n    }\n    uiZ &= ~roundBitsMask;\n    if ( exact && (uiZ != uiA) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_sqrt.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat64_t f64_sqrt( float64_t a )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool signA;\n    int_fast16_t expA;\n    uint_fast64_t sigA, uiZ;\n    struct exp16_sig64 normExpSig;\n    int_fast16_t expZ;\n    uint32_t sig32A, recipSqrt32, sig32Z;\n    uint_fast64_t rem;\n    uint32_t q;\n    uint_fast64_t sigZ, shiftedSigZ;\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF64UI( uiA );\n    expA  = expF64UI( uiA );\n    sigA  = fracF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x7FF ) {\n        if ( sigA ) {\n            uiZ = softfloat_propagateNaNF64UI( uiA, 0 );\n            goto uiZ;\n        }\n        if ( ! signA ) return a;\n        goto invalid;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( signA ) {\n        if ( ! (expA | sigA) ) return a;\n        goto invalid;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! sigA ) return a;\n        normExpSig = softfloat_normSubnormalF64Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    | (`sig32Z' is guaranteed to be a lower bound on the square root of\n    | `sig32A', which makes `sig32Z' also a lower bound on the square root of\n    | `sigA'.)\n    *------------------------------------------------------------------------*/\n    expZ = ((expA - 0x3FF)>>1) + 0x3FE;\n    expA &= 1;\n    sigA |= UINT64_C( 0x0010000000000000 );\n    sig32A = sigA>>21;\n    recipSqrt32 = softfloat_approxRecipSqrt32_1( expA, sig32A );\n    sig32Z = ((uint_fast64_t) sig32A * recipSqrt32)>>32;\n    if ( expA ) {\n        sigA <<= 8;\n        sig32Z >>= 1;\n    } else {\n        sigA <<= 9;\n    }\n    rem = sigA - (uint_fast64_t) sig32Z * sig32Z;\n    q = ((uint32_t) (rem>>2) * (uint_fast64_t) recipSqrt32)>>32;\n    sigZ = ((uint_fast64_t) sig32Z<<32 | 1<<5) + ((uint_fast64_t) q<<3);\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( (sigZ & 0x1FF) < 0x22 ) {\n        sigZ &= ~(uint_fast64_t) 0x3F;\n        shiftedSigZ = sigZ>>6;\n        rem = (sigA<<52) - shiftedSigZ * shiftedSigZ;\n        if ( rem & UINT64_C( 0x8000000000000000 ) ) {\n            --sigZ;\n        } else {\n            if ( rem ) sigZ |= 1;\n        }\n    }\n    return softfloat_roundPackToF64( 0, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF64UI;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_sub.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat64_t f64_sub( float64_t a, float64_t b )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool signA;\n    union ui64_f64 uB;\n    uint_fast64_t uiB;\n    bool signB;\n#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2)\n    float64_t (*magsFuncPtr)( uint_fast64_t, uint_fast64_t, bool );\n#endif\n\n    uA.f = a;\n    uiA = uA.ui;\n    signA = signF64UI( uiA );\n    uB.f = b;\n    uiB = uB.ui;\n    signB = signF64UI( uiB );\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\n    if ( signA == signB ) {\n        return softfloat_subMagsF64( uiA, uiB, signA );\n    } else {\n        return softfloat_addMagsF64( uiA, uiB, signA );\n    }\n#else\n    magsFuncPtr =\n        (signA == signB) ? softfloat_subMagsF64 : softfloat_addMagsF64;\n    return (*magsFuncPtr)( uiA, uiB, signA );\n#endif\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_to_f128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat128_t f64_to_f128( float64_t a )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast64_t frac;\n    struct commonNaN commonNaN;\n    struct uint128 uiZ;\n    struct exp16_sig64 normExpSig;\n    struct uint128 frac128;\n    union ui128_f128 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF64UI( uiA );\n    exp  = expF64UI( uiA );\n    frac = fracF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x7FF ) {\n        if ( frac ) {\n            softfloat_f64UIToCommonNaN( uiA, &commonNaN );\n            uiZ = softfloat_commonNaNToF128UI( &commonNaN );\n        } else {\n            uiZ.v64 = packToF128UI64( sign, 0x7FFF, 0 );\n            uiZ.v0  = 0;\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! exp ) {\n        if ( ! frac ) {\n            uiZ.v64 = packToF128UI64( sign, 0, 0 );\n            uiZ.v0  = 0;\n            goto uiZ;\n        }\n        normExpSig = softfloat_normSubnormalF64Sig( frac );\n        exp = normExpSig.exp - 1;\n        frac = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    frac128 = softfloat_shortShiftLeft128( 0, frac, 60 );\n    uiZ.v64 = packToF128UI64( sign, exp + 0x3C00, frac128.v64 );\n    uiZ.v0  = frac128.v0;\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_to_f16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat16_t f64_to_f16( float64_t a )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast64_t frac;\n    struct commonNaN commonNaN;\n    uint_fast16_t uiZ, frac16;\n    union ui16_f16 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF64UI( uiA );\n    exp  = expF64UI( uiA );\n    frac = fracF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x7FF ) {\n        if ( frac ) {\n            softfloat_f64UIToCommonNaN( uiA, &commonNaN );\n            uiZ = softfloat_commonNaNToF16UI( &commonNaN );\n        } else {\n            uiZ = packToF16UI( sign, 0x1F, 0 );\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    frac16 = softfloat_shortShiftRightJam64( frac, 38 );\n    if ( ! (exp | frac16) ) {\n        uiZ = packToF16UI( sign, 0, 0 );\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    return softfloat_roundPackToF16( sign, exp - 0x3F1, frac16 | 0x4000 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_to_f32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat32_t f64_to_f32( float64_t a )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast64_t frac;\n    struct commonNaN commonNaN;\n    uint_fast32_t uiZ, frac32;\n    union ui32_f32 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF64UI( uiA );\n    exp  = expF64UI( uiA );\n    frac = fracF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp == 0x7FF ) {\n        if ( frac ) {\n            softfloat_f64UIToCommonNaN( uiA, &commonNaN );\n            uiZ = softfloat_commonNaNToF32UI( &commonNaN );\n        } else {\n            uiZ = packToF32UI( sign, 0xFF, 0 );\n        }\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    frac32 = softfloat_shortShiftRightJam64( frac, 22 );\n    if ( ! (exp | frac32) ) {\n        uiZ = packToF32UI( sign, 0, 0 );\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    return softfloat_roundPackToF32( sign, exp - 0x381, frac32 | 0x40000000 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_to_i32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast32_t f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast64_t sig;\n    int_fast16_t shiftDist;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF64UI( uiA );\n    exp  = expF64UI( uiA );\n    sig  = fracF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)\n    if ( (exp == 0x7FF) && sig ) {\n#if (i32_fromNaN == i32_fromPosOverflow)\n        sign = 0;\n#elif (i32_fromNaN == i32_fromNegOverflow)\n        sign = 1;\n#else\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return i32_fromNaN;\n#endif\n    }\n#endif\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp ) sig |= UINT64_C( 0x0010000000000000 );\n    shiftDist = 0x427 - exp;\n    if ( 0 < shiftDist ) sig = softfloat_shiftRightJam64( sig, shiftDist );\n    return softfloat_roundToI32( sign, sig, roundingMode, exact );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_to_i32_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast32_t f64_to_i32_r_minMag( float64_t a, bool exact )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    int_fast16_t exp;\n    uint_fast64_t sig;\n    int_fast16_t shiftDist;\n    bool sign;\n    int_fast32_t absZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp = expF64UI( uiA );\n    sig = fracF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0x433 - exp;\n    if ( 53 <= shiftDist ) {\n        if ( exact && (exp | sig) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF64UI( uiA );\n    if ( shiftDist < 22 ) {\n        if (\n            sign && (exp == 0x41E) && (sig < UINT64_C( 0x0000000000200000 ))\n        ) {\n            if ( exact && sig ) {\n                softfloat_exceptionFlags |= softfloat_flag_inexact;\n            }\n            return -0x7FFFFFFF - 1;\n        }\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0x7FF) && sig ? i32_fromNaN\n                : sign ? i32_fromNegOverflow : i32_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig |= UINT64_C( 0x0010000000000000 );\n    absZ = sig>>shiftDist;\n    if ( exact && ((uint_fast64_t) (uint_fast32_t) absZ<<shiftDist != sig) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return sign ? -absZ : absZ;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_to_i64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast64_t f64_to_i64( float64_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast64_t sig;\n    int_fast16_t shiftDist;\n#ifdef SOFTFLOAT_FAST_INT64\n    struct uint64_extra sigExtra;\n#else\n    uint32_t extSig[3];\n#endif\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF64UI( uiA );\n    exp  = expF64UI( uiA );\n    sig  = fracF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp ) sig |= UINT64_C( 0x0010000000000000 );\n    shiftDist = 0x433 - exp;\n#ifdef SOFTFLOAT_FAST_INT64\n    if ( shiftDist <= 0 ) {\n        if ( shiftDist < -11 ) goto invalid;\n        sigExtra.v = sig<<-shiftDist;\n        sigExtra.extra = 0;\n    } else {\n        sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist );\n    }\n    return\n        softfloat_roundToI64(\n            sign, sigExtra.v, sigExtra.extra, roundingMode, exact );\n#else\n    extSig[indexWord( 3, 0 )] = 0;\n    if ( shiftDist <= 0 ) {\n        if ( shiftDist < -11 ) goto invalid;\n        sig <<= -shiftDist;\n        extSig[indexWord( 3, 2 )] = sig>>32;\n        extSig[indexWord( 3, 1 )] = sig;\n    } else {\n        extSig[indexWord( 3, 2 )] = sig>>32;\n        extSig[indexWord( 3, 1 )] = sig;\n        softfloat_shiftRightJam96M( extSig, shiftDist, extSig );\n    }\n    return softfloat_roundMToI64( sign, extSig, roundingMode, exact );\n#endif\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return\n        (exp == 0x7FF) && fracF64UI( uiA ) ? i64_fromNaN\n            : sign ? i64_fromNegOverflow : i64_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_to_i64_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast64_t f64_to_i64_r_minMag( float64_t a, bool exact )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast64_t sig;\n    int_fast16_t shiftDist;\n    int_fast64_t absZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF64UI( uiA );\n    exp  = expF64UI( uiA );\n    sig  = fracF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0x433 - exp;\n    if ( shiftDist <= 0 ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( shiftDist < -10 ) {\n            if ( uiA == packToF64UI( 1, 0x43E, 0 ) ) {\n                return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1;\n            }\n            softfloat_raiseFlags( softfloat_flag_invalid );\n            return\n                (exp == 0x7FF) && sig ? i64_fromNaN\n                    : sign ? i64_fromNegOverflow : i64_fromPosOverflow;\n        }\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        sig |= UINT64_C( 0x0010000000000000 );\n        absZ = sig<<-shiftDist;\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( 53 <= shiftDist ) {\n            if ( exact && (exp | sig) ) {\n                softfloat_exceptionFlags |= softfloat_flag_inexact;\n            }\n            return 0;\n        }\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        sig |= UINT64_C( 0x0010000000000000 );\n        absZ = sig>>shiftDist;\n        if ( exact && (absZ<<shiftDist != sig) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n    }\n    return sign ? -absZ : absZ;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_to_ui32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast32_t f64_to_ui32( float64_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast64_t sig;\n    int_fast16_t shiftDist;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF64UI( uiA );\n    exp  = expF64UI( uiA );\n    sig  = fracF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)\n    if ( (exp == 0x7FF) && sig ) {\n#if (ui32_fromNaN == ui32_fromPosOverflow)\n        sign = 0;\n#elif (ui32_fromNaN == ui32_fromNegOverflow)\n        sign = 1;\n#else\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return ui32_fromNaN;\n#endif\n    }\n#endif\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp ) sig |= UINT64_C( 0x0010000000000000 );\n    shiftDist = 0x427 - exp;\n    if ( 0 < shiftDist ) sig = softfloat_shiftRightJam64( sig, shiftDist );\n    return softfloat_roundToUI32( sign, sig, roundingMode, exact );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_to_ui32_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast32_t f64_to_ui32_r_minMag( float64_t a, bool exact )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    int_fast16_t exp;\n    uint_fast64_t sig;\n    int_fast16_t shiftDist;\n    bool sign;\n    uint_fast32_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp = expF64UI( uiA );\n    sig = fracF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0x433 - exp;\n    if ( 53 <= shiftDist ) {\n        if ( exact && (exp | sig) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF64UI( uiA );\n    if ( sign || (shiftDist < 21) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        return\n            (exp == 0x7FF) && sig ? ui32_fromNaN\n                : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig |= UINT64_C( 0x0010000000000000 );\n    z = sig>>shiftDist;\n    if ( exact && ((uint_fast64_t) z<<shiftDist != sig) ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return z;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_to_ui64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast64_t f64_to_ui64( float64_t a, uint_fast8_t roundingMode, bool exact )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    bool sign;\n    int_fast16_t exp;\n    uint_fast64_t sig;\n    int_fast16_t shiftDist;\n#ifdef SOFTFLOAT_FAST_INT64\n    struct uint64_extra sigExtra;\n#else\n    uint32_t extSig[3];\n#endif\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    sign = signF64UI( uiA );\n    exp  = expF64UI( uiA );\n    sig  = fracF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( exp ) sig |= UINT64_C( 0x0010000000000000 );\n    shiftDist = 0x433 - exp;\n#ifdef SOFTFLOAT_FAST_INT64\n    if ( shiftDist <= 0 ) {\n        if ( shiftDist < -11 ) goto invalid;\n        sigExtra.v = sig<<-shiftDist;\n        sigExtra.extra = 0;\n    } else {\n        sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist );\n    }\n    return\n        softfloat_roundToUI64(\n            sign, sigExtra.v, sigExtra.extra, roundingMode, exact );\n#else\n    extSig[indexWord( 3, 0 )] = 0;\n    if ( shiftDist <= 0 ) {\n        if ( shiftDist < -11 ) goto invalid;\n        sig <<= -shiftDist;\n        extSig[indexWord( 3, 2 )] = sig>>32;\n        extSig[indexWord( 3, 1 )] = sig;\n    } else {\n        extSig[indexWord( 3, 2 )] = sig>>32;\n        extSig[indexWord( 3, 1 )] = sig;\n        softfloat_shiftRightJam96M( extSig, shiftDist, extSig );\n    }\n    return softfloat_roundMToUI64( sign, extSig, roundingMode, exact );\n#endif\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return\n        (exp == 0x7FF) && fracF64UI( uiA ) ? ui64_fromNaN\n            : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/f64_to_ui64_r_minMag.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast64_t f64_to_ui64_r_minMag( float64_t a, bool exact )\n{\n    union ui64_f64 uA;\n    uint_fast64_t uiA;\n    int_fast16_t exp;\n    uint_fast64_t sig;\n    int_fast16_t shiftDist;\n    bool sign;\n    uint_fast64_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    uA.f = a;\n    uiA = uA.ui;\n    exp = expF64UI( uiA );\n    sig = fracF64UI( uiA );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 0x433 - exp;\n    if ( 53 <= shiftDist ) {\n        if ( exact && (exp | sig) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n        return 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sign = signF64UI( uiA );\n    if ( sign ) goto invalid;\n    if ( shiftDist <= 0 ) {\n        if ( shiftDist < -11 ) goto invalid;\n        z = (sig | UINT64_C( 0x0010000000000000 ))<<-shiftDist;\n    } else {\n        sig |= UINT64_C( 0x0010000000000000 );\n        z = sig>>shiftDist;\n        if ( exact && (uint64_t) (sig<<(-shiftDist & 63)) ) {\n            softfloat_exceptionFlags |= softfloat_flag_inexact;\n        }\n    }\n    return z;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return\n        (exp == 0x7FF) && sig ? ui64_fromNaN\n            : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/i32_to_f128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat128_t i32_to_f128( int32_t a )\n{\n    uint_fast64_t uiZ64;\n    bool sign;\n    uint_fast32_t absA;\n    int_fast8_t shiftDist;\n    union ui128_f128 uZ;\n\n    uiZ64 = 0;\n    if ( a ) {\n        sign = (a < 0);\n        absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a;\n        shiftDist = softfloat_countLeadingZeros32( absA ) + 17;\n        uiZ64 =\n            packToF128UI64(\n                sign, 0x402E - shiftDist, (uint_fast64_t) absA<<shiftDist );\n    }\n    uZ.ui.v64 = uiZ64;\n    uZ.ui.v0  = 0;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/i32_to_f16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat16_t i32_to_f16( int32_t a )\n{\n    bool sign;\n    uint_fast32_t absA;\n    int_fast8_t shiftDist;\n    union ui16_f16 u;\n    uint_fast16_t sig;\n\n    sign = (a < 0);\n    absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a;\n    shiftDist = softfloat_countLeadingZeros32( absA ) - 21;\n    if ( 0 <= shiftDist ) {\n        u.ui =\n            a ? packToF16UI(\n                    sign, 0x18 - shiftDist, (uint_fast16_t) absA<<shiftDist )\n                : 0;\n        return u.f;\n    } else {\n        shiftDist += 4;\n        sig =\n            (shiftDist < 0)\n                ? absA>>(-shiftDist)\n                      | ((uint32_t) (absA<<(shiftDist & 31)) != 0)\n                : (uint_fast16_t) absA<<shiftDist;\n        return softfloat_roundPackToF16( sign, 0x1C - shiftDist, sig );\n    }\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/i32_to_f32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat32_t i32_to_f32( int32_t a )\n{\n    bool sign;\n    union ui32_f32 uZ;\n    uint_fast32_t absA;\n\n    sign = (a < 0);\n    if ( ! (a & 0x7FFFFFFF) ) {\n        uZ.ui = sign ? packToF32UI( 1, 0x9E, 0 ) : 0;\n        return uZ.f;\n    }\n    absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a;\n    return softfloat_normRoundPackToF32( sign, 0x9C, absA );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/i32_to_f64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat64_t i32_to_f64( int32_t a )\n{\n    uint_fast64_t uiZ;\n    bool sign;\n    uint_fast32_t absA;\n    int_fast8_t shiftDist;\n    union ui64_f64 uZ;\n\n    if ( ! a ) {\n        uiZ = 0;\n    } else {\n        sign = (a < 0);\n        absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a;\n        shiftDist = softfloat_countLeadingZeros32( absA ) + 21;\n        uiZ =\n            packToF64UI(\n                sign, 0x432 - shiftDist, (uint_fast64_t) absA<<shiftDist );\n    }\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/i64_to_f128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat128_t i64_to_f128( int64_t a )\n{\n    uint_fast64_t uiZ64, uiZ0;\n    bool sign;\n    uint_fast64_t absA;\n    int_fast8_t shiftDist;\n    struct uint128 zSig;\n    union ui128_f128 uZ;\n\n    if ( ! a ) {\n        uiZ64 = 0;\n        uiZ0  = 0;\n    } else {\n        sign = (a < 0);\n        absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a;\n        shiftDist = softfloat_countLeadingZeros64( absA ) + 49;\n        if ( 64 <= shiftDist ) {\n            zSig.v64 = absA<<(shiftDist - 64);\n            zSig.v0  = 0;\n        } else {\n            zSig = softfloat_shortShiftLeft128( 0, absA, shiftDist );\n        }\n        uiZ64 = packToF128UI64( sign, 0x406E - shiftDist, zSig.v64 );\n        uiZ0  = zSig.v0;\n    }\n    uZ.ui.v64 = uiZ64;\n    uZ.ui.v0  = uiZ0;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/i64_to_f16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat16_t i64_to_f16( int64_t a )\n{\n    bool sign;\n    uint_fast64_t absA;\n    int_fast8_t shiftDist;\n    union ui16_f16 u;\n    uint_fast16_t sig;\n\n    sign = (a < 0);\n    absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a;\n    shiftDist = softfloat_countLeadingZeros64( absA ) - 53;\n    if ( 0 <= shiftDist ) {\n        u.ui =\n            a ? packToF16UI(\n                    sign, 0x18 - shiftDist, (uint_fast16_t) absA<<shiftDist )\n                : 0;\n        return u.f;\n    } else {\n        shiftDist += 4;\n        sig =\n            (shiftDist < 0)\n                ? softfloat_shortShiftRightJam64( absA, -shiftDist )\n                : (uint_fast16_t) absA<<shiftDist;\n        return softfloat_roundPackToF16( sign, 0x1C - shiftDist, sig );\n    }\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/i64_to_f32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat32_t i64_to_f32( int64_t a )\n{\n    bool sign;\n    uint_fast64_t absA;\n    int_fast8_t shiftDist;\n    union ui32_f32 u;\n    uint_fast32_t sig;\n\n    sign = (a < 0);\n    absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a;\n    shiftDist = softfloat_countLeadingZeros64( absA ) - 40;\n    if ( 0 <= shiftDist ) {\n        u.ui =\n            a ? packToF32UI(\n                    sign, 0x95 - shiftDist, (uint_fast32_t) absA<<shiftDist )\n                : 0;\n        return u.f;\n    } else {\n        shiftDist += 7;\n        sig =\n            (shiftDist < 0)\n                ? softfloat_shortShiftRightJam64( absA, -shiftDist )\n                : (uint_fast32_t) absA<<shiftDist;\n        return softfloat_roundPackToF32( sign, 0x9C - shiftDist, sig );\n    }\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/i64_to_f64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat64_t i64_to_f64( int64_t a )\n{\n    bool sign;\n    union ui64_f64 uZ;\n    uint_fast64_t absA;\n\n    sign = (a < 0);\n    if ( ! (a & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) {\n        uZ.ui = sign ? packToF64UI( 1, 0x43E, 0 ) : 0;\n        return uZ.f;\n    }\n    absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a;\n    return softfloat_normRoundPackToF64( sign, 0x43C, absA );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/include/softfloat/internals.h",
    "content": "\n/*============================================================================\n\nThis C header file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#ifndef internals_h\n#define internals_h 1\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"primitives.h\"\n#include \"softfloat_types.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nunion ui16_f16 { uint16_t ui; float16_t f; };\nunion ui32_f32 { uint32_t ui; float32_t f; };\nunion ui64_f64 { uint64_t ui; float64_t f; };\n\n#ifdef SOFTFLOAT_FAST_INT64\nunion extF80M_extF80 { struct extFloat80M fM; extFloat80_t f; };\nunion ui128_f128 { struct uint128 ui; float128_t f; };\n#endif\n\nenum {\n    softfloat_mulAdd_subC    = 1,\n    softfloat_mulAdd_subProd = 2\n};\n\n/*----------------------------------------------------------------------------\n*----------------------------------------------------------------------------*/\nuint_fast32_t softfloat_roundToUI32( bool, uint_fast64_t, uint_fast8_t, bool );\n\n#ifdef SOFTFLOAT_FAST_INT64\nuint_fast64_t\n softfloat_roundToUI64(\n     bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool );\n#else\nuint_fast64_t softfloat_roundMToUI64( bool, uint32_t *, uint_fast8_t, bool );\n#endif\n\nint_fast32_t softfloat_roundToI32( bool, uint_fast64_t, uint_fast8_t, bool );\n\n#ifdef SOFTFLOAT_FAST_INT64\nint_fast64_t\n softfloat_roundToI64(\n     bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool );\n#else\nint_fast64_t softfloat_roundMToI64( bool, uint32_t *, uint_fast8_t, bool );\n#endif\n\n/*----------------------------------------------------------------------------\n*----------------------------------------------------------------------------*/\n#define signF16UI( a ) ((bool) ((uint16_t) (a)>>15))\n#define expF16UI( a ) ((int_fast8_t) ((a)>>10) & 0x1F)\n#define fracF16UI( a ) ((a) & 0x03FF)\n#define packToF16UI( sign, exp, sig ) (((uint16_t) (sign)<<15) + ((uint16_t) (exp)<<10) + (sig))\n\n#define isNaNF16UI( a ) (((~(a) & 0x7C00) == 0) && ((a) & 0x03FF))\n\nstruct exp8_sig16 { int_fast8_t exp; uint_fast16_t sig; };\nstruct exp8_sig16 softfloat_normSubnormalF16Sig( uint_fast16_t );\n\nfloat16_t softfloat_roundPackToF16( bool, int_fast16_t, uint_fast16_t );\nfloat16_t softfloat_normRoundPackToF16( bool, int_fast16_t, uint_fast16_t );\n\nfloat16_t softfloat_addMagsF16( uint_fast16_t, uint_fast16_t );\nfloat16_t softfloat_subMagsF16( uint_fast16_t, uint_fast16_t );\nfloat16_t\n softfloat_mulAddF16(\n     uint_fast16_t, uint_fast16_t, uint_fast16_t, uint_fast8_t );\n\n/*----------------------------------------------------------------------------\n*----------------------------------------------------------------------------*/\n#define signF32UI( a ) ((bool) ((uint32_t) (a)>>31))\n#define expF32UI( a ) ((int_fast16_t) ((a)>>23) & 0xFF)\n#define fracF32UI( a ) ((a) & 0x007FFFFF)\n#define packToF32UI( sign, exp, sig ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<23) + (sig))\n\n#define isNaNF32UI( a ) (((~(a) & 0x7F800000) == 0) && ((a) & 0x007FFFFF))\n\nstruct exp16_sig32 { int_fast16_t exp; uint_fast32_t sig; };\nstruct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t );\n\nfloat32_t softfloat_roundPackToF32( bool, int_fast16_t, uint_fast32_t );\nfloat32_t softfloat_normRoundPackToF32( bool, int_fast16_t, uint_fast32_t );\n\nfloat32_t softfloat_addMagsF32( uint_fast32_t, uint_fast32_t );\nfloat32_t softfloat_subMagsF32( uint_fast32_t, uint_fast32_t );\nfloat32_t\n softfloat_mulAddF32(\n     uint_fast32_t, uint_fast32_t, uint_fast32_t, uint_fast8_t );\n\n/*----------------------------------------------------------------------------\n*----------------------------------------------------------------------------*/\n#define signF64UI( a ) ((bool) ((uint64_t) (a)>>63))\n#define expF64UI( a ) ((int_fast16_t) ((a)>>52) & 0x7FF)\n#define fracF64UI( a ) ((a) & UINT64_C( 0x000FFFFFFFFFFFFF ))\n#define packToF64UI( sign, exp, sig ) ((uint64_t) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<52) + (sig)))\n\n#define isNaNF64UI( a ) (((~(a) & UINT64_C( 0x7FF0000000000000 )) == 0) && ((a) & UINT64_C( 0x000FFFFFFFFFFFFF )))\n\nstruct exp16_sig64 { int_fast16_t exp; uint_fast64_t sig; };\nstruct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t );\n\nfloat64_t softfloat_roundPackToF64( bool, int_fast16_t, uint_fast64_t );\nfloat64_t softfloat_normRoundPackToF64( bool, int_fast16_t, uint_fast64_t );\n\nfloat64_t softfloat_addMagsF64( uint_fast64_t, uint_fast64_t, bool );\nfloat64_t softfloat_subMagsF64( uint_fast64_t, uint_fast64_t, bool );\nfloat64_t\n softfloat_mulAddF64(\n     uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t );\n\n/*----------------------------------------------------------------------------\n*----------------------------------------------------------------------------*/\n#define signExtF80UI64( a64 ) ((bool) ((uint16_t) (a64)>>15))\n#define expExtF80UI64( a64 ) ((a64) & 0x7FFF)\n#define packToExtF80UI64( sign, exp ) ((uint_fast16_t) (sign)<<15 | (exp))\n\n#define isNaNExtF80UI( a64, a0 ) ((((a64) & 0x7FFF) == 0x7FFF) && ((a0) & UINT64_C( 0x7FFFFFFFFFFFFFFF )))\n\n#ifdef SOFTFLOAT_FAST_INT64\n\n/*----------------------------------------------------------------------------\n*----------------------------------------------------------------------------*/\n\nstruct exp32_sig64 { int_fast32_t exp; uint64_t sig; };\nstruct exp32_sig64 softfloat_normSubnormalExtF80Sig( uint_fast64_t );\n\nextFloat80_t\n softfloat_roundPackToExtF80(\n     bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t );\nextFloat80_t\n softfloat_normRoundPackToExtF80(\n     bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t );\n\nextFloat80_t\n softfloat_addMagsExtF80(\n     uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool );\nextFloat80_t\n softfloat_subMagsExtF80(\n     uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool );\n\n/*----------------------------------------------------------------------------\n*----------------------------------------------------------------------------*/\n#define signF128UI64( a64 ) ((bool) ((uint64_t) (a64)>>63))\n#define expF128UI64( a64 ) ((int_fast32_t) ((a64)>>48) & 0x7FFF)\n#define fracF128UI64( a64 ) ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF ))\n#define packToF128UI64( sign, exp, sig64 ) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<48) + (sig64))\n\n#define isNaNF128UI( a64, a0 ) (((~(a64) & UINT64_C( 0x7FFF000000000000 )) == 0) && (a0 || ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF ))))\n\nstruct exp32_sig128 { int_fast32_t exp; struct uint128 sig; };\nstruct exp32_sig128\n softfloat_normSubnormalF128Sig( uint_fast64_t, uint_fast64_t );\n\nfloat128_t\n softfloat_roundPackToF128(\n     bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast64_t );\nfloat128_t\n softfloat_normRoundPackToF128(\n     bool, int_fast32_t, uint_fast64_t, uint_fast64_t );\n\nfloat128_t\n softfloat_addMagsF128(\n     uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool );\nfloat128_t\n softfloat_subMagsF128(\n     uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool );\nfloat128_t\n softfloat_mulAddF128(\n     uint_fast64_t,\n     uint_fast64_t,\n     uint_fast64_t,\n     uint_fast64_t,\n     uint_fast64_t,\n     uint_fast64_t,\n     uint_fast8_t\n );\n\n#else\n\n/*----------------------------------------------------------------------------\n*----------------------------------------------------------------------------*/\n\nbool\n softfloat_tryPropagateNaNExtF80M(\n     const struct extFloat80M *,\n     const struct extFloat80M *,\n     struct extFloat80M *\n );\nvoid softfloat_invalidExtF80M( struct extFloat80M * );\n\nint softfloat_normExtF80SigM( uint64_t * );\n\nvoid\n softfloat_roundPackMToExtF80M(\n     bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * );\nvoid\n softfloat_normRoundPackMToExtF80M(\n     bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * );\n\nvoid\n softfloat_addExtF80M(\n     const struct extFloat80M *,\n     const struct extFloat80M *,\n     struct extFloat80M *,\n     bool\n );\n\nint\n softfloat_compareNonnormExtF80M(\n     const struct extFloat80M *, const struct extFloat80M * );\n\n/*----------------------------------------------------------------------------\n*----------------------------------------------------------------------------*/\n#define signF128UI96( a96 ) ((bool) ((uint32_t) (a96)>>31))\n#define expF128UI96( a96 ) ((int32_t) ((a96)>>16) & 0x7FFF)\n#define fracF128UI96( a96 ) ((a96) & 0x0000FFFF)\n#define packToF128UI96( sign, exp, sig96 ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<16) + (sig96))\n\nbool softfloat_isNaNF128M( const uint32_t * );\n\nbool\n softfloat_tryPropagateNaNF128M(\n     const uint32_t *, const uint32_t *, uint32_t * );\nvoid softfloat_invalidF128M( uint32_t * );\n\nint softfloat_shiftNormSigF128M( const uint32_t *, uint_fast8_t, uint32_t * );\n\nvoid softfloat_roundPackMToF128M( bool, int32_t, uint32_t *, uint32_t * );\nvoid softfloat_normRoundPackMToF128M( bool, int32_t, uint32_t *, uint32_t * );\n\nvoid\n softfloat_addF128M( const uint32_t *, const uint32_t *, uint32_t *, bool );\nvoid\n softfloat_mulAddF128M(\n     const uint32_t *,\n     const uint32_t *,\n     const uint32_t *,\n     uint32_t *,\n     uint_fast8_t\n );\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/include/softfloat/platform.h",
    "content": "\n/*============================================================================\n\nThis C header file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3a, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n/*----------------------------------------------------------------------------\n*----------------------------------------------------------------------------*/\n#define LITTLEENDIAN 1\n\n//#define INLINE_LEVEL 5\n//#define SOFTFLOAT_FAST_INT64\n//#define SOFTFLOAT_FAST_DIV64TO32\n\n/*----------------------------------------------------------------------------\n*----------------------------------------------------------------------------*/\n#define INLINE static inline\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/include/softfloat/primitiveTypes.h",
    "content": "\n/*============================================================================\n\nThis C header file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3a, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#ifndef primitiveTypes_h\n#define primitiveTypes_h 1\n\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifdef SOFTFLOAT_FAST_INT64\n\n#ifdef LITTLEENDIAN\nstruct uint128 { uint64_t v0, v64; };\nstruct uint64_extra { uint64_t extra, v; };\nstruct uint128_extra { uint64_t extra; struct uint128 v; };\n#else\nstruct uint128 { uint64_t v64, v0; };\nstruct uint64_extra { uint64_t v, extra; };\nstruct uint128_extra { struct uint128 v; uint64_t extra; };\n#endif\n\n#endif\n\n/*----------------------------------------------------------------------------\n| These macros are used to isolate the differences in word order between big-\n| endian and little-endian platforms.\n*----------------------------------------------------------------------------*/\n#ifdef LITTLEENDIAN\n#define wordIncr 1\n#define indexWord( total, n ) (n)\n#define indexWordHi( total ) ((total) - 1)\n#define indexWordLo( total ) 0\n#define indexMultiword( total, m, n ) (n)\n#define indexMultiwordHi( total, n ) ((total) - (n))\n#define indexMultiwordLo( total, n ) 0\n#define indexMultiwordHiBut( total, n ) (n)\n#define indexMultiwordLoBut( total, n ) 0\n#define INIT_UINTM4( v3, v2, v1, v0 ) { v0, v1, v2, v3 }\n#else\n#define wordIncr -1\n#define indexWord( total, n ) ((total) - 1 - (n))\n#define indexWordHi( total ) 0\n#define indexWordLo( total ) ((total) - 1)\n#define indexMultiword( total, m, n ) ((total) - 1 - (m))\n#define indexMultiwordHi( total, n ) 0\n#define indexMultiwordLo( total, n ) ((total) - (n))\n#define indexMultiwordHiBut( total, n ) 0\n#define indexMultiwordLoBut( total, n ) (n)\n#define INIT_UINTM4( v3, v2, v1, v0 ) { v3, v2, v1, v0 }\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/include/softfloat/primitives.h",
    "content": "\n/*============================================================================\n\nThis C header file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#ifndef primitives_h\n#define primitives_h 1\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"primitiveTypes.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef softfloat_shortShiftRightJam64\n/*----------------------------------------------------------------------------\n| Shifts 'a' right by the number of bits given in 'dist', which must be in\n| the range 1 to 63.  If any nonzero bits are shifted off, they are \"jammed\"\n| into the least-significant bit of the shifted value by setting the least-\n| significant bit to 1.  This shifted-and-jammed value is returned.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\nINLINE\nuint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist )\n    { return a>>dist | ((a & (((uint_fast64_t) 1<<dist) - 1)) != 0); }\n#else\nuint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist );\n#endif\n#endif\n\n#ifndef softfloat_shiftRightJam32\n/*----------------------------------------------------------------------------\n| Shifts 'a' right by the number of bits given in 'dist', which must not\n| be zero.  If any nonzero bits are shifted off, they are \"jammed\" into the\n| least-significant bit of the shifted value by setting the least-significant\n| bit to 1.  This shifted-and-jammed value is returned.\n|   The value of 'dist' can be arbitrarily large.  In particular, if 'dist' is\n| greater than 32, the result will be either 0 or 1, depending on whether 'a'\n| is zero or nonzero.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\nINLINE uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist )\n{\n    return\n        (dist < 31) ? a>>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0);\n}\n#else\nuint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist );\n#endif\n#endif\n\n#ifndef softfloat_shiftRightJam64\n/*----------------------------------------------------------------------------\n| Shifts 'a' right by the number of bits given in 'dist', which must not\n| be zero.  If any nonzero bits are shifted off, they are \"jammed\" into the\n| least-significant bit of the shifted value by setting the least-significant\n| bit to 1.  This shifted-and-jammed value is returned.\n|   The value of 'dist' can be arbitrarily large.  In particular, if 'dist' is\n| greater than 64, the result will be either 0 or 1, depending on whether 'a'\n| is zero or nonzero.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)\nINLINE uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist )\n{\n    return\n        (dist < 63) ? a>>dist | ((uint64_t) (a<<(-dist & 63)) != 0) : (a != 0);\n}\n#else\nuint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist );\n#endif\n#endif\n\n/*----------------------------------------------------------------------------\n| A constant table that translates an 8-bit unsigned integer (the array index)\n| into the number of leading 0 bits before the most-significant 1 of that\n| integer.  For integer zero (index 0), the corresponding table element is 8.\n*----------------------------------------------------------------------------*/\nextern const uint_least8_t softfloat_countLeadingZeros8[256];\n\n#ifndef softfloat_countLeadingZeros16\n/*----------------------------------------------------------------------------\n| Returns the number of leading 0 bits before the most-significant 1 bit of\n| 'a'.  If 'a' is zero, 16 is returned.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\nINLINE uint_fast8_t softfloat_countLeadingZeros16( uint16_t a )\n{\n    uint_fast8_t count = 8;\n    if ( 0x100 <= a ) {\n        count = 0;\n        a >>= 8;\n    }\n    count += softfloat_countLeadingZeros8[a];\n    return count;\n}\n#else\nuint_fast8_t softfloat_countLeadingZeros16( uint16_t a );\n#endif\n#endif\n\n#ifndef softfloat_countLeadingZeros32\n/*----------------------------------------------------------------------------\n| Returns the number of leading 0 bits before the most-significant 1 bit of\n| 'a'.  If 'a' is zero, 32 is returned.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)\nINLINE uint_fast8_t softfloat_countLeadingZeros32( uint32_t a )\n{\n    uint_fast8_t count = 0;\n    if ( a < 0x10000 ) {\n        count = 16;\n        a <<= 16;\n    }\n    if ( a < 0x1000000 ) {\n        count += 8;\n        a <<= 8;\n    }\n    count += softfloat_countLeadingZeros8[a>>24];\n    return count;\n}\n#else\nuint_fast8_t softfloat_countLeadingZeros32( uint32_t a );\n#endif\n#endif\n\n#ifndef softfloat_countLeadingZeros64\n/*----------------------------------------------------------------------------\n| Returns the number of leading 0 bits before the most-significant 1 bit of\n| 'a'.  If 'a' is zero, 64 is returned.\n*----------------------------------------------------------------------------*/\nuint_fast8_t softfloat_countLeadingZeros64( uint64_t a );\n#endif\n\nextern const uint16_t softfloat_approxRecip_1k0s[16];\nextern const uint16_t softfloat_approxRecip_1k1s[16];\n\n#ifndef softfloat_approxRecip32_1\n/*----------------------------------------------------------------------------\n| Returns an approximation to the reciprocal of the number represented by 'a',\n| where 'a' is interpreted as an unsigned fixed-point number with one integer\n| bit and 31 fraction bits.  The 'a' input must be \"normalized\", meaning that\n| its most-significant bit (bit 31) must be 1.  Thus, if A is the value of\n| the fixed-point interpretation of 'a', then 1 <= A < 2.  The returned value\n| is interpreted as a pure unsigned fraction, having no integer bits and 32\n| fraction bits.  The approximation returned is never greater than the true\n| reciprocal 1/A, and it differs from the true reciprocal by at most 2.006 ulp\n| (units in the last place).\n*----------------------------------------------------------------------------*/\n#ifdef SOFTFLOAT_FAST_DIV64TO32\n#define softfloat_approxRecip32_1( a ) ((uint32_t) (UINT64_C( 0x7FFFFFFFFFFFFFFF ) / (uint32_t) (a)))\n#else\nuint32_t softfloat_approxRecip32_1( uint32_t a );\n#endif\n#endif\n\nextern const uint16_t softfloat_approxRecipSqrt_1k0s[16];\nextern const uint16_t softfloat_approxRecipSqrt_1k1s[16];\n\n#ifndef softfloat_approxRecipSqrt32_1\n/*----------------------------------------------------------------------------\n| Returns an approximation to the reciprocal of the square root of the number\n| represented by 'a', where 'a' is interpreted as an unsigned fixed-point\n| number either with one integer bit and 31 fraction bits or with two integer\n| bits and 30 fraction bits.  The format of 'a' is determined by 'oddExpA',\n| which must be either 0 or 1.  If 'oddExpA' is 1, 'a' is interpreted as\n| having one integer bit, and if 'oddExpA' is 0, 'a' is interpreted as having\n| two integer bits.  The 'a' input must be \"normalized\", meaning that its\n| most-significant bit (bit 31) must be 1.  Thus, if A is the value of the\n| fixed-point interpretation of 'a', it follows that 1 <= A < 2 when 'oddExpA'\n| is 1, and 2 <= A < 4 when 'oddExpA' is 0.\n|   The returned value is interpreted as a pure unsigned fraction, having\n| no integer bits and 32 fraction bits.  The approximation returned is never\n| greater than the true reciprocal 1/sqrt(A), and it differs from the true\n| reciprocal by at most 2.06 ulp (units in the last place).  The approximation\n| returned is also always within the range 0.5 to 1; thus, the most-\n| significant bit of the result is always set.\n*----------------------------------------------------------------------------*/\nuint32_t softfloat_approxRecipSqrt32_1( unsigned int oddExpA, uint32_t a );\n#endif\n\n#ifdef SOFTFLOAT_FAST_INT64\n\n/*----------------------------------------------------------------------------\n| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is\n| defined.\n*----------------------------------------------------------------------------*/\n\n#ifndef softfloat_eq128\n/*----------------------------------------------------------------------------\n| Returns true if the 128-bit unsigned integer formed by concatenating 'a64'\n| and 'a0' is equal to the 128-bit unsigned integer formed by concatenating\n| 'b64' and 'b0'.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL)\nINLINE\nbool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )\n    { return (a64 == b64) && (a0 == b0); }\n#else\nbool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );\n#endif\n#endif\n\n#ifndef softfloat_le128\n/*----------------------------------------------------------------------------\n| Returns true if the 128-bit unsigned integer formed by concatenating 'a64'\n| and 'a0' is less than or equal to the 128-bit unsigned integer formed by\n| concatenating 'b64' and 'b0'.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\nINLINE\nbool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )\n    { return (a64 < b64) || ((a64 == b64) && (a0 <= b0)); }\n#else\nbool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );\n#endif\n#endif\n\n#ifndef softfloat_lt128\n/*----------------------------------------------------------------------------\n| Returns true if the 128-bit unsigned integer formed by concatenating 'a64'\n| and 'a0' is less than the 128-bit unsigned integer formed by concatenating\n| 'b64' and 'b0'.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\nINLINE\nbool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )\n    { return (a64 < b64) || ((a64 == b64) && (a0 < b0)); }\n#else\nbool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );\n#endif\n#endif\n\n#ifndef softfloat_shortShiftLeft128\n/*----------------------------------------------------------------------------\n| Shifts the 128 bits formed by concatenating 'a64' and 'a0' left by the\n| number of bits given in 'dist', which must be in the range 1 to 63.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\nINLINE\nstruct uint128\n softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t dist )\n{\n    struct uint128 z;\n    z.v64 = a64<<dist | a0>>(-dist & 63);\n    z.v0 = a0<<dist;\n    return z;\n}\n#else\nstruct uint128\n softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t dist );\n#endif\n#endif\n\n#ifndef softfloat_shortShiftRight128\n/*----------------------------------------------------------------------------\n| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the\n| number of bits given in 'dist', which must be in the range 1 to 63.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\nINLINE\nstruct uint128\n softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t dist )\n{\n    struct uint128 z;\n    z.v64 = a64>>dist;\n    z.v0 = a64<<(-dist & 63) | a0>>dist;\n    return z;\n}\n#else\nstruct uint128\n softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t dist );\n#endif\n#endif\n\n#ifndef softfloat_shortShiftRightJam64Extra\n/*----------------------------------------------------------------------------\n| This function is the same as 'softfloat_shiftRightJam64Extra' (below),\n| except that 'dist' must be in the range 1 to 63.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\nINLINE\nstruct uint64_extra\n softfloat_shortShiftRightJam64Extra(\n     uint64_t a, uint64_t extra, uint_fast8_t dist )\n{\n    struct uint64_extra z;\n    z.v = a>>dist;\n    z.extra = a<<(-dist & 63) | (extra != 0);\n    return z;\n}\n#else\nstruct uint64_extra\n softfloat_shortShiftRightJam64Extra(\n     uint64_t a, uint64_t extra, uint_fast8_t dist );\n#endif\n#endif\n\n#ifndef softfloat_shortShiftRightJam128\n/*----------------------------------------------------------------------------\n| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the\n| number of bits given in 'dist', which must be in the range 1 to 63.  If any\n| nonzero bits are shifted off, they are \"jammed\" into the least-significant\n| bit of the shifted value by setting the least-significant bit to 1.  This\n| shifted-and-jammed value is returned.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)\nINLINE\nstruct uint128\n softfloat_shortShiftRightJam128(\n     uint64_t a64, uint64_t a0, uint_fast8_t dist )\n{\n    uint_fast8_t negDist = -dist;\n    struct uint128 z;\n    z.v64 = a64>>dist;\n    z.v0 =\n        a64<<(negDist & 63) | a0>>dist\n            | ((uint64_t) (a0<<(negDist & 63)) != 0);\n    return z;\n}\n#else\nstruct uint128\n softfloat_shortShiftRightJam128(\n     uint64_t a64, uint64_t a0, uint_fast8_t dist );\n#endif\n#endif\n\n#ifndef softfloat_shortShiftRightJam128Extra\n/*----------------------------------------------------------------------------\n| This function is the same as 'softfloat_shiftRightJam128Extra' (below),\n| except that 'dist' must be in the range 1 to 63.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)\nINLINE\nstruct uint128_extra\n softfloat_shortShiftRightJam128Extra(\n     uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist )\n{\n    uint_fast8_t negDist = -dist;\n    struct uint128_extra z;\n    z.v.v64 = a64>>dist;\n    z.v.v0 = a64<<(negDist & 63) | a0>>dist;\n    z.extra = a0<<(negDist & 63) | (extra != 0);\n    return z;\n}\n#else\nstruct uint128_extra\n softfloat_shortShiftRightJam128Extra(\n     uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist );\n#endif\n#endif\n\n#ifndef softfloat_shiftRightJam64Extra\n/*----------------------------------------------------------------------------\n| Shifts the 128 bits formed by concatenating 'a' and 'extra' right by 64\n| _plus_ the number of bits given in 'dist', which must not be zero.  This\n| shifted value is at most 64 nonzero bits and is returned in the 'v' field\n| of the 'struct uint64_extra' result.  The 64-bit 'extra' field of the result\n| contains a value formed as follows from the bits that were shifted off:  The\n| _last_ bit shifted off is the most-significant bit of the 'extra' field, and\n| the other 63 bits of the 'extra' field are all zero if and only if _all_but_\n| _the_last_ bits shifted off were all zero.\n|   (This function makes more sense if 'a' and 'extra' are considered to form\n| an unsigned fixed-point number with binary point between 'a' and 'extra'.\n| This fixed-point value is shifted right by the number of bits given in\n| 'dist', and the integer part of this shifted value is returned in the 'v'\n| field of the result.  The fractional part of the shifted value is modified\n| as described above and returned in the 'extra' field of the result.)\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (4 <= INLINE_LEVEL)\nINLINE\nstruct uint64_extra\n softfloat_shiftRightJam64Extra(\n     uint64_t a, uint64_t extra, uint_fast32_t dist )\n{\n    struct uint64_extra z;\n    if ( dist < 64 ) {\n        z.v = a>>dist;\n        z.extra = a<<(-dist & 63);\n    } else {\n        z.v = 0;\n        z.extra = (dist == 64) ? a : (a != 0);\n    }\n    z.extra |= (extra != 0);\n    return z;\n}\n#else\nstruct uint64_extra\n softfloat_shiftRightJam64Extra(\n     uint64_t a, uint64_t extra, uint_fast32_t dist );\n#endif\n#endif\n\n#ifndef softfloat_shiftRightJam128\n/*----------------------------------------------------------------------------\n| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the\n| number of bits given in 'dist', which must not be zero.  If any nonzero bits\n| are shifted off, they are \"jammed\" into the least-significant bit of the\n| shifted value by setting the least-significant bit to 1.  This shifted-and-\n| jammed value is returned.\n|   The value of 'dist' can be arbitrarily large.  In particular, if 'dist' is\n| greater than 128, the result will be either 0 or 1, depending on whether the\n| original 128 bits are all zeros.\n*----------------------------------------------------------------------------*/\nstruct uint128\n softfloat_shiftRightJam128( uint64_t a64, uint64_t a0, uint_fast32_t dist );\n#endif\n\n#ifndef softfloat_shiftRightJam128Extra\n/*----------------------------------------------------------------------------\n| Shifts the 192 bits formed by concatenating 'a64', 'a0', and 'extra' right\n| by 64 _plus_ the number of bits given in 'dist', which must not be zero.\n| This shifted value is at most 128 nonzero bits and is returned in the 'v'\n| field of the 'struct uint128_extra' result.  The 64-bit 'extra' field of the\n| result contains a value formed as follows from the bits that were shifted\n| off:  The _last_ bit shifted off is the most-significant bit of the 'extra'\n| field, and the other 63 bits of the 'extra' field are all zero if and only\n| if _all_but_the_last_ bits shifted off were all zero.\n|   (This function makes more sense if 'a64', 'a0', and 'extra' are considered\n| to form an unsigned fixed-point number with binary point between 'a0' and\n| 'extra'.  This fixed-point value is shifted right by the number of bits\n| given in 'dist', and the integer part of this shifted value is returned\n| in the 'v' field of the result.  The fractional part of the shifted value\n| is modified as described above and returned in the 'extra' field of the\n| result.)\n*----------------------------------------------------------------------------*/\nstruct uint128_extra\n softfloat_shiftRightJam128Extra(\n     uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t dist );\n#endif\n\n#ifndef softfloat_shiftRightJam256M\n/*----------------------------------------------------------------------------\n| Shifts the 256-bit unsigned integer pointed to by 'aPtr' right by the number\n| of bits given in 'dist', which must not be zero.  If any nonzero bits are\n| shifted off, they are \"jammed\" into the least-significant bit of the shifted\n| value by setting the least-significant bit to 1.  This shifted-and-jammed\n| value is stored at the location pointed to by 'zPtr'.  Each of 'aPtr' and\n| 'zPtr' points to an array of four 64-bit elements that concatenate in the\n| platform's normal endian order to form a 256-bit integer.\n|   The value of 'dist' can be arbitrarily large.  In particular, if 'dist'\n| is greater than 256, the stored result will be either 0 or 1, depending on\n| whether the original 256 bits are all zeros.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_shiftRightJam256M(\n     const uint64_t *aPtr, uint_fast32_t dist, uint64_t *zPtr );\n#endif\n\n#ifndef softfloat_add128\n/*----------------------------------------------------------------------------\n| Returns the sum of the 128-bit integer formed by concatenating 'a64' and\n| 'a0' and the 128-bit integer formed by concatenating 'b64' and 'b0'.  The\n| addition is modulo 2^128, so any carry out is lost.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\nINLINE\nstruct uint128\n softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )\n{\n    struct uint128 z;\n    z.v0 = a0 + b0;\n    z.v64 = a64 + b64 + (z.v0 < a0);\n    return z;\n}\n#else\nstruct uint128\n softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );\n#endif\n#endif\n\n#ifndef softfloat_add256M\n/*----------------------------------------------------------------------------\n| Adds the two 256-bit integers pointed to by 'aPtr' and 'bPtr'.  The addition\n| is modulo 2^256, so any carry out is lost.  The sum is stored at the\n| location pointed to by 'zPtr'.  Each of 'aPtr', 'bPtr', and 'zPtr' points to\n| an array of four 64-bit elements that concatenate in the platform's normal\n| endian order to form a 256-bit integer.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_add256M(\n     const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr );\n#endif\n\n#ifndef softfloat_sub128\n/*----------------------------------------------------------------------------\n| Returns the difference of the 128-bit integer formed by concatenating 'a64'\n| and 'a0' and the 128-bit integer formed by concatenating 'b64' and 'b0'.\n| The subtraction is modulo 2^128, so any borrow out (carry out) is lost.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\nINLINE\nstruct uint128\n softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )\n{\n    struct uint128 z;\n    z.v0 = a0 - b0;\n    z.v64 = a64 - b64;\n    z.v64 -= (a0 < b0);\n    return z;\n}\n#else\nstruct uint128\n softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );\n#endif\n#endif\n\n#ifndef softfloat_sub256M\n/*----------------------------------------------------------------------------\n| Subtracts the 256-bit integer pointed to by 'bPtr' from the 256-bit integer\n| pointed to by 'aPtr'.  The addition is modulo 2^256, so any borrow out\n| (carry out) is lost.  The difference is stored at the location pointed to\n| by 'zPtr'.  Each of 'aPtr', 'bPtr', and 'zPtr' points to an array of four\n| 64-bit elements that concatenate in the platform's normal endian order to\n| form a 256-bit integer.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_sub256M(\n     const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr );\n#endif\n\n#ifndef softfloat_mul64ByShifted32To128\n/*----------------------------------------------------------------------------\n| Returns the 128-bit product of 'a', 'b', and 2^32.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)\nINLINE struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b )\n{\n    uint_fast64_t mid;\n    struct uint128 z;\n    mid = (uint_fast64_t) (uint32_t) a * b;\n    z.v0 = mid<<32;\n    z.v64 = (uint_fast64_t) (uint32_t) (a>>32) * b + (mid>>32);\n    return z;\n}\n#else\nstruct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b );\n#endif\n#endif\n\n#ifndef softfloat_mul64To128\n/*----------------------------------------------------------------------------\n| Returns the 128-bit product of 'a' and 'b'.\n*----------------------------------------------------------------------------*/\nstruct uint128 softfloat_mul64To128( uint64_t a, uint64_t b );\n#endif\n\n#ifndef softfloat_mul128By32\n/*----------------------------------------------------------------------------\n| Returns the product of the 128-bit integer formed by concatenating 'a64' and\n| 'a0', multiplied by 'b'.  The multiplication is modulo 2^128; any overflow\n| bits are discarded.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (4 <= INLINE_LEVEL)\nINLINE\nstruct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b )\n{\n    struct uint128 z;\n    uint_fast64_t mid;\n    uint_fast32_t carry;\n    z.v0 = a0 * b;\n    mid = (uint_fast64_t) (uint32_t) (a0>>32) * b;\n    carry = (uint32_t) ((uint_fast32_t) (z.v0>>32) - (uint_fast32_t) mid);\n    z.v64 = a64 * b + (uint_fast32_t) ((mid + carry)>>32);\n    return z;\n}\n#else\nstruct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b );\n#endif\n#endif\n\n#ifndef softfloat_mul128To256M\n/*----------------------------------------------------------------------------\n| Multiplies the 128-bit unsigned integer formed by concatenating 'a64' and\n| 'a0' by the 128-bit unsigned integer formed by concatenating 'b64' and\n| 'b0'.  The 256-bit product is stored at the location pointed to by 'zPtr'.\n| Argument 'zPtr' points to an array of four 64-bit elements that concatenate\n| in the platform's normal endian order to form a 256-bit integer.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_mul128To256M(\n     uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr );\n#endif\n\n#else\n\n/*----------------------------------------------------------------------------\n| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is not\n| defined.\n*----------------------------------------------------------------------------*/\n\n#ifndef softfloat_compare96M\n/*----------------------------------------------------------------------------\n| Compares the two 96-bit unsigned integers pointed to by 'aPtr' and 'bPtr'.\n| Returns -1 if the first integer (A) is less than the second (B); returns 0\n| if the two integers are equal; and returns +1 if the first integer (A)\n| is greater than the second (B).  (The result is thus the signum of A - B.)\n| Each of 'aPtr' and 'bPtr' points to an array of three 32-bit elements that\n| concatenate in the platform's normal endian order to form a 96-bit integer.\n*----------------------------------------------------------------------------*/\nint_fast8_t softfloat_compare96M( const uint32_t *aPtr, const uint32_t *bPtr );\n#endif\n\n#ifndef softfloat_compare128M\n/*----------------------------------------------------------------------------\n| Compares the two 128-bit unsigned integers pointed to by 'aPtr' and 'bPtr'.\n| Returns -1 if the first integer (A) is less than the second (B); returns 0\n| if the two integers are equal; and returns +1 if the first integer (A)\n| is greater than the second (B).  (The result is thus the signum of A - B.)\n| Each of 'aPtr' and 'bPtr' points to an array of four 32-bit elements that\n| concatenate in the platform's normal endian order to form a 128-bit integer.\n*----------------------------------------------------------------------------*/\nint_fast8_t\n softfloat_compare128M( const uint32_t *aPtr, const uint32_t *bPtr );\n#endif\n\n#ifndef softfloat_shortShiftLeft64To96M\n/*----------------------------------------------------------------------------\n| Extends 'a' to 96 bits and shifts the value left by the number of bits given\n| in 'dist', which must be in the range 1 to 31.  The result is stored at the\n| location pointed to by 'zPtr'.  Argument 'zPtr' points to an array of three\n| 32-bit elements that concatenate in the platform's normal endian order to\n| form a 96-bit integer.\n*----------------------------------------------------------------------------*/\n#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)\nINLINE\nvoid\n softfloat_shortShiftLeft64To96M(\n     uint64_t a, uint_fast8_t dist, uint32_t *zPtr )\n{\n    zPtr[indexWord( 3, 0 )] = (uint32_t) a<<dist;\n    a >>= 32 - dist;\n    zPtr[indexWord( 3, 2 )] = a>>32;\n    zPtr[indexWord( 3, 1 )] = a;\n}\n#else\nvoid\n softfloat_shortShiftLeft64To96M(\n     uint64_t a, uint_fast8_t dist, uint32_t *zPtr );\n#endif\n#endif\n\n#ifndef softfloat_shortShiftLeftM\n/*----------------------------------------------------------------------------\n| Shifts the N-bit unsigned integer pointed to by 'aPtr' left by the number\n| of bits given in 'dist', where N = 'size_words' * 32.  The value of 'dist'\n| must be in the range 1 to 31.  Any nonzero bits shifted off are lost.  The\n| shifted N-bit result is stored at the location pointed to by 'zPtr'.  Each\n| of 'aPtr' and 'zPtr' points to a 'size_words'-long array of 32-bit elements\n| that concatenate in the platform's normal endian order to form an N-bit\n| integer.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_shortShiftLeftM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     uint_fast8_t dist,\n     uint32_t *zPtr\n );\n#endif\n\n#ifndef softfloat_shortShiftLeft96M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shortShiftLeftM' with\n| 'size_words' = 3 (N = 96).\n*----------------------------------------------------------------------------*/\n#define softfloat_shortShiftLeft96M( aPtr, dist, zPtr ) softfloat_shortShiftLeftM( 3, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_shortShiftLeft128M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shortShiftLeftM' with\n| 'size_words' = 4 (N = 128).\n*----------------------------------------------------------------------------*/\n#define softfloat_shortShiftLeft128M( aPtr, dist, zPtr ) softfloat_shortShiftLeftM( 4, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_shortShiftLeft160M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shortShiftLeftM' with\n| 'size_words' = 5 (N = 160).\n*----------------------------------------------------------------------------*/\n#define softfloat_shortShiftLeft160M( aPtr, dist, zPtr ) softfloat_shortShiftLeftM( 5, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_shiftLeftM\n/*----------------------------------------------------------------------------\n| Shifts the N-bit unsigned integer pointed to by 'aPtr' left by the number\n| of bits given in 'dist', where N = 'size_words' * 32.  The value of 'dist'\n| must not be zero.  Any nonzero bits shifted off are lost.  The shifted\n| N-bit result is stored at the location pointed to by 'zPtr'.  Each of 'aPtr'\n| and 'zPtr' points to a 'size_words'-long array of 32-bit elements that\n| concatenate in the platform's normal endian order to form an N-bit integer.\n|   The value of 'dist' can be arbitrarily large.  In particular, if 'dist' is\n| greater than N, the stored result will be 0.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_shiftLeftM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     uint32_t dist,\n     uint32_t *zPtr\n );\n#endif\n\n#ifndef softfloat_shiftLeft96M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shiftLeftM' with\n| 'size_words' = 3 (N = 96).\n*----------------------------------------------------------------------------*/\n#define softfloat_shiftLeft96M( aPtr, dist, zPtr ) softfloat_shiftLeftM( 3, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_shiftLeft128M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shiftLeftM' with\n| 'size_words' = 4 (N = 128).\n*----------------------------------------------------------------------------*/\n#define softfloat_shiftLeft128M( aPtr, dist, zPtr ) softfloat_shiftLeftM( 4, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_shiftLeft160M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shiftLeftM' with\n| 'size_words' = 5 (N = 160).\n*----------------------------------------------------------------------------*/\n#define softfloat_shiftLeft160M( aPtr, dist, zPtr ) softfloat_shiftLeftM( 5, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_shortShiftRightM\n/*----------------------------------------------------------------------------\n| Shifts the N-bit unsigned integer pointed to by 'aPtr' right by the number\n| of bits given in 'dist', where N = 'size_words' * 32.  The value of 'dist'\n| must be in the range 1 to 31.  Any nonzero bits shifted off are lost.  The\n| shifted N-bit result is stored at the location pointed to by 'zPtr'.  Each\n| of 'aPtr' and 'zPtr' points to a 'size_words'-long array of 32-bit elements\n| that concatenate in the platform's normal endian order to form an N-bit\n| integer.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_shortShiftRightM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     uint_fast8_t dist,\n     uint32_t *zPtr\n );\n#endif\n\n#ifndef softfloat_shortShiftRight128M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shortShiftRightM' with\n| 'size_words' = 4 (N = 128).\n*----------------------------------------------------------------------------*/\n#define softfloat_shortShiftRight128M( aPtr, dist, zPtr ) softfloat_shortShiftRightM( 4, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_shortShiftRight160M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shortShiftRightM' with\n| 'size_words' = 5 (N = 160).\n*----------------------------------------------------------------------------*/\n#define softfloat_shortShiftRight160M( aPtr, dist, zPtr ) softfloat_shortShiftRightM( 5, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_shortShiftRightJamM\n/*----------------------------------------------------------------------------\n| Shifts the N-bit unsigned integer pointed to by 'aPtr' right by the number\n| of bits given in 'dist', where N = 'size_words' * 32.  The value of 'dist'\n| must be in the range 1 to 31.  If any nonzero bits are shifted off, they are\n| \"jammed\" into the least-significant bit of the shifted value by setting the\n| least-significant bit to 1.  This shifted-and-jammed N-bit result is stored\n| at the location pointed to by 'zPtr'.  Each of 'aPtr' and 'zPtr' points\n| to a 'size_words'-long array of 32-bit elements that concatenate in the\n| platform's normal endian order to form an N-bit integer.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_shortShiftRightJamM(\n     uint_fast8_t, const uint32_t *, uint_fast8_t, uint32_t * );\n#endif\n\n#ifndef softfloat_shortShiftRightJam160M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shortShiftRightJamM' with\n| 'size_words' = 5 (N = 160).\n*----------------------------------------------------------------------------*/\n#define softfloat_shortShiftRightJam160M( aPtr, dist, zPtr ) softfloat_shortShiftRightJamM( 5, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_shiftRightM\n/*----------------------------------------------------------------------------\n| Shifts the N-bit unsigned integer pointed to by 'aPtr' right by the number\n| of bits given in 'dist', where N = 'size_words' * 32.  The value of 'dist'\n| must not be zero.  Any nonzero bits shifted off are lost.  The shifted\n| N-bit result is stored at the location pointed to by 'zPtr'.  Each of 'aPtr'\n| and 'zPtr' points to a 'size_words'-long array of 32-bit elements that\n| concatenate in the platform's normal endian order to form an N-bit integer.\n|   The value of 'dist' can be arbitrarily large.  In particular, if 'dist' is\n| greater than N, the stored result will be 0.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_shiftRightM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     uint32_t dist,\n     uint32_t *zPtr\n );\n#endif\n\n#ifndef softfloat_shiftRight96M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shiftRightM' with\n| 'size_words' = 3 (N = 96).\n*----------------------------------------------------------------------------*/\n#define softfloat_shiftRight96M( aPtr, dist, zPtr ) softfloat_shiftRightM( 3, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_shiftRightJamM\n/*----------------------------------------------------------------------------\n| Shifts the N-bit unsigned integer pointed to by 'aPtr' right by the number\n| of bits given in 'dist', where N = 'size_words' * 32.  The value of 'dist'\n| must not be zero.  If any nonzero bits are shifted off, they are \"jammed\"\n| into the least-significant bit of the shifted value by setting the least-\n| significant bit to 1.  This shifted-and-jammed N-bit result is stored\n| at the location pointed to by 'zPtr'.  Each of 'aPtr' and 'zPtr' points\n| to a 'size_words'-long array of 32-bit elements that concatenate in the\n| platform's normal endian order to form an N-bit integer.\n|   The value of 'dist' can be arbitrarily large.  In particular, if 'dist'\n| is greater than N, the stored result will be either 0 or 1, depending on\n| whether the original N bits are all zeros.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_shiftRightJamM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     uint32_t dist,\n     uint32_t *zPtr\n );\n#endif\n\n#ifndef softfloat_shiftRightJam96M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shiftRightJamM' with\n| 'size_words' = 3 (N = 96).\n*----------------------------------------------------------------------------*/\n#define softfloat_shiftRightJam96M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 3, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_shiftRightJam128M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shiftRightJamM' with\n| 'size_words' = 4 (N = 128).\n*----------------------------------------------------------------------------*/\n#define softfloat_shiftRightJam128M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 4, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_shiftRightJam160M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_shiftRightJamM' with\n| 'size_words' = 5 (N = 160).\n*----------------------------------------------------------------------------*/\n#define softfloat_shiftRightJam160M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 5, aPtr, dist, zPtr )\n#endif\n\n#ifndef softfloat_addM\n/*----------------------------------------------------------------------------\n| Adds the two N-bit integers pointed to by 'aPtr' and 'bPtr', where N =\n| 'size_words' * 32.  The addition is modulo 2^N, so any carry out is lost.\n| The N-bit sum is stored at the location pointed to by 'zPtr'.  Each of\n| 'aPtr', 'bPtr', and 'zPtr' points to a 'size_words'-long array of 32-bit\n| elements that concatenate in the platform's normal endian order to form an\n| N-bit integer.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_addM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     const uint32_t *bPtr,\n     uint32_t *zPtr\n );\n#endif\n\n#ifndef softfloat_add96M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_addM' with 'size_words'\n| = 3 (N = 96).\n*----------------------------------------------------------------------------*/\n#define softfloat_add96M( aPtr, bPtr, zPtr ) softfloat_addM( 3, aPtr, bPtr, zPtr )\n#endif\n\n#ifndef softfloat_add128M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_addM' with 'size_words'\n| = 4 (N = 128).\n*----------------------------------------------------------------------------*/\n#define softfloat_add128M( aPtr, bPtr, zPtr ) softfloat_addM( 4, aPtr, bPtr, zPtr )\n#endif\n\n#ifndef softfloat_add160M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_addM' with 'size_words'\n| = 5 (N = 160).\n*----------------------------------------------------------------------------*/\n#define softfloat_add160M( aPtr, bPtr, zPtr ) softfloat_addM( 5, aPtr, bPtr, zPtr )\n#endif\n\n#ifndef softfloat_addCarryM\n/*----------------------------------------------------------------------------\n| Adds the two N-bit unsigned integers pointed to by 'aPtr' and 'bPtr', where\n| N = 'size_words' * 32, plus 'carry', which must be either 0 or 1.  The N-bit\n| sum (modulo 2^N) is stored at the location pointed to by 'zPtr', and any\n| carry out is returned as the result.  Each of 'aPtr', 'bPtr', and 'zPtr'\n| points to a 'size_words'-long array of 32-bit elements that concatenate in\n| the platform's normal endian order to form an N-bit integer.\n*----------------------------------------------------------------------------*/\nuint_fast8_t\n softfloat_addCarryM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     const uint32_t *bPtr,\n     uint_fast8_t carry,\n     uint32_t *zPtr\n );\n#endif\n\n#ifndef softfloat_addComplCarryM\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_addCarryM', except that\n| the value of the unsigned integer pointed to by 'bPtr' is bit-wise completed\n| before the addition.\n*----------------------------------------------------------------------------*/\nuint_fast8_t\n softfloat_addComplCarryM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     const uint32_t *bPtr,\n     uint_fast8_t carry,\n     uint32_t *zPtr\n );\n#endif\n\n#ifndef softfloat_addComplCarry96M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_addComplCarryM' with\n| 'size_words' = 3 (N = 96).\n*----------------------------------------------------------------------------*/\n#define softfloat_addComplCarry96M( aPtr, bPtr, carry, zPtr ) softfloat_addComplCarryM( 3, aPtr, bPtr, carry, zPtr )\n#endif\n\n#ifndef softfloat_negXM\n/*----------------------------------------------------------------------------\n| Replaces the N-bit unsigned integer pointed to by 'zPtr' by the\n| 2s-complement of itself, where N = 'size_words' * 32.  Argument 'zPtr'\n| points to a 'size_words'-long array of 32-bit elements that concatenate in\n| the platform's normal endian order to form an N-bit integer.\n*----------------------------------------------------------------------------*/\nvoid softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr );\n#endif\n\n#ifndef softfloat_negX96M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_negXM' with 'size_words'\n| = 3 (N = 96).\n*----------------------------------------------------------------------------*/\n#define softfloat_negX96M( zPtr ) softfloat_negXM( 3, zPtr )\n#endif\n\n#ifndef softfloat_negX128M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_negXM' with 'size_words'\n| = 4 (N = 128).\n*----------------------------------------------------------------------------*/\n#define softfloat_negX128M( zPtr ) softfloat_negXM( 4, zPtr )\n#endif\n\n#ifndef softfloat_negX160M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_negXM' with 'size_words'\n| = 5 (N = 160).\n*----------------------------------------------------------------------------*/\n#define softfloat_negX160M( zPtr ) softfloat_negXM( 5, zPtr )\n#endif\n\n#ifndef softfloat_negX256M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_negXM' with 'size_words'\n| = 8 (N = 256).\n*----------------------------------------------------------------------------*/\n#define softfloat_negX256M( zPtr ) softfloat_negXM( 8, zPtr )\n#endif\n\n#ifndef softfloat_sub1XM\n/*----------------------------------------------------------------------------\n| Subtracts 1 from the N-bit integer pointed to by 'zPtr', where N =\n| 'size_words' * 32.  The subtraction is modulo 2^N, so any borrow out (carry\n| out) is lost.  Argument 'zPtr' points to a 'size_words'-long array of 32-bit\n| elements that concatenate in the platform's normal endian order to form an\n| N-bit integer.\n*----------------------------------------------------------------------------*/\nvoid softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr );\n#endif\n\n#ifndef softfloat_sub1X96M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_sub1XM' with 'size_words'\n| = 3 (N = 96).\n*----------------------------------------------------------------------------*/\n#define softfloat_sub1X96M( zPtr ) softfloat_sub1XM( 3, zPtr )\n#endif\n\n#ifndef softfloat_sub1X160M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_sub1XM' with 'size_words'\n| = 5 (N = 160).\n*----------------------------------------------------------------------------*/\n#define softfloat_sub1X160M( zPtr ) softfloat_sub1XM( 5, zPtr )\n#endif\n\n#ifndef softfloat_subM\n/*----------------------------------------------------------------------------\n| Subtracts the two N-bit integers pointed to by 'aPtr' and 'bPtr', where N =\n| 'size_words' * 32.  The subtraction is modulo 2^N, so any borrow out (carry\n| out) is lost.  The N-bit difference is stored at the location pointed to by\n| 'zPtr'.  Each of 'aPtr', 'bPtr', and 'zPtr' points to a 'size_words'-long\n| array of 32-bit elements that concatenate in the platform's normal endian\n| order to form an N-bit integer.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_subM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     const uint32_t *bPtr,\n     uint32_t *zPtr\n );\n#endif\n\n#ifndef softfloat_sub96M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_subM' with 'size_words'\n| = 3 (N = 96).\n*----------------------------------------------------------------------------*/\n#define softfloat_sub96M( aPtr, bPtr, zPtr ) softfloat_subM( 3, aPtr, bPtr, zPtr )\n#endif\n\n#ifndef softfloat_sub128M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_subM' with 'size_words'\n| = 4 (N = 128).\n*----------------------------------------------------------------------------*/\n#define softfloat_sub128M( aPtr, bPtr, zPtr ) softfloat_subM( 4, aPtr, bPtr, zPtr )\n#endif\n\n#ifndef softfloat_sub160M\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_subM' with 'size_words'\n| = 5 (N = 160).\n*----------------------------------------------------------------------------*/\n#define softfloat_sub160M( aPtr, bPtr, zPtr ) softfloat_subM( 5, aPtr, bPtr, zPtr )\n#endif\n\n#ifndef softfloat_mul64To128M\n/*----------------------------------------------------------------------------\n| Multiplies 'a' and 'b' and stores the 128-bit product at the location\n| pointed to by 'zPtr'.  Argument 'zPtr' points to an array of four 32-bit\n| elements that concatenate in the platform's normal endian order to form a\n| 128-bit integer.\n*----------------------------------------------------------------------------*/\nvoid softfloat_mul64To128M( uint64_t a, uint64_t b, uint32_t *zPtr );\n#endif\n\n#ifndef softfloat_mul128MTo256M\n/*----------------------------------------------------------------------------\n| Multiplies the two 128-bit unsigned integers pointed to by 'aPtr' and\n| 'bPtr', and stores the 256-bit product at the location pointed to by 'zPtr'.\n| Each of 'aPtr' and 'bPtr' points to an array of four 32-bit elements that\n| concatenate in the platform's normal endian order to form a 128-bit integer.\n| Argument 'zPtr' points to an array of eight 32-bit elements that concatenate\n| to form a 256-bit integer.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_mul128MTo256M(\n     const uint32_t *aPtr, const uint32_t *bPtr, uint32_t *zPtr );\n#endif\n\n#ifndef softfloat_remStepMBy32\n/*----------------------------------------------------------------------------\n| Performs a \"remainder reduction step\" as follows:  Arguments 'remPtr' and\n| 'bPtr' both point to N-bit unsigned integers, where N = 'size_words' * 32.\n| Defining R and B as the values of those integers, the expression (R<<'dist')\n| - B * q is computed modulo 2^N, and the N-bit result is stored at the\n| location pointed to by 'zPtr'.  Each of 'remPtr', 'bPtr', and 'zPtr' points\n| to a 'size_words'-long array of 32-bit elements that concatenate in the\n| platform's normal endian order to form an N-bit integer.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_remStepMBy32(\n     uint_fast8_t size_words,\n     const uint32_t *remPtr,\n     uint_fast8_t dist,\n     const uint32_t *bPtr,\n     uint32_t q,\n     uint32_t *zPtr\n );\n#endif\n\n#ifndef softfloat_remStep96MBy32\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_remStepMBy32' with\n| 'size_words' = 3 (N = 96).\n*----------------------------------------------------------------------------*/\n#define softfloat_remStep96MBy32( remPtr, dist, bPtr, q, zPtr ) softfloat_remStepMBy32( 3, remPtr, dist, bPtr, q, zPtr )\n#endif\n\n#ifndef softfloat_remStep128MBy32\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_remStepMBy32' with\n| 'size_words' = 4 (N = 128).\n*----------------------------------------------------------------------------*/\n#define softfloat_remStep128MBy32( remPtr, dist, bPtr, q, zPtr ) softfloat_remStepMBy32( 4, remPtr, dist, bPtr, q, zPtr )\n#endif\n\n#ifndef softfloat_remStep160MBy32\n/*----------------------------------------------------------------------------\n| This function or macro is the same as 'softfloat_remStepMBy32' with\n| 'size_words' = 5 (N = 160).\n*----------------------------------------------------------------------------*/\n#define softfloat_remStep160MBy32( remPtr, dist, bPtr, q, zPtr ) softfloat_remStepMBy32( 5, remPtr, dist, bPtr, q, zPtr )\n#endif\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/include/softfloat/softfloat.h",
    "content": "\n/*============================================================================\n\nThis C header file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n\n/*============================================================================\n| Note:  If SoftFloat is made available as a general library for programs to\n| use, it is strongly recommended that a platform-specific version of this\n| header, \"softfloat.h\", be created that folds in \"softfloat_types.h\" and that\n| eliminates all dependencies on compile-time macros.\n*============================================================================*/\n\n\n#ifndef softfloat_h\n#define softfloat_h 1\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"softfloat_types.h\"\n\n#ifndef THREAD_LOCAL\n#define THREAD_LOCAL\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*----------------------------------------------------------------------------\n| Software floating-point underflow tininess-detection mode.\n*----------------------------------------------------------------------------*/\nextern THREAD_LOCAL uint_fast8_t softfloat_detectTininess;\nenum {\n    softfloat_tininess_beforeRounding = 0,\n    softfloat_tininess_afterRounding  = 1\n};\n\n/*----------------------------------------------------------------------------\n| Software floating-point rounding mode.  (Mode \"odd\" is supported only if\n| SoftFloat is compiled with macro 'SOFTFLOAT_ROUND_ODD' defined.)\n*----------------------------------------------------------------------------*/\nextern THREAD_LOCAL uint_fast8_t softfloat_roundingMode;\nenum {\n    softfloat_round_near_even   = 0,\n    softfloat_round_minMag      = 1,\n    softfloat_round_min         = 2,\n    softfloat_round_max         = 3,\n    softfloat_round_near_maxMag = 4,\n    softfloat_round_odd         = 5\n};\n\n/*----------------------------------------------------------------------------\n| Software floating-point exception flags.\n*----------------------------------------------------------------------------*/\nextern THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags;\nenum {\n    softfloat_flag_inexact   =  1,\n    softfloat_flag_underflow =  2,\n    softfloat_flag_overflow  =  4,\n    softfloat_flag_infinite  =  8,\n    softfloat_flag_invalid   = 16\n};\n\n/*----------------------------------------------------------------------------\n| Routine to raise any or all of the software floating-point exception flags.\n*----------------------------------------------------------------------------*/\nvoid softfloat_raiseFlags( uint_fast8_t );\n\n/*----------------------------------------------------------------------------\n| Integer-to-floating-point conversion routines.\n*----------------------------------------------------------------------------*/\nfloat16_t ui32_to_f16( uint32_t );\nfloat32_t ui32_to_f32( uint32_t );\nfloat64_t ui32_to_f64( uint32_t );\n#ifdef SOFTFLOAT_FAST_INT64\nextFloat80_t ui32_to_extF80( uint32_t );\nfloat128_t ui32_to_f128( uint32_t );\n#endif\nvoid ui32_to_extF80M( uint32_t, extFloat80_t * );\nvoid ui32_to_f128M( uint32_t, float128_t * );\nfloat16_t ui64_to_f16( uint64_t );\nfloat32_t ui64_to_f32( uint64_t );\nfloat64_t ui64_to_f64( uint64_t );\n#ifdef SOFTFLOAT_FAST_INT64\nextFloat80_t ui64_to_extF80( uint64_t );\nfloat128_t ui64_to_f128( uint64_t );\n#endif\nvoid ui64_to_extF80M( uint64_t, extFloat80_t * );\nvoid ui64_to_f128M( uint64_t, float128_t * );\nfloat16_t i32_to_f16( int32_t );\nfloat32_t i32_to_f32( int32_t );\nfloat64_t i32_to_f64( int32_t );\n#ifdef SOFTFLOAT_FAST_INT64\nextFloat80_t i32_to_extF80( int32_t );\nfloat128_t i32_to_f128( int32_t );\n#endif\nvoid i32_to_extF80M( int32_t, extFloat80_t * );\nvoid i32_to_f128M( int32_t, float128_t * );\nfloat16_t i64_to_f16( int64_t );\nfloat32_t i64_to_f32( int64_t );\nfloat64_t i64_to_f64( int64_t );\n#ifdef SOFTFLOAT_FAST_INT64\nextFloat80_t i64_to_extF80( int64_t );\nfloat128_t i64_to_f128( int64_t );\n#endif\nvoid i64_to_extF80M( int64_t, extFloat80_t * );\nvoid i64_to_f128M( int64_t, float128_t * );\n\n/*----------------------------------------------------------------------------\n| 16-bit (half-precision) floating-point operations.\n*----------------------------------------------------------------------------*/\nuint_fast32_t f16_to_ui32( float16_t, uint_fast8_t, bool );\nuint_fast64_t f16_to_ui64( float16_t, uint_fast8_t, bool );\nint_fast32_t f16_to_i32( float16_t, uint_fast8_t, bool );\nint_fast64_t f16_to_i64( float16_t, uint_fast8_t, bool );\nuint_fast32_t f16_to_ui32_r_minMag( float16_t, bool );\nuint_fast64_t f16_to_ui64_r_minMag( float16_t, bool );\nint_fast32_t f16_to_i32_r_minMag( float16_t, bool );\nint_fast64_t f16_to_i64_r_minMag( float16_t, bool );\nfloat32_t f16_to_f32( float16_t );\nfloat64_t f16_to_f64( float16_t );\n#ifdef SOFTFLOAT_FAST_INT64\nextFloat80_t f16_to_extF80( float16_t );\nfloat128_t f16_to_f128( float16_t );\n#endif\nvoid f16_to_extF80M( float16_t, extFloat80_t * );\nvoid f16_to_f128M( float16_t, float128_t * );\nfloat16_t f16_roundToInt( float16_t, uint_fast8_t, bool );\nfloat16_t f16_add( float16_t, float16_t );\nfloat16_t f16_sub( float16_t, float16_t );\nfloat16_t f16_mul( float16_t, float16_t );\nfloat16_t f16_mulAdd( float16_t, float16_t, float16_t );\nfloat16_t f16_div( float16_t, float16_t );\nfloat16_t f16_rem( float16_t, float16_t );\nfloat16_t f16_sqrt( float16_t );\nbool f16_eq( float16_t, float16_t );\nbool f16_le( float16_t, float16_t );\nbool f16_lt( float16_t, float16_t );\nbool f16_eq_signaling( float16_t, float16_t );\nbool f16_le_quiet( float16_t, float16_t );\nbool f16_lt_quiet( float16_t, float16_t );\nbool f16_isSignalingNaN( float16_t );\n\n/*----------------------------------------------------------------------------\n| 32-bit (single-precision) floating-point operations.\n*----------------------------------------------------------------------------*/\nuint_fast32_t f32_to_ui32( float32_t, uint_fast8_t, bool );\nuint_fast64_t f32_to_ui64( float32_t, uint_fast8_t, bool );\nint_fast32_t f32_to_i32( float32_t, uint_fast8_t, bool );\nint_fast64_t f32_to_i64( float32_t, uint_fast8_t, bool );\nuint_fast32_t f32_to_ui32_r_minMag( float32_t, bool );\nuint_fast64_t f32_to_ui64_r_minMag( float32_t, bool );\nint_fast32_t f32_to_i32_r_minMag( float32_t, bool );\nint_fast64_t f32_to_i64_r_minMag( float32_t, bool );\nfloat16_t f32_to_f16( float32_t );\nfloat64_t f32_to_f64( float32_t );\n#ifdef SOFTFLOAT_FAST_INT64\nextFloat80_t f32_to_extF80( float32_t );\nfloat128_t f32_to_f128( float32_t );\n#endif\nvoid f32_to_extF80M( float32_t, extFloat80_t * );\nvoid f32_to_f128M( float32_t, float128_t * );\nfloat32_t f32_roundToInt( float32_t, uint_fast8_t, bool );\nfloat32_t f32_add( float32_t, float32_t );\nfloat32_t f32_sub( float32_t, float32_t );\nfloat32_t f32_mul( float32_t, float32_t );\nfloat32_t f32_mulAdd( float32_t, float32_t, float32_t );\nfloat32_t f32_div( float32_t, float32_t );\nfloat32_t f32_rem( float32_t, float32_t );\nfloat32_t f32_sqrt( float32_t );\nbool f32_eq( float32_t, float32_t );\nbool f32_le( float32_t, float32_t );\nbool f32_lt( float32_t, float32_t );\nbool f32_eq_signaling( float32_t, float32_t );\nbool f32_le_quiet( float32_t, float32_t );\nbool f32_lt_quiet( float32_t, float32_t );\nbool f32_isSignalingNaN( float32_t );\nuint_fast16_t f32_classify( float32_t );\n\n/*----------------------------------------------------------------------------\n| 64-bit (double-precision) floating-point operations.\n*----------------------------------------------------------------------------*/\nuint_fast32_t f64_to_ui32( float64_t, uint_fast8_t, bool );\nuint_fast64_t f64_to_ui64( float64_t, uint_fast8_t, bool );\nint_fast32_t f64_to_i32( float64_t, uint_fast8_t, bool );\nint_fast64_t f64_to_i64( float64_t, uint_fast8_t, bool );\nuint_fast32_t f64_to_ui32_r_minMag( float64_t, bool );\nuint_fast64_t f64_to_ui64_r_minMag( float64_t, bool );\nint_fast32_t f64_to_i32_r_minMag( float64_t, bool );\nint_fast64_t f64_to_i64_r_minMag( float64_t, bool );\nfloat16_t f64_to_f16( float64_t );\nfloat32_t f64_to_f32( float64_t );\n#ifdef SOFTFLOAT_FAST_INT64\nextFloat80_t f64_to_extF80( float64_t );\nfloat128_t f64_to_f128( float64_t );\n#endif\nvoid f64_to_extF80M( float64_t, extFloat80_t * );\nvoid f64_to_f128M( float64_t, float128_t * );\nfloat64_t f64_roundToInt( float64_t, uint_fast8_t, bool );\nfloat64_t f64_add( float64_t, float64_t );\nfloat64_t f64_sub( float64_t, float64_t );\nfloat64_t f64_mul( float64_t, float64_t );\nfloat64_t f64_mulAdd( float64_t, float64_t, float64_t );\nfloat64_t f64_div( float64_t, float64_t );\nfloat64_t f64_rem( float64_t, float64_t );\nfloat64_t f64_sqrt( float64_t );\nbool f64_eq( float64_t, float64_t );\nbool f64_le( float64_t, float64_t );\nbool f64_lt( float64_t, float64_t );\nbool f64_eq_signaling( float64_t, float64_t );\nbool f64_le_quiet( float64_t, float64_t );\nbool f64_lt_quiet( float64_t, float64_t );\nbool f64_isSignalingNaN( float64_t );\nuint_fast16_t f64_classify( float64_t );\n\n/*----------------------------------------------------------------------------\n| Rounding precision for 80-bit extended double-precision floating-point.\n| Valid values are 32, 64, and 80.\n*----------------------------------------------------------------------------*/\nextern THREAD_LOCAL uint_fast8_t extF80_roundingPrecision;\n\n/*----------------------------------------------------------------------------\n| 80-bit extended double-precision floating-point operations.\n*----------------------------------------------------------------------------*/\n#ifdef SOFTFLOAT_FAST_INT64\nuint_fast32_t extF80_to_ui32( extFloat80_t, uint_fast8_t, bool );\nuint_fast64_t extF80_to_ui64( extFloat80_t, uint_fast8_t, bool );\nint_fast32_t extF80_to_i32( extFloat80_t, uint_fast8_t, bool );\nint_fast64_t extF80_to_i64( extFloat80_t, uint_fast8_t, bool );\nuint_fast32_t extF80_to_ui32_r_minMag( extFloat80_t, bool );\nuint_fast64_t extF80_to_ui64_r_minMag( extFloat80_t, bool );\nint_fast32_t extF80_to_i32_r_minMag( extFloat80_t, bool );\nint_fast64_t extF80_to_i64_r_minMag( extFloat80_t, bool );\nfloat16_t extF80_to_f16( extFloat80_t );\nfloat32_t extF80_to_f32( extFloat80_t );\nfloat64_t extF80_to_f64( extFloat80_t );\nfloat128_t extF80_to_f128( extFloat80_t );\nextFloat80_t extF80_roundToInt( extFloat80_t, uint_fast8_t, bool );\nextFloat80_t extF80_add( extFloat80_t, extFloat80_t );\nextFloat80_t extF80_sub( extFloat80_t, extFloat80_t );\nextFloat80_t extF80_mul( extFloat80_t, extFloat80_t );\nextFloat80_t extF80_div( extFloat80_t, extFloat80_t );\nextFloat80_t extF80_rem( extFloat80_t, extFloat80_t );\nextFloat80_t extF80_sqrt( extFloat80_t );\nbool extF80_eq( extFloat80_t, extFloat80_t );\nbool extF80_le( extFloat80_t, extFloat80_t );\nbool extF80_lt( extFloat80_t, extFloat80_t );\nbool extF80_eq_signaling( extFloat80_t, extFloat80_t );\nbool extF80_le_quiet( extFloat80_t, extFloat80_t );\nbool extF80_lt_quiet( extFloat80_t, extFloat80_t );\nbool extF80_isSignalingNaN( extFloat80_t );\n#endif\nuint_fast32_t extF80M_to_ui32( const extFloat80_t *, uint_fast8_t, bool );\nuint_fast64_t extF80M_to_ui64( const extFloat80_t *, uint_fast8_t, bool );\nint_fast32_t extF80M_to_i32( const extFloat80_t *, uint_fast8_t, bool );\nint_fast64_t extF80M_to_i64( const extFloat80_t *, uint_fast8_t, bool );\nuint_fast32_t extF80M_to_ui32_r_minMag( const extFloat80_t *, bool );\nuint_fast64_t extF80M_to_ui64_r_minMag( const extFloat80_t *, bool );\nint_fast32_t extF80M_to_i32_r_minMag( const extFloat80_t *, bool );\nint_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *, bool );\nfloat16_t extF80M_to_f16( const extFloat80_t * );\nfloat32_t extF80M_to_f32( const extFloat80_t * );\nfloat64_t extF80M_to_f64( const extFloat80_t * );\nvoid extF80M_to_f128M( const extFloat80_t *, float128_t * );\nvoid\n extF80M_roundToInt(\n     const extFloat80_t *, uint_fast8_t, bool, extFloat80_t * );\nvoid extF80M_add( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );\nvoid extF80M_sub( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );\nvoid extF80M_mul( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );\nvoid extF80M_div( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );\nvoid extF80M_rem( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );\nvoid extF80M_sqrt( const extFloat80_t *, extFloat80_t * );\nbool extF80M_eq( const extFloat80_t *, const extFloat80_t * );\nbool extF80M_le( const extFloat80_t *, const extFloat80_t * );\nbool extF80M_lt( const extFloat80_t *, const extFloat80_t * );\nbool extF80M_eq_signaling( const extFloat80_t *, const extFloat80_t * );\nbool extF80M_le_quiet( const extFloat80_t *, const extFloat80_t * );\nbool extF80M_lt_quiet( const extFloat80_t *, const extFloat80_t * );\nbool extF80M_isSignalingNaN( const extFloat80_t * );\n\n/*----------------------------------------------------------------------------\n| 128-bit (quadruple-precision) floating-point operations.\n*----------------------------------------------------------------------------*/\n#ifdef SOFTFLOAT_FAST_INT64\nuint_fast32_t f128_to_ui32( float128_t, uint_fast8_t, bool );\nuint_fast64_t f128_to_ui64( float128_t, uint_fast8_t, bool );\nint_fast32_t f128_to_i32( float128_t, uint_fast8_t, bool );\nint_fast64_t f128_to_i64( float128_t, uint_fast8_t, bool );\nuint_fast32_t f128_to_ui32_r_minMag( float128_t, bool );\nuint_fast64_t f128_to_ui64_r_minMag( float128_t, bool );\nint_fast32_t f128_to_i32_r_minMag( float128_t, bool );\nint_fast64_t f128_to_i64_r_minMag( float128_t, bool );\nfloat16_t f128_to_f16( float128_t );\nfloat32_t f128_to_f32( float128_t );\nfloat64_t f128_to_f64( float128_t );\nextFloat80_t f128_to_extF80( float128_t );\nfloat128_t f128_roundToInt( float128_t, uint_fast8_t, bool );\nfloat128_t f128_add( float128_t, float128_t );\nfloat128_t f128_sub( float128_t, float128_t );\nfloat128_t f128_mul( float128_t, float128_t );\nfloat128_t f128_mulAdd( float128_t, float128_t, float128_t );\nfloat128_t f128_div( float128_t, float128_t );\nfloat128_t f128_rem( float128_t, float128_t );\nfloat128_t f128_sqrt( float128_t );\nbool f128_eq( float128_t, float128_t );\nbool f128_le( float128_t, float128_t );\nbool f128_lt( float128_t, float128_t );\nbool f128_eq_signaling( float128_t, float128_t );\nbool f128_le_quiet( float128_t, float128_t );\nbool f128_lt_quiet( float128_t, float128_t );\nbool f128_isSignalingNaN( float128_t );\nuint_fast16_t f128_classify( float128_t );\n#endif\nuint_fast32_t f128M_to_ui32( const float128_t *, uint_fast8_t, bool );\nuint_fast64_t f128M_to_ui64( const float128_t *, uint_fast8_t, bool );\nint_fast32_t f128M_to_i32( const float128_t *, uint_fast8_t, bool );\nint_fast64_t f128M_to_i64( const float128_t *, uint_fast8_t, bool );\nuint_fast32_t f128M_to_ui32_r_minMag( const float128_t *, bool );\nuint_fast64_t f128M_to_ui64_r_minMag( const float128_t *, bool );\nint_fast32_t f128M_to_i32_r_minMag( const float128_t *, bool );\nint_fast64_t f128M_to_i64_r_minMag( const float128_t *, bool );\nfloat16_t f128M_to_f16( const float128_t * );\nfloat32_t f128M_to_f32( const float128_t * );\nfloat64_t f128M_to_f64( const float128_t * );\nvoid f128M_to_extF80M( const float128_t *, extFloat80_t * );\nvoid f128M_roundToInt( const float128_t *, uint_fast8_t, bool, float128_t * );\nvoid f128M_add( const float128_t *, const float128_t *, float128_t * );\nvoid f128M_sub( const float128_t *, const float128_t *, float128_t * );\nvoid f128M_mul( const float128_t *, const float128_t *, float128_t * );\nvoid\n f128M_mulAdd(\n     const float128_t *, const float128_t *, const float128_t *, float128_t *\n );\nvoid f128M_div( const float128_t *, const float128_t *, float128_t * );\nvoid f128M_rem( const float128_t *, const float128_t *, float128_t * );\nvoid f128M_sqrt( const float128_t *, float128_t * );\nbool f128M_eq( const float128_t *, const float128_t * );\nbool f128M_le( const float128_t *, const float128_t * );\nbool f128M_lt( const float128_t *, const float128_t * );\nbool f128M_eq_signaling( const float128_t *, const float128_t * );\nbool f128M_le_quiet( const float128_t *, const float128_t * );\nbool f128M_lt_quiet( const float128_t *, const float128_t * );\nbool f128M_isSignalingNaN( const float128_t * );\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/include/softfloat/softfloat.hpp",
    "content": "#pragma once\nextern \"C\" {\n#include \"softfloat.h\"\n}\n"
  },
  {
    "path": "vp/src/vendor/softfloat/include/softfloat/softfloat_types.h",
    "content": "\n/*============================================================================\n\nThis C header file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#ifndef softfloat_types_h\n#define softfloat_types_h 1\n\n#include <stdint.h>\n\n/*----------------------------------------------------------------------------\n| Types used to pass 16-bit, 32-bit, 64-bit, and 128-bit floating-point\n| arguments and results to/from functions.  These types must be exactly\n| 16 bits, 32 bits, 64 bits, and 128 bits in size, respectively.  Where a\n| platform has \"native\" support for IEEE-Standard floating-point formats,\n| the types below may, if desired, be defined as aliases for the native types\n| (typically 'float' and 'double', and possibly 'long double').\n*----------------------------------------------------------------------------*/\ntypedef struct { uint16_t v; } float16_t;\ntypedef struct { uint32_t v; } float32_t;\ntypedef struct { uint64_t v; } float64_t;\ntypedef struct { uint64_t v[2]; } float128_t;\n\n/*----------------------------------------------------------------------------\n| The format of an 80-bit extended floating-point number in memory.  This\n| structure must contain a 16-bit field named 'signExp' and a 64-bit field\n| named 'signif'.\n*----------------------------------------------------------------------------*/\n#ifdef LITTLEENDIAN\nstruct extFloat80M { uint64_t signif; uint16_t signExp; };\n#else\nstruct extFloat80M { uint16_t signExp; uint64_t signif; };\n#endif\n\n/*----------------------------------------------------------------------------\n| The type used to pass 80-bit extended floating-point arguments and\n| results to/from functions.  This type must have size identical to\n| 'struct extFloat80M'.  Type 'extFloat80_t' can be defined as an alias for\n| 'struct extFloat80M'.  Alternatively, if a platform has \"native\" support\n| for IEEE-Standard 80-bit extended floating-point, it may be possible,\n| if desired, to define 'extFloat80_t' as an alias for the native type\n| (presumably either 'long double' or a nonstandard compiler-intrinsic type).\n| In that case, the 'signif' and 'signExp' fields of 'struct extFloat80M'\n| must align exactly with the locations in memory of the sign, exponent, and\n| significand of the native type.\n*----------------------------------------------------------------------------*/\ntypedef struct extFloat80M extFloat80_t;\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/include/softfloat/specialize.h",
    "content": "\n/*============================================================================\n\nThis C header file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#ifndef specialize_h\n#define specialize_h 1\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"primitiveTypes.h\"\n#include \"softfloat.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*----------------------------------------------------------------------------\n| Default value for `softfloat_detectTininess'.\n*----------------------------------------------------------------------------*/\n#define init_detectTininess softfloat_tininess_afterRounding\n\n/*----------------------------------------------------------------------------\n| The values to return on conversions to 32-bit integer formats that raise an\n| invalid exception.\n*----------------------------------------------------------------------------*/\n#define ui32_fromPosOverflow 0xFFFFFFFF\n#define ui32_fromNegOverflow 0\n#define ui32_fromNaN         0xFFFFFFFF\n#define i32_fromPosOverflow  0x7FFFFFFF\n#define i32_fromNegOverflow  (-0x7FFFFFFF - 1)\n#define i32_fromNaN          0x7FFFFFFF\n\n/*----------------------------------------------------------------------------\n| The values to return on conversions to 64-bit integer formats that raise an\n| invalid exception.\n*----------------------------------------------------------------------------*/\n#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF )\n#define ui64_fromNegOverflow 0\n#define ui64_fromNaN         UINT64_C( 0xFFFFFFFFFFFFFFFF )\n#define i64_fromPosOverflow  UINT64_C( 0x7FFFFFFFFFFFFFFF )\n#define i64_fromNegOverflow  (-UINT64_C( 0x7FFFFFFFFFFFFFFF ) - 1)\n#define i64_fromNaN          UINT64_C( 0x7FFFFFFFFFFFFFFF )\n\n/*----------------------------------------------------------------------------\n| \"Common NaN\" structure, used to transfer NaN representations from one format\n| to another.\n*----------------------------------------------------------------------------*/\nstruct commonNaN { char _unused; };\n\n/*----------------------------------------------------------------------------\n| The bit pattern for a default generated 16-bit floating-point NaN.\n*----------------------------------------------------------------------------*/\n#define defaultNaNF16UI 0x7E00\n\n/*----------------------------------------------------------------------------\n| Returns true when 16-bit unsigned integer `uiA' has the bit pattern of a\n| 16-bit floating-point signaling NaN.\n| Note:  This macro evaluates its argument more than once.\n*----------------------------------------------------------------------------*/\n#define softfloat_isSigNaNF16UI( uiA ) ((((uiA) & 0x7E00) == 0x7C00) && ((uiA) & 0x01FF))\n\n/*----------------------------------------------------------------------------\n| Assuming `uiA' has the bit pattern of a 16-bit floating-point NaN, converts\n| this NaN to the common NaN form, and stores the resulting common NaN at the\n| location pointed to by `zPtr'.  If the NaN is a signaling NaN, the invalid\n| exception is raised.\n*----------------------------------------------------------------------------*/\n#define softfloat_f16UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x0200) ) softfloat_raiseFlags( softfloat_flag_invalid )\n\n/*----------------------------------------------------------------------------\n| Converts the common NaN pointed to by `aPtr' into a 16-bit floating-point\n| NaN, and returns the bit pattern of this value as an unsigned integer.\n*----------------------------------------------------------------------------*/\n#define softfloat_commonNaNToF16UI( aPtr ) ((uint_fast16_t) defaultNaNF16UI)\n\n/*----------------------------------------------------------------------------\n| Interpreting `uiA' and `uiB' as the bit patterns of two 16-bit floating-\n| point values, at least one of which is a NaN, returns the bit pattern of\n| the combined NaN result.  If either `uiA' or `uiB' has the pattern of a\n| signaling NaN, the invalid exception is raised.\n*----------------------------------------------------------------------------*/\nuint_fast16_t\n softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );\n\n/*----------------------------------------------------------------------------\n| The bit pattern for a default generated 32-bit floating-point NaN.\n*----------------------------------------------------------------------------*/\n#define defaultNaNF32UI 0x7FC00000\n\n/*----------------------------------------------------------------------------\n| Returns true when 32-bit unsigned integer `uiA' has the bit pattern of a\n| 32-bit floating-point signaling NaN.\n| Note:  This macro evaluates its argument more than once.\n*----------------------------------------------------------------------------*/\n#define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF))\n\n/*----------------------------------------------------------------------------\n| Assuming `uiA' has the bit pattern of a 32-bit floating-point NaN, converts\n| this NaN to the common NaN form, and stores the resulting common NaN at the\n| location pointed to by `zPtr'.  If the NaN is a signaling NaN, the invalid\n| exception is raised.\n*----------------------------------------------------------------------------*/\n#define softfloat_f32UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x00400000) ) softfloat_raiseFlags( softfloat_flag_invalid )\n\n/*----------------------------------------------------------------------------\n| Converts the common NaN pointed to by `aPtr' into a 32-bit floating-point\n| NaN, and returns the bit pattern of this value as an unsigned integer.\n*----------------------------------------------------------------------------*/\n#define softfloat_commonNaNToF32UI( aPtr ) ((uint_fast32_t) defaultNaNF32UI)\n\n/*----------------------------------------------------------------------------\n| Interpreting `uiA' and `uiB' as the bit patterns of two 32-bit floating-\n| point values, at least one of which is a NaN, returns the bit pattern of\n| the combined NaN result.  If either `uiA' or `uiB' has the pattern of a\n| signaling NaN, the invalid exception is raised.\n*----------------------------------------------------------------------------*/\nuint_fast32_t\n softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );\n\n/*----------------------------------------------------------------------------\n| The bit pattern for a default generated 64-bit floating-point NaN.\n*----------------------------------------------------------------------------*/\n#define defaultNaNF64UI UINT64_C( 0x7FF8000000000000 )\n\n/*----------------------------------------------------------------------------\n| Returns true when 64-bit unsigned integer `uiA' has the bit pattern of a\n| 64-bit floating-point signaling NaN.\n| Note:  This macro evaluates its argument more than once.\n*----------------------------------------------------------------------------*/\n#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF )))\n\n/*----------------------------------------------------------------------------\n| Assuming `uiA' has the bit pattern of a 64-bit floating-point NaN, converts\n| this NaN to the common NaN form, and stores the resulting common NaN at the\n| location pointed to by `zPtr'.  If the NaN is a signaling NaN, the invalid\n| exception is raised.\n*----------------------------------------------------------------------------*/\n#define softfloat_f64UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & UINT64_C( 0x0008000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid )\n\n/*----------------------------------------------------------------------------\n| Converts the common NaN pointed to by `aPtr' into a 64-bit floating-point\n| NaN, and returns the bit pattern of this value as an unsigned integer.\n*----------------------------------------------------------------------------*/\n#define softfloat_commonNaNToF64UI( aPtr ) ((uint_fast64_t) defaultNaNF64UI)\n\n/*----------------------------------------------------------------------------\n| Interpreting `uiA' and `uiB' as the bit patterns of two 64-bit floating-\n| point values, at least one of which is a NaN, returns the bit pattern of\n| the combined NaN result.  If either `uiA' or `uiB' has the pattern of a\n| signaling NaN, the invalid exception is raised.\n*----------------------------------------------------------------------------*/\nuint_fast64_t\n softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );\n\n/*----------------------------------------------------------------------------\n| The bit pattern for a default generated 80-bit extended floating-point NaN.\n*----------------------------------------------------------------------------*/\n#define defaultNaNExtF80UI64 0x7FFF\n#define defaultNaNExtF80UI0  UINT64_C( 0xC000000000000000 )\n\n/*----------------------------------------------------------------------------\n| Returns true when the 80-bit unsigned integer formed from concatenating\n| 16-bit `uiA64' and 64-bit `uiA0' has the bit pattern of an 80-bit extended\n| floating-point signaling NaN.\n| Note:  This macro evaluates its arguments more than once.\n*----------------------------------------------------------------------------*/\n#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF )))\n\n#ifdef SOFTFLOAT_FAST_INT64\n\n/*----------------------------------------------------------------------------\n| The following functions are needed only when `SOFTFLOAT_FAST_INT64' is\n| defined.\n*----------------------------------------------------------------------------*/\n\n/*----------------------------------------------------------------------------\n| Assuming the unsigned integer formed from concatenating `uiA64' and `uiA0'\n| has the bit pattern of an 80-bit extended floating-point NaN, converts\n| this NaN to the common NaN form, and stores the resulting common NaN at the\n| location pointed to by `zPtr'.  If the NaN is a signaling NaN, the invalid\n| exception is raised.\n*----------------------------------------------------------------------------*/\n#define softfloat_extF80UIToCommonNaN( uiA64, uiA0, zPtr ) if ( ! ((uiA0) & UINT64_C( 0x4000000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid )\n\n/*----------------------------------------------------------------------------\n| Converts the common NaN pointed to by `aPtr' into an 80-bit extended\n| floating-point NaN, and returns the bit pattern of this value as an unsigned\n| integer.\n*----------------------------------------------------------------------------*/\n#if defined INLINE && ! defined softfloat_commonNaNToExtF80UI\nINLINE\nstruct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr )\n{\n    struct uint128 uiZ;\n    uiZ.v64 = defaultNaNExtF80UI64;\n    uiZ.v0  = defaultNaNExtF80UI0;\n    return uiZ;\n}\n#else\nstruct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );\n#endif\n\n/*----------------------------------------------------------------------------\n| Interpreting the unsigned integer formed from concatenating `uiA64' and\n| `uiA0' as an 80-bit extended floating-point value, and likewise interpreting\n| the unsigned integer formed from concatenating `uiB64' and `uiB0' as another\n| 80-bit extended floating-point value, and assuming at least on of these\n| floating-point values is a NaN, returns the bit pattern of the combined NaN\n| result.  If either original floating-point value is a signaling NaN, the\n| invalid exception is raised.\n*----------------------------------------------------------------------------*/\nstruct uint128\n softfloat_propagateNaNExtF80UI(\n     uint_fast16_t uiA64,\n     uint_fast64_t uiA0,\n     uint_fast16_t uiB64,\n     uint_fast64_t uiB0\n );\n\n/*----------------------------------------------------------------------------\n| The bit pattern for a default generated 128-bit floating-point NaN.\n*----------------------------------------------------------------------------*/\n#define defaultNaNF128UI64 UINT64_C( 0x7FFF800000000000 )\n#define defaultNaNF128UI0  UINT64_C( 0 )\n\n/*----------------------------------------------------------------------------\n| Returns true when the 128-bit unsigned integer formed from concatenating\n| 64-bit `uiA64' and 64-bit `uiA0' has the bit pattern of a 128-bit floating-\n| point signaling NaN.\n| Note:  This macro evaluates its arguments more than once.\n*----------------------------------------------------------------------------*/\n#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF ))))\n\n/*----------------------------------------------------------------------------\n| Assuming the unsigned integer formed from concatenating `uiA64' and `uiA0'\n| has the bit pattern of a 128-bit floating-point NaN, converts this NaN to\n| the common NaN form, and stores the resulting common NaN at the location\n| pointed to by `zPtr'.  If the NaN is a signaling NaN, the invalid exception\n| is raised.\n*----------------------------------------------------------------------------*/\n#define softfloat_f128UIToCommonNaN( uiA64, uiA0, zPtr ) if ( ! ((uiA64) & UINT64_C( 0x0000800000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid )\n\n/*----------------------------------------------------------------------------\n| Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point\n| NaN, and returns the bit pattern of this value as an unsigned integer.\n*----------------------------------------------------------------------------*/\n#if defined INLINE && ! defined softfloat_commonNaNToF128UI\nINLINE\nstruct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr )\n{\n    struct uint128 uiZ;\n    uiZ.v64 = defaultNaNF128UI64;\n    uiZ.v0  = defaultNaNF128UI0;\n    return uiZ;\n}\n#else\nstruct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );\n#endif\n\n/*----------------------------------------------------------------------------\n| Interpreting the unsigned integer formed from concatenating `uiA64' and\n| `uiA0' as a 128-bit floating-point value, and likewise interpreting the\n| unsigned integer formed from concatenating `uiB64' and `uiB0' as another\n| 128-bit floating-point value, and assuming at least on of these floating-\n| point values is a NaN, returns the bit pattern of the combined NaN result.\n| If either original floating-point value is a signaling NaN, the invalid\n| exception is raised.\n*----------------------------------------------------------------------------*/\nstruct uint128\n softfloat_propagateNaNF128UI(\n     uint_fast64_t uiA64,\n     uint_fast64_t uiA0,\n     uint_fast64_t uiB64,\n     uint_fast64_t uiB0\n );\n\n#else\n\n/*----------------------------------------------------------------------------\n| The following functions are needed only when `SOFTFLOAT_FAST_INT64' is not\n| defined.\n*----------------------------------------------------------------------------*/\n\n/*----------------------------------------------------------------------------\n| Assuming the 80-bit extended floating-point value pointed to by `aSPtr' is\n| a NaN, converts this NaN to the common NaN form, and stores the resulting\n| common NaN at the location pointed to by `zPtr'.  If the NaN is a signaling\n| NaN, the invalid exception is raised.\n*----------------------------------------------------------------------------*/\n#define softfloat_extF80MToCommonNaN( aSPtr, zPtr ) if ( ! ((aSPtr)->signif & UINT64_C( 0x4000000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid )\n\n/*----------------------------------------------------------------------------\n| Converts the common NaN pointed to by `aPtr' into an 80-bit extended\n| floating-point NaN, and stores this NaN at the location pointed to by\n| `zSPtr'.\n*----------------------------------------------------------------------------*/\n#if defined INLINE && ! defined softfloat_commonNaNToExtF80M\nINLINE\nvoid\n softfloat_commonNaNToExtF80M(\n     const struct commonNaN *aPtr, struct extFloat80M *zSPtr )\n{\n    zSPtr->signExp = defaultNaNExtF80UI64;\n    zSPtr->signif  = defaultNaNExtF80UI0;\n}\n#else\nvoid\n softfloat_commonNaNToExtF80M(\n     const struct commonNaN *aPtr, struct extFloat80M *zSPtr );\n#endif\n\n/*----------------------------------------------------------------------------\n| Assuming at least one of the two 80-bit extended floating-point values\n| pointed to by `aSPtr' and `bSPtr' is a NaN, stores the combined NaN result\n| at the location pointed to by `zSPtr'.  If either original floating-point\n| value is a signaling NaN, the invalid exception is raised.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_propagateNaNExtF80M(\n     const struct extFloat80M *aSPtr,\n     const struct extFloat80M *bSPtr,\n     struct extFloat80M *zSPtr\n );\n\n/*----------------------------------------------------------------------------\n| The bit pattern for a default generated 128-bit floating-point NaN.\n*----------------------------------------------------------------------------*/\n#define defaultNaNF128UI96 0x7FFF8000\n#define defaultNaNF128UI64 0\n#define defaultNaNF128UI32 0\n#define defaultNaNF128UI0  0\n\n/*----------------------------------------------------------------------------\n| Assuming the 128-bit floating-point value pointed to by `aWPtr' is a NaN,\n| converts this NaN to the common NaN form, and stores the resulting common\n| NaN at the location pointed to by `zPtr'.  If the NaN is a signaling NaN,\n| the invalid exception is raised.  Argument `aWPtr' points to an array of\n| four 32-bit elements that concatenate in the platform's normal endian order\n| to form a 128-bit floating-point value.\n*----------------------------------------------------------------------------*/\n#define softfloat_f128MToCommonNaN( aWPtr, zPtr ) if ( ! ((aWPtr)[indexWordHi( 4 )] & UINT64_C( 0x0000800000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid )\n\n/*----------------------------------------------------------------------------\n| Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point\n| NaN, and stores this NaN at the location pointed to by `zWPtr'.  Argument\n| `zWPtr' points to an array of four 32-bit elements that concatenate in the\n| platform's normal endian order to form a 128-bit floating-point value.\n*----------------------------------------------------------------------------*/\n#if defined INLINE && ! defined softfloat_commonNaNToF128M\nINLINE\nvoid\n softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr )\n{\n    zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96;\n    zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64;\n    zWPtr[indexWord( 4, 1 )] = defaultNaNF128UI32;\n    zWPtr[indexWord( 4, 0 )] = defaultNaNF128UI0;\n}\n#else\nvoid\n softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );\n#endif\n\n/*----------------------------------------------------------------------------\n| Assuming at least one of the two 128-bit floating-point values pointed to by\n| `aWPtr' and `bWPtr' is a NaN, stores the combined NaN result at the location\n| pointed to by `zWPtr'.  If either original floating-point value is a\n| signaling NaN, the invalid exception is raised.  Each of `aWPtr', `bWPtr',\n| and `zWPtr' points to an array of four 32-bit elements that concatenate in\n| the platform's normal endian order to form a 128-bit floating-point value.\n*----------------------------------------------------------------------------*/\nvoid\n softfloat_propagateNaNF128M(\n     const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_add128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_add128\n\nstruct uint128\n softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )\n{\n    struct uint128 z;\n\n    z.v0 = a0 + b0;\n    z.v64 = a64 + b64 + (z.v0 < a0);\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_add256M.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_add256M\n\nvoid\n softfloat_add256M(\n     const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr )\n{\n    unsigned int index;\n    uint_fast8_t carry;\n    uint64_t wordA, wordZ;\n\n    index = indexWordLo( 4 );\n    carry = 0;\n    for (;;) {\n        wordA = aPtr[index];\n        wordZ = wordA + bPtr[index] + carry;\n        zPtr[index] = wordZ;\n        if ( index == indexWordHi( 4 ) ) break;\n        if ( wordZ != wordA ) carry = (wordZ < wordA);\n        index += wordIncr;\n    }\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_addCarryM.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_addCarryM\n\nuint_fast8_t\n softfloat_addCarryM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     const uint32_t *bPtr,\n     uint_fast8_t carry,\n     uint32_t *zPtr\n )\n{\n    unsigned int index, lastIndex;\n    uint32_t wordA, wordZ;\n\n    index = indexWordLo( size_words );\n    lastIndex = indexWordHi( size_words );\n    for (;;) {\n        wordA = aPtr[index];\n        wordZ = wordA + bPtr[index] + carry;\n        zPtr[index] = wordZ;\n        if ( wordZ != wordA ) carry = (wordZ < wordA);\n        if ( index == lastIndex ) break;\n        index += wordIncr;\n    }\n    return carry;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_addComplCarryM.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_addComplCarryM\n\nuint_fast8_t\n softfloat_addComplCarryM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     const uint32_t *bPtr,\n     uint_fast8_t carry,\n     uint32_t *zPtr\n )\n{\n    unsigned int index, lastIndex;\n    uint32_t wordA, wordZ;\n\n    index = indexWordLo( size_words );\n    lastIndex = indexWordHi( size_words );\n    for (;;) {\n        wordA = aPtr[index];\n        wordZ = wordA + ~bPtr[index] + carry;\n        zPtr[index] = wordZ;\n        if ( wordZ != wordA ) carry = (wordZ < wordA);\n        if ( index == lastIndex ) break;\n        index += wordIncr;\n    }\n    return carry;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_addM.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_addM\n\nvoid\n softfloat_addM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     const uint32_t *bPtr,\n     uint32_t *zPtr\n )\n{\n    unsigned int index, lastIndex;\n    uint_fast8_t carry;\n    uint32_t wordA, wordZ;\n\n    index = indexWordLo( size_words );\n    lastIndex = indexWordHi( size_words );\n    carry = 0;\n    for (;;) {\n        wordA = aPtr[index];\n        wordZ = wordA + bPtr[index] + carry;\n        zPtr[index] = wordZ;\n        if ( index == lastIndex ) break;\n        if ( wordZ != wordA ) carry = (wordZ < wordA);\n        index += wordIncr;\n    }\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_addMagsF128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n\nfloat128_t\n softfloat_addMagsF128(\n     uint_fast64_t uiA64,\n     uint_fast64_t uiA0,\n     uint_fast64_t uiB64,\n     uint_fast64_t uiB0,\n     bool signZ\n )\n{\n    int_fast32_t expA;\n    struct uint128 sigA;\n    int_fast32_t expB;\n    struct uint128 sigB;\n    int_fast32_t expDiff;\n    struct uint128 uiZ, sigZ;\n    int_fast32_t expZ;\n    uint_fast64_t sigZExtra;\n    struct uint128_extra sig128Extra;\n    union ui128_f128 uZ;\n\n    expA = expF128UI64( uiA64 );\n    sigA.v64 = fracF128UI64( uiA64 );\n    sigA.v0  = uiA0;\n    expB = expF128UI64( uiB64 );\n    sigB.v64 = fracF128UI64( uiB64 );\n    sigB.v0  = uiB0;\n    expDiff = expA - expB;\n    if ( ! expDiff ) {\n        if ( expA == 0x7FFF ) {\n            if ( sigA.v64 | sigA.v0 | sigB.v64 | sigB.v0 ) goto propagateNaN;\n            uiZ.v64 = uiA64;\n            uiZ.v0  = uiA0;\n            goto uiZ;\n        }\n        sigZ = softfloat_add128( sigA.v64, sigA.v0, sigB.v64, sigB.v0 );\n        if ( ! expA ) {\n            uiZ.v64 = packToF128UI64( signZ, 0, sigZ.v64 );\n            uiZ.v0  = sigZ.v0;\n            goto uiZ;\n        }\n        expZ = expA;\n        sigZ.v64 |= UINT64_C( 0x0002000000000000 );\n        sigZExtra = 0;\n        goto shiftRight1;\n    }\n    if ( expDiff < 0 ) {\n        if ( expB == 0x7FFF ) {\n            if ( sigB.v64 | sigB.v0 ) goto propagateNaN;\n            uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 );\n            uiZ.v0  = 0;\n            goto uiZ;\n        }\n        expZ = expB;\n        if ( expA ) {\n            sigA.v64 |= UINT64_C( 0x0001000000000000 );\n        } else {\n            ++expDiff;\n            sigZExtra = 0;\n            if ( ! expDiff ) goto newlyAligned;\n        }\n        sig128Extra =\n            softfloat_shiftRightJam128Extra( sigA.v64, sigA.v0, 0, -expDiff );\n        sigA = sig128Extra.v;\n        sigZExtra = sig128Extra.extra;\n    } else {\n        if ( expA == 0x7FFF ) {\n            if ( sigA.v64 | sigA.v0 ) goto propagateNaN;\n            uiZ.v64 = uiA64;\n            uiZ.v0  = uiA0;\n            goto uiZ;\n        }\n        expZ = expA;\n        if ( expB ) {\n            sigB.v64 |= UINT64_C( 0x0001000000000000 );\n        } else {\n            --expDiff;\n            sigZExtra = 0;\n            if ( ! expDiff ) goto newlyAligned;\n        }\n        sig128Extra =\n            softfloat_shiftRightJam128Extra( sigB.v64, sigB.v0, 0, expDiff );\n        sigB = sig128Extra.v;\n        sigZExtra = sig128Extra.extra;\n    }\n newlyAligned:\n    sigZ =\n        softfloat_add128(\n            sigA.v64 | UINT64_C( 0x0001000000000000 ),\n            sigA.v0,\n            sigB.v64,\n            sigB.v0\n        );\n    --expZ;\n    if ( sigZ.v64 < UINT64_C( 0x0002000000000000 ) ) goto roundAndPack;\n    ++expZ;\n shiftRight1:\n    sig128Extra =\n        softfloat_shortShiftRightJam128Extra(\n            sigZ.v64, sigZ.v0, sigZExtra, 1 );\n    sigZ = sig128Extra.v;\n    sigZExtra = sig128Extra.extra;\n roundAndPack:\n    return\n        softfloat_roundPackToF128( signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra );\n propagateNaN:\n    uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_addMagsF16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat16_t softfloat_addMagsF16( uint_fast16_t uiA, uint_fast16_t uiB )\n{\n    int_fast8_t expA;\n    uint_fast16_t sigA;\n    int_fast8_t expB;\n    uint_fast16_t sigB;\n    int_fast8_t expDiff;\n    uint_fast16_t uiZ;\n    bool signZ;\n    int_fast8_t expZ;\n    uint_fast16_t sigZ;\n    uint_fast16_t sigX, sigY;\n    int_fast8_t shiftDist;\n    uint_fast32_t sig32Z;\n    int_fast8_t roundingMode;\n    union ui16_f16 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expA = expF16UI( uiA );\n    sigA = fracF16UI( uiA );\n    expB = expF16UI( uiB );\n    sigB = fracF16UI( uiB );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expDiff = expA - expB;\n    if ( ! expDiff ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( ! expA ) {\n            uiZ = uiA + sigB;\n            goto uiZ;\n        }\n        if ( expA == 0x1F ) {\n            if ( sigA | sigB ) goto propagateNaN;\n            uiZ = uiA;\n            goto uiZ;\n        }\n        signZ = signF16UI( uiA );\n        expZ = expA;\n        sigZ = 0x0800 + sigA + sigB;\n        if ( ! (sigZ & 1) && (expZ < 0x1E) ) {\n            sigZ >>= 1;\n            goto pack;\n        }\n        sigZ <<= 3;\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        signZ = signF16UI( uiA );\n        if ( expDiff < 0 ) {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            if ( expB == 0x1F ) {\n                if ( sigB ) goto propagateNaN;\n                uiZ = packToF16UI( signZ, 0x1F, 0 );\n                goto uiZ;\n            }\n            if ( expDiff <= -13 ) {\n                uiZ = packToF16UI( signZ, expB, sigB );\n                if ( expA | sigA ) goto addEpsilon;\n                goto uiZ;\n            }\n            expZ = expB;\n            sigX = sigB | 0x0400;\n            sigY = sigA + (expA ? 0x0400 : sigA);\n            shiftDist = 19 + expDiff;\n        } else {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            uiZ = uiA;\n            if ( expA == 0x1F ) {\n                if ( sigA ) goto propagateNaN;\n                goto uiZ;\n            }\n            if ( 13 <= expDiff ) {\n                if ( expB | sigB ) goto addEpsilon;\n                goto uiZ;\n            }\n            expZ = expA;\n            sigX = sigA | 0x0400;\n            sigY = sigB + (expB ? 0x0400 : sigB);\n            shiftDist = 19 - expDiff;\n        }\n        sig32Z =\n            ((uint_fast32_t) sigX<<19) + ((uint_fast32_t) sigY<<shiftDist);\n        if ( sig32Z < 0x40000000 ) {\n            --expZ;\n            sig32Z <<= 1;\n        }\n        sigZ = sig32Z>>16;\n        if ( sig32Z & 0xFFFF ) {\n            sigZ |= 1;\n        } else {\n            if ( ! (sigZ & 0xF) && (expZ < 0x1E) ) {\n                sigZ >>= 4;\n                goto pack;\n            }\n        }\n    }\n    return softfloat_roundPackToF16( signZ, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF16UI( uiA, uiB );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n addEpsilon:\n    roundingMode = softfloat_roundingMode;\n    if ( roundingMode != softfloat_round_near_even ) {\n        if (\n            roundingMode\n                == (signF16UI( uiZ ) ? softfloat_round_min\n                        : softfloat_round_max)\n        ) {\n            ++uiZ;\n            if ( (uint16_t) (uiZ<<1) == 0xF800 ) {\n                softfloat_raiseFlags(\n                    softfloat_flag_overflow | softfloat_flag_inexact );\n            }\n        }\n#ifdef SOFTFLOAT_ROUND_ODD\n        else if ( roundingMode == softfloat_round_odd ) {\n            uiZ |= 1;\n        }\n#endif\n    }\n    softfloat_exceptionFlags |= softfloat_flag_inexact;\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n pack:\n    uiZ = packToF16UI( signZ, expZ, sigZ );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_addMagsF32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n\nfloat32_t softfloat_addMagsF32( uint_fast32_t uiA, uint_fast32_t uiB )\n{\n    int_fast16_t expA;\n    uint_fast32_t sigA;\n    int_fast16_t expB;\n    uint_fast32_t sigB;\n    int_fast16_t expDiff;\n    uint_fast32_t uiZ;\n    bool signZ;\n    int_fast16_t expZ;\n    uint_fast32_t sigZ;\n    union ui32_f32 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expA = expF32UI( uiA );\n    sigA = fracF32UI( uiA );\n    expB = expF32UI( uiB );\n    sigB = fracF32UI( uiB );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expDiff = expA - expB;\n    if ( ! expDiff ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( ! expA ) {\n            uiZ = uiA + sigB;\n            goto uiZ;\n        }\n        if ( expA == 0xFF ) {\n            if ( sigA | sigB ) goto propagateNaN;\n            uiZ = uiA;\n            goto uiZ;\n        }\n        signZ = signF32UI( uiA );\n        expZ = expA;\n        sigZ = 0x01000000 + sigA + sigB;\n        if ( ! (sigZ & 1) && (expZ < 0xFE) ) {\n            uiZ = packToF32UI( signZ, expZ, sigZ>>1 );\n            goto uiZ;\n        }\n        sigZ <<= 6;\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        signZ = signF32UI( uiA );\n        sigA <<= 6;\n        sigB <<= 6;\n        if ( expDiff < 0 ) {\n            if ( expB == 0xFF ) {\n                if ( sigB ) goto propagateNaN;\n                uiZ = packToF32UI( signZ, 0xFF, 0 );\n                goto uiZ;\n            }\n            expZ = expB;\n            sigA += expA ? 0x20000000 : sigA;\n            sigA = softfloat_shiftRightJam32( sigA, -expDiff );\n        } else {\n            if ( expA == 0xFF ) {\n                if ( sigA ) goto propagateNaN;\n                uiZ = uiA;\n                goto uiZ;\n            }\n            expZ = expA;\n            sigB += expB ? 0x20000000 : sigB;\n            sigB = softfloat_shiftRightJam32( sigB, expDiff );\n        }\n        sigZ = 0x20000000 + sigA + sigB;\n        if ( sigZ < 0x40000000 ) {\n            --expZ;\n            sigZ <<= 1;\n        }\n    }\n    return softfloat_roundPackToF32( signZ, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF32UI( uiA, uiB );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_addMagsF64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n\nfloat64_t\n softfloat_addMagsF64( uint_fast64_t uiA, uint_fast64_t uiB, bool signZ )\n{\n    int_fast16_t expA;\n    uint_fast64_t sigA;\n    int_fast16_t expB;\n    uint_fast64_t sigB;\n    int_fast16_t expDiff;\n    uint_fast64_t uiZ;\n    int_fast16_t expZ;\n    uint_fast64_t sigZ;\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expA = expF64UI( uiA );\n    sigA = fracF64UI( uiA );\n    expB = expF64UI( uiB );\n    sigB = fracF64UI( uiB );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expDiff = expA - expB;\n    if ( ! expDiff ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( ! expA ) {\n            uiZ = uiA + sigB;\n            goto uiZ;\n        }\n        if ( expA == 0x7FF ) {\n            if ( sigA | sigB ) goto propagateNaN;\n            uiZ = uiA;\n            goto uiZ;\n        }\n        expZ = expA;\n        sigZ = UINT64_C( 0x0020000000000000 ) + sigA + sigB;\n        sigZ <<= 9;\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        sigA <<= 9;\n        sigB <<= 9;\n        if ( expDiff < 0 ) {\n            if ( expB == 0x7FF ) {\n                if ( sigB ) goto propagateNaN;\n                uiZ = packToF64UI( signZ, 0x7FF, 0 );\n                goto uiZ;\n            }\n            expZ = expB;\n            if ( expA ) {\n                sigA += UINT64_C( 0x2000000000000000 );\n            } else {\n                sigA <<= 1;\n            }\n            sigA = softfloat_shiftRightJam64( sigA, -expDiff );\n        } else {\n            if ( expA == 0x7FF ) {\n                if ( sigA ) goto propagateNaN;\n                uiZ = uiA;\n                goto uiZ;\n            }\n            expZ = expA;\n            if ( expB ) {\n                sigB += UINT64_C( 0x2000000000000000 );\n            } else {\n                sigB <<= 1;\n            }\n            sigB = softfloat_shiftRightJam64( sigB, expDiff );\n        }\n        sigZ = UINT64_C( 0x2000000000000000 ) + sigA + sigB;\n        if ( sigZ < UINT64_C( 0x4000000000000000 ) ) {\n            --expZ;\n            sigZ <<= 1;\n        }\n    }\n    return softfloat_roundPackToF64( signZ, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF64UI( uiA, uiB );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_approxRecip32_1.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifndef softfloat_approxRecip32_1\n\nextern const uint16_t softfloat_approxRecip_1k0s[16];\nextern const uint16_t softfloat_approxRecip_1k1s[16];\n\nuint32_t softfloat_approxRecip32_1( uint32_t a )\n{\n    int index;\n    uint16_t eps, r0;\n    uint32_t sigma0;\n    uint_fast32_t r;\n    uint32_t sqrSigma0;\n\n    index = a>>27 & 0xF;\n    eps = (uint16_t) (a>>11);\n    r0 = softfloat_approxRecip_1k0s[index]\n             - ((softfloat_approxRecip_1k1s[index] * (uint_fast32_t) eps)>>20);\n    sigma0 = ~(uint_fast32_t) ((r0 * (uint_fast64_t) a)>>7);\n    r = ((uint_fast32_t) r0<<16) + ((r0 * (uint_fast64_t) sigma0)>>24);\n    sqrSigma0 = ((uint_fast64_t) sigma0 * sigma0)>>32;\n    r += ((uint32_t) r * (uint_fast64_t) sqrSigma0)>>48;\n    return r;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_approxRecipSqrt32_1.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifndef softfloat_approxRecipSqrt32_1\n\nextern const uint16_t softfloat_approxRecipSqrt_1k0s[];\nextern const uint16_t softfloat_approxRecipSqrt_1k1s[];\n\nuint32_t softfloat_approxRecipSqrt32_1( unsigned int oddExpA, uint32_t a )\n{\n    int index;\n    uint16_t eps, r0;\n    uint_fast32_t ESqrR0;\n    uint32_t sigma0;\n    uint_fast32_t r;\n    uint32_t sqrSigma0;\n\n    index = (a>>27 & 0xE) + oddExpA;\n    eps = (uint16_t) (a>>12);\n    r0 = softfloat_approxRecipSqrt_1k0s[index]\n             - ((softfloat_approxRecipSqrt_1k1s[index] * (uint_fast32_t) eps)\n                    >>20);\n    ESqrR0 = (uint_fast32_t) r0 * r0;\n    if ( ! oddExpA ) ESqrR0 <<= 1;\n    sigma0 = ~(uint_fast32_t) (((uint32_t) ESqrR0 * (uint_fast64_t) a)>>23);\n    r = ((uint_fast32_t) r0<<16) + ((r0 * (uint_fast64_t) sigma0)>>25);\n    sqrSigma0 = ((uint_fast64_t) sigma0 * sigma0)>>32;\n    r += ((uint32_t) ((r>>1) + (r>>3) - ((uint_fast32_t) r0<<14))\n              * (uint_fast64_t) sqrSigma0)\n             >>48;\n    if ( ! (r & 0x80000000) ) r = 0x80000000;\n    return r;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_approxRecipSqrt_1Ks.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitives.h\"\n\nconst uint16_t softfloat_approxRecipSqrt_1k0s[16] = {\n    0xB4C9, 0xFFAB, 0xAA7D, 0xF11C, 0xA1C5, 0xE4C7, 0x9A43, 0xDA29,\n    0x93B5, 0xD0E5, 0x8DED, 0xC8B7, 0x88C6, 0xC16D, 0x8424, 0xBAE1\n};\nconst uint16_t softfloat_approxRecipSqrt_1k1s[16] = {\n    0xA5A5, 0xEA42, 0x8C21, 0xC62D, 0x788F, 0xAA7F, 0x6928, 0x94B6,\n    0x5CC7, 0x8335, 0x52A6, 0x74E2, 0x4A3E, 0x68FE, 0x432B, 0x5EFD\n};\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_approxRecip_1Ks.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitives.h\"\n\nconst uint16_t softfloat_approxRecip_1k0s[16] = {\n    0xFFC4, 0xF0BE, 0xE363, 0xD76F, 0xCCAD, 0xC2F0, 0xBA16, 0xB201,\n    0xAA97, 0xA3C6, 0x9D7A, 0x97A6, 0x923C, 0x8D32, 0x887E, 0x8417\n};\nconst uint16_t softfloat_approxRecip_1k1s[16] = {\n    0xF0F1, 0xD62C, 0xBFA1, 0xAC77, 0x9C0A, 0x8DDB, 0x8185, 0x76BA,\n    0x6D3B, 0x64D4, 0x5D5C, 0x56B1, 0x50B6, 0x4B55, 0x4679, 0x4211\n};\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_commonNaNToF128UI.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#define softfloat_commonNaNToF128UI softfloat_commonNaNToF128UI\n#include \"specialize.h\"\n\n/*----------------------------------------------------------------------------\n| Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point\n| NaN, and returns the bit pattern of this value as an unsigned integer.\n*----------------------------------------------------------------------------*/\nstruct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr )\n{\n    struct uint128 uiZ;\n\n    uiZ.v64 = defaultNaNF128UI64;\n    uiZ.v0  = defaultNaNF128UI0;\n    return uiZ;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_commonNaNToF16UI.c",
    "content": "\n/*----------------------------------------------------------------------------\n| This file intentionally contains no code.\n*----------------------------------------------------------------------------*/\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_commonNaNToF32UI.c",
    "content": "\n/*----------------------------------------------------------------------------\n| This file intentionally contains no code.\n*----------------------------------------------------------------------------*/\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_commonNaNToF64UI.c",
    "content": "\n/*----------------------------------------------------------------------------\n| This file intentionally contains no code.\n*----------------------------------------------------------------------------*/\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_compare128M.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_compare128M\n\nint_fast8_t softfloat_compare128M( const uint32_t *aPtr, const uint32_t *bPtr )\n{\n    unsigned int index, lastIndex;\n    uint32_t wordA, wordB;\n\n    index = indexWordHi( 4 );\n    lastIndex = indexWordLo( 4 );\n    for (;;) {\n        wordA = aPtr[index];\n        wordB = bPtr[index];\n        if ( wordA != wordB ) return (wordA < wordB) ? -1 : 1;\n        if ( index == lastIndex ) break;\n        index -= wordIncr;\n    }\n    return 0;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_compare96M.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_compare96M\n\nint_fast8_t softfloat_compare96M( const uint32_t *aPtr, const uint32_t *bPtr )\n{\n    unsigned int index, lastIndex;\n    uint32_t wordA, wordB;\n\n    index = indexWordHi( 3 );\n    lastIndex = indexWordLo( 3 );\n    for (;;) {\n        wordA = aPtr[index];\n        wordB = bPtr[index];\n        if ( wordA != wordB ) return (wordA < wordB) ? -1 : 1;\n        if ( index == lastIndex ) break;\n        index -= wordIncr;\n    }\n    return 0;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_countLeadingZeros16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifndef softfloat_countLeadingZeros16\n\n#define softfloat_countLeadingZeros16 softfloat_countLeadingZeros16\n#include \"primitives.h\"\n\nuint_fast8_t softfloat_countLeadingZeros16( uint16_t a )\n{\n    uint_fast8_t count;\n\n    count = 8;\n    if ( 0x100 <= a ) {\n        count = 0;\n        a >>= 8;\n    }\n    count += softfloat_countLeadingZeros8[a];\n    return count;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_countLeadingZeros32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifndef softfloat_countLeadingZeros32\n\n#define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32\n#include \"primitives.h\"\n\nuint_fast8_t softfloat_countLeadingZeros32( uint32_t a )\n{\n    uint_fast8_t count;\n\n    count = 0;\n    if ( a < 0x10000 ) {\n        count = 16;\n        a <<= 16;\n    }\n    if ( a < 0x1000000 ) {\n        count += 8;\n        a <<= 8;\n    }\n    count += softfloat_countLeadingZeros8[a>>24];\n    return count;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_countLeadingZeros64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifndef softfloat_countLeadingZeros64\n\n#define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64\n#include \"primitives.h\"\n\nuint_fast8_t softfloat_countLeadingZeros64( uint64_t a )\n{\n    uint_fast8_t count;\n    uint32_t a32;\n\n    count = 0;\n    a32 = a>>32;\n    if ( ! a32 ) {\n        count = 32;\n        a32 = a;\n    }\n    /*------------------------------------------------------------------------\n    | From here, result is current count + count leading zeros of `a32'.\n    *------------------------------------------------------------------------*/\n    if ( a32 < 0x10000 ) {\n        count += 16;\n        a32 <<= 16;\n    }\n    if ( a32 < 0x1000000 ) {\n        count += 8;\n        a32 <<= 8;\n    }\n    count += softfloat_countLeadingZeros8[a32>>24];\n    return count;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_countLeadingZeros8.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitives.h\"\n\nconst uint_least8_t softfloat_countLeadingZeros8[256] = {\n    8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,\n    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n};\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_eq128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifndef softfloat_eq128\n\nbool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )\n{\n\n    return (a64 == b64) && (a0 == b0);\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_f128UIToCommonNaN.c",
    "content": "\n/*----------------------------------------------------------------------------\n| This file intentionally contains no code.\n*----------------------------------------------------------------------------*/\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_f16UIToCommonNaN.c",
    "content": "\n/*----------------------------------------------------------------------------\n| This file intentionally contains no code.\n*----------------------------------------------------------------------------*/\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_f32UIToCommonNaN.c",
    "content": "\n/*----------------------------------------------------------------------------\n| This file intentionally contains no code.\n*----------------------------------------------------------------------------*/\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_f64UIToCommonNaN.c",
    "content": "\n/*----------------------------------------------------------------------------\n| This file intentionally contains no code.\n*----------------------------------------------------------------------------*/\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_le128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifndef softfloat_le128\n\nbool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )\n{\n\n    return (a64 < b64) || ((a64 == b64) && (a0 <= b0));\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_lt128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifndef softfloat_lt128\n\nbool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )\n{\n\n    return (a64 < b64) || ((a64 == b64) && (a0 < b0));\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_mul128By32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_mul128By32\n\nstruct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b )\n{\n    struct uint128 z;\n    uint_fast64_t mid;\n    uint_fast32_t carry;\n\n    z.v0 = a0 * b;\n    mid = (uint_fast64_t) (uint32_t) (a0>>32) * b;\n    carry = (uint32_t) ((uint_fast32_t) (z.v0>>32) - (uint_fast32_t) mid);\n    z.v64 = a64 * b + (uint_fast32_t) ((mid + carry)>>32);\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_mul128MTo256M.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_mul128MTo256M\n\nvoid\n softfloat_mul128MTo256M(\n     const uint32_t *aPtr, const uint32_t *bPtr, uint32_t *zPtr )\n{\n    uint32_t *lastZPtr, wordB;\n    uint64_t dwordProd;\n    uint32_t wordZ;\n    uint_fast8_t carry;\n\n    bPtr += indexWordLo( 4 );\n    lastZPtr = zPtr + indexMultiwordHi( 8, 5 );\n    zPtr += indexMultiwordLo( 8, 5 );\n    wordB = *bPtr;\n    dwordProd = (uint64_t) aPtr[indexWord( 4, 0 )] * wordB;\n    zPtr[indexWord( 5, 0 )] = dwordProd;\n    dwordProd = (uint64_t) aPtr[indexWord( 4, 1 )] * wordB + (dwordProd>>32);\n    zPtr[indexWord( 5, 1 )] = dwordProd;\n    dwordProd = (uint64_t) aPtr[indexWord( 4, 2 )] * wordB + (dwordProd>>32);\n    zPtr[indexWord( 5, 2 )] = dwordProd;\n    dwordProd = (uint64_t) aPtr[indexWord( 4, 3 )] * wordB + (dwordProd>>32);\n    zPtr[indexWord( 5, 3 )] = dwordProd;\n    zPtr[indexWord( 5, 4 )] = dwordProd>>32;\n    do {\n        bPtr += wordIncr;\n        zPtr += wordIncr;\n        wordB = *bPtr;\n        dwordProd = (uint64_t) aPtr[indexWord( 4, 0 )] * wordB;\n        wordZ = zPtr[indexWord( 5, 0 )] + (uint32_t) dwordProd;\n        zPtr[indexWord( 5, 0 )] = wordZ;\n        carry = (wordZ < (uint32_t) dwordProd);\n        dwordProd =\n            (uint64_t) aPtr[indexWord( 4, 1 )] * wordB + (dwordProd>>32);\n        wordZ = zPtr[indexWord( 5, 1 )] + (uint32_t) dwordProd + carry;\n        zPtr[indexWord( 5, 1 )] = wordZ;\n        if ( wordZ != (uint32_t) dwordProd ) {\n            carry = (wordZ < (uint32_t) dwordProd);\n        }\n        dwordProd =\n            (uint64_t) aPtr[indexWord( 4, 2 )] * wordB + (dwordProd>>32);\n        wordZ = zPtr[indexWord( 5, 2 )] + (uint32_t) dwordProd + carry;\n        zPtr[indexWord( 5, 2 )] = wordZ;\n        if ( wordZ != (uint32_t) dwordProd ) {\n            carry = (wordZ < (uint32_t) dwordProd);\n        }\n        dwordProd =\n            (uint64_t) aPtr[indexWord( 4, 3 )] * wordB + (dwordProd>>32);\n        wordZ = zPtr[indexWord( 5, 3 )] + (uint32_t) dwordProd + carry;\n        zPtr[indexWord( 5, 3 )] = wordZ;\n        if ( wordZ != (uint32_t) dwordProd ) {\n            carry = (wordZ < (uint32_t) dwordProd);\n        }\n        zPtr[indexWord( 5, 4 )] = (dwordProd>>32) + carry;\n    } while ( zPtr != lastZPtr );\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_mul128To256M.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifndef softfloat_mul128To256M\n\n#define softfloat_mul128To256M softfloat_mul128To256M\n#include \"primitives.h\"\n\nvoid\n softfloat_mul128To256M(\n     uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr )\n{\n    struct uint128 p0, p64, p128;\n    uint_fast64_t z64, z128, z192;\n\n    p0 = softfloat_mul64To128( a0, b0 );\n    zPtr[indexWord( 4, 0 )] = p0.v0;\n    p64 = softfloat_mul64To128( a64, b0 );\n    z64 = p64.v0 + p0.v64;\n    z128 = p64.v64 + (z64 < p64.v0);\n    p128 = softfloat_mul64To128( a64, b64 );\n    z128 += p128.v0;\n    z192 = p128.v64 + (z128 < p128.v0);\n    p64 = softfloat_mul64To128( a0, b64 );\n    z64 += p64.v0;\n    zPtr[indexWord( 4, 1 )] = z64;\n    p64.v64 += (z64 < p64.v0);\n    z128 += p64.v64;\n    zPtr[indexWord( 4, 2 )] = z128;\n    zPtr[indexWord( 4, 3 )] = z192 + (z128 < p64.v64);\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_mul64ByShifted32To128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_mul64ByShifted32To128\n\nstruct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b )\n{\n    uint_fast64_t mid;\n    struct uint128 z;\n\n    mid = (uint_fast64_t) (uint32_t) a * b;\n    z.v0 = mid<<32;\n    z.v64 = (uint_fast64_t) (uint32_t) (a>>32) * b + (mid>>32);\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_mul64To128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_mul64To128\n\nstruct uint128 softfloat_mul64To128( uint64_t a, uint64_t b )\n{\n    uint32_t a32, a0, b32, b0;\n    struct uint128 z;\n    uint64_t mid1, mid;\n\n    a32 = a>>32;\n    a0 = a;\n    b32 = b>>32;\n    b0 = b;\n    z.v0 = (uint_fast64_t) a0 * b0;\n    mid1 = (uint_fast64_t) a32 * b0;\n    mid = mid1 + (uint_fast64_t) a0 * b32;\n    z.v64 = (uint_fast64_t) a32 * b32;\n    z.v64 += (uint_fast64_t) (mid < mid1)<<32 | mid>>32;\n    mid <<= 32;\n    z.v0 += mid;\n    z.v64 += (z.v0 < mid);\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_mul64To128M.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_mul64To128M\n\nvoid softfloat_mul64To128M( uint64_t a, uint64_t b, uint32_t *zPtr )\n{\n    uint32_t a32, a0, b32, b0;\n    uint64_t z0, mid1, z64, mid;\n\n    a32 = a>>32;\n    a0 = a;\n    b32 = b>>32;\n    b0 = b;\n    z0 = (uint64_t) a0 * b0;\n    mid1 = (uint64_t) a32 * b0;\n    mid = mid1 + (uint64_t) a0 * b32;\n    z64 = (uint64_t) a32 * b32;\n    z64 += (uint64_t) (mid < mid1)<<32 | mid>>32;\n    mid <<= 32;\n    z0 += mid;\n    zPtr[indexWord( 4, 1 )] = z0>>32;\n    zPtr[indexWord( 4, 0 )] = z0;\n    z64 += (z0 < mid);\n    zPtr[indexWord( 4, 3 )] = z64>>32;\n    zPtr[indexWord( 4, 2 )] = z64;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_mulAddF128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat128_t\n softfloat_mulAddF128(\n     uint_fast64_t uiA64,\n     uint_fast64_t uiA0,\n     uint_fast64_t uiB64,\n     uint_fast64_t uiB0,\n     uint_fast64_t uiC64,\n     uint_fast64_t uiC0,\n     uint_fast8_t op\n )\n{\n    bool signA;\n    int_fast32_t expA;\n    struct uint128 sigA;\n    bool signB;\n    int_fast32_t expB;\n    struct uint128 sigB;\n    bool signC;\n    int_fast32_t expC;\n    struct uint128 sigC;\n    bool signZ;\n    uint_fast64_t magBits;\n    struct uint128 uiZ;\n    struct exp32_sig128 normExpSig;\n    int_fast32_t expZ;\n    uint64_t sig256Z[4];\n    struct uint128 sigZ;\n    int_fast32_t shiftDist, expDiff;\n    struct uint128 x128;\n    uint64_t sig256C[4];\n    static uint64_t zero256[4] = INIT_UINTM4( 0, 0, 0, 0 );\n    uint_fast64_t sigZExtra, sig256Z0;\n    union ui128_f128 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    signA = signF128UI64( uiA64 );\n    expA  = expF128UI64( uiA64 );\n    sigA.v64 = fracF128UI64( uiA64 );\n    sigA.v0  = uiA0;\n    signB = signF128UI64( uiB64 );\n    expB  = expF128UI64( uiB64 );\n    sigB.v64 = fracF128UI64( uiB64 );\n    sigB.v0  = uiB0;\n    signC = signF128UI64( uiC64 ) ^ (op == softfloat_mulAdd_subC);\n    expC  = expF128UI64( uiC64 );\n    sigC.v64 = fracF128UI64( uiC64 );\n    sigC.v0  = uiC0;\n    signZ = signA ^ signB ^ (op == softfloat_mulAdd_subProd);\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x7FFF ) {\n        if (\n            (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))\n        ) {\n            goto propagateNaN_ABC;\n        }\n        magBits = expB | sigB.v64 | sigB.v0;\n        goto infProdArg;\n    }\n    if ( expB == 0x7FFF ) {\n        if ( sigB.v64 | sigB.v0 ) goto propagateNaN_ABC;\n        magBits = expA | sigA.v64 | sigA.v0;\n        goto infProdArg;\n    }\n    if ( expC == 0x7FFF ) {\n        if ( sigC.v64 | sigC.v0 ) {\n            uiZ.v64 = 0;\n            uiZ.v0  = 0;\n            goto propagateNaN_ZC;\n        }\n        uiZ.v64 = uiC64;\n        uiZ.v0  = uiC0;\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! (sigA.v64 | sigA.v0) ) goto zeroProd;\n        normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    if ( ! expB ) {\n        if ( ! (sigB.v64 | sigB.v0) ) goto zeroProd;\n        normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = expA + expB - 0x3FFE;\n    sigA.v64 |= UINT64_C( 0x0001000000000000 );\n    sigB.v64 |= UINT64_C( 0x0001000000000000 );\n    sigA = softfloat_shortShiftLeft128( sigA.v64, sigA.v0, 8 );\n    sigB = softfloat_shortShiftLeft128( sigB.v64, sigB.v0, 15 );\n    softfloat_mul128To256M( sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z );\n    sigZ.v64 = sig256Z[indexWord( 4, 3 )];\n    sigZ.v0  = sig256Z[indexWord( 4, 2 )];\n    shiftDist = 0;\n    if ( ! (sigZ.v64 & UINT64_C( 0x0100000000000000 )) ) {\n        --expZ;\n        shiftDist = -1;\n    }\n    if ( ! expC ) {\n        if ( ! (sigC.v64 | sigC.v0) ) {\n            shiftDist += 8;\n            goto sigZ;\n        }\n        normExpSig = softfloat_normSubnormalF128Sig( sigC.v64, sigC.v0 );\n        expC = normExpSig.exp;\n        sigC = normExpSig.sig;\n    }\n    sigC.v64 |= UINT64_C( 0x0001000000000000 );\n    sigC = softfloat_shortShiftLeft128( sigC.v64, sigC.v0, 8 );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expDiff = expZ - expC;\n    if ( expDiff < 0 ) {\n        expZ = expC;\n        if ( (signZ == signC) || (expDiff < -1) ) {\n            shiftDist -= expDiff;\n            if ( shiftDist ) {\n                sigZ =\n                    softfloat_shiftRightJam128( sigZ.v64, sigZ.v0, shiftDist );\n            }\n        } else {\n            if ( ! shiftDist ) {\n                x128 =\n                    softfloat_shortShiftRight128(\n                        sig256Z[indexWord( 4, 1 )], sig256Z[indexWord( 4, 0 )],\n                        1\n                    );\n                sig256Z[indexWord( 4, 1 )] = (sigZ.v0<<63) | x128.v64;\n                sig256Z[indexWord( 4, 0 )] = x128.v0;\n                sigZ = softfloat_shortShiftRight128( sigZ.v64, sigZ.v0, 1 );\n                sig256Z[indexWord( 4, 3 )] = sigZ.v64;\n                sig256Z[indexWord( 4, 2 )] = sigZ.v0;\n            }\n        }\n    } else {\n        if ( shiftDist ) softfloat_add256M( sig256Z, sig256Z, sig256Z );\n        if ( ! expDiff ) {\n            sigZ.v64 = sig256Z[indexWord( 4, 3 )];\n            sigZ.v0  = sig256Z[indexWord( 4, 2 )];\n        } else {\n            sig256C[indexWord( 4, 3 )] = sigC.v64;\n            sig256C[indexWord( 4, 2 )] = sigC.v0;\n            sig256C[indexWord( 4, 1 )] = 0;\n            sig256C[indexWord( 4, 0 )] = 0;\n            softfloat_shiftRightJam256M( sig256C, expDiff, sig256C );\n        }\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    shiftDist = 8;\n    if ( signZ == signC ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( expDiff <= 0 ) {\n            sigZ = softfloat_add128( sigC.v64, sigC.v0, sigZ.v64, sigZ.v0 );\n        } else {\n            softfloat_add256M( sig256Z, sig256C, sig256Z );\n            sigZ.v64 = sig256Z[indexWord( 4, 3 )];\n            sigZ.v0  = sig256Z[indexWord( 4, 2 )];\n        }\n        if ( sigZ.v64 & UINT64_C( 0x0200000000000000 ) ) {\n            ++expZ;\n            shiftDist = 9;\n        }\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( expDiff < 0 ) {\n            signZ = signC;\n            if ( expDiff < -1 ) {\n                sigZ =\n                    softfloat_sub128( sigC.v64, sigC.v0, sigZ.v64, sigZ.v0 );\n                sigZExtra =\n                    sig256Z[indexWord( 4, 1 )] | sig256Z[indexWord( 4, 0 )];\n                if ( sigZExtra ) {\n                    sigZ = softfloat_sub128( sigZ.v64, sigZ.v0, 0, 1 );\n                }\n                if ( ! (sigZ.v64 & UINT64_C( 0x0100000000000000 )) ) {\n                    --expZ;\n                    shiftDist = 7;\n                }\n                goto shiftRightRoundPack;\n            } else {\n                sig256C[indexWord( 4, 3 )] = sigC.v64;\n                sig256C[indexWord( 4, 2 )] = sigC.v0;\n                sig256C[indexWord( 4, 1 )] = 0;\n                sig256C[indexWord( 4, 0 )] = 0;\n                softfloat_sub256M( sig256C, sig256Z, sig256Z );\n            }\n        } else if ( ! expDiff ) {\n            sigZ = softfloat_sub128( sigZ.v64, sigZ.v0, sigC.v64, sigC.v0 );\n            if (\n                ! (sigZ.v64 | sigZ.v0) && ! sig256Z[indexWord( 4, 1 )]\n                    && ! sig256Z[indexWord( 4, 0 )]\n            ) {\n                goto completeCancellation;\n            }\n            sig256Z[indexWord( 4, 3 )] = sigZ.v64;\n            sig256Z[indexWord( 4, 2 )] = sigZ.v0;\n            if ( sigZ.v64 & UINT64_C( 0x8000000000000000 ) ) {\n                signZ = ! signZ;\n                softfloat_sub256M( zero256, sig256Z, sig256Z );\n            }\n        } else {\n            softfloat_sub256M( sig256Z, sig256C, sig256Z );\n            if ( 1 < expDiff ) {\n                sigZ.v64 = sig256Z[indexWord( 4, 3 )];\n                sigZ.v0  = sig256Z[indexWord( 4, 2 )];\n                if ( ! (sigZ.v64 & UINT64_C( 0x0100000000000000 )) ) {\n                    --expZ;\n                    shiftDist = 7;\n                }\n                goto sigZ;\n            }\n        }\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        sigZ.v64  = sig256Z[indexWord( 4, 3 )];\n        sigZ.v0   = sig256Z[indexWord( 4, 2 )];\n        sigZExtra = sig256Z[indexWord( 4, 1 )];\n        sig256Z0  = sig256Z[indexWord( 4, 0 )];\n        if ( sigZ.v64 ) {\n            if ( sig256Z0 ) sigZExtra |= 1;\n        } else {\n            expZ -= 64;\n            sigZ.v64  = sigZ.v0;\n            sigZ.v0   = sigZExtra;\n            sigZExtra = sig256Z0;\n            if ( ! sigZ.v64 ) {\n                expZ -= 64;\n                sigZ.v64  = sigZ.v0;\n                sigZ.v0   = sigZExtra;\n                sigZExtra = 0;\n                if ( ! sigZ.v64 ) {\n                    expZ -= 64;\n                    sigZ.v64 = sigZ.v0;\n                    sigZ.v0  = 0;\n                }\n            }\n        }\n        shiftDist = softfloat_countLeadingZeros64( sigZ.v64 );\n        expZ += 7 - shiftDist;\n        shiftDist = 15 - shiftDist;\n        if ( 0 < shiftDist ) goto shiftRightRoundPack;\n        if ( shiftDist ) {\n            shiftDist = -shiftDist;\n            sigZ = softfloat_shortShiftLeft128( sigZ.v64, sigZ.v0, shiftDist );\n            x128 = softfloat_shortShiftLeft128( 0, sigZExtra, shiftDist );\n            sigZ.v0 |= x128.v64;\n            sigZExtra = x128.v0;\n        }\n        goto roundPack;\n    }\n sigZ:\n    sigZExtra = sig256Z[indexWord( 4, 1 )] | sig256Z[indexWord( 4, 0 )];\n shiftRightRoundPack:\n    sigZExtra = (uint64_t) (sigZ.v0<<(64 - shiftDist)) | (sigZExtra != 0);\n    sigZ = softfloat_shortShiftRight128( sigZ.v64, sigZ.v0, shiftDist );\n roundPack:\n    return\n        softfloat_roundPackToF128(\n            signZ, expZ - 1, sigZ.v64, sigZ.v0, sigZExtra );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN_ABC:\n    uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 );\n    goto propagateNaN_ZC;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infProdArg:\n    if ( magBits ) {\n        uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 );\n        uiZ.v0 = 0;\n        if ( expC != 0x7FFF ) goto uiZ;\n        if ( sigC.v64 | sigC.v0 ) goto propagateNaN_ZC;\n        if ( signZ == signC ) goto uiZ;\n    }\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ.v64 = defaultNaNF128UI64;\n    uiZ.v0  = defaultNaNF128UI0;\n propagateNaN_ZC:\n    uiZ = softfloat_propagateNaNF128UI( uiZ.v64, uiZ.v0, uiC64, uiC0 );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zeroProd:\n    uiZ.v64 = uiC64;\n    uiZ.v0  = uiC0;\n    if ( ! (expC | sigC.v64 | sigC.v0) && (signZ != signC) ) {\n completeCancellation:\n        uiZ.v64 =\n            packToF128UI64(\n                (softfloat_roundingMode == softfloat_round_min), 0, 0 );\n        uiZ.v0 = 0;\n    }\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_mulAddF16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat16_t\n softfloat_mulAddF16(\n     uint_fast16_t uiA, uint_fast16_t uiB, uint_fast16_t uiC, uint_fast8_t op )\n{\n    bool signA;\n    int_fast8_t expA;\n    uint_fast16_t sigA;\n    bool signB;\n    int_fast8_t expB;\n    uint_fast16_t sigB;\n    bool signC;\n    int_fast8_t expC;\n    uint_fast16_t sigC;\n    bool signProd;\n    uint_fast16_t magBits, uiZ;\n    struct exp8_sig16 normExpSig;\n    int_fast8_t expProd;\n    uint_fast32_t sigProd;\n    bool signZ;\n    int_fast8_t expZ;\n    uint_fast16_t sigZ;\n    int_fast8_t expDiff;\n    uint_fast32_t sig32Z, sig32C;\n    int_fast8_t shiftDist;\n    union ui16_f16 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    signA = signF16UI( uiA );\n    expA  = expF16UI( uiA );\n    sigA  = fracF16UI( uiA );\n    signB = signF16UI( uiB );\n    expB  = expF16UI( uiB );\n    sigB  = fracF16UI( uiB );\n    signC = signF16UI( uiC ) ^ (op == softfloat_mulAdd_subC);\n    expC  = expF16UI( uiC );\n    sigC  = fracF16UI( uiC );\n    signProd = signA ^ signB ^ (op == softfloat_mulAdd_subProd);\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x1F ) {\n        if ( sigA || ((expB == 0x1F) && sigB) ) goto propagateNaN_ABC;\n        magBits = expB | sigB;\n        goto infProdArg;\n    }\n    if ( expB == 0x1F ) {\n        if ( sigB ) goto propagateNaN_ABC;\n        magBits = expA | sigA;\n        goto infProdArg;\n    }\n    if ( expC == 0x1F ) {\n        if ( sigC ) {\n            uiZ = 0;\n            goto propagateNaN_ZC;\n        }\n        uiZ = uiC;\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! sigA ) goto zeroProd;\n        normExpSig = softfloat_normSubnormalF16Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    if ( ! expB ) {\n        if ( ! sigB ) goto zeroProd;\n        normExpSig = softfloat_normSubnormalF16Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expProd = expA + expB - 0xE;\n    sigA = (sigA | 0x0400)<<4;\n    sigB = (sigB | 0x0400)<<4;\n    sigProd = (uint_fast32_t) sigA * sigB;\n    if ( sigProd < 0x20000000 ) {\n        --expProd;\n        sigProd <<= 1;\n    }\n    signZ = signProd;\n    if ( ! expC ) {\n        if ( ! sigC ) {\n            expZ = expProd - 1;\n            sigZ = sigProd>>15 | ((sigProd & 0x7FFF) != 0);\n            goto roundPack;\n        }\n        normExpSig = softfloat_normSubnormalF16Sig( sigC );\n        expC = normExpSig.exp;\n        sigC = normExpSig.sig;\n    }\n    sigC = (sigC | 0x0400)<<3;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expDiff = expProd - expC;\n    if ( signProd == signC ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( expDiff <= 0 ) {\n            expZ = expC;\n            sigZ = sigC + softfloat_shiftRightJam32( sigProd, 16 - expDiff );\n        } else {\n            expZ = expProd;\n            sig32Z =\n                sigProd\n                    + softfloat_shiftRightJam32(\n                          (uint_fast32_t) sigC<<16, expDiff );\n            sigZ = sig32Z>>16 | ((sig32Z & 0xFFFF) != 0 );\n        }\n        if ( sigZ < 0x4000 ) {\n            --expZ;\n            sigZ <<= 1;\n        }\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        sig32C = (uint_fast32_t) sigC<<16;\n        if ( expDiff < 0 ) {\n            signZ = signC;\n            expZ = expC;\n            sig32Z = sig32C - softfloat_shiftRightJam32( sigProd, -expDiff );\n        } else if ( ! expDiff ) {\n            expZ = expProd;\n            sig32Z = sigProd - sig32C;\n            if ( ! sig32Z ) goto completeCancellation;\n            if ( sig32Z & 0x80000000 ) {\n                signZ = ! signZ;\n                sig32Z = -sig32Z;\n            }\n        } else {\n            expZ = expProd;\n            sig32Z = sigProd - softfloat_shiftRightJam32( sig32C, expDiff );\n        }\n        shiftDist = softfloat_countLeadingZeros32( sig32Z ) - 1;\n        expZ -= shiftDist;\n        shiftDist -= 16;\n        if ( shiftDist < 0 ) {\n            sigZ =\n                sig32Z>>(-shiftDist)\n                    | ((uint32_t) (sig32Z<<(shiftDist & 31)) != 0);\n        } else {\n            sigZ = (uint_fast16_t) sig32Z<<shiftDist;\n        }\n    }\n roundPack:\n    return softfloat_roundPackToF16( signZ, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN_ABC:\n    uiZ = softfloat_propagateNaNF16UI( uiA, uiB );\n    goto propagateNaN_ZC;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infProdArg:\n    if ( magBits ) {\n        uiZ = packToF16UI( signProd, 0x1F, 0 );\n        if ( expC != 0x1F ) goto uiZ;\n        if ( sigC ) goto propagateNaN_ZC;\n        if ( signProd == signC ) goto uiZ;\n    }\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF16UI;\n propagateNaN_ZC:\n    uiZ = softfloat_propagateNaNF16UI( uiZ, uiC );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zeroProd:\n    uiZ = uiC;\n    if ( ! (expC | sigC) && (signProd != signC) ) {\n completeCancellation:\n        uiZ =\n            packToF16UI(\n                (softfloat_roundingMode == softfloat_round_min), 0, 0 );\n    }\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_mulAddF32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat32_t\n softfloat_mulAddF32(\n     uint_fast32_t uiA, uint_fast32_t uiB, uint_fast32_t uiC, uint_fast8_t op )\n{\n    bool signA;\n    int_fast16_t expA;\n    uint_fast32_t sigA;\n    bool signB;\n    int_fast16_t expB;\n    uint_fast32_t sigB;\n    bool signC;\n    int_fast16_t expC;\n    uint_fast32_t sigC;\n    bool signProd;\n    uint_fast32_t magBits, uiZ;\n    struct exp16_sig32 normExpSig;\n    int_fast16_t expProd;\n    uint_fast64_t sigProd;\n    bool signZ;\n    int_fast16_t expZ;\n    uint_fast32_t sigZ;\n    int_fast16_t expDiff;\n    uint_fast64_t sig64Z, sig64C;\n    int_fast8_t shiftDist;\n    union ui32_f32 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    signA = signF32UI( uiA );\n    expA  = expF32UI( uiA );\n    sigA  = fracF32UI( uiA );\n    signB = signF32UI( uiB );\n    expB  = expF32UI( uiB );\n    sigB  = fracF32UI( uiB );\n    signC = signF32UI( uiC ) ^ (op == softfloat_mulAdd_subC);\n    expC  = expF32UI( uiC );\n    sigC  = fracF32UI( uiC );\n    signProd = signA ^ signB ^ (op == softfloat_mulAdd_subProd);\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0xFF ) {\n        if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN_ABC;\n        magBits = expB | sigB;\n        goto infProdArg;\n    }\n    if ( expB == 0xFF ) {\n        if ( sigB ) goto propagateNaN_ABC;\n        magBits = expA | sigA;\n        goto infProdArg;\n    }\n    if ( expC == 0xFF ) {\n        if ( sigC ) {\n            uiZ = 0;\n            goto propagateNaN_ZC;\n        }\n        uiZ = uiC;\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! sigA ) goto zeroProd;\n        normExpSig = softfloat_normSubnormalF32Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    if ( ! expB ) {\n        if ( ! sigB ) goto zeroProd;\n        normExpSig = softfloat_normSubnormalF32Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expProd = expA + expB - 0x7E;\n    sigA = (sigA | 0x00800000)<<7;\n    sigB = (sigB | 0x00800000)<<7;\n    sigProd = (uint_fast64_t) sigA * sigB;\n    if ( sigProd < UINT64_C( 0x2000000000000000 ) ) {\n        --expProd;\n        sigProd <<= 1;\n    }\n    signZ = signProd;\n    if ( ! expC ) {\n        if ( ! sigC ) {\n            expZ = expProd - 1;\n            sigZ = softfloat_shortShiftRightJam64( sigProd, 31 );\n            goto roundPack;\n        }\n        normExpSig = softfloat_normSubnormalF32Sig( sigC );\n        expC = normExpSig.exp;\n        sigC = normExpSig.sig;\n    }\n    sigC = (sigC | 0x00800000)<<6;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expDiff = expProd - expC;\n    if ( signProd == signC ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( expDiff <= 0 ) {\n            expZ = expC;\n            sigZ = sigC + softfloat_shiftRightJam64( sigProd, 32 - expDiff );\n        } else {\n            expZ = expProd;\n            sig64Z =\n                sigProd\n                    + softfloat_shiftRightJam64(\n                          (uint_fast64_t) sigC<<32, expDiff );\n            sigZ = softfloat_shortShiftRightJam64( sig64Z, 32 );\n        }\n        if ( sigZ < 0x40000000 ) {\n            --expZ;\n            sigZ <<= 1;\n        }\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        sig64C = (uint_fast64_t) sigC<<32;\n        if ( expDiff < 0 ) {\n            signZ = signC;\n            expZ = expC;\n            sig64Z = sig64C - softfloat_shiftRightJam64( sigProd, -expDiff );\n        } else if ( ! expDiff ) {\n            expZ = expProd;\n            sig64Z = sigProd - sig64C;\n            if ( ! sig64Z ) goto completeCancellation;\n            if ( sig64Z & UINT64_C( 0x8000000000000000 ) ) {\n                signZ = ! signZ;\n                sig64Z = -sig64Z;\n            }\n        } else {\n            expZ = expProd;\n            sig64Z = sigProd - softfloat_shiftRightJam64( sig64C, expDiff );\n        }\n        shiftDist = softfloat_countLeadingZeros64( sig64Z ) - 1;\n        expZ -= shiftDist;\n        shiftDist -= 32;\n        if ( shiftDist < 0 ) {\n            sigZ = softfloat_shortShiftRightJam64( sig64Z, -shiftDist );\n        } else {\n            sigZ = (uint_fast32_t) sig64Z<<shiftDist;\n        }\n    }\n roundPack:\n    return softfloat_roundPackToF32( signZ, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN_ABC:\n    uiZ = softfloat_propagateNaNF32UI( uiA, uiB );\n    goto propagateNaN_ZC;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infProdArg:\n    if ( magBits ) {\n        uiZ = packToF32UI( signProd, 0xFF, 0 );\n        if ( expC != 0xFF ) goto uiZ;\n        if ( sigC ) goto propagateNaN_ZC;\n        if ( signProd == signC ) goto uiZ;\n    }\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF32UI;\n propagateNaN_ZC:\n    uiZ = softfloat_propagateNaNF32UI( uiZ, uiC );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zeroProd:\n    uiZ = uiC;\n    if ( ! (expC | sigC) && (signProd != signC) ) {\n completeCancellation:\n        uiZ =\n            packToF32UI(\n                (softfloat_roundingMode == softfloat_round_min), 0, 0 );\n    }\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_mulAddF64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\n#ifdef SOFTFLOAT_FAST_INT64\n\nfloat64_t\n softfloat_mulAddF64(\n     uint_fast64_t uiA, uint_fast64_t uiB, uint_fast64_t uiC, uint_fast8_t op )\n{\n    bool signA;\n    int_fast16_t expA;\n    uint_fast64_t sigA;\n    bool signB;\n    int_fast16_t expB;\n    uint_fast64_t sigB;\n    bool signC;\n    int_fast16_t expC;\n    uint_fast64_t sigC;\n    bool signZ;\n    uint_fast64_t magBits, uiZ;\n    struct exp16_sig64 normExpSig;\n    int_fast16_t expZ;\n    struct uint128 sig128Z;\n    uint_fast64_t sigZ;\n    int_fast16_t expDiff;\n    struct uint128 sig128C;\n    int_fast8_t shiftDist;\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    signA = signF64UI( uiA );\n    expA  = expF64UI( uiA );\n    sigA  = fracF64UI( uiA );\n    signB = signF64UI( uiB );\n    expB  = expF64UI( uiB );\n    sigB  = fracF64UI( uiB );\n    signC = signF64UI( uiC ) ^ (op == softfloat_mulAdd_subC);\n    expC  = expF64UI( uiC );\n    sigC  = fracF64UI( uiC );\n    signZ = signA ^ signB ^ (op == softfloat_mulAdd_subProd);\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x7FF ) {\n        if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN_ABC;\n        magBits = expB | sigB;\n        goto infProdArg;\n    }\n    if ( expB == 0x7FF ) {\n        if ( sigB ) goto propagateNaN_ABC;\n        magBits = expA | sigA;\n        goto infProdArg;\n    }\n    if ( expC == 0x7FF ) {\n        if ( sigC ) {\n            uiZ = 0;\n            goto propagateNaN_ZC;\n        }\n        uiZ = uiC;\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! sigA ) goto zeroProd;\n        normExpSig = softfloat_normSubnormalF64Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    if ( ! expB ) {\n        if ( ! sigB ) goto zeroProd;\n        normExpSig = softfloat_normSubnormalF64Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = expA + expB - 0x3FE;\n    sigA = (sigA | UINT64_C( 0x0010000000000000 ))<<10;\n    sigB = (sigB | UINT64_C( 0x0010000000000000 ))<<10;\n    sig128Z = softfloat_mul64To128( sigA, sigB );\n    if ( sig128Z.v64 < UINT64_C( 0x2000000000000000 ) ) {\n        --expZ;\n        sig128Z =\n            softfloat_add128(\n                sig128Z.v64, sig128Z.v0, sig128Z.v64, sig128Z.v0 );\n    }\n    if ( ! expC ) {\n        if ( ! sigC ) {\n            --expZ;\n            sigZ = sig128Z.v64<<1 | (sig128Z.v0 != 0);\n            goto roundPack;\n        }\n        normExpSig = softfloat_normSubnormalF64Sig( sigC );\n        expC = normExpSig.exp;\n        sigC = normExpSig.sig;\n    }\n    sigC = (sigC | UINT64_C( 0x0010000000000000 ))<<9;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expDiff = expZ - expC;\n    if ( expDiff < 0 ) {\n        expZ = expC;\n        if ( (signZ == signC) || (expDiff < -1) ) {\n            sig128Z.v64 = softfloat_shiftRightJam64( sig128Z.v64, -expDiff );\n        } else {\n            sig128Z =\n                softfloat_shortShiftRightJam128( sig128Z.v64, sig128Z.v0, 1 );\n        }\n    } else if ( expDiff ) {\n        sig128C = softfloat_shiftRightJam128( sigC, 0, expDiff );\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( signZ == signC ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( expDiff <= 0 ) {\n            sigZ = (sigC + sig128Z.v64) | (sig128Z.v0 != 0);\n        } else {\n            sig128Z =\n                softfloat_add128(\n                    sig128Z.v64, sig128Z.v0, sig128C.v64, sig128C.v0 );\n            sigZ = sig128Z.v64 | (sig128Z.v0 != 0);\n        }\n        if ( sigZ < UINT64_C( 0x4000000000000000 ) ) {\n            --expZ;\n            sigZ <<= 1;\n        }\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( expDiff < 0 ) {\n            signZ = signC;\n            sig128Z = softfloat_sub128( sigC, 0, sig128Z.v64, sig128Z.v0 );\n        } else if ( ! expDiff ) {\n            sig128Z.v64 = sig128Z.v64 - sigC;\n            if ( ! (sig128Z.v64 | sig128Z.v0) ) goto completeCancellation;\n            if ( sig128Z.v64 & UINT64_C( 0x8000000000000000 ) ) {\n                signZ = ! signZ;\n                sig128Z = softfloat_sub128( 0, 0, sig128Z.v64, sig128Z.v0 );\n            }\n        } else {\n            sig128Z =\n                softfloat_sub128(\n                    sig128Z.v64, sig128Z.v0, sig128C.v64, sig128C.v0 );\n        }\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( ! sig128Z.v64 ) {\n            expZ -= 64;\n            sig128Z.v64 = sig128Z.v0;\n            sig128Z.v0 = 0;\n        }\n        shiftDist = softfloat_countLeadingZeros64( sig128Z.v64 ) - 1;\n        expZ -= shiftDist;\n        if ( shiftDist < 0 ) {\n            sigZ = softfloat_shortShiftRightJam64( sig128Z.v64, -shiftDist );\n        } else {\n            sig128Z =\n                softfloat_shortShiftLeft128(\n                    sig128Z.v64, sig128Z.v0, shiftDist );\n            sigZ = sig128Z.v64;\n        }\n        sigZ |= (sig128Z.v0 != 0);\n    }\n roundPack:\n    return softfloat_roundPackToF64( signZ, expZ, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN_ABC:\n    uiZ = softfloat_propagateNaNF64UI( uiA, uiB );\n    goto propagateNaN_ZC;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infProdArg:\n    if ( magBits ) {\n        uiZ = packToF64UI( signZ, 0x7FF, 0 );\n        if ( expC != 0x7FF ) goto uiZ;\n        if ( sigC ) goto propagateNaN_ZC;\n        if ( signZ == signC ) goto uiZ;\n    }\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF64UI;\n propagateNaN_ZC:\n    uiZ = softfloat_propagateNaNF64UI( uiZ, uiC );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zeroProd:\n    uiZ = uiC;\n    if ( ! (expC | sigC) && (signZ != signC) ) {\n completeCancellation:\n        uiZ =\n            packToF64UI(\n                (softfloat_roundingMode == softfloat_round_min), 0, 0 );\n    }\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n#else\n\nfloat64_t\n softfloat_mulAddF64(\n     uint_fast64_t uiA, uint_fast64_t uiB, uint_fast64_t uiC, uint_fast8_t op )\n{\n    bool signA;\n    int_fast16_t expA;\n    uint64_t sigA;\n    bool signB;\n    int_fast16_t expB;\n    uint64_t sigB;\n    bool signC;\n    int_fast16_t expC;\n    uint64_t sigC;\n    bool signZ;\n    uint64_t magBits, uiZ;\n    struct exp16_sig64 normExpSig;\n    int_fast16_t expZ;\n    uint32_t sig128Z[4];\n    uint64_t sigZ;\n    int_fast16_t shiftDist, expDiff;\n    uint32_t sig128C[4];\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    signA = signF64UI( uiA );\n    expA  = expF64UI( uiA );\n    sigA  = fracF64UI( uiA );\n    signB = signF64UI( uiB );\n    expB  = expF64UI( uiB );\n    sigB  = fracF64UI( uiB );\n    signC = signF64UI( uiC ) ^ (op == softfloat_mulAdd_subC);\n    expC  = expF64UI( uiC );\n    sigC  = fracF64UI( uiC );\n    signZ = signA ^ signB ^ (op == softfloat_mulAdd_subProd);\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( expA == 0x7FF ) {\n        if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN_ABC;\n        magBits = expB | sigB;\n        goto infProdArg;\n    }\n    if ( expB == 0x7FF ) {\n        if ( sigB ) goto propagateNaN_ABC;\n        magBits = expA | sigA;\n        goto infProdArg;\n    }\n    if ( expC == 0x7FF ) {\n        if ( sigC ) {\n            uiZ = 0;\n            goto propagateNaN_ZC;\n        }\n        uiZ = uiC;\n        goto uiZ;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( ! expA ) {\n        if ( ! sigA ) goto zeroProd;\n        normExpSig = softfloat_normSubnormalF64Sig( sigA );\n        expA = normExpSig.exp;\n        sigA = normExpSig.sig;\n    }\n    if ( ! expB ) {\n        if ( ! sigB ) goto zeroProd;\n        normExpSig = softfloat_normSubnormalF64Sig( sigB );\n        expB = normExpSig.exp;\n        sigB = normExpSig.sig;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expZ = expA + expB - 0x3FE;\n    sigA = (sigA | UINT64_C( 0x0010000000000000 ))<<10;\n    sigB = (sigB | UINT64_C( 0x0010000000000000 ))<<11;\n    softfloat_mul64To128M( sigA, sigB, sig128Z );\n    sigZ =\n        (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 | sig128Z[indexWord( 4, 2 )];\n    shiftDist = 0;\n    if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) {\n        --expZ;\n        shiftDist = -1;\n    }\n    if ( ! expC ) {\n        if ( ! sigC ) {\n            if ( shiftDist ) sigZ <<= 1;\n            goto sigZ;\n        }\n        normExpSig = softfloat_normSubnormalF64Sig( sigC );\n        expC = normExpSig.exp;\n        sigC = normExpSig.sig;\n    }\n    sigC = (sigC | UINT64_C( 0x0010000000000000 ))<<10;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expDiff = expZ - expC;\n    if ( expDiff < 0 ) {\n        expZ = expC;\n        if ( (signZ == signC) || (expDiff < -1) ) {\n            shiftDist -= expDiff;\n            if ( shiftDist) {\n                sigZ = softfloat_shiftRightJam64( sigZ, shiftDist );\n            }\n        } else {\n            if ( ! shiftDist ) {\n                softfloat_shortShiftRight128M( sig128Z, 1, sig128Z );\n            }\n        }\n    } else {\n        if ( shiftDist ) softfloat_add128M( sig128Z, sig128Z, sig128Z );\n        if ( ! expDiff ) {\n            sigZ =\n                (uint64_t) sig128Z[indexWord( 4, 3 )]<<32\n                    | sig128Z[indexWord( 4, 2 )];\n        } else {\n            sig128C[indexWord( 4, 3 )] = sigC>>32;\n            sig128C[indexWord( 4, 2 )] = sigC;\n            sig128C[indexWord( 4, 1 )] = 0;\n            sig128C[indexWord( 4, 0 )] = 0;\n            softfloat_shiftRightJam128M( sig128C, expDiff, sig128C );\n        }\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( signZ == signC ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( expDiff <= 0 ) {\n            sigZ += sigC;\n        } else {\n            softfloat_add128M( sig128Z, sig128C, sig128Z );\n            sigZ =\n                (uint64_t) sig128Z[indexWord( 4, 3 )]<<32\n                    | sig128Z[indexWord( 4, 2 )];\n        }\n        if ( sigZ & UINT64_C( 0x8000000000000000 ) ) {\n            ++expZ;\n            sigZ = softfloat_shortShiftRightJam64( sigZ, 1 );\n        }\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( expDiff < 0 ) {\n            signZ = signC;\n            if ( expDiff < -1 ) {\n                sigZ = sigC - sigZ;\n                if (\n                    sig128Z[indexWord( 4, 1 )] || sig128Z[indexWord( 4, 0 )]\n                ) {\n                    sigZ = (sigZ - 1) | 1;\n                }\n                if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) {\n                    --expZ;\n                    sigZ <<= 1;\n                }\n                goto roundPack;\n            } else {\n                sig128C[indexWord( 4, 3 )] = sigC>>32;\n                sig128C[indexWord( 4, 2 )] = sigC;\n                sig128C[indexWord( 4, 1 )] = 0;\n                sig128C[indexWord( 4, 0 )] = 0;\n                softfloat_sub128M( sig128C, sig128Z, sig128Z );\n            }\n        } else if ( ! expDiff ) {\n            sigZ -= sigC;\n            if (\n                ! sigZ && ! sig128Z[indexWord( 4, 1 )]\n                    && ! sig128Z[indexWord( 4, 0 )]\n            ) {\n                goto completeCancellation;\n            }\n            sig128Z[indexWord( 4, 3 )] = sigZ>>32;\n            sig128Z[indexWord( 4, 2 )] = sigZ;\n            if ( sigZ & UINT64_C( 0x8000000000000000 ) ) {\n                signZ = ! signZ;\n                softfloat_negX128M( sig128Z );\n            }\n        } else {\n            softfloat_sub128M( sig128Z, sig128C, sig128Z );\n            if ( 1 < expDiff ) {\n                sigZ =\n                    (uint64_t) sig128Z[indexWord( 4, 3 )]<<32\n                        | sig128Z[indexWord( 4, 2 )];\n                if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) {\n                    --expZ;\n                    sigZ <<= 1;\n                }\n                goto sigZ;\n            }\n        }\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        shiftDist = 0;\n        sigZ =\n            (uint64_t) sig128Z[indexWord( 4, 3 )]<<32\n                | sig128Z[indexWord( 4, 2 )];\n        if ( ! sigZ ) {\n            shiftDist = 64;\n            sigZ =\n                (uint64_t) sig128Z[indexWord( 4, 1 )]<<32\n                    | sig128Z[indexWord( 4, 0 )];\n        }\n        shiftDist += softfloat_countLeadingZeros64( sigZ ) - 1;\n        if ( shiftDist ) {\n            expZ -= shiftDist;\n            softfloat_shiftLeft128M( sig128Z, shiftDist, sig128Z );\n            sigZ =\n                (uint64_t) sig128Z[indexWord( 4, 3 )]<<32\n                    | sig128Z[indexWord( 4, 2 )];\n        }\n    }\n sigZ:\n    if ( sig128Z[indexWord( 4, 1 )] || sig128Z[indexWord( 4, 0 )] ) sigZ |= 1;\n roundPack:\n    return softfloat_roundPackToF64( signZ, expZ - 1, sigZ );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN_ABC:\n    uiZ = softfloat_propagateNaNF64UI( uiA, uiB );\n    goto propagateNaN_ZC;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n infProdArg:\n    if ( magBits ) {\n        uiZ = packToF64UI( signZ, 0x7FF, 0 );\n        if ( expC != 0x7FF ) goto uiZ;\n        if ( sigC ) goto propagateNaN_ZC;\n        if ( signZ == signC ) goto uiZ;\n    }\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    uiZ = defaultNaNF64UI;\n propagateNaN_ZC:\n    uiZ = softfloat_propagateNaNF64UI( uiZ, uiC );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n zeroProd:\n    uiZ = uiC;\n    if ( ! (expC | sigC) && (signZ != signC) ) {\n completeCancellation:\n        uiZ =\n            packToF64UI(\n                (softfloat_roundingMode == softfloat_round_min), 0, 0 );\n    }\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_negXM.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_negXM\n\nvoid softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr )\n{\n    unsigned int index, lastIndex;\n    uint_fast8_t carry;\n    uint32_t word;\n\n    index = indexWordLo( size_words );\n    lastIndex = indexWordHi( size_words );\n    carry = 1;\n    for (;;) {\n        word = ~zPtr[index] + carry;\n        zPtr[index] = word;\n        if ( index == lastIndex ) break;\n        index += wordIncr;\n        if ( word ) carry = 0;\n    }\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_normRoundPackToF128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n\nfloat128_t\n softfloat_normRoundPackToF128(\n     bool sign, int_fast32_t exp, uint_fast64_t sig64, uint_fast64_t sig0 )\n{\n    int_fast8_t shiftDist;\n    struct uint128 sig128;\n    union ui128_f128 uZ;\n    uint_fast64_t sigExtra;\n    struct uint128_extra sig128Extra;\n\n    if ( ! sig64 ) {\n        exp -= 64;\n        sig64 = sig0;\n        sig0 = 0;\n    }\n    shiftDist = softfloat_countLeadingZeros64( sig64 ) - 15;\n    exp -= shiftDist;\n    if ( 0 <= shiftDist ) {\n        if ( shiftDist ) {\n            sig128 = softfloat_shortShiftLeft128( sig64, sig0, shiftDist );\n            sig64 = sig128.v64;\n            sig0  = sig128.v0;\n        }\n        if ( (uint32_t) exp < 0x7FFD ) {\n            uZ.ui.v64 = packToF128UI64( sign, sig64 | sig0 ? exp : 0, sig64 );\n            uZ.ui.v0  = sig0;\n            return uZ.f;\n        }\n        sigExtra = 0;\n    } else {\n        sig128Extra =\n            softfloat_shortShiftRightJam128Extra( sig64, sig0, 0, -shiftDist );\n        sig64 = sig128Extra.v.v64;\n        sig0  = sig128Extra.v.v0;\n        sigExtra = sig128Extra.extra;\n    }\n    return softfloat_roundPackToF128( sign, exp, sig64, sig0, sigExtra );\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_normRoundPackToF16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n\nfloat16_t\n softfloat_normRoundPackToF16( bool sign, int_fast16_t exp, uint_fast16_t sig )\n{\n    int_fast8_t shiftDist;\n    union ui16_f16 uZ;\n\n    shiftDist = softfloat_countLeadingZeros16( sig ) - 1;\n    exp -= shiftDist;\n    if ( (4 <= shiftDist) && ((unsigned int) exp < 0x1D) ) {\n        uZ.ui = packToF16UI( sign, sig ? exp : 0, sig<<(shiftDist - 4) );\n        return uZ.f;\n    } else {\n        return softfloat_roundPackToF16( sign, exp, sig<<shiftDist );\n    }\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_normRoundPackToF32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n\nfloat32_t\n softfloat_normRoundPackToF32( bool sign, int_fast16_t exp, uint_fast32_t sig )\n{\n    int_fast8_t shiftDist;\n    union ui32_f32 uZ;\n\n    shiftDist = softfloat_countLeadingZeros32( sig ) - 1;\n    exp -= shiftDist;\n    if ( (7 <= shiftDist) && ((unsigned int) exp < 0xFD) ) {\n        uZ.ui = packToF32UI( sign, sig ? exp : 0, sig<<(shiftDist - 7) );\n        return uZ.f;\n    } else {\n        return softfloat_roundPackToF32( sign, exp, sig<<shiftDist );\n    }\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_normRoundPackToF64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n\nfloat64_t\n softfloat_normRoundPackToF64( bool sign, int_fast16_t exp, uint_fast64_t sig )\n{\n    int_fast8_t shiftDist;\n    union ui64_f64 uZ;\n\n    shiftDist = softfloat_countLeadingZeros64( sig ) - 1;\n    exp -= shiftDist;\n    if ( (10 <= shiftDist) && ((unsigned int) exp < 0x7FD) ) {\n        uZ.ui = packToF64UI( sign, sig ? exp : 0, sig<<(shiftDist - 10) );\n        return uZ.f;\n    } else {\n        return softfloat_roundPackToF64( sign, exp, sig<<shiftDist );\n    }\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_normSubnormalF128Sig.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n\nstruct exp32_sig128\n softfloat_normSubnormalF128Sig( uint_fast64_t sig64, uint_fast64_t sig0 )\n{\n    int_fast8_t shiftDist;\n    struct exp32_sig128 z;\n\n    if ( ! sig64 ) {\n        shiftDist = softfloat_countLeadingZeros64( sig0 ) - 15;\n        z.exp = -63 - shiftDist;\n        if ( shiftDist < 0 ) {\n            z.sig.v64 = sig0>>-shiftDist;\n            z.sig.v0  = sig0<<(shiftDist & 63);\n        } else {\n            z.sig.v64 = sig0<<shiftDist;\n            z.sig.v0  = 0;\n        }\n    } else {\n        shiftDist = softfloat_countLeadingZeros64( sig64 ) - 15;\n        z.exp = 1 - shiftDist;\n        z.sig = softfloat_shortShiftLeft128( sig64, sig0, shiftDist );\n    }\n    return z;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_normSubnormalF16Sig.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n\nstruct exp8_sig16 softfloat_normSubnormalF16Sig( uint_fast16_t sig )\n{\n    int_fast8_t shiftDist;\n    struct exp8_sig16 z;\n\n    shiftDist = softfloat_countLeadingZeros16( sig ) - 5;\n    z.exp = 1 - shiftDist;\n    z.sig = sig<<shiftDist;\n    return z;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_normSubnormalF32Sig.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n\nstruct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t sig )\n{\n    int_fast8_t shiftDist;\n    struct exp16_sig32 z;\n\n    shiftDist = softfloat_countLeadingZeros32( sig ) - 8;\n    z.exp = 1 - shiftDist;\n    z.sig = sig<<shiftDist;\n    return z;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_normSubnormalF64Sig.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n\nstruct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t sig )\n{\n    int_fast8_t shiftDist;\n    struct exp16_sig64 z;\n\n    shiftDist = softfloat_countLeadingZeros64( sig ) - 11;\n    z.exp = 1 - shiftDist;\n    z.sig = sig<<shiftDist;\n    return z;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_propagateNaNF128UI.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\n/*----------------------------------------------------------------------------\n| Interpreting the unsigned integer formed from concatenating `uiA64' and\n| `uiA0' as a 128-bit floating-point value, and likewise interpreting the\n| unsigned integer formed from concatenating `uiB64' and `uiB0' as another\n| 128-bit floating-point value, and assuming at least on of these floating-\n| point values is a NaN, returns the bit pattern of the combined NaN result.\n| If either original floating-point value is a signaling NaN, the invalid\n| exception is raised.\n*----------------------------------------------------------------------------*/\nstruct uint128\n softfloat_propagateNaNF128UI(\n     uint_fast64_t uiA64,\n     uint_fast64_t uiA0,\n     uint_fast64_t uiB64,\n     uint_fast64_t uiB0\n )\n{\n    struct uint128 uiZ;\n\n    if (\n           softfloat_isSigNaNF128UI( uiA64, uiA0 )\n        || softfloat_isSigNaNF128UI( uiB64, uiB0 )\n    ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n    }\n    uiZ.v64 = defaultNaNF128UI64;\n    uiZ.v0  = defaultNaNF128UI0;\n    return uiZ;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_propagateNaNF16UI.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\n/*----------------------------------------------------------------------------\n| Interpreting `uiA' and `uiB' as the bit patterns of two 16-bit floating-\n| point values, at least one of which is a NaN, returns the bit pattern of\n| the combined NaN result.  If either `uiA' or `uiB' has the pattern of a\n| signaling NaN, the invalid exception is raised.\n*----------------------------------------------------------------------------*/\nuint_fast16_t\n softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB )\n{\n\n    if ( softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n    }\n    return defaultNaNF16UI;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_propagateNaNF32UI.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\n/*----------------------------------------------------------------------------\n| Interpreting `uiA' and `uiB' as the bit patterns of two 32-bit floating-\n| point values, at least one of which is a NaN, returns the bit pattern of\n| the combined NaN result.  If either `uiA' or `uiB' has the pattern of a\n| signaling NaN, the invalid exception is raised.\n*----------------------------------------------------------------------------*/\nuint_fast32_t\n softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB )\n{\n\n    if ( softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n    }\n    return defaultNaNF32UI;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_propagateNaNF64UI.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\n/*----------------------------------------------------------------------------\n| Interpreting `uiA' and `uiB' as the bit patterns of two 64-bit floating-\n| point values, at least one of which is a NaN, returns the bit pattern of\n| the combined NaN result.  If either `uiA' or `uiB' has the pattern of a\n| signaling NaN, the invalid exception is raised.\n*----------------------------------------------------------------------------*/\nuint_fast64_t\n softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB )\n{\n\n    if ( softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB ) ) {\n        softfloat_raiseFlags( softfloat_flag_invalid );\n    }\n    return defaultNaNF64UI;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_remStepMBy32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_remStepMBy32\n\nvoid\n softfloat_remStepMBy32(\n     uint_fast8_t size_words,\n     const uint32_t *remPtr,\n     uint_fast8_t dist,\n     const uint32_t *bPtr,\n     uint32_t q,\n     uint32_t *zPtr\n )\n{\n    unsigned int index, lastIndex;\n    uint64_t dwordProd;\n    uint32_t wordRem, wordShiftedRem, wordProd;\n    uint_fast8_t uNegDist, borrow;\n\n    index = indexWordLo( size_words );\n    lastIndex = indexWordHi( size_words );\n    dwordProd = (uint64_t) bPtr[index] * q;\n    wordRem = remPtr[index];\n    wordShiftedRem = wordRem<<dist;\n    wordProd = dwordProd;\n    zPtr[index] = wordShiftedRem - wordProd;\n    if ( index != lastIndex ) {\n        uNegDist = -dist;\n        borrow = (wordShiftedRem < wordProd);\n        for (;;) {\n            wordShiftedRem = wordRem>>(uNegDist & 31);\n            index += wordIncr;\n            dwordProd = (uint64_t) bPtr[index] * q + (dwordProd>>32);\n            wordRem = remPtr[index];\n            wordShiftedRem |= wordRem<<dist;\n            wordProd = dwordProd;\n            zPtr[index] = wordShiftedRem - wordProd - borrow;\n            if ( index == lastIndex ) break;\n            borrow =\n                borrow ? (wordShiftedRem <= wordProd)\n                    : (wordShiftedRem < wordProd);\n        }\n    }\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundMToI64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast64_t\n softfloat_roundMToI64(\n     bool sign, uint32_t *extSigPtr, uint_fast8_t roundingMode, bool exact )\n{\n    bool roundNearEven;\n    uint32_t sigExtra;\n    bool doIncrement;\n    uint64_t sig;\n    union { uint64_t ui; int64_t i; } uZ;\n    int64_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    sigExtra = extSigPtr[indexWordLo( 3 )];\n    doIncrement = (0x80000000 <= sigExtra);\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        doIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                && sigExtra;\n    }\n    sig =\n        (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32\n            | extSigPtr[indexWord( 3, 1 )];\n    if ( doIncrement ) {\n        ++sig;\n        if ( ! sig ) goto invalid;\n        if ( ! (sigExtra & 0x7FFFFFFF) && roundNearEven ) sig &= ~1;\n    }\n    uZ.ui = sign ? -sig : sig;\n    z = uZ.i;\n    if ( z && ((z < 0) ^ sign) ) goto invalid;\n    if ( exact && sigExtra ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return z;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return sign ? i64_fromNegOverflow : i64_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundMToUI64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast64_t\n softfloat_roundMToUI64(\n     bool sign, uint32_t *extSigPtr, uint_fast8_t roundingMode, bool exact )\n{\n    bool roundNearEven;\n    uint32_t sigExtra;\n    bool doIncrement;\n    uint64_t sig;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    sigExtra = extSigPtr[indexWordLo( 3 )];\n    doIncrement = (0x80000000 <= sigExtra);\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        doIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                && sigExtra;\n    }\n    sig =\n        (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32\n            | extSigPtr[indexWord( 3, 1 )];\n    if ( doIncrement ) {\n        ++sig;\n        if ( ! sig ) goto invalid;\n        if ( ! (sigExtra & 0x7FFFFFFF) && roundNearEven ) sig &= ~1;\n    }\n    if ( sign && sig ) goto invalid;\n    if ( exact && sigExtra ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return sig;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundPackMToI64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3a+, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast64_t\n softfloat_roundPackMToI64(\n     bool sign, uint32_t *extSigPtr, uint_fast8_t roundingMode, bool exact )\n{\n    bool roundNearEven;\n    uint32_t sigExtra;\n    bool doIncrement;\n    uint64_t sig;\n    union { uint64_t ui; int64_t i; } uZ;\n    int64_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    sigExtra = extSigPtr[indexWordLo( 3 )];\n    doIncrement = (0x80000000 <= sigExtra);\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        doIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                && sigExtra;\n    }\n    sig =\n        (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32\n            | extSigPtr[indexWord( 3, 1 )];\n    if ( doIncrement ) {\n        ++sig;\n        if ( ! sig ) goto invalid;\n        if ( ! (sigExtra & 0x7FFFFFFF) && roundNearEven ) sig &= ~1;\n    }\n    uZ.ui = sign ? -sig : sig;\n    z = uZ.i;\n    if ( z && ((z < 0) ^ sign) ) goto invalid;\n    if ( exact && sigExtra ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return z;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return sign ? i64_fromNegOverflow : i64_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundPackMToUI64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3a+, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast64_t\n softfloat_roundPackMToUI64(\n     bool sign, uint32_t *extSigPtr, uint_fast8_t roundingMode, bool exact )\n{\n    bool roundNearEven;\n    uint32_t sigExtra;\n    bool doIncrement;\n    uint64_t sig;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    sigExtra = extSigPtr[indexWordLo( 3 )];\n    doIncrement = (0x80000000 <= sigExtra);\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        doIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                && sigExtra;\n    }\n    sig =\n        (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32\n            | extSigPtr[indexWord( 3, 1 )];\n    if ( doIncrement ) {\n        ++sig;\n        if ( ! sig ) goto invalid;\n        if ( ! (sigExtra & 0x7FFFFFFF) && roundNearEven ) sig &= ~1;\n    }\n    if ( sign && sig ) goto invalid;\n    if ( exact && sigExtra ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return sig;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundPackToF128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat128_t\n softfloat_roundPackToF128(\n     bool sign,\n     int_fast32_t exp,\n     uint_fast64_t sig64,\n     uint_fast64_t sig0,\n     uint_fast64_t sigExtra\n )\n{\n    uint_fast8_t roundingMode;\n    bool roundNearEven, doIncrement, isTiny;\n    struct uint128_extra sig128Extra;\n    uint_fast64_t uiZ64, uiZ0;\n    struct uint128 sig128;\n    union ui128_f128 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundingMode = softfloat_roundingMode;\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra);\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        doIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                && sigExtra;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( 0x7FFD <= (uint32_t) exp ) {\n        if ( exp < 0 ) {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            isTiny =\n                   (softfloat_detectTininess\n                        == softfloat_tininess_beforeRounding)\n                || (exp < -1)\n                || ! doIncrement\n                || softfloat_lt128(\n                       sig64,\n                       sig0,\n                       UINT64_C( 0x0001FFFFFFFFFFFF ),\n                       UINT64_C( 0xFFFFFFFFFFFFFFFF )\n                   );\n            sig128Extra =\n                softfloat_shiftRightJam128Extra( sig64, sig0, sigExtra, -exp );\n            sig64 = sig128Extra.v.v64;\n            sig0  = sig128Extra.v.v0;\n            sigExtra = sig128Extra.extra;\n            exp = 0;\n            if ( isTiny && sigExtra ) {\n                softfloat_raiseFlags( softfloat_flag_underflow );\n            }\n            doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra);\n            if (\n                   ! roundNearEven\n                && (roundingMode != softfloat_round_near_maxMag)\n            ) {\n                doIncrement =\n                    (roundingMode\n                         == (sign ? softfloat_round_min : softfloat_round_max))\n                        && sigExtra;\n            }\n        } else if (\n               (0x7FFD < exp)\n            || ((exp == 0x7FFD)\n                    && softfloat_eq128( \n                           sig64,\n                           sig0,\n                           UINT64_C( 0x0001FFFFFFFFFFFF ),\n                           UINT64_C( 0xFFFFFFFFFFFFFFFF )\n                       )\n                    && doIncrement)\n        ) {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            softfloat_raiseFlags(\n                softfloat_flag_overflow | softfloat_flag_inexact );\n            if (\n                   roundNearEven\n                || (roundingMode == softfloat_round_near_maxMag)\n                || (roundingMode\n                        == (sign ? softfloat_round_min : softfloat_round_max))\n            ) {\n                uiZ64 = packToF128UI64( sign, 0x7FFF, 0 );\n                uiZ0  = 0;\n            } else {\n                uiZ64 =\n                    packToF128UI64(\n                        sign, 0x7FFE, UINT64_C( 0x0000FFFFFFFFFFFF ) );\n                uiZ0 = UINT64_C( 0xFFFFFFFFFFFFFFFF );\n            }\n            goto uiZ;\n        }\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( sigExtra ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n#ifdef SOFTFLOAT_ROUND_ODD\n        if ( roundingMode == softfloat_round_odd ) {\n            sig0 |= 1;\n            goto packReturn;\n        }\n#endif\n    }\n    if ( doIncrement ) {\n        sig128 = softfloat_add128( sig64, sig0, 0, 1 );\n        sig64 = sig128.v64;\n        sig0 =\n            sig128.v0\n                & ~(uint64_t)\n                       (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n                            & roundNearEven);\n    } else {\n        if ( ! (sig64 | sig0) ) exp = 0;\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n packReturn:\n    uiZ64 = packToF128UI64( sign, exp, sig64 );\n    uiZ0  = sig0;\n uiZ:\n    uZ.ui.v64 = uiZ64;\n    uZ.ui.v0  = uiZ0;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundPackToF16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat16_t\n softfloat_roundPackToF16( bool sign, int_fast16_t exp, uint_fast16_t sig )\n{\n    uint_fast8_t roundingMode;\n    bool roundNearEven;\n    uint_fast8_t roundIncrement, roundBits;\n    bool isTiny;\n    uint_fast16_t uiZ;\n    union ui16_f16 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundingMode = softfloat_roundingMode;\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    roundIncrement = 0x8;\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        roundIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                ? 0xF\n                : 0;\n    }\n    roundBits = sig & 0xF;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( 0x1D <= (unsigned int) exp ) {\n        if ( exp < 0 ) {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            isTiny =\n                (softfloat_detectTininess == softfloat_tininess_beforeRounding)\n                    || (exp < -1) || (sig + roundIncrement < 0x8000);\n            sig = softfloat_shiftRightJam32( sig, -exp );\n            exp = 0;\n            roundBits = sig & 0xF;\n            if ( isTiny && roundBits ) {\n                softfloat_raiseFlags( softfloat_flag_underflow );\n            }\n        } else if ( (0x1D < exp) || (0x8000 <= sig + roundIncrement) ) {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            softfloat_raiseFlags(\n                softfloat_flag_overflow | softfloat_flag_inexact );\n            uiZ = packToF16UI( sign, 0x1F, 0 ) - ! roundIncrement;\n            goto uiZ;\n        }\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig = (sig + roundIncrement)>>4;\n    if ( roundBits ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n#ifdef SOFTFLOAT_ROUND_ODD\n        if ( roundingMode == softfloat_round_odd ) {\n            sig |= 1;\n            goto packReturn;\n        }\n#endif\n    }\n    sig &= ~(uint_fast16_t) (! (roundBits ^ 8) & roundNearEven);\n    if ( ! sig ) exp = 0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n packReturn:\n    uiZ = packToF16UI( sign, exp, sig );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundPackToF32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat32_t\n softfloat_roundPackToF32( bool sign, int_fast16_t exp, uint_fast32_t sig )\n{\n    uint_fast8_t roundingMode;\n    bool roundNearEven;\n    uint_fast8_t roundIncrement, roundBits;\n    bool isTiny;\n    uint_fast32_t uiZ;\n    union ui32_f32 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundingMode = softfloat_roundingMode;\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    roundIncrement = 0x40;\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        roundIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                ? 0x7F\n                : 0;\n    }\n    roundBits = sig & 0x7F;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( 0xFD <= (unsigned int) exp ) {\n        if ( exp < 0 ) {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            isTiny =\n                (softfloat_detectTininess == softfloat_tininess_beforeRounding)\n                    || (exp < -1) || (sig + roundIncrement < 0x80000000);\n            sig = softfloat_shiftRightJam32( sig, -exp );\n            exp = 0;\n            roundBits = sig & 0x7F;\n            if ( isTiny && roundBits ) {\n                softfloat_raiseFlags( softfloat_flag_underflow );\n            }\n        } else if ( (0xFD < exp) || (0x80000000 <= sig + roundIncrement) ) {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            softfloat_raiseFlags(\n                softfloat_flag_overflow | softfloat_flag_inexact );\n            uiZ = packToF32UI( sign, 0xFF, 0 ) - ! roundIncrement;\n            goto uiZ;\n        }\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig = (sig + roundIncrement)>>7;\n    if ( roundBits ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n#ifdef SOFTFLOAT_ROUND_ODD\n        if ( roundingMode == softfloat_round_odd ) {\n            sig |= 1;\n            goto packReturn;\n        }\n#endif\n    }\n    sig &= ~(uint_fast32_t) (! (roundBits ^ 0x40) & roundNearEven);\n    if ( ! sig ) exp = 0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n packReturn:\n    uiZ = packToF32UI( sign, exp, sig );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundPackToF64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat64_t\n softfloat_roundPackToF64( bool sign, int_fast16_t exp, uint_fast64_t sig )\n{\n    uint_fast8_t roundingMode;\n    bool roundNearEven;\n    uint_fast16_t roundIncrement, roundBits;\n    bool isTiny;\n    uint_fast64_t uiZ;\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundingMode = softfloat_roundingMode;\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    roundIncrement = 0x200;\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        roundIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                ? 0x3FF\n                : 0;\n    }\n    roundBits = sig & 0x3FF;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    if ( 0x7FD <= (uint16_t) exp ) {\n        if ( exp < 0 ) {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            isTiny =\n                (softfloat_detectTininess == softfloat_tininess_beforeRounding)\n                    || (exp < -1)\n                    || (sig + roundIncrement < UINT64_C( 0x8000000000000000 ));\n            sig = softfloat_shiftRightJam64( sig, -exp );\n            exp = 0;\n            roundBits = sig & 0x3FF;\n            if ( isTiny && roundBits ) {\n                softfloat_raiseFlags( softfloat_flag_underflow );\n            }\n        } else if (\n            (0x7FD < exp)\n                || (UINT64_C( 0x8000000000000000 ) <= sig + roundIncrement)\n        ) {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            softfloat_raiseFlags(\n                softfloat_flag_overflow | softfloat_flag_inexact );\n            uiZ = packToF64UI( sign, 0x7FF, 0 ) - ! roundIncrement;\n            goto uiZ;\n        }\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    sig = (sig + roundIncrement)>>10;\n    if ( roundBits ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n#ifdef SOFTFLOAT_ROUND_ODD\n        if ( roundingMode == softfloat_round_odd ) {\n            sig |= 1;\n            goto packReturn;\n        }\n#endif\n    }\n    sig &= ~(uint_fast64_t) (! (roundBits ^ 0x200) & roundNearEven);\n    if ( ! sig ) exp = 0;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n packReturn:\n    uiZ = packToF64UI( sign, exp, sig );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundPackToI32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3a+, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast32_t\n softfloat_roundPackToI32(\n     bool sign, uint_fast64_t sig, uint_fast8_t roundingMode, bool exact )\n{\n    bool roundNearEven;\n    uint_fast8_t roundIncrement, roundBits;\n    uint_fast32_t sig32;\n    union { uint32_t ui; int32_t i; } uZ;\n    int_fast32_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    roundIncrement = 0x40;\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        roundIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                ? 0x7F\n                : 0;\n    }\n    roundBits = sig & 0x7F;\n    sig += roundIncrement;\n    if ( sig & UINT64_C( 0xFFFFFF8000000000 ) ) goto invalid;\n    sig32 = sig>>7;\n    sig32 &= ~(uint_fast32_t) (! (roundBits ^ 0x40) & roundNearEven);\n    uZ.ui = sign ? -sig32 : sig32;\n    z = uZ.i;\n    if ( z && ((z < 0) ^ sign) ) goto invalid;\n    if ( exact && roundBits ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return z;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return sign ? i32_fromNegOverflow : i32_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundPackToI64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3a+, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast64_t\n softfloat_roundPackToI64(\n     bool sign,\n     uint_fast64_t sig,\n     uint_fast64_t sigExtra,\n     uint_fast8_t roundingMode,\n     bool exact\n )\n{\n    bool roundNearEven, doIncrement;\n    union { uint64_t ui; int64_t i; } uZ;\n    int_fast64_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra);\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        doIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                && sigExtra;\n    }\n    if ( doIncrement ) {\n        ++sig;\n        if ( ! sig ) goto invalid;\n        sig &=\n            ~(uint_fast64_t)\n                 (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n                      & roundNearEven);\n    }\n    uZ.ui = sign ? -sig : sig;\n    z = uZ.i;\n    if ( z && ((z < 0) ^ sign) ) goto invalid;\n    if ( exact && sigExtra ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return z;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return sign ? i64_fromNegOverflow : i64_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundPackToUI32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3a+, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast32_t\n softfloat_roundPackToUI32(\n     bool sign, uint_fast64_t sig, uint_fast8_t roundingMode, bool exact )\n{\n    bool roundNearEven;\n    uint_fast8_t roundIncrement, roundBits;\n    uint_fast32_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    roundIncrement = 0x40;\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        roundIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                ? 0x7F\n                : 0;\n    }\n    roundBits = sig & 0x7F;\n    sig += roundIncrement;\n    if ( sig & UINT64_C( 0xFFFFFF8000000000 ) ) goto invalid;\n    z = sig>>7;\n    z &= ~(uint_fast32_t) (! (roundBits ^ 0x40) & roundNearEven);\n    if ( sign && z ) goto invalid;\n    if ( exact && roundBits ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return z;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundPackToUI64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3a+, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast64_t\n softfloat_roundPackToUI64(\n     bool sign,\n     uint_fast64_t sig,\n     uint_fast64_t sigExtra,\n     uint_fast8_t roundingMode,\n     bool exact\n )\n{\n    bool roundNearEven, doIncrement;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra);\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        doIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                && sigExtra;\n    }\n    if ( doIncrement ) {\n        ++sig;\n        if ( ! sig ) goto invalid;\n        sig &=\n            ~(uint_fast64_t)\n                 (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n                      & roundNearEven);\n    }\n    if ( sign && sig ) goto invalid;\n    if ( exact && sigExtra ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return sig;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundToI32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast32_t\n softfloat_roundToI32(\n     bool sign, uint_fast64_t sig, uint_fast8_t roundingMode, bool exact )\n{\n    bool roundNearEven;\n    uint_fast16_t roundIncrement, roundBits;\n    uint_fast32_t sig32;\n    union { uint32_t ui; int32_t i; } uZ;\n    int_fast32_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    roundIncrement = 0x800;\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        roundIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                ? 0xFFF\n                : 0;\n    }\n    roundBits = sig & 0xFFF;\n    sig += roundIncrement;\n    if ( sig & UINT64_C( 0xFFFFF00000000000 ) ) goto invalid;\n    sig32 = sig>>12;\n    sig32 &= ~(uint_fast32_t) (! (roundBits ^ 0x800) & roundNearEven);\n    uZ.ui = sign ? -sig32 : sig32;\n    z = uZ.i;\n    if ( z && ((z < 0) ^ sign) ) goto invalid;\n    if ( exact && roundBits ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return z;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return sign ? i32_fromNegOverflow : i32_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundToI64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nint_fast64_t\n softfloat_roundToI64(\n     bool sign,\n     uint_fast64_t sig,\n     uint_fast64_t sigExtra,\n     uint_fast8_t roundingMode,\n     bool exact\n )\n{\n    bool roundNearEven, doIncrement;\n    union { uint64_t ui; int64_t i; } uZ;\n    int_fast64_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra);\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        doIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                && sigExtra;\n    }\n    if ( doIncrement ) {\n        ++sig;\n        if ( ! sig ) goto invalid;\n        sig &=\n            ~(uint_fast64_t)\n                 (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n                      & roundNearEven);\n    }\n    uZ.ui = sign ? -sig : sig;\n    z = uZ.i;\n    if ( z && ((z < 0) ^ sign) ) goto invalid;\n    if ( exact && sigExtra ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return z;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return sign ? i64_fromNegOverflow : i64_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundToUI32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast32_t\n softfloat_roundToUI32(\n     bool sign, uint_fast64_t sig, uint_fast8_t roundingMode, bool exact )\n{\n    bool roundNearEven;\n    uint_fast16_t roundIncrement, roundBits;\n    uint_fast32_t z;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    roundIncrement = 0x800;\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        roundIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                ? 0xFFF\n                : 0;\n    }\n    roundBits = sig & 0xFFF;\n    sig += roundIncrement;\n    if ( sig & UINT64_C( 0xFFFFF00000000000 ) ) goto invalid;\n    z = sig>>12;\n    z &= ~(uint_fast32_t) (! (roundBits ^ 0x800) & roundNearEven);\n    if ( sign && z ) goto invalid;\n    if ( exact && roundBits ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return z;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_roundToUI64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nuint_fast64_t\n softfloat_roundToUI64(\n     bool sign,\n     uint_fast64_t sig,\n     uint_fast64_t sigExtra,\n     uint_fast8_t roundingMode,\n     bool exact\n )\n{\n    bool roundNearEven, doIncrement;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    roundNearEven = (roundingMode == softfloat_round_near_even);\n    doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra);\n    if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {\n        doIncrement =\n            (roundingMode\n                 == (sign ? softfloat_round_min : softfloat_round_max))\n                && sigExtra;\n    }\n    if ( doIncrement ) {\n        ++sig;\n        if ( ! sig ) goto invalid;\n        sig &=\n            ~(uint_fast64_t)\n                 (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF ))\n                      & roundNearEven);\n    }\n    if ( sign && sig ) goto invalid;\n    if ( exact && sigExtra ) {\n        softfloat_exceptionFlags |= softfloat_flag_inexact;\n    }\n    return sig;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n invalid:\n    softfloat_raiseFlags( softfloat_flag_invalid );\n    return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shiftRightJam128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_shiftRightJam128\n\nstruct uint128\n softfloat_shiftRightJam128( uint64_t a64, uint64_t a0, uint_fast32_t dist )\n{\n    uint_fast8_t u8NegDist;\n    struct uint128 z;\n\n    if ( dist < 64 ) {\n        u8NegDist = -dist;\n        z.v64 = a64>>dist;\n        z.v0 =\n            a64<<(u8NegDist & 63) | a0>>dist\n                | ((uint64_t) (a0<<(u8NegDist & 63)) != 0);\n    } else {\n        z.v64 = 0;\n        z.v0 =\n            (dist < 127)\n                ? a64>>(dist & 63)\n                      | (((a64 & (((uint_fast64_t) 1<<(dist & 63)) - 1)) | a0)\n                             != 0)\n                : ((a64 | a0) != 0);\n    }\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shiftRightJam128Extra.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_shiftRightJam128Extra\n\nstruct uint128_extra\n softfloat_shiftRightJam128Extra(\n     uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t dist )\n{\n    uint_fast8_t u8NegDist;\n    struct uint128_extra z;\n\n    u8NegDist = -dist;\n    if ( dist < 64 ) {\n        z.v.v64 = a64>>dist;\n        z.v.v0 = a64<<(u8NegDist & 63) | a0>>dist;\n        z.extra = a0<<(u8NegDist & 63);\n    } else {\n        z.v.v64 = 0;\n        if ( dist == 64 ) {\n            z.v.v0 = a64;\n            z.extra = a0;\n        } else {\n            extra |= a0;\n            if ( dist < 128 ) {\n                z.v.v0 = a64>>(dist & 63);\n                z.extra = a64<<(u8NegDist & 63);\n            } else {\n                z.v.v0 = 0;\n                z.extra = (dist == 128) ? a64 : (a64 != 0);\n            }\n        }\n    }\n    z.extra |= (extra != 0);\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shiftRightJam256M.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_shiftRightJam256M\n\nstatic\n void\n  softfloat_shortShiftRightJamM(\n      uint_fast8_t size_words,\n      const uint64_t *aPtr,\n      uint_fast8_t dist,\n      uint64_t *zPtr\n  )\n{\n    uint_fast8_t uNegDist;\n    unsigned int index, lastIndex;\n    uint64_t partWordZ, wordA;\n\n    uNegDist = -dist;\n    index = indexWordLo( size_words );\n    lastIndex = indexWordHi( size_words );\n    wordA = aPtr[index];\n    partWordZ = wordA>>dist;\n    if ( partWordZ<<dist != wordA ) partWordZ |= 1;\n    while ( index != lastIndex ) {\n        wordA = aPtr[index + wordIncr];\n        zPtr[index] = wordA<<(uNegDist & 63) | partWordZ;\n        index += wordIncr;\n        partWordZ = wordA>>dist;\n    }\n    zPtr[index] = partWordZ;\n\n}\n\nvoid\n softfloat_shiftRightJam256M(\n     const uint64_t *aPtr, uint_fast32_t dist, uint64_t *zPtr )\n{\n    uint64_t wordJam;\n    uint_fast32_t wordDist;\n    uint64_t *ptr;\n    uint_fast8_t i, innerDist;\n\n    wordJam = 0;\n    wordDist = dist>>6;\n    if ( wordDist ) {\n        if ( 4 < wordDist ) wordDist = 4;\n        ptr = (uint64_t *) (aPtr + indexMultiwordLo( 4, wordDist ));\n        i = wordDist;\n        do {\n            wordJam = *ptr++;\n            if ( wordJam ) break;\n            --i;\n        } while ( i );\n        ptr = zPtr;\n    }\n    if ( wordDist < 4 ) {\n        aPtr += indexMultiwordHiBut( 4, wordDist );\n        innerDist = dist & 63;\n        if ( innerDist ) {\n            softfloat_shortShiftRightJamM(\n                4 - wordDist,\n                aPtr,\n                innerDist,\n                zPtr + indexMultiwordLoBut( 4, wordDist )\n            );\n            if ( ! wordDist ) goto wordJam;\n        } else {\n            aPtr += indexWordLo( 4 - wordDist );\n            ptr = zPtr + indexWordLo( 4 );\n            for ( i = 4 - wordDist; i; --i ) {\n                *ptr = *aPtr;\n                aPtr += wordIncr;\n                ptr += wordIncr;\n            }\n        }\n        ptr = zPtr + indexMultiwordHi( 4, wordDist );\n    }\n    do {\n        *ptr++ = 0;\n        --wordDist;\n    } while ( wordDist );\n wordJam:\n    if ( wordJam ) zPtr[indexWordLo( 4 )] |= 1;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shiftRightJam32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifndef softfloat_shiftRightJam32\n\nuint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist )\n{\n\n    return\n        (dist < 31) ? a>>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0);\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shiftRightJam64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifndef softfloat_shiftRightJam64\n\nuint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist )\n{\n\n    return\n        (dist < 63) ? a>>dist | ((uint64_t) (a<<(-dist & 63)) != 0) : (a != 0);\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shiftRightJam64Extra.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_shiftRightJam64Extra\n\nstruct uint64_extra\n softfloat_shiftRightJam64Extra(\n     uint64_t a, uint64_t extra, uint_fast32_t dist )\n{\n    struct uint64_extra z;\n\n    if ( dist < 64 ) {\n        z.v = a>>dist;\n        z.extra = a<<(-dist & 63);\n    } else {\n        z.v = 0;\n        z.extra = (dist == 64) ? a : (a != 0);\n    }\n    z.extra |= (extra != 0);\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shortShiftLeft128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_shortShiftLeft128\n\nstruct uint128\n softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t dist )\n{\n    struct uint128 z;\n\n    z.v64 = a64<<dist | a0>>(-dist & 63);\n    z.v0 = a0<<dist;\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shortShiftLeft64To96M.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_shortShiftLeft64To96M\n\nvoid\n softfloat_shortShiftLeft64To96M(\n     uint64_t a, uint_fast8_t dist, uint32_t *zPtr )\n{\n\n    zPtr[indexWord( 3, 0 )] = (uint32_t) a<<dist;\n    a >>= 32 - dist;\n    zPtr[indexWord( 3, 2 )] = a>>32;\n    zPtr[indexWord( 3, 1 )] = a;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shortShiftRight128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_shortShiftRight128\n\nstruct uint128\n softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t dist )\n{\n    struct uint128 z;\n\n    z.v64 = a64>>dist;\n    z.v0 = a64<<(-dist & 63) | a0>>dist;\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shortShiftRightExtendM.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_shortShiftRightExtendM\n\nvoid\n softfloat_shortShiftRightExtendM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     uint_fast8_t dist,\n     uint32_t *zPtr\n )\n{\n    uint_fast8_t uNegDist;\n    unsigned int indexA, lastIndexA;\n    uint32_t partWordZ, wordA;\n\n    uNegDist = -dist;\n    indexA = indexWordLo( size_words );\n    lastIndexA = indexWordHi( size_words );\n    zPtr += indexWordLo( size_words + 1 );\n    partWordZ = 0;\n    for (;;) {\n        wordA = aPtr[indexA];\n        *zPtr = wordA<<(uNegDist & 31) | partWordZ;\n        zPtr += wordIncr;\n        partWordZ = wordA>>dist;\n        if ( indexA == lastIndexA ) break;\n        indexA += wordIncr;\n    }\n    *zPtr = partWordZ;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shortShiftRightJam128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_shortShiftRightJam128\n\nstruct uint128\n softfloat_shortShiftRightJam128(\n     uint64_t a64, uint64_t a0, uint_fast8_t dist )\n{\n    uint_fast8_t uNegDist;\n    struct uint128 z;\n\n    uNegDist = -dist;\n    z.v64 = a64>>dist;\n    z.v0 =\n        a64<<(uNegDist & 63) | a0>>dist\n            | ((uint64_t) (a0<<(uNegDist & 63)) != 0);\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shortShiftRightJam128Extra.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_shortShiftRightJam128Extra\n\nstruct uint128_extra\n softfloat_shortShiftRightJam128Extra(\n     uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist )\n{\n    uint_fast8_t uNegDist;\n    struct uint128_extra z;\n\n    uNegDist = -dist;\n    z.v.v64 = a64>>dist;\n    z.v.v0 = a64<<(uNegDist & 63) | a0>>dist;\n    z.extra = a0<<(uNegDist & 63) | (extra != 0);\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shortShiftRightJam64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n\n#ifndef softfloat_shortShiftRightJam64\n\nuint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist )\n{\n\n    return a>>dist | ((a & (((uint_fast64_t) 1<<dist) - 1)) != 0);\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shortShiftRightJam64Extra.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_shortShiftRightJam64Extra\n\nstruct uint64_extra\n softfloat_shortShiftRightJam64Extra(\n     uint64_t a, uint64_t extra, uint_fast8_t dist )\n{\n    struct uint64_extra z;\n\n    z.v = a>>dist;\n    z.extra = a<<(-dist & 63) | (extra != 0);\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_shortShiftRightM.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_shortShiftRightM\n\nvoid\n softfloat_shortShiftRightM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     uint_fast8_t dist,\n     uint32_t *zPtr\n )\n{\n    uint_fast8_t uNegDist;\n    unsigned int index, lastIndex;\n    uint32_t partWordZ, wordA;\n\n    uNegDist = -dist;\n    index = indexWordLo( size_words );\n    lastIndex = indexWordHi( size_words );\n    partWordZ = aPtr[index]>>dist;\n    while ( index != lastIndex ) {\n        wordA = aPtr[index + wordIncr];\n        zPtr[index] = wordA<<(uNegDist & 31) | partWordZ;\n        index += wordIncr;\n        partWordZ = wordA>>dist;\n    }\n    zPtr[index] = partWordZ;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_sub128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_sub128\n\nstruct uint128\n softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )\n{\n    struct uint128 z;\n\n    z.v0 = a0 - b0;\n    z.v64 = a64 - b64 - (a0 < b0);\n    return z;\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_sub1XM.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_sub1XM\n\nvoid softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr )\n{\n    unsigned int index, lastIndex;\n    uint32_t wordA;\n\n    index = indexWordLo( size_words );\n    lastIndex = indexWordHi( size_words );\n    for (;;) {\n        wordA = zPtr[index];\n        zPtr[index] = wordA - 1;\n        if ( wordA || (index == lastIndex) ) break;\n        index += wordIncr;\n    }\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_sub256M.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_sub256M\n\nvoid\n softfloat_sub256M(\n     const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr )\n{\n    unsigned int index;\n    uint_fast8_t borrow;\n    uint64_t wordA, wordB;\n\n    index = indexWordLo( 4 );\n    borrow = 0;\n    for (;;) {\n        wordA = aPtr[index];\n        wordB = bPtr[index];\n        zPtr[index] = wordA - wordB - borrow;\n        if ( index == indexWordHi( 4 ) ) break;\n        borrow = borrow ? (wordA <= wordB) : (wordA < wordB);\n        index += wordIncr;\n    }\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_subM.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"primitiveTypes.h\"\n\n#ifndef softfloat_subM\n\nvoid\n softfloat_subM(\n     uint_fast8_t size_words,\n     const uint32_t *aPtr,\n     const uint32_t *bPtr,\n     uint32_t *zPtr\n )\n{\n    unsigned int index, lastIndex;\n    uint_fast8_t borrow;\n    uint32_t wordA, wordB;\n\n    index = indexWordLo( size_words );\n    lastIndex = indexWordHi( size_words );\n    borrow = 0;\n    for (;;) {\n        wordA = aPtr[index];\n        wordB = bPtr[index];\n        zPtr[index] = wordA - wordB - borrow;\n        if ( index == lastIndex ) break;\n        borrow = borrow ? (wordA <= wordB) : (wordA < wordB);\n        index += wordIncr;\n    }\n\n}\n\n#endif\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_subMagsF128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat128_t\n softfloat_subMagsF128(\n     uint_fast64_t uiA64,\n     uint_fast64_t uiA0,\n     uint_fast64_t uiB64,\n     uint_fast64_t uiB0,\n     bool signZ\n )\n{\n    int_fast32_t expA;\n    struct uint128 sigA;\n    int_fast32_t expB;\n    struct uint128 sigB, sigZ;\n    int_fast32_t expDiff, expZ;\n    struct uint128 uiZ;\n    union ui128_f128 uZ;\n\n    expA = expF128UI64( uiA64 );\n    sigA.v64 = fracF128UI64( uiA64 );\n    sigA.v0  = uiA0;\n    expB = expF128UI64( uiB64 );\n    sigB.v64 = fracF128UI64( uiB64 );\n    sigB.v0  = uiB0;\n    sigA = softfloat_shortShiftLeft128( sigA.v64, sigA.v0, 4 );\n    sigB = softfloat_shortShiftLeft128( sigB.v64, sigB.v0, 4 );\n    expDiff = expA - expB;\n    if ( 0 < expDiff ) goto expABigger;\n    if ( expDiff < 0 ) goto expBBigger;\n    if ( expA == 0x7FFF ) {\n        if ( sigA.v64 | sigA.v0 | sigB.v64 | sigB.v0 ) goto propagateNaN;\n        softfloat_raiseFlags( softfloat_flag_invalid );\n        uiZ.v64 = defaultNaNF128UI64;\n        uiZ.v0  = defaultNaNF128UI0;\n        goto uiZ;\n    }\n    expZ = expA;\n    if ( ! expZ ) expZ = 1;\n    if ( sigB.v64 < sigA.v64 ) goto aBigger;\n    if ( sigA.v64 < sigB.v64 ) goto bBigger;\n    if ( sigB.v0 < sigA.v0 ) goto aBigger;\n    if ( sigA.v0 < sigB.v0 ) goto bBigger;\n    uiZ.v64 =\n        packToF128UI64(\n            (softfloat_roundingMode == softfloat_round_min), 0, 0 );\n    uiZ.v0 = 0;\n    goto uiZ;\n expBBigger:\n    if ( expB == 0x7FFF ) {\n        if ( sigB.v64 | sigB.v0 ) goto propagateNaN;\n        uiZ.v64 = packToF128UI64( signZ ^ 1, 0x7FFF, 0 );\n        uiZ.v0  = 0;\n        goto uiZ;\n    }\n    if ( expA ) {\n        sigA.v64 |= UINT64_C( 0x0010000000000000 );\n    } else {\n        ++expDiff;\n        if ( ! expDiff ) goto newlyAlignedBBigger;\n    }\n    sigA = softfloat_shiftRightJam128( sigA.v64, sigA.v0, -expDiff );\n newlyAlignedBBigger:\n    expZ = expB;\n    sigB.v64 |= UINT64_C( 0x0010000000000000 );\n bBigger:\n    signZ = ! signZ;\n    sigZ = softfloat_sub128( sigB.v64, sigB.v0, sigA.v64, sigA.v0 );\n    goto normRoundPack;\n expABigger:\n    if ( expA == 0x7FFF ) {\n        if ( sigA.v64 | sigA.v0 ) goto propagateNaN;\n        uiZ.v64 = uiA64;\n        uiZ.v0  = uiA0;\n        goto uiZ;\n    }\n    if ( expB ) {\n        sigB.v64 |= UINT64_C( 0x0010000000000000 );\n    } else {\n        --expDiff;\n        if ( ! expDiff ) goto newlyAlignedABigger;\n    }\n    sigB = softfloat_shiftRightJam128( sigB.v64, sigB.v0, expDiff );\n newlyAlignedABigger:\n    expZ = expA;\n    sigA.v64 |= UINT64_C( 0x0010000000000000 );\n aBigger:\n    sigZ = softfloat_sub128( sigA.v64, sigA.v0, sigB.v64, sigB.v0 );\n normRoundPack:\n    return softfloat_normRoundPackToF128( signZ, expZ - 5, sigZ.v64, sigZ.v0 );\n propagateNaN:\n    uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_subMagsF16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the\nUniversity of California.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat16_t softfloat_subMagsF16( uint_fast16_t uiA, uint_fast16_t uiB )\n{\n    int_fast8_t expA;\n    uint_fast16_t sigA;\n    int_fast8_t expB;\n    uint_fast16_t sigB;\n    int_fast8_t expDiff;\n    uint_fast16_t uiZ;\n    int_fast16_t sigDiff;\n    bool signZ;\n    int_fast8_t shiftDist, expZ;\n    uint_fast16_t sigZ, sigX, sigY;\n    uint_fast32_t sig32Z;\n    int_fast8_t roundingMode;\n    union ui16_f16 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expA = expF16UI( uiA );\n    sigA = fracF16UI( uiA );\n    expB = expF16UI( uiB );\n    sigB = fracF16UI( uiB );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expDiff = expA - expB;\n    if ( ! expDiff ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( expA == 0x1F ) {\n            if ( sigA | sigB ) goto propagateNaN;\n            softfloat_raiseFlags( softfloat_flag_invalid );\n            uiZ = defaultNaNF16UI;\n            goto uiZ;\n        }\n        sigDiff = sigA - sigB;\n        if ( ! sigDiff ) {\n            uiZ =\n                packToF16UI(\n                    (softfloat_roundingMode == softfloat_round_min), 0, 0 );\n            goto uiZ;\n        }\n        if ( expA ) --expA;\n        signZ = signF16UI( uiA );\n        if ( sigDiff < 0 ) {\n            signZ = ! signZ;\n            sigDiff = -sigDiff;\n        }\n        shiftDist = softfloat_countLeadingZeros16( sigDiff ) - 5;\n        expZ = expA - shiftDist;\n        if ( expZ < 0 ) {\n            shiftDist = expA;\n            expZ = 0;\n        }\n        sigZ = sigDiff<<shiftDist;\n        goto pack;\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        signZ = signF16UI( uiA );\n        if ( expDiff < 0 ) {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            signZ = ! signZ;\n            if ( expB == 0x1F ) {\n                if ( sigB ) goto propagateNaN;\n                uiZ = packToF16UI( signZ, 0x1F, 0 );\n                goto uiZ;\n            }\n            if ( expDiff <= -13 ) {\n                uiZ = packToF16UI( signZ, expB, sigB );\n                if ( expA | sigA ) goto subEpsilon;\n                goto uiZ;\n            }\n            expZ = expA + 19;\n            sigX = sigB | 0x0400;\n            sigY = sigA + (expA ? 0x0400 : sigA);\n            expDiff = -expDiff;\n        } else {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            uiZ = uiA;\n            if ( expA == 0x1F ) {\n                if ( sigA ) goto propagateNaN;\n                goto uiZ;\n            }\n            if ( 13 <= expDiff ) {\n                if ( expB | sigB ) goto subEpsilon;\n                goto uiZ;\n            }\n            expZ = expB + 19;\n            sigX = sigA | 0x0400;\n            sigY = sigB + (expB ? 0x0400 : sigB);\n        }\n        sig32Z = ((uint_fast32_t) sigX<<expDiff) - sigY;\n        shiftDist = softfloat_countLeadingZeros32( sig32Z ) - 1;\n        sig32Z <<= shiftDist;\n        expZ -= shiftDist;\n        sigZ = sig32Z>>16;\n        if ( sig32Z & 0xFFFF ) {\n            sigZ |= 1;\n        } else {\n            if ( ! (sigZ & 0xF) && ((unsigned int) expZ < 0x1E) ) {\n                sigZ >>= 4;\n                goto pack;\n            }\n        }\n        return softfloat_roundPackToF16( signZ, expZ, sigZ );\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF16UI( uiA, uiB );\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n subEpsilon:\n    roundingMode = softfloat_roundingMode;\n    if ( roundingMode != softfloat_round_near_even ) {\n        if (\n            (roundingMode == softfloat_round_minMag)\n                || (roundingMode\n                        == (signF16UI( uiZ ) ? softfloat_round_max\n                                : softfloat_round_min))\n        ) {\n            --uiZ;\n        }\n#ifdef SOFTFLOAT_ROUND_ODD\n        else if ( roundingMode == softfloat_round_odd ) {\n            uiZ = (uiZ - 1) | 1;\n        }\n#endif\n    }\n    softfloat_exceptionFlags |= softfloat_flag_inexact;\n    goto uiZ;\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n pack:\n    uiZ = packToF16UI( signZ, expZ, sigZ );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_subMagsF32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat32_t softfloat_subMagsF32( uint_fast32_t uiA, uint_fast32_t uiB )\n{\n    int_fast16_t expA;\n    uint_fast32_t sigA;\n    int_fast16_t expB;\n    uint_fast32_t sigB;\n    int_fast16_t expDiff;\n    uint_fast32_t uiZ;\n    int_fast32_t sigDiff;\n    bool signZ;\n    int_fast8_t shiftDist;\n    int_fast16_t expZ;\n    uint_fast32_t sigX, sigY;\n    union ui32_f32 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expA = expF32UI( uiA );\n    sigA = fracF32UI( uiA );\n    expB = expF32UI( uiB );\n    sigB = fracF32UI( uiB );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expDiff = expA - expB;\n    if ( ! expDiff ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( expA == 0xFF ) {\n            if ( sigA | sigB ) goto propagateNaN;\n            softfloat_raiseFlags( softfloat_flag_invalid );\n            uiZ = defaultNaNF32UI;\n            goto uiZ;\n        }\n        sigDiff = sigA - sigB;\n        if ( ! sigDiff ) {\n            uiZ =\n                packToF32UI(\n                    (softfloat_roundingMode == softfloat_round_min), 0, 0 );\n            goto uiZ;\n        }\n        if ( expA ) --expA;\n        signZ = signF32UI( uiA );\n        if ( sigDiff < 0 ) {\n            signZ = ! signZ;\n            sigDiff = -sigDiff;\n        }\n        shiftDist = softfloat_countLeadingZeros32( sigDiff ) - 8;\n        expZ = expA - shiftDist;\n        if ( expZ < 0 ) {\n            shiftDist = expA;\n            expZ = 0;\n        }\n        uiZ = packToF32UI( signZ, expZ, sigDiff<<shiftDist );\n        goto uiZ;\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        signZ = signF32UI( uiA );\n        sigA <<= 7;\n        sigB <<= 7;\n        if ( expDiff < 0 ) {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            signZ = ! signZ;\n            if ( expB == 0xFF ) {\n                if ( sigB ) goto propagateNaN;\n                uiZ = packToF32UI( signZ, 0xFF, 0 );\n                goto uiZ;\n            }\n            expZ = expB - 1;\n            sigX = sigB | 0x40000000;\n            sigY = sigA + (expA ? 0x40000000 : sigA);\n            expDiff = -expDiff;\n        } else {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            if ( expA == 0xFF ) {\n                if ( sigA ) goto propagateNaN;\n                uiZ = uiA;\n                goto uiZ;\n            }\n            expZ = expA - 1;\n            sigX = sigA | 0x40000000;\n            sigY = sigB + (expB ? 0x40000000 : sigB);\n        }\n        return\n            softfloat_normRoundPackToF32(\n                signZ, expZ, sigX - softfloat_shiftRightJam32( sigY, expDiff )\n            );\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF32UI( uiA, uiB );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/s_subMagsF64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdbool.h>\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\nfloat64_t\n softfloat_subMagsF64( uint_fast64_t uiA, uint_fast64_t uiB, bool signZ )\n{\n    int_fast16_t expA;\n    uint_fast64_t sigA;\n    int_fast16_t expB;\n    uint_fast64_t sigB;\n    int_fast16_t expDiff;\n    uint_fast64_t uiZ;\n    int_fast64_t sigDiff;\n    int_fast8_t shiftDist;\n    int_fast16_t expZ;\n    uint_fast64_t sigZ;\n    union ui64_f64 uZ;\n\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expA = expF64UI( uiA );\n    sigA = fracF64UI( uiA );\n    expB = expF64UI( uiB );\n    sigB = fracF64UI( uiB );\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n    expDiff = expA - expB;\n    if ( ! expDiff ) {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        if ( expA == 0x7FF ) {\n            if ( sigA | sigB ) goto propagateNaN;\n            softfloat_raiseFlags( softfloat_flag_invalid );\n            uiZ = defaultNaNF64UI;\n            goto uiZ;\n        }\n        sigDiff = sigA - sigB;\n        if ( ! sigDiff ) {\n            uiZ =\n                packToF64UI(\n                    (softfloat_roundingMode == softfloat_round_min), 0, 0 );\n            goto uiZ;\n        }\n        if ( expA ) --expA;\n        if ( sigDiff < 0 ) {\n            signZ = ! signZ;\n            sigDiff = -sigDiff;\n        }\n        shiftDist = softfloat_countLeadingZeros64( sigDiff ) - 11;\n        expZ = expA - shiftDist;\n        if ( expZ < 0 ) {\n            shiftDist = expA;\n            expZ = 0;\n        }\n        uiZ = packToF64UI( signZ, expZ, sigDiff<<shiftDist );\n        goto uiZ;\n    } else {\n        /*--------------------------------------------------------------------\n        *--------------------------------------------------------------------*/\n        sigA <<= 10;\n        sigB <<= 10;\n        if ( expDiff < 0 ) {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            signZ = ! signZ;\n            if ( expB == 0x7FF ) {\n                if ( sigB ) goto propagateNaN;\n                uiZ = packToF64UI( signZ, 0x7FF, 0 );\n                goto uiZ;\n            }\n            sigA += expA ? UINT64_C( 0x4000000000000000 ) : sigA;\n            sigA = softfloat_shiftRightJam64( sigA, -expDiff );\n            sigB |= UINT64_C( 0x4000000000000000 );\n            expZ = expB;\n            sigZ = sigB - sigA;\n        } else {\n            /*----------------------------------------------------------------\n            *----------------------------------------------------------------*/\n            if ( expA == 0x7FF ) {\n                if ( sigA ) goto propagateNaN;\n                uiZ = uiA;\n                goto uiZ;\n            }\n            sigB += expB ? UINT64_C( 0x4000000000000000 ) : sigB;\n            sigB = softfloat_shiftRightJam64( sigB, expDiff );\n            sigA |= UINT64_C( 0x4000000000000000 );\n            expZ = expA;\n            sigZ = sigA - sigB;\n        }\n        return softfloat_normRoundPackToF64( signZ, expZ - 1, sigZ );\n    }\n    /*------------------------------------------------------------------------\n    *------------------------------------------------------------------------*/\n propagateNaN:\n    uiZ = softfloat_propagateNaNF64UI( uiA, uiB );\n uiZ:\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/softfloat_raiseFlags.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include \"platform.h\"\n#include \"softfloat.h\"\n\n/*----------------------------------------------------------------------------\n| Raises the exceptions specified by `flags'.  Floating-point traps can be\n| defined here if desired.  It is currently not possible for such a trap\n| to substitute a result value.  If traps are not implemented, this routine\n| should be simply `softfloat_exceptionFlags |= flags;'.\n*----------------------------------------------------------------------------*/\nvoid softfloat_raiseFlags( uint_fast8_t flags )\n{\n\n    softfloat_exceptionFlags |= flags;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/softfloat_state.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All Rights Reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"specialize.h\"\n#include \"softfloat.h\"\n\n#ifndef THREAD_LOCAL\n#define THREAD_LOCAL\n#endif\n\nTHREAD_LOCAL uint_fast8_t softfloat_roundingMode = softfloat_round_near_even;\nTHREAD_LOCAL uint_fast8_t softfloat_detectTininess = init_detectTininess;\nTHREAD_LOCAL uint_fast8_t softfloat_exceptionFlags = 0;\n\nTHREAD_LOCAL uint_fast8_t extF80_roundingPrecision = 80;\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/ui32_to_f128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All Rights Reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat128_t ui32_to_f128( uint32_t a )\n{\n    uint_fast64_t uiZ64;\n    int_fast8_t shiftDist;\n    union ui128_f128 uZ;\n\n    uiZ64 = 0;\n    if ( a ) {\n        shiftDist = softfloat_countLeadingZeros32( a ) + 17;\n        uiZ64 =\n            packToF128UI64(\n                0, 0x402E - shiftDist, (uint_fast64_t) a<<shiftDist );\n    }\n    uZ.ui.v64 = uiZ64;\n    uZ.ui.v0  = 0;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/ui32_to_f16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All Rights Reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat16_t ui32_to_f16( uint32_t a )\n{\n    int_fast8_t shiftDist;\n    union ui16_f16 u;\n    uint_fast16_t sig;\n\n    shiftDist = softfloat_countLeadingZeros32( a ) - 21;\n    if ( 0 <= shiftDist ) {\n        u.ui =\n            a ? packToF16UI(\n                    0, 0x18 - shiftDist, (uint_fast16_t) a<<shiftDist )\n                : 0;\n        return u.f;\n    } else {\n        shiftDist += 4;\n        sig =\n            (shiftDist < 0)\n                ? a>>(-shiftDist) | ((uint32_t) (a<<(shiftDist & 31)) != 0)\n                : (uint_fast16_t) a<<shiftDist;\n        return softfloat_roundPackToF16( 0, 0x1C - shiftDist, sig );\n    }\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/ui32_to_f32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll Rights Reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat32_t ui32_to_f32( uint32_t a )\n{\n    union ui32_f32 uZ;\n\n    if ( ! a ) {\n        uZ.ui = 0;\n        return uZ.f;\n    }\n    if ( a & 0x80000000 ) {\n        return softfloat_roundPackToF32( 0, 0x9D, a>>1 | (a & 1) );\n    } else {\n        return softfloat_normRoundPackToF32( 0, 0x9C, a );\n    }\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/ui32_to_f64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All Rights Reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat64_t ui32_to_f64( uint32_t a )\n{\n    uint_fast64_t uiZ;\n    int_fast8_t shiftDist;\n    union ui64_f64 uZ;\n\n    if ( ! a ) {\n        uiZ = 0;\n    } else {\n        shiftDist = softfloat_countLeadingZeros32( a ) + 21;\n        uiZ =\n            packToF64UI( 0, 0x432 - shiftDist, (uint_fast64_t) a<<shiftDist );\n    }\n    uZ.ui = uiZ;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/ui64_to_f128.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All Rights Reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat128_t ui64_to_f128( uint64_t a )\n{\n    uint_fast64_t uiZ64, uiZ0;\n    int_fast8_t shiftDist;\n    struct uint128 zSig;\n    union ui128_f128 uZ;\n\n    if ( ! a ) {\n        uiZ64 = 0;\n        uiZ0  = 0;\n    } else {\n        shiftDist = softfloat_countLeadingZeros64( a ) + 49;\n        if ( 64 <= shiftDist ) {\n            zSig.v64 = a<<(shiftDist - 64);\n            zSig.v0  = 0;\n        } else {\n            zSig = softfloat_shortShiftLeft128( 0, a, shiftDist );\n        }\n        uiZ64 = packToF128UI64( 0, 0x406E - shiftDist, zSig.v64 );\n        uiZ0  = zSig.v0;\n    }\n    uZ.ui.v64 = uiZ64;\n    uZ.ui.v0  = uiZ0;\n    return uZ.f;\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/ui64_to_f16.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All Rights Reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat16_t ui64_to_f16( uint64_t a )\n{\n    int_fast8_t shiftDist;\n    union ui16_f16 u;\n    uint_fast16_t sig;\n\n    shiftDist = softfloat_countLeadingZeros64( a ) - 53;\n    if ( 0 <= shiftDist ) {\n        u.ui =\n            a ? packToF16UI(\n                    0, 0x18 - shiftDist, (uint_fast16_t) a<<shiftDist )\n                : 0;\n        return u.f;\n    } else {\n        shiftDist += 4;\n        sig =\n            (shiftDist < 0) ? softfloat_shortShiftRightJam64( a, -shiftDist )\n                : (uint_fast16_t) a<<shiftDist;\n        return softfloat_roundPackToF16( 0, 0x1C - shiftDist, sig );\n    }\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/ui64_to_f32.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of\nCalifornia.  All Rights Reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat32_t ui64_to_f32( uint64_t a )\n{\n    int_fast8_t shiftDist;\n    union ui32_f32 u;\n    uint_fast32_t sig;\n\n    shiftDist = softfloat_countLeadingZeros64( a ) - 40;\n    if ( 0 <= shiftDist ) {\n        u.ui =\n            a ? packToF32UI(\n                    0, 0x95 - shiftDist, (uint_fast32_t) a<<shiftDist )\n                : 0;\n        return u.f;\n    } else {\n        shiftDist += 7;\n        sig =\n            (shiftDist < 0) ? softfloat_shortShiftRightJam64( a, -shiftDist )\n                : (uint_fast32_t) a<<shiftDist;\n        return softfloat_roundPackToF32( 0, 0x9C - shiftDist, sig );\n    }\n\n}\n\n"
  },
  {
    "path": "vp/src/vendor/softfloat/ui64_to_f64.c",
    "content": "\n/*============================================================================\n\nThis C source file is part of the SoftFloat IEEE Floating-Point Arithmetic\nPackage, Release 3d, by John R. Hauser.\n\nCopyright 2011, 2012, 2013, 2014 The Regents of the University of California.\nAll Rights Reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice,\n    this list of conditions, and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions, and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n 3. Neither the name of the University nor the names of its contributors may\n    be used to endorse or promote products derived from this software without\n    specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS \"AS IS\", AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE\nDISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n=============================================================================*/\n\n#include <stdint.h>\n#include \"platform.h\"\n#include \"internals.h\"\n#include \"softfloat.h\"\n\nfloat64_t ui64_to_f64( uint64_t a )\n{\n    union ui64_f64 uZ;\n\n    if ( ! a ) {\n        uZ.ui = 0;\n        return uZ.f;\n    }\n    if ( a & UINT64_C( 0x8000000000000000 ) ) {\n        return\n            softfloat_roundPackToF64(\n                0, 0x43D, softfloat_shortShiftRightJam64( a, 1 ) );\n    } else {\n        return softfloat_normRoundPackToF64( 0, 0x43C, a );\n    }\n\n}\n\n"
  }
]