Compare commits

...

636 Commits

Author SHA1 Message Date
Pavel R. 7adbc171f6 changed types to strict (nil disallowed) in lcode.c
3 years ago
Pavel R. 072d2c37f0 Fixed possibility to initialize empty strings (and booleans)
3 years ago
Pavel R. 21fd437e89 added missing optional types opcodes to JIT interface
3 years ago
annelin 73de201165 added new (optional) types to lparser.c (no idea what does it affect)
3 years ago
annelin be65484feb Removed RAVI_DEFER_STATEMENT define (there are no reasons to disable it)
3 years ago
annelin 7d376acf62 Added `debug.settype(typ, metatable)` function
3 years ago
Pavel R. 3995761bf1 Add README.md
3 years ago
Pavel R. 5359ca1d5f - Added boolean type
3 years ago
Dibyendu Majumdar d022074ae6 Update Lua 5.4.3 defer patch - minor change to remove some leftover stuff
3 years ago
Dibyendu Majumdar cf3be2e688
Update README.rst
3 years ago
Dibyendu Majumdar bbf2c29077 Lua 5.4.3 defer statement patch
3 years ago
Dibyendu Majumdar 2c81edafa0 issue #169 Sync with upstream project
3 years ago
Dibyendu Majumdar b073242254 issue #198 Sync with upstream project
3 years ago
Dibyendu Majumdar 6eb43324dd issue #169 Add GNUInstallDirs
3 years ago
Dibyendu Majumdar 4bfc061a2a issue #169 Apply upstream fixes
3 years ago
Dibyendu Majumdar 3efaddee6b issue #222 Lua 5.4 change for bitwise ops
3 years ago
Dibyendu Majumdar d5e324fd53 issue #217 fix the ravicomp compiler to use the same typecodes as Ravi
3 years ago
Dibyendu Majumdar e3d8203bd9 Refactor
3 years ago
Dibyendu Majumdar 53ec0c19b3
Merge pull request #218 from XmiliaH/bump-binary-version
3 years ago
XmiliaH 5ca801596a Bump binary version & smaller sizes for stripped binaries
3 years ago
Dibyendu Majumdar 58980db5cb issue #217 define ravitype_t in terms of the new values
3 years ago
Dibyendu Majumdar 347ae985bc
Merge pull request #213 from XmiliaH/type-maps
3 years ago
Dibyendu Majumdar 063a55604e
Merge branch 'new_type_info' into type-maps
3 years ago
Dibyendu Majumdar 8e815bd67a issue #215 adapt fix by XmiliaH from pull request
3 years ago
Dibyendu Majumdar 658f04c3d8 issue #215 adapt fix by XmiliaH from pull request
3 years ago
Dibyendu Majumdar 8fd3a1bbab issue #214 since we haven't implemented boolean type annotation fully, the parser will no longer recognize the :boolean annotation.
3 years ago
Dibyendu Majumdar b5afdfaa46 issue #215 The top level check v->ravi_type != vartype is not correct as it means we miss out checking scenario where v->k == VINDEXED.
3 years ago
Dibyendu Majumdar 88ccaf34a0 Reformat
3 years ago
Dibyendu Majumdar 5c30d255c7 some improvements to type checking via XmiliaH
3 years ago
Dibyendu Majumdar 248c730c43 refactoring via XmiliaH
3 years ago
Dibyendu Majumdar 4a20693671 refactoring via XmiliaH
3 years ago
Dibyendu Majumdar cb6943a1eb tests updated
3 years ago
XmiliaH 837dc959cf
Merge branch 'master' into type-maps
3 years ago
Dibyendu Majumdar 754fcefc26
Merge pull request #212 from XmiliaH/some-improvements
3 years ago
XmiliaH b4359b9391 Cleanup and Fixes
3 years ago
XmiliaH a9537957d5 Remove old ravi_type_t from jit
3 years ago
XmiliaH 435480f4db Better deduction for not
3 years ago
XmiliaH 62ab591343 Fix concat
3 years ago
XmiliaH f80e4d5442 Fix concat
3 years ago
XmiliaH 7789f4f32d Finish type maps
3 years ago
XmiliaH c0122cd816 FIx tests
3 years ago
XmiliaH 58cdc8d7dc RAVI_TSTRINGs can be nil
3 years ago
XmiliaH 6af3d804a4 First part for type maps
3 years ago
XmiliaH 871b76fea2 Format changed code
3 years ago
XmiliaH 0b43c94a4d Use the right enum for opcodes
3 years ago
XmiliaH e85634270f Add back that len of table is int and fix tests.
3 years ago
XmiliaH 4cce67ec13 Improve type deduction
3 years ago
Dibyendu Majumdar a2ec53624d issue #211 since the up-value carries the type of the local variable, we can safely infer that the result of a get on array is a primitive type
3 years ago
Dibyendu Majumdar 9bceadd099 issue #211 since the up-value carries the type of the local variable, we can safely infer that the result of a get on array is a primitive type
3 years ago
Dibyendu Majumdar 25dbc31393 issue #211 since the up-value carries the type of the local variable, we can safely infer that the result of a get on array is a primitive type
3 years ago
Dibyendu Majumdar 2c5b958d04 issue #211 since the up-value carries the type of the local variable, we can safely infer that the result of a get on array is a primitive type
3 years ago
Dibyendu Majumdar b0a5b01142 issue #211 The type of update index op is not known.
3 years ago
Dibyendu Majumdar 170fd797a2 It seems that we don't really need this - must be the bug was elsewhere
3 years ago
Dibyendu Majumdar b2cc7c30c5 issue #210 tests
3 years ago
Dibyendu Majumdar 2decef927a issue #210 tests
3 years ago
Dibyendu Majumdar 486145900b issue #208 check for overflow when resizing array
3 years ago
Dibyendu Majumdar a3b933aa43 issue #208 check for overflow when resizing array
3 years ago
Dibyendu Majumdar 1e8597de7d issue #210 fix a test
3 years ago
Dibyendu Majumdar 9ced7e2bc0 issue #210 bug in recognizing the type change when an expression of VINDEXED type gets resolved
3 years ago
Dibyendu Majumdar fe7c76fff5 issue #207 add test
3 years ago
Dibyendu Majumdar ad4fc4e2d2 issue #207 check size more carefully when creating a slice
3 years ago
Dibyendu Majumdar 2c44bdd68b issue #208 add test
3 years ago
Dibyendu Majumdar 8bd404f62e issue #208 check for size overflow when creating integer/number array
3 years ago
Dibyendu Majumdar 4342fc7630 issue #210 #209 tests
3 years ago
Dibyendu Majumdar 927ddbf6a0 issue #210 LEN on any value other than array or table should be any type
3 years ago
Dibyendu Majumdar b549302d70 issue #209 BNOT on any value other than integer should result in any type
3 years ago
Dibyendu Majumdar 56a59a1f31 issue #169 apply latest upstream changes
3 years ago
Dibyendu Majumdar 773ebd9d32 issue #169 Update MIR sources - includes a memory leak bug fix
3 years ago
Dibyendu Majumdar def4d76ac9 Remove cmake branch from build.yml
3 years ago
Dibyendu Majumdar ef24ca67cb Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
3 years ago
Dibyendu Majumdar 77cd6b9527 Update copyright notices
3 years ago
Dibyendu Majumdar 61a8ac889f Update docs
3 years ago
Dibyendu Majumdar 102c8bee8b Update copyright notices
3 years ago
Dibyendu Majumdar 3e05644f51 issue #198 Cleanup
3 years ago
Dibyendu Majumdar f7f59eed0f issue #198 Cleanup
3 years ago
Dibyendu Majumdar 2aeeea4dd3 issue #198 Include Ravi Compiler
3 years ago
Dibyendu Majumdar 31774723ff Merge branch 'cmake'
3 years ago
Dibyendu Majumdar cc0c098011 CMake refactoring
3 years ago
Dibyendu Majumdar f072326ea4 CMake build refactoring
3 years ago
Dibyendu Majumdar 66615703a6 Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
3 years ago
Dibyendu Majumdar ef30fb2065
Update build.yml
3 years ago
Dibyendu Majumdar 2335973259
Update build.yml
3 years ago
Dibyendu Majumdar fae2a2bf77 issue #186 leftover cleanup
3 years ago
Dibyendu Majumdar 08c05100cf issue #203 leftover cleanup
3 years ago
Dibyendu Majumdar 3b09a22e96 issue #204 Code reorg
3 years ago
Dibyendu Majumdar 1f1d8cb428 issue #198 Add tests
3 years ago
Dibyendu Majumdar 9083492dcb issue #198 Add a test
3 years ago
Dibyendu Majumdar e6890743f0 issue #169 Update MIR
3 years ago
Dibyendu Majumdar 9cc59144ad issue #195 lstrlib
3 years ago
Dibyendu Majumdar f27792f050 issue #195 strings tests part 7
3 years ago
Dibyendu Majumdar df748ee844 issue #195 strings tests part 6
3 years ago
Dibyendu Majumdar ed90926c8d issue #195 strings tests part 5
3 years ago
Dibyendu Majumdar 1fb5b08491 issue #195 strings tests part 4
3 years ago
Dibyendu Majumdar facb56e0c1 issue #195 strings tests part 3
3 years ago
Dibyendu Majumdar 9a86f11bc3 issue #195 strings tests part 2
3 years ago
Dibyendu Majumdar 92fd0e3faf issue #195 strings tests part 1
3 years ago
Dibyendu Majumdar 54fc5277d6 issue #195 vararg tests part 2
3 years ago
Dibyendu Majumdar c11122376e issue #195 vararg tests part 1
3 years ago
Dibyendu Majumdar 36639d863a issue #196 reformat
3 years ago
Dibyendu Majumdar 71644f5450 issue #196 use a macro for slices
3 years ago
Dibyendu Majumdar b717be20e0 Fix a missing check
3 years ago
Dibyendu Majumdar 249f22c215 issue #196 Another test restored to 5.3 version.
3 years ago
Dibyendu Majumdar 2f76a1e869 issue #196 GC upvalue/thread cycle test reverted to 5.3 version due to difference in behaviour in Lua 5.4 (as up-values are not reference counted anymore).
3 years ago
Dibyendu Majumdar 4acc325c97 issue #196 Fix test case
3 years ago
Dibyendu Majumdar ec2d27a7dc issue #196 Fix test case
3 years ago
Dibyendu Majumdar 7320131275 Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
3 years ago
Dibyendu Majumdar f9c4b5dbec issue #203 Removing LLVM support, see llvm branch for archived version
3 years ago
Dibyendu Majumdar 0c3277ad4a
issue #203 Doc update
3 years ago
Dibyendu Majumdar d6422fe2e3
Update .travis.yml
3 years ago
Dibyendu Majumdar 66511033fd issue #203 Removing LLVM support, see llvm branch for archived version
3 years ago
Dibyendu Majumdar 05f365352c issue #169 Fix issue on ARM64
3 years ago
Dibyendu Majumdar 219d44c2ba issue #196 Revise upval barrier code - TBC
3 years ago
Dibyendu Majumdar e4a240be77 add assertions
3 years ago
Dibyendu Majumdar 2ace67282d issue #196 Undo a change that was not needed
3 years ago
Dibyendu Majumdar 6909d79f61 Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
3 years ago
Dibyendu Majumdar 16ea0643cd issue #202 Prepare for testing on different archs
3 years ago
Dibyendu Majumdar a83afe2d02
Update build.yml
3 years ago
Dibyendu Majumdar d5668379b1
Update build.yml
3 years ago
Dibyendu Majumdar 849819e891
Update build.yml
3 years ago
Dibyendu Majumdar 53ff35455a issue #198 Updated interface to the compiler lib
3 years ago
Dibyendu Majumdar f9acba8142 issue #169 MIR update
3 years ago
Dibyendu Majumdar 389c98ee35
Merge pull request #200 from dibyendumajumdar/lua542-gc
3 years ago
Dibyendu Majumdar e9cb48e15c issue #196 Update GC code from Lua 5.4.2
3 years ago
Dibyendu Majumdar f346122073 issue #196 Update GC code from Lua 5.4.2
3 years ago
Dibyendu Majumdar 001dceb996 issue #198 Initial support for AOT compiled code
3 years ago
Dibyendu Majumdar 0f6a4084ae issue #198 Refactor
3 years ago
Dibyendu Majumdar 95ac6123a9 issue #198 Refactored api that puts all of the codegen at the compiler end, making the way for an AOT solution
3 years ago
Dibyendu Majumdar 8d6e403f30 issue #198 Refactored api that puts all of the codegen at the compiler end, making the way for an AOT solution
3 years ago
Dibyendu Majumdar bb218051ba Add support for codespaces
4 years ago
Dibyendu Majumdar bc4142428c issue #198 add expected results for the tests
4 years ago
Dibyendu Majumdar 86c2020411 issue #198 more tests
4 years ago
Dibyendu Majumdar 5a0c3600fc issue #198 add test
4 years ago
Dibyendu Majumdar a54f156304 issue #198 add test
4 years ago
Dibyendu Majumdar 8cec4cc827 issue #198 More tests
4 years ago
Dibyendu Majumdar a82d42b847 issue #169 MIR update
4 years ago
Dibyendu Majumdar a3bf9dc10e issue #198 add another test for sieve - but using while loop
4 years ago
Dibyendu Majumdar ea6c408c97 issue #198 tests for farray opcodes
4 years ago
Dibyendu Majumdar 487624cee9 issue #198 tests for iarray opcodes
4 years ago
Dibyendu Majumdar e361bd7387 issue #198 add luaD_growstack to the list of linked functions in the JIT
4 years ago
Dibyendu Majumdar 69840eacdb issue #198 Tests for op_call instruction - couple fail due to missing support for multiret in return
4 years ago
Dibyendu Majumdar d0b3ed989b issue #169 Enable MIR on Windows
4 years ago
Dibyendu Majumdar f6378c97b4 issue #169 Apply upstream changes
4 years ago
Dibyendu Majumdar 7f94078e8e issue #169 update MIR sources from upstream
4 years ago
Dibyendu Majumdar 174cfa0168 issue #198 add tests for op_loadglobal, op_storeglobal
4 years ago
Dibyendu Majumdar 523f07ba57 issue #198 initialize the _ENV upvalue
4 years ago
Dibyendu Majumdar 71bb74f773 Merge branch 'ravi-compiler'
4 years ago
Dibyendu Majumdar 6b273f7468 issue #198 Make the MIR portion of the compiler optional so that we can just get the C codegen
4 years ago
Dibyendu Majumdar a3940b0120 Add link to the VSCode debugger
4 years ago
Dibyendu Majumdar b1f36a56e1 Merge branch 'ravi-compiler' of https://github.com/dibyendumajumdar/ravi into ravi-compiler
4 years ago
Dibyendu Majumdar 6daf1a5529 Add link to the VSCode debugger
4 years ago
Dibyendu Majumdar 4819f38a80 issue #198 Test cases for op_mov, op_br, op_cbr
4 years ago
Dibyendu Majumdar 4f7cab694c issue #198 Test case for op_mov
4 years ago
Dibyendu Majumdar d65beddb75 issue #198 Test case for op_ret
4 years ago
Dibyendu Majumdar 45f823b604 issue #198 Missing initializer for proto->upvalues[i].usertype when usertype is NULL
4 years ago
Dibyendu Majumdar a45eaa8a24 issue #198 Cmake build failing to find c2mir header
4 years ago
Dibyendu Majumdar 902f5c1653 Comments
4 years ago
Dibyendu Majumdar 48617fda44 issue #198 WIP add api functions for setting some proto attributes
4 years ago
Dibyendu Majumdar fba87f24f1 issue #198 WIP add api for error reporting and generating debug messages
4 years ago
Dibyendu Majumdar 90a26a4b88 issue #198 WIP add api for marking a proto as var arg
4 years ago
Dibyendu Majumdar 0f698f354c issue #198 WIP add api for adding an upvalue. Hook up the compiler library.
4 years ago
Dibyendu Majumdar 7515ef9d89 Merge branch 'master' into ravi-compiler
4 years ago
Dibyendu Majumdar 2a6c5575e3 issue #198 WIP revise the api for compiling C code using MIR
4 years ago
Dibyendu Majumdar 98c96c11eb issue #198 WIP flesh out some more api functions
4 years ago
Dibyendu Majumdar 2cab1f104a issue #198 WIP flesh out some more api functions
4 years ago
Dibyendu Majumdar be67d117c2 Merge branch 'master' into ravi-compiler
4 years ago
Dibyendu Majumdar 430f9a532b issue #169 preparation for ravicomp integration
4 years ago
Dibyendu Majumdar e20df095df issue #169 Fix builds failure
4 years ago
Dibyendu Majumdar 90f54987eb issue #169 Update MIR to latest version
4 years ago
Dibyendu Majumdar cde0a39bc2 issue #169 Refactor the c2mir invocation so that we can reuse this when integrating with ravicomp library.
4 years ago
Dibyendu Majumdar 16d59f65ee issue #169 Add include directories of MIR to help CLion find them
4 years ago
Dibyendu Majumdar 534abc7525 issue #169 fix memory leak
4 years ago
Dibyendu Majumdar 02a7796f77 issue #198 WIP
4 years ago
Dibyendu Majumdar 34c6b33a2f issue #198 WIP add interface to RaviCompiler project
4 years ago
Dibyendu Majumdar 0d22f81b2a Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
4 years ago
Dibyendu Majumdar ee056a1bd6 Comment added aboit upvalues
4 years ago
Dibyendu Majumdar 40e020916a
Update README.rst
4 years ago
Dibyendu Majumdar 57f6fc82f7
Update README.rst
4 years ago
Dibyendu Majumdar c4535d5d9f
Update README.rst
4 years ago
Dibyendu Majumdar 940a80d9bb On returning from a function the results are copied to the registers starting at at the function's reference in CallInfo->func
4 years ago
Dibyendu Majumdar 4d348e0609 Update readme / intro
4 years ago
Dibyendu Majumdar f76b4690f0 Initial patch to implement 'defer' statement in Lua 5.4
4 years ago
Dibyendu Majumdar 42cfa54e9e Initial patch to implement 'defer' statement in Lua 5.4
4 years ago
Dibyendu Majumdar 81555acc72 Update docs to correctly state the default garbage collector.
4 years ago
Dibyendu Majumdar 7e219f76bd Lua 5.3 patch that implements 'defer' statement
4 years ago
Dibyendu Majumdar 8b854b0a02 Lua 5.3 patch that implements 'defer' statement
4 years ago
Dibyendu Majumdar 920cd2dab8 issue #196 test case for the gen GC bug
4 years ago
Dibyendu Majumdar b73322ad16 issue #157 Detail
4 years ago
Dibyendu Majumdar 844b15683b issue #196 When an object aged OLD1 is finalized, it is moved from the list 'finobj' to the *beginning* of the list 'allgc'. So, this part of the
4 years ago
Dibyendu Majumdar 63bf14b43c issue #169 Merge latest MIR code from upstream
4 years ago
Dibyendu Majumdar 73d6bc1c07 issue #195 Some improvements to Makefile build - based on Lua 5.4 build improvements
4 years ago
Dibyendu Majumdar c42ac0e9fa issue #196 don't make generational GC the default yet - various issues reported on Lua mailing list.
4 years ago
Dibyendu Majumdar d26e3626b9 issue #182 ASAN support must be explicitly enabled as not all installations have asan installed
4 years ago
Dibyendu Majumdar f8a680ed82 Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
4 years ago
Dibyendu Majumdar 4bbcb908ec issue #157 fix build error on windows
4 years ago
Dibyendu Majumdar 7f63b9fae7 issue #182 add asan support if available
4 years ago
Dibyendu Majumdar 3a75ee9eb7 Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
4 years ago
Dibyendu Majumdar cdd6fbfeaa issue #182: remove commented lines
4 years ago
Dibyendu Majumdar 73c2c6426f issue #163 Maintain optionality of defer statement
4 years ago
Dibyendu Majumdar b63005fd3f issue #163 Couple of more tests for coroutines and deferred functions, plus some changes in ldo.c back-ported from Lua 5.4
4 years ago
Dibyendu Majumdar e832dcc32f issue #163 Fix issue with handling of deferred functions when a Lua thread is closed.
4 years ago
Dibyendu Majumdar d8a60ddd23 issue #163 Split out defer tests to a separate file. Also backport a few tests from Lua 5.4
4 years ago
Dibyendu Majumdar bf2f55eece issue #163 Do not generate TAILCALL opcode if a defer closure is in scope; back-ported from Lua 5.4.
4 years ago
Dibyendu Majumdar 9c745caafe issue #157 Doc updates
4 years ago
Dibyendu Majumdar 2934cbe5c0 issue #157 Add Ravi api functions to return JIT name and options
4 years ago
Dibyendu Majumdar 7dd5c1fdf0 issue #157 cleanup
4 years ago
Dibyendu Majumdar 9e2a4f4645 issue #163 Fix bug in OP_RETURN in interpreter and MIR JIT backend; we need to reload RA after call to luaF_close() as stack may been reallocated
4 years ago
Dibyendu Majumdar e483fe40ee
Update ravi-reference.rst
4 years ago
Dibyendu Majumdar 7e26dc8d0f issue #195 number and integer comparisons
4 years ago
Dibyendu Majumdar 0e41a51114 issue #195 number and integer conversions
4 years ago
Dibyendu Majumdar f884782a60 issue #195 backport luaO_pushvfstring
4 years ago
Dibyendu Majumdar 2861754b3c issue #195 backport luaO_pushvfstring
4 years ago
Dibyendu Majumdar 22d84e74d0 issue #195 backport luaO_pushvfstring
4 years ago
Dibyendu Majumdar f547edd330 issue #195 lexer / utf8 improvements from Lua 5.4
4 years ago
Dibyendu Majumdar d4992e8d08 Revert "issue #195 Misc updates from Lua 5.4"
4 years ago
Dibyendu Majumdar 4795374610 issue #195 Misc updates from Lua 5.4
4 years ago
Dibyendu Majumdar 93c0a0c61e issue #196 doc updates
4 years ago
Dibyendu Majumdar 4ccc2759e8
Add information regarding Lua 5.4
4 years ago
Dibyendu Majumdar 062550b84d issue #196 backport generational GC from Lua 5.4
4 years ago
Dibyendu Majumdar f4752a513f issue #195: move upvalue struct to lobject.h as in Lua 5.4
4 years ago
Dibyendu Majumdar e0881115e4 issue #195: lua tests update
4 years ago
Dibyendu Majumdar 2eb4daf7ff issue #192 when searching for values in table use raw key comparison; back ported from Lua 5.4
4 years ago
Dibyendu Majumdar d2a295688f issue #195 lua 5.4 object.h layout for easier comparison
4 years ago
Dibyendu Majumdar d2b9810a06 issue #193 Lua 5.4 string library improvements back-ported
4 years ago
Dibyendu Majumdar a2e0c2fc3d issue #191 #193 backport random number generator from Lua 5.4
4 years ago
Dibyendu Majumdar bf5aa3e3f6 issue #169 update MIR code from upstream
4 years ago
Dibyendu Majumdar 4d6f9dd9f2 issue #99 test case
4 years ago
Dibyendu Majumdar cf7f8ed380 issue #157 remove redundant test script
4 years ago
Dibyendu Majumdar ff91fbfc8d issue #169 details
4 years ago
Dibyendu Majumdar 3cf60d2972 Fix travis build
4 years ago
Dibyendu Majumdar 18ff6c1f36 issue #157 Long overdue reorg of tests, much more needs to be done, but this is a start
4 years ago
Dibyendu Majumdar 5f286815ed issue #169 Update to latest MIR code
4 years ago
Dibyendu Majumdar 76f9bbdffb issue #99 Merge splitting out of the RaviArray structure from Table
4 years ago
Dibyendu Majumdar a8ee5a60e1 issue #99 LLVM JIT updates to support RaviArray breakout from Table structure
4 years ago
Dibyendu Majumdar 0d2b3161e3
Delete FUNDING.yml
4 years ago
Dibyendu Majumdar f3886accbe issue #99 remove blank
4 years ago
Dibyendu Majumdar e16310f742 issue #99 Fix missing field in GCUnion
4 years ago
Dibyendu Majumdar 4b34875605 issue #99 Use dedicated structure for Ravi array types
4 years ago
Dibyendu Majumdar eb3d9ca72d Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
4 years ago
Dibyendu Majumdar a5759bbb25 issue #188
4 years ago
Dibyendu Majumdar 71e5bd8d8c issue #169 MIR update
4 years ago
Dibyendu Majumdar 6f7313594c issue #188 update docs
4 years ago
Dibyendu Majumdar 83e0a739b0 issue #188 add missing symbol
4 years ago
Dibyendu Majumdar 23141174d4 issue #169 Update to latest MIR codebase and set default opt level to 2
4 years ago
Dibyendu Majumdar 6500e11c01 issue #184
4 years ago
Dibyendu Majumdar 59f92f04df issue #184 first pass revision of OP_TEST and OP_TESTSET
4 years ago
Dibyendu Majumdar b317b19c3c issue #184 first pass revision of OP_TEST and OP_TESTSET
4 years ago
Dibyendu Majumdar 0ff5baa1a5 issue #184 first pass revision of OP_TEST and OP_TESTSET
4 years ago
Dibyendu Majumdar 9202468bb7 issue #188 Fix missing symbol registrations
4 years ago
Dibyendu Majumdar 89b9451437 issue #188
4 years ago
Dibyendu Majumdar 9db31dabd8 issue #187
4 years ago
Dibyendu Majumdar 2edf9f6936 issue #187
4 years ago
Dibyendu Majumdar d39da2757e
issue #187
4 years ago
Dibyendu Majumdar 9b8f89dad0
issue #187
4 years ago
Dibyendu Majumdar edcec3a4cd
issue #187
4 years ago
Dibyendu Majumdar 5d0b594135
issue #187
4 years ago
Dibyendu Majumdar 10ca66a4fd
issue #187
4 years ago
Dibyendu Majumdar f5cc3fdfcf issue #175
4 years ago
Dibyendu Majumdar 4e53c74180 issue #175
4 years ago
Dibyendu Majumdar 4cc6fcf8b0 issue #186
4 years ago
Dibyendu Majumdar 3253283648 issue #186
4 years ago
Dibyendu Majumdar bcc094d953 issue #186
4 years ago
Dibyendu Majumdar 0e1815b3e5 issue #98
4 years ago
Dibyendu Majumdar bfdb4937b3 issue #98
4 years ago
Dibyendu Majumdar 352f03ad61 issue #186
4 years ago
Dibyendu Majumdar 5834e4c78f issue #98 removing new parser code as migrated to ravi-compiler project
4 years ago
Dibyendu Majumdar bfaf2a3cef issue #163 improve codegen for binary op involving two floats when one is a constant
4 years ago
Dibyendu Majumdar 69d4b0dcfd issue #163 improve codegen for binary op involving two floats when one is a constant
4 years ago
Dibyendu Majumdar eae8eb971d issue #163 improve codegen for adding two integers when one is a constant
4 years ago
Dibyendu Majumdar 22c467e5b6 issue #163 misleading #define
4 years ago
Dibyendu Majumdar ced70c2d60 Add some compiler flags conditionally to improve performance
4 years ago
Dibyendu Majumdar be6e3bc543 Add a Lua version of the sieve benchmark
4 years ago
Dibyendu Majumdar 37a99ccfc8 issue #169 merge
4 years ago
Dibyendu Majumdar f92bc32dd3 try fixing travis build
4 years ago
Dibyendu Majumdar b8af71583d issue #163 'defer' implementation now controlled via RAVI_DEFER_STATEMENT macro. This allows testing of performance with and without the 'defer' statement
4 years ago
Dibyendu Majumdar c51efcb658 issue #182
4 years ago
Dibyendu Majumdar 5f4989fa68 issue #169 Update MIR to latest version
4 years ago
Dibyendu Majumdar 788cd0d92d issue #169 Update MIR to latest version
4 years ago
Dibyendu Majumdar ab9fb1f8fb issue #98 fix scoping of local vars
4 years ago
Dibyendu Majumdar 6ccca76ff1
Update README.rst
4 years ago
Dibyendu Majumdar 6157e9270b
Update ravi-reference.rst
4 years ago
Dibyendu Majumdar 9dcaad872e issue #183 use ravi_writestring() instead of printf() to dump the bytecodes
4 years ago
Dibyendu Majumdar 606a5de5f9 issue #157 Update docs
4 years ago
Dibyendu Majumdar 224ae4f3df issue #169 apply latest updates from MIR project
4 years ago
Dibyendu Majumdar 84b4949aa9 issue #157 Cleanup some unwanted api functions that are really only for debugging
4 years ago
Dibyendu Majumdar e9cb1d3b20 issue #182
4 years ago
Dibyendu Majumdar ca0d65e786 issue #182
4 years ago
Dibyendu Majumdar 722e696028 issue #182
4 years ago
Dibyendu Majumdar 31c64d6bb8 issue #182 #178 Fix issue with scripst after moving to CMAKE_INSTALL_BINDIR
4 years ago
Dibyendu Majumdar a01fcc296d issue #182
4 years ago
Dibyendu Majumdar d5dc17e5a4 issue #182
4 years ago
Dibyendu Majumdar a63cad72f5 issue #182
4 years ago
Dibyendu Majumdar 7b9255798d issue #182
4 years ago
Dibyendu Majumdar ca74bab98f issue #182
4 years ago
Dibyendu Majumdar f8ec7f2b28 issue #182
4 years ago
Dibyendu Majumdar 4ba87d85fa issue #182
4 years ago
Dibyendu Majumdar 2792401274 issue #182
4 years ago
Dibyendu Majumdar 439000d1f1 issue #182
4 years ago
Dibyendu Majumdar d32c418951 issue #182
4 years ago
Dibyendu Majumdar 65bca5007f
issue #182
4 years ago
Dibyendu Majumdar 25958e4359
issue #182
4 years ago
Dibyendu Majumdar 638f061f61
issue #182
4 years ago
Dibyendu Majumdar eec9e3edad issue #182 baby steps
4 years ago
Dibyendu Majumdar 3ad35cdd54 Fix OSX support in cmake config
4 years ago
Dibyendu Majumdar 35e5647cc1 Try to fix the issue locating the library on Linux
4 years ago
Dibyendu Majumdar 124a58b66d Rename cmake config file
4 years ago
Dibyendu Majumdar f5d57a7215 issue #169 update MIR from upstream
4 years ago
Dibyendu Majumdar 0796d0da0b issue #181 remove old c tests
4 years ago
Dibyendu Majumdar ea5e34f447 issue #180 removing llvm lua api
4 years ago
Dibyendu Majumdar 7834343893 issue #179 removed ASMVM but it is available on asmvm branch
4 years ago
Dibyendu Majumdar 72067c0893 issue #178 Added scripts that will be configured by CMake
4 years ago
Dibyendu Majumdar 01ea473c27
Add CI badge
4 years ago
Dibyendu Majumdar fcae3d293a issue #169 fix wrong error message - found due to travis build failure
4 years ago
Dibyendu Majumdar fd65a803cb issue #169 fix wrong error message - found due to travis build failure
4 years ago
Dibyendu Majumdar 29d7bff586 issue #169 fix wrong error message - found due to travis build failure
4 years ago
Dibyendu Majumdar bf94ff65e8 issue #169 fix wrong error message - found due to travis build failure
4 years ago
Dibyendu Majumdar ccbf2c0eb9 issue #169 apply latest updates from upstream MIR project plus make MIR a default part of Ravi on supported systems
4 years ago
Dibyendu Majumdar ba47449efc issue #169 apply latest updates from upstream MIR project plus make MIR a default part of Ravi on supported systems
4 years ago
Dibyendu Majumdar 1e5cac14b0 issue #169 apply fixes from MIR project
4 years ago
Dibyendu Majumdar a12d049d42 issue #169 apply fixes from MIR project
4 years ago
Dibyendu Majumdar 544ee84c66 Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
4 years ago
Dibyendu Majumdar ba9a63b4ff Start making the tests runnable by Suravi lua version - wip
4 years ago
Dibyendu Majumdar 4e3d01ec97 issue #163 add simple defer case in debugger test
4 years ago
Dibyendu Majumdar 7f833faf61 Undo unintended reformatting
4 years ago
Dibyendu Majumdar a44a98ca96
Update README.rst
4 years ago
Dibyendu Majumdar c739dfb2ab
Remove unwanted stuff
4 years ago
Dibyendu Majumdar e7dbdedff3
Remove unwanted stuff
4 years ago
Dibyendu Majumdar b9d92ff4de issue #163 Add couple of tests
4 years ago
Dibyendu Majumdar 5a2f52a422 issue #175
4 years ago
Dibyendu Majumdar 76accd1930 Update copyright notices
4 years ago
Dibyendu Majumdar b57e778b55 issue #169 nan and inf literal generated by JIT C codegen, but these are not valid literals. Temporarily use macros to replace these but a better fix is needed
4 years ago
Dibyendu Majumdar e85d471bcd
Update README.rst
4 years ago
Dibyendu Majumdar db2993e2a9 issue #174 Allow arguments in the launch script
4 years ago
Dibyendu Majumdar 3509c69923 Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
4 years ago
Dibyendu Majumdar be79af1577 isue #173 Skip drive letter when comparing paths
4 years ago
Dibyendu Majumdar 6308c1d929 issue #169 add missing opcode emits
4 years ago
Dibyendu Majumdar 9d65c41a3b issue #169 temp change to test case
4 years ago
Dibyendu Majumdar 63c8906455 Doc updates
4 years ago
Dibyendu Majumdar 971a165d95 Doc updates
4 years ago
Dibyendu Majumdar 6e62ff2351 formatting
4 years ago
Dibyendu Majumdar efccd8bd9f issue #169 add remaining opcodes
4 years ago
Dibyendu Majumdar e0ebac6d7a Reformat
4 years ago
Dibyendu Majumdar d0c95d16c9 issue #169 add support for int bit ops and unm op codes; however this has caused for num loop tests to fail where a string value is being used
4 years ago
Dibyendu Majumdar 3df623c029 issue #169 Update doc
4 years ago
Dibyendu Majumdar f92ef5084a Formatting
4 years ago
Dibyendu Majumdar 9479a76ce4 issue #169 add MIR builds to CI
4 years ago
Dibyendu Majumdar 31824e2a9b issue #169 add op_defer support in JIT backend
4 years ago
Dibyendu Majumdar da64639ef1 issue #171 fix build
4 years ago
Dibyendu Majumdar 2c13ac8ee8 Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
4 years ago
Dibyendu Majumdar 6967c5d54b issue #169
4 years ago
Dibyendu Majumdar 803acc3d1d issue #171
4 years ago
Dibyendu Majumdar 3e5df1fdb8 issue #171
4 years ago
Dibyendu Majumdar feae81c25f
Various updates
4 years ago
Dibyendu Majumdar 39a5e40b5f
Update ravi-mir-instructions.rst
4 years ago
Dibyendu Majumdar c66883c4c0
Update ravi-overview.rst
4 years ago
Dibyendu Majumdar 7d218c2160
Update README.rst
4 years ago
Dibyendu Majumdar e04a016b74 Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
4 years ago
Dibyendu Majumdar 483569d8db issue #171 SETLIST is no longer an inline op code in the VM
4 years ago
Dibyendu Majumdar 07d5390d7e
Added defer statement
4 years ago
Dibyendu Majumdar f7c09814d0 Updated docs
4 years ago
Dibyendu Majumdar 0fe4cf90d0
Update index.rst
4 years ago
Dibyendu Majumdar 60c71e7099
Create ravi-mir-instructions.rst
4 years ago
Dibyendu Majumdar 662b2f905f
Updated plans for 2020
4 years ago
Dibyendu Majumdar 8214dbe04c
Create README.md
4 years ago
Dibyendu Majumdar 1621ac50ab Add MIR project
4 years ago
Dibyendu Majumdar 8c6387facf issue #169 cleanup
4 years ago
Dibyendu Majumdar 1e85a5b37a issue #169 cleanups
4 years ago
Dibyendu Majumdar 9b477bf5fe issue #169 update to latest MIR interface
4 years ago
Dibyendu Majumdar 66a37d14ea
Update README.rst
4 years ago
Dibyendu Majumdar d307677913 issue #163
4 years ago
Dibyendu Majumdar 12eda8ca0d issue #163 fix bugs - wrong type associated with the LLVM definition of raviV_op_defer()
4 years ago
Dibyendu Majumdar aaee69bfd2 issue #163 fix bugs - in particular the offet of value in UpVal has changed
4 years ago
Dibyendu Majumdar 07a422eb74 issue #163 fixes related to loading of base following luaF_close
4 years ago
Dibyendu Majumdar 6f29bc6cd8 issue #163 add DEFER bytecode to LLVM backend
4 years ago
Dibyendu Majumdar 51eeb4e8c2 issue #163 simplify defer statement and fix memory leak
4 years ago
Dibyendu Majumdar edce55b997 issue #163 Base must be protected as luaF_close can now reallocate stack due to invocation of deferred functions
4 years ago
Dibyendu Majumdar 9a0ced9620 issue #163 First attempt to implement a Go like defer statement
4 years ago
Dibyendu Majumdar de42b8b0eb issue #98 some work work on type checking - table expressions, do while and repeat statements
4 years ago
Dibyendu Majumdar 2c66f62c09
Update README.rst
5 years ago
Dibyendu Majumdar bdaa211faf Merge branch 'master' into mir
5 years ago
Dibyendu Majumdar 2e748fcefc issue #169
5 years ago
Dibyendu Majumdar 4727dd052a issue #170 Add support for LLVM 9
5 years ago
Dibyendu Majumdar 4e445f46bf issue #169 Add initial support for MIR JIT backend
5 years ago
Dibyendu Majumdar 41135f39c0 issue #110 Do not generate fcmpne or dcmpne because these op codes cause a crash in the X86 codegen later on during optimization
5 years ago
Dibyendu Majumdar c3952c2b98 issue #98 add type conversion for some assignments
5 years ago
Dibyendu Majumdar e4f0b7aa1a issue #98 type check for statements
5 years ago
Dibyendu Majumdar 859eb75316 issue #98 type check for statements
5 years ago
Dibyendu Majumdar fecb13dbc2 issue #98 type check for statements
5 years ago
Dibyendu Majumdar db626e34c1 issue #98 type check for statements
5 years ago
Dibyendu Majumdar 22daaf8588 Set mayHaveLoops flag to trigger loop optimzation at O2
5 years ago
Dibyendu Majumdar 99d9fcbdd2 issue #98 make the normal parser consistent with the new typechecker
5 years ago
Dibyendu Majumdar 6b5315366a issue #98 print type info for some more ast nodes
5 years ago
Dibyendu Majumdar 4ad83f8abf issue #98 typecheck expression statements
5 years ago
Dibyendu Majumdar 271bbc7e5a Fix library name when building static version and reformat CMakeLists.txt
5 years ago
Dibyendu Majumdar 5d75cf64e7 issue #165 added dockerfile for ubuntu
5 years ago
Dibyendu Majumdar 7dd9e9b1d2 issue #164 disable ORCv2 in LLVM 8 temporarily
5 years ago
Dibyendu Majumdar 4c39afe84e issue #98 typecheck local stmt (incomplete)
5 years ago
Dibyendu Majumdar 5d03214477 issue #98 renaming of fields for consistency
5 years ago
Dibyendu Majumdar e2f91553b6 issue #98 more on suffixed expr typechecks
5 years ago
Dibyendu Majumdar cf7f4b33c0 issue #98 start to implement suffixed expr typechecks
5 years ago
Dibyendu Majumdar b2120b97cc issue #98 implement type checks for binary operators
5 years ago
Dibyendu Majumdar a5bfc25163 issue #98 split up the source for the AST parser to make it more workable
5 years ago
Dibyendu Majumdar 5b15a2ffce issue #164 try to get ORC v2 working
5 years ago
Dibyendu Majumdar 9c88c84b0f issue #164
5 years ago
Dibyendu Majumdar d3898daa5b
Update ravi-llvm-instructions.rst
5 years ago
Dibyendu Majumdar 51268d59df
Update ravi-llvm-instructions.rst
5 years ago
Dibyendu Majumdar 01e67ee61e issue #164 try to get ORC v2 working
5 years ago
Dibyendu Majumdar 58c0b2c8df issue #164 try to get ORC v2 working
5 years ago
Dibyendu Majumdar 5f8bf68a3e issue #164 simplify code as suggested by Lang Hames
5 years ago
Dibyendu Majumdar 529169d816 issue #126 fix seg fault due to attempt to remove a module was never added; also if env var RAVI_USE_DMRC_LLVM is set then enable dmrC based LLVM
5 years ago
Dibyendu Majumdar 9dfcd7c2b8 issue #126 add support for dmr_C based LLVM backend. Not enabled yet.
5 years ago
Dibyendu Majumdar b1396c8886 issue #114 experiment with for loop
5 years ago
Dibyendu Majumdar 2aa2515fe1 issue #164 optimizeModule() no longer static
5 years ago
Dibyendu Majumdar aa805c04a2 issue #164 trying our ORC v2 apis, but optimzation is broken so disable for now
5 years ago
Dibyendu Majumdar e1298a4e95 issue #164 trying our ORC v2 apis, but optimzation is broken so disable for now
5 years ago
Dibyendu Majumdar ba66177cbe Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
5 years ago
Dibyendu Majumdar b163aab427 issue #164 added support for llvm 8.0.1
5 years ago
Dibyendu Majumdar 426bc347e8
Update ravi-llvm-instructions.rst
5 years ago
Dibyendu Majumdar 5ce7810402 issue #164 added support for llvm 8.0.1
5 years ago
Dibyendu Majumdar 1b45bcf320 issue #164 added support for llvm 8.0.1
5 years ago
Dibyendu Majumdar b607cb0447 Add a test
5 years ago
Dibyendu Majumdar 46c64ba704 Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
5 years ago
Dibyendu Majumdar 9046fa7e3c Add a test
5 years ago
Dibyendu Majumdar a70a8c3dde
Added point about line terminators
5 years ago
Dibyendu Majumdar dca547868d
Use correct path to LLVM
5 years ago
Dibyendu Majumdar 10380ff4d0
Make dependency on xenial explicit
5 years ago
Dibyendu Majumdar 43de559a8a
Update LLVM 6.0.1 to 16.04 build
5 years ago
Dibyendu Majumdar f676ba9de1
Try to fix CI build issues - simplify
5 years ago
Dibyendu Majumdar 58cc6cf5e5 issue #157 cleanup api for getting access to array raw data and revise the inline short string table lookup so that we have an inline part and a slow part
5 years ago
Dibyendu Majumdar 8cafee0762
Create FUNDING.yml
5 years ago
Dibyendu Majumdar bb7aa82cfc
issue #98 update docs
5 years ago
Dibyendu Majumdar e05c35c01f
issue #135
5 years ago
Dibyendu Majumdar 5274ccca8e issue #135 update clang output
5 years ago
dibyendumajumdar 7a80bbdc80 issue #135 Save gcc 8.3 output
5 years ago
dibyendumajumdar 2672b86904 Merge branch 'master' of https://github.com/dibyendumajumdar/ravi
5 years ago
dibyendumajumdar 16f40a39f6 Fix gcc warning
5 years ago
Dibyendu Majumdar 58161ccc5d issue #135 missed file
5 years ago
Dibyendu Majumdar 16576517df issue #135 some restructuring
5 years ago
Dibyendu Majumdar c0d9b9018a
Update vm-design.rst
5 years ago
Dibyendu Majumdar b775fff18f
Update vm-design.rst
5 years ago
Dibyendu Majumdar 91071c376e
Update vm-design.rst
5 years ago
Dibyendu Majumdar 81b4b1fb35 doc updates and some minor reformatting
5 years ago
Dibyendu Majumdar 72b5dc551a issue #98 tiny bit of work in type checking - table expr
5 years ago
Dibyendu Majumdar fe3ca414f1 issue #98 tiny bit of work in type checking - table expr
5 years ago
Dibyendu Majumdar 93121f3afe issue #98 tiny bit of work in type checking, handle unary expr
5 years ago
dibyendumajumdar fe2632bad9 The simple makefile build should not enable assertions and ltests
5 years ago
Dibyendu Majumdar e59e5e63c7
Fix issue #162
5 years ago
Dibyendu Majumdar a92416f864 issue #98 fix compile error
5 years ago
Dibyendu Majumdar 3a98ffe3c2 issue #98 dump list of locals for each function, and start work on type checker
5 years ago
Dibyendu Majumdar 65ad3ea3e3 issue #98 more testing
5 years ago
Dibyendu Majumdar f9c74b3b08 issue #98 fix bug in while parsing - remove extra endscope
5 years ago
Dibyendu Majumdar 2912415983 issue #98 fix parsing of consecutive labels
5 years ago
Dibyendu Majumdar e0b4d65402 issue #98 cleanup
5 years ago
Dibyendu Majumdar 83bcfcbed2 issue #98 add missing end_function() calls
5 years ago
Dibyendu Majumdar 2f85d6e8bc issue #98 reformat
5 years ago
Dibyendu Majumdar 06335d0d36 issue #98 cleanup
5 years ago
Dibyendu Majumdar 7385d76f12 issue #98 refactor scope and ast so that statement lists are no longer in scope
5 years ago
Dibyendu Majumdar 74e8c76f5a issue #98 fix bug - final return not handled correctly, and ensure on parser failure error message is pushed as a second value after nil
5 years ago
Dibyendu Majumdar 90bb58272f
Update README.rst
5 years ago
Dibyendu Majumdar 04b1885011 issue #98 redo upvalue implementation - wip
5 years ago
Dibyendu Majumdar abe4759bc7 issue #114 fix bug in handling of function call
5 years ago
Dibyendu Majumdar b95a2e7016 issue #98 Reformat using clangformat
5 years ago
Dibyendu Majumdar 631e237ef9 comments etc
5 years ago
Dibyendu Majumdar 01eb83dcfe issue #161 avoid taking address of math functions in the fast call scenario, instead assign unique codes to functions that may be inlined
5 years ago
Dibyendu Majumdar 45716255c0 Add some tests
6 years ago
Dibyendu Majumdar 9204624217 issue #110
6 years ago
Dibyendu Majumdar 2bed233296
Update ravi-dmrc.rst
6 years ago
dibyendumajumdar f057c79ccf issue #157
6 years ago
Dibyendu Majumdar 1216ebfaa2 issue #157
6 years ago
Dibyendu Majumdar d27dbd7619 issue #110
6 years ago
Dibyendu Majumdar 41265afe96 issue #157
6 years ago
Dibyendu Majumdar 37e0bda162 issue #160
6 years ago
Dibyendu Majumdar e5b5ae9f05 issue #110
6 years ago
Dibyendu Majumdar ebff2906c7 issue #110
6 years ago
Dibyendu Majumdar 62d5bace74
Update README.rst
6 years ago
Dibyendu Majumdar 680c35bacb
Update README.rst
6 years ago
Dibyendu Majumdar ceeb4d86bf issue #110 update savedpc befaore function calls
6 years ago
Dibyendu Majumdar cb3f9282e5 issue #110 bug fix
6 years ago
Dibyendu Majumdar e3522a470d issue #126 use setjmp/longjmp to handle fatal errors
6 years ago
Dibyendu Majumdar b1fc484492 issue #126 use setjmp/longjmp for error handling
6 years ago
Dibyendu Majumdar 52800b4be9 issue #157
6 years ago
Dibyendu Majumdar 07db5d1008 issue #157 code comments
6 years ago
Dibyendu Majumdar 08157b102c issue #157 rename bytecodes
6 years ago
Dibyendu Majumdar 5e552ab4a7 issue #157 more renaming of bytecodes
6 years ago
Dibyendu Majumdar 489e118012 issue #157 more renaming of bytecodes
6 years ago
Dibyendu Majumdar b65c595e05 issue #157 import from Lua 5.4 changes to the way number conversions are done in the VM to push string coersion down to string metamethods
6 years ago
Dibyendu Majumdar dd593cdcd5 issue #157 import from Lua 5.4 changes to the way number conversions are done in the VM to push string coersion down to string metamethods
6 years ago
Dibyendu Majumdar 21028d833b issue #157 more renaming of op codes
6 years ago
Dibyendu Majumdar 31f4e178ee issue #157 more opcode renaming
6 years ago
Dibyendu Majumdar fc6929aa58 issue #157 more opcode renaming
6 years ago
Dibyendu Majumdar f66b38dc99 issue #158 fix test failure
6 years ago
Dibyendu Majumdar 126e7fb461 issue #158 fix test failure
6 years ago
Dibyendu Majumdar edac3648f0 issue #158 import the string metamethods from 5.4
6 years ago
Dibyendu Majumdar 7041827d53 issue #157 rename the array get/set op codes
6 years ago
Dibyendu Majumdar eec9a49414 issue #157: rename GETTABLE_SK and SETTABLE_SK opcodes
6 years ago
Dibyendu Majumdar 04ca32e8f5 Remove the metatable api alternatives
6 years ago
Dibyendu Majumdar d4d679bb3c issue #156
6 years ago
Dibyendu Majumdar fe8e4d5c0b initial attempt to fix bug in opt when local values have their address taken
6 years ago
Dibyendu Majumdar e4187524d7
Create ravi-new-parser-codegenerator.rst
6 years ago
Dibyendu Majumdar af01269bb8 issue #110 doc update
6 years ago
Dibyendu Majumdar f588644396 issue #110 update doc
6 years ago
Dibyendu Majumdar 8ab1f6641d issue #110 update doc
6 years ago
Dibyendu Majumdar 3ee99e64f8 issue #110 update doc
6 years ago
Dibyendu Majumdar 6ba107d7e6 issue #110 update doc
6 years ago
Dibyendu Majumdar 91302e10a0 issue #110 update doc
6 years ago
Dibyendu Majumdar 2fa8a00291 issue #110 update doc
6 years ago
Dibyendu Majumdar 2d646a0bde issue #110 Enable setting opt level
6 years ago
Dibyendu Majumdar 82ebd78a15 issue #150 Set NDEBUG in CMakeLists.txt for non debug builds so that we don't get LTESTS enabled in non debug builds
6 years ago
Dibyendu Majumdar 21427cf741 issue #98
6 years ago
Dibyendu Majumdar 478375f354 issue #98
6 years ago
Dibyendu Majumdar 0574ec24b9 issue #110 doc update
6 years ago
Dibyendu Majumdar 026b514c41 issue #110 doc update
6 years ago
Dibyendu Majumdar 1f1115eb06 issue #110 add more specific method calls for table set/get ops
6 years ago
Dibyendu Majumdar 90a901495a Apply corrections from Gavin Wraith
6 years ago
Dibyendu Majumdar 79e5655b11
Update ravi-reference.rst
6 years ago
Dibyendu Majumdar 073fc2bacc
Update ravi-reference.rst
6 years ago
Dibyendu Majumdar d3c7285248
Update ravi-reference.rst
6 years ago
Dibyendu Majumdar 821db89d66
Update ravi-reference.rst
6 years ago
Dibyendu Majumdar bdbb10a096
Update ravi-reference.rst
6 years ago
Dibyendu Majumdar 0fbc730ed9
Update ravi-reference.rst
6 years ago
Dibyendu Majumdar 257ed680d1
Update ravi-reference.rst
6 years ago
Dibyendu Majumdar 5f4b94bed6 issue #110 dump C intermediate code if verbosity is on
6 years ago
Dibyendu Majumdar d704a04189 Documentation refactoring
6 years ago
Dibyendu Majumdar 605dedbb54 Documentation refactoring
6 years ago
Dibyendu Majumdar a93a091c82 Documentation refactoring
6 years ago
Dibyendu Majumdar 849e15558f Documentation refactoring
6 years ago
Dibyendu Majumdar 6ad06fe402 Documentation refactoring
6 years ago
Dibyendu Majumdar c7428f1dfc Documentation refactoring
6 years ago
Dibyendu Majumdar 3def57baf8 issue #110 option to inline some arithmetic ops
6 years ago
Dibyendu Majumdar 5d5d036fdc issue #110 more opcodes
6 years ago
Dibyendu Majumdar 3e1d1bc752 issue #110 add support for a few more op codes
6 years ago
Dibyendu Majumdar 31bb288c2c issue #98 rearrange code
6 years ago
Dibyendu Majumdar f6fc9b100b issue #98 rearrange code
6 years ago
Dibyendu Majumdar d3cf8fb6b4 issue #110 avoid calling functions with local vars passed by reference due to incorrect opt by OMR JIT; this also means that we cannot do implicit conversions in some opcodes such as the arith opcodes or for num loops
6 years ago
Dibyendu Majumdar 405fc20f91 issue #110 add support for omitting range checks on array read access for OMR JIT
6 years ago
Dibyendu Majumdar 8830789362 issue #110 updates to dmrC
6 years ago
Dibyendu Majumdar 9f3043dcc9 reduce compiler noise (warnings)
6 years ago
Dibyendu Majumdar 183f932b23 try to fix travis build
6 years ago
Dibyendu Majumdar 365a4157af issue #110 refactoring
6 years ago
Dibyendu Majumdar a11cf5ae66 issue #110 fix missing refresh of base pointer and define full set of loop vars even for the int loop instruction
6 years ago
Dibyendu Majumdar 1c97bd1974 issue #110 add implementations of JIT api
6 years ago
Dibyendu Majumdar 1a8c432625 issue #110 fix stupid typo bug in ravi_jitshared (emit_op_movef) and add implementations of JIT api
6 years ago
Dibyendu Majumdar bc76d7a7ab issue #110 reformat code
6 years ago
Dibyendu Majumdar 7d465a0ab5 issue #110 #154
6 years ago
Dibyendu Majumdar 74cb2401d8 issue #31 tidy up
6 years ago
Dibyendu Majumdar ae04b04e05 Various cleanups mainly to reduce compiler warnings as part of issue #110
6 years ago
Dibyendu Majumdar b9bc276a23 tech debt compiler warnings
6 years ago
Dibyendu Majumdar 471280ca3a tech debt compiler warnings
6 years ago
Dibyendu Majumdar 7a055dc0c2 formatting and compiler warnings
6 years ago
Dibyendu Majumdar 831120e143 issue #110 continuing attempts to provide better aliasing info to omr jit backend
6 years ago
Dibyendu Majumdar 7e00e0d2e3 issue #110 prep for slow arith ops
6 years ago
Dibyendu Majumdar 5dbaf0b391 issue #110 C code gen - update to emit go to error block
6 years ago
Dibyendu Majumdar 37a98cdbc7 issue #126: trim dmr_C by removing the simplification passes
6 years ago
Dibyendu Majumdar be20b2e37e
Explain wht dmr_C is for
6 years ago
Dibyendu Majumdar 6a7cd48d0e issue #110 experiments
6 years ago
Dibyendu Majumdar a073d0277d issue #110 add build script helper for omrjit backend
6 years ago
Dibyendu Majumdar d51e2224ae issue #110 wip perf fixes
6 years ago
Dibyendu Majumdar ef60e52ce4 issue #110 fix to dmrC
6 years ago
Dibyendu Majumdar 47e0cddfaf issue #110 Initial implementation of JIT backend using OMRJIT
6 years ago
Dibyendu Majumdar a3757ce010 issue #110 report omrjit
6 years ago
Dibyendu Majumdar 8f105712b5 issue #110 Bring JIT C codegen up to date
6 years ago
dibyendumajumdar 5afdd3f6bb issue #114 fix compilation error on Linux
6 years ago
Dibyendu Majumdar 1583e618ab issue #114 complete rename
6 years ago
Dibyendu Majumdar 7dec6fa08f issue #114 add new LUA_TFUNCTION subtype to allow direct (faster) calls to simple C functions
6 years ago
Dibyendu Majumdar 4676f220a4 issue #114 Prepare for implementing fast C calls; the Lua typecode is extended to 16 bits to allow more type variants to be added. The intention is that for light C functions, we can encode return type / parameter types to enable calling some C functions directly without having to go through the Lua api.
6 years ago
Dibyendu Majumdar 5c17bca34e Some cleanup
6 years ago
Dibyendu Majumdar 77c044c0cf issue #126 fix problems with symbol parser
6 years ago
Dibyendu Majumdar e10ab7b04f issue #126 dmr_C now integral part of Ravi
6 years ago
Dibyendu Majumdar c2cd74143e issue #126 remove dmr_C as a submodule
6 years ago
Dibyendu Majumdar aef846e9cc issue #150 only set NO_LUA_DEBUG when LTESTS is OFF
6 years ago
Dibyendu Majumdar bdbbe5e021 issue #150 remove ltests.h and include its contents in lua.h. Now Debug builds will always enable ltests, however, we will not mess with the Lua data structures or other settings
6 years ago
Dibyendu Majumdar be1f7e82ce issue #151 enable dlmalloc
6 years ago
Dibyendu Majumdar 60eccabd2b issue #151 enable dlmalloc by default
6 years ago
Dibyendu Majumdar aa7e271083 issue #151 adopt Doug Lea's allocator
6 years ago
Dibyendu Majumdar b584ce9862 issue #151 memory allocator updates
6 years ago
Dibyendu Majumdar 4ccf6cb2ef issue #151 fix compile on Linux
6 years ago
Dibyendu Majumdar 73c31bb59d issue #151 import LuaJIT's allocator
6 years ago
Dibyendu Majumdar 7ad859f79b issue #151 import LuaJIT's allocator
6 years ago
Dibyendu Majumdar a3fdf76103 issue #98 refactoring and start on value types
6 years ago
Dibyendu Majumdar 693c2b716e issue #98 some code cleanup
6 years ago
Dibyendu Majumdar d27e18d617 issue #98 for/while/repeat statement revision to make AST more syntax tree like, and various cleanups
6 years ago
Dibyendu Majumdar 29a507b911 issue #98 for statement parsing - wip
6 years ago
Dibyendu Majumdar 2d30da5bd0 issue #98 more on while and repeat statement parsing
6 years ago
Dibyendu Majumdar 01cb2ad69d issue #98 start on while/repeat statements
6 years ago
Dibyendu Majumdar 20c7e6c4e5 issue #98 if statement parsing
6 years ago
Dibyendu Majumdar 463d0bbd71 issue #98 added if statement parsing
6 years ago
Dibyendu Majumdar 49b8fdea0f issue #98 function call, assignment and expression statement parsing
6 years ago
Dibyendu Majumdar 7a5aef4989 issue #98 parse do statement
6 years ago
Dibyendu Majumdar b3ad4d2579 issue #98 goto and label statements parsing
6 years ago
Dibyendu Majumdar e6daa68980 issue #98 fix incorrect use of stack value, and add more tests
6 years ago
Dibyendu Majumdar 19d13d5817 issue #98 start adding some tests
6 years ago
Dibyendu Majumdar cb7977d4bb issue #98 function parameter parsing fix and a different attempt to output the parse tree
6 years ago
Dibyendu Majumdar c9b7939cc1 issue #98 instead of printing out generate a string from ast and expose as api method
6 years ago
Dibyendu Majumdar 5978dcfb42 issue #98 fix scoping
6 years ago
Dibyendu Majumdar 3a042f0ade issue #98 function statement parsing
6 years ago
Dibyendu Majumdar 5c714ff948 issue #98 function parsing, and print up-values too
6 years ago
Dibyendu Majumdar 9dc2630ecf issue #98 parse function literal
6 years ago
Dibyendu Majumdar 2e0af5cecc issue #98 local statement parsing
6 years ago
Dibyendu Majumdar 48807fb351 issue #98 local statement parsing
6 years ago
Dibyendu Majumdar fff8452d21 issue #98 start on local vars
6 years ago
Dibyendu Majumdar 8ba41946dc issue #98 improve output of AST
6 years ago
Dibyendu Majumdar 45e41e044b issue #98 improve output of AST
6 years ago
Dibyendu Majumdar ebebb72416 issue #98 return statement and more on printing out the AST
6 years ago
Dibyendu Majumdar 051f75b8c0 issue #98 block scope has statement list
6 years ago
Dibyendu Majumdar 67accd8a41 issue #98 refactor ast library to be just a library and resolve the issue with lua_lock()
6 years ago
Dibyendu Majumdar 0a69234b07 issue #98 return statement
6 years ago
Dibyendu Majumdar 417c2965cc issue #98 unary and binary sub expression parsing
6 years ago
Dibyendu Majumdar 00847ef2b8 issue #98 suffixed expr
6 years ago
Dibyendu Majumdar 79a4265962 issue #98 primary expr
6 years ago
Dibyendu Majumdar 7547883b54 issue #98 parse table constructors
6 years ago
Dibyendu Majumdar 20052594a1 issue #98 more work on basics: including searching for vars in scopes
6 years ago
Dibyendu Majumdar fc95eb1223 issue #98 more work on function and scope linkage
6 years ago
Dibyendu Majumdar e42073b064 issue #98 initial steps in setting up scope and attempt to create main function
6 years ago
Dibyendu Majumdar 7ce94baedc issue #98 more work on fleshing out function, block and ast structure
6 years ago
Dibyendu Majumdar 6a2f94953a issue #98 more work on fleshing out function, block and ast structure
6 years ago
Dibyendu Majumdar b39fdf9399 issue #98 added ptrlist and started to flesh out ast structures
6 years ago
Dibyendu Majumdar f3fed79bc7 issue #98 start changing the api so that build_ast returns a userdata object containing the AST
6 years ago
Dibyendu Majumdar c465af3465 issue #98 rename functions and start to change the api to construct AST as a userdata object
6 years ago
Dibyendu Majumdar 24ac6f29f3 issue #98 merge changes in master
6 years ago
Dibyendu Majumdar f9793dc527 issue #136 added support for user defined type names to have '.' in them
6 years ago
Dibyendu Majumdar 855773dec7 issue #98 wip
7 years ago
Dibyendu Majumdar 61da43d105 issue #98 wip
7 years ago
Dibyendu Majumdar d477e76155 issue #98 merge changes from master
7 years ago
Dibyendu Majumdar 996bffcbc9 issue #98 add a simple bump allocator
8 years ago
Dibyendu Majumdar 0fd9d953a1 issue #98
8 years ago
Dibyendu Majumdar 8e4eb5b4e2 issue #98
8 years ago
Dibyendu Majumdar 19510c7ace Merge branch 'master' into ast
8 years ago
Dibyendu Majumdar 087489ebb9 issue #100 add tests from lua test suite
8 years ago
Dibyendu Majumdar 62922d4e85 issue #98 merge master into ast branch
8 years ago
Dibyendu Majumdar dc4c00faa0 Merge branch 'master' into ast
8 years ago
Dibyendu Majumdar 5270e64802 lu decomp sample
8 years ago
Dibyendu Majumdar 0ebd3e5536 lu decomp sample
8 years ago
Dibyendu Majumdar 70af72c2c7 lu decomp sample
8 years ago
Dibyendu Majumdar a602f7246c ast wip
8 years ago
Dibyendu Majumdar 1916346886 ast wip
8 years ago
Dibyendu Majumdar 22146f6bc8 ast wip
8 years ago
Dibyendu Majumdar 8882799d67 abstract syntax tree
8 years ago

@ -9,11 +9,11 @@ AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
@ -35,7 +35,7 @@ BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 80
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4

@ -0,0 +1,7 @@
# [Choice] Debian / Ubuntu version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
ARG VARIANT=buster
FROM mcr.microsoft.com/vscode/devcontainers/cpp:dev-${VARIANT}
# [Optional] Uncomment this section to install additional packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>

@ -0,0 +1,12 @@
# [Choice] Debian / Ubuntu version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
ARG VARIANT=buster
FROM mcr.microsoft.com/vscode/devcontainers/base:${VARIANT}
# Install needed packages. Use a separate RUN statement to add your own dependencies.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install build-essential cmake cppcheck valgrind clang lldb llvm gdb \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>

@ -0,0 +1,28 @@
{
"name": "C++",
"build": {
"dockerfile": "Dockerfile",
// Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
"args": { "VARIANT": "debian-10" }
},
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-vscode.cpptools"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "gcc -v",
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode"
}

@ -0,0 +1,48 @@
name: build
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
run: sudo apt-get install -y libreadline-dev
- name: Create Build Environment
run: cmake -E make_directory ${{runner.workspace}}/build
- name: Configure CMake
# Use a bash shell so we can use the same syntax for environment variable
# access regardless of the host operating system
shell: bash
working-directory: ${{runner.workspace}}/build
# Note the current convention is to use the -S and -B options here to specify source
# and build directories, but this is only available with CMake 3.13 and higher.
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
- name: Build
working-directory: ${{runner.workspace}}/build
shell: bash
# Execute the build. You can specify a specific target with "--target <NAME>"
run: cmake --build . --config $BUILD_TYPE
- name: Test
shell: bash
run: cd tests && sh run_tests.sh ${{runner.workspace}}/build/ravi

11
.gitignore vendored

@ -4,3 +4,14 @@ CMakeScripts
cmake_install.cmake
install_manifest.txt
CTestTestfile.cmake
build
buildmir
omrjit
buildllvm
.vscode
.idea
cmake-build-debug
cmake-build-release
buildnojit
nojit
nojita

4
.gitmodules vendored

@ -1,3 +1 @@
[submodule "dmr_c"]
path = dmr_c
url = https://github.com/dibyendumajumdar/dmr_c.git

@ -1,33 +1,20 @@
language: cpp
os:
- linux
env:
- ARCH="x86_64"
arch:
- amd64
- arm64
compiler:
- gcc
cache: ccache
dist: focal
addons:
apt:
sources:
- llvm-toolchain-precise
- ubuntu-toolchain-r-test
packages:
- clang-3.7
- g++-5
- gcc-5
- gcc
- ccache
install:
- if [ "$CXX" = "g++" ]; then export CXX="ccache g++-5" CC="ccache gcc-5"; fi
- if [ "$CXX" = "clang++" ]; then export CXX="ccache clang++-3.7" CC="ccache clang-3.7"; fi
- curl https://cmake.org/files/v3.4/cmake-3.4.0-Linux-x86_64.tar.gz | tar -xzf -
- curl http://www.llvm.org/releases/3.7.0/llvm-3.7.0.src.tar.xz | tar -xJf -
- mkdir $TRAVIS_BUILD_DIR/llvm-3.7.0.src/build
- cd $TRAVIS_BUILD_DIR/llvm-3.7.0.src/build && $TRAVIS_BUILD_DIR/cmake-3.4.0-Linux-x86_64/bin/cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/LLVM37 -DLLVM_TARGETS_TO_BUILD="X86" ..
- cd $TRAVIS_BUILD_DIR/llvm-3.7.0.src/build && make install
script:
- if [ "$CXX" = "g++" ]; then export CXX="ccache g++-5" CC="ccache gcc-5"; fi
- if [ "$CXX" = "clang++" ]; then export CXX="ccache clang++-3.7" CC="ccache clang-3.7"; fi
- mkdir $TRAVIS_BUILD_DIR/build
- cd $TRAVIS_BUILD_DIR/build && $TRAVIS_BUILD_DIR/cmake-3.4.0-Linux-x86_64/bin/cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_DIR=/tmp/LLVM37/share/llvm/cmake -G "Unix Makefiles" -DLLVM_JIT=ON ..
- cd $TRAVIS_BUILD_DIR/build && make
- cd $TRAVIS_BUILD_DIR/lua-tests && sh ./run_travis_tests.sh $TRAVIS_BUILD_DIR/build/ravi
- mkdir $TRAVIS_BUILD_DIR/buildmir
- cd $TRAVIS_BUILD_DIR/buildmir && cmake -DCMAKE_BUILD_TYPE=Debug -DLTESTS=ON -DMIR_JIT=ON -G "Unix Makefiles" ..
- cd $TRAVIS_BUILD_DIR/buildmir && make
- cd $TRAVIS_BUILD_DIR/tests && sh ./run_tests.sh $TRAVIS_BUILD_DIR/buildmir/ravi

@ -1,197 +1,99 @@
cmake_minimum_required(VERSION 2.8)
project(Ravi)
cmake_minimum_required(VERSION 3.12)
project(Ravi VERSION 1.0.4 LANGUAGES C)
enable_language(CXX)
enable_language(C)
enable_language(ASM)
enable_testing()
# By default MIR JIT backend is automatically enabled. To disable user must specify
# NO_JIT=ON
# By default JIT is OFF
option(LLVM_JIT "Controls whether LLVM JIT compilation will be enabled, default is OFF" OFF)
option(NO_JIT "Controls whether JIT should be disabled, default is OFF" OFF)
option(STATIC_BUILD "Build static version of Ravi, default is OFF" OFF)
option(EMBEDDED_DMRC "Controls whether the embedded dmrC feature should be enabled, default is OFF" OFF)
option(COMPUTED_GOTO "Controls whether the interpreter switch will use computed gotos on gcc/clang, default is OFF" ON)
option(ASM_VM "Controls whether to use the new VM (not ready yet! so don't turn on)" OFF)
option(LTESTS "Controls whether ltests are enabled in Debug mode" OFF)
if (LLVM_JIT)
set(ASM_VM OFF)
endif()
option(COMPUTED_GOTO "Controls whether the interpreter switch will use computed gotos on gcc/clang, default is ON" ON)
option(LTESTS "Controls whether ltests are enabled in Debug mode; note requires Debug build" ON)
option(ASAN "Controls whether address sanitizer should be enabled" OFF)
option(RAVICOMP "Controls whether to link in RaviComp" ON)
# By we enable MIR JIT
if (NOT NO_JIT)
set(MIR_JIT ON)
endif ()
if (ASM_VM)
# For now we switch to static build
# TODO A fix is needed to ensure that in shared library the asm functions are resolved
set(STATIC_BUILD ON)
set(LTESTS OFF)
endif()
if (MIR_JIT)
set(STATIC_BUILD OFF) # Because we need to expose the symbols in the library
endif ()
if (STATIC_BUILD)
message(STATUS "STATIC library build enabled")
else()
set(LIBRAVI_BUILD_TYPE STATIC)
else ()
message(STATUS "DYNAMIC library build enabled")
endif()
if (LLVM_JIT)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
# We also need to define USE_LLVM when compiling code
# but rather than setting globally we set this when building the
# library
endif()
set(LIBRAVI_BUILD_TYPE SHARED)
endif ()
message(STATUS "Computed goto ${COMPUTED_GOTO}")
if (COMPUTED_GOTO AND MSVC)
message(WARNING "Computed goto is not available with MSVC")
endif()
if (NOT LLVM_JIT)
message(WARNING "LLVM will not be enabled; specify -DLLVM_JIT=ON to enable")
endif()
if (MSVC)
set(CMAKE_C_FLAGS_DEBUG "/Od /D_DEBUG /MDd /Zi /RTC1 /EHsc")
set(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /MD /EHsc")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/DNDEBUG /O2 /MD /Zi /EHsc")
set(CMAKE_C_FLAGS_MINSIZEREL "/DNDEBUG /O2 /MD /EHsc")
set(CMAKE_CXX_FLAGS "/EHsc")
set(CMAKE_CXX_FLAGS_DEBUG "/Od /D_DEBUG /MDd /Zi /RTC1 /EHsc")
set(CMAKE_CXX_FLAGS_RELEASE "/DNDEBUG /O2 /MD /EHsc")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/DNDEBUG /O2 /MD /Zi /EHsc")
set(CMAKE_CXX_FLAGS_MINSIZEREL "/DNDEBUG /O2 /MD /EHsc")
# Disable signed/unsigned int conversion warnings.
add_definitions("/wd4018")
# Disable warning about using struct/class for the same symobl.
add_definitions("/wd4099")
# Disable performance warning about int-to-bool conversion.
add_definitions("/wd4800")
# Disable signed/unsigned int conversion warnings.
add_definitions("/wd4018")
# Disable warning about the insecurity of using "std::copy".
add_definitions("/wd4996")
add_definitions("/wd4291")
add_definitions("/wd4624")
add_definitions("/wd4141")
add_definitions("/DLUA_COMPAT_5_2")
add_definitions("/DLUA_COMPAT_5_1")
elseif ((CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") AND NOT APPLE)
if (NOT WIN32)
# assume Linux
set(OS_FLAGS "-DLUA_USE_LINUX")
endif ()
# set(SANITIZER_FLAGS "-fsanitize=address")
set(LUA_COMPAT_FLAGS "-DLUA_COMPAT_5_2 -DLUA_COMPAT_5_1")
set(CMAKE_C_FLAGS "-std=c99 -O2 -fomit-frame-pointer -Wall -Wextra -Winline ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "${SANITIZER_FLAGS} -fno-omit-frame-pointer -std=c99 -O0 -g3 -Wall -Wextra ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_C_FLAGS_RELEASE "-std=c99 -O2 -fomit-frame-pointer -Wall -Wextra -Winline ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${SANITIZER_FLAGS} -std=c99 -O1 -g3 -Wall -Wextra ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_CXX_FLAGS "-fno-rtti -O2 -fomit-frame-pointer -Wall -Wno-sign-compare -Winline -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "-fno-rtti -O2 -fomit-frame-pointer -Wall -Wno-sign-compare -Winline -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${SANITIZER_FLAGS} -fno-omit-frame-pointer -fno-rtti -O0 -g3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${SANITIZER_FLAGS} -fno-rtti -O1 -g3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} ${OS_FLAGS}")
elseif (APPLE)
set(LUA_COMPAT_FLAGS "-DLUA_COMPAT_5_2 -DLUA_COMPAT_5_1")
set(CMAKE_C_FLAGS "-std=c99 -O3 -Wall -Wextra ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_C_FLAGS_DEBUG "-std=c99 -O0 -g3 -Wall -Wextra ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_C_FLAGS_RELEASE "-std=c99 -O3 -Wall -Wextra ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-std=c99 -O1 -g3 -Wall -Wextra ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_CXX_FLAGS "-O3 -Wall -fno-rtti -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_CXX_FLAGS_RELEASE "-fno-rtti -O3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_CXX_FLAGS_DEBUG "-fno-rtti -O0 -g3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-fno-rtti -O1 -g3 -Wall -Wno-sign-compare -std=c++11 -fno-exceptions ${LUA_COMPAT_FLAGS} -DLUA_USE_MACOSX")
else()
message(FATAL_ERROR "Unsupported platform")
endif ()
include_directories("${PROJECT_SOURCE_DIR}/include")
if ((CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "DEBUG") AND LTESTS AND NOT ASM_VM)
# Note that enabling ltests.h messes with global_State and thus interferes with ASM_VM
message(STATUS "Enabling Lua extended test harness 'ltests'")
add_definitions(-DLUA_USER_H="ltests.h")
endif ()
if (ASM_VM)
# For now we switch to static build
# TODO A fix is needed to ensure that in shared library the asm functions are resolved
add_definitions(-DRAVI_USE_ASMVM)
set ( ASMVM_DEFS ${PROJECT_SOURCE_DIR}/include/ravi_asmvm_defs.h )
if (WIN32 AND NOT CYGWIN)
set(VMMODE peobj)
elseif (APPLE)
set(VMMODE machasm)
else()
set(VMMODE elfasm)
endif()
# This macro runs the buildvm command to generate the VM code
macro(add_buildvm_target _target _mode)
add_custom_command(OUTPUT ${_target}
COMMAND ${PROJECT_SOURCE_DIR}/vmbuilder/bin/buildvm ARGS -m ${_mode} -o ${_target} ${ARGN}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${PROJECT_SOURCE_DIR}/vmbuilder/bin/buildvm ${ARGN}
)
endmacro(add_buildvm_target)
# Generate ravi_asmvm.obj / ravi_asmvm.s (obj on Windows)
if ( WIN32 AND NOT CYGWIN )
add_buildvm_target ( ${CMAKE_CURRENT_BINARY_DIR}/ravi_asmvm.obj ${VMMODE} )
set (ASMVM_SRC ${CMAKE_CURRENT_BINARY_DIR}/ravi_asmvm.obj)
else ()
add_buildvm_target ( ${CMAKE_CURRENT_BINARY_DIR}/ravi_asmvm.s ${VMMODE} )
set (ASMVM_SRC ${CMAKE_CURRENT_BINARY_DIR}/ravi_asmvm.s)
endif ()
# Generate the ravi_bcdef.h header file
add_buildvm_target ( ${ASMVM_DEFS} bcdef ${LJLIB_C} )
SET (ASMVM_DEPS
${ASMVM_SRC}
${ASMVM_DEFS}
)
endif()
# define LLVM JIT compiler sources
if (LLVM_JIT)
set(LLVM_JIT_SRCS src/ravi_llvmjit.cpp src/ravi_llvmtypes.cpp
src/ravi_llvmcodegen.cpp src/ravi_llvmforprep.cpp src/ravi_llvmcomp.cpp
src/ravi_llvmreturn.cpp src/ravi_llvmload.cpp src/ravi_llvmforloop.cpp
src/ravi_llvmarith1.cpp src/ravi_llvmcall.cpp src/ravi_llvmtable.cpp
src/ravi_llvmarith2.cpp src/ravi_llvmtforcall.cpp src/ravi_llvmrest.cpp
src/ravi_llvmluaapi.cpp)
else()
set(NO_JIT_SRCS src/ravi_nojit.c)
endif()
# define the lua core source files
# define the Lua core source files
set(LUA_CORE_SRCS src/lapi.c src/lcode.c src/lctype.c src/ldebug.c src/ldo.c src/ldump.c
src/lfunc.c src/lgc.c src/llex.c src/lmem.c src/lobject.c src/lopcodes.c
src/lparser.c src/lstate.c src/lstring.c src/ltable.c src/ltm.c src/lundump.c
src/lvm.c src/lzio.c src/ravijit.cpp src/ltests.c src/ravi_profile.c src/ravi_membuf.c
src/ravi_jitshared.c src/bit.c)
src/lvm.c src/lzio.c src/ravi_jit.c src/ltests.c src/ravi_profile.c
src/ravi_membuf.c src/ravi_jitshared.c src/bit.c src/ravi_alloc.c)
# define the Lua library source files
set(LUA_LIB_SRCS src/lauxlib.c src/lbaselib.c src/lbitlib.c src/lcorolib.c src/ldblib.c src/liolib.c
src/lmathlib.c src/loslib.c src/ltablib.c src/lstrlib.c src/loadlib.c src/linit.c src/lutf8lib.c)
set(LUA_HEADERS include/lua.h include/luaconf.h include/lualib.h include/lauxlib.h)
set(MIR_JIT_SRCS src/ravi_mirjit.c)
set(NO_JIT_SRCS src/ravi_nojit.c)
set(LUA_CMD_SRCS src/lua.c)
set(RAVICOMP_SRCS src/ravi_complib.c)
file(GLOB RAVI_HEADERS "${PROJECT_SOURCE_DIR}/include/*.h")
if (COMPUTED_GOTO AND NOT MSVC)
if (CMAKE_C_COMPILER_ID MATCHES "Clang")
if (CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "AppleClang")
set_source_files_properties(src/lvm.c PROPERTIES COMPILE_FLAGS -DRAVI_USE_COMPUTED_GOTO)
elseif(CMAKE_C_COMPILER_ID MATCHES "GNU")
elseif (CMAKE_C_COMPILER_ID MATCHES "GNU")
set_source_files_properties(src/lvm.c PROPERTIES COMPILE_FLAGS "-fno-crossjumping -fno-gcse -DRAVI_USE_COMPUTED_GOTO")
endif()
endif()
# define the lua lib source files
set(LUA_LIB_SRCS src/lauxlib.c src/lbaselib.c src/lbitlib.c src/lcorolib.c src/ldblib.c src/liolib.c
src/lmathlib.c src/loslib.c src/ltablib.c src/lstrlib.c src/loadlib.c src/linit.c src/lutf8lib.c)
endif ()
endif ()
file(GLOB RAVI_HEADERS "${PROJECT_SOURCE_DIR}/include/*.h")
set(LUA_HEADERS include/lua.h include/luaconf.h include/lualib.h include/lauxlib.h)
include(CheckCCompilerFlag)
check_c_compiler_flag("-march=native" COMPILER_OPT_ARCH_NATIVE_SUPPORTED)
if (COMPILER_OPT_ARCH_NATIVE_SUPPORTED AND NOT CMAKE_C_FLAGS MATCHES "-march=")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native")
endif ()
if (ASAN)
set(CMAKE_REQUIRED_FLAGS "-fsanitize=address")
check_c_compiler_flag("-fsanitize=address" COMPILER_ASAN_SUPPORTED)
if (COMPILER_ASAN_SUPPORTED AND NOT CMAKE_C_FLAGS_DEBUG MATCHES "-fsanitize=address")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address")
endif ()
endif ()
if (MIR_JIT)
message(STATUS "MIRJIT enabled")
add_subdirectory(mir)
set(MIRJIT_LIBRARIES c2mir)
set(JIT_SRCS ${MIR_JIT_SRCS})
else ()
set(JIT_SRCS ${NO_JIT_SRCS})
endif ()
if (RAVICOMP)
set(ADDON_SRCS ${RAVICOMP_SRCS})
add_subdirectory(ravicomp)
set(RAVICOMP_LIBRARIES ravicomp)
endif ()
# IDE stuff
if (MSVC OR APPLE)
source_group("Ravi Headers" FILES ${RAVI_HEADERS})
source_group("Ravi Source Files" FILES ${LUA_CORE_SRCS} ${LUA_LIB_SRCS}
${LLVM_JIT_SRCS})
source_group("Ravi Source Files" FILES ${LUA_CORE_SRCS} ${LUA_LIB_SRCS} ${JIT_SRCS} ${ADDON_SRCS})
endif ()
# Misc setup
if (MSVC OR APPLE)
if (APPLE)
set(EXTRA_LIBRARIES m readline)
endif ()
@ -202,253 +104,132 @@ elseif (NOT WIN32)
set(EXTRA_LIBRARIES m dl readline)
endif ()
if (EMBEDDED_DMRC)
if (CMAKE_COMPILER_IS_GNUCC)
execute_process(COMMAND ${CMAKE_C_COMPILER} --print-file-name=
OUTPUT_VARIABLE GCC_BASE OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${CMAKE_C_COMPILER} -print-multiarch
OUTPUT_VARIABLE MULTIARCH_TRIPLET ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
add_definitions(-DGCC_BASE="${GCC_BASE}")
add_definitions(-DMULTIARCH_TRIPLET="${MULTIARCH_TRIPLET}")
endif()
message( STATUS "GCC_BASE_DIR : " ${GCC_BASE})
message( STATUS "MULTIARCH_TRIPLET : " ${MULTIARCH_TRIPLET} )
include_directories("${PROJECT_SOURCE_DIR}/dmr_c/src")
set(DMR_C_HEADERS
dmr_c/src/allocate.h
dmr_c/src/char.h
dmr_c/src/expression.h
dmr_c/src/flow.h
dmr_c/src/ident-list.h
dmr_c/src/linearize.h
dmr_c/src/lib.h
dmr_c/src/parse.h
dmr_c/src/port.h
dmr_c/src/ptrlist.h
dmr_c/src/scope.h
dmr_c/src/symbol.h
dmr_c/src/target.h
dmr_c/src/token.h
dmr_c/src/walksymbol.h
)
set(DMR_C_SRCS
dmr_c/src/allocate.c
dmr_c/src/builtin.c
dmr_c/src/char.c
dmr_c/src/cse.c
dmr_c/src/expression.c
dmr_c/src/evaluate.c
dmr_c/src/expand.c
dmr_c/src/flow.c
dmr_c/src/inline.c
dmr_c/src/lib.c
dmr_c/src/linearize.c
dmr_c/src/liveness.c
dmr_c/src/memops.c
dmr_c/src/parse.c
dmr_c/src/target.c
dmr_c/src/tokenize.c
dmr_c/src/pre-process.c
dmr_c/src/ptrlist.c
dmr_c/src/scope.c
dmr_c/src/show-parse.c
dmr_c/src/simplify.c
dmr_c/src/symbol.c
dmr_c/src/unssa.c
dmr_c/src/walksymbol.c
src/ravi_dmrc_parsesymbols.c
)
if (LLVM_JIT)
set(DMR_C_JIT_SRCS
dmr_c/llvm-backend/sparse-llvm.c
)
set(DMR_C_JIT_HEADERS
dmr_c/llvm-backend/dmr_c.h
)
include_directories("${PROJECT_SOURCE_DIR}/dmr_c/llvm-backend")
else()
set(DMR_C_JIT_HEADERS
dmr_c/null-backend/dmr_c.h
)
include_directories("${PROJECT_SOURCE_DIR}/dmr_c/null-backend")
endif()
if (MSVC OR APPLE)
source_group("dmrC Headers" FILES ${DMR_C_HEADERS} ${DMR_C_JIT_HEADERS})
source_group("dmrC Source Files" FILES ${DMR_C_SRCS} ${DMR_C_JIT_SRCS})
endif()
endif()
# Enable minimal required LLVM components so that the
# the size of the resulting binary is manageable
if (LLVM_JIT)
if (${LLVM_PACKAGE_VERSION} VERSION_LESS "3.8")
set(LLVM_EXTRA_LIBS ipa)
endif()
if (NOT ${LLVM_PACKAGE_VERSION} VERSION_LESS "5.0.0")
set(LLVM_EXTRA_LIBS orcjit)
endif()
message(STATUS "SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR}")
if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
set(LLVM_LIBS_PROCESSOR
X86CodeGen
X86AsmParser
X86Disassembler
X86AsmPrinter
X86Desc
X86Info
X86Utils
)
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
set(LLVM_LIBS_PROCESSOR
ARMCodeGen
ARMAsmParser
ARMDisassembler
ARMAsmPrinter
ARMDesc
ARMInfo
)
endif()
llvm_map_components_to_libnames(LLVM_LIBS
Analysis
AsmParser
AsmPrinter
BitReader
Core
CodeGen
ExecutionEngine
InstCombine
${LLVM_EXTRA_LIBS}
ipo
MC
MCJIT
MCParser
Object
RuntimeDyld
ScalarOpts
Support
Target
TransformUtils
${LLVM_LIBS_PROCESSOR}
)
message(STATUS "LLVM_LIBS ${LLVM_LIBS}")
endif ()
if (NOT STATIC_BUILD)
set(LIBRAVI_BUILD_TYPE SHARED)
endif()
if (LLVM_JIT)
set (LIBRAVI_NAME libravillvm)
else()
set (LIBRAVI_NAME libravinojit)
endif()
set(LIBRAVI_NAME libravi)
#Main library
add_library(${LIBRAVI_NAME} ${LIBRAVI_BUILD_TYPE}
add_library(${LIBRAVI_NAME} ${LIBRAVI_BUILD_TYPE}
${RAVI_HEADERS}
${LUA_LIB_SRCS}
${LUA_LIB_SRCS}
${LUA_CORE_SRCS}
${LLVM_JIT_SRCS}
${NO_JIT_SRCS}
${DMR_C_HEADERS}
${DMR_C_SRCS}
${DMR_C_JIT_SRCS}
${ASMVM_DEPS}
)
if (NOT STATIC_BUILD)
if (WIN32)
# enable DLL export
set_target_properties(${LIBRAVI_NAME} PROPERTIES DEFINE_SYMBOL "LUA_BUILD_AS_DLL")
else()
set_target_properties(${LIBRAVI_NAME} PROPERTIES PREFIX "")
endif ()
endif()
if (LLVM_JIT)
set_target_properties(${LIBRAVI_NAME} PROPERTIES COMPILE_DEFINITIONS "USE_LLVM=1")
endif()
if (EMBEDDED_DMRC)
set_target_properties(${LIBRAVI_NAME} PROPERTIES COMPILE_DEFINITIONS "USE_DMR_C=1")
endif()
target_link_libraries(${LIBRAVI_NAME} ${EXTRA_LIBRARIES} ${LLVM_LIBS})
${JIT_SRCS}
${ADDON_SRCS})
target_link_libraries(${LIBRAVI_NAME} LINK_PUBLIC ${EXTRA_LIBRARIES} ${MIRJIT_LIBRARIES} ${RAVICOMP_LIBRARIES})
# Main Ravi executable
add_executable(ravi src/lua.c)
if (LLVM_JIT)
set_target_properties(ravi PROPERTIES COMPILE_DEFINITIONS "USE_LLVM=1")
endif()
if (EMBEDDED_DMRC)
set_target_properties(ravi PROPERTIES COMPILE_DEFINITIONS "USE_DMR_C=1")
endif()
add_executable(ravi ${LUA_CMD_SRCS})
target_link_libraries(ravi ${LIBRAVI_NAME})
# Sources that are needed for a static NOJIT basic library
set(NOJIT_RAVI_SRCS
${RAVI_HEADERS}
${LUA_LIB_SRCS}
${LUA_CORE_SRCS}
src/ravi_nojit.c)
set(NOJIT_RAVI_SRCS
${RAVI_HEADERS}
${LUA_LIB_SRCS}
${LUA_CORE_SRCS}
${NO_JIT_SRCS})
set(RAVI_STATICEXEC_TARGET ravi_s)
# We always build a static library without JIT so that
# we can create some default executables
add_library(libravinojit_static
${NOJIT_RAVI_SRCS})
add_library(libravinojit_static
${NOJIT_RAVI_SRCS})
set_target_properties(libravinojit_static PROPERTIES PREFIX "") # As we already prefix with lib
target_link_libraries(libravinojit_static ${EXTRA_LIBRARIES})
# Create a simple NoJIT version of statically linked ravi
# This is sometimes useful in other projects that just need a Lua commandline
# but do not care about the shared library
add_executable(ravi_s
src/lua.c)
# but do not care about the shared library
add_executable(${RAVI_STATICEXEC_TARGET}
${LUA_CMD_SRCS})
target_link_libraries(ravi_s libravinojit_static)
if (NOT LTESTS)
# Note that enabling ltests.h messes with global_State
message(STATUS "Disabling Lua extended test harness 'ltests'")
set_property(
TARGET ${LIBRAVI_NAME} ravi
APPEND
PROPERTY COMPILE_DEFINITIONS NO_LUA_DEBUG)
set(NO_LUA_DEBUG 1)
endif ()
if (MIR_JIT)
set_property(
TARGET ${LIBRAVI_NAME} ravi
APPEND
PROPERTY COMPILE_DEFINITIONS "USE_MIRJIT=1")
set(USE_MIRJIT 1)
endif ()
if (NOT STATIC_BUILD)
if (WIN32)
# enable DLL export
set_property(
TARGET ${LIBRAVI_NAME}
APPEND
PROPERTY COMPILE_DEFINITIONS LUA_BUILD_AS_DLL)
else ()
set_target_properties(${LIBRAVI_NAME} PROPERTIES PREFIX "")
endif ()
else ()
set_target_properties(${LIBRAVI_NAME} PROPERTIES PREFIX "")
endif ()
if (RAVICOMP)
set_property(
TARGET ${LIBRAVI_NAME}
APPEND
PROPERTY COMPILE_DEFINITIONS "USE_RAVICOMP=1")
set(USE_RAVICOMP 1)
endif ()
if (APPLE)
set_property(
TARGET ${LIBRAVI_NAME} libravinojit_static
APPEND
PROPERTY COMPILE_DEFINITIONS "LUA_USE_MACOSX=1")
elseif (UNIX)
set_property(
TARGET ${LIBRAVI_NAME} libravinojit_static
APPEND
PROPERTY COMPILE_DEFINITIONS "LUA_USE_LINUX=1")
endif ()
include(GNUInstallDirs)
configure_file(ravi-config.h.in ravi-config.h @ONLY)
target_include_directories(${LIBRAVI} ravi
PUBLIC
"${PROJECT_BINARY_DIR}")
# Ravi VSCode Debug adapter
set(RAVI_DEBUGGER_TARGET ravidebug)
add_executable(${RAVI_DEBUGGER_TARGET}
vscode-debugger/src/ravidebug.c
vscode-debugger/src/json.c
vscode-debugger/src/protocol.c)
add_executable(${RAVI_DEBUGGER_TARGET}
vscode-debugger/src/ravidebug.c
vscode-debugger/src/json.c
vscode-debugger/src/protocol.c)
target_link_libraries(${RAVI_DEBUGGER_TARGET} libravinojit_static)
# Tests for VSCode Debug Adapter
add_executable(testravidebug
vscode-debugger/src/testravidebug.c
vscode-debugger/src/json.c
vscode-debugger/src/protocol.c)
# Tests for VSCode Debug Adapter
add_executable(testravidebug
vscode-debugger/src/testravidebug.c
vscode-debugger/src/json.c
vscode-debugger/src/protocol.c)
target_link_libraries(testravidebug libravinojit_static)
# Simple VM tests
add_executable(test_vm tests/test_vm.c)
target_link_libraries(test_vm ${LIBRAVI_NAME})
configure_file(lua-config.cmake.in lua-config.cmake @ONLY)
if (LLVM_JIT)
# LLVM playground
add_executable(test_llvm tests/test_llvm.cpp)
set_target_properties(test_llvm PROPERTIES COMPILE_DEFINITIONS "USE_LLVM=1")
target_link_libraries(test_llvm ${LIBRAVI_NAME})
endif ()
add_executable(test_misc tests/test_misc.c)
add_test(TestRaviDebug testravidebug)
if (LLVM_JIT)
add_test(TestLLVM test_llvm)
if (WIN32)
configure_file(ravi-env.bat.in ravi-env.bat @ONLY)
set(RAVI_SCRIPTS ${CMAKE_CURRENT_BINARY_DIR}/ravi-env.bat)
elseif (APPLE)
configure_file(ravi-env.osx.sh.in ravi-env.sh @ONLY)
set(RAVI_SCRIPTS ${CMAKE_CURRENT_BINARY_DIR}/ravi-env.sh)
else ()
configure_file(ravi-env.linux.sh.in ravi-env.sh @ONLY)
set(RAVI_SCRIPTS ${CMAKE_CURRENT_BINARY_DIR}/ravi-env.sh)
endif ()
add_test(TestVM test_vm)
add_test(TestMisc test_misc)
install(FILES ${LUA_HEADERS}
DESTINATION include/ravi)
install(TARGETS ${LIBRAVI_NAME} ravi ${RAVI_DEBUGGER_TARGET} ravi_s
RUNTIME DESTINATION bin
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib)
install(TARGETS ${LIBRAVI_NAME} ravi ${RAVI_DEBUGGER_TARGET} ${RAVI_STATICEXEC_TARGET}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Ravi_Runtime
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Ravi_Development
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Ravi_Runtime)
install(FILES ${RAVI_SCRIPTS}
DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lua-config.cmake
DESTINATION cmake)

@ -1,5 +1,23 @@
Most of Ravi is under MIT License
There are components that are under GPL - please see relevant
source files. These are optional components that are part of the
libgccjit implementation of the JIT compiler. You can remove these
components if you do not want GPL license.
/******************************************************************************
* Copyright (C) 1994-2019 Lua.org, PUC-Rio.
* Portions 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
* "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.
******************************************************************************/

@ -6,7 +6,7 @@
# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
# Your platform. See PLATS for possible values.
PLAT= none
PLAT= guess
# Where to install. The installation starts in the src and doc directories,
# so take care if INSTALL_TOP is not an absolute path. See the local target.
@ -38,7 +38,7 @@ RM= rm -f
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
# Convenience platforms targets.
PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
PLATS= guess aix bsd c89 freebsd generic linux linux-noreadline macosx mingw posix solaris
# What to install.
TO_BIN= ravi
@ -48,7 +48,7 @@ TO_LIB= libravinojit.a
# Lua version and release.
V= 5.3
R= $V.4
R= $V.5
# Targets start here.
all: $(PLAT)

@ -0,0 +1,195 @@
Ravi Programming Language
=========================
![image](https://travis-ci.org/dibyendumajumdar/ravi.svg?branch=master%0A%20:target:%20https://travis-ci.org/dibyendumajumdar/ravi)
Ravi is a dialect of [Lua](http://www.lua.org/) with limited optional
static typing and features [MIR](https://github.com/vnmakarov/mir)
powered JIT compilers. The name Ravi comes from the Sanskrit word for
the Sun. Interestingly a precursor to Lua was
[Sol](http://www.lua.org/history.html) which had support for static
types; Sol means the Sun in Portugese.
Lua is perfect as a small embeddable dynamic language so why a
derivative? Ravi extends Lua with static typing for improved performance
when JIT compilation is enabled. However, the static typing is optional
and therefore Lua programs are also valid Ravi programs.
There are other attempts to add static typing to Lua - e.g. [Typed
Lua](https://github.com/andremm/typedlua) but these efforts are mostly
about adding static type checks in the language while leaving the VM
unmodified. The Typed Lua effort is very similar to the approach taken
by Typescript in the JavaScript world. The static typing is to aid
programming in the large - the code is eventually translated to standard
Lua and executed in the unmodified Lua VM.
My motivation is somewhat different - I want to enhance the VM to
support more efficient operations when types are known. Type information
can be exploited by JIT compilation technology to improve performance.
At the same time, I want to keep the language safe and therefore usable
by non-expert programmers.
Of course there is the fantastic [LuaJIT](http://luajit.org)
implementation. Ravi has a different goal compared to LuaJIT. Ravi
prioritizes ease of maintenance and support, language safety, and
compatibility with Lua 5.3, over maximum performance. For more detailed
comparison please refer to the documentation links below.
Features
--------
- Optional static typing - for details [see the reference
manual](https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-reference.html).
- Type specific bytecodes to improve performance
- Compatibility with Lua 5.3 (see Compatibility section below)
- Generational GC from Lua 5.4
- `defer` statement for releasing resources
- Compact JIT backend [MIR](https://github.com/vnmakarov/mir).
- A [distribution with
batteries](https://github.com/dibyendumajumdar/Suravi).
- A [Visual Studio Code debugger
extension](https://marketplace.visualstudio.com/items?itemName=ravilang.ravi-debug)
- interpreted mode debugger.
Documentation
-------------
- For the Lua extensions in Ravi see the [Reference
Manual](https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-reference.html).
- [MIR JIT Build
instructions](https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-mir-instructions.html).
- Also see [Ravi
Documentation](http://the-ravi-programming-language.readthedocs.org/en/latest/index.html).
- and the slides I presented at the [Lua 2015
Workshop](http://www.lua.org/wshop15.html).
Lua Goodies
-----------
- [An Introduction to
Lua](http://the-ravi-programming-language.readthedocs.io/en/latest/lua-introduction.html)
attempts to provide a quick overview of Lua for folks coming from
other languages.
- [Lua 5.3 Bytecode
Reference](http://the-ravi-programming-language.readthedocs.io/en/latest/lua_bytecode_reference.html)
is my attempt to bring up to date the [Lua 5.1 Bytecode
Reference](http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf).
- A [patch for Lua
5.3](https://github.com/dibyendumajumdar/ravi/blob/master/patches/defer_statement_for_Lua_5_3.patch)
implements the 'defer' statement.
- A [patch for Lua
5.4.[0-2]](https://github.com/dibyendumajumdar/ravi/blob/master/patches/defer_statement_for_Lua_5_4.patch)
implements the 'defer' statement.
- Updated [patch for Lua
5.4.3](https://github.com/dibyendumajumdar/ravi/blob/master/patches/defer_statement_patch_for_Lua_5_4_3.patch)
implements the 'defer' statement.
Lua 5.4 Position Statement
--------------------------
Lua 5.4 relationship to Ravi is as follows:
- Generational GC - back-ported to Ravi.
- New random number generator - back-ported to Ravi.
- Multiple user values can be associated with userdata - under
consideration.
- `<const>` variables - not planned.
- `<close>` variables - Ravi has `'defer'` statement which is the
better option in my opinion, hence no plans to support `<close>`
variables.
- Interpreter performance improvements - these are beneficial to Lua
interpreter but not to the JIT backends, hence not much point in
back-porting.
- Table implementation changes - under consideration.
- String to number coercion is now part of string library metamethods
- back-ported to Ravi.
- utf8 library accepts codepoints up to 2\^31 - back-ported to Ravi.
- Removal of compatibility layers for 5.1, and 5.2 - not implemented
as Ravi continues to provide these layers as per Lua 5.3.
Compatibility with Lua 5.3
--------------------------
Ravi should be able to run all Lua 5.3 programs in interpreted mode, but
following should be noted:
- Ravi supports optional typing and enhanced types such as arrays (see
the documentation). Programs using these features cannot be run by
standard Lua. However all types in Ravi can be passed to Lua
functions; operations on Ravi arrays within Lua code will be subject
to restrictions as described in the section above on arrays.
- Values crossing from Lua to Ravi will be subjected to typechecks
should these values be assigned to typed variables.
- Upvalues cannot subvert the static typing of local variables (issue
\#26) when types are annotated.
- Certain Lua limits are reduced due to changed byte code structure.
These are described below.
- Ravi uses an extended bytecode which means it is not compatible with
Lua 5.x bytecode.
- Ravi incorporates the new Generational GC from Lua 5.4, hence the GC
interface has changed.
Limit name Lua value Ravi value
------------------ -------------- --------------
MAXUPVAL 255 125
LUAI\_MAXCCALLS 200 125
MAXREGS 255 125
MAXVARS 200 125
MAXARGLINE 250 120
When JIT compilation is enabled there are following additional
constraints:
- Ravi will only execute JITed code from the main Lua thread; any
secondary threads (coroutines) execute in interpreter mode.
- In JITed code tailcalls are implemented as regular calls so unlike
the interpreter VM which supports infinite tail recursion JIT
compiled code only supports tail recursion to a depth of about 110
(issue \#17)
- Debug api and hooks are not supported in JIT mode
History
-------
- 2015
: - Implemented JIT compilation using LLVM
- Implemented [libgccjit based alternative
JIT](https://github.com/dibyendumajumdar/ravi/tree/gccjit-ravi534)
(now discontinued)
- 2016
: - Implemented debugger for Ravi and Lua 5.3 for [Visual Studio
Code](https://github.com/dibyendumajumdar/ravi/tree/master/vscode-debugger)
- 2017
: - Embedded C compiler using dmrC project (C JIT compiler) (now
discontinued)
- Additional type-annotations
- 2018
: - Implemented [Eclipse OMR JIT
backend](https://github.com/dibyendumajumdar/ravi/tree/omrjit)
(now discontinued)
- Created [Ravi with
batteries](https://github.com/dibyendumajumdar/Suravi).
- 2019
: - New language feature - defer statement
- New JIT backend [MIR](https://github.com/vnmakarov/mir).
- 2020
: - [New parser / type checker /
compiler](https://github.com/dibyendumajumdar/ravi-compiler)
- Generational GC back-ported from Lua 5.4
- Support for [LLVM
backend](https://github.com/dibyendumajumdar/ravi/tree/llvm)
archived
- 2021 (Plan)
: - Integrated AOT and JIT compilation support
- Ravi 1.0 release
License
-------
MIT License

@ -1,524 +0,0 @@
=========================
Ravi Programming Language
=========================
Ravi is a derivative/dialect of `Lua 5.3 <http://www.lua.org/>`_ with limited optional static typing and an `LLVM <http://www.llvm.org/>`_ powered JIT compiler. 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 greater performance under JIT compilation. 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 also 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.
.. contents:: Table of Contents
:depth: 1
:backlinks: top
Features
========
* Optional static typing
* Type specific bytecodes to improve performance
* Compatibility with Lua 5.3 (see Compatibility section below)
* `LLVM <http://www.llvm.org/>`_ powered JIT compiler
* Additionally a `libgccjit <https://gcc.gnu.org/wiki/JIT>`_ based alternative JIT compiler is also available (on a branch), although this is not currently being worked on
* LLVM bindings exposed in Lua
Recent Work
===========
* A `distribution of Ravi/Lua 5.3 <https://github.com/dibyendumajumdar/ravi-distro>`_ is in the works - this will provide ready made binary downloads of Ravi/Lua with select high quality libraries.
* `Experimental Type Annotations`_ for user defined types was implemented in Oct 2017.
* A new `X86-64 VM written in assembler <https://github.com/dibyendumajumdar/ravi/tree/master/vmbuilder>`_ using `dynasm <https://luajit.org/dynasm.html>`_ tool is under development currently.
Documentation
=============
See `Ravi Documentation <http://the-ravi-programming-language.readthedocs.org/en/latest/index.html>`_.
As more stuff is built I will keep updating the documentation so please revisit for latest information.
Also see 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>`_.
JIT Implementation
==================
The LLVM JIT compiler is functional. The Lua and Ravi bytecodes currently implemented in LLVM are described in `JIT Status <http://the-ravi-programming-language.readthedocs.org/en/latest/ravi-jit-status.html>`_ page.
Ravi also provides an `LLVM binding <http://the-ravi-programming-language.readthedocs.org/en/latest/llvm-bindings.html>`_; this is still work in progress so please check documentation for the latest status.
Ravi Extensions to Lua 5.3
==========================
Optional Static Typing
----------------------
Ravi allows you to annotate ``local`` variables and function parameters with static types. The supported types and the resulting behaviour are as follows:
``integer``
denotes an integral value of 64-bits.
``number``
denotes a double (floating point) value of 8 bytes.
``integer[]``
denotes an array of integers
``number[]``
denotes an array of numbers
``table``
a Lua table
Additionally there are some `Experimental Type Annotations`_.
Declaring the types of ``local`` variables and function parameters has following advantages.
* ``integer`` and ``number`` types are automatically initialized to zero
* Arithmetic operations on numeric types make use of type specific bytecodes which leads to more efficient JIT compilation
* Specialised operators to get/set from array types are implemented; this makes array access more efficient in JIT mode as the access can be inlined
* Declared tables allow specialized opcodes for table gets involving integer and short literal string keys; these opcodes result in more efficient JIT code
* Values assigned to typed variables are checked statically when possible; if the values are results from a function call then runtime type checking is performed
* The standard table operations on arrays are checked to ensure that the type is not subverted
* Even if a typed variable is captured in a closure its type must be respected
* When function parameters are decorated with types, Ravi performs an implicit coersion of those parameters to the required types. If the coersion fails a runtime error occurs.
The array types (``number[]`` and ``integer[]``) are specializations of Lua table with some additional special behaviour:
* Array types are not compatible with declared table variables, i.e. following is not allowed::
local t: table = {}
local t2: number[] = t -- error!
local t3: number[] = {}
local t4: table = t3 -- error!
But following is okay::
local t5: number[] = {}
local t6 = t5 -- t6 treated as table
The reason for these restrictions is that declared table types generate optimized JIT code which assumes that the keys are integers
or literal short strings. Similarly declared array types result in specialized JIT code that assume integer keys and numeric values.
The generated JIT code would be incorrect if the types were not as expected.
* Indices >= 1 should be used when accessing array elements. Ravi arrays (and slices) have a hidden slot at index 0 for performance reasons, but this is not visible in ``pairs()`` or ``ipairs()``, or when initializing an array using a literal initializer; only direct access via the ``[]`` operator can see this slot.
* Arrays must always be initialized::
local t: number[] = {} -- okay
local t2: number[] -- error!
This restriction is placed as otherwise the JIT code would need to insert tests to validate that the variable is not nil.
* An array will grow automatically (unless the array was created as fixed length using ``table.intarray()`` or ``table.numarray()``) if the user sets the element just past the array length::
local t: number[] = {} -- dynamic array
t[1] = 4.2 -- okay, array grows by 1
t[5] = 2.4 -- error! as attempt to set value
* It is an error to attempt to set an element that is beyond len+1 on dynamic arrays; for fixed length arrays attempting to set elements at positions greater than len will cause an error.
* The current used length of the array is recorded and returned by len operations
* The array only permits the right type of value to be assigned (this is also checked at runtime to allow compatibility with Lua)
* Accessing out of bounds elements will cause an error, except for setting the len+1 element on dynamic arrays
* It is possible to pass arrays to functions and return arrays from functions. Arrays passed to functions appear as Lua tables inside
those functions if the parameters are untyped - however the tables will still be subject to restrictions as above. If the parameters are typed then the arrays will be recognized at compile time::
local function f(a, b: integer[], c)
-- Here a is dynamic type
-- b is declared as integer[]
-- c is also a dynamic type
b[1] = a[1] -- Okay only if a is actually also integer[]
b[1] = c[1] -- Will fail if c[1] cannot be converted to an integer
end
local a : integer[] = {1}
local b : integer[] = {}
local c = {1}
f(a,b,c) -- ok as c[1] is integer
f(a,b, {'hi'}) -- error!
* Arrays returned from functions can be stored into appropriately typed local variables - there is validation that the types match::
local t: number[] = f() -- type will be checked at runtime
* Operations on array types can be optimised to special bytecode and JIT only when the array type is statically known. Otherwise regular table access will be used subject to runtime checks.
* Array types ignore ``__index``, ``__newindex`` and ``__len`` metamethods.
* Array types cannot be set as metatables for other values.
* ``pairs()`` and ``ipairs()`` work on arrays as normal
* There is no way to delete an array element.
* The array data is stored in contiguous memory just like native C arrays; morever the garbage collector does not scan the array data
A declared table (as shown below) has some additional nuances::
local t: table = {}
* Like array types, a variable of ``table`` type must be initialized
* Array types are not compatible with declared table variables, i.e. following is not allowed::
local t: table = {}
local t2: number[] = t -- error!
* When short string literals are used to access a table element, specialized bytecodes are generated that are more efficiently JIT compiled::
local t: table = { name='dibyendu'}
print(t.name) -- The GETTABLE opcode is specialized in this case
* As with array types, specialized bytecodes are generated when integer keys are used
Following library functions allow creation of array types of defined length.
``table.intarray(num_elements, initial_value)``
creates an integer array of specified size, and initializes with initial value. The return type is integer[]. The size of the array cannot be changed dynamically, i.e. it is fixed to the initial specified size. This allows slices to be created on such arrays.
``table.numarray(num_elements, initial_value)``
creates an number array of specified size, and initializes with initial value. The return type is number[]. The size of the array cannot be changed dynamically, i.e. it is fixed to the initial specified size. This allows slices to be created on such arrays.
Type Assertions
---------------
Ravi does not support defining new types, or structured types based on tables. This creates some practical issues when dynamic types are mixed with static types. For example::
local t = { 1,2,3 }
local i: integer = t[1] -- generates an error
Above code generates an error as the compiler does not know that the value in ``t[1]`` is an integer. However often we as programmers know the type that is expected and it would be nice to be able to tell the compiler what the expected type of ``t[1]`` is above. To enable this Ravi supports type assertion operators. A type assertion is introduced by the '``@``' symbol, which must be followed by the type name. So we can rewrite the above example as::
local t = { 1,2,3 }
local i: integer = @integer( t[1] )
The type assertion operator is a unary operator and binds to the expression following the operator. We use the parenthesis above to enure that the type assertion is applied to ``t[1]`` rather than ``t``. More examples are shown below::
local a: number[] = @number[] { 1,2,3 }
local t = { @number[] { 4,5,6 }, @integer[] { 6,7,8 } }
local a1: number[] = @number[]( t[1] )
local a2: integer[] = @integer[]( t[2] )
For a real example of how type assertions can be used, please have a look at the test program `gaussian2.lua <https://github.com/dibyendumajumdar/ravi/blob/master/ravi-tests/gaussian2.lua>`_
Experimental Type Annotations
-----------------------------
Following type annotations have experimental support. These type annotations are not always statically enforced. Furthermore using these types does not affect the JIT code generation, i.e. variables annotated using these types are still treated as dynamic types.
The scenarios where these type annotations have an impact are:
* Function parameters containing these annotations lead to type assertions at runtime.
* The type assertion operator @ can be applied to these types - leading to runtime assertions.
* Annotating ``local`` declarations results in type assertions.
``string``
denotes a string
``closure``
denotes a function
Name
Denotes a value that has a `metatable registered under Name <https://www.lua.org/pil/28.2.html>`_ in the Lua registry. The Name must be a valid Lua name - hence periods in the name are not allowed.
The main use case for these annotations is to help with type checking of larger Ravi programs. These type checks, particularly the one for user defined types, are executed directly by the VM and hence are more efficient than performing the checks in other ways.
All three types above allow ``nil`` assignment.
Examples::
-- Create a metatable
local mt = { __name='MyType'}
-- Register the metatable in Lua registry
debug.getregistry().MyType = mt
-- Create an object and assign the metatable as its type
local t = {}
setmetatable(t, mt)
-- Use the metatable name as the object's type
function x(s: MyType)
local assert = assert
assert(@MyType(s) == @MyType(t))
assert(@MyType(t) == t)
end
-- Here we use the string type
function x(s1: string, s2: string)
return @string( s1 .. s2 )
end
-- Following demonstrates an error caused by the type checking
-- Note that this error is raised at runtime
function x()
local s: string
-- call a function that returns integer value
-- and try to assign to s
s = (function() return 1 end)()
end
x() -- will fail at runtime
Array Slices
------------
Since release 0.6 Ravi supports array slices. An array slice allows a portion of a Ravi array to be treated as if it is an array - this allows efficient access to the underlying array elements. Following new functions are available:
``table.slice(array, start_index, num_elements)``
creates a slice from an existing *fixed size* array - allowing efficient access to the underlying array elements.
Slices access the memory of the underlying array; hence a slice can only be created on fixed size arrays (constructed by ``table.numarray()`` or ``table.intarray()``). This ensures that the array memory cannot be reallocated while a slice is referring to it. Ravi does not track the slices that refer to arrays - slices get garbage collected as normal.
Slices cannot extend the array size for the same reasons above.
The type of a slice is the same as that of the underlying array - hence slices get the same optimized JIT operations for array access.
Each slice holds an internal reference to the underlying array to ensure that the garbage collector does not reclaim the array while there are slices pointing to it.
For an example use of slices please see the `matmul1.ravi <https://github.com/dibyendumajumdar/ravi/blob/master/ravi-tests/matmul1.ravi>`_ benchmark program in the repository. Note that this feature is highly experimental and not very well tested.
Examples
--------
Example of code that works - you can copy this to the command line input::
function tryme()
local i,j = 5,6
return i,j
end
local i:integer, j:integer = tryme(); print(i+j)
When values from a function call are assigned to a typed variable, an implicit type coersion takes place. In above example an error would occur if the function returned values that could not converted to integers.
In the following example, the parameter ``j`` is defined as a ``number``, hence it is an error to pass a value that cannot be converted to a ``number``::
function tryme(j: number)
for i=1,1000000000 do
j = j+1
end
return j
end
print(tryme(0.0))
An example with arrays::
function tryme()
local a : number[], j:number = {}
for i=1,10 do
a[i] = i
j = j + a[i]
end
return j
end
print(tryme())
Another example using arrays. Here the function receives a parameter ``arr`` of type ``number[]`` - it would be an error to pass any other type to the function because only ``number[]`` types can be converted to ``number[]`` types::
function sum(arr: number[])
local n: number = 0.0
for i = 1,#arr do
n = n + arr[i]
end
return n
end
print(sum(table.numarray(10, 2.0)))
The ``table.numarray(n, initial_value)`` creates a ``number[]`` of specified size and initializes the array with the given initial value.
All type checks are at runtime
------------------------------
To keep with Lua's dynamic nature Ravi uses a mix of compile type checking and runtime type checks. However due to the dynamic nature of Lua, compilation happens at runtime anyway so effectually all checks are at runtime.
JIT API
-------
The LLVM based JIT compiler is functional.
There are two modes of JIT compilation.
auto mode
in this mode the compiler decides when to compile a Lua function. The current implementation is very simple - any Lua function call is checked to see if the bytecodes contained in it can be compiled. If this is true then the function is compiled provided either a) function has a fornum loop, or b) it is largish (greater than 150 bytecodes) or c) it is being executed many times (> 50). Because of the simplistic behaviour performance the benefit of JIT compilation is only available if the JIT compiled functions will be executed many times so that the cost of JIT compilation can be amortized.
manual mode
in this mode user must explicitly request compilation. This is the default mode. This mode is suitable for library developers who can pre compile the functions in library module table.
A JIT api is available with following functions:
``ravi.jit([b])``
returns enabled setting of JIT compiler; also enables/disables the JIT compiler; defaults to true
``ravi.auto([b [, min_size [, min_executions]]])``
returns setting of auto compilation and compilation thresholds; also sets the new settings if values are supplied; defaults are false, 150, 50.
``ravi.compile(func_or_table[, options])``
compiles a Lua function (or functions if a table is supplied) if possible, returns ``true`` if compilation was successful for at least one function. ``options`` is an optional table with compilation options - in particular ``omitArrayGetRangeCheck`` - which disables range checks in array get operations to improve performance in some cases. Note that at present if the first argument is a table of functions and has more than 100 functions then only the first 100 will be compiled. You can invoke compile() repeatedly on the table until it returns false. Each invocation leads to a new module being created; any functions already compiled are skipped.
``ravi.iscompiled(func)``
returns the JIT status of a function
``ravi.dumplua(func)``
dumps the Lua bytecode of the function
``ravi.dumpir(func)``
(deprecated) dumps the IR of the compiled function (only if function was compiled; only available in LLVM 4.0 and earlier)
``ravi.dumpasm(func)``
(deprecated) dumps the machine code using the currently set optimization level (only if function was compiled; only available in LLVM version 4.0 and earlier)
``ravi.optlevel([n])``
sets LLVM optimization level (0, 1, 2, 3); defaults to 2. These levels are handled by reusing LLVMs default pass definitions which are geared towards C/C++ programs, but appear to work well here. If level is set to 0, then an attempt is made to use fast instruction selection to further speed up compilation.
``ravi.sizelevel([n])``
sets LLVM size level (0, 1, 2); defaults to 0
``ravi.tracehook([b])``
Enables support for line hooks via the debug api. Note that enabling this option will result in inefficient JIT as a call to a C function will be inserted at beginning of every Lua bytecode boundary; use this option only when you want to use the debug api to step through code line by line
``ravi.verbosity([b])``
Controls the amount of verbose messages generated during compilation. Currently only available for LLVM.
Performance
===========
For performance benchmarks please visit the `Ravi Performance Benchmarks <http://the-ravi-programming-language.readthedocs.org/en/latest/ravi-benchmarks.html>`_ page.
To obtain the best possible performance, types must be annotated so that Ravi's JIT compiler can generate efficient code.
Additionally function calls are expensive - as the JIT compiler cannot inline function calls, all function calls go via the Lua call protocol which has a large overhead. This is true for both Lua functions and C functions. For best performance avoid function calls inside loops.
Compatibility with Lua
======================
Ravi should be able to run all Lua 5.3 programs in interpreted mode, but following should be noted:
* Ravi supports optional typing and enhanced types such as arrays (described above). Programs using these features cannot be run by standard Lua. However all types in Ravi can be passed to Lua functions; operations on Ravi arrays within Lua code will be subject to restrictions as described in the section above on arrays.
* Values crossing from Lua to Ravi will be subjected to typechecks should these values be assigned to typed variables.
* Upvalues cannot subvert the static typing of local variables (issue #26) when types are annotated.
* Certain Lua limits are reduced due to changed byte code structure. These are described below.
+-----------------+-------------+-------------+
| 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)
Building Ravi
=============
Quick build without JIT
-----------------------
A Makefile is supplied for a simple build without the JIT. Just run ``make`` and follow instructions. You may need to customize the Makefiles.
For building Ravi with JIT options please read on.
Build Dependencies
------------------
* CMake
Ravi can be built with or without LLVM. Following versions of LLVM work with Ravi.
* LLVM 3.7 or 3.8 or 3.9 or 4.0 or 5.0
* LLVM 3.5 and 3.6 should also work but have not been recently tested
Unless otherwise noted the instructions below should work for LLVM 3.9 and later.
Since LLVM 5.0 Ravi has begun to use the new ORC JIT apis. These apis are more memory efficient compared to the MCJIT apis because they release the Module IR as early as possible, whereas with MCJIT the Module IR hangs around as long as the compiled code is held. Because of this significant improvement, I recommend using LLVM 5.0 and above.
Building LLVM on Windows
------------------------
I built LLVM from source. I used the following sequence from the VS2017 command window::
cd \github\llvm
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=c:\LLVM -DLLVM_TARGETS_TO_BUILD="X86" -G "Visual Studio 15 2017 Win64" ..
I then opened the generated solution in VS2017 and performed a INSTALL build from there. Above will build the 64-bit version of LLVM libraries. To build a 32-bit version omit the ``Win64`` parameter.
.. note:: Note that if you perform a Release build of LLVM then you will also need to do a Release build of Ravi otherwise you will get link errors.
Building LLVM on Ubuntu
-----------------------
On Ubuntu I found that the official LLVM distributions don't work with CMake. The CMake config files appear to be broken.
So I ended up downloading and building LLVM from source and that worked. The approach is similar to that described for MAC OS X below.
Building LLVM on MAC OS X
-------------------------
I am using Max OSX El Capitan. Pre-requisites are XCode 7.x and CMake.
Ensure cmake is on the path.
Assuming that LLVM source has been extracted to ``$HOME/llvm-3.7.0.src`` I follow these steps::
cd llvm-3.7.0.src
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$HOME/LLVM -DLLVM_TARGETS_TO_BUILD="X86" ..
make install
Building Ravi with JIT enabled
------------------------------
I am developing Ravi using Visual Studio 2017 Community Edition on Windows 10 64bit, gcc on Unbuntu 64-bit, and clang/Xcode on MAC OS X. I was also able to successfully build a Ubuntu version on Windows 10 using the newly released Ubuntu/Linux sub-system for Windows 10.
.. note:: Location of cmake files prior to LLVM 3.9 was ``$LLVM_INSTALL_DIR/share/llvm/cmake``.
Assuming that LLVM has been installed as described above, then on Windows I invoke the cmake config as follows::
cd build
cmake -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=c:\ravi -DLLVM_DIR=c:\LLVM\lib\cmake\llvm -G "Visual Studio 15 2017 Win64" ..
I then open the solution in VS2017 and do a build from there.
On Ubuntu I use::
cd build
cmake -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/lib/cmake/llvm -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" ..
make
Note that on a clean install of Ubuntu 15.10 I had to install following packages:
* cmake
* git
* libreadline-dev
On MAC OS X I use::
cd build
cmake -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/lib/cmake/llvm -DCMAKE_BUILD_TYPE=Release -G "Xcode" ..
I open the generated project in Xcode and do a build from there. You can also use the command line build tools if you wish - generate the make files in the same way as for Linux.
Building without JIT
--------------------
You can omit ``-DLLVM_JIT=ON`` option above to build Ravi with a null JIT implementation.
Building Static Libraries
-------------------------
By default the build generates a shared library for Ravi. You can choose to create a static library and statically linked executables by supplying the argument ``-DSTATIC_BUILD=ON`` to CMake.
Build Artifacts
---------------
The Ravi build creates a shared or static depending upon options supplied to CMake, the Ravi executable and some test programs. Additionally when JIT compilation is switched off, the ``ravidebug`` executable is generated which is the `debug adapter for use by Visual Studio Code <https://github.com/dibyendumajumdar/ravi/tree/master/vscode-debugger>`_.
The ``ravi`` command recognizes following environment variables. Note that these are only for internal debugging purposes.
``RAVI_DEBUG_EXPR``
if set to a value this triggers debug output of expression parsing
``RAVI_DEBUG_CODEGEN``
if set to a value this triggers a dump of the code being generated
``RAVI_DEBUG_VARS``
if set this triggers a dump of local variables construction and destruction
Also see section above on available API for dumping either Lua bytecode or LLVM IR for compiled code.
Testing
-------
I test the build by running a modified version of Lua 5.3.3 test suite. These tests are located in the ``lua-tests`` folder. Additionally I have ravi specific tests in the ``ravi-tests`` folder. There is a also a travis build that occurs upon commits - this build runs the tests as well.
.. note:: To thoroughly test changes, you need to invoke CMake with ``-DCMAKE_BUILD_TYPE=Debug`` option. This turns on assertions, memory checking, and also enables an internal module used by Lua tests.
Roadmap
=======
* 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)
- Additional type annotations
* 2018
- 1.0 release of Ravi
- More testing and test cases
- ASM VM for X86-64 platform
- Better support for earlier Lua versions (5.1 especially)
License
=======
MIT License for LLVM version.

@ -5,4 +5,4 @@ The scripts here are unsupported - these are just my personal
build scripts.
The unix LLVM debug builds enable 'ltests' and address sanitizer.
The debug builds enable 'ltests' and address sanitizer.

@ -1,5 +0,0 @@
mkdir llvm32
cd llvm32
rem cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM37_32\share\llvm\cmake -DBUILD_STATIC=OFF ..
cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM39_32\lib\cmake\llvm -DSTATIC_BUILD=OFF ..
cd ..

@ -1,5 +0,0 @@
mkdir llvm32
cd llvm32
rem cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM37_32\share\llvm\cmake ..
cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM39\lib\cmake\llvm -DSTATIC_BUILD=ON ..
cd ..

@ -1,5 +0,0 @@
mkdir llvm32d
cd llvm32d
rem cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM37_32\share\llvm\cmake ..
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM39D_32\lib\cmake\llvm -DSTATIC_BUILD=ON ..
cd ..

@ -1,6 +0,0 @@
mkdir llvm64d
cd llvm64d
rem cmake -DCMAKE_INSTALL_PREFIX=c:\ravi64llvmd -G "Visual Studio 14 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\LLVM37debug\share\llvm\cmake ..
rem cmake -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=c:\d\ravi64llvmd -G "Visual Studio 15 2017 Win64" -DLLVM_JIT=ON -DEMBEDDED_DMRC=ON -DLLVM_DIR=c:\d\LLVM39D64\lib\cmake\llvm ..
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DLTESTS=ON -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm501d\lib\cmake\llvm ..
cd ..

@ -1,7 +0,0 @@
mkdir llvm64
cd llvm64
rem pre LLVM 3.9
rem cmake -DCMAKE_INSTALL_PREFIX=c:\ravi -G "Visual Studio 14 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\LLVM37\share\llvm\cmake ..
rem cmake -DCMAKE_INSTALL_PREFIX=c:\ravi -G "Visual Studio 15 2017 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\d\LLVM40_64\lib\cmake\llvm ..
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DSTATIC_BUILD=ON -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm501r\lib\cmake\llvm ..
cd ..

@ -1,4 +0,0 @@
mkdir asmvm
cd asmvm
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi-asmvm -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DASM_VM=ON -G "Visual Studio 15 2017 Win64" ..
cd ..

@ -1,4 +1,4 @@
mkdir nojit64a
cd nojit64a
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Debug -DLTESTS=ON -G "Visual Studio 15 2017 Win64" ..
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Debug -DLTESTS=ON ..
cd ..

@ -1,4 +1,4 @@
mkdir nojit64
cd nojit64
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Debug -DSTATIC_BUILD=OFF -G "Visual Studio 15 2017 Win64" ..
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Release -DSTATIC_BUILD=OFF -G "Visual Studio 15 2017 Win64" ..
cd ..

@ -1,4 +0,0 @@
mkdir xcodellvm
cd xcodellvm
#cmake -DCMAKE_BUILD_TYPE=Debug -G Xcode -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/share/llvm/cmake ..
cmake -DCMAKE_BUILD_TYPE=Debug -G Xcode -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM5/lib/cmake/llvm ..

@ -1,5 +0,0 @@
mkdir buildllvmd
cd buildllvmd
#cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/share/llvm/cmake ..
#cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DLTESTS=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM5/lib/cmake/llvm ..
cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DLTESTS=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravillvm -DLLVM_DIR=$HOME/Software/llvm600/lib/cmake/llvm ..

@ -1,4 +0,0 @@
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 ..

@ -1,3 +0,0 @@
mkdir buildasmvm
cd buildasmvm
cmake -DSTATIC_BUILD=ON -DASM_VM=ON -DCMAKE_BUILD_TYPE=Debug -DCOMPUTED_GOTO=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi ..

@ -1,73 +0,0 @@
; ModuleID = 'inline_getstr.c'
source_filename = "inline_getstr.c"
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-pc-windows-msvc"
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.Table = type { %struct.GCObject*, i8, i8, i8, i8, i32, %struct.TValue*, %struct.Node*, %struct.Node*, %struct.Table*, %struct.GCObject*, %struct.RaviArray, i32 }
%struct.Node = type { %struct.TValue, %union.TKey }
%union.TKey = type { %struct.anon.1 }
%struct.anon.1 = type { %union.Value, i32, i32 }
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.RaviArray = type { i8*, i32, i32, i32 }
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i8, i32, %union.anon.2 }
%union.anon.2 = type { i64 }
; Function Attrs: nounwind
define %struct.TValue* @ravi_getstr(%struct.Table* %t, %struct.TString* %key) local_unnamed_addr #0 {
entry:
%hash = getelementptr inbounds %struct.TString, %struct.TString* %key, i32 0, i32 5
%0 = load i32, i32* %hash, align 8, !tbaa !1
%hmask = getelementptr inbounds %struct.Table, %struct.Table* %t, i32 0, i32 12
%1 = load i32, i32* %hmask, align 4, !tbaa !7
%and = and i32 %1, %0
%node = getelementptr inbounds %struct.Table, %struct.Table* %t, i32 0, i32 7
%2 = load %struct.Node*, %struct.Node** %node, align 4, !tbaa !10
%3 = getelementptr inbounds %struct.Node, %struct.Node* %2, i32 %and, i32 1, i32 0, i32 1
%4 = load i32, i32* %3, align 8, !tbaa !11
%cmp = icmp eq i32 %4, 68
br i1 %cmp, label %land.lhs.true, label %if.end
land.lhs.true: ; preds = %entry
%value_ = getelementptr inbounds %struct.Node, %struct.Node* %2, i32 %and, i32 1, i32 0, i32 0
%5 = bitcast %union.Value* %value_ to %struct.TString**
%6 = load %struct.TString*, %struct.TString** %5, align 8, !tbaa !13
%cmp1 = icmp eq %struct.TString* %6, %key
br i1 %cmp1, label %if.then, label %if.end
if.then: ; preds = %land.lhs.true
%i_val = getelementptr inbounds %struct.Node, %struct.Node* %2, i32 %and, i32 0
br label %cleanup
if.end: ; preds = %land.lhs.true, %entry
%call = tail call %struct.TValue* @luaH_getstr(%struct.Table* nonnull %t, %struct.TString* nonnull %key) #2
br label %cleanup
cleanup: ; preds = %if.end, %if.then
%retval.0 = phi %struct.TValue* [ %i_val, %if.then ], [ %call, %if.end ]
ret %struct.TValue* %retval.0
}
declare %struct.TValue* @luaH_getstr(%struct.Table*, %struct.TString*) local_unnamed_addr #1
attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.9.0 (trunk)"}
!1 = !{!2, !6, i64 8}
!2 = !{!"TString", !3, i64 0, !4, i64 4, !4, i64 5, !4, i64 6, !4, i64 7, !6, i64 8, !4, i64 16}
!3 = !{!"any pointer", !4, i64 0}
!4 = !{!"omnipotent char", !5, i64 0}
!5 = !{!"Simple C/C++ TBAA"}
!6 = !{!"int", !4, i64 0}
!7 = !{!8, !6, i64 48}
!8 = !{!"Table", !3, i64 0, !4, i64 4, !4, i64 5, !4, i64 6, !4, i64 7, !6, i64 8, !3, i64 12, !3, i64 16, !3, i64 20, !3, i64 24, !3, i64 28, !9, i64 32, !6, i64 48}
!9 = !{!"RaviArray", !3, i64 0, !4, i64 4, !6, i64 8, !6, i64 12}
!10 = !{!8, !3, i64 16}
!11 = !{!12, !6, i64 8}
!12 = !{!"TValue", !4, i64 0, !6, i64 8}
!13 = !{!3, !3, i64 0}

@ -1,784 +0,0 @@
; ModuleID = 'lua_for_num.c'
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i32, i64, %struct.TString* }
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
@.str1 = private unnamed_addr constant [29 x i8] c"'for' limit must be a number\00", align 1
@.str2 = private unnamed_addr constant [28 x i8] c"'for' step must be a number\00", align 1
@.str3 = private unnamed_addr constant [37 x i8] c"'for' initial value must be a number\00", align 1
@.str4 = private unnamed_addr constant [13 x i8] c"ptr diff %d\0A\00", align 1
; Function Attrs: nounwind
define void @testfunc(%struct.GCObject* %obj) #0 {
entry:
%obj.addr = alloca %struct.GCObject*, align 4
store %struct.GCObject* %obj, %struct.GCObject** %obj.addr, align 4, !tbaa !1
%0 = load %struct.GCObject*, %struct.GCObject** %obj.addr, align 4, !tbaa !1
%tt = getelementptr inbounds %struct.GCObject, %struct.GCObject* %0, i32 0, i32 1
%1 = load i8, i8* %tt, align 1, !tbaa !5
%conv = zext i8 %1 to i32
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 %conv)
ret void
}
declare i32 @printf(i8*, ...) #1
; Function Attrs: nounwind
define void @test1(%struct.lua_State* %L) #0 {
entry:
%L.addr = alloca %struct.lua_State*, align 4
%ci = alloca %struct.CallInfoLua*, align 4
%cl = alloca %struct.LClosure*, align 4
%k = alloca %struct.TValue*, align 4
%base = alloca %struct.TValue*, align 4
%cil = alloca %struct.CallInfoL*, align 4
%ra = alloca %struct.TValue*, align 4
%rb = alloca %struct.TValue*, align 4
%rc = alloca %struct.TValue*, align 4
%b = alloca i32, align 4
%init = alloca %struct.TValue*, align 4
%plimit = alloca %struct.TValue*, align 4
%pstep = alloca %struct.TValue*, align 4
%ilimit = alloca i64, align 8
%stopnow = alloca i32, align 4
%init_is_integer = alloca i32, align 4
%pstep_is_integer = alloca i32, align 4
%fl = alloca i32, align 4
%initv = alloca i64, align 8
%ninit = alloca double, align 8
%nlimit = alloca double, align 8
%nstep = alloca double, align 8
%plimit_is_float = alloca i32, align 4
%pstep_is_float = alloca i32, align 4
%init_is_float = alloca i32, align 4
%step = alloca i64, align 8
%idx = alloca i64, align 8
%limit = alloca i64, align 8
%cleanup.dest.slot = alloca i32
%step116 = alloca double, align 8
%idx119 = alloca double, align 8
%limit124 = alloca double, align 8
store %struct.lua_State* %L, %struct.lua_State** %L.addr, align 4, !tbaa !1
%0 = bitcast %struct.CallInfoLua** %ci to i8*
call void @llvm.lifetime.start(i64 4, i8* %0) #2
%1 = bitcast %struct.LClosure** %cl to i8*
call void @llvm.lifetime.start(i64 4, i8* %1) #2
%2 = bitcast %struct.TValue** %k to i8*
call void @llvm.lifetime.start(i64 4, i8* %2) #2
%3 = bitcast %struct.TValue** %base to i8*
call void @llvm.lifetime.start(i64 4, i8* %3) #2
%4 = bitcast %struct.CallInfoL** %cil to i8*
call void @llvm.lifetime.start(i64 4, i8* %4) #2
%5 = bitcast %struct.TValue** %ra to i8*
call void @llvm.lifetime.start(i64 4, i8* %5) #2
%6 = bitcast %struct.TValue** %rb to i8*
call void @llvm.lifetime.start(i64 4, i8* %6) #2
%7 = bitcast %struct.TValue** %rc to i8*
call void @llvm.lifetime.start(i64 4, i8* %7) #2
%8 = bitcast i32* %b to i8*
call void @llvm.lifetime.start(i64 4, i8* %8) #2
%9 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%ci1 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %9, i32 0, i32 6
%10 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci1, align 4, !tbaa !7
store %struct.CallInfoLua* %10, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%11 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %11, i32 0, i32 4
%base2 = getelementptr inbounds %struct.CallInfoL, %struct.CallInfoL* %l, i32 0, i32 0
%12 = load %struct.TValue*, %struct.TValue** %base2, align 4, !tbaa !13
store %struct.TValue* %12, %struct.TValue** %base, align 4, !tbaa !1
%13 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%func = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %13, i32 0, i32 0
%14 = load %struct.TValue*, %struct.TValue** %func, align 4, !tbaa !16
%value_ = getelementptr inbounds %struct.TValue, %struct.TValue* %14, i32 0, i32 0
%gc = bitcast %union.Value* %value_ to %struct.GCObject**
%15 = load %struct.GCObject*, %struct.GCObject** %gc, align 4, !tbaa !1
%16 = bitcast %struct.GCObject* %15 to %struct.LClosure*
store %struct.LClosure* %16, %struct.LClosure** %cl, align 4, !tbaa !1
%17 = load %struct.LClosure*, %struct.LClosure** %cl, align 4, !tbaa !1
%p = getelementptr inbounds %struct.LClosure, %struct.LClosure* %17, i32 0, i32 5
%18 = load %struct.Proto*, %struct.Proto** %p, align 4, !tbaa !17
%k3 = getelementptr inbounds %struct.Proto, %struct.Proto* %18, i32 0, i32 14
%19 = load %struct.TValue*, %struct.TValue** %k3, align 4, !tbaa !19
store %struct.TValue* %19, %struct.TValue** %k, align 4, !tbaa !1
%20 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr = getelementptr inbounds %struct.TValue, %struct.TValue* %20, i32 0
store %struct.TValue* %add.ptr, %struct.TValue** %ra, align 4, !tbaa !1
%21 = load %struct.TValue*, %struct.TValue** %k, align 4, !tbaa !1
%add.ptr4 = getelementptr inbounds %struct.TValue, %struct.TValue* %21, i32 0
store %struct.TValue* %add.ptr4, %struct.TValue** %rb, align 4, !tbaa !1
%22 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%23 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%24 = bitcast %struct.TValue* %22 to i8*
%25 = bitcast %struct.TValue* %23 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %24, i8* %25, i32 16, i32 8, i1 false), !tbaa.struct !22
%26 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr5 = getelementptr inbounds %struct.TValue, %struct.TValue* %26, i32 1
store %struct.TValue* %add.ptr5, %struct.TValue** %ra, align 4, !tbaa !1
%27 = load %struct.TValue*, %struct.TValue** %k, align 4, !tbaa !1
%add.ptr6 = getelementptr inbounds %struct.TValue, %struct.TValue* %27, i32 1
store %struct.TValue* %add.ptr6, %struct.TValue** %rb, align 4, !tbaa !1
%28 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%29 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%30 = bitcast %struct.TValue* %28 to i8*
%31 = bitcast %struct.TValue* %29 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %30, i8* %31, i32 16, i32 8, i1 false), !tbaa.struct !22
%32 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr7 = getelementptr inbounds %struct.TValue, %struct.TValue* %32, i32 2
store %struct.TValue* %add.ptr7, %struct.TValue** %ra, align 4, !tbaa !1
%33 = load %struct.TValue*, %struct.TValue** %k, align 4, !tbaa !1
%add.ptr8 = getelementptr inbounds %struct.TValue, %struct.TValue* %33, i32 2
store %struct.TValue* %add.ptr8, %struct.TValue** %rb, align 4, !tbaa !1
%34 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%35 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%36 = bitcast %struct.TValue* %34 to i8*
%37 = bitcast %struct.TValue* %35 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %36, i8* %37, i32 16, i32 8, i1 false), !tbaa.struct !22
%38 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr9 = getelementptr inbounds %struct.TValue, %struct.TValue* %38, i32 3
store %struct.TValue* %add.ptr9, %struct.TValue** %ra, align 4, !tbaa !1
%39 = load %struct.TValue*, %struct.TValue** %k, align 4, !tbaa !1
%add.ptr10 = getelementptr inbounds %struct.TValue, %struct.TValue* %39, i32 1
store %struct.TValue* %add.ptr10, %struct.TValue** %rb, align 4, !tbaa !1
%40 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%41 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%42 = bitcast %struct.TValue* %40 to i8*
%43 = bitcast %struct.TValue* %41 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %42, i8* %43, i32 16, i32 8, i1 false), !tbaa.struct !22
br label %label_forprep
label_forprep: ; preds = %entry
%44 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr11 = getelementptr inbounds %struct.TValue, %struct.TValue* %44, i32 1
store %struct.TValue* %add.ptr11, %struct.TValue** %ra, align 4, !tbaa !1
%45 = bitcast %struct.TValue** %init to i8*
call void @llvm.lifetime.start(i64 4, i8* %45) #2
%46 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
store %struct.TValue* %46, %struct.TValue** %init, align 4, !tbaa !1
%47 = bitcast %struct.TValue** %plimit to i8*
call void @llvm.lifetime.start(i64 4, i8* %47) #2
%48 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr12 = getelementptr inbounds %struct.TValue, %struct.TValue* %48, i32 1
store %struct.TValue* %add.ptr12, %struct.TValue** %plimit, align 4, !tbaa !1
%49 = bitcast %struct.TValue** %pstep to i8*
call void @llvm.lifetime.start(i64 4, i8* %49) #2
%50 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr13 = getelementptr inbounds %struct.TValue, %struct.TValue* %50, i32 2
store %struct.TValue* %add.ptr13, %struct.TValue** %pstep, align 4, !tbaa !1
%51 = bitcast i64* %ilimit to i8*
call void @llvm.lifetime.start(i64 8, i8* %51) #2
%52 = bitcast i32* %stopnow to i8*
call void @llvm.lifetime.start(i64 4, i8* %52) #2
%53 = bitcast i32* %init_is_integer to i8*
call void @llvm.lifetime.start(i64 4, i8* %53) #2
%54 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%tt_ = getelementptr inbounds %struct.TValue, %struct.TValue* %54, i32 0, i32 1
%55 = load i32, i32* %tt_, align 4, !tbaa !27
%cmp = icmp eq i32 %55, 19
%conv = zext i1 %cmp to i32
store i32 %conv, i32* %init_is_integer, align 4, !tbaa !23
%56 = bitcast i32* %pstep_is_integer to i8*
call void @llvm.lifetime.start(i64 4, i8* %56) #2
%57 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%tt_14 = getelementptr inbounds %struct.TValue, %struct.TValue* %57, i32 0, i32 1
%58 = load i32, i32* %tt_14, align 4, !tbaa !27
%cmp15 = icmp eq i32 %58, 19
%conv16 = zext i1 %cmp15 to i32
store i32 %conv16, i32* %pstep_is_integer, align 4, !tbaa !23
%59 = bitcast i32* %fl to i8*
call void @llvm.lifetime.start(i64 4, i8* %59) #2
%60 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%61 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%value_17 = getelementptr inbounds %struct.TValue, %struct.TValue* %61, i32 0, i32 0
%i = bitcast %union.Value* %value_17 to i64*
%62 = load i64, i64* %i, align 8, !tbaa !24
%call = call i32 @forlimit(%struct.TValue* %60, i64* %ilimit, i64 %62, i32* %stopnow)
store i32 %call, i32* %fl, align 4, !tbaa !23
%63 = load i32, i32* %init_is_integer, align 4, !tbaa !23
%tobool = icmp ne i32 %63, 0
br i1 %tobool, label %land.lhs.true, label %if.else
land.lhs.true: ; preds = %label_forprep
%64 = load i32, i32* %pstep_is_integer, align 4, !tbaa !23
%tobool18 = icmp ne i32 %64, 0
br i1 %tobool18, label %land.lhs.true19, label %if.else
land.lhs.true19: ; preds = %land.lhs.true
%65 = load i32, i32* %fl, align 4, !tbaa !23
%tobool20 = icmp ne i32 %65, 0
br i1 %tobool20, label %if.then, label %if.else
if.then: ; preds = %land.lhs.true19
%66 = bitcast i64* %initv to i8*
call void @llvm.lifetime.start(i64 8, i8* %66) #2
%67 = load i32, i32* %stopnow, align 4, !tbaa !23
%tobool21 = icmp ne i32 %67, 0
br i1 %tobool21, label %cond.true, label %cond.false
cond.true: ; preds = %if.then
br label %cond.end
cond.false: ; preds = %if.then
%68 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%value_22 = getelementptr inbounds %struct.TValue, %struct.TValue* %68, i32 0, i32 0
%i23 = bitcast %union.Value* %value_22 to i64*
%69 = load i64, i64* %i23, align 8, !tbaa !24
br label %cond.end
cond.end: ; preds = %cond.false, %cond.true
%cond = phi i64 [ 0, %cond.true ], [ %69, %cond.false ]
store i64 %cond, i64* %initv, align 8, !tbaa !24
%70 = load i64, i64* %ilimit, align 8, !tbaa !24
%71 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%value_24 = getelementptr inbounds %struct.TValue, %struct.TValue* %71, i32 0, i32 0
%i25 = bitcast %union.Value* %value_24 to i64*
store i64 %70, i64* %i25, align 8, !tbaa !24
%72 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%tt_26 = getelementptr inbounds %struct.TValue, %struct.TValue* %72, i32 0, i32 1
store i32 19, i32* %tt_26, align 4, !tbaa !27
%73 = load i64, i64* %initv, align 8, !tbaa !24
%74 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%value_27 = getelementptr inbounds %struct.TValue, %struct.TValue* %74, i32 0, i32 0
%i28 = bitcast %union.Value* %value_27 to i64*
%75 = load i64, i64* %i28, align 8, !tbaa !24
%sub = sub nsw i64 %73, %75
%76 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%value_29 = getelementptr inbounds %struct.TValue, %struct.TValue* %76, i32 0, i32 0
%i30 = bitcast %union.Value* %value_29 to i64*
store i64 %sub, i64* %i30, align 8, !tbaa !24
%77 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%tt_31 = getelementptr inbounds %struct.TValue, %struct.TValue* %77, i32 0, i32 1
store i32 19, i32* %tt_31, align 4, !tbaa !27
%78 = bitcast i64* %initv to i8*
call void @llvm.lifetime.end(i64 8, i8* %78) #2
br label %if.end79
if.else: ; preds = %land.lhs.true19, %land.lhs.true, %label_forprep
%79 = bitcast double* %ninit to i8*
call void @llvm.lifetime.start(i64 8, i8* %79) #2
%80 = bitcast double* %nlimit to i8*
call void @llvm.lifetime.start(i64 8, i8* %80) #2
%81 = bitcast double* %nstep to i8*
call void @llvm.lifetime.start(i64 8, i8* %81) #2
%82 = bitcast i32* %plimit_is_float to i8*
call void @llvm.lifetime.start(i64 4, i8* %82) #2
store i32 0, i32* %plimit_is_float, align 4, !tbaa !23
%83 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%tt_32 = getelementptr inbounds %struct.TValue, %struct.TValue* %83, i32 0, i32 1
%84 = load i32, i32* %tt_32, align 4, !tbaa !27
%cmp33 = icmp eq i32 %84, 3
br i1 %cmp33, label %if.then35, label %if.else37
if.then35: ; preds = %if.else
store i32 1, i32* %plimit_is_float, align 4, !tbaa !23
%85 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%value_36 = getelementptr inbounds %struct.TValue, %struct.TValue* %85, i32 0, i32 0
%n = bitcast %union.Value* %value_36 to double*
%86 = load double, double* %n, align 8, !tbaa !25
store double %86, double* %nlimit, align 8, !tbaa !25
br label %if.end
if.else37: ; preds = %if.else
%87 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%call38 = call i32 @luaV_tonumber_(%struct.TValue* %87, double* %nlimit)
store i32 %call38, i32* %plimit_is_float, align 4, !tbaa !23
br label %if.end
if.end: ; preds = %if.else37, %if.then35
%88 = load i32, i32* %plimit_is_float, align 4, !tbaa !23
%tobool39 = icmp ne i32 %88, 0
br i1 %tobool39, label %if.end42, label %if.then40
if.then40: ; preds = %if.end
%89 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%call41 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %89, i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str1, i32 0, i32 0))
br label %if.end42
if.end42: ; preds = %if.then40, %if.end
%90 = load double, double* %nlimit, align 8, !tbaa !25
%91 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%value_43 = getelementptr inbounds %struct.TValue, %struct.TValue* %91, i32 0, i32 0
%n44 = bitcast %union.Value* %value_43 to double*
store double %90, double* %n44, align 8, !tbaa !25
%92 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
%tt_45 = getelementptr inbounds %struct.TValue, %struct.TValue* %92, i32 0, i32 1
store i32 3, i32* %tt_45, align 4, !tbaa !27
%93 = bitcast i32* %pstep_is_float to i8*
call void @llvm.lifetime.start(i64 4, i8* %93) #2
store i32 0, i32* %pstep_is_float, align 4, !tbaa !23
%94 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%tt_46 = getelementptr inbounds %struct.TValue, %struct.TValue* %94, i32 0, i32 1
%95 = load i32, i32* %tt_46, align 4, !tbaa !27
%cmp47 = icmp eq i32 %95, 3
br i1 %cmp47, label %if.then49, label %if.else52
if.then49: ; preds = %if.end42
store i32 1, i32* %pstep_is_float, align 4, !tbaa !23
%96 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%value_50 = getelementptr inbounds %struct.TValue, %struct.TValue* %96, i32 0, i32 0
%n51 = bitcast %union.Value* %value_50 to double*
%97 = load double, double* %n51, align 8, !tbaa !25
store double %97, double* %nstep, align 8, !tbaa !25
br label %if.end54
if.else52: ; preds = %if.end42
%98 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%call53 = call i32 @luaV_tonumber_(%struct.TValue* %98, double* %nstep)
store i32 %call53, i32* %pstep_is_float, align 4, !tbaa !23
br label %if.end54
if.end54: ; preds = %if.else52, %if.then49
%99 = load i32, i32* %pstep_is_float, align 4, !tbaa !23
%tobool55 = icmp ne i32 %99, 0
br i1 %tobool55, label %if.end58, label %if.then56
if.then56: ; preds = %if.end54
%100 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%call57 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %100, i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str2, i32 0, i32 0))
br label %if.end58
if.end58: ; preds = %if.then56, %if.end54
%101 = load double, double* %nstep, align 8, !tbaa !25
%102 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%value_59 = getelementptr inbounds %struct.TValue, %struct.TValue* %102, i32 0, i32 0
%n60 = bitcast %union.Value* %value_59 to double*
store double %101, double* %n60, align 8, !tbaa !25
%103 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
%tt_61 = getelementptr inbounds %struct.TValue, %struct.TValue* %103, i32 0, i32 1
store i32 3, i32* %tt_61, align 4, !tbaa !27
%104 = bitcast i32* %init_is_float to i8*
call void @llvm.lifetime.start(i64 4, i8* %104) #2
store i32 0, i32* %init_is_float, align 4, !tbaa !23
%105 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%tt_62 = getelementptr inbounds %struct.TValue, %struct.TValue* %105, i32 0, i32 1
%106 = load i32, i32* %tt_62, align 4, !tbaa !27
%cmp63 = icmp eq i32 %106, 3
br i1 %cmp63, label %if.then65, label %if.else68
if.then65: ; preds = %if.end58
store i32 1, i32* %init_is_float, align 4, !tbaa !23
%107 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%value_66 = getelementptr inbounds %struct.TValue, %struct.TValue* %107, i32 0, i32 0
%n67 = bitcast %union.Value* %value_66 to double*
%108 = load double, double* %n67, align 8, !tbaa !25
store double %108, double* %ninit, align 8, !tbaa !25
br label %if.end70
if.else68: ; preds = %if.end58
%109 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%call69 = call i32 @luaV_tonumber_(%struct.TValue* %109, double* %ninit)
store i32 %call69, i32* %init_is_float, align 4, !tbaa !23
br label %if.end70
if.end70: ; preds = %if.else68, %if.then65
%110 = load i32, i32* %init_is_float, align 4, !tbaa !23
%tobool71 = icmp ne i32 %110, 0
br i1 %tobool71, label %if.end74, label %if.then72
if.then72: ; preds = %if.end70
%111 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%call73 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %111, i8* getelementptr inbounds ([37 x i8], [37 x i8]* @.str3, i32 0, i32 0))
br label %if.end74
if.end74: ; preds = %if.then72, %if.end70
%112 = load double, double* %ninit, align 8, !tbaa !25
%113 = load double, double* %nstep, align 8, !tbaa !25
%sub75 = fsub double %112, %113
%114 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%value_76 = getelementptr inbounds %struct.TValue, %struct.TValue* %114, i32 0, i32 0
%n77 = bitcast %union.Value* %value_76 to double*
store double %sub75, double* %n77, align 8, !tbaa !25
%115 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
%tt_78 = getelementptr inbounds %struct.TValue, %struct.TValue* %115, i32 0, i32 1
store i32 3, i32* %tt_78, align 4, !tbaa !27
%116 = bitcast i32* %init_is_float to i8*
call void @llvm.lifetime.end(i64 4, i8* %116) #2
%117 = bitcast i32* %pstep_is_float to i8*
call void @llvm.lifetime.end(i64 4, i8* %117) #2
%118 = bitcast i32* %plimit_is_float to i8*
call void @llvm.lifetime.end(i64 4, i8* %118) #2
%119 = bitcast double* %nstep to i8*
call void @llvm.lifetime.end(i64 8, i8* %119) #2
%120 = bitcast double* %nlimit to i8*
call void @llvm.lifetime.end(i64 8, i8* %120) #2
%121 = bitcast double* %ninit to i8*
call void @llvm.lifetime.end(i64 8, i8* %121) #2
br label %if.end79
if.end79: ; preds = %if.end74, %cond.end
br label %label_forloop
label_loopbody: ; preds = %cleanup144, %cleanup
%122 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr80 = getelementptr inbounds %struct.TValue, %struct.TValue* %122, i32 0
store %struct.TValue* %add.ptr80, %struct.TValue** %ra, align 4, !tbaa !1
%123 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr81 = getelementptr inbounds %struct.TValue, %struct.TValue* %123, i32 4
store %struct.TValue* %add.ptr81, %struct.TValue** %rb, align 4, !tbaa !1
%124 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%125 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%126 = bitcast %struct.TValue* %124 to i8*
%127 = bitcast %struct.TValue* %125 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %126, i8* %127, i32 16, i32 8, i1 false), !tbaa.struct !22
br label %label_forloop
label_forloop: ; preds = %label_loopbody, %if.end79
%128 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr82 = getelementptr inbounds %struct.TValue, %struct.TValue* %128, i32 1
store %struct.TValue* %add.ptr82, %struct.TValue** %ra, align 4, !tbaa !1
%129 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%tt_83 = getelementptr inbounds %struct.TValue, %struct.TValue* %129, i32 0, i32 1
%130 = load i32, i32* %tt_83, align 4, !tbaa !27
%cmp84 = icmp eq i32 %130, 19
br i1 %cmp84, label %if.then86, label %if.else114
if.then86: ; preds = %label_forloop
%131 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr87 = getelementptr inbounds %struct.TValue, %struct.TValue* %131, i32 2
store %struct.TValue* %add.ptr87, %struct.TValue** %rb, align 4, !tbaa !1
%132 = bitcast i64* %step to i8*
call void @llvm.lifetime.start(i64 8, i8* %132) #2
%133 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%value_88 = getelementptr inbounds %struct.TValue, %struct.TValue* %133, i32 0, i32 0
%i89 = bitcast %union.Value* %value_88 to i64*
%134 = load i64, i64* %i89, align 8, !tbaa !24
store i64 %134, i64* %step, align 8, !tbaa !24
%135 = bitcast i64* %idx to i8*
call void @llvm.lifetime.start(i64 8, i8* %135) #2
%136 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%value_90 = getelementptr inbounds %struct.TValue, %struct.TValue* %136, i32 0, i32 0
%i91 = bitcast %union.Value* %value_90 to i64*
%137 = load i64, i64* %i91, align 8, !tbaa !24
%138 = load i64, i64* %step, align 8, !tbaa !24
%add = add nsw i64 %137, %138
store i64 %add, i64* %idx, align 8, !tbaa !24
%139 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr92 = getelementptr inbounds %struct.TValue, %struct.TValue* %139, i32 1
store %struct.TValue* %add.ptr92, %struct.TValue** %rc, align 4, !tbaa !1
%140 = bitcast i64* %limit to i8*
call void @llvm.lifetime.start(i64 8, i8* %140) #2
%141 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
%value_93 = getelementptr inbounds %struct.TValue, %struct.TValue* %141, i32 0, i32 0
%i94 = bitcast %union.Value* %value_93 to i64*
%142 = load i64, i64* %i94, align 8, !tbaa !24
store i64 %142, i64* %limit, align 8, !tbaa !24
%143 = load i64, i64* %step, align 8, !tbaa !24
%cmp95 = icmp slt i64 0, %143
br i1 %cmp95, label %cond.true97, label %cond.false100
cond.true97: ; preds = %if.then86
%144 = load i64, i64* %idx, align 8, !tbaa !24
%145 = load i64, i64* %limit, align 8, !tbaa !24
%cmp98 = icmp sle i64 %144, %145
br i1 %cmp98, label %if.then103, label %if.end111
cond.false100: ; preds = %if.then86
%146 = load i64, i64* %limit, align 8, !tbaa !24
%147 = load i64, i64* %idx, align 8, !tbaa !24
%cmp101 = icmp sle i64 %146, %147
br i1 %cmp101, label %if.then103, label %if.end111
if.then103: ; preds = %cond.false100, %cond.true97
%148 = load i64, i64* %idx, align 8, !tbaa !24
%149 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%value_104 = getelementptr inbounds %struct.TValue, %struct.TValue* %149, i32 0, i32 0
%i105 = bitcast %union.Value* %value_104 to i64*
store i64 %148, i64* %i105, align 8, !tbaa !24
%150 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%tt_106 = getelementptr inbounds %struct.TValue, %struct.TValue* %150, i32 0, i32 1
store i32 19, i32* %tt_106, align 4, !tbaa !27
%151 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr107 = getelementptr inbounds %struct.TValue, %struct.TValue* %151, i32 3
store %struct.TValue* %add.ptr107, %struct.TValue** %rc, align 4, !tbaa !1
%152 = load i64, i64* %idx, align 8, !tbaa !24
%153 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
%value_108 = getelementptr inbounds %struct.TValue, %struct.TValue* %153, i32 0, i32 0
%i109 = bitcast %union.Value* %value_108 to i64*
store i64 %152, i64* %i109, align 8, !tbaa !24
%154 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
%tt_110 = getelementptr inbounds %struct.TValue, %struct.TValue* %154, i32 0, i32 1
store i32 19, i32* %tt_110, align 4, !tbaa !27
store i32 4, i32* %cleanup.dest.slot
br label %cleanup
if.end111: ; preds = %cond.false100, %cond.true97
store i32 0, i32* %cleanup.dest.slot
br label %cleanup
cleanup: ; preds = %if.end111, %if.then103
%155 = bitcast i64* %limit to i8*
call void @llvm.lifetime.end(i64 8, i8* %155) #2
%156 = bitcast i64* %idx to i8*
call void @llvm.lifetime.end(i64 8, i8* %156) #2
%157 = bitcast i64* %step to i8*
call void @llvm.lifetime.end(i64 8, i8* %157) #2
%cleanup.dest = load i32, i32* %cleanup.dest.slot
switch i32 %cleanup.dest, label %unreachable [
i32 0, label %cleanup.cont
i32 4, label %label_loopbody
]
cleanup.cont: ; preds = %cleanup
br label %if.end149
if.else114: ; preds = %label_forloop
%158 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr115 = getelementptr inbounds %struct.TValue, %struct.TValue* %158, i32 2
store %struct.TValue* %add.ptr115, %struct.TValue** %rb, align 4, !tbaa !1
%159 = bitcast double* %step116 to i8*
call void @llvm.lifetime.start(i64 8, i8* %159) #2
%160 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
%value_117 = getelementptr inbounds %struct.TValue, %struct.TValue* %160, i32 0, i32 0
%n118 = bitcast %union.Value* %value_117 to double*
%161 = load double, double* %n118, align 8, !tbaa !25
store double %161, double* %step116, align 8, !tbaa !25
%162 = bitcast double* %idx119 to i8*
call void @llvm.lifetime.start(i64 8, i8* %162) #2
%163 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%value_120 = getelementptr inbounds %struct.TValue, %struct.TValue* %163, i32 0, i32 0
%n121 = bitcast %union.Value* %value_120 to double*
%164 = load double, double* %n121, align 8, !tbaa !25
%165 = load double, double* %step116, align 8, !tbaa !25
%add122 = fadd double %164, %165
store double %add122, double* %idx119, align 8, !tbaa !25
%166 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr123 = getelementptr inbounds %struct.TValue, %struct.TValue* %166, i32 1
store %struct.TValue* %add.ptr123, %struct.TValue** %rc, align 4, !tbaa !1
%167 = bitcast double* %limit124 to i8*
call void @llvm.lifetime.start(i64 8, i8* %167) #2
%168 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
%value_125 = getelementptr inbounds %struct.TValue, %struct.TValue* %168, i32 0, i32 0
%n126 = bitcast %union.Value* %value_125 to double*
%169 = load double, double* %n126, align 8, !tbaa !25
store double %169, double* %limit124, align 8, !tbaa !25
%170 = load double, double* %step116, align 8, !tbaa !25
%cmp127 = fcmp olt double 0.000000e+00, %170
br i1 %cmp127, label %cond.true129, label %cond.false132
cond.true129: ; preds = %if.else114
%171 = load double, double* %idx119, align 8, !tbaa !25
%172 = load double, double* %limit124, align 8, !tbaa !25
%cmp130 = fcmp ole double %171, %172
br i1 %cmp130, label %if.then135, label %if.end143
cond.false132: ; preds = %if.else114
%173 = load double, double* %limit124, align 8, !tbaa !25
%174 = load double, double* %idx119, align 8, !tbaa !25
%cmp133 = fcmp ole double %173, %174
br i1 %cmp133, label %if.then135, label %if.end143
if.then135: ; preds = %cond.false132, %cond.true129
%175 = load double, double* %idx119, align 8, !tbaa !25
%176 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%value_136 = getelementptr inbounds %struct.TValue, %struct.TValue* %176, i32 0, i32 0
%n137 = bitcast %union.Value* %value_136 to double*
store double %175, double* %n137, align 8, !tbaa !25
%177 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%tt_138 = getelementptr inbounds %struct.TValue, %struct.TValue* %177, i32 0, i32 1
store i32 3, i32* %tt_138, align 4, !tbaa !27
%178 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%add.ptr139 = getelementptr inbounds %struct.TValue, %struct.TValue* %178, i32 3
store %struct.TValue* %add.ptr139, %struct.TValue** %rc, align 4, !tbaa !1
%179 = load double, double* %idx119, align 8, !tbaa !25
%180 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
%value_140 = getelementptr inbounds %struct.TValue, %struct.TValue* %180, i32 0, i32 0
%n141 = bitcast %union.Value* %value_140 to double*
store double %179, double* %n141, align 8, !tbaa !25
%181 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
%tt_142 = getelementptr inbounds %struct.TValue, %struct.TValue* %181, i32 0, i32 1
store i32 3, i32* %tt_142, align 4, !tbaa !27
store i32 4, i32* %cleanup.dest.slot
br label %cleanup144
if.end143: ; preds = %cond.false132, %cond.true129
store i32 0, i32* %cleanup.dest.slot
br label %cleanup144
cleanup144: ; preds = %if.end143, %if.then135
%182 = bitcast double* %limit124 to i8*
call void @llvm.lifetime.end(i64 8, i8* %182) #2
%183 = bitcast double* %idx119 to i8*
call void @llvm.lifetime.end(i64 8, i8* %183) #2
%184 = bitcast double* %step116 to i8*
call void @llvm.lifetime.end(i64 8, i8* %184) #2
%cleanup.dest147 = load i32, i32* %cleanup.dest.slot
switch i32 %cleanup.dest147, label %unreachable [
i32 0, label %cleanup.cont148
i32 4, label %label_loopbody
]
cleanup.cont148: ; preds = %cleanup144
br label %if.end149
if.end149: ; preds = %cleanup.cont148, %cleanup.cont
store i32 2, i32* %b, align 4, !tbaa !23
%185 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%add.ptr150 = getelementptr inbounds %struct.TValue, %struct.TValue* %185, i32 0
store %struct.TValue* %add.ptr150, %struct.TValue** %ra, align 4, !tbaa !1
%186 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%187 = load i32, i32* %b, align 4, !tbaa !23
%add.ptr151 = getelementptr inbounds %struct.TValue, %struct.TValue* %186, i32 %187
%add.ptr152 = getelementptr inbounds %struct.TValue, %struct.TValue* %add.ptr151, i32 -1
%188 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%top = getelementptr inbounds %struct.lua_State, %struct.lua_State* %188, i32 0, i32 4
store %struct.TValue* %add.ptr152, %struct.TValue** %top, align 4, !tbaa !29
%189 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%190 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%top153 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %190, i32 0, i32 4
%191 = load %struct.TValue*, %struct.TValue** %top153, align 4, !tbaa !29
%sub.ptr.lhs.cast = ptrtoint %struct.TValue* %189 to i32
%sub.ptr.rhs.cast = ptrtoint %struct.TValue* %191 to i32
%sub.ptr.sub = sub i32 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
%sub.ptr.div = sdiv exact i32 %sub.ptr.sub, 16
%call154 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str4, i32 0, i32 0), i32 %sub.ptr.div)
%192 = load %struct.LClosure*, %struct.LClosure** %cl, align 4, !tbaa !1
%p155 = getelementptr inbounds %struct.LClosure, %struct.LClosure* %192, i32 0, i32 5
%193 = load %struct.Proto*, %struct.Proto** %p155, align 4, !tbaa !17
%sizep = getelementptr inbounds %struct.Proto, %struct.Proto* %193, i32 0, i32 10
%194 = load i32, i32* %sizep, align 4, !tbaa !30
%cmp156 = icmp sgt i32 %194, 0
br i1 %cmp156, label %if.then158, label %if.end160
if.then158: ; preds = %if.end149
%195 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%196 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
%call159 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %195, %struct.TValue* %196)
br label %if.end160
if.end160: ; preds = %if.then158, %if.end149
%197 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%198 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
%call161 = call i32 @luaD_poscall(%struct.lua_State* %197, %struct.TValue* %198)
store i32 %call161, i32* %b, align 4, !tbaa !23
%199 = load i32, i32* %b, align 4, !tbaa !23
%tobool162 = icmp ne i32 %199, 0
br i1 %tobool162, label %if.then163, label %if.end166
if.then163: ; preds = %if.end160
%200 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%top164 = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %200, i32 0, i32 1
%201 = load %struct.TValue*, %struct.TValue** %top164, align 4, !tbaa !31
%202 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%top165 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %202, i32 0, i32 4
store %struct.TValue* %201, %struct.TValue** %top165, align 4, !tbaa !29
br label %if.end166
if.end166: ; preds = %if.then163, %if.end160
store i32 1, i32* %cleanup.dest.slot
%203 = bitcast i32* %fl to i8*
call void @llvm.lifetime.end(i64 4, i8* %203) #2
%204 = bitcast i32* %pstep_is_integer to i8*
call void @llvm.lifetime.end(i64 4, i8* %204) #2
%205 = bitcast i32* %init_is_integer to i8*
call void @llvm.lifetime.end(i64 4, i8* %205) #2
%206 = bitcast i32* %stopnow to i8*
call void @llvm.lifetime.end(i64 4, i8* %206) #2
%207 = bitcast i64* %ilimit to i8*
call void @llvm.lifetime.end(i64 8, i8* %207) #2
%208 = bitcast %struct.TValue** %pstep to i8*
call void @llvm.lifetime.end(i64 4, i8* %208) #2
%209 = bitcast %struct.TValue** %plimit to i8*
call void @llvm.lifetime.end(i64 4, i8* %209) #2
%210 = bitcast %struct.TValue** %init to i8*
call void @llvm.lifetime.end(i64 4, i8* %210) #2
%211 = bitcast i32* %b to i8*
call void @llvm.lifetime.end(i64 4, i8* %211) #2
%212 = bitcast %struct.TValue** %rc to i8*
call void @llvm.lifetime.end(i64 4, i8* %212) #2
%213 = bitcast %struct.TValue** %rb to i8*
call void @llvm.lifetime.end(i64 4, i8* %213) #2
%214 = bitcast %struct.TValue** %ra to i8*
call void @llvm.lifetime.end(i64 4, i8* %214) #2
%215 = bitcast %struct.CallInfoL** %cil to i8*
call void @llvm.lifetime.end(i64 4, i8* %215) #2
%216 = bitcast %struct.TValue** %base to i8*
call void @llvm.lifetime.end(i64 4, i8* %216) #2
%217 = bitcast %struct.TValue** %k to i8*
call void @llvm.lifetime.end(i64 4, i8* %217) #2
%218 = bitcast %struct.LClosure** %cl to i8*
call void @llvm.lifetime.end(i64 4, i8* %218) #2
%219 = bitcast %struct.CallInfoLua** %ci to i8*
call void @llvm.lifetime.end(i64 4, i8* %219) #2
ret void
unreachable: ; preds = %cleanup144, %cleanup
unreachable
}
; Function Attrs: nounwind
declare void @llvm.lifetime.start(i64, i8* nocapture) #2
; Function Attrs: nounwind
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #2
declare i32 @forlimit(%struct.TValue*, i64*, i64, i32*) #1
; Function Attrs: nounwind
declare void @llvm.lifetime.end(i64, i8* nocapture) #2
declare i32 @luaV_tonumber_(%struct.TValue*, double*) #1
declare i32 @luaG_runerror(...) #1
declare i32 @luaF_close(...) #1
declare i32 @luaD_poscall(%struct.lua_State*, %struct.TValue*) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.7.0 (trunk)"}
!1 = !{!2, !2, i64 0}
!2 = !{!"any pointer", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}
!5 = !{!6, !3, i64 4}
!6 = !{!"GCObject", !2, i64 0, !3, i64 4, !3, i64 5}
!7 = !{!8, !2, i64 16}
!8 = !{!"lua_State", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !2, i64 16, !2, i64 20, !2, i64 24, !2, i64 28, !2, i64 32, !2, i64 36, !2, i64 40, !2, i64 44, !9, i64 48, !2, i64 104, !10, i64 112, !12, i64 120, !12, i64 124, !12, i64 128, !11, i64 132, !11, i64 134, !3, i64 136, !3, i64 137}
!9 = !{!"CallInfo", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !3, i64 16, !10, i64 40, !11, i64 48, !3, i64 50, !3, i64 51}
!10 = !{!"long long", !3, i64 0}
!11 = !{!"short", !3, i64 0}
!12 = !{!"int", !3, i64 0}
!13 = !{!14, !2, i64 16}
!14 = !{!"CallInfoLua", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !15, i64 16, !10, i64 32, !11, i64 40, !3, i64 42, !3, i64 43}
!15 = !{!"CallInfoL", !2, i64 0, !2, i64 4, !10, i64 8}
!16 = !{!14, !2, i64 0}
!17 = !{!18, !2, i64 12}
!18 = !{!"LClosure", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !3, i64 16}
!19 = !{!20, !2, i64 44}
!20 = !{!"Proto", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !3, i64 7, !3, i64 8, !12, i64 12, !12, i64 16, !12, i64 20, !12, i64 24, !12, i64 28, !12, i64 32, !12, i64 36, !12, i64 40, !2, i64 44, !2, i64 48, !2, i64 52, !2, i64 56, !2, i64 60, !2, i64 64, !2, i64 68, !2, i64 72, !2, i64 76, !21, i64 80}
!21 = !{!"RaviJITProto", !3, i64 0, !2, i64 4, !2, i64 8}
!22 = !{i64 0, i64 4, !1, i64 0, i64 4, !1, i64 0, i64 4, !23, i64 0, i64 4, !1, i64 0, i64 8, !24, i64 0, i64 8, !25, i64 8, i64 4, !23}
!23 = !{!12, !12, i64 0}
!24 = !{!10, !10, i64 0}
!25 = !{!26, !26, i64 0}
!26 = !{!"double", !3, i64 0}
!27 = !{!28, !12, i64 8}
!28 = !{!"TValue", !3, i64 0, !12, i64 8}
!29 = !{!8, !2, i64 8}
!30 = !{!20, !12, i64 28}
!31 = !{!14, !2, i64 4}

@ -1,406 +0,0 @@
; ModuleID = 'lua_if_else.c'
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i32, i64, %struct.TString* }
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
; Function Attrs: nounwind
define void @testfunc(%struct.GCObject* %obj) #0 {
entry:
%obj.addr = alloca %struct.GCObject*, align 4
store %struct.GCObject* %obj, %struct.GCObject** %obj.addr, align 4, !tbaa !1
%0 = load %struct.GCObject** %obj.addr, align 4, !tbaa !1
%tt = getelementptr inbounds %struct.GCObject* %0, i32 0, i32 1
%1 = load i8* %tt, align 1, !tbaa !5
%conv = zext i8 %1 to i32
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 %conv)
ret void
}
declare i32 @printf(i8*, ...) #1
; Function Attrs: nounwind
define void @test1(%struct.lua_State* %L) #0 {
entry:
%L.addr = alloca %struct.lua_State*, align 4
%ci = alloca %struct.CallInfoLua*, align 4
%cl = alloca %struct.LClosure*, align 4
%k = alloca %struct.TValue*, align 4
%base = alloca %struct.TValue*, align 4
%cil = alloca %struct.CallInfoL*, align 4
%ra2 = alloca %struct.TValue*, align 4
%rb2 = alloca %struct.TValue*, align 4
%ra3 = alloca %struct.TValue*, align 4
%b = alloca i32, align 4
%ra = alloca %struct.TValue*, align 4
%rb = alloca %struct.TValue*, align 4
%rc = alloca %struct.TValue*, align 4
%eq = alloca i32, align 4
%a = alloca i32, align 4
%a39 = alloca i32, align 4
store %struct.lua_State* %L, %struct.lua_State** %L.addr, align 4, !tbaa !1
%0 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%ci1 = getelementptr inbounds %struct.lua_State* %0, i32 0, i32 6
%1 = load %struct.CallInfoLua** %ci1, align 4, !tbaa !7
store %struct.CallInfoLua* %1, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%2 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l = getelementptr inbounds %struct.CallInfoLua* %2, i32 0, i32 4
%base2 = getelementptr inbounds %struct.CallInfoL* %l, i32 0, i32 0
%3 = load %struct.TValue** %base2, align 4, !tbaa !13
store %struct.TValue* %3, %struct.TValue** %base, align 4, !tbaa !1
%4 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%func = getelementptr inbounds %struct.CallInfoLua* %4, i32 0, i32 0
%5 = load %struct.TValue** %func, align 4, !tbaa !16
%value_ = getelementptr inbounds %struct.TValue* %5, i32 0, i32 0
%gc = bitcast %union.Value* %value_ to %struct.GCObject**
%6 = load %struct.GCObject** %gc, align 4, !tbaa !1
%7 = bitcast %struct.GCObject* %6 to %struct.LClosure*
store %struct.LClosure* %7, %struct.LClosure** %cl, align 4, !tbaa !1
%8 = load %struct.LClosure** %cl, align 4, !tbaa !1
%p = getelementptr inbounds %struct.LClosure* %8, i32 0, i32 5
%9 = load %struct.Proto** %p, align 4, !tbaa !17
%k3 = getelementptr inbounds %struct.Proto* %9, i32 0, i32 14
%10 = load %struct.TValue** %k3, align 4, !tbaa !19
store %struct.TValue* %10, %struct.TValue** %k, align 4, !tbaa !1
%11 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr = getelementptr inbounds %struct.TValue* %11, i32 0
store %struct.TValue* %add.ptr, %struct.TValue** %ra, align 4, !tbaa !1
%12 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr4 = getelementptr inbounds %struct.TValue* %12, i32 0
store %struct.TValue* %add.ptr4, %struct.TValue** %rb, align 4, !tbaa !1
%13 = load %struct.TValue** %k, align 4, !tbaa !1
%add.ptr5 = getelementptr inbounds %struct.TValue* %13, i32 0
store %struct.TValue* %add.ptr5, %struct.TValue** %rc, align 4, !tbaa !1
%14 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%15 = load %struct.TValue** %rb, align 4, !tbaa !1
%16 = load %struct.TValue** %rc, align 4, !tbaa !1
%call = call i32 bitcast (i32 (...)* @luaV_equalobj to i32 (%struct.lua_State*, %struct.TValue*, %struct.TValue*)*)(%struct.lua_State* %14, %struct.TValue* %15, %struct.TValue* %16)
store i32 %call, i32* %eq, align 4, !tbaa !22
%17 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l6 = getelementptr inbounds %struct.CallInfoLua* %17, i32 0, i32 4
%base7 = getelementptr inbounds %struct.CallInfoL* %l6, i32 0, i32 0
%18 = load %struct.TValue** %base7, align 4, !tbaa !13
store %struct.TValue* %18, %struct.TValue** %base, align 4, !tbaa !1
%19 = load i32* %eq, align 4, !tbaa !22
%cmp = icmp eq i32 %19, 0
br i1 %cmp, label %if.then, label %if.end15
if.then: ; preds = %entry
store i32 0, i32* %a, align 4, !tbaa !22
%20 = load i32* %a, align 4, !tbaa !22
%cmp8 = icmp sgt i32 %20, 0
br i1 %cmp8, label %if.then9, label %if.end
if.then9: ; preds = %if.then
%21 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%22 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l10 = getelementptr inbounds %struct.CallInfoLua* %22, i32 0, i32 4
%base11 = getelementptr inbounds %struct.CallInfoL* %l10, i32 0, i32 0
%23 = load %struct.TValue** %base11, align 4, !tbaa !13
%24 = load i32* %a, align 4, !tbaa !22
%add.ptr12 = getelementptr inbounds %struct.TValue* %23, i32 %24
%add.ptr13 = getelementptr inbounds %struct.TValue* %add.ptr12, i32 -1
%call14 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %21, %struct.TValue* %add.ptr13)
br label %if.end
if.end: ; preds = %if.then9, %if.then
br label %label6
if.end15: ; preds = %entry
br label %label3
label3: ; preds = %if.end15
%25 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr16 = getelementptr inbounds %struct.TValue* %25, i32 1
store %struct.TValue* %add.ptr16, %struct.TValue** %ra2, align 4, !tbaa !1
%26 = load %struct.TValue** %k, align 4, !tbaa !1
%add.ptr17 = getelementptr inbounds %struct.TValue* %26, i32 1
store %struct.TValue* %add.ptr17, %struct.TValue** %rb2, align 4, !tbaa !1
%27 = load %struct.TValue** %ra2, align 4, !tbaa !1
%28 = load %struct.TValue** %rb2, align 4, !tbaa !1
%29 = bitcast %struct.TValue* %27 to i8*
%30 = bitcast %struct.TValue* %28 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %29, i8* %30, i32 16, i32 8, i1 false), !tbaa.struct !23
store i32 2, i32* %b, align 4, !tbaa !22
%31 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr18 = getelementptr inbounds %struct.TValue* %31, i32 1
store %struct.TValue* %add.ptr18, %struct.TValue** %ra3, align 4, !tbaa !1
%32 = load %struct.TValue** %ra3, align 4, !tbaa !1
%33 = load i32* %b, align 4, !tbaa !22
%add.ptr19 = getelementptr inbounds %struct.TValue* %32, i32 %33
%add.ptr20 = getelementptr inbounds %struct.TValue* %add.ptr19, i32 -1
%34 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%top = getelementptr inbounds %struct.lua_State* %34, i32 0, i32 4
store %struct.TValue* %add.ptr20, %struct.TValue** %top, align 4, !tbaa !27
%35 = load %struct.LClosure** %cl, align 4, !tbaa !1
%p21 = getelementptr inbounds %struct.LClosure* %35, i32 0, i32 5
%36 = load %struct.Proto** %p21, align 4, !tbaa !17
%sizep = getelementptr inbounds %struct.Proto* %36, i32 0, i32 10
%37 = load i32* %sizep, align 4, !tbaa !28
%cmp22 = icmp sgt i32 %37, 0
br i1 %cmp22, label %if.then23, label %if.end25
if.then23: ; preds = %label3
%38 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%39 = load %struct.TValue** %base, align 4, !tbaa !1
%call24 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %38, %struct.TValue* %39)
br label %if.end25
if.end25: ; preds = %if.then23, %label3
%40 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%41 = load %struct.TValue** %ra3, align 4, !tbaa !1
%call26 = call i32 @luaD_poscall(%struct.lua_State* %40, %struct.TValue* %41)
store i32 %call26, i32* %b, align 4, !tbaa !22
%42 = load i32* %b, align 4, !tbaa !22
%tobool = icmp ne i32 %42, 0
br i1 %tobool, label %if.then27, label %if.end30
if.then27: ; preds = %if.end25
%43 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%top28 = getelementptr inbounds %struct.CallInfoLua* %43, i32 0, i32 1
%44 = load %struct.TValue** %top28, align 4, !tbaa !29
%45 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%top29 = getelementptr inbounds %struct.lua_State* %45, i32 0, i32 4
store %struct.TValue* %44, %struct.TValue** %top29, align 4, !tbaa !27
br label %if.end30
if.end30: ; preds = %if.then27, %if.end25
br label %return
label6: ; preds = %if.end
%46 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr31 = getelementptr inbounds %struct.TValue* %46, i32 0
store %struct.TValue* %add.ptr31, %struct.TValue** %ra, align 4, !tbaa !1
%47 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr32 = getelementptr inbounds %struct.TValue* %47, i32 0
store %struct.TValue* %add.ptr32, %struct.TValue** %rb, align 4, !tbaa !1
%48 = load %struct.TValue** %k, align 4, !tbaa !1
%add.ptr33 = getelementptr inbounds %struct.TValue* %48, i32 2
store %struct.TValue* %add.ptr33, %struct.TValue** %rc, align 4, !tbaa !1
%49 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%50 = load %struct.TValue** %rb, align 4, !tbaa !1
%51 = load %struct.TValue** %rc, align 4, !tbaa !1
%call34 = call i32 bitcast (i32 (...)* @luaV_equalobj to i32 (%struct.lua_State*, %struct.TValue*, %struct.TValue*)*)(%struct.lua_State* %49, %struct.TValue* %50, %struct.TValue* %51)
store i32 %call34, i32* %eq, align 4, !tbaa !22
%52 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l35 = getelementptr inbounds %struct.CallInfoLua* %52, i32 0, i32 4
%base36 = getelementptr inbounds %struct.CallInfoL* %l35, i32 0, i32 0
%53 = load %struct.TValue** %base36, align 4, !tbaa !13
store %struct.TValue* %53, %struct.TValue** %base, align 4, !tbaa !1
%54 = load i32* %eq, align 4, !tbaa !22
%cmp37 = icmp eq i32 %54, 0
br i1 %cmp37, label %if.then38, label %if.end48
if.then38: ; preds = %label6
store i32 0, i32* %a39, align 4, !tbaa !22
%55 = load i32* %a39, align 4, !tbaa !22
%cmp40 = icmp sgt i32 %55, 0
br i1 %cmp40, label %if.then41, label %if.end47
if.then41: ; preds = %if.then38
%56 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%57 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l42 = getelementptr inbounds %struct.CallInfoLua* %57, i32 0, i32 4
%base43 = getelementptr inbounds %struct.CallInfoL* %l42, i32 0, i32 0
%58 = load %struct.TValue** %base43, align 4, !tbaa !13
%59 = load i32* %a39, align 4, !tbaa !22
%add.ptr44 = getelementptr inbounds %struct.TValue* %58, i32 %59
%add.ptr45 = getelementptr inbounds %struct.TValue* %add.ptr44, i32 -1
%call46 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %56, %struct.TValue* %add.ptr45)
br label %if.end47
if.end47: ; preds = %if.then41, %if.then38
br label %label11
if.end48: ; preds = %label6
br label %label8
label8: ; preds = %if.end48
%60 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr49 = getelementptr inbounds %struct.TValue* %60, i32 1
store %struct.TValue* %add.ptr49, %struct.TValue** %ra2, align 4, !tbaa !1
%61 = load %struct.TValue** %k, align 4, !tbaa !1
%add.ptr50 = getelementptr inbounds %struct.TValue* %61, i32 3
store %struct.TValue* %add.ptr50, %struct.TValue** %rb2, align 4, !tbaa !1
%62 = load %struct.TValue** %ra2, align 4, !tbaa !1
%63 = load %struct.TValue** %rb2, align 4, !tbaa !1
%64 = bitcast %struct.TValue* %62 to i8*
%65 = bitcast %struct.TValue* %63 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %64, i8* %65, i32 16, i32 8, i1 false), !tbaa.struct !23
store i32 2, i32* %b, align 4, !tbaa !22
%66 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr51 = getelementptr inbounds %struct.TValue* %66, i32 1
store %struct.TValue* %add.ptr51, %struct.TValue** %ra3, align 4, !tbaa !1
%67 = load %struct.TValue** %ra3, align 4, !tbaa !1
%68 = load i32* %b, align 4, !tbaa !22
%add.ptr52 = getelementptr inbounds %struct.TValue* %67, i32 %68
%add.ptr53 = getelementptr inbounds %struct.TValue* %add.ptr52, i32 -1
%69 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%top54 = getelementptr inbounds %struct.lua_State* %69, i32 0, i32 4
store %struct.TValue* %add.ptr53, %struct.TValue** %top54, align 4, !tbaa !27
%70 = load %struct.LClosure** %cl, align 4, !tbaa !1
%p55 = getelementptr inbounds %struct.LClosure* %70, i32 0, i32 5
%71 = load %struct.Proto** %p55, align 4, !tbaa !17
%sizep56 = getelementptr inbounds %struct.Proto* %71, i32 0, i32 10
%72 = load i32* %sizep56, align 4, !tbaa !28
%cmp57 = icmp sgt i32 %72, 0
br i1 %cmp57, label %if.then58, label %if.end60
if.then58: ; preds = %label8
%73 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%74 = load %struct.TValue** %base, align 4, !tbaa !1
%call59 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %73, %struct.TValue* %74)
br label %if.end60
if.end60: ; preds = %if.then58, %label8
%75 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%76 = load %struct.TValue** %ra3, align 4, !tbaa !1
%call61 = call i32 @luaD_poscall(%struct.lua_State* %75, %struct.TValue* %76)
store i32 %call61, i32* %b, align 4, !tbaa !22
%77 = load i32* %b, align 4, !tbaa !22
%tobool62 = icmp ne i32 %77, 0
br i1 %tobool62, label %if.then63, label %if.end66
if.then63: ; preds = %if.end60
%78 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%top64 = getelementptr inbounds %struct.CallInfoLua* %78, i32 0, i32 1
%79 = load %struct.TValue** %top64, align 4, !tbaa !29
%80 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%top65 = getelementptr inbounds %struct.lua_State* %80, i32 0, i32 4
store %struct.TValue* %79, %struct.TValue** %top65, align 4, !tbaa !27
br label %if.end66
if.end66: ; preds = %if.then63, %if.end60
br label %return
label11: ; preds = %if.end47
%81 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr67 = getelementptr inbounds %struct.TValue* %81, i32 1
store %struct.TValue* %add.ptr67, %struct.TValue** %ra2, align 4, !tbaa !1
%82 = load %struct.TValue** %k, align 4, !tbaa !1
%add.ptr68 = getelementptr inbounds %struct.TValue* %82, i32 4
store %struct.TValue* %add.ptr68, %struct.TValue** %rb2, align 4, !tbaa !1
%83 = load %struct.TValue** %ra2, align 4, !tbaa !1
%84 = load %struct.TValue** %rb2, align 4, !tbaa !1
%85 = bitcast %struct.TValue* %83 to i8*
%86 = bitcast %struct.TValue* %84 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %85, i8* %86, i32 16, i32 8, i1 false), !tbaa.struct !23
store i32 2, i32* %b, align 4, !tbaa !22
%87 = load %struct.TValue** %base, align 4, !tbaa !1
%add.ptr69 = getelementptr inbounds %struct.TValue* %87, i32 1
store %struct.TValue* %add.ptr69, %struct.TValue** %ra3, align 4, !tbaa !1
%88 = load %struct.TValue** %ra3, align 4, !tbaa !1
%89 = load i32* %b, align 4, !tbaa !22
%add.ptr70 = getelementptr inbounds %struct.TValue* %88, i32 %89
%add.ptr71 = getelementptr inbounds %struct.TValue* %add.ptr70, i32 -1
%90 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%top72 = getelementptr inbounds %struct.lua_State* %90, i32 0, i32 4
store %struct.TValue* %add.ptr71, %struct.TValue** %top72, align 4, !tbaa !27
%91 = load %struct.LClosure** %cl, align 4, !tbaa !1
%p73 = getelementptr inbounds %struct.LClosure* %91, i32 0, i32 5
%92 = load %struct.Proto** %p73, align 4, !tbaa !17
%sizep74 = getelementptr inbounds %struct.Proto* %92, i32 0, i32 10
%93 = load i32* %sizep74, align 4, !tbaa !28
%cmp75 = icmp sgt i32 %93, 0
br i1 %cmp75, label %if.then76, label %if.end78
if.then76: ; preds = %label11
%94 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%95 = load %struct.TValue** %base, align 4, !tbaa !1
%call77 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %94, %struct.TValue* %95)
br label %if.end78
if.end78: ; preds = %if.then76, %label11
%96 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%97 = load %struct.TValue** %ra3, align 4, !tbaa !1
%call79 = call i32 @luaD_poscall(%struct.lua_State* %96, %struct.TValue* %97)
store i32 %call79, i32* %b, align 4, !tbaa !22
%98 = load i32* %b, align 4, !tbaa !22
%tobool80 = icmp ne i32 %98, 0
br i1 %tobool80, label %if.then81, label %if.end84
if.then81: ; preds = %if.end78
%99 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
%top82 = getelementptr inbounds %struct.CallInfoLua* %99, i32 0, i32 1
%100 = load %struct.TValue** %top82, align 4, !tbaa !29
%101 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
%top83 = getelementptr inbounds %struct.lua_State* %101, i32 0, i32 4
store %struct.TValue* %100, %struct.TValue** %top83, align 4, !tbaa !27
br label %if.end84
if.end84: ; preds = %if.then81, %if.end78
br label %return
label_return: ; No predecessors!
br label %return
return: ; preds = %label_return, %if.end84, %if.end66, %if.end30
ret void
}
declare i32 @luaV_equalobj(...) #1
declare i32 @luaF_close(...) #1
; Function Attrs: nounwind
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #2
declare i32 @luaD_poscall(%struct.lua_State*, %struct.TValue*) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
!1 = metadata !{metadata !2, metadata !2, i64 0}
!2 = metadata !{metadata !"any pointer", metadata !3, i64 0}
!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0}
!4 = metadata !{metadata !"Simple C/C++ TBAA"}
!5 = metadata !{metadata !6, metadata !3, i64 4}
!6 = metadata !{metadata !"GCObject", metadata !2, i64 0, metadata !3, i64 4, metadata !3, i64 5}
!7 = metadata !{metadata !8, metadata !2, i64 16}
!8 = metadata !{metadata !"lua_State", metadata !2, i64 0, metadata !3, i64 4, metadata !3, i64 5, metadata !3, i64 6, metadata !2, i64 8, metadata !2, i64 12, metadata !2, i64 16, metadata !2, i64 20, metadata !2, i64 24, metadata !2, i64 28, metadata !2, i64 32, metadata !2, i64 36, metadata !2, i64 40, metadata !2, i64 44, metadata !9, i64 48, metadata !2, i64 104, metadata !10, i64 112, metadata !12, i64 120, metadata !12, i64 124, metadata !12, i64 128, metadata !11, i64 132, metadata !11, i64 134, metadata !3, i64 136, metadata !3, i64 137}
!9 = metadata !{metadata !"CallInfo", metadata !2, i64 0, metadata !2, i64 4, metadata !2, i64 8, metadata !2, i64 12, metadata !3, i64 16, metadata !10, i64 40, metadata !11, i64 48, metadata !3, i64 50, metadata !3, i64 51}
!10 = metadata !{metadata !"long long", metadata !3, i64 0}
!11 = metadata !{metadata !"short", metadata !3, i64 0}
!12 = metadata !{metadata !"int", metadata !3, i64 0}
!13 = metadata !{metadata !14, metadata !2, i64 16}
!14 = metadata !{metadata !"CallInfoLua", metadata !2, i64 0, metadata !2, i64 4, metadata !2, i64 8, metadata !2, i64 12, metadata !15, i64 16, metadata !10, i64 32, metadata !11, i64 40, metadata !3, i64 42, metadata !3, i64 43}
!15 = metadata !{metadata !"CallInfoL", metadata !2, i64 0, metadata !2, i64 4, metadata !10, i64 8}
!16 = metadata !{metadata !14, metadata !2, i64 0}
!17 = metadata !{metadata !18, metadata !2, i64 12}
!18 = metadata !{metadata !"LClosure", metadata !2, i64 0, metadata !3, i64 4, metadata !3, i64 5, metadata !3, i64 6, metadata !2, i64 8, metadata !2, i64 12, metadata !3, i64 16}
!19 = metadata !{metadata !20, metadata !2, i64 44}
!20 = metadata !{metadata !"Proto", metadata !2, i64 0, metadata !3, i64 4, metadata !3, i64 5, metadata !3, i64 6, metadata !3, i64 7, metadata !3, i64 8, metadata !12, i64 12, metadata !12, i64 16, metadata !12, i64 20, metadata !12, i64 24, metadata !12, i64 28, metadata !12, i64 32, metadata !12, i64 36, metadata !12, i64 40, metadata !2, i64 44, metadata !2, i64 48, metadata !2, i64 52, metadata !2, i64 56, metadata !2, i64 60, metadata !2, i64 64, metadata !2, i64 68, metadata !2, i64 72, metadata !2, i64 76, metadata !21, i64 80}
!21 = metadata !{metadata !"RaviJITProto", metadata !3, i64 0, metadata !2, i64 4, metadata !2, i64 8}
!22 = metadata !{metadata !12, metadata !12, i64 0}
!23 = metadata !{i64 0, i64 4, metadata !1, i64 0, i64 4, metadata !1, i64 0, i64 4, metadata !22, i64 0, i64 4, metadata !1, i64 0, i64 8, metadata !24, i64 0, i64 8, metadata !25, i64 8, i64 4, metadata !22}
!24 = metadata !{metadata !10, metadata !10, i64 0}
!25 = metadata !{metadata !26, metadata !26, i64 0}
!26 = metadata !{metadata !"double", metadata !3, i64 0}
!27 = metadata !{metadata !8, metadata !2, i64 8}
!28 = metadata !{metadata !20, metadata !12, i64 28}
!29 = metadata !{metadata !14, metadata !2, i64 4}

@ -1,79 +0,0 @@
; ModuleID = 'lua_op_call.c'
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
; Function Attrs: nounwind
define void @luaV_op_call(%struct.lua_State* %L, %struct.CallInfo* nocapture readonly %ci, %struct.TValue* %ra, i32 %b, i32 %c) #0 {
entry:
%sub = add nsw i32 %c, -1
%cmp = icmp eq i32 %b, 0
br i1 %cmp, label %if.end, label %if.then
if.then: ; preds = %entry
%add.ptr = getelementptr inbounds %struct.TValue* %ra, i32 %b
%top = getelementptr inbounds %struct.lua_State* %L, i32 0, i32 4
store %struct.TValue* %add.ptr, %struct.TValue** %top, align 4, !tbaa !1
br label %if.end
if.end: ; preds = %entry, %if.then
%call = tail call i32 @luaD_precall(%struct.lua_State* %L, %struct.TValue* %ra, i32 %sub, i32 1) #2
%tobool = icmp eq i32 %call, 0
br i1 %tobool, label %if.else, label %if.then1
if.then1: ; preds = %if.end
%cmp2 = icmp eq i32 %call, 1
%cmp3 = icmp sgt i32 %c, 0
%or.cond = and i1 %cmp3, %cmp2
br i1 %or.cond, label %if.then4, label %if.end8
if.then4: ; preds = %if.then1
%top5 = getelementptr inbounds %struct.CallInfo* %ci, i32 0, i32 1
%0 = load %struct.TValue** %top5, align 4, !tbaa !10
%top6 = getelementptr inbounds %struct.lua_State* %L, i32 0, i32 4
store %struct.TValue* %0, %struct.TValue** %top6, align 4, !tbaa !1
br label %if.end8
if.else: ; preds = %if.end
tail call void @luaV_execute(%struct.lua_State* %L) #2
br label %if.end8
if.end8: ; preds = %if.then1, %if.then4, %if.else
ret void
}
declare i32 @luaD_precall(%struct.lua_State*, %struct.TValue*, i32, i32) #1
declare void @luaV_execute(%struct.lua_State*) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
!1 = metadata !{metadata !2, metadata !3, i64 8}
!2 = metadata !{metadata !"lua_State", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5, metadata !4, i64 6, metadata !3, i64 8, metadata !3, i64 12, metadata !3, i64 16, metadata !3, i64 20, metadata !3, i64 24, metadata !3, i64 28, metadata !3, i64 32, metadata !3, i64 36, metadata !3, i64 40, metadata !3, i64 44, metadata !6, i64 48, metadata !3, i64 104, metadata !7, i64 112, metadata !9, i64 120, metadata !9, i64 124, metadata !9, i64 128, metadata !8, i64 132, metadata !8, i64 134, metadata !4, i64 136, metadata !4, i64 137}
!3 = metadata !{metadata !"any pointer", metadata !4, i64 0}
!4 = metadata !{metadata !"omnipotent char", metadata !5, i64 0}
!5 = metadata !{metadata !"Simple C/C++ TBAA"}
!6 = metadata !{metadata !"CallInfo", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !4, i64 16, metadata !7, i64 40, metadata !8, i64 48, metadata !4, i64 50, metadata !4, i64 51}
!7 = metadata !{metadata !"long long", metadata !4, i64 0}
!8 = metadata !{metadata !"short", metadata !4, i64 0}
!9 = metadata !{metadata !"int", metadata !4, i64 0}
!10 = metadata !{metadata !6, metadata !3, i64 4}

@ -1,142 +0,0 @@
; ModuleID = 'lua_op_forloop.c'
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
@.str1 = private unnamed_addr constant [6 x i8] c"dummy\00", align 1
; Function Attrs: nounwind
define void @testfunc(%struct.GCObject* nocapture readonly %obj) #0 {
entry:
%tt = getelementptr inbounds %struct.GCObject* %obj, i32 0, i32 1
%0 = load i8* %tt, align 1, !tbaa !1
%conv = zext i8 %0 to i32
%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 %conv) #1
ret void
}
; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) #0
; Function Attrs: nounwind
define void @test1(%struct.lua_State* nocapture readonly %L) #0 {
entry:
%ci1 = getelementptr inbounds %struct.lua_State* %L, i32 0, i32 6
%0 = load %struct.CallInfoLua** %ci1, align 4, !tbaa !6
%base2 = getelementptr inbounds %struct.CallInfoLua* %0, i32 0, i32 4, i32 0
%1 = load %struct.TValue** %base2, align 4, !tbaa !12
%add.ptr = getelementptr inbounds %struct.TValue* %1, i32 1
%tt_ = getelementptr inbounds %struct.TValue* %1, i32 1, i32 1
%value_5 = getelementptr inbounds %struct.TValue* %1, i32 3, i32 0
%i = getelementptr inbounds %union.Value* %value_5, i32 0, i32 0
%i7 = getelementptr inbounds %struct.TValue* %add.ptr, i32 0, i32 0, i32 0
%i12 = getelementptr inbounds %struct.TValue* %1, i32 2, i32 0, i32 0
%i23 = getelementptr inbounds %struct.TValue* %1, i32 4, i32 0, i32 0
%tt_24 = getelementptr inbounds %struct.TValue* %1, i32 4, i32 1
%n = bitcast %union.Value* %value_5 to double*
%n31 = bitcast %struct.TValue* %add.ptr to double*
%value_36 = getelementptr inbounds %struct.TValue* %1, i32 2, i32 0
%n37 = bitcast %union.Value* %value_36 to double*
%add.ptr48 = getelementptr inbounds %struct.TValue* %1, i32 4
%n50 = bitcast %struct.TValue* %add.ptr48 to double*
br label %label_loopbody
label_loopbody: ; preds = %label_loopbody.backedge, %entry
%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0)) #1
%2 = load i32* %tt_, align 4, !tbaa !15
%cmp = icmp eq i32 %2, 19
br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %label_loopbody
%3 = load i64* %i, align 8, !tbaa !17
%4 = load i64* %i7, align 8, !tbaa !17
%add8 = add nsw i64 %4, %3
%5 = load i64* %i12, align 8, !tbaa !17
%cmp13 = icmp sgt i64 %3, 0
br i1 %cmp13, label %cond.true, label %cond.false
cond.true: ; preds = %if.then
%cmp14 = icmp sgt i64 %add8, %5
br i1 %cmp14, label %if.end53, label %if.then16
cond.false: ; preds = %if.then
%cmp15 = icmp sgt i64 %5, %add8
br i1 %cmp15, label %if.end53, label %if.then16
if.then16: ; preds = %cond.true, %cond.false
store i64 %add8, i64* %i7, align 8, !tbaa !17
store i32 19, i32* %tt_, align 4, !tbaa !15
store i64 %add8, i64* %i23, align 8, !tbaa !17
br label %label_loopbody.backedge
label_loopbody.backedge: ; preds = %if.then16, %if.then43
%storemerge = phi i32 [ 3, %if.then43 ], [ 19, %if.then16 ]
store i32 %storemerge, i32* %tt_24, align 4, !tbaa !15
br label %label_loopbody
if.else: ; preds = %label_loopbody
%6 = load double* %n, align 8, !tbaa !18
%7 = load double* %n31, align 8, !tbaa !18
%add32 = fadd double %6, %7
%8 = load double* %n37, align 8, !tbaa !18
%cmp38 = fcmp ogt double %6, 0.000000e+00
br i1 %cmp38, label %cond.true39, label %cond.false41
cond.true39: ; preds = %if.else
%cmp40 = fcmp ugt double %add32, %8
br i1 %cmp40, label %if.end53, label %if.then43
cond.false41: ; preds = %if.else
%cmp42 = fcmp ugt double %8, %add32
br i1 %cmp42, label %if.end53, label %if.then43
if.then43: ; preds = %cond.true39, %cond.false41
store double %add32, double* %n31, align 8, !tbaa !18
store i32 3, i32* %tt_, align 4, !tbaa !15
store double %add32, double* %n50, align 8, !tbaa !18
br label %label_loopbody.backedge
if.end53: ; preds = %cond.true, %cond.false, %cond.true39, %cond.false41
ret void
}
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
!1 = metadata !{metadata !2, metadata !4, i64 4}
!2 = metadata !{metadata !"GCObject", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5}
!3 = metadata !{metadata !"any pointer", metadata !4, i64 0}
!4 = metadata !{metadata !"omnipotent char", metadata !5, i64 0}
!5 = metadata !{metadata !"Simple C/C++ TBAA"}
!6 = metadata !{metadata !7, metadata !3, i64 16}
!7 = metadata !{metadata !"lua_State", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5, metadata !4, i64 6, metadata !3, i64 8, metadata !3, i64 12, metadata !3, i64 16, metadata !3, i64 20, metadata !3, i64 24, metadata !3, i64 28, metadata !3, i64 32, metadata !3, i64 36, metadata !3, i64 40, metadata !3, i64 44, metadata !8, i64 48, metadata !3, i64 104, metadata !9, i64 112, metadata !11, i64 120, metadata !11, i64 124, metadata !11, i64 128, metadata !10, i64 132, metadata !10, i64 134, metadata !4, i64 136, metadata !4, i64 137}
!8 = metadata !{metadata !"CallInfo", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !4, i64 16, metadata !9, i64 40, metadata !10, i64 48, metadata !4, i64 50, metadata !4, i64 51}
!9 = metadata !{metadata !"long long", metadata !4, i64 0}
!10 = metadata !{metadata !"short", metadata !4, i64 0}
!11 = metadata !{metadata !"int", metadata !4, i64 0}
!12 = metadata !{metadata !13, metadata !3, i64 16}
!13 = metadata !{metadata !"CallInfoLua", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !14, i64 16, metadata !9, i64 32, metadata !10, i64 40, metadata !4, i64 42, metadata !4, i64 43}
!14 = metadata !{metadata !"CallInfoL", metadata !3, i64 0, metadata !3, i64 4, metadata !9, i64 8}
!15 = metadata !{metadata !16, metadata !11, i64 8}
!16 = metadata !{metadata !"TValue", metadata !4, i64 0, metadata !11, i64 8}
!17 = metadata !{metadata !9, metadata !9, i64 0}
!18 = metadata !{metadata !19, metadata !19, i64 0}
!19 = metadata !{metadata !"double", metadata !4, i64 0}

@ -1,204 +0,0 @@
; ModuleID = 'lua_op_forprep.c'
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
@.str1 = private unnamed_addr constant [29 x i8] c"'for' limit must be a number\00", align 1
@.str2 = private unnamed_addr constant [28 x i8] c"'for' step must be a number\00", align 1
@.str3 = private unnamed_addr constant [37 x i8] c"'for' initial value must be a number\00", align 1
; Function Attrs: nounwind
define void @testfunc(%struct.GCObject* nocapture readonly %obj) #0 {
entry:
%tt = getelementptr inbounds %struct.GCObject* %obj, i32 0, i32 1
%0 = load i8* %tt, align 1, !tbaa !1
%conv = zext i8 %0 to i32
%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 %conv) #2
ret void
}
; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) #0
; Function Attrs: nounwind
define void @test1(%struct.lua_State* %L) #0 {
entry:
%ilimit = alloca i64, align 8
%stopnow = alloca i32, align 4
%ninit = alloca double, align 8
%nlimit = alloca double, align 8
%nstep = alloca double, align 8
%ci1 = getelementptr inbounds %struct.lua_State* %L, i32 0, i32 6
%0 = load %struct.CallInfoLua** %ci1, align 4, !tbaa !6
%base2 = getelementptr inbounds %struct.CallInfoLua* %0, i32 0, i32 4, i32 0
%1 = load %struct.TValue** %base2, align 4, !tbaa !12
%add.ptr = getelementptr inbounds %struct.TValue* %1, i32 1
%add.ptr5 = getelementptr inbounds %struct.TValue* %1, i32 2
%add.ptr6 = getelementptr inbounds %struct.TValue* %1, i32 3
%tt_ = getelementptr inbounds %struct.TValue* %1, i32 1, i32 1
%2 = load i32* %tt_, align 4, !tbaa !15
%cmp = icmp eq i32 %2, 19
%tt_7 = getelementptr inbounds %struct.TValue* %1, i32 3, i32 1
%3 = load i32* %tt_7, align 4, !tbaa !15
%cmp8 = icmp eq i32 %3, 19
%i = getelementptr inbounds %struct.TValue* %add.ptr6, i32 0, i32 0, i32 0
%4 = load i64* %i, align 8, !tbaa !17
%call = call i32 @forlimit(%struct.TValue* %add.ptr5, i64* %ilimit, i64 %4, i32* %stopnow) #2
%or.cond = and i1 %cmp, %cmp8
%tobool13 = icmp ne i32 %call, 0
%or.cond73 = and i1 %or.cond, %tobool13
br i1 %or.cond73, label %if.then, label %if.else
if.then: ; preds = %entry
%5 = load i32* %stopnow, align 4, !tbaa !18
%tobool14 = icmp eq i32 %5, 0
%i16 = getelementptr inbounds %struct.TValue* %add.ptr, i32 0, i32 0, i32 0
br i1 %tobool14, label %cond.false, label %cond.end
cond.false: ; preds = %if.then
%6 = load i64* %i16, align 8, !tbaa !17
br label %cond.end
cond.end: ; preds = %if.then, %cond.false
%cond = phi i64 [ %6, %cond.false ], [ 0, %if.then ]
%7 = load i64* %ilimit, align 8, !tbaa !17
%i18 = getelementptr inbounds %struct.TValue* %add.ptr5, i32 0, i32 0, i32 0
store i64 %7, i64* %i18, align 8, !tbaa !17
%tt_19 = getelementptr inbounds %struct.TValue* %1, i32 2, i32 1
store i32 19, i32* %tt_19, align 4, !tbaa !15
%8 = load i64* %i, align 8, !tbaa !17
%sub = sub nsw i64 %cond, %8
store i64 %sub, i64* %i16, align 8, !tbaa !17
br label %label_forloop
if.else: ; preds = %entry
%tt_25 = getelementptr inbounds %struct.TValue* %1, i32 2, i32 1
%9 = load i32* %tt_25, align 4, !tbaa !15
%cmp26 = icmp eq i32 %9, 3
br i1 %cmp26, label %if.then28, label %if.else30
if.then28: ; preds = %if.else
%n = bitcast %struct.TValue* %add.ptr5 to double*
%10 = load double* %n, align 8, !tbaa !19
store double %10, double* %nlimit, align 8, !tbaa !19
br label %if.end35
if.else30: ; preds = %if.else
%call31 = call i32 @luaV_tonumber_(%struct.TValue* %add.ptr5, double* %nlimit) #2
%phitmp = icmp eq i32 %call31, 0
br i1 %phitmp, label %if.then33, label %if.end35
if.then33: ; preds = %if.else30
%call34 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %L, i8* getelementptr inbounds ([29 x i8]* @.str1, i32 0, i32 0)) #2
br label %if.end35
if.end35: ; preds = %if.else30, %if.then28, %if.then33
%11 = load double* %nlimit, align 8, !tbaa !19
%n37 = bitcast %struct.TValue* %add.ptr5 to double*
store double %11, double* %n37, align 8, !tbaa !19
store i32 3, i32* %tt_25, align 4, !tbaa !15
%12 = load i32* %tt_7, align 4, !tbaa !15
%cmp40 = icmp eq i32 %12, 3
br i1 %cmp40, label %if.then42, label %if.else45
if.then42: ; preds = %if.end35
%n44 = bitcast %struct.TValue* %add.ptr6 to double*
%13 = load double* %n44, align 8, !tbaa !19
store double %13, double* %nstep, align 8, !tbaa !19
br label %if.end51
if.else45: ; preds = %if.end35
%call46 = call i32 @luaV_tonumber_(%struct.TValue* %add.ptr6, double* %nstep) #2
%phitmp104 = icmp eq i32 %call46, 0
br i1 %phitmp104, label %if.then49, label %if.end51
if.then49: ; preds = %if.else45
%call50 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %L, i8* getelementptr inbounds ([28 x i8]* @.str2, i32 0, i32 0)) #2
br label %if.end51
if.end51: ; preds = %if.else45, %if.then42, %if.then49
%14 = load double* %nstep, align 8, !tbaa !19
%n53 = bitcast %struct.TValue* %add.ptr6 to double*
store double %14, double* %n53, align 8, !tbaa !19
store i32 3, i32* %tt_7, align 4, !tbaa !15
%15 = load i32* %tt_, align 4, !tbaa !15
%cmp56 = icmp eq i32 %15, 3
br i1 %cmp56, label %if.then58, label %if.else61
if.then58: ; preds = %if.end51
%n60 = bitcast %struct.TValue* %add.ptr to double*
%16 = load double* %n60, align 8, !tbaa !19
store double %16, double* %ninit, align 8, !tbaa !19
br label %if.end67
if.else61: ; preds = %if.end51
%call62 = call i32 @luaV_tonumber_(%struct.TValue* %add.ptr, double* %ninit) #2
%phitmp105 = icmp eq i32 %call62, 0
br i1 %phitmp105, label %if.then65, label %if.end67
if.then65: ; preds = %if.else61
%call66 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %L, i8* getelementptr inbounds ([37 x i8]* @.str3, i32 0, i32 0)) #2
br label %if.end67
if.end67: ; preds = %if.else61, %if.then58, %if.then65
%17 = load double* %ninit, align 8, !tbaa !19
%18 = load double* %nstep, align 8, !tbaa !19
%sub68 = fsub double %17, %18
%n70 = bitcast %struct.TValue* %add.ptr to double*
store double %sub68, double* %n70, align 8, !tbaa !19
br label %label_forloop
label_forloop: ; preds = %cond.end, %if.end67
%storemerge = phi i32 [ 3, %if.end67 ], [ 19, %cond.end ]
store i32 %storemerge, i32* %tt_, align 4, !tbaa !15
ret void
}
declare i32 @forlimit(%struct.TValue*, i64*, i64, i32*) #1
declare i32 @luaV_tonumber_(%struct.TValue*, double*) #1
declare i32 @luaG_runerror(...) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
!1 = metadata !{metadata !2, metadata !4, i64 4}
!2 = metadata !{metadata !"GCObject", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5}
!3 = metadata !{metadata !"any pointer", metadata !4, i64 0}
!4 = metadata !{metadata !"omnipotent char", metadata !5, i64 0}
!5 = metadata !{metadata !"Simple C/C++ TBAA"}
!6 = metadata !{metadata !7, metadata !3, i64 16}
!7 = metadata !{metadata !"lua_State", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5, metadata !4, i64 6, metadata !3, i64 8, metadata !3, i64 12, metadata !3, i64 16, metadata !3, i64 20, metadata !3, i64 24, metadata !3, i64 28, metadata !3, i64 32, metadata !3, i64 36, metadata !3, i64 40, metadata !3, i64 44, metadata !8, i64 48, metadata !3, i64 104, metadata !9, i64 112, metadata !11, i64 120, metadata !11, i64 124, metadata !11, i64 128, metadata !10, i64 132, metadata !10, i64 134, metadata !4, i64 136, metadata !4, i64 137}
!8 = metadata !{metadata !"CallInfo", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !4, i64 16, metadata !9, i64 40, metadata !10, i64 48, metadata !4, i64 50, metadata !4, i64 51}
!9 = metadata !{metadata !"long long", metadata !4, i64 0}
!10 = metadata !{metadata !"short", metadata !4, i64 0}
!11 = metadata !{metadata !"int", metadata !4, i64 0}
!12 = metadata !{metadata !13, metadata !3, i64 16}
!13 = metadata !{metadata !"CallInfoLua", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !14, i64 16, metadata !9, i64 32, metadata !10, i64 40, metadata !4, i64 42, metadata !4, i64 43}
!14 = metadata !{metadata !"CallInfoL", metadata !3, i64 0, metadata !3, i64 4, metadata !9, i64 8}
!15 = metadata !{metadata !16, metadata !11, i64 8}
!16 = metadata !{metadata !"TValue", metadata !4, i64 0, metadata !11, i64 8}
!17 = metadata !{metadata !9, metadata !9, i64 0}
!18 = metadata !{metadata !11, metadata !11, i64 0}
!19 = metadata !{metadata !20, metadata !20, i64 0}
!20 = metadata !{metadata !"double", metadata !4, i64 0}

@ -1,123 +0,0 @@
; ModuleID = 'lua_op_loadk_return.c'
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i8, i32, %union.anon.1 }
%union.anon.1 = type { i64 }
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
; Function Attrs: nounwind
define void @testfunc(%struct.GCObject* %obj) #0 {
entry:
%obj.addr = alloca %struct.GCObject*, align 4
store %struct.GCObject* %obj, %struct.GCObject** %obj.addr, align 4, !tbaa !1
%0 = load %struct.GCObject*, %struct.GCObject** %obj.addr, align 4, !tbaa !1
%tt = getelementptr inbounds %struct.GCObject, %struct.GCObject* %0, i32 0, i32 1
%1 = load i8, i8* %tt, align 1, !tbaa !5
%conv = zext i8 %1 to i32
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 %conv)
ret void
}
declare i32 @printf(i8*, ...) #1
; Function Attrs: nounwind
define void @test1(%struct.lua_State* %L, i32 %b, i32 %x) #0 {
entry:
%L.addr = alloca %struct.lua_State*, align 4
%b.addr = alloca i32, align 4
%x.addr = alloca i32, align 4
%ci = alloca %struct.CallInfoLua*, align 4
%cl = alloca %struct.LClosure*, align 4
%k = alloca %struct.TValue*, align 4
%base = alloca %struct.TValue*, align 4
%cil = alloca %struct.CallInfoL*, align 4
store %struct.lua_State* %L, %struct.lua_State** %L.addr, align 4, !tbaa !1
store i32 %b, i32* %b.addr, align 4, !tbaa !7
store i32 %x, i32* %x.addr, align 4, !tbaa !7
%0 = bitcast %struct.CallInfoLua** %ci to i8*
call void @llvm.lifetime.start(i64 4, i8* %0) #2
%1 = bitcast %struct.LClosure** %cl to i8*
call void @llvm.lifetime.start(i64 4, i8* %1) #2
%2 = bitcast %struct.TValue** %k to i8*
call void @llvm.lifetime.start(i64 4, i8* %2) #2
%3 = bitcast %struct.TValue** %base to i8*
call void @llvm.lifetime.start(i64 4, i8* %3) #2
%4 = bitcast %struct.CallInfoL** %cil to i8*
call void @llvm.lifetime.start(i64 4, i8* %4) #2
%5 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%ci1 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %5, i32 0, i32 6
%6 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci1, align 4, !tbaa !9
store %struct.CallInfoLua* %6, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%7 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %7, i32 0, i32 4
%base2 = getelementptr inbounds %struct.CallInfoL, %struct.CallInfoL* %l, i32 0, i32 0
%8 = load %struct.TValue*, %struct.TValue** %base2, align 4, !tbaa !14
store %struct.TValue* %8, %struct.TValue** %base, align 4, !tbaa !1
%9 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l3 = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %9, i32 0, i32 4
%savedpc = getelementptr inbounds %struct.CallInfoL, %struct.CallInfoL* %l3, i32 0, i32 1
store i32* %x.addr, i32** %savedpc, align 4, !tbaa !17
%10 = bitcast %struct.CallInfoL** %cil to i8*
call void @llvm.lifetime.end(i64 4, i8* %10) #2
%11 = bitcast %struct.TValue** %base to i8*
call void @llvm.lifetime.end(i64 4, i8* %11) #2
%12 = bitcast %struct.TValue** %k to i8*
call void @llvm.lifetime.end(i64 4, i8* %12) #2
%13 = bitcast %struct.LClosure** %cl to i8*
call void @llvm.lifetime.end(i64 4, i8* %13) #2
%14 = bitcast %struct.CallInfoLua** %ci to i8*
call void @llvm.lifetime.end(i64 4, i8* %14) #2
ret void
}
; Function Attrs: nounwind
declare void @llvm.lifetime.start(i64, i8* nocapture) #2
; Function Attrs: nounwind
declare void @llvm.lifetime.end(i64, i8* nocapture) #2
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.7.0 (trunk)"}
!1 = !{!2, !2, i64 0}
!2 = !{!"any pointer", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}
!5 = !{!6, !3, i64 4}
!6 = !{!"GCObject", !2, i64 0, !3, i64 4, !3, i64 5}
!7 = !{!8, !8, i64 0}
!8 = !{!"int", !3, i64 0}
!9 = !{!10, !2, i64 16}
!10 = !{!"lua_State", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !2, i64 16, !2, i64 20, !2, i64 24, !2, i64 28, !2, i64 32, !2, i64 36, !2, i64 40, !2, i64 44, !11, i64 48, !2, i64 104, !12, i64 112, !8, i64 120, !8, i64 124, !8, i64 128, !13, i64 132, !13, i64 134, !3, i64 136, !3, i64 137}
!11 = !{!"CallInfo", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !3, i64 16, !12, i64 40, !13, i64 48, !3, i64 50, !3, i64 51}
!12 = !{!"long long", !3, i64 0}
!13 = !{!"short", !3, i64 0}
!14 = !{!15, !2, i64 16}
!15 = !{!"CallInfoLua", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !16, i64 16, !12, i64 32, !13, i64 40, !3, i64 42, !3, i64 43}
!16 = !{!"CallInfoL", !2, i64 0, !2, i64 4, !12, i64 8}
!17 = !{!15, !2, i64 20}

@ -1,145 +0,0 @@
; ModuleID = 'lua_savedpc.c'
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i8, i32, %union.anon.1 }
%union.anon.1 = type { i64 }
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
; Function Attrs: nounwind
define void @test1(%struct.lua_State* %L, i32 %b) #0 {
entry:
%L.addr = alloca %struct.lua_State*, align 4
%b.addr = alloca i32, align 4
%ci = alloca %struct.CallInfoLua*, align 4
%cl = alloca %struct.LClosure*, align 4
%p = alloca %struct.Proto*, align 4
store %struct.lua_State* %L, %struct.lua_State** %L.addr, align 4, !tbaa !1
store i32 %b, i32* %b.addr, align 4, !tbaa !5
%0 = bitcast %struct.CallInfoLua** %ci to i8*
call void @llvm.lifetime.start(i64 4, i8* %0) #1
%1 = bitcast %struct.LClosure** %cl to i8*
call void @llvm.lifetime.start(i64 4, i8* %1) #1
%2 = bitcast %struct.Proto** %p to i8*
call void @llvm.lifetime.start(i64 4, i8* %2) #1
%3 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%ci1 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %3, i32 0, i32 6
%4 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci1, align 4, !tbaa !7
store %struct.CallInfoLua* %4, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%5 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%func = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %5, i32 0, i32 0
%6 = load %struct.TValue*, %struct.TValue** %func, align 4, !tbaa !12
%value_ = getelementptr inbounds %struct.TValue, %struct.TValue* %6, i32 0, i32 0
%gc = bitcast %union.Value* %value_ to %struct.GCObject**
%7 = load %struct.GCObject*, %struct.GCObject** %gc, align 4, !tbaa !1
%8 = bitcast %struct.GCObject* %7 to %struct.LClosure*
store %struct.LClosure* %8, %struct.LClosure** %cl, align 4, !tbaa !1
%9 = load %struct.LClosure*, %struct.LClosure** %cl, align 4, !tbaa !1
%p2 = getelementptr inbounds %struct.LClosure, %struct.LClosure* %9, i32 0, i32 5
%10 = load %struct.Proto*, %struct.Proto** %p2, align 4, !tbaa !15
store %struct.Proto* %10, %struct.Proto** %p, align 4, !tbaa !1
%11 = load i32, i32* %b.addr, align 4, !tbaa !5
%12 = load %struct.Proto*, %struct.Proto** %p, align 4, !tbaa !1
%code = getelementptr inbounds %struct.Proto, %struct.Proto* %12, i32 0, i32 15
%13 = load i32*, i32** %code, align 4, !tbaa !17
%arrayidx = getelementptr inbounds i32, i32* %13, i32 %11
%14 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
%l = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %14, i32 0, i32 4
%savedpc = getelementptr inbounds %struct.CallInfoL, %struct.CallInfoL* %l, i32 0, i32 1
store i32* %arrayidx, i32** %savedpc, align 4, !tbaa !20
%15 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%hookmask = getelementptr inbounds %struct.lua_State, %struct.lua_State* %15, i32 0, i32 22
%16 = load i8, i8* %hookmask, align 1, !tbaa !21
%conv = zext i8 %16 to i32
%and = and i32 %conv, 12
%tobool = icmp ne i32 %and, 0
br i1 %tobool, label %land.lhs.true, label %if.end
land.lhs.true: ; preds = %entry
%17 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%hookcount = getelementptr inbounds %struct.lua_State, %struct.lua_State* %17, i32 0, i32 19
%18 = load i32, i32* %hookcount, align 4, !tbaa !22
%dec = add nsw i32 %18, -1
store i32 %dec, i32* %hookcount, align 4, !tbaa !22
%cmp = icmp eq i32 %dec, 0
br i1 %cmp, label %if.then, label %lor.lhs.false
lor.lhs.false: ; preds = %land.lhs.true
%19 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
%hookmask4 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %19, i32 0, i32 22
%20 = load i8, i8* %hookmask4, align 1, !tbaa !21
%conv5 = zext i8 %20 to i32
%and6 = and i32 %conv5, 4
%tobool7 = icmp ne i32 %and6, 0
br i1 %tobool7, label %if.then, label %if.end
if.then: ; preds = %lor.lhs.false, %land.lhs.true
%21 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
call void @luaG_traceexec(%struct.lua_State* %21)
br label %if.end
if.end: ; preds = %if.then, %lor.lhs.false, %entry
%22 = bitcast %struct.Proto** %p to i8*
call void @llvm.lifetime.end(i64 4, i8* %22) #1
%23 = bitcast %struct.LClosure** %cl to i8*
call void @llvm.lifetime.end(i64 4, i8* %23) #1
%24 = bitcast %struct.CallInfoLua** %ci to i8*
call void @llvm.lifetime.end(i64 4, i8* %24) #1
ret void
}
; Function Attrs: nounwind
declare void @llvm.lifetime.start(i64, i8* nocapture) #1
declare void @luaG_traceexec(%struct.lua_State*) #2
; Function Attrs: nounwind
declare void @llvm.lifetime.end(i64, i8* nocapture) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.7.0 (trunk)"}
!1 = !{!2, !2, i64 0}
!2 = !{!"any pointer", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}
!5 = !{!6, !6, i64 0}
!6 = !{!"int", !3, i64 0}
!7 = !{!8, !2, i64 16}
!8 = !{!"lua_State", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !2, i64 16, !2, i64 20, !2, i64 24, !2, i64 28, !2, i64 32, !2, i64 36, !2, i64 40, !2, i64 44, !9, i64 48, !2, i64 104, !10, i64 112, !6, i64 120, !6, i64 124, !6, i64 128, !11, i64 132, !11, i64 134, !3, i64 136, !3, i64 137}
!9 = !{!"CallInfo", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !3, i64 16, !10, i64 40, !11, i64 48, !3, i64 50, !3, i64 51}
!10 = !{!"long long", !3, i64 0}
!11 = !{!"short", !3, i64 0}
!12 = !{!13, !2, i64 0}
!13 = !{!"CallInfoLua", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !14, i64 16, !10, i64 32, !11, i64 40, !3, i64 42, !3, i64 43}
!14 = !{!"CallInfoL", !2, i64 0, !2, i64 4, !10, i64 8}
!15 = !{!16, !2, i64 12}
!16 = !{!"LClosure", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !3, i64 16}
!17 = !{!18, !2, i64 48}
!18 = !{!"Proto", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !3, i64 7, !3, i64 8, !6, i64 12, !6, i64 16, !6, i64 20, !6, i64 24, !6, i64 28, !6, i64 32, !6, i64 36, !6, i64 40, !2, i64 44, !2, i64 48, !2, i64 52, !2, i64 56, !2, i64 60, !2, i64 64, !2, i64 68, !2, i64 72, !2, i64 76, !19, i64 80}
!19 = !{!"RaviJITProto", !3, i64 0, !2, i64 4, !2, i64 8}
!20 = !{!13, !2, i64 20}
!21 = !{!8, !3, i64 136}
!22 = !{!8, !6, i64 128}

@ -1,83 +0,0 @@
; ModuleID = 'lua_upval.c'
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-gnu"
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
%struct.global_State = type opaque
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
%union.anon.0 = type { %struct.TValue }
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.lua_longjmp = type opaque
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
%union.anon = type { %struct.CallInfoC }
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
%struct.lua_Debug = type opaque
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i32, i64, %struct.TString* }
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
; Function Attrs: nounwind
define void @luaV_op_call(%struct.lua_State* %L, %struct.LClosure* nocapture readonly %cl, %struct.TValue* nocapture readonly %ra, i32 %b, i32 %c) #0 {
entry:
%arrayidx = getelementptr inbounds %struct.LClosure* %cl, i32 0, i32 6, i32 %b
%0 = load %struct.UpVal** %arrayidx, align 4, !tbaa !1
%tt_ = getelementptr inbounds %struct.TValue* %ra, i32 0, i32 1
%1 = load i32* %tt_, align 4, !tbaa !5
%v = getelementptr inbounds %struct.UpVal* %0, i32 0, i32 0
%2 = load %struct.TValue** %v, align 4, !tbaa !8
%tt_1 = getelementptr inbounds %struct.TValue* %2, i32 0, i32 1
store i32 %1, i32* %tt_1, align 4, !tbaa !5
%n = bitcast %struct.TValue* %ra to double*
%3 = load double* %n, align 8, !tbaa !11
%4 = bitcast %struct.UpVal* %0 to double**
%5 = load double** %4, align 4, !tbaa !8
store double %3, double* %5, align 8, !tbaa !11
%6 = load %struct.TValue** %v, align 4, !tbaa !8
%tt_6 = getelementptr inbounds %struct.TValue* %6, i32 0, i32 1
%7 = load i32* %tt_6, align 4, !tbaa !5
%and = and i32 %7, 64
%value = getelementptr inbounds %struct.UpVal* %0, i32 0, i32 2, i32 0
%tt_7 = getelementptr inbounds %struct.UpVal* %0, i32 0, i32 2, i32 0, i32 1
store i32 1, i32* %tt_7, align 4, !tbaa !5
%8 = load %struct.TValue** %v, align 4, !tbaa !8
%cmp = icmp ne %struct.TValue* %8, %value
%tobool = icmp eq i32 %and, 0
%or.cond = or i1 %tobool, %cmp
br i1 %or.cond, label %if.end, label %if.then
if.then: ; preds = %entry
tail call void @luaC_upvalbarrier_(%struct.lua_State* %L, %struct.UpVal* %0) #2
br label %if.end
if.end: ; preds = %entry, %if.then
ret void
}
declare void @luaC_upvalbarrier_(%struct.lua_State*, %struct.UpVal*) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
!1 = metadata !{metadata !2, metadata !2, i64 0}
!2 = metadata !{metadata !"any pointer", metadata !3, i64 0}
!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0}
!4 = metadata !{metadata !"Simple C/C++ TBAA"}
!5 = metadata !{metadata !6, metadata !7, i64 8}
!6 = metadata !{metadata !"TValue", metadata !3, i64 0, metadata !7, i64 8}
!7 = metadata !{metadata !"int", metadata !3, i64 0}
!8 = metadata !{metadata !9, metadata !2, i64 0}
!9 = metadata !{metadata !"UpVal", metadata !2, i64 0, metadata !10, i64 8, metadata !3, i64 16}
!10 = metadata !{metadata !"long long", metadata !3, i64 0}
!11 = metadata !{metadata !12, metadata !12, i64 0}
!12 = metadata !{metadata !"double", metadata !3, i64 0}

@ -1,5 +0,0 @@
setlocal
set PATH=%PATH%;"c:\Program Files (x86)\LLVM\bin"
rem clang -cc1 -O1 -disable-llvm-optzns -S -emit-llvm %1
clang -cc1 -O2 -S -emit-llvm %1

@ -1,37 +0,0 @@
; ModuleID = 'tab.c'
source_filename = "tab.c"
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-pc-windows-msvc"
%struct.TValue = type { %union.Value, i32 }
%union.Value = type { i64 }
%struct.Table = type { %struct.GCObject*, i8, i8, i8, i8, i32, %struct.TValue*, %struct.Node*, %struct.Node*, %struct.Table*, %struct.GCObject*, %struct.RaviArray, i32 }
%struct.Node = type { %struct.TValue, %union.TKey }
%union.TKey = type { %struct.anon.2 }
%struct.anon.2 = type { %union.Value, i32, i32 }
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
%struct.RaviArray = type { i8*, i32, i32, i32 }
; Function Attrs: norecurse nounwind readonly
define i32 @tablevalue(%struct.TValue* nocapture readonly %v) local_unnamed_addr #0 {
entry:
%0 = bitcast %struct.TValue* %v to %struct.Table**
%1 = load %struct.Table*, %struct.Table** %0, align 8, !tbaa !1
%sizearray = getelementptr inbounds %struct.Table, %struct.Table* %1, i32 0, i32 5
%2 = load i32, i32* %sizearray, align 8, !tbaa !5
ret i32 %2
}
attributes #0 = { norecurse nounwind readonly "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.9.0 (trunk)"}
!1 = !{!2, !2, i64 0}
!2 = !{!"any pointer", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}
!5 = !{!6, !7, i64 8}
!6 = !{!"Table", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !3, i64 7, !7, i64 8, !2, i64 12, !2, i64 16, !2, i64 20, !2, i64 24, !2, i64 28, !8, i64 32, !7, i64 48}
!7 = !{!"int", !3, i64 0}
!8 = !{!"RaviArray", !2, i64 0, !3, i64 4, !7, i64 8, !7, i64 12}

@ -1 +0,0 @@
Subproject commit 5b42a99121627677952d4cf3445d795be85582de

@ -0,0 +1,30 @@
FROM ubuntu:18.04
RUN set -x \
&& apt-get update \
&& apt-get install -y libreadline-dev \
&& apt-get install -y build-essential \
&& apt-get install -y git wget \
&& apt-get install -y zlib1g-dev \
&& apt-get clean \
&& mkdir -p /Software \
&& wget -O "/Software/cmake-3.14.5-Linux-x86_64.tar.gz" "https://github.com/Kitware/CMake/releases/download/v3.14.5/cmake-3.14.5-Linux-x86_64.tar.gz" \
&& cd /Software \
&& tar xvf "cmake-3.14.5-Linux-x86_64.tar.gz" \
&& rm -rf "/Software/cmake-3.14.5-Linux-x86_64.tar.gz" \
&& mkdir -p /sources \
&& cd /sources \
&& git clone https://github.com/dibyendumajumdar/ravi.git \
&& cd /sources/ravi \
&& mkdir build \
&& cd build \
&& /Software/cmake-3.14.5-Linux-x86_64/bin/cmake -DCMAKE_INSTALL_PREFIX=/Software/ravi -DCMAKE_BUILD_TYPE=Release .. \
&& make install \
&& rm -rf /Software/cmake-3.14.5-Linux-x86_64 \
&& rm -rf /sources \
&& apt-get autoremove \
&& apt-get remove -y --purge git wget build-essential \
&& apt-get clean
ENV PATH /Software/ravi/bin:${PATH}

@ -1,5 +1,5 @@
/*
** $Id: lauxlib.h,v 1.131 2016/12/06 14:54:31 roberto Exp $
** $Id: lauxlib.h $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@ -15,6 +15,12 @@
#include "lua.h"
/* global table */
#define LUA_GNAME "_G"
typedef struct luaL_Buffer luaL_Buffer;
/* extra error code for 'luaL_loadfilex' */
#define LUA_ERRFILE (LUA_ERRERR+1)
@ -48,6 +54,7 @@ LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
api function ravi_typename() */
LUALIB_API const char *(raviL_tolstring) (lua_State *L, int idx, size_t *len);
LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
LUALIB_API int (luaL_typeerror) (lua_State *L, int arg, const char *tname);
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
size_t *l);
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg,
@ -77,6 +84,7 @@ LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def,
LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
/* predefined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)
@ -97,8 +105,10 @@ LUALIB_API lua_State *(luaL_newstate) (void);
LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
const char *r);
LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s,
const char *p, const char *r);
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s,
const char *p, const char *r);
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
@ -125,6 +135,10 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
#define luaL_argcheck(L, cond,arg,extramsg) \
((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
#define luaL_argexpected(L,cond,arg,tname) \
((void)((cond) || luaL_typeerror(L, (arg), (tname))))
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
@ -143,6 +157,10 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
/* push the value used to represent failure/error */
#define luaL_pushfail(L) lua_pushnil(L)
/*
** {======================================================
** Generic Buffer manipulation
@ -271,44 +289,12 @@ LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
#endif
/* }============================================================ */
/*
The normal Lua metatable functions in C use string
keys - these are expensive as the key needs to be
converted to Lua string, hash code computed etc.
Following implementations are taken from a post in
Lua mailing list (http://lua-users.org/lists/lua-l/2010-11/msg00151.html)
meta_key is the key assigned to the meta table of the userdata
IMPORTANT: Caller must ensure that supplied meta_key points to somewhere in
static storage as otherwise memory fault will occur.
*/
LUALIB_API int (luaL_newmetatable)(lua_State *L, const char *tname);
LUALIB_API void (luaL_setmetatable)(lua_State *L, const char *tname);
LUALIB_API void *(luaL_testudata)(lua_State *L, int ud, const char *tname);
LUALIB_API void *(luaL_checkudata)(lua_State *L, int ud, const char *tname);
#if 0
LUALIB_API int raviL_newmetatable(lua_State *L, const void *meta_key,
const char *tname);
/* meta_key is the key assigned to the meta table of the userdata */
LUALIB_API void raviL_getmetatable(lua_State *L, const void *meta_key);
/*
arg_index is the position of userdata argument on the stack
meta_key is the key assigned to the meta table of the userdata
*/
LUALIB_API void *raviL_testudata(lua_State *L, int arg_index, const void *meta_key);
/*
arg_index is the position of userdata argument on the stack
meta_key is the key assigned to the meta table of the userdata
*/
LUALIB_API void *raviL_checkudata(lua_State *L, int arg_index, const void *meta_key);
#else
#define raviL_newmetatable(L, meta_key, tname) luaL_newmetatable(L, meta_key)
#define raviL_getmetatable(L, meta_key) luaL_getmetatable(L, meta_key)
#define raviL_testudata(L, arg_index, meta_key) luaL_testudata(L, arg_index, meta_key)
#define raviL_checkudata(L, arg_index, meta_key) luaL_checkudata(L, arg_index, meta_key)
#endif
LUALIB_API void *ravi_alloc_f(void *msp, void *ptr, size_t osize, size_t nsize);
#endif

@ -1,147 +0,0 @@
/*
** $Id: lgc.h,v 2.91 2015/12/21 13:02:14 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
#ifndef lgc_h
#define lgc_h
#include "lobject.h"
#include "lstate.h"
/*
** Collectable objects may have one of three colors: white, which
** means the object is not marked; gray, which means the
** object is marked, but its references may be not marked; and
** black, which means that the object and all its references are marked.
** The main invariant of the garbage collector, while marking objects,
** is that a black object can never point to a white one. Moreover,
** any gray object must be in a "gray list" (gray, grayagain, weak,
** allweak, ephemeron) so that it can be visited again before finishing
** the collection cycle. These lists have no meaning when the invariant
** is not being enforced (e.g., sweep phase).
*/
/* how much to allocate before next GC step */
#if !defined(GCSTEPSIZE)
/* ~100 small strings */
#define GCSTEPSIZE (cast_int(100 * sizeof(TString)))
#endif
/*
** Possible states of the Garbage Collector
*/
#define GCSpropagate 0
#define GCSatomic 1
#define GCSswpallgc 2
#define GCSswpfinobj 3
#define GCSswptobefnz 4
#define GCSswpend 5
#define GCScallfin 6
#define GCSpause 7
#define issweepphase(g) \
(GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend)
/*
** macro to tell when main invariant (white objects cannot point to black
** ones) must be kept. During a collection, the sweep
** phase may break the invariant, as objects turned white may point to
** still-black objects. The invariant is restored when sweep ends and
** all objects are white again.
*/
#define keepinvariant(g) ((g)->gcstate <= GCSatomic)
/*
** some useful bit tricks
*/
#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
#define setbits(x,m) ((x) |= (m))
#define testbits(x,m) ((x) & (m))
#define bitmask(b) (1<<(b))
#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
#define l_setbit(x,b) setbits(x, bitmask(b))
#define resetbit(x,b) resetbits(x, bitmask(b))
#define testbit(x,b) testbits(x, bitmask(b))
/* Layout for bit use in 'marked' field: */
#define WHITE0BIT 0 /* object is white (type 0) */
#define WHITE1BIT 1 /* object is white (type 1) */
#define BLACKBIT 2 /* object is black */
#define FINALIZEDBIT 3 /* object has been marked for finalization */
/* bit 7 is currently used by tests (luaL_checkmemory) */
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
#define iswhite(x) testbits((x)->marked, WHITEBITS)
#define isblack(x) testbit((x)->marked, BLACKBIT)
#define isgray(x) /* neither white nor black */ \
(!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT)))
#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT)
#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS)
#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked)
#define changewhite(x) ((x)->marked ^= WHITEBITS)
#define gray2black(x) l_setbit((x)->marked, BLACKBIT)
#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
/*
** Does one step of collection when debt becomes positive. 'pre'/'pos'
** allows some adjustments to be done only when needed. macro
** 'condchangemem' is used only for heavy tests (forcing a full
** GC cycle on every opportunity)
*/
#define luaC_condGC(L,pre,pos) \
{ if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \
condchangemem(L,pre,pos); }
/* more often than not, 'pre'/'pos' are empty */
#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0)
#define luaC_barrier(L,p,v) ( \
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0))
#define luaC_barrierback(L,p,v) ( \
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
luaC_barrierback_(L,p) : cast_void(0))
#define luaC_objbarrier(L,p,o) ( \
(isblack(p) && iswhite(o)) ? \
luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0))
#define luaC_upvalbarrier(L,uv) ( \
(iscollectable((uv)->v) && !upisopen(uv)) ? \
luaC_upvalbarrier_(L,uv) : cast_void(0))
LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
LUAI_FUNC void luaC_freeallobjects (lua_State *L);
LUAI_FUNC void luaC_step (lua_State *L);
LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o);
LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv);
LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv);
#endif

@ -1,136 +0,0 @@
/*
** $Id: ltests.h,v 2.49 2015/09/22 14:18:24 roberto Exp roberto $
** Internal Header for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
#ifndef ltests_h
#define ltests_h
#include <stdlib.h>
/* test Lua with no compatibility code */
#undef LUA_COMPAT_MATHLIB
#undef LUA_COMPAT_IPAIRS
#undef LUA_COMPAT_BITLIB
#undef LUA_COMPAT_APIINTCASTS
#undef LUA_COMPAT_FLOATSTRING
#undef LUA_COMPAT_UNPACK
#undef LUA_COMPAT_LOADERS
#undef LUA_COMPAT_LOG10
#undef LUA_COMPAT_LOADSTRING
#undef LUA_COMPAT_MAXN
#undef LUA_COMPAT_MODULE
#define LUA_DEBUG
/* turn on assertions */
#undef NDEBUG
#include <assert.h>
#define lua_assert(c) assert(c)
#if !defined(RAVI_OPTION_STRING1)
#define RAVI_OPTION_STRING1 " assertions"
#endif
#define RAVI_OPTION_STRING2 " ltests"
/* to avoid warnings, and to make sure value is really unused */
#define UNUSED(x) (x=0, (void)(x))
/* test for sizes in 'l_sprintf' (make sure whole buffer is available) */
#undef l_sprintf
#if !defined(LUA_USE_C89)
#define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), snprintf(s,sz,f,i))
#else
#define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), sprintf(s,f,i))
#endif
/* memory-allocator control variables */
typedef struct Memcontrol {
unsigned long numblocks;
unsigned long total;
unsigned long maxmem;
unsigned long memlimit;
unsigned long objcount[LUA_NUMTAGS];
} Memcontrol;
// LUA_API Memcontrol l_memcontrol;
/*
** generic variable for debug tricks
*/
extern void *l_Trick;
/*
** Function to traverse and check all memory used by Lua
*/
int lua_checkmemory (lua_State *L);
/* test for lock/unlock */
struct L_EXTRA { int lock; int *plock; };
#undef LUA_EXTRASPACE
#define LUA_EXTRASPACE sizeof(struct L_EXTRA)
#define getlock(l) cast(struct L_EXTRA*, lua_getextraspace(l))
#define luai_userstateopen(l) \
(getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock))
#define luai_userstateclose(l) \
lua_assert(getlock(l)->lock == 1 && getlock(l)->plock == &(getlock(l)->lock))
#define luai_userstatethread(l,l1) \
lua_assert(getlock(l1)->plock == getlock(l)->plock)
#define luai_userstatefree(l,l1) \
lua_assert(getlock(l)->plock == getlock(l1)->plock)
#define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0)
#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0)
LUA_API int luaB_opentests (lua_State *L);
LUA_API void *debug_realloc (void *ud, void *block,
size_t osize, size_t nsize);
LUA_API Memcontrol* luaB_getmemcontrol(void);
#if defined(lua_c)
#define luaL_newstate() lua_newstate(debug_realloc, luaB_getmemcontrol())
#define luaL_openlibs(L) \
{ (luaL_openlibs)(L); \
luaL_requiref(L, "T", luaB_opentests, 1); \
lua_pop(L, 1); }
#endif
/* change some sizes to give some bugs a chance */
#undef LUAL_BUFFERSIZE
#define LUAL_BUFFERSIZE 23
#define MINSTRTABSIZE 2
//#define MAXINDEXRK 1
/* make stack-overflow tests run faster */
#undef LUAI_MAXSTACK
#define LUAI_MAXSTACK 50000
#if 0 /* Ravi change */
#undef LUAI_USER_ALIGNMENT_T
#define LUAI_USER_ALIGNMENT_T union { char b[sizeof(void*) * 8]; }
#endif
#define STRCACHE_N 23
#define STRCACHE_M 5
#endif

@ -1,5 +1,5 @@
/*
** $Id: lua.h,v 1.332 2016/12/22 15:51:20 roberto Exp $
** $Id: lua.h,v 1.332.1.2 2018/06/13 16:58:17 roberto Exp $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
@ -19,11 +19,11 @@
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "3"
#define LUA_VERSION_NUM 503
#define LUA_VERSION_RELEASE "4"
#define LUA_VERSION_RELEASE "5"
#define LUA_VERSION "Ravi " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
#define LUA_COPYRIGHT LUA_RELEASE "\nCopyright (C) 1994-2017 Lua.org, PUC-Rio\nPortions Copyright (C) 2015-2017 Dibyendu Majumdar"
#define LUA_COPYRIGHT LUA_RELEASE "\nCopyright (C) 1994-2019 Lua.org, PUC-Rio\nPortions Copyright (C) 2015-2020 Dibyendu Majumdar"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes, Dibyendu Majumdar"
@ -129,13 +129,90 @@ typedef void(*ravi_Writeline)(void);
typedef void(*ravi_Writestringerror)(const char *fmt, const char *p);
/** RAVI change end **/
/* RAVI change - always enable LTESTS in debug builds */
#if !defined(NDEBUG) && !defined(NO_LUA_DEBUG)
#define LUA_DEBUG
#endif
#ifdef LUA_DEBUG
/* turn on assertions */
#include <assert.h>
#define lua_assert(c) assert(c)
#if !defined(RAVI_OPTION_STRING1)
#define RAVI_OPTION_STRING1 "assertions "
#endif
#define RAVI_OPTION_STRING2 "ltests "
/* to avoid warnings, and to make sure value is really unused */
#define UNUSED(x) (x=0, (void)(x))
/* test for sizes in 'l_sprintf' (make sure whole buffer is available) */
#undef l_sprintf
#if !defined(LUA_USE_C89)
#define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), snprintf(s,sz,f,i))
#else
#define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), sprintf(s,f,i))
#endif
/* memory-allocator control variables */
typedef struct Memcontrol {
unsigned long numblocks;
unsigned long total;
unsigned long maxmem;
unsigned long memlimit;
unsigned long countlimit;
unsigned long objcount[LUA_NUMTAGS];
} Memcontrol;
/*
** generic variable for debug tricks
*/
extern void *l_Trick;
/*
** generic extra include file
** Function to traverse and check all memory used by Lua
*/
#if defined(LUA_USER_H)
#include LUA_USER_H
extern int lua_checkmemory(lua_State *L);
/* test for lock/unlock */
struct L_EXTRA { int lock; int *plock; };
#undef LUA_EXTRASPACE
#define LUA_EXTRASPACE sizeof(struct L_EXTRA)
#define getlock(l) cast(struct L_EXTRA*, lua_getextraspace(l))
#define luai_userstateopen(l) \
(getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock))
#define luai_userstateclose(l) \
lua_assert(getlock(l)->lock == 1 && getlock(l)->plock == &(getlock(l)->lock))
#define luai_userstatethread(l,l1) \
lua_assert(getlock(l1)->plock == getlock(l)->plock)
#define luai_userstatefree(l,l1) \
lua_assert(getlock(l)->plock == getlock(l1)->plock)
#define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0)
#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0)
LUA_API int luaB_opentests(lua_State *L);
LUA_API void *debug_realloc(void *ud, void *block,
size_t osize, size_t nsize);
LUA_API Memcontrol* luaB_getmemcontrol(void);
#if defined(lua_c)
#define luaL_newstate() lua_newstate(debug_realloc, luaB_getmemcontrol())
#define luaL_openlibs(L) \
{ (luaL_openlibs)(L); \
luaL_requiref(L, "T", luaB_opentests, 1); \
lua_pop(L, 1); }
#endif
#endif
/*
** RCS ident string
@ -149,8 +226,7 @@ extern const char lua_ident[];
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
LUA_API void (lua_close) (lua_State *L);
LUA_API lua_State *(lua_newthread) (lua_State *L);
LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
LUA_API int (lua_resetthread) (lua_State *L);
LUA_API const lua_Number *(lua_version) (lua_State *L);
@ -287,11 +363,14 @@ LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
lua_KContext ctx, lua_KFunction k);
#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL)
/* A Lua Closure must be on top of the stack. This will set _ENV upvalue */
LUA_API void (ravi_closure_setenv) (lua_State* L);
LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
const char *chunkname, const char *mode);
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
LUA_API void (raviV_raise_error) (lua_State *L, int errorcode);
/*
** coroutine functions
@ -318,8 +397,10 @@ LUA_API int (lua_isyieldable) (lua_State *L);
#define LUA_GCSETPAUSE 6
#define LUA_GCSETSTEPMUL 7
#define LUA_GCISRUNNING 9
#define LUA_GCGEN 10
#define LUA_GCINC 11
LUA_API int (lua_gc) (lua_State *L, int what, int data);
LUA_API int (lua_gc) (lua_State *L, int what, ...);
/*
@ -471,6 +552,16 @@ struct lua_Debug {
/* RAVI Extensions */
LUA_API void (ravi_pushcfastcall)(lua_State *L, void *ptr, int tag);
/* Allowed tags - subject to change. Max value is 128. Note that
each tag requires special handling in ldo.c */
enum {
RAVI_TFCF_EXP = 1,
RAVI_TFCF_LOG = 2,
RAVI_TFCF_D_D = 3,
};
/* Create an integer array (specialization of Lua table)
* of given size and initialize array with supplied initial value
*/
@ -508,10 +599,24 @@ LUA_API int ravi_is_integer_array(lua_State *L, int idx);
/* Get the raw data associated with the number array at idx.
* Note that Ravi arrays have an extra element at offset 0 - this
* function returns a pointer to &data[0]. The number of
* array elements is returned in len.
* array elements is returned in length.
*/
LUA_API lua_Number *ravi_get_number_array_rawdata(lua_State *L, int idx, size_t *len);
LUA_API lua_Integer *ravi_get_integer_array_rawdata(lua_State *L, int idx, size_t *len);
typedef struct {
lua_Number *data;
unsigned int length;
} Ravi_NumberArray;
LUA_API void ravi_get_number_array_rawdata(lua_State *L, int idx, Ravi_NumberArray *array_data);
/* Get the raw data associated with the integer array at idx.
* Note that Ravi arrays have an extra element at offset 0 - this
* function returns a pointer to &data[0]. The number of
* array elements is returned in length.
*/
typedef struct {
lua_Integer *data;
unsigned int length;
} Ravi_IntegerArray;
LUA_API void ravi_get_integer_array_rawdata(lua_State *L, int idx, Ravi_IntegerArray *array_data);
/* API to set the output functions used by Lua / Ravi
* This allows the default implementations to be overridden
@ -527,34 +632,27 @@ LUA_API void ravi_writestringerror(lua_State *L, const char *fmt, const char *p)
LUA_API void ravi_set_debugger_data(lua_State *L, void *data);
LUA_API void *ravi_get_debugger_data(lua_State *L);
/////////////////////////////////////////////////////////////////////////////
/*
Bunch of useful functions for debugging
*/
struct lua_TValue;
struct Proto;
LUA_API void ravi_dump_value(lua_State *L, const struct lua_TValue *v);
LUA_API void ravi_dump_stack(lua_State *L, const char *s);
LUA_API void ravi_dump_stacktop(lua_State *L, const char *s);
LUA_API void ravi_debug_trace(lua_State *L, int opCode, int pc);
LUA_API void ravi_print_function(const struct Proto *f, int full);
/* Dumps the ravi Bytecode to stdout */
LUA_API void ravi_dump_function(lua_State *L);
/* Returns a table of lines containing Ravi bytecode */
LUA_API int ravi_list_code(lua_State *L);
/* Returns a table with various system limits */
LUA_API int ravi_get_limits(lua_State *L);
/* Options */
LUA_API const char *raviV_options(struct lua_State *L);
/* Following are for debugging purposes only */
LUAI_DDEC int ravi_parser_debug;
LUA_API void ravi_set_debuglevel(int level);
#define RAVI_DEBUG_STACK(p) if ((ravi_parser_debug & 8) != 0) {p;} else {}
#define RAVI_ENABLED 1
#define RAVI_BYTECODE_PROFILING_ENABLED 0
/******************************************************************************
* Copyright (C) 1994-2017 Lua.org, PUC-Rio.
* Copyright (C) 1994-2019 Lua.org, PUC-Rio.
* Portions 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

@ -1,5 +1,5 @@
/*
** $Id: luaconf.h,v 1.259 2016/12/22 13:08:50 roberto Exp $
** $Id: luaconf.h,v 1.259.1.1 2017/04/19 17:29:57 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@ -61,15 +61,19 @@
#if defined(LUA_USE_LINUX)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
#ifndef LUA_USE_READLINE
#define LUA_USE_READLINE /* needs some extra libraries */
#endif
#endif
#if defined(LUA_USE_MACOSX)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* MacOS does not need -ldl */
#ifndef LUA_USE_READLINE
#define LUA_USE_READLINE /* needs an extra library: -lreadline */
#endif
#endif
/*
@ -256,9 +260,11 @@
#endif /* } */
/* more often than not the libs go together with the core */
/*
** More often than not the libs go together with the core.
*/
#define LUALIB_API LUA_API
#define LUAMOD_API LUALIB_API
#define LUAMOD_API LUA_API
/*
@ -275,15 +281,17 @@
** give a warning about it. To avoid these warnings, change to the
** default definition.
*/
#if 0
#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
defined(__ELF__) /* { */
/** RAVI change **/
#define LUAI_FUNC /* __attribute__((visibility("hidden")))*/ extern
#define LUAI_FUNC __attribute__((visibility("internal"))) extern
#else /* }{ */
#define LUAI_FUNC extern
#endif /* } */
#endif
#define LUAI_FUNC LUA_API /* AOT code needs to access symbols */
#define LUAI_DDEC LUAI_FUNC
#define LUAI_DDEC extern
#define LUAI_DDEF /* empty */
/* }================================================================== */
@ -295,6 +303,8 @@
** ===================================================================
*/
#define LUA_COMPAT_5_2
#define LUA_COMPAT_5_1
/*
@@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2.
@@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1.
@ -419,14 +429,14 @@
@@ LUA_NUMBER is the floating-point type used by Lua.
@@ LUAI_UACNUMBER is the result of a 'default argument promotion'
@@ over a floating number.
@@ l_mathlim(x) corrects limit name 'x' to the proper float type
@@ l_floatatt(x) corrects float attribute 'x' to the proper float type
** by prefixing it with one of FLT/DBL/LDBL.
@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
@@ LUA_NUMBER_FMT is the format for writing floats.
@@ lua_number2str converts a float to a string.
@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
@@ l_floor takes the floor of a float.
@@ lua_str2number converts a decimal numeric string to a number.
@@ lua_str2number converts a decimal numeral to a number.
*/
@ -438,12 +448,13 @@
l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n))
/*
@@ lua_numbertointeger converts a float number to an integer, or
** returns 0 if float is not within the range of a lua_Integer.
** (The range comparisons are tricky because of rounding. The tests
** here assume a two-complement representation, where MININTEGER always
** has an exact representation as a float; MAXINTEGER may not have one,
** and therefore its conversion to float may have an ill-defined value.)
@@ lua_numbertointeger converts a float number with an integral value
** to an integer, or returns 0 if float is not within the range of
** a lua_Integer. (The range comparisons are tricky because of
** rounding. The tests here assume a two-complement representation,
** where MININTEGER always has an exact representation as a float;
** MAXINTEGER may not have one, and therefore its conversion to float
** may have an ill-defined value.)
*/
#define lua_numbertointeger(n,p) \
((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \
@ -457,7 +468,7 @@
#define LUA_NUMBER float
#define l_mathlim(n) (FLT_##n)
#define l_floatatt(n) (FLT_##n)
#define LUAI_UACNUMBER double
@ -473,7 +484,7 @@
#define LUA_NUMBER long double
#define l_mathlim(n) (LDBL_##n)
#define l_floatatt(n) (LDBL_##n)
#define LUAI_UACNUMBER long double
@ -488,7 +499,7 @@
#define LUA_NUMBER double
#define l_mathlim(n) (DBL_##n)
#define l_floatatt(n) (DBL_##n)
#define LUAI_UACNUMBER double
@ -513,11 +524,13 @@
@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
**
@@ LUAI_UACINT is the result of a 'default argument promotion'
@@ over a lUA_INTEGER.
@@ over a LUA_INTEGER.
@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
@@ LUA_INTEGER_FMT is the format for writing integers.
@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED.
@@ LUA_UNSIGNEDBITS is the number of bits in a LUA_UNSIGNED.
@@ lua_integer2str converts an integer to a string.
*/
@ -538,6 +551,9 @@
#define LUA_UNSIGNED unsigned LUAI_UACINT
#define LUA_UNSIGNEDBITS (sizeof(LUA_UNSIGNED) * CHAR_BIT)
/* now the variable definitions */
#if LUA_INT_TYPE == LUA_INT_INT /* { int */
@ -548,6 +564,8 @@
#define LUA_MAXINTEGER INT_MAX
#define LUA_MININTEGER INT_MIN
#define LUA_MAXUNSIGNED UINT_MAX
#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */
#define LUA_INTEGER long
@ -556,6 +574,8 @@
#define LUA_MAXINTEGER LONG_MAX
#define LUA_MININTEGER LONG_MIN
#define LUA_MAXUNSIGNED ULONG_MAX
#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */
/* use presence of macro LLONG_MAX as proxy for C99 compliance */
@ -568,6 +588,8 @@
#define LUA_MAXINTEGER LLONG_MAX
#define LUA_MININTEGER LLONG_MIN
#define LUA_MAXUNSIGNED ULLONG_MAX
#elif defined(LUA_USE_WINDOWS) /* }{ */
/* in Windows, can use specific Windows types */
@ -577,6 +599,8 @@
#define LUA_MAXINTEGER _I64_MAX
#define LUA_MININTEGER _I64_MIN
#define LUA_MAXUNSIGNED _UI64_MAX
#else /* }{ */
#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \
@ -611,7 +635,7 @@
/*
@@ lua_strx2number converts an hexadecimal numeric string to a number.
@@ lua_strx2number converts a hexadecimal numeral to a number.
** In C99, 'strtod' does that conversion. Otherwise, you can
** leave 'lua_strx2number' undefined and Lua will provide its own
** implementation.
@ -622,7 +646,14 @@
/*
@@ lua_number2strx converts a float to an hexadecimal numeric string.
@@ lua_pointer2str converts a pointer to a readable string in a
** non-specified way.
*/
#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p)
/*
@@ lua_number2strx converts a float to a hexadecimal numeral.
** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
** provide its own implementation.
@ -668,7 +699,7 @@
/*
@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
** Change that if you do not want to use C locales. (Code using this
** macro must include header 'locale.h'.)
** macro must include the header 'locale.h'.)
*/
#if !defined(lua_getlocaledecpoint)
#define lua_getlocaledecpoint() (localeconv()->decimal_point[0])
@ -709,7 +740,7 @@
** {==================================================================
** Macros that affect the API and must be stable (that is, must be the
** same when you compile Lua and when you compile code that links to
** Lua). You probably do not want/need to change them.
** Lua).
** =====================================================================
*/
@ -804,7 +835,7 @@
#endif
#if defined(_MSC_VER)
#if defined(_MSC_VER) && !defined(__clang__)
#define RAVI_NORETURN __declspec(noreturn)
#define RAVI_INLINE __inline
@ -816,11 +847,11 @@
#endif
/* Use LuaJIT style hashing */
#define RAVI_USE_NEWHASH 1
#define RAVI_USE_LLVM_BRANCH_WEIGHTS 1
/* If following is defined as true then LLVM instructions emitted for arithmetic ops
priority floating point ops, else default is to prioritise integer ops */
#define RAVI_USE_LLVM_ARITH_FLOATPRIORITY 1
/* Following cause the first hash lookup to be inlined,
and if value is 2 then the second hash lookup is also inlined. */
#define RAVI_USE_INLINE_SHORTSTR_TGET 1
#endif

@ -1,5 +1,5 @@
/*
** $Id: lualib.h,v 1.45 2017/01/12 17:14:26 roberto Exp $
** $Id: lualib.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@ -52,13 +52,13 @@ LUAMOD_API int (luaopen_package) (lua_State *L);
/** RAVI change start **/
#define LUA_RAVILIBNAME "ravi"
LUAMOD_API int (raviopen_llvmjit)(lua_State *L);
LUAMOD_API int (raviopen_jit)(lua_State *L);
#define LUA_RAVICOMPLIBNAME "compiler"
LUAMOD_API int (raviopen_compiler)(lua_State *L);
#ifdef USE_LLVM
#define LUA_LLVMLIBNAME "llvm"
LUAMOD_API int (raviopen_llvmluaapi)(lua_State *L);
#endif
/** RAVI change end */
/* open all previous libraries */
LUALIB_API void (luaL_openlibs) (lua_State *L);

@ -1,104 +0,0 @@
/******************************************************************************
* Copyright (C) 2015 Dibyendu Majumdar
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************/
#ifndef RAVI_LLVM_H
#define RAVI_LLVM_H
#ifdef USE_LLVM
#include "llvm/Config/llvm-config.h"
#if (LLVM_VERSION_MAJOR < 3 || LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5)
#error Unsupported LLVM version
#endif
#if LLVM_VERSION_MAJOR >= 5
#define USE_ORC_JIT 1
#else
#define USE_ORC_JIT 0
#endif
// In lua.c we include this just to get version numbers
// We cannot have C++ headers in that case
#ifdef __cplusplus
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/Metadata.h"
#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 7
#include "llvm/PassManager.h"
#else
#include "llvm/IR/LegacyPassManager.h"
#endif
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/FormattedStream.h"
#if USE_ORC_JIT
#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"
#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,8 +0,0 @@
These are examples using the Lua LLVM bindings.
``helloworld.lua``
This illustrates creating a Lua callable C function that prints hello world.
``fib.lua``
This illustrates implementing a fibonacci sequence in LLVM using Lua.

@ -1,107 +0,0 @@
-- ensure that LLVM bindings are available
assert(llvm)
-- Get the LLVM context - right now this is the
-- global context
context = llvm.context()
assert(ravitype(context) == "LLVMcontext")
-- The bindings provide a number of predefined types that
-- are Lua specific plus some standard C types such as 'int',
-- 'double', 'int64_t', etc.
types = context:types()
print 'Listing types'
for k,v in pairs(types) do
print('\t', k, ravitype(v))
llvm.dump(v)
end
-- ***************************************************\
-- Test creating a struct type
-- Just as an exercise create a struct type
-- Initially we have an opaque struct
gcobject = context:structtype("GCObject")
assert(ravitype(gcobject) == "LLVMstructtype")
-- Create pointer to GCObject
gcobject_p = context:pointertype(gcobject)
assert(ravitype(gcobject_p) == "LLVMpointertype")
-- Add the members of the struct
-- Following demonstrates the use of predefined Lua types
gcobject:setbody {gcobject_p, types.lu_byte, types.lu_byte}
-- Display structure of gcobject
llvm.dump(gcobject)
-- ****************************************************/
-- ****************************************************\
-- Test building a Lua C function without writing C code!
--
-- Create a lua_CFunction instance
-- At this stage the function will get a module and
-- execution engine but no body
myfunc = context:lua_CFunction("myfunc")
assert(ravitype(myfunc) == "LLVMmainfunction")
-- Get a new IRBuilder intance
-- this will be garbage collected by Lua
irbuilder = context:irbuilder()
assert(ravitype(irbuilder) == "LLVMirbuilder")
-- Create a basic block
block = context:basicblock("entry")
-- Add it to the end of the function
myfunc:appendblock(block)
-- Set this as the next instruction point
irbuilder:setinsertpoint(block)
-----------------------------------------------
-- Test calling a predefined extern function
-- Get printf decl
-----------------------------------------------
printf = myfunc:extern("printf")
assert(ravitype(printf) == "LLVMconstant")
luaL_checklstring = myfunc:extern("luaL_checklstring")
assert(ravitype(luaL_checklstring) == "LLVMconstant")
hellostr = irbuilder:stringconstant("hello world!\n")
irbuilder:call(printf, { hellostr })
-------------------------------------------------
-- Test calling a random function
-------------------------------------------------
puts_type = context:functiontype(types.int, {types.pchar}, {vararg=false})
assert(ravitype(puts_type) == "LLVMfunctiontype")
-- Declare extern puts()
puts = myfunc:extern("puts", puts_type);
assert(ravitype(puts) == "LLVMconstant")
-- Get the L parameter of myfunc
L = myfunc:arg(1)
-- get the first argument as a string
str = irbuilder:call(luaL_checklstring, {L, context:intconstant(1),
context:nullconstant(types.psize_t)} )
-- Call puts
irbuilder:call(puts, { str })
-- add CreateRet(0)
inst = irbuilder:ret(context:intconstant(0))
assert(ravitype(inst) == "LLVMinstruction")
-- **************************************************/
-- what did we get?
llvm.dump(myfunc)
-- JIT compile the function
-- returns a C Closure
runnable = myfunc:compile()
print('Type of compiled function is', type(runnable))
assert(not runnable('ok\n'))

@ -1,141 +0,0 @@
-- This program demonstrates creating a
-- recursive fibonacci calc function in LLVM
-- Example based upon
-- https://llvm.org/svn/llvm-project/llvm/trunk/examples/Fibonacci/fibonacci.cpp
-- ensure that LLVM bindings are available
assert(llvm)
-- Generate the fibonacci function
local function makefib(context, module, types)
-- The goal of this snippet is to create in the memory the LLVM module
-- consisting of one function as follow:
--
-- int fib(int x) {
-- if(x<=2) return 1;
-- return fib(x-1)+fib(x-2);
-- }
--
-- Create the fib function and insert it into module M. This function is said
-- to return an int and take an int parameter.
local fibtype = context:functiontype(types.int, {types.int})
local FibF = module:newfunction("fib", fibtype)
-- Get a new IRBuilder intance
-- this will be garbage collected by Lua
local ir = context:irbuilder()
-- Add a basic block to the function.
local BB = context:basicblock("EntryBlock");
FibF:appendblock(BB)
ir:setinsertpoint(BB)
-- Get pointers to the constants.
local One = context:intconstant(1);
local Two = context:intconstant(2);
-- Get pointer to the integer argument of the add1 function...
local ArgX = FibF:arg(1); -- Get the arg.
-- Create the true_block.
local RetBB = context:basicblock("return");
FibF:appendblock(RetBB)
-- Create an exit block.
local RecurseBB = context:basicblock("recurse");
FibF:appendblock(RecurseBB)
-- Create the "if (arg <= 2) goto exitbb"
local CondInst = ir:icmpsle(ArgX, Two);
ir:condbr(CondInst, RetBB, RecurseBB);
ir:setinsertpoint(RetBB)
-- Create: ret int 1
ir:ret(One);
-- create fib(x-1)
ir:setinsertpoint(RecurseBB)
local Sub = ir:nswsub(ArgX, One);
local CallFibX1 = ir:call(FibF, {Sub}, {tailcall=true});
-- create fib(x-2)
Sub = ir:nswsub(ArgX, Two);
local CallFibX2 = ir:call(FibF, {Sub}, {tailcall=true});
-- fib(x-1)+fib(x-2)
local Sum = ir:nswadd(CallFibX1, CallFibX2);
-- Create the return instruction and add it to the basic block
ir:ret(Sum);
return FibF
end
-- Get the LLVM context - right now this is the
-- global context
local context = llvm.context()
-- The bindings provide a number of predefined types that
-- are Lua specific plus some standard C types such as 'int',
-- 'double', 'int64_t', etc.
local types = context:types()
-- Create a lua_CFunction instance
-- At this stage the function will get a module and
-- execution engine but no body
local mainfunc = context:lua_CFunction("demofib")
-- Get hold of the module
-- as we will create the fib function as an
-- iternal function
local module = mainfunc:module()
-- The actual fibonacci function is an internal
-- function so that it is pure native function
local fib = makefib(context, module, types)
-- Get a new IRBuilder
local ir = context:irbuilder()
-- Our main Lua function has only one block
local BB = context:basicblock("entry")
mainfunc:appendblock(BB)
ir:setinsertpoint(BB)
-- Declare prototypes
local luaL_checkinteger = mainfunc:extern("luaL_checkinteger")
local lua_pushinteger = mainfunc:extern("lua_pushinteger")
-- Get lua_State*
local L = mainfunc:arg(1)
-- We are expecting one integer parameter
local intparam = ir:call(luaL_checkinteger, {L, context:intconstant(1)})
-- cast from 64 to 32 bit
intparam = ir:truncorbitcast(intparam, types.int)
-- Call the fib calculator
local result = ir:call(fib, {intparam})
-- Extend from 32 to 64 bit
result = ir:zext(result, types.lua_Integer)
-- Push the final integer result
ir:call(lua_pushinteger, {L, result})
-- Return 1
ir:ret(context:intconstant(1))
---- We are done! ---
-- Dump the module for info
module:dump()
-- compile the Lua callable function
local runnable = mainfunc:compile()
assert(runnable(11) == 89)
print 'Ok'

@ -1,63 +0,0 @@
-- This small demo creates a compiled function
-- takes a string parameter and calls puts() to
-- print this
-- ensure that LLVM bindings are available
assert(llvm)
-- Get the LLVM context - right now this is the
-- global context
context = llvm.context()
-- The bindings provide a number of predefined types that
-- are Lua specific plus some standard C types such as 'int',
-- 'double', 'int64_t', etc.
types = context:types()
-- Create a lua_CFunction instance
-- At this stage the function will get a module and
-- execution engine but no body
myfunc = context:lua_CFunction("myfunc")
-- Get a new IRBuilder intance
-- this will be garbage collected by Lua
irbuilder = context:irbuilder()
-- Create a basic block
block = context:basicblock("entry")
-- Add it to the end of the function
myfunc:appendblock(block)
-- Set this as the next instruction point
irbuilder:setinsertpoint(block)
-- get declaration for luaL_checklstring
luaL_checklstring = myfunc:extern("luaL_checklstring")
-- Get the L parameter of myfunc
L = myfunc:arg(1)
-- get the first argument as a string
str = irbuilder:call(luaL_checklstring,
{L, context:intconstant(1),
context:nullconstant(types.psize_t)})
-- declare puts
puts_type = context:functiontype(types.int, {types.pchar})
puts = myfunc:extern("puts", puts_type);
-- Call puts
irbuilder:call(puts, {str})
-- add CreateRet(0)
irbuilder:ret(context:intconstant(0))
-- **************************************************/
-- what did we get?
llvm.dump(myfunc)
-- JIT compile the function
-- returns a C Closure
runnable = myfunc:compile()
assert(not runnable('hello world\n'))

@ -0,0 +1,61 @@
find_path(LUA_INCLUDE_DIR lua.h
PATHS
@CMAKE_INSTALL_PREFIX@/include/ravi
)
find_library(LUA_LIBRARIES
NAMES @LIBRAVI_NAME@ @LIBRAVI_NAME@.so @LIBRAVI_NAME@.dylib
PATHS
@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@
)
find_program(LUA_EXE
NAMES ravi_s
PATHS
@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@
)
# LUA_INCDIR - place where lua headers exist
set(LUA_INCDIR ${LUA_INCLUDE_DIR})
# LIBDIR - LUA_CPATH
if (WIN32)
get_filename_component(LIBDIR
${LUA_EXE}
DIRECTORY)
else()
get_filename_component(LIBDIR
${LUA_LIBRARIES}
DIRECTORY)
endif()
get_filename_component(LUA_BINDIR
${LUA_EXE}
DIRECTORY)
# LUA_LIBDIR - place where lua native libraries exist
get_filename_component(LUA_LIBDIR
${LUA_LIBRARIES}
DIRECTORY
)
if (NOT WIN32)
set(LUA_LIBRARIES "${LUA_LIBRARIES};m")
endif()
# LUALIB - the lua library to link against
set(LUALIB ${LUA_LIBRARIES})
# LUADIR - LUA_PATH
if (USE_LUA53)
set(LUADIR "${LUA_LIBDIR}/../share/lua/5.3")
else()
set(LUADIR "${LUA_LIBDIR}/../share/lua/5.3")
endif()
set(LUA "${LUA_EXE}")

@ -1,42 +0,0 @@
LUA=$1
if [ "$LUA" = "" ]
then
echo "Please pass path to Lua"
exit 1
fi
# Run the interpreter tests first
$LUA -e"_port=true" all.lua
if [ $? != 0 ]
then
echo "all.lua interpreted failed"
exit 1
fi
# Run tests in JIT mode without support for the line hook
$LUA -e"_port=true; ravi.auto(true,1)" all.lua
if [ $? != 0 ]
then
echo "all.lua compiled without tracehook failed"
exit 1
fi
# Run tests in JIT mode with suppor for the line hook
$LUA -e"_port=true; ravi.tracehook(true); ravi.auto(true,1)" all.lua
if [ $? != 0 ]
then
echo "all.lua compiled with tracehook failed"
exit 1
fi
# Run tests in partial JIT mode, with line hook
$LUA -e"_port=true; ravi.tracehook(true); ravi.auto(true)" all.lua
if [ $? != 0 ]
then
echo "all.lua partially compiled with tracehook failed"
exit 1
fi
cd ../ravi-tests
. ./run_tests.sh "$LUA"
cd -

@ -1,26 +0,0 @@
LUA=$1
if [ "$LUA" = "" ]
then
echo "Please pass path to Lua"
exit 1
fi
# Run the interpreter tests first
$LUA -e"_port=true" all.lua
if [ $? != 0 ]
then
echo "all.lua interpreted failed"
exit 1
fi
# Run tests in partial JIT mode, with line hook
$LUA -e"_port=true; ravi.auto(true)" all.lua
if [ $? != 0 ]
then
echo "all.lua partially compiled with tracehook failed"
exit 1
fi
cd ../ravi-tests
. ./run_tests.sh "$LUA"
cd -

@ -0,0 +1,20 @@
BasedOnStyle: google
SpaceBeforeParens: Always
IndentCaseLabels: false
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
SpaceAfterCStyleCast: true
PointerAlignment: Right
BreakBeforeBinaryOperators: All
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
ContinuationIndentWidth: 2
PenaltyBreakBeforeFirstCallParameter: 10000
SortIncludes: false
BreakStringLiterals: true
BreakBeforeTernaryOperators: true
AllowShortCaseLabelsOnASingleLine: true
ColumnLimit: 100
MaxEmptyLinesToKeep: 1
#StatementMacros: [ 'REP2', 'REP3', 'REP4', 'REP5', 'REP6', 'REP7', 'REP8' ]
#TypenameMacros: [ 'VARR', 'DLIST', 'HTAB' ]

@ -0,0 +1,71 @@
cmake_minimum_required(VERSION 3.12)
project(mir LANGUAGES C)
message(STATUS "OS type is ${CMAKE_SYSTEM_NAME}")
message(STATUS "System processor is ${CMAKE_HOST_SYSTEM_PROCESSOR}")
message(STATUS "Build type is ${CMAKE_BUILD_TYPE}")
set(MIR_HEADERS
mir.h
mir-gen.h
mir-varr.h
mir-dlist.h
mir-htab.h
mir-hash.h
mir-bitmap.h
)
set(MIR_SRCS
mir.c
mir-gen.c
)
set(C2MIR_SRCS
c2mir/c2mir.c
)
set(LIBS ${CMAKE_DL_LIBS})
if (WIN32)
set(MIR_BUILD_TYPE STATIC)
else()
set(MIR_BUILD_TYPE SHARED)
endif()
#add_definitions(-DMIR_NO_IO=0)
#add_definitions(-DMIR_NO_SCAN=1)
set_property(SOURCE ${MIR_SRCS} ${C2MIR_SRCS} ${MIR_JIT_SRCS}
APPEND
PROPERTY COMPILE_DEFINITIONS "MIR_NO_IO=0;MIR_NO_SCAN=1;MIR_NO_INTERP=1")
if ($ENV{CLION_IDE})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/c2mir)
endif()
include(CheckCCompilerFlag)
check_c_compiler_flag("-fsigned-char" COMPILER_OPT_SIGNED_CHAR_SUPPORTED)
if (COMPILER_OPT_SIGNED_CHAR_SUPPORTED AND NOT CMAKE_C_FLAGS MATCHES "-fsigned-char")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsigned-char")
endif()
check_c_compiler_flag("-fno-tree-sra" COMPILER_OPT_NO_TREE_SRA_SUPPORTED)
if (COMPILER_OPT_NO_TREE_SRA_SUPPORTED AND NOT CMAKE_C_FLAGS MATCHES "-fno-tree-sra")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-tree-sra")
endif()
check_c_compiler_flag("-fno-ipa-cp-clone" COMPILER_OPT_NO_IPA_CP_CLONE_SUPPORTED)
if (COMPILER_OPT_NO_IPA_CP_CLONE_SUPPORTED AND NOT CMAKE_C_FLAGS MATCHES "-fno-ipa-cp-clone")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-ipa-cp-clone")
endif()
include(GNUInstallDirs)
add_library(c2mir ${MIR_BUILD_TYPE}
${MIR_HEADERS}
${MIR_SRCS}
${C2MIR_SRCS})
target_link_libraries(c2mir ${LIBS})
target_include_directories(c2mir PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/c2mir)
set_property(TARGET c2mir PROPERTY C_STANDARD 11)
install(TARGETS c2mir
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT mir_Runtime
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT mir_Development
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT mir_Runtime)

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018-2020 Vladimir Makarov
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.

@ -0,0 +1,637 @@
# Medium Intermediate Representation (file mir.h)
* This document describes MIR itself, API for its creation, and MIR textual representation
* MIR textual representation is assembler like. Each directive or insn should be put on a separate line
* In MIR textual syntax we use
* `[]` for optional construction
* `{}` for repeating zero or more times
* `<>` for some informal construction description or construction already described or will be described
## MIR context
* MIR API code has an implicit state called by MIR context
* MIR context is represented by data of `MIR_context_t`
* MIR context is created by function `MIR_context_t MIR_init (void)`
* Every MIR API function (except for `MIR_init`) requires MIR context passed through the first argument of type `MIR_context_t`
* You can use MIR functions in different threads without any synchronization
if they work with different contexts in each thread
## MIR program
* MIR program consists of MIR **modules**
* To start work with MIR program, you should first call API function `MIR_init`
* API function `MIR_finish (MIR_context_t ctx)` should be called last. It frees all internal data used to work with MIR program and all IR (insns, functions, items, and modules) created in this context
* API function `MIR_output (MIR_context_t ctx, FILE *f)` outputs MIR textual representation of the program into given file
* API function `MIR_scan_string (MIR_context_t ctx, const char *str)` reads textual MIR representation given by a string
* API functions `MIR_write (MIR_context_t ctx, FILE *f)` and
`MIR_read (MIR_context_t ctx, FILE *f)` outputs and reads
**binary MIR representation** to/from given file. There are also
functions `MIR_write_with_func (MIR_context_t ctx, const int
(*writer_func) (MIR_context_t, uint8_t))` and `MIR_read_with_func
(MIR_context_t ctx, const int (*reader_func) (MIR_context_t))` to
output and read **binary MIR representation** through a function
given as an argument. The reader function should return EOF as
the end of the binary MIR representation, the writer function
should be return the number of successfully output bytes
* Binary MIR representation much more compact and faster to read than textual one
## MIR data type
* MIR program works with the following **data types**:
* `MIR_T_I8` and `MIR_T_U8` -- signed and unsigned 8-bit integer values
* `MIR_T_I16` and `MIR_T_U16` -- signed and unsigned 16-bit integer values
* `MIR_T_I32` and `MIR_T_U32` -- signed and unsigned 32-bit integer values
* `MIR_T_I64` and `MIR_T_U64` -- signed and unsigned 64-bit integer values
* ??? signed and unsigned 64-bit integer types in most cases
are interchangeable as insns themselves decide how to treat
their value
* `MIR_T_F` and `MIR_T_D` -- IEEE single and double precision floating point values
* `MIR_T_LD` - long double values. It is machine-dependent and can be IEEE double, x86 80-bit FP,
or IEEE quad precision FP values. If it is the same as double, the double type will be used instead.
So please don't expect machine-independence of MIR code working with long double values
* `MIR_T_P` -- pointer values. Depending on the target pointer value is actually 32-bit or 64-bit integer value
* `MIR_T_BLK` .. `MIR_T_BLK + MIR_BLK_NUM - 1` -- block data with given case. This type can be used only
for argument of function. Different case numbers can denote different ways to pass the block data
on a particular target to implement the target call ABI. Currently there are 5 block
types (`MIR_BLK_NUM = 5`)
* `MIR_T_RBLK` -- return block data. This type can be used only for argument of function
* MIR textual representation of the types are correspondingly `i8`,
`u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `f`, `d`, `ld`, `p`,
and `blk`
* Function `int MIR_int_type_p (MIR_type_t t)` returns TRUE if given type is an integer one (it includes pointer type too)
* Function `int MIR_fp_type_p (MIR_type_t t)` returns TRUE if given type is a floating point type
## MIR module
* Module is a high level entity of MIR program
* Module is created through API function `MIR_module_t MIR_new_module (const char *name)`
* Module creation is finished by calling API function `MIR_finish_module`
* You can create only one module at any given time
* List of all created modules can be gotten by function `DLIST (MIR_module_t) *MIR_get_module_list (MIR_context_t ctx)`
* MIR module consists of **items**. There are following **item types** (and function for their creation):
* **Function**: `MIR_func_item`
* **Import**: `MIR_import_item` (`MIR_item_t MIR_new_import (MIR_context_t ctx, const char *name)`)
* **Export**: `MIR_export_item` (`MIR_item_t MIR_new_export (MIR_context_t ctx, const char *name)`)
* **Forward declaration**: `MIR_forward_item` (`MIR_item_t MIR_new_forward (MIR_context_t ctx, const char *name)`)
* **Prototype**: `MIR_proto_item` (`MIR_new_proto_arr`, `MIR_new_proto`, `MIR_new_vararg_proto_arr`,
`MIR_new_vararg_proto` analogous to `MIR_new_func_arr`, `MIR_new_func`, `MIR_new_vararg_func_arr` and
`MIR_new_vararg_func` -- see below). The only difference is that
two or more prototype argument names can be the same
* **Data**: `MIR_data_item` with optional name
(`MIR_item_t MIR_new_data (MIR_context_t ctx, const char *name, MIR_type_t el_type, size_t nel, const void *els)`
or `MIR_item_t MIR_new_string_data (MIR_context_t ctx, const char *name, MIR_str_t str)`)
* **Reference data**: `MIR_ref_data_item` with optional name
(`MIR_item_t MIR_new_ref_data (MIR_context_t ctx, const char *name, MIR_item_t item, int64_t disp)`
* The address of the item after linking plus `disp` is used to initialize the data
* **Expression Data**: `MIR_expr_data_item` with optional name
(`MIR_item_t MIR_new_expr_data (MIR_context_t ctx, const char *name, MIR_item_func_item)`)
* Not all MIR functions can be used for expression data. The expression function should have
only one result, have no arguments, not use any call or any instruction with memory
* The expression function is called during linking and its result is used to initialize the data
* **Memory segment**: `MIR_bss_item` with optional name (`MIR_item_t MIR_new_bss (MIR_context_t ctx, const char *name, size_t len)`)
* Long double data item is changed to double one, if long double coincides with double for given target or ABI
* Names of MIR functions, imports, and prototypes should be unique in a module
* API functions `MIR_output_item (MIR_context_t ctx, FILE *f, MIR_item_t item)`
and `MIR_output_module (MIR_context_t ctx, FILE *f, MIR_module_t module)` output item or module
textual representation into given file
* MIR text module syntax looks the following:
```
<module name>: module
{<module item>}
endmodule
```
## MIR function
* Function is an module item
* Function has a **frame**, a stack memory reserved for each function invocation
* Function has **local variables** (sometimes called **registers**), a part of which are **arguments**
* A variable should have an unique name in the function
* A variable is represented by a structure of type `MIR_var_t`
* The structure contains variable name and its type
* The structure contains also type size for variable of block types (`MIR_T_BLK`..`MIR_T_BLK + MIR_BLK_NUM - 1`)
or `MIR_T_RBLK` type
* MIR function with its arguments is created through API function `MIR_item_t MIR_new_func (MIR_context_t ctx, const
char *name, size_t nres, MIR_type_t *res_types, size_t nargs, ...)`
or function `MIR_item_t MIR_new_func_arr (MIR_context_t ctx, const char *name, size_t nres, MIR_type_t *res_types, size_t nargs, MIR_var_t *arg_vars)`
* Argument variables can be any type
* This type only denotes how the argument value is passed
* Any integer type argument variable has actually type `MIR_T_I64`
* MIR functions with variable number of arguments are created through API functions
`MIR_item_t MIR_new_vararg_func (MIR_context_t ctx, const char *name, size_t nres, MIR_type_t *res_types, size_t nargs, ...)`
or function `MIR_item_t MIR_new_vararg_func_arr (MIR_context_t ctx, const char *name, size_t nres, MIR_type_t *res_types, size_t nargs, MIR_var_t *arg_vars)`
* `nargs` and `arg_vars` define only fixed arguments
* MIR functions can have more one result but possible number of results
and combination of their types are machine-defined. For example, for x86-64
the function can have upto six results and return two integer
values, two float or double values, and two long double values
in any combination
* MIR function creation is finished by calling API function `MIR_finish_func (MIR_context_t ctx)`
* You can create only one MIR function at any given time
* MIR text function syntax looks the following (arg-var always has a name besides type):
```
<function name>: func {<result type>, } [ arg-var {, <arg-var> } [, ...]]
{<insn>}
endfun
```
* Textual presentation of block type argument in `func` has form `blk:<size>(<var_name>)`.
The corresponding argument in `call` insn should have analogous form
`blk:<the same size>(<local var name containing address of passed block data>)`
* Block data are passed by value. How they are exactly passed is machine-defined:
* they are always passed on stack for x86-64, aarch64, and s390x
* they can (partially) passed through registers and on stack for ppc64
* Non-argument function variables are created through API function
`MIR_reg_t MIR_new_func_reg (MIR_context_t ctx, MIR_func_t func, MIR_type_t type, const char *name)`
* The only permitted integer type for the variable is `MIR_T_I64` (or MIR_T_U64???)
* Names in form `t<number>` can not be used as they are fixed for internal purposes
* You can create function variables even after finishing the
function creation. This can be used to modify function insns,
e.g. for optimizations
* Non-argument variable declaration syntax in MIR textual representation looks the following:
```
local [ <var type>:<var name> {, <var type>:<var name>} ]
```
* In MIR textual representation variable should be defined through `local` before its use
## MIR insn operands
* MIR insns work with operands
* There are following operands:
* Signed or unsigned **64-bit integer value operands** created through API functions
`MIR_op_t MIR_new_int_op (MIR_context_t ctx, int64_t v)` and `MIR_op_t MIR_new_uint_op (MIR_context_t ctx, uint64_t v)`
* In MIR text they are represented the same way as C integer numbers (e.g. octal, decimal, hexadecimal ones)
* **Float, double or long double value operands** created through API functions `MIR_op_t MIR_new_float_op (MIR_context_t ctx, float v)`,
`MIR_op_t MIR_new_double_op (MIR_context_t ctx, double v)`,
and `MIR_op_t MIR_new_ldouble_op (MIR_context_t ctx, long double v)`.
Long double operand is changed to double one when long double coincides with double for given target or ABI
* In MIR text they are represented the same way as C floating point numbers
* **String operands** created through API functions `MIR_op_t MIR_new_str_op (MIR_context_t ctx, MIR_str_t str)`
* In MIR text they are represented by `typedef struct MIR_str {size_t len; const char *s;} MIR_str_t`
* Strings for each operand are put into memory (which can be modified) and the memory address actually presents the string
* **Label operand** created through API function `MIR_op_t MIR_new_label_op (MIR_context_t ctx, MIR_label_t label)`
* Here `label` is a special insn created by API function `MIR_insn_t MIR_new_label (MIR_context_t ctx)`
* In MIR text, they are represented by unique label name
* **Reference operands** created through API function `MIR_op_t MIR_new_ref_op (MIR_context_t ctx, MIR_item_t item)`
* In MIR text, they are represented by the corresponding item name
* **Register (variable) operands** created through API function `MIR_op_t MIR_new_reg_op (MIR_context_t ctx, MIR_reg_t reg)`
* In MIR text they are represented by the corresponding variable name
* Value of type `MIR_reg_t` is returned by function `MIR_new_func_reg`
or can be gotten by function `MIR_reg_t MIR_reg (MIR_context_t ctx, const char *reg_name, MIR_func_t func)`, e.g. for argument-variables
* **Memory operands** consists of type, displacement, base
register, index register and index scale. Memory operand is
created through API function `MIR_op_t MIR_new_mem_op (MIR_context_t ctx, MIR_type_t type,
MIR_disp_t disp, MIR_reg_t base, MIR_reg_t index, MIR_scale_t
scale)`
* The arguments define address of memory as `disp + base + index * scale`
* Integer type input memory is transformed to 64-bit integer value with sign or zero extension
depending on signedness of the type
* result 64-bit integer value is truncated to integer memory type
* Memory operand has the following syntax in MIR text (absent displacement means zero one,
absent scale means one, scale should be 1, 2, 4, or 8):
```
<type>: <disp>
<type>: [<disp>] (<base reg> [, <index reg> [, <scale> ]])
```
* API function `MIR_output_op (MIR_context_t ctx, FILE *f, MIR_op_t op, MIR_func_t func)` outputs the operand
textual representation into given file
## MIR insns
* All MIR insns (but call or ret one) expects fixed number of operands
* Most MIR insns are 3-operand insns: two inputs and one output
* In majority cases **the first insn operand** describes where the insn result (if any) will be placed
* Only register or memory operand can be insn output (result) operand
* MIR insn can be created through API functions `MIR_insn_t MIR_new_insn (MIR_context_t ctx, MIR_insn_code_t code, ...)`
and `MIR_insn_t MIR_new_insn_arr (MIR_context_t ctx, MIR_insn_code_t code, size_t nops, MIR_op_t *ops)`
* Number of operands and their types should be what is expected by the insn being created
* You can not use `MIR_new_insn` for the creation of call and ret insns as these insns have a variable number of operands.
To create such insns you should use `MIR_new_insn_arr` or special functions
`MIR_insn_t MIR_new_call_insn (MIR_context_t ctx, size_t nops, ...)` and `MIR_insn_t MIR_new_ret_insn (MIR_context_t ctx, size_t nops, ...)`
* Long double insns are changed by double ones if long double coincides with double for given target or ABI
* You can get insn name and number of insn operands through API functions
`const char *MIR_insn_name (MIR_context_t ctx, MIR_insn_code_t code)` and `size_t MIR_insn_nops (MIR_context_t ctx, MIR_insn_t insn)`
* You can add a created insn at the beginning or end of function insn list through API functions
`MIR_prepend_insn (MIR_context_t ctx, MIR_item_t func, MIR_insn_t insn)` and `MIR_append_insn (MIR_context_t ctx, MIR_item_t func, MIR_insn_t insn)`
* You can insert a created insn in the middle of function insn list through API functions
`MIR_insert_insn_after (MIR_context_t ctx, MIR_item_t func, MIR_insn_t after, MIR_insn_t insn)` and
`MIR_insert_insn_before (MIR_context_t ctx, MIR_item_t func, MIR_insn_t before, MIR_insn_t insn)`
* The insn `after` and `before` should be already in the list
* You can remove insn from the function list through API function `MIR_remove_insn (MIR_context_t ctx, MIR_item_t func, MIR_insn_t insn)`
* The insn should be not inserted in the list if it is already there
* The insn should be not removed form the list if it is not there
* API function `MIR_output_insn (MIR_context_t ctx, FILE *f, MIR_insn_t insn, MIR_func_t func, int newline_p)` outputs the insn
textual representation into given file with a newline at the end depending on value of `newline_p`
* Insn has the following syntax in MIR text:
```
{<label name>:} [<insn name> <operand> {, <operand>}]
```
* More one insn can be put on the same line by separating the insns by `;`
### MIR move insns
* There are following MIR move insns:
| Insn Code | Nops | Description |
|-------------------------|-----:|--------------------------------------------------------|
| `MIR_MOV` | 2 | move 64-bit integer values |
| `MIR_FMOV` | 2 | move **single precision** floating point values |
| `MIR_DMOV` | 2 | move **double precision** floating point values |
| `MIR_LDMOV` | 2 | move **long double** floating point values |
### MIR integer insns
* If insn has suffix `S` in insn name, the insn works with lower 32-bit part of 64-bit integer value
* The higher part of 32-bit insn result is undefined
* If insn has prefix `U` in insn name, the insn treats integer as unsigned integers
* Some insns has no unsigned variant as MIR is oriented to CPUs with two complement integer arithmetic
(the huge majority of all CPUs)
| Insn Code | Nops | Description |
|-------------------------|-----:|--------------------------------------------------------|
| `MIR_EXT8` | 2 | **sign** extension of lower **8 bit** input part |
| `MIR_UEXT8` | 2 | **zero** extension of lower **8 bit** input part |
| `MIR_EXT16` | 2 | **sign** extension of lower **16 bit** input part |
| `MIR_UEXT16` | 2 | **zero** extension of lower **16 bit** input part |
| `MIR_EXT32` | 2 | **sign** extension of lower **32 bit** input part |
| `MIR_UEXT32` | 2 | **zero** extension of lower **32 bit** input part |
| | | |
| `MIR_NEG` | 2 | changing sign of **64-bit* integer value |
| `MIR_NEGS` | 2 | changing sign of **32-bit* integer value |
| | | |
| `MIR_ADD`, `MIR_SUB` | 3 | **64-bit** integer addition and subtraction |
| `MIR_ADDS`, `MIR_SUBS` | 3 | **32-bit** integer addition and subtraction |
| `MIR_MUL`, `MIR_DIV` | 3 | **64-bit signed** multiplication and divison |
| `MIR_UMUL`, `MIR_UDIV` | 3 | **64-bit unsigned** integer multiplication and divison |
| `MIR_MULS`, `MIR_DIVS` | 3 | **32-bit signed** multiplication and divison |
| `MIR_UMULS`, `MIR_UDIVS`| 3 | **32-bit unsigned** integer multiplication and divison |
| `MIR_MOD` | 3 | **64-bit signed** modulo operation |
| `MIR_UMOD` | 3 | **64-bit unsigned** integer modulo operation |
| `MIR_MODS` | 3 | **32-bit signed** modulo operation |
| `MIR_UMODS` | 3 | **32-bit unsigned** integer modulo operation |
| | | |
| `MIR_AND`, `MIR_OR` | 3 | **64-bit** integer bitwise AND and OR |
| `MIR_ANDS`, `MIR_ORS` | 3 | **32-bit** integer bitwise AND and OR |
| `MIR_XOR` | 3 | **64-bit** integer bitwise XOR |
| `MIR_XORS` | 3 | **32-bit** integer bitwise XOR |
| | | |
| `MIR_LSH` | 3 | **64-bit** integer left shift |
| `MIR_LSHS` | 3 | **32-bit** integer left shift |
| `MIR_RSH` | 3 | **64-bit** integer right shift with **sign** extension |
| `MIR_RSHS` | 3 | **32-bit** integer right shift with **sign** extension |
| `MIR_URSH` | 3 | **64-bit** integer right shift with **zero** extension |
| `MIR_URSHS` | 3 | **32-bit** integer right shift with **zero** extension |
| | | |
| `MIR_EQ`, `MIR_NE` | 3 | equality/inequality of **64-bit** integers |
| `MIR_EQS`, `MIR_NES` | 3 | equality/inequality of **32-bit** integers |
| `MIR_LT`, `MIR_LE` | 3 | **64-bit signed** less than/less than or equal |
| `MIR_ULT`, `MIR_ULE` | 3 | **64-bit unsigned** less than/less than or equal |
| `MIR_LTS`, `MIR_LES` | 3 | **32-bit signed** less than/less than or equal |
| `MIR_ULTS`, `MIR_ULES` | 3 | **32-bit unsigned** less than/less than or equal |
| `MIR_GT`, `MIR_GE` | 3 | **64-bit signed** greater than/greater than or equal |
| `MIR_UGT`, `MIR_UGE` | 3 | **64-bit unsigned** greater than/greater than or equal |
| `MIR_GTS`, `MIR_GES` | 3 | **32-bit signed** greater than/greater than or equal |
| `MIR_UGTS`, `MIR_UGES` | 3 | **32-bit unsigned** greater than/greater than or equal |
### MIR floating point insns
* If insn has prefix `F` in insn name, the insn is single precision float point insn. Its operands should have `MIR_T_F` type
* If insn has prefix `D` in insn name, the insn is double precision float point insn. Its operands should have `MIR_T_D` type
* Otherwise, insn has prefix `LD` in insn name and the insn is a long double insn.
Its operands should have `MIR_T_LD` type.
* The result of comparison insn is a 64-bit integer value, so the result operand should be of integer type
| Insn Code | Nops | Description |
|--------------------------------------|-----:|-----------------------------------------------------------------|
| `MIR_F2I`, `MIR_D2I`, `MIR_LD2I` | 2 | transforming floating point value into 64-bit integer |
| `MIR_F2D` | 2 | transforming single to double precision FP value |
| `MIR_F2LD` | 2 | transforming single precision to long double FP value |
| `MIR_D2F` | 2 | transforming double to single precision FP value |
| `MIR_D2LD` | 2 | transforming double precision to long double FP value |
| `MIR_LD2F` | 2 | transforming long double to single precision FP value |
| `MIR_LD2D` | 2 | transforming long double to double precision FP value |
| `MIR_I2F`, `MIR_I2D`, `MIR_I2LD` | 2 | transforming 64-bit integer into a floating point value |
| `MIR_UI2F`, `MIR_UI2D`, `MIR_UI2LD` | 2 | transforming unsigned 64-bit integer into a floating point value|
| `MIR_FNEG`, `MIR_DNEG`, `MIR_LDNEG` | 2 | changing sign of floating point value |
| `MIR_FADD`, `MIR_FSUB` | 3 | **single** precision addition and subtraction |
| `MIR_DADD`, `MIR_DSUB` | 3 | **double** precision addition and subtraction |
| `MIR_LDADD`, `MIR_LDSUB` | 3 | **long double** addition and subtraction |
| `MIR_FMUL`, `MIR_FDIV` | 3 | **single** precision multiplication and divison |
| `MIR_DMUL`, `MIR_DDIV` | 3 | **double** precision multiplication and divison |
| `MIR_LDMUL`, `MIR_LDDIV` | 3 | **long double** multiplication and divison |
| `MIR_FEQ`, `MIR_FNE` | 3 | equality/inequality of **single** precision values |
| `MIR_DEQ`, `MIR_DNE` | 3 | equality/inequality of **double** precision values |
| `MIR_LDEQ`, `MIR_LDNE` | 3 | equality/inequality of **long double** values |
| `MIR_FLT`, `MIR_FLE` | 3 | **single** precision less than/less than or equal |
| `MIR_DLT`, `MIR_DLE` | 3 | **double** precision less than/less than or equal |
| `MIR_LDLT`, `MIR_LDLE` | 3 | **long double** less than/less than or equal |
| `MIR_FGT`, `MIR_FGE` | 3 | **single** precision greater than/greater than or equal |
| `MIR_DGT`, `MIR_DGE` | 3 | **double** precision greater than/greater than or equal |
| `MIR_LDGT`, `MIR_LDGE` | 3 | **long double** greater than/greater than or equal |
### MIR branch insns
* The first operand of the insn should be label
| Insn Code | Nops | Description |
|-------------------------|-----:|---------------------------------------------------------------|
| `MIR_JMP` | 1 | unconditional jump to the label |
| `MIR_BT` | 2 | jump to the label when 2nd **64-bit** operand is **nonzero** |
| `MIR_BTS` | 2 | jump to the label when 2nd **32-bit** operand is **nonzero** |
| `MIR_BF` | 2 | jump to the label when 2nd **64-bit** operand is **zero** |
| `MIR_BFS` | 2 | jump to the label when 2nd **32-bit** operand is **zero** |
### MIR switch insn
* The first operand of `MIR_SWITCH` insn should have an integer value from 0 to `N - 1` inclusive
* The rest operands should be `N` labels, where `N > 0`
* Execution of the insn will be an jump on the label corresponding to the first operand value
* If the first operand value is out of the range of permitted values, the execution result is undefined
### MIR integer comparison and branch insn
* The first operand of the insn should be label. Label will be the next executed insn if the result of comparison is non-zero
| Insn Code | Nops | Description |
|-------------------------|-----:|---------------------------------------------------------------|
| `MIR_BEQ`, `MIR_BNE` | 3 | jump on **64-bit** equality/inequality |
| `MIR_BEQS`, `MIR_BNES` | 3 | jump on **32-bit** equality/inequality |
| `MIR_BLT`, `MIR_BLE` | 3 | jump on **signed 64-bit** less than/less than or equal |
| `MIR_UBLT`, `MIR_UBLE` | 3 | jump on **unsigned 64-bit** less than/less than or equal |
| `MIR_BLTS`, `MIR_BLES` | 3 | jump on **signed 32-bit** less than/less than or equal |
| `MIR_UBLTS`, `MIR_UBLES`| 3 | jump on **unsigned 32-bit** less than/less than or equal |
| `MIR_BGT`, `MIR_BGE` | 3 | jump on **signed 64-bit** greater than/greater than or equal |
| `MIR_UBGT`, `MIR_UBGE` | 3 | jump on **unsigned 64-bit** greater than/greater than or equal|
| `MIR_BGTS`, `MIR_BGES` | 3 | jump on **signed 32-bit** greater than/greater than or equal |
| `MIR_UBGTS`, `MIR_UBLES`| 3 | jump on **unsigned 32-bit** greater than/greater than or equal|
### MIR floating point comparison and branch insn
* The first operand of the insn should be label. Label will be the next executed insn if the result of comparison is non-zero
* See comparison semantics in the corresponding comparison insns
| Insn Code | Nops | Description |
|---------------------------|-----:|----------------------------------------------------------------|
| `MIR_FBEQ`, `MIR_FBNE` | 3 | jump on **single** precision equality/inequality |
| `MIR_DBEQ`, `MIR_DBNE` | 3 | jump on **double** precision equality/inequality |
| `MIR_LDBEQ`, `MIR_LDBNE` | 3 | jump on **long double** equality/inequality |
| `MIR_FBLT`, `MIR_FBLE` | 3 | jump on **single** precision less than/less than or equal |
| `MIR_DBLT`, `MIR_DBLE` | 3 | jump on **double** precision less than/less than or equal |
| `MIR_LDBLT`, `MIR_LDBLE` | 3 | jump on **long double** less than/less than or equal |
| `MIR_FBGT`, `MIR_FBGE` | 3 | jump on **single** precision greater than/greater than or equal|
| `MIR_DBGT`, `MIR_DBGE` | 3 | jump on **double** precision greater than/less/ than or equal |
| `MIR_LDBGT`, `MIR_LDBGE` | 3 | jump on **long double** greater than/less/ than or equal |
### MIR return insn
* Return insn has zero or more operands
* Return insn operands should correspond to return types of the function
* 64-bit integer value is truncated to the corresponding function return type first
* The return values will be the function call values
### MIR_CALL insn
* The insn has variable number of operands
* The first operand is a prototype reference operand
* The second operand is a called function address
* The prototype should correspond MIR function definition if function address represents a MIR function
* The prototype should correspond C function definition if the address is C function address
* If the prototype has *N* return types, the next *N* operands are
output operands which will contain the result values of the function
call
* The subsequent operands are arguments. Their types and number and should be the same as in the prototype
* Integer arguments are truncated according to integer prototype argument type
### MIR_INLINE insn
* This insn is analogous to `MIR_CALL` but after linking this insn
will be changed by inlined function body if it is possible
* Calls of vararg functions are never inlined
### MIR_ALLOCA insn
* Reserve memory on the stack whose size is given as the 2nd operand and assign the memory address to the 1st operand
* The reserved memory will be aligned according target ABI
### MIR_BSTART and MIR_BEND insns
* MIR users can use them implement blocks with automatic
deallocation of memory allocated by `MIR_ALLOCA` inside the
blocks. But mostly these insns are used to implement call
inlining of functions using alloca
* The both insns use one operand
* The first insn saves the stack pointer in the operand
* The second insn restores stack pointer from the operand
### MIR_VA_START, MIR_VA_ARG, MIR_VA_BLOCK_ARG, and MIR_VA_END insns
* These insns are only for variable number arguments functions
* `MIR_VA_START` and `MIR_VA_END` have one input operand, an address
of va_list structure (see C stdarg.h for more details). Unlike C
va_start, MIR_VA_START just takes one parameter
* `MIR_VA_ARG` takes va_list and any memory operand and returns
address of the next argument in the 1st insn operand. The memory
operand type defines the type of the argument
* `MIR_VA_BLOCK_ARG` takes result address, va_list address, integer operand (size),
and block type (case) number and moves the next argument passed as block of given
size and type to the result address
* va_list operand can be memory with undefined type. In this case
address of the va_list is not in the memory but is the
memory address
## MIR API example
* The following code on C creates MIR analog of C code
`int64_t loop (int64_t arg1) {int64_t count = 0; while (count < arg1) count++; return count;}`
```c
MIR_module_t m = MIR_new_module (ctx, "m");
MIR_item_t func = MIR_new_func (ctx, "loop", MIR_T_I64, 1, MIR_T_I64, "arg1");
MIR_reg_t COUNT = MIR_new_func_reg (ctx, func->u.func, MIR_T_I64, "count");
MIR_reg_t ARG1 = MIR_reg (ctx, "arg1", func->u.func);
MIR_label_t fin = MIR_new_label (ctx), cont = MIR_new_label (ctx);
MIR_append_insn (ctx, func, MIR_new_insn (ctx, MIR_MOV, MIR_new_reg_op (ctx, COUNT),
MIR_new_int_op (ctx, 0)));
MIR_append_insn (ctx, func, MIR_new_insn (ctx, MIR_BGE, MIR_new_label_op (ctx, fin),
MIR_new_reg_op (ctx, COUNT), MIR_new_reg_op (ctx, ARG1)));
MIR_append_insn (ctx, func, cont);
MIR_append_insn (ctx, func, MIR_new_insn (ctx, MIR_ADD, MIR_new_reg_op (ctx, COUNT),
MIR_new_reg_op (ctx, COUNT), MIR_new_int_op (ctx, 1)));
MIR_append_insn (ctx, func, MIR_new_insn (ctx, MIR_BLT, MIR_new_label_op (ctx, cont),
MIR_new_reg_op (ctx, COUNT), MIR_new_reg_op (ctx, ARG1)));
MIR_append_insn (ctx, func, fin);
MIR_append_insn (ctx, func, MIR_new_ret_insn (ctx, 1, MIR_new_reg_op (ctx, COUNT)));
MIR_finish_func (ctx);
MIR_finish_module (ctx);
```
## MIR text examples
* Sieve of eratosthenes:
```mir
m_sieve: module
export sieve
sieve: func i32, i32:N
local i64:iter, i64:count, i64:i, i64:k, i64:prime, i64:temp, i64:flags
alloca flags, 819000
mov iter, 0
loop: bge fin, iter, N
mov count, 0; mov i, 0
loop2: bge fin2, i, 819000
mov u8:(flags, i), 1; add i, i, 1
jmp loop2
fin2: mov i, 0
loop3: bge fin3, i, 819000
beq cont3, u8:(flags,i), 0
add temp, i, i; add prime, temp, 3; add k, i, prime
loop4: bge fin4, k, 819000
mov u8:(flags, k), 0; add k, k, prime
jmp loop4
fin4: add count, count, 1
cont3: add i, i, 1
jmp loop3
fin3: add iter, iter, 1
jmp loop
fin: rets count
endfunc
endmodule
m_ex100: module
format: string "sieve (10) = %d\n"
p_printf: proto p:fmt, i32:v
p_seive: proto i32, i32:iter
export ex100
import sieve, printf
ex100: func v
local i64:r
call p_sieve, sieve, r, 100
call p_printf, printf, format, r
endfunc
endmodule
```
* Example of block arguments and `va_stack_arg`
```mir
m0: module
f_p: proto i64, 16:blk(a), ...
f: func i64, 16:blk(a), ...
local i64:r, i64:va, i64:a2
alloca va, 32 # allocate enough space va_list
va_start va
va_stack_arg a2, va, 16 # get address of the 2nd blk arg
add r, i64:0(a), i64:8(a2)
ret r
main: func
local i64:a, i64:r
alloca a, 16
mov i64:0(a), 42
mov i64:8(a), 24
call f_p, f, r, blk:16(a), blk:16(a)
ret r
endfunc
endmodule
```
## Other MIR API functions
* MIR API can find a lot of errors. They are reported through a
error function of type `void (*MIR_error_func_t) (MIR_context ctx, MIR_error_type_t
error_type, const char *message)`. The function is considered to
never return. To see all error types, please look at the
definition of error type `MIR_error_type_t` in file mir.h
* You can get and set up the current error function through API
functions `MIR_error_func_t MIR_get_error_func (MIR_context ctx)` and `MIR_set_error_func
(MIR_context ctx, MIR_error_func_t func)`.
* The default error function prints the message into stderr and call `exit (1)`
* MIR is pretty flexible and can describe complex insns, e.g. insns
whose all operands are memory. Sometimes you need a very simple
form of MIR representation. During load of module all its functions are simplified as much
as possible by adding new insns and registers resulting in a form in which:
* immediate, memory, reference operands can be used only in move insns
* memory have only base register (no displacement and index register)
* string and float immediate operands (if `mem_float_p`) are changed onto
references for new string and data items
* Before execution of MIR code (through interpreter or machine code generated by JIT),
you need to load and link it
* You can load MIR module through API function `MIR_load_module
(MIR_context ctx, MIR_module_t m)`. The function simplifies module code.
It also allocates the module data/bss
and makes visible the exported module items to other module
during subsequent linking. There is a guarantee that the
different data/bss items will be in adjacent memory if the
data/bss items go one after another and all the data/bss items
except the first one are anonymous (it means they have no name).
Such adjacent data/bss items are called a **section**.
Alignment of the section is malloc alignment. There are no any
memory space between data/bss in the section. If you need to
provide necessary alignment of a data/bss in the section you
should do it yourself by putting additional anonymous data/bss
before given data/bss if it is necessary. BSS memory is
initialized by zero and data memory is initialized by the
corresponding data. If there is already an exported item with
the same name, it will be not visible for linking anymore. Such
visibility mechanism permits usage of different versions of the
same function
* Reference data are initialized not during loading but during linking after
the referenced item address is known. The address is used for the data
initialization
* Expression data are also initialized not during loading but during linking after
all addresses are known. The expression function is evaluated by the interpreter
and its evaluation result is used for the data initialization. For example, if
you need to initialize data by item address plus offset you should use
an expression data
* MIR permits to use imported items not implemented in MIR, for
example to use C standard function `strcmp`. You need to inform
MIR about it. API function `MIR_load_external (MIR_context ctx, const char
*name, void *addr)` informs that imported items with given name
have given address (e.g. C function address or data)
* Imports/exports of modules loaded since the last link can be
linked through API function `MIR_link (MIR_context ctx, void (*set_interface) (MIR_item_t item),
void * (*import_resolver) (const char *))`
* `MIR_link` function inlines most `MIR_INLINE` calls
* `MIR_link` function also sets up call interface
* If you pass `MIR_set_interp_interface` to `MIR_link`, then
called functions from MIR code will be interpreted
* If you pass `MIR_set_gen_interface` to `MIR_link`, then
MIR-generator will generate machine code for all loaded MIR
functions and called functions from MIR code will execute the
machine code
* If you pass `MIR_set_lazy_gen_interface` to `MIR_link`, then
MIR-generator will generate machine code only on the first
function call and called functions from MIR code will execute
the machine code
* If you pass non-null `import_resolver` function, it will be
called for defining address for import without definition.
The function get the import name and return the address which
will be used for the import item. This function can be useful
for searching `dlopen` library symbols when use of
MIR_load_external is not convenient
# MIR code execution
* Linked MIR code can be executed by an **interpreter** or machine code generated by **MIR generator**
# MIR code interpretation
* The interpreter is an obligatory part of MIR API because it can be used during linking
* The interpreter is automatically initialized and finished with MIR API initialization and finishing
* The interpreter works with values represented by type `MIR_val_t` which is union
`union {..., int64_t i; uint64_t u; float f; double d; long double d;}`
* You can execute a MIR function code by API functions `void
MIR_interp (MIR_context ctx, MIR_item_t func_item, MIR_val_t *results, size_t nargs, ...)` and
`void MIR_interp_arr (MIR_context ctx, MIR_item_t func_item, MIR_val_t *results, size_t nargs,
MIR_val_t *vals)`
* The function results are returned through parameter `results`. You should pass
a container of enough size to return all function results.
* You can execute a MIR function code also through C function call
mechanism. First you need to setup the C function interface
through API function `MIR_set_interp_interface (MIR_context ctx, MIR_item_t
func_item)`. After that you can `func_item->addr` to call the
MIR function as usual C function
* C function interface is implemented by generation of machine
code specialized for MIR function. Therefore the interface
works only on the same targets as MIR generator
# MIR generator (file mir-gen.h)
* Before use of MIR generator for given context you should initialize it by API function
`MIR_gen_init (MIR_context ctx, int gens_num)`. `gens_num` defines how many generator instances you need.
Each generator instance can be used in a different thread to compile different MIR functions from the same context.
If you pass a negative or zero number `gens_num`, it will have the same effect as value `1`
* API function `MIR_gen_finish (MIR_context ctx)` frees all internal generator data (and its instances) for the context.
If you want to generate code for the context again after the `MIR_gen_finish` call, you should call
`MIR_gen_init` again first
* API function `void *MIR_gen (MIR_context ctx, int gen_num, MIR_item_t func_item)` generates machine code
of given MIR function in generator instance `gen_num` and returns an address to call it. You can call
the code as usual C function by using this address as the called function address.
`gen_num` should be a number in the range `0` .. `gens_num - 1` from corresponding `MIR_gen_init`
* API function `void MIR_gen_set_debug_file (MIR_context_t ctx, int gen_num, FILE *f)` sets up MIR generator
debug file to `f` for generator instance `gen_num`.
If it is not NULL a lot of debugging and optimization information will be output to the file. It is useful mostly
for MIR developers
* API function `void MIR_gen_set_optimize_level (MIR_context_t ctx, int gen_num, unsigned int level)` sets up optimization
level for MIR generator instance `gen_num`:
* `0` means only register allocator and machine code generator work
* `1` means additional code selection task. On this level MIR generator creates more compact and faster
code than on zero level with practically on the same speed
* `2` means additionally common sub-expression elimination and sparse conditional constant propagation.
This is a default level. This level is valuable if you generate bad input MIR code with a lot redundancy
and constants. The generation speed on level `1` is about 50% faster than on level `2`
* `3` means additionally register renaming and loop invariant code motion. The generation speed
on level `2` is about 50% faster than on level `3`

@ -0,0 +1,7 @@
This is a private copy of the [MIR](https://github.com/vnmakarov/mir) project for use by Ravi. The code will be occasionally refreshed from the upstream
project. Following changes have been made:
* A CMake build script added to create a library
* Unused files / tests have been removed to avoid clutter
Last update: 7th Jan 2021

@ -0,0 +1,98 @@
/* This file is a part of MIR project.
Copyright (C) 2018-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
aarch64 call ABI target specific code.
*/
typedef int target_arg_info_t;
static void target_init_arg_vars (c2m_ctx_t c2m_ctx, target_arg_info_t *arg_info) {}
static int target_return_by_addr_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
return ((ret_type->mode == TM_STRUCT || ret_type->mode == TM_UNION)
&& type_size (c2m_ctx, ret_type) > 2 * 8);
}
static int reg_aggregate_size (c2m_ctx_t c2m_ctx, struct type *type) {
int size;
if (type->mode != TM_STRUCT && type->mode != TM_UNION) return -1;
return (size = type_size (c2m_ctx, type)) <= 2 * 8 ? size : -1;
}
static void target_add_res_proto (c2m_ctx_t c2m_ctx, struct type *ret_type,
target_arg_info_t *arg_info, VARR (MIR_type_t) * res_types,
VARR (MIR_var_t) * arg_vars) {
MIR_var_t var;
int size;
if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0) {
simple_add_res_proto (c2m_ctx, ret_type, arg_info, res_types, arg_vars);
return;
}
if (size == 0) return;
VARR_PUSH (MIR_type_t, res_types, MIR_T_I64);
if (size > 8) VARR_PUSH (MIR_type_t, res_types, MIR_T_I64);
}
static int target_add_call_res_op (c2m_ctx_t c2m_ctx, struct type *ret_type,
target_arg_info_t *arg_info, size_t call_arg_area_offset) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
MIR_context_t ctx = c2m_ctx->ctx;
int size;
if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0)
return simple_add_call_res_op (c2m_ctx, ret_type, arg_info, call_arg_area_offset);
if (size == 0) return -1;
VARR_PUSH (MIR_op_t, call_ops,
MIR_new_reg_op (ctx, get_new_temp (c2m_ctx, MIR_T_I64).mir_op.u.reg));
if (size > 8)
VARR_PUSH (MIR_op_t, call_ops,
MIR_new_reg_op (ctx, get_new_temp (c2m_ctx, MIR_T_I64).mir_op.u.reg));
return size <= 8 ? 1 : 2;
}
static op_t target_gen_post_call_res_code (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res,
MIR_insn_t call, size_t call_ops_start) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
int size;
if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0)
return simple_gen_post_call_res_code (c2m_ctx, ret_type, res, call, call_ops_start);
if (size != 0)
gen_multiple_load_store (c2m_ctx, ret_type, &VARR_ADDR (MIR_op_t, call_ops)[call_ops_start + 2],
res.mir_op, FALSE);
return res;
}
static void target_add_ret_ops (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
int i, size;
if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0) {
simple_add_ret_ops (c2m_ctx, ret_type, res);
return;
}
assert (res.mir_op.mode == MIR_OP_MEM && VARR_LENGTH (MIR_op_t, ret_ops) == 0 && size <= 2 * 8);
for (i = 0; size > 0; size -= 8, i++)
VARR_PUSH (MIR_op_t, ret_ops, get_new_temp (c2m_ctx, MIR_T_I64).mir_op);
gen_multiple_load_store (c2m_ctx, ret_type, VARR_ADDR (MIR_op_t, ret_ops), res.mir_op, TRUE);
}
static MIR_type_t target_get_blk_type (c2m_ctx_t c2m_ctx, struct type *arg_type) {
return MIR_T_BLK; /* one BLK is enough */
}
static void target_add_arg_proto (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
target_arg_info_t *arg_info, VARR (MIR_var_t) * arg_vars) {
simple_add_arg_proto (c2m_ctx, name, arg_type, arg_info, arg_vars);
}
static void target_add_call_arg_op (c2m_ctx_t c2m_ctx, struct type *arg_type,
target_arg_info_t *arg_info, op_t arg) {
simple_add_call_arg_op (c2m_ctx, arg_type, arg_info, arg);
}
static int target_gen_gather_arg (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
decl_t param_decl, target_arg_info_t *arg_info) {
return FALSE;
}

@ -0,0 +1,28 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
#include "../mirc.h"
#include "mirc_aarch64_linux.h"
#include "mirc_aarch64_float.h"
#include "mirc_aarch64_limits.h"
#include "mirc_aarch64_stdarg.h"
#include "mirc_aarch64_stdint.h"
#include "mirc_aarch64_stddef.h"
static string_include_t standard_includes[]
= {{NULL, mirc}, {NULL, aarch64_mirc}, TARGET_STD_INCLUDES};
#define MAX_ALIGNMENT 16
#define ADJUST_VAR_ALIGNMENT(c2m_ctx, align, type) \
aarch64_adjust_var_alignment (c2m_ctx, align, type)
static int aarch64_adjust_var_alignment (c2m_ctx_t c2m_ctx, int align, struct type *type) {
return align;
}
static int invalid_alignment (mir_llong align) {
return align != 0 && align != 1 && align != 2 && align != 4 && align != 8 && align != 16;
}

@ -0,0 +1,55 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
#include <stdint.h>
#define MIR_CHAR_BIT 8
typedef int8_t mir_schar;
typedef int16_t mir_short;
typedef int32_t mir_int;
typedef int64_t mir_long;
typedef int64_t mir_llong;
#define MIR_SCHAR_MIN INT8_MIN
#define MIR_SCHAR_MAX INT8_MAX
#define MIR_SHORT_MIN INT16_MIN
#define MIR_SHORT_MAX INT16_MAX
#define MIR_INT_MIN INT32_MIN
#define MIR_INT_MAX INT32_MAX
#define MIR_LONG_MIN INT64_MIN
#define MIR_LONG_MAX INT64_MAX
#define MIR_LLONG_MIN INT64_MIN
#define MIR_LLONG_MAX INT64_MAX
typedef uint8_t mir_uchar;
typedef uint16_t mir_ushort;
typedef uint32_t mir_uint;
typedef uint64_t mir_ulong;
typedef uint64_t mir_ullong;
typedef uint32_t mir_wchar;
typedef uint16_t mir_char16;
typedef uint32_t mir_char32;
#define MIR_UCHAR_MAX UINT8_MAX
#define MIR_USHORT_MAX UINT16_MAX
#define MIR_UINT_MAX UINT32_MAX
#define MIR_ULONG_MAX UINT64_MAX
#define MIR_ULLONG_MAX UINT64_MAX
#define MIR_WCHAR_MIN 0
#define MIR_WCHAR_MAX UINT32_MAX
typedef mir_schar mir_char;
#define MIR_CHAR_MIN MIR_SCHAR_MIN
#define MIR_CHAR_MAX MIR_SCHAR_MAX
typedef float mir_float;
typedef double mir_double;
typedef long double mir_ldouble;
typedef uint8_t mir_bool;
typedef int64_t mir_ptrdiff_t;
typedef uint64_t mir_size_t;
#define MIR_SIZE_MAX UINT64_MAX

@ -0,0 +1,60 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 5.2.4.2.2 */
static char float_str[]
= "#ifndef __FLOAT_H\n"
"#define __FLOAT_H\n"
"\n"
"#define FLT_RADIX 2\n"
"\n"
"#define FLT_MANT_DIG 24\n"
"#define DBL_MANT_DIG 53\n"
"#define LDBL_MANT_DIG DBL_MANT_DIG\n"
"\n"
"#define FLT_DECIMAL_DIG 9\n"
"#define DBL_DECIMAL_DIG 17\n"
"#define LDBL_DECIMAL_DIG DBL_DECIMAL_DIG\n"
"#define FLT_DIG FLT_DECIMAL_DIG\n"
"#define DBL_DIG DBL_DECIMAL_DIG\n"
"#define LDBL_DIG LDBL_DECIMAL_DIG\n"
"\n"
"#define DECIMAL_DIG LDBL_DECIMAL_DIG\n"
"\n"
"#define FLT_MIN_EXP -125\n"
"#define DBL_MIN_EXP -1021\n"
"#define LDBL_MIN_EXP DBL_MIN_EXP\n"
"\n"
"#define FLT_MIN_10_EXP -37\n"
"#define DBL_MIN_10_EXP -307\n"
"#define LDBL_MIN_10_EXP DBL_MIN_10_EXP\n"
"\n"
"#define FLT_MAX_EXP 128\n"
"#define DBL_MAX_EXP 1024\n"
"#define LDBL_MAX_EXP DBL_MAX_EXP\n"
"\n"
"#define FLT_MAX_10_EXP 38\n"
"#define DBL_MAX_10_EXP 308\n"
"#define LDBL_MAX_10_EXP DBL_MAX_10_EXP\n"
"\n"
"#define FLT_MAX 0x1.fffffep+127\n"
"#define DBL_MAX 0x1.fffffffffffffp+1023\n"
"#define LDBL_MAX DBL_MAX\n"
"\n"
"#define FLT_EPSILON 0x1p-23\n"
"#define DBL_EPSILON 0x1p-52\n"
"#define LDBL_EPSILON DBL_EPSILON\n"
"\n"
"#define FLT_MIN 0x1p-126\n"
"#define DBL_MIN 0x1p-1022\n"
"#define LDBL_MIN DBL_MIN\n"
"\n"
"#define FLT_TRUE_MIN 0x1p-149\n"
"#define DBL_TRUE_MIN 0x0.0000000000001p-1022\n"
"#define LDBL_TRUE_MIN DBL_TRUE_MIN\n"
"\n"
"#define FLT_EVAL_METHOD 0\n"
"#define FLT_ROUNDS 1 /* round to the nearest */\n"
"\n"
"#endif /* #ifndef __FLOAT_H */\n";

@ -0,0 +1,38 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See 5.2.4.2 */
static char limits_str[]
= "#ifndef __LIMITS_H\n"
"#define __LIMITS_H\n"
"\n"
"#define CHAR_BIT 8\n"
"\n"
"#define SCHAR_MIN (-SCHAR_MAX - 1)\n"
"#define SCHAR_MAX 127\n"
"#define UCHAR_MAX (SCHAR_MAX * 2 + 1)\n"
"\n"
"#define MB_LEN_MAX 1\n"
"\n"
"#define SHRT_MIN (-SHRT_MAX - 1)\n"
"#define SHRT_MAX 32767\n"
"#define USHRT_MAX (SHRT_MAX * 2 + 1)\n"
"\n"
"#define INT_MIN (-INT_MAX - 1)\n"
"#define INT_MAX 2147483647\n"
"#define UINT_MAX (INT_MAX * 2u + 1u)\n"
"\n"
"#define LONG_MIN (-LONG_MAX - 1l)\n"
"#define LONG_MAX 9223372036854775807l\n"
"#define ULONG_MAX (LONG_MAX * 2ul + 1ul)\n"
"\n"
"#define LLONG_MIN LONG_MIN\n"
"#define LLONG_MAX LONG_MAX\n"
"#define ULLONG_MAX ULONG_MAX\n"
"\n"
"/* signed char by default */\n"
"#define CHAR_MIN SCHAR_MIN\n"
"#define CHAR_MAX SCHAR_MAX\n"
"\n"
"#endif /* #ifndef __LIMITS_H */\n";

@ -0,0 +1,93 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
static char aarch64_mirc[]
= "#define __aarch64__ 1\n"
"#define _LP64 1\n"
"#define __LP64__ 1\n"
"#define __ARM_ARCH 8\n"
"\n"
"#define __SIZEOF_DOUBLE__ 8\n"
"#define __SIZEOF_FLOAT__ 4\n"
"#define __SIZEOF_INT__ 4\n"
"#define __SIZEOF_LONG_DOUBLE__ 16\n"
"#define __SIZEOF_LONG_LONG__ 8\n"
"#define __SIZEOF_LONG__ 8\n"
"#define __SIZEOF_POINTER__ 8\n"
"#define __SIZEOF_PTRDIFF_T__ 8\n"
"#define __SIZEOF_SHORT__ 2\n"
"#define __SIZEOF_SIZE_T__ 8\n"
"\n"
"#define __BYTE_ORDER__ 1234\n"
"#define __ORDER_LITTLE_ENDIAN__ 1234\n"
"#define __ORDER_BIG_ENDIAN__ 4321\n"
"\n"
"/* Some GCC predefined macros: */\n"
"#define __SIZE_TYPE__ unsigned long\n"
"#define __PTRDIFF_TYPE__ long\n"
"#define __INTMAX_TYPE__ long\n"
"#define __UINTMAX_TYPE__ unsigned long\n"
"#define __INT8_TYPE__ signed char\n"
"#define __INT16_TYPE__ short\n"
"#define __INT32_TYPE__ int\n"
"#define __INT64_TYPE__ long\n"
"#define __UINT8_TYPE__ unsigned char\n"
"#define __UINT16_TYPE__ unsigned short\n"
"#define __UINT32_TYPE__ unsigned int\n"
"#define __UINT64_TYPE__ unsigned long\n"
"#define __INTPTR_TYPE__ long\n"
"#define __UINTPTR_TYPE__ unsigned long\n"
"\n"
"#define __CHAR_BIT__ 8\n"
"#define __INT8_MAX__ 127\n"
"#define __INT16_MAX__ 32767\n"
"#define __INT32_MAX__ 2147483647\n"
"#define __INT64_MAX__ 9223372036854775807l\n"
"#define __UINT8_MAX__ (__INT8_MAX__ * 2u + 1u)\n"
"#define __UINT16_MAX__ (__INT16_MAX__ * 2u + 1u)\n"
"#define __UINT32_MAX__ (__INT32_MAX__ * 2u + 1u)\n"
"#define __UINT64_MAX__ (__INT64_MAX__ * 2u + 1u)\n"
"#define __SCHAR_MAX__ __INT8_MAX__\n"
"#define __SHRT_MAX__ __INT16_MAX__\n"
"#define __INT_MAX__ __INT32_MAX__\n"
"#define __LONG_MAX__ __INT64_MAX__\n"
"#define __LONG_LONG_MAX__ __INT64_MAX__\n"
"#define __SIZE_MAX__ __UINT64_MAX__\n"
"#define __PTRDIFF_MAX__ __INT64_MAX__\n"
"#define __INTMAX_MAX__ __INT64_MAX__\n"
"#define __UINTMAX_MAX__ __UINT64_MAX__\n"
"#define __INTPTR_MAX__ __INT64_MAX__\n"
"#define __UINTPTR_MAX__ __UINT64_MAX__\n"
"\n"
"#define __FLT_MIN_EXP__ (-125)\n"
"#define __FLT_MAX_EXP__ 128\n"
"#define __FLT_DIG__ 6\n"
"#define __FLT_DECIMAL_DIG__ 9\n"
"#define __FLT_MANT_DIG__ 24\n"
"#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F\n"
"#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F\n"
"#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F\n"
"\n"
"#define __DBL_MIN_EXP__ (-1021)\n"
"#define __DBL_MAX_EXP__ 1024\n"
"#define __DBL_DIG__ 15\n"
"#define __DBL_DECIMAL_DIG__ 17\n"
"#define __DBL_MANT_DIG__ 53\n"
"#define __DBL_MAX__ ((double) 1.79769313486231570814527423731704357e+308L)\n"
"#define __DBL_MIN__ ((double) 2.22507385850720138309023271733240406e-308L)\n"
"#define __DBL_EPSILON__ ((double) 2.22044604925031308084726333618164062e-16L)\n"
"\n"
"typedef unsigned short char16_t;\n"
"typedef unsigned int char32_t;\n"
"\n"
#if defined(__linux__)
"#define __gnu_linux__ 1\n"
"#define __linux 1\n"
"#define __linux__ 1\n"
"#define linux 1\n"
"#define __unix 1\n"
"#define __unix__ 1\n"
#endif
"\n"
"void *alloca (unsigned long);\n";

@ -0,0 +1,27 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
static char stdarg_str[]
= "#ifndef __STDARG_H\n"
"#define __STDARG_H\n"
"\n"
"typedef struct {\n"
" void *__stack;\n"
" void *__gr_top;\n"
" void *__vr_top;\n"
" int __gr_offs;\n"
" int __vr_offs;\n"
"} va_list;\n"
"\n"
"#define va_start(ap, param) __builtin_va_start (ap)\n"
"#define va_arg(ap, type) __builtin_va_arg(ap, (type *) 0)\n"
"#define va_end(ap) 0\n"
"#define va_copy(dest, src) ((dest)[0] = (src)[0])\n"
"\n"
"/* For standard headers of a GNU system: */\n"
"#ifndef __GNUC_VA_LIST\n"
"#define __GNUC_VA_LIST 1\n"
"#endif\n"
"typedef va_list __gnuc_va_list;\n"
"#endif /* #ifndef __STDARG_H */\n";

@ -0,0 +1,19 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 7.19 */
static char stddef_str[]
= "#ifndef __STDDEF_H\n"
"#define __STDDEF_H\n"
"\n"
"typedef long ptrdiff_t;\n"
"typedef unsigned long size_t;\n"
"typedef long double max_align_t;\n"
"typedef unsigned int wchar_t;\n"
"\n"
"#define NULL ((void *) 0)\n"
"\n"
"#define offsetof(type, member_designator) ((size_t) & ((type *) 0)->member_designator)\n"
"\n"
"#endif /* #ifndef __STDDEF_H */\n";

@ -0,0 +1,130 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 7.20 */
static char stdint_str[]
= "#ifndef _STDINT_H\n"
"#define _STDINT_H 1\n"
"\n"
"#ifndef __int8_t_defined\n"
"#define __int8_t_defined\n"
"typedef signed char int8_t;\n"
"#endif\n"
"typedef short int int16_t;\n"
"typedef int int32_t;\n"
"typedef long int int64_t;\n"
"\n"
"typedef unsigned char uint8_t;\n"
"typedef unsigned short int uint16_t;\n"
"typedef unsigned int uint32_t;\n"
"typedef unsigned long int uint64_t;\n"
"\n"
"typedef signed char int_least8_t;\n"
"typedef short int int_least16_t;\n"
"typedef int int_least32_t;\n"
"typedef long int int_least64_t;\n"
"\n"
"typedef unsigned char uint_least8_t;\n"
"typedef unsigned short int uint_least16_t;\n"
"typedef unsigned int uint_least32_t;\n"
"typedef unsigned long int uint_least64_t;\n"
"\n"
"typedef signed char int_fast8_t;\n"
"typedef long int int_fast16_t;\n"
"typedef long int int_fast32_t;\n"
"typedef long int int_fast64_t;\n"
"\n"
"typedef unsigned char uint_fast8_t;\n"
"typedef unsigned long int uint_fast16_t;\n"
"typedef unsigned long int uint_fast32_t;\n"
"typedef unsigned long int uint_fast64_t;\n"
"\n"
"#define __intptr_t_defined\n"
"typedef long int intptr_t;\n"
"typedef unsigned long int uintptr_t;\n"
"\n"
"typedef long int intmax_t;\n"
"typedef unsigned long int uintmax_t;\n"
"\n"
"#define __INT64_C(c) c##L\n"
"#define __UINT64_C(c) c##UL\n"
"\n"
"#define INT8_MIN (-128)\n"
"#define INT16_MIN (-32768)\n"
"#define INT32_MIN (-2147483648)\n"
"#define INT64_MIN (-9223372036854775808l)\n"
"\n"
"#define INT8_MAX (127)\n"
"#define INT16_MAX (32767)\n"
"#define INT32_MAX (2147483647)\n"
"#define INT64_MAX (9223372036854775807l)\n"
"\n"
"#define UINT8_MAX (255)\n"
"#define UINT16_MAX (65535)\n"
"#define UINT32_MAX (4294967295u)\n"
"#define UINT64_MAX (18446744073709551615ul)\n"
"\n"
"#define INT_LEAST8_MIN (-128)\n"
"#define INT_LEAST16_MIN (-32768)\n"
"#define INT_LEAST32_MIN (-2147483648)\n"
"#define INT_LEAST64_MIN (-9223372036854775808L)\n"
"\n"
"#define INT_LEAST8_MAX (127)\n"
"#define INT_LEAST16_MAX (32767)\n"
"#define INT_LEAST32_MAX (2147483647)\n"
"#define INT_LEAST64_MAX (9223372036854775807L)\n"
"\n"
"#define UINT_LEAST8_MAX (255)\n"
"#define UINT_LEAST16_MAX (65535)\n"
"#define UINT_LEAST32_MAX (4294967295U)\n"
"#define UINT_LEAST64_MAX (18446744073709551615UL)\n"
"\n"
"#define INT_FAST8_MIN (-128)\n"
"#define INT_FAST16_MIN (-9223372036854775808L)\n"
"#define INT_FAST32_MIN (-9223372036854775808L)\n"
"#define INT_FAST64_MIN (-9223372036854775808L)\n"
"\n"
"#define INT_FAST8_MAX (127)\n"
"#define INT_FAST16_MAX (9223372036854775807L)\n"
"#define INT_FAST32_MAX (9223372036854775807L)\n"
"#define INT_FAST64_MAX (9223372036854775807L)\n"
"\n"
"#define UINT_FAST8_MAX (255)\n"
"#define UINT_FAST16_MAX (18446744073709551615UL)\n"
"#define UINT_FAST32_MAX (18446744073709551615UL)\n"
"#define UINT_FAST64_MAX (18446744073709551615UL)\n"
"\n"
"#define INTPTR_MIN (-9223372036854775808L)\n"
"#define INTPTR_MAX (9223372036854775807L)\n"
"#define UINTPTR_MAX (18446744073709551615UL)\n"
"\n"
"#define INTMAX_MIN (-9223372036854775808L)\n"
"#define INTMAX_MAX (9223372036854775807L)\n"
"#define UINTMAX_MAX (18446744073709551615UL)\n"
"\n"
"#define PTRDIFF_MIN (-9223372036854775808L)\n"
"#define PTRDIFF_MAX (9223372036854775807L)\n"
"\n"
"#define SIZE_MAX (18446744073709551615UL)\n"
"\n"
"/* For signed wchar_t and wint_t: */\n"
"#define WCHAR_MIN INT32_MIN\n"
"#define WCHAR_MAX INT32_MAX\n"
"#define WINT_MIN WCHAR_MIN\n"
"#define WINT_MAX WCHAR_MAX\n"
"\n"
"#define INT8_C(value) value\n"
"#define INT16_C(value) value\n"
"#define INT32_C(value) value\n"
"#define INT64_C(value) value##L\n"
"\n"
"#define UINT8_C(value) value\n"
"#define UINT16_C(value) value\n"
"#define UINT32_C(value) value##U\n"
"#define UINT64_C(value) value##UL\n"
"\n"
"#define INTMAX_C(value) value##L\n"
"#define UINTMAX_C(value) value##UL\n"
"\n"
"#endif /* #ifndef _STDINT_H */\n";

File diff suppressed because it is too large Load Diff

@ -0,0 +1,36 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
#ifndef C2MIR_H
#define C2MIR_H
#include "mir.h"
#define COMMAND_LINE_SOURCE_NAME "<command-line>"
#define STDIN_SOURCE_NAME "<stdin>"
struct c2mir_macro_command {
int def_p; /* #define or #undef */
const char *name, *def; /* def is used only when def_p is true */
};
struct c2mir_options {
FILE *message_file;
int debug_p, verbose_p, ignore_warnings_p, no_prepro_p, prepro_only_p;
int syntax_only_p, pedantic_p, asm_p, object_p;
size_t module_num;
FILE *prepro_output_file; /* non-null for prepro_only_p */
const char *output_file_name;
size_t macro_commands_num, include_dirs_num;
struct c2mir_macro_command *macro_commands;
const char **include_dirs;
};
void c2mir_init (MIR_context_t ctx);
void c2mir_finish (MIR_context_t ctx);
int c2mir_compile (MIR_context_t ctx, struct c2mir_options *ops, int (*getc_func) (void *),
void *getc_data, const char *source_name, FILE *output_file);
#endif

@ -0,0 +1,39 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
static const char mirc[]
= "#define __mirc__ 1\n"
"#define __MIRC__ 1\n"
"#define __STDC_HOSTED__ 1\n"
"//#define __STDC_ISO_10646__ 201103L\n"
"#define __STDC_NO_ATOMICS__ 1\n"
"#define __STDC_NO_COMPLEX__ 1\n"
"#define __STDC_NO_THREADS__ 1\n"
"#define __STDC_NO_VLA__ 1\n"
"#define __STDC_UTF_16__ 1\n"
"#define __STDC_UTF_32__ 1\n"
"#define __STDC_VERSION__ 201112L\n"
"#define __STDC__ 1\n"
"\n"
"/* Some GCC alternative keywords used but not defined in standard headers: */\n"
"#define __const const\n"
"#define __const__ const\n"
"#define __inline__ inline\n"
"#define __restrict__ restrict\n"
"#define __signed signed\n"
"#define __signed__ signed\n"
"#define __volatile volatile\n"
"#define __volatile__ volatile\n";
#include "mirc_iso646.h"
#include "mirc_stdalign.h"
#include "mirc_stdbool.h"
#include "mirc_stdnoreturn.h"
#define TARGET_STD_INCLUDES \
{"iso646.h", iso646_str}, {"stdalign.h", stdalign_str}, {"stdbool.h", stdbool_str}, \
{"stdnoreturn.h", stdnoreturn_str}, {"float.h", float_str}, {"limits.h", limits_str}, \
{"stdarg.h", stdarg_str}, {"stdint.h", stdint_str}, { \
"stddef.h", stddef_str \
}

@ -0,0 +1,21 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 7.9 */
static char iso646_str[]
= "#ifndef __ISO646_H\n"
"#define __ISO646_H\n"
"\n"
"#define and &&\n"
"#define and_eq &=\n"
"#define bitand &\n"
"#define bitor |\n"
"#define compl ~\n"
"#define not !\n"
"#define not_eq !=\n"
"#define or ||\n"
"#define or_eq |=\n"
"#define xor ^\n"
"#define xor_eq ^=\n"
"#endif /* #ifndef __ISO646_H */\n";

@ -0,0 +1,14 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 7.15 */
static char stdalign_str[]
= "#ifndef __STDALIGN_H\n"
"#define __STDALIGN_H\n"
"\n"
"#define alignas _Alignas\n"
"#define alignof _Alignof\n"
"#define __alignas_is_defined 1\n"
"#define __alignof_is_defined 1\n"
"#endif /* #ifndef __STDALIGN_H */\n";

@ -0,0 +1,14 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 7.18 */
static char stdbool_str[]
= "#ifndef __STDBOOL_H\n"
"#define __STDBOOL_H\n"
"\n"
"#define bool _Bool\n"
"#define true 1\n"
"#define false 0\n"
"#define __bool_true_false_are_defined 1\n"
"#endif /* #ifndef __STDBOOL_H */\n";

@ -0,0 +1,11 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 7.23 */
static char stdnoreturn_str[]
= "#ifndef __STDNORETURN_H\n"
"#define __STDNORETURN_H\n"
"\n"
"#define noreturn _Noreturn\n"
"#endif /* #ifndef __STDNORETURN_H */\n";

@ -0,0 +1,310 @@
/* This file is a part of MIR project.
Copyright (C) 2018-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
ppc64 call ABI target specific code.
*/
typedef int target_arg_info_t;
static void target_init_arg_vars (c2m_ctx_t c2m_ctx, target_arg_info_t *arg_info) {}
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
static MIR_type_t fp_homogeneous_type (c2m_ctx_t c2m_ctx, struct type *param_type, int *num) {
return MIR_T_UNDEF;
}
#else
static MIR_type_t fp_homogeneous_type_1 (c2m_ctx_t c2m_ctx, MIR_type_t curr_type, struct type *type,
int *num) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
int n;
MIR_type_t t;
if (type->mode == TM_STRUCT || type->mode == TM_UNION || type->mode == TM_ARR) {
switch (type->mode) {
case TM_ARR: { /* Arrays are handled as small records. */
struct arr_type *arr_type = type->u.arr_type;
struct expr *cexpr = arr_type->size->attr;
if ((t = fp_homogeneous_type_1 (c2m_ctx, curr_type, type->u.arr_type->el_type, &n))
== MIR_T_UNDEF)
return MIR_T_UNDEF;
*num = arr_type->size->code == N_IGNORE || !cexpr->const_p ? 1 : cexpr->u.i_val;
return t;
}
case TM_STRUCT:
case TM_UNION:
t = curr_type;
*num = 0;
for (node_t el = NL_HEAD (NL_EL (type->u.tag_type->u.ops, 1)->u.ops); el != NULL;
el = NL_NEXT (el))
if (el->code == N_MEMBER) {
decl_t decl = el->attr;
if ((t = fp_homogeneous_type_1 (c2m_ctx, t, decl->decl_spec.type, &n)) == MIR_T_UNDEF)
return MIR_T_UNDEF;
if (type->mode == TM_STRUCT)
*num += n;
else if (*num < n)
*num = n;
}
return t;
default: assert (FALSE);
}
}
assert (scalar_type_p (type));
if ((t = get_mir_type (c2m_ctx, type)) != MIR_T_F && t != MIR_T_D) return MIR_T_UNDEF;
if (curr_type != t && curr_type != MIR_T_UNDEF) return MIR_T_UNDEF;
*num = 1;
return t;
}
static MIR_type_t fp_homogeneous_type (c2m_ctx_t c2m_ctx, struct type *param_type, int *num) {
if (param_type->mode != TM_STRUCT && param_type->mode != TM_UNION) return MIR_T_UNDEF;
return fp_homogeneous_type_1 (c2m_ctx, MIR_T_UNDEF, param_type, num);
}
#endif
static int reg_aggregate_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
return FALSE;
#else
return type_size (c2m_ctx, ret_type) <= 2 * 8;
#endif
}
static int target_return_by_addr_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
MIR_type_t type;
int n;
if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) return FALSE;
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
&& n <= 8)
return FALSE;
return !reg_aggregate_p (c2m_ctx, ret_type);
}
static void target_add_res_proto (c2m_ctx_t c2m_ctx, struct type *ret_type,
target_arg_info_t *arg_info, VARR (MIR_type_t) * res_types,
VARR (MIR_var_t) * arg_vars) {
MIR_var_t var;
MIR_type_t type;
int i, n, size;
if (void_type_p (ret_type)) return;
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
&& n <= 8) {
for (i = 0; i < n; i++) VARR_PUSH (MIR_type_t, res_types, type);
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
VARR_PUSH (MIR_type_t, res_types, get_mir_type (c2m_ctx, ret_type));
} else if (reg_aggregate_p (c2m_ctx, ret_type)) {
size = type_size (c2m_ctx, ret_type);
for (; size > 0; size -= 8) VARR_PUSH (MIR_type_t, res_types, MIR_T_I64);
} else {
var.name = RET_ADDR_NAME;
var.type = MIR_T_RBLK;
var.size = type_size (c2m_ctx, ret_type);
VARR_PUSH (MIR_var_t, arg_vars, var);
}
}
static int target_add_call_res_op (c2m_ctx_t c2m_ctx, struct type *ret_type,
target_arg_info_t *arg_info, size_t call_arg_area_offset) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
MIR_context_t ctx = c2m_ctx->ctx;
MIR_type_t type;
op_t temp;
int i, n, size;
if (void_type_p (ret_type)) return -1;
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
&& n <= 8) {
for (i = 0; i < n; i++) {
temp = get_new_temp (c2m_ctx, type);
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
}
return n;
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
type = get_mir_type (c2m_ctx, ret_type);
type = promote_mir_int_type (type);
temp = get_new_temp (c2m_ctx, type);
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
return 1;
} else if (reg_aggregate_p (c2m_ctx, ret_type)) {
size = type_size (c2m_ctx, ret_type);
if (size == 0) return -1;
for (int s = size; s > 0; s -= 8) {
temp = get_new_temp (c2m_ctx, MIR_T_I64);
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
}
return (size + 7) / 8;
} else {
temp = get_new_temp (c2m_ctx, MIR_T_I64);
emit3 (c2m_ctx, MIR_ADD, temp.mir_op,
MIR_new_reg_op (ctx, MIR_reg (ctx, FP_NAME, curr_func->u.func)),
MIR_new_int_op (ctx, call_arg_area_offset));
temp.mir_op
= MIR_new_mem_op (ctx, MIR_T_RBLK, type_size (c2m_ctx, ret_type), temp.mir_op.u.reg, 0, 1);
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
return 0;
}
}
static op_t target_gen_post_call_res_code (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res,
MIR_insn_t call, size_t call_ops_start) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
MIR_context_t ctx = c2m_ctx->ctx;
MIR_type_t type;
MIR_insn_t insn;
int i, n;
if (void_type_p (ret_type)) return res;
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
&& n <= 8) {
assert (res.mir_op.mode == MIR_OP_MEM);
for (i = 0; i < n; i++) {
insn = MIR_new_insn (ctx, tp_mov (type),
MIR_new_mem_op (ctx, type,
res.mir_op.u.mem.disp + (type == MIR_T_F ? 4 : 8) * i,
res.mir_op.u.mem.base, res.mir_op.u.mem.index,
res.mir_op.u.mem.scale),
VARR_GET (MIR_op_t, call_ops, i + call_ops_start + 2));
MIR_append_insn (ctx, curr_func, insn);
}
} else if ((ret_type->mode == TM_STRUCT || ret_type->mode == TM_UNION)
&& reg_aggregate_p (c2m_ctx, ret_type)) {
assert (res.mir_op.mode == MIR_OP_MEM); /* addr */
gen_multiple_load_store (c2m_ctx, ret_type, &VARR_ADDR (MIR_op_t, call_ops)[call_ops_start + 2],
res.mir_op, FALSE);
}
return res;
}
static void target_add_ret_ops (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
MIR_context_t ctx = c2m_ctx->ctx;
MIR_type_t type;
MIR_insn_t insn;
MIR_reg_t ret_addr_reg;
op_t temp, var;
int i, n, size;
if (void_type_p (ret_type)) return;
if (((type = fp_homogeneous_type (c2m_ctx, ret_type, &n)) == MIR_T_F || type == MIR_T_D)
&& n <= 8) {
assert (res.mir_op.mode == MIR_OP_MEM);
for (int i = 0; i < n; i++) {
temp = get_new_temp (c2m_ctx, type);
insn = MIR_new_insn (ctx, tp_mov (type), temp.mir_op,
MIR_new_mem_op (ctx, type,
res.mir_op.u.mem.disp + (type == MIR_T_F ? 4 : 8) * i,
res.mir_op.u.mem.base, res.mir_op.u.mem.index,
res.mir_op.u.mem.scale));
MIR_append_insn (ctx, curr_func, insn);
VARR_PUSH (MIR_op_t, ret_ops, temp.mir_op);
}
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
VARR_PUSH (MIR_op_t, ret_ops, res.mir_op);
} else if (reg_aggregate_p (c2m_ctx, ret_type)) {
size = type_size (c2m_ctx, ret_type);
assert (res.mir_op.mode == MIR_OP_MEM && VARR_LENGTH (MIR_op_t, ret_ops) == 0);
for (int i = 0; size > 0; size -= 8, i++)
VARR_PUSH (MIR_op_t, ret_ops, get_new_temp (c2m_ctx, MIR_T_I64).mir_op);
gen_multiple_load_store (c2m_ctx, ret_type, &VARR_ADDR (MIR_op_t, ret_ops)[0], res.mir_op,
TRUE);
} else {
ret_addr_reg = MIR_reg (ctx, RET_ADDR_NAME, curr_func->u.func);
var = new_op (NULL, MIR_new_mem_op (ctx, MIR_T_I8, 0, ret_addr_reg, 0, 1));
size = type_size (c2m_ctx, ret_type);
block_move (c2m_ctx, var, res, size);
}
}
static MIR_type_t target_get_blk_type (c2m_ctx_t c2m_ctx, struct type *arg_type) {
return MIR_T_BLK; /* one BLK is enough */
}
static void target_add_arg_proto (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
target_arg_info_t *arg_info, VARR (MIR_var_t) * arg_vars) {
MIR_var_t var;
MIR_type_t type;
int n;
if (((type = fp_homogeneous_type (c2m_ctx, arg_type, &n)) == MIR_T_F || type == MIR_T_D)
&& n <= 8) {
for (int i = 0; i < n; i++) {
var.name = gen_get_indexed_name (c2m_ctx, name, i);
var.type = type;
VARR_PUSH (MIR_var_t, arg_vars, var);
}
return;
}
type = (arg_type->mode == TM_STRUCT || arg_type->mode == TM_UNION
? MIR_T_BLK
: get_mir_type (c2m_ctx, arg_type));
var.name = name;
var.type = type;
if (type == MIR_T_BLK) var.size = type_size (c2m_ctx, arg_type);
VARR_PUSH (MIR_var_t, arg_vars, var);
}
static void target_add_call_arg_op (c2m_ctx_t c2m_ctx, struct type *arg_type,
target_arg_info_t *arg_info, op_t arg) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
MIR_context_t ctx = c2m_ctx->ctx;
MIR_var_t var;
MIR_type_t type;
op_t temp;
int n;
if (((type = fp_homogeneous_type (c2m_ctx, arg_type, &n)) == MIR_T_F || type == MIR_T_D)
&& n <= 8) {
assert (arg.mir_op.mode == MIR_OP_MEM);
arg = mem_to_address (c2m_ctx, arg, TRUE);
for (int i = 0; i < n; i++) {
temp = get_new_temp (c2m_ctx, type);
MIR_append_insn (ctx, curr_func,
MIR_new_insn (ctx, tp_mov (type), temp.mir_op,
MIR_new_mem_op (ctx, type, (type == MIR_T_F ? 4 : 8) * i,
arg.mir_op.u.reg, 0, 1)));
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
}
return;
}
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION) {
VARR_PUSH (MIR_op_t, call_ops, arg.mir_op);
} else {
assert (arg.mir_op.mode == MIR_OP_MEM);
arg = mem_to_address (c2m_ctx, arg, TRUE);
VARR_PUSH (MIR_op_t, call_ops,
MIR_new_mem_op (ctx, MIR_T_BLK, type_size (c2m_ctx, arg_type), arg.mir_op.u.reg, 0,
1));
}
}
static int target_gen_gather_arg (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
decl_t param_decl, target_arg_info_t *arg_info) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
MIR_context_t ctx = c2m_ctx->ctx;
MIR_var_t var;
MIR_type_t type;
reg_var_t reg_var;
int i, n;
if (((type = fp_homogeneous_type (c2m_ctx, arg_type, &n)) == MIR_T_F || type == MIR_T_D)
&& n <= 8) {
for (i = 0; i < n; i++) {
assert (!param_decl->reg_p);
reg_var = get_reg_var (c2m_ctx, type, gen_get_indexed_name (c2m_ctx, name, i));
MIR_append_insn (ctx, curr_func,
MIR_new_insn (ctx, tp_mov (type),
MIR_new_mem_op (ctx, type,
param_decl->offset
+ (type == MIR_T_F ? 4 : 8) * i,
MIR_reg (ctx, FP_NAME, curr_func->u.func), 0,
1),
MIR_new_reg_op (ctx, reg_var.reg)));
}
return TRUE;
}
return FALSE;
}

@ -0,0 +1,27 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
#include "../mirc.h"
#include "mirc_ppc64_linux.h"
#include "mirc_ppc64_float.h"
#include "mirc_ppc64_limits.h"
#include "mirc_ppc64_stdarg.h"
#include "mirc_ppc64_stdint.h"
#include "mirc_ppc64_stddef.h"
static string_include_t standard_includes[]
= {{NULL, mirc}, {NULL, ppc64_mirc}, TARGET_STD_INCLUDES};
#define MAX_ALIGNMENT 16
#define ADJUST_VAR_ALIGNMENT(c2m_ctx, align, type) ppc64_adjust_var_alignment (c2m_ctx, align, type)
static int ppc64_adjust_var_alignment (c2m_ctx_t c2m_ctx, int align, struct type *type) {
return align;
}
static int invalid_alignment (mir_llong align) {
return align != 0 && align != 1 && align != 2 && align != 4 && align != 8 && align != 16;
}

@ -0,0 +1,55 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
#include <stdint.h>
#define MIR_CHAR_BIT 8
typedef int8_t mir_schar;
typedef int16_t mir_short;
typedef int32_t mir_int;
typedef int64_t mir_long;
typedef int64_t mir_llong;
#define MIR_SCHAR_MIN INT8_MIN
#define MIR_SCHAR_MAX INT8_MAX
#define MIR_SHORT_MIN INT16_MIN
#define MIR_SHORT_MAX INT16_MAX
#define MIR_INT_MIN INT32_MIN
#define MIR_INT_MAX INT32_MAX
#define MIR_LONG_MIN INT64_MIN
#define MIR_LONG_MAX INT64_MAX
#define MIR_LLONG_MIN INT64_MIN
#define MIR_LLONG_MAX INT64_MAX
typedef uint8_t mir_uchar;
typedef uint16_t mir_ushort;
typedef uint32_t mir_uint;
typedef uint64_t mir_ulong;
typedef uint64_t mir_ullong;
typedef uint32_t mir_wchar;
typedef uint16_t mir_char16;
typedef uint32_t mir_char32;
#define MIR_UCHAR_MAX UINT8_MAX
#define MIR_USHORT_MAX UINT16_MAX
#define MIR_UINT_MAX UINT32_MAX
#define MIR_ULONG_MAX UINT64_MAX
#define MIR_ULLONG_MAX UINT64_MAX
#define MIR_WCHAR_MIN 0
#define MIR_WCHAR_MAX UINT32_MAX
typedef mir_schar mir_char;
#define MIR_CHAR_MIN MIR_SCHAR_MIN
#define MIR_CHAR_MAX MIR_SCHAR_MAX
typedef float mir_float;
typedef double mir_double;
typedef long double mir_ldouble;
typedef uint8_t mir_bool;
typedef int64_t mir_ptrdiff_t;
typedef uint64_t mir_size_t;
#define MIR_SIZE_MAX UINT64_MAX

@ -0,0 +1,60 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 5.2.4.2.2 */
static char float_str[]
= "#ifndef __FLOAT_H\n"
"#define __FLOAT_H\n"
"\n"
"#define FLT_RADIX 2\n"
"\n"
"#define FLT_MANT_DIG 24\n"
"#define DBL_MANT_DIG 53\n"
"#define LDBL_MANT_DIG DBL_MANT_DIG\n"
"\n"
"#define FLT_DECIMAL_DIG 9\n"
"#define DBL_DECIMAL_DIG 17\n"
"#define LDBL_DECIMAL_DIG DBL_DECIMAL_DIG\n"
"#define FLT_DIG FLT_DECIMAL_DIG\n"
"#define DBL_DIG DBL_DECIMAL_DIG\n"
"#define LDBL_DIG LDBL_DECIMAL_DIG\n"
"\n"
"#define DECIMAL_DIG LDBL_DECIMAL_DIG\n"
"\n"
"#define FLT_MIN_EXP -125\n"
"#define DBL_MIN_EXP -1021\n"
"#define LDBL_MIN_EXP DBL_MIN_EXP\n"
"\n"
"#define FLT_MIN_10_EXP -37\n"
"#define DBL_MIN_10_EXP -307\n"
"#define LDBL_MIN_10_EXP DBL_MIN_10_EXP\n"
"\n"
"#define FLT_MAX_EXP 128\n"
"#define DBL_MAX_EXP 1024\n"
"#define LDBL_MAX_EXP DBL_MAX_EXP\n"
"\n"
"#define FLT_MAX_10_EXP 38\n"
"#define DBL_MAX_10_EXP 308\n"
"#define LDBL_MAX_10_EXP DBL_MAX_10_EXP\n"
"\n"
"#define FLT_MAX 0x1.fffffep+127\n"
"#define DBL_MAX 0x1.fffffffffffffp+1023\n"
"#define LDBL_MAX DBL_MAX\n"
"\n"
"#define FLT_EPSILON 0x1p-23\n"
"#define DBL_EPSILON 0x1p-52\n"
"#define LDBL_EPSILON DBL_EPSILON\n"
"\n"
"#define FLT_MIN 0x1p-126\n"
"#define DBL_MIN 0x1p-1022\n"
"#define LDBL_MIN DBL_MIN\n"
"\n"
"#define FLT_TRUE_MIN 0x1p-149\n"
"#define DBL_TRUE_MIN 0x0.0000000000001p-1022\n"
"#define LDBL_TRUE_MIN DBL_TRUE_MIN\n"
"\n"
"#define FLT_EVAL_METHOD 0\n"
"#define FLT_ROUNDS 1 /* round to the nearest */\n"
"\n"
"#endif /* #ifndef __FLOAT_H */\n";

@ -0,0 +1,38 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See 5.2.4.2 */
static char limits_str[]
= "#ifndef __LIMITS_H\n"
"#define __LIMITS_H\n"
"\n"
"#define CHAR_BIT 8\n"
"\n"
"#define SCHAR_MIN (-SCHAR_MAX - 1)\n"
"#define SCHAR_MAX 127\n"
"#define UCHAR_MAX (SCHAR_MAX * 2 + 1)\n"
"\n"
"#define MB_LEN_MAX 1\n"
"\n"
"#define SHRT_MIN (-SHRT_MAX - 1)\n"
"#define SHRT_MAX 32767\n"
"#define USHRT_MAX (SHRT_MAX * 2 + 1)\n"
"\n"
"#define INT_MIN (-INT_MAX - 1)\n"
"#define INT_MAX 2147483647\n"
"#define UINT_MAX (INT_MAX * 2u + 1u)\n"
"\n"
"#define LONG_MIN (-LONG_MAX - 1l)\n"
"#define LONG_MAX 9223372036854775807l\n"
"#define ULONG_MAX (LONG_MAX * 2ul + 1ul)\n"
"\n"
"#define LLONG_MIN LONG_MIN\n"
"#define LLONG_MAX LONG_MAX\n"
"#define ULLONG_MAX ULONG_MAX\n"
"\n"
"/* unsigned char by default */\n"
"#define CHAR_MIN 0\n"
"#define CHAR_MAX UCHAR_MAX\n"
"\n"
"#endif /* #ifndef __LIMITS_H */\n";

@ -0,0 +1,107 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
static char ppc64_mirc[]
= "#define __PPC64__ 1\n"
"#define _ARCH_PPC64 1\n"
"#define _LP64 1\n"
"#define __LP64__ 1\n"
"#define __powerpc64__ 1\n"
"#define __powerpc__ 1\n"
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
"#define _CALL_ELF 1\n"
#else
"#define _CALL_ELF 2\n"
#endif
"\n"
"#define __LONG_DOUBLE_128__ 1\n" // ???
"#define __SIZEOF_DOUBLE__ 8\n"
"#define __SIZEOF_FLOAT__ 4\n"
"#define __SIZEOF_INT__ 4\n"
"#define __SIZEOF_LONG_DOUBLE__ 16\n"
"#define __SIZEOF_LONG_LONG__ 8\n"
"#define __SIZEOF_LONG__ 8\n"
"#define __SIZEOF_POINTER__ 8\n"
"#define __SIZEOF_PTRDIFF_T__ 8\n"
"#define __SIZEOF_SHORT__ 2\n"
"#define __SIZEOF_SIZE_T__ 8\n"
"\n"
"#define __ORDER_LITTLE_ENDIAN__ 1234\n"
"#define __ORDER_BIG_ENDIAN__ 4321\n"
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
"#define _BIG_ENDIAN 1\n"
"#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__\n"
#else
"#define _LITTLE_ENDIAN 1\n"
"#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__\n"
#endif
"\n"
"/* Some GCC predefined macros: */\n"
"#define __SIZE_TYPE__ unsigned long\n"
"#define __PTRDIFF_TYPE__ long\n"
"#define __INTMAX_TYPE__ long\n"
"#define __UINTMAX_TYPE__ unsigned long\n"
"#define __INT8_TYPE__ signed char\n"
"#define __INT16_TYPE__ short\n"
"#define __INT32_TYPE__ int\n"
"#define __INT64_TYPE__ long\n"
"#define __UINT8_TYPE__ unsigned char\n"
"#define __UINT16_TYPE__ unsigned short\n"
"#define __UINT32_TYPE__ unsigned int\n"
"#define __UINT64_TYPE__ unsigned long\n"
"#define __INTPTR_TYPE__ long\n"
"#define __UINTPTR_TYPE__ unsigned long\n"
"\n"
"#define __CHAR_BIT__ 8\n"
"#define __INT8_MAX__ 127\n"
"#define __INT16_MAX__ 32767\n"
"#define __INT32_MAX__ 2147483647\n"
"#define __INT64_MAX__ 9223372036854775807l\n"
"#define __UINT8_MAX__ (__INT8_MAX__ * 2u + 1u)\n"
"#define __UINT16_MAX__ (__INT16_MAX__ * 2u + 1u)\n"
"#define __UINT32_MAX__ (__INT32_MAX__ * 2u + 1u)\n"
"#define __UINT64_MAX__ (__INT64_MAX__ * 2u + 1u)\n"
"#define __SCHAR_MAX__ __INT8_MAX__\n"
"#define __SHRT_MAX__ __INT16_MAX__\n"
"#define __INT_MAX__ __INT32_MAX__\n"
"#define __LONG_MAX__ __INT64_MAX__\n"
"#define __LONG_LONG_MAX__ __INT64_MAX__\n"
"#define __SIZE_MAX__ __UINT64_MAX__\n"
"#define __PTRDIFF_MAX__ __INT64_MAX__\n"
"#define __INTMAX_MAX__ __INT64_MAX__\n"
"#define __UINTMAX_MAX__ __UINT64_MAX__\n"
"#define __INTPTR_MAX__ __INT64_MAX__\n"
"#define __UINTPTR_MAX__ __UINT64_MAX__\n"
"\n"
"#define __FLT_MIN_EXP__ (-125)\n"
"#define __FLT_MAX_EXP__ 128\n"
"#define __FLT_DIG__ 6\n"
"#define __FLT_DECIMAL_DIG__ 9\n"
"#define __FLT_MANT_DIG__ 24\n"
"#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F\n"
"#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F\n"
"#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F\n"
"\n"
"#define __DBL_MIN_EXP__ (-1021)\n"
"#define __DBL_MAX_EXP__ 1024\n"
"#define __DBL_DIG__ 15\n"
"#define __DBL_DECIMAL_DIG__ 17\n"
"#define __DBL_MANT_DIG__ 53\n"
"#define __DBL_MAX__ ((double) 1.79769313486231570814527423731704357e+308L)\n"
"#define __DBL_MIN__ ((double) 2.22507385850720138309023271733240406e-308L)\n"
"#define __DBL_EPSILON__ ((double) 2.22044604925031308084726333618164062e-16L)\n"
"\n"
"typedef unsigned short char16_t;\n"
"typedef unsigned int char32_t;\n"
"\n"
#if defined(__linux__)
"#define __gnu_linux__ 1\n"
"#define __linux 1\n"
"#define __linux__ 1\n"
"#define linux 1\n"
"#define __unix 1\n"
"#define __unix__ 1\n"
#endif
"\n"
"void *alloca (unsigned long);\n";

@ -0,0 +1,21 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
static char stdarg_str[]
= "#ifndef __STDARG_H\n"
"#define __STDARG_H\n"
"\n"
"typedef void *va_list[1];\n"
"\n"
"#define va_start(ap, param) __builtin_va_start (ap)\n"
"#define va_arg(ap, type) __builtin_va_arg(ap, (type *) 0)\n"
"#define va_end(ap) 0\n"
"#define va_copy(dest, src) ((dest) = (src))\n"
"\n"
"/* For standard headers of a GNU system: */\n"
"#ifndef __GNUC_VA_LIST\n"
"#define __GNUC_VA_LIST 1\n"
"#endif\n"
"typedef va_list __gnuc_va_list;\n"
"#endif /* #ifndef __STDARG_H */\n";

@ -0,0 +1,19 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 7.19 */
static char stddef_str[]
= "#ifndef __STDDEF_H\n"
"#define __STDDEF_H\n"
"\n"
"typedef long ptrdiff_t;\n"
"typedef unsigned long size_t;\n"
"typedef long double max_align_t;\n"
"typedef unsigned int wchar_t;\n"
"\n"
"#define NULL ((void *) 0)\n"
"\n"
"#define offsetof(type, member_designator) ((size_t) & ((type *) 0)->member_designator)\n"
"\n"
"#endif /* #ifndef __STDDEF_H */\n";

@ -0,0 +1,130 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 7.20 */
static char stdint_str[]
= "#ifndef _STDINT_H\n"
"#define _STDINT_H 1\n"
"\n"
"#ifndef __int8_t_defined\n"
"#define __int8_t_defined\n"
"typedef signed char int8_t;\n"
"#endif\n"
"typedef short int int16_t;\n"
"typedef int int32_t;\n"
"typedef long int int64_t;\n"
"\n"
"typedef unsigned char uint8_t;\n"
"typedef unsigned short int uint16_t;\n"
"typedef unsigned int uint32_t;\n"
"typedef unsigned long int uint64_t;\n"
"\n"
"typedef signed char int_least8_t;\n"
"typedef short int int_least16_t;\n"
"typedef int int_least32_t;\n"
"typedef long int int_least64_t;\n"
"\n"
"typedef unsigned char uint_least8_t;\n"
"typedef unsigned short int uint_least16_t;\n"
"typedef unsigned int uint_least32_t;\n"
"typedef unsigned long int uint_least64_t;\n"
"\n"
"typedef signed char int_fast8_t;\n"
"typedef long int int_fast16_t;\n"
"typedef long int int_fast32_t;\n"
"typedef long int int_fast64_t;\n"
"\n"
"typedef unsigned char uint_fast8_t;\n"
"typedef unsigned long int uint_fast16_t;\n"
"typedef unsigned long int uint_fast32_t;\n"
"typedef unsigned long int uint_fast64_t;\n"
"\n"
"#define __intptr_t_defined\n"
"typedef long int intptr_t;\n"
"typedef unsigned long int uintptr_t;\n"
"\n"
"typedef long int intmax_t;\n"
"typedef unsigned long int uintmax_t;\n"
"\n"
"#define __INT64_C(c) c##L\n"
"#define __UINT64_C(c) c##UL\n"
"\n"
"#define INT8_MIN (-128)\n"
"#define INT16_MIN (-32768)\n"
"#define INT32_MIN (-2147483648)\n"
"#define INT64_MIN (-9223372036854775808l)\n"
"\n"
"#define INT8_MAX (127)\n"
"#define INT16_MAX (32767)\n"
"#define INT32_MAX (2147483647)\n"
"#define INT64_MAX (9223372036854775807l)\n"
"\n"
"#define UINT8_MAX (255)\n"
"#define UINT16_MAX (65535)\n"
"#define UINT32_MAX (4294967295u)\n"
"#define UINT64_MAX (18446744073709551615ul)\n"
"\n"
"#define INT_LEAST8_MIN (-128)\n"
"#define INT_LEAST16_MIN (-32768)\n"
"#define INT_LEAST32_MIN (-2147483648)\n"
"#define INT_LEAST64_MIN (-9223372036854775808L)\n"
"\n"
"#define INT_LEAST8_MAX (127)\n"
"#define INT_LEAST16_MAX (32767)\n"
"#define INT_LEAST32_MAX (2147483647)\n"
"#define INT_LEAST64_MAX (9223372036854775807L)\n"
"\n"
"#define UINT_LEAST8_MAX (255)\n"
"#define UINT_LEAST16_MAX (65535)\n"
"#define UINT_LEAST32_MAX (4294967295U)\n"
"#define UINT_LEAST64_MAX (18446744073709551615UL)\n"
"\n"
"#define INT_FAST8_MIN (-128)\n"
"#define INT_FAST16_MIN (-9223372036854775808L)\n"
"#define INT_FAST32_MIN (-9223372036854775808L)\n"
"#define INT_FAST64_MIN (-9223372036854775808L)\n"
"\n"
"#define INT_FAST8_MAX (127)\n"
"#define INT_FAST16_MAX (9223372036854775807L)\n"
"#define INT_FAST32_MAX (9223372036854775807L)\n"
"#define INT_FAST64_MAX (9223372036854775807L)\n"
"\n"
"#define UINT_FAST8_MAX (255)\n"
"#define UINT_FAST16_MAX (18446744073709551615UL)\n"
"#define UINT_FAST32_MAX (18446744073709551615UL)\n"
"#define UINT_FAST64_MAX (18446744073709551615UL)\n"
"\n"
"#define INTPTR_MIN (-9223372036854775808L)\n"
"#define INTPTR_MAX (9223372036854775807L)\n"
"#define UINTPTR_MAX (18446744073709551615UL)\n"
"\n"
"#define INTMAX_MIN (-9223372036854775808L)\n"
"#define INTMAX_MAX (9223372036854775807L)\n"
"#define UINTMAX_MAX (18446744073709551615UL)\n"
"\n"
"#define PTRDIFF_MIN (-9223372036854775808L)\n"
"#define PTRDIFF_MAX (9223372036854775807L)\n"
"\n"
"#define SIZE_MAX (18446744073709551615UL)\n"
"\n"
"/* For signed wchar_t and wint_t: */\n"
"#define WCHAR_MIN INT32_MIN\n"
"#define WCHAR_MAX INT32_MAX\n"
"#define WINT_MIN WCHAR_MIN\n"
"#define WINT_MAX WCHAR_MAX\n"
"\n"
"#define INT8_C(value) value\n"
"#define INT16_C(value) value\n"
"#define INT32_C(value) value\n"
"#define INT64_C(value) value##L\n"
"\n"
"#define UINT8_C(value) value\n"
"#define UINT16_C(value) value\n"
"#define UINT32_C(value) value##U\n"
"#define UINT64_C(value) value##UL\n"
"\n"
"#define INTMAX_C(value) value##L\n"
"#define UINTMAX_C(value) value##UL\n"
"\n"
"#endif /* #ifndef _STDINT_H */\n";

@ -0,0 +1,100 @@
/* This file is a part of MIR project.
Copyright (C) 2018-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
s390x call ABI target specific code.
*/
typedef int target_arg_info_t;
static void target_init_arg_vars (c2m_ctx_t c2m_ctx, target_arg_info_t *arg_info) {}
static int target_return_by_addr_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
return simple_return_by_addr_p (c2m_ctx, ret_type);
}
static void target_add_res_proto (c2m_ctx_t c2m_ctx, struct type *ret_type,
target_arg_info_t *arg_info, VARR (MIR_type_t) * res_types,
VARR (MIR_var_t) * arg_vars) {
simple_add_res_proto (c2m_ctx, ret_type, arg_info, res_types, arg_vars);
}
static int target_add_call_res_op (c2m_ctx_t c2m_ctx, struct type *ret_type,
target_arg_info_t *arg_info, size_t call_arg_area_offset) {
return simple_add_call_res_op (c2m_ctx, ret_type, arg_info, call_arg_area_offset);
}
static op_t target_gen_post_call_res_code (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res,
MIR_insn_t call, size_t call_ops_start) {
return simple_gen_post_call_res_code (c2m_ctx, ret_type, res, call, call_ops_start);
}
static void target_add_ret_ops (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res) {
simple_add_ret_ops (c2m_ctx, ret_type, res);
}
static int reg_aggregate_p (c2m_ctx_t c2m_ctx, struct type *arg_type) {
size_t size = type_size (c2m_ctx, arg_type);
return size == 1 || size == 2 || size == 4 || size == 8;
}
static MIR_type_t target_get_blk_type (c2m_ctx_t c2m_ctx, struct type *arg_type) {
return MIR_T_BLK; /* one BLK is enough */
}
static void target_add_arg_proto (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
target_arg_info_t *arg_info, VARR (MIR_var_t) * arg_vars) {
MIR_var_t var;
MIR_type_t type;
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION)
type = get_mir_type (c2m_ctx, arg_type);
else if (reg_aggregate_p (c2m_ctx, arg_type))
type = MIR_T_I64;
else
type = MIR_T_BLK;
var.name = name;
var.type = type;
if (type == MIR_T_BLK) var.size = type_size (c2m_ctx, arg_type);
VARR_PUSH (MIR_var_t, arg_vars, var);
}
static void target_add_call_arg_op (c2m_ctx_t c2m_ctx, struct type *arg_type,
target_arg_info_t *arg_info, op_t arg) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
op_t temp;
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION) {
VARR_PUSH (MIR_op_t, call_ops, arg.mir_op);
} else if (reg_aggregate_p (c2m_ctx, arg_type)) {
assert (arg.mir_op.mode == MIR_OP_MEM);
temp = get_new_temp (c2m_ctx, MIR_T_I64);
gen_multiple_load_store (c2m_ctx, arg_type, &temp.mir_op, arg.mir_op, TRUE);
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
} else {
assert (arg.mir_op.mode == MIR_OP_MEM);
arg = mem_to_address (c2m_ctx, arg, TRUE);
VARR_PUSH (MIR_op_t, call_ops,
MIR_new_mem_op (c2m_ctx->ctx, MIR_T_BLK, type_size (c2m_ctx, arg_type),
arg.mir_op.u.reg, 0, 1));
}
}
static int target_gen_gather_arg (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
decl_t param_decl, target_arg_info_t *arg_info) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
MIR_context_t ctx = c2m_ctx->ctx;
MIR_type_t type;
MIR_op_t param_op;
reg_var_t reg_var;
if ((arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION)
|| !reg_aggregate_p (c2m_ctx, arg_type))
return FALSE;
assert (!param_decl->reg_p);
reg_var = get_reg_var (c2m_ctx, MIR_T_I64, name);
param_op = MIR_new_reg_op (ctx, reg_var.reg);
gen_multiple_load_store (c2m_ctx, arg_type, &param_op,
MIR_new_mem_op (ctx, MIR_T_UNDEF, param_decl->offset,
MIR_reg (ctx, FP_NAME, curr_func->u.func), 0, 1),
FALSE);
return TRUE;
}

@ -0,0 +1,27 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
#include "../mirc.h"
#include "mirc_s390x_linux.h"
#include "mirc_s390x_float.h"
#include "mirc_s390x_limits.h"
#include "mirc_s390x_stdarg.h"
#include "mirc_s390x_stdint.h"
#include "mirc_s390x_stddef.h"
static string_include_t standard_includes[]
= {{NULL, mirc}, {NULL, s390x_mirc}, TARGET_STD_INCLUDES};
#define MAX_ALIGNMENT 16
#define ADJUST_VAR_ALIGNMENT(c2m_ctx, align, type) s390x_adjust_var_alignment (c2m_ctx, align, type)
static int s390x_adjust_var_alignment (c2m_ctx_t c2m_ctx, int align, struct type *type) {
return align;
}
static int invalid_alignment (mir_llong align) {
return align != 0 && align != 1 && align != 2 && align != 4 && align != 8 && align != 16;
}

@ -0,0 +1,55 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
#include <stdint.h>
#define MIR_CHAR_BIT 8
typedef int8_t mir_schar;
typedef int16_t mir_short;
typedef int32_t mir_int;
typedef int64_t mir_long;
typedef int64_t mir_llong;
#define MIR_SCHAR_MIN INT8_MIN
#define MIR_SCHAR_MAX INT8_MAX
#define MIR_SHORT_MIN INT16_MIN
#define MIR_SHORT_MAX INT16_MAX
#define MIR_INT_MIN INT32_MIN
#define MIR_INT_MAX INT32_MAX
#define MIR_LONG_MIN INT64_MIN
#define MIR_LONG_MAX INT64_MAX
#define MIR_LLONG_MIN INT64_MIN
#define MIR_LLONG_MAX INT64_MAX
typedef uint8_t mir_uchar;
typedef uint16_t mir_ushort;
typedef uint32_t mir_uint;
typedef uint64_t mir_ulong;
typedef uint64_t mir_ullong;
typedef uint32_t mir_wchar;
typedef uint16_t mir_char16;
typedef uint32_t mir_char32;
#define MIR_UCHAR_MAX UINT8_MAX
#define MIR_USHORT_MAX UINT16_MAX
#define MIR_UINT_MAX UINT32_MAX
#define MIR_ULONG_MAX UINT64_MAX
#define MIR_ULLONG_MAX UINT64_MAX
#define MIR_WCHAR_MIN 0
#define MIR_WCHAR_MAX UINT32_MAX
typedef mir_schar mir_char;
#define MIR_CHAR_MIN MIR_SCHAR_MIN
#define MIR_CHAR_MAX MIR_SCHAR_MAX
typedef float mir_float;
typedef double mir_double;
typedef long double mir_ldouble;
typedef uint8_t mir_bool;
typedef int64_t mir_ptrdiff_t;
typedef uint64_t mir_size_t;
#define MIR_SIZE_MAX UINT64_MAX

@ -0,0 +1,60 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 5.2.4.2.2 */
static char float_str[]
= "#ifndef __FLOAT_H\n"
"#define __FLOAT_H\n"
"\n"
"#define FLT_RADIX 2\n"
"\n"
"#define FLT_MANT_DIG 24\n"
"#define DBL_MANT_DIG 53\n"
"#define LDBL_MANT_DIG DBL_MANT_DIG\n"
"\n"
"#define FLT_DECIMAL_DIG 9\n"
"#define DBL_DECIMAL_DIG 17\n"
"#define LDBL_DECIMAL_DIG DBL_DECIMAL_DIG\n"
"#define FLT_DIG FLT_DECIMAL_DIG\n"
"#define DBL_DIG DBL_DECIMAL_DIG\n"
"#define LDBL_DIG LDBL_DECIMAL_DIG\n"
"\n"
"#define DECIMAL_DIG LDBL_DECIMAL_DIG\n"
"\n"
"#define FLT_MIN_EXP -125\n"
"#define DBL_MIN_EXP -1021\n"
"#define LDBL_MIN_EXP DBL_MIN_EXP\n"
"\n"
"#define FLT_MIN_10_EXP -37\n"
"#define DBL_MIN_10_EXP -307\n"
"#define LDBL_MIN_10_EXP DBL_MIN_10_EXP\n"
"\n"
"#define FLT_MAX_EXP 128\n"
"#define DBL_MAX_EXP 1024\n"
"#define LDBL_MAX_EXP DBL_MAX_EXP\n"
"\n"
"#define FLT_MAX_10_EXP 38\n"
"#define DBL_MAX_10_EXP 308\n"
"#define LDBL_MAX_10_EXP DBL_MAX_10_EXP\n"
"\n"
"#define FLT_MAX 0x1.fffffep+127\n"
"#define DBL_MAX 0x1.fffffffffffffp+1023\n"
"#define LDBL_MAX DBL_MAX\n"
"\n"
"#define FLT_EPSILON 0x1p-23\n"
"#define DBL_EPSILON 0x1p-52\n"
"#define LDBL_EPSILON DBL_EPSILON\n"
"\n"
"#define FLT_MIN 0x1p-126\n"
"#define DBL_MIN 0x1p-1022\n"
"#define LDBL_MIN DBL_MIN\n"
"\n"
"#define FLT_TRUE_MIN 0x1p-149\n"
"#define DBL_TRUE_MIN 0x0.0000000000001p-1022\n"
"#define LDBL_TRUE_MIN DBL_TRUE_MIN\n"
"\n"
"#define FLT_EVAL_METHOD 0\n"
"#define FLT_ROUNDS 1 /* round to the nearest */\n"
"\n"
"#endif /* #ifndef __FLOAT_H */\n";

@ -0,0 +1,38 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See 5.2.4.2 */
static char limits_str[]
= "#ifndef __LIMITS_H\n"
"#define __LIMITS_H\n"
"\n"
"#define CHAR_BIT 8\n"
"\n"
"#define SCHAR_MIN (-SCHAR_MAX - 1)\n"
"#define SCHAR_MAX 127\n"
"#define UCHAR_MAX (SCHAR_MAX * 2 + 1)\n"
"\n"
"#define MB_LEN_MAX 1\n"
"\n"
"#define SHRT_MIN (-SHRT_MAX - 1)\n"
"#define SHRT_MAX 32767\n"
"#define USHRT_MAX (SHRT_MAX * 2 + 1)\n"
"\n"
"#define INT_MIN (-INT_MAX - 1)\n"
"#define INT_MAX 2147483647\n"
"#define UINT_MAX (INT_MAX * 2u + 1u)\n"
"\n"
"#define LONG_MIN (-LONG_MAX - 1l)\n"
"#define LONG_MAX 9223372036854775807l\n"
"#define ULONG_MAX (LONG_MAX * 2ul + 1ul)\n"
"\n"
"#define LLONG_MIN LONG_MIN\n"
"#define LLONG_MAX LONG_MAX\n"
"#define ULLONG_MAX ULONG_MAX\n"
"\n"
"/* unsigned char by default */\n"
"#define CHAR_MIN 0\n"
"#define CHAR_MAX UCHAR_MAX\n"
"\n"
"#endif /* #ifndef __LIMITS_H */\n";

@ -0,0 +1,102 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
static char s390x_mirc[]
= "#define __zarch__ 1\n"
"#define _LP64 1\n"
"#define __LP64__ 1\n"
"#define __s390__ 1\n"
"#define __s390x__ 1\n"
"#define __ELF__ 1\n"
"\n"
#if __SIZEOF_LONG_DOUBLE__ == 16
"#define __LONG_DOUBLE_128__ 1\n" // ???
"#define __SIZEOF_LONG_DOUBLE__ 16\n"
#else
"#define __SIZEOF_LONG_DOUBLE__ 8\n"
#endif
"#define __SIZEOF_FLOAT__ 4\n"
"#define __SIZEOF_INT__ 4\n"
"#define __SIZEOF_LONG_DOUBLE__ 16\n"
"#define __SIZEOF_LONG_LONG__ 8\n"
"#define __SIZEOF_LONG__ 8\n"
"#define __SIZEOF_POINTER__ 8\n"
"#define __SIZEOF_PTRDIFF_T__ 8\n"
"#define __SIZEOF_SHORT__ 2\n"
"#define __SIZEOF_SIZE_T__ 8\n"
"\n"
"#define __ORDER_LITTLE_ENDIAN__ 1234\n"
"#define __ORDER_BIG_ENDIAN__ 4321\n"
"#define _BIG_ENDIAN 1\n"
"#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__\n"
"\n"
"/* Some GCC predefined macros: */\n"
"#define __SIZE_TYPE__ unsigned long\n"
"#define __PTRDIFF_TYPE__ long\n"
"#define __INTMAX_TYPE__ long\n"
"#define __UINTMAX_TYPE__ unsigned long\n"
"#define __INT8_TYPE__ signed char\n"
"#define __INT16_TYPE__ short\n"
"#define __INT32_TYPE__ int\n"
"#define __INT64_TYPE__ long\n"
"#define __UINT8_TYPE__ unsigned char\n"
"#define __UINT16_TYPE__ unsigned short\n"
"#define __UINT32_TYPE__ unsigned int\n"
"#define __UINT64_TYPE__ unsigned long\n"
"#define __INTPTR_TYPE__ long\n"
"#define __UINTPTR_TYPE__ unsigned long\n"
"\n"
"#define __CHAR_BIT__ 8\n"
"#define __INT8_MAX__ 127\n"
"#define __INT16_MAX__ 32767\n"
"#define __INT32_MAX__ 2147483647\n"
"#define __INT64_MAX__ 9223372036854775807l\n"
"#define __UINT8_MAX__ (__INT8_MAX__ * 2u + 1u)\n"
"#define __UINT16_MAX__ (__INT16_MAX__ * 2u + 1u)\n"
"#define __UINT32_MAX__ (__INT32_MAX__ * 2u + 1u)\n"
"#define __UINT64_MAX__ (__INT64_MAX__ * 2u + 1u)\n"
"#define __SCHAR_MAX__ __INT8_MAX__\n"
"#define __SHRT_MAX__ __INT16_MAX__\n"
"#define __INT_MAX__ __INT32_MAX__\n"
"#define __LONG_MAX__ __INT64_MAX__\n"
"#define __LONG_LONG_MAX__ __INT64_MAX__\n"
"#define __SIZE_MAX__ __UINT64_MAX__\n"
"#define __PTRDIFF_MAX__ __INT64_MAX__\n"
"#define __INTMAX_MAX__ __INT64_MAX__\n"
"#define __UINTMAX_MAX__ __UINT64_MAX__\n"
"#define __INTPTR_MAX__ __INT64_MAX__\n"
"#define __UINTPTR_MAX__ __UINT64_MAX__\n"
"\n"
"#define __FLT_MIN_EXP__ (-125)\n"
"#define __FLT_MAX_EXP__ 128\n"
"#define __FLT_DIG__ 6\n"
"#define __FLT_DECIMAL_DIG__ 9\n"
"#define __FLT_MANT_DIG__ 24\n"
"#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F\n"
"#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F\n"
"#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F\n"
"\n"
"#define __DBL_MIN_EXP__ (-1021)\n"
"#define __DBL_MAX_EXP__ 1024\n"
"#define __DBL_DIG__ 15\n"
"#define __DBL_DECIMAL_DIG__ 17\n"
"#define __DBL_MANT_DIG__ 53\n"
"#define __DBL_MAX__ ((double) 1.79769313486231570814527423731704357e+308L)\n"
"#define __DBL_MIN__ ((double) 2.22507385850720138309023271733240406e-308L)\n"
"#define __DBL_EPSILON__ ((double) 2.22044604925031308084726333618164062e-16L)\n"
"\n"
"typedef unsigned short char16_t;\n"
"typedef unsigned int char32_t;\n"
"\n"
#if defined(__linux__)
"#define __gnu_linux__ 1\n"
"#define __linux 1\n"
"#define __linux__ 1\n"
"#define linux 1\n"
"#define unix 1\n"
"#define __unix 1\n"
"#define __unix__ 1\n"
#endif
"\n"
"void *alloca (unsigned long);\n";

@ -0,0 +1,25 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
static char stdarg_str[]
= "#ifndef __STDARG_H\n"
"#define __STDARG_H\n"
"\n"
"typedef struct {\n"
" long __gpr, __fpr;\n"
" void *__overflow_arg_area;\n"
" void *__reg_save_area;\n"
"} va_list[1];\n"
"\n"
"#define va_start(ap, param) __builtin_va_start (ap)\n"
"#define va_arg(ap, type) __builtin_va_arg(ap, (type *) 0)\n"
"#define va_end(ap) 0\n"
"#define va_copy(dest, src) ((dest) = (src))\n"
"\n"
"/* For standard headers of a GNU system: */\n"
"#ifndef __GNUC_VA_LIST\n"
"#define __GNUC_VA_LIST 1\n"
"#endif\n"
"typedef va_list __gnuc_va_list;\n"
"#endif /* #ifndef __STDARG_H */\n";

@ -0,0 +1,19 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 7.19 */
static char stddef_str[]
= "#ifndef __STDDEF_H\n"
"#define __STDDEF_H\n"
"\n"
"typedef long ptrdiff_t;\n"
"typedef unsigned long size_t;\n"
"typedef long double max_align_t;\n"
"typedef unsigned int wchar_t;\n"
"\n"
"#define NULL ((void *) 0)\n"
"\n"
"#define offsetof(type, member_designator) ((size_t) & ((type *) 0)->member_designator)\n"
"\n"
"#endif /* #ifndef __STDDEF_H */\n";

@ -0,0 +1,130 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 7.20 */
static char stdint_str[]
= "#ifndef _STDINT_H\n"
"#define _STDINT_H 1\n"
"\n"
"#ifndef __int8_t_defined\n"
"#define __int8_t_defined\n"
"typedef signed char int8_t;\n"
"#endif\n"
"typedef short int int16_t;\n"
"typedef int int32_t;\n"
"typedef long int int64_t;\n"
"\n"
"typedef unsigned char uint8_t;\n"
"typedef unsigned short int uint16_t;\n"
"typedef unsigned int uint32_t;\n"
"typedef unsigned long int uint64_t;\n"
"\n"
"typedef signed char int_least8_t;\n"
"typedef short int int_least16_t;\n"
"typedef int int_least32_t;\n"
"typedef long int int_least64_t;\n"
"\n"
"typedef unsigned char uint_least8_t;\n"
"typedef unsigned short int uint_least16_t;\n"
"typedef unsigned int uint_least32_t;\n"
"typedef unsigned long int uint_least64_t;\n"
"\n"
"typedef signed char int_fast8_t;\n"
"typedef long int int_fast16_t;\n"
"typedef long int int_fast32_t;\n"
"typedef long int int_fast64_t;\n"
"\n"
"typedef unsigned char uint_fast8_t;\n"
"typedef unsigned long int uint_fast16_t;\n"
"typedef unsigned long int uint_fast32_t;\n"
"typedef unsigned long int uint_fast64_t;\n"
"\n"
"#define __intptr_t_defined\n"
"typedef long int intptr_t;\n"
"typedef unsigned long int uintptr_t;\n"
"\n"
"typedef long int intmax_t;\n"
"typedef unsigned long int uintmax_t;\n"
"\n"
"#define __INT64_C(c) c##L\n"
"#define __UINT64_C(c) c##UL\n"
"\n"
"#define INT8_MIN (-128)\n"
"#define INT16_MIN (-32768)\n"
"#define INT32_MIN (-2147483648)\n"
"#define INT64_MIN (-9223372036854775808l)\n"
"\n"
"#define INT8_MAX (127)\n"
"#define INT16_MAX (32767)\n"
"#define INT32_MAX (2147483647)\n"
"#define INT64_MAX (9223372036854775807l)\n"
"\n"
"#define UINT8_MAX (255)\n"
"#define UINT16_MAX (65535)\n"
"#define UINT32_MAX (4294967295u)\n"
"#define UINT64_MAX (18446744073709551615ul)\n"
"\n"
"#define INT_LEAST8_MIN (-128)\n"
"#define INT_LEAST16_MIN (-32768)\n"
"#define INT_LEAST32_MIN (-2147483648)\n"
"#define INT_LEAST64_MIN (-9223372036854775808L)\n"
"\n"
"#define INT_LEAST8_MAX (127)\n"
"#define INT_LEAST16_MAX (32767)\n"
"#define INT_LEAST32_MAX (2147483647)\n"
"#define INT_LEAST64_MAX (9223372036854775807L)\n"
"\n"
"#define UINT_LEAST8_MAX (255)\n"
"#define UINT_LEAST16_MAX (65535)\n"
"#define UINT_LEAST32_MAX (4294967295U)\n"
"#define UINT_LEAST64_MAX (18446744073709551615UL)\n"
"\n"
"#define INT_FAST8_MIN (-128)\n"
"#define INT_FAST16_MIN (-9223372036854775808L)\n"
"#define INT_FAST32_MIN (-9223372036854775808L)\n"
"#define INT_FAST64_MIN (-9223372036854775808L)\n"
"\n"
"#define INT_FAST8_MAX (127)\n"
"#define INT_FAST16_MAX (9223372036854775807L)\n"
"#define INT_FAST32_MAX (9223372036854775807L)\n"
"#define INT_FAST64_MAX (9223372036854775807L)\n"
"\n"
"#define UINT_FAST8_MAX (255)\n"
"#define UINT_FAST16_MAX (18446744073709551615UL)\n"
"#define UINT_FAST32_MAX (18446744073709551615UL)\n"
"#define UINT_FAST64_MAX (18446744073709551615UL)\n"
"\n"
"#define INTPTR_MIN (-9223372036854775808L)\n"
"#define INTPTR_MAX (9223372036854775807L)\n"
"#define UINTPTR_MAX (18446744073709551615UL)\n"
"\n"
"#define INTMAX_MIN (-9223372036854775808L)\n"
"#define INTMAX_MAX (9223372036854775807L)\n"
"#define UINTMAX_MAX (18446744073709551615UL)\n"
"\n"
"#define PTRDIFF_MIN (-9223372036854775808L)\n"
"#define PTRDIFF_MAX (9223372036854775807L)\n"
"\n"
"#define SIZE_MAX (18446744073709551615UL)\n"
"\n"
"/* For signed wchar_t and wint_t: */\n"
"#define WCHAR_MIN INT32_MIN\n"
"#define WCHAR_MAX INT32_MAX\n"
"#define WINT_MIN WCHAR_MIN\n"
"#define WINT_MAX WCHAR_MAX\n"
"\n"
"#define INT8_C(value) value\n"
"#define INT16_C(value) value\n"
"#define INT32_C(value) value\n"
"#define INT64_C(value) value##L\n"
"\n"
"#define UINT8_C(value) value\n"
"#define UINT16_C(value) value\n"
"#define UINT32_C(value) value##U\n"
"#define UINT64_C(value) value##UL\n"
"\n"
"#define INTMAX_C(value) value##L\n"
"#define UINTMAX_C(value) value##UL\n"
"\n"
"#endif /* #ifndef _STDINT_H */\n";

@ -0,0 +1,401 @@
/* This file is a part of MIR project.
Copyright (C) 2018-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
x86_64 ABI target specific code.
*/
/* See https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf. We use MIR_T_UNDEF for
MEMORY. */
enum add_arg_class { NO_CLASS = MIR_T_BOUND + 1, X87UP_CLASS };
#ifndef _WIN32
#define MAX_QWORDS 2
#else
#define MAX_QWORDS 1
#endif
static MIR_type_t get_result_type (MIR_type_t arg_type1, MIR_type_t arg_type2) {
if (arg_type1 == arg_type2) return arg_type1;
if ((enum add_arg_class) arg_type1 == NO_CLASS) return arg_type2;
if ((enum add_arg_class) arg_type2 == NO_CLASS) return arg_type1;
if (arg_type1 == MIR_T_UNDEF || arg_type2 == MIR_T_UNDEF) return MIR_T_UNDEF;
if (arg_type1 == MIR_T_I64 || arg_type1 == MIR_T_I32 || arg_type2 == MIR_T_I64
|| arg_type2 == MIR_T_I32)
return MIR_T_I64;
if (arg_type1 == MIR_T_LD || arg_type2 == MIR_T_LD
|| (enum add_arg_class) arg_type1 == X87UP_CLASS
|| (enum add_arg_class) arg_type2 == X87UP_CLASS)
return MIR_T_UNDEF;
return MIR_T_D;
}
static int classify_arg (c2m_ctx_t c2m_ctx, struct type *type, MIR_type_t types[MAX_QWORDS],
int bit_field_p) {
size_t size = type_size (c2m_ctx, type);
int i, n_el_qwords, n_qwords = (size + 7) / 8;
MIR_type_t mir_type;
if (type->mode == TM_STRUCT || type->mode == TM_UNION || type->mode == TM_ARR) {
MIR_type_t subtypes[MAX_QWORDS];
if (n_qwords > MAX_QWORDS) return 0; /* too big aggregate */
#ifndef _WIN32
for (i = 0; i < n_qwords; i++) types[i] = (MIR_type_t) NO_CLASS;
switch (type->mode) {
case TM_ARR: { /* Arrays are handled as small records. */
n_el_qwords = classify_arg (c2m_ctx, type->u.arr_type->el_type, subtypes, FALSE);
if (n_el_qwords == 0) return 0;
/* make full types: */
for (i = 0; i < n_qwords; i++)
types[i] = get_result_type (types[i], subtypes[i % n_el_qwords]);
break;
}
case TM_STRUCT:
case TM_UNION:
for (node_t el = NL_HEAD (NL_EL (type->u.tag_type->u.ops, 1)->u.ops); el != NULL;
el = NL_NEXT (el))
if (el->code == N_MEMBER) {
decl_t decl = el->attr;
int start_qword = decl->offset / 8;
if (decl->bit_offset >= 0) {
types[start_qword] = get_result_type (MIR_T_I64, types[start_qword]);
} else {
n_el_qwords
= classify_arg (c2m_ctx, decl->decl_spec.type, subtypes, decl->bit_offset >= 0);
if (n_el_qwords == 0) return 0;
for (i = 0; i < n_el_qwords && (i + start_qword) < n_qwords; i++)
types[i + start_qword] = get_result_type (subtypes[i], types[i + start_qword]);
}
}
break;
default: assert (FALSE);
}
if (n_qwords > 2) return 0; /* as we don't have vector values (see SSEUP_CLASS) */
for (i = 0; i < n_qwords; i++) {
if (types[i] == MIR_T_UNDEF) return 0; /* pass in memory if a word class is memory. */
if ((enum add_arg_class) types[i] == X87UP_CLASS && (i == 0 || types[i - 1] != MIR_T_LD))
return 0;
}
return n_qwords;
#else
types[0] = MIR_T_I64;
return 1;
#endif
}
assert (scalar_type_p (type));
switch (mir_type = get_mir_type (c2m_ctx, type)) {
case MIR_T_F:
case MIR_T_D: types[0] = MIR_T_D; return 1;
case MIR_T_LD:
types[0] = MIR_T_LD;
types[1] = (MIR_type_t) X87UP_CLASS;
return 2;
default: types[0] = MIR_T_I64; return 1;
}
}
typedef struct target_arg_info {
int n_iregs, n_fregs;
} target_arg_info_t;
static void target_init_arg_vars (c2m_ctx_t c2m_ctx, target_arg_info_t *arg_info) {
arg_info->n_iregs = arg_info->n_fregs = 0;
}
static void update_last_qword_type (c2m_ctx_t c2m_ctx, struct type *type,
MIR_type_t qword_types[MAX_QWORDS], int n) {
size_t last_size, size = type_size (c2m_ctx, type);
MIR_type_t mir_type;
assert (n != 0);
if ((last_size = size % 8) == 0 || n > 1) return;
mir_type = qword_types[n - 1];
if (last_size <= 4 && mir_type == MIR_T_D) qword_types[n - 1] = MIR_T_F;
if (last_size <= 4 && mir_type == MIR_T_I64)
qword_types[n - 1] = last_size <= 1 ? MIR_T_I8 : last_size <= 2 ? MIR_T_I16 : MIR_T_I32;
}
static int process_ret_type (c2m_ctx_t c2m_ctx, struct type *ret_type,
MIR_type_t qword_types[MAX_QWORDS]) {
MIR_type_t type;
int n, n_iregs, n_fregs, n_stregs, curr;
int n_qwords = classify_arg (c2m_ctx, ret_type, qword_types, FALSE);
if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) return 0;
if (n_qwords != 0) {
update_last_qword_type (c2m_ctx, ret_type, qword_types, n_qwords);
n_iregs = n_fregs = n_stregs = curr = 0;
for (n = 0; n < n_qwords; n++) { /* start from the last qword */
type = qword_types[n];
qword_types[curr++] = type;
switch ((int) type) {
case MIR_T_I8:
case MIR_T_I16:
case MIR_T_I32:
case MIR_T_I64: n_iregs++; break;
case MIR_T_F:
case MIR_T_D: n_fregs++; break;
case MIR_T_LD: n_stregs++; break;
case X87UP_CLASS:
n_qwords--;
curr--;
break;
default: assert (FALSE);
}
}
if (n_iregs > 2 || n_fregs > 2 || n_stregs > 1) n_qwords = 0;
}
return n_qwords;
}
static int target_return_by_addr_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
MIR_type_t qword_types[MAX_QWORDS];
int n_qwords;
if (void_type_p (ret_type)) return FALSE;
n_qwords = process_ret_type (c2m_ctx, ret_type, qword_types);
return n_qwords == 0 && (ret_type->mode == TM_STRUCT || ret_type->mode == TM_UNION);
}
static void target_add_res_proto (c2m_ctx_t c2m_ctx, struct type *ret_type,
target_arg_info_t *arg_info, VARR (MIR_type_t) * res_types,
VARR (MIR_var_t) * arg_vars) {
MIR_var_t var;
MIR_type_t type;
MIR_type_t qword_types[MAX_QWORDS];
int n, n_qwords;
if (void_type_p (ret_type)) return;
n_qwords = process_ret_type (c2m_ctx, ret_type, qword_types);
if (n_qwords != 0) {
for (n = 0; n < n_qwords; n++)
VARR_PUSH (MIR_type_t, res_types, promote_mir_int_type (qword_types[n]));
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
type = get_mir_type (c2m_ctx, ret_type);
VARR_PUSH (MIR_type_t, res_types, type);
} else { /* return by reference */
var.name = RET_ADDR_NAME;
var.type = MIR_T_RBLK;
var.size = type_size (c2m_ctx, ret_type);
VARR_PUSH (MIR_var_t, arg_vars, var);
arg_info->n_iregs++;
}
}
static int target_add_call_res_op (c2m_ctx_t c2m_ctx, struct type *ret_type,
target_arg_info_t *arg_info, size_t call_arg_area_offset) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
MIR_context_t ctx = c2m_ctx->ctx;
MIR_type_t type;
MIR_type_t qword_types[MAX_QWORDS];
op_t temp;
int i, n_qwords;
if (void_type_p (ret_type)) return -1;
n_qwords = process_ret_type (c2m_ctx, ret_type, qword_types);
if (n_qwords != 0) {
for (i = 0; i < n_qwords; i++) {
temp = get_new_temp (c2m_ctx, promote_mir_int_type (qword_types[i]));
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
}
return n_qwords;
} else if (ret_type->mode == TM_STRUCT || ret_type->mode == TM_UNION) { /* return by reference */
arg_info->n_iregs++;
temp = get_new_temp (c2m_ctx, MIR_T_I64);
emit3 (c2m_ctx, MIR_ADD, temp.mir_op,
MIR_new_reg_op (ctx, MIR_reg (ctx, FP_NAME, curr_func->u.func)),
MIR_new_int_op (ctx, call_arg_area_offset));
temp.mir_op
= MIR_new_mem_op (ctx, MIR_T_RBLK, type_size (c2m_ctx, ret_type), temp.mir_op.u.reg, 0, 1);
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
return 0;
} else {
type = get_mir_type (c2m_ctx, ret_type);
type = promote_mir_int_type (type);
temp = get_new_temp (c2m_ctx, type);
VARR_PUSH (MIR_op_t, call_ops, temp.mir_op);
return 1;
}
}
static op_t target_gen_post_call_res_code (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res,
MIR_insn_t call, size_t call_ops_start) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
MIR_context_t ctx = c2m_ctx->ctx;
MIR_type_t type;
MIR_insn_t insn;
MIR_type_t qword_types[MAX_QWORDS];
int i, n_qwords;
if (void_type_p (ret_type)) return res;
n_qwords = process_ret_type (c2m_ctx, ret_type, qword_types);
if (n_qwords != 0) {
assert (res.mir_op.mode == MIR_OP_MEM);
for (i = 0; i < n_qwords; i++) {
type = qword_types[i];
insn = MIR_new_insn (ctx, tp_mov (type),
MIR_new_mem_op (ctx, type, res.mir_op.u.mem.disp + 8 * i,
res.mir_op.u.mem.base, res.mir_op.u.mem.index,
res.mir_op.u.mem.scale),
VARR_GET (MIR_op_t, call_ops, i + call_ops_start + 2));
MIR_append_insn (ctx, curr_func, insn);
}
}
return res;
}
static void target_add_ret_ops (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
MIR_context_t ctx = c2m_ctx->ctx;
MIR_type_t type;
MIR_type_t qword_types[MAX_QWORDS];
MIR_insn_t insn;
MIR_reg_t ret_addr_reg;
op_t temp, var;
int i, size, n_qwords;
if (void_type_p (ret_type)) return;
n_qwords = process_ret_type (c2m_ctx, ret_type, qword_types);
if (n_qwords != 0) {
for (i = 0; i < n_qwords; i++) {
type = qword_types[i];
temp = get_new_temp (c2m_ctx, promote_mir_int_type (type));
insn = MIR_new_insn (ctx, tp_mov (type), temp.mir_op,
MIR_new_mem_op (ctx, type, res.mir_op.u.mem.disp + 8 * i,
res.mir_op.u.mem.base, res.mir_op.u.mem.index,
res.mir_op.u.mem.scale));
MIR_append_insn (ctx, curr_func, insn);
VARR_PUSH (MIR_op_t, ret_ops, temp.mir_op);
}
} else if (ret_type->mode != TM_STRUCT && ret_type->mode != TM_UNION) {
VARR_PUSH (MIR_op_t, ret_ops, res.mir_op);
} else {
ret_addr_reg = MIR_reg (ctx, RET_ADDR_NAME, curr_func->u.func);
var = new_op (NULL, MIR_new_mem_op (ctx, MIR_T_I8, 0, ret_addr_reg, 0, 1));
size = type_size (c2m_ctx, ret_type);
block_move (c2m_ctx, var, res, size);
}
}
static int process_aggregate_arg (c2m_ctx_t c2m_ctx, struct type *arg_type,
target_arg_info_t *arg_info, MIR_type_t qword_types[MAX_QWORDS]) {
MIR_type_t type;
int n, n_iregs, n_fregs, n_qwords = classify_arg (c2m_ctx, arg_type, qword_types, FALSE);
if (n_qwords == 0) return 0;
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION) return 0;
update_last_qword_type (c2m_ctx, arg_type, qword_types, n_qwords);
n_iregs = n_fregs = 0;
for (n = 0; n < n_qwords; n++) { /* start from the last qword */
switch ((int) (type = qword_types[n])) {
case MIR_T_I8:
case MIR_T_I16:
case MIR_T_I32:
case MIR_T_I64: n_iregs++; break;
case MIR_T_F:
case MIR_T_D: n_fregs++; break;
case X87UP_CLASS:
case MIR_T_LD: return 0;
default: assert (FALSE);
}
}
if (arg_info->n_iregs + n_iregs > 6 || arg_info->n_fregs + n_fregs > 8) return 0;
/* aggregate passed by value: update arg_info */
arg_info->n_iregs += n_iregs;
arg_info->n_fregs += n_fregs;
return n_qwords;
}
static MIR_type_t get_blk_type (int n_qwords, MIR_type_t *qword_types) {
int n, n_iregs = 0, n_fregs = 0;
assert (n_qwords <= 2);
if (n_qwords == 0) return MIR_T_BLK;
for (n = 0; n < n_qwords; n++) { /* start from the last qword */
switch ((int) qword_types[n]) {
case MIR_T_I8:
case MIR_T_I16:
case MIR_T_I32:
case MIR_T_I64: n_iregs++; break;
case MIR_T_F:
case MIR_T_D: n_fregs++; break;
case X87UP_CLASS:
case MIR_T_LD: return MIR_T_BLK;
default: assert (FALSE);
}
}
if (n_iregs == n_qwords) return MIR_T_BLK + 1;
if (n_fregs == n_qwords) return MIR_T_BLK + 2;
if (qword_types[0] == MIR_T_F || qword_types[0] == MIR_T_D) return MIR_T_BLK + 4;
return MIR_T_BLK + 3;
}
static MIR_type_t target_get_blk_type (c2m_ctx_t c2m_ctx, struct type *arg_type) {
MIR_type_t qword_types[MAX_QWORDS];
int n_qwords = classify_arg (c2m_ctx, arg_type, qword_types, FALSE);
assert (arg_type->mode == TM_STRUCT || arg_type->mode == TM_UNION);
return get_blk_type (n_qwords, qword_types);
}
static void target_add_arg_proto (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
target_arg_info_t *arg_info, VARR (MIR_var_t) * arg_vars) {
MIR_var_t var;
MIR_type_t type;
MIR_type_t qword_types[MAX_QWORDS];
int n_qwords = process_aggregate_arg (c2m_ctx, arg_type, arg_info, qword_types);
/* pass aggregates on the stack and pass by value for others: */
var.name = name;
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION) {
type = get_mir_type (c2m_ctx, arg_type);
var.type = type;
if (type == MIR_T_F || type == MIR_T_D)
arg_info->n_fregs++;
else if (type != MIR_T_LD)
arg_info->n_iregs++;
} else {
var.type = get_blk_type (n_qwords, qword_types);
var.size = type_size (c2m_ctx, arg_type);
}
VARR_PUSH (MIR_var_t, arg_vars, var);
}
static void target_add_call_arg_op (c2m_ctx_t c2m_ctx, struct type *arg_type,
target_arg_info_t *arg_info, op_t arg) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
MIR_context_t ctx = c2m_ctx->ctx;
MIR_type_t type;
MIR_type_t qword_types[MAX_QWORDS];
int n_qwords = process_aggregate_arg (c2m_ctx, arg_type, arg_info, qword_types);
/* pass aggregates on the stack and pass by value for others: */
if (arg_type->mode != TM_STRUCT && arg_type->mode != TM_UNION) {
type = get_mir_type (c2m_ctx, arg_type);
VARR_PUSH (MIR_op_t, call_ops, arg.mir_op);
if (type == MIR_T_F || type == MIR_T_D)
arg_info->n_fregs++;
else if (type != MIR_T_LD)
arg_info->n_iregs++;
} else {
assert (arg.mir_op.mode == MIR_OP_MEM);
arg = mem_to_address (c2m_ctx, arg, TRUE);
type = get_blk_type (n_qwords, qword_types);
VARR_PUSH (MIR_op_t, call_ops,
MIR_new_mem_op (ctx, type, type_size (c2m_ctx, arg_type), arg.mir_op.u.reg, 0, 1));
}
}
static int target_gen_gather_arg (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
decl_t param_decl, target_arg_info_t *arg_info) {
return FALSE;
}

@ -0,0 +1,34 @@
/* This file is a part of MIR project.
Copyright (C) 2018-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
#include "../mirc.h"
#ifndef _WIN32
#include "mirc_x86_64_linux.h"
#else
#include "mirc_x86_64_win.h"
#endif
#include "mirc_x86_64_float.h"
#include "mirc_x86_64_limits.h"
#include "mirc_x86_64_stdarg.h"
#include "mirc_x86_64_stdint.h"
#include "mirc_x86_64_stddef.h"
static string_include_t standard_includes[]
= {{NULL, mirc}, {NULL, x86_64_mirc}, TARGET_STD_INCLUDES};
#define MAX_ALIGNMENT 16
#define ADJUST_VAR_ALIGNMENT(c2m_ctx, align, type) x86_adjust_var_alignment (c2m_ctx, align, type)
static int x86_adjust_var_alignment (c2m_ctx_t c2m_ctx, int align, struct type *type) {
/* see https://www.uclibc.org/docs/psABI-x86_64.pdf */
if (type->mode == TM_ARR && raw_type_size (c2m_ctx, type) >= 16) return 16;
return align;
}
static int invalid_alignment (mir_llong align) {
return align != 0 && align != 1 && align != 2 && align != 4 && align != 8 && align != 16;
}

@ -0,0 +1,78 @@
/* This file is a part of MIR project.
Copyright (C) 2018-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
#include <stdint.h>
#define MIR_CHAR_BIT 8
typedef int8_t mir_schar;
typedef int16_t mir_short;
typedef int32_t mir_int;
#ifdef _WIN32
typedef int32_t mir_long;
#else
typedef int64_t mir_long;
#endif
typedef int64_t mir_llong;
#define MIR_SCHAR_MIN INT8_MIN
#define MIR_SCHAR_MAX INT8_MAX
#define MIR_SHORT_MIN INT16_MIN
#define MIR_SHORT_MAX INT16_MAX
#define MIR_INT_MIN INT32_MIN
#define MIR_INT_MAX INT32_MAX
#ifdef _WIN32
#define MIR_LONG_MIN INT32_MIN
#define MIR_LONG_MAX INT32_MAX
#else
#define MIR_LONG_MIN INT64_MIN
#define MIR_LONG_MAX INT64_MAX
#endif
#define MIR_LLONG_MIN INT64_MIN
#define MIR_LLONG_MAX INT64_MAX
typedef uint8_t mir_uchar;
typedef uint16_t mir_ushort;
typedef uint32_t mir_uint;
typedef uint64_t mir_ullong;
#ifdef _WIN32
typedef uint32_t mir_ulong;
typedef uint16_t mir_wchar;
#else
typedef uint64_t mir_ulong;
typedef uint32_t mir_wchar;
#endif
typedef uint16_t mir_char16;
typedef uint32_t mir_char32;
#define MIR_UCHAR_MAX UINT8_MAX
#define MIR_USHORT_MAX UINT16_MAX
#define MIR_UINT_MAX UINT32_MAX
#ifdef _WIN32
#define MIR_ULONG_MAX UINT32_MAX
#define MIR_WCHAR_MAX UINT16_MAX
#else
#define MIR_ULONG_MAX UINT64_MAX
#define MIR_WCHAR_MAX UINT32_MAX
#endif
#define MIR_WCHAR_MIN 0
#define MIR_ULLONG_MAX UINT64_MAX
typedef mir_schar mir_char;
#define MIR_CHAR_MIN MIR_SCHAR_MIN
#define MIR_CHAR_MAX MIR_SCHAR_MAX
typedef float mir_float;
typedef double mir_double;
#ifdef _WIN32
typedef double mir_ldouble;
#else
typedef long double mir_ldouble;
#endif
typedef uint8_t mir_bool;
typedef int64_t mir_ptrdiff_t;
typedef uint64_t mir_size_t;
#define MIR_SIZE_MAX UINT64_MAX

@ -0,0 +1,60 @@
/* This file is a part of MIR project.
Copyright (C) 2019-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 5.2.4.2.2 */
static char float_str[]
= "#ifndef __FLOAT_H\n"
"#define __FLOAT_H\n"
"\n"
"#define FLT_RADIX 2\n"
"\n"
"#define FLT_MANT_DIG 24\n"
"#define DBL_MANT_DIG 53\n"
"#define LDBL_MANT_DIG DBL_MANT_DIG\n"
"\n"
"#define FLT_DECIMAL_DIG 9\n"
"#define DBL_DECIMAL_DIG 17\n"
"#define LDBL_DECIMAL_DIG DBL_DECIMAL_DIG\n"
"#define FLT_DIG FLT_DECIMAL_DIG\n"
"#define DBL_DIG DBL_DECIMAL_DIG\n"
"#define LDBL_DIG LDBL_DECIMAL_DIG\n"
"\n"
"#define DECIMAL_DIG LDBL_DECIMAL_DIG\n"
"\n"
"#define FLT_MIN_EXP -125\n"
"#define DBL_MIN_EXP -1021\n"
"#define LDBL_MIN_EXP DBL_MIN_EXP\n"
"\n"
"#define FLT_MIN_10_EXP -37\n"
"#define DBL_MIN_10_EXP -307\n"
"#define LDBL_MIN_10_EXP DBL_MIN_10_EXP\n"
"\n"
"#define FLT_MAX_EXP 128\n"
"#define DBL_MAX_EXP 1024\n"
"#define LDBL_MAX_EXP DBL_MAX_EXP\n"
"\n"
"#define FLT_MAX_10_EXP 38\n"
"#define DBL_MAX_10_EXP 308\n"
"#define LDBL_MAX_10_EXP DBL_MAX_10_EXP\n"
"\n"
"#define FLT_MAX 0x1.fffffep+127\n"
"#define DBL_MAX 0x1.fffffffffffffp+1023\n"
"#define LDBL_MAX DBL_MAX\n"
"\n"
"#define FLT_EPSILON 0x1p-23\n"
"#define DBL_EPSILON 0x1p-52\n"
"#define LDBL_EPSILON DBL_EPSILON\n"
"\n"
"#define FLT_MIN 0x1p-126\n"
"#define DBL_MIN 0x1p-1022\n"
"#define LDBL_MIN DBL_MIN\n"
"\n"
"#define FLT_TRUE_MIN 0x1p-149\n"
"#define DBL_TRUE_MIN 0x0.0000000000001p-1022\n"
"#define LDBL_TRUE_MIN DBL_TRUE_MIN\n"
"\n"
"#define FLT_EVAL_METHOD 0\n"
"#define FLT_ROUNDS 1 /* round to the nearest */\n"
"\n"
"#endif /* #ifndef __FLOAT_H */\n";

@ -0,0 +1,48 @@
/* This file is a part of MIR project.
Copyright (C) 2019-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See 5.2.4.2 */
static char limits_str[]
= "#ifndef __LIMITS_H\n"
"#define __LIMITS_H\n"
"\n"
"#define CHAR_BIT 8\n"
"\n"
"#define SCHAR_MIN (-SCHAR_MAX - 1)\n"
"#define SCHAR_MAX 127\n"
"#define UCHAR_MAX (SCHAR_MAX * 2 + 1)\n"
"\n"
"#define MB_LEN_MAX 1\n"
"\n"
"#define SHRT_MIN (-SHRT_MAX - 1)\n"
"#define SHRT_MAX 32767\n"
"#define USHRT_MAX (SHRT_MAX * 2 + 1)\n"
"\n"
"#define INT_MIN (-INT_MAX - 1)\n"
"#define INT_MAX 2147483647\n"
"#define UINT_MAX (INT_MAX * 2u + 1u)\n"
"\n"
#if defined(_WIN32)
"#define LONG_MIN (-LONG_MAX - 1l)\n"
"#define LONG_MAX 2147483647l\n"
"#define ULONG_MAX (LONG_MAX * 2ul + 1ul)\n"
"\n"
"#define LLONG_MIN (-LLONG_MAX - 1ll)\n"
"#define LLONG_MAX 9223372036854775807ll\n"
"#define ULLONG_MAX (LLONG_MAX * 2ull + 1ull)\n"
#else
"#define LONG_MIN (-LONG_MAX - 1l)\n"
"#define LONG_MAX 9223372036854775807l\n"
"#define ULONG_MAX (LONG_MAX * 2ul + 1ul)\n"
"\n"
"#define LLONG_MIN (-LLONG_MAX - 1ll)\n"
"#define LLONG_MAX 9223372036854775807ll\n"
"#define ULLONG_MAX (LLONG_MAX * 2ull + 1ull)\n"
#endif
"\n"
"/* signed char by default */\n"
"#define CHAR_MIN SCHAR_MIN\n"
"#define CHAR_MAX SCHAR_MAX\n"
"\n"
"#endif /* #ifndef __LIMITS_H */\n";

@ -0,0 +1,106 @@
/* This file is a part of MIR project.
Copyright (C) 2019-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
static char x86_64_mirc[]
= "#define __amd64 1\n"
"#define __amd64__ 1\n"
"#define _LP64 1\n"
"#define __LP64__ 1\n"
"#define __x86_64 1\n"
"#define __x86_64__ 1\n"
"\n"
"#define __SIZEOF_DOUBLE__ 8\n"
"#define __SIZEOF_FLOAT__ 4\n"
"#define __SIZEOF_INT__ 4\n"
"#define __SIZEOF_LONG_DOUBLE__ 16\n"
"#define __SIZEOF_LONG_LONG__ 8\n"
"#define __SIZEOF_LONG__ 8\n"
"#define __SIZEOF_POINTER__ 8\n"
"#define __SIZEOF_PTRDIFF_T__ 8\n"
"#define __SIZEOF_SHORT__ 2\n"
"#define __SIZEOF_SIZE_T__ 8\n"
"\n"
"#define __BYTE_ORDER__ 1234\n"
"#define __ORDER_LITTLE_ENDIAN__ 1234\n"
"#define __ORDER_BIG_ENDIAN__ 4321\n"
"\n"
"/* Some GCC predefined macros: */\n"
"#define __SIZE_TYPE__ unsigned long\n"
"#define __PTRDIFF_TYPE__ long\n"
"#define __INTMAX_TYPE__ long\n"
"#define __UINTMAX_TYPE__ unsigned long\n"
"#define __INT8_TYPE__ signed char\n"
"#define __INT16_TYPE__ short\n"
"#define __INT32_TYPE__ int\n"
"#define __INT64_TYPE__ long\n"
"#define __UINT8_TYPE__ unsigned char\n"
"#define __UINT16_TYPE__ unsigned short\n"
"#define __UINT32_TYPE__ unsigned int\n"
"#define __UINT64_TYPE__ unsigned long\n"
"#define __INTPTR_TYPE__ long\n"
"#define __UINTPTR_TYPE__ unsigned long\n"
"\n"
"#define __CHAR_BIT__ 8\n"
"#define __INT8_MAX__ 127\n"
"#define __INT16_MAX__ 32767\n"
"#define __INT32_MAX__ 2147483647\n"
"#define __INT64_MAX__ 9223372036854775807l\n"
"#define __UINT8_MAX__ (__INT8_MAX__ * 2u + 1u)\n"
"#define __UINT16_MAX__ (__INT16_MAX__ * 2u + 1u)\n"
"#define __UINT32_MAX__ (__INT32_MAX__ * 2u + 1u)\n"
"#define __UINT64_MAX__ (__INT64_MAX__ * 2u + 1u)\n"
"#define __SCHAR_MAX__ __INT8_MAX__\n"
"#define __SHRT_MAX__ __INT16_MAX__\n"
"#define __INT_MAX__ __INT32_MAX__\n"
"#define __LONG_MAX__ __INT64_MAX__\n"
"#define __LONG_LONG_MAX__ __INT64_MAX__\n"
"#define __SIZE_MAX__ __UINT64_MAX__\n"
"#define __PTRDIFF_MAX__ __INT64_MAX__\n"
"#define __INTMAX_MAX__ __INT64_MAX__\n"
"#define __UINTMAX_MAX__ __UINT64_MAX__\n"
"#define __INTPTR_MAX__ __INT64_MAX__\n"
"#define __UINTPTR_MAX__ __UINT64_MAX__\n"
"\n"
"#define __FLT_MIN_EXP__ (-125)\n"
"#define __FLT_MAX_EXP__ 128\n"
"#define __FLT_DIG__ 6\n"
"#define __FLT_DECIMAL_DIG__ 9\n"
"#define __FLT_MANT_DIG__ 24\n"
"#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F\n"
"#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F\n"
"#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F\n"
"\n"
"#define __DBL_MIN_EXP__ (-1021)\n"
"#define __DBL_MAX_EXP__ 1024\n"
"#define __DBL_DIG__ 15\n"
"#define __DBL_DECIMAL_DIG__ 17\n"
"#define __DBL_MANT_DIG__ 53\n"
"#define __DBL_MAX__ ((double) 1.79769313486231570814527423731704357e+308L)\n"
"#define __DBL_MIN__ ((double) 2.22507385850720138309023271733240406e-308L)\n"
"#define __DBL_EPSILON__ ((double) 2.22044604925031308084726333618164062e-16L)\n"
"\n"
"typedef unsigned short char16_t;\n"
"typedef unsigned int char32_t;\n"
"\n"
#if defined(__linux__)
"#define __gnu_linux__ 1\n"
"#define __linux 1\n"
"#define __linux__ 1\n"
"#define linux 1\n"
"#define __unix 1\n"
"#define __unix__ 1\n"
#elif defined(__APPLE__)
"#define __APPLE__ 1\n"
"#define __DARWIN_OS_INLINE static inline\n"
"typedef struct {\n"
" unsigned int gp_offset;\n"
" unsigned int fp_offset;\n"
" void *overflow_arg_area;\n"
" void *reg_save_area;\n"
"} __darwin_va_list[1];\n"
#else
#error Uknown OS
#endif
"\n"
"void *alloca (unsigned long);\n";

@ -0,0 +1,41 @@
/* This file is a part of MIR project.
Copyright (C) 2019-2021 Vladimir Makarov <vmakarov.gcc@gmail.com>.
*/
/* See C11 7.16 and https://www.uclibc.org/docs/psABI-x86_64.pdf */
static char stdarg_str[]
= "#ifndef __STDARG_H\n"
"#define __STDARG_H\n"
"\n"
#if defined(__APPLE__)
"typedef __darwin_va_list va_list;\n"
#elif defined(__WIN32)
"typedef char *va_list;\n"
#else
"typedef struct {\n"
" unsigned int gp_offset;\n"
" unsigned int fp_offset;\n"
" void *overflow_arg_area;\n"
" void *reg_save_area;\n"
"} va_list[1];\n"
#endif
"\n"
#if defined(__WIN32)
"#define va_start(ap, param) __va_start (ap, param)\n"
#else
"#define va_start(ap, param) __builtin_va_start (ap)\n"
#endif
"#define va_arg(ap, type) __builtin_va_arg(ap, (type *) 0)\n"
"#define va_end(ap) 0\n"
#if defined(__APPLE__) || defined(__WIN32)
"#define va_copy(dest, src) ((dest) = (src))\n"
#else
"#define va_copy(dest, src) ((dest)[0] = (src)[0])\n"
#endif
"\n"
"/* For standard headers of a GNU system: */\n"
"#ifndef __GNUC_VA_LIST\n"
"#define __GNUC_VA_LIST 1\n"
"#endif\n"
"typedef va_list __gnuc_va_list;\n"
"#endif /* #ifndef __STDARG_H */\n";

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save