Compare commits
249 Commits
Author | SHA1 | Date |
---|---|---|
Pavel R. | 7adbc171f6 | 3 years ago |
Pavel R. | 072d2c37f0 | 3 years ago |
Pavel R. | 21fd437e89 | 3 years ago |
annelin | 73de201165 | 3 years ago |
annelin | be65484feb | 3 years ago |
annelin | 7d376acf62 | 3 years ago |
Pavel R. | 3995761bf1 | 3 years ago |
Pavel R. | 5359ca1d5f | 3 years ago |
Dibyendu Majumdar | d022074ae6 | 3 years ago |
Dibyendu Majumdar | cf3be2e688 | 3 years ago |
Dibyendu Majumdar | bbf2c29077 | 3 years ago |
Dibyendu Majumdar | 2c81edafa0 | 3 years ago |
Dibyendu Majumdar | b073242254 | 3 years ago |
Dibyendu Majumdar | 6eb43324dd | 3 years ago |
Dibyendu Majumdar | 4bfc061a2a | 3 years ago |
Dibyendu Majumdar | 3efaddee6b | 3 years ago |
Dibyendu Majumdar | d5e324fd53 | 3 years ago |
Dibyendu Majumdar | e3d8203bd9 | 3 years ago |
Dibyendu Majumdar | 53ec0c19b3 | 3 years ago |
XmiliaH | 5ca801596a | 3 years ago |
Dibyendu Majumdar | 58980db5cb | 3 years ago |
Dibyendu Majumdar | 347ae985bc | 3 years ago |
Dibyendu Majumdar | 063a55604e | 3 years ago |
Dibyendu Majumdar | 8e815bd67a | 3 years ago |
Dibyendu Majumdar | 658f04c3d8 | 3 years ago |
Dibyendu Majumdar | 8fd3a1bbab | 3 years ago |
Dibyendu Majumdar | b5afdfaa46 | 3 years ago |
Dibyendu Majumdar | 88ccaf34a0 | 3 years ago |
Dibyendu Majumdar | 5c30d255c7 | 3 years ago |
Dibyendu Majumdar | 248c730c43 | 3 years ago |
Dibyendu Majumdar | 4a20693671 | 3 years ago |
Dibyendu Majumdar | cb6943a1eb | 3 years ago |
XmiliaH | 837dc959cf | 3 years ago |
Dibyendu Majumdar | 754fcefc26 | 3 years ago |
XmiliaH | b4359b9391 | 3 years ago |
XmiliaH | a9537957d5 | 3 years ago |
XmiliaH | 435480f4db | 3 years ago |
XmiliaH | 62ab591343 | 3 years ago |
XmiliaH | f80e4d5442 | 3 years ago |
XmiliaH | 7789f4f32d | 3 years ago |
XmiliaH | c0122cd816 | 3 years ago |
XmiliaH | 58cdc8d7dc | 3 years ago |
XmiliaH | 6af3d804a4 | 3 years ago |
XmiliaH | 871b76fea2 | 3 years ago |
XmiliaH | 0b43c94a4d | 3 years ago |
XmiliaH | e85634270f | 3 years ago |
XmiliaH | 4cce67ec13 | 3 years ago |
Dibyendu Majumdar | a2ec53624d | 3 years ago |
Dibyendu Majumdar | 9bceadd099 | 3 years ago |
Dibyendu Majumdar | 25dbc31393 | 3 years ago |
Dibyendu Majumdar | 2c5b958d04 | 3 years ago |
Dibyendu Majumdar | b0a5b01142 | 3 years ago |
Dibyendu Majumdar | 170fd797a2 | 3 years ago |
Dibyendu Majumdar | b2cc7c30c5 | 3 years ago |
Dibyendu Majumdar | 2decef927a | 3 years ago |
Dibyendu Majumdar | 486145900b | 3 years ago |
Dibyendu Majumdar | a3b933aa43 | 3 years ago |
Dibyendu Majumdar | 1e8597de7d | 3 years ago |
Dibyendu Majumdar | 9ced7e2bc0 | 3 years ago |
Dibyendu Majumdar | fe7c76fff5 | 3 years ago |
Dibyendu Majumdar | ad4fc4e2d2 | 3 years ago |
Dibyendu Majumdar | 2c44bdd68b | 3 years ago |
Dibyendu Majumdar | 8bd404f62e | 3 years ago |
Dibyendu Majumdar | 4342fc7630 | 3 years ago |
Dibyendu Majumdar | 927ddbf6a0 | 3 years ago |
Dibyendu Majumdar | b549302d70 | 3 years ago |
Dibyendu Majumdar | 56a59a1f31 | 3 years ago |
Dibyendu Majumdar | 773ebd9d32 | 3 years ago |
Dibyendu Majumdar | def4d76ac9 | 3 years ago |
Dibyendu Majumdar | ef24ca67cb | 3 years ago |
Dibyendu Majumdar | 77cd6b9527 | 3 years ago |
Dibyendu Majumdar | 61a8ac889f | 3 years ago |
Dibyendu Majumdar | 102c8bee8b | 3 years ago |
Dibyendu Majumdar | 3e05644f51 | 3 years ago |
Dibyendu Majumdar | f7f59eed0f | 3 years ago |
Dibyendu Majumdar | 2aeeea4dd3 | 3 years ago |
Dibyendu Majumdar | 31774723ff | 3 years ago |
Dibyendu Majumdar | cc0c098011 | 3 years ago |
Dibyendu Majumdar | f072326ea4 | 3 years ago |
Dibyendu Majumdar | 66615703a6 | 3 years ago |
Dibyendu Majumdar | ef30fb2065 | 3 years ago |
Dibyendu Majumdar | 2335973259 | 3 years ago |
Dibyendu Majumdar | fae2a2bf77 | 3 years ago |
Dibyendu Majumdar | 08c05100cf | 3 years ago |
Dibyendu Majumdar | 3b09a22e96 | 3 years ago |
Dibyendu Majumdar | 1f1d8cb428 | 3 years ago |
Dibyendu Majumdar | 9083492dcb | 3 years ago |
Dibyendu Majumdar | e6890743f0 | 3 years ago |
Dibyendu Majumdar | 9cc59144ad | 3 years ago |
Dibyendu Majumdar | f27792f050 | 3 years ago |
Dibyendu Majumdar | df748ee844 | 3 years ago |
Dibyendu Majumdar | ed90926c8d | 3 years ago |
Dibyendu Majumdar | 1fb5b08491 | 3 years ago |
Dibyendu Majumdar | facb56e0c1 | 3 years ago |
Dibyendu Majumdar | 9a86f11bc3 | 3 years ago |
Dibyendu Majumdar | 92fd0e3faf | 3 years ago |
Dibyendu Majumdar | 54fc5277d6 | 3 years ago |
Dibyendu Majumdar | c11122376e | 3 years ago |
Dibyendu Majumdar | 36639d863a | 3 years ago |
Dibyendu Majumdar | 71644f5450 | 3 years ago |
Dibyendu Majumdar | b717be20e0 | 3 years ago |
Dibyendu Majumdar | 249f22c215 | 3 years ago |
Dibyendu Majumdar | 2f76a1e869 | 3 years ago |
Dibyendu Majumdar | 4acc325c97 | 3 years ago |
Dibyendu Majumdar | ec2d27a7dc | 3 years ago |
Dibyendu Majumdar | 7320131275 | 3 years ago |
Dibyendu Majumdar | f9c4b5dbec | 3 years ago |
Dibyendu Majumdar | 0c3277ad4a | 3 years ago |
Dibyendu Majumdar | d6422fe2e3 | 3 years ago |
Dibyendu Majumdar | 66511033fd | 3 years ago |
Dibyendu Majumdar | 05f365352c | 3 years ago |
Dibyendu Majumdar | 219d44c2ba | 3 years ago |
Dibyendu Majumdar | e4a240be77 | 3 years ago |
Dibyendu Majumdar | 2ace67282d | 3 years ago |
Dibyendu Majumdar | 6909d79f61 | 3 years ago |
Dibyendu Majumdar | 16ea0643cd | 3 years ago |
Dibyendu Majumdar | a83afe2d02 | 3 years ago |
Dibyendu Majumdar | d5668379b1 | 3 years ago |
Dibyendu Majumdar | 849819e891 | 3 years ago |
Dibyendu Majumdar | 53ff35455a | 3 years ago |
Dibyendu Majumdar | f9acba8142 | 3 years ago |
Dibyendu Majumdar | 389c98ee35 | 3 years ago |
Dibyendu Majumdar | e9cb48e15c | 3 years ago |
Dibyendu Majumdar | f346122073 | 3 years ago |
Dibyendu Majumdar | 001dceb996 | 3 years ago |
Dibyendu Majumdar | 0f6a4084ae | 3 years ago |
Dibyendu Majumdar | 95ac6123a9 | 3 years ago |
Dibyendu Majumdar | 8d6e403f30 | 3 years ago |
Dibyendu Majumdar | bb218051ba | 4 years ago |
Dibyendu Majumdar | bc4142428c | 4 years ago |
Dibyendu Majumdar | 86c2020411 | 4 years ago |
Dibyendu Majumdar | 5a0c3600fc | 4 years ago |
Dibyendu Majumdar | a54f156304 | 4 years ago |
Dibyendu Majumdar | 8cec4cc827 | 4 years ago |
Dibyendu Majumdar | a82d42b847 | 4 years ago |
Dibyendu Majumdar | a3bf9dc10e | 4 years ago |
Dibyendu Majumdar | ea6c408c97 | 4 years ago |
Dibyendu Majumdar | 487624cee9 | 4 years ago |
Dibyendu Majumdar | e361bd7387 | 4 years ago |
Dibyendu Majumdar | 69840eacdb | 4 years ago |
Dibyendu Majumdar | d0b3ed989b | 4 years ago |
Dibyendu Majumdar | f6378c97b4 | 4 years ago |
Dibyendu Majumdar | 7f94078e8e | 4 years ago |
Dibyendu Majumdar | 174cfa0168 | 4 years ago |
Dibyendu Majumdar | 523f07ba57 | 4 years ago |
Dibyendu Majumdar | 71bb74f773 | 4 years ago |
Dibyendu Majumdar | 6b273f7468 | 4 years ago |
Dibyendu Majumdar | a3940b0120 | 4 years ago |
Dibyendu Majumdar | b1f36a56e1 | 4 years ago |
Dibyendu Majumdar | 6daf1a5529 | 4 years ago |
Dibyendu Majumdar | 4819f38a80 | 4 years ago |
Dibyendu Majumdar | 4f7cab694c | 4 years ago |
Dibyendu Majumdar | d65beddb75 | 4 years ago |
Dibyendu Majumdar | 45f823b604 | 4 years ago |
Dibyendu Majumdar | a45eaa8a24 | 4 years ago |
Dibyendu Majumdar | 902f5c1653 | 4 years ago |
Dibyendu Majumdar | 48617fda44 | 4 years ago |
Dibyendu Majumdar | fba87f24f1 | 4 years ago |
Dibyendu Majumdar | 90a26a4b88 | 4 years ago |
Dibyendu Majumdar | 0f698f354c | 4 years ago |
Dibyendu Majumdar | 7515ef9d89 | 4 years ago |
Dibyendu Majumdar | 2a6c5575e3 | 4 years ago |
Dibyendu Majumdar | 98c96c11eb | 4 years ago |
Dibyendu Majumdar | 2cab1f104a | 4 years ago |
Dibyendu Majumdar | be67d117c2 | 4 years ago |
Dibyendu Majumdar | 430f9a532b | 4 years ago |
Dibyendu Majumdar | e20df095df | 4 years ago |
Dibyendu Majumdar | 90f54987eb | 4 years ago |
Dibyendu Majumdar | cde0a39bc2 | 4 years ago |
Dibyendu Majumdar | 16d59f65ee | 4 years ago |
Dibyendu Majumdar | 534abc7525 | 4 years ago |
Dibyendu Majumdar | 02a7796f77 | 4 years ago |
Dibyendu Majumdar | 34c6b33a2f | 4 years ago |
Dibyendu Majumdar | 0d22f81b2a | 4 years ago |
Dibyendu Majumdar | ee056a1bd6 | 4 years ago |
Dibyendu Majumdar | 40e020916a | 4 years ago |
Dibyendu Majumdar | 57f6fc82f7 | 4 years ago |
Dibyendu Majumdar | c4535d5d9f | 4 years ago |
Dibyendu Majumdar | 940a80d9bb | 4 years ago |
Dibyendu Majumdar | 4d348e0609 | 4 years ago |
Dibyendu Majumdar | f76b4690f0 | 4 years ago |
Dibyendu Majumdar | 42cfa54e9e | 4 years ago |
Dibyendu Majumdar | 81555acc72 | 4 years ago |
Dibyendu Majumdar | 7e219f76bd | 4 years ago |
Dibyendu Majumdar | 8b854b0a02 | 4 years ago |
Dibyendu Majumdar | 920cd2dab8 | 4 years ago |
Dibyendu Majumdar | b73322ad16 | 4 years ago |
Dibyendu Majumdar | 844b15683b | 4 years ago |
Dibyendu Majumdar | 63bf14b43c | 4 years ago |
Dibyendu Majumdar | 73d6bc1c07 | 4 years ago |
Dibyendu Majumdar | c42ac0e9fa | 4 years ago |
Dibyendu Majumdar | d26e3626b9 | 4 years ago |
Dibyendu Majumdar | f8a680ed82 | 4 years ago |
Dibyendu Majumdar | 4bbcb908ec | 4 years ago |
Dibyendu Majumdar | 7f63b9fae7 | 4 years ago |
Dibyendu Majumdar | 3a75ee9eb7 | 4 years ago |
Dibyendu Majumdar | cdd6fbfeaa | 4 years ago |
Dibyendu Majumdar | 73c2c6426f | 4 years ago |
Dibyendu Majumdar | b63005fd3f | 4 years ago |
Dibyendu Majumdar | e832dcc32f | 4 years ago |
Dibyendu Majumdar | d8a60ddd23 | 4 years ago |
Dibyendu Majumdar | bf2f55eece | 4 years ago |
Dibyendu Majumdar | 9c745caafe | 4 years ago |
Dibyendu Majumdar | 2934cbe5c0 | 4 years ago |
Dibyendu Majumdar | 7dd5c1fdf0 | 4 years ago |
Dibyendu Majumdar | 9e2a4f4645 | 4 years ago |
Dibyendu Majumdar | e483fe40ee | 4 years ago |
Dibyendu Majumdar | 7e26dc8d0f | 4 years ago |
Dibyendu Majumdar | 0e41a51114 | 4 years ago |
Dibyendu Majumdar | f884782a60 | 4 years ago |
Dibyendu Majumdar | 2861754b3c | 4 years ago |
Dibyendu Majumdar | 22d84e74d0 | 4 years ago |
Dibyendu Majumdar | f547edd330 | 4 years ago |
Dibyendu Majumdar | d4992e8d08 | 4 years ago |
Dibyendu Majumdar | 4795374610 | 4 years ago |
Dibyendu Majumdar | 93c0a0c61e | 4 years ago |
Dibyendu Majumdar | 4ccc2759e8 | 4 years ago |
Dibyendu Majumdar | 062550b84d | 4 years ago |
Dibyendu Majumdar | f4752a513f | 4 years ago |
Dibyendu Majumdar | e0881115e4 | 4 years ago |
Dibyendu Majumdar | 2eb4daf7ff | 4 years ago |
Dibyendu Majumdar | d2a295688f | 4 years ago |
Dibyendu Majumdar | d2b9810a06 | 4 years ago |
Dibyendu Majumdar | a2e0c2fc3d | 4 years ago |
Dibyendu Majumdar | bf5aa3e3f6 | 4 years ago |
Dibyendu Majumdar | 4d6f9dd9f2 | 4 years ago |
Dibyendu Majumdar | cf7f8ed380 | 4 years ago |
Dibyendu Majumdar | ff91fbfc8d | 4 years ago |
Dibyendu Majumdar | 3cf60d2972 | 4 years ago |
Dibyendu Majumdar | 18ff6c1f36 | 4 years ago |
Dibyendu Majumdar | 5f286815ed | 4 years ago |
Dibyendu Majumdar | 76f9bbdffb | 4 years ago |
Dibyendu Majumdar | a8ee5a60e1 | 4 years ago |
Dibyendu Majumdar | 0d2b3161e3 | 4 years ago |
Dibyendu Majumdar | f3886accbe | 4 years ago |
Dibyendu Majumdar | e16310f742 | 4 years ago |
Dibyendu Majumdar | 4b34875605 | 4 years ago |
Dibyendu Majumdar | eb3d9ca72d | 4 years ago |
Dibyendu Majumdar | a5759bbb25 | 4 years ago |
Dibyendu Majumdar | 71e5bd8d8c | 4 years ago |
Dibyendu Majumdar | 6f7313594c | 4 years ago |
Dibyendu Majumdar | 83e0a739b0 | 4 years ago |
Dibyendu Majumdar | 23141174d4 | 4 years ago |
Dibyendu Majumdar | 6500e11c01 | 4 years ago |
Dibyendu Majumdar | 59f92f04df | 4 years ago |
Dibyendu Majumdar | b317b19c3c | 4 years ago |
Dibyendu Majumdar | 0ff5baa1a5 | 4 years ago |
Dibyendu Majumdar | 9202468bb7 | 4 years ago |
Dibyendu Majumdar | 89b9451437 | 4 years ago |
@ -0,0 +1,7 @@
|
||||
# [Choice] Debian / Ubuntu version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
|
||||
ARG VARIANT=buster
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/cpp:dev-${VARIANT}
|
||||
|
||||
# [Optional] Uncomment this section to install additional packages.
|
||||
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
@ -0,0 +1,12 @@
|
||||
# [Choice] Debian / Ubuntu version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
|
||||
ARG VARIANT=buster
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/base:${VARIANT}
|
||||
|
||||
# Install needed packages. Use a separate RUN statement to add your own dependencies.
|
||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install build-essential cmake cppcheck valgrind clang lldb llvm gdb \
|
||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# [Optional] Uncomment this section to install additional OS packages.
|
||||
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "C++",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
// Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
|
||||
"args": { "VARIANT": "debian-10" }
|
||||
},
|
||||
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/bash"
|
||||
},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "gcc -v",
|
||||
|
||||
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||
"remoteUser": "vscode"
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: dibyendumajumdar # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
custom: # Replace with a single custom sponsorship URL
|
@ -0,0 +1,195 @@
|
||||
Ravi Programming Language
|
||||
=========================
|
||||
|
||||
![image](https://travis-ci.org/dibyendumajumdar/ravi.svg?branch=master%0A%20:target:%20https://travis-ci.org/dibyendumajumdar/ravi)
|
||||
|
||||
Ravi is a dialect of [Lua](http://www.lua.org/) with limited optional
|
||||
static typing and features [MIR](https://github.com/vnmakarov/mir)
|
||||
powered JIT compilers. The name Ravi comes from the Sanskrit word for
|
||||
the Sun. Interestingly a precursor to Lua was
|
||||
[Sol](http://www.lua.org/history.html) which had support for static
|
||||
types; Sol means the Sun in Portugese.
|
||||
|
||||
Lua is perfect as a small embeddable dynamic language so why a
|
||||
derivative? Ravi extends Lua with static typing for improved performance
|
||||
when JIT compilation is enabled. However, the static typing is optional
|
||||
and therefore Lua programs are also valid Ravi programs.
|
||||
|
||||
There are other attempts to add static typing to Lua - e.g. [Typed
|
||||
Lua](https://github.com/andremm/typedlua) but these efforts are mostly
|
||||
about adding static type checks in the language while leaving the VM
|
||||
unmodified. The Typed Lua effort is very similar to the approach taken
|
||||
by Typescript in the JavaScript world. The static typing is to aid
|
||||
programming in the large - the code is eventually translated to standard
|
||||
Lua and executed in the unmodified Lua VM.
|
||||
|
||||
My motivation is somewhat different - I want to enhance the VM to
|
||||
support more efficient operations when types are known. Type information
|
||||
can be exploited by JIT compilation technology to improve performance.
|
||||
At the same time, I want to keep the language safe and therefore usable
|
||||
by non-expert programmers.
|
||||
|
||||
Of course there is the fantastic [LuaJIT](http://luajit.org)
|
||||
implementation. Ravi has a different goal compared to LuaJIT. Ravi
|
||||
prioritizes ease of maintenance and support, language safety, and
|
||||
compatibility with Lua 5.3, over maximum performance. For more detailed
|
||||
comparison please refer to the documentation links below.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Optional static typing - for details [see the reference
|
||||
manual](https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-reference.html).
|
||||
- Type specific bytecodes to improve performance
|
||||
- Compatibility with Lua 5.3 (see Compatibility section below)
|
||||
- Generational GC from Lua 5.4
|
||||
- `defer` statement for releasing resources
|
||||
- Compact JIT backend [MIR](https://github.com/vnmakarov/mir).
|
||||
- A [distribution with
|
||||
batteries](https://github.com/dibyendumajumdar/Suravi).
|
||||
- A [Visual Studio Code debugger
|
||||
extension](https://marketplace.visualstudio.com/items?itemName=ravilang.ravi-debug)
|
||||
- interpreted mode debugger.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
- For the Lua extensions in Ravi see the [Reference
|
||||
Manual](https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-reference.html).
|
||||
- [MIR JIT Build
|
||||
instructions](https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-mir-instructions.html).
|
||||
- Also see [Ravi
|
||||
Documentation](http://the-ravi-programming-language.readthedocs.org/en/latest/index.html).
|
||||
- and the slides I presented at the [Lua 2015
|
||||
Workshop](http://www.lua.org/wshop15.html).
|
||||
|
||||
Lua Goodies
|
||||
-----------
|
||||
|
||||
- [An Introduction to
|
||||
Lua](http://the-ravi-programming-language.readthedocs.io/en/latest/lua-introduction.html)
|
||||
attempts to provide a quick overview of Lua for folks coming from
|
||||
other languages.
|
||||
- [Lua 5.3 Bytecode
|
||||
Reference](http://the-ravi-programming-language.readthedocs.io/en/latest/lua_bytecode_reference.html)
|
||||
is my attempt to bring up to date the [Lua 5.1 Bytecode
|
||||
Reference](http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf).
|
||||
- A [patch for Lua
|
||||
5.3](https://github.com/dibyendumajumdar/ravi/blob/master/patches/defer_statement_for_Lua_5_3.patch)
|
||||
implements the 'defer' statement.
|
||||
- A [patch for Lua
|
||||
5.4.[0-2]](https://github.com/dibyendumajumdar/ravi/blob/master/patches/defer_statement_for_Lua_5_4.patch)
|
||||
implements the 'defer' statement.
|
||||
- Updated [patch for Lua
|
||||
5.4.3](https://github.com/dibyendumajumdar/ravi/blob/master/patches/defer_statement_patch_for_Lua_5_4_3.patch)
|
||||
implements the 'defer' statement.
|
||||
|
||||
Lua 5.4 Position Statement
|
||||
--------------------------
|
||||
|
||||
Lua 5.4 relationship to Ravi is as follows:
|
||||
|
||||
- Generational GC - back-ported to Ravi.
|
||||
- New random number generator - back-ported to Ravi.
|
||||
- Multiple user values can be associated with userdata - under
|
||||
consideration.
|
||||
- `<const>` variables - not planned.
|
||||
- `<close>` variables - Ravi has `'defer'` statement which is the
|
||||
better option in my opinion, hence no plans to support `<close>`
|
||||
variables.
|
||||
- Interpreter performance improvements - these are beneficial to Lua
|
||||
interpreter but not to the JIT backends, hence not much point in
|
||||
back-porting.
|
||||
- Table implementation changes - under consideration.
|
||||
- String to number coercion is now part of string library metamethods
|
||||
- back-ported to Ravi.
|
||||
- utf8 library accepts codepoints up to 2\^31 - back-ported to Ravi.
|
||||
- Removal of compatibility layers for 5.1, and 5.2 - not implemented
|
||||
as Ravi continues to provide these layers as per Lua 5.3.
|
||||
|
||||
Compatibility with Lua 5.3
|
||||
--------------------------
|
||||
|
||||
Ravi should be able to run all Lua 5.3 programs in interpreted mode, but
|
||||
following should be noted:
|
||||
|
||||
- Ravi supports optional typing and enhanced types such as arrays (see
|
||||
the documentation). Programs using these features cannot be run by
|
||||
standard Lua. However all types in Ravi can be passed to Lua
|
||||
functions; operations on Ravi arrays within Lua code will be subject
|
||||
to restrictions as described in the section above on arrays.
|
||||
- Values crossing from Lua to Ravi will be subjected to typechecks
|
||||
should these values be assigned to typed variables.
|
||||
- Upvalues cannot subvert the static typing of local variables (issue
|
||||
\#26) when types are annotated.
|
||||
- Certain Lua limits are reduced due to changed byte code structure.
|
||||
These are described below.
|
||||
- Ravi uses an extended bytecode which means it is not compatible with
|
||||
Lua 5.x bytecode.
|
||||
- Ravi incorporates the new Generational GC from Lua 5.4, hence the GC
|
||||
interface has changed.
|
||||
|
||||
Limit name Lua value Ravi value
|
||||
------------------ -------------- --------------
|
||||
MAXUPVAL 255 125
|
||||
LUAI\_MAXCCALLS 200 125
|
||||
MAXREGS 255 125
|
||||
MAXVARS 200 125
|
||||
MAXARGLINE 250 120
|
||||
|
||||
When JIT compilation is enabled there are following additional
|
||||
constraints:
|
||||
|
||||
- Ravi will only execute JITed code from the main Lua thread; any
|
||||
secondary threads (coroutines) execute in interpreter mode.
|
||||
- In JITed code tailcalls are implemented as regular calls so unlike
|
||||
the interpreter VM which supports infinite tail recursion JIT
|
||||
compiled code only supports tail recursion to a depth of about 110
|
||||
(issue \#17)
|
||||
- Debug api and hooks are not supported in JIT mode
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
- 2015
|
||||
: - Implemented JIT compilation using LLVM
|
||||
- Implemented [libgccjit based alternative
|
||||
JIT](https://github.com/dibyendumajumdar/ravi/tree/gccjit-ravi534)
|
||||
(now discontinued)
|
||||
|
||||
- 2016
|
||||
: - Implemented debugger for Ravi and Lua 5.3 for [Visual Studio
|
||||
Code](https://github.com/dibyendumajumdar/ravi/tree/master/vscode-debugger)
|
||||
|
||||
- 2017
|
||||
: - Embedded C compiler using dmrC project (C JIT compiler) (now
|
||||
discontinued)
|
||||
- Additional type-annotations
|
||||
|
||||
- 2018
|
||||
: - Implemented [Eclipse OMR JIT
|
||||
backend](https://github.com/dibyendumajumdar/ravi/tree/omrjit)
|
||||
(now discontinued)
|
||||
- Created [Ravi with
|
||||
batteries](https://github.com/dibyendumajumdar/Suravi).
|
||||
|
||||
- 2019
|
||||
: - New language feature - defer statement
|
||||
- New JIT backend [MIR](https://github.com/vnmakarov/mir).
|
||||
|
||||
- 2020
|
||||
: - [New parser / type checker /
|
||||
compiler](https://github.com/dibyendumajumdar/ravi-compiler)
|
||||
- Generational GC back-ported from Lua 5.4
|
||||
- Support for [LLVM
|
||||
backend](https://github.com/dibyendumajumdar/ravi/tree/llvm)
|
||||
archived
|
||||
|
||||
- 2021 (Plan)
|
||||
: - Integrated AOT and JIT compilation support
|
||||
- Ravi 1.0 release
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT License
|
@ -1,106 +0,0 @@
|
||||
=========================
|
||||
Ravi Programming Language
|
||||
=========================
|
||||
.. image:: https://travis-ci.org/dibyendumajumdar/ravi.svg?branch=master
|
||||
:target: https://travis-ci.org/dibyendumajumdar/ravi
|
||||
|
||||
Ravi is a derivative/dialect of `Lua 5.3 <http://www.lua.org/>`_ with limited optional static typing and
|
||||
features `MIR <https://github.com/vnmakarov/mir>`_ and `LLVM <http://www.llvm.org/>`_ powered JIT compilers.
|
||||
The name Ravi comes from the Sanskrit word for the Sun.
|
||||
Interestingly a precursor to Lua was `Sol <http://www.lua.org/history.html>`_ which had support for
|
||||
static types; Sol means the Sun in Portugese.
|
||||
|
||||
Lua is perfect as a small embeddable dynamic language so why a derivative? Ravi extends Lua with
|
||||
static typing for improved performance when JIT compilation is enabled. However, the static typing is
|
||||
optional and therefore Lua programs are also valid Ravi programs.
|
||||
|
||||
There are other attempts to add static typing to Lua - e.g. `Typed Lua <https://github.com/andremm/typedlua>`_ but
|
||||
these efforts are mostly about adding static type checks in the language while leaving the VM unmodified.
|
||||
The Typed Lua effort is very similar to the approach taken by Typescript in the JavaScript world.
|
||||
The static typing is to aid programming in the large - the code is eventually translated to standard Lua
|
||||
and executed in the unmodified Lua VM.
|
||||
|
||||
My motivation is somewhat different - I want to enhance the VM to support more efficient operations when types are
|
||||
known. Type information can be exploited by JIT compilation technology to improve performance. At the same time,
|
||||
I want to keep the language safe and therefore usable by non-expert programmers.
|
||||
|
||||
Of course there is the fantastic `LuaJIT <http://luajit.org>`_ implementation. Ravi has a different goal compared to
|
||||
LuaJIT. Ravi prioritizes ease of maintenance and support, language safety, and compatibility with Lua 5.3,
|
||||
over maximum performance. For more detailed comparison please refer to the documentation links below.
|
||||
|
||||
Features
|
||||
========
|
||||
* Optional static typing - for details `see the reference manual <https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-reference.html>`_.
|
||||
* Type specific bytecodes to improve performance
|
||||
* Compatibility with Lua 5.3 (see Compatibility section below)
|
||||
* New! JIT backend `MIR <https://github.com/vnmakarov/mir>`_; only Linux and x86-64 supported for now.
|
||||
* `LLVM <http://www.llvm.org/>`_ powered JIT compiler
|
||||
* A `distribution with batteries <https://github.com/dibyendumajumdar/Suravi>`_.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
* For the Lua extensions in Ravi see the `Reference Manual <https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-reference.html>`_.
|
||||
* `MIR JIT Build instructions <https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-mir-instructions.html>`_.
|
||||
* `LLVM JIT Build instructions <https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-llvm-instructions.html>`_.
|
||||
* Also see `Ravi Documentation <http://the-ravi-programming-language.readthedocs.org/en/latest/index.html>`_.
|
||||
* and the slides I presented at the `Lua 2015 Workshop <http://www.lua.org/wshop15.html>`_.
|
||||
|
||||
Lua Goodies
|
||||
===========
|
||||
* `An Introduction to Lua <http://the-ravi-programming-language.readthedocs.io/en/latest/lua-introduction.html>`_ attempts to provide a quick overview of Lua for folks coming from other languages.
|
||||
* `Lua 5.3 Bytecode Reference <http://the-ravi-programming-language.readthedocs.io/en/latest/lua_bytecode_reference.html>`_ is my attempt to bring up to date the `Lua 5.1 Bytecode Reference <http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf>`_.
|
||||
* A `patch for Lua 5.3 <http://lua-users.org/lists/lua-l/2020-01/msg00004.html>`_ implements the 'defer' statement.
|
||||
|
||||
Compatibility with Lua
|
||||
======================
|
||||
Ravi should be able to run all Lua 5.3 programs in interpreted mode, but following should be noted:
|
||||
|
||||
* Ravi supports optional typing and enhanced types such as arrays (described above). Programs using these features cannot be run by standard Lua. However all types in Ravi can be passed to Lua functions; operations on Ravi arrays within Lua code will be subject to restrictions as described in the section above on arrays.
|
||||
* Values crossing from Lua to Ravi will be subjected to typechecks should these values be assigned to typed variables.
|
||||
* Upvalues cannot subvert the static typing of local variables (issue #26) when types are annotated.
|
||||
* Certain Lua limits are reduced due to changed byte code structure. These are described below.
|
||||
* Ravi uses an extended bytecode which means it is not compatible with Lua 5.3 bytecode.
|
||||
|
||||
+-----------------+-------------+-------------+
|
||||
| Limit name | Lua value | Ravi value |
|
||||
+=================+=============+=============+
|
||||
| MAXUPVAL | 255 | 125 |
|
||||
+-----------------+-------------+-------------+
|
||||
| LUAI_MAXCCALLS | 200 | 125 |
|
||||
+-----------------+-------------+-------------+
|
||||
| MAXREGS | 255 | 125 |
|
||||
+-----------------+-------------+-------------+
|
||||
| MAXVARS | 200 | 125 |
|
||||
+-----------------+-------------+-------------+
|
||||
| MAXARGLINE | 250 | 120 |
|
||||
+-----------------+-------------+-------------+
|
||||
|
||||
When JIT compilation is enabled there are following additional constraints:
|
||||
|
||||
* Ravi will only execute JITed code from the main Lua thread; any secondary threads (coroutines) execute in interpreter mode.
|
||||
* In JITed code tailcalls are implemented as regular calls so unlike the interpreter VM which supports infinite tail recursion JIT compiled code only supports tail recursion to a depth of about 110 (issue #17)
|
||||
|
||||
History
|
||||
=======
|
||||
* 2015
|
||||
- Implemented JIT compilation using LLVM
|
||||
- Implemented libgccjit based alternative JIT (now discontinued)
|
||||
* 2016
|
||||
- Implemented debugger for Ravi and Lua 5.3 for `Visual Studio Code <https://github.com/dibyendumajumdar/ravi/tree/master/vscode-debugger>`_
|
||||
* 2017
|
||||
- Embedded C compiler using dmrC project (C JIT compiler) (now discontinued)
|
||||
- Additional type-annotations
|
||||
* 2018
|
||||
- Implemented Eclipse OMR JIT backend (now discontinued)
|
||||
- Created `Ravi with batteries <https://github.com/dibyendumajumdar/Suravi>`_.
|
||||
* 2019
|
||||
- New language feature - `defer` statement
|
||||
- New JIT backend `MIR <https://github.com/vnmakarov/mir>`_.
|
||||
|
||||
* 2020 (Plan)
|
||||
- `New optimizing byte code generator based on new parser / type checker <https://github.com/dibyendumajumdar/ravi-compiler>`_
|
||||
- Ravi 1.0 release
|
||||
|
||||
License
|
||||
=======
|
||||
MIT License
|
@ -1,5 +0,0 @@
|
||||
mkdir llvm32
|
||||
cd llvm32
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM37_32\share\llvm\cmake -DBUILD_STATIC=OFF ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM39_32\lib\cmake\llvm -DSTATIC_BUILD=OFF ..
|
||||
cd ..
|
@ -1,5 +0,0 @@
|
||||
mkdir llvm32
|
||||
cd llvm32
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM37_32\share\llvm\cmake ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM39\lib\cmake\llvm -DSTATIC_BUILD=ON ..
|
||||
cd ..
|
@ -1,5 +0,0 @@
|
||||
mkdir llvm32d
|
||||
cd llvm32d
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM37_32\share\llvm\cmake ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM39D_32\lib\cmake\llvm -DSTATIC_BUILD=ON ..
|
||||
cd ..
|
@ -1,6 +0,0 @@
|
||||
mkdir llvm64d
|
||||
cd llvm64d
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=c:\ravi64llvmd -G "Visual Studio 14 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\LLVM37debug\share\llvm\cmake ..
|
||||
rem cmake -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=c:\d\ravi64llvmd -G "Visual Studio 15 2017 Win64" -DLLVM_JIT=ON -DEMBEDDED_DMRC=ON -DLLVM_DIR=c:\d\LLVM39D64\lib\cmake\llvm ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm501d\lib\cmake\llvm ..
|
||||
cd ..
|
@ -1,7 +0,0 @@
|
||||
mkdir llvm64
|
||||
cd llvm64
|
||||
rem pre LLVM 3.9
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=c:\ravi -G "Visual Studio 14 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\LLVM37\share\llvm\cmake ..
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=c:\ravi -G "Visual Studio 15 2017 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\d\LLVM40_64\lib\cmake\llvm ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DSTATIC_BUILD=ON -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm601r\lib\cmake\llvm ..
|
||||
cd ..
|
@ -1,5 +0,0 @@
|
||||
rmdir /s llvm8
|
||||
mkdir llvm8
|
||||
cd llvm8
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=Release -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm801\lib\cmake\llvm ..
|
||||
cd ..
|
@ -1,5 +0,0 @@
|
||||
rmdir /s llvm9d
|
||||
mkdir llvm9d
|
||||
cd llvm9d
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm900\lib\cmake\llvm ..
|
||||
cd ..
|
@ -1,6 +0,0 @@
|
||||
rmdir /s llvm9r
|
||||
mkdir llvm9r
|
||||
cd llvm9r
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm900r\lib\cmake\llvm ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 16 2019" -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm900r\lib\cmake\llvm ..
|
||||
cd ..
|
@ -1,4 +1,4 @@
|
||||
mkdir nojit64a
|
||||
cd nojit64a
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Debug -DLTESTS=ON -G "Visual Studio 15 2017 Win64" ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Debug -DLTESTS=ON ..
|
||||
cd ..
|
@ -1,4 +0,0 @@
|
||||
mkdir omrjit
|
||||
cd omrjit
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=Debug -DOMR_JIT=ON ..
|
||||
cd ..
|
@ -1,4 +0,0 @@
|
||||
mkdir xcodellvm
|
||||
cd xcodellvm
|
||||
#cmake -DCMAKE_BUILD_TYPE=Debug -G Xcode -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/share/llvm/cmake ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug -G Xcode -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM5/lib/cmake/llvm ..
|
@ -1,5 +0,0 @@
|
||||
mkdir buildllvmd
|
||||
cd buildllvmd
|
||||
#cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/share/llvm/cmake ..
|
||||
#cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DLTESTS=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM5/lib/cmake/llvm ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DLTESTS=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravillvm -DLLVM_DIR=$HOME/Software/llvm600/lib/cmake/llvm ..
|
@ -1,6 +0,0 @@
|
||||
rm -rf buildllvm
|
||||
mkdir buildllvm
|
||||
cd buildllvm
|
||||
#cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/share/llvm/cmake ..
|
||||
#cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM5/lib/cmake/llvm ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DSTATIC_BUILD=ON -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/Software/ravi -DLLVM_DIR=$HOME/Software/llvm801/lib/cmake/llvm ..
|
@ -1,3 +0,0 @@
|
||||
mkdir omrjit
|
||||
cd omrjit
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DOMR_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi ..
|
@ -1,147 +0,0 @@
|
||||
/*
|
||||
** $Id: lgc.h,v 2.91.1.1 2017/04/19 17:39:34 roberto Exp $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lgc_h
|
||||
#define lgc_h
|
||||
|
||||
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
|
||||
/*
|
||||
** Collectable objects may have one of three colors: white, which
|
||||
** means the object is not marked; gray, which means the
|
||||
** object is marked, but its references may be not marked; and
|
||||
** black, which means that the object and all its references are marked.
|
||||
** The main invariant of the garbage collector, while marking objects,
|
||||
** is that a black object can never point to a white one. Moreover,
|
||||
** any gray object must be in a "gray list" (gray, grayagain, weak,
|
||||
** allweak, ephemeron) so that it can be visited again before finishing
|
||||
** the collection cycle. These lists have no meaning when the invariant
|
||||
** is not being enforced (e.g., sweep phase).
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* how much to allocate before next GC step */
|
||||
#if !defined(GCSTEPSIZE)
|
||||
/* ~100 small strings */
|
||||
#define GCSTEPSIZE (cast_int(100 * sizeof(TString)))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Possible states of the Garbage Collector
|
||||
*/
|
||||
#define GCSpropagate 0
|
||||
#define GCSatomic 1
|
||||
#define GCSswpallgc 2
|
||||
#define GCSswpfinobj 3
|
||||
#define GCSswptobefnz 4
|
||||
#define GCSswpend 5
|
||||
#define GCScallfin 6
|
||||
#define GCSpause 7
|
||||
|
||||
|
||||
#define issweepphase(g) \
|
||||
(GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend)
|
||||
|
||||
|
||||
/*
|
||||
** macro to tell when main invariant (white objects cannot point to black
|
||||
** ones) must be kept. During a collection, the sweep
|
||||
** phase may break the invariant, as objects turned white may point to
|
||||
** still-black objects. The invariant is restored when sweep ends and
|
||||
** all objects are white again.
|
||||
*/
|
||||
|
||||
#define keepinvariant(g) ((g)->gcstate <= GCSatomic)
|
||||
|
||||
|
||||
/*
|
||||
** some useful bit tricks
|
||||
*/
|
||||
#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
|
||||
#define setbits(x,m) ((x) |= (m))
|
||||
#define testbits(x,m) ((x) & (m))
|
||||
#define bitmask(b) (1<<(b))
|
||||
#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
|
||||
#define l_setbit(x,b) setbits(x, bitmask(b))
|
||||
#define resetbit(x,b) resetbits(x, bitmask(b))
|
||||
#define testbit(x,b) testbits(x, bitmask(b))
|
||||
|
||||
|
||||
/* Layout for bit use in 'marked' field: */
|
||||
#define WHITE0BIT 0 /* object is white (type 0) */
|
||||
#define WHITE1BIT 1 /* object is white (type 1) */
|
||||
#define BLACKBIT 2 /* object is black */
|
||||
#define FINALIZEDBIT 3 /* object has been marked for finalization */
|
||||
/* bit 7 is currently used by tests (luaL_checkmemory) */
|
||||
|
||||
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
|
||||
|
||||
|
||||
#define iswhite(x) testbits((x)->marked, WHITEBITS)
|
||||
#define isblack(x) testbit((x)->marked, BLACKBIT)
|
||||
#define isgray(x) /* neither white nor black */ \
|
||||
(!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT)))
|
||||
|
||||
#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT)
|
||||
|
||||
#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS)
|
||||
#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
|
||||
#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked)
|
||||
|
||||
#define changewhite(x) ((x)->marked ^= WHITEBITS)
|
||||
#define gray2black(x) l_setbit((x)->marked, BLACKBIT)
|
||||
|
||||
#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
|
||||
|
||||
|
||||
/*
|
||||
** Does one step of collection when debt becomes positive. 'pre'/'pos'
|
||||
** allows some adjustments to be done only when needed. macro
|
||||
** 'condchangemem' is used only for heavy tests (forcing a full
|
||||
** GC cycle on every opportunity)
|
||||
*/
|
||||
#define luaC_condGC(L,pre,pos) \
|
||||
{ if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \
|
||||
condchangemem(L,pre,pos); }
|
||||
|
||||
/* more often than not, 'pre'/'pos' are empty */
|
||||
#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0)
|
||||
|
||||
|
||||
#define luaC_barrier(L,p,v) ( \
|
||||
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
|
||||
luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0))
|
||||
|
||||
#define luaC_barrierback(L,p,v) ( \
|
||||
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
|
||||
luaC_barrierback_(L,p) : cast_void(0))
|
||||
|
||||
#define luaC_objbarrier(L,p,o) ( \
|
||||
(isblack(p) && iswhite(o)) ? \
|
||||
luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0))
|
||||
|
||||
#define luaC_upvalbarrier(L,uv) ( \
|
||||
(iscollectable((uv)->v) && !upisopen(uv)) ? \
|
||||
luaC_upvalbarrier_(L,uv) : cast_void(0))
|
||||
|
||||
LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
|
||||
LUAI_FUNC void luaC_freeallobjects (lua_State *L);
|
||||
LUAI_FUNC void luaC_step (lua_State *L);
|
||||
LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
|
||||
LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
|
||||
LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
|
||||
LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
|
||||
LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o);
|
||||
LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv);
|
||||
LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
|
||||
LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv);
|
||||
|
||||
|
||||
#endif
|
@ -1,120 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2015 Dibyendu Majumdar
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
#ifndef RAVI_LLVM_H
|
||||
#define RAVI_LLVM_H
|
||||
|
||||
#ifdef USE_LLVM
|
||||
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
|
||||
#if (LLVM_VERSION_MAJOR < 3 || LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5 || LLVM_VERSION_MAJOR == 7)
|
||||
#error Unsupported LLVM version
|
||||
#endif
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 5
|
||||
#define USE_ORC_JIT 1
|
||||
#else
|
||||
#define USE_ORC_JIT 0
|
||||
#endif
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 8 && !defined(_WIN32)
|
||||
#define USE_ORCv2_JIT 0
|
||||
#else
|
||||
#define USE_ORCv2_JIT 0
|
||||
#endif
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 9
|
||||
#define USE_ORCv2_JIT 0
|
||||
#endif
|
||||
|
||||
// In lua.c we include this just to get version numbers
|
||||
// We cannot have C++ headers in that case
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Analysis/Passes.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/MDBuilder.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 7
|
||||
#include "llvm/PassManager.h"
|
||||
#else
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#endif
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
#include "llvm/Transforms/Instrumentation.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
|
||||
|
||||
#if USE_ORC_JIT || USE_ORCv2_JIT
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Transforms/Scalar/GVN.h"
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 8
|
||||
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
|
||||
#include "llvm/ExecutionEngine/Orc/Legacy.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
#endif //__cplusplus
|
||||
|
||||
#endif //USE_LLVM
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,42 +0,0 @@
|
||||
LUA=$1
|
||||
if [ "$LUA" = "" ]
|
||||
then
|
||||
echo "Please pass path to Lua"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run the interpreter tests first
|
||||
$LUA -e"_port=true" all.lua
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo "all.lua interpreted failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run tests in JIT mode without support for the line hook
|
||||
$LUA -e"_port=true; ravi.auto(true,1)" all.lua
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo "all.lua compiled without tracehook failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run tests in JIT mode with suppor for the line hook
|
||||
$LUA -e"_port=true; ravi.tracehook(true); ravi.auto(true,1)" all.lua
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo "all.lua compiled with tracehook failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run tests in partial JIT mode, with line hook
|
||||
$LUA -e"_port=true; ravi.tracehook(true); ravi.auto(true)" all.lua
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo "all.lua partially compiled with tracehook failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ../ravi-tests
|
||||
. ./run_tests.sh "$LUA"
|
||||
cd -
|
@ -1,26 +0,0 @@
|
||||
LUA=$1
|
||||
if [ "$LUA" = "" ]
|
||||
then
|
||||
echo "Please pass path to Lua"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run the interpreter tests first
|
||||
$LUA -e"_port=true" all.lua
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo "all.lua interpreted failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run tests in JIT mode without support for the line hook
|
||||
$LUA -e"_port=true; ravi.auto(true)" all.lua
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo "all.lua partially compiled with tracehook failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ../ravi-tests
|
||||
. ./run_tests.sh "$LUA"
|
||||
cd -
|
@ -0,0 +1,98 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2018-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
aarch64 call ABI target specific code.
|
||||
*/
|
||||
|
||||
typedef int target_arg_info_t;
|
||||
|
||||
static void target_init_arg_vars (c2m_ctx_t c2m_ctx, target_arg_info_t *arg_info) {}
|
||||
|
||||
static int target_return_by_addr_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
|
||||
return ((ret_type->mode == TM_STRUCT || ret_type->mode == TM_UNION)
|
||||
&& type_size (c2m_ctx, ret_type) > 2 * 8);
|
||||
}
|
||||
|
||||
static int reg_aggregate_size (c2m_ctx_t c2m_ctx, struct type *type) {
|
||||
int size;
|
||||
|
||||
if (type->mode != TM_STRUCT && type->mode != TM_UNION) return -1;
|
||||
return (size = type_size (c2m_ctx, type)) <= 2 * 8 ? size : -1;
|
||||
}
|
||||
|
||||
static void target_add_res_proto (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_type_t) * res_types,
|
||||
VARR (MIR_var_t) * arg_vars) {
|
||||
MIR_var_t var;
|
||||
int size;
|
||||
|
||||
if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0) {
|
||||
simple_add_res_proto (c2m_ctx, ret_type, arg_info, res_types, arg_vars);
|
||||
return;
|
||||
}
|
||||
if (size == 0) return;
|
||||
VARR_PUSH (MIR_type_t, res_types, MIR_T_I64);
|
||||
if (size > 8) VARR_PUSH (MIR_type_t, res_types, MIR_T_I64);
|
||||
}
|
||||
|
||||
static int target_add_call_res_op (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, size_t call_arg_area_offset) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
int size;
|
||||
|
||||
if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0)
|
||||
return simple_add_call_res_op (c2m_ctx, ret_type, arg_info, call_arg_area_offset);
|
||||
if (size == 0) return -1;
|
||||
VARR_PUSH (MIR_op_t, call_ops,
|
||||
MIR_new_reg_op (ctx, get_new_temp (c2m_ctx, MIR_T_I64).mir_op.u.reg));
|
||||
if (size > 8)
|
||||
VARR_PUSH (MIR_op_t, call_ops,
|
||||
MIR_new_reg_op (ctx, get_new_temp (c2m_ctx, MIR_T_I64).mir_op.u.reg));
|
||||
return size <= 8 ? 1 : 2;
|
||||
}
|
||||
|
||||
static op_t target_gen_post_call_res_code (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res,
|
||||
MIR_insn_t call, size_t call_ops_start) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
int size;
|
||||
|
||||
if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0)
|
||||
return simple_gen_post_call_res_code (c2m_ctx, ret_type, res, call, call_ops_start);
|
||||
if (size != 0)
|
||||
gen_multiple_load_store (c2m_ctx, ret_type, &VARR_ADDR (MIR_op_t, call_ops)[call_ops_start + 2],
|
||||
res.mir_op, FALSE);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void target_add_ret_ops (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
int i, size;
|
||||
|
||||
if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0) {
|
||||
simple_add_ret_ops (c2m_ctx, ret_type, res);
|
||||
return;
|
||||
}
|
||||
assert (res.mir_op.mode == MIR_OP_MEM && VARR_LENGTH (MIR_op_t, ret_ops) == 0 && size <= 2 * 8);
|
||||
for (i = 0; size > 0; size -= 8, i++)
|
||||
VARR_PUSH (MIR_op_t, ret_ops, get_new_temp (c2m_ctx, MIR_T_I64).mir_op);
|
||||
gen_multiple_load_store (c2m_ctx, ret_type, VARR_ADDR (MIR_op_t, ret_ops), res.mir_op, TRUE);
|
||||
}
|
||||
|
||||
static MIR_type_t target_get_blk_type (c2m_ctx_t c2m_ctx, struct type *arg_type) {
|
||||
return MIR_T_BLK; /* one BLK is enough */
|
||||
}
|
||||
|
||||
static void target_add_arg_proto (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_var_t) * arg_vars) {
|
||||
simple_add_arg_proto (c2m_ctx, name, arg_type, arg_info, arg_vars);
|
||||
}
|
||||
|
||||
static void target_add_call_arg_op (c2m_ctx_t c2m_ctx, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, op_t arg) {
|
||||
simple_add_call_arg_op (c2m_ctx, arg_type, arg_info, arg);
|
||||
}
|
||||
|
||||
static int target_gen_gather_arg (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
decl_t param_decl, target_arg_info_t *arg_info) {
|
||||
return FALSE;
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 5.2.4.2.2 */
|
||||
static char float_str[]
|
||||
= "#ifndef __FLOAT_H\n"
|
||||
"#define __FLOAT_H\n"
|
||||
"\n"
|
||||
"#define FLT_RADIX 2\n"
|
||||
"\n"
|
||||
"#define FLT_MANT_DIG 24\n"
|
||||
"#define DBL_MANT_DIG 53\n"
|
||||
"#define LDBL_MANT_DIG DBL_MANT_DIG\n"
|
||||
"\n"
|
||||
"#define FLT_DECIMAL_DIG 9\n"
|
||||
"#define DBL_DECIMAL_DIG 17\n"
|
||||
"#define LDBL_DECIMAL_DIG DBL_DECIMAL_DIG\n"
|
||||
"#define FLT_DIG FLT_DECIMAL_DIG\n"
|
||||
"#define DBL_DIG DBL_DECIMAL_DIG\n"
|
||||
"#define LDBL_DIG LDBL_DECIMAL_DIG\n"
|
||||
"\n"
|
||||
"#define DECIMAL_DIG LDBL_DECIMAL_DIG\n"
|
||||
"\n"
|
||||
"#define FLT_MIN_EXP -125\n"
|
||||
"#define DBL_MIN_EXP -1021\n"
|
||||
"#define LDBL_MIN_EXP DBL_MIN_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MIN_10_EXP -37\n"
|
||||
"#define DBL_MIN_10_EXP -307\n"
|
||||
"#define LDBL_MIN_10_EXP DBL_MIN_10_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MAX_EXP 128\n"
|
||||
"#define DBL_MAX_EXP 1024\n"
|
||||
"#define LDBL_MAX_EXP DBL_MAX_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MAX_10_EXP 38\n"
|
||||
"#define DBL_MAX_10_EXP 308\n"
|
||||
"#define LDBL_MAX_10_EXP DBL_MAX_10_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MAX 0x1.fffffep+127\n"
|
||||
"#define DBL_MAX 0x1.fffffffffffffp+1023\n"
|
||||
"#define LDBL_MAX DBL_MAX\n"
|
||||
"\n"
|
||||
"#define FLT_EPSILON 0x1p-23\n"
|
||||
"#define DBL_EPSILON 0x1p-52\n"
|
||||
"#define LDBL_EPSILON DBL_EPSILON\n"
|
||||
"\n"
|
||||
"#define FLT_MIN 0x1p-126\n"
|
||||
"#define DBL_MIN 0x1p-1022\n"
|
||||
"#define LDBL_MIN DBL_MIN\n"
|
||||
"\n"
|
||||
"#define FLT_TRUE_MIN 0x1p-149\n"
|
||||
"#define DBL_TRUE_MIN 0x0.0000000000001p-1022\n"
|
||||
"#define LDBL_TRUE_MIN DBL_TRUE_MIN\n"
|
||||
"\n"
|
||||
"#define FLT_EVAL_METHOD 0\n"
|
||||
"#define FLT_ROUNDS 1 /* round to the nearest */\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef __FLOAT_H */\n";
|
@ -0,0 +1,38 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See 5.2.4.2 */
|
||||
static char limits_str[]
|
||||
= "#ifndef __LIMITS_H\n"
|
||||
"#define __LIMITS_H\n"
|
||||
"\n"
|
||||
"#define CHAR_BIT 8\n"
|
||||
"\n"
|
||||
"#define SCHAR_MIN (-SCHAR_MAX - 1)\n"
|
||||
"#define SCHAR_MAX 127\n"
|
||||
"#define UCHAR_MAX (SCHAR_MAX * 2 + 1)\n"
|
||||
"\n"
|
||||
"#define MB_LEN_MAX 1\n"
|
||||
"\n"
|
||||
"#define SHRT_MIN (-SHRT_MAX - 1)\n"
|
||||
"#define SHRT_MAX 32767\n"
|
||||
"#define USHRT_MAX (SHRT_MAX * 2 + 1)\n"
|
||||
"\n"
|
||||
"#define INT_MIN (-INT_MAX - 1)\n"
|
||||
"#define INT_MAX 2147483647\n"
|
||||
"#define UINT_MAX (INT_MAX * 2u + 1u)\n"
|
||||
"\n"
|
||||
"#define LONG_MIN (-LONG_MAX - 1l)\n"
|
||||
"#define LONG_MAX 9223372036854775807l\n"
|
||||
"#define ULONG_MAX (LONG_MAX * 2ul + 1ul)\n"
|
||||
"\n"
|
||||
"#define LLONG_MIN LONG_MIN\n"
|
||||
"#define LLONG_MAX LONG_MAX\n"
|
||||
"#define ULLONG_MAX ULONG_MAX\n"
|
||||
"\n"
|
||||
"/* signed char by default */\n"
|
||||
"#define CHAR_MIN SCHAR_MIN\n"
|
||||
"#define CHAR_MAX SCHAR_MAX\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef __LIMITS_H */\n";
|
@ -1,5 +1,5 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
static char aarch64_mirc[]
|
@ -0,0 +1,27 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
static char stdarg_str[]
|
||||
= "#ifndef __STDARG_H\n"
|
||||
"#define __STDARG_H\n"
|
||||
"\n"
|
||||
"typedef struct {\n"
|
||||
" void *__stack;\n"
|
||||
" void *__gr_top;\n"
|
||||
" void *__vr_top;\n"
|
||||
" int __gr_offs;\n"
|
||||
" int __vr_offs;\n"
|
||||
"} va_list;\n"
|
||||
"\n"
|
||||
"#define va_start(ap, param) __builtin_va_start (ap)\n"
|
||||
"#define va_arg(ap, type) __builtin_va_arg(ap, (type *) 0)\n"
|
||||
"#define va_end(ap) 0\n"
|
||||
"#define va_copy(dest, src) ((dest)[0] = (src)[0])\n"
|
||||
"\n"
|
||||
"/* For standard headers of a GNU system: */\n"
|
||||
"#ifndef __GNUC_VA_LIST\n"
|
||||
"#define __GNUC_VA_LIST 1\n"
|
||||
"#endif\n"
|
||||
"typedef va_list __gnuc_va_list;\n"
|
||||
"#endif /* #ifndef __STDARG_H */\n";
|
@ -0,0 +1,19 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.19 */
|
||||
static char stddef_str[]
|
||||
= "#ifndef __STDDEF_H\n"
|
||||
"#define __STDDEF_H\n"
|
||||
"\n"
|
||||
"typedef long ptrdiff_t;\n"
|
||||
"typedef unsigned long size_t;\n"
|
||||
"typedef long double max_align_t;\n"
|
||||
"typedef unsigned int wchar_t;\n"
|
||||
"\n"
|
||||
"#define NULL ((void *) 0)\n"
|
||||
"\n"
|
||||
"#define offsetof(type, member_designator) ((size_t) & ((type *) 0)->member_designator)\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef __STDDEF_H */\n";
|
@ -0,0 +1,130 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.20 */
|
||||
static char stdint_str[]
|
||||
= "#ifndef _STDINT_H\n"
|
||||
"#define _STDINT_H 1\n"
|
||||
"\n"
|
||||
"#ifndef __int8_t_defined\n"
|
||||
"#define __int8_t_defined\n"
|
||||
"typedef signed char int8_t;\n"
|
||||
"#endif\n"
|
||||
"typedef short int int16_t;\n"
|
||||
"typedef int int32_t;\n"
|
||||
"typedef long int int64_t;\n"
|
||||
"\n"
|
||||
"typedef unsigned char uint8_t;\n"
|
||||
"typedef unsigned short int uint16_t;\n"
|
||||
"typedef unsigned int uint32_t;\n"
|
||||
"typedef unsigned long int uint64_t;\n"
|
||||
"\n"
|
||||
"typedef signed char int_least8_t;\n"
|
||||
"typedef short int int_least16_t;\n"
|
||||
"typedef int int_least32_t;\n"
|
||||
"typedef long int int_least64_t;\n"
|
||||
"\n"
|
||||
"typedef unsigned char uint_least8_t;\n"
|
||||
"typedef unsigned short int uint_least16_t;\n"
|
||||
"typedef unsigned int uint_least32_t;\n"
|
||||
"typedef unsigned long int uint_least64_t;\n"
|
||||
"\n"
|
||||
"typedef signed char int_fast8_t;\n"
|
||||
"typedef long int int_fast16_t;\n"
|
||||
"typedef long int int_fast32_t;\n"
|
||||
"typedef long int int_fast64_t;\n"
|
||||
"\n"
|
||||
"typedef unsigned char uint_fast8_t;\n"
|
||||
"typedef unsigned long int uint_fast16_t;\n"
|
||||
"typedef unsigned long int uint_fast32_t;\n"
|
||||
"typedef unsigned long int uint_fast64_t;\n"
|
||||
"\n"
|
||||
"#define __intptr_t_defined\n"
|
||||
"typedef long int intptr_t;\n"
|
||||
"typedef unsigned long int uintptr_t;\n"
|
||||
"\n"
|
||||
"typedef long int intmax_t;\n"
|
||||
"typedef unsigned long int uintmax_t;\n"
|
||||
"\n"
|
||||
"#define __INT64_C(c) c##L\n"
|
||||
"#define __UINT64_C(c) c##UL\n"
|
||||
"\n"
|
||||
"#define INT8_MIN (-128)\n"
|
||||
"#define INT16_MIN (-32768)\n"
|
||||
"#define INT32_MIN (-2147483648)\n"
|
||||
"#define INT64_MIN (-9223372036854775808l)\n"
|
||||
"\n"
|
||||
"#define INT8_MAX (127)\n"
|
||||
"#define INT16_MAX (32767)\n"
|
||||
"#define INT32_MAX (2147483647)\n"
|
||||
"#define INT64_MAX (9223372036854775807l)\n"
|
||||
"\n"
|
||||
"#define UINT8_MAX (255)\n"
|
||||
"#define UINT16_MAX (65535)\n"
|
||||
"#define UINT32_MAX (4294967295u)\n"
|
||||
"#define UINT64_MAX (18446744073709551615ul)\n"
|
||||
"\n"
|
||||
"#define INT_LEAST8_MIN (-128)\n"
|
||||
"#define INT_LEAST16_MIN (-32768)\n"
|
||||
"#define INT_LEAST32_MIN (-2147483648)\n"
|
||||
"#define INT_LEAST64_MIN (-9223372036854775808L)\n"
|
||||
"\n"
|
||||
"#define INT_LEAST8_MAX (127)\n"
|
||||
"#define INT_LEAST16_MAX (32767)\n"
|
||||
"#define INT_LEAST32_MAX (2147483647)\n"
|
||||
"#define INT_LEAST64_MAX (9223372036854775807L)\n"
|
||||
"\n"
|
||||
"#define UINT_LEAST8_MAX (255)\n"
|
||||
"#define UINT_LEAST16_MAX (65535)\n"
|
||||
"#define UINT_LEAST32_MAX (4294967295U)\n"
|
||||
"#define UINT_LEAST64_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define INT_FAST8_MIN (-128)\n"
|
||||
"#define INT_FAST16_MIN (-9223372036854775808L)\n"
|
||||
"#define INT_FAST32_MIN (-9223372036854775808L)\n"
|
||||
"#define INT_FAST64_MIN (-9223372036854775808L)\n"
|
||||
"\n"
|
||||
"#define INT_FAST8_MAX (127)\n"
|
||||
"#define INT_FAST16_MAX (9223372036854775807L)\n"
|
||||
"#define INT_FAST32_MAX (9223372036854775807L)\n"
|
||||
"#define INT_FAST64_MAX (9223372036854775807L)\n"
|
||||
"\n"
|
||||
"#define UINT_FAST8_MAX (255)\n"
|
||||
"#define UINT_FAST16_MAX (18446744073709551615UL)\n"
|
||||
"#define UINT_FAST32_MAX (18446744073709551615UL)\n"
|
||||
"#define UINT_FAST64_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define INTPTR_MIN (-9223372036854775808L)\n"
|
||||
"#define INTPTR_MAX (9223372036854775807L)\n"
|
||||
"#define UINTPTR_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define INTMAX_MIN (-9223372036854775808L)\n"
|
||||
"#define INTMAX_MAX (9223372036854775807L)\n"
|
||||
"#define UINTMAX_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define PTRDIFF_MIN (-9223372036854775808L)\n"
|
||||
"#define PTRDIFF_MAX (9223372036854775807L)\n"
|
||||
"\n"
|
||||
"#define SIZE_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"/* For signed wchar_t and wint_t: */\n"
|
||||
"#define WCHAR_MIN INT32_MIN\n"
|
||||
"#define WCHAR_MAX INT32_MAX\n"
|
||||
"#define WINT_MIN WCHAR_MIN\n"
|
||||
"#define WINT_MAX WCHAR_MAX\n"
|
||||
"\n"
|
||||
"#define INT8_C(value) value\n"
|
||||
"#define INT16_C(value) value\n"
|
||||
"#define INT32_C(value) value\n"
|
||||
"#define INT64_C(value) value##L\n"
|
||||
"\n"
|
||||
"#define UINT8_C(value) value\n"
|
||||
"#define UINT16_C(value) value\n"
|
||||
"#define UINT32_C(value) value##U\n"
|
||||
"#define UINT64_C(value) value##UL\n"
|
||||
"\n"
|
||||
"#define INTMAX_C(value) value##L\n"
|
||||
"#define UINTMAX_C(value) value##UL\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef _STDINT_H */\n";
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,21 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.9 */
|
||||
static char iso646_str[]
|
||||
= "#ifndef __ISO646_H\n"
|
||||
"#define __ISO646_H\n"
|
||||
"\n"
|
||||
"#define and &&\n"
|
||||
"#define and_eq &=\n"
|
||||
"#define bitand &\n"
|
||||
"#define bitor |\n"
|
||||
"#define compl ~\n"
|
||||
"#define not !\n"
|
||||
"#define not_eq !=\n"
|
||||
"#define or ||\n"
|
||||
"#define or_eq |=\n"
|
||||
"#define xor ^\n"
|
||||
"#define xor_eq ^=\n"
|
||||
"#endif /* #ifndef __ISO646_H */\n";
|
@ -0,0 +1,14 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.15 */
|
||||
static char stdalign_str[]
|
||||
= "#ifndef __STDALIGN_H\n"
|
||||
"#define __STDALIGN_H\n"
|
||||
"\n"
|
||||
"#define alignas _Alignas\n"
|
||||
"#define alignof _Alignof\n"
|
||||
"#define __alignas_is_defined 1\n"
|
||||
"#define __alignof_is_defined 1\n"
|
||||
"#endif /* #ifndef __STDALIGN_H */\n";
|
@ -0,0 +1,14 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.18 */
|
||||
static char stdbool_str[]
|
||||
= "#ifndef __STDBOOL_H\n"
|
||||
"#define __STDBOOL_H\n"
|
||||
"\n"
|
||||
"#define bool _Bool\n"
|
||||
"#define true 1\n"
|
||||
"#define false 0\n"
|
||||
"#define __bool_true_false_are_defined 1\n"
|
||||
"#endif /* #ifndef __STDBOOL_H */\n";
|
@ -0,0 +1,11 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.23 */
|
||||
static char stdnoreturn_str[]
|
||||
= "#ifndef __STDNORETURN_H\n"
|
||||
"#define __STDNORETURN_H\n"
|
||||
"\n"
|
||||
"#define noreturn _Noreturn\n"
|
||||
"#endif /* #ifndef __STDNORETURN_H */\n";
|
@ -0,0 +1,310 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2018-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
ppc64 call ABI target specific code.
|
||||
*/
|
||||
|
||||
typedef int target_arg_info_t;
|
||||
|
||||
static void target_init_arg_vars (c2m_ctx_t c2m_ctx, target_arg_info_t *arg_info) {}
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
static MIR_type_t fp_homogeneous_type (c2m_ctx_t c2m_ctx, struct type *param_type, int *num) {
|
||||
return MIR_T_UNDEF;
|
||||
}
|
||||
#else
|
||||
static MIR_type_t fp_homogeneous_type_1 (c2m_ctx_t c2m_ctx, MIR_type_t curr_type, struct type *type,
|
||||
int *num) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
int n;
|
||||
MIR_type_t t;
|
||||
|
||||
if (type->mode == TM_STRUCT || type->mode == TM_UNION || type->mode == TM_ARR) {
|
||||
switch (type->mode) {
|
||||
case TM_ARR: { /* Arrays are handled as small records. */
|
||||
struct arr_type *arr_type = type->u.arr_type;
|
||||
struct expr *cexpr = arr_type->size->attr;
|
||||
|
||||
if ((t = fp_homogeneous_type_1 (c2m_ctx, curr_type, type->u.arr_type->el_type, &n))
|
||||
== MIR_T_UNDEF)
|
||||
return MIR_T_UNDEF;
|
||||
*num = arr_type->size->code == N_IGNORE || !cexpr->const_p ? 1 : cexpr->u.i_val;
|
||||
return t;
|
||||
}
|
||||
case TM_STRUCT:
|
||||
case TM_UNION:
|
||||
t = curr_type;
|
||||
*num = 0;
|
||||
for (node_t el = NL_HEAD (NL_EL (type->u.tag_type->u.ops, 1)->u.ops); el != NULL;
|
||||
el = NL_NEXT (el))
|
||||
if (el->code == N_MEMBER) {
|
||||
decl_t decl = el->attr;
|
||||
|
||||
if ((t = fp_homogeneous_type_1 (c2m_ctx, t, decl->decl_spec.type, &n)) == MIR_T_UNDEF)
|
||||
return MIR_T_UNDEF;
|
||||
if (type->mode == TM_STRUCT)
|
||||
*num += n;
|
||||
else if (*num < n)
|
||||
*num = n;
|
||||
}
|
||||
return t;
|
||||
default: assert (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
assert (scalar_type_p (type));
|
||||
if ((t = get_mir_type (c2m_ctx, type)) != MIR_T_F && t != MIR_T_D) return MIR_T_UNDEF;
|
||||
if (curr_type != t && curr_type != MIR_T_UNDEF) return MIR_T_UNDEF;
|
||||
*num = 1;
|
||||
return t;
|
||||
}
|
||||
|
||||
static MIR_type_t fp_homogeneous_type (c2m_ctx_t c2m_ctx, struct type *param_type, int *num) {
|
||||
if (param_type->mode != TM_STRUCT && param_type->mode != TM_UNION) return MIR_T_UNDEF;
|
||||
return fp_homogeneous_type_1 (c2m_ctx, MIR_T_UNDEF, param_type, num);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int reg_aggregate_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
return FALSE;
|
||||
#else
|
||||
return type_size (c2m_ctx, ret_type) <= 2 * 8;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int target_return_by_addr_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
|
||||
MIR_type_t type;
|
||||
int n;
|
||||
|
||||
if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) return FALSE;
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8)
|
||||
return FALSE;
|
||||
return !reg_aggregate_p (c2m_ctx, ret_type);
|
||||
}
|
||||
|
||||
static void target_add_res_proto (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_type_t) * res_types,
|
||||
VARR (MIR_var_t) * arg_vars) {
|
||||
MIR_var_t var;
|
||||
MIR_type_t type;
|
||||
int i, n, size;
|
||||
|
||||
if (void_type_p (ret_type)) return;
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
for (i = 0; i < n; i++) VARR_PUSH (MIR_type_t, res_types, type);
|
||||
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
|
||||
VARR_PUSH (MIR_type_t, res_types, get_mir_type (c2m_ctx, ret_type));
|
||||
} else if (reg_aggregate_p (c2m_ctx, ret_type)) {
|
||||
size = type_size (c2m_ctx, ret_type);
|
||||
for (; size > 0; size -= 8) VARR_PUSH (MIR_type_t, res_types, MIR_T_I64);
|
||||
} else {
|
||||
var.name = RET_ADDR_NAME;
|
||||
var.type = MIR_T_RBLK;
|
||||
var.size = type_size (c2m_ctx, ret_type);
|
||||
VARR_PUSH (MIR_var_t, arg_vars, var);
|
||||
}
|
||||
}
|
||||
|
||||
static int target_add_call_res_op (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, size_t call_arg_area_offset) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_type_t type;
|
||||
op_t temp;
|
||||
int i, n, size;
|
||||
|
||||
if (void_type_p (ret_type)) return -1;
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
for (i = 0; i < n; i++) {
|
||||
temp = get_new_temp (c2m_ctx, type);
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
}
|
||||
return n;
|
||||
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
|
||||
type = get_mir_type (c2m_ctx, ret_type);
|
||||
type = promote_mir_int_type (type);
|
||||
temp = get_new_temp (c2m_ctx, type);
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
return 1;
|
||||
} else if (reg_aggregate_p (c2m_ctx, ret_type)) {
|
||||
size = type_size (c2m_ctx, ret_type);
|
||||
if (size == 0) return -1;
|
||||
for (int s = size; s > 0; s -= 8) {
|
||||
temp = get_new_temp (c2m_ctx, MIR_T_I64);
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
}
|
||||
return (size + 7) / 8;
|
||||
} else {
|
||||
temp = get_new_temp (c2m_ctx, MIR_T_I64);
|
||||
emit3 (c2m_ctx, MIR_ADD, temp.mir_op,
|
||||
MIR_new_reg_op (ctx, MIR_reg (ctx, FP_NAME, curr_func->u.func)),
|
||||
MIR_new_int_op (ctx, call_arg_area_offset));
|
||||
temp.mir_op
|
||||
= MIR_new_mem_op (ctx, MIR_T_RBLK, type_size (c2m_ctx, ret_type), temp.mir_op.u.reg, 0, 1);
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static op_t target_gen_post_call_res_code (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res,
|
||||
MIR_insn_t call, size_t call_ops_start) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_type_t type;
|
||||
MIR_insn_t insn;
|
||||
int i, n;
|
||||
|
||||
if (void_type_p (ret_type)) return res;
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
assert (res.mir_op.mode == MIR_OP_MEM);
|
||||
for (i = 0; i < n; i++) {
|
||||
insn = MIR_new_insn (ctx, tp_mov (type),
|
||||
MIR_new_mem_op (ctx, type,
|
||||
res.mir_op.u.mem.disp + (type == MIR_T_F ? 4 : 8) * i,
|
||||
res.mir_op.u.mem.base, res.mir_op.u.mem.index,
|
||||
res.mir_op.u.mem.scale),
|
||||
VARR_GET (MIR_op_t, call_ops, i + call_ops_start + 2));
|
||||
MIR_append_insn (ctx, curr_func, insn);
|
||||
}
|
||||
} else if ((ret_type->mode == TM_STRUCT || ret_type->mode == TM_UNION)
|
||||
&& reg_aggregate_p (c2m_ctx, ret_type)) {
|
||||
assert (res.mir_op.mode == MIR_OP_MEM); /* addr */
|
||||
gen_multiple_load_store (c2m_ctx, ret_type, &VARR_ADDR (MIR_op_t, call_ops)[call_ops_start + 2],
|
||||
res.mir_op, FALSE);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void target_add_ret_ops (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_type_t type;
|
||||
MIR_insn_t insn;
|
||||
MIR_reg_t ret_addr_reg;
|
||||
op_t temp, var;
|
||||
int i, n, size;
|
||||
|
||||
if (void_type_p (ret_type)) return;
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
assert (res.mir_op.mode == MIR_OP_MEM);
|
||||
for (int i = 0; i < n; i++) {
|
||||
temp = get_new_temp (c2m_ctx, type);
|
||||
insn = MIR_new_insn (ctx, tp_mov (type), temp.mir_op,
|
||||
MIR_new_mem_op (ctx, type,
|
||||
res.mir_op.u.mem.disp + (type == MIR_T_F ? 4 : 8) * i,
|
||||
res.mir_op.u.mem.base, res.mir_op.u.mem.index,
|
||||
res.mir_op.u.mem.scale));
|
||||
MIR_append_insn (ctx, curr_func, insn);
|
||||
VARR_PUSH (MIR_op_t, ret_ops, temp.mir_op);
|
||||
}
|
||||
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
|
||||
VARR_PUSH (MIR_op_t, ret_ops, res.mir_op);
|
||||
} else if (reg_aggregate_p (c2m_ctx, ret_type)) {
|
||||
size = type_size (c2m_ctx, ret_type);
|
||||
assert (res.mir_op.mode == MIR_OP_MEM && VARR_LENGTH (MIR_op_t, ret_ops) == 0);
|
||||
for (int i = 0; size > 0; size -= 8, i++)
|
||||
VARR_PUSH (MIR_op_t, ret_ops, get_new_temp (c2m_ctx, MIR_T_I64).mir_op);
|
||||
gen_multiple_load_store (c2m_ctx, ret_type, &VARR_ADDR (MIR_op_t, ret_ops)[0], res.mir_op,
|
||||
TRUE);
|
||||
} else {
|
||||
ret_addr_reg = MIR_reg (ctx, RET_ADDR_NAME, curr_func->u.func);
|
||||
var = new_op (NULL, MIR_new_mem_op (ctx, MIR_T_I8, 0, ret_addr_reg, 0, 1));
|
||||
size = type_size (c2m_ctx, ret_type);
|
||||
block_move (c2m_ctx, var, res, size);
|
||||
}
|
||||
}
|
||||
|
||||
static MIR_type_t target_get_blk_type (c2m_ctx_t c2m_ctx, struct type *arg_type) {
|
||||
return MIR_T_BLK; /* one BLK is enough */
|
||||
}
|
||||
|
||||
static void target_add_arg_proto (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_var_t) * arg_vars) {
|
||||
MIR_var_t var;
|
||||
MIR_type_t type;
|
||||
int n;
|
||||
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, arg_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
var.name = gen_get_indexed_name (c2m_ctx, name, i);
|
||||
var.type = type;
|
||||
VARR_PUSH (MIR_var_t, arg_vars, var);
|
||||
}
|
||||
return;
|
||||
}
|
||||
type = (arg_type->mode == TM_STRUCT || arg_type->mode == TM_UNION
|
||||
? MIR_T_BLK
|
||||
: get_mir_type (c2m_ctx, arg_type));
|
||||
var.name = name;
|
||||
var.type = type;
|
||||
if (type == MIR_T_BLK) var.size = type_size (c2m_ctx, arg_type);
|
||||
VARR_PUSH (MIR_var_t, arg_vars, var);
|
||||
}
|
||||
|
||||
static void target_add_call_arg_op (c2m_ctx_t c2m_ctx, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, op_t arg) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_var_t var;
|
||||
MIR_type_t type;
|
||||
op_t temp;
|
||||
int n;
|
||||
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, arg_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
assert (arg.mir_op.mode == MIR_OP_MEM);
|
||||
arg = mem_to_address (c2m_ctx, arg, TRUE);
|
||||
for (int i = 0; i < n; i++) {
|
||||
temp = get_new_temp (c2m_ctx, type);
|
||||
MIR_append_insn (ctx, curr_func,
|
||||
MIR_new_insn (ctx, tp_mov (type), temp.mir_op,
|
||||
MIR_new_mem_op (ctx, type, (type == MIR_T_F ? 4 : 8) * i,
|
||||
arg.mir_op.u.reg, 0, 1)));
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION) {
|
||||
VARR_PUSH (MIR_op_t, call_ops, arg.mir_op);
|
||||
} else {
|
||||
assert (arg.mir_op.mode == MIR_OP_MEM);
|
||||
arg = mem_to_address (c2m_ctx, arg, TRUE);
|
||||
VARR_PUSH (MIR_op_t, call_ops,
|
||||
MIR_new_mem_op (ctx, MIR_T_BLK, type_size (c2m_ctx, arg_type), arg.mir_op.u.reg, 0,
|
||||
1));
|
||||
}
|
||||
}
|
||||
|
||||
static int target_gen_gather_arg (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
decl_t param_decl, target_arg_info_t *arg_info) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_var_t var;
|
||||
MIR_type_t type;
|
||||
reg_var_t reg_var;
|
||||
int i, n;
|
||||
|
||||
if (((type = fp_homogeneous_type (c2m_ctx, arg_type, &n)) == MIR_T_F || type == MIR_T_D)
|
||||
&& n <= 8) {
|
||||
for (i = 0; i < n; i++) {
|
||||
assert (!param_decl->reg_p);
|
||||
reg_var = get_reg_var (c2m_ctx, type, gen_get_indexed_name (c2m_ctx, name, i));
|
||||
MIR_append_insn (ctx, curr_func,
|
||||
MIR_new_insn (ctx, tp_mov (type),
|
||||
MIR_new_mem_op (ctx, type,
|
||||
param_decl->offset
|
||||
+ (type == MIR_T_F ? 4 : 8) * i,
|
||||
MIR_reg (ctx, FP_NAME, curr_func->u.func), 0,
|
||||
1),
|
||||
MIR_new_reg_op (ctx, reg_var.reg)));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 5.2.4.2.2 */
|
||||
static char float_str[]
|
||||
= "#ifndef __FLOAT_H\n"
|
||||
"#define __FLOAT_H\n"
|
||||
"\n"
|
||||
"#define FLT_RADIX 2\n"
|
||||
"\n"
|
||||
"#define FLT_MANT_DIG 24\n"
|
||||
"#define DBL_MANT_DIG 53\n"
|
||||
"#define LDBL_MANT_DIG DBL_MANT_DIG\n"
|
||||
"\n"
|
||||
"#define FLT_DECIMAL_DIG 9\n"
|
||||
"#define DBL_DECIMAL_DIG 17\n"
|
||||
"#define LDBL_DECIMAL_DIG DBL_DECIMAL_DIG\n"
|
||||
"#define FLT_DIG FLT_DECIMAL_DIG\n"
|
||||
"#define DBL_DIG DBL_DECIMAL_DIG\n"
|
||||
"#define LDBL_DIG LDBL_DECIMAL_DIG\n"
|
||||
"\n"
|
||||
"#define DECIMAL_DIG LDBL_DECIMAL_DIG\n"
|
||||
"\n"
|
||||
"#define FLT_MIN_EXP -125\n"
|
||||
"#define DBL_MIN_EXP -1021\n"
|
||||
"#define LDBL_MIN_EXP DBL_MIN_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MIN_10_EXP -37\n"
|
||||
"#define DBL_MIN_10_EXP -307\n"
|
||||
"#define LDBL_MIN_10_EXP DBL_MIN_10_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MAX_EXP 128\n"
|
||||
"#define DBL_MAX_EXP 1024\n"
|
||||
"#define LDBL_MAX_EXP DBL_MAX_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MAX_10_EXP 38\n"
|
||||
"#define DBL_MAX_10_EXP 308\n"
|
||||
"#define LDBL_MAX_10_EXP DBL_MAX_10_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MAX 0x1.fffffep+127\n"
|
||||
"#define DBL_MAX 0x1.fffffffffffffp+1023\n"
|
||||
"#define LDBL_MAX DBL_MAX\n"
|
||||
"\n"
|
||||
"#define FLT_EPSILON 0x1p-23\n"
|
||||
"#define DBL_EPSILON 0x1p-52\n"
|
||||
"#define LDBL_EPSILON DBL_EPSILON\n"
|
||||
"\n"
|
||||
"#define FLT_MIN 0x1p-126\n"
|
||||
"#define DBL_MIN 0x1p-1022\n"
|
||||
"#define LDBL_MIN DBL_MIN\n"
|
||||
"\n"
|
||||
"#define FLT_TRUE_MIN 0x1p-149\n"
|
||||
"#define DBL_TRUE_MIN 0x0.0000000000001p-1022\n"
|
||||
"#define LDBL_TRUE_MIN DBL_TRUE_MIN\n"
|
||||
"\n"
|
||||
"#define FLT_EVAL_METHOD 0\n"
|
||||
"#define FLT_ROUNDS 1 /* round to the nearest */\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef __FLOAT_H */\n";
|
@ -0,0 +1,38 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See 5.2.4.2 */
|
||||
static char limits_str[]
|
||||
= "#ifndef __LIMITS_H\n"
|
||||
"#define __LIMITS_H\n"
|
||||
"\n"
|
||||
"#define CHAR_BIT 8\n"
|
||||
"\n"
|
||||
"#define SCHAR_MIN (-SCHAR_MAX - 1)\n"
|
||||
"#define SCHAR_MAX 127\n"
|
||||
"#define UCHAR_MAX (SCHAR_MAX * 2 + 1)\n"
|
||||
"\n"
|
||||
"#define MB_LEN_MAX 1\n"
|
||||
"\n"
|
||||
"#define SHRT_MIN (-SHRT_MAX - 1)\n"
|
||||
"#define SHRT_MAX 32767\n"
|
||||
"#define USHRT_MAX (SHRT_MAX * 2 + 1)\n"
|
||||
"\n"
|
||||
"#define INT_MIN (-INT_MAX - 1)\n"
|
||||
"#define INT_MAX 2147483647\n"
|
||||
"#define UINT_MAX (INT_MAX * 2u + 1u)\n"
|
||||
"\n"
|
||||
"#define LONG_MIN (-LONG_MAX - 1l)\n"
|
||||
"#define LONG_MAX 9223372036854775807l\n"
|
||||
"#define ULONG_MAX (LONG_MAX * 2ul + 1ul)\n"
|
||||
"\n"
|
||||
"#define LLONG_MIN LONG_MIN\n"
|
||||
"#define LLONG_MAX LONG_MAX\n"
|
||||
"#define ULLONG_MAX ULONG_MAX\n"
|
||||
"\n"
|
||||
"/* unsigned char by default */\n"
|
||||
"#define CHAR_MIN 0\n"
|
||||
"#define CHAR_MAX UCHAR_MAX\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef __LIMITS_H */\n";
|
@ -0,0 +1,107 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
static char ppc64_mirc[]
|
||||
= "#define __PPC64__ 1\n"
|
||||
"#define _ARCH_PPC64 1\n"
|
||||
"#define _LP64 1\n"
|
||||
"#define __LP64__ 1\n"
|
||||
"#define __powerpc64__ 1\n"
|
||||
"#define __powerpc__ 1\n"
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
"#define _CALL_ELF 1\n"
|
||||
#else
|
||||
"#define _CALL_ELF 2\n"
|
||||
#endif
|
||||
"\n"
|
||||
"#define __LONG_DOUBLE_128__ 1\n" // ???
|
||||
"#define __SIZEOF_DOUBLE__ 8\n"
|
||||
"#define __SIZEOF_FLOAT__ 4\n"
|
||||
"#define __SIZEOF_INT__ 4\n"
|
||||
"#define __SIZEOF_LONG_DOUBLE__ 16\n"
|
||||
"#define __SIZEOF_LONG_LONG__ 8\n"
|
||||
"#define __SIZEOF_LONG__ 8\n"
|
||||
"#define __SIZEOF_POINTER__ 8\n"
|
||||
"#define __SIZEOF_PTRDIFF_T__ 8\n"
|
||||
"#define __SIZEOF_SHORT__ 2\n"
|
||||
"#define __SIZEOF_SIZE_T__ 8\n"
|
||||
"\n"
|
||||
"#define __ORDER_LITTLE_ENDIAN__ 1234\n"
|
||||
"#define __ORDER_BIG_ENDIAN__ 4321\n"
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
"#define _BIG_ENDIAN 1\n"
|
||||
"#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__\n"
|
||||
#else
|
||||
"#define _LITTLE_ENDIAN 1\n"
|
||||
"#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__\n"
|
||||
#endif
|
||||
"\n"
|
||||
"/* Some GCC predefined macros: */\n"
|
||||
"#define __SIZE_TYPE__ unsigned long\n"
|
||||
"#define __PTRDIFF_TYPE__ long\n"
|
||||
"#define __INTMAX_TYPE__ long\n"
|
||||
"#define __UINTMAX_TYPE__ unsigned long\n"
|
||||
"#define __INT8_TYPE__ signed char\n"
|
||||
"#define __INT16_TYPE__ short\n"
|
||||
"#define __INT32_TYPE__ int\n"
|
||||
"#define __INT64_TYPE__ long\n"
|
||||
"#define __UINT8_TYPE__ unsigned char\n"
|
||||
"#define __UINT16_TYPE__ unsigned short\n"
|
||||
"#define __UINT32_TYPE__ unsigned int\n"
|
||||
"#define __UINT64_TYPE__ unsigned long\n"
|
||||
"#define __INTPTR_TYPE__ long\n"
|
||||
"#define __UINTPTR_TYPE__ unsigned long\n"
|
||||
"\n"
|
||||
"#define __CHAR_BIT__ 8\n"
|
||||
"#define __INT8_MAX__ 127\n"
|
||||
"#define __INT16_MAX__ 32767\n"
|
||||
"#define __INT32_MAX__ 2147483647\n"
|
||||
"#define __INT64_MAX__ 9223372036854775807l\n"
|
||||
"#define __UINT8_MAX__ (__INT8_MAX__ * 2u + 1u)\n"
|
||||
"#define __UINT16_MAX__ (__INT16_MAX__ * 2u + 1u)\n"
|
||||
"#define __UINT32_MAX__ (__INT32_MAX__ * 2u + 1u)\n"
|
||||
"#define __UINT64_MAX__ (__INT64_MAX__ * 2u + 1u)\n"
|
||||
"#define __SCHAR_MAX__ __INT8_MAX__\n"
|
||||
"#define __SHRT_MAX__ __INT16_MAX__\n"
|
||||
"#define __INT_MAX__ __INT32_MAX__\n"
|
||||
"#define __LONG_MAX__ __INT64_MAX__\n"
|
||||
"#define __LONG_LONG_MAX__ __INT64_MAX__\n"
|
||||
"#define __SIZE_MAX__ __UINT64_MAX__\n"
|
||||
"#define __PTRDIFF_MAX__ __INT64_MAX__\n"
|
||||
"#define __INTMAX_MAX__ __INT64_MAX__\n"
|
||||
"#define __UINTMAX_MAX__ __UINT64_MAX__\n"
|
||||
"#define __INTPTR_MAX__ __INT64_MAX__\n"
|
||||
"#define __UINTPTR_MAX__ __UINT64_MAX__\n"
|
||||
"\n"
|
||||
"#define __FLT_MIN_EXP__ (-125)\n"
|
||||
"#define __FLT_MAX_EXP__ 128\n"
|
||||
"#define __FLT_DIG__ 6\n"
|
||||
"#define __FLT_DECIMAL_DIG__ 9\n"
|
||||
"#define __FLT_MANT_DIG__ 24\n"
|
||||
"#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F\n"
|
||||
"#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F\n"
|
||||
"#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F\n"
|
||||
"\n"
|
||||
"#define __DBL_MIN_EXP__ (-1021)\n"
|
||||
"#define __DBL_MAX_EXP__ 1024\n"
|
||||
"#define __DBL_DIG__ 15\n"
|
||||
"#define __DBL_DECIMAL_DIG__ 17\n"
|
||||
"#define __DBL_MANT_DIG__ 53\n"
|
||||
"#define __DBL_MAX__ ((double) 1.79769313486231570814527423731704357e+308L)\n"
|
||||
"#define __DBL_MIN__ ((double) 2.22507385850720138309023271733240406e-308L)\n"
|
||||
"#define __DBL_EPSILON__ ((double) 2.22044604925031308084726333618164062e-16L)\n"
|
||||
"\n"
|
||||
"typedef unsigned short char16_t;\n"
|
||||
"typedef unsigned int char32_t;\n"
|
||||
"\n"
|
||||
#if defined(__linux__)
|
||||
"#define __gnu_linux__ 1\n"
|
||||
"#define __linux 1\n"
|
||||
"#define __linux__ 1\n"
|
||||
"#define linux 1\n"
|
||||
"#define __unix 1\n"
|
||||
"#define __unix__ 1\n"
|
||||
#endif
|
||||
"\n"
|
||||
"void *alloca (unsigned long);\n";
|
@ -0,0 +1,21 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
static char stdarg_str[]
|
||||
= "#ifndef __STDARG_H\n"
|
||||
"#define __STDARG_H\n"
|
||||
"\n"
|
||||
"typedef void *va_list[1];\n"
|
||||
"\n"
|
||||
"#define va_start(ap, param) __builtin_va_start (ap)\n"
|
||||
"#define va_arg(ap, type) __builtin_va_arg(ap, (type *) 0)\n"
|
||||
"#define va_end(ap) 0\n"
|
||||
"#define va_copy(dest, src) ((dest) = (src))\n"
|
||||
"\n"
|
||||
"/* For standard headers of a GNU system: */\n"
|
||||
"#ifndef __GNUC_VA_LIST\n"
|
||||
"#define __GNUC_VA_LIST 1\n"
|
||||
"#endif\n"
|
||||
"typedef va_list __gnuc_va_list;\n"
|
||||
"#endif /* #ifndef __STDARG_H */\n";
|
@ -0,0 +1,19 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.19 */
|
||||
static char stddef_str[]
|
||||
= "#ifndef __STDDEF_H\n"
|
||||
"#define __STDDEF_H\n"
|
||||
"\n"
|
||||
"typedef long ptrdiff_t;\n"
|
||||
"typedef unsigned long size_t;\n"
|
||||
"typedef long double max_align_t;\n"
|
||||
"typedef unsigned int wchar_t;\n"
|
||||
"\n"
|
||||
"#define NULL ((void *) 0)\n"
|
||||
"\n"
|
||||
"#define offsetof(type, member_designator) ((size_t) & ((type *) 0)->member_designator)\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef __STDDEF_H */\n";
|
@ -0,0 +1,130 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.20 */
|
||||
static char stdint_str[]
|
||||
= "#ifndef _STDINT_H\n"
|
||||
"#define _STDINT_H 1\n"
|
||||
"\n"
|
||||
"#ifndef __int8_t_defined\n"
|
||||
"#define __int8_t_defined\n"
|
||||
"typedef signed char int8_t;\n"
|
||||
"#endif\n"
|
||||
"typedef short int int16_t;\n"
|
||||
"typedef int int32_t;\n"
|
||||
"typedef long int int64_t;\n"
|
||||
"\n"
|
||||
"typedef unsigned char uint8_t;\n"
|
||||
"typedef unsigned short int uint16_t;\n"
|
||||
"typedef unsigned int uint32_t;\n"
|
||||
"typedef unsigned long int uint64_t;\n"
|
||||
"\n"
|
||||
"typedef signed char int_least8_t;\n"
|
||||
"typedef short int int_least16_t;\n"
|
||||
"typedef int int_least32_t;\n"
|
||||
"typedef long int int_least64_t;\n"
|
||||
"\n"
|
||||
"typedef unsigned char uint_least8_t;\n"
|
||||
"typedef unsigned short int uint_least16_t;\n"
|
||||
"typedef unsigned int uint_least32_t;\n"
|
||||
"typedef unsigned long int uint_least64_t;\n"
|
||||
"\n"
|
||||
"typedef signed char int_fast8_t;\n"
|
||||
"typedef long int int_fast16_t;\n"
|
||||
"typedef long int int_fast32_t;\n"
|
||||
"typedef long int int_fast64_t;\n"
|
||||
"\n"
|
||||
"typedef unsigned char uint_fast8_t;\n"
|
||||
"typedef unsigned long int uint_fast16_t;\n"
|
||||
"typedef unsigned long int uint_fast32_t;\n"
|
||||
"typedef unsigned long int uint_fast64_t;\n"
|
||||
"\n"
|
||||
"#define __intptr_t_defined\n"
|
||||
"typedef long int intptr_t;\n"
|
||||
"typedef unsigned long int uintptr_t;\n"
|
||||
"\n"
|
||||
"typedef long int intmax_t;\n"
|
||||
"typedef unsigned long int uintmax_t;\n"
|
||||
"\n"
|
||||
"#define __INT64_C(c) c##L\n"
|
||||
"#define __UINT64_C(c) c##UL\n"
|
||||
"\n"
|
||||
"#define INT8_MIN (-128)\n"
|
||||
"#define INT16_MIN (-32768)\n"
|
||||
"#define INT32_MIN (-2147483648)\n"
|
||||
"#define INT64_MIN (-9223372036854775808l)\n"
|
||||
"\n"
|
||||
"#define INT8_MAX (127)\n"
|
||||
"#define INT16_MAX (32767)\n"
|
||||
"#define INT32_MAX (2147483647)\n"
|
||||
"#define INT64_MAX (9223372036854775807l)\n"
|
||||
"\n"
|
||||
"#define UINT8_MAX (255)\n"
|
||||
"#define UINT16_MAX (65535)\n"
|
||||
"#define UINT32_MAX (4294967295u)\n"
|
||||
"#define UINT64_MAX (18446744073709551615ul)\n"
|
||||
"\n"
|
||||
"#define INT_LEAST8_MIN (-128)\n"
|
||||
"#define INT_LEAST16_MIN (-32768)\n"
|
||||
"#define INT_LEAST32_MIN (-2147483648)\n"
|
||||
"#define INT_LEAST64_MIN (-9223372036854775808L)\n"
|
||||
"\n"
|
||||
"#define INT_LEAST8_MAX (127)\n"
|
||||
"#define INT_LEAST16_MAX (32767)\n"
|
||||
"#define INT_LEAST32_MAX (2147483647)\n"
|
||||
"#define INT_LEAST64_MAX (9223372036854775807L)\n"
|
||||
"\n"
|
||||
"#define UINT_LEAST8_MAX (255)\n"
|
||||
"#define UINT_LEAST16_MAX (65535)\n"
|
||||
"#define UINT_LEAST32_MAX (4294967295U)\n"
|
||||
"#define UINT_LEAST64_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define INT_FAST8_MIN (-128)\n"
|
||||
"#define INT_FAST16_MIN (-9223372036854775808L)\n"
|
||||
"#define INT_FAST32_MIN (-9223372036854775808L)\n"
|
||||
"#define INT_FAST64_MIN (-9223372036854775808L)\n"
|
||||
"\n"
|
||||
"#define INT_FAST8_MAX (127)\n"
|
||||
"#define INT_FAST16_MAX (9223372036854775807L)\n"
|
||||
"#define INT_FAST32_MAX (9223372036854775807L)\n"
|
||||
"#define INT_FAST64_MAX (9223372036854775807L)\n"
|
||||
"\n"
|
||||
"#define UINT_FAST8_MAX (255)\n"
|
||||
"#define UINT_FAST16_MAX (18446744073709551615UL)\n"
|
||||
"#define UINT_FAST32_MAX (18446744073709551615UL)\n"
|
||||
"#define UINT_FAST64_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define INTPTR_MIN (-9223372036854775808L)\n"
|
||||
"#define INTPTR_MAX (9223372036854775807L)\n"
|
||||
"#define UINTPTR_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define INTMAX_MIN (-9223372036854775808L)\n"
|
||||
"#define INTMAX_MAX (9223372036854775807L)\n"
|
||||
"#define UINTMAX_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define PTRDIFF_MIN (-9223372036854775808L)\n"
|
||||
"#define PTRDIFF_MAX (9223372036854775807L)\n"
|
||||
"\n"
|
||||
"#define SIZE_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"/* For signed wchar_t and wint_t: */\n"
|
||||
"#define WCHAR_MIN INT32_MIN\n"
|
||||
"#define WCHAR_MAX INT32_MAX\n"
|
||||
"#define WINT_MIN WCHAR_MIN\n"
|
||||
"#define WINT_MAX WCHAR_MAX\n"
|
||||
"\n"
|
||||
"#define INT8_C(value) value\n"
|
||||
"#define INT16_C(value) value\n"
|
||||
"#define INT32_C(value) value\n"
|
||||
"#define INT64_C(value) value##L\n"
|
||||
"\n"
|
||||
"#define UINT8_C(value) value\n"
|
||||
"#define UINT16_C(value) value\n"
|
||||
"#define UINT32_C(value) value##U\n"
|
||||
"#define UINT64_C(value) value##UL\n"
|
||||
"\n"
|
||||
"#define INTMAX_C(value) value##L\n"
|
||||
"#define UINTMAX_C(value) value##UL\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef _STDINT_H */\n";
|
@ -0,0 +1,100 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2018-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
s390x call ABI target specific code.
|
||||
*/
|
||||
|
||||
typedef int target_arg_info_t;
|
||||
|
||||
static void target_init_arg_vars (c2m_ctx_t c2m_ctx, target_arg_info_t *arg_info) {}
|
||||
|
||||
static int target_return_by_addr_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
|
||||
return simple_return_by_addr_p (c2m_ctx, ret_type);
|
||||
}
|
||||
|
||||
static void target_add_res_proto (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_type_t) * res_types,
|
||||
VARR (MIR_var_t) * arg_vars) {
|
||||
simple_add_res_proto (c2m_ctx, ret_type, arg_info, res_types, arg_vars);
|
||||
}
|
||||
|
||||
static int target_add_call_res_op (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, size_t call_arg_area_offset) {
|
||||
return simple_add_call_res_op (c2m_ctx, ret_type, arg_info, call_arg_area_offset);
|
||||
}
|
||||
|
||||
static op_t target_gen_post_call_res_code (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res,
|
||||
MIR_insn_t call, size_t call_ops_start) {
|
||||
return simple_gen_post_call_res_code (c2m_ctx, ret_type, res, call, call_ops_start);
|
||||
}
|
||||
|
||||
static void target_add_ret_ops (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res) {
|
||||
simple_add_ret_ops (c2m_ctx, ret_type, res);
|
||||
}
|
||||
|
||||
static int reg_aggregate_p (c2m_ctx_t c2m_ctx, struct type *arg_type) {
|
||||
size_t size = type_size (c2m_ctx, arg_type);
|
||||
return size == 1 || size == 2 || size == 4 || size == 8;
|
||||
}
|
||||
|
||||
static MIR_type_t target_get_blk_type (c2m_ctx_t c2m_ctx, struct type *arg_type) {
|
||||
return MIR_T_BLK; /* one BLK is enough */
|
||||
}
|
||||
|
||||
static void target_add_arg_proto (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_var_t) * arg_vars) {
|
||||
MIR_var_t var;
|
||||
MIR_type_t type;
|
||||
|
||||
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION)
|
||||
type = get_mir_type (c2m_ctx, arg_type);
|
||||
else if (reg_aggregate_p (c2m_ctx, arg_type))
|
||||
type = MIR_T_I64;
|
||||
else
|
||||
type = MIR_T_BLK;
|
||||
var.name = name;
|
||||
var.type = type;
|
||||
if (type == MIR_T_BLK) var.size = type_size (c2m_ctx, arg_type);
|
||||
VARR_PUSH (MIR_var_t, arg_vars, var);
|
||||
}
|
||||
|
||||
static void target_add_call_arg_op (c2m_ctx_t c2m_ctx, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, op_t arg) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
op_t temp;
|
||||
|
||||
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION) {
|
||||
VARR_PUSH (MIR_op_t, call_ops, arg.mir_op);
|
||||
} else if (reg_aggregate_p (c2m_ctx, arg_type)) {
|
||||
assert (arg.mir_op.mode == MIR_OP_MEM);
|
||||
temp = get_new_temp (c2m_ctx, MIR_T_I64);
|
||||
gen_multiple_load_store (c2m_ctx, arg_type, &temp.mir_op, arg.mir_op, TRUE);
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
} else {
|
||||
assert (arg.mir_op.mode == MIR_OP_MEM);
|
||||
arg = mem_to_address (c2m_ctx, arg, TRUE);
|
||||
VARR_PUSH (MIR_op_t, call_ops,
|
||||
MIR_new_mem_op (c2m_ctx->ctx, MIR_T_BLK, type_size (c2m_ctx, arg_type),
|
||||
arg.mir_op.u.reg, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
static int target_gen_gather_arg (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
decl_t param_decl, target_arg_info_t *arg_info) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_type_t type;
|
||||
MIR_op_t param_op;
|
||||
reg_var_t reg_var;
|
||||
|
||||
if ((arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION)
|
||||
|| !reg_aggregate_p (c2m_ctx, arg_type))
|
||||
return FALSE;
|
||||
assert (!param_decl->reg_p);
|
||||
reg_var = get_reg_var (c2m_ctx, MIR_T_I64, name);
|
||||
param_op = MIR_new_reg_op (ctx, reg_var.reg);
|
||||
gen_multiple_load_store (c2m_ctx, arg_type, ¶m_op,
|
||||
MIR_new_mem_op (ctx, MIR_T_UNDEF, param_decl->offset,
|
||||
MIR_reg (ctx, FP_NAME, curr_func->u.func), 0, 1),
|
||||
FALSE);
|
||||
return TRUE;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
#include "../mirc.h"
|
||||
#include "mirc_s390x_linux.h"
|
||||
|
||||
#include "mirc_s390x_float.h"
|
||||
#include "mirc_s390x_limits.h"
|
||||
#include "mirc_s390x_stdarg.h"
|
||||
#include "mirc_s390x_stdint.h"
|
||||
#include "mirc_s390x_stddef.h"
|
||||
|
||||
static string_include_t standard_includes[]
|
||||
= {{NULL, mirc}, {NULL, s390x_mirc}, TARGET_STD_INCLUDES};
|
||||
|
||||
#define MAX_ALIGNMENT 16
|
||||
|
||||
#define ADJUST_VAR_ALIGNMENT(c2m_ctx, align, type) s390x_adjust_var_alignment (c2m_ctx, align, type)
|
||||
|
||||
static int s390x_adjust_var_alignment (c2m_ctx_t c2m_ctx, int align, struct type *type) {
|
||||
return align;
|
||||
}
|
||||
|
||||
static int invalid_alignment (mir_llong align) {
|
||||
return align != 0 && align != 1 && align != 2 && align != 4 && align != 8 && align != 16;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MIR_CHAR_BIT 8
|
||||
|
||||
typedef int8_t mir_schar;
|
||||
typedef int16_t mir_short;
|
||||
typedef int32_t mir_int;
|
||||
typedef int64_t mir_long;
|
||||
typedef int64_t mir_llong;
|
||||
|
||||
#define MIR_SCHAR_MIN INT8_MIN
|
||||
#define MIR_SCHAR_MAX INT8_MAX
|
||||
#define MIR_SHORT_MIN INT16_MIN
|
||||
#define MIR_SHORT_MAX INT16_MAX
|
||||
#define MIR_INT_MIN INT32_MIN
|
||||
#define MIR_INT_MAX INT32_MAX
|
||||
#define MIR_LONG_MIN INT64_MIN
|
||||
#define MIR_LONG_MAX INT64_MAX
|
||||
#define MIR_LLONG_MIN INT64_MIN
|
||||
#define MIR_LLONG_MAX INT64_MAX
|
||||
|
||||
typedef uint8_t mir_uchar;
|
||||
typedef uint16_t mir_ushort;
|
||||
typedef uint32_t mir_uint;
|
||||
typedef uint64_t mir_ulong;
|
||||
typedef uint64_t mir_ullong;
|
||||
typedef uint32_t mir_wchar;
|
||||
typedef uint16_t mir_char16;
|
||||
typedef uint32_t mir_char32;
|
||||
|
||||
#define MIR_UCHAR_MAX UINT8_MAX
|
||||
#define MIR_USHORT_MAX UINT16_MAX
|
||||
#define MIR_UINT_MAX UINT32_MAX
|
||||
#define MIR_ULONG_MAX UINT64_MAX
|
||||
#define MIR_ULLONG_MAX UINT64_MAX
|
||||
#define MIR_WCHAR_MIN 0
|
||||
#define MIR_WCHAR_MAX UINT32_MAX
|
||||
|
||||
typedef mir_schar mir_char;
|
||||
#define MIR_CHAR_MIN MIR_SCHAR_MIN
|
||||
#define MIR_CHAR_MAX MIR_SCHAR_MAX
|
||||
|
||||
typedef float mir_float;
|
||||
typedef double mir_double;
|
||||
typedef long double mir_ldouble;
|
||||
|
||||
typedef uint8_t mir_bool;
|
||||
typedef int64_t mir_ptrdiff_t;
|
||||
typedef uint64_t mir_size_t;
|
||||
|
||||
#define MIR_SIZE_MAX UINT64_MAX
|
@ -0,0 +1,60 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 5.2.4.2.2 */
|
||||
static char float_str[]
|
||||
= "#ifndef __FLOAT_H\n"
|
||||
"#define __FLOAT_H\n"
|
||||
"\n"
|
||||
"#define FLT_RADIX 2\n"
|
||||
"\n"
|
||||
"#define FLT_MANT_DIG 24\n"
|
||||
"#define DBL_MANT_DIG 53\n"
|
||||
"#define LDBL_MANT_DIG DBL_MANT_DIG\n"
|
||||
"\n"
|
||||
"#define FLT_DECIMAL_DIG 9\n"
|
||||
"#define DBL_DECIMAL_DIG 17\n"
|
||||
"#define LDBL_DECIMAL_DIG DBL_DECIMAL_DIG\n"
|
||||
"#define FLT_DIG FLT_DECIMAL_DIG\n"
|
||||
"#define DBL_DIG DBL_DECIMAL_DIG\n"
|
||||
"#define LDBL_DIG LDBL_DECIMAL_DIG\n"
|
||||
"\n"
|
||||
"#define DECIMAL_DIG LDBL_DECIMAL_DIG\n"
|
||||
"\n"
|
||||
"#define FLT_MIN_EXP -125\n"
|
||||
"#define DBL_MIN_EXP -1021\n"
|
||||
"#define LDBL_MIN_EXP DBL_MIN_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MIN_10_EXP -37\n"
|
||||
"#define DBL_MIN_10_EXP -307\n"
|
||||
"#define LDBL_MIN_10_EXP DBL_MIN_10_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MAX_EXP 128\n"
|
||||
"#define DBL_MAX_EXP 1024\n"
|
||||
"#define LDBL_MAX_EXP DBL_MAX_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MAX_10_EXP 38\n"
|
||||
"#define DBL_MAX_10_EXP 308\n"
|
||||
"#define LDBL_MAX_10_EXP DBL_MAX_10_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MAX 0x1.fffffep+127\n"
|
||||
"#define DBL_MAX 0x1.fffffffffffffp+1023\n"
|
||||
"#define LDBL_MAX DBL_MAX\n"
|
||||
"\n"
|
||||
"#define FLT_EPSILON 0x1p-23\n"
|
||||
"#define DBL_EPSILON 0x1p-52\n"
|
||||
"#define LDBL_EPSILON DBL_EPSILON\n"
|
||||
"\n"
|
||||
"#define FLT_MIN 0x1p-126\n"
|
||||
"#define DBL_MIN 0x1p-1022\n"
|
||||
"#define LDBL_MIN DBL_MIN\n"
|
||||
"\n"
|
||||
"#define FLT_TRUE_MIN 0x1p-149\n"
|
||||
"#define DBL_TRUE_MIN 0x0.0000000000001p-1022\n"
|
||||
"#define LDBL_TRUE_MIN DBL_TRUE_MIN\n"
|
||||
"\n"
|
||||
"#define FLT_EVAL_METHOD 0\n"
|
||||
"#define FLT_ROUNDS 1 /* round to the nearest */\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef __FLOAT_H */\n";
|
@ -0,0 +1,38 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See 5.2.4.2 */
|
||||
static char limits_str[]
|
||||
= "#ifndef __LIMITS_H\n"
|
||||
"#define __LIMITS_H\n"
|
||||
"\n"
|
||||
"#define CHAR_BIT 8\n"
|
||||
"\n"
|
||||
"#define SCHAR_MIN (-SCHAR_MAX - 1)\n"
|
||||
"#define SCHAR_MAX 127\n"
|
||||
"#define UCHAR_MAX (SCHAR_MAX * 2 + 1)\n"
|
||||
"\n"
|
||||
"#define MB_LEN_MAX 1\n"
|
||||
"\n"
|
||||
"#define SHRT_MIN (-SHRT_MAX - 1)\n"
|
||||
"#define SHRT_MAX 32767\n"
|
||||
"#define USHRT_MAX (SHRT_MAX * 2 + 1)\n"
|
||||
"\n"
|
||||
"#define INT_MIN (-INT_MAX - 1)\n"
|
||||
"#define INT_MAX 2147483647\n"
|
||||
"#define UINT_MAX (INT_MAX * 2u + 1u)\n"
|
||||
"\n"
|
||||
"#define LONG_MIN (-LONG_MAX - 1l)\n"
|
||||
"#define LONG_MAX 9223372036854775807l\n"
|
||||
"#define ULONG_MAX (LONG_MAX * 2ul + 1ul)\n"
|
||||
"\n"
|
||||
"#define LLONG_MIN LONG_MIN\n"
|
||||
"#define LLONG_MAX LONG_MAX\n"
|
||||
"#define ULLONG_MAX ULONG_MAX\n"
|
||||
"\n"
|
||||
"/* unsigned char by default */\n"
|
||||
"#define CHAR_MIN 0\n"
|
||||
"#define CHAR_MAX UCHAR_MAX\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef __LIMITS_H */\n";
|
@ -0,0 +1,25 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
static char stdarg_str[]
|
||||
= "#ifndef __STDARG_H\n"
|
||||
"#define __STDARG_H\n"
|
||||
"\n"
|
||||
"typedef struct {\n"
|
||||
" long __gpr, __fpr;\n"
|
||||
" void *__overflow_arg_area;\n"
|
||||
" void *__reg_save_area;\n"
|
||||
"} va_list[1];\n"
|
||||
"\n"
|
||||
"#define va_start(ap, param) __builtin_va_start (ap)\n"
|
||||
"#define va_arg(ap, type) __builtin_va_arg(ap, (type *) 0)\n"
|
||||
"#define va_end(ap) 0\n"
|
||||
"#define va_copy(dest, src) ((dest) = (src))\n"
|
||||
"\n"
|
||||
"/* For standard headers of a GNU system: */\n"
|
||||
"#ifndef __GNUC_VA_LIST\n"
|
||||
"#define __GNUC_VA_LIST 1\n"
|
||||
"#endif\n"
|
||||
"typedef va_list __gnuc_va_list;\n"
|
||||
"#endif /* #ifndef __STDARG_H */\n";
|
@ -0,0 +1,19 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.19 */
|
||||
static char stddef_str[]
|
||||
= "#ifndef __STDDEF_H\n"
|
||||
"#define __STDDEF_H\n"
|
||||
"\n"
|
||||
"typedef long ptrdiff_t;\n"
|
||||
"typedef unsigned long size_t;\n"
|
||||
"typedef long double max_align_t;\n"
|
||||
"typedef unsigned int wchar_t;\n"
|
||||
"\n"
|
||||
"#define NULL ((void *) 0)\n"
|
||||
"\n"
|
||||
"#define offsetof(type, member_designator) ((size_t) & ((type *) 0)->member_designator)\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef __STDDEF_H */\n";
|
@ -0,0 +1,130 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.20 */
|
||||
static char stdint_str[]
|
||||
= "#ifndef _STDINT_H\n"
|
||||
"#define _STDINT_H 1\n"
|
||||
"\n"
|
||||
"#ifndef __int8_t_defined\n"
|
||||
"#define __int8_t_defined\n"
|
||||
"typedef signed char int8_t;\n"
|
||||
"#endif\n"
|
||||
"typedef short int int16_t;\n"
|
||||
"typedef int int32_t;\n"
|
||||
"typedef long int int64_t;\n"
|
||||
"\n"
|
||||
"typedef unsigned char uint8_t;\n"
|
||||
"typedef unsigned short int uint16_t;\n"
|
||||
"typedef unsigned int uint32_t;\n"
|
||||
"typedef unsigned long int uint64_t;\n"
|
||||
"\n"
|
||||
"typedef signed char int_least8_t;\n"
|
||||
"typedef short int int_least16_t;\n"
|
||||
"typedef int int_least32_t;\n"
|
||||
"typedef long int int_least64_t;\n"
|
||||
"\n"
|
||||
"typedef unsigned char uint_least8_t;\n"
|
||||
"typedef unsigned short int uint_least16_t;\n"
|
||||
"typedef unsigned int uint_least32_t;\n"
|
||||
"typedef unsigned long int uint_least64_t;\n"
|
||||
"\n"
|
||||
"typedef signed char int_fast8_t;\n"
|
||||
"typedef long int int_fast16_t;\n"
|
||||
"typedef long int int_fast32_t;\n"
|
||||
"typedef long int int_fast64_t;\n"
|
||||
"\n"
|
||||
"typedef unsigned char uint_fast8_t;\n"
|
||||
"typedef unsigned long int uint_fast16_t;\n"
|
||||
"typedef unsigned long int uint_fast32_t;\n"
|
||||
"typedef unsigned long int uint_fast64_t;\n"
|
||||
"\n"
|
||||
"#define __intptr_t_defined\n"
|
||||
"typedef long int intptr_t;\n"
|
||||
"typedef unsigned long int uintptr_t;\n"
|
||||
"\n"
|
||||
"typedef long int intmax_t;\n"
|
||||
"typedef unsigned long int uintmax_t;\n"
|
||||
"\n"
|
||||
"#define __INT64_C(c) c##L\n"
|
||||
"#define __UINT64_C(c) c##UL\n"
|
||||
"\n"
|
||||
"#define INT8_MIN (-128)\n"
|
||||
"#define INT16_MIN (-32768)\n"
|
||||
"#define INT32_MIN (-2147483648)\n"
|
||||
"#define INT64_MIN (-9223372036854775808l)\n"
|
||||
"\n"
|
||||
"#define INT8_MAX (127)\n"
|
||||
"#define INT16_MAX (32767)\n"
|
||||
"#define INT32_MAX (2147483647)\n"
|
||||
"#define INT64_MAX (9223372036854775807l)\n"
|
||||
"\n"
|
||||
"#define UINT8_MAX (255)\n"
|
||||
"#define UINT16_MAX (65535)\n"
|
||||
"#define UINT32_MAX (4294967295u)\n"
|
||||
"#define UINT64_MAX (18446744073709551615ul)\n"
|
||||
"\n"
|
||||
"#define INT_LEAST8_MIN (-128)\n"
|
||||
"#define INT_LEAST16_MIN (-32768)\n"
|
||||
"#define INT_LEAST32_MIN (-2147483648)\n"
|
||||
"#define INT_LEAST64_MIN (-9223372036854775808L)\n"
|
||||
"\n"
|
||||
"#define INT_LEAST8_MAX (127)\n"
|
||||
"#define INT_LEAST16_MAX (32767)\n"
|
||||
"#define INT_LEAST32_MAX (2147483647)\n"
|
||||
"#define INT_LEAST64_MAX (9223372036854775807L)\n"
|
||||
"\n"
|
||||
"#define UINT_LEAST8_MAX (255)\n"
|
||||
"#define UINT_LEAST16_MAX (65535)\n"
|
||||
"#define UINT_LEAST32_MAX (4294967295U)\n"
|
||||
"#define UINT_LEAST64_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define INT_FAST8_MIN (-128)\n"
|
||||
"#define INT_FAST16_MIN (-9223372036854775808L)\n"
|
||||
"#define INT_FAST32_MIN (-9223372036854775808L)\n"
|
||||
"#define INT_FAST64_MIN (-9223372036854775808L)\n"
|
||||
"\n"
|
||||
"#define INT_FAST8_MAX (127)\n"
|
||||
"#define INT_FAST16_MAX (9223372036854775807L)\n"
|
||||
"#define INT_FAST32_MAX (9223372036854775807L)\n"
|
||||
"#define INT_FAST64_MAX (9223372036854775807L)\n"
|
||||
"\n"
|
||||
"#define UINT_FAST8_MAX (255)\n"
|
||||
"#define UINT_FAST16_MAX (18446744073709551615UL)\n"
|
||||
"#define UINT_FAST32_MAX (18446744073709551615UL)\n"
|
||||
"#define UINT_FAST64_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define INTPTR_MIN (-9223372036854775808L)\n"
|
||||
"#define INTPTR_MAX (9223372036854775807L)\n"
|
||||
"#define UINTPTR_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define INTMAX_MIN (-9223372036854775808L)\n"
|
||||
"#define INTMAX_MAX (9223372036854775807L)\n"
|
||||
"#define UINTMAX_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define PTRDIFF_MIN (-9223372036854775808L)\n"
|
||||
"#define PTRDIFF_MAX (9223372036854775807L)\n"
|
||||
"\n"
|
||||
"#define SIZE_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"/* For signed wchar_t and wint_t: */\n"
|
||||
"#define WCHAR_MIN INT32_MIN\n"
|
||||
"#define WCHAR_MAX INT32_MAX\n"
|
||||
"#define WINT_MIN WCHAR_MIN\n"
|
||||
"#define WINT_MAX WCHAR_MAX\n"
|
||||
"\n"
|
||||
"#define INT8_C(value) value\n"
|
||||
"#define INT16_C(value) value\n"
|
||||
"#define INT32_C(value) value\n"
|
||||
"#define INT64_C(value) value##L\n"
|
||||
"\n"
|
||||
"#define UINT8_C(value) value\n"
|
||||
"#define UINT16_C(value) value\n"
|
||||
"#define UINT32_C(value) value##U\n"
|
||||
"#define UINT64_C(value) value##UL\n"
|
||||
"\n"
|
||||
"#define INTMAX_C(value) value##L\n"
|
||||
"#define UINTMAX_C(value) value##UL\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef _STDINT_H */\n";
|
@ -0,0 +1,401 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2018-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
x86_64 ABI target specific code.
|
||||
*/
|
||||
|
||||
/* See https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf. We use MIR_T_UNDEF for
|
||||
MEMORY. */
|
||||
|
||||
enum add_arg_class { NO_CLASS = MIR_T_BOUND + 1, X87UP_CLASS };
|
||||
|
||||
#ifndef _WIN32
|
||||
#define MAX_QWORDS 2
|
||||
#else
|
||||
#define MAX_QWORDS 1
|
||||
#endif
|
||||
|
||||
static MIR_type_t get_result_type (MIR_type_t arg_type1, MIR_type_t arg_type2) {
|
||||
if (arg_type1 == arg_type2) return arg_type1;
|
||||
if ((enum add_arg_class) arg_type1 == NO_CLASS) return arg_type2;
|
||||
if ((enum add_arg_class) arg_type2 == NO_CLASS) return arg_type1;
|
||||
|
||||
if (arg_type1 == MIR_T_UNDEF || arg_type2 == MIR_T_UNDEF) return MIR_T_UNDEF;
|
||||
|
||||
if (arg_type1 == MIR_T_I64 || arg_type1 == MIR_T_I32 || arg_type2 == MIR_T_I64
|
||||
|| arg_type2 == MIR_T_I32)
|
||||
return MIR_T_I64;
|
||||
|
||||
if (arg_type1 == MIR_T_LD || arg_type2 == MIR_T_LD
|
||||
|| (enum add_arg_class) arg_type1 == X87UP_CLASS
|
||||
|| (enum add_arg_class) arg_type2 == X87UP_CLASS)
|
||||
return MIR_T_UNDEF;
|
||||
|
||||
return MIR_T_D;
|
||||
}
|
||||
|
||||
static int classify_arg (c2m_ctx_t c2m_ctx, struct type *type, MIR_type_t types[MAX_QWORDS],
|
||||
int bit_field_p) {
|
||||
size_t size = type_size (c2m_ctx, type);
|
||||
int i, n_el_qwords, n_qwords = (size + 7) / 8;
|
||||
MIR_type_t mir_type;
|
||||
|
||||
if (type->mode == TM_STRUCT || type->mode == TM_UNION || type->mode == TM_ARR) {
|
||||
MIR_type_t subtypes[MAX_QWORDS];
|
||||
|
||||
if (n_qwords > MAX_QWORDS) return 0; /* too big aggregate */
|
||||
|
||||
#ifndef _WIN32
|
||||
for (i = 0; i < n_qwords; i++) types[i] = (MIR_type_t) NO_CLASS;
|
||||
|
||||
switch (type->mode) {
|
||||
case TM_ARR: { /* Arrays are handled as small records. */
|
||||
n_el_qwords = classify_arg (c2m_ctx, type->u.arr_type->el_type, subtypes, FALSE);
|
||||
if (n_el_qwords == 0) return 0;
|
||||
/* make full types: */
|
||||
for (i = 0; i < n_qwords; i++)
|
||||
types[i] = get_result_type (types[i], subtypes[i % n_el_qwords]);
|
||||
break;
|
||||
}
|
||||
case TM_STRUCT:
|
||||
case TM_UNION:
|
||||
for (node_t el = NL_HEAD (NL_EL (type->u.tag_type->u.ops, 1)->u.ops); el != NULL;
|
||||
el = NL_NEXT (el))
|
||||
if (el->code == N_MEMBER) {
|
||||
decl_t decl = el->attr;
|
||||
int start_qword = decl->offset / 8;
|
||||
|
||||
if (decl->bit_offset >= 0) {
|
||||
types[start_qword] = get_result_type (MIR_T_I64, types[start_qword]);
|
||||
} else {
|
||||
n_el_qwords
|
||||
= classify_arg (c2m_ctx, decl->decl_spec.type, subtypes, decl->bit_offset >= 0);
|
||||
if (n_el_qwords == 0) return 0;
|
||||
for (i = 0; i < n_el_qwords && (i + start_qword) < n_qwords; i++)
|
||||
types[i + start_qword] = get_result_type (subtypes[i], types[i + start_qword]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: assert (FALSE);
|
||||
}
|
||||
|
||||
if (n_qwords > 2) return 0; /* as we don't have vector values (see SSEUP_CLASS) */
|
||||
|
||||
for (i = 0; i < n_qwords; i++) {
|
||||
if (types[i] == MIR_T_UNDEF) return 0; /* pass in memory if a word class is memory. */
|
||||
if ((enum add_arg_class) types[i] == X87UP_CLASS && (i == 0 || types[i - 1] != MIR_T_LD))
|
||||
return 0;
|
||||
}
|
||||
return n_qwords;
|
||||
#else
|
||||
types[0] = MIR_T_I64;
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
assert (scalar_type_p (type));
|
||||
switch (mir_type = get_mir_type (c2m_ctx, type)) {
|
||||
case MIR_T_F:
|
||||
case MIR_T_D: types[0] = MIR_T_D; return 1;
|
||||
case MIR_T_LD:
|
||||
types[0] = MIR_T_LD;
|
||||
types[1] = (MIR_type_t) X87UP_CLASS;
|
||||
return 2;
|
||||
default: types[0] = MIR_T_I64; return 1;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct target_arg_info {
|
||||
int n_iregs, n_fregs;
|
||||
} target_arg_info_t;
|
||||
|
||||
static void target_init_arg_vars (c2m_ctx_t c2m_ctx, target_arg_info_t *arg_info) {
|
||||
arg_info->n_iregs = arg_info->n_fregs = 0;
|
||||
}
|
||||
|
||||
static void update_last_qword_type (c2m_ctx_t c2m_ctx, struct type *type,
|
||||
MIR_type_t qword_types[MAX_QWORDS], int n) {
|
||||
size_t last_size, size = type_size (c2m_ctx, type);
|
||||
MIR_type_t mir_type;
|
||||
|
||||
assert (n != 0);
|
||||
if ((last_size = size % 8) == 0 || n > 1) return;
|
||||
mir_type = qword_types[n - 1];
|
||||
if (last_size <= 4 && mir_type == MIR_T_D) qword_types[n - 1] = MIR_T_F;
|
||||
if (last_size <= 4 && mir_type == MIR_T_I64)
|
||||
qword_types[n - 1] = last_size <= 1 ? MIR_T_I8 : last_size <= 2 ? MIR_T_I16 : MIR_T_I32;
|
||||
}
|
||||
|
||||
static int process_ret_type (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
MIR_type_t qword_types[MAX_QWORDS]) {
|
||||
MIR_type_t type;
|
||||
int n, n_iregs, n_fregs, n_stregs, curr;
|
||||
int n_qwords = classify_arg (c2m_ctx, ret_type, qword_types, FALSE);
|
||||
|
||||
if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) return 0;
|
||||
if (n_qwords != 0) {
|
||||
update_last_qword_type (c2m_ctx, ret_type, qword_types, n_qwords);
|
||||
n_iregs = n_fregs = n_stregs = curr = 0;
|
||||
for (n = 0; n < n_qwords; n++) { /* start from the last qword */
|
||||
type = qword_types[n];
|
||||
qword_types[curr++] = type;
|
||||
switch ((int) type) {
|
||||
case MIR_T_I8:
|
||||
case MIR_T_I16:
|
||||
case MIR_T_I32:
|
||||
case MIR_T_I64: n_iregs++; break;
|
||||
case MIR_T_F:
|
||||
case MIR_T_D: n_fregs++; break;
|
||||
case MIR_T_LD: n_stregs++; break;
|
||||
case X87UP_CLASS:
|
||||
n_qwords--;
|
||||
curr--;
|
||||
break;
|
||||
default: assert (FALSE);
|
||||
}
|
||||
}
|
||||
if (n_iregs > 2 || n_fregs > 2 || n_stregs > 1) n_qwords = 0;
|
||||
}
|
||||
return n_qwords;
|
||||
}
|
||||
|
||||
static int target_return_by_addr_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
|
||||
MIR_type_t qword_types[MAX_QWORDS];
|
||||
int n_qwords;
|
||||
|
||||
if (void_type_p (ret_type)) return FALSE;
|
||||
n_qwords = process_ret_type (c2m_ctx, ret_type, qword_types);
|
||||
return n_qwords == 0 && (ret_type->mode == TM_STRUCT || ret_type->mode == TM_UNION);
|
||||
}
|
||||
|
||||
static void target_add_res_proto (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_type_t) * res_types,
|
||||
VARR (MIR_var_t) * arg_vars) {
|
||||
MIR_var_t var;
|
||||
MIR_type_t type;
|
||||
MIR_type_t qword_types[MAX_QWORDS];
|
||||
int n, n_qwords;
|
||||
|
||||
if (void_type_p (ret_type)) return;
|
||||
n_qwords = process_ret_type (c2m_ctx, ret_type, qword_types);
|
||||
if (n_qwords != 0) {
|
||||
for (n = 0; n < n_qwords; n++)
|
||||
VARR_PUSH (MIR_type_t, res_types, promote_mir_int_type (qword_types[n]));
|
||||
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
|
||||
type = get_mir_type (c2m_ctx, ret_type);
|
||||
VARR_PUSH (MIR_type_t, res_types, type);
|
||||
} else { /* return by reference */
|
||||
var.name = RET_ADDR_NAME;
|
||||
var.type = MIR_T_RBLK;
|
||||
var.size = type_size (c2m_ctx, ret_type);
|
||||
VARR_PUSH (MIR_var_t, arg_vars, var);
|
||||
arg_info->n_iregs++;
|
||||
}
|
||||
}
|
||||
|
||||
static int target_add_call_res_op (c2m_ctx_t c2m_ctx, struct type *ret_type,
|
||||
target_arg_info_t *arg_info, size_t call_arg_area_offset) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_type_t type;
|
||||
MIR_type_t qword_types[MAX_QWORDS];
|
||||
op_t temp;
|
||||
int i, n_qwords;
|
||||
|
||||
if (void_type_p (ret_type)) return -1;
|
||||
n_qwords = process_ret_type (c2m_ctx, ret_type, qword_types);
|
||||
if (n_qwords != 0) {
|
||||
for (i = 0; i < n_qwords; i++) {
|
||||
temp = get_new_temp (c2m_ctx, promote_mir_int_type (qword_types[i]));
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
}
|
||||
return n_qwords;
|
||||
} else if (ret_type->mode == TM_STRUCT || ret_type->mode == TM_UNION) { /* return by reference */
|
||||
arg_info->n_iregs++;
|
||||
temp = get_new_temp (c2m_ctx, MIR_T_I64);
|
||||
emit3 (c2m_ctx, MIR_ADD, temp.mir_op,
|
||||
MIR_new_reg_op (ctx, MIR_reg (ctx, FP_NAME, curr_func->u.func)),
|
||||
MIR_new_int_op (ctx, call_arg_area_offset));
|
||||
temp.mir_op
|
||||
= MIR_new_mem_op (ctx, MIR_T_RBLK, type_size (c2m_ctx, ret_type), temp.mir_op.u.reg, 0, 1);
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
return 0;
|
||||
} else {
|
||||
type = get_mir_type (c2m_ctx, ret_type);
|
||||
type = promote_mir_int_type (type);
|
||||
temp = get_new_temp (c2m_ctx, type);
|
||||
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static op_t target_gen_post_call_res_code (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res,
|
||||
MIR_insn_t call, size_t call_ops_start) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_type_t type;
|
||||
MIR_insn_t insn;
|
||||
MIR_type_t qword_types[MAX_QWORDS];
|
||||
int i, n_qwords;
|
||||
|
||||
if (void_type_p (ret_type)) return res;
|
||||
n_qwords = process_ret_type (c2m_ctx, ret_type, qword_types);
|
||||
if (n_qwords != 0) {
|
||||
assert (res.mir_op.mode == MIR_OP_MEM);
|
||||
for (i = 0; i < n_qwords; i++) {
|
||||
type = qword_types[i];
|
||||
insn = MIR_new_insn (ctx, tp_mov (type),
|
||||
MIR_new_mem_op (ctx, type, res.mir_op.u.mem.disp + 8 * i,
|
||||
res.mir_op.u.mem.base, res.mir_op.u.mem.index,
|
||||
res.mir_op.u.mem.scale),
|
||||
VARR_GET (MIR_op_t, call_ops, i + call_ops_start + 2));
|
||||
MIR_append_insn (ctx, curr_func, insn);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void target_add_ret_ops (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_type_t type;
|
||||
MIR_type_t qword_types[MAX_QWORDS];
|
||||
MIR_insn_t insn;
|
||||
MIR_reg_t ret_addr_reg;
|
||||
op_t temp, var;
|
||||
int i, size, n_qwords;
|
||||
|
||||
if (void_type_p (ret_type)) return;
|
||||
n_qwords = process_ret_type (c2m_ctx, ret_type, qword_types);
|
||||
if (n_qwords != 0) {
|
||||
for (i = 0; i < n_qwords; i++) {
|
||||
type = qword_types[i];
|
||||
temp = get_new_temp (c2m_ctx, promote_mir_int_type (type));
|
||||
insn = MIR_new_insn (ctx, tp_mov (type), temp.mir_op,
|
||||
MIR_new_mem_op (ctx, type, res.mir_op.u.mem.disp + 8 * i,
|
||||
res.mir_op.u.mem.base, res.mir_op.u.mem.index,
|
||||
res.mir_op.u.mem.scale));
|
||||
MIR_append_insn (ctx, curr_func, insn);
|
||||
VARR_PUSH (MIR_op_t, ret_ops, temp.mir_op);
|
||||
}
|
||||
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
|
||||
VARR_PUSH (MIR_op_t, ret_ops, res.mir_op);
|
||||
} else {
|
||||
ret_addr_reg = MIR_reg (ctx, RET_ADDR_NAME, curr_func->u.func);
|
||||
var = new_op (NULL, MIR_new_mem_op (ctx, MIR_T_I8, 0, ret_addr_reg, 0, 1));
|
||||
size = type_size (c2m_ctx, ret_type);
|
||||
block_move (c2m_ctx, var, res, size);
|
||||
}
|
||||
}
|
||||
|
||||
static int process_aggregate_arg (c2m_ctx_t c2m_ctx, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, MIR_type_t qword_types[MAX_QWORDS]) {
|
||||
MIR_type_t type;
|
||||
int n, n_iregs, n_fregs, n_qwords = classify_arg (c2m_ctx, arg_type, qword_types, FALSE);
|
||||
|
||||
if (n_qwords == 0) return 0;
|
||||
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION) return 0;
|
||||
update_last_qword_type (c2m_ctx, arg_type, qword_types, n_qwords);
|
||||
n_iregs = n_fregs = 0;
|
||||
for (n = 0; n < n_qwords; n++) { /* start from the last qword */
|
||||
switch ((int) (type = qword_types[n])) {
|
||||
case MIR_T_I8:
|
||||
case MIR_T_I16:
|
||||
case MIR_T_I32:
|
||||
case MIR_T_I64: n_iregs++; break;
|
||||
case MIR_T_F:
|
||||
case MIR_T_D: n_fregs++; break;
|
||||
case X87UP_CLASS:
|
||||
case MIR_T_LD: return 0;
|
||||
default: assert (FALSE);
|
||||
}
|
||||
}
|
||||
if (arg_info->n_iregs + n_iregs > 6 || arg_info->n_fregs + n_fregs > 8) return 0;
|
||||
/* aggregate passed by value: update arg_info */
|
||||
arg_info->n_iregs += n_iregs;
|
||||
arg_info->n_fregs += n_fregs;
|
||||
return n_qwords;
|
||||
}
|
||||
|
||||
static MIR_type_t get_blk_type (int n_qwords, MIR_type_t *qword_types) {
|
||||
int n, n_iregs = 0, n_fregs = 0;
|
||||
|
||||
assert (n_qwords <= 2);
|
||||
if (n_qwords == 0) return MIR_T_BLK;
|
||||
for (n = 0; n < n_qwords; n++) { /* start from the last qword */
|
||||
switch ((int) qword_types[n]) {
|
||||
case MIR_T_I8:
|
||||
case MIR_T_I16:
|
||||
case MIR_T_I32:
|
||||
case MIR_T_I64: n_iregs++; break;
|
||||
case MIR_T_F:
|
||||
case MIR_T_D: n_fregs++; break;
|
||||
case X87UP_CLASS:
|
||||
case MIR_T_LD: return MIR_T_BLK;
|
||||
default: assert (FALSE);
|
||||
}
|
||||
}
|
||||
if (n_iregs == n_qwords) return MIR_T_BLK + 1;
|
||||
if (n_fregs == n_qwords) return MIR_T_BLK + 2;
|
||||
if (qword_types[0] == MIR_T_F || qword_types[0] == MIR_T_D) return MIR_T_BLK + 4;
|
||||
return MIR_T_BLK + 3;
|
||||
}
|
||||
|
||||
static MIR_type_t target_get_blk_type (c2m_ctx_t c2m_ctx, struct type *arg_type) {
|
||||
MIR_type_t qword_types[MAX_QWORDS];
|
||||
int n_qwords = classify_arg (c2m_ctx, arg_type, qword_types, FALSE);
|
||||
assert (arg_type->mode == TM_STRUCT || arg_type->mode == TM_UNION);
|
||||
return get_blk_type (n_qwords, qword_types);
|
||||
}
|
||||
|
||||
static void target_add_arg_proto (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, VARR (MIR_var_t) * arg_vars) {
|
||||
MIR_var_t var;
|
||||
MIR_type_t type;
|
||||
MIR_type_t qword_types[MAX_QWORDS];
|
||||
int n_qwords = process_aggregate_arg (c2m_ctx, arg_type, arg_info, qword_types);
|
||||
|
||||
/* pass aggregates on the stack and pass by value for others: */
|
||||
var.name = name;
|
||||
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION) {
|
||||
type = get_mir_type (c2m_ctx, arg_type);
|
||||
var.type = type;
|
||||
if (type == MIR_T_F || type == MIR_T_D)
|
||||
arg_info->n_fregs++;
|
||||
else if (type != MIR_T_LD)
|
||||
arg_info->n_iregs++;
|
||||
} else {
|
||||
var.type = get_blk_type (n_qwords, qword_types);
|
||||
var.size = type_size (c2m_ctx, arg_type);
|
||||
}
|
||||
VARR_PUSH (MIR_var_t, arg_vars, var);
|
||||
}
|
||||
|
||||
static void target_add_call_arg_op (c2m_ctx_t c2m_ctx, struct type *arg_type,
|
||||
target_arg_info_t *arg_info, op_t arg) {
|
||||
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
|
||||
MIR_context_t ctx = c2m_ctx->ctx;
|
||||
MIR_type_t type;
|
||||
MIR_type_t qword_types[MAX_QWORDS];
|
||||
int n_qwords = process_aggregate_arg (c2m_ctx, arg_type, arg_info, qword_types);
|
||||
|
||||
/* pass aggregates on the stack and pass by value for others: */
|
||||
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION) {
|
||||
type = get_mir_type (c2m_ctx, arg_type);
|
||||
VARR_PUSH (MIR_op_t, call_ops, arg.mir_op);
|
||||
if (type == MIR_T_F || type == MIR_T_D)
|
||||
arg_info->n_fregs++;
|
||||
else if (type != MIR_T_LD)
|
||||
arg_info->n_iregs++;
|
||||
} else {
|
||||
assert (arg.mir_op.mode == MIR_OP_MEM);
|
||||
arg = mem_to_address (c2m_ctx, arg, TRUE);
|
||||
type = get_blk_type (n_qwords, qword_types);
|
||||
VARR_PUSH (MIR_op_t, call_ops,
|
||||
MIR_new_mem_op (ctx, type, type_size (c2m_ctx, arg_type), arg.mir_op.u.reg, 0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
static int target_gen_gather_arg (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
|
||||
decl_t param_decl, target_arg_info_t *arg_info) {
|
||||
return FALSE;
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2019-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 5.2.4.2.2 */
|
||||
static char float_str[]
|
||||
= "#ifndef __FLOAT_H\n"
|
||||
"#define __FLOAT_H\n"
|
||||
"\n"
|
||||
"#define FLT_RADIX 2\n"
|
||||
"\n"
|
||||
"#define FLT_MANT_DIG 24\n"
|
||||
"#define DBL_MANT_DIG 53\n"
|
||||
"#define LDBL_MANT_DIG DBL_MANT_DIG\n"
|
||||
"\n"
|
||||
"#define FLT_DECIMAL_DIG 9\n"
|
||||
"#define DBL_DECIMAL_DIG 17\n"
|
||||
"#define LDBL_DECIMAL_DIG DBL_DECIMAL_DIG\n"
|
||||
"#define FLT_DIG FLT_DECIMAL_DIG\n"
|
||||
"#define DBL_DIG DBL_DECIMAL_DIG\n"
|
||||
"#define LDBL_DIG LDBL_DECIMAL_DIG\n"
|
||||
"\n"
|
||||
"#define DECIMAL_DIG LDBL_DECIMAL_DIG\n"
|
||||
"\n"
|
||||
"#define FLT_MIN_EXP -125\n"
|
||||
"#define DBL_MIN_EXP -1021\n"
|
||||
"#define LDBL_MIN_EXP DBL_MIN_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MIN_10_EXP -37\n"
|
||||
"#define DBL_MIN_10_EXP -307\n"
|
||||
"#define LDBL_MIN_10_EXP DBL_MIN_10_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MAX_EXP 128\n"
|
||||
"#define DBL_MAX_EXP 1024\n"
|
||||
"#define LDBL_MAX_EXP DBL_MAX_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MAX_10_EXP 38\n"
|
||||
"#define DBL_MAX_10_EXP 308\n"
|
||||
"#define LDBL_MAX_10_EXP DBL_MAX_10_EXP\n"
|
||||
"\n"
|
||||
"#define FLT_MAX 0x1.fffffep+127\n"
|
||||
"#define DBL_MAX 0x1.fffffffffffffp+1023\n"
|
||||
"#define LDBL_MAX DBL_MAX\n"
|
||||
"\n"
|
||||
"#define FLT_EPSILON 0x1p-23\n"
|
||||
"#define DBL_EPSILON 0x1p-52\n"
|
||||
"#define LDBL_EPSILON DBL_EPSILON\n"
|
||||
"\n"
|
||||
"#define FLT_MIN 0x1p-126\n"
|
||||
"#define DBL_MIN 0x1p-1022\n"
|
||||
"#define LDBL_MIN DBL_MIN\n"
|
||||
"\n"
|
||||
"#define FLT_TRUE_MIN 0x1p-149\n"
|
||||
"#define DBL_TRUE_MIN 0x0.0000000000001p-1022\n"
|
||||
"#define LDBL_TRUE_MIN DBL_TRUE_MIN\n"
|
||||
"\n"
|
||||
"#define FLT_EVAL_METHOD 0\n"
|
||||
"#define FLT_ROUNDS 1 /* round to the nearest */\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef __FLOAT_H */\n";
|
@ -0,0 +1,48 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2019-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See 5.2.4.2 */
|
||||
static char limits_str[]
|
||||
= "#ifndef __LIMITS_H\n"
|
||||
"#define __LIMITS_H\n"
|
||||
"\n"
|
||||
"#define CHAR_BIT 8\n"
|
||||
"\n"
|
||||
"#define SCHAR_MIN (-SCHAR_MAX - 1)\n"
|
||||
"#define SCHAR_MAX 127\n"
|
||||
"#define UCHAR_MAX (SCHAR_MAX * 2 + 1)\n"
|
||||
"\n"
|
||||
"#define MB_LEN_MAX 1\n"
|
||||
"\n"
|
||||
"#define SHRT_MIN (-SHRT_MAX - 1)\n"
|
||||
"#define SHRT_MAX 32767\n"
|
||||
"#define USHRT_MAX (SHRT_MAX * 2 + 1)\n"
|
||||
"\n"
|
||||
"#define INT_MIN (-INT_MAX - 1)\n"
|
||||
"#define INT_MAX 2147483647\n"
|
||||
"#define UINT_MAX (INT_MAX * 2u + 1u)\n"
|
||||
"\n"
|
||||
#if defined(_WIN32)
|
||||
"#define LONG_MIN (-LONG_MAX - 1l)\n"
|
||||
"#define LONG_MAX 2147483647l\n"
|
||||
"#define ULONG_MAX (LONG_MAX * 2ul + 1ul)\n"
|
||||
"\n"
|
||||
"#define LLONG_MIN (-LLONG_MAX - 1ll)\n"
|
||||
"#define LLONG_MAX 9223372036854775807ll\n"
|
||||
"#define ULLONG_MAX (LLONG_MAX * 2ull + 1ull)\n"
|
||||
#else
|
||||
"#define LONG_MIN (-LONG_MAX - 1l)\n"
|
||||
"#define LONG_MAX 9223372036854775807l\n"
|
||||
"#define ULONG_MAX (LONG_MAX * 2ul + 1ul)\n"
|
||||
"\n"
|
||||
"#define LLONG_MIN (-LLONG_MAX - 1ll)\n"
|
||||
"#define LLONG_MAX 9223372036854775807ll\n"
|
||||
"#define ULLONG_MAX (LLONG_MAX * 2ull + 1ull)\n"
|
||||
#endif
|
||||
"\n"
|
||||
"/* signed char by default */\n"
|
||||
"#define CHAR_MIN SCHAR_MIN\n"
|
||||
"#define CHAR_MAX SCHAR_MAX\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef __LIMITS_H */\n";
|
@ -0,0 +1,41 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2019-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.16 and https://www.uclibc.org/docs/psABI-x86_64.pdf */
|
||||
static char stdarg_str[]
|
||||
= "#ifndef __STDARG_H\n"
|
||||
"#define __STDARG_H\n"
|
||||
"\n"
|
||||
#if defined(__APPLE__)
|
||||
"typedef __darwin_va_list va_list;\n"
|
||||
#elif defined(__WIN32)
|
||||
"typedef char *va_list;\n"
|
||||
#else
|
||||
"typedef struct {\n"
|
||||
" unsigned int gp_offset;\n"
|
||||
" unsigned int fp_offset;\n"
|
||||
" void *overflow_arg_area;\n"
|
||||
" void *reg_save_area;\n"
|
||||
"} va_list[1];\n"
|
||||
#endif
|
||||
"\n"
|
||||
#if defined(__WIN32)
|
||||
"#define va_start(ap, param) __va_start (ap, param)\n"
|
||||
#else
|
||||
"#define va_start(ap, param) __builtin_va_start (ap)\n"
|
||||
#endif
|
||||
"#define va_arg(ap, type) __builtin_va_arg(ap, (type *) 0)\n"
|
||||
"#define va_end(ap) 0\n"
|
||||
#if defined(__APPLE__) || defined(__WIN32)
|
||||
"#define va_copy(dest, src) ((dest) = (src))\n"
|
||||
#else
|
||||
"#define va_copy(dest, src) ((dest)[0] = (src)[0])\n"
|
||||
#endif
|
||||
"\n"
|
||||
"/* For standard headers of a GNU system: */\n"
|
||||
"#ifndef __GNUC_VA_LIST\n"
|
||||
"#define __GNUC_VA_LIST 1\n"
|
||||
"#endif\n"
|
||||
"typedef va_list __gnuc_va_list;\n"
|
||||
"#endif /* #ifndef __STDARG_H */\n";
|
@ -0,0 +1,32 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2019-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.19 */
|
||||
static char stddef_str[]
|
||||
= "#ifndef __STDDEF_H\n"
|
||||
"#define __STDDEF_H\n"
|
||||
"\n"
|
||||
#ifdef _WIN32
|
||||
"typedef long long int ptrdiff_t;\n"
|
||||
"typedef unsigned long long size_t;\n"
|
||||
#else
|
||||
"typedef long ptrdiff_t;\n"
|
||||
"typedef unsigned long size_t;\n"
|
||||
#endif
|
||||
"typedef long double max_align_t;\n"
|
||||
#if defined(__APPLE__)
|
||||
"typedef int wchar_t;\n"
|
||||
#elif defined(_WIN32)
|
||||
"typedef unsigned short wchar_t;\n"
|
||||
#else
|
||||
"typedef unsigned int wchar_t;\n"
|
||||
#endif
|
||||
"\n"
|
||||
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||
"#define NULL ((void *) 0)\n"
|
||||
#endif
|
||||
"\n"
|
||||
"#define offsetof(type, member_designator) ((size_t) & ((type *) 0)->member_designator)\n"
|
||||
"\n"
|
||||
"#endif /* #ifndef __STDDEF_H */\n";
|
@ -0,0 +1,175 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2019-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* See C11 7.20 */
|
||||
static char stdint_str[]
|
||||
= "#ifndef _STDINT_H\n"
|
||||
"#define _STDINT_H 1\n"
|
||||
"\n"
|
||||
"typedef signed char int8_t;\n"
|
||||
"typedef short int int16_t;\n"
|
||||
"typedef int int32_t;\n"
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
"typedef long long int int64_t;\n"
|
||||
#else
|
||||
"typedef long int int64_t;\n"
|
||||
#endif
|
||||
"\n"
|
||||
"typedef unsigned char uint8_t;\n"
|
||||
"typedef unsigned short int uint16_t;\n"
|
||||
"typedef unsigned int uint32_t;\n"
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
"typedef unsigned long long int uint64_t;\n"
|
||||
#else
|
||||
"typedef unsigned long int uint64_t;\n"
|
||||
#endif
|
||||
"\n"
|
||||
"typedef signed char int_least8_t;\n"
|
||||
"typedef short int int_least16_t;\n"
|
||||
"typedef int int_least32_t;\n"
|
||||
#if defined(_WIN32)
|
||||
"typedef long long int int_least64_t;\n"
|
||||
#else
|
||||
"typedef long int int_least64_t;\n"
|
||||
#endif
|
||||
"\n"
|
||||
"typedef unsigned char uint_least8_t;\n"
|
||||
"typedef unsigned short int uint_least16_t;\n"
|
||||
"typedef unsigned int uint_least32_t;\n"
|
||||
#if defined(_WIN32)
|
||||
"typedef unsigned long long int uint_least64_t;\n"
|
||||
#else
|
||||
"typedef unsigned long int uint_least64_t;\n"
|
||||
#endif
|
||||
"\n"
|
||||
"typedef signed char int_fast8_t;\n"
|
||||
"typedef long int int_fast16_t;\n"
|
||||
"typedef long int int_fast32_t;\n"
|
||||
#if defined(_WIN32)
|
||||
"typedef long long int int_fast64_t;\n"
|
||||
#else
|
||||
"typedef long int int_fast64_t;\n"
|
||||
#endif
|
||||
"\n"
|
||||
"typedef unsigned char uint_fast8_t;\n"
|
||||
"typedef unsigned long int uint_fast16_t;\n"
|
||||
"typedef unsigned long int uint_fast32_t;\n"
|
||||
#if defined(_WIN32)
|
||||
"typedef unsigned long long int uint_fast64_t;\n"
|
||||
#else
|
||||
"typedef unsigned long int uint_fast64_t;\n"
|
||||
#endif
|
||||
"\n"
|
||||
"#define __intptr_t_defined\n"
|
||||
#if defined(_WIN32)
|
||||
"typedef long long int intptr_t;\n"
|
||||
"typedef unsigned long long int uintptr_t;\n"
|
||||
"\n"
|
||||
"typedef long long int intmax_t;\n"
|
||||
"typedef unsigned long long int uintmax_t;\n"
|
||||
"\n"
|
||||
"#define __INT64_C(c) c##LL\n"
|
||||
"#define __UINT64_C(c) c##ULL\n"
|
||||
#else
|
||||
"typedef long int intptr_t;\n"
|
||||
"typedef unsigned long int uintptr_t;\n"
|
||||
"\n"
|
||||
"typedef long int intmax_t;\n"
|
||||
"typedef unsigned long int uintmax_t;\n"
|
||||
"\n"
|
||||
"#define __INT64_C(c) c##L\n"
|
||||
"#define __UINT64_C(c) c##UL\n"
|
||||
#endif
|
||||
"\n"
|
||||
"#define INT8_MIN (-128)\n"
|
||||
"#define INT16_MIN (-32768)\n"
|
||||
"#define INT32_MIN (-2147483648)\n"
|
||||
"#define INT64_MIN (-9223372036854775808l)\n"
|
||||
"\n"
|
||||
"#define INT8_MAX (127)\n"
|
||||
"#define INT16_MAX (32767)\n"
|
||||
"#define INT32_MAX (2147483647)\n"
|
||||
"#define INT64_MAX (9223372036854775807l)\n"
|
||||
"\n"
|
||||
"#define UINT8_MAX (255)\n"
|
||||
"#define UINT16_MAX (65535)\n"
|
||||
"#define UINT32_MAX (4294967295u)\n"
|
||||
"#define UINT64_MAX (18446744073709551615ul)\n"
|
||||
"\n"
|
||||
"#define INT_LEAST8_MIN (-128)\n"
|
||||
"#define INT_LEAST16_MIN (-32768)\n"
|
||||
"#define INT_LEAST32_MIN (-2147483648)\n"
|
||||
"#define INT_LEAST64_MIN (-9223372036854775808L)\n"
|
||||
"\n"
|
||||
"#define INT_LEAST8_MAX (127)\n"
|
||||
"#define INT_LEAST16_MAX (32767)\n"
|
||||
"#define INT_LEAST32_MAX (2147483647)\n"
|
||||
"#define INT_LEAST64_MAX (9223372036854775807L)\n"
|
||||
"\n"
|
||||
"#define UINT_LEAST8_MAX (255)\n"
|
||||
"#define UINT_LEAST16_MAX (65535)\n"
|
||||
"#define UINT_LEAST32_MAX (4294967295U)\n"
|
||||
"#define UINT_LEAST64_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define INT_FAST8_MIN (-128)\n"
|
||||
"#define INT_FAST16_MIN (-9223372036854775808L)\n"
|
||||
"#define INT_FAST32_MIN (-9223372036854775808L)\n"
|
||||
"#define INT_FAST64_MIN (-9223372036854775808L)\n"
|
||||
"\n"
|
||||
"#define INT_FAST8_MAX (127)\n"
|
||||
"#define INT_FAST16_MAX (9223372036854775807L)\n"
|
||||
"#define INT_FAST32_MAX (9223372036854775807L)\n"
|
||||
"#define INT_FAST64_MAX (9223372036854775807L)\n"
|
||||
"\n"
|
||||
"#define UINT_FAST8_MAX (255)\n"
|
||||
"#define UINT_FAST16_MAX (18446744073709551615UL)\n"
|
||||
"#define UINT_FAST32_MAX (18446744073709551615UL)\n"
|
||||
"#define UINT_FAST64_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define INTPTR_MIN (-9223372036854775808L)\n"
|
||||
"#define INTPTR_MAX (9223372036854775807L)\n"
|
||||
"#define UINTPTR_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define INTMAX_MIN (-9223372036854775808L)\n"
|
||||
"#define INTMAX_MAX (9223372036854775807L)\n"
|
||||
"#define UINTMAX_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"#define PTRDIFF_MIN (-9223372036854775808L)\n"
|
||||
"#define PTRDIFF_MAX (9223372036854775807L)\n"
|
||||
"\n"
|
||||
"#define SIZE_MAX (18446744073709551615UL)\n"
|
||||
"\n"
|
||||
"/* For signed wchar_t and wint_t: */\n"
|
||||
"#define WCHAR_MIN INT32_MIN\n"
|
||||
"#define WCHAR_MAX INT32_MAX\n"
|
||||
"#define WINT_MIN WCHAR_MIN\n"
|
||||
"#define WINT_MAX WCHAR_MAX\n"
|
||||
"\n"
|
||||
"#define INT8_C(value) value\n"
|
||||
"#define INT16_C(value) value\n"
|
||||
"#define INT32_C(value) value\n"
|
||||
#if defined(_WIN32)
|
||||
"#define INT64_C(value) value##LL\n"
|
||||
#else
|
||||
"#define INT64_C(value) value##L\n"
|
||||
#endif
|
||||
"\n"
|
||||
"#define UINT8_C(value) value\n"
|
||||
"#define UINT16_C(value) value\n"
|
||||
"#define UINT32_C(value) value##U\n"
|
||||
#if defined(_WIN32)
|
||||
"#define UINT64_C(value) value##ULL\n"
|
||||
#else
|
||||
"#define UINT64_C(value) value##UL\n"
|
||||
#endif
|
||||
"\n"
|
||||
#if defined(_WIN32)
|
||||
"#define INTMAX_C(value) value##L\n"
|
||||
"#define UINTMAX_C(value) value##UL\n"
|
||||
#else
|
||||
"#define INTMAX_C(value) value##LL\n"
|
||||
"#define UINTMAX_C(value) value##ULL\n"
|
||||
#endif
|
||||
"\n"
|
||||
"#endif /* #ifndef _STDINT_H */\n";
|
@ -0,0 +1,116 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2019-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
static char x86_64_mirc[]
|
||||
= "#define __amd64 1\n"
|
||||
"#define __amd64__ 1\n"
|
||||
"#define __x86_64 1\n"
|
||||
"#define __x86_64__ 1\n"
|
||||
"#define _M_AMD64 1\n"
|
||||
"#define _M_X64 1\n"
|
||||
"\n"
|
||||
"#define __SIZEOF_DOUBLE__ 8\n"
|
||||
"#define __SIZEOF_FLOAT__ 4\n"
|
||||
"#define __SIZEOF_INT__ 4\n"
|
||||
#if !defined(_WIN32) && __SIZEOF_LONG_DOUBLE__ == 16
|
||||
"#define __SIZEOF_LONG_DOUBLE__ 16\n"
|
||||
#else
|
||||
"#define __SIZEOF_LONG_DOUBLE__ 8\n"
|
||||
#endif
|
||||
"#define __SIZEOF_LONG_LONG__ 8\n"
|
||||
"#define __SIZEOF_LONG__ 4\n"
|
||||
"#define __SIZEOF_POINTER__ 8\n"
|
||||
"#define __SIZEOF_PTRDIFF_T__ 8\n"
|
||||
"#define __SIZEOF_SHORT__ 2\n"
|
||||
"#define __SIZEOF_SIZE_T__ 8\n"
|
||||
"\n"
|
||||
"#define __BYTE_ORDER__ 1234\n"
|
||||
"#define __ORDER_LITTLE_ENDIAN__ 1234\n"
|
||||
"#define __ORDER_BIG_ENDIAN__ 4321\n"
|
||||
"\n"
|
||||
"/* Some type macros: */\n"
|
||||
"#define __SIZE_TYPE__ long long unsigned int\n"
|
||||
"#define __PTRDIFF_TYPE__ long long int\n"
|
||||
"#define __INTMAX_TYPE__ long long int\n"
|
||||
"#define __UINTMAX_TYPE__ long long unsigned int\n"
|
||||
"#define __INT8_TYPE__ signed char\n"
|
||||
"#define __INT16_TYPE__ short\n"
|
||||
"#define __INT32_TYPE__ int\n"
|
||||
"#define __INT64_TYPE__ long long int\n"
|
||||
"#define __UINT8_TYPE__ unsigned char\n"
|
||||
"#define __UINT16_TYPE__ unsigned short\n"
|
||||
"#define __UINT32_TYPE__ unsigned int\n"
|
||||
"#define __UINT64_TYPE__ long long unsigned int\n"
|
||||
"#define __INTPTR_TYPE__ long long int\n"
|
||||
"#define __UINTPTR_TYPE__ long long unsigned int\n"
|
||||
"\n"
|
||||
"#define __int8 __INT8_TYPE__\n"
|
||||
"#define __int16 __INT16_TYPE__\n"
|
||||
"#define __int32 __INT32_TYPE__\n"
|
||||
"#define __int64 __INT64_TYPE__\n"
|
||||
"\n"
|
||||
"#define __ptr32\n"
|
||||
"#define __ptr64\n"
|
||||
"#define __forceinline inline\n"
|
||||
"#define __cdecl\n"
|
||||
"#define __pragma(p)\n"
|
||||
"#define __declspec(attr)\n"
|
||||
"#define __unaligned\n"
|
||||
"\n"
|
||||
"#define __CHAR_BIT__ 8\n"
|
||||
"#define __INT8_MAX__ 127\n"
|
||||
"#define __INT16_MAX__ 32767\n"
|
||||
"#define __INT32_MAX__ 2147483647\n"
|
||||
"#define __INT64_MAX__ 9223372036854775807LL\n"
|
||||
"#define __UINT8_MAX__ (__INT8_MAX__ * 2u + 1u)\n"
|
||||
"#define __UINT16_MAX__ (__INT16_MAX__ * 2u + 1u)\n"
|
||||
"#define __UINT32_MAX__ (__INT32_MAX__ * 2u + 1u)\n"
|
||||
"#define __UINT64_MAX__ (__INT64_MAX__ * 2u + 1u)\n"
|
||||
"#define __SCHAR_MAX__ __INT8_MAX__\n"
|
||||
"#define __SHRT_MAX__ __INT16_MAX__\n"
|
||||
"#define __INT_MAX__ __INT32_MAX__\n"
|
||||
"#define __LONG_MAX__ __INT32_MAX__\n"
|
||||
"#define __LONG_LONG_MAX__ __INT64_MAX__\n"
|
||||
"#define __SIZE_MAX__ __UINT64_MAX__\n"
|
||||
"#define __PTRDIFF_MAX__ __INT64_MAX__\n"
|
||||
"#define __INTMAX_MAX__ __INT64_MAX__\n"
|
||||
"#define __UINTMAX_MAX__ __UINT64_MAX__\n"
|
||||
"#define __INTPTR_MAX__ __INT64_MAX__\n"
|
||||
"#define __UINTPTR_MAX__ __UINT64_MAX__\n"
|
||||
"\n"
|
||||
"#define __FLT_MIN_EXP__ (-125)\n"
|
||||
"#define __FLT_MAX_EXP__ 128\n"
|
||||
"#define __FLT_DIG__ 6\n"
|
||||
"#define __FLT_DECIMAL_DIG__ 9\n"
|
||||
"#define __FLT_MANT_DIG__ 24\n"
|
||||
"#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F\n"
|
||||
"#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F\n"
|
||||
"#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F\n"
|
||||
"\n"
|
||||
"#define __DBL_MIN_EXP__ (-1021)\n"
|
||||
"#define __DBL_MAX_EXP__ 1024\n"
|
||||
"#define __DBL_DIG__ 15\n"
|
||||
"#define __DBL_DECIMAL_DIG__ 17\n"
|
||||
"#define __DBL_MANT_DIG__ 53\n"
|
||||
"#define __DBL_MAX__ ((double) 1.79769313486231570814527423731704357e+308L)\n"
|
||||
"#define __DBL_MIN__ ((double) 2.22507385850720138309023271733240406e-308L)\n"
|
||||
"#define __DBL_EPSILON__ ((double) 2.22044604925031308084726333618164062e-16L)\n"
|
||||
"\n"
|
||||
"typedef unsigned short char16_t;\n"
|
||||
"typedef unsigned int char32_t;\n"
|
||||
"\n"
|
||||
"#define WIN32 1\n"
|
||||
"#define _WIN32 1\n"
|
||||
"#define __WIN32 1\n"
|
||||
"#define __WIN32__ 1\n"
|
||||
"#define WIN64 1\n"
|
||||
"#define _WIN64 1\n"
|
||||
"#define __WIN64 1\n"
|
||||
"#define __WIN64__ 1\n"
|
||||
"#define WINNT 1\n"
|
||||
"#define __WINNT 1\n"
|
||||
"#define __WINNT__ 1\n"
|
||||
"#define __MSVCRT__ 1\n"
|
||||
"\n"
|
||||
"void *alloca (long long unsigned);\n";
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,461 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2018-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
/* Long doubles (-mlong-double=128) are always passed by its address (for args and results) */
|
||||
|
||||
/* All BLK type values and RBLK args are always passed by address. */
|
||||
|
||||
#if 0 && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#error "s390x works only in BE mode"
|
||||
#endif
|
||||
|
||||
#define VA_LIST_IS_ARRAY_P 1 /* one element array of struct s390x_va_list */
|
||||
|
||||
#define S390X_STACK_HEADER_SIZE 160
|
||||
|
||||
static uint8_t *push_insns (VARR (uint8_t) * insn_varr, const uint8_t *pat, size_t pat_len) {
|
||||
for (size_t i = 0; i < pat_len; i++) VARR_PUSH (uint8_t, insn_varr, pat[i]);
|
||||
return VARR_ADDR (uint8_t, insn_varr) + VARR_LENGTH (uint8_t, insn_varr) - pat_len;
|
||||
}
|
||||
|
||||
static void s390x_gen_mov (VARR (uint8_t) * insn_varr, unsigned to, unsigned from) {
|
||||
uint32_t lgr = (0xb904 << 16) | (to << 4) | from; /* lgr to,from: */
|
||||
assert (to < 16 && from < 16);
|
||||
push_insns (insn_varr, (uint8_t *) &lgr, 4);
|
||||
}
|
||||
|
||||
static void s390x_gen_mvi (VARR (uint8_t) * insn_varr, int val, unsigned base, int disp) {
|
||||
uint64_t mvghi /* mvghi disp(base), val: */
|
||||
= ((0xe548l << 32) | ((uint64_t) base << 28) | ((disp & 0xfff) << 16) | (val & 0xffff)) << 16;
|
||||
assert (base < 16 && 0 <= disp && disp < (1 << 12) && -(1 << 15) < val && val < (1 << 15));
|
||||
push_insns (insn_varr, (uint8_t *) &mvghi, 6);
|
||||
}
|
||||
|
||||
static void s390x_gen_ld_st (VARR (uint8_t) * insn_varr, unsigned reg, unsigned base, int disp,
|
||||
MIR_type_t type, int ld_p) {
|
||||
int single_p = type == MIR_T_F;
|
||||
int double_p = type == MIR_T_D;
|
||||
uint64_t dl = disp & 0xfff, dh = (disp >> 12) & 0xff;
|
||||
uint64_t common = ((uint64_t) reg << 36) | ((uint64_t) base << 28) | (dl << 16) | (dh << 8);
|
||||
uint64_t lgopcode
|
||||
= (type == MIR_T_I8
|
||||
? (ld_p ? 0x77 : 0x72)
|
||||
: type == MIR_T_U8 ? (ld_p ? 0x90 : 0x72)
|
||||
: type == MIR_T_I16
|
||||
? (ld_p ? 0x78 : 0x70)
|
||||
: type == MIR_T_U16
|
||||
? (ld_p ? 0x91 : 0x70)
|
||||
: type == MIR_T_I32 ? (ld_p ? 0x14 : 0x50)
|
||||
: type == MIR_T_U32 ? (ld_p ? 0x16 : 0x50)
|
||||
: (ld_p ? 0x04 : 0x24));
|
||||
uint64_t g = ((0xe3l << 40) | common | lgopcode) << 16;
|
||||
uint64_t ey = ((0xedl << 40) | common | (ld_p ? 0x64 : 0x66)) << 16;
|
||||
uint64_t dy = ((0xedl << 40) | common | (ld_p ? 0x65 : 0x67)) << 16;
|
||||
/* (lg|lgf|llgf|lgb|llgc|lhy|llgh|ley|ldy|stg|sty|sthy|stcy|stey|stdy) reg, disp(base): */
|
||||
assert (type != MIR_T_LD && reg < 16 && base < 16 && -(1 << 19) < disp && disp < (1 << 19));
|
||||
push_insns (insn_varr, (uint8_t *) (single_p ? &ey : double_p ? &dy : &g), 6);
|
||||
}
|
||||
|
||||
static void s390x_gen_ld (VARR (uint8_t) * insn_varr, unsigned to, unsigned base, int disp,
|
||||
MIR_type_t type) {
|
||||
s390x_gen_ld_st (insn_varr, to, base, disp, type, TRUE);
|
||||
}
|
||||
|
||||
static void s390x_gen_st (VARR (uint8_t) * insn_varr, unsigned from, unsigned base, int disp,
|
||||
MIR_type_t type) {
|
||||
s390x_gen_ld_st (insn_varr, from, base, disp, type, FALSE);
|
||||
}
|
||||
|
||||
static void s390x_gen_ldstm (VARR (uint8_t) * insn_varr, unsigned from, unsigned to, unsigned base,
|
||||
int disp, int ld_p) {
|
||||
uint64_t dl = disp & 0xfff, dh = (disp >> 12) & 0xff;
|
||||
uint64_t common = ((uint64_t) from << 36) | ((uint64_t) to << 32) | ((uint64_t) base << 28)
|
||||
| (dl << 16) | (dh << 8);
|
||||
uint64_t g = ((0xebl << 40) | common | (ld_p ? 0x4 : 0x24)) << 16;
|
||||
/* (lmg|stmg) from,to,disp(base): */
|
||||
assert (from < 16 && to < 16 && base < 16 && -(1 << 19) < disp && disp < (1 << 19));
|
||||
push_insns (insn_varr, (uint8_t *) &g, 6);
|
||||
}
|
||||
|
||||
static void s390x_gen_jump (VARR (uint8_t) * insn_varr, unsigned int reg, int call_p) {
|
||||
uint16_t bcr = (0x7 << 8) | (15 << 4) | reg; /* bcr 15,reg: */
|
||||
uint16_t balr = (0x5 << 8) | (14 << 4) | reg; /* balr 14,reg: */
|
||||
assert (reg < 16);
|
||||
push_insns (insn_varr, (uint8_t *) (call_p ? &balr : &bcr), 2);
|
||||
}
|
||||
|
||||
static void s390x_gen_addi (VARR (uint8_t) * insn_varr, unsigned dst, unsigned src, int disp) {
|
||||
uint64_t dl = disp & 0xfff, dh = (disp >> 12) & 0xff;
|
||||
uint64_t ops = ((uint64_t) dst << 36) | ((uint64_t) src << 28) | (dl << 16) | (dh << 8);
|
||||
uint64_t lay = ((0xe3l << 40) | ops | 0x71) << 16; /* lay dst,disp(src) */
|
||||
assert (dst < 16 && src < 16 && -(1 << 19) < disp && disp < (1 << 19));
|
||||
push_insns (insn_varr, (uint8_t *) &lay, 6);
|
||||
}
|
||||
|
||||
static void s390x_gen_3addrs (VARR (uint8_t) * insn_varr, unsigned int r1, void *a1,
|
||||
unsigned int r2, void *a2, unsigned int r3, void *a3) {
|
||||
/* 6b:lalr r3,22+align;6b:lg r1,0(r3);6b:lg r2,8(r3);6b:lg r3,16(r3);4b:bc m15,28;align;a1-a3 */
|
||||
size_t rem = (VARR_LENGTH (uint8_t, insn_varr) + 28) % 8;
|
||||
size_t padding = rem == 0 ? 0 : 8 - rem;
|
||||
uint64_t lalr = ((0xc0l << 40) | ((uint64_t) r1 << 36) | (28 + padding) / 2) << 16;
|
||||
uint32_t brc = (0xa7 << 24) | (15 << 20) | (4 << 16) | (28 + padding) / 2; /* brc m15,28: */
|
||||
assert (r1 != 0);
|
||||
push_insns (insn_varr, (uint8_t *) &lalr, 6);
|
||||
s390x_gen_ld (insn_varr, r3, r1, 16, MIR_T_I64); /* lg r3,16(r1) */
|
||||
s390x_gen_ld (insn_varr, r2, r1, 8, MIR_T_I64); /* lg r2,8(r1) */
|
||||
s390x_gen_ld (insn_varr, r1, r1, 0, MIR_T_I64); /* lg r1,0(r1) */
|
||||
push_insns (insn_varr, (uint8_t *) &brc, 4);
|
||||
for (size_t i = 0; i < padding; i++) VARR_PUSH (uint8_t, insn_varr, 0);
|
||||
push_insns (insn_varr, (uint8_t *) &a1, 8);
|
||||
push_insns (insn_varr, (uint8_t *) &a2, 8);
|
||||
push_insns (insn_varr, (uint8_t *) &a3, 8);
|
||||
}
|
||||
|
||||
static void s390x_gen_blk_mov (VARR (uint8_t) * insn_varr, uint32_t param_offset,
|
||||
uint32_t addr_offset, uint32_t qwords, uint32_t addr_reg) {
|
||||
uint16_t *addr;
|
||||
static const uint16_t blk_mov_pat[] = {
|
||||
/*0:*/ 0xa7a9, 0x0000, /* lghi %r10,<size> */
|
||||
/*4:*/ 0xa7ab, 0xfff8, /* aghi %r10,-8 */
|
||||
/*8:*/ 0xe30a, 0x9000, 0x0004, /* lg %r0,0(%r10,%r9) */
|
||||
/*14:*/ 0xe30a, 0x0000, 0x0024, /* stg %r0,0(%r10,<addr_reg:2-6,8>) */
|
||||
/*20:*/ 0xb902, 0x00aa, /* ltgr %r10,%r10 */
|
||||
/*24:*/ 0xa724, 0xfff6, /* jh 4 */
|
||||
};
|
||||
s390x_gen_addi (insn_varr, addr_reg, 15, addr_offset); /* lay <addr_reg>,addr_offset(r15) */
|
||||
if (qwords == 0) return;
|
||||
assert (qwords * 8 < (1 << 15) && addr_reg < 16 && addr_offset % 8 == 0);
|
||||
s390x_gen_ld (insn_varr, 9, 7, param_offset, MIR_T_I64); /* lg* 9,param_offset(r7) */
|
||||
addr = (uint16_t *) push_insns (insn_varr, (uint8_t *) blk_mov_pat, sizeof (blk_mov_pat));
|
||||
addr[1] |= qwords * 8; /* lghi */
|
||||
addr[8] |= addr_reg << 12; /* stg */
|
||||
}
|
||||
|
||||
void *_MIR_get_bstart_builtin (MIR_context_t ctx) {
|
||||
VARR (uint8_t) * code;
|
||||
void *res;
|
||||
|
||||
VARR_CREATE (uint8_t, code, 128);
|
||||
s390x_gen_mov (code, 2, 15); /* lgr r2,15 */
|
||||
s390x_gen_jump (code, 14, FALSE); /* bcr m15,r14 */
|
||||
res = _MIR_publish_code (ctx, VARR_ADDR (uint8_t, code), VARR_LENGTH (uint8_t, code));
|
||||
VARR_DESTROY (uint8_t, code);
|
||||
return res;
|
||||
}
|
||||
|
||||
void *_MIR_get_bend_builtin (MIR_context_t ctx) {
|
||||
VARR (uint8_t) * code;
|
||||
void *res;
|
||||
|
||||
VARR_CREATE (uint8_t, code, 128);
|
||||
s390x_gen_ld (code, 0, 15, 0, MIR_T_I64); /* r0 = 0(r15) */
|
||||
s390x_gen_st (code, 0, 2, 0, MIR_T_I64); /* 0(r2) = r0 */
|
||||
s390x_gen_mov (code, 15, 2); /* lgr r15,2 */
|
||||
s390x_gen_jump (code, 14, FALSE); /* bcr m15,r14 */
|
||||
res = _MIR_publish_code (ctx, VARR_ADDR (uint8_t, code), VARR_LENGTH (uint8_t, code));
|
||||
VARR_DESTROY (uint8_t, code);
|
||||
return res;
|
||||
}
|
||||
|
||||
void *_MIR_get_thunk (MIR_context_t ctx) {
|
||||
const int max_thunk_len = (4 * 8); /* see _MIR_redirect_thunk */
|
||||
VARR (uint8_t) * code;
|
||||
void *res;
|
||||
|
||||
VARR_CREATE (uint8_t, code, 128);
|
||||
for (int i = 0; i < max_thunk_len; i++) VARR_PUSH (uint8_t, code, 0);
|
||||
res = _MIR_publish_code (ctx, VARR_ADDR (uint8_t, code), VARR_LENGTH (uint8_t, code));
|
||||
VARR_DESTROY (uint8_t, code);
|
||||
return res;
|
||||
}
|
||||
|
||||
void _MIR_redirect_thunk (MIR_context_t ctx, void *thunk, void *to) {
|
||||
int64_t offset = (uint8_t *) to - (uint8_t *) thunk;
|
||||
VARR (uint8_t) * code;
|
||||
|
||||
VARR_CREATE (uint8_t, code, 128);
|
||||
assert (offset % 2 == 0);
|
||||
offset /= 2;
|
||||
if (-(1l << 31) < offset && offset < (1l << 31)) { /* brcl m15,offset: */
|
||||
uint64_t brcl = ((0xc0l << 40) | (15l << 36) | (4l << 32) | offset & 0xffffffff) << 16;
|
||||
push_insns (code, (uint8_t *) &brcl, 6);
|
||||
} else { /* 6b:lalr r1,8+padding; 6b:lg r1,0(r1); 2b:bcr m15,r1;padding; 64-bit address: */
|
||||
size_t rem = (VARR_LENGTH (uint8_t, code) + 14) % 8;
|
||||
size_t padding = rem == 0 ? 0 : 8 - rem;
|
||||
uint64_t lalr = ((0xc0l << 40) | (1l << 36) | (14 + padding) / 2) << 16;
|
||||
uint64_t lg = ((0xe3l << 40) | (1l << 36) | (1l << 28) | 0x4) << 16;
|
||||
uint16_t bcr = (0x7 << 8) | (15 << 4) | 1; /* bcr 15,r1: */
|
||||
push_insns (code, (uint8_t *) &lalr, 6);
|
||||
push_insns (code, (uint8_t *) &lg, 6);
|
||||
push_insns (code, (uint8_t *) &bcr, 2);
|
||||
for (size_t i = 0; i < padding; i++) VARR_PUSH (uint8_t, code, 0);
|
||||
push_insns (code, (uint8_t *) &to, 8);
|
||||
}
|
||||
_MIR_change_code (ctx, thunk, VARR_ADDR (uint8_t, code), VARR_LENGTH (uint8_t, code));
|
||||
VARR_DESTROY (uint8_t, code);
|
||||
}
|
||||
|
||||
struct s390x_va_list {
|
||||
long __gpr, __fpr; /* number of args read until now */
|
||||
void *__overflow_arg_area; /* argument on the stack to read next */
|
||||
void *__reg_save_area; /* curr func frame start */
|
||||
};
|
||||
|
||||
void *va_arg_builtin (void *p, uint64_t t) {
|
||||
struct s390x_va_list *va = p;
|
||||
MIR_type_t type = t;
|
||||
int fp_p = type == MIR_T_F || type == MIR_T_D;
|
||||
void *a;
|
||||
|
||||
if (!fp_p) {
|
||||
if (va->__gpr < 5) {
|
||||
a = (char *) va->__reg_save_area + 16 + 8 * va->__gpr;
|
||||
} else {
|
||||
a = va->__overflow_arg_area;
|
||||
va->__overflow_arg_area = (char *) va->__overflow_arg_area + 8;
|
||||
}
|
||||
va->__gpr++;
|
||||
if (type == MIR_T_LD) a = *(void **) a; /* always passed by address */
|
||||
} else {
|
||||
if (va->__fpr < 4) {
|
||||
a = (char *) va->__reg_save_area + 128 + 8 * va->__fpr;
|
||||
} else {
|
||||
a = va->__overflow_arg_area;
|
||||
va->__overflow_arg_area = (char *) va->__overflow_arg_area + 8;
|
||||
}
|
||||
va->__fpr++;
|
||||
}
|
||||
if (type == MIR_T_F || type == MIR_T_I32) a = (char *) a + 4; /* 2nd word of doubleword */
|
||||
return a;
|
||||
}
|
||||
|
||||
void va_block_arg_builtin (void *res, void *p, size_t s, uint64_t ncase) {
|
||||
memcpy (res, *(void **) va_arg_builtin (p, MIR_T_I64), s);
|
||||
}
|
||||
|
||||
void va_start_interp_builtin (MIR_context_t ctx, void *p, void *a) {
|
||||
struct s390x_va_list *va = p;
|
||||
va_list *vap = a;
|
||||
|
||||
assert (sizeof (struct s390x_va_list) == sizeof (va_list));
|
||||
*va = *(struct s390x_va_list *) vap;
|
||||
}
|
||||
|
||||
void va_end_interp_builtin (MIR_context_t ctx, void *p) {}
|
||||
|
||||
/* Generation: fun (fun_addr, res_arg_addresses):
|
||||
save r6, r7, r14 (r15 + 48,112);
|
||||
allocate and stack frame (S390X_STACK_HEADER_SIZE + param area size + ld arg values size);
|
||||
r1=r2 (fun_addr);
|
||||
r7=r3 (res_arg_addresses);
|
||||
(arg_reg=mem[r7,arg_offset] or
|
||||
(f1,r0)=mem[r7,arg_offset];mem[r15,S390X_STACK_HEADER_SIZE+offset]=(f1,r0)) ... call *r1;
|
||||
r0=mem[r7,<res_offset>]; res_reg=mem[r0]; ...
|
||||
restore r15; restore r6, r7, r14; return. */
|
||||
void *_MIR_get_ff_call (MIR_context_t ctx, size_t nres, MIR_type_t *res_types, size_t nargs,
|
||||
_MIR_arg_desc_t *arg_descs, int vararg_p) {
|
||||
MIR_type_t type;
|
||||
int n_gpregs = 0, n_fpregs = 0, res_reg = 7, frame_size, disp, param_offset, blk_offset;
|
||||
uint32_t qwords, addr_reg;
|
||||
VARR (uint8_t) * code;
|
||||
void *res;
|
||||
|
||||
VARR_CREATE (uint8_t, code, 128);
|
||||
blk_offset = frame_size = S390X_STACK_HEADER_SIZE;
|
||||
if (nres > 0 && res_types[0] == MIR_T_LD) n_gpregs++; /* ld address */
|
||||
for (uint32_t i = 0; i < nargs; i++) { /* calculate param area size: */
|
||||
type = arg_descs[i].type;
|
||||
if (MIR_blk_type_p (type)) frame_size += (arg_descs[i].size + 7) / 8; /* blk value space */
|
||||
if ((type == MIR_T_F || type == MIR_T_D) && n_fpregs < 4) {
|
||||
n_fpregs++;
|
||||
} else if (type != MIR_T_F && type != MIR_T_D && n_gpregs < 5) { /* RBLK too */
|
||||
n_gpregs++;
|
||||
} else {
|
||||
frame_size += 8;
|
||||
blk_offset += 8;
|
||||
}
|
||||
}
|
||||
s390x_gen_ldstm (code, 6, 7, 15, 48, FALSE); /* stmg 6,7,48(r15) : */
|
||||
s390x_gen_ldstm (code, 8, 9, 15, 64, FALSE); /* stmg 8,9,64(r15) : */
|
||||
s390x_gen_st (code, 10, 15, 80, MIR_T_I64); /* stg r10,80(r15) */
|
||||
s390x_gen_st (code, 14, 15, 112, MIR_T_I64); /* stg r14,112(r15) */
|
||||
s390x_gen_addi (code, 15, 15, -frame_size); /* lay r15,-frame_size(r15) */
|
||||
s390x_gen_mov (code, 1, 2); /* fun_addr */
|
||||
s390x_gen_mov (code, res_reg, 3); /* results & args */
|
||||
n_gpregs = n_fpregs = 0;
|
||||
param_offset = nres * 16; /* args start */
|
||||
disp = S390X_STACK_HEADER_SIZE; /* param area start */
|
||||
if (nres > 0 && res_types[0] == MIR_T_LD) { /* ld address: */
|
||||
s390x_gen_mov (code, 2, res_reg); /* lgr r2,r7 */
|
||||
n_gpregs++;
|
||||
}
|
||||
for (uint32_t i = 0; i < nargs; i++) { /* load args: */
|
||||
type = arg_descs[i].type;
|
||||
if ((type == MIR_T_F || type == MIR_T_D) && n_fpregs < 4) {
|
||||
/* (le,ld) (f0,f2,f4,f6),param_ofset(r7) */
|
||||
s390x_gen_ld (code, n_fpregs * 2, res_reg, param_offset, type);
|
||||
n_fpregs++;
|
||||
} else if (type == MIR_T_F || type == MIR_T_D) {
|
||||
s390x_gen_ld (code, 1, res_reg, param_offset, type); /* (le,ld) f1,param_offset(r7) */
|
||||
s390x_gen_st (code, 1, 15, disp, type); /* (ste,std) f1,disp(r15) */
|
||||
disp += 8;
|
||||
} else if (type == MIR_T_LD && n_gpregs < 5) { /* ld address */
|
||||
s390x_gen_addi (code, n_gpregs + 2, res_reg, param_offset); /* lay rn,param_offset(r7) */
|
||||
n_gpregs++;
|
||||
} else if (type == MIR_T_LD) { /* pass address of location in the result: */
|
||||
s390x_gen_addi (code, 0, res_reg, param_offset); /* lay r0,param_offset(r7) */
|
||||
s390x_gen_st (code, 0, 15, disp, MIR_T_I64); /* stg r0,disp(r15) */
|
||||
disp += 8;
|
||||
} else if (MIR_blk_type_p (type)) {
|
||||
qwords = (arg_descs[i].size + 7) / 8;
|
||||
addr_reg = n_gpregs < 5 ? n_gpregs + 2 : 8;
|
||||
s390x_gen_blk_mov (code, param_offset, blk_offset, qwords, addr_reg);
|
||||
blk_offset += qwords * 8;
|
||||
if (n_gpregs < 5) {
|
||||
n_gpregs++;
|
||||
} else {
|
||||
s390x_gen_st (code, 8, 15, disp, MIR_T_I64); /* stg r8,disp(r15) */
|
||||
disp += 8;
|
||||
}
|
||||
} else if (n_gpregs < 5) { /* RBLK too */
|
||||
s390x_gen_ld (code, n_gpregs + 2, res_reg, param_offset,
|
||||
MIR_T_I64); /* lg* rn,param_offset(r7) */
|
||||
n_gpregs++;
|
||||
} else {
|
||||
s390x_gen_ld (code, 0, res_reg, param_offset, MIR_T_I64); /* lg* r0,param_offset(r7) */
|
||||
s390x_gen_st (code, 0, 15, disp, MIR_T_I64); /* stg* r0,disp(r15) */
|
||||
disp += 8;
|
||||
}
|
||||
param_offset += 16;
|
||||
}
|
||||
s390x_gen_jump (code, 1, TRUE); /* call *r1 */
|
||||
n_gpregs = n_fpregs = 0;
|
||||
disp = 0;
|
||||
for (uint32_t i = 0; i < nres; i++) {
|
||||
type = res_types[i];
|
||||
if (type == MIR_T_LD) continue; /* do nothing: the result value is already in results */
|
||||
if ((type == MIR_T_F || type == MIR_T_D) && n_fpregs < 4) {
|
||||
s390x_gen_st (code, n_fpregs * 2, res_reg, disp, type);
|
||||
n_fpregs++;
|
||||
} else if (type != MIR_T_F && type != MIR_T_D && n_gpregs < 1) { // just one gp reg
|
||||
s390x_gen_st (code, n_gpregs + 2, res_reg, disp, MIR_T_I64);
|
||||
n_gpregs++;
|
||||
} else {
|
||||
MIR_get_error_func (ctx) (MIR_ret_error,
|
||||
"s390x can not handle this combination of return values");
|
||||
}
|
||||
disp += 16;
|
||||
}
|
||||
s390x_gen_addi (code, 15, 15, frame_size); /* lay 15,frame_size(15) */
|
||||
s390x_gen_ldstm (code, 6, 7, 15, 48, TRUE); /* lmg 6,7,48(r15) : */
|
||||
s390x_gen_ldstm (code, 8, 9, 15, 64, TRUE); /* lmg 8,9,64(r15) : */
|
||||
s390x_gen_ld (code, 10, 15, 80, MIR_T_I64); /* lg 10,80(r15) */
|
||||
s390x_gen_ld (code, 14, 15, 112, MIR_T_I64); /* lg 14,112(r15) */
|
||||
s390x_gen_jump (code, 14, FALSE); /* bcr m15,r14 */
|
||||
res = _MIR_publish_code (ctx, VARR_ADDR (uint8_t, code), VARR_LENGTH (uint8_t, code));
|
||||
VARR_DESTROY (uint8_t, code);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Transform C call to call of void handler (MIR_context_t ctx, MIR_item_t func_item,
|
||||
va_list va, MIR_val_t *results):
|
||||
Brief: save all C call args to register save area; save r7, r14;
|
||||
allocate shim stack frame (S390X_STACK_HEADER_SIZE + space for results and va);
|
||||
call handler with args; move results to return regs; restore r7,r14,r15; return */
|
||||
void *_MIR_get_interp_shim (MIR_context_t ctx, MIR_item_t func_item, void *handler) {
|
||||
MIR_func_t func = func_item->u.func;
|
||||
uint32_t nres = func->nres, nargs = func->nargs;
|
||||
MIR_type_t type, *res_types = func->res_types;
|
||||
int disp, frame_size, local_var_size, n_gpregs, n_fpregs, va_list_disp, results_disp;
|
||||
VARR (uint8_t) * code;
|
||||
void *res;
|
||||
|
||||
VARR_CREATE (uint8_t, code, 128);
|
||||
frame_size = S390X_STACK_HEADER_SIZE; /* register save area */
|
||||
s390x_gen_st (code, 14, 15, 112, MIR_T_I64); /* stg 14,112(r15) */
|
||||
s390x_gen_ldstm (code, 2, 6, 15, 16, FALSE); /* stmg 2,6,16(r15) : */
|
||||
for (unsigned reg = 0; reg <= 6; reg += 2) /* stdy f0,f2,f4,f6,128(r15) : */
|
||||
s390x_gen_st (code, reg, 15, reg * 4 + 128, MIR_T_D);
|
||||
local_var_size = sizeof (struct s390x_va_list) + nres * 16; /* allocate va and results */
|
||||
va_list_disp = frame_size;
|
||||
results_disp = va_list_disp + sizeof (struct s390x_va_list);
|
||||
frame_size += local_var_size;
|
||||
assert (frame_size % 8 == 0);
|
||||
s390x_gen_addi (code, 15, 15, -frame_size);
|
||||
/* setup va: mvghi va(15),(0,1): __gpr */
|
||||
s390x_gen_mvi (code, nres > 0 && res_types[0] == MIR_T_LD ? 1 : 0, 15, va_list_disp);
|
||||
s390x_gen_mvi (code, 0, 15, va_list_disp + 8); /* mvghi va+8(15),0: __fpr */
|
||||
s390x_gen_addi (code, 1, 15, frame_size); /* lay 1,frame_size(15) */
|
||||
s390x_gen_st (code, 1, 15, va_list_disp + 24, MIR_T_I64); /* stg 1,va+24(r15): __reg_save_area */
|
||||
s390x_gen_addi (code, 1, 1, S390X_STACK_HEADER_SIZE); /* lay 1,S390X_STACK_HEADER_SIZE(1) */
|
||||
/* stg 1,va+16(r15):__overflow_arg_area: */
|
||||
s390x_gen_st (code, 1, 15, va_list_disp + 16, MIR_T_I64);
|
||||
/* call handler: */
|
||||
s390x_gen_3addrs (code, 2, ctx, 3, func_item, 1, handler);
|
||||
s390x_gen_addi (code, 4, 15, va_list_disp);
|
||||
s390x_gen_addi (code, 5, 15, results_disp);
|
||||
s390x_gen_jump (code, 1, TRUE);
|
||||
/* setup result regs: */
|
||||
disp = results_disp;
|
||||
n_gpregs = n_fpregs = 0;
|
||||
for (uint32_t i = 0; i < nres; i++) {
|
||||
type = res_types[i];
|
||||
if ((type == MIR_T_F || type == MIR_T_D) && n_fpregs < 4) {
|
||||
s390x_gen_ld (code, n_fpregs * 2, 15, disp, type);
|
||||
n_fpregs++;
|
||||
} else if (type != MIR_T_F && type != MIR_T_D && n_gpregs < 1) { // just one gp reg
|
||||
if (type != MIR_T_LD) {
|
||||
s390x_gen_ld (code, n_gpregs + 2, 15, disp, MIR_T_I64);
|
||||
} else {
|
||||
/* ld address: lg r2,16+frame_size(r15) */
|
||||
s390x_gen_ld (code, 2, 15, 16 + frame_size, MIR_T_I64);
|
||||
s390x_gen_ld (code, 0, 15, disp, MIR_T_D); /* ld f0,disp(r15) */
|
||||
s390x_gen_ld (code, 2, 15, disp + 8, MIR_T_D); /* ld f2,disp + 8(r15) */
|
||||
s390x_gen_st (code, 0, 2, 0, MIR_T_D); /* st f0,0(r2) */
|
||||
s390x_gen_st (code, 2, 2, 8, MIR_T_D); /* st f2,8(r2) */
|
||||
}
|
||||
n_gpregs++;
|
||||
} else {
|
||||
MIR_get_error_func (ctx) (MIR_ret_error,
|
||||
"s390x can not handle this combination of return values");
|
||||
}
|
||||
disp += 16;
|
||||
}
|
||||
s390x_gen_addi (code, 15, 15, frame_size); /* lay 15,frame_size(15) */
|
||||
s390x_gen_ld (code, 6, 15, 48, MIR_T_I64); /* lg 6,48(r15) : */
|
||||
s390x_gen_ld (code, 14, 15, 112, MIR_T_I64); /* lg 14,112(r15) */
|
||||
s390x_gen_jump (code, 14, FALSE); /* bcr m15,r14 */
|
||||
res = _MIR_publish_code (ctx, VARR_ADDR (uint8_t, code), VARR_LENGTH (uint8_t, code));
|
||||
VARR_DESTROY (uint8_t, code);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Brief: save r14 (r15+120); save all param regs r2-r6 (r15+16),f0,f2,f4,f6 (r15+128);
|
||||
update r15; allocate and form minimal wrapper stack frame (S390X_STACK_HEADER_SIZE);
|
||||
r2 = call hook_address (ctx, called_func); r1=r2; restore all params regs, r15, r14; bcr r1 */
|
||||
void *_MIR_get_wrapper (MIR_context_t ctx, MIR_item_t called_func, void *hook_address) {
|
||||
int frame_size = S390X_STACK_HEADER_SIZE;
|
||||
VARR (uint8_t) * code;
|
||||
void *res;
|
||||
|
||||
VARR_CREATE (uint8_t, code, 128);
|
||||
s390x_gen_st (code, 14, 15, 112, MIR_T_I64); /* stg 14,112(r15) */
|
||||
s390x_gen_ldstm (code, 2, 6, 15, 16, FALSE); /* stmg 2,6,16(r15) : */
|
||||
for (unsigned reg = 0; reg <= 6; reg += 2) /* stdy f0,f2,f4,f6,128(r15) : */
|
||||
s390x_gen_st (code, reg, 15, reg * 4 + 128, MIR_T_D);
|
||||
/* r15 -= frame_size: */
|
||||
s390x_gen_addi (code, 15, 15, -frame_size);
|
||||
s390x_gen_3addrs (code, 2, ctx, 3, called_func, 4, hook_address);
|
||||
s390x_gen_jump (code, 4, TRUE);
|
||||
s390x_gen_mov (code, 1, 2);
|
||||
s390x_gen_addi (code, 15, 15, frame_size);
|
||||
for (unsigned reg = 0; reg <= 6; reg += 2) /* ldy fn,disp(r15) : */
|
||||
s390x_gen_ld (code, reg, 15, reg * 4 + 128, MIR_T_D);
|
||||
s390x_gen_ldstm (code, 2, 6, 15, 16, TRUE); /* lmg 2,6,16(r15) : */
|
||||
s390x_gen_ld (code, 14, 15, 112, MIR_T_I64); /* lg 14,112(r15) */
|
||||
s390x_gen_jump (code, 1, FALSE);
|
||||
res = _MIR_publish_code (ctx, VARR_ADDR (uint8_t, code), VARR_LENGTH (uint8_t, code));
|
||||
VARR_DESTROY (uint8_t, code);
|
||||
return res;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue