Compare commits
24 Commits
master
...
ravi-distr
Author | SHA1 | Date |
---|---|---|
Dibyendu Majumdar | c28b956a3e | 4 years ago |
Dibyendu Majumdar | a6caf1b402 | 4 years ago |
Dibyendu Majumdar | e9774b3e96 | 4 years ago |
Dibyendu Majumdar | 79c44082ec | 4 years ago |
Dibyendu Majumdar | 5bdb49e326 | 4 years ago |
Dibyendu Majumdar | cd851e3414 | 4 years ago |
Dibyendu Majumdar | bfe5f3e645 | 4 years ago |
Dibyendu Majumdar | d501efc2b6 | 4 years ago |
Dibyendu Majumdar | cfee58f7ee | 4 years ago |
Dibyendu Majumdar | 79a572a7cd | 4 years ago |
Dibyendu Majumdar | 54aaa6ac28 | 4 years ago |
Dibyendu Majumdar | 259cd3a726 | 4 years ago |
Dibyendu Majumdar | dc19cf15b2 | 4 years ago |
Dibyendu Majumdar | c997305390 | 4 years ago |
Dibyendu Majumdar | 7d8b3fd924 | 4 years ago |
Dibyendu Majumdar | b862baf4a8 | 4 years ago |
Dibyendu Majumdar | 3c7828439f | 4 years ago |
Dibyendu Majumdar | 460d32f15f | 5 years ago |
Dibyendu Majumdar | 4874e85401 | 5 years ago |
Dibyendu Majumdar | c3ea9e83d5 | 6 years ago |
Dibyendu Majumdar | 011ccf4da9 | 6 years ago |
Dibyendu Majumdar | 4a08e13f9b | 6 years ago |
Dibyendu Majumdar | 563d1d7862 | 6 years ago |
Dibyendu Majumdar | c8e25fda98 | 6 years ago |
@ -1,7 +0,0 @@
|
||||
# [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>
|
@ -1,12 +0,0 @@
|
||||
# [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>
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"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,195 +0,0 @@
|
||||
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
|
@ -0,0 +1,125 @@
|
||||
=========================
|
||||
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)
|
||||
* Generational GC from Lua 5.4
|
||||
* ``defer`` statement for releasing resources
|
||||
* Compact JIT backend `MIR <https://github.com/vnmakarov/mir>`_; only Linux and x86-64 supported for now.
|
||||
* `LLVM <http://www.llvm.org/>`_ supported as alternative JIT backend.
|
||||
* 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.
|
||||
|
||||
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 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 (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.
|
||||
* 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)
|
||||
|
||||
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>`_
|
||||
- Generational GC back-ported from Lua 5.4
|
||||
- Ravi 1.0 release
|
||||
|
||||
License
|
||||
=======
|
||||
MIT License
|
@ -0,0 +1,16 @@
|
||||
# Run this on LLVM 10 source dir
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake3 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$HOME/Software/llvm10 \
|
||||
-DLLVM_TARGETS_TO_BUILD="X86" \
|
||||
-DLLVM_BUILD_TOOLS=OFF \
|
||||
-DLLVM_INCLUDE_TOOLS=OFF \
|
||||
-DLLVM_BUILD_EXAMPLES=OFF \
|
||||
-DLLVM_INCLUDE_EXAMPLES=OFF \
|
||||
-DLLVM_BUILD_TESTS=OFF \
|
||||
-DLLVM_INCLUDE_TESTS=OFF \
|
||||
-DLLVM_OPTIMIZED_TABLEGEN=ON \
|
||||
..
|
||||
make install
|
@ -0,0 +1,5 @@
|
||||
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 ..
|
@ -0,0 +1,5 @@
|
||||
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 ..
|
@ -0,0 +1,5 @@
|
||||
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 ..
|
@ -0,0 +1,6 @@
|
||||
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 ..
|
@ -0,0 +1,7 @@
|
||||
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 ..
|
@ -0,0 +1,5 @@
|
||||
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 ..
|
@ -0,0 +1,5 @@
|
||||
rmdir /s llvm10d
|
||||
mkdir llvm10d
|
||||
cd llvm10d
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 16 2019" -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm10d\lib\cmake\llvm ..
|
||||
cd ..
|
@ -0,0 +1,6 @@
|
||||
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 ..
|
@ -0,0 +1,4 @@
|
||||
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 ..
|
@ -0,0 +1,4 @@
|
||||
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 ..
|
@ -0,0 +1,5 @@
|
||||
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 ..
|
@ -0,0 +1,7 @@
|
||||
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 ..
|
||||
cmake3 -DCMAKE_BUILD_TYPE=Release -DSTATIC_BUILD=ON -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/Software/ravi -DLLVM_DIR=$HOME/Software/llvm10/lib/cmake/llvm ..
|
@ -0,0 +1,3 @@
|
||||
mkdir omrjit
|
||||
cd omrjit
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DOMR_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi ..
|
@ -1,5 +1,5 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2015-2021 Dibyendu Majumdar
|
||||
* Copyright (C) 2015-2020 Dibyendu Majumdar
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
@ -0,0 +1,121 @@
|
||||
/******************************************************************************
|
||||
* 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 >= 10
|
||||
#undef USE_ORCv2_JIT
|
||||
#define USE_ORCv2_JIT 1
|
||||
#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,98 +0,0 @@
|
||||
/* 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;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/* This file is a part of MIR project.
|
||||
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
Copyright (C) 2020 Vladimir Makarov <vmakarov.gcc@gmail.com>.
|
||||
*/
|
||||
|
||||
static char aarch64_mirc[]
|
@ -1,60 +0,0 @@
|
||||
/* 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";
|
@ -1,38 +0,0 @@
|
||||
/* 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,27 +0,0 @@
|
||||
/* 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";
|
@ -1,19 +0,0 @@
|
||||
/* 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";
|
@ -1,130 +0,0 @@
|
||||
/* 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
@ -1,21 +0,0 @@
|
||||
/* 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";
|
@ -1,14 +0,0 @@
|
||||
/* 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";
|
@ -1,14 +0,0 @@
|
||||
/* 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";
|
@ -1,11 +0,0 @@
|
||||
/* 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";
|
@ -1,310 +0,0 @@
|
||||
/* 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;
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/* 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";
|
@ -1,38 +0,0 @@
|
||||
/* 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";
|
@ -1,21 +0,0 @@
|
||||
/* 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";
|
@ -1,19 +0,0 @@
|
||||
/* 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";
|
@ -1,130 +0,0 @@
|
||||
/* 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";
|
@ -1,100 +0,0 @@
|
||||
/* 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;
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/* 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";
|
@ -1,38 +0,0 @@
|
||||
/* 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";
|
@ -1,25 +0,0 @@
|
||||
/* 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";
|
@ -1,19 +0,0 @@
|
||||
/* 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";
|
@ -1,130 +0,0 @@
|
||||
/* 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";
|
@ -1,401 +0,0 @@
|
||||
/* 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;
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/* 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";
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue