From: Abou Al Montacir Date: Fri, 12 Jan 2018 08:54:33 +0000 (+0000) Subject: Import fpc_3.0.4+dfsg-13.debian.tar.xz X-Git-Tag: archive/raspbian/3.0.4+dfsg-13+rpi1^2~33^2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=d39c09c0a945e78fb8edf165b2db63058aabcb69;p=fpc.git Import fpc_3.0.4+dfsg-13.debian.tar.xz [dgit import tarball fpc 3.0.4+dfsg-13 fpc_3.0.4+dfsg-13.debian.tar.xz] --- d39c09c0a945e78fb8edf165b2db63058aabcb69 diff --git a/README.Debian.in b/README.Debian.in new file mode 100644 index 00000000..c27575c4 --- /dev/null +++ b/README.Debian.in @@ -0,0 +1,26 @@ +The Free Pascal Compiler for Debian +- ----------------------------------- + +Only PDF docs are built as shipped. You may want to make the HTML files with +tex4ht by yourself and eventually adapt the doc-base file. + +To create a new config file for fpc (/etc/fpc.cfg) use the command: + /usr/lib/${DEB_HOST_MULTIARCH}/fpc/%{fpcversion}/samplecfg /usr/lib/fpc/%{fpcversion} +However, you should be aware that said file (/etc/fpc.cfg) is +declared as a conffile since version 1.0.2. + +And, yes - this is a i386/amd64/powerpc/sparc/arm only package currently. + + -- Varun Hiremath , Sat, 20 Jan 2007 01:28:28 +0530 + + +Debugging support +------------------------------------- + +As discussed in bug 528855 [1], fp-ide currently does not have debugging +support. We are still trying to define a proper solution, but for now it +just doesn't work. + +[1] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=528855 + + -- Paul Gevers Mon, 23 Sep 2013 21:20:16 +0200 diff --git a/TODO b/TODO new file mode 100644 index 00000000..6edda879 --- /dev/null +++ b/TODO @@ -0,0 +1,15 @@ +* Text in Help window tells you to download the documentation while it is + already packaged (in fp-docs-##). Preferably, the documentation is + automatically found, but if not, it should mention the packaging. + +* Add autopkgtest with mini programs that just require as little units as + possible such that it can be checked that the packages work as intended and + can be used to compile these simple programs. + +* Think about how to find the proper -dev packages to recommend (or suggest) + for the different fp-units-* packages + +* fpcmake building is broken as mentioned upstream + +* Check generated files with h2pas and see if we can regenerate during build + diff --git a/changelog b/changelog new file mode 100644 index 00000000..7839c1ba --- /dev/null +++ b/changelog @@ -0,0 +1,1664 @@ +fpc (3.0.4+dfsg-13) unstable; urgency=medium + + * Fixed typo in change log file. + * Bumped standard version to 4.1.3. Use https in URLS. + * Fixed fp-utils_${VERSION} package dependencies to fix upgrade issues. + (Closes: Bug#886859) + * Fixed alternatives removal for package fp-compiler_${VERSION}. + (Closes: Bug#886926) + * Added missing man file of fp-fix-timestamp in package fp-utils. + Removes a lintian warning. + + -- Abou Al Montacir Fri, 12 Jan 2018 09:54:33 +0100 + +fpc (3.0.4+dfsg-12) unstable; urgency=medium + + * Changed fp-ide and fp-utils packages to be arch:all as suggested by + Multiarch hinter tool. + * Fixed man pages after executables renaming required by MA changes. + * Fix IDE GDB support by importing MI supoort from upstream trunk. + (Closes: Bug#528855) + + -- Abou Al Montacir Sun, 07 Jan 2018 13:37:01 +0100 + +fpc (3.0.4+dfsg-11) unstable; urgency=medium + + * Fixed upgrade of fp-utils from older version. (Closes: #885102) + + -- Abou Al Montacir Sat, 30 Dec 2017 21:14:32 +0100 + +fpc (3.0.4+dfsg-10) unstable; urgency=medium + + * Fixed upgrade of fp-utils from older version. (Closes: #885102) + * Fixed upstream test suite by generating missing configuration file. + + -- Abou Al Montacir Mon, 25 Dec 2017 20:30:59 +0100 + +fpc (3.0.4+dfsg-9) unstable; urgency=medium + + * Renamed binaries of fp-compiler to -* as it is forbidden by + policy to have sub-directories in /us/bin. + * Moved grab_vcsa from fp-compiler to fp-utils as this is a tool that is + not required by the compiler, but by video unit from fp-units-base. + * Fixed generation of make files for test suite, including sub directories. + + -- Abou Al Montacir Mon, 18 Dec 2017 23:48:31 +0100 + +fpc (3.0.4+dfsg-8) unstable; urgency=medium + + * Fixed generation of make files for test suite. + * Moved binaries of fp-compiler to /usr/bin/ to be MA compatible. + + -- Abou Al Montacir Sat, 16 Dec 2017 23:05:46 +0100 + +fpc (3.0.4+dfsg-7) unstable; urgency=medium + + * Upload to unstable MA related fixes, previously uploaded to exprimental. + + -- Abou Al Montacir Thu, 14 Dec 2017 10:27:15 +0100 + +fpc (3.0.4+dfsg-6) experimental; urgency=medium + + * Fixed issue in postinst/postrm scripts related to unknown env variable. + + -- Abou Al Montacir Thu, 14 Dec 2017 10:25:29 +0100 + +fpc (3.0.4+dfsg-5) experimental; urgency=medium + + * Fixed units installation path according to MA policy. + * Bump standards version to 4.1.2 (no changes) + + -- Abou Al Montacir Sat, 09 Dec 2017 00:33:46 +0100 + +fpc (3.0.4+dfsg-4) experimental; urgency=medium + + * Accelerated generation of make files. + * Fixed units installation path. + + -- Abou Al Montacir Mon, 04 Dec 2017 23:59:34 +0100 + +fpc (3.0.4+dfsg-3) experimental; urgency=medium + + * Install unit files to a multi-arch safe location. + + -- Abou Al Montacir Thu, 30 Nov 2017 22:36:25 +0100 + +fpc (3.0.4+dfsg-2) unstable; urgency=medium + + [ Adam Conrad ] + * fix_texpfncase_test.patch: Cherrypick upstream fix to texpfncase test. + (Closes: 875838) + + [ Abou Al Montacir ] + * Set Muti-Arch: foreign for fp-utils* and fp-ide*. + * Set Muti-Arch: same for fp-compiler*. + + -- Abou Al Montacir Sun, 12 Nov 2017 17:13:55 +0100 + +fpc (3.0.4+dfsg-1) unstable; urgency=medium + + * New upstream version (Closes: #875838) + * Refresh patches + * Add create-directory-before-copy-in-Makefile.fpc.patch to prevent + FTBFS + * Merge experimental package into unstable + + -- Paul Gevers Mon, 30 Oct 2017 20:32:33 +0100 + +fpc (3.0.4~rc1+dfsg-1) experimental; urgency=medium + + [ Abou Al Montacir ] + * Removed declaration of legacy ncursus variables. (Closes: #789091) + These variables are now internal and no more exported by new ncursus + libraries. + * Removed Multi-Arch: same from packages with Architecture: all. + * Set Multi-Arch: same for fp-units-* packages to allow installing on + a host system for cross compiling. + + [ Paul Gevers ] + * New upstream release RC candidate + * Refresh patches and drop those applied upstream + * Refresh d/copyright for changes + * Add drop-jsminifier-from-build-as-we-strip-it.patch as we strip an + additional file now and we need to exclude that from building + * Bump standards version to 4.1.0 (no changes) + * Remove Multi-Arch: same from fp-utils, fp-compiler and fp-ide + + -- Paul Gevers Thu, 24 Aug 2017 21:47:45 +0200 + +fpc (3.0.2+dfsg-6) unstable; urgency=medium + + * Removed declaration of legacy ncursus variables. (Closes: #789091) + These variables are now internal and no more exported by new ncursus + libraries. + * Removed Muti-Arch: same from packages with Architecture: all. + * Set Muti-Arch: same for fp-units-* packages to allow installing on + a host system for cross compiling. + * Set Muti-Arch: foreign for fp-docs* and fpc-source* to allow satisfying + dependency of other architectures using host architecture (all) package. + + -- Abou Al Montacir Sat, 07 Oct 2017 16:12:36 +0200 + +fpc (3.0.2+dfsg-5) unstable; urgency=medium + + * Drop kfreebsd patches for now, resurrect them from git when required + * Add fix_mips_mipsel_lazarus_FTBFS.patch to try to fix the lazarus + FTBFS failure on mips and mipsel + + -- Paul Gevers Mon, 07 Aug 2017 13:00:17 -0400 + +fpc (3.0.2+dfsg-4) unstable; urgency=medium + + * Upload to unstable + * Fix 86 vs 68 typo in manpage creation/clean for m68k (thanks ginggs) + * Bump standards to version 4.0.0 (no changes) + + -- Paul Gevers Sun, 09 Jul 2017 15:10:33 +0200 + +fpc (3.0.2+dfsg-3) experimental; urgency=medium + + * Add symlink in fpc-source to tree in fpc-source- (Closes: + #849416) + * Fix fp-units-gfx.install for linux-m68k, linux-mips and linux-mipsel + (Closes: #863589, #863746, #863807) + * Fix mips and mipsel target in d/rules (Closes: #863747, #863808) + * Generate manpages for all new architectures (Closes: #863737, #863748, + #863809) + + -- Paul Gevers Thu, 01 Jun 2017 22:24:07 +0200 + +fpc (3.0.2+dfsg-2) experimental; urgency=medium + + * [tests] Update reference files for results on autopkgtest.u.c + + -- Paul Gevers Sun, 09 Apr 2017 11:44:58 +0200 + +fpc (3.0.2+dfsg-1) experimental; urgency=medium + + * New upstream release + - Drop obsolete patches and update the rest + - Update d/copyright for removed and new files and new years + - Recreate d/s/timestamps because of new upstream + * New fpc packages go into fp-units-fcl and fp-units-net + * Add fix_tests_for_make_print_directory.patch to fix test suite + * [tests] Update reference files + + -- Paul Gevers Wed, 08 Mar 2017 20:13:08 +0100 + +fpc (3.0.0+dfsg-12) unstable; urgency=medium + + * Fix "[fp-units-rtl-3.0.0] Incorrect conversion from local time to + UTC". Backported fix from 3.0.2 (Closes: #864148) + + -- Abou Al Montacir Sat, 10 Jun 2017 19:13:48 +0200 + +fpc (3.0.0+dfsg-11) unstable; urgency=medium + + * Team upload + * Fix armhf vstr/vld offset (Closes: #852798) + + -- Graham Inggs Wed, 08 Feb 2017 11:53:35 +0200 + +fpc (3.0.0+dfsg-10) unstable; urgency=medium + + * Add Multi-Arch metadata (as suggested by the hinter on tracker.d.o) + * Strip current path from the configuration paths as stored in fpm files + because it results in unreproducible builds and is useless anyways + because the path doesn't exist in the packages. + * Update amd64 reference to enable Ubuntu to pass + * Fix typo in ppdep such that it now recognizes the {$ELSE} directive + (Closes: #845504) + * Drop Carlos Laviola from uploaders: thanks for all the fish + * Bump compat level to 10 + * Replace mysql/mariadb dev suggests to default-libmysqlclient-dev + * Enable bindnow in the linker flags + * Drop obsolete lintian overrides + * Fix some more spelling errors (thanks Lintian) + + -- Paul Gevers Mon, 12 Dec 2016 21:35:43 +0100 + +fpc (3.0.0+dfsg-9) unstable; urgency=medium + + * Drop Torsten Werner from uploaders: thanks for all the fish + * [tests] Fix autopkgtests as it always fails + + -- Paul Gevers Mon, 12 Sep 2016 20:48:12 +0200 + +fpc (3.0.0+dfsg-8) unstable; urgency=medium + + * add a further powerpc patch from upstream (hopefully really closes: #826300). + + -- Peter Michael Green Sat, 3 Sep 2016 03:05:00 +0000 + +fpc (3.0.0+dfsg-7) unstable; urgency=medium + + [ Paul Gevers ] + * Now really bumb Standards to 3.9.8 (forgot control.in) + * Make output of fix-fp-timestamps update unique + * autopkgtest failed to run properly due to accidental removal of code + in 3.0.0+dfsg-5 and missing g++ + * Add fp-utils-# and fp-docs-# to the Depends of fpc to get all packages + installed + * Add fix_powerpc_ftbfs_with_new_glibc.patch to fix the FTBFS on powerpc + with glibc 2.23 (Closes: #826300) + + [ Peter Michael Green ] + * Add elf tag to mark hardfp binaries as such. (Closes: #695547) + * Add further-arm64-fixes.patch to fix IDE crash on arm64 (Closes: + #830906) + + -- Paul Gevers Mon, 22 Aug 2016 22:03:07 +0200 + +fpc (3.0.0+dfsg-6) unstable; urgency=medium + + * Fix FTBFS due to wrong logic for latex files, we only need to ship + fpc.sty and fakehtml.sty (the other files were never included in + build-arch only builds anyways) + + -- Paul Gevers Thu, 02 Jun 2016 21:38:47 +0200 + +fpc (3.0.0+dfsg-5) unstable; urgency=medium + + * Don't install latex style files that are already in + texlive-latex-recommended and more up-to-date there (Closes: #820445) + * Let fpc-source break/replace fpc-src from upstream (LP: #1568072) + * Update test suite: little rework + more reference files for different + architectures + * Add arm_UMULL_support_fix.patch to enable hedgewars to build with PIC + (Follow-up from #813452) + * Add fp-fix-timestamps to ease maintainers work to get reproducible + builds where timestamps in ppu files are concerned and use it + * Bump Standards to 3.9.8 (no changes) + * Update FSF address where applicable + * Fixed several spelling errors reported by Lintian + * Add multiple lintian overrides to trim down the list + * Add fp-units-gtk2 examples back + + -- Paul Gevers Wed, 01 Jun 2016 22:16:37 +0200 + +fpc (3.0.0+dfsg-4) unstable; urgency=medium + + [ Peter Michael Green ] + * modify debian/patches/Keep-the-GOT-offset-in-a-virtual-register-for-i386-n.patch + (Closes: Bug#818663) + for compatibility with fpc 3.0.0 to fix FTBFS on i386 + + move globtype from implementation uses to interface uses in hlcgcpu.pas + + remove "paras" parameter from thlcgcpu.a_call_name + + Add symconst and aasmcpu to implementation uses in hlcgcpu.pas + + -- Abou Al Montacir Tue, 22 Mar 2016 08:54:18 +0100 + +fpc (3.0.0+dfsg-3) unstable; urgency=medium + + [ Paul Gevers ] + * Add fix_ppc64s_prt0.as_as_shown_by_cge.patch to let castle-game-engine + build on ppc64 + * Test suite was failing on the old d/rules targets (need to generate + new reference data before it can be completely run succesfull) + * Change Vcs-* to https + * Fix up typo and missing dh-exec in d/control.in + * Move libtar from fp-units-misc to fp-units-base now that fpmkunit + depends on it and add appropriate versioned Breaks/Replaces. + * Bump Standards to 3.9.7 (no changes) + + [ Abou Al Montacir ] + * Back ported some commits from upstream trunk to fix PIC issues. + (Closes: Bug#813452) + + -- Paul Gevers Fri, 18 Mar 2016 08:48:55 +0100 + +fpc (3.0.0+dfsg-2) unstable; urgency=medium + + * Upload to unstable + * Make reverse dependent package more reproducible by adding + let_ppudump_honor_TZ_var.patch + * Add after_patch_arm64_systems.pas.patch (Closes: #807479) + * Fix i386 issue with duplicate files in multiple packages + * Move cairo units from gfx to gtk2 package (Closes: #810573) + * Switch to 'dpkg-parsechangelog --show-field' instead of bumping + build-depends on dpkg-dev to >=1.17.21. + + -- Paul Gevers Thu, 28 Jan 2016 20:04:04 +0100 + +fpc (3.0.0+dfsg-1) experimental; urgency=medium + + * New upstream release + * Reproducibility never ends: add honor_SOURCE_DATE_EPOCH_in_date.patch + to improve some timestamps in binaries + + -- Paul Gevers Fri, 27 Nov 2015 14:51:44 +0100 + +fpc (3.0.0~rc2+dfsg-3) experimental; urgency=medium + + * Make package finally build reproducible (hopefully) + * Add fpm files to the respective packages + * Update auto-pkg-tests with results from CI + runs on my amd64 system + * use debfix to create and dh_lintian to install lintian overrides + * Update testsuite for 3.0.0 layout + * Restructure the clean targets to allow time reduction if desired + * Reorganize d/rules to make sure the source is copied early + * Add fix_typo_in_ppc64.patch to allow ppc64 to build again and don't + install graph and opencl there as these units aren't build + + -- Paul Gevers Thu, 12 Nov 2015 20:35:17 +0100 + +fpc (3.0.0~rc2+dfsg-2) experimental; urgency=medium + + * The second Edmund Grimley Evans release: arm64 bootstrapped + (Closes: #784569) + - enable arm64 patches + * Another try to fix the FTBFS on armhf (missed this dh-exec issue) + + -- Paul Gevers Sat, 31 Oct 2015 11:16:23 +0100 + +fpc (3.0.0~rc2+dfsg-1) experimental; urgency=medium + + * New upstream release candidate + - Remove obsolete patch + - Update + refresh patches that require changes + * Fix FTBFS on powerpc (the previous fix was not complete) + * Fix FTBFS on armhf, the logic was not in the right place + * Add patches (but don't apply them yet) to support arm64, see + bug 784569 + * Simplify logic in *.install.in and d/rules for arch dependent + install by using dh-exec + + -- Paul Gevers Wed, 28 Oct 2015 19:40:13 +0100 + +fpc (3.0.0~rc1+dfsg-2) experimental; urgency=medium + + * The first Edmund Grimley Evans release (thanks for your work) + * Fix FTBFS on i386, powerpc and ppc64 with new patch: + fix_FTBFS_on_linux_not_amd64.patch (Closes: #800811) + * Fix FTBFS on armhf by not optimizing during the first cycles of + building the new compiler (it is suggested that our 2.6.4 armhf + compiler may have had bugs and upstream didn't support it) + + -- Paul Gevers Sat, 10 Oct 2015 21:06:43 +0200 + +fpc (3.0.0~rc1+dfsg-1) experimental; urgency=medium + + * New upstream release (Release candidate 1) + * Drop obsolete changes and refresh most other ones + * Include "upstream" patch from Abou to fix IDE data file location + * Include man pages for new binaries (forgotten upstream) + * Fix documentation build process (source location is wrong) + * Update d/moveexamples to also move documentation + * Add shlibs:Depends to packages containing binaries + * Distribute new units of the packages + * Update description of the multimedia unit and add libvlc-dev to + its Recommends + * Use fpcmake from the installed packages for now as building the + new fpcmake in the clean target is broken + * Several units aren't build on ARM anymore, so exclude them from + the installation + * Hopefully improve reproducible building by adding LC_ALL=C to the + documentation build line + * Convert d/copyright to machine readable format (what a hell) + + -- Paul Gevers Sun, 13 Sep 2015 20:44:48 +0200 + +fpc (2.6.4+dfsg-8) unstable; urgency=medium + + * Fix FTBFS, I missed two dependencies of fpgtk removed in the + previous upload (Closes: #795323) + * Bump dephelper compat to 9 (now matching in d/compat and d/control) + and update d/clean to fix the clean target + + -- Paul Gevers Fri, 14 Aug 2015 13:16:44 +0200 + +fpc (2.6.4+dfsg-7) unstable; urgency=medium + + * Fix path mistake in run-upstream-testsuite + * Add more locations with time stamps to the configure target + - Add patch to create fpmkunitsrc.inc in the right folder + * Minor clean-up of d/rules by moving to be deleted files to d/clean + * Wrap-and-sort d/control(|.in) + * Move libgtk2.0-dev back to Depends, but now of the gtk2 package + * Stop building and shipping gtk1 and gnome1 packages as the + corresponding libraries are removed more than 6 years ago from + Debian + * Add Hungarian translation for debconf from upstream SVN and make + sure that translations are always up-to-date in clean target + * Missed one timestamp locale in the previous upload + + -- Paul Gevers Mon, 10 Aug 2015 13:23:15 +0200 + +fpc (2.6.4+dfsg-6) unstable; urgency=medium + + * Fix typo in debian/tests/control which caused the autopkgtest to fail + * Improve the timestamp in d/rules to not depend on the timezone which + caused the build to fail reproducibility tests. + * Migrate maintainership to the Pascal Packaging Team + * Update TODO list + * Move -dev packages from Depends to Recommends in our unit packages + * Add Suggests to fp-units-db- + + -- Paul Gevers Sun, 31 May 2015 13:25:57 +0200 + +fpc (2.6.4+dfsg-5) unstable; urgency=medium + + [ José de Figueiredo ] + * Udated the Brazilian Portuguese translation of PO debconf. + (Closes: Bug#778442) + + [ Paul Gevers ] + * Add fpc-source to depends of fp-utils, fpcmake needs it. + * True to build reproducible + - Add patch to not have the timestamp in makefiles created by fpcmake + - Add patch to not include timestamp in fpdoc generated documentation + - Replace build time by Debian changelog time in binaries + - Replace build time by Debian changelog time in man page for fpc-depends + * Refresh patches with fuzz + * Add TODO list + * Add autopkgtest for the upstream testsuite + + -- Paul Gevers Mon, 25 May 2015 20:16:52 +0200 + +fpc (2.6.4+dfsg-4) unstable; urgency=low + + * Let "Select manually" be translatable in debconf questions and update + language files accordingly. + * Bump standards version to 3.9.6 (no changes) + * New/updated translations + - Danish (Joe Hansen) (Closes: #763984) + - Dutch (Paul Gevers) + - German (Chris Leick) (Closes: #763807) + - Italian (Beatrice Torracca) (Closes: #764934) + - Japanese (victory) + - Swedish (Martin Bagge / brother) (Closes: #763446) + + -- Paul Gevers Mon, 13 Oct 2014 21:16:54 +0200 + +fpc (2.6.4+dfsg-3) unstable; urgency=low + + [ Abou Al Montacir ] + * Added libgmp-dev to recommended packages list of fp-units-math in order to + avoid users getting lik errors about missing libgmp. (Closes: Bug#749418) + [ Michal Šimůnek ] + * Updated Czech translation of PO debconf. (Closes: Bug#751387) + + -- Abou Al Montacir Thu, 12 Jun 2014 21:01:47 +0200 + +fpc (2.6.4+dfsg-2) unstable; urgency=medium + + * Revert manpage change in previous upload + * Next time, in case of repack, also remove Windows dll files + * Fix fpc-abi version provided by fp-units-rtl-## (Closes: #746794) + + -- Paul Gevers Sat, 03 May 2014 18:25:46 +0200 + +fpc (2.6.4+dfsg-1) unstable; urgency=low + + [ Abou Al Montacir ] + * New upstream point release with many fixes to the 2.6.2 fixes branch. + - List of changes that may affect the behaviour of previously working + code, and how to cope with these changes is available online on + http://wiki.freepascal.org/User_Changes_2.6.4 + - List of reported bugs which have been fixed in this release is available + online on http://bugs.freepascal.org/changelog_page.php?version_id=315 + * Packages changes: + + Lots and lots fixes and improvements for fcl-db + + web and json packages synchronized. + + improvements to the chmcmd compiler. + + Several fixes for winunits (and winceunits) + * Docs changes: + + Many additions. + + fpjson documented. + * Fixed bug making fp-utils not installable in multiple versions. + * Moved removing alternatives from postrm script to prerm as is recommended. + * Bumped standard version to 3.9.5. + + [ Paul Gevers ] + * Update bug number in previous changelog entry + * Remove nearly obsolete bzip compression for binary packages + (See https://lists.debian.org/debian-devel/2014/01/msg00542.html) + * Fixed versioning of ptop.cfg and fpc.cfg manpage + * Add lintian override for two text documents it considers Flash files + * Repack source to strip fpcsrc/rtl/netwlibc/pre/libcpre.gcc.o + + -- Paul Gevers Sat, 19 Apr 2014 18:05:27 +0200 + +fpc (2.6.2-8) unstable; urgency=low + + [ Gianfranco Costamagna ] + * Backport upstream revision 22477 to fix a FTBFS. (Closes: Bug#733618) + + [ Abou Al Montacir ] + * Change path of localization files to fit Debian standard. + (Closes: Bug#733688) + * Fix encoding of German localization files to be UTF-8. + + -- Abou Al Montacir Mon, 20 Jan 2014 20:39:35 +0100 + +fpc (2.6.2-7) unstable; urgency=low + + [ Christian Perrier ] + * Update debian/control and debconf templates file from Debian translation + team. (Closes: Bug#725851) + * Update Russian translation (Yuri Kozlov). (Closes: Bug#729391) + * Update Danish translation (Joe Hansen). (Closes: Bug#729428) + * Update German translation (Chris Leick). (Closes: Bug#729841) + * Update Polish translation (Michał Kułach). (Closes: Bug#730064) + * Update Swedish translation (Martin Bagge / brother). (Closes: Bug#730186) + * Update Slovak translation (Slavko). (Closes: Bug#730303) + * Update French translation (David Prévot). (Closes: Bug#730514) + * Update Italian translation (Beatrice Torracca). (Closes: Bug#730579) + * Update Japanese translation (victory). (Closes: Bug#730607) + * Update Portuguese translation (Américo Monteiro). (Closes: Bug#730706) + * Update Spanish translation (Matias Bellone). (Closes: Bug#731767) + + [ Paul Gevers ] + * fp-docs, prevent loads of duplicate files, replace with symlinks + - Add Build-Depends-Indep on rdfind and symlinks + * Removed some dependencies in d/rules target to ease manual building + * lintian override for extra-license-file (it is a Pascal header) + * Allow $EXAMPLE_TEMP to be non-existent in d/moveexamples + * Remove fix-doc-build-with-fpdoc-2.6.0.diff (obsolete) + * Allow builds on all arches (will automatically fail on unsatified + build-depends when never bootstrapped on that arch before) + * Initial work for kfreebsd (not finished yet) + - Don't hardcode linux in d/rules + - Add find_iconv_in_libc_on_debian.patch to force use of libc for iconv + - Add kfreebsd-amd64_bootstrap.patch for freebsd target to set linker to + /lib/ld-kfreebsd-x86-64.so.1 and errno to __errno_location + - Add dont_build_fastcgi_fcl-web_and_fppkg_on_kfreebsd.patch to do exactly + that. + + -- Paul Gevers Sun, 15 Dec 2013 21:08:59 +0100 + +fpc (2.6.2-6) unstable; urgency=low + + [ Peter Michael Green ] + * Actually apply add-ppc64-support.diff (Closes: Bug#716813) + + [ Abou Al Montacir ] + * Removed dependency on svgalib which was removed from Debian. Users may + install it manually to link against it. (Closes: Bug#714025) + + [ Paul Gevers ] + * Fix clean target to run as any user and to not require configure target to + run. + * Update README.Debian to describe debugging situation (see bug 528855) and + remove useless information. + * d/control(.in) + - Remove deprecated DM-Upload-Allowed field + - Update Standards-Version (no changes needed) + - Add myself to uploaders + - Add recommends for *-dev packages for fp-units-gfx- + (Closes: #702689, LP: 1153007) + + -- Paul Gevers Mon, 07 Oct 2013 20:24:12 +0200 + +fpc (2.6.2-5) unstable; urgency=high + + * Add -f to rm statements introduced in last upload so they don't fail if + the files are not present. + + -- Peter Michael Green Wed, 24 Jul 2013 17:28:54 +0000 + +fpc (2.6.2-4) unstable; urgency=high + + * Remove the config files used to pass options to the compiler during the + build in clean target to produce clean source packages and to ensure that + they are generated correctly for each architecture. + + -- Peter Michael Green Wed, 24 Jul 2013 11:28:06 +0000 + +fpc (2.6.2-3) unstable; urgency=high + + [Abou Al Montacir] + * Added a new directive, CFGDIR, to configuration file allowing one to add a + directory to a list where included configuration files are searched. + * Define a default location, multi-arch compatible, for third party units, + which should be installed in /usr/lib/$fpctarget-gnu/fp-units-2.6.2/$pkg/. + Each fp-units package should install a configuration file called $pkg.cfg + in configuration directory /etc/fp-units-$fpcversion.cfg.d/$fpctarget/. + * Use compiler configuration file to pass debian custom compilaer flags. + * Pass "-z relro" to linker to remove lintian error. + * Restored ppc64 compiler man page. (Closes: Bug#716813) + + [Peter Michael Green] + * Use "FPMAKE_SKIP_CONFIG" rather than "FPCFPMAKE" to pass linker option + needed for building fpmake. This method unlike the previous one shouldn't + break crossbuilding. (though I don't know if crossbuilding works in + general) + * Change way patching is done for doc build to fix build with newer + versions of patch. + * Remove conflicts with binutils-gold (Closes: Bug#717651) + * Use ld.bfd explicitly (Helps with: Bug#624525) + * Use urgency high so that above binutils related changes hopefully get into + Testing before new binutils does. + + -- Peter Michael Green Tue, 23 Jul 2013 21:48:50 +0000 + +fpc (2.6.2-2) unstable; urgency=low + + [Abou Al Montacir] + * debian/rules + - Allow generating each autogenrated file separately on demand. + - Avoid changing content of hidden directory .pc as this is used by quilt and changing its content may cause some tricky issues. + + [Peter Michael Green] + * debian/patches/armhf-build-with-2.6.0 + - fixup some conditionals in arm assembler to avoid using instrutions that + fpc 2.6.0 doesn't support when building the rtl with 2.6.0 (first stage) + * debian/rules + - Pass 'PPCFPMAKE=$PPCNEW -Fl/usr/lib/$(DEB_BUILD_MULTIARCH)' during + packages build so that fpmake links successfully. + - Pass 'OPT=-Fl/usr/lib/$(DEB_HOST_MULTIARCH)' during utils build so + fpdoc links successfully. + + -- Peter Michael Green Thu, 30 May 2013 11:16:27 +0000 + +fpc (2.6.2-1) unstable; urgency=low + + * New upstream point release with many fixes to the 2.6.0 fixes branch. + - List of changes that may affect the behaviour of previously working + code, and how to cope with these changes is available online on + http://wiki.freepascal.org/User_Changes_2.6.2 + - List of reported bugs which have been fixed in this release is available + online on http://bugs.freepascal.org/changelog_page.php?version_id=223 + - List of new features which have been added to this release is available + online on http://wiki.freepascal.org/FPC_New_Features_2.6.2 + * Compiler changes: + - Improvements and fixes for the ARM architecture + * Packages changes: + - New package fpindexer (indexing engine) + - Support for observer pattern added to fcl-base (and base classes in RTL) + - Lots and lots fixes and improvements for fcl-db + + Support for JSON dataset added among others + - Fixes and improvements for fcl-passrc (and fpdoc) + - Updates for PTCPas and gtk2 + - fpmkunit improvements (better support for future switch to fpmake) + - Several fixes for x11 + - Several fixes for winunits (and winceunits) + * Platforms specific changes: + - Improvements to the NativeNT target (newly introduced as alpha in 2.6.0) + - Many fixes for OpenBSD and NetBSD (considered in beta state now) + - Internal ELF writer supported for more BSD targets + - Fixes and improvements for gba and nds + * Added new tool relpath to compute relative path according to a given base + directory. + * Added new tool ifpc (Instant Free Pascal Compiler) for compiling and + running pascal scripts. + + -- Abou Al Montacir Wed, 7 May 2013 19:41:59 +0100 + +fpc (2.6.0-12) unstable; urgency=low + + [ Abou Al Montacir ] + * Fix lookup keys in debconf database. (Closes: Bug#706459) + * Fixed typo in variable name in post installation script for fp-compiler + package. + * Apply sed changes directly on new configuration file and update + alternatives later. Using sed -i on symbolic link seems to change it on + plain file introducing a regression. + * Fix lintian wraning about questions in debconf prompts. + [ Peter Michael Green ] + * Upload to unstable + + -- Peter Michael Green Sun, 5 May 2013 22:02:00 +0000 + +fpc (2.6.0-11) experimental; urgency=low + + * more powerpc64 fixes (Really closes: Bug#692893) + + set PPUSF to ppc64 in debian/rules. + + add manpage patch to series file. + + -- Peter Michael Green Tue, 30 Apr 2013 09:05:24 +0000 + +fpc (2.6.0-10) experimental; urgency=low + + [ Abou Al Montacir ] + * Fixed typo in French translation. (Closes: Bug#696536) + * Removed auto-generation of debian/control during build process as required + by policy. (Closes: Bug#704252) + * Detect when user refused to migrate to update-alternatives managed and + do not handle configuration files. (Closes: Bug#704251) + * Added debconf screens to let user select a default .rc MS Windows resourse + files compiler either from mingw32-binutils package or any others custom + installed the system. (Closes: UpstreamBug#23092) + [Hiroyuki Yamamoto] + * Added support for ppc64 architecture. (Closes: Bug#692893) + [ Peter Michael Green ] + * Don't remove fpc.*dpkg* the release team don't like it and + as far as I can tell it isn't needed. + + -- Abou Al Montacir Fri, 26 Apr 2013 18:59:00 +0100 + +fpc (2.6.0-9) unstable; urgency=low + + * Revert previous broken and unnessacerally intrustive fix for debian/control + issue. Replace it with a more targetted fix inspired by abou's and paul's + proposed patches. + + -- Peter Michael Green Sat, 13 Apr 2013 07:52:42 +0000 + +fpc (2.6.0-8) unstable; urgency=low + + * Removed auto-generation of debian/control during build process as required + by policy. (Closes: Bug#704252) + + -- Abou Al Montacir Tue, 26 Mar 2013 09:54:00 +0100 + +fpc (2.6.0-7) unstable; urgency=low + + * Proofread templates by debian-l10n-english list. (Closes: Bug#686038) + * Added Danish translation. (Closes: Bug#687069) + * Added Slovak translation. (Closes: Bug#687087) + * Added Portuguese translation. (Closes: Bug#687116) + * Added Russian translation. (Closes: Bug#687192) + * Added German translation. (Closes: Bug#687444) + * Added Polish translation. (Closes: Bug#687550) + * Added Czech translation. (Closes: Bug#687713) + * Added French translation. (Closes: Bug#687724) + * Added Italian translation. (Closes: Bug#687771) + * Added Japanese translation. (Closes: Bug#688143) + * Added Swedish translation. (Closes: Bug#688424) + * Added Spanish translation. (Closes: Bug#689468) + + -- Abou Al Montacir Thu, 04 Oct 2012 09:12:00 +0000 + +fpc (2.6.0-6) unstable; urgency=low + + * Removed error thrown when trying to build help index if the documentation + is installed on a read only file system and tries to store the index file + in current directory. (Closes: Bug#528863) + * Fixed postrm script to guarantee removal of backup configuration files + during purge operation. (Closes: Bug#668742) + + -- Abou Al Montacir Tue, 30 Jul 2012 19:22:00 +0000 + +fpc (2.6.0-5) unstable; urgency=low + + * Add patch to fix inverted exception masking on arm vfp (armhf). + This patch is needed for the armhf compiler to work on hardware that + supports vfp exception trapping. + + -- Peter Michael Green Sun, 29 Jul 2012 00:52:27 +0000 + +fpc (2.6.0-4) unstable; urgency=low + + [ Peter Michael Green ] + * Add myself to uploaders in control.in as well as control so that the build + process doesn't blow my changes away + [ Abou Al Montacir ] + * Moved mention to openal from fp-units-gfx description to fp-untis-multimedia + description. (Closes: Bug#679138) + + -- Peter Michael Green Fri, 06 Jul 2012 20:25:10 +0000 + +fpc (2.6.0-3) unstable; urgency=low + * Add myself to uploaders + * Add support for armhf (Closes: Bug#666264) + - debian/rules: + + Specify arm variant explicitly when cycling the compiler so that it is + possible to bootstrap with a starting compiler from another arm variant. + + Use DEB_*_ARCH_CPU to reduce the ammount of special casing we + require when setting CPU_SOURCE and CPU_TARGET. + - debian/control: add armhf to architecture list. + - debian/patches/armhf.diff: main changes for port, based on patch + submitted upstream with adjustments to backport to 2.6.0 + - debian/patches/regenerate_messages.diff: regenerate messages file + to add new message introduced by armhf.diff + - armhf-linker-path.diff: change dynamic linker path to reflect new + cross-distro agreement. + * fixups to clean target in debian/rules: + - Don't remove .pc since we aren't removing the patches anymore + (fixes issues where quilt doesn't think the patches are applied even + though in fact they are) + - Cleanup some files which seem to get left behind by + the upstream build/cleanup process. + - Cleanup install-source-stamp + - Cleanup various generated files in debian directory + * set CFG_FILE in postrm so that the rm command in purge actually + removes the configuration file. + -- Peter Michael Green Sat, 21 Apr 2012 13:13:00 +0100 + + +fpc (2.6.0-2) unstable; urgency=low + + * Added alternatives to handle fp (IDE) binary. (Closes: Bug#655626) + * Set priority according to version in fpc and fp-utils so that newer version + is automatically selected. + * Fix default FPCDIR value in fpcmake utility reading links recursively. + (Closes: Bug#662814) + * Checked conformance to policy 3.9.3 and updated standard version. + + -- Abou Al Montacir Wed, 28 Mar 2012 11:51:00 +0100 + +fpc (2.6.0-1) unstable; urgency=low + + * Changed build dependencies on gs-common to ghostscript as the first no more + exists. (Closes: Bug#649703) + * Configuration file is now built on the fly by the post installation script. + * New upstream major release with many features and new targets + - List of changes which may affect the behaviour of previously working + code, and how to cope with these changes is available online on + http://wiki.freepascal.org/User_Changes_2.6.0 for a list + - List of reported bugs which have been fixed in this release is available + online on http://bugs.freepascal.org/changelog_page.php + - List of new features which have been added to this release is available + online on http://wiki.freepascal.org/FPC_New_Features_2.6.0 + * New Platforms: + - iPhoneSimulator target + * Compiler changes: + - Many new language features: + + Objective-Pascal dialect, supported on all Mac OS X and iOS targets + + constref parameter modifier for "const by reference" + + Pascal boolean types with multiple sizes (boolean16/32/64) + + ISO 7185 language mode (except for I/O). Features amongst others: + . Nested procedure variables + . Non-local goto's + + Mac Pascal mode improvements + . Nested procedure variables + . Univ modifier + + Intrinsics + . sar (shift arithmetic right) + . bsf/bsr (bitscan forward/reverse) + + Delphi compatibility mode improvements + . Nested types, class variables and class local constants + . Advanced records syntax (no constructors yet) + . (for..in) Enumerators in records + . Class and record helpers + . Generic records, arrays and procedural types + . Delphi-compatibility of generics improved + . Scoped enumerations + . Custom messages for "deprecated" directive + . Ability to use "&" for escaping keywords + - New ARM code generator features + + ARM VFPv2 and VFPv3 floating point unit support + + Thumb-2 support + * Packages changes: + - Many improvements to the rtl + - Many improvements to the database units (fcl-db) + - Objective-Pascal interfaces to Foundation, AppKit, CoreData and WebCore + - OpenGL headers updated to OpenGL 4.0 + - Added bindings for libzorba + + -- Abou Al Montacir Mon, 27 Dec 2011 11:30:00 +0100 + +fpc (2.4.4-3) unstable; urgency=low + + * Added libsdl-mixer1.2-dev to dependency list of fp-units-multimedia. + * Fixed link issue related to multi-arch by adding arch path to /etc/fpc.cfg. + (Closes: Bug#636802) + * Moved resource compiler fpcres alternative rule to be slave of fpc instead + of being slave of fp-utils. (Closes: Bug#624361) + + -- Abou Al Montacir Tue, 18 Oct 2011 19:12:00 +0200 + +fpc (2.4.4-2) unstable; urgency=low + + * Moved resource compiler fpcres binary to fp-compiler as this part of the + compiler itself. (Closes: Bug#624361) + * Use plain sh for moveexample script. + * Applied patches from upstream to fix armel buildd crash. + * Packages fpc.sty and fakehtml.sty to the default latex directory as these + are required to compile fpdoc latex output. (Closes: Bug#628100) + + -- Abou Al Montacir Mon, 04 Jul 2011 18:10:00 +0200 + +fpc (2.4.4-1) unstable; urgency=low + + * New upstream release with many fixes and a few new features. + - Most library fixes from early June 2010 till March 2011. + + New lib in fp-untis-misc: libsee + + New libs in fp-untis-gfx: hermes, ptc + + New lib in fp-units-fcl: fcl-js + - Some compiler fixes, most relating to 64-bit. + - List of changes which may affect the behaviour of previously working + code, and how to cope with these changes is available online on + http://wiki.freepascal.org/User_Changes_2.4.4 + - List of reported bugs which have been fixed in this release is + available online on http://bugs.freepascal.org/changelog_page.php + * Packages: + - Many improvements to the XML units + - Many improvements to the database units. + + Specially sqlite got quite some fixes. + - Many improvements to the chm units. + + Including a command line CHM compiler + - New interface units: + + opencl + + lua + - Many improvements to fppkg and fpmake for another round of testing. + * Platforms: + - Fixes for multi-threading support in OS/2 RTL. + * Alternative system priority is now set on build time, if given, or + automatically depending on upstream version. + * Removed build dependency on quilt and bumped standard version to 3.9.2. + + -- Abou Al Montacir Mon, 23 May 2011 09:50:00 +0200 + +fpc (2.4.2-3) unstable; urgency=low + + * Added depency on binutils package and declared conflict with binutils-gold + as FPC does not work new binutils chain.(Closes:Bug#620815) + * Fixed various lintian warnings and notes. + * Removed dependency of fp-units-gfx on libsvga1-dev on architectures where + it does not exist. + * Moved fd2pascal from fp-units-gfx to fp-utils. + + -- Abou Al Montacir Tue, 06 Apr 2011 23:30:00 +0200 + +fpc (2.4.2-2) unstable; urgency=low + + * Test for dh_input exit status 30 as this is a normal exit status which just + informs that the question was not displayed because of its priority. + (Closes:Bug#620803) + + -- Abou Al Montacir Tue, 05 Apr 2011 17:14:00 +0200 + +fpc (2.4.2-1) unstable; urgency=low + + * New upstream release with many fixes and a few new features. + (Closes:Bug#606655) + - Most bugfixes in the RTL and packages before june 2010 have been merged. + - List of changes which may affect the behaviour of previously working + code, and how to cope with these changes is available online on + http://wiki.freepascal.org/User_Changes_2.4.2 + - List of reported bugs which have been fixed in this release is + available online on http://bugs.freepascal.org/changelog_page.php + * New Platforms: + - Long term bug in OS/2 implementation of unit Video finally fixed which + among others allows inclusion of the text-mode IDE (without debugger) + for this platform as part of the distribution again. + * Compiler changes: + - Support D2006+ FOR..IN, with some FPC specific enhancements. Refer to + http://wiki.freepascal.org/for-in_loop for more information + - Support for sealed and abstract classes. + * Packages changes: + - Many improvements to the XML units + - Many improvements to the database units + - Many improvements to the chm units + - Moved fpc-subst tool from fp-compiler package to fp-utils one + * Set 2.4.2 as default FPC version. + + -- Abou Al Montacir Tue, 09 Mar 2011 10:02:00 +0100 + +fpc (2.4.0-4) unstable; urgency=low + + * Unset 2.4.0 as default FPC version. + + -- Abou Al Montacir Mon, 07 Mar 2011 09:21:00 +0100 + +fpc (2.4.0-3) unstable; urgency=low + + * Added dependncy for fp-units-gfx to libsvga1-dev. (Closes:Bug#608834) + * Added support for multiple version coexistence in the same system. This will + allow installing multiple versions of FPC in the same system and choose a + default using update-alternatives. + * Use version in package names and provide old names as virtual packages + * Moved fpc-subst tool from fp-compiler package to fp-utils one + + -- Abou Al Montacir Wed, 17 Feb 2011 08:41:00 +0100 + +fpc (2.4.0-2) unstable; urgency=low + + [ Abou Al Montacir ] + * Fixed build dependencies on fp-compiler (>= 2.2.4-5). (Closes:Bug#570591) + * Added dependency on ${misc:Depends} as required for packages using + debhelper. + * Removed pre-dependency on dpkg (>= 1.10.24). + * Fixed spell errors removing lintian warning. + * Fixed dependencies of fp-units-math package. (Closes:Bug#567574) + * Bumped standard version to 3.8.4. + * Updated lintian override files. + [ Stefan Kisdaroczi ] + * Fixed Pred and Succ functions. (Closes: Bug#569023) + + -- Abou Al Montacir Mon, 03 Feb 2010 22:48:00 +0100 + +fpc (2.4.0-1) unstable; urgency=low + + * New upstream release with many fixes and new features offering a nice + collection of new functionality and bug fixes. + * New platforms: + - Mac OS X/PowerPC64 + - Mac OS X/x86_64 + - Mac OS X/ARM (iPhone) + * Compiler changes: + - Support for Delphi-style resource handling + - Whole-program optimization infrastructure, which initially supports + program devirtualization and unused virtual method removal + - Much faster compilation of units containing many type-sections + - The ability to suppress individual hints/warnings/notes + - Several improvements to the DWARF debug information generation + - Fixes to the generics support + - Fixes to the interface delegation (implements) support + - Improved cpu register allocation + - Improved ARM/EABI support + * RTL changes: + - Linearly scaling multi-threaded memory manager + - Support for (advisory) file locking on Unix-based platforms + - when using the SysUtils file creation/opening routines + - Support for ANSI ISO Extended Pascal ReadStr/WriteStr + - A UnicodeString type that, while not yet equivalent to Delphi 2009's + UnicodeString type, offers reference counted UnicodeString support on + the Windows, Linux, Mac OS X, FreeBSD and Beos/Haiku platforms. + * Packages changes: + - Many improvements to the XML units + - Many improvements to the database units + - Updated the common Mac OS X Pascal interfaces to r241, including + header a translation of the CFNetwork framework + - The zipper unit now works correctly on big endian platforms + * Added a patch fixing building documentation on Debian systems. + * Included quilt.make in rules file. (Closes: Bug#538552) + * Packaged news utility program (fpclasschart) poducing a class tree from + source files. + * Removed duplicate section field. + * Fixed fp-units-i386 package short description. + * Removed unneeded override rule. + * Added doc-base file for fp-compiler package. + * Fixed lintian warnings related to spell errors. + * Fixed upgrade breakage from 2.2.4-3 caused by moving files from fp-units-gfx + to fp-units-multimedia. (Closes: Bug#565167) + + -- Abou Al Montacir Sun, 13 Dec 2009 22:25:00 +0100 + +fpc (2.2.4-5) unstable; urgency=low + + * Added a new package fp-units-math for math development support. + + -- Abou Al Montacir Sun, 04 Dec 2009 21:11:00 +0100 + +fpc (2.2.4-4) unstable; urgency=low + + * Added support of armel arch to fpcmake from upstream. + * Adde documentation index file. (fixes linitan warning) + * Bumped standard version to 3.8.3. + * Added README.source. (fixes linitian warning) + * Added support for automatic cross-platform deb packaging. + * Updated fcl-xml from upstream to allow building next upstream release doc. + * Bumped fpc-abi to take in account new fcl-xml interface changes. + * Removed build dependency on libreadline5-dev as no more required. + + -- Abou Al Montacir Sun, 30 Nov 2009 19:03:00 +0100 + +fpc (2.2.4-3) unstable; urgency=low + + [ Abou Al Montacir ] + * Fixed compilation error on power PC. + + -- Abou Al Montacir Wed, 03 Jun 2009 12:44:00 +0200 + +fpc (2.2.4-2) unstable; urgency=low + + [ Stefan Kisdaroczi ] + * Fixed FindFirst and FindGetFileInfo functions. (Closes: Bug#528681) + + [ Abou Al Montacir ] + * Added lintian override rules for embedded-zlib + * Fixed wrong passing of function parameters for powerpc architecture. + (Closes: Bug#515035, Bug#511626) + + -- Abou Al Montacir Sat, 30 May 2009 17:46:00 +0200 + +fpc (2.2.4-1) unstable; urgency=low + + [ Abou Al Montacir ] + * new upstream release + - Added support for TIFF reading/writing in fcl-image + - Improvements and fixes in CHM support + - Fixed linking the gtk2-package with gtk versions above 2.13.4 + - Added support for CHM help files + * Remove patches that are now obsolete. + * Removed dependency from GTK1 as it was removed from Squeeze. + [ Paul Gevers ] + * Fixed typo in sysconst.pp. (Closes: Bug#519013) + + -- Abou Al Montacir Sat, 02 May 2009 16:40:30 +0200 + +fpc (2.2.2-8) unstable; urgency=low + + * Removed .pc directory in clean target to avoid a lintian warning. + * Moved chmcmd and chmls tools to fp-utils and added man files for them. + * Added Debian build version to compiler full version. + + -- Abou Al Montacir Tue, 16 Dec 2008 23:23:00 +0100 + +fpc (2.2.2-7) unstable; urgency=low + + [ Abou Al Montacir ] + * Patches were not applyed by patch system, fixed. (Closes: Bug#508415) + + -- Torsten Werner Mon, 15 Dec 2008 06:12:58 +0100 + +fpc (2.2.2-6) unstable; urgency=low + + * Remove auto-generated make files in clean target to avoid lintian warning + (Closes: Bug#508013). + * Removed gtk file system bindings as these no more exist in new gtk + libraries. (Closes: Bug#507520) + + -- Abou Al Montacir Wed, 04 Dec 2008 12:21:00 +0100 + +fpc (2.2.2-5) unstable; urgency=low + + * Added missing man pages to remove lintian warnings. + * Fixed bug in clean-patched target causing configuration files to be removed + before arch independent packages are build. + * Updated description of fp-docs package. (Closes: Bug#506065) + customizations. + * Fixed dependencies in rules file speeding package generation by avoiding + rebuilding binaries up to four times. + + -- Abou Al Montacir Thu, 18 Nov 2008 16:50:00 +0100 + +fpc (2.2.2-4) unstable; urgency=low + + [ Torsten Werner ] + * Update ABI version in fpc-depends automatically. + * Remove empty directories from binary package fpc-source. + + [ Abou Al Montacir ] + * Removed leading path when calling update-alternatives to remove a Lintian + error. + * Fixed clean target. + * Improved description of packages. (Closes: #498882) + + -- Abou Al Montacir Thu, 09 Oct 2008 23:29:00 +0200 + +fpc (2.2.2-3) unstable; urgency=low + + * Add *.fpc files to the binary package fpc-source. + + -- Torsten Werner Wed, 20 Aug 2008 01:07:06 +0200 + +fpc (2.2.2-2) unstable; urgency=low + + * Add patch manpages.diff that fixes various errors in the man pages. + * Switch from dpatch to quilt. + * Yak shaving to make lintian happy: remove unneeded files from binary + package fpc-source. + * Fix Provides: field of fp-unit-rtl. + + -- Torsten Werner Sun, 17 Aug 2008 15:10:22 +0200 + +fpc (2.2.2-1) unstable; urgency=low + + [ Abou Al Montacir ] + * new upstream release + - shlobj changes + - fix for wince library support + - fix for windows 64 bit support for >2GB memory + - Documentation was updated completely to conform to the actual state of + the compiler and RTL. + - Possible CodeGear Copyright infringements in the source were reworked + using cleanroom approach. + * Remove all patches that are now obsolete. + + [ Torsten Werner ] + * Bump up Standards-Version: 3.8.0 (no changes needed). + * Do not install extra license files. + * Fix some other lintian warnings. + + -- Torsten Werner Tue, 12 Aug 2008 16:55:14 +0200 + +fpc (2.2.0-dfsg1-9) unstable; urgency=low + + [ Torsten Werner ] + * Add Abou Al Montacir to Uploaders field. + + [ Abou Al Montacir ] + * Moved FPC sources into a version dependent directory from /usr/share/fpcsrc + to /usr/share/fpcsrc/${FPCVERSION}. This allow installing more than on FPC + release. + * Fixed far call issue in compiler preventing building huge binearies. + (closes: #477743) + * Updated building dependencies, recomennded and suggested packages. + * Moved fppkg to fp-utils as it is just a helper tool and is not required by + compiler. + + -- Abou Al Montacir Sat, 17 May 2008 17:12:11 +0200 + +fpc (2.2.0-dfsg1-8) unstable; urgency=low + + [ Abou Al Montacir ] + * Fixed build of fpc-source package cased by accidental remove of + fpc-source.install file during clean-patched target execution. + * Fixed Build-Depend clause (needs binutils instead of binutils-dev and no + need for libgpmg1-dev). + * Added man pages to the same packages including corresponding binaries. + * Removed from fpc-source code which isn't required by Lazarus code tool. + + -- Abou Al Montacir Thu, 08 May 2008 17:45:19 +0200 + +fpc (2.2.0-dfsg1-7) unstable; urgency=low + + [ Abou Al Montacir ] + * Added make files to source package. This required by fpcmake tool to succeed + cross platform compilation. + * Added man pages for fpcmkcfg, fpcsubst, fpcres, mkxmlrpc and rmcvsdir + binaries. + + -- Abou Al Montacir Wed, 30 Apr 2008 16:01:50 +0200 + +fpc (2.2.0-dfsg1-6) unstable; urgency=medium + + * Remove the patch 09_powerpc again because the bug is in libgdb-dev and + will be fixed there. + * Disable Build-Depends: libexpat1-dev, libgdb-dev because fpc is + incompatible to gdb 6.8. (Closes: #473955) + * Set urgency to medium because we are fixing a FTBFS bug only. + + -- Torsten Werner Sat, 29 Mar 2008 23:31:44 +0100 + +fpc (2.2.0-dfsg1-5) unstable; urgency=low + + [ Abou Al Montacir ] + * Applied fixes from upstream to packages/fcl-xml + + [ Torsten Werner ] + * Add a new patch 09_powerpc to make the package builds on powerpc + architecture. + + -- Torsten Werner Sat, 29 Mar 2008 10:39:26 +0100 + +fpc (2.2.0-dfsg1-4) unstable; urgency=low + + * Build fp-ide with debugger support. (Closes: #328701) + * Remove unneeded Build-Depends: findutils. + * Update Standards-Version: 3.7.3. + * Change Depends: mawk | awk. + * Clean up some lintian errors and warnings. + + -- Torsten Werner Sat, 15 Mar 2008 19:18:23 +0100 + +fpc (2.2.0-dfsg1-3) unstable; urgency=low + + * Add files matching *.inc to package fpc-source. + + -- Torsten Werner Sat, 29 Dec 2007 22:29:07 +0100 + +fpc (2.2.0-dfsg1-2) unstable; urgency=low + + [ Torsten Werner ] + * Set Architecture: all for fpc package. + * Fix bug in debian/rules: it's $(FPCVERSION) not $(FPC_VERSION). + (Closes: #457951) + + [ Abou Al Montacir ] + * New patch from upstream fixes non-deterministic register allocation on + sparc + * Modified rules to apply patches before building compiler + + -- Torsten Werner Sat, 29 Dec 2007 15:49:57 +0100 + +fpc (2.2.0-dfsg1-1) unstable; urgency=low + + * Remove all files matching *.o from upstream's tarball. + * Change fpc-source package: + - Do not copy directories installer and tests because they are not needed + by lazarus. + - Install only files matching *.pas and *.pp. + * Clean up the XXXVERSION cruft in debian/rules and debian/fixdeb. + * Update FSF address in debian/copyright. + + -- Torsten Werner Thu, 20 Dec 2007 18:46:55 +0100 + +fpc (2.2.0-3) unstable; urgency=low + + * Create binary package fpc-source again after having some discussion on + debian-devel. (Closes: #413805) + * Use bzip2 when creating binary packages and add + Pre-Depends: dpkg (>= 1.10.24). + * Add the fpc-depends tool. + + -- Torsten Werner Sun, 09 Dec 2007 22:35:01 +0100 + +fpc (2.2.0-2) unstable; urgency=low + + [ Abou Al Montacir ] + * Added dbase to fcl-db packaged units for arch other than i386. + * Fixed build issue for sparc and powerpc arch. + + -- Torsten Werner Fri, 07 Dec 2007 09:22:17 +0100 + +fpc (2.2.0-1) unstable; urgency=low + + [ Carlos Laviola ] + * New upstream release. (Closes: #442206) + * Added arm as a supported arch. (Closes: #408693) + * fp-units-gfx depends on libggi-dev. (Closes: #423659) + * fp-ide bugs fixed in the new version. (Closes: #423099, #423601, #423602) + * general cleanup on debian/{rules,control,...} + + [ Torsten Werner ] + * Complete debian/copyright. + * Add debian/watch and get-orig-source target in debian/rules. + * Remove *.dll, *.exe, and *.log from upstream tarball. + + -- Torsten Werner Fri, 23 Nov 2007 20:30:45 +0100 + +fpc (2.0.4-5) unstable; urgency=low + + * Fixed Build-Depends. + * Add myself to Uploaders in debian/control. + * Make sure that the sources are really patched before building them. + * Build unit 'libc' on powerpc too. + + -- Torsten Werner Sat, 27 Jan 2007 20:08:50 +0100 + +fpc (2.0.4-4) unstable; urgency=low + + * debian/rules: Separate out the documentation build into build-doc to + stop the documentations from building on binary-arch builds resulting + in FTBFS. + * Add Index value in debian/fp-docs.doc-base (Closes: #407715) + + -- Varun Hiremath Sun, 21 Jan 2007 20:49:43 +0530 + +fpc (2.0.4-3) unstable; urgency=medium + + * Added dpatch as a build dependency. (Closes: #407594) + + -- Carlos Laviola Sun, 21 Jan 2007 17:08:58 -0200 + +fpc (2.0.4-2) unstable; urgency=low + + * New release fixes Bug: "fp-compiler: miscompiles multilevel + if-statement" (Closes: #403586) + * Provide html docs (Closes: #150150) + + debian/rules: Set DOCTYPE=html and use CONVERTER=hevea + + debian/control: Add hevea to Build-Depends + + -- Varun Hiremath Tue, 16 Jan 2007 21:53:01 +0530 + +fpc (2.0.4-1) unstable; urgency=low + + [ Abou Al Montacir ] + * New release (Closes: #383055) + + [ Torsten Werner ] + * Fix bugs in debian/fp-compiler.pre*.in. + * Updated debian/control to use variables provides by newer versions of + dpkg. + * Add XS-X-Vcs-Svn header to debian/control. + * Add german po files from Holger Wansing. (Closes: #348408, #346247) + * Remove unneeded debian/fp-compiler.conffiles. + * Fixed debian/changelog (lintian error). + * Changed Build-Depends: gawk | awk. + + [ Varun Hiremath ] + * Bump Standards version to 3.7.2 + * Add Homepage in debian/control file. + * Add fp-units-gtk2 missing dependencies (Closes: #337990) + + -- Torsten Werner Sun, 14 Jan 2007 11:40:59 +0100 + +fpc (2.0.4-rc3) unstable; urgency=low + + * New release candidate + + -- Abou Al Montacir Sun, 06 Aug 2006 19:00:00 +0200 + +fpc (2.0.4-rc2) unstable; urgency=low + + * New release candidate + + -- Abou Al Montacir Tue, 18 Jul 2006 21:23:26 +0200 + +fpc (2.0.4-rc1) unstable; urgency=low + + * New release + + -- Peter Vreman Thu, 07 Jul 2006 12:00:00 +0100 + +fpc (2.0.0-4) unstable; urgency=low + + * debian/control.in: add amd64 to the Architecture field. + + -- Carlos Laviola Fri, 9 Sep 2005 18:38:26 -0300 + +fpc (2.0.0-3) unstable; urgency=medium + + * Created a prerm and preinst for fp-compiler, as /usr/bin/fpc needs to + be removed from the list of 'pc' alternatives. (Closes: #311436) + * Added amd64 to the architecture list. (Closes: #315220) + + -- Carlos Laviola Fri, 2 Sep 2005 10:27:21 -0300 + +fpc (2.0.0-2) unstable; urgency=low + + * debian/fp-compiler.postinst.in: forgot to reapply the patch that + correctly creates the slave link to pc(1). (Closes: #310907) + + -- Carlos Laviola Mon, 30 May 2005 11:59:10 -0300 + +fpc (2.0.0-1) unstable; urgency=low + + * As I couldn't upload 1.9.8 on all supported architectures before 2.0.0 + was released, I'm rehashing its changelog now. + * New upstream release. + Bugs fixed on CVS before 1.9.8: + * man/man1/fpc.1: -OPn changed to -Opn in rev 1.8 (Closes: #255960) + * debian/fp-compiler.postinst.in: fixed in rev 1.5 (Closes: #269853) + Bugs fixed on CVS before 1.9.6: + * rtl/unix/crt.pp: fixed in rev 1.20 (Closes: #216060) + * rtl/i386/strings.inc: fixed in rev 1.16 (Closes: #288955) + * compiler/nadd.pas: fixed in rev 1.126 (Closes: #297881) + * debian/control: Added missing build dependencies on libgpmg1-dev and + libncurses5-dev and set save_size at build time, which finally makes + the package build without manual intervention. (Closes: #304633) + + -- Carlos Laviola Fri, 20 May 2005 19:07:00 -0300 + +fpc (1.9.6-2) unstable; urgency=low + + * debian/control: Oops -- fp-units-fv had the wrong description. + + -- Carlos Laviola Fri, 14 Jan 2005 13:15:50 -0200 + +fpc (1.9.6-1) unstable; urgency=low + + * New upstream release. + * debian/control: Added build dependency on libgpmg1-dev. + + -- Carlos Laviola Fri, 31 Dec 2004 21:16:25 -0200 + +fpc (1.9.4-5) unstable; urgency=low + + * fp-compiler: needs ld, adding dependency on binutils. (Closes: #265265) + + -- Carlos Laviola Thu, 12 Aug 2004 16:29:37 -0300 + +fpc (1.9.4-4) unstable; urgency=low + + * debian/control.in: Oops, forgot to update the Build-Deps for this file, + which generates debian/control per se. (Closes: #263942) + + -- Carlos Laviola Sun, 8 Aug 2004 22:12:41 -0300 + +fpc (1.9.4-3) unstable; urgency=low + + * Package needs fpcmake to build pretty much everything, so we need to + build-dep on fp-utils. Thanks to Daniel Schepler for finding the bug + and for Jurij Smakov's aid. (Closes: #263942) + * debian/README.Debian: removes mentions to old problems with tetex, fixes + spelling mistakes and other minor issues. + + -- Carlos Laviola Fri, 6 Aug 2004 19:46:51 -0300 + +fpc (1.9.4-2) unstable; urgency=low + + * The following fixes are the work of Marco van de Voort from CVS HEAD: + - man/man1/ppc386.1: typo fix. (Closes: #255960) + - rtl/unix/crt.pp: gotoxy/XY2Ansi fixes from. + (Closes: #216057, #216060) + - docs/linuxex, docs/dosex, docs/refex: various examples ported to + fpc 1.9.x's new API. + + -- Carlos Laviola Tue, 20 Jul 2004 15:12:05 -0300 + +fpc (1.9.4-1) unstable; urgency=low + + * This release is partly the work of Peter Vreman . + * Acknowledging NMU. (Closes: #221316) + * Made the description for the units packages more informative. + (Closes: #209518, #209581, #209613) + * Applied some patches from Marco van de Voort to CVS HEAD that fixed + compiling the documentation on powerpc with some adaptations of mine. + + -- Carlos Laviola Sat, 17 Jul 2004 21:53:03 -0300 + +fpc (1.0.10-1.2) unstable; urgency=low + + * NMU + * debian/control: Also had to remove build dependency on latex2html here + (Closes: #221316) + + -- Roland Stigge Thu, 12 Feb 2004 10:27:20 +0100 + +fpc (1.0.10-1.1) unstable; urgency=low + + * NMU + * debian/control.in: Removed Build-Depends: latex2html which moved to + non-free (Closes: #221316) + + -- Roland Stigge Sat, 20 Dec 2003 20:45:41 +0100 + +fpc (1.0.10-1) unstable; urgency=low + + * New upstream release. + * Acknowledging Amaya's NMU. Thanks for the hand. (Closes: #141439) + * Package dependency lists corrected. (Closes: #84863, #155158) + * Example compiles correctly now. (Closes: #174371) + * Fixed vanishing fpc(1) manpage if gpc is installed. (Closes: #136283) + * Fixed manpage error. (Closes: #191695) + * Spelling mistakes are gone. (Closes: #124637, #124638) + * Both bugs (doc-base-file-references-usr-doc and debian-changelog-file- + contains-obsolete-user-emacs-settings, in lintian tags) were corrected + long ago. (Closes: #127092) + * Upstream have added the AddDisk function. (Closes: #103163) + + -- Carlos Laviola Sat, 2 Aug 2003 04:35:51 -0300 + +fpc (1.0.6-2) unstable; urgency=low + + * NMU for Debcamp BSP. + * Apply a very silly patch (Closes: #141439), which was RC. The PDF file now + builds. + * Updated versioned-build-depends-on-debhelper. + + -- Amaya Rodrigo Sastre Sat, 12 Jul 2003 17:58:50 +0200 + +fpc (1.0.6-1) unstable; urgency=low + + * New upstream version. (Closes: #154199) + + -- Carlos Laviola Sat, 10 Aug 2002 04:26:15 -0300 + +fpc (1.0.4+1.0.6cvs20020228-1) unstable; urgency=low + + * New upstream version. + + -- Peter Vreman Tue, 1 Mar 2002 11:01:50 +0100 + +fpc (1.0.4-2) unstable; urgency=low + + * New maintainer. + * debian/README.Debian: Added a note on building 'pdflatex.fmt', which is + needed by pdflatex, in order to build the documentation in PDF format. + * debian/control: added latex2html, dvipdfm and tetex-extra to the + build-deps list. + + -- Carlos Laviola Wed, 29 Aug 2001 23:15:17 -0300 + +fpc (1.0.4-1) unstable; urgency=low + + * New upstream version. + + -- Ulf Jaenicke-Roessler Tue, 2 Jan 2001 11:01:50 +0100 + +fpc (1.0.3-0.20001206.1) unstable; urgency=low + + * Snapshot release from CVS 2000/12/06. + * Fixes internal compiler error on (buggy) appearance of + array of Date (Closes:#60720). + * ppc386 can be called more intuitively as fpc (Closes:#74810). + * Help option '-h' is (somewhat) more propagated than '-?' + (Closes:#74811). Furthermore, help is displayed when fpc + is called without any parameter. + * Package supports alternatives now, in order to be used as + "Pascal compiler" (pc) from Makefile(s) (Closes:#76615). + + -- Ulf Jaenicke-Roessler Wed, 6 Dec 2000 11:29:28 +0100 + +fpc (1.0.2-1) unstable; urgency=low + + * New upstream version. + * Maintainer field changed. + * Bug#60720 had already been fixed in the development tree some + time ago after the last upload (hence, this Closes: #60720). + + -- Ulf Jaenicke-Roessler Fri, 13 Oct 2000 13:11:34 +0200 + +fpc (1.0.1-0.20000811.1) unstable; urgency=low + + * Built for `official' upload. CVS as of 2000/08/11 - NMU. + * Update to latest version, thus Closes: #56873. + * Removes /usr/bin/ppc386 link upon package removal. Closes: #64403. + * This upload also Closes: #68801. + * Added Build-Depends. Hmmm, 'fp-compiler' is somehow like `the chicken + and the egg' story... + + -- Ulf Jaenicke-Roessler Fri, 11 Aug 2000 22:49:37 +0200 + +fpc (1.0.1-0) unstable; urgency=low + + * New Upstream Release + + -- Peter Vreman Sun, 09 Jun 2000 12:00:00 +0200 + +fpc (0.99.13-19991013-4) unstable; urgency=low + + * Fixed bashism in samplecfg (Closes: Bug#50636) + * Changed source-arch to 'i386' (Closes: Bug#50438) + + -- Mika Fischer Sat, 20 Nov 1999 22:18:11 +0100 + +fpc (0.99.13-19991013-3) unstable; urgency=low + + * Fixed bug which overwrote existing config files during an update + (Closes: Bug#50278) + + -- Mika Fischer Tue, 16 Nov 1999 23:57:36 +0100 + +fpc (0.99.13-19991013-2) unstable; urgency=low + + * Fixed bug in debian/rules (Fixes: #50096) + + -- Mika Fischer Sat, 13 Nov 1999 20:31:20 +0100 + +fpc (0.99.13-19991013-1) unstable; urgency=low + + * Removed fp-fv due to licensing issues. + + -- Mika Fischer Wed, 13 Oct 1999 19:33:30 +0200 + +fpc (0.99.13-19991005-1) unstable; urgency=low + + * New maintainer + + -- Mika Fischer Wed, 13 Oct 1999 19:33:13 +0200 + +fpc (0.99.13-19991001-1) unstable; urgency=low + + * New maintainer + * Updated to policy 3.0.1 + + -- Joseph Carter Tue, 27 Jul 1999 18:05:05 -0700 + +fpc (0.99.12b-1) unstable; urgency=low + + * New Upstream Release + + -- Peter Vreman Thu, 10 Jun 1999 12:00:00 +0200 + +fpc (0.99.12a-1) unstable; urgency=low + + * Initial Release + + -- Peter Vreman Thu, 10 Jun 1999 12:00:00 +0200 diff --git a/clean b/clean new file mode 100644 index 00000000..96a557b9 --- /dev/null +++ b/clean @@ -0,0 +1,37 @@ +debian/*.config +debian/*.doc-base +debian/*.docs +debian/*.examples +debian/*.files +debian/*.*.install +debian/fp-*.links +debian/*.*.lintian-overrides +debian/*.*.manpages +debian/*.postinst +debian/*.postrm +debian/*.preinst +debian/*.prerm +debian/*.templates +debian/README*.Debian +debian/dirs +debian/docs +debian/fpc-depends +debian/fpc-depends-*.1 +debian/fp-fix-timestamps.1 +install/man/man1/ppc68k.1 +install/man/man1/ppca64.1 +install/man/man1/ppcmips.1 +install/man/man1/ppcmipsel.1 +install/man/man1/ppcppc64.1 +fpcdocs/fpdoc.haux +fpcdocs/prog.haux +fpcdocs/ref.haux +fpcdocs/ref.hind +fpcdocs/tree.xml +fpcdocs/user.haux +fpcsrc/compiler/msgtxt.inc +fpcsrc/compiler/utils/msg2inc +fpcsrc/compiler/version.inc +fpcsrc/packages/gdbint/src/gdbver.inc +fpcsrc/utils/fpcm/fpcmake.inc +fpcsrc/utils/fpdoc/intl/*.mo diff --git a/compat b/compat new file mode 100644 index 00000000..f599e28b --- /dev/null +++ b/compat @@ -0,0 +1 @@ +10 diff --git a/control b/control new file mode 100644 index 00000000..4854675e --- /dev/null +++ b/control @@ -0,0 +1,950 @@ +Source: fpc +Section: devel +Priority: optional +Maintainer: Pascal Packaging Team +Uploaders: + Abou Al Montacir , + Paul Gevers , + Peter Michael Green , +Standards-Version: 4.1.3 +Build-Depends: + binutils, + debhelper (>= 10~), + dh-exec (>=0.22), + fp-compiler, + fp-units-base, + fp-units-fcl, + fp-utils, + ghostscript, + libncurses-dev, + mawk | awk, + po-debconf, + txt2man, +Build-Depends-Indep: + hevea, + rdfind, + symlinks +Vcs-Git: https://anonscm.debian.org/git/pkg-pascal/fpc.git +Vcs-Browser: https://anonscm.debian.org/cgit/pkg-pascal/fpc.git +Homepage: https://www.freepascal.org/ + +Package: fpc-3.0.4 +Architecture: all +Depends: + fp-compiler-3.0.4 (>= ${binary:Version}), + fp-ide-3.0.4 (>= ${binary:Version}), + fp-units-base-3.0.4 (>= ${binary:Version}), + fp-units-db-3.0.4 (>= ${binary:Version}), + fp-units-fcl-3.0.4 (>= ${binary:Version}), + fp-units-fv-3.0.4 (>= ${binary:Version}), + fp-units-gfx-3.0.4 (>= ${binary:Version}), + fp-units-gtk2-3.0.4 (>= ${binary:Version}), + fp-units-math-3.0.4 (>= ${binary:Version}), + fp-units-misc-3.0.4 (>= ${binary:Version}), + fp-units-multimedia-3.0.4 (>= ${binary:Version}), + fp-units-net-3.0.4 (>= ${binary:Version}), + fp-units-rtl-3.0.4 (>= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + fp-utils-3.0.4 +Suggests: + fp-docs-3.0.4 (>= ${source:Upstream-Version}), + lazarus +Provides: + fpc +Breaks: + fpc (<= 3.0.4+dfsg-0), +Replaces: + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - SDK-3.0.4 suite + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + Extensions have been added to the language, such as function overloading, + creation and linking of shared libraries, and Delphi language extensions + including classes, exceptions, ANSI strings, and open arrays. + . + This metapackage pulls in all the FPC packages provided for this + architecture. Experienced users may instead prefer to install the particular + packages they require by hand. + +Package: fpc-source-3.0.4 +Architecture: all +Multi-Arch: foreign +Depends: + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fpc-source +Breaks: + fpc-source (<= 2.4.0-3), + fpc-src +Replaces: + fpc-source (<= 2.4.0-3), + fpc-src +Description: Free Pascal - SDK source code + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal's own source code. It is meant to be used by + the Lazarus IDE. + +Package: fp-compiler-3.0.4 +Architecture: any +Multi-Arch: same +Depends: + binutils, + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + fp-utils-3.0.4 (>= ${binary:Version}) +Suggests: + fp-docs-3.0.4 (>= ${source:Upstream-Version}), +Provides: + fp-compiler +Breaks: + fp-compiler (<= 2.4.0-3), + fp-utils-2.4.2 (<= 2.4.2-3), + fp-utils-2.4.4 (<= 2.4.4-2), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-compiler (<= 2.4.0-3), + fp-utils-2.4.4 (<= 2.4.4-1), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - compiler + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + Extensions have been added to the language, such as function overloading, + creation and linking of shared libraries, and Delphi language extensions + including classes, exceptions, ANSI strings, and open arrays. + . + This package contains the command line compiler. + +Package: fp-ide-3.0.4 +Architecture: any +Multi-Arch: foreign +Depends: + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + fp-utils-3.0.4 (>= ${binary:Version}) +Suggests: + fp-docs-3.0.4 (>= ${source:Upstream-Version}) +Provides: + fp-ide +Breaks: + fp-ide (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-ide (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - IDE + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + Extensions have been added to the language, such as function overloading, + creation and linking of shared libraries, and Delphi language extensions + including classes, exceptions, ANSI strings, and open arrays. + . + This package contains the Integrated Development Environment (IDE). The IDE + has an internal compiler. + +Package: fp-utils-3.0.4 +Architecture: any +Multi-Arch: foreign +Depends: + fpc-source-3.0.4, + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + fp-compiler-3.0.4 (= ${binary:Version}) +Provides: + fp-utils +Breaks: + fp-compiler-3.0.4 (<= 3.0.4+dfsg-11), + fp-compiler (<= 2.4.0-3), + fp-units-gfx (<= 2.4.2-2), + fp-units-gfx-2.4.2 (<= 2.4.2-2), + fp-utils (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-compiler-3.0.4 (<= 3.0.4+dfsg-11), + fp-compiler (<= 2.4.0-3), + fp-utils (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - utilities + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains some handy utilities for use with the Free Pascal + Compiler: + * data2inc convert binary/text data to include files; + * fpcmake create Makefile from Makefile.fpc; + * h2pas convert .h files to Pascal units; + * plex/pyacc Pascal Lex and Yacc implementations; + * ppdep create a dependency file for use with Makefiles; + * ppudump dump the information stored in a .ppu (unit) file; + * ppufiles show needed files for units; + * ppumove place multiple units in a shared library; + * ptop beautify source. + +Package: fp-docs-3.0.4 +Section: doc +Architecture: all +Multi-Arch: foreign +Depends: + ${misc:Depends}, + ${shlibs:Depends}, +Provides: + fp-docs +Breaks: + fp-docs (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-docs (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - documentation + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package provides documentation for the Free Pascal Compiler in HTML + format. + +Package: fp-units-rtl-3.0.4 +Architecture: any +Multi-Arch: same +Depends: + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + fp-compiler-3.0.4 (= ${binary:Version}) +Provides: + fp-units-rtl, + fpc-abi-3.0.4 +Breaks: + fp-units-rtl (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-units-rtl (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - runtime libraries + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains the RunTime Libraries for the Free Pascal Compiler. + +Package: fp-units-base-3.0.4 +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Suggests: + uuid-dev +Provides: + fp-units-base +Breaks: + fp-units-base (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), + fp-units-misc-3.0.0 (<= 3.0.0+dfsg-2), +Replaces: + fp-units-base (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), + fp-units-misc-3.0.0 (<= 3.0.0+dfsg-2), +Description: Free Pascal - base units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal units for common libraries (some of which + are also required by the Free Component Library): NCurses, X11 (Xlib, + Xutil), and ZLib. + +Package: fp-units-fcl-3.0.4 +Architecture: any +Multi-Arch: same +Depends: + fp-units-base-3.0.4 (= ${binary:Version}), + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-fcl +Breaks: + fp-units-fcl (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-units-fcl (<= 2.4.0-3) +Description: Free Pascal - Free Component Library + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains the Free Component Library for the Free Pascal Compiler. + +Package: fp-units-fv-3.0.4 +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-fv +Breaks: + fp-units-fv (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-units-fv (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - Free Vision units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains the Free Vision units for the Free Pascal Compiler + (which provide a framework for developing text user interfaces). + +Package: fp-units-gtk2-3.0.4 +Architecture: any +Multi-Arch: same +Depends: + fp-units-fcl-3.0.4 (= ${binary:Version}), + fp-units-rtl-3.0.4 (= ${binary:Version}), + libgtk2.0-dev, + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-gtk2 +Breaks: + fp-units-gtk2 (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-units-gtk2 (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - GTK+ 2.x units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal units and examples to create + programs with GTK+ 2.x. + +Package: fp-units-db-3.0.4 +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Suggests: + firebird-dev, + freetds-dev, + libgdbm-dev, + default-libmysqlclient-dev, + libpq-dev, + libsqlite3-dev, + pxlib-dev, + unixodbc-dev +Provides: + fp-units-db +Breaks: + fp-units-db (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-units-db (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - database-library units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal units with bindings for GDBM, Interbase, + MySQL, PostgreSQL, ODBC, Oracle, and SQLite. + +Package: fp-units-gfx-3.0.4 +Architecture: any +Multi-Arch: same +Depends: + fp-units-base-3.0.4 (= ${binary:Version}), + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-gfx +Recommends: + libcairo2-dev, + libforms-dev, + libgd-dev, + libggi2-dev, + libgl1-mesa-dev, + libgraphviz-dev, + libpng-dev, + libxxf86dga-dev, + libxxf86vm-dev +Breaks: + fp-units-gfx (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-units-gfx (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - graphics-library units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal units with bindings for cairo, forms, ggi, + graph, libgd, libpng, opengl, and svgalib. + . + SVGALib is no longer packaged by Debian and should be installed manually by + users who want to link against it. + +Package: fp-units-net-3.0.4 +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-net +Breaks: + fp-units-net (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-units-net (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - networking units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal units for creating network tools: D-Bus, + httpd-1.3, httpd-2.0, httpd-2.2, ldap, libasync, libcurl, netdb, openssl, + and pcap. + +Package: fp-units-math-3.0.4 +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + libgmp-dev +Provides: + fp-units-math +Breaks: + fp-units-math (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-units-math (<= 2.4.0-3), + fp-units-misc (<= 2.2.4-4), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - math units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal math interfacing units for: + * gmp (the GNU Multiple Precision arithmetic library); + * numlib (numerical computing); + * proj4 (cartographic projections); + * symbolic (symbolic computing). + +Package: fp-units-misc-3.0.4 +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-misc +Breaks: + fp-units-misc (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-units-misc (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - miscellaneous units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains miscellaneous Free Pascal units: fppkg (the FPC + packaging system), PasZLib (a Pascal-only zlib implementation), and Utmp. + +Package: fp-units-multimedia-3.0.4 +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + a52dec-dev, + libdts-dev, + libmad0-dev, + libmodplug-dev, + libogg-dev, + libsdl-mixer1.2-dev, + libvorbis-dev, + libvlc-dev +Provides: + fp-units-multimedia +Breaks: + fp-units-multimedia (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-units-gfx (<= 2.2.4-3), + fp-units-multimedia (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - multimedia units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal multimedia units: a52, dts, mad, modplug, + oggvorbis, openal, and vlc. + +Package: fp-units-i386-3.0.4 +Architecture: i386 +Multi-Arch: same +Depends: + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-i386 +Breaks: + fp-units-i386 (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Replaces: + fp-units-i386 (<= 2.4.0-3), + fpc (<= 3.0.4+dfsg-0), +Description: Free Pascal - Kylix compatibility units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains the deprecated Free Pascal libc unit for the i386 + architecture (used for compatibility with Borland's Kylix). + +Package: fpc +Architecture: all +Depends: + fpc-3.0.4 (= ${binary:Version}), + fp-docs-3.0.4, + fp-utils-3.0.4, + ${misc:Depends} +Description: Free Pascal - SDK suite dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + Extensions have been added to the language, such as function overloading, + creation and linking of shared libraries, and Delphi language extensions + including classes, exceptions, ANSI strings, and open arrays. + . + This dependency package always depends on the latest available version of + the metapackage pulling in all the FPC packages provided for this + architecture. Experienced users may instead prefer to install the particular + packages they require by hand. + +Package: fpc-source +Architecture: all +Multi-Arch: foreign +Depends: + fpc-source-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - SDK source code dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal's own source code. It is meant to be used by + the Lazarus IDE. + +Package: fp-compiler +Architecture: any +Multi-Arch: same +Depends: + fp-compiler-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - compiler dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + Extensions have been added to the language, such as function overloading, + creation and linking of shared libraries, and Delphi language extensions + including classes, exceptions, ANSI strings, and open arrays. + . + This dependency package always depends on the latest available version of + the package containing the command line compiler. + +Package: fp-ide +Architecture: all +Multi-Arch: foreign +Depends: + fp-ide-3.0.4 (>= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - IDE dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + Extensions have been added to the language, such as function overloading, + creation and linking of shared libraries, and Delphi language extensions + including classes, exceptions, ANSI strings, and open arrays. + . + This dependency package always depends on the latest available version of + the package containing the Integrated Development Environment (IDE). The IDE + has an internal compiler. + +Package: fp-utils +Architecture: all +Multi-Arch: foreign +Depends: + fp-utils-3.0.4 (>= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - utilities dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing some handy utilities for use with the Free Pascal + Compiler: + * data2inc convert binary/text data to include files; + * fpcmake create Makefile from Makefile.fpc; + * h2pas convert .h files to Pascal units; + * plex/pyacc Pascal Lex and Yacc implementations; + * ppdep create a dependency file for use with Makefiles; + * ppudump dump the information stored in a .ppu (unit) file; + * ppufiles show needed files for units; + * ppumove place multiple units in a shared library; + * ptop beautify source. + +Package: fp-docs +Section: doc +Architecture: all +Multi-Arch: foreign +Depends: + fp-docs-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - documentation dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing documentation for the Free Pascal Compiler in HTML + format. + +Package: fp-units-rtl +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - runtime libraries dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing the RunTime Libraries for the Free Pascal Compiler. + +Package: fp-units-base +Architecture: any +Multi-Arch: same +Depends: + fp-units-base-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - base units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal units for common libraries (some of which + are also required by the Free Component Library): NCurses, X11 (Xlib, + Xutil), and ZLib. + +Package: fp-units-fcl +Architecture: any +Multi-Arch: same +Depends: + fp-units-fcl-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - Free Component Library dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing the Free Component Library for the Free Pascal Compiler. + +Package: fp-units-fv +Architecture: any +Multi-Arch: same +Depends: + fp-units-fv-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - Free Vision units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing the Free Vision units for the Free Pascal Compiler + (which provide a framework for developing text user interfaces). + +Package: fp-units-gtk2 +Architecture: any +Multi-Arch: same +Depends: + fp-units-gtk2-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - GTK+ 2.x units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal units and examples to create + programs with GTK+ 2.x. + +Package: fp-units-db +Architecture: any +Multi-Arch: same +Depends: + fp-units-db-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - database-library units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal units with bindings for GDBM, Interbase, + MySQL, PostgreSQL, ODBC, Oracle, and SQLite. + +Package: fp-units-gfx +Architecture: any +Multi-Arch: same +Depends: + fp-units-gfx-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - graphics-library units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal units with bindings for cairo, forms, ggi, + graph, libgd, libpng, opengl, and svgalib. + . + SVGALib is no longer packaged by Debian and should be installed manually by + users who want to link against it. + +Package: fp-units-net +Architecture: any +Multi-Arch: same +Depends: + fp-units-net-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - networking units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal units for creating network tools: D-Bus, + httpd-1.3, httpd-2.0, httpd-2.2, ldap, libasync, libcurl, netdb, openssl, + and pcap. + +Package: fp-units-math +Architecture: any +Multi-Arch: same +Depends: + fp-units-math-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - math units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal math interfacing units for: + * gmp (the GNU Multiple Precision arithmetic library); + * numlib (numerical computing); + * proj4 (cartographic projections); + * symbolic (symbolic computing). + +Package: fp-units-misc +Architecture: any +Multi-Arch: same +Depends: + fp-units-misc-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - miscellaneous units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing miscellaneous Free Pascal units: fppkg (the FPC + packaging system), PasZLib (a Pascal-only zlib implementation), and Utmp. + +Package: fp-units-multimedia +Architecture: any +Multi-Arch: same +Depends: + fp-units-multimedia-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - multimedia units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal multimedia units: a52, dts, mad, modplug, + oggvorbis, openal, and vlc. + +Package: fp-units-i386 +Architecture: i386 +Depends: + fp-units-i386-3.0.4 (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - Kylix compatibility units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing the deprecated Free Pascal libc unit for the i386 + architecture (used for compatibility with Borland's Kylix). diff --git a/control.in b/control.in new file mode 100644 index 00000000..dfab61a8 --- /dev/null +++ b/control.in @@ -0,0 +1,950 @@ +Source: fpc +Section: devel +Priority: optional +Maintainer: Pascal Packaging Team +Uploaders: + Abou Al Montacir , + Paul Gevers , + Peter Michael Green , +Standards-Version: 4.1.3 +Build-Depends: + binutils, + debhelper (>= 10~), + dh-exec (>=0.22), + fp-compiler, + fp-units-base, + fp-units-fcl, + fp-utils, + ghostscript, + libncurses-dev, + mawk | awk, + po-debconf, + txt2man, +Build-Depends-Indep: + hevea, + rdfind, + symlinks +Vcs-Git: https://anonscm.debian.org/git/pkg-pascal/fpc.git +Vcs-Browser: https://anonscm.debian.org/cgit/pkg-pascal/fpc.git +Homepage: https://www.freepascal.org/ + +Package: fpc${PACKAGESUFFIX} +Architecture: all +Depends: + fp-compiler${PACKAGESUFFIX} (>= ${binary:Version}), + fp-ide${PACKAGESUFFIX} (>= ${binary:Version}), + fp-units-base${PACKAGESUFFIX} (>= ${binary:Version}), + fp-units-db${PACKAGESUFFIX} (>= ${binary:Version}), + fp-units-fcl${PACKAGESUFFIX} (>= ${binary:Version}), + fp-units-fv${PACKAGESUFFIX} (>= ${binary:Version}), + fp-units-gfx${PACKAGESUFFIX} (>= ${binary:Version}), + fp-units-gtk2${PACKAGESUFFIX} (>= ${binary:Version}), + fp-units-math${PACKAGESUFFIX} (>= ${binary:Version}), + fp-units-misc${PACKAGESUFFIX} (>= ${binary:Version}), + fp-units-multimedia${PACKAGESUFFIX} (>= ${binary:Version}), + fp-units-net${PACKAGESUFFIX} (>= ${binary:Version}), + fp-units-rtl${PACKAGESUFFIX} (>= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + fp-utils${PACKAGESUFFIX} +Suggests: + fp-docs${PACKAGESUFFIX} (>= ${source:Upstream-Version}), + lazarus +Provides: + fpc +Breaks: + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - SDK${PACKAGESUFFIX} suite + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + Extensions have been added to the language, such as function overloading, + creation and linking of shared libraries, and Delphi language extensions + including classes, exceptions, ANSI strings, and open arrays. + . + This metapackage pulls in all the FPC packages provided for this + architecture. Experienced users may instead prefer to install the particular + packages they require by hand. + +Package: fpc-source${PACKAGESUFFIX} +Architecture: all +Multi-Arch: foreign +Depends: + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fpc-source +Breaks: + fpc-source (<= 2.4.0-3), + fpc-src +Replaces: + fpc-source (<= 2.4.0-3), + fpc-src +Description: Free Pascal - SDK source code + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal's own source code. It is meant to be used by + the Lazarus IDE. + +Package: fp-compiler${PACKAGESUFFIX} +Architecture: any +Multi-Arch: same +Depends: + binutils, + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + fp-utils${PACKAGESUFFIX} (>= ${binary:Version}) +Suggests: + fp-docs${PACKAGESUFFIX} (>= ${source:Upstream-Version}), +Provides: + fp-compiler +Breaks: + fp-compiler (<= 2.4.0-3), + fp-utils-2.4.2 (<= 2.4.2-3), + fp-utils-2.4.4 (<= 2.4.4-2), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-compiler (<= 2.4.0-3), + fp-utils-2.4.4 (<= 2.4.4-1), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - compiler + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + Extensions have been added to the language, such as function overloading, + creation and linking of shared libraries, and Delphi language extensions + including classes, exceptions, ANSI strings, and open arrays. + . + This package contains the command line compiler. + +Package: fp-ide${PACKAGESUFFIX} +Architecture: any +Multi-Arch: foreign +Depends: + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + fp-utils${PACKAGESUFFIX} (>= ${binary:Version}) +Suggests: + fp-docs${PACKAGESUFFIX} (>= ${source:Upstream-Version}) +Provides: + fp-ide +Breaks: + fp-ide (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-ide (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - IDE + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + Extensions have been added to the language, such as function overloading, + creation and linking of shared libraries, and Delphi language extensions + including classes, exceptions, ANSI strings, and open arrays. + . + This package contains the Integrated Development Environment (IDE). The IDE + has an internal compiler. + +Package: fp-utils${PACKAGESUFFIX} +Architecture: any +Multi-Arch: foreign +Depends: + fpc-source${PACKAGESUFFIX}, + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + fp-compiler${PACKAGESUFFIX} (= ${binary:Version}) +Provides: + fp-utils +Breaks: + fp-compiler${PACKAGESUFFIX} (<= 3.0.4+dfsg-11), + fp-compiler (<= 2.4.0-3), + fp-units-gfx (<= 2.4.2-2), + fp-units-gfx-2.4.2 (<= 2.4.2-2), + fp-utils (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-compiler${PACKAGESUFFIX} (<= 3.0.4+dfsg-11), + fp-compiler (<= 2.4.0-3), + fp-utils (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - utilities + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains some handy utilities for use with the Free Pascal + Compiler: + * data2inc convert binary/text data to include files; + * fpcmake create Makefile from Makefile.fpc; + * h2pas convert .h files to Pascal units; + * plex/pyacc Pascal Lex and Yacc implementations; + * ppdep create a dependency file for use with Makefiles; + * ppudump dump the information stored in a .ppu (unit) file; + * ppufiles show needed files for units; + * ppumove place multiple units in a shared library; + * ptop beautify source. + +Package: fp-docs${PACKAGESUFFIX} +Section: doc +Architecture: all +Multi-Arch: foreign +Depends: + ${misc:Depends}, + ${shlibs:Depends}, +Provides: + fp-docs +Breaks: + fp-docs (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-docs (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - documentation + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package provides documentation for the Free Pascal Compiler in HTML + format. + +Package: fp-units-rtl${PACKAGESUFFIX} +Architecture: any +Multi-Arch: same +Depends: + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + fp-compiler${PACKAGESUFFIX} (= ${binary:Version}) +Provides: + fp-units-rtl, + fpc-abi${PACKAGESUFFIX} +Breaks: + fp-units-rtl (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-units-rtl (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - runtime libraries + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains the RunTime Libraries for the Free Pascal Compiler. + +Package: fp-units-base${PACKAGESUFFIX} +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Suggests: + uuid-dev +Provides: + fp-units-base +Breaks: + fp-units-base (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), + fp-units-misc-3.0.0 (<= 3.0.0+dfsg-2), +Replaces: + fp-units-base (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), + fp-units-misc-3.0.0 (<= 3.0.0+dfsg-2), +Description: Free Pascal - base units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal units for common libraries (some of which + are also required by the Free Component Library): NCurses, X11 (Xlib, + Xutil), and ZLib. + +Package: fp-units-fcl${PACKAGESUFFIX} +Architecture: any +Multi-Arch: same +Depends: + fp-units-base${PACKAGESUFFIX} (= ${binary:Version}), + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-fcl +Breaks: + fp-units-fcl (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-units-fcl (<= 2.4.0-3) +Description: Free Pascal - Free Component Library + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains the Free Component Library for the Free Pascal Compiler. + +Package: fp-units-fv${PACKAGESUFFIX} +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-fv +Breaks: + fp-units-fv (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-units-fv (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - Free Vision units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains the Free Vision units for the Free Pascal Compiler + (which provide a framework for developing text user interfaces). + +Package: fp-units-gtk2${PACKAGESUFFIX} +Architecture: any +Multi-Arch: same +Depends: + fp-units-fcl${PACKAGESUFFIX} (= ${binary:Version}), + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + libgtk2.0-dev, + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-gtk2 +Breaks: + fp-units-gtk2 (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-units-gtk2 (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - GTK+ 2.x units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal units and examples to create + programs with GTK+ 2.x. + +Package: fp-units-db${PACKAGESUFFIX} +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Suggests: + firebird-dev, + freetds-dev, + libgdbm-dev, + default-libmysqlclient-dev, + libpq-dev, + libsqlite3-dev, + pxlib-dev, + unixodbc-dev +Provides: + fp-units-db +Breaks: + fp-units-db (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-units-db (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - database-library units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal units with bindings for GDBM, Interbase, + MySQL, PostgreSQL, ODBC, Oracle, and SQLite. + +Package: fp-units-gfx${PACKAGESUFFIX} +Architecture: any +Multi-Arch: same +Depends: + fp-units-base${PACKAGESUFFIX} (= ${binary:Version}), + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-gfx +Recommends: + libcairo2-dev, + libforms-dev, + libgd-dev, + libggi2-dev, + libgl1-mesa-dev, + libgraphviz-dev, + libpng-dev, + libxxf86dga-dev, + libxxf86vm-dev +Breaks: + fp-units-gfx (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-units-gfx (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - graphics-library units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal units with bindings for cairo, forms, ggi, + graph, libgd, libpng, opengl, and svgalib. + . + SVGALib is no longer packaged by Debian and should be installed manually by + users who want to link against it. + +Package: fp-units-net${PACKAGESUFFIX} +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-net +Breaks: + fp-units-net (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-units-net (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - networking units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal units for creating network tools: D-Bus, + httpd-1.3, httpd-2.0, httpd-2.2, ldap, libasync, libcurl, netdb, openssl, + and pcap. + +Package: fp-units-math${PACKAGESUFFIX} +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + libgmp-dev +Provides: + fp-units-math +Breaks: + fp-units-math (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-units-math (<= 2.4.0-3), + fp-units-misc (<= 2.2.4-4), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - math units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal math interfacing units for: + * gmp (the GNU Multiple Precision arithmetic library); + * numlib (numerical computing); + * proj4 (cartographic projections); + * symbolic (symbolic computing). + +Package: fp-units-misc${PACKAGESUFFIX} +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-misc +Breaks: + fp-units-misc (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-units-misc (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - miscellaneous units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains miscellaneous Free Pascal units: fppkg (the FPC + packaging system), PasZLib (a Pascal-only zlib implementation), and Utmp. + +Package: fp-units-multimedia${PACKAGESUFFIX} +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + a52dec-dev, + libdts-dev, + libmad0-dev, + libmodplug-dev, + libogg-dev, + libsdl-mixer1.2-dev, + libvorbis-dev, + libvlc-dev +Provides: + fp-units-multimedia +Breaks: + fp-units-multimedia (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-units-gfx (<= 2.2.4-3), + fp-units-multimedia (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - multimedia units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains Free Pascal multimedia units: a52, dts, mad, modplug, + oggvorbis, openal, and vlc. + +Package: fp-units-i386${PACKAGESUFFIX} +Architecture: i386 +Multi-Arch: same +Depends: + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Provides: + fp-units-i386 +Breaks: + fp-units-i386 (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Replaces: + fp-units-i386 (<= 2.4.0-3), + fpc (<= ${UPSTREAM_VERSION}-0), +Description: Free Pascal - Kylix compatibility units + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This package contains the deprecated Free Pascal libc unit for the i386 + architecture (used for compatibility with Borland's Kylix). + +Package: fpc +Architecture: all +Depends: + fpc${PACKAGESUFFIX} (= ${binary:Version}), + fp-docs${PACKAGESUFFIX}, + fp-utils${PACKAGESUFFIX}, + ${misc:Depends} +Description: Free Pascal - SDK suite dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + Extensions have been added to the language, such as function overloading, + creation and linking of shared libraries, and Delphi language extensions + including classes, exceptions, ANSI strings, and open arrays. + . + This dependency package always depends on the latest available version of + the metapackage pulling in all the FPC packages provided for this + architecture. Experienced users may instead prefer to install the particular + packages they require by hand. + +Package: fpc-source +Architecture: all +Multi-Arch: foreign +Depends: + fpc-source${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - SDK source code dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal's own source code. It is meant to be used by + the Lazarus IDE. + +Package: fp-compiler +Architecture: any +Multi-Arch: same +Depends: + fp-compiler${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - compiler dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + Extensions have been added to the language, such as function overloading, + creation and linking of shared libraries, and Delphi language extensions + including classes, exceptions, ANSI strings, and open arrays. + . + This dependency package always depends on the latest available version of + the package containing the command line compiler. + +Package: fp-ide +Architecture: all +Multi-Arch: foreign +Depends: + fp-ide${PACKAGESUFFIX} (>= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - IDE dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + Extensions have been added to the language, such as function overloading, + creation and linking of shared libraries, and Delphi language extensions + including classes, exceptions, ANSI strings, and open arrays. + . + This dependency package always depends on the latest available version of + the package containing the Integrated Development Environment (IDE). The IDE + has an internal compiler. + +Package: fp-utils +Architecture: all +Multi-Arch: foreign +Depends: + fp-utils${PACKAGESUFFIX} (>= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - utilities dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing some handy utilities for use with the Free Pascal + Compiler: + * data2inc convert binary/text data to include files; + * fpcmake create Makefile from Makefile.fpc; + * h2pas convert .h files to Pascal units; + * plex/pyacc Pascal Lex and Yacc implementations; + * ppdep create a dependency file for use with Makefiles; + * ppudump dump the information stored in a .ppu (unit) file; + * ppufiles show needed files for units; + * ppumove place multiple units in a shared library; + * ptop beautify source. + +Package: fp-docs +Section: doc +Architecture: all +Multi-Arch: foreign +Depends: + fp-docs${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - documentation dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing documentation for the Free Pascal Compiler in HTML + format. + +Package: fp-units-rtl +Architecture: any +Multi-Arch: same +Depends: + fp-units-rtl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - runtime libraries dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing the RunTime Libraries for the Free Pascal Compiler. + +Package: fp-units-base +Architecture: any +Multi-Arch: same +Depends: + fp-units-base${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - base units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal units for common libraries (some of which + are also required by the Free Component Library): NCurses, X11 (Xlib, + Xutil), and ZLib. + +Package: fp-units-fcl +Architecture: any +Multi-Arch: same +Depends: + fp-units-fcl${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - Free Component Library dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing the Free Component Library for the Free Pascal Compiler. + +Package: fp-units-fv +Architecture: any +Multi-Arch: same +Depends: + fp-units-fv${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - Free Vision units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing the Free Vision units for the Free Pascal Compiler + (which provide a framework for developing text user interfaces). + +Package: fp-units-gtk2 +Architecture: any +Multi-Arch: same +Depends: + fp-units-gtk2${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - GTK+ 2.x units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal units and examples to create + programs with GTK+ 2.x. + +Package: fp-units-db +Architecture: any +Multi-Arch: same +Depends: + fp-units-db${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - database-library units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal units with bindings for GDBM, Interbase, + MySQL, PostgreSQL, ODBC, Oracle, and SQLite. + +Package: fp-units-gfx +Architecture: any +Multi-Arch: same +Depends: + fp-units-gfx${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - graphics-library units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal units with bindings for cairo, forms, ggi, + graph, libgd, libpng, opengl, and svgalib. + . + SVGALib is no longer packaged by Debian and should be installed manually by + users who want to link against it. + +Package: fp-units-net +Architecture: any +Multi-Arch: same +Depends: + fp-units-net${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - networking units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal units for creating network tools: D-Bus, + httpd-1.3, httpd-2.0, httpd-2.2, ldap, libasync, libcurl, netdb, openssl, + and pcap. + +Package: fp-units-math +Architecture: any +Multi-Arch: same +Depends: + fp-units-math${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - math units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal math interfacing units for: + * gmp (the GNU Multiple Precision arithmetic library); + * numlib (numerical computing); + * proj4 (cartographic projections); + * symbolic (symbolic computing). + +Package: fp-units-misc +Architecture: any +Multi-Arch: same +Depends: + fp-units-misc${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - miscellaneous units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing miscellaneous Free Pascal units: fppkg (the FPC + packaging system), PasZLib (a Pascal-only zlib implementation), and Utmp. + +Package: fp-units-multimedia +Architecture: any +Multi-Arch: same +Depends: + fp-units-multimedia${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - multimedia units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing Free Pascal multimedia units: a52, dts, mad, modplug, + oggvorbis, openal, and vlc. + +Package: fp-units-i386 +Architecture: i386 +Depends: + fp-units-i386${PACKAGESUFFIX} (= ${binary:Version}), + ${misc:Depends} +Description: Free Pascal - Kylix compatibility units dependency package + The Free Pascal Compiler is an Object Pascal compiler supporting both Delphi + and Turbo Pascal 7.0 dialects, as well as Mac Pascal dialects. It provides a + completely portable RunTime Library (RTL) available on many platforms and + compatible with Turbo Pascal, along with a platform-independent class-based + Free Component Library (FCL) adding many Delphi extensions and interfacing + with many popular open source libraries. + . + This dependency package always depends on the latest available version of + the package containing the deprecated Free Pascal libc unit for the i386 + architecture (used for compatibility with Borland's Kylix). diff --git a/copyright b/copyright new file mode 100644 index 00000000..7485b72b --- /dev/null +++ b/copyright @@ -0,0 +1,2063 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: lazarus +Source: + http://freepascal.org/ + . + The upstream source has been repacked to remove non-distributable files: + fpcsrc/rtl/netwlibc/pre/libcpre.gcc.o and + fpcsrc/packages/fcl-js/src/jsminifier.pp. Because repacking needed to be done + anyways, also other precompiled files and generated Makefiles were removed, in + order to save considerable amounts of disk space. The Makefiles can be + recreated by running the make-files target in debian/rules, i.e.: $ + debian/rules make-files +Comment: + The original description of upstream's view on the licenses can be found in + install/doc/readme.txt in the section called license. The text from there is + given below. Mind that some items that are discussed are stripped from + the Debian source tar ball. + . + . + The compiler and most utilities and executables distributed in this package + fall under the GPL, for more information read the file COPYING.v2. + . + Some specific utilities and programs come under the license described in + COPYING.v3, COPYING.DJ, COPYING.EMX, COPYING.RSX and licensez.ip. + . + FPC for JVM comes with some third party tools which are convered by + the following licenses: + - jasmin.jar comes under the license described in jasminli.txt + - bcel-6.0-SNAPSHOT.jar comes under the Apache 2.0 license, described by + apache2.txt + . + Some of the licenses of the third party tools require to make the source + available. If you cannot find the sources or information where to find + them for a certain tool under such a license included into the FPC + distribution, please contact us through the contact details given + at http://www.freepascal.org/moreinfo.var and we will provide you + the sources or information where to find them. + . + The documentation, unless otherwise noted, is distributed as free + text, and is distributed under the GNU Library General Public + License as found in file COPYING. + . + The runtime library, package libraries, free component library, and + other libraries which are used to create executables by the compiler + come under a modified GNU Library General Public license. Additional + information about the library license is found in COPYING.FPC. + . + License conditions for DPMI provider for GO32v2 version (CWSDPMI.EXE) + can be found in cwsdpmi.txt, sources and/or binary updates may be + downloaded from http://clio.rice.edu/cwsdpmi/. + . + The DOS version (go32v2) contains some binaries of DJGPP. You can obtain + the full DJGPP package at: http://www.delorie.com/djgpp/ + . + NOTE: OS/2 version of the installer uses the library UNZIP32.DLL from + Info-ZIP. Info-ZIP's software (Zip, UnZip and related utilities) + is free and can be obtained as source code or executables from + Internet/WWW sites, including http://www.info-zip.org. + +Files: * +Copyright: + 1990-2000 Albert Graef + 1993-1998 Stefan Zeiger + 1996 Berend de Boer + 1996 Simon Tatham + 1998-2002 Berczi Gabor + 1998-2002 Daniel Mantione + 1998-2002 Eberhard Mattes + 1998-2002 Michael van Canneyt + 1998-2002 Pavel + 1998-2007 Pierre Muller + 1998-2008 Carl Eric Codere + 1998-2014 Mazen NEIFER + 1998-2012 David Zhang + 1998-2012 Peter Vreman + 1998-2012 the Free Pascal team + 1998-2017 Florian Klaempfl + 1998-2014 Jonas Maebe + 1998-2014 the Free Pascal development team + 1999-2000 Aaron Holtzman + 1999-2002 Thomas Schatzl + 2000 International Business Machines Corp. + 2000-2002 Marco van de Voort + 2000-2002 Michel Lespinasse + 2000-2003 Underbit Technologies, Inc + 2001-2002 Pavel + 2002-2003 CodeFactory AB + 2002-2006 Red Hat Inc + 2002-2007 Daniel Mantione + 2003 Wiktor Sywula + 2003 Yuri Prokushev + 2004 Gildas Bazin + 2005-2012 Jeppe Johansen + 2006 Graeme Geldenhuys + 2006 Ivo Steinmann + 2007 contributors of the Free Pascal Compiler + 2008 Giulio Bernardi + 2008 the Free Pascal Compiler team + 2008-2008 Olivier Coursière + 2009 Sven Barth + 2009-2010 Dmitry Boyarintsev + 2011 Armin Diehl + 2011 Francesco Lombardi + 2011 Mattias Gaertner + 2012 Sergei Gorelkin + 2013 Yury Sidorov + 2014 Nikolay Nikolov +License: GPL-2+ + +Files: debian/* +Copyright: + 1999-2006 Peter Vreman + 1999 Mika Fischer + 2000-2001 Ulf Jaenicke-Roessler + 2001-2007 Carlos Laviola + 2003 Amaya Rodrigo Sastre + 2003-2004 Roland Stigge + 2006-2014 Abou Al Montacir + 2007 Varun Hiremath + 2007-2008 Torsten Werner + 2009-2017 Paul Gevers + 2012-2013 Peter Michael Green +License: GPL-2+ + +Files: + demo/freebsd/demo_kqueue.pas + demo/freebsd/demo_sendfile.pas + demo/freebsd/sysmousetest.pas + demo/graph/fpctris.pp + demo/graph/gameunit.pp + demo/graph/mandel.pp + demo/graph/samegame.pp + demo/lister/flist.pas + demo/lister/flist.pas + demo/lister/lister.pas + demo/lister/lister.pas + demo/modex/voxel.pp + demo/morphos/ahitest.pas + demo/morphos/asltest.pas + demo/morphos/getvolumes.pas + demo/morphos/muidemo.pas + demo/morphos/muidemo2.pas + demo/morphos/openlib.pas + demo/morphos/process.pas + demo/morphos/window.pas + demo/netware/check.pp + demo/os2/basicpm.pas + demo/os2/getctry.pas + demo/text/blackbox.pp + demo/text/eratos.pp + demo/text/hello.pp + demo/text/lines.pp + demo/text/magic.pp + demo/text/qsort.pp + demo/unix/cgibmp.pp + demo/unix/cgibmp.pp + demo/wince/testemu/w32rapi.pp + demo/wince/testemu/wcetemu.pp + demo/wince/testemu/wcetrun.pp + fpcdocs/Makefile.fpc + fpcdocs/htmwrite8859.pp + fpcdocs/makehtm.pp + fpcsrc/compiler/aarch64/cpuinfo.pas + fpcsrc/compiler/alpha/cpuinfo.pas + fpcsrc/compiler/arm/cpuinfo.pas + fpcsrc/compiler/avr/cpuinfo.pas + fpcsrc/compiler/ccharset.pas + fpcsrc/compiler/compinnr.inc + fpcsrc/compiler/generic/cpuinfo.pas + fpcsrc/compiler/jvm/cpuinfo.pas + fpcsrc/compiler/m68k/cpuinfo.pas + fpcsrc/compiler/mips/cpuinfo.pas + fpcsrc/compiler/powerpc/cpuinfo.pas + fpcsrc/compiler/powerpc64/cpuinfo.pas + fpcsrc/compiler/utils/dummyas.pp + fpcsrc/compiler/utils/fixlog.pp + fpcsrc/compiler/utils/fixnasm.pp + fpcsrc/compiler/utils/mk68kreg.pp + fpcsrc/compiler/utils/mka64ins.pp + fpcsrc/compiler/utils/mka64reg.pp + fpcsrc/compiler/utils/mkarmins.pp + fpcsrc/compiler/utils/mkarmreg.pp + fpcsrc/compiler/utils/mkavrreg.pp + fpcsrc/compiler/utils/mkia64reg.pp + fpcsrc/compiler/utils/mkjvmreg.pp + fpcsrc/compiler/utils/mkmpsreg.pp + fpcsrc/compiler/utils/mkppcreg.pp + fpcsrc/compiler/utils/mkspreg.pp + fpcsrc/compiler/utils/mkx86ins.pp + fpcsrc/compiler/utils/mkx86reg.pp + fpcsrc/compiler/utils/msg2inc.pp + fpcsrc/compiler/utils/msgdif.pp + fpcsrc/compiler/vis/cpuinfo.pas + fpcsrc/ide/fp.pas + fpcsrc/ide/fpcalc.pas + fpcsrc/ide/fpcatch.pas + fpcsrc/ide/fpcodcmp.pas + fpcsrc/ide/fpcodtmp.pas + fpcsrc/ide/fpcompil.pas + fpcsrc/ide/fpconst.pas + fpcsrc/ide/fpdebug.pas + fpcsrc/ide/fpdesk.pas + fpcsrc/ide/fpdpansi.pas + fpcsrc/ide/fpevalw.pas + fpcsrc/ide/fphelp.pas + fpcsrc/ide/fpide.pas + fpcsrc/ide/fpini.pas + fpcsrc/ide/fpintf.pas + fpcsrc/ide/fpkeys.pas + fpcsrc/ide/fpmansi.inc + fpcsrc/ide/fpmcomp.inc + fpcsrc/ide/fpmdebug.inc + fpcsrc/ide/fpmedit.inc + fpcsrc/ide/fpmfile.inc + fpcsrc/ide/fpmhelp.inc + fpcsrc/ide/fpmingw.pas + fpcsrc/ide/fpmopts.inc + fpcsrc/ide/fpmrun.inc + fpcsrc/ide/fpmsrch.inc + fpcsrc/ide/fpmtools.inc + fpcsrc/ide/fpmwnd.inc + fpcsrc/ide/fpredir.pas + fpcsrc/ide/fpregs.pas + fpcsrc/ide/fpswitch.pas + fpcsrc/ide/fpsymbol.pas + fpcsrc/ide/fptemplt.pas + fpcsrc/ide/fptools.pas + fpcsrc/ide/fpusrscr.pas + fpcsrc/ide/fputils.pas + fpcsrc/ide/fpvars.pas + fpcsrc/ide/fpviews.pas + fpcsrc/ide/gplprog.pt + fpcsrc/ide/gplunit.pt + fpcsrc/ide/wansi.pas + fpcsrc/ide/wcedit.pas + fpcsrc/ide/wchmhwrap.pas + fpcsrc/ide/wconsole.pas + fpcsrc/ide/weditor.pas + fpcsrc/ide/whelp.pas + fpcsrc/ide/whlpview.pas + fpcsrc/ide/whtml.pas + fpcsrc/ide/whtmlhlp.pas + fpcsrc/ide/whtmlscn.pas + fpcsrc/ide/winclip.pas + fpcsrc/ide/windebug.pas + fpcsrc/ide/wini.pas + fpcsrc/ide/wnghelp.pas + fpcsrc/ide/woahelp.pas + fpcsrc/ide/wos2help.pas + fpcsrc/ide/wresourc.pas + fpcsrc/ide/wtphwrit.pas + fpcsrc/ide/wutils.pas + fpcsrc/ide/wviews.pas + fpcsrc/ide/wvphelp.pas + fpcsrc/ide/wwinhelp.pas + fpcsrc/installer/install.pas + fpcsrc/installer/insthelp.pas + fpcsrc/installer/scroll.pas + fpcsrc/installer/writeidx.pas + fpcsrc/packages/* + fpcsrc/rtl/* + fpcsrc/tests/test/packages/bzip2/tbzip2streamtest.pp + fpcsrc/tests/test/packages/hash/tmdtest.pp + fpcsrc/tests/test/units/dos/tfexpand.pp + fpcsrc/tests/test/units/dos/tfsearch.pp + fpcsrc/tests/test/units/sysutils/tfexpand2.pp + fpcsrc/tests/tstunits/popuperr.pp + fpcsrc/tests/tstunits/win32err.pp + fpcsrc/tests/utils/bench.pp + fpcsrc/tests/utils/dbconfig.pp + fpcsrc/tests/utils/dbdigest.pp + fpcsrc/tests/utils/digest.pp + fpcsrc/tests/utils/dotest.pp + fpcsrc/tests/utils/fpts2junit.pp + fpcsrc/tests/utils/libtar.pas + fpcsrc/tests/utils/prepup.pp + fpcsrc/tests/utils/redir.pp + fpcsrc/tests/utils/testfail.pp + fpcsrc/tests/utils/teststr.pp + fpcsrc/tests/utils/tresults.pp + fpcsrc/tests/webtbs/tw19610.pp + fpcsrc/utils/bin2obj.pp + fpcsrc/utils/creumap.pp + fpcsrc/utils/data2inc.pp + fpcsrc/utils/debugsvr/console/debugserver.pp + fpcsrc/utils/debugsvr/dbugintf.pp + fpcsrc/utils/debugsvr/debugserverintf.pp + fpcsrc/utils/debugsvr/gtk/bitmapdata.pp + fpcsrc/utils/debugsvr/gtk/debugserver.pp + fpcsrc/utils/debugsvr/gtk/frmabout.pp + fpcsrc/utils/debugsvr/gtk/frmmain.pp + fpcsrc/utils/debugsvr/msgintf.pp + fpcsrc/utils/debugsvr/speeddebug.pp + fpcsrc/utils/debugsvr/testdebug.pp + fpcsrc/utils/fpcm/fpcmake.pp + fpcsrc/utils/fpcm/fpcmdic.pp + fpcsrc/utils/fpcm/fpcmmain.pp + fpcsrc/utils/fpcm/fpcmpkg.pp + fpcsrc/utils/fpcm/fpcmwr.pp + fpcsrc/utils/fpcmkcfg/fpcmkcfg.pp + fpcsrc/utils/fpdoc/sh_pas.pp + fpcsrc/utils/fpmc/fpmc.pp + fpcsrc/utils/fpmc/frmabout.pp + fpcsrc/utils/fpmc/msgcomp.pp + fpcsrc/utils/fpmc/readmsg.pp + fpcsrc/utils/fppkg/examples/rep2xml.lpr + fpcsrc/utils/fppkg/examples/testrep.pp + fpcsrc/utils/grab_vcsa.pp + fpcsrc/utils/mkinsadd.pp + fpcsrc/utils/pas2js/dist/rtl.js + fpcsrc/utils/pas2js/pas2js.pp + fpcsrc/utils/pas2ut/pas2ut.pp + fpcsrc/utils/ppdep.pp + fpcsrc/utils/ptop.pp + fpcsrc/utils/ptopu.pp + fpcsrc/utils/rstconv.pp + fpcsrc/utils/usubst.pp + install/cross/aswrapper.pas +Copyright: + 1986-1987 William S. Hawes + 1987 Digital Equipment Corporation, Maynard, Massachusetts + 1987-1998 The Open Group + 1988 Jef Poskanzer + 1989-1991 Free Software Foundation, Inc + 1990 Regents of the University of Michigan + 1991 J. John Sprenger + 1991-1989 Carnegie Mellon University + 1991-1998 Thomas G. Lane + 1991-2000 Silicon Graphics, Inc + 1991-2005 Oracle Corporation + 1992 Andreas Neumann (NEUDELSoft) + 1992 Borland International + 1992 T.Schmid + 1992-1993 NeXT Computer, Inc + 1993-1997 Stefan Stuntz + 1993-2017 Free Pascal team + 1993-2014 Florian Klaempfl + 1994 BetaSoft + 1994-1997 Martin Blom + 1994-2005 Symbian Software Ltd + 1995 Andreas Tetzl + 1995 Jon Tombs + 1995 XFree86 Inc + 1995-1998 3Com Corporation or its subsidiaries ("3Com") + 1995-1998 Jean-loup Gailly + 1995-1998 Mark Adler + 1996-1998 Alexander Kneer + 1996-1998 Jacques Nomssi Nzali + 1996-1998 Tobias Abt + 1996-1998 phase5 digital products + 1996-2000 Berczi Gabor + 1996-2000 Leon de Boer + 1996-2000 Richard Koerber + 1996-2005 Peter Vreman + 1996-2009 Marco van de Voort + 1996-2017 Michael Van Canneyt + 1997 Balazs Scheidler + 1997-1998 Gertjan Schouten + 1997-2000 Daniel Mantione + 1997-2000 TEK neoscientists + 1997-2000 University of Cambridge + 1997-2008 the Daniel Mantione + 1997-2014 the Free Pascal development team + 1998 Christian Nentwich + 1998 Gilles Vollant + 1998 Jacques Nomssi Nzali + 1998-2002 Dirk Stöcker + 1998-2003 Nils Sjöholm + 1998-2003 The OpenLDAP Foundation, Redwood City, California, USA + 1998-2009 Pierre Muller + 1999 Sebastian Guenther + 1999-2000 Daniel Mantione + 1999-2000 Eberhard Mattes + 1999-2004 Karoly Balogh (aka Charlie/INQ) + 1999-2000 Pavel Ozerski + 1999-2000 Ramon Bosque + 1999-2000 Thomas Schatzl + 1999-2000 Tomas Hajny + 1999-2002 Carl-Eric Codere + 1999-2004 Andrey V. Sorokin, St.Petersburg, Russia + 1999-2007 Several contributors + 1999-2008 Pavel Ozerski + 1999-2009 David Zhang + 1999-2009 ImageMagick Studio LLC, a non-profit organization + 1999-2012 Jonas Maebe + 1999-2014 Joost van der Sluis + 1999-2014 Maciej Izak + 2000 Casey Duncan + 2000 Compaq Computer Corporation + 2000 Jacques Nomssi Nzali + 2000 Satanic Dreams Software + 2000-2001 madded2 + 2000-2004 Free Pascal core team + 2000-2006 Stefan Heymann + 2001 Keith Packard + 2001 Tramontana Co + 2001-2006 Stefan Heymann + 2001-2011 Armin Diehl + 2001-2017 Nikolay Nikolov (nickysn@users.sourceforge.net) + 2002 Daniel Mantione + 2002 Grzegorz Kraszewski + 2002 Hewlett Packard, Inc + 2002-2003 The MorphOS Development Team + 2002-2004 Yuri Prokushev + 2002-2012 Sergei Gorelkin + 2002-2015 Tomas Hajny + 2003-2004 Olle Raab + 2004 Jazarsoft + 2004-2005 Karoly Balogh for Genesi S.a.r.l. + 2004-2015 Karoly Balogh + 2005 Daniel Mantione + 2005 Soren Ager + 2005-2006 Ales Katona + 2005-2006 Thomas Schatzl + 2005-2007 Hexis BV + 2005-2008 NVIDIA Corporation + 2005-2010 Giulio Bernardi + 2006-2011 Francesco Lombardi + 2006-2011 Ivo Steinmann + 2007 contributors of the Free Pascal Compiler + 2008 Andreas Jakobsche + 2009 Jan Mercl + 2009-2010 Dmitry Boyarintsev + 2009-2012 Paul Ishenin + 2009-2012 Sven Barth + 2010-2016 Graeme Geldenhuys + 2010 Jasper Lievisse Adriaanse + 2010 Olivier Coursière + 2011 Marcus Sackrow + 2012 Reinier Olislagers + 2012-2015 Inoussa OUEDRAOGO + 2013 Denis Volodarsky + 2015 Gilson Nunes + 2015 Joao Morais + 2015 Silvio Clecio + 2015 Ondrej Pokorny + 2015 Yury Sidorov + 2017 Mattias Gaertner +License: LGPL-2.1+ with staticLink exception + +Files: fpcsrc/packages/libmicrohttpd/examples* +Copyright: + 2007-2015 Christian Grothoff +License: LGPL-2.1+ + +Files: + fpcsrc/packages/httpd13/src/* + fpcsrc/packages/httpd20/src/* + fpcsrc/packages/httpd22/src/* + fpcsrc/packages/httpd24/src/* + fpcsrc/packages/zorba/src/* +Copyright: + Apache Software Foundation (ASF) + 2006-2008 The FLWOR Foundation + 2009 Ivo Steinmann +License: Apache-2 + +Files: + fpcsrc/packages/openssl/src/openssl.pas + fpcsrc/tests/test/cg/obj/stdint.h +Copyright: + 1999-2005 Lukas Gebauer + 2005 Paul Hsieh +License: BSD-3-clause + +Files: fpcsrc/rtl/solaris/x86_64/start.inc +Copyright: + 2007 Sun Microsystems, Inc + 2009 Pierre Muller +License: CDDL-1 and LGPL-2.1+ with staticLink exception + +Files: + fpcsrc/packages/libndsfpc/src/dswifi/inc/dswifi7.inc + fpcsrc/packages/libndsfpc/src/dswifi/inc/dswifi9.inc + fpcsrc/packages/libndsfpc/src/dswifi/inc/netdb.inc + fpcsrc/packages/libndsfpc/src/dswifi/inc/netinet/in.inc + fpcsrc/packages/libndsfpc/src/dswifi/inc/sgIP_errno.inc + fpcsrc/packages/libndsfpc/src/dswifi/inc/sys/socket.inc + fpcsrc/packages/ncurses/src/eti.inc + fpcsrc/packages/proj4/src/proj.pas + fpcsrc/packages/x11/src/xfixes.pp + fpcsrc/packages/x11/src/xfixeswire.inc + fpcsrc/packages/x11/src/xge.pp + fpcsrc/packages/x11/src/xi2.pp + fpcsrc/packages/x11/src/xinput2.pp + fpcsrc/packages/xforms/src/cursorfont.inc +Copyright: + 1987 X Consortium + 1998 Free Software Foundation, Inc. + 2001-2008 Frank Warmerdam + 2005-2006 Stephen Stair + 2006 Francesco Lombardi + 2006 Oracle and/or its affiliates + 2007-2008 Peter Hutterer + 2009 Ivo Steinmann + 2009-2011 Red Hat, Inc. +License: expat + +Files: fpcsrc/packages/x11/src/xinput.pp +Copyright: + 1989 Hewlett-Packard Company, Palo Alto, California. + 1989-1998 The Open Group +License: expat and mit-HP + +License: mit-HP + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation, and that the name of Hewlett-Packard not be + used in advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + . + HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. + +Files: + fpcsrc/packages/opengles/src/gles20.pas +Copyright: + 2007-2009 The Khronos Group Inc. +License: expat and expat-like + +Files: + fpcsrc/rtl/go32v2/emu387.pp + fpcsrc/rtl/go32v2/exit16.asm + fpcsrc/rtl/go32v2/fpu.as + fpcsrc/rtl/go32v2/sbrk16.asm + fpcsrc/rtl/go32v2/v2prt0.as + fpcsrc/utils/dxegen/coff.pp + fpcsrc/utils/dxegen/dxegen.pp +Copyright: + 1994-1995 DJ Delorie + 1995 Charles Sandmann + 2001 Marco van de Voort +License: GPL-djd + +Files: fpcsrc/utils/mksymbian/*.pas +Copyright: 2006-2007 Felipe Monteiro de Carvalho +License: GPL-2-fmc + +Files: + fpcsrc/utils/javapp/src/fpc/tools/javapp/AttrData.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/ClassData.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/Constants.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/CPX2.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/CPX.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/FieldData.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/InnerClassData.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/JavapEnvironment.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/JavapPrinter.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/LineNumData.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/LocVarData.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/Main.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/MethodData.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/RuntimeConstants.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/StackMapData.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/StackMapTableData.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/Tables.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/TrapData.java + fpcsrc/utils/javapp/src/fpc/tools/javapp/TypeSignature.java +Copyright: + 2002-2006 Oracle and/or its affiliates + 2011 Jonas Maebe +License: GPL-2-oracle + +Files: + fpcsrc/packages/libgbafpc/src/maxmod/inc/maxmod.inc + fpcsrc/packages/libgbafpc/src/maxmod/inc/mm_types.inc + fpcsrc/packages/libndsfpc/src/maxmod/inc/mm_mas.inc + fpcsrc/packages/libndsfpc/src/maxmod/inc/maxmod.inc + fpcsrc/packages/libndsfpc/src/maxmod/inc/mm_types.inc + fpcsrc/packages/libndsfpc/src/maxmod/inc/mm_msl.inc + fpcsrc/packages/libndsfpc/src/maxmod/inc/maxmod9.inc + fpcsrc/packages/libndsfpc/src/maxmod/inc/maxmod7.inc +Copyright: 2008 Mukunda Johnson +License: ISC + +Files: + fpcdocs/fcl.tex + fpcdocs/fpc-hevea.tex + fpcdocs/fpc-html.tex + fpcdocs/fpdoc.tex + fpcdocs/ide.tex + fpcdocs/internal.tex + fpcdocs/msmouse.tex + fpcdocs/onechap.tex + fpcdocs/prog.tex + fpcdocs/ref.tex + fpcdocs/rtl.tex + fpcdocs/units.tex + fpcdocs/user.tex + fpcsrc/packages/chm/src/* + fpcsrc/packages/fcl-db/src/sqldb/sqlite/sqlite3backup.pas + fpcsrc/packages/fcl-db/src/sqlite/customsqliteds.pas + fpcsrc/packages/fcl-db/src/sqlite/sqlite3ds.pas + fpcsrc/packages/fcl-db/src/sqlite/sqliteds.pas + fpcsrc/packages/fcl-fpcunit/src/consoletestrunner.pas + fpcsrc/packages/fcl-image/src/fpreadjpeg.pas + fpcsrc/packages/fcl-image/src/fpreadpcx.pas + fpcsrc/packages/fcl-image/src/fpwritejpeg.pas + fpcsrc/packages/fcl-image/src/fpwritepcx.pas + fpcsrc/packages/fuse/src/fuse.pas + fpcsrc/packages/graph/src/inc/graph.tex + fpcsrc/packages/gtk2/src/atk/atk.inc + fpcsrc/packages/gtk2/src/atk/atk.pas + fpcsrc/packages/gtk2/src/glib/glib2.pas + fpcsrc/packages/gtk2/src/glib/gparamspecs.inc + fpcsrc/packages/gtk2/src/glib/gtypemodule.inc + fpcsrc/packages/gtk2/src/gtkext/gtkstatusiconh.inc + fpcsrc/packages/gtk2/src/gtk+/gdk/gdk2.pas + fpcsrc/packages/gtk2/src/gtk+/gdk/gdki18n.inc + fpcsrc/packages/gtk2/src/gtk+/gdk/gdkprivate.inc + fpcsrc/packages/gtk2/src/gtk+/gdk-pixbuf/gdk2pixbuf.pas + fpcsrc/packages/gtk2/src/gtk+/gtk/gtk2.pas + fpcsrc/packages/gtk2/src/gtk+/gtk/gtkhsv.inc + fpcsrc/packages/gtk2/src/gtk+/gtk/gtkimmodule.inc + fpcsrc/packages/gtk2/src/gtk+/gtk/gtkkeyhash.inc + fpcsrc/packages/gtk2/src/gtk+/gtk/gtktextdisplay.inc + fpcsrc/packages/gtk2/src/gtk+/gtk/gtktextutil.inc + fpcsrc/packages/gtk2/src/gtk+/gtk/gtkthemes.inc + fpcsrc/packages/gtk2/src/gtk+/gtk/gtktreedatalist.inc + fpcsrc/packages/gtk2/src/gtk+/gtk/gtkwindow-decorate.inc + fpcsrc/packages/gtk2/src/gtkhtml/gtkhtml.pas + fpcsrc/packages/gtk2/src/libglade/libglade2.pas + fpcsrc/packages/gtk2/src/pangocairo/pangocairo.pas + fpcsrc/packages/gtk2/src/pango/pango.pas + fpcsrc/packages/gtk2/src/pango/pangoutils.pas + fpcsrc/packages/libgbafpc/src/gba/fade.inc + fpcsrc/packages/libgbafpc/src/gba/gba_affine.inc + fpcsrc/packages/libgbafpc/src/gba/gba_base.inc + fpcsrc/packages/libgbafpc/src/gba/gba_compression.inc + fpcsrc/packages/libgbafpc/src/gba/gba_console.inc + fpcsrc/packages/libgbafpc/src/gba/gba_dma.inc + fpcsrc/packages/libgbafpc/src/gba/gba_input.inc + fpcsrc/packages/libgbafpc/src/gba/gba_interrupt.inc + fpcsrc/packages/libgbafpc/src/gba/gba_multiboot.inc + fpcsrc/packages/libgbafpc/src/gba/gba_sio.inc + fpcsrc/packages/libgbafpc/src/gba/gba_sound.inc + fpcsrc/packages/libgbafpc/src/gba/gba_sprites.inc + fpcsrc/packages/libgbafpc/src/gba/gba_systemcalls.inc + fpcsrc/packages/libgbafpc/src/gba/gba_timers.inc + fpcsrc/packages/libgbafpc/src/gba/gba_types.inc + fpcsrc/packages/libgbafpc/src/gba/gba_video.inc + fpcsrc/packages/libgbafpc/src/gba/mappy.inc + fpcsrc/packages/libgbafpc/src/gba/mbv2.inc + fpcsrc/packages/libgbafpc/src/gba/pcx.inc + fpcsrc/packages/librsvg/src/rsvg.pas + fpcsrc/packages/openal/src/alh.inc + fpcsrc/packages/os2units/src/clkdll.pas + fpcsrc/packages/os2units/src/ftpapi.pas + fpcsrc/packages/os2units/src/hwvideo.pas + fpcsrc/packages/os2units/src/mciapi.pas + fpcsrc/packages/os2units/src/mcidrv.pas + fpcsrc/packages/os2units/src/mci.pas + fpcsrc/packages/os2units/src/mmbase.pas + fpcsrc/packages/os2units/src/mmio.pas + fpcsrc/packages/os2units/src/som.pas + fpcsrc/packages/os2units/src/sw.pas + fpcsrc/packages/winunits-base/src/typelib.pas + fpcsrc/rtl/inc/flt_conv.inc + fpcsrc/rtl/inc/flt_core.inc + fpcsrc/rtl/sparc/setjumph.inc + fpcsrc/rtl/wince/wininc/base.inc + fpcsrc/rtl/wince/wininc/defines.inc + fpcsrc/rtl/wince/wininc/errors.inc + fpcsrc/rtl/wince/wininc/messages.inc + fpcsrc/rtl/wince/wininc/struct.inc + fpcsrc/rtl/win/wininc/ascdef.inc + fpcsrc/rtl/win/wininc/ascfun.inc + fpcsrc/rtl/win/wininc/base.inc + fpcsrc/rtl/win/wininc/defines.inc + fpcsrc/rtl/win/wininc/errors.inc + fpcsrc/rtl/win/wininc/func.inc + fpcsrc/rtl/win/wininc/messages.inc + fpcsrc/rtl/win/wininc/struct.inc + fpcsrc/rtl/win/wininc/unidef.inc + fpcsrc/rtl/win/wininc/unifun.inc + install/binw32/windres.h +Copyright: + 1990-1996 International Business Machines Corporation + 1991-1999 Free Software Foundation, Inc + 1992-1994 The Regents of the University of California + 1994-2001 Sun Microsystems, Inc + 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + 1997 Antony T Curtis + 1997 Michael Van Canneyt + 1997-2002 the Free Pascal development team + 1997-2001 Tim Janik + 1997-2004 Red Hat, Inc + 1998-2002 James Henstridge + 1998-2014 Florian Klaempfl + 1999 Red Hat Software + 1999-2000 authors + 2000 Anders Carlsson + 2000 CodeFactory AB + 2000 Eazel, Inc + 2000 Jonas Borgström + 2000 Jonathan Blandford + 2000-2002 Jonas Maebe + 2001-2007 Miklos Szeredi + 2002 Andry Svirgunov + 2002 Matthew T. Russotto + 2002 Mark Eckstein + 2002 Valery Gaynullin + 2002 Red Hat Inc + 2002-2005 Yuri Prokushev + 2003-2005 Mattias Gaertner + 2003 Sun Microsystems, Inc + 2003-2006 Dave Murphy + 2004-2007 Luiz Américo Pereira Câmara + 2005 Olaf Leidinger + 2005-2010 Andrew Haines + 2006 Francesco Lombardi + 2006 Vincent Snijders + 2007 Laurent Jacques + 2008 Danny Milosavljevic + 2009 Ivo Steinmann + 2009 Michael A. Green + 2012 Ludo Brands + 2013 Max Nazhalov +License: LGPL-2+ + +Files: fpcsrc/packages/chm/src/paslzxcomp.pas +Copyright: + 2002 Matthew T. Russotto + 2005 Andrew Haines +License: LGPL-2.1 + +Files: + fpcsrc/packages/gtk2/src/gtkglext/g*kglext.pas + fpcsrc/packages/libgbafpc/src/gba/gba_helper.inc + fpcsrc/packages/libgbafpc/src/gba/helper.inc + fpcsrc/packages/matroska/src/matroska.pas +Copyright: + 1998 Glenn Fielder (gaffer@gaffer.org) + 1998 Intel Corporation + 1999 Jonathan Matthew (jmatthew@uq.net.au) + 2002-2003 Steve Lhomme + 2002-2004 Naofumi Yasufuku + 2005 Michalis Kamburelis + 2006 Francesco Lombardi + 2006 Ivo Steinmann +License: LGPL-2.1+ + +Files: fpcsrc/packages/hash/src/md5.pp +Copyright: 1991-1992 RSA Data Security, Inc. +License: RSA + +Files: + fpcsrc/packages/sdl/src/jedi-sdl.inc + fpcsrc/packages/sdl/src/logger.pas + fpcsrc/packages/sdl/src/sdl.pas + fpcsrc/packages/sdl/src/sdl_image.pas + fpcsrc/packages/sdl/src/sdl_mixer.pas + fpcsrc/packages/sdl/src/sdl_net.pas + fpcsrc/packages/sdl/src/sdl_ttf.pas + fpcsrc/packages/sdl/src/sdlutils.pas + fpcsrc/packages/sdl/src/smpeg.pas +Copyright: + 1997-2004 Sam Lantinga + 2000-2004 Dominqiue Louis + 2000-2007 Prof. Abimbola Olowofoyeku + 2000-2001 Tom Jones +License: MPL-1.1 + +Files: fpcsrc/packages/winunits-jedi/src/* +Copyright: + 1983-2003 Microsoft Corporation + 1998 Luk Vermeulen + 1999-2005 Marcel van Brakel + 1995-1999 Citrix Systems Inc. + 1996 the University of Southern California + 2000 Rudy Velthuis + 2001-2005 Oliver Schneider (assarbad) + 1999-2001 Wayne Sherman + 2004-2005 Robert Marquardt +Comment: The files don't mention which version of the LGPL they mean. Most + files and copyright statements are from a time before LGPL-3 was written. The + text mentions "Lesser General Public License" and link to the lesser license + on the GNU website, which is now (2015.09.07) LGPL-3. Therefore I conclude it + is LGPL-2.1+. +License: MPL-1.1 or LGPL-2.1+ + +Files: fpcsrc/packages/winunits-jedi/src/jwalpmapi.pas +Copyright: + 1995-2001 Microsoft Corporation + 1999-2001 Marcel van Brakel +License: MPL-1.1 or LGPL-2.1+, and SC + +Files: + fpcsrc/packages/libgbafpc/src/gba/boyscout.inc + fpcsrc/packages/libndsfpc/src/fat/fat.inc + fpcsrc/packages/libndsfpc/src/fat/gbfs.inc + fpcsrc/packages/libndsfpc/src/nds/arm9/keyboard.inc + fpcsrc/packages/libndsfpc/src/nds/ipc.inc + fpcsrc/packages/libndsfpc/src/nds/nds.inc + fpcsrc/packages/openal/examples/wavopenal.pas + fpcsrc/packages/paszlib/src/zbase.pas + fpcsrc/rtl/i386/fastmove.inc +Copyright: + 1995-1998 Jean-loup Gailly + 1995-1998 Mark Adler + 1998 Jacques Nomssi Nzali + 2001 Willem Kokke + 2002-2004 Damian Yerrick + 2004 John O'Harrow + 2005 Christer Andersson + 2005 Dave Murphy (WinterMute) + 2005 Jason Rogers (dovoto) + 2006 Francesco Lombardi + 2010 Dmitry Boyarintsev +License: Zlib + +Files: + fpcsrc/packages/x11/src/deckeysym.pp + fpcsrc/packages/x11/src/hpkeysym.pp +Copyright: 1988-1991 by Digital Equipment Corporation, Maynard, Massachusetts + 1988-1998 The Open Group +License: DEC and Open + +Files: + fpcsrc/packages/x11/src/sunkeysym.pp +Copyright: 1991 Oracle and/or its affiliates + 1991-1998 The Open Group +License: Expat and Open + +Files: + fpcsrc/rtl/i386/math.inc + fpcsrc/rtl/x86_64/math.inc +Copyright: + 1999-2005 the Free Pascal development team + 2009-2013 Wolfgang Ehrhardt +License: Zlib and LGPL-2.1+ with staticLink exception + +Files: fpcsrc/rtl/inc/genmath.inc +Copyright: + Copyright Abandoned, 1987, Fred Fish + 1992 Odent Jean Philippe + 1997 Carl Eric Codere + 1993 Sun Microsystems, Inc. + 2013 Wolfgang Ehrhardt + 1999-2007 Several contributors +License: Zlib and LGPL-2.1+ with staticLink exception and abandoned and mention and sun + +Files: + fpcsrc/compiler/macho.pas + fpcsrc/packages/httpd20/src/apriconv/apr_iconv.inc + fpcsrc/packages/httpd22/src/apriconv/apr_iconv.inc + fpcsrc/packages/ptc/src/win32/directx/p_dinput.pp + fpcsrc/packages/pthreads/src/pthrhaiku.inc + fpcsrc/packages/pthreads/src/pthrbsd.inc + fpcsrc/packages/pthreads/src/pthrbeos.inc + fpcsrc/packages/univint/src/* + fpcsrc/rtl/darwin/errno.inc + fpcsrc/rtl/darwin/ppcgen/sig_ppc.inc + fpcsrc/rtl/darwin/signal.inc + fpcsrc/rtl/darwin/sysctlh.inc + fpcsrc/rtl/darwin/termios.inc + fpcsrc/rtl/darwin/x86/sig_x86.inc + fpcsrc/rtl/openbsd/sysctlh.inc +Copyright: Not applicable +License: public-domain + The header of these files suggests that they are under a non-DFSG license, + i.e. the Apple APSL V1.1 or V2 license or the BSD with advertizing + clause. However, the Debian Pascal team claims that these files are merely + interface files, only defining data types. There is no instruction code. It is + exactly equivalent to a C header file for any library that does not include + any function definition. + . + It is our understanding that this kind of interfacing file is not covered by + intellectual property as long as the interface itself is publicly available. + +Files: fpcsrc/packages/gtk2/examples/gtkglext/gears.pas +Copyright: Not applicable +License: public-domain-2 + This codepage information is based on what is documented at + 1. http://wiki.whatwg.org/wiki/Web_Encodings + 2. http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx + . + This file only uses bare facts and API information from the above pages + rather than descriptions or code, neither of which are copyrightable. + +License: abandoned + This previously copyrighted work has been placed into the + public domain by the author (Fred Fish) and may be freely used + for any purpose, private or commercial. I would appreciate + it, as a courtesy, if this notice is left in all copies and + derivative works. Thank you, and enjoy... + . + The author makes no warranty of any kind with respect to this + product and explicitly disclaims any implied warranties of + merchantability or fitness for any particular purpose. + +License: Apache-2 + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + . + http://www.apache.org/licenses/LICENSE-2.0 + . + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + . + On Debian systems, the complete text of the Apache License, + Version 2.0 can be found in '/usr/share/common-licenses/Apache-2.0'. + +License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + . + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + . + Redistributions in binary form must not misrepresent the orignal + source in the documentation and/or other materials provided + with the distribution. + . + The names of the authors not its contributors may be used to + endorse or promote products derived from this software without + specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + +License: CDDL-1 + The contents of this file are subject to the terms of the + Common Development and Distribution License (the "License"). + You may not use this file except in compliance with the License. + . + You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + or http://www.opensolaris.org/os/licensing. + See the License for the specific language governing permissions + and limitations under the License. + . + . + The content of the CDDL license: + . + COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) + Version 1.0 + . + 1. Definitions. + . + 1.1. “Contributor” means each individual or entity that creates or contributes + to the creation of Modifications. + . + 1.2. “Contributor Version” means the combination of the Original Software, + prior Modifications used by a Contributor (if any), and the Modifications made + by that particular Contributor. + . + 1.3. “Covered Software” means (a) the Original Software, or (b) Modifications, + or (c) the combination of files containing Original Software with files + containing Modifications, in each case including portions thereof. + . + 1.4. “Executable” means the Covered Software in any form other than Source + Code. + . + 1.5. “Initial Developer” means the individual or entity that first makes + Original Software available under this License. + . + 1.6. “Larger Work” means a work which combines Covered Software or portions + thereof with code not governed by the terms of this License. + . + 1.7. “License” means this document. + . + 1.8. “Licensable” means having the right to grant, to the maximum extent + possible, whether at the time of the initial grant or subsequently acquired, + any and all of the rights conveyed herein. + . + 1.9. “Modifications” means the Source Code and Executable form of any of the + following: + . + A. Any file that results from an addition to, deletion from or modification of + the contents of a file containing Original Software or previous Modifications; + . + B. Any new file that contains any part of the Original Software or previous + Modification; or + . + C. Any new file that is contributed or otherwise made available under the + terms of this License. + . + 1.10. “Original Software” means the Source Code and Executable form of + computer software code that is originally released under this License. + . + 1.11. “Patent Claims” means any patent claim(s), now owned or hereafter + acquired, including without limitation, method, process, and apparatus claims, + in any patent Licensable by grantor. + . + 1.12. “Source Code” means (a) the common form of computer software code in + which modifications are made and (b) associated documentation included in or + with such code. + . + 1.13. “You” (or “Your”) means an individual or a legal entity exercising + rights under, and complying with all of the terms of, this License. For legal + entities, “You” includes any entity which controls, is controlled by, or is + under common control with You. For purposes of this definition, “control” + means (a) the power, direct or indirect, to cause the direction or management + of such entity, whether by contract or otherwise, or (b) ownership of more + than fifty percent (50%) of the outstanding shares or beneficial ownership of + such entity. + . + 2. License Grants. + . + 2.1. The Initial Developer Grant. Conditioned upon Your compliance with + Section 3.1 below and subject to third party intellectual property claims, the + Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive + license: + . + (a) under intellectual property rights (other than patent or trademark) + Licensable by Initial Developer, to use, reproduce, modify, display, perform, + sublicense and distribute the Original Software (or portions thereof), with or + without Modifications, and/or as part of a Larger Work; and + . + (b) under Patent Claims infringed by the making, using or selling of Original + Software, to make, have made, use, practice, sell, and offer for sale, and/or + otherwise dispose of the Original Software (or portions thereof). + . + (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date + Initial Developer first distributes or otherwise makes the Original Software + available to a third party under the terms of this License. + . + (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) + for code that You delete from the Original Software, or (2) for infringements + caused by: (i) the modification of the Original Software, or (ii) the + combination of the Original Software with other software or devices. + . + 2.2. Contributor Grant. Conditioned upon Your compliance with Section 3.1 + below and subject to third party intellectual property claims, each + Contributor hereby grants You a world-wide, royalty-free, non-exclusive + license: + . + (a) under intellectual property rights (other than patent or trademark) + Licensable by Contributor to use, reproduce, modify, display, perform, + sublicense and distribute the Modifications created by such Contributor (or + portions thereof), either on an unmodified basis, with other Modifications, as + Covered Software and/or as part of a Larger Work; and + . + (b) under Patent Claims infringed by the making, using, or selling of + Modifications made by that Contributor either alone and/or in combination with + its Contributor Version (or portions of such combination), to make, use, sell, + offer for sale, have made, and/or otherwise dispose of: (1) Modifications made + by that Contributor (or portions thereof); and (2) the combination of + Modifications made by that Contributor with its Contributor Version (or + portions of such combination). + . + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the + date Contributor first distributes or otherwise makes the Modifications + available to a third party. + . + (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) + for any code that Contributor has deleted from the Contributor Version; (2) + for infringements caused by: (i) third party modifications of Contributor + Version, or (ii) the combination of Modifications made by that Contributor + with other software (except as part of the Contributor Version) or other + devices; or (3) under Patent Claims infringed by Covered Software in the + absence of Modifications made by that Contributor. + . + 3. Distribution Obligations. + . + 3.1. Availability of Source Code. Any Covered Software that You distribute or + otherwise make available in Executable form must also be made available in + Source Code form and that Source Code form must be distributed only under the + terms of this License. You must include a copy of this License with every copy + of the Source Code form of the Covered Software You distribute or otherwise + make available. You must inform recipients of any such Covered Software in + Executable form as to how they can obtain such Covered Software in Source Code + form in a reasonable manner on or through a medium customarily used for + software exchange. + . + 3.2. Modifications. The Modifications that You create or to which You + contribute are governed by the terms of this License. You represent that You + believe Your Modifications are Your original creation(s) and/or You have + sufficient rights to grant the rights conveyed by this License. + . + 3.3. Required Notices. You must include a notice in each of Your + Modifications that identifies You as the Contributor of the Modification. You + may not remove or alter any copyright, patent or trademark notices contained + within the Covered Software, or any notices of licensing or any descriptive + text giving attribution to any Contributor or the Initial Developer. + . + 3.4. Application of Additional Terms. You may not offer or impose any terms + on any Covered Software in Source Code form that alters or restricts the + applicable version of this License or the recipients’ rights hereunder. You + may choose to offer, and to charge a fee for, warranty, support, indemnity or + liability obligations to one or more recipients of Covered Software. However, + you may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity or liability obligation is offered by You alone, + and You hereby agree to indemnify the Initial Developer and every Contributor + for any liability incurred by the Initial Developer or such Contributor as a + result of warranty, support, indemnity or liability terms You offer. + . + 3.5. Distribution of Executable Versions. You may distribute the Executable + form of the Covered Software under the terms of this License or under the + terms of a license of Your choice, which may contain terms different from this + License, provided that You are in compliance with the terms of this License + and that the license for the Executable form does not attempt to limit or + alter the recipient’s rights in the Source Code form from the rights set forth + in this License. If You distribute the Covered Software in Executable form + under a different license, You must make it absolutely clear that any terms + which differ from this License are offered by You alone, not by the Initial + Developer or Contributor. You hereby agree to indemnify the Initial Developer + and every Contributor for any liability incurred by the Initial Developer or + such Contributor as a result of any such terms You offer. + . + 3.6. Larger Works. You may create a Larger Work by combining Covered Software + with other code not governed by the terms of this License and distribute the + Larger Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Software. + . + 4. Versions of the License. + . + 4.1. New Versions. Sun Microsystems, Inc. is the initial license steward and + may publish revised and/or new versions of this License from time to + time. Each version will be given a distinguishing version number. Except as + provided in Section 4.3, no one other than the license steward has the right + to modify this License. + . + 4.2. Effect of New Versions. You may always continue to use, distribute or + otherwise make the Covered Software available under the terms of the version + of the License under which You originally received the Covered Software. If + the Initial Developer includes a notice in the Original Software prohibiting + it from being distributed or otherwise made available under any subsequent + version of the License, You must distribute and make the Covered Software + available under the terms of the version of the License under which You + originally received the Covered Software. Otherwise, You may also choose to + use, distribute or otherwise make the Covered Software available under the + terms of any subsequent version of the License published by the license + steward. + . + 4.3. Modified Versions. When You are an Initial Developer and You want to + create a new license for Your Original Software, You may create and use a + modified version of this License if You: (a) rename the license and remove any + references to the name of the license steward (except to note that the license + differs from this License); and (b) otherwise make it clear that the license + contains terms which differ from this License. + . + 5. DISCLAIMER OF WARRANTY. + . + COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT + LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, + MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK + AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD + ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL + DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY + SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN + ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED + HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + . + 6. TERMINATION. + . + 6.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure such + breach within 30 days of becoming aware of the breach. Provisions which, by + their nature, must remain in effect beyond the termination of this License + shall survive. + . + 6.2. If You assert a patent infringement claim (excluding declaratory judgment + actions) against Initial Developer or a Contributor (the Initial Developer or + Contributor against whom You assert such claim is referred to as + “Participant”) alleging that the Participant Software (meaning the Contributor + Version where the Participant is a Contributor or the Original Software where + the Participant is the Initial Developer) directly or indirectly infringes any + patent, then any and all rights granted directly or indirectly to You by such + Participant, the Initial Developer (if the Initial Developer is not the + Participant) and all Contributors under Sections 2.1 and/or 2.2 of this + License shall, upon 60 days notice from Participant terminate prospectively + and automatically at the expiration of such 60 day notice period, unless if + within such 60 day period You withdraw Your claim with respect to the + Participant Software against such Participant either unilaterally or pursuant + to a written agreement with Participant. + . + 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end user + licenses that have been validly granted by You or any distributor hereunder + prior to termination (excluding licenses granted to You by any distributor) + shall survive termination. + . + 7. LIMITATION OF LIABILITY. + . + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING + NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY + OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF + ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, + INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT + LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, + COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR + LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH + DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH + OR PERSONAL INJURY RESULTING FROM SUCH PARTY’S NEGLIGENCE TO THE EXTENT + APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS + EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + . + 8. U.S. GOVERNMENT END USERS. + . + The Covered Software is a “commercial item,” as that term is defined in 48 + C.F.R. 2.101 (Oct. 1995), consisting of “commercial computer software” (as + that term is defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial + computer software documentation” as such terms are used in 48 C.F.R. 12.212 + (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 + through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered + Software with only those rights set forth herein. This U.S. Government Rights + clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or + provision that addresses Government rights in computer software under this + License. + . + 9. MISCELLANEOUS. + . + This License represents the complete agreement concerning subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. This License shall be governed by the law of the jurisdiction + specified in a notice contained within the Original Software (except to the + extent applicable law, if any, provides otherwise), excluding such + jurisdiction’s conflict-of-law provisions. Any litigation relating to this + License shall be subject to the jurisdiction of the courts located in the + jurisdiction and venue specified in a notice contained within the Original + Software, with the losing party responsible for costs, including, without + limitation, court costs and reasonable attorneys’ fees and expenses. The + application of the United Nations Convention on Contracts for the + International Sale of Goods is expressly excluded. Any law or regulation which + provides that the language of a contract shall be construed against the + drafter shall not apply to this License. You agree that You alone are + responsible for compliance with the United States export administration + regulations (and the export control laws and regulation of any other + countries) when You use, distribute or otherwise make available any Covered + Software. + . + 10. RESPONSIBILITY FOR CLAIMS. + . + As between Initial Developer and the Contributors, each party is responsible + for claims and damages arising, directly or indirectly, out of its utilization + of rights under this License and You agree to work with Initial Developer and + Contributors to distribute such responsibility on an equitable basis. Nothing + herein is intended or shall be deemed to constitute any admission of liability. + +License: DEC + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation, and that the name of Digital not be + used in advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + . + DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. + +License: expat + 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 X CONSORTIUM 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. + +License: expat-like + GLESv2 part: + . + This document is licensed under the SGI Free Software B License Version + 2.0. For details, see http://oss.sgi.com/projects/FreeB/ + . + SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + Copyright (C) [dates of first publication] Silicon Graphics, Inc. All Rights + Reserved. + . + 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 including the dates of first publication and either + this permission notice or a reference to http://oss.sgi.com/projects/FreeB/ + 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 SILICON GRAPHICS, INC. 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. + . + Except as contained in this notice, the name of Silicon Graphics, Inc. shall + not be used in advertising or otherwise to promote the sale, use or other + dealings in this Software without prior written authorization from Silicon + Graphics, Inc + +License: GPL-djd + This document is Copyright (C) DJ Delorie and may be distributed + verbatim, but changing it is not allowed. + . + Source code copyright DJ Delorie is distributed under the terms of the + GNU General Public Licence, with the following exceptions: + . + * Any existing copyright or authorship information in any given source + file must remain intact. If you modify a source file, a notice to that + effect must be added to the authorship information in the source file. + . + * binaries provided in djgpp may be distributed without sources ONLY if + the recipient is given sufficient information to obtain a copy of djgpp + themselves. This primarily applies to go32.exe, emu387, stub.exe, and + the graphics drivers. + . + * modified versions of the binaries provided in djgpp must be + distributed under the terms of the GPL. + . + * objects and libraries linked into an application may be distributed + without sources. + +License: GPL-2-fmc + This file is part of MkSymbian build tool. + . + MkSymbian is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License version 2 as published by the Free + Software Foundation. + . + MkSymbian is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + . + Please note that the General Public License version 2 does not permit + incorporating MkSymbian into proprietary programs. + . + On Debian systems, the complete text of version 2 of the GNU General + Public License can be found in '/usr/share/common-licenses/GPL-2'. + +License: GPL-2-oracle + This code is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License version 2 only, as + published by the Free Software Foundation. Oracle designates this + particular file as subject to the "Classpath" exception as provided + by Oracle in the LICENSE file that accompanied this code. + . + This code is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + version 2 for more details (a copy is included in the LICENSE file that + accompanied this code). + . + You should have received a copy of the GNU General Public License version + 2 along with this work; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + . + Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + or visit www.oracle.com if you need additional information or have any + questions. + . + On Debian systems, the complete text of version 2 of the GNU General + Public License can be found in '/usr/share/common-licenses/GPL-2'. + +License: GPL-2+ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + . + On Debian systems, the complete text of version 2 of the GNU General + Public License can be found in '/usr/share/common-licenses/GPL-2'. + +License: ISC + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + . + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +License: LGPL-2+ + . + On Debian systems, the complete text of version 2 of the GNU Lesser + General Public License can be found in '/usr/share/common-licenses/LGPL-2'. + +License: LGPL-2.1 + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; version 2.1 only + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + . + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + . + On Debian systems, the complete text of version 2.1 of the GNU Lesser + General Public License can be found in '/usr/share/common-licenses/LGPL-2.1'. + +License: LGPL-2.1+ + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + . + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + . + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + . + On Debian systems, the complete text of version 2.1 of the GNU Lesser + General Public License can be found in '/usr/share/common-licenses/LGPL-2.1'. + +License: LGPL-2.1+ with staticLink exception + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version + with the following modification: + . + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent modules,and + to copy and distribute the resulting executable under terms of your choice, + provided that you also meet, for each linked independent module, the terms + and conditions of the license of that module. An independent module is a + module which is not derived from or based on this library. If you modify + this library, you may extend this exception to your version of the library, + but you are not obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + . + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + . + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + . + On Debian systems, the complete text of version 2.1 of the GNU Lesser + General Public License can be found in '/usr/share/common-licenses/LGPL-2.1'. + +License: mention + The source can be modified as long as my name appears and some + notes explaining the modifications done are included in the file. + +License: MPL-1.1 + The contents of this file are subject to the Mozilla Public License Version + 1.1 (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ + . + Software distributed under the License is distributed on an "AS IS" basis, + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + the specific language governing rights and limitations under the License. + . + MOZILLA PUBLIC LICENSE + Version 1.1 + . + --------------- + . + 1. Definitions. + . + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + . + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + . + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + . + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + . + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + . + 1.5. "Executable" means Covered Code in any form other than Source + Code. + . + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + . + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + . + 1.8. "License" means this document. + . + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + . + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + . + B. Any new file that contains any part of the Original Code or + previous Modifications. + . + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + . + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + . + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + . + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + . + 2. Source Code License. + . + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + . + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + . + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + . + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + . + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + . + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + . + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + . + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + . + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + . + 3. Distribution Obligations. + . + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + . + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + . + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + . + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + . + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + . + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + . + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + . + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + . + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + . + 4. Inability to Comply Due to Statute or Regulation. + . + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + . + 5. Application of this License. + . + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + . + 6. Versions of the License. + . + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + . + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + . + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + . + 7. DISCLAIMER OF WARRANTY. + . + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + . + 8. TERMINATION. + . + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + . + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + . + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + . + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + . + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + . + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + . + 9. LIMITATION OF LIABILITY. + . + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + . + 10. U.S. GOVERNMENT END USERS. + . + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + . + 11. MISCELLANEOUS. + . + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + . + 12. RESPONSIBILITY FOR CLAIMS. + . + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + . + 13. MULTIPLE-LICENSED CODE. + . + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the MPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + . + EXHIBIT A -Mozilla Public License. + . + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + . + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + . + The Original Code is ______________________________________. + . + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + . + Contributor(s): ______________________________________. + . + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + . + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + +License: Open + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + . + 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 + OPEN GROUP 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. + . + Except as contained in this notice, the name of The Open Group shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from The Open Group. + +License: RSA + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + . + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + . + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + . + These notices must be retained in any copies of any part of this + documentation and/or software. + +License: SC + Permission to use, copy, modify, and distribute this software and its + documentation in source and binary forms for any purpose and without + fee is hereby granted, provided that both the above copyright notice + and this permission notice appear in all copies, and that any + documentation, advertising materials, and other materials related to + such distribution and use acknowledge that the software was developed + in part by the University of Southern California, Information + Sciences Institute. The name of the University may not be used to + endorse or promote products derived from this software without + specific prior written permission. + . + THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about + the suitability of this software for any purpose. THIS SOFTWARE IS + PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + . + Other copyrights might apply to parts of this software and are so + noted when applicable. + +License: sun + Developed at SunPro, a Sun Microsystems, Inc. business. + Permission to use, copy, modify, and distribute this + software is freely granted, provided that this notice + is preserved. + +License: Zlib + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + . + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + . + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + . + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + . + 3. This notice may not be removed or altered from any source + distribution. diff --git a/fixdeb b/fixdeb new file mode 100755 index 00000000..5ba67650 --- /dev/null +++ b/fixdeb @@ -0,0 +1,57 @@ +#!/bin/bash +# +# Create debian files from *.in files +# + +set -e + +usage() +{ + echo 'Usage : DEB_SUBST_= ... DEB_SUBST_= fixdeb [-sc|--gen-control] [file1.in] ... [filen.in]' + echo ' Changes environment variables with their values. The variables to be' + echo ' changed should be exported prefixed with DEB_SUBST_' + echo ' --gen-control: do not skip generating control file, by default it will be ignored' + echo ' = space separated list to debian files templates' + echo + echo ' List of defined variables' + set | grep '^DEB_SUBST_' + exit 1 +} + +true ${DEB_SUBST_PACKAGEVERSION:=$(dpkg-parsechangelog | sed -ne's,^Version: \(.*\),\1,p')} +true ${DEB_SUBST_VERSION:=$(echo $DEB_SUBST_PACKAGEVERSION | sed -ne's,^\([0-9.]*\).*,\1,p')} +true ${DEB_SUBST_DEBVERSION:=$(echo $DEB_SUBST_PACKAGEVERSION | awk -F '-' '{ print $NF }')} +true ${DEB_SUBST_UPSTREAM_VERSION:=$(echo ${DEB_SUBST_PACKAGEVERSION} | cut -f 1 -d -)} +true ${DEB_SUBST_UPSTREAM_MAIN_VERSION:=$(echo ${DEB_SUBST_UPSTREAM_VERSION} | sed -e 's/^\([0-9\.]*\).*/\1/')} +true ${DEB_SUBST_PACKAGESUFFIX:=-${DEB_SUBST_UPSTREAM_MAIN_VERSION}} +true ${DEB_SUBST_PRIORITY:=$(($(echo ${DEB_SUBST_VERSION}.0.0.0.0 | sed -e 's@\([0-9]\)\+\.\([0-9]\)\+\.\([0-9]\+\)\.\([0-9]\+\).*@((\1*100+\2)*100+\3)*100+\4@')))} +true ${DEB_SUBST_TARGET:=$(dpkg-architecture -qDEB_BUILD_ARCH)-$(dpkg-architecture -qDEB_BUILD_ARCH_OS)} + +if test ${1} = '--gen-control' +then + echo ========== Genrating debian/control as per explicit request ========== + gen_control=true + shift +else + gen_control=false +fi +if test $# -lt 1 +then + usage +fi + +echo 'List of defined variables' +set | grep '^DEB_SUBST_' +SUBST_CMD=$(set | sed -n -e 's/^DEB_SUBST_\([A-Z_]\+\)=\(.*\)/-e s@\${\1}@\2@g/p') + +for i in $* +do + f=$(basename ${i} .in) + if ${gen_control} || test ${f} != 'control' + then + d=$(dirname ${i}) + o=${d}/${f/./${DEB_SUBST_PACKAGESUFFIX}.} + echo " * Generating ${o}" + sed ${SUBST_CMD} ${i} > ${o} + fi +done diff --git a/fp-compiler.config.in b/fp-compiler.config.in new file mode 100644 index 00000000..5eb7cb56 --- /dev/null +++ b/fp-compiler.config.in @@ -0,0 +1,34 @@ +#! /bin/sh + +set -e + +# Load debconf +. /usr/share/debconf/confmodule + +CFG_FILE='/etc/fpc.cfg' +CFG_PRIORITY=$(echo ${VERSION} | sed -e 's/\.//g') +if test -f "${CFG_FILE}" && ! test -L "${CFG_FILE}" +then + db_input high fp-compiler/rename_cfg || test $? -eq 30 +fi +WINDRES_BINS=$(find '/usr/bin' -maxdepth 1 -mindepth 1 -executable -name "*windres*" -printf "%p, ") +# The last comma needs to be stripped because the template already has it +db_subst fp-compiler/windres-select choices ${WINDRES_BINS%, } +db_metaget fp-compiler/windres-select choices +# The last entry of the template now has "Select manually" but let's not hardcode +# it here. It should remain the last item though. +MANUAL_SELECT_MESSAGE="${RET##*, }" +db_input low fp-compiler/windres-select || test $? -eq 30 +db_go +db_get fp-compiler/windres-select +if test "${RET}" = "${MANUAL_SELECT_MESSAGE}" +then + db_input low fp-compiler/windres || test $? -eq 30 +else + WINDRES_BIN=${RET} + db_set fp-compiler/windres "${WINDRES_BIN}" +fi +db_go + +# Debhelper code +#DEBHELPER# diff --git a/fp-compiler.doc-base.in b/fp-compiler.doc-base.in new file mode 100644 index 00000000..f6549652 --- /dev/null +++ b/fp-compiler.doc-base.in @@ -0,0 +1,10 @@ +Document: fp-compiler${PACKAGESUFFIX} +Title: Free Pascal FAQ +Author: Michael van Canneyt +Abstract: Frequnetly Asked Questions about the Free Pascal Compiler. + . +Section: Programming + +Format: html +Files: /usr/share/doc/fp-compiler/${VERSION}/* +Index: /usr/share/doc/fp-compiler/${VERSION}/faq.html diff --git a/fp-compiler.install.in b/fp-compiler.install.in new file mode 100644 index 00000000..6b4cf091 --- /dev/null +++ b/fp-compiler.install.in @@ -0,0 +1,9 @@ +#! /usr/bin/dh-exec +usr/bin/fpc-depends-${VERSION} +usr/bin/${DEB_HOST_MULTIARCH}-fpc-${VERSION} +usr/bin/${DEB_HOST_MULTIARCH}-fpcmkcfg-${VERSION} +usr/bin/${DEB_HOST_MULTIARCH}-fpcres-${VERSION} +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/${PPCBIN} +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/msg +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/samplecfg +usr/share/doc/fp-compiler [!freebsd-any] diff --git a/fp-compiler.links.in b/fp-compiler.links.in new file mode 100644 index 00000000..d5fc15cc --- /dev/null +++ b/fp-compiler.links.in @@ -0,0 +1,4 @@ +/usr/lib/${DEB_HOST_MULTIARCH}/fpc/${VERSION}/${PPCBIN} /usr/bin/${PPCBIN}-${VERSION} +/usr/share/man/man1/fpc-${VERSION}.1.gz /usr/share/man/man1/${DEB_HOST_MULTIARCH}-fpc-${VERSION}.1.gz +/usr/share/man/man1/fpcmkcfg-${VERSION}.1.gz /usr/share/man/man1/${DEB_HOST_MULTIARCH}-fpcmkcfg-${VERSION}.1.gz +/usr/share/man/man1/fpcres-${VERSION}.1.gz /usr/share/man/man1/${DEB_HOST_MULTIARCH}-fpcres-${VERSION}.1.gz diff --git a/fp-compiler.lintian-overrides b/fp-compiler.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-compiler.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-compiler.lintian-overrides.in b/fp-compiler.lintian-overrides.in new file mode 100644 index 00000000..43822bd6 --- /dev/null +++ b/fp-compiler.lintian-overrides.in @@ -0,0 +1,6 @@ +# Free pascal binaries are often statically linked. +# The Free Pascal Compiler does not properly support linking. Please +# see BTS #472304. +statically-linked-binary +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-compiler.manpages.in b/fp-compiler.manpages.in new file mode 100644 index 00000000..5932fb53 --- /dev/null +++ b/fp-compiler.manpages.in @@ -0,0 +1,6 @@ +debian/fpc-depends-${VERSION}.1 +debian/tmp/usr/man/man1/fpc-${VERSION}.1 +debian/tmp/usr/man/man1/fpcmkcfg-${VERSION}.1 +debian/tmp/usr/man/man1/fpcres-${VERSION}.1 +debian/tmp/usr/man/man1/${PPCBIN}-${VERSION}.1 +debian/tmp/usr/man/man5/fpc-${VERSION}.cfg.5 diff --git a/fp-compiler.postinst.in b/fp-compiler.postinst.in new file mode 100644 index 00000000..b2bb9073 --- /dev/null +++ b/fp-compiler.postinst.in @@ -0,0 +1,76 @@ +#! /bin/sh + +set -e + +# Load debconf +. /usr/share/debconf/confmodule + +CFG_PATH='/etc/fpc.cfg' +PKG_CFG_PATH="/etc/fpc-${VERSION}.cfg" +LIB_DIR="/usr/lib/${DEB_HOST_MULTIARCH}/fpc" +MAN_DIR="/usr/share/man/man1" +MKCFG="/usr/bin/${DEB_HOST_MULTIARCH}-fpcmkcfg-${VERSION}" + +# Debhelper code +#DEBHELPER# + +USER_HAS_ENABLED_NEW_CONF="test -L ${CFG_PATH} -o ! -e ${CFG_PATH}" + +if ! ${USER_HAS_ENABLED_NEW_CONF} +then + db_get fp-compiler/rename_cfg + if test "${RET}" = "true" -a -e ${CFG_PATH} + then + mv "${CFG_PATH}" "${CFG_PATH}.bak" + fi +fi + +# Create new compiler configuration file +${MKCFG} -0 -d "basepath=${LIB_DIR}/\$fpcversion" -o "${PKG_CFG_PATH}" +# Add multiarch path to /etc/fpc.cfg so executables linked against libc can be corectly linked +echo '# multiarch library search path' >> ${PKG_CFG_PATH} +echo '-Fl/usr/lib/$fpctarget-*' >> ${PKG_CFG_PATH} +# Define a default location, multi-arch compatible, for third party units. +cat >> ${PKG_CFG_PATH} <> ${PKG_CFG_PATH} + echo "-FC${WINDRES_BIN}" >> ${PKG_CFG_PATH} +fi + +# add alternatives +update-alternatives \ + --install /usr/bin/fpc fpc /usr/bin/${DEB_HOST_MULTIARCH}-fpc-${VERSION} ${PRIORITY} \ + --slave /usr/bin/${PPCBIN} ${PPCBIN} ${LIB_DIR}/${VERSION}/${PPCBIN} \ + --slave /usr/bin/fpc-depends fpc-depends /usr/bin/fpc-depends-${VERSION} \ + --slave /usr/bin/fpcres fpcres /usr/bin/${DEB_HOST_MULTIARCH}-fpcres-${VERSION} \ + --slave ${MAN_DIR}/${PPCBIN}.1.gz ${PPCBIN}.1.gz ${MAN_DIR}/${PPCBIN}-${VERSION}.1.gz \ + --slave ${MAN_DIR}/fpc.1.gz fpc.1.gz ${MAN_DIR}/fpc-${VERSION}.1.gz \ + --slave ${MAN_DIR}/fpc-depends.1.gz fpc-depends.1.gz ${MAN_DIR}/fpc-depends-${VERSION}.1.gz \ + --slave ${MAN_DIR}/fpcres.1.gz fpcres.1.gz ${MAN_DIR}/fpcres-${VERSION}.1.gz +# Configuration file is a special case as it is backward compatible and is +# likely to be handled as a special alternative pointing to the latest release +if ${USER_HAS_ENABLED_NEW_CONF} +then + update-alternatives \ + --install ${CFG_PATH} fpc.cfg ${PKG_CFG_PATH} ${PRIORITY} +fi +# Replace legacy/gnu pascal compilers +update-alternatives \ + --install /usr/bin/pc pc /usr/bin/fpc 20 \ + --slave ${MAN_DIR}/pc.1.gz pc.1.gz ${MAN_DIR}/fpc.1.gz diff --git a/fp-compiler.postrm.in b/fp-compiler.postrm.in new file mode 100644 index 00000000..5199a598 --- /dev/null +++ b/fp-compiler.postrm.in @@ -0,0 +1,16 @@ +#! /bin/sh + +set -e + +ACTION=$1 + +CFG_FILE="/etc/fpc-${VERSION}" + +# Debhelper code +#DEBHELPER# + +if test "${ACTION}" = "purge" +then + rm -f "${CFG_FILE}".cfg + rm -f "${CFG_FILE}".bak +fi diff --git a/fp-compiler.prerm.in b/fp-compiler.prerm.in new file mode 100644 index 00000000..ff4c725e --- /dev/null +++ b/fp-compiler.prerm.in @@ -0,0 +1,11 @@ +#! /bin/sh + +set -e + +# remove alternative +update-alternatives --remove fpc /usr/bin/${DEB_HOST_MULTIARCH}-fpc-${VERSION} +update-alternatives --remove fpc.cfg /etc/fpc-${VERSION}.cfg +update-alternatives --remove pc /usr/bin/fpc-${VERSION} + +# Debhelper code +#DEBHELPER# diff --git a/fp-compiler.templates.in b/fp-compiler.templates.in new file mode 100644 index 00000000..7cfa337b --- /dev/null +++ b/fp-compiler.templates.in @@ -0,0 +1,60 @@ +# These templates have been reviewed by the debian-l10n-english +# team +# +# If modifications/additions/rewording are needed, please ask +# debian-l10n-english@lists.debian.org for advice. +# +# Even minor modifications require translation updates and such +# changes should be coordinated with translators and reviewers. + +Template: fp-compiler/rename_cfg +Type: boolean +Default: true +_Description: Rename "/etc/fpc.cfg" to "/etc/fpc.cfg.bak"? + FPC now supports having multiple versions installed on the same system. + The update-alternatives command can be used to set a default version for + * fpc (the compiler); + * fpc.cfg (the configuration file); + * fp-utils (the helper tools). + . + Whatever version you may choose as default, the configuration files are + always backward compatible, so it should always be safe to use the latest + version. + . + In order to use the alternatives system on the system wide FPC configuration + file you must accept renaming "/etc/fpc.cfg"; otherwise you will need to + manage this manually by yourself. + +Template: fp-compiler/windres-select +Type: select +# This string should be in sync with the translation in the description +#flag:translate:2 +__Choices: ${choices}, Select manually +Default: Select manually +#flag:comment:4 +# "Select manually" should be in sync with the text elsewhere in the +# translation +_Description: Default MS Windows .rc resource compiler: + FPC supports compiling programs that embed resources as MS Windows + .rc-format files on all platforms where the MinGW windres tool is available. + . + In order to be able to compile projects using .rc files, you need first to + manually install the package mingw32-binutils. mingw32-binutils is suggested + by fp-compiler but not pulled in automatically. + . + If you want to enter a custom .rc file compiler that does not appear in this + list or if you simply want to disable this feature, please select + "Select manually". + +Template: fp-compiler/windres +Type: string +Default: +_Description: Default MS Windows .rc resource compiler: + FPC supports compiling programs that embed resources as MS Windows + .rc-format files on all platforms where the MinGW windres tool is available. + . + In order to be able to compile projects using .rc files, you need first to + manually install the package mingw32-binutils. mingw32-binutils is suggested + by fp-compiler but not pulled in automatically. + . + If you don't want to use a default .rc file compiler, leave this blank. diff --git a/fp-docs.doc-base.in b/fp-docs.doc-base.in new file mode 100644 index 00000000..edcf3d95 --- /dev/null +++ b/fp-docs.doc-base.in @@ -0,0 +1,10 @@ +Document: fpc-docs${PACKAGESUFFIX} +Title: Free Pascal Documentation +Author: Michael van Canneyt +Abstract: Documentation for the Free Pascal Compiler. + . +Section: Programming + +Format: html +Files: /usr/share/doc/fp-docs/${VERSION}/* +Index: /usr/share/doc/fp-docs/${VERSION}/fpctoc.html diff --git a/fp-docs.install.in b/fp-docs.install.in new file mode 100644 index 00000000..d3f6e031 --- /dev/null +++ b/fp-docs.install.in @@ -0,0 +1,2 @@ +#! /usr/bin/dh-exec +usr/share/doc/fp-docs [!freebsd-any] diff --git a/fp-docs.lintian-overrides b/fp-docs.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-docs.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-docs.lintian-overrides.in b/fp-docs.lintian-overrides.in new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-docs.lintian-overrides.in @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-fix-timestamps b/fp-fix-timestamps new file mode 100755 index 00000000..bf1000cd --- /dev/null +++ b/fp-fix-timestamps @@ -0,0 +1,98 @@ +#!/bin/sh + +# This script is meant to be used by source packages in the Free Pascal stack +# in Debian and derivatives. The aim of this script is to fix the timestamps of +# patched files (with respect to upstream) that would otherwise end up changing +# the timestamp stored in ppu files. This timestamp in ppu files has two +# issues: 1) it deteriorates reproducible builds. 2) reverse dependent packages +# that also build ppu files may believe that the source has changed and either +# require recompilation of the source or at least require recalculation all the +# time. +# +# See also: https://wiki.debian.org/ReproducibleBuilds/TimestampsInPPUGeneratedByFPC + +set -e + +myTmpFile=$(mktemp) +myNewRef=$(mktemp) +myOldRefSorted=$(mktemp) +ReferenceFile=debian/source/timestamps + +trap 'rm $myTmpFile $myNewRef $myOldRefSorted' 0 + +if [ ! -f debian/source/format ] ; then + echo "debian/source/format not found: $0 only works if it can check the Debian source format." + return 1 +fi + +if [ "$(cat debian/source/format)" != "3.0 (quilt)" ] ; then + echo "debian/source/format is not 3.0 (quilt): $0 doesn't know how to proceed." + return 1 +fi + +checkAgainstRef(){ + diff -q $myOldRefSorted $myNewRef > /dev/null +} + +makeNewRef(){ + now="$(date --iso-8601='minutes' --universal)" + if [ -f $ReferenceFile ] ; then + cat $ReferenceFile | LC_ALL=C.UTF-8 sort > $myOldRefSorted + fi + for FILE in $fpcFiles ; do + FILE=${FILE#*/} + existingFile="$(grep $FILE $myOldRefSorted || true)" + if [ -z "$existingFile" ] ; then + echo "$FILE $now" >> $myTmpFile + else + echo "$existingFile" >> $myTmpFile + fi + done + cat $myTmpFile | LC_ALL=C.UTF-8 sort | uniq > $myNewRef +} + +updateRef(){ + if [ ! -d "$(dirname $ReferenceFile)" ] ; then + mkdir "$(dirname $ReferenceFile)" + fi + cat $myNewRef > $ReferenceFile +} + +# We need something smarter for commented out patches I guess. Warning, +# checking d/p/series alone is not enough, see man dpkg-source. Maybe what can +# be done is that we use dpkg-parsechangelog to extract the date of the +# packaging and in the check option verify that those files are actually newer +# than that. Unfortunately, that also depends on the way-of-working. +fpcFiles="$(rgrep "^+++" debian/patches | awk '{print $2}' | grep -e "\.pas$" -e "\.inc$" -e "\.pp$" | sort | uniq)" + +if [ -z "$fpcFiles" ] ; then + echo "Nothing to do as no patched Free Pascal source files were found." + return 0 +fi + +makeNewRef + +case $1 in + check) + if checkAgainstRef ; then + echo "Reference file up-to-date" + else + echo "Reference file needs updating" + return 1 + fi + ;; + update) + if ! checkAgainstRef ; then + updateRef + else + echo "No update needed" + fi + ;; + touch) + awk '{system("touch " $1 " -d" $2)}' $ReferenceFile + ;; + *) + echo "No input arguments given" + return 1 + ;; +esac diff --git a/fp-fix-timestamps.txt b/fp-fix-timestamps.txt new file mode 100644 index 00000000..45247343 --- /dev/null +++ b/fp-fix-timestamps.txt @@ -0,0 +1,44 @@ +NAME +fp-fix-timestamps - helper script for the Free Pascal stack in Debian + +SYNOPSIS +fp-fix-timestamps check|update|touch + +DESCRIPTION + +fp-fix-timestamps is meant to be used by Debian source packages in the Free +Pascal stack. The primary location for use is the debian/rules file. The aim of +this script is to fix the timestamps of patched files (with respect to +upstream) that would otherwise end up changing the timestamp stored in ppu +files. + +This timestamp in ppu files has two issues: + +1. It deteriorates reproducible builds. + +2. Reverse dependent packages that also build ppu files may believe that the +source has changed and either require recompilation of the source or at least +require recalculation all the time. + +Currently this script supports three operations. + +1. touch: The main operation is to touch the files that are listed in +debian/source/timestamps to the associated timestamps (in that same file). + +2. check: When the situation is simple and the only changes in the package to +the source come from patches, the check option can be used to verify that the +list in debian/source/timestamps is still up-to-date in the sense that all +files touched by patches are listed and that all files listed are touched by +patches. + +3. update: Similar to check, but also update the debian/source/timestamps file. + +When the maintainer scripts modify a source file outside of the patches, the +maintainer is free to add those files manually to the timestamps file, but then +the check and update options don't work as expected anymore. + +SEE ALSO +https://wiki.debian.org/ReproducibleBuilds/TimestampsInPPUGeneratedByFPC + +AUTHOR +Paul Gevers diff --git a/fp-ide.install.in b/fp-ide.install.in new file mode 100644 index 00000000..42b18f94 --- /dev/null +++ b/fp-ide.install.in @@ -0,0 +1,5 @@ +#! /usr/bin/dh-exec +usr/bin/fp-* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/ide +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/fpmkinst/*/ide.fpm +usr/share/doc/fp-ide [!freebsd-any] diff --git a/fp-ide.lintian-overrides b/fp-ide.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-ide.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-ide.lintian-overrides.in b/fp-ide.lintian-overrides.in new file mode 100644 index 00000000..69aeb9fd --- /dev/null +++ b/fp-ide.lintian-overrides.in @@ -0,0 +1,5 @@ +# Free pascal binaries are often statically linked. +fp-ide${PACKAGESUFFIX} binary: statically-linked-binary +fp-ide${PACKAGESUFFIX}: statically-linked-binary +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-ide.manpages.in b/fp-ide.manpages.in new file mode 100644 index 00000000..a75880e3 --- /dev/null +++ b/fp-ide.manpages.in @@ -0,0 +1 @@ +debian/tmp/usr/man/man1/fp-${VERSION}.1 diff --git a/fp-ide.postinst.in b/fp-ide.postinst.in new file mode 100644 index 00000000..7ab74f18 --- /dev/null +++ b/fp-ide.postinst.in @@ -0,0 +1,16 @@ +#! /bin/sh + +set -e + +# Load debconf +. /usr/share/debconf/confmodule + +LIB_DIR="/usr/lib/${DEB_HOST_MULTIARCH}/fpc" +MAN_DIR="/usr/share/man/man1" + +# Debhelper code +#DEBHELPER# + +# add alternatives +update-alternatives \ + --install /usr/bin/fp fp /usr/bin/fp-${VERSION} ${PRIORITY} diff --git a/fp-ide.prerm.in b/fp-ide.prerm.in new file mode 100644 index 00000000..31582321 --- /dev/null +++ b/fp-ide.prerm.in @@ -0,0 +1,9 @@ +#! /bin/sh + +set -e + +# remove alternative +update-alternatives --remove fp /usr/bin/fp-${VERSION} + +# Debhelper code +#DEBHELPER# diff --git a/fp-units-base.install.in b/fp-units-base.install.in new file mode 100644 index 00000000..0569606a --- /dev/null +++ b/fp-units-base.install.in @@ -0,0 +1,11 @@ +#! /usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fpmkunit* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/hash* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/libtar* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/ncurses* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/pasjpeg* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/paszlib* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/regexpr* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/uuid* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/x11* +usr/share/doc/fp-units-base [!freebsd-any] diff --git a/fp-units-base.lintian-overrides b/fp-units-base.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-base.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-base.lintian-overrides.in b/fp-units-base.lintian-overrides.in new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-base.lintian-overrides.in @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-db.install.in b/fp-units-db.install.in new file mode 100644 index 00000000..658dbc5f --- /dev/null +++ b/fp-units-db.install.in @@ -0,0 +1,11 @@ +#! /usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/dblib* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/gdbm* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/ibase* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/mysql* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/odbc* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/oracle* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/postgres* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/pxlib* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/sqlite* +usr/share/doc/fp-units-db [!freebsd-any] diff --git a/fp-units-db.lintian-overrides b/fp-units-db.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-db.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-db.lintian-overrides.in b/fp-units-db.lintian-overrides.in new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-db.lintian-overrides.in @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-fcl.install.in b/fp-units-fcl.install.in new file mode 100644 index 00000000..b07d79e0 --- /dev/null +++ b/fp-units-fcl.install.in @@ -0,0 +1,21 @@ +#! /usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-async* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-base* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-db* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-extra* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-fpcunit* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-image* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-js* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-json* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-net* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-passrc* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-pdf* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-process* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-registry* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-res* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-sdo* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-sound* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-stl* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-web* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fcl-xml* +usr/share/doc/fp-units-fcl [!freebsd-any] diff --git a/fp-units-fcl.lintian-overrides b/fp-units-fcl.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-fcl.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-fcl.lintian-overrides.in b/fp-units-fcl.lintian-overrides.in new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-fcl.lintian-overrides.in @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-fv.install.in b/fp-units-fv.install.in new file mode 100644 index 00000000..13dc9a76 --- /dev/null +++ b/fp-units-fv.install.in @@ -0,0 +1,3 @@ +#! /usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fv* +usr/share/doc/fp-units-fv [!freebsd-any] diff --git a/fp-units-fv.lintian-overrides b/fp-units-fv.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-fv.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-fv.lintian-overrides.in b/fp-units-fv.lintian-overrides.in new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-fv.lintian-overrides.in @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-gfx.install.in b/fp-units-gfx.install.in new file mode 100644 index 00000000..141f9ff0 --- /dev/null +++ b/fp-units-gfx.install.in @@ -0,0 +1,15 @@ +#! /usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/ggi* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/graph* [!linux-arm64 !linux-armel !linux-armhf !linux-m68k !linux-mips !linux-mipsel !linux-ppc64] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/hermes* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/imagemagick* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/libgd* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/libpng* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/opencl* [!freebsd-any !linux-arm64 !linux-armel !linux-armhf !linux-m68k !linux-mips !linux-mipsel !linux-powerpc !linux-ppc64] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/opengl* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/opengles* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/ptc* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/rsvg* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/svgalib* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/xforms* +usr/share/doc/fp-units-gfx [!freebsd-any] diff --git a/fp-units-gfx.lintian-overrides b/fp-units-gfx.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-gfx.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-gfx.lintian-overrides.in b/fp-units-gfx.lintian-overrides.in new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-gfx.lintian-overrides.in @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-gtk2.install.in b/fp-units-gtk2.install.in new file mode 100644 index 00000000..e7017fa6 --- /dev/null +++ b/fp-units-gtk2.install.in @@ -0,0 +1,4 @@ +#! /usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/cairo* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/gtk2* +usr/share/doc/fp-units-gtk2 diff --git a/fp-units-gtk2.lintian-overrides b/fp-units-gtk2.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-gtk2.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-gtk2.lintian-overrides.in b/fp-units-gtk2.lintian-overrides.in new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-gtk2.lintian-overrides.in @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-i386.install.in b/fp-units-i386.install.in new file mode 100644 index 00000000..f73b19e9 --- /dev/null +++ b/fp-units-i386.install.in @@ -0,0 +1,4 @@ +#! /usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/libc +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/fpmkinst/*/libc.fpm +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/unixutil* diff --git a/fp-units-i386.lintian-overrides b/fp-units-i386.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-i386.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-i386.lintian-overrides.in b/fp-units-i386.lintian-overrides.in new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-i386.lintian-overrides.in @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-math.install.in b/fp-units-math.install.in new file mode 100644 index 00000000..c7619caa --- /dev/null +++ b/fp-units-math.install.in @@ -0,0 +1,6 @@ +#! /usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/gmp* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/numlib* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/proj4* [!freebsd-math] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/symbolic* +usr/share/doc/fp-units-math [!freebsd-any] diff --git a/fp-units-math.lintian-overrides b/fp-units-math.lintian-overrides new file mode 100644 index 00000000..d584c65d --- /dev/null +++ b/fp-units-math.lintian-overrides @@ -0,0 +1,5 @@ +# False positive because the first occurrence is a name of a unit, while the +# second occurrence (between brackets) is a description of the unit. +spelling-error-in-description symbolic symbolic (duplicate word) symbolic +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-math.lintian-overrides.in b/fp-units-math.lintian-overrides.in new file mode 100644 index 00000000..d584c65d --- /dev/null +++ b/fp-units-math.lintian-overrides.in @@ -0,0 +1,5 @@ +# False positive because the first occurrence is a name of a unit, while the +# second occurrence (between brackets) is a description of the unit. +spelling-error-in-description symbolic symbolic (duplicate word) symbolic +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-misc.install.in b/fp-units-misc.install.in new file mode 100644 index 00000000..bc8dac2c --- /dev/null +++ b/fp-units-misc.install.in @@ -0,0 +1,24 @@ +#! /usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/aspell* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/bfd* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/bzip2* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/cdrom* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/chm* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fftw* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fpindexer* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fppkg* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/gdbint* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/iconvenc* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/jni* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/libsee* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/libxml2* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/lua* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/newt* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/pthreads* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/syslog* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/tcl* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/unzip* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/users* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/utmp* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/zlib* +usr/share/doc/fp-units-misc [!freebsd-any] diff --git a/fp-units-misc.lintian-overrides b/fp-units-misc.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-misc.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-misc.lintian-overrides.in b/fp-units-misc.lintian-overrides.in new file mode 100644 index 00000000..f473cad4 --- /dev/null +++ b/fp-units-misc.lintian-overrides.in @@ -0,0 +1,4 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original +# Spelling error in variable name in object file +spelling-error-in-binary relocateable relocatable diff --git a/fp-units-multimedia.install.in b/fp-units-multimedia.install.in new file mode 100644 index 00000000..3450ee10 --- /dev/null +++ b/fp-units-multimedia.install.in @@ -0,0 +1,10 @@ +#! /usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/a52* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/dts* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/libvlc* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/mad* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/modplug* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/oggvorbis* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/openal* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/sdl* +usr/share/doc/fp-units-multimedia [!freebsd-any] diff --git a/fp-units-multimedia.lintian-overrides b/fp-units-multimedia.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-multimedia.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-multimedia.lintian-overrides.in b/fp-units-multimedia.lintian-overrides.in new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-multimedia.lintian-overrides.in @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-net.install.in b/fp-units-net.install.in new file mode 100644 index 00000000..04392dcf --- /dev/null +++ b/fp-units-net.install.in @@ -0,0 +1,13 @@ +#! /usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/dbus* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/fastcgi* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/googleapi* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/httpd22* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/httpd24* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/ldap* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/libmicrohttpd* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/libcurl* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/openssl* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/pcap* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/zorba* [!freebsd-any] +usr/share/doc/fp-units-net [!freebsd-any] diff --git a/fp-units-net.lintian-overrides b/fp-units-net.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-net.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-net.lintian-overrides.in b/fp-units-net.lintian-overrides.in new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-net.lintian-overrides.in @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-rtl.install.in b/fp-units-rtl.install.in new file mode 100644 index 00000000..4e4e21da --- /dev/null +++ b/fp-units-rtl.install.in @@ -0,0 +1,6 @@ +#! /usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/rtl +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/rtl-console* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/rtl-extra* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/rtl-objpas* +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/rtl-unicode* diff --git a/fp-units-rtl.lintian-overrides b/fp-units-rtl.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-units-rtl.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-units-rtl.lintian-overrides.in b/fp-units-rtl.lintian-overrides.in new file mode 100644 index 00000000..2326a316 --- /dev/null +++ b/fp-units-rtl.lintian-overrides.in @@ -0,0 +1,3 @@ +fp-units-rtl${PACKAGESUFFIX}: spelling-error-in-binary */rtl/stdconvs.o ang and +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-utils.install b/fp-utils.install new file mode 100644 index 00000000..ba908402 --- /dev/null +++ b/fp-utils.install @@ -0,0 +1,4 @@ +#! /usr/bin/dh-exec +# sh-bang not really needed here, but because of the d/rules logic to make all +# install files executable +debian/fp-fix-timestamps usr/bin/ diff --git a/fp-utils.install.in b/fp-utils.install.in new file mode 100644 index 00000000..d1a63586 --- /dev/null +++ b/fp-utils.install.in @@ -0,0 +1,38 @@ +#! /usr/bin/dh-exec +usr/bin/bin2obj-* +usr/bin/chmcmd-* +usr/bin/chmls-* +usr/bin/data2inc-* +usr/bin/delp-* +usr/bin/fd2pascal-* +usr/bin/fpcjres-* +usr/bin/fpclasschart-* [!freebsd-any] +usr/bin/fpcmake-* +usr/bin/fpcsubst-* +usr/bin/fpdoc-* +usr/bin/fppkg-* +usr/bin/fprcp-* +usr/bin/grab_vcsa-* [!freebsd-any] +usr/bin/h2pas-* +usr/bin/h2paspp-* +usr/bin/ifpc-* +usr/bin/makeskel-* [!freebsd-any] +usr/bin/pas2fpm-* +usr/bin/pas2jni-* +usr/bin/pas2ut-* +usr/bin/plex-* +usr/bin/postw32-* +usr/bin/ppdep-* +usr/bin/ppudump-* +usr/bin/ppufiles-* +usr/bin/ppumove-* +usr/bin/ptop-* +usr/bin/pyacc-* +usr/bin/relpath-* +usr/bin/rmcvsdir-* +usr/bin/rstconv-* +usr/bin/unitdiff-* [!freebsd-any] +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/lexyacc/*.cod +usr/lib/${DEB_HOST_MULTIARCH}/fpc/*/*/*/utils-lexyacc* +usr/share/locale +usr/share/texmf/tex/latex/fpc-* diff --git a/fp-utils.lintian-overrides b/fp-utils.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fp-utils.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-utils.lintian-overrides.in b/fp-utils.lintian-overrides.in new file mode 100644 index 00000000..1fde3b81 --- /dev/null +++ b/fp-utils.lintian-overrides.in @@ -0,0 +1,7 @@ +# Free pascal binaries are often statically linked. +# The Free Pascal Compiler does not properly support linking. Please +# see BTS #472304. +fp-utils${PACKAGESUFFIX} binary: statically-linked-binary +fp-utils${PACKAGESUFFIX}: statically-linked-binary +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fp-utils.manpages b/fp-utils.manpages new file mode 100644 index 00000000..9148f8cf --- /dev/null +++ b/fp-utils.manpages @@ -0,0 +1 @@ +debian/fp-fix-timestamps.1 diff --git a/fp-utils.manpages.in b/fp-utils.manpages.in new file mode 100644 index 00000000..b665fcd9 --- /dev/null +++ b/fp-utils.manpages.in @@ -0,0 +1,35 @@ +debian/tmp/usr/man/man1/bin2obj-${VERSION}.1 +debian/tmp/usr/man/man1/chmcmd-${VERSION}.1 +debian/tmp/usr/man/man1/chmls-${VERSION}.1 +debian/tmp/usr/man/man1/data2inc-${VERSION}.1 +debian/tmp/usr/man/man1/delp-${VERSION}.1 +debian/tmp/usr/man/man1/fd2pascal-${VERSION}.1 +debian/tmp/usr/man/man1/fpcjres-${VERSION}.1 +debian/tmp/usr/man/man1/fpclasschart-${VERSION}.1 +debian/tmp/usr/man/man1/fpcmake-${VERSION}.1 +debian/tmp/usr/man/man1/fpcsubst-${VERSION}.1 +debian/tmp/usr/man/man1/fpdoc-${VERSION}.1 +debian/tmp/usr/man/man1/fppkg-${VERSION}.1 +debian/tmp/usr/man/man1/fprcp-${VERSION}.1 +debian/tmp/usr/man/man1/grab_vcsa-${VERSION}.1 +debian/tmp/usr/man/man1/h2pas-${VERSION}.1 +debian/tmp/usr/man/man1/h2paspp-${VERSION}.1 +debian/tmp/usr/man/man1/ifpc-${VERSION}.1 +debian/tmp/usr/man/man1/makeskel-${VERSION}.1 +debian/tmp/usr/man/man1/pas2fpm-${VERSION}.1 +debian/tmp/usr/man/man1/pas2jni-${VERSION}.1 +debian/tmp/usr/man/man1/pas2ut-${VERSION}.1 +debian/tmp/usr/man/man1/plex-${VERSION}.1 +debian/tmp/usr/man/man1/postw32-${VERSION}.1 +debian/tmp/usr/man/man1/ppdep-${VERSION}.1 +debian/tmp/usr/man/man1/ppudump-${VERSION}.1 +debian/tmp/usr/man/man1/ppufiles-${VERSION}.1 +debian/tmp/usr/man/man1/ppumove-${VERSION}.1 +debian/tmp/usr/man/man1/ptop-${VERSION}.1 +debian/tmp/usr/man/man1/pyacc-${VERSION}.1 +debian/tmp/usr/man/man1/relpath-${VERSION}.1 +debian/tmp/usr/man/man1/rmcvsdir-${VERSION}.1 +debian/tmp/usr/man/man1/rstconv-${VERSION}.1 +debian/tmp/usr/man/man1/unitdiff-${VERSION}.1 +debian/tmp/usr/man/man5/fpcmake-${VERSION}.5 +debian/tmp/usr/man/man5/ptop-${VERSION}.cfg.5 diff --git a/fp-utils.postinst.in b/fp-utils.postinst.in new file mode 100644 index 00000000..060b0025 --- /dev/null +++ b/fp-utils.postinst.in @@ -0,0 +1,72 @@ +#! /bin/sh + +set -e + +FPCDIR=/usr/lib/${DEB_HOST_MULTIARCH}/fpc + +# add alternatives +update-alternatives \ + --install ${FPCDIR}/default fp-utils ${FPCDIR}/${VERSION} ${PRIORITY} \ + --slave ${FPCDIR}/lexyacc fplexyacc ${FPCDIR}/${VERSION}/lexyacc \ + --slave /usr/bin/chmcmd chmcmd /usr/bin/chmcmd-${VERSION} \ + --slave /usr/bin/chmls chmls /usr/bin/chmls-${VERSION} \ + --slave /usr/bin/ifpc ifpc /usr/bin/ifpc-${VERSION} \ + --slave /usr/bin/fppkg fppkg /usr/bin/fppkg-${VERSION} \ + --slave /usr/bin/grab_vcsa grab_vcsa /usr/bin/grab_vcsa-${VERSION} \ + --slave /usr/bin/instantfpc instantfpc /usr/bin/ifpc-${VERSION} \ + --slave /usr/bin/ppufiles ppufiles /usr/bin/ppufiles-${VERSION} \ + --slave /usr/bin/ppudump ppudump /usr/bin/ppudump-${VERSION} \ + --slave /usr/bin/ppumove ppumove /usr/bin/ppumove-${VERSION} \ + --slave /usr/bin/ppdep ppdep /usr/bin/ppdep-${VERSION} \ + --slave /usr/bin/ptop ptop /usr/bin/ptop-${VERSION} \ + --slave /usr/bin/rstconv rstconv /usr/bin/rstconv-${VERSION} \ + --slave /usr/bin/data2inc data2inc /usr/bin/data2inc-${VERSION} \ + --slave /usr/bin/bin2obj bin2obj /usr/bin/bin2obj-${VERSION} \ + --slave /usr/bin/delp delp /usr/bin/delp-${VERSION} \ + --slave /usr/bin/plex plex /usr/bin/plex-${VERSION} \ + --slave /usr/bin/pyacc pyacc /usr/bin/pyacc-${VERSION} \ + --slave /usr/bin/h2pas h2pas /usr/bin/h2pas-${VERSION} \ + --slave /usr/bin/h2paspp h2paspp /usr/bin/h2paspp-${VERSION} \ + --slave /usr/bin/postw32 postw32 /usr/bin/postw32-${VERSION} \ + --slave /usr/bin/fpclasschart fpclasschart /usr/bin/fpclasschart-${VERSION} \ + --slave /usr/bin/fpcmake fpcmake /usr/bin/fpcmake-${VERSION} \ + --slave /usr/bin/fpcsubst fpcsubst /usr/bin/fpcsubst-${VERSION} \ + --slave /usr/bin/fprcp fprcp /usr/bin/fprcp-${VERSION} \ + --slave /usr/bin/fpdoc fpdoc /usr/bin/fpdoc-${VERSION} \ + --slave /usr/bin/makeskel makeskel /usr/bin/makeskel-${VERSION} \ + --slave /usr/bin/relpath relpath /usr/bin/relpath-${VERSION} \ + --slave /usr/bin/rmcvsdir rmcvsdir /usr/bin/rmcvsdir-${VERSION} \ + --slave /usr/bin/unitdiff unitdiff /usr/bin/unitdiff-${VERSION} \ + --slave /usr/share/man/man1/chmcmd.1.gz chmcmd.1.gz /usr/share/man/man1/chmcmd-${VERSION}.1.gz \ + --slave /usr/share/man/man1/chmls.1.gz chmls.1.gz /usr/share/man/man1/chmls-${VERSION}.1.gz \ + --slave /usr/share/man/man1/ifpc.1.gz ifpc.1.gz /usr/share/man/man1/ifpc-${VERSION}.1.gz \ + --slave /usr/share/man/man1/fppkg.1.gz fppkg.1.gz /usr/share/man/man1/fppkg-${VERSION}.1.gz \ + --slave /usr/share/man/man1/instantfpc.1.gz instantfpc.1.gz /usr/share/man/man1/ifpc-${VERSION}.1.gz \ + --slave /usr/share/man/man1/bin2obj.1.gz bin2obj.1.gz /usr/share/man/man1/bin2obj-${VERSION}.1.gz \ + --slave /usr/share/man/man1/data2inc.1.gz data2inc.1.gz /usr/share/man/man1/data2inc-${VERSION}.1.gz \ + --slave /usr/share/man/man1/fprcp.1.gz fprcp.1.gz /usr/share/man/man1/fprcp-${VERSION}.1.gz \ + --slave /usr/share/man/man1/h2paspp.1.gz h2paspp.1.gz /usr/share/man/man1/h2paspp-${VERSION}.1.gz \ + --slave /usr/share/man/man1/makeskel.1.gz makeskel.1.gz /usr/share/man/man1/makeskel-${VERSION}.1.gz \ + --slave /usr/share/man/man1/postw32.1.gz postw32.1.gz /usr/share/man/man1/postw32-${VERSION}.1.gz \ + --slave /usr/share/man/man1/relpath.1.gz relpath.1.gz /usr/share/man/man1/relpath-${VERSION}.1.gz \ + --slave /usr/share/man/man1/rmcvsdir.1.gz rmcvsdir.1.gz /usr/share/man/man1/rmcvsdir-${VERSION}.1.gz \ + --slave /usr/share/man/man1/unitdiff.1.gz unitdiff.1.gz /usr/share/man/man1/unitdiff-${VERSION}.1.gz \ + --slave /usr/share/man/man1/delp.1.gz delp.1.gz /usr/share/man/man1/delp-${VERSION}.1.gz \ + --slave /usr/share/man/man1/fpcmake.1.gz fpcmake.1.gz /usr/share/man/man1/fpcmake-${VERSION}.1.gz \ + --slave /usr/share/man/man1/fpcsubst.1.gz fpcsubst.1.gz /usr/share/man/man1/fpcsubst-${VERSION}.1.gz \ + --slave /usr/share/man/man1/h2pas.1.gz h2pas.1.gz /usr/share/man/man1/h2pas-${VERSION}.1.gz \ + --slave /usr/share/man/man1/plex.1.gz plex.1.gz /usr/share/man/man1/plex-${VERSION}.1.gz \ + --slave /usr/share/man/man1/ppdep.1.gz ppdep.1.gz /usr/share/man/man1/ppdep-${VERSION}.1.gz \ + --slave /usr/share/man/man1/ppudump.1.gz ppudump.1.gz /usr/share/man/man1/ppudump-${VERSION}.1.gz \ + --slave /usr/share/man/man1/ppufiles.1.gz ppufiles.1.gz /usr/share/man/man1/ppufiles-${VERSION}.1.gz \ + --slave /usr/share/man/man1/ppumove.1.gz ppumove.1.gz /usr/share/man/man1/ppumove-${VERSION}.1.gz \ + --slave /usr/share/man/man1/ptop.1.gz ptop.1.gz /usr/share/man/man1/ptop-${VERSION}.1.gz \ + --slave /usr/share/man/man1/pyacc.1.gz pyacc.1.gz /usr/share/man/man1/pyacc-${VERSION}.1.gz \ + --slave /usr/share/man/man1/rstconv.1.gz rstconv.1.gz /usr/share/man/man1/rstconv-${VERSION}.1.gz \ + --slave /usr/share/man/man1/fpdoc.1.gz fpdoc.1.gz /usr/share/man/man1/fpdoc-${VERSION}.1.gz \ + --slave /usr/share/man/man1/fpclasschart.1.gz fpclasschart.1.gz /usr/share/man/man1/fpclasschart-${VERSION}.1.gz \ + --slave /usr/share/man/man5/fpcmake.5.gz fpcmake.5.gz /usr/share/man/man5/fpcmake-${VERSION}.5.gz \ + --slave /usr/share/man/man5/ptop.cfg.5.gz ptop.cfg.5.gz /usr/share/man/man5/ptop-${VERSION}.cfg.5.gz + +# Debhelper code +#DEBHELPER# diff --git a/fp-utils.prerm.in b/fp-utils.prerm.in new file mode 100644 index 00000000..e18a55ad --- /dev/null +++ b/fp-utils.prerm.in @@ -0,0 +1,12 @@ +#! /bin/sh + +set -e + +FPCDIR=/usr/lib/${DEB_HOST_MULTIARCH}/fpc + +# remove alternatives +update-alternatives \ + --remove fp-utils ${FPCDIR}/${VERSION} + +# Debhelper code +#DEBHELPER# diff --git a/fpc-depends.in b/fpc-depends.in new file mode 100755 index 00000000..ddc3c348 --- /dev/null +++ b/fpc-depends.in @@ -0,0 +1,65 @@ +#!/usr/bin/perl + +# Copyright (c) 2005 Rafael Laboissiere +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +=head1 NAME + +fpc-depends - calculates free pascal dependencies + +=cut + +use strict; +use warnings; +use Debian::Debhelper::Dh_Lib; + +=head1 SYNOPSIS + +B [S>] + +=head1 DESCRIPTION + +fpc-depends is a debhelper-like program that is responsible for +generating the ${fpc-abi:Depends} substitutions and adding them to +substvars files. + +If you use this program, your package must build-depend on fp-utils +(>= 2.4.2-1). + + +=cut + +init (); + +foreach my $package (@{$dh{DOPACKAGES}}) { + delsubstvar($package, "fpc-abi:Depends"); + addsubstvar($package, "fpc-abi:Depends", "fpc-abi-${VERSION}"); +} + +=head1 SEE ALSO + +L + +This program is not part of debhelper. + +=head1 AUTHOR + +Torsten Werner + +Most ideas borrowed from octave-depends by Rafael Laboissiere +. + +=cut diff --git a/fpc-source.install.in b/fpc-source.install.in new file mode 100644 index 00000000..aa14a925 --- /dev/null +++ b/fpc-source.install.in @@ -0,0 +1,4 @@ +#! /usr/bin/dh-exec +usr/share/fpcsrc/*/compiler +usr/share/fpcsrc/*/packages +usr/share/fpcsrc/*/rtl diff --git a/fpc-source.links b/fpc-source.links new file mode 100755 index 00000000..c8653143 --- /dev/null +++ b/fpc-source.links @@ -0,0 +1,2 @@ +#! /usr/bin/dh-exec +/usr/share/fpcsrc/${DEB_UPSTREAM_MAIN_VERSION} /usr/share/fpcsrc/default diff --git a/fpc-source.lintian-overrides b/fpc-source.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fpc-source.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fpc-source.lintian-overrides.in b/fpc-source.lintian-overrides.in new file mode 100644 index 00000000..6ccd1d87 --- /dev/null +++ b/fpc-source.lintian-overrides.in @@ -0,0 +1,4 @@ +# False positive, this is a Pascal header file +fpc-source${PACKAGESUFFIX}: extra-license-file +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fpc.lintian-overrides b/fpc.lintian-overrides new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fpc.lintian-overrides @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/fpc.lintian-overrides.in b/fpc.lintian-overrides.in new file mode 100644 index 00000000..82802734 --- /dev/null +++ b/fpc.lintian-overrides.in @@ -0,0 +1,2 @@ +# Spelling error in upstream license text +spelling-error-in-copyright orignal original diff --git a/gbp.conf b/gbp.conf new file mode 100644 index 00000000..45b55b53 --- /dev/null +++ b/gbp.conf @@ -0,0 +1,16 @@ +[DEFAULT] +pristine-tar = True +cleaner = /bin/true + +[import-orig] +filter = [ 'fpcsrc/packages/gnome1', 'fpcsrc/packages/gtk1', + 'fpcsrc/packages/imlib', 'fpcsrc/packages/fpgtk', + 'fpcsrc/utils/fpdoc/fpde', 'fpcsrc/utils/fpmc' ] + +[buildpackage] +pbuilder = True +pbuilder-options=--source-only-changes + +[dch] +git-author = True +full = True diff --git a/moveexamples b/moveexamples new file mode 100644 index 00000000..8dde6a9a --- /dev/null +++ b/moveexamples @@ -0,0 +1,71 @@ +#!/bin/sh + +set -e + +EXAMPLE_TEMP=$1 +DOC_DIR=$2 +VERSION=$3 + +move_examples() +{ + local pkgName=$1 + local pkgContent=$2 + # Make examples dir + install -d -m 755 ${DOC_DIR}/${pkgName}/${VERSION}/examples + for package in ${pkgContent} + do + EXAMPLE_TEMP_DIR="$EXAMPLE_TEMP/${package}/examples" + if [ -d "$EXAMPLE_TEMP_DIR" ]; then + echo "Moving examples of ${package}" + EXAMPLE_INSTALL_DIR="${DOC_DIR}/${pkgName}/${VERSION}/examples/${package}" + # Move dir renaming it + if [ -e "${EXAMPLE_INSTALL_DIR}" ] + then + echo "#### \"${EXAMPLE_INSTALL_DIR}\" is in the way, please remove it first ####" + exit 255 + else + mv -v -f "${EXAMPLE_TEMP_DIR}" "${EXAMPLE_INSTALL_DIR}" + # Remove empty directories: + rmdir --ignore-fail-on-non-empty "${EXAMPLE_INSTALL_DIR}" + fi + fi + DOC_TEMP_DIR="$EXAMPLE_TEMP/${package}" + if [ -d "$DOC_TEMP_DIR" ]; then + echo "Moving documentation of ${package}" + DOC_INSTALL_DIR="${DOC_DIR}/${pkgName}/${VERSION}/${package}" + # Move dir renaming it + if [ -e "${DOC_INSTALL_DIR}" ] + then + echo "#### \"${DOC_INSTALL_DIR}\" is in the way, please remove it first ####" + exit 255 + else + mv -v -f "${DOC_TEMP_DIR}" "${DOC_INSTALL_DIR}" + # Remove empty directories: + rmdir --ignore-fail-on-non-empty "${DOC_INSTALL_DIR}" + fi + fi + done + + # Remove empty directories: + rmdir --parents --ignore-fail-on-non-empty ${DOC_DIR}/${pkgName}/${VERSION}/examples +} + +echo '**** Copying examples ****' +PACKAGE_LIST='debian/'*'.install.in' + +for PACKAGE_FILE in ${PACKAGE_LIST} +do + PACKAGE_NAME=`basename "${PACKAGE_FILE}" '.install.in'` + PACKAGE_CONTENT=`grep 'usr/lib/${DEB_HOST_MULTIARCH}/fpc' "${PACKAGE_FILE}" | awk '{print $1}' | sed -e 's@.*/\([^/]\)@\1@' | sed -e 's/\*//'` + echo ' **** PACKAGE_NAME = "'${PACKAGE_NAME}'"' + echo ' **** PACKAGE_CONTENT = "'${PACKAGE_CONTENT}'"' + move_examples "${PACKAGE_NAME}" "${PACKAGE_CONTENT}" +done + +echo '**** Examples copied ****' + +if [ -d $EXAMPLE_TEMP ] ; then + echo "Example dir should be empty now or the rmdir command will fail, showing current content follows:" + ls -al $EXAMPLE_TEMP + rmdir $EXAMPLE_TEMP +fi diff --git a/orig-tar.sh b/orig-tar.sh new file mode 100755 index 00000000..9a57dc29 --- /dev/null +++ b/orig-tar.sh @@ -0,0 +1,39 @@ +#!/bin/sh -xe + +PACKAGE_NAME=fpc +TMP_DIR=`/bin/mktemp -d -t ${PACKAGE_NAME}.XXXXXX` || exit 1 +ORIG_PATH=$(pwd) + +while test $# -gt 0 +do + case $1 in + --upstream-version) + shift + VERSION=$1 + ;; + *) + ORIG_SRC_TAR=$(readlink -m $1) + ;; + esac + shift +done + +ORIG_SRC_DIR=${PACKAGE_NAME} +DEB_SRC_DIR=${PACKAGE_NAME}-${VERSION}+dfsg +DEB_SRC_TAR=${PACKAGE_NAME}_${VERSION}+dfsg.orig.tar.gz + +cd ${TMP_DIR} +tar -axf ${ORIG_SRC_TAR} +mv ${ORIG_SRC_DIR}* ${DEB_SRC_DIR} +cd ${DEB_SRC_DIR} +find -name Makefile.fpc -execdir sh -c 'rm $(basename {} .fpc)' ';' +find -regex '.*\.\(a\|or?\|so\.*\|ppu\|compiled\|exe\|dll\|jar\)' -delete +find -name '*.pp' -exec chmod a-x {} ';' +# https://bugs.freepascal.org/view.php?id=32288 (the fact the bug is closed +# doesn't mean the issue is resolved) +rm fpcsrc/packages/fcl-js/src/jsminifier.pp +cd .. +tar -acf ${DEB_SRC_TAR} ${DEB_SRC_DIR} +cd ${ORIG_PATH} +mv ${TMP_DIR}/${DEB_SRC_TAR} ../ +rm -rf ${TMP_DIR} diff --git a/patches/add-arm64-support.patch b/patches/add-arm64-support.patch new file mode 100644 index 00000000..cff518d8 --- /dev/null +++ b/patches/add-arm64-support.patch @@ -0,0 +1,37068 @@ +Description: Upstream includes in svn already arm64 support + This patch was created with a recipe from bug 784569 + minor changes by Elbrus: + mkdir a b + wget ftp://ftp.freepascal.org/pub/fpc/beta/3.0.0-rc2/source/fpcbuild-3.0.0rc2.tar.gz + tar xzf fpcbuild-3.0.0rc2.tar.gz -C a --strip-components=1 + svn export -r 32015 http://svn.freepascal.org/svn/fpc/branches/fixes_3_0_ios b/fpcsrc + . + find [ab]/fpcsrc -name Makefile -delete + find [ab]/fpcsrc -name '*.[ao]' -o -name '*.exe' -delete + + ( cd b && ../a/install/updfpmkver 3.0.0rc2 ) + ( cd b && ../a/install/updmkver 3.0.0rc2 true ) + cp -rT [ab]/fpcsrc/installer + cp -rT [ab]/fpcsrc/packages/chm + perl -i -pe "s/(patch_nr\s*=\s*)'.*'/\$1'0'/;" b/fpcsrc/compiler/version.pas + perl -i -pe "s/(minorpatch\s*=\s*)'.*'/\$1'rc2'/;" b/fpcsrc/compiler/version.pas + . + # delete directories univint and tests + . + git diff --no-prefix [ab]/fpcsrc > add-arm64-support.patch + . + # apply on top of full debian patches + quilt refresh + . + . + This patch was updated manually by elbrus upon merging 3.0.2 which should + contain support for AArch64, but too much of the patch still applied cleanly. +Author: Edmund Grimley Evans +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=784569 + +Index: fpc/fpcsrc/Makefile.fpc +=================================================================== +--- fpc.orig/fpcsrc/Makefile.fpc ++++ fpc/fpcsrc/Makefile.fpc +@@ -78,6 +78,9 @@ endif + ifeq ($(CPU_TARGET),avr) + PPSUF=avr + endif ++ifeq ($(CPU_TARGET),aarch64) ++PPSUF=a64 ++endif + + # cross compilers uses full cpu_target, not just ppc-suffix + # (except if the target cannot run a native compiler) +Index: fpc/fpcsrc/compiler/Makefile.fpc +=================================================================== +--- fpc.orig/fpcsrc/compiler/Makefile.fpc ++++ fpc/fpcsrc/compiler/Makefile.fpc +@@ -32,7 +32,7 @@ fpcdir=.. + unexport FPC_VERSION FPC_COMPILERINFO + + # Which platforms are ready for inclusion in the cycle +-CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr jvm i8086 ++CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr jvm i8086 aarch64 + + # All supported targets used for clean + ALLTARGETS=$(CYCLETARGETS) +@@ -80,6 +80,9 @@ endif + ifdef I8086 + PPC_TARGET=i8086 + endif ++ifdef AARCH64 ++PPC_TARGET=aarch64 ++endif + + # Default is to generate a compiler for the same + # platform as CPU_TARGET (a native compiler) +@@ -205,6 +208,9 @@ endif + ifeq ($(CPC_TARGET),i8086) + CPUSUF=8086 + endif ++ifeq ($(CPC_TARGET),aarch64) ++CPUSUF=a64 ++endif + + # Do not define the default -d$(CPU_TARGET) because that + # will conflict with our -d$(CPC_TARGET) +@@ -400,7 +406,7 @@ endif + # CPU targets + ##################################################################### + +-PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 alpha vis ia64 mips mipsel avr jvm i8086 ++PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 alpha vis ia64 mips mipsel avr jvm i8086 aarch64 + INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS))) + + .PHONY: $(PPC_TARGETS) $(INSTALL_TARGETS) +@@ -455,12 +461,12 @@ tempclean: + -$(DEL) $(PPCROSSNAME) $(TEMPNAME) $(TEMPNAME1) $(TEMPNAME2) $(TEMPNAME3) $(MSG2INC) pp1.wpo pp2.wpo + + execlean : +- -$(DEL) ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) ppc8086$(EXEEXT) $(EXENAME) $(TEMPWPONAME1) $(TEMPWPONAME2) ++ -$(DEL) ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) ppc8086$(EXEEXT) ppca64$(EXEEXT) $(EXENAME) $(TEMPWPONAME1) $(TEMPWPONAME2) + + $(addsuffix _clean,$(ALLTARGETS)): + -$(DELTREE) $(addprefix $(subst _clean,,$@),/units) + -$(DEL) $(addprefix $(subst _clean,,$@)/,*$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)) +- -$(DEL) $(addprefix $(subst _clean,,$@)/,ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) ppc8086$(EXEEXT) $(EXENAME)) ++ -$(DEL) $(addprefix $(subst _clean,,$@)/,ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) ppc8086$(EXEEXT) ppca64$(EXEEXT) $(EXENAME)) + + cycleclean: cleanall $(addsuffix _clean,$(CPC_TARGET)) + -$(DEL) $(EXENAME) +Index: fpc/fpcsrc/compiler/aarch64/a64att.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/a64att.inc ++++ fpc/fpcsrc/compiler/aarch64/a64att.inc +@@ -1,15 +1,37 @@ +-{ don't edit, this file is generated from armins.dat } ++{ don't edit, this file is generated from a64ins.dat } + ( +-'nop', ++'none', + 'b', +-'cb', +-'tb', ++'cbz', ++'cbnz', ++'tbz', ++'tbnz', + 'bl', + 'blr', + 'br', + 'ret', ++'brk', ++'hlt', ++'hvc', ++'smc', ++'svc', ++'eret', ++'dcps1', ++'dcps2', ++'dcps3', ++'drps', ++'dc', ++'at', ++'tlbi', ++'hint', ++'clrex', ++'dsb', ++'dmb', ++'isb', + 'ldr', + 'str', ++'ldur', ++'stur', + 'ldp', + 'stp', + 'ldnp', +@@ -17,40 +39,66 @@ + 'ldtr', + 'sttr', + 'ldxr', ++'ldxp', + 'stxr', ++'stxp', + 'ldar', + 'stlr', + 'ldaxr', + 'stlxr', ++'stlxp', ++'ld1', ++'ld2', ++'ld3', ++'ld4', ++'st1', ++'st2', ++'st3', ++'st4', ++'ld1r', ++'ld2r', ++'ld3r', ++'ld4r', + 'prfm', ++'prfum', + 'add', +-'adc', + 'sub', +-'sbc', + 'cmp', + 'cmn', +-'mov', + 'and', +-'bic', + 'eor', +-'eon', + 'orr', + 'orn', + 'tst', +-'mvn', ++'movz', ++'movn', + 'movk', ++'mrs', ++'msr', + 'adrp', + 'adr', + 'bfm', + 'sbfm', + 'ubfm', + 'extr', +-'sxt', +-'uxt', ++'adc', ++'sbc', ++'bic', ++'eon', + 'asrv', +-'llslv', ++'lslv', + 'lsrv', + 'rorv', ++'madd', ++'msub', ++'smaddl', ++'smsubl', ++'smulh', ++'umaddl', ++'umsubl', ++'umulh', ++'sdiv', ++'udiv', + 'cls', + 'clz', + 'rbit', +@@ -63,33 +111,39 @@ + 'csneg', + 'ccmn', + 'ccmp', +-'madd', +-'msub', +-'smaddl', +-'smsubl', +-'smulh', +-'umaddl', +-'umsubl', +-'umulh', +-'sdiv', +-'udiv', +-'neg', ++'nop', ++'yield', ++'wfe', ++'wfi', ++'sev', ++'sevl', ++'mov', ++'bfi', ++'bfxil', ++'sbfiz', ++'sbfx', ++'ubfiz', ++'ubfx', + 'asr', + 'lsl', + 'lsr', + 'ror', +-'cset', +-'csetm', +-'cinc', +-'cinv', +-'cneg', ++'sxt', ++'uxt', ++'neg', + 'ngc', ++'mvn', + 'mneg', + 'mul', + 'smnegl', + 'smull', + 'umnegl', + 'umull', ++'cset', ++'csetm', ++'cinc', ++'cinv', ++'cneg', + 'fmov', + 'fcvt', + 'fcvtas', +@@ -104,13 +158,13 @@ + 'fcvtzu', + 'scvtf', + 'ucvtf', +-'fprinta', +-'fprinti', +-'fprintm', +-'fprintn', +-'fprintp', +-'fprintx', +-'fprintz', ++'frinta', ++'frinti', ++'frintm', ++'frintn', ++'frintp', ++'frintx', ++'frintz', + 'fabs', + 'fneg', + 'fsqrt', +@@ -130,5 +184,8 @@ + 'fcmpe', + 'fccmp', + 'fcmmpe', +-'fcsel' ++'fcsel', ++'umov', ++'ins', ++'movi' + ); +Index: fpc/fpcsrc/compiler/aarch64/a64atts.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/a64atts.inc ++++ fpc/fpcsrc/compiler/aarch64/a64atts.inc +@@ -1,8 +1,65 @@ +-{ don't edit, this file is generated from armins.dat } ++{ don't edit, this file is generated from a64ins.dat } + ( + attsufNONE, + attsufNONE, + attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, + attsufNONE, + attsufNONE, + attsufNONE, +Index: fpc/fpcsrc/compiler/aarch64/a64ins.dat +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/a64ins.dat ++++ fpc/fpcsrc/compiler/aarch64/a64ins.dat +@@ -1,10 +1,15 @@ +-[NOP] ++; invalid ++[NONE] + + [B] + +-[CB] ++[CBZ] ++ ++[CBNZ] + +-[TB] ++[TBZ] ++ ++[TBNZ] + + [BL] + +@@ -14,10 +19,50 @@ + + [RET] + ++[BRK] ++ ++[HLT] ++ ++[HVC] ++ ++[SMC] ++ ++[SVC] ++ ++[ERET] ++ ++[DCPS1] ++ ++[DCPS2] ++ ++[DCPS3] ++ ++[DRPS] ++ ++[DC] ++ ++[AT] ++ ++[TLBI] ++ ++[HINT] ++ ++[CLREX] ++ ++[DSB] ++ ++[DMB] ++ ++[ISB] ++ + [LDR] + + [STR] + ++[LDUR] ++ ++[STUR] ++ + [LDP] + + [STP] +@@ -32,8 +77,12 @@ + + [LDXR] + ++[LDXP] ++ + [STXR] + ++[STXP] ++ + [LDAR] + + [STLR] +@@ -42,40 +91,64 @@ + + [STLXR] + ++[STLXP] ++ ++[LD1] ++ ++[LD2] ++ ++[LD3] ++ ++[LD4] ++ ++[ST1] ++ ++[ST2] ++ ++[ST3] ++ ++[ST4] ++ ++[LD1R] ++ ++[LD2R] ++ ++[LD3R] ++ ++[LD4R] ++ + [PRFM] + +-[ADD] ++[PRFUM] + +-[ADC] ++[ADD] + + [SUB] + +-[SBC] +- + [CMP] + + [CMN] + +-[MOV] +- + [AND] + +-[BIC] +- + [EOR] + +-[EON] +- + [ORR] + + [ORN] + + [TST] + +-[MVN] ++[MOVZ] ++ ++[MOVN] + + [MOVK] + ++[MRS] ++ ++[MSR] ++ + [ADRP] + + [ADR] +@@ -88,18 +161,42 @@ + + [EXTR] + +-[SXT] ++[ADC] + +-[UXT] ++[SBC] ++ ++[BIC] ++ ++[EON] + + [ASRV] + +-[LLSLV] ++[LSLV] + + [LSRV] + + [RORV] + ++[MADD] ++ ++[MSUB] ++ ++[SMADDL] ++ ++[SMSUBL] ++ ++[SMULH] ++ ++[UMADDL] ++ ++[UMSUBL] ++ ++[UMULH] ++ ++[SDIV] ++ ++[UDIV] ++ + [CLS] + + [CLZ] +@@ -124,29 +221,33 @@ + + [CCMP] + +-[MADD] ++; Aliases ++; they are not generated by the compiler, they are only used for inline assembler ++[NOP] + +-[MSUB] ++[YIELD] + +-[SMADDL] ++[WFE] + +-[SMSUBL] ++[WFI] + +-[SMULH] ++[SEV] + +-[UMADDL] ++[SEVL] + +-[UMSUBL] ++[MOV] + +-[UMULH] ++[BFI] + +-[SDIV] ++[BFXIL] + +-[UDIV] ++[SBFIZ] + +-; Aliases +-; they are not generated by the compiler, they are only used for inline assembler +-[NEG] ++[SBFX] ++ ++[UBFIZ] ++ ++[UBFX] + + [ASR] + +@@ -156,18 +257,16 @@ + + [ROR] + +-[CSET] +- +-[CSETM] +- +-[CINC] ++[SXT] + +-[CINV] ++[UXT] + +-[CNEG] ++[NEG] + + [NGC] + ++[MVN] ++ + [MNEG] + + [MUL] +@@ -180,6 +279,16 @@ + + [UMULL] + ++[CSET] ++ ++[CSETM] ++ ++[CINC] ++ ++[CINV] ++ ++[CNEG] ++ + [FMOV] + + [FCVT] +@@ -208,19 +317,19 @@ + + [UCVTF] + +-[FPRINTA] ++[FRINTA] + +-[FPRINTI] ++[FRINTI] + +-[FPRINTM] ++[FRINTM] + +-[FPRINTN] ++[FRINTN] + +-[FPRINTP] ++[FRINTP] + +-[FPRINTX] ++[FRINTX] + +-[FPRINTZ] ++[FRINTZ] + + [FABS] + +@@ -262,3 +371,8 @@ + + [FCSEL] + ++[UMOV] ++ ++[INS] ++ ++[MOVI] +Index: fpc/fpcsrc/compiler/aarch64/a64op.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/a64op.inc ++++ fpc/fpcsrc/compiler/aarch64/a64op.inc +@@ -1,15 +1,37 @@ +-{ don't edit, this file is generated from armins.dat } ++{ don't edit, this file is generated from a64ins.dat } + ( +-A_NOP, ++A_NONE, + A_B, +-A_CB, +-A_TB, ++A_CBZ, ++A_CBNZ, ++A_TBZ, ++A_TBNZ, + A_BL, + A_BLR, + A_BR, + A_RET, ++A_BRK, ++A_HLT, ++A_HVC, ++A_SMC, ++A_SVC, ++A_ERET, ++A_DCPS1, ++A_DCPS2, ++A_DCPS3, ++A_DRPS, ++A_DC, ++A_AT, ++A_TLBI, ++A_HINT, ++A_CLREX, ++A_DSB, ++A_DMB, ++A_ISB, + A_LDR, + A_STR, ++A_LDUR, ++A_STUR, + A_LDP, + A_STP, + A_LDNP, +@@ -17,40 +39,66 @@ A_STNP, + A_LDTR, + A_STTR, + A_LDXR, ++A_LDXP, + A_STXR, ++A_STXP, + A_LDAR, + A_STLR, + A_LDAXR, + A_STLXR, ++A_STLXP, ++A_LD1, ++A_LD2, ++A_LD3, ++A_LD4, ++A_ST1, ++A_ST2, ++A_ST3, ++A_ST4, ++A_LD1R, ++A_LD2R, ++A_LD3R, ++A_LD4R, + A_PRFM, ++A_PRFUM, + A_ADD, +-A_ADC, + A_SUB, +-A_SBC, + A_CMP, + A_CMN, +-A_MOV, + A_AND, +-A_BIC, + A_EOR, +-A_EON, + A_ORR, + A_ORN, + A_TST, +-A_MVN, ++A_MOVZ, ++A_MOVN, + A_MOVK, ++A_MRS, ++A_MSR, + A_ADRP, + A_ADR, + A_BFM, + A_SBFM, + A_UBFM, + A_EXTR, +-A_SXT, +-A_UXT, ++A_ADC, ++A_SBC, ++A_BIC, ++A_EON, + A_ASRV, +-A_LLSLV, ++A_LSLV, + A_LSRV, + A_RORV, ++A_MADD, ++A_MSUB, ++A_SMADDL, ++A_SMSUBL, ++A_SMULH, ++A_UMADDL, ++A_UMSUBL, ++A_UMULH, ++A_SDIV, ++A_UDIV, + A_CLS, + A_CLZ, + A_RBIT, +@@ -63,33 +111,39 @@ A_CSINV, + A_CSNEG, + A_CCMN, + A_CCMP, +-A_MADD, +-A_MSUB, +-A_SMADDL, +-A_SMSUBL, +-A_SMULH, +-A_UMADDL, +-A_UMSUBL, +-A_UMULH, +-A_SDIV, +-A_UDIV, +-A_NEG, ++A_NOP, ++A_YIELD, ++A_WFE, ++A_WFI, ++A_SEV, ++A_SEVL, ++A_MOV, ++A_BFI, ++A_BFXIL, ++A_SBFIZ, ++A_SBFX, ++A_UBFIZ, ++A_UBFX, + A_ASR, + A_LSL, + A_LSR, + A_ROR, +-A_CSET, +-A_CSETM, +-A_CINC, +-A_CINV, +-A_CNEG, ++A_SXT, ++A_UXT, ++A_NEG, + A_NGC, ++A_MVN, + A_MNEG, + A_MUL, + A_SMNEGL, + A_SMULL, + A_UMNEGL, + A_UMULL, ++A_CSET, ++A_CSETM, ++A_CINC, ++A_CINV, ++A_CNEG, + A_FMOV, + A_FCVT, + A_FCVTAS, +@@ -104,13 +158,13 @@ A_FCVTZS, + A_FCVTZU, + A_SCVTF, + A_UCVTF, +-A_FPRINTA, +-A_FPRINTI, +-A_FPRINTM, +-A_FPRINTN, +-A_FPRINTP, +-A_FPRINTX, +-A_FPRINTZ, ++A_FRINTA, ++A_FRINTI, ++A_FRINTM, ++A_FRINTN, ++A_FRINTP, ++A_FRINTX, ++A_FRINTZ, + A_FABS, + A_FNEG, + A_FSQRT, +@@ -130,5 +184,8 @@ A_FCMP, + A_FCMPE, + A_FCCMP, + A_FCMMPE, +-A_FCSEL ++A_FCSEL, ++A_UMOV, ++A_INS, ++A_MOVI + ); +Index: fpc/fpcsrc/compiler/aarch64/a64reg.dat +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/a64reg.dat ++++ fpc/fpcsrc/compiler/aarch64/a64reg.dat +@@ -70,169 +70,176 @@ W30,$01,$04,$1E,w30,30,30 + X30,$01,$05,$1E,x30,30,30 + WZR,$01,$04,$1F,wzr,31,31 + XZR,$01,$05,$1F,xzr,31,31 ++; sp and zr share the same register number, but we still have to be able to ++; differentiate them because some instructions can be encoded with both -> ++; use a different superregister after all ++WSP,$01,$04,$20,wsp,31,31 ++SP,$01,$05,$20,sp,31,31 + + + ; vfp registers +-B0,$04,$01,$00,b0,0,0 +-H0,$04,$03,$00,h0,0,0 +-S0,$04,$09,$00,s0,0,0 +-D0,$04,$0a,$00,d0,0,0 +-Q0,$04,$05,$00,q0,0,0 +-B1,$04,$01,$01,b1,1,1 +-H1,$04,$03,$01,h1,1,1 +-S1,$04,$09,$01,s1,1,1 +-D1,$04,$0a,$01,d1,1,1 +-Q1,$04,$05,$01,q1,1,1 +-B2,$04,$01,$02,b2,2,2 +-H2,$04,$03,$02,h2,2,2 +-S2,$04,$09,$02,s2,2,2 +-D2,$04,$0a,$02,d2,2,2 +-Q2,$04,$05,$02,q2,2,2 +-B3,$04,$01,$03,b3,3,3 +-H3,$04,$03,$03,h3,3,3 +-S3,$04,$09,$03,s3,3,3 +-D3,$04,$0a,$03,d3,3,3 +-Q3,$04,$05,$03,q3,3,3 +-B4,$04,$01,$04,b4,4,4 +-H4,$04,$03,$04,h4,4,4 +-S4,$04,$09,$04,s4,4,4 +-D4,$04,$0a,$04,d4,4,4 +-Q4,$04,$05,$04,q4,4,4 +-B5,$04,$01,$05,b5,5,5 +-H5,$04,$03,$05,h5,5,5 +-S5,$04,$09,$05,s5,5,5 +-D5,$04,$0a,$05,d5,5,5 +-Q5,$04,$05,$05,q5,5,5 +-B6,$04,$01,$06,b6,6,6 +-H6,$04,$03,$06,h6,6,6 +-S6,$04,$09,$06,s6,6,6 +-D6,$04,$0a,$06,d6,6,6 +-Q6,$04,$05,$06,q6,6,6 +-B7,$04,$01,$07,b7,7,7 +-H7,$04,$03,$07,h7,7,7 +-S7,$04,$09,$07,s7,7,7 +-D7,$04,$0a,$07,d7,7,7 +-Q7,$04,$05,$07,q7,7,7 +-B8,$04,$01,$08,b8,8,8 +-H8,$04,$03,$08,h8,8,8 +-S8,$04,$09,$08,s8,8,8 +-D8,$04,$0a,$08,d8,8,8 +-Q8,$04,$05,$08,q8,8,8 +-B9,$04,$01,$09,b9,9,9 +-H9,$04,$03,$09,h9,9,9 +-S9,$04,$09,$09,s9,9,9 +-D9,$04,$0a,$09,d9,9,9 +-Q9,$04,$05,$09,q9,9,9 +-B10,$04,$01,$0A,b10,10,10 +-H10,$04,$03,$0A,h10,10,10 +-S10,$04,$09,$0A,s10,10,10 +-D10,$04,$0a,$0A,d10,10,10 +-Q10,$04,$05,$0A,q10,10,10 +-B11,$04,$01,$0B,b11,11,11 +-H11,$04,$03,$0B,h11,11,11 +-S11,$04,$09,$0B,s11,11,11 +-D11,$04,$0a,$0B,d11,11,11 +-Q11,$04,$05,$0B,q11,11,11 +-B12,$04,$01,$0C,b12,12,12 +-H12,$04,$03,$0C,h12,12,12 +-S12,$04,$09,$0C,s12,12,12 +-D12,$04,$0a,$0C,d12,12,12 +-Q12,$04,$05,$0C,q12,12,12 +-B13,$04,$01,$0D,b13,13,13 +-H13,$04,$03,$0D,h13,13,13 +-S13,$04,$09,$0D,s13,13,13 +-D13,$04,$0a,$0D,d13,13,13 +-Q13,$04,$05,$0D,q13,13,13 +-B14,$04,$01,$0E,b14,14,14 +-H14,$04,$03,$0E,h14,14,14 +-S14,$04,$09,$0E,s14,14,14 +-D14,$04,$0a,$0E,d14,14,14 +-Q14,$04,$05,$0E,q14,14,14 +-B15,$04,$01,$0F,b15,15,15 +-H15,$04,$03,$0F,h15,15,15 +-S15,$04,$09,$0F,s15,15,15 +-D15,$04,$0a,$0F,d15,15,15 +-Q15,$04,$05,$0F,q15,15,15 +-B16,$04,$01,$10,b16,16,16 +-H16,$04,$03,$10,h16,16,16 +-S16,$04,$09,$10,s16,16,16 +-D16,$04,$0a,$10,d16,16,16 +-Q16,$04,$05,$10,q16,16,16 +-B17,$04,$01,$11,b17,17,17 +-H17,$04,$03,$11,h17,17,17 +-S17,$04,$09,$11,s17,17,17 +-D17,$04,$0a,$11,d17,17,17 +-Q17,$04,$05,$11,q17,17,17 +-B18,$04,$01,$12,b18,18,18 +-H18,$04,$03,$12,h18,18,18 +-S18,$04,$09,$12,s18,18,18 +-D18,$04,$0a,$12,d18,18,18 +-Q18,$04,$05,$12,q18,18,18 +-B19,$04,$01,$13,b19,19,19 +-H19,$04,$03,$13,h19,19,19 +-S19,$04,$09,$13,s19,19,19 +-D19,$04,$0a,$13,d19,19,19 +-Q19,$04,$05,$13,q19,19,19 +-B20,$04,$01,$14,b20,20,20 +-H20,$04,$03,$14,h20,20,20 +-S20,$04,$09,$14,s20,20,20 +-D20,$04,$0a,$14,d20,20,20 +-Q20,$04,$05,$14,q20,20,20 +-B21,$04,$01,$15,b21,21,21 +-H21,$04,$03,$15,h21,21,21 +-S21,$04,$09,$15,s21,21,21 +-D21,$04,$0a,$15,d21,21,21 +-Q21,$04,$05,$15,q21,21,21 +-B22,$04,$01,$16,b22,22,22 +-H22,$04,$03,$16,h22,22,22 +-S22,$04,$09,$16,s22,22,22 +-D22,$04,$0a,$16,d22,22,22 +-Q22,$04,$05,$16,q22,22,22 +-B23,$04,$01,$17,b23,23,23 +-H23,$04,$03,$17,h23,23,23 +-S23,$04,$09,$17,s23,23,23 +-D23,$04,$0a,$17,d23,23,23 +-Q23,$04,$05,$17,q23,23,23 +-B24,$04,$01,$18,b24,24,24 +-H24,$04,$03,$18,h24,24,24 +-S24,$04,$09,$18,s24,24,24 +-D24,$04,$0a,$18,d24,24,24 +-Q24,$04,$05,$18,q24,24,24 +-B25,$04,$01,$19,b25,25,25 +-H25,$04,$03,$19,h25,25,25 +-S25,$04,$09,$19,s25,25,25 +-D25,$04,$0a,$19,d25,25,25 +-Q25,$04,$05,$19,q25,25,25 +-B26,$04,$01,$1A,b26,26,26 +-H26,$04,$03,$1A,h26,26,26 +-S26,$04,$09,$1A,s26,26,26 +-D26,$04,$0a,$1A,d26,26,26 +-Q26,$04,$05,$1A,q26,26,26 +-B27,$04,$01,$1B,b27,27,27 +-H27,$04,$03,$1B,h27,27,27 +-S27,$04,$09,$1B,s27,27,27 +-D27,$04,$0a,$1B,d27,27,27 +-Q27,$04,$05,$1B,q27,27,27 +-B28,$04,$01,$1C,b28,28,28 +-H28,$04,$03,$1C,h28,28,28 +-S28,$04,$09,$1C,s28,28,28 +-D28,$04,$0a,$1C,d28,28,28 +-Q28,$04,$05,$1C,q28,28,28 +-B29,$04,$01,$1D,b29,29,29 +-H29,$04,$03,$1D,h29,29,29 +-S29,$04,$09,$1D,s29,29,29 +-D29,$04,$0a,$1D,d29,29,29 +-Q29,$04,$05,$1D,q29,29,29 +-B30,$04,$01,$1E,b30,30,30 +-H30,$04,$03,$1E,h30,30,30 +-S30,$04,$09,$1E,s30,30,30 +-D30,$04,$0a,$1E,d30,30,30 +-Q30,$04,$05,$1E,q30,30,30 +-B31,$04,$01,$1F,b31,31,31 +-H31,$04,$03,$1F,h31,31,31 +-S31,$04,$09,$1F,s31,31,31 +-D31,$04,$0a,$1F,d31,31,31 +-Q31,$04,$05,$1F,q31,31,31 ++B0,$04,$01,$00,b0,64,64 ++H0,$04,$03,$00,h0,64,64 ++S0,$04,$09,$00,s0,64,64 ++D0,$04,$0a,$00,d0,64,64 ++Q0,$04,$05,$00,q0,64,64 ++B1,$04,$01,$01,b1,65,65 ++H1,$04,$03,$01,h1,65,65 ++S1,$04,$09,$01,s1,65,65 ++D1,$04,$0a,$01,d1,65,65 ++Q1,$04,$05,$01,q1,65,65 ++B2,$04,$01,$02,b2,66,66 ++H2,$04,$03,$02,h2,66,66 ++S2,$04,$09,$02,s2,66,66 ++D2,$04,$0a,$02,d2,66,66 ++Q2,$04,$05,$02,q2,66,66 ++B3,$04,$01,$03,b3,67,67 ++H3,$04,$03,$03,h3,67,67 ++S3,$04,$09,$03,s3,67,67 ++D3,$04,$0a,$03,d3,67,67 ++Q3,$04,$05,$03,q3,67,67 ++B4,$04,$01,$04,b4,68,68 ++H4,$04,$03,$04,h4,68,68 ++S4,$04,$09,$04,s4,68,68 ++D4,$04,$0a,$04,d4,68,68 ++Q4,$04,$05,$04,q4,68,68 ++B5,$04,$01,$05,b5,69,69 ++H5,$04,$03,$05,h5,69,69 ++S5,$04,$09,$05,s5,69,69 ++D5,$04,$0a,$05,d5,69,69 ++Q5,$04,$05,$05,q5,69,69 ++B6,$04,$01,$06,b6,70,70 ++H6,$04,$03,$06,h6,70,70 ++S6,$04,$09,$06,s6,70,70 ++D6,$04,$0a,$06,d6,70,70 ++Q6,$04,$05,$06,q6,70,70 ++B7,$04,$01,$07,b7,71,71 ++H7,$04,$03,$07,h7,71,71 ++S7,$04,$09,$07,s7,71,71 ++D7,$04,$0a,$07,d7,71,71 ++Q7,$04,$05,$07,q7,71,71 ++B8,$04,$01,$08,b8,72,72 ++H8,$04,$03,$08,h8,72,72 ++S8,$04,$09,$08,s8,72,72 ++D8,$04,$0a,$08,d8,72,72 ++Q8,$04,$05,$08,q8,72,72 ++B9,$04,$01,$09,b9,73,73 ++H9,$04,$03,$09,h9,73,73 ++S9,$04,$09,$09,s9,73,73 ++D9,$04,$0a,$09,d9,73,73 ++Q9,$04,$05,$09,q9,73,73 ++B10,$04,$01,$0A,b10,74,74 ++H10,$04,$03,$0A,h10,74,74 ++S10,$04,$09,$0A,s10,74,74 ++D10,$04,$0a,$0A,d10,74,74 ++Q10,$04,$05,$0A,q10,74,74 ++B11,$04,$01,$0B,b11,75,75 ++H11,$04,$03,$0B,h11,75,75 ++S11,$04,$09,$0B,s11,75,75 ++D11,$04,$0a,$0B,d11,75,75 ++Q11,$04,$05,$0B,q11,75,75 ++B12,$04,$01,$0C,b12,76,76 ++H12,$04,$03,$0C,h12,76,76 ++S12,$04,$09,$0C,s12,76,76 ++D12,$04,$0a,$0C,d12,76,76 ++Q12,$04,$05,$0C,q12,76,76 ++B13,$04,$01,$0D,b13,77,77 ++H13,$04,$03,$0D,h13,77,77 ++S13,$04,$09,$0D,s13,77,77 ++D13,$04,$0a,$0D,d13,77,77 ++Q13,$04,$05,$0D,q13,77,77 ++B14,$04,$01,$0E,b14,78,78 ++H14,$04,$03,$0E,h14,78,78 ++S14,$04,$09,$0E,s14,78,78 ++D14,$04,$0a,$0E,d14,78,78 ++Q14,$04,$05,$0E,q14,78,78 ++B15,$04,$01,$0F,b15,79,79 ++H15,$04,$03,$0F,h15,79,79 ++S15,$04,$09,$0F,s15,79,79 ++D15,$04,$0a,$0F,d15,79,79 ++Q15,$04,$05,$0F,q15,79,79 ++B16,$04,$01,$10,b16,80,80 ++H16,$04,$03,$10,h16,80,80 ++S16,$04,$09,$10,s16,80,80 ++D16,$04,$0a,$10,d16,80,80 ++Q16,$04,$05,$10,q16,80,80 ++B17,$04,$01,$11,b17,81,81 ++H17,$04,$03,$11,h17,81,81 ++S17,$04,$09,$11,s17,81,81 ++D17,$04,$0a,$11,d17,81,81 ++Q17,$04,$05,$11,q17,81,81 ++B18,$04,$01,$12,b18,82,82 ++H18,$04,$03,$12,h18,82,82 ++S18,$04,$09,$12,s18,82,82 ++D18,$04,$0a,$12,d18,82,82 ++Q18,$04,$05,$12,q18,82,82 ++B19,$04,$01,$13,b19,83,83 ++H19,$04,$03,$13,h19,83,83 ++S19,$04,$09,$13,s19,83,83 ++D19,$04,$0a,$13,d19,83,83 ++Q19,$04,$05,$13,q19,83,83 ++B20,$04,$01,$14,b20,84,84 ++H20,$04,$03,$14,h20,84,84 ++S20,$04,$09,$14,s20,84,84 ++D20,$04,$0a,$14,d20,84,84 ++Q20,$04,$05,$14,q20,84,84 ++B21,$04,$01,$15,b21,85,85 ++H21,$04,$03,$15,h21,85,85 ++S21,$04,$09,$15,s21,85,85 ++D21,$04,$0a,$15,d21,85,85 ++Q21,$04,$05,$15,q21,85,85 ++B22,$04,$01,$16,b22,86,86 ++H22,$04,$03,$16,h22,86,86 ++S22,$04,$09,$16,s22,86,86 ++D22,$04,$0a,$16,d22,86,86 ++Q22,$04,$05,$16,q22,86,86 ++B23,$04,$01,$17,b23,87,87 ++H23,$04,$03,$17,h23,87,87 ++S23,$04,$09,$17,s23,87,87 ++D23,$04,$0a,$17,d23,87,87 ++Q23,$04,$05,$17,q23,87,87 ++B24,$04,$01,$18,b24,88,88 ++H24,$04,$03,$18,h24,88,88 ++S24,$04,$09,$18,s24,88,88 ++D24,$04,$0a,$18,d24,88,88 ++Q24,$04,$05,$18,q24,88,88 ++B25,$04,$01,$19,b25,89,89 ++H25,$04,$03,$19,h25,89,89 ++S25,$04,$09,$19,s25,89,89 ++D25,$04,$0a,$19,d25,89,89 ++Q25,$04,$05,$19,q25,89,89 ++B26,$04,$01,$1A,b26,90,90 ++H26,$04,$03,$1A,h26,90,90 ++S26,$04,$09,$1A,s26,90,90 ++D26,$04,$0a,$1A,d26,90,90 ++Q26,$04,$05,$1A,q26,90,90 ++B27,$04,$01,$1B,b27,91,91 ++H27,$04,$03,$1B,h27,91,91 ++S27,$04,$09,$1B,s27,91,91 ++D27,$04,$0a,$1B,d27,91,91 ++Q27,$04,$05,$1B,q27,91,91 ++B28,$04,$01,$1C,b28,92,92 ++H28,$04,$03,$1C,h28,92,92 ++S28,$04,$09,$1C,s28,92,92 ++D28,$04,$0a,$1C,d28,92,92 ++Q28,$04,$05,$1C,q28,92,92 ++B29,$04,$01,$1D,b29,93,93 ++H29,$04,$03,$1D,h29,93,93 ++S29,$04,$09,$1D,s29,93,93 ++D29,$04,$0a,$1D,d29,93,93 ++Q29,$04,$05,$1D,q29,93,93 ++B30,$04,$01,$1E,b30,94,94 ++H30,$04,$03,$1E,h30,94,94 ++S30,$04,$09,$1E,s30,94,94 ++D30,$04,$0a,$1E,d30,94,94 ++Q30,$04,$05,$1E,q30,94,94 ++B31,$04,$01,$1F,b31,95,95 ++H31,$04,$03,$1F,h31,95,95 ++S31,$04,$09,$1F,s31,95,95 ++D31,$04,$0a,$1F,d31,95,95 ++Q31,$04,$05,$1F,q31,95,95 + + NZCV,$05,$00,$00,nzcv,0,0 +- ++FPCR,$05,$00,$01,fpcr,0,0 ++FPSR,$05,$00,$02,fpsr,0,0 ++TPIDR_EL0,$05,$00,$03,tpidr_el0,0,0 +Index: fpc/fpcsrc/compiler/aarch64/a64tab.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/a64tab.inc ++++ fpc/fpcsrc/compiler/aarch64/a64tab.inc +@@ -1,4 +1,4 @@ +-{ don't edit, this file is generated from armins.dat } ++{ don't edit, this file is generated from a64ins.dat } + ( + + ); +Index: fpc/fpcsrc/compiler/aarch64/aasmcpu.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/aasmcpu.pas ++++ fpc/fpcsrc/compiler/aarch64/aasmcpu.pas +@@ -1,7 +1,7 @@ + { + Copyright (c) 2003-2012 by Florian Klaempfl and others + +- Contains the assembler object for ARM64 ++ Contains the assembler object for Aarch64 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -149,9 +149,6 @@ uses + + pinsentry=^tinsentry; + +-{ const +- InsTab : array[0..instabentries-1] of TInsEntry={$i a64tab.inc} } +- + var + InsTabCache : PInsTabCache; + +@@ -159,6 +156,7 @@ uses + taicpu = class(tai_cpu_abstract_sym) + oppostfix : TOpPostfix; + procedure loadshifterop(opidx:longint;const so:tshifterop); ++ procedure loadconditioncode(opidx: longint; const c: tasmcond); + constructor op_none(op : tasmop); + + constructor op_reg(op : tasmop;_op1 : tregister); +@@ -167,15 +165,21 @@ uses + + constructor op_reg_reg(op : tasmop;_op1,_op2 : tregister); + constructor op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference); ++ constructor op_reg_cond(op: tasmop; _op1: tregister; _op2: tasmcond); + constructor op_reg_const(op:tasmop; _op1: tregister; _op2: aint); ++ constructor op_reg_const_shifterop(op : tasmop;_op1: tregister; _op2: aint;_op3 : tshifterop); + + constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister); + constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister); + constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aint); ++ constructor op_reg_reg_const_const(op : tasmop;_op1,_op2 : tregister; _op3, _op4: aint); ++ constructor op_reg_reg_const_shifterop(op : tasmop;_op1,_op2 : tregister; _op3: aint; const _op4 : tshifterop); + constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint); + constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference); + constructor op_reg_reg_shifterop(op : tasmop;_op1,_op2 : tregister;_op3 : tshifterop); +- constructor op_reg_reg_reg_shifterop(op : tasmop;_op1,_op2,_op3 : tregister;_op4 : tshifterop); ++ constructor op_reg_reg_reg_shifterop(op : tasmop;_op1,_op2,_op3 : tregister; const _op4 : tshifterop); ++ constructor op_reg_reg_reg_cond(op : tasmop;_op1,_op2,_op3 : tregister; const _op4: tasmcond); ++ + + { this is for Jmp instructions } + constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol); +@@ -188,6 +192,7 @@ uses + function is_same_reg_move(regtype: Tregistertype):boolean; override; + + function spilling_get_operation_type(opnr: longint): topertype;override; ++ function spilling_get_operation_type_ref(opnr: longint; reg: tregister): topertype;override; + + { assembler } + public +@@ -203,28 +208,29 @@ uses + procedure ppuwriteoper(ppufile:tcompilerppufile;const o:toper);override; + procedure ppubuildderefimploper(var o:toper);override; + procedure ppuderefoper(var o:toper);override; +- private +- { next fields are filled in pass1, so pass2 is faster } +- inssize : shortint; +- insoffset : longint; +- LastInsOffset : longint; { need to be public to be reset } +- insentry : PInsEntry; +- function InsEnd:longint; +- procedure create_ot(objdata:TObjData); +- function Matches(p:PInsEntry):longint; +- function calcsize(p:PInsEntry):shortint; +- procedure gencode(objdata:TObjData); +- function NeedAddrPrefix(opidx:byte):boolean; +- procedure Swapoperands; +- function FindInsentry(objdata:TObjData):boolean; + end; + + tai_align = class(tai_align_abstract) + { nothing to add } + end; + +- function spilling_create_load(const ref:treference;r:tregister):Taicpu; +- function spilling_create_store(r:tregister; const ref:treference):Taicpu; ++ type ++ tsimplereftype = ++ { valid reference } ++ (sr_simple, ++ { invalid reference, should not be generated by the code generator (but ++ can be encountered via inline assembly, where it must be rejected) } ++ sr_internal_illegal, ++ { invalid reference, may be generated by the code generator and then ++ must be simplified (also rejected in inline assembly) } ++ sr_complex); ++ ++ function simple_ref_type(op: tasmop; size:tcgsize; oppostfix: toppostfix; const ref: treference): tsimplereftype; ++ function can_be_shifter_operand(opc: tasmop; opnr: longint): boolean; ++ function valid_shifter_operand(opc: tasmop; useszr, usessp, is64bit: boolean; sm: tshiftmode; shiftimm: longint): boolean; ++ ++ function spilling_create_load(const ref: treference; r: tregister): taicpu; ++ function spilling_create_store(r: tregister; const ref: treference): taicpu; + + function setoppostfix(i : taicpu;pf : toppostfix) : taicpu; + function setcondition(i : taicpu;c : tasmcond) : taicpu; +@@ -261,6 +267,21 @@ implementation + end; + + ++ procedure taicpu.loadconditioncode(opidx: longint; const c: tasmcond); ++ begin ++ allocate_oper(opidx+1); ++ with oper[opidx]^ do ++ begin ++ if typ<>top_conditioncode then ++ begin ++ clearop(opidx); ++ end; ++ cc:=c; ++ typ:=top_conditioncode; ++ end; ++ end; ++ ++ + {***************************************************************************** + taicpu Constructors + *****************************************************************************} +@@ -314,6 +335,16 @@ implementation + end; + + ++ constructor taicpu.op_reg_const_shifterop(op: tasmop; _op1: tregister; _op2: aint; _op3: tshifterop); ++ begin ++ inherited create(op); ++ ops:=3; ++ loadreg(0,_op1); ++ loadconst(1,_op2); ++ loadshifterop(2,_op3); ++ end; ++ ++ + constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference); + begin + inherited create(op); +@@ -323,6 +354,15 @@ implementation + end; + + ++ constructor taicpu.op_reg_cond(op: tasmop; _op1: tregister; _op2: tasmcond); ++ begin ++ inherited create(op); ++ ops:=2; ++ loadreg(0,_op1); ++ loadconditioncode(1,_op2); ++ end; ++ ++ + constructor taicpu.op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister); + begin + inherited create(op); +@@ -354,6 +394,28 @@ implementation + end; + + ++ constructor taicpu.op_reg_reg_const_const(op: tasmop; _op1, _op2: tregister; _op3, _op4: aint); ++ begin ++ inherited create(op); ++ ops:=4; ++ loadreg(0,_op1); ++ loadreg(1,_op2); ++ loadconst(2,aint(_op3)); ++ loadconst(3,aint(_op4)); ++ end; ++ ++ ++ constructor taicpu.op_reg_reg_const_shifterop(op: tasmop; _op1, _op2: tregister; _op3: aint; const _op4: tshifterop); ++ begin ++ inherited create(op); ++ ops:=4; ++ loadreg(0,_op1); ++ loadreg(1,_op2); ++ loadconst(2,aint(_op3)); ++ loadshifterop(3,_op4); ++ end; ++ ++ + constructor taicpu.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint); + begin + inherited create(op); +@@ -384,7 +446,7 @@ implementation + end; + + +- constructor taicpu.op_reg_reg_reg_shifterop(op : tasmop;_op1,_op2,_op3 : tregister;_op4 : tshifterop); ++ constructor taicpu.op_reg_reg_reg_shifterop(op : tasmop;_op1,_op2,_op3 : tregister; const _op4 : tshifterop); + begin + inherited create(op); + ops:=4; +@@ -394,6 +456,16 @@ implementation + loadshifterop(3,_op4); + end; + ++ constructor taicpu.op_reg_reg_reg_cond(op: tasmop; _op1, _op2, _op3: tregister; const _op4: tasmcond); ++ begin ++ inherited create(op); ++ ops:=4; ++ loadreg(0,_op1); ++ loadreg(1,_op2); ++ loadreg(2,_op3); ++ loadconditioncode(3,_op4); ++ end; ++ + + constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol); + begin +@@ -454,85 +526,403 @@ implementation + end; + + +- function spilling_create_load(const ref:treference;r:tregister):Taicpu; ++ function spilling_create_op(op: tasmop; const ref: treference; r: tregister): taicpu; ++ const ++ { invalid sizes for aarch64 are 0 } ++ subreg2bytesize: array[TSubRegister] of byte = ++ (0,0,0,0,4,8,0,0,0,4,8,0,0,0); + var +- op: tasmop; ++ scalefactor: byte; + begin ++ scalefactor:=subreg2bytesize[getsubreg(r)]; ++ if scalefactor=0 then ++ internalerror(2014120301); ++ if (ref.offset>4095*scalefactor) or ++ ((ref.offset>255) and ++ ((ref.offset mod scalefactor)<>0)) or ++ (ref.offset<-256) then ++ internalerror(2014120302); + case getregtype(r) of +- R_INTREGISTER : +- result:=taicpu.op_reg_ref(A_LDR,r,ref); +- R_MMREGISTER : +- begin +- case getsubreg(r) of +- R_SUBFD: +- op:=A_LDR; +- R_SUBFS: +- op:=A_LDR; +- else +- internalerror(2009112905); +- end; +- result:=taicpu.op_reg_ref(op,r,ref); +- end; ++ R_INTREGISTER, ++ R_MMREGISTER: ++ result:=taicpu.op_reg_ref(op,r,ref); + else + internalerror(200401041); + end; + end; + + +- function spilling_create_store(r:tregister; const ref:treference):Taicpu; ++ function is_valid_load_symbol(op: tasmop; oppostfix: toppostfix; const ref: treference): tsimplereftype; ++ begin ++ result:=sr_complex; ++ if not assigned(ref.symboldata) and ++ not(ref.refaddr in [addr_gotpageoffset,addr_gotpage,addr_pageoffset,addr_page]) then ++ exit; ++ { can't use pre-/post-indexed mode here (makes no sense either) } ++ if ref.addressmode<>AM_OFFSET then ++ exit; ++ { "ldr literal" must be a 32/64 bit LDR and have a symbol } ++ if assigned(ref.symboldata) and ++ ((op<>A_LDR) or ++ not(oppostfix in [PF_NONE,PF_W,PF_SW]) or ++ not assigned(ref.symbol)) then ++ exit; ++ { if this is a (got) page offset load, we must have a base register and a ++ symbol } ++ if (ref.refaddr in [addr_gotpageoffset,addr_pageoffset]) and ++ (not assigned(ref.symbol) or ++ (ref.base=NR_NO) or ++ (ref.index<>NR_NO) or ++ (ref.offset<>0)) then ++ begin ++ result:=sr_internal_illegal; ++ exit; ++ end; ++ { cannot have base or index register (we generate these kind of ++ references internally, they should never end up here with an ++ extra base or offset) } ++ if (ref.refaddr in [addr_gotpage,addr_page]) and ++ (ref.base<>NR_NO) or ++ (ref.index<>NR_NO) then ++ begin ++ result:=sr_internal_illegal; ++ exit; ++ end; ++ result:=sr_simple; ++ end; ++ ++ ++ function simple_ref_type(op: tasmop; size:tcgsize; oppostfix: toppostfix; const ref: treference): tsimplereftype; + var +- op: tasmop; ++ maxoffs: asizeint; ++ accesssize: longint; + begin +- case getregtype(r) of +- R_INTREGISTER : +- result:=taicpu.op_reg_ref(A_STR,r,ref); +- R_MMREGISTER : +- begin +- case getsubreg(r) of +- R_SUBFD: +- op:=A_STR; +- R_SUBFS: +- op:=A_STR; ++ result:=sr_internal_illegal; ++ { post-indexed is only allowed for vector and immediate loads/stores } ++ if (ref.addressmode=AM_POSTINDEXED) and ++ not(op in [A_LD1,A_LD2,A_LD3,A_LD4,A_ST1,A_ST2,A_ST3,A_ST4]) and ++ (not(op in [A_LDR,A_STR,A_LDP,A_STP]) or ++ (ref.base=NR_NO) or ++ (ref.index<>NR_NO)) then ++ exit; ++ ++ { can only have a shift mode if we have an index } ++ if (ref.index=NR_NO) and ++ (ref.shiftmode<>SM_None) then ++ exit; ++ ++ { the index can never be the stack pointer } ++ if ref.index=NR_SP then ++ exit; ++ ++ { no instruction supports an index without a base } ++ if (ref.base=NR_NO) and ++ (ref.index<>NR_NO) then ++ begin ++ result:=sr_complex; ++ exit; ++ end; ++ ++ { LDR literal or GOT entry: 32 or 64 bit, label } ++ if assigned(ref.symboldata) or ++ assigned(ref.symbol) then ++ begin ++ { we generate these kind of references internally; at least for now, ++ they should never end up here with an extra base or offset or so } ++ result:=is_valid_load_symbol(op,oppostfix,ref); ++ exit; ++ end; ++ ++ { any other reference cannot be gotpage/gotpageoffset/pic } ++ if ref.refaddr in [addr_gotpage,addr_gotpageoffset,addr_page,addr_pageoffset,addr_pic] then ++ exit; ++ ++ { base & index: ++ * index cannot be the stack pointer ++ * offset must be 0 ++ * can scale with the size of the access ++ * can zero/sign extend 32 bit index register, and/or multiple by ++ access size ++ * no pre/post-indexing ++ } ++ if (ref.base<>NR_NO) and ++ (ref.index<>NR_NO) then ++ begin ++ if ref.addressmode in [AM_PREINDEXED,AM_POSTINDEXED] then ++ exit; ++ case op of ++ { this holds for both integer and fpu/vector loads } ++ A_LDR,A_STR: ++ if (ref.offset=0) and ++ (((ref.shiftmode=SM_None) and ++ (ref.shiftimm=0)) or ++ ((ref.shiftmode in [SM_LSL,SM_UXTW,SM_SXTW]) and ++ (ref.shiftimm=tcgsizep2size[size]))) then ++ result:=sr_simple + else +- internalerror(2009112904); +- end; +- result:=taicpu.op_reg_ref(op,r,ref); ++ result:=sr_complex; ++ { todo } ++ A_LD1,A_LD2,A_LD3,A_LD4, ++ A_ST1,A_ST2,A_ST3,A_ST4: ++ internalerror(2014110704); ++ { these don't support base+index } ++ A_LDUR,A_STUR, ++ A_LDP,A_STP: ++ result:=sr_complex; ++ else ++ { nothing: result is already sr_internal_illegal }; ++ end; ++ exit; ++ end; ++ ++ { base + immediate offset. Variants: ++ * LDR*/STR*: ++ - pre- or post-indexed with signed 9 bit immediate ++ - regular with unsiged scaled immediate (multiple of access ++ size), in the range 0 to (12 bit * access_size)-1 ++ * LDP/STP ++ - pre- or post-indexed with signed 9 bit immediate ++ - regular with signed 9 bit immediate ++ * LDUR*/STUR*: ++ - regular with signed 9 bit immediate ++ } ++ if ref.base<>NR_NO then ++ begin ++ accesssize:=1 shl tcgsizep2size[size]; ++ case op of ++ A_LDR,A_STR: ++ begin ++ if (ref.addressmode=AM_OFFSET) and ++ (ref.offset>=0) and ++ (ref.offset<(((1 shl 12)-1)*accesssize)) and ++ ((ref.offset mod accesssize)=0) then ++ result:=sr_simple ++ else if (ref.offset>=-256) and ++ (ref.offset<=255) then ++ begin ++ { non pre-/post-indexed regular loads/stores can only be ++ performed using LDUR/STUR } ++ if ref.addressmode in [AM_PREINDEXED,AM_POSTINDEXED] then ++ result:=sr_simple ++ else ++ result:=sr_complex ++ end ++ else ++ result:=sr_complex; ++ end; ++ A_LDP,A_LDNP, ++ A_STP,A_STNP: ++ begin ++ { only supported for 32/64 bit } ++ if not(oppostfix in [PF_W,PF_SW,PF_None]) then ++ exit; ++ { offset must be a multple of the access size } ++ if (ref.offset mod accesssize)<>0 then ++ exit; ++ { offset must fit in a signed 7 bit offset } ++ if (ref.offset>=-(1 shl (6+tcgsizep2size[size]))) and ++ (ref.offset<=(1 shl (6+tcgsizep2size[size]))-1) then ++ result:=sr_simple ++ else ++ result:=sr_complex; ++ end; ++ A_LDUR,A_STUR: ++ begin ++ if (ref.addressmode=AM_OFFSET) and ++ (ref.offset>=-256) and ++ (ref.offset<=255) then ++ result:=sr_simple ++ else ++ result:=sr_complex; ++ end; ++ { todo } ++ A_LD1,A_LD2,A_LD3,A_LD4, ++ A_ST1,A_ST2,A_ST3,A_ST4: ++ internalerror(2014110907); ++ A_LDAR, ++ A_LDAXR, ++ A_LDXR, ++ A_LDXP, ++ A_STLR, ++ A_STLXR, ++ A_STLXP, ++ A_STXP, ++ A_STXR: ++ begin ++ if (ref.addressmode=AM_OFFSET) and ++ (ref.offset=0) then ++ result:=sr_simple; ++ end ++ else ++ { nothing: result is already sr_internal_illegal }; + end; ++ exit; ++ end; ++ { absolute addresses are not supported, have to load them first into ++ a register } ++ result:=sr_complex; ++ end; ++ ++ ++ function can_be_shifter_operand(opc: tasmop; opnr: longint): boolean; ++ begin ++ case opc of ++ A_ADD, ++ A_AND, ++ A_EON, ++ A_EOR, ++ A_ORN, ++ A_ORR, ++ A_SUB: ++ result:=opnr=3; ++ A_BIC, ++ A_CMN, ++ A_CMP, ++ A_MOVK, ++ A_MOVZ, ++ A_MOVN, ++ A_MVN, ++ A_NEG, ++ A_TST: ++ result:=opnr=2; + else +- internalerror(200401041); ++ result:=false; + end; + end; + + ++ function valid_shifter_operand(opc: tasmop; useszr, usessp, is64bit: boolean; sm: tshiftmode; shiftimm: longint): boolean; ++ begin ++ case opc of ++ A_ADD, ++ A_SUB, ++ A_NEG, ++ A_AND, ++ A_TST, ++ A_CMN, ++ A_CMP: ++ begin ++ result:=false; ++ if not useszr then ++ result:= ++ (sm in shiftedregmodes) and ++ ((shiftimm in [0..31]) or ++ (is64bit and ++ (shiftimm in [32..63]))); ++ if not usessp then ++ result:= ++ result or ++ ((sm in extendedregmodes) and ++ (shiftimm in [0..4])); ++ end; ++ A_BIC, ++ A_EON, ++ A_EOR, ++ A_MVN, ++ A_ORN, ++ A_ORR: ++ result:= ++ (sm in shiftedregmodes) and ++ (shiftimm in [0..31*(ord(is64bit)+1)+ord(is64bit)]); ++ A_MOVK, ++ A_MOVZ, ++ A_MOVN: ++ result:= ++ (sm=SM_LSL) and ++ ((shiftimm in [0,16]) or ++ (is64bit and ++ (shiftimm in [32,48]))); ++ else ++ result:=false; ++ end; ++ end; ++ ++ ++ function spilling_create_load(const ref: treference; r: tregister): taicpu; ++ var ++ op: tasmop; ++ begin ++ if (ref.index<>NR_NO) or ++ (ref.offset<-256) or ++ (ref.offset>255) then ++ op:=A_LDR ++ else ++ op:=A_LDUR; ++ result:=spilling_create_op(op,ref,r); ++ end; ++ ++ ++ function spilling_create_store(r: tregister; const ref: treference): taicpu; ++ var ++ op: tasmop; ++ begin ++ if (ref.index<>NR_NO) or ++ (ref.offset<-256) or ++ (ref.offset>255) then ++ op:=A_STR ++ else ++ op:=A_STUR; ++ result:=spilling_create_op(op,ref,r); ++ end; ++ ++ + function taicpu.spilling_get_operation_type(opnr: longint): topertype; + begin + case opcode of +- A_ADC,A_ADD,A_AND,A_BIC, +- A_EOR,A_CLZ,A_RBIT, +- A_LDR, +- A_MOV,A_MVN,A_MUL, +- A_ORR,A_SBC,A_SUB, +- A_UXT,A_SXT: ++ A_B,A_BL, ++ A_CMN,A_CMP, ++ A_CCMN,A_CCMP, ++ A_TST: ++ result:=operand_read; ++ A_STR,A_STUR: + if opnr=0 then +- result:=operand_write ++ result:=operand_read + else ++ { check for pre/post indexed in spilling_get_operation_type_ref } + result:=operand_read; +- A_B,A_BL, +- A_CMN,A_CMP,A_TST: +- result:=operand_read; +- A_STR: +- { important is what happens with the involved registers } ++ A_STLXP, ++ A_STLXR, ++ A_STXP, ++ A_STXR: + if opnr=0 then +- result := operand_read ++ result:=operand_write + else +- { check for pre/post indexed } +- result := operand_read; +- else +- internalerror(200403151); ++ result:=operand_read; ++ A_STP: ++ begin ++ if opnr in [0,1] then ++ result:=operand_read ++ else ++ { check for pre/post indexed in spilling_get_operation_type_ref } ++ result:=operand_read; ++ end; ++ A_LDP, ++ A_LDXP: ++ begin ++ if opnr in [0,1] then ++ result:=operand_write ++ else ++ { check for pre/post indexed in spilling_get_operation_type_ref } ++ result:=operand_read; ++ end; ++ else ++ if opnr=0 then ++ result:=operand_write ++ else ++ result:=operand_read; + end; + end; + + ++ function taicpu.spilling_get_operation_type_ref(opnr: longint; reg: tregister): topertype; ++ begin ++ result:=operand_read; ++ if (oper[opnr]^.ref^.base = reg) and ++ (oper[opnr]^.ref^.addressmode in [AM_PREINDEXED,AM_POSTINDEXED]) then ++ result:=operand_readwrite; ++ end; ++ ++ + procedure BuildInsTabCache; + var + i : longint; +@@ -1069,22 +1459,12 @@ implementation + { we need to reset everything here, because the choosen insentry + can be invalid for a new situation where the previously optimized + insentry is not correct } +- InsEntry:=nil; +- InsSize:=0; +- LastInsOffset:=-1; + end; + + + procedure taicpu.ResetPass2; + begin + { we are here in a second pass, check if the instruction can be optimized } +- if assigned(InsEntry) and +- ((InsEntry^.flags and IF_PASS2)<>0) then +- begin +- InsEntry:=nil; +- InsSize:=0; +- end; +- LastInsOffset:=-1; + end; + + +@@ -1097,18 +1477,15 @@ implementation + function taicpu.Pass1(objdata:TObjData):longint; + begin + Pass1:=0; +- LastInsOffset:=-1; + end; + + + procedure taicpu.Pass2(objdata:TObjData); + begin + { error in pass1 ? } +- if insentry=nil then +- exit; + current_filepos:=fileinfo; + { Generate the instruction } +- GenCode(objdata); ++ { GenCode(objdata); } + end; + + +@@ -1132,1046 +1509,6 @@ implementation + end; + + +- function taicpu.InsEnd:longint; +- begin +- Result:=0; { unimplemented } +- end; +- +- +- procedure taicpu.create_ot(objdata:TObjData); +- begin +- end; +- +- +- function taicpu.Matches(p:PInsEntry):longint; +- begin +- end; +- +- +- function taicpu.calcsize(p:PInsEntry):shortint; +- begin +- result:=4; +- end; +- +- +- function taicpu.NeedAddrPrefix(opidx:byte):boolean; +- begin +- Result:=False; { unimplemented } +- end; +- +- +- procedure taicpu.Swapoperands; +- begin +- end; +- +- +- function taicpu.FindInsentry(objdata:TObjData):boolean; +- begin +- end; +- +- +- procedure taicpu.gencode(objdata:TObjData); +- var +- bytes : dword; +- i_field : byte; +- +- procedure setshifterop(op : byte); +- begin +- case oper[op]^.typ of +- top_const: +- begin +- i_field:=1; +- bytes:=bytes or dword(oper[op]^.val and $fff); +- end; +- top_reg: +- begin +- i_field:=0; +- bytes:=bytes or (getsupreg(oper[op]^.reg) shl 16); +- +- { does a real shifter op follow? } +- if (op+1<=op) and (oper[op+1]^.typ=top_shifterop) then +- begin +- end; +- end; +- else +- internalerror(2005091103); +- end; +- end; +- +- begin +- bytes:=$0; +- { evaluate and set condition code } +- +- { condition code allowed? } +- +- { setup rest of the instruction } +- case insentry^.code[0] of +- #$08: +- begin +- { set instruction code } +- bytes:=bytes or (ord(insentry^.code[1]) shl 26); +- bytes:=bytes or (ord(insentry^.code[2]) shl 21); +- +- { set destination } +- bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); +- +- { create shifter op } +- setshifterop(1); +- +- { set i field } +- bytes:=bytes or (i_field shl 25); +- +- { set s if necessary } +- if oppostfix=PF_S then +- bytes:=bytes or (1 shl 20); +- end; +- #$ff: +- internalerror(2005091101); +- else +- internalerror(2005091102); +- end; +- { we're finished, write code } +- objdata.writebytes(bytes,sizeof(bytes)); +- end; +- +- +-{$ifdef dummy} +-(* +-static void gencode (long segment, long offset, int bits, +- insn *ins, char *codes, long insn_end) +-{ +- int has_S_code; /* S - setflag */ +- int has_B_code; /* B - setflag */ +- int has_T_code; /* T - setflag */ +- int has_W_code; /* ! => W flag */ +- int has_F_code; /* ^ => S flag */ +- int keep; +- unsigned char c; +- unsigned char bytes[4]; +- long data, size; +- static int cc_code[] = /* bit pattern of cc */ +- { /* order as enum in */ +- 0x0E, 0x03, 0x02, 0x00, /* nasm.h */ +- 0x0A, 0x0C, 0x08, 0x0D, +- 0x09, 0x0B, 0x04, 0x01, +- 0x05, 0x07, 0x06, +- }; +- +- +-#ifdef DEBUG +-static char *CC[] = +- { /* condition code names */ +- "AL", "CC", "CS", "EQ", +- "GE", "GT", "HI", "LE", +- "LS", "LT", "MI", "NE", +- "PL", "VC", "VS", "", +- "S" +-}; +- +- +- has_S_code = (ins->condition & C_SSETFLAG); +- has_B_code = (ins->condition & C_BSETFLAG); +- has_T_code = (ins->condition & C_TSETFLAG); +- has_W_code = (ins->condition & C_EXSETFLAG); +- has_F_code = (ins->condition & C_FSETFLAG); +- ins->condition = (ins->condition & 0x0F); +- +- +- if (rt_debug) +- { +- printf ("gencode: instruction: %s%s", insn_names[ins->opcode], +- CC[ins->condition & 0x0F]); +- if (has_S_code) +- printf ("S"); +- if (has_B_code) +- printf ("B"); +- if (has_T_code) +- printf ("T"); +- if (has_W_code) +- printf ("!"); +- if (has_F_code) +- printf ("^"); +- +- printf ("\n"); +- +- c = *codes; +- +- printf (" (%d) decode - '0x%02X'\n", ins->operands, c); +- +- +- bytes[0] = 0xB; +- bytes[1] = 0xE; +- bytes[2] = 0xE; +- bytes[3] = 0xF; +- } +- +- // First condition code in upper nibble +- if (ins->condition < C_NONE) +- { +- c = cc_code[ins->condition] << 4; +- } +- else +- { +- c = cc_code[C_AL] << 4; // is often ALWAYS but not always +- } +- +- +- switch (keep = *codes) +- { +- case 1: +- // B, BL +- ++codes; +- c |= *codes++; +- bytes[0] = c; +- +- if (ins->oprs[0].segment != segment) +- { +- // fais une relocation +- c = 1; +- data = 0; // Let the linker locate ?? +- } +- else +- { +- c = 0; +- data = ins->oprs[0].offset - (offset + 8); +- +- if (data % 4) +- { +- errfunc (ERR_NONFATAL, "offset not aligned on 4 bytes"); +- } +- } +- +- if (data >= 0x1000) +- { +- errfunc (ERR_NONFATAL, "too long offset"); +- } +- +- data = data >> 2; +- bytes[1] = (data >> 16) & 0xFF; +- bytes[2] = (data >> 8) & 0xFF; +- bytes[3] = (data ) & 0xFF; +- +- if (c == 1) +- { +-// out (offset, segment, &bytes[0], OUT_RAWDATA+1, NO_SEG, NO_SEG); +- out (offset, segment, &bytes[0], OUT_REL3ADR+4, ins->oprs[0].segment, NO_SEG); +- } +- else +- { +- out (offset, segment, &bytes[0], OUT_RAWDATA+4, NO_SEG, NO_SEG); +- } +- return; +- +- case 2: +- // SWI +- ++codes; +- c |= *codes++; +- bytes[0] = c; +- data = ins->oprs[0].offset; +- bytes[1] = (data >> 16) & 0xFF; +- bytes[2] = (data >> 8) & 0xFF; +- bytes[3] = (data) & 0xFF; +- out (offset, segment, &bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +- return; +- case 3: +- // BX +- ++codes; +- c |= *codes++; +- bytes[0] = c; +- bytes[1] = *codes++; +- bytes[2] = *codes++; +- bytes[3] = *codes++; +- c = regval (&ins->oprs[0],1); +- if (c == 15) // PC +- { +- errfunc (ERR_WARNING, "'BX' with R15 has undefined behaviour"); +- } +- else if (c > 15) +- { +- errfunc (ERR_NONFATAL, "Illegal register specified for 'BX'"); +- } +- +- bytes[3] |= (c & 0x0F); +- out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +- return; +- +- case 4: // AND Rd,Rn,Rm +- case 5: // AND Rd,Rn,Rm,Rs +- case 6: // AND Rd,Rn,Rm,imm +- case 7: // AND Rd,Rn,imm +- ++codes; +-#ifdef DEBUG +- if (rt_debug) +- { +- printf (" decode - '0x%02X'\n", keep); +- printf (" code - '0x%02X'\n", (unsigned char) ( *codes)); +- } +-#endif +- bytes[0] = c | *codes; +- ++codes; +- +- bytes[1] = *codes; +- if (has_S_code) +- bytes[1] |= 0x10; +- c = regval (&ins->oprs[1],1); +- // Rn in low nibble +- bytes[1] |= c; +- +- // Rd in high nibble +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- +- if (keep != 7) +- { +- // Rm in low nibble +- bytes[3] = regval (&ins->oprs[2],1); +- } +- +- // Shifts if any +- if (keep == 5 || keep == 6) +- { +- // Shift in bytes 2 and 3 +- if (keep == 5) +- { +- // Rs +- c = regval (&ins->oprs[3],1); +- bytes[2] |= c; +- +- c = 0x10; // Set bit 4 in byte[3] +- } +- if (keep == 6) +- { +- c = (ins->oprs[3].offset) & 0x1F; +- +- // #imm +- bytes[2] |= c >> 1; +- if (c & 0x01) +- { +- bytes[3] |= 0x80; +- } +- c = 0; // Clr bit 4 in byte[3] +- } +- // +- c |= shiftval (&ins->oprs[3]) << 5; +- +- bytes[3] |= c; +- } +- +- // reg,reg,imm +- if (keep == 7) +- { +- int shimm; +- +- shimm = imm_shift (ins->oprs[2].offset); +- +- if (shimm == -1) +- { +- errfunc (ERR_NONFATAL, "cannot create that constant"); +- } +- bytes[3] = shimm & 0xFF; +- bytes[2] |= (shimm & 0xF00) >> 8; +- } +- +- out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +- return; +- +- case 8: // MOV Rd,Rm +- case 9: // MOV Rd,Rm,Rs +- case 0xA: // MOV Rd,Rm,imm +- case 0xB: // MOV Rd,imm +- ++codes; +-#ifdef DEBUG +- if (rt_debug) +- { +- printf (" decode - '0x%02X'\n", keep); +- printf (" code - '0x%02X'\n", (unsigned char) ( *codes)); +- } +-#endif +- bytes[0] = c | *codes; +- ++codes; +- +- bytes[1] = *codes; +- if (has_S_code) +- bytes[1] |= 0x10; +- +- // Rd in high nibble +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- +- if (keep != 0x0B) +- { +- // Rm in low nibble +- bytes[3] = regval (&ins->oprs[1],1); +- } +- +- // Shifts if any +- if (keep == 0x09 || keep == 0x0A) +- { +- // Shift in bytes 2 and 3 +- if (keep == 0x09) +- { +- // Rs +- c = regval (&ins->oprs[2],1); +- bytes[2] |= c; +- +- c = 0x10; // Set bit 4 in byte[3] +- } +- if (keep == 0x0A) +- { +- c = (ins->oprs[2].offset) & 0x1F; +- +- // #imm +- bytes[2] |= c >> 1; +- if (c & 0x01) +- { +- bytes[3] |= 0x80; +- } +- c = 0; // Clr bit 4 in byte[3] +- } +- // +- c |= shiftval (&ins->oprs[2]) << 5; +- +- bytes[3] |= c; +- } +- +- // reg,imm +- if (keep == 0x0B) +- { +- int shimm; +- +- shimm = imm_shift (ins->oprs[1].offset); +- +- if (shimm == -1) +- { +- errfunc (ERR_NONFATAL, "cannot create that constant"); +- } +- bytes[3] = shimm & 0xFF; +- bytes[2] |= (shimm & 0xF00) >> 8; +- } +- +- out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +- return; +- +- +- case 0xC: // CMP Rn,Rm +- case 0xD: // CMP Rn,Rm,Rs +- case 0xE: // CMP Rn,Rm,imm +- case 0xF: // CMP Rn,imm +- ++codes; +- +- bytes[0] = c | *codes++; +- +- bytes[1] = *codes; +- +- // Implicit S code +- bytes[1] |= 0x10; +- +- c = regval (&ins->oprs[0],1); +- // Rn in low nibble +- bytes[1] |= c; +- +- // No destination +- bytes[2] = 0; +- +- if (keep != 0x0B) +- { +- // Rm in low nibble +- bytes[3] = regval (&ins->oprs[1],1); +- } +- +- // Shifts if any +- if (keep == 0x0D || keep == 0x0E) +- { +- // Shift in bytes 2 and 3 +- if (keep == 0x0D) +- { +- // Rs +- c = regval (&ins->oprs[2],1); +- bytes[2] |= c; +- +- c = 0x10; // Set bit 4 in byte[3] +- } +- if (keep == 0x0E) +- { +- c = (ins->oprs[2].offset) & 0x1F; +- +- // #imm +- bytes[2] |= c >> 1; +- if (c & 0x01) +- { +- bytes[3] |= 0x80; +- } +- c = 0; // Clr bit 4 in byte[3] +- } +- // +- c |= shiftval (&ins->oprs[2]) << 5; +- +- bytes[3] |= c; +- } +- +- // reg,imm +- if (keep == 0x0F) +- { +- int shimm; +- +- shimm = imm_shift (ins->oprs[1].offset); +- +- if (shimm == -1) +- { +- errfunc (ERR_NONFATAL, "cannot create that constant"); +- } +- bytes[3] = shimm & 0xFF; +- bytes[2] |= (shimm & 0xF00) >> 8; +- } +- +- out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +- return; +- +- case 0x10: // MRS Rd, +- ++codes; +- +- bytes[0] = c | *codes++; +- +- bytes[1] = *codes++; +- +- // Rd +- c = regval (&ins->oprs[0],1); +- +- bytes[2] = c << 4; +- +- bytes[3] = 0; +- +- c = ins->oprs[1].basereg; +- +- if (c == R_CPSR || c == R_SPSR) +- { +- if (c == R_SPSR) +- { +- bytes[1] |= 0x40; +- } +- } +- else +- { +- errfunc (ERR_NONFATAL, "CPSR or SPSR expected"); +- } +- +- out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +- +- return; +- +- case 0x11: // MSR ,Rm +- case 0x12: // MSR ,Rm +- case 0x13: // MSR ,#expression +- ++codes; +- +- bytes[0] = c | *codes++; +- +- bytes[1] = *codes++; +- +- bytes[2] = *codes; +- +- +- if (keep == 0x11 || keep == 0x12) +- { +- // Rm +- c = regval (&ins->oprs[1],1); +- +- bytes[3] = c; +- } +- else +- { +- int shimm; +- +- shimm = imm_shift (ins->oprs[1].offset); +- +- if (shimm == -1) +- { +- errfunc (ERR_NONFATAL, "cannot create that constant"); +- } +- bytes[3] = shimm & 0xFF; +- bytes[2] |= (shimm & 0xF00) >> 8; +- } +- +- c = ins->oprs[0].basereg; +- +- if ( keep == 0x11) +- { +- if ( c == R_CPSR || c == R_SPSR) +- { +- if ( c== R_SPSR) +- { +- bytes[1] |= 0x40; +- } +- } +- else +- { +- errfunc (ERR_NONFATAL, "CPSR or SPSR expected"); +- } +- } +- else +- { +- if ( c == R_CPSR_FLG || c == R_SPSR_FLG) +- { +- if ( c== R_SPSR_FLG) +- { +- bytes[1] |= 0x40; +- } +- } +- else +- { +- errfunc (ERR_NONFATAL, "CPSR_flg or SPSR_flg expected"); +- } +- } +- break; +- +- case 0x14: // MUL Rd,Rm,Rs +- case 0x15: // MULA Rd,Rm,Rs,Rn +- ++codes; +- +- bytes[0] = c | *codes++; +- +- bytes[1] = *codes++; +- +- bytes[3] = *codes; +- +- // Rd +- bytes[1] |= regval (&ins->oprs[0],1); +- if (has_S_code) +- bytes[1] |= 0x10; +- +- // Rm +- bytes[3] |= regval (&ins->oprs[1],1); +- +- // Rs +- bytes[2] = regval (&ins->oprs[2],1); +- +- if (keep == 0x15) +- { +- bytes[2] |= regval (&ins->oprs[3],1) << 4; +- } +- break; +- +- case 0x16: // SMLAL RdHi,RdLo,Rm,Rs +- ++codes; +- +- bytes[0] = c | *codes++; +- +- bytes[1] = *codes++; +- +- bytes[3] = *codes; +- +- // RdHi +- bytes[1] |= regval (&ins->oprs[1],1); +- if (has_S_code) +- bytes[1] |= 0x10; +- +- // RdLo +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- // Rm +- bytes[3] |= regval (&ins->oprs[2],1); +- +- // Rs +- bytes[2] |= regval (&ins->oprs[3],1); +- +- break; +- +- case 0x17: // LDR Rd, expression +- ++codes; +- +- bytes[0] = c | *codes++; +- +- bytes[1] = *codes++; +- +- // Rd +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- if (has_B_code) +- bytes[1] |= 0x40; +- if (has_T_code) +- { +- errfunc (ERR_NONFATAL, "'T' not allowed in pre-index mode"); +- } +- if (has_W_code) +- { +- errfunc (ERR_NONFATAL, "'!' not allowed"); +- } +- +- // Rn - implicit R15 +- bytes[1] |= 0xF; +- +- if (ins->oprs[1].segment != segment) +- { +- errfunc (ERR_NONFATAL, "label not in same segment"); +- } +- +- data = ins->oprs[1].offset - (offset + 8); +- +- if (data < 0) +- { +- data = -data; +- } +- else +- { +- bytes[1] |= 0x80; +- } +- +- if (data >= 0x1000) +- { +- errfunc (ERR_NONFATAL, "too long offset"); +- } +- +- bytes[2] |= ((data & 0xF00) >> 8); +- bytes[3] = data & 0xFF; +- break; +- +- case 0x18: // LDR Rd, [Rn] +- ++codes; +- +- bytes[0] = c | *codes++; +- +- bytes[1] = *codes++; +- +- // Rd +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- if (has_B_code) +- bytes[1] |= 0x40; +- if (has_T_code) +- { +- bytes[1] |= 0x20; // write-back +- } +- else +- { +- bytes[0] |= 0x01; // implicit pre-index mode +- } +- +- if (has_W_code) +- { +- bytes[1] |= 0x20; // write-back +- } +- +- // Rn +- c = regval (&ins->oprs[1],1); +- bytes[1] |= c; +- +- if (c == 0x15) // R15 +- data = -8; +- else +- data = 0; +- +- if (data < 0) +- { +- data = -data; +- } +- else +- { +- bytes[1] |= 0x80; +- } +- +- bytes[2] |= ((data & 0xF00) >> 8); +- bytes[3] = data & 0xFF; +- break; +- +- case 0x19: // LDR Rd, [Rn,#expression] +- case 0x20: // LDR Rd, [Rn,Rm] +- case 0x21: // LDR Rd, [Rn,Rm,shift] +- ++codes; +- +- bytes[0] = c | *codes++; +- +- bytes[1] = *codes++; +- +- // Rd +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- if (has_B_code) +- bytes[1] |= 0x40; +- +- // Rn +- c = regval (&ins->oprs[1],1); +- bytes[1] |= c; +- +- if (ins->oprs[ins->operands-1].bracket) // FIXME: Bracket on last operand -> pre-index <-- +- { +- bytes[0] |= 0x01; // pre-index mode +- if (has_W_code) +- { +- bytes[1] |= 0x20; +- } +- if (has_T_code) +- { +- errfunc (ERR_NONFATAL, "'T' not allowed in pre-index mode"); +- } +- } +- else +- { +- if (has_T_code) // Forced write-back in post-index mode +- { +- bytes[1] |= 0x20; +- } +- if (has_W_code) +- { +- errfunc (ERR_NONFATAL, "'!' not allowed in post-index mode"); +- } +- } +- +- if (keep == 0x19) +- { +- data = ins->oprs[2].offset; +- +- if (data < 0) +- { +- data = -data; +- } +- else +- { +- bytes[1] |= 0x80; +- } +- +- if (data >= 0x1000) +- { +- errfunc (ERR_NONFATAL, "too long offset"); +- } +- +- bytes[2] |= ((data & 0xF00) >> 8); +- bytes[3] = data & 0xFF; +- } +- else +- { +- if (ins->oprs[2].minus == 0) +- { +- bytes[1] |= 0x80; +- } +- c = regval (&ins->oprs[2],1); +- bytes[3] = c; +- +- if (keep == 0x21) +- { +- c = ins->oprs[3].offset; +- if (c > 0x1F) +- { +- errfunc (ERR_NONFATAL, "too large shiftvalue"); +- c = c & 0x1F; +- } +- +- bytes[2] |= c >> 1; +- if (c & 0x01) +- { +- bytes[3] |= 0x80; +- } +- bytes[3] |= shiftval (&ins->oprs[3]) << 5; +- } +- } +- +- break; +- +- case 0x22: // LDRH Rd, expression +- ++codes; +- +- bytes[0] = c | 0x01; // Implicit pre-index +- +- bytes[1] = *codes++; +- +- // Rd +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- +- // Rn - implicit R15 +- bytes[1] |= 0xF; +- +- if (ins->oprs[1].segment != segment) +- { +- errfunc (ERR_NONFATAL, "label not in same segment"); +- } +- +- data = ins->oprs[1].offset - (offset + 8); +- +- if (data < 0) +- { +- data = -data; +- } +- else +- { +- bytes[1] |= 0x80; +- } +- +- if (data >= 0x100) +- { +- errfunc (ERR_NONFATAL, "too long offset"); +- } +- bytes[3] = *codes++; +- +- bytes[2] |= ((data & 0xF0) >> 4); +- bytes[3] |= data & 0xF; +- break; +- +- case 0x23: // LDRH Rd, Rn +- ++codes; +- +- bytes[0] = c | 0x01; // Implicit pre-index +- +- bytes[1] = *codes++; +- +- // Rd +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- +- // Rn +- c = regval (&ins->oprs[1],1); +- bytes[1] |= c; +- +- if (c == 0x15) // R15 +- data = -8; +- else +- data = 0; +- +- if (data < 0) +- { +- data = -data; +- } +- else +- { +- bytes[1] |= 0x80; +- } +- +- if (data >= 0x100) +- { +- errfunc (ERR_NONFATAL, "too long offset"); +- } +- bytes[3] = *codes++; +- +- bytes[2] |= ((data & 0xF0) >> 4); +- bytes[3] |= data & 0xF; +- break; +- +- case 0x24: // LDRH Rd, Rn, expression +- case 0x25: // LDRH Rd, Rn, Rm +- ++codes; +- +- bytes[0] = c; +- +- bytes[1] = *codes++; +- +- // Rd +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- +- // Rn +- c = regval (&ins->oprs[1],1); +- bytes[1] |= c; +- +- if (ins->oprs[ins->operands-1].bracket) // FIXME: Bracket on last operand -> pre-index <-- +- { +- bytes[0] |= 0x01; // pre-index mode +- if (has_W_code) +- { +- bytes[1] |= 0x20; +- } +- } +- else +- { +- if (has_W_code) +- { +- errfunc (ERR_NONFATAL, "'!' not allowed in post-index mode"); +- } +- } +- +- bytes[3] = *codes++; +- +- if (keep == 0x24) +- { +- data = ins->oprs[2].offset; +- +- if (data < 0) +- { +- data = -data; +- } +- else +- { +- bytes[1] |= 0x80; +- } +- +- if (data >= 0x100) +- { +- errfunc (ERR_NONFATAL, "too long offset"); +- } +- +- bytes[2] |= ((data & 0xF0) >> 4); +- bytes[3] |= data & 0xF; +- } +- else +- { +- if (ins->oprs[2].minus == 0) +- { +- bytes[1] |= 0x80; +- } +- c = regval (&ins->oprs[2],1); +- bytes[3] |= c; +- +- } +- break; +- +- case 0x26: // LDM/STM Rn, {reg-list} +- ++codes; +- +- bytes[0] = c; +- +- bytes[0] |= ( *codes >> 4) & 0xF; +- bytes[1] = ( *codes << 4) & 0xF0; +- ++codes; +- +- if (has_W_code) +- { +- bytes[1] |= 0x20; +- } +- if (has_F_code) +- { +- bytes[1] |= 0x40; +- } +- +- // Rn +- bytes[1] |= regval (&ins->oprs[0],1); +- +- data = ins->oprs[1].basereg; +- +- bytes[2] = ((data >> 8) & 0xFF); +- bytes[3] = (data & 0xFF); +- +- break; +- +- case 0x27: // SWP Rd, Rm, [Rn] +- ++codes; +- +- bytes[0] = c; +- +- bytes[0] |= *codes++; +- +- bytes[1] = regval (&ins->oprs[2],1); +- if (has_B_code) +- { +- bytes[1] |= 0x40; +- } +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- bytes[3] = *codes++; +- bytes[3] |= regval (&ins->oprs[1],1); +- break; +- +- default: +- errfunc (ERR_FATAL, "unknown decoding of instruction"); +- +- bytes[0] = c; +- // And a fix nibble +- ++codes; +- bytes[0] |= *codes++; +- +- if ( *codes == 0x01) // An I bit +- { +- +- } +- if ( *codes == 0x02) // An I bit +- { +- +- } +- ++codes; +- } +- out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +-} +- +-*) +-{$endif dummy} +- + begin + cai_align:=tai_align; + end. +Index: fpc/fpcsrc/compiler/aarch64/agcpugas.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/agcpugas.pas +@@ -0,0 +1,303 @@ ++{ ++ Copyright (c) 2003,2014 by Florian Klaempfl and Jonas Maebe ++ ++ This unit implements an asm for AArch64 ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ **************************************************************************** ++} ++{ This unit implements the GNU Assembler writer for AArch64 ++} ++ ++unit agcpugas; ++ ++{$i fpcdefs.inc} ++ ++ interface ++ ++ uses ++ globtype, ++ aasmtai, ++ aggas, ++ cpubase,cpuinfo; ++ ++ type ++ TAArch64InstrWriter=class(TCPUInstrWriter) ++ procedure WriteInstruction(hp : tai);override; ++ end; ++ ++ TAArch64Assembler=class(TGNUassembler) ++ constructor create(smart: boolean); override; ++ end; ++ ++ TAArch64AppleAssembler=class(TAppleGNUassembler) ++ constructor create(smart: boolean); override; ++ end; ++ ++ ++ const ++ gas_shiftmode2str : array[tshiftmode] of string[4] = ( ++ '','lsl','lsr','asr', ++ 'uxtb','uxth','uxtw','uxtx', ++ 'sxtb','sxth','sxtw','sxtx'); ++ ++ const ++ cputype_to_gas_march : array[tcputype] of string = ( ++ '', // cpu_none ++ 'armv8' ++ ); ++ ++ implementation ++ ++ uses ++ cutils,globals,verbose, ++ systems, ++ assemble, ++ aasmcpu, ++ itcpugas, ++ cgbase,cgutils; ++ ++ ++{****************************************************************************} ++{ AArch64 Assembler writer } ++{****************************************************************************} ++ ++ constructor TAArch64Assembler.create(smart: boolean); ++ begin ++ inherited create(smart); ++ InstrWriter := TAArch64InstrWriter.create(self); ++ end; ++ ++{****************************************************************************} ++{ Apple AArch64 Assembler writer } ++{****************************************************************************} ++ ++ constructor TAArch64AppleAssembler.create(smart: boolean); ++ begin ++ inherited create(smart); ++ InstrWriter := TAArch64InstrWriter.create(self); ++ end; ++ ++ ++{****************************************************************************} ++{ Helper routines for Instruction Writer } ++{****************************************************************************} ++ ++ function getreferencestring(var ref : treference) : string; ++ const ++ darwin_addrpage2str: array[addr_page..addr_gotpageoffset] of string[11] = ++ ('@PAGE','@PAGEOFF','@GOTPAGE','@GOTPAGEOFF'); ++ linux_addrpage2str: array[addr_page..addr_gotpageoffset] of string[10] = ++ ('',':lo12:',':got:',':got_lo12:'); ++ begin ++ if ref.base=NR_NO then ++ begin ++ case ref.refaddr of ++ addr_gotpage, ++ addr_page, ++ addr_gotpageoffset, ++ addr_pageoffset: ++ begin ++ if not assigned(ref.symbol) or ++ (ref.base<>NR_NO) or ++ (ref.index<>NR_NO) or ++ (ref.shiftmode<>SM_None) or ++ (ref.offset<>0) then ++ internalerror(2014121501); ++ if target_info.system in systems_darwin then ++ result:=ref.symbol.name+darwin_addrpage2str[ref.refaddr] ++ else ++ result:=linux_addrpage2str[ref.refaddr]+ref.symbol.name ++ end ++ else ++ internalerror(2015022301); ++ end ++ end ++ else ++ begin ++ result:='['+gas_regname(ref.base); ++ if ref.addressmode=AM_POSTINDEXED then ++ result:=result+']'; ++ if ref.index<>NR_NO then ++ begin ++ if (ref.offset<>0) or ++ assigned(ref.symbol) then ++ internalerror(2014121504); ++ result:=result+', '+gas_regname(ref.index); ++ case ref.shiftmode of ++ SM_None: ; ++ SM_LSL, ++ SM_UXTW, SM_UXTX, SM_SXTW, SM_SXTX: ++ begin ++ result:=result+', '+gas_shiftmode2str[ref.shiftmode]; ++ if (ref.shiftmode=SM_LSL) or ++ (ref.shiftimm<>0) then ++ result:=result+' #'+tostr(ref.shiftimm); ++ end ++ else ++ internalerror(2014121505); ++ end; ++ end ++ else ++ begin ++ if assigned(ref.symbol) then ++ begin ++ case ref.refaddr of ++ addr_gotpageoffset, ++ addr_pageoffset: ++ begin ++ if target_info.system in systems_darwin then ++ result:=result+', '+ref.symbol.name+darwin_addrpage2str[ref.refaddr] ++ else ++ result:=result+', '+linux_addrpage2str[ref.refaddr]+ref.symbol.name ++ end ++ else ++ { todo: not yet generated/don't know syntax } ++ internalerror(2014121506); ++ end; ++ end ++ else ++ begin ++ if ref.refaddr<>addr_no then ++ internalerror(2014121506); ++ if (ref.offset<>0) then ++ result:=result+', #'+tostr(ref.offset); ++ end; ++ end; ++ case ref.addressmode of ++ AM_OFFSET: ++ result:=result+']'; ++ AM_PREINDEXED: ++ result:=result+']!'; ++ end; ++ end; ++ end; ++ ++ ++ function getopstr(hp: taicpu; opnr: longint; const o: toper): string; ++ begin ++ case o.typ of ++ top_reg: ++ { we cannot yet represent "umov w0, v4.s[0]" or "ins v4.d[0], x1", ++ so for now we use "s4" or "d4" instead -> translate here } ++ if ((hp.opcode=A_INS) or ++ (hp.opcode=A_UMOV)) and ++ (getregtype(hp.oper[opnr]^.reg)=R_MMREGISTER) then ++ begin ++ case getsubreg(hp.oper[opnr]^.reg) of ++ R_SUBMMS: ++ getopstr:='v'+tostr(getsupreg(hp.oper[opnr]^.reg))+'.S[0]'; ++ R_SUBMMD: ++ getopstr:='v'+tostr(getsupreg(hp.oper[opnr]^.reg))+'.D[0]'; ++ else ++ internalerror(2014122907); ++ end; ++ end ++ else ++ getopstr:=gas_regname(o.reg); ++ top_shifterop: ++ begin ++ getopstr:=gas_shiftmode2str[o.shifterop^.shiftmode]; ++ if o.shifterop^.shiftimm<>0 then ++ getopstr:=getopstr+' #'+tostr(o.shifterop^.shiftimm) ++ end; ++ top_const: ++ if o.val>=0 then ++ getopstr:='#'+tostr(o.val) ++ else ++ getopstr:='#0x'+hexStr(o.val,16); ++ top_conditioncode: ++ getopstr:=cond2str[o.cc]; ++ top_ref: ++ if is_calljmp(hp.opcode) then ++ begin ++ if o.ref^.refaddr<>addr_full then ++ internalerror(2014122220); ++ if not assigned(o.ref^.symbol) or ++ assigned(o.ref^.relsymbol) or ++ (o.ref^.base<>NR_NO) or ++ (o.ref^.index<>NR_NO) or ++ (o.ref^.offset<>0) then ++ internalerror(2014122221); ++ getopstr:=o.ref^.symbol.name; ++ end ++ else ++ getopstr:=getreferencestring(o.ref^); ++ else ++ internalerror(2014121507); ++ end; ++ end; ++ ++ ++ procedure TAArch64InstrWriter.WriteInstruction(hp : tai); ++ var ++ op: TAsmOp; ++ s: string; ++ i: byte; ++ sep: string[3]; ++ begin ++ op:=taicpu(hp).opcode; ++ s:=#9+gas_op2str[op]+oppostfix2str[taicpu(hp).oppostfix]; ++ if taicpu(hp).condition<>C_NONE then ++ s:=s+'.'+cond2str[taicpu(hp).condition]; ++ if taicpu(hp).ops<>0 then ++ begin ++ sep:=#9; ++ for i:=0 to taicpu(hp).ops-1 do ++ begin ++ // debug code ++ // writeln(s); ++ // writeln(taicpu(hp).fileinfo.line); ++ s:=s+sep+getopstr(taicpu(hp),i,taicpu(hp).oper[i]^); ++ sep:=','; ++ end; ++ end; ++ owner.AsmWriteLn(s); ++ end; ++ ++ ++ const ++ as_aarch64_gas_info : tasminfo = ++ ( ++ id : as_gas; ++ idtxt : 'AS'; ++ asmbin : 'as'; ++ asmcmd : '-o $OBJ $EXTRAOPT $ASM'; ++ supported_targets : [system_aarch64_linux]; ++ flags : [af_needar,af_smartlink_sections]; ++ labelprefix : '.L'; ++ comment : '// '; ++ dollarsign: '$'; ++ ); ++ ++ as_aarch64_clang_darwin_info : tasminfo = ++ ( ++ id : as_clang; ++ idtxt : 'CLANG'; ++ asmbin : 'clang'; ++ asmcmd : '-c -o $OBJ $EXTRAOPT -arch arm64 $DARWINVERSION -x assembler $ASM'; ++ supported_targets : [system_aarch64_darwin]; ++ flags : [af_needar,af_smartlink_sections,af_supports_dwarf]; ++ labelprefix : 'L'; ++ comment : '# '; ++ dollarsign: '$'; ++ ); ++ ++ ++begin ++ RegisterAssembler(as_aarch64_gas_info,TAArch64Assembler); ++ RegisterAssembler(as_aarch64_clang_darwin_info,TAArch64AppleAssembler); ++end. +Index: fpc/fpcsrc/compiler/aarch64/aoptcpub.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/aoptcpub.pas ++++ fpc/fpcsrc/compiler/aarch64/aoptcpub.pas +@@ -118,17 +118,35 @@ Implementation + End; + + +- function TAoptBaseCpu.RegModifiedByInstruction(Reg: TRegister; p1: tai): boolean; ++ function TAoptBaseCpu.RegModifiedByInstruction(reg: tregister; p1: tai): boolean; + var +- i : Longint; ++ i: longint; ++ preg: tregister; + begin + result:=false; + for i:=0 to taicpu(p1).ops-1 do +- if (taicpu(p1).oper[i]^.typ=top_reg) and (taicpu(p1).oper[i]^.reg=Reg) and (taicpu(p1).spilling_get_operation_type(i) in [operand_write,operand_readwrite]) then +- begin +- result:=true; +- exit; +- end; ++ case taicpu(p1).oper[i]^.typ of ++ top_reg: ++ begin ++ preg:=taicpu(p1).oper[i]^.reg; ++ if (getregtype(preg)=getregtype(reg)) and ++ (getsupreg(preg)=getsupreg(reg)) and ++ (taicpu(p1).spilling_get_operation_type(i) in [operand_write,operand_readwrite]) then ++ begin ++ result:=true; ++ exit; ++ end; ++ end; ++ top_ref: ++ begin ++ if (taicpu(p1).oper[i]^.ref^.addressmode<>am_offset) and ++ (reg=taicpu(p1).oper[i]^.ref^.base) then ++ begin ++ result:=true; ++ exit ++ end; ++ end; ++ end; + end; + + End. +Index: fpc/fpcsrc/compiler/aarch64/cgcpu.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/cgcpu.pas +@@ -0,0 +1,2275 @@ ++{ ++ Copyright (c) 2014 by Jonas Maebe ++ ++ This unit implements the code generator for AArch64 ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ **************************************************************************** ++} ++unit cgcpu; ++ ++{$i fpcdefs.inc} ++ ++interface ++ ++ uses ++ globtype,parabase, ++ cgbase,cgutils,cgobj, ++ aasmbase,aasmtai,aasmdata,aasmcpu, ++ cpubase,cpuinfo, ++ node,symconst,SymType,symdef, ++ rgcpu; ++ ++ type ++ tcgaarch64=class(tcg) ++ protected ++ { simplifies "ref" so it can be used with "op". If "ref" can be used ++ with a different load/Store operation that has the same meaning as the ++ original one, "op" will be replaced with the alternative } ++ procedure make_simple_ref(list:TAsmList; var op: tasmop; size: tcgsize; oppostfix: toppostfix; var ref: treference; preferred_newbasereg: tregister); ++ { changes register size without adding register allocation info } ++ function makeregsize(reg: tregister; size: tcgsize): tregister; overload; ++ public ++ function getfpuregister(list: TAsmList; size: Tcgsize): Tregister; override; ++ procedure handle_reg_imm12_reg(list: TAsmList; op: Tasmop; size: tcgsize; src: tregister; a: tcgint; dst: tregister; tmpreg: tregister; setflags, usedest: boolean); ++ procedure init_register_allocators;override; ++ procedure done_register_allocators;override; ++ function getmmregister(list:TAsmList;size:tcgsize):tregister;override; ++ function handle_load_store(list:TAsmList; op: tasmop; size: tcgsize; oppostfix: toppostfix; reg: tregister; ref: treference):treference; ++ procedure a_call_name(list:TAsmList;const s:string; weak: boolean);override; ++ procedure a_call_reg(list:TAsmList;Reg:tregister);override; ++ { General purpose instructions } ++ procedure maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister); ++ procedure a_op_const_reg(list: TAsmList; op: topcg; size: tcgsize; a: tcgint; reg: tregister);override; ++ procedure a_op_reg_reg(list: TAsmList; op: topcg; size: tcgsize; src, dst: tregister);override; ++ procedure a_op_const_reg_reg(list: TAsmList; op: topcg; size: tcgsize; a: tcgint; src, dst: tregister);override; ++ procedure a_op_reg_reg_reg(list: TAsmList; op: topcg; size: tcgsize; src1, src2, dst: tregister);override; ++ procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: topcg; size: tcgsize; a: tcgint; src, dst: tregister; setflags : boolean; var ovloc : tlocation);override; ++ procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: topcg; size: tcgsize; src1, src2, dst: tregister; setflags : boolean; var ovloc : tlocation);override; ++ { move instructions } ++ procedure a_load_const_reg(list: TAsmList; size: tcgsize; a: tcgint; reg: tregister);override; ++ procedure a_load_const_ref(list: TAsmList; size: tcgsize; a: tcgint; const ref: treference); override; ++ procedure a_load_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister;const ref: TReference);override; ++ procedure a_load_reg_ref_unaligned(list: TAsmList; fromsize, tosize: tcgsize; register: tregister; const ref: treference); override; ++ procedure a_load_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: TReference; reg: tregister);override; ++ procedure a_load_ref_reg_unaligned(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; register: tregister); override; ++ procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister);override; ++ procedure a_loadaddr_ref_reg(list: TAsmList; const ref: TReference; r: tregister);override; ++ { fpu move instructions (not used, all floating point is vector unit-based) } ++ procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override; ++ procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); override; ++ procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override; ++ procedure a_loadmm_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister;shuffle : pmmshuffle);override; ++ procedure a_loadmm_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: TReference; reg: tregister; shuffle: pmmshuffle);override; ++ procedure a_loadmm_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: TReference; shuffle: pmmshuffle);override; ++ ++ procedure a_loadmm_intreg_reg(list: TAsmList; fromsize, tosize: tcgsize; intreg, mmreg: tregister; shuffle: pmmshuffle); override; ++ procedure a_loadmm_reg_intreg(list: TAsmList; fromsize, tosize: tcgsize; mmreg, intreg: tregister; shuffle: pmmshuffle); override; ++ ++ procedure a_opmm_reg_reg(list: TAsmList; Op: TOpCG; size: tcgsize; src, dst: tregister; shuffle: pmmshuffle); override; ++ ++ procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tcgsize; src, dst: TRegister); override; ++ { comparison operations } ++ procedure a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);override; ++ procedure a_cmp_reg_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);override; ++ procedure a_jmp_always(list: TAsmList; l: TAsmLabel);override; ++ procedure a_jmp_name(list: TAsmList; const s: string);override; ++ procedure a_jmp_cond(list: TAsmList; cond: TOpCmp; l: tasmlabel);{ override;} ++ procedure a_jmp_flags(list: TAsmList; const f: tresflags; l: tasmlabel);override; ++ procedure g_flags2reg(list: TAsmList; size: tcgsize; const f:tresflags; reg: tregister);override; ++ procedure g_overflowcheck(list: TAsmList; const loc: tlocation; def: tdef);override; ++ procedure g_overflowcheck_loc(list: TAsmList; const loc: tlocation; def: tdef; ovloc: tlocation);override; ++ procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean);override; ++ procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean);override; ++ procedure g_maybe_got_init(list: TAsmList); override; ++ procedure g_restore_registers(list: TAsmList);override; ++ procedure g_save_registers(list: TAsmList);override; ++ procedure g_concatcopy_move(list: TAsmList; const source, dest: treference; len: tcgint); ++ procedure g_concatcopy(list: TAsmList; const source, dest: treference; len: tcgint);override; ++ procedure g_adjust_self_value(list: TAsmList; procdef: tprocdef; ioffset: tcgint);override; ++ procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override; ++ private ++ function save_regs(list: TAsmList; rt: tregistertype; lowsr, highsr: tsuperregister; sub: tsubregister): longint; ++ procedure load_regs(list: TAsmList; rt: tregistertype; lowsr, highsr: tsuperregister; sub: tsubregister); ++ end; ++ ++ procedure create_codegen; ++ ++ const ++ TOpCG2AsmOpReg: array[topcg] of TAsmOp = ( ++ A_NONE,A_MOV,A_ADD,A_AND,A_UDIV,A_SDIV,A_MUL,A_MUL,A_NEG,A_MVN,A_ORR,A_ASRV,A_LSLV,A_LSRV,A_SUB,A_EOR,A_NONE,A_RORV ++ ); ++ TOpCG2AsmOpImm: array[topcg] of TAsmOp = ( ++ A_NONE,A_MOV,A_ADD,A_AND,A_UDIV,A_SDIV,A_MUL,A_MUL,A_NEG,A_MVN,A_ORR,A_ASR,A_LSL,A_LSR,A_SUB,A_EOR,A_NONE,A_ROR ++ ); ++ TOpCmp2AsmCond: array[topcmp] of TAsmCond = (C_NONE,C_EQ,C_GT, ++ C_LT,C_GE,C_LE,C_NE,C_LS,C_CC,C_CS,C_HI ++ ); ++ ++ ++implementation ++ ++ uses ++ globals,verbose,systems,cutils, ++ paramgr,fmodule, ++ symtable,symsym, ++ tgobj, ++ procinfo,cpupi; ++ ++ ++ procedure tcgaarch64.make_simple_ref(list:TAsmList; var op: tasmop; size: tcgsize; oppostfix: toppostfix; var ref: treference; preferred_newbasereg: tregister); ++ var ++ href: treference; ++ so: tshifterop; ++ accesssize: longint; ++ begin ++ if (ref.base=NR_NO) then ++ begin ++ if ref.shiftmode<>SM_None then ++ internalerror(2014110701); ++ ref.base:=ref.index; ++ ref.index:=NR_NO; ++ end; ++ { no abitrary scale factor support (the generic code doesn't set it, ++ AArch-specific code shouldn't either) } ++ if not(ref.scalefactor in [0,1]) then ++ internalerror(2014111002); ++ ++ case simple_ref_type(op,size,oppostfix,ref) of ++ sr_simple: ++ exit; ++ sr_internal_illegal: ++ internalerror(2014121702); ++ sr_complex: ++ { continue } ; ++ end; ++ ++ if assigned(ref.symbol) then ++ begin ++ { internal "load symbol" instructions should already be valid } ++ if assigned(ref.symboldata) or ++ (ref.refaddr in [addr_pic,addr_gotpage,addr_gotpageoffset,addr_page,addr_pageoffset]) then ++ internalerror(2014110802); ++ { no relative symbol support (needed) yet } ++ if assigned(ref.relsymbol) then ++ internalerror(2014111001); ++ { loading a symbol address (whether it's in the GOT or not) consists ++ of two parts: first load the page on which it is located, then ++ either the offset in the page or load the value at that offset in ++ the page. This final GOT-load can be relaxed by the linker in case ++ the variable itself can be stored directly in the GOT } ++ if (preferred_newbasereg=NR_NO) or ++ (ref.base=preferred_newbasereg) or ++ (ref.index=preferred_newbasereg) then ++ preferred_newbasereg:=getaddressregister(list); ++ { load the (GOT) page } ++ reference_reset_symbol(href,ref.symbol,0,8); ++ if ((ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) and ++ (ref.symbol.bind in [AB_LOCAL,AB_GLOBAL])) or ++ ((ref.symbol.typ=AT_DATA) and ++ (ref.symbol.bind=AB_LOCAL)) then ++ href.refaddr:=addr_page ++ else ++ href.refaddr:=addr_gotpage; ++ list.concat(taicpu.op_reg_ref(A_ADRP,preferred_newbasereg,href)); ++ { load the GOT entry (= address of the variable) } ++ reference_reset_base(href,preferred_newbasereg,0,sizeof(pint)); ++ href.symbol:=ref.symbol; ++ { code symbols defined in the current compilation unit do not ++ have to be accessed via the GOT } ++ if ((ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) and ++ (ref.symbol.bind in [AB_LOCAL,AB_GLOBAL])) or ++ ((ref.symbol.typ=AT_DATA) and ++ (ref.symbol.bind=AB_LOCAL)) then ++ begin ++ href.base:=NR_NO; ++ href.refaddr:=addr_pageoffset; ++ list.concat(taicpu.op_reg_reg_ref(A_ADD,preferred_newbasereg,preferred_newbasereg,href)); ++ end ++ else ++ begin ++ href.refaddr:=addr_gotpageoffset; ++ { use a_load_ref_reg() rather than directly encoding the LDR, ++ so that we'll check the validity of the reference } ++ a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,preferred_newbasereg); ++ end; ++ { set as new base register } ++ if ref.base=NR_NO then ++ ref.base:=preferred_newbasereg ++ else if ref.index=NR_NO then ++ ref.index:=preferred_newbasereg ++ else ++ begin ++ { make sure it's valid in case ref.base is SP -> make it ++ the second operand} ++ a_op_reg_reg_reg(list,OP_ADD,OS_ADDR,preferred_newbasereg,ref.base,preferred_newbasereg); ++ ref.base:=preferred_newbasereg ++ end; ++ ref.symbol:=nil; ++ end; ++ ++ { base & index } ++ if (ref.base<>NR_NO) and ++ (ref.index<>NR_NO) then ++ begin ++ case op of ++ A_LDR, A_STR: ++ begin ++ if (ref.shiftmode=SM_None) and ++ (ref.shiftimm<>0) then ++ internalerror(2014110805); ++ { wrong shift? (possible in case of something like ++ array_of_2byte_rec[x].bytefield -> shift will be set 1, but ++ the final load is a 1 byte -> can't use shift after all } ++ if (ref.shiftmode in [SM_LSL,SM_UXTW,SM_SXTW]) and ++ ((ref.shiftimm<>BsfDWord(tcgsizep2size[size])) or ++ (ref.offset<>0)) then ++ begin ++ if preferred_newbasereg=NR_NO then ++ preferred_newbasereg:=getaddressregister(list); ++ { "add" supports a superset of the shift modes supported by ++ load/store instructions } ++ shifterop_reset(so); ++ so.shiftmode:=ref.shiftmode; ++ so.shiftimm:=ref.shiftimm; ++ list.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,preferred_newbasereg,ref.base,ref.index,so)); ++ reference_reset_base(ref,preferred_newbasereg,ref.offset,ref.alignment); ++ { possibly still an invalid offset -> fall through } ++ end ++ else if ref.offset<>0 then ++ begin ++ if (preferred_newbasereg=NR_NO) or ++ { we keep ref.index, so it must not be overwritten } ++ (ref.index=preferred_newbasereg) then ++ preferred_newbasereg:=getaddressregister(list); ++ { add to the base and not to the index, because the index ++ may be scaled; this works even if the base is SP } ++ a_op_const_reg_reg(list,OP_ADD,OS_ADDR,ref.offset,ref.base,preferred_newbasereg); ++ ref.offset:=0; ++ ref.base:=preferred_newbasereg; ++ { finished } ++ exit; ++ end ++ else ++ { valid -> exit } ++ exit; ++ end; ++ { todo } ++ A_LD1,A_LD2,A_LD3,A_LD4, ++ A_ST1,A_ST2,A_ST3,A_ST4: ++ internalerror(2014110704); ++ { these don't support base+index } ++ A_LDUR,A_STUR, ++ A_LDP,A_STP: ++ begin ++ { these either don't support pre-/post-indexing, or don't ++ support it with base+index } ++ if ref.addressmode<>AM_OFFSET then ++ internalerror(2014110911); ++ if preferred_newbasereg=NR_NO then ++ preferred_newbasereg:=getaddressregister(list); ++ if ref.shiftmode<>SM_None then ++ begin ++ { "add" supports a superset of the shift modes supported by ++ load/store instructions } ++ shifterop_reset(so); ++ so.shiftmode:=ref.shiftmode; ++ so.shiftimm:=ref.shiftimm; ++ list.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,preferred_newbasereg,ref.base,ref.index,so)); ++ end ++ else ++ a_op_reg_reg_reg(list,OP_ADD,OS_ADDR,ref.index,ref.base,preferred_newbasereg); ++ reference_reset_base(ref,preferred_newbasereg,ref.offset,ref.alignment); ++ { fall through to the handling of base + offset, since the ++ offset may still be too big } ++ end; ++ else ++ internalerror(2014110901); ++ end; ++ end; ++ ++ { base + offset } ++ if ref.base<>NR_NO then ++ begin ++ { valid offset for LDUR/STUR -> use that } ++ if (ref.addressmode=AM_OFFSET) and ++ (op in [A_LDR,A_STR]) and ++ (ref.offset>=-256) and ++ (ref.offset<=255) then ++ begin ++ if op=A_LDR then ++ op:=A_LDUR ++ else ++ op:=A_STUR ++ end ++ { if it's not a valid LDUR/STUR, use LDR/STR } ++ else if (op in [A_LDUR,A_STUR]) and ++ ((ref.offset<-256) or ++ (ref.offset>255) or ++ (ref.addressmode<>AM_OFFSET)) then ++ begin ++ if op=A_LDUR then ++ op:=A_LDR ++ else ++ op:=A_STR ++ end; ++ case op of ++ A_LDR,A_STR: ++ begin ++ case ref.addressmode of ++ AM_PREINDEXED: ++ begin ++ { since the loaded/stored register cannot be the same ++ as the base register, we can safely add the ++ offset to the base if it doesn't fit} ++ if (ref.offset<-256) or ++ (ref.offset>255) then ++ begin ++ a_op_const_reg(list,OP_ADD,OS_ADDR,ref.offset,ref.base); ++ ref.offset:=0; ++ end; ++ end; ++ AM_POSTINDEXED: ++ begin ++ { cannot emulate post-indexing if we have to fold the ++ offset into the base register } ++ if (ref.offset<-256) or ++ (ref.offset>255) then ++ internalerror(2014110909); ++ { ok } ++ end; ++ AM_OFFSET: ++ begin ++ { unsupported offset -> fold into base register } ++ accesssize:=1 shl tcgsizep2size[size]; ++ if (ref.offset<0) or ++ (ref.offset>(((1 shl 12)-1)*accesssize)) or ++ ((ref.offset mod accesssize)<>0) then ++ begin ++ if preferred_newbasereg=NR_NO then ++ preferred_newbasereg:=getaddressregister(list); ++ { can we split the offset beween an ++ "add/sub (imm12 shl 12)" and the load (also an ++ imm12)? ++ -- the offset from the load will always be added, ++ that's why the lower bound has a smaller range ++ than the upper bound; it must also be a multiple ++ of the access size } ++ if (ref.offset>=-(((1 shl 12)-1) shl 12)) and ++ (ref.offset<=((1 shl 12)-1) shl 12 + ((1 shl 12)-1)) and ++ ((ref.offset mod accesssize)=0) then ++ begin ++ a_op_const_reg_reg(list,OP_ADD,OS_ADDR,(ref.offset shr 12) shl 12,ref.base,preferred_newbasereg); ++ ref.offset:=ref.offset-(ref.offset shr 12) shl 12; ++ end ++ else ++ begin ++ a_op_const_reg_reg(list,OP_ADD,OS_ADDR,ref.offset,ref.base,preferred_newbasereg); ++ ref.offset:=0; ++ end; ++ reference_reset_base(ref,preferred_newbasereg,ref.offset,ref.alignment); ++ end; ++ end ++ else ++ internalerror(2014110904); ++ end; ++ end; ++ A_LDP,A_STP: ++ begin ++ { unsupported offset -> fold into base register (these ++ instructions support all addressmodes) } ++ if (ref.offset<-(1 shl (6+tcgsizep2size[size]))) or ++ (ref.offset>(1 shl (6+tcgsizep2size[size]))-1) then ++ begin ++ case ref.addressmode of ++ AM_POSTINDEXED: ++ { don't emulate post-indexing if we have to fold the ++ offset into the base register } ++ internalerror(2014110910); ++ AM_PREINDEXED: ++ { this means the offset must be added to the current ++ base register } ++ preferred_newbasereg:=ref.base; ++ AM_OFFSET: ++ if preferred_newbasereg=NR_NO then ++ preferred_newbasereg:=getaddressregister(list); ++ end; ++ a_op_const_reg_reg(list,OP_ADD,OS_ADDR,ref.offset,ref.base,preferred_newbasereg); ++ reference_reset_base(ref,preferred_newbasereg,0,ref.alignment); ++ end ++ end; ++ A_LDUR,A_STUR: ++ begin ++ { valid, checked above } ++ end; ++ { todo } ++ A_LD1,A_LD2,A_LD3,A_LD4, ++ A_ST1,A_ST2,A_ST3,A_ST4: ++ internalerror(2014110908); ++ else ++ internalerror(2014110708); ++ end; ++ { done } ++ exit; ++ end; ++ ++ { only an offset -> change to base (+ offset 0) } ++ if preferred_newbasereg=NR_NO then ++ preferred_newbasereg:=getaddressregister(list); ++ a_load_const_reg(list,OS_ADDR,ref.offset,preferred_newbasereg); ++ reference_reset_base(ref,preferred_newbasereg,0,newalignment(8,ref.offset)); ++ end; ++ ++ ++ function tcgaarch64.makeregsize(reg: tregister; size: tcgsize): tregister; ++ var ++ subreg:Tsubregister; ++ begin ++ subreg:=cgsize2subreg(getregtype(reg),size); ++ result:=reg; ++ setsubreg(result,subreg); ++ end; ++ ++ ++ function tcgaarch64.getfpuregister(list: TAsmList; size: Tcgsize): Tregister; ++ begin ++ internalerror(2014122110); ++ { squash warning } ++ result:=NR_NO; ++ end; ++ ++ ++ function tcgaarch64.handle_load_store(list: TAsmList; op: tasmop; size: tcgsize; oppostfix: toppostfix; reg: tregister; ref: treference):treference; ++ begin ++ make_simple_ref(list,op,size,oppostfix,ref,NR_NO); ++ list.concat(setoppostfix(taicpu.op_reg_ref(op,reg,ref),oppostfix)); ++ result:=ref; ++ end; ++ ++ ++ procedure tcgaarch64.handle_reg_imm12_reg(list: TAsmList; op: Tasmop; size: tcgsize; src: tregister; a: tcgint; dst: tregister; tmpreg: tregister; setflags, usedest: boolean); ++ var ++ instr: taicpu; ++ so: tshifterop; ++ hadtmpreg: boolean; ++ begin ++ { imm12 } ++ if (a>=0) and ++ (a<=((1 shl 12)-1)) then ++ if usedest then ++ instr:=taicpu.op_reg_reg_const(op,dst,src,a) ++ else ++ instr:=taicpu.op_reg_const(op,src,a) ++ { imm12 lsl 12 } ++ else if (a and not(((tcgint(1) shl 12)-1) shl 12))=0 then ++ begin ++ so.shiftmode:=SM_LSL; ++ so.shiftimm:=12; ++ if usedest then ++ instr:=taicpu.op_reg_reg_const_shifterop(op,dst,src,a shr 12,so) ++ else ++ instr:=taicpu.op_reg_const_shifterop(op,src,a shr 12,so) ++ end ++ else ++ begin ++ { todo: other possible optimizations (e.g. load 16 bit constant in ++ register and then add/sub/cmp/cmn shifted the rest) } ++ if tmpreg=NR_NO then ++ begin ++ hadtmpreg:=false; ++ tmpreg:=getintregister(list,size); ++ end ++ else ++ begin ++ hadtmpreg:=true; ++ getcpuregister(list,tmpreg); ++ end; ++ a_load_const_reg(list,size,a,tmpreg); ++ if usedest then ++ instr:=taicpu.op_reg_reg_reg(op,dst,src,tmpreg) ++ else ++ instr:=taicpu.op_reg_reg(op,src,tmpreg); ++ if hadtmpreg then ++ ungetcpuregister(list,tmpreg); ++ end; ++ if setflags then ++ setoppostfix(instr,PF_S); ++ list.concat(instr); ++ end; ++ ++ ++{**************************************************************************** ++ Assembler code ++****************************************************************************} ++ ++ procedure tcgaarch64.init_register_allocators; ++ begin ++ inherited init_register_allocators; ++ ++ rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE, ++ [RS_X0,RS_X1,RS_X2,RS_X3,RS_X4,RS_X5,RS_X6,RS_X7,RS_X8, ++ RS_X9,RS_X10,RS_X11,RS_X12,RS_X13,RS_X14,RS_X15,RS_X16,RS_X17, ++ RS_X19,RS_X20,RS_X21,RS_X22,RS_X23,RS_X24,RS_X25,RS_X26,RS_X27,RS_X28 ++ { maybe we can enable this in the future for leaf functions (it's ++ the frame pointer) ++ ,RS_X29 }], ++ first_int_imreg,[]); ++ ++ rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBMMD, ++ [RS_Q0,RS_Q1,RS_Q2,RS_Q3,RS_Q4,RS_Q5,RS_Q6,RS_Q7, ++ RS_Q8,RS_Q9,RS_Q10,RS_Q11,RS_Q12,RS_Q13,RS_Q14,RS_Q15, ++ RS_Q16,RS_Q17,RS_Q18,RS_Q19,RS_Q20,RS_Q21,RS_Q22,RS_Q23, ++ RS_Q24,RS_Q25,RS_Q26,RS_Q27,RS_Q28,RS_Q29,RS_Q30,RS_Q31], ++ first_mm_imreg,[]); ++ end; ++ ++ ++ procedure tcgaarch64.done_register_allocators; ++ begin ++ rg[R_INTREGISTER].free; ++ rg[R_FPUREGISTER].free; ++ rg[R_MMREGISTER].free; ++ inherited done_register_allocators; ++ end; ++ ++ ++ function tcgaarch64.getmmregister(list: TAsmList; size: tcgsize):tregister; ++ begin ++ case size of ++ OS_F32: ++ result:=rg[R_MMREGISTER].getregister(list,R_SUBMMS); ++ OS_F64: ++ result:=rg[R_MMREGISTER].getregister(list,R_SUBMMD) ++ else ++ internalerror(2014102701); ++ end; ++ end; ++ ++ ++ procedure tcgaarch64.a_call_name(list: TAsmList; const s: string; weak: boolean); ++ begin ++ if not weak then ++ list.concat(taicpu.op_sym(A_BL,current_asmdata.RefAsmSymbol(s))) ++ else ++ list.concat(taicpu.op_sym(A_BL,current_asmdata.WeakRefAsmSymbol(s))); ++ end; ++ ++ ++ procedure tcgaarch64.a_call_reg(list:TAsmList;Reg:tregister); ++ begin ++ list.concat(taicpu.op_reg(A_BLR,reg)); ++ end; ++ ++ ++ {********************** load instructions ********************} ++ ++ procedure tcgaarch64.a_load_const_reg(list: TAsmList; size: tcgsize; a: tcgint; reg : tregister); ++ var ++ preva: tcgint; ++ opc: tasmop; ++ shift,maxshift: byte; ++ so: tshifterop; ++ reginited: boolean; ++ mask: tcgint; ++ begin ++ { if we load a value into a 32 bit register, it is automatically ++ zero-extended to 64 bit } ++ if (high(a)=0) and ++ (size in [OS_64,OS_S64]) then ++ begin ++ size:=OS_32; ++ reg:=makeregsize(reg,size); ++ end; ++ { values <= 32 bit are stored in a 32 bit register } ++ if not(size in [OS_64,OS_S64]) then ++ a:=cardinal(a); ++ ++ if size in [OS_64,OS_S64] then ++ begin ++ mask:=-1; ++ maxshift:=64; ++ end ++ else ++ begin ++ mask:=$ffffffff; ++ maxshift:=32; ++ end; ++ { single movn enough? (to be extended) } ++ shift:=16; ++ preva:=a; ++ repeat ++ if (a shr shift)=(mask shr shift) then ++ begin ++ if shift=16 then ++ list.concat(taicpu.op_reg_const(A_MOVN,reg,not(word(preva)))) ++ else ++ begin ++ shifterop_reset(so); ++ so.shiftmode:=SM_LSL; ++ so.shiftimm:=shift-16; ++ list.concat(taicpu.op_reg_const_shifterop(A_MOVN,reg,not(word(preva)),so)); ++ end; ++ exit; ++ end; ++ { only try the next 16 bits if the current one is all 1 bits, since ++ the movn will set all lower bits to 1 } ++ if word(a shr (shift-16))<>$ffff then ++ break; ++ inc(shift,16); ++ until shift=maxshift; ++ reginited:=false; ++ shift:=0; ++ { can be optimized later to use more movn } ++ repeat ++ { leftover is shifterconst? (don't check if we can represent it just ++ as effectively with movz/movk, as this check is expensive) } ++ if ((shift0) and ++ ((a shr 16)<>0)) and ++ is_shifter_const(a shl shift,size) then ++ begin ++ if reginited then ++ list.concat(taicpu.op_reg_reg_const(A_ORR,reg,reg,a shl shift)) ++ else ++ list.concat(taicpu.op_reg_reg_const(A_ORR,reg,makeregsize(NR_XZR,size),a shl shift)); ++ exit; ++ end; ++ { set all 16 bit parts <> 0 } ++ if (word(a)<>0) or ++ ((shift=0) and ++ (a=0)) then ++ if shift=0 then ++ begin ++ list.concat(taicpu.op_reg_const(A_MOVZ,reg,word(a))); ++ reginited:=true; ++ end ++ else ++ begin ++ shifterop_reset(so); ++ so.shiftmode:=SM_LSL; ++ so.shiftimm:=shift; ++ if not reginited then ++ begin ++ opc:=A_MOVZ; ++ reginited:=true; ++ end ++ else ++ opc:=A_MOVK; ++ list.concat(taicpu.op_reg_const_shifterop(opc,reg,word(a),so)); ++ end; ++ preva:=a; ++ a:=a shr 16; ++ inc(shift,16); ++ until word(preva)=preva; ++ if not reginited then ++ internalerror(2014102702); ++ end; ++ ++ ++ procedure tcgaarch64.a_load_const_ref(list: TAsmList; size: tcgsize; a: tcgint; const ref: treference); ++ var ++ reg: tregister; ++ begin ++ { use the zero register if possible } ++ if a=0 then ++ begin ++ if size in [OS_64,OS_S64] then ++ reg:=NR_XZR ++ else ++ reg:=NR_WZR; ++ a_load_reg_ref(list,size,size,reg,ref); ++ end ++ else ++ inherited; ++ end; ++ ++ ++ procedure tcgaarch64.a_load_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); ++ var ++ oppostfix:toppostfix; ++ hreg: tregister; ++ begin ++ if tcgsize2Size[fromsize]>=tcgsize2Size[tosize] then ++ fromsize:=tosize ++ { have a 32 bit register but need a 64 bit one? } ++ else if tosize in [OS_64,OS_S64] then ++ begin ++ { sign extend if necessary } ++ if fromsize in [OS_S8,OS_S16,OS_S32] then ++ begin ++ { can't overwrite reg, may be a constant reg } ++ hreg:=getintregister(list,tosize); ++ a_load_reg_reg(list,fromsize,tosize,reg,hreg); ++ reg:=hreg; ++ end ++ else ++ { top 32 bit are zero by default } ++ reg:=makeregsize(reg,OS_64); ++ fromsize:=tosize; ++ end; ++ if (ref.alignment<>0) and ++ (ref.alignment=tcgsize2Size[tosize] then ++ fromsize:=tosize; ++ { ensure that all bits of the 32/64 register are always correctly set: ++ * default behaviour is always to zero-extend to the entire (64 bit) ++ register -> unsigned 8/16/32 bit loads only exist with a 32 bit ++ target register, as the upper 32 bit will be zeroed implicitly ++ -> always make target register 32 bit ++ * signed loads exist both with 32 and 64 bit target registers, ++ depending on whether the value should be sign extended to 32 or ++ to 64 bit (if sign extended to 32 bit, the upper 32 bits of the ++ corresponding 64 bit register are again zeroed) -> no need to ++ change anything (we only have 32 and 64 bit registers), except that ++ when loading an OS_S32 to a 32 bit register, we don't need/can't ++ use sign extension ++ } ++ if fromsize in [OS_8,OS_16,OS_32] then ++ reg:=makeregsize(reg,OS_32); ++ if (ref.alignment<>0) and ++ (ref.alignment insert conversion when when ++ we have to truncate/sign extend inside the (32 or 64 bit) register ++ holding the value, and when we sign extend from a 32 to a 64 bit ++ register } ++ if (tcgsize2size[fromsize]>tcgsize2size[tosize]) or ++ ((tcgsize2size[fromsize]=tcgsize2size[tosize]) and ++ (fromsize<>tosize) and ++ not(fromsize in [OS_32,OS_S32,OS_64,OS_S64])) or ++ ((fromsize in [OS_S8,OS_S16,OS_S32]) and ++ (tosize in [OS_64,OS_S64])) or ++ { needs to mask out the sign in the top 16 bits } ++ ((fromsize=OS_S8) and ++ (tosize=OS_16)) then ++ begin ++ case tosize of ++ OS_8: ++ list.concat(setoppostfix(taicpu.op_reg_reg(A_UXT,reg2,makeregsize(reg1,OS_32)),PF_B)); ++ OS_16: ++ list.concat(setoppostfix(taicpu.op_reg_reg(A_UXT,reg2,makeregsize(reg1,OS_32)),PF_H)); ++ OS_S8: ++ list.concat(setoppostfix(taicpu.op_reg_reg(A_SXT,reg2,makeregsize(reg1,OS_32)),PF_B)); ++ OS_S16: ++ list.concat(setoppostfix(taicpu.op_reg_reg(A_SXT,reg2,makeregsize(reg1,OS_32)),PF_H)); ++ { while "mov wN, wM" automatically inserts a zero-extension and ++ hence we could encode a 64->32 bit move like that, the problem ++ is that we then can't distinguish 64->32 from 32->32 moves, and ++ the 64->32 truncation could be removed altogether... So use a ++ different instruction } ++ OS_32, ++ OS_S32: ++ { in theory, reg1 should be 64 bit here (since fromsize>tosize), ++ but because of the way location_force_register() tries to ++ avoid superfluous zero/sign extensions, it's not always the ++ case -> also force reg1 to to 64 bit } ++ list.concat(taicpu.op_reg_reg_const_const(A_UBFIZ,makeregsize(reg2,OS_64),makeregsize(reg1,OS_64),0,32)); ++ OS_64, ++ OS_S64: ++ list.concat(setoppostfix(taicpu.op_reg_reg(A_SXT,reg2,makeregsize(reg1,OS_32)),PF_W)); ++ else ++ internalerror(2002090901); ++ end; ++ end ++ else ++ begin ++ { 32 -> 32 bit move implies zero extension (sign extensions have ++ been handled above) -> also use for 32 <-> 64 bit moves } ++ if not(fromsize in [OS_64,OS_S64]) or ++ not(tosize in [OS_64,OS_S64]) then ++ instr:=taicpu.op_reg_reg(A_MOV,makeregsize(reg2,OS_32),makeregsize(reg1,OS_32)) ++ else ++ instr:=taicpu.op_reg_reg(A_MOV,reg2,reg1); ++ list.Concat(instr); ++ { Notify the register allocator that we have written a move instruction so ++ it can try to eliminate it. } ++ add_move_instruction(instr); ++ end; ++ end; ++ ++ ++ procedure tcgaarch64.a_loadaddr_ref_reg(list: TAsmList; const ref: treference; r: tregister); ++ var ++ href: treference; ++ so: tshifterop; ++ op: tasmop; ++ begin ++ op:=A_LDR; ++ href:=ref; ++ { simplify as if we're going to perform a regular 64 bit load, using ++ "r" as the new base register if possible/necessary } ++ make_simple_ref(list,op,OS_ADDR,PF_None,href,r); ++ { load literal? } ++ if assigned(href.symbol) then ++ begin ++ if (href.base<>NR_NO) or ++ (href.index<>NR_NO) or ++ not assigned(href.symboldata) then ++ internalerror(2014110912); ++ list.concat(taicpu.op_reg_sym_ofs(A_ADR,r,href.symbol,href.offset)); ++ end ++ else ++ begin ++ if href.index<>NR_NO then ++ begin ++ if href.shiftmode<>SM_None then ++ begin ++ { "add" supports a supperset of the shift modes supported by ++ load/store instructions } ++ shifterop_reset(so); ++ so.shiftmode:=href.shiftmode; ++ so.shiftimm:=href.shiftimm; ++ list.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,r,href.base,href.index,so)); ++ end ++ else ++ a_op_reg_reg_reg(list,OP_ADD,OS_ADDR,href.index,href.base,r); ++ end ++ else if href.offset<>0 then ++ a_op_const_reg_reg(list,OP_ADD,OS_ADDR,href.offset,href.base,r) ++ else ++ a_load_reg_reg(list,OS_ADDR,OS_ADDR,href.base,r); ++ end; ++ end; ++ ++ ++ procedure tcgaarch64.a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); ++ begin ++ internalerror(2014122107) ++ end; ++ ++ ++ procedure tcgaarch64.a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); ++ begin ++ internalerror(2014122108) ++ end; ++ ++ ++ procedure tcgaarch64.a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); ++ begin ++ internalerror(2014122109) ++ end; ++ ++ ++ procedure tcgaarch64.a_loadmm_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister; shuffle: pmmshuffle); ++ var ++ instr: taicpu; ++ begin ++ if assigned(shuffle) and ++ not shufflescalar(shuffle) then ++ internalerror(2014122104); ++ if fromsize=tosize then ++ begin ++ instr:=taicpu.op_reg_reg(A_FMOV,reg2,reg1); ++ { Notify the register allocator that we have written a move ++ instruction so it can try to eliminate it. } ++ add_move_instruction(instr); ++ end ++ else ++ begin ++ if (reg_cgsize(reg1)<>fromsize) or ++ (reg_cgsize(reg2)<>tosize) then ++ internalerror(2014110913); ++ instr:=taicpu.op_reg_reg(A_FCVT,reg2,reg1); ++ end; ++ list.Concat(instr); ++ end; ++ ++ ++ procedure tcgaarch64.a_loadmm_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister; shuffle: pmmshuffle); ++ var ++ tmpreg: tregister; ++ begin ++ if assigned(shuffle) and ++ not shufflescalar(shuffle) then ++ internalerror(2014122105); ++ tmpreg:=NR_NO; ++ if (fromsize<>tosize) then ++ begin ++ tmpreg:=reg; ++ reg:=getmmregister(list,fromsize); ++ end; ++ handle_load_store(list,A_LDR,fromsize,PF_None,reg,ref); ++ if (fromsize<>tosize) then ++ a_loadmm_reg_reg(list,fromsize,tosize,reg,tmpreg,nil); ++ end; ++ ++ ++ procedure tcgaarch64.a_loadmm_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference; shuffle: pmmshuffle); ++ var ++ tmpreg: tregister; ++ begin ++ if assigned(shuffle) and ++ not shufflescalar(shuffle) then ++ internalerror(2014122106); ++ if (fromsize<>tosize) then ++ begin ++ tmpreg:=getmmregister(list,tosize); ++ a_loadmm_reg_reg(list,fromsize,tosize,reg,tmpreg,nil); ++ reg:=tmpreg; ++ end; ++ handle_load_store(list,A_STR,tosize,PF_NONE,reg,ref); ++ end; ++ ++ ++ procedure tcgaarch64.a_loadmm_intreg_reg(list: TAsmList; fromsize, tosize: tcgsize; intreg, mmreg: tregister; shuffle: pmmshuffle); ++ begin ++ if not shufflescalar(shuffle) then ++ internalerror(2014122801); ++ if not(tcgsize2size[fromsize] in [4,8]) or ++ (tcgsize2size[fromsize]<>tcgsize2size[tosize]) then ++ internalerror(2014122803); ++ list.concat(taicpu.op_reg_reg(A_INS,mmreg,intreg)); ++ end; ++ ++ ++ procedure tcgaarch64.a_loadmm_reg_intreg(list: TAsmList; fromsize, tosize: tcgsize; mmreg, intreg: tregister; shuffle: pmmshuffle); ++ begin ++ if not shufflescalar(shuffle) then ++ internalerror(2014122802); ++ if not(tcgsize2size[fromsize] in [4,8]) or ++ (tcgsize2size[fromsize]<>tcgsize2size[tosize]) then ++ internalerror(2014122804); ++ list.concat(taicpu.op_reg_reg(A_UMOV,intreg,mmreg)); ++ end; ++ ++ ++ procedure tcgaarch64.a_opmm_reg_reg(list: TAsmList; Op: TOpCG; size: tcgsize; src, dst: tregister; shuffle: pmmshuffle); ++ begin ++ case op of ++ { "xor Vx,Vx" is used to initialize global regvars to 0 } ++ OP_XOR: ++ begin ++ if (src<>dst) or ++ (reg_cgsize(src)<>size) or ++ assigned(shuffle) then ++ internalerror(2015011401); ++ case size of ++ OS_F32, ++ OS_F64: ++ list.concat(taicpu.op_reg_const(A_MOVI,makeregsize(dst,OS_F64),0)); ++ else ++ internalerror(2015011402); ++ end; ++ end ++ else ++ internalerror(2015011403); ++ end; ++ end; ++ ++ ++ procedure tcgaarch64.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tcgsize; src, dst: TRegister); ++ var ++ bitsize, ++ signbit: longint; ++ begin ++ if srcsize in [OS_64,OS_S64] then ++ begin ++ bitsize:=64; ++ signbit:=6; ++ end ++ else ++ begin ++ bitsize:=32; ++ signbit:=5; ++ end; ++ { source is 0 -> dst will have to become 255 } ++ list.concat(taicpu.op_reg_const(A_CMP,src,0)); ++ if reverse then ++ begin ++ list.Concat(taicpu.op_reg_reg(A_CLZ,makeregsize(dst,srcsize),src)); ++ { xor 31/63 is the same as setting the lower 5/6 bits to ++ "31/63-(lower 5/6 bits of dst)" } ++ list.Concat(taicpu.op_reg_reg_const(A_EOR,dst,dst,bitsize-1)); ++ end ++ else ++ begin ++ list.Concat(taicpu.op_reg_reg(A_RBIT,makeregsize(dst,srcsize),src)); ++ list.Concat(taicpu.op_reg_reg(A_CLZ,dst,dst)); ++ end; ++ { set dst to -1 if src was 0 } ++ list.Concat(taicpu.op_reg_reg_reg_cond(A_CSINV,dst,dst,makeregsize(NR_XZR,dstsize),C_NE)); ++ { mask the -1 to 255 if src was 0 (anyone find a two-instruction ++ branch-free version? All of mine are 3...) } ++ list.Concat(setoppostfix(taicpu.op_reg_reg(A_UXT,makeregsize(dst,OS_32),makeregsize(dst,OS_32)),PF_B)); ++ end; ++ ++ ++ procedure tcgaarch64.a_load_reg_ref_unaligned(list: TAsmList; fromsize, tosize: tcgsize; register: tregister; const ref: treference); ++ var ++ href: treference; ++ hreg1, hreg2, tmpreg: tregister; ++ begin ++ if fromsize in [OS_64,OS_S64] then ++ begin ++ { split into two 32 bit stores } ++ hreg1:=makeregsize(register,OS_32); ++ hreg2:=getintregister(list,OS_32); ++ a_op_const_reg_reg(list,OP_SHR,OS_64,32,register,makeregsize(hreg2,OS_64)); ++ if target_info.endian=endian_big then ++ begin ++ tmpreg:=hreg1; ++ hreg1:=hreg2; ++ hreg2:=tmpreg; ++ end; ++ { can we use STP? } ++ if (ref.alignment=4) and ++ (simple_ref_type(A_STP,OS_32,PF_None,ref)=sr_simple) then ++ list.concat(taicpu.op_reg_reg_ref(A_STP,hreg1,hreg2,ref)) ++ else ++ begin ++ a_load_reg_ref(list,OS_32,OS_32,hreg1,ref); ++ href:=ref; ++ inc(href.offset,4); ++ a_load_reg_ref(list,OS_32,OS_32,hreg2,href); ++ end; ++ end ++ else ++ inherited; ++ end; ++ ++ ++ procedure tcgaarch64.maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister); ++ const ++ overflowops = [OP_MUL,OP_IMUL,OP_SHL,OP_ADD,OP_SUB,OP_NOT,OP_NEG]; ++ begin ++ if (op in overflowops) and ++ (size in [OS_8,OS_S8,OS_16,OS_S16]) then ++ a_load_reg_reg(list,OS_32,size,makeregsize(dst,OS_32),makeregsize(dst,OS_32)) ++ end; ++ ++ ++ procedure tcgaarch64.a_op_const_reg(list: TAsmList; op: topcg; size: tcgsize; a: tcgint; reg: tregister); ++ begin ++ optimize_op_const(size,op,a); ++ case op of ++ OP_NONE: ++ exit; ++ OP_MOVE: ++ a_load_const_reg(list,size,a,reg); ++ OP_NEG,OP_NOT: ++ internalerror(200306011); ++ else ++ a_op_const_reg_reg(list,op,size,a,reg,reg); ++ end; ++ end; ++ ++ ++ procedure tcgaarch64.a_op_reg_reg(list:TAsmList;op:topcg;size:tcgsize;src,dst:tregister); ++ begin ++ Case op of ++ OP_NEG, ++ OP_NOT: ++ begin ++ list.concat(taicpu.op_reg_reg(TOpCG2AsmOpReg[op],dst,src)); ++ maybeadjustresult(list,op,size,dst); ++ end ++ else ++ a_op_reg_reg_reg(list,op,size,src,dst,dst); ++ end; ++ end; ++ ++ ++ procedure tcgaarch64.a_op_const_reg_reg(list: TAsmList; op: topcg; size: tcgsize; a: tcgint; src, dst: tregister); ++ var ++ l: tlocation; ++ begin ++ a_op_const_reg_reg_checkoverflow(list,op,size,a,src,dst,false,l); ++ end; ++ ++ ++ procedure tcgaarch64.a_op_reg_reg_reg(list: TAsmList; op: topcg; size: tcgsize; src1, src2, dst: tregister); ++ var ++ hreg: tregister; ++ begin ++ { no ROLV opcode... } ++ if op=OP_ROL then ++ begin ++ case size of ++ OS_32,OS_S32, ++ OS_64,OS_S64: ++ begin ++ hreg:=getintregister(list,size); ++ a_load_const_reg(list,size,tcgsize2size[size]*8,hreg); ++ a_op_reg_reg(list,OP_SUB,size,src1,hreg); ++ a_op_reg_reg_reg(list,OP_ROR,size,hreg,src2,dst); ++ exit; ++ end; ++ else ++ internalerror(2014111005); ++ end; ++ end ++ else if (op=OP_ROR) and ++ not(size in [OS_32,OS_S32,OS_64,OS_S64]) then ++ internalerror(2014111006); ++ if TOpCG2AsmOpReg[op]=A_NONE then ++ internalerror(2014111007); ++ list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOpReg[op],dst,src2,src1)); ++ maybeadjustresult(list,op,size,dst); ++ end; ++ ++ ++ procedure tcgaarch64.a_op_const_reg_reg_checkoverflow(list: TAsmList; op: topcg; size: tcgsize; a: tcgint; src, dst: tregister; setflags : boolean; var ovloc : tlocation); ++ var ++ shiftcountmask: longint; ++ constreg: tregister; ++ begin ++ { add/sub instructions have only positive immediate operands } ++ if (op in [OP_ADD,OP_SUB]) and ++ (a<0) then ++ begin ++ if op=OP_ADD then ++ op:=op_SUB ++ else ++ op:=OP_ADD; ++ { avoid range/overflow error in case a = low(tcgint) } ++{$push}{$r-}{$q-} ++ a:=-a; ++{$pop} ++ end; ++ ovloc.loc:=LOC_VOID; ++ optimize_op_const(size,op,a); ++ case op of ++ OP_NONE: ++ begin ++ a_load_reg_reg(list,size,size,src,dst); ++ exit; ++ end; ++ OP_MOVE: ++ begin ++ a_load_const_reg(list,size,a,dst); ++ exit; ++ end; ++ end; ++ case op of ++ OP_ADD, ++ OP_SUB: ++ begin ++ handle_reg_imm12_reg(list,TOpCG2AsmOpImm[op],size,src,a,dst,NR_NO,setflags,true); ++ { on a 64 bit target, overflows with smaller data types ++ are handled via range errors } ++ if setflags and ++ (size in [OS_64,OS_S64]) then ++ begin ++ location_reset(ovloc,LOC_FLAGS,OS_8); ++ if size=OS_64 then ++ if op=OP_ADD then ++ ovloc.resflags:=F_CS ++ else ++ ovloc.resflags:=F_CC ++ else ++ ovloc.resflags:=F_VS; ++ end; ++ end; ++ OP_OR, ++ OP_AND, ++ OP_XOR: ++ begin ++ if not(size in [OS_64,OS_S64]) then ++ a:=cardinal(a); ++ if is_shifter_const(a,size) then ++ list.concat(taicpu.op_reg_reg_const(TOpCG2AsmOpReg[op],dst,src,a)) ++ else ++ begin ++ constreg:=getintregister(list,size); ++ a_load_const_reg(list,size,a,constreg); ++ a_op_reg_reg_reg(list,op,size,constreg,src,dst); ++ end; ++ end; ++ OP_SHL, ++ OP_SHR, ++ OP_SAR: ++ begin ++ if size in [OS_64,OS_S64] then ++ shiftcountmask:=63 ++ else ++ shiftcountmask:=31; ++ if (a and shiftcountmask)<>0 Then ++ list.concat(taicpu.op_reg_reg_const( ++ TOpCG2AsmOpImm[Op],dst,src,a and shiftcountmask)) ++ else ++ a_load_reg_reg(list,size,size,src,dst); ++ if (a and not(tcgint(shiftcountmask)))<>0 then ++ internalError(2014112101); ++ end; ++ OP_ROL, ++ OP_ROR: ++ begin ++ case size of ++ OS_32,OS_S32: ++ if (a and not(tcgint(31)))<>0 then ++ internalError(2014112102); ++ OS_64,OS_S64: ++ if (a and not(tcgint(63)))<>0 then ++ internalError(2014112103); ++ else ++ internalError(2014112104); ++ end; ++ { there's only a ror opcode } ++ if op=OP_ROL then ++ a:=(tcgsize2size[size]*8)-a; ++ list.concat(taicpu.op_reg_reg_const(A_ROR,dst,src,a)); ++ end; ++ OP_MUL, ++ OP_IMUL, ++ OP_DIV, ++ OP_IDIV: ++ begin ++ constreg:=getintregister(list,size); ++ a_load_const_reg(list,size,a,constreg); ++ a_op_reg_reg_reg_checkoverflow(list,op,size,constreg,src,dst,setflags,ovloc); ++ end; ++ else ++ internalerror(2014111403); ++ end; ++ maybeadjustresult(list,op,size,dst); ++ end; ++ ++ ++ procedure tcgaarch64.a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: topcg; size: tcgsize; src1, src2, dst: tregister; setflags : boolean; var ovloc : tlocation); ++ var ++ tmpreg1: tregister; ++ begin ++ ovloc.loc:=LOC_VOID; ++ { overflow can only occur with 64 bit calculations on 64 bit cpus } ++ if setflags and ++ (size in [OS_64,OS_S64]) then ++ begin ++ case op of ++ OP_ADD, ++ OP_SUB: ++ begin ++ list.concat(setoppostfix(taicpu.op_reg_reg_reg(TOpCG2AsmOpReg[op],dst,src2,src1),PF_S)); ++ ovloc.loc:=LOC_FLAGS; ++ if size=OS_64 then ++ if op=OP_ADD then ++ ovloc.resflags:=F_CS ++ else ++ ovloc.resflags:=F_CC ++ else ++ ovloc.resflags:=F_VS; ++ { finished; since we won't call through to a_op_reg_reg_reg, ++ adjust the result here if necessary } ++ maybeadjustresult(list,op,size,dst); ++ exit; ++ end; ++ OP_MUL: ++ begin ++ { check whether the upper 64 bit of the 128 bit product is 0 } ++ tmpreg1:=getintregister(list,OS_64); ++ list.concat(taicpu.op_reg_reg_reg(A_UMULH,tmpreg1,src2,src1)); ++ list.concat(taicpu.op_reg_const(A_CMP,tmpreg1,0)); ++ ovloc.loc:=LOC_FLAGS; ++ ovloc.resflags:=F_NE; ++ { still have to perform the actual multiplication } ++ end; ++ OP_IMUL: ++ begin ++ { check whether the sign bit of the (128 bit) result is the ++ same as "sign bit of src1" xor "signbit of src2" (if so, no ++ overflow and the xor-product of all sign bits is 0) } ++ tmpreg1:=getintregister(list,OS_64); ++ list.concat(taicpu.op_reg_reg_reg(A_SMULH,tmpreg1,src2,src1)); ++ list.concat(taicpu.op_reg_reg_reg(A_EOR,tmpreg1,tmpreg1,src1)); ++ list.concat(taicpu.op_reg_reg_reg(A_EOR,tmpreg1,tmpreg1,src2)); ++ list.concat(taicpu.op_reg_const(A_TST,tmpreg1,$80000000)); ++ ovloc.loc:=LOC_FLAGS; ++ ovloc.resflags:=F_NE; ++ { still have to perform the actual multiplication } ++ end; ++ OP_IDIV, ++ OP_DIV: ++ begin ++ { not handled here, needs div-by-zero check (dividing by zero ++ just gives a 0 result on aarch64), and low(int64) div -1 ++ check for overflow) } ++ internalerror(2014122101); ++ end; ++ end; ++ end; ++ a_op_reg_reg_reg(list,op,size,src1,src2,dst); ++ end; ++ ++ ++ ++ {*************** compare instructructions ****************} ++ ++ procedure tcgaarch64.a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel); ++ var ++ op: tasmop; ++ begin ++ if a>=0 then ++ op:=A_CMP ++ else ++ op:=A_CMN; ++ { avoid range/overflow error in case a=low(tcgint) } ++{$push}{$r-}{$q-} ++ handle_reg_imm12_reg(list,op,size,reg,abs(a),NR_XZR,NR_NO,false,false); ++{$pop} ++ a_jmp_cond(list,cmp_op,l); ++ end; ++ ++ ++ procedure tcgaarch64.a_cmp_reg_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg1,reg2: tregister; l: tasmlabel); ++ begin ++ list.concat(taicpu.op_reg_reg(A_CMP,reg2,reg1)); ++ a_jmp_cond(list,cmp_op,l); ++ end; ++ ++ ++ procedure tcgaarch64.a_jmp_always(list: TAsmList; l: TAsmLabel); ++ var ++ ai: taicpu; ++ begin ++ ai:=TAiCpu.op_sym(A_B,current_asmdata.RefAsmSymbol(l.name)); ++ ai.is_jmp:=true; ++ list.Concat(ai); ++ end; ++ ++ ++ procedure tcgaarch64.a_jmp_name(list: TAsmList; const s: string); ++ var ++ ai: taicpu; ++ begin ++ ai:=TAiCpu.op_sym(A_B,current_asmdata.RefAsmSymbol(s)); ++ ai.is_jmp:=true; ++ list.Concat(ai); ++ end; ++ ++ ++ procedure tcgaarch64.a_jmp_cond(list: TAsmList; cond: TOpCmp; l: TAsmLabel); ++ var ++ ai: taicpu; ++ begin ++ ai:=TAiCpu.op_sym(A_B,l); ++ ai.is_jmp:=true; ++ ai.SetCondition(TOpCmp2AsmCond[cond]); ++ list.Concat(ai); ++ end; ++ ++ ++ procedure tcgaarch64.a_jmp_flags(list: TAsmList; const f: tresflags; l: tasmlabel); ++ var ++ ai : taicpu; ++ begin ++ ai:=Taicpu.op_sym(A_B,l); ++ ai.is_jmp:=true; ++ ai.SetCondition(flags_to_cond(f)); ++ list.Concat(ai); ++ end; ++ ++ ++ procedure tcgaarch64.g_flags2reg(list: TAsmList; size: tcgsize; const f: tresflags; reg: tregister); ++ begin ++ list.concat(taicpu.op_reg_cond(A_CSET,reg,flags_to_cond(f))); ++ end; ++ ++ ++ procedure tcgaarch64.g_overflowcheck(list: TAsmList; const loc: tlocation; def: tdef); ++ begin ++ { we need an explicit overflow location, because there are many ++ possibilities (not just the overflow flag, which is only used for ++ signed add/sub) } ++ internalerror(2014112303); ++ end; ++ ++ ++ procedure tcgaarch64.g_overflowcheck_loc(list: TAsmList; const loc: tlocation; def: tdef; ovloc : tlocation); ++ var ++ hl : tasmlabel; ++ hflags : tresflags; ++ begin ++ if not(cs_check_overflow in current_settings.localswitches) then ++ exit; ++ current_asmdata.getjumplabel(hl); ++ case ovloc.loc of ++ LOC_FLAGS: ++ begin ++ hflags:=ovloc.resflags; ++ inverse_flags(hflags); ++ cg.a_jmp_flags(list,hflags,hl); ++ end; ++ else ++ internalerror(2014112304); ++ end; ++ a_call_name(list,'FPC_OVERFLOW',false); ++ a_label(list,hl); ++ end; ++ ++ { *********** entry/exit code and address loading ************ } ++ ++ function tcgaarch64.save_regs(list: TAsmList; rt: tregistertype; lowsr, highsr: tsuperregister; sub: tsubregister): longint; ++ var ++ ref: treference; ++ sr: tsuperregister; ++ pairreg: tregister; ++ begin ++ result:=0; ++ reference_reset_base(ref,NR_SP,-16,16); ++ ref.addressmode:=AM_PREINDEXED; ++ pairreg:=NR_NO; ++ { store all used registers pairwise } ++ for sr:=lowsr to highsr do ++ if sr in rg[rt].used_in_proc then ++ if pairreg=NR_NO then ++ pairreg:=newreg(rt,sr,sub) ++ else ++ begin ++ inc(result,16); ++ list.concat(taicpu.op_reg_reg_ref(A_STP,pairreg,newreg(rt,sr,sub),ref)); ++ pairreg:=NR_NO ++ end; ++ { one left -> store twice (stack must be 16 bytes aligned) } ++ if pairreg<>NR_NO then ++ begin ++ list.concat(taicpu.op_reg_reg_ref(A_STP,pairreg,pairreg,ref)); ++ inc(result,16); ++ end; ++ end; ++ ++ ++ procedure FixupOffsets(p:TObject;arg:pointer); ++ var ++ sym: tabstractnormalvarsym absolute p; ++ begin ++ if (tsym(p).typ in [paravarsym,localvarsym]) and ++ (sym.localloc.loc=LOC_REFERENCE) and ++ (sym.localloc.reference.base=NR_STACK_POINTER_REG) then ++ begin ++ sym.localloc.reference.base:=NR_FRAME_POINTER_REG; ++ dec(sym.localloc.reference.offset,PLongint(arg)^); ++ end; ++ end; ++ ++ ++ procedure tcgaarch64.g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean); ++ var ++ ref: treference; ++ totalstackframesize: longint; ++ begin ++ if nostackframe then ++ exit; ++ { stack pointer has to be aligned to 16 bytes at all times } ++ localsize:=align(localsize,16); ++ ++ { save stack pointer and return address } ++ reference_reset_base(ref,NR_SP,-16,16); ++ ref.addressmode:=AM_PREINDEXED; ++ list.concat(taicpu.op_reg_reg_ref(A_STP,NR_FP,NR_LR,ref)); ++ { initialise frame pointer } ++ a_load_reg_reg(list,OS_ADDR,OS_ADDR,NR_SP,NR_FP); ++ ++ totalstackframesize:=localsize; ++ { save modified integer registers } ++ inc(totalstackframesize, ++ save_regs(list,R_INTREGISTER,RS_X19,RS_X28,R_SUBWHOLE)); ++ { only the lower 64 bits of the modified vector registers need to be ++ saved; if the caller needs the upper 64 bits, it has to save them ++ itself } ++ inc(totalstackframesize, ++ save_regs(list,R_MMREGISTER,RS_D8,RS_D15,R_SUBMMD)); ++ ++ { allocate stack space } ++ if localsize<>0 then ++ begin ++ localsize:=align(localsize,16); ++ current_procinfo.final_localsize:=localsize; ++ handle_reg_imm12_reg(list,A_SUB,OS_ADDR,NR_SP,localsize,NR_SP,NR_IP0,false,true); ++ end; ++ { By default, we use the frame pointer to access parameters passed via ++ the stack and the stack pointer to address local variables and temps ++ because ++ a) we can use bigger positive than negative offsets (so accessing ++ locals via negative offsets from the frame pointer would be less ++ efficient) ++ b) we don't know the local size while generating the code, so ++ accessing the parameters via the stack pointer is not possible ++ without copying them ++ The problem with this is the get_frame() intrinsic: ++ a) it must return the same value as what we pass as parentfp ++ parameter, since that's how it's used in the TP-style objects unit ++ b) its return value must usable to access all local data from a ++ routine (locals and parameters), since it's all the nested ++ routines have access to ++ c) its return value must be usable to construct a backtrace, as it's ++ also used by the exception handling routines ++ ++ The solution we use here, based on something similar that's done in ++ the MIPS port, is to generate all accesses to locals in the routine ++ itself SP-relative, and then after the code is generated and the local ++ size is known (namely, here), we change all SP-relative variables/ ++ parameters into FP-relative ones. This means that they'll be accessed ++ less efficiently from nested routines, but those accesses are indirect ++ anyway and at least this way they can be accessed at all ++ } ++ if current_procinfo.has_nestedprocs then ++ begin ++ current_procinfo.procdef.localst.SymList.ForEachCall(@FixupOffsets,@totalstackframesize); ++ current_procinfo.procdef.parast.SymList.ForEachCall(@FixupOffsets,@totalstackframesize); ++ end; ++ end; ++ ++ ++ procedure tcgaarch64.g_maybe_got_init(list : TAsmList); ++ begin ++ { nothing to do on Darwin or Linux } ++ end; ++ ++ ++ procedure tcgaarch64.g_restore_registers(list:TAsmList); ++ begin ++ { done in g_proc_exit } ++ end; ++ ++ ++ procedure tcgaarch64.load_regs(list: TAsmList; rt: tregistertype; lowsr, highsr: tsuperregister; sub: tsubregister); ++ var ++ ref: treference; ++ sr, highestsetsr: tsuperregister; ++ pairreg: tregister; ++ regcount: longint; ++ begin ++ reference_reset_base(ref,NR_SP,16,16); ++ ref.addressmode:=AM_POSTINDEXED; ++ { highest reg stored twice? } ++ regcount:=0; ++ highestsetsr:=RS_NO; ++ for sr:=lowsr to highsr do ++ if sr in rg[rt].used_in_proc then ++ begin ++ inc(regcount); ++ highestsetsr:=sr; ++ end; ++ if odd(regcount) then ++ begin ++ list.concat(taicpu.op_reg_ref(A_LDR,newreg(rt,highestsetsr,sub),ref)); ++ highestsetsr:=pred(highestsetsr); ++ end; ++ { load all (other) used registers pairwise } ++ pairreg:=NR_NO; ++ for sr:=highestsetsr downto lowsr do ++ if sr in rg[rt].used_in_proc then ++ if pairreg=NR_NO then ++ pairreg:=newreg(rt,sr,sub) ++ else ++ begin ++ list.concat(taicpu.op_reg_reg_ref(A_LDP,newreg(rt,sr,sub),pairreg,ref)); ++ pairreg:=NR_NO ++ end; ++ { There can't be any register left } ++ if pairreg<>NR_NO then ++ internalerror(2014112602); ++ end; ++ ++ ++ ++ procedure tcgaarch64.g_proc_exit(list : TAsmList;parasize:longint;nostackframe:boolean); ++ var ++ ref: treference; ++ regsstored: boolean; ++ sr: tsuperregister; ++ begin ++ if not nostackframe then ++ begin ++ { if no registers have been stored, we don't have to subtract the ++ allocated temp space from the stack pointer } ++ regsstored:=false; ++ for sr:=RS_X19 to RS_X28 do ++ if sr in rg[R_INTREGISTER].used_in_proc then ++ begin ++ regsstored:=true; ++ break; ++ end; ++ if not regsstored then ++ for sr:=RS_D8 to RS_D15 do ++ if sr in rg[R_MMREGISTER].used_in_proc then ++ begin ++ regsstored:=true; ++ break; ++ end; ++ { restore registers (and stack pointer) } ++ if regsstored then ++ begin ++ if current_procinfo.final_localsize<>0 then ++ handle_reg_imm12_reg(list,A_ADD,OS_ADDR,NR_SP,current_procinfo.final_localsize,NR_SP,NR_IP0,false,true); ++ load_regs(list,R_MMREGISTER,RS_D8,RS_D15,R_SUBMMD); ++ load_regs(list,R_INTREGISTER,RS_X19,RS_X28,R_SUBWHOLE); ++ end ++ else if current_procinfo.final_localsize<>0 then ++ { restore stack pointer } ++ a_load_reg_reg(list,OS_ADDR,OS_ADDR,NR_FP,NR_SP); ++ ++ { restore framepointer and return address } ++ reference_reset_base(ref,NR_SP,16,16); ++ ref.addressmode:=AM_POSTINDEXED; ++ list.concat(taicpu.op_reg_reg_ref(A_LDP,NR_FP,NR_LR,ref)); ++ end; ++ ++ { return } ++ list.concat(taicpu.op_none(A_RET)); ++ end; ++ ++ ++ procedure tcgaarch64.g_save_registers(list : TAsmList); ++ begin ++ { done in g_proc_entry } ++ end; ++ ++ ++ { ************* concatcopy ************ } ++ ++ procedure tcgaarch64.g_concatcopy_move(list : TAsmList;const source,dest : treference;len : tcgint); ++ var ++ paraloc1,paraloc2,paraloc3 : TCGPara; ++ pd : tprocdef; ++ begin ++ pd:=search_system_proc('MOVE'); ++ paraloc1.init; ++ paraloc2.init; ++ paraloc3.init; ++ paramanager.getintparaloc(pd,1,paraloc1); ++ paramanager.getintparaloc(pd,2,paraloc2); ++ paramanager.getintparaloc(pd,3,paraloc3); ++ a_load_const_cgpara(list,OS_SINT,len,paraloc3); ++ a_loadaddr_ref_cgpara(list,dest,paraloc2); ++ a_loadaddr_ref_cgpara(list,source,paraloc1); ++ paramanager.freecgpara(list,paraloc3); ++ paramanager.freecgpara(list,paraloc2); ++ paramanager.freecgpara(list,paraloc1); ++ alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); ++ alloccpuregisters(list,R_MMREGISTER,paramanager.get_volatile_registers_mm(pocall_default)); ++ a_call_name(list,'FPC_MOVE',false); ++ dealloccpuregisters(list,R_MMREGISTER,paramanager.get_volatile_registers_mm(pocall_default)); ++ dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); ++ paraloc3.done; ++ paraloc2.done; ++ paraloc1.done; ++ end; ++ ++ ++ procedure tcgaarch64.g_concatcopy(list: TAsmList; const source, dest: treference; len: tcgint); ++ ++ var ++ sourcebasereplaced, destbasereplaced: boolean; ++ ++ { get optimal memory operation to use for loading/storing data ++ in an unrolled loop } ++ procedure getmemop(scaledop, unscaledop: tasmop; const startref, endref: treference; opsize: tcgsize; postfix: toppostfix; out memop: tasmop; out needsimplify: boolean); ++ begin ++ if (simple_ref_type(scaledop,opsize,postfix,startref)=sr_simple) and ++ (simple_ref_type(scaledop,opsize,postfix,endref)=sr_simple) then ++ begin ++ memop:=unscaledop; ++ needsimplify:=true; ++ end ++ else if (unscaledop<>A_NONE) and ++ (simple_ref_type(unscaledop,opsize,postfix,startref)=sr_simple) and ++ (simple_ref_type(unscaledop,opsize,postfix,endref)=sr_simple) then ++ begin ++ memop:=unscaledop; ++ needsimplify:=false; ++ end ++ else ++ begin ++ memop:=scaledop; ++ needsimplify:=true; ++ end; ++ end; ++ ++ { adjust the offset and/or addressing mode after a load/store so it's ++ correct for the next one of the same size } ++ procedure updaterefafterloadstore(var ref: treference; oplen: longint); ++ begin ++ case ref.addressmode of ++ AM_OFFSET: ++ inc(ref.offset,oplen); ++ AM_POSTINDEXED: ++ { base register updated by instruction, next offset can remain ++ the same } ++ ; ++ AM_PREINDEXED: ++ begin ++ { base register updated by instruction -> next instruction can ++ use post-indexing with offset = sizeof(operation) } ++ ref.offset:=0; ++ ref.addressmode:=AM_OFFSET; ++ end; ++ end; ++ end; ++ ++ { generate a load/store and adjust the reference offset to the next ++ memory location if necessary } ++ procedure genloadstore(list: TAsmList; op: tasmop; reg: tregister; var ref: treference; postfix: toppostfix; opsize: tcgsize); ++ begin ++ list.concat(setoppostfix(taicpu.op_reg_ref(op,reg,ref),postfix)); ++ updaterefafterloadstore(ref,tcgsize2size[opsize]); ++ end; ++ ++ { generate a dual load/store (ldp/stp) and adjust the reference offset to ++ the next memory location if necessary } ++ procedure gendualloadstore(list: TAsmList; op: tasmop; reg1, reg2: tregister; var ref: treference; postfix: toppostfix; opsize: tcgsize); ++ begin ++ list.concat(setoppostfix(taicpu.op_reg_reg_ref(op,reg1,reg2,ref),postfix)); ++ updaterefafterloadstore(ref,tcgsize2size[opsize]*2); ++ end; ++ ++ { turn a reference into a pre- or post-indexed reference for use in a ++ load/store of a particular size } ++ procedure makesimpleforcopy(list: TAsmList; var scaledop: tasmop; opsize: tcgsize; postfix: toppostfix; forcepostindexing: boolean; var ref: treference; var basereplaced: boolean); ++ var ++ tmpreg: tregister; ++ scaledoffset: longint; ++ orgaddressmode: taddressmode; ++ begin ++ scaledoffset:=tcgsize2size[opsize]; ++ if scaledop in [A_LDP,A_STP] then ++ scaledoffset:=scaledoffset*2; ++ { can we use the reference as post-indexed without changes? } ++ if forcepostindexing then ++ begin ++ orgaddressmode:=ref.addressmode; ++ ref.addressmode:=AM_POSTINDEXED; ++ if (orgaddressmode=AM_POSTINDEXED) or ++ ((ref.offset=0) and ++ (simple_ref_type(scaledop,opsize,postfix,ref)=sr_simple)) then ++ begin ++ { just change the post-indexed offset to the access size } ++ ref.offset:=scaledoffset; ++ { and replace the base register if that didn't happen yet ++ (could be sp or a regvar) } ++ if not basereplaced then ++ begin ++ tmpreg:=getaddressregister(list); ++ a_load_reg_reg(list,OS_ADDR,OS_ADDR,ref.base,tmpreg); ++ ref.base:=tmpreg; ++ basereplaced:=true; ++ end; ++ exit; ++ end; ++ ref.addressmode:=orgaddressmode; ++ end; ++{$ifdef dummy} ++ This could in theory be useful in case you have a concatcopy from ++ e.g. x1+255 to x1+267 *and* the reference is aligned, but this seems ++ very unlikely. Disabled because it still needs fixes, as it ++ also generates pre-indexed loads right now at the very end for the ++ left-over gencopies ++ ++ { can we turn it into a pre-indexed reference for free? (after the ++ first operation, it will be turned into an offset one) } ++ if not forcepostindexing and ++ (ref.offset<>0) then ++ begin ++ orgaddressmode:=ref.addressmode; ++ ref.addressmode:=AM_PREINDEXED; ++ tmpreg:=ref.base; ++ if not basereplaced and ++ (ref.base=tmpreg) then ++ begin ++ tmpreg:=getaddressregister(list); ++ a_load_reg_reg(list,OS_ADDR,OS_ADDR,ref.base,tmpreg); ++ ref.base:=tmpreg; ++ basereplaced:=true; ++ end; ++ if simple_ref_type(scaledop,opsize,postfix,ref)<>sr_simple then ++ make_simple_ref(list,scaledop,opsize,postfix,ref,NR_NO); ++ exit; ++ end; ++{$endif dummy} ++ if not forcepostindexing then ++ begin ++ ref.addressmode:=AM_OFFSET; ++ make_simple_ref(list,scaledop,opsize,postfix,ref,NR_NO); ++ { this may still cause problems if the final offset is no longer ++ a simple ref; it's a bit complicated to pass all information ++ through at all places and check that here, so play safe: we ++ currently never generate unrolled copies for more than 64 ++ bytes (32 with non-double-register copies) } ++ if ref.index=NR_NO then ++ begin ++ if ((scaledop in [A_LDP,A_STP]) and ++ (ref.offset<((64-8)*tcgsize2size[opsize]))) or ++ ((scaledop in [A_LDUR,A_STUR]) and ++ (ref.offset<(255-8*tcgsize2size[opsize]))) or ++ ((scaledop in [A_LDR,A_STR]) and ++ (ref.offset<((4096-8)*tcgsize2size[opsize]))) then ++ exit; ++ end; ++ end; ++ tmpreg:=getaddressregister(list); ++ a_loadaddr_ref_reg(list,ref,tmpreg); ++ basereplaced:=true; ++ if forcepostindexing then ++ begin ++ reference_reset_base(ref,tmpreg,scaledoffset,ref.alignment); ++ ref.addressmode:=AM_POSTINDEXED; ++ end ++ else ++ begin ++ reference_reset_base(ref,tmpreg,0,ref.alignment); ++ ref.addressmode:=AM_OFFSET; ++ end ++ end; ++ ++ { prepare a reference for use by gencopy. This is done both after the ++ unrolled and regular copy loop -> get rid of post-indexing mode, make ++ sure ref is valid } ++ procedure preparecopy(list: tasmlist; scaledop, unscaledop: tasmop; var ref: treference; opsize: tcgsize; postfix: toppostfix; out op: tasmop; var basereplaced: boolean); ++ var ++ simplify: boolean; ++ begin ++ if ref.addressmode=AM_POSTINDEXED then ++ ref.offset:=tcgsize2size[opsize]; ++ getmemop(scaledop,scaledop,ref,ref,opsize,postfix,op,simplify); ++ if simplify then ++ begin ++ makesimpleforcopy(list,scaledop,opsize,postfix,false,ref,basereplaced); ++ op:=scaledop; ++ end; ++ end; ++ ++ { generate a copy from source to dest of size opsize/postfix } ++ procedure gencopy(list: TAsmList; var source, dest: treference; postfix: toppostfix; opsize: tcgsize); ++ var ++ reg: tregister; ++ loadop, storeop: tasmop; ++ begin ++ preparecopy(list,A_LDR,A_LDUR,source,opsize,postfix,loadop,sourcebasereplaced); ++ preparecopy(list,A_STR,A_STUR,dest,opsize,postfix,storeop,destbasereplaced); ++ reg:=getintregister(list,opsize); ++ genloadstore(list,loadop,reg,source,postfix,opsize); ++ genloadstore(list,storeop,reg,dest,postfix,opsize); ++ end; ++ ++ ++ { copy the leftovers after an unrolled or regular copy loop } ++ procedure gencopyleftovers(list: TAsmList; var source, dest: treference; len: longint); ++ begin ++ { stop post-indexing if we did so in the loop, since in that case all ++ offsets definitely can be represented now } ++ if source.addressmode=AM_POSTINDEXED then ++ begin ++ source.addressmode:=AM_OFFSET; ++ source.offset:=0; ++ end; ++ if dest.addressmode=AM_POSTINDEXED then ++ begin ++ dest.addressmode:=AM_OFFSET; ++ dest.offset:=0; ++ end; ++ { transfer the leftovers } ++ if len>=8 then ++ begin ++ dec(len,8); ++ gencopy(list,source,dest,PF_NONE,OS_64); ++ end; ++ if len>=4 then ++ begin ++ dec(len,4); ++ gencopy(list,source,dest,PF_NONE,OS_32); ++ end; ++ if len>=2 then ++ begin ++ dec(len,2); ++ gencopy(list,source,dest,PF_H,OS_16); ++ end; ++ if len>=1 then ++ begin ++ dec(len); ++ gencopy(list,source,dest,PF_B,OS_8); ++ end; ++ end; ++ ++ ++ const ++ { load_length + loop dec + cbnz } ++ loopoverhead=12; ++ { loop overhead + load + store } ++ totallooplen=loopoverhead + 8; ++ var ++ totalalign: longint; ++ maxlenunrolled: tcgint; ++ loadop, storeop: tasmop; ++ opsize: tcgsize; ++ postfix: toppostfix; ++ tmpsource, tmpdest: treference; ++ scaledstoreop, unscaledstoreop, ++ scaledloadop, unscaledloadop: tasmop; ++ regs: array[1..8] of tregister; ++ countreg: tregister; ++ i, regcount: longint; ++ hl: tasmlabel; ++ simplifysource, simplifydest: boolean; ++ begin ++ if len=0 then ++ exit; ++ sourcebasereplaced:=false; ++ destbasereplaced:=false; ++ { maximum common alignment } ++ totalalign:=max(1,newalignment(source.alignment,dest.alignment)); ++ { use a simple load/store? } ++ if (len in [1,2,4,8]) and ++ ((totalalign>=(len div 2)) or ++ (source.alignment=len) or ++ (dest.alignment=len)) then ++ begin ++ opsize:=int_cgsize(len); ++ a_load_ref_ref(list,opsize,opsize,source,dest); ++ exit; ++ end; ++ ++ { alignment > length is not useful, and would break some checks below } ++ while totalalign>len do ++ totalalign:=totalalign div 2; ++ ++ { operation sizes to use based on common alignment } ++ case totalalign of ++ 1: ++ begin ++ postfix:=PF_B; ++ opsize:=OS_8; ++ end; ++ 2: ++ begin ++ postfix:=PF_H; ++ opsize:=OS_16; ++ end; ++ 4: ++ begin ++ postfix:=PF_None; ++ opsize:=OS_32; ++ end ++ else ++ begin ++ totalalign:=8; ++ postfix:=PF_None; ++ opsize:=OS_64; ++ end; ++ end; ++ { maximum length to handled with an unrolled loop (4 loads + 4 stores) } ++ maxlenunrolled:=min(totalalign,8)*4; ++ { ldp/stp -> 2 registers per instruction } ++ if (totalalign>=4) and ++ (len>=totalalign*2) then ++ begin ++ maxlenunrolled:=maxlenunrolled*2; ++ scaledstoreop:=A_STP; ++ scaledloadop:=A_LDP; ++ unscaledstoreop:=A_NONE; ++ unscaledloadop:=A_NONE; ++ end ++ else ++ begin ++ scaledstoreop:=A_STR; ++ scaledloadop:=A_LDR; ++ unscaledstoreop:=A_STUR; ++ unscaledloadop:=A_LDUR; ++ end; ++ { we only need 4 instructions extra to call FPC_MOVE } ++ if cs_opt_size in current_settings.optimizerswitches then ++ maxlenunrolled:=maxlenunrolled div 2; ++ if (len>maxlenunrolled) and ++ (len>totalalign*8) then ++ begin ++ g_concatcopy_move(list,source,dest,len); ++ exit; ++ end; ++ ++ simplifysource:=true; ++ simplifydest:=true; ++ tmpsource:=source; ++ tmpdest:=dest; ++ { can we directly encode all offsets in an unrolled loop? } ++ if len<=maxlenunrolled then ++ begin ++{$ifdef extdebug} ++ list.concat(tai_comment.Create(strpnew('concatcopy unrolled loop; len/opsize/align: '+tostr(len)+'/'+tostr(tcgsize2size[opsize])+'/'+tostr(totalalign)))); ++{$endif extdebug} ++ { the leftovers will be handled separately -> -(len mod opsize) } ++ inc(tmpsource.offset,len-(len mod tcgsize2size[opsize])); ++ { additionally, the last regular load/store will be at ++ offset+len-opsize (if len-(len mod opsize)>len) } ++ if tmpsource.offset>source.offset then ++ dec(tmpsource.offset,tcgsize2size[opsize]); ++ getmemop(scaledloadop,unscaledloadop,source,tmpsource,opsize,postfix,loadop,simplifysource); ++ inc(tmpdest.offset,len-(len mod tcgsize2size[opsize])); ++ if tmpdest.offset>dest.offset then ++ dec(tmpdest.offset,tcgsize2size[opsize]); ++ getmemop(scaledstoreop,unscaledstoreop,dest,tmpdest,opsize,postfix,storeop,simplifydest); ++ tmpsource:=source; ++ tmpdest:=dest; ++ { if we can't directly encode all offsets, simplify } ++ if simplifysource then ++ begin ++ loadop:=scaledloadop; ++ makesimpleforcopy(list,loadop,opsize,postfix,false,tmpsource,sourcebasereplaced); ++ end; ++ if simplifydest then ++ begin ++ storeop:=scaledstoreop; ++ makesimpleforcopy(list,storeop,opsize,postfix,false,tmpdest,destbasereplaced); ++ end; ++ regcount:=len div tcgsize2size[opsize]; ++ { in case we transfer two registers at a time, we copy an even ++ number of registers } ++ if loadop=A_LDP then ++ regcount:=regcount and not(1); ++ { initialise for dfa } ++ regs[low(regs)]:=NR_NO; ++ { max 4 loads/stores -> max 8 registers (in case of ldp/stdp) } ++ for i:=1 to regcount do ++ regs[i]:=getintregister(list,opsize); ++ if loadop=A_LDP then ++ begin ++ { load registers } ++ for i:=1 to (regcount div 2) do ++ gendualloadstore(list,loadop,regs[i*2-1],regs[i*2],tmpsource,postfix,opsize); ++ { store registers } ++ for i:=1 to (regcount div 2) do ++ gendualloadstore(list,storeop,regs[i*2-1],regs[i*2],tmpdest,postfix,opsize); ++ end ++ else ++ begin ++ for i:=1 to regcount do ++ genloadstore(list,loadop,regs[i],tmpsource,postfix,opsize); ++ for i:=1 to regcount do ++ genloadstore(list,storeop,regs[i],tmpdest,postfix,opsize); ++ end; ++ { leftover } ++ len:=len-regcount*tcgsize2size[opsize]; ++{$ifdef extdebug} ++ list.concat(tai_comment.Create(strpnew('concatcopy unrolled loop leftover: '+tostr(len)))); ++{$endif extdebug} ++ end ++ else ++ begin ++{$ifdef extdebug} ++ list.concat(tai_comment.Create(strpnew('concatcopy regular loop; len/align: '+tostr(len)+'/'+tostr(totalalign)))); ++{$endif extdebug} ++ { regular loop -> definitely use post-indexing } ++ loadop:=scaledloadop; ++ makesimpleforcopy(list,loadop,opsize,postfix,true,tmpsource,sourcebasereplaced); ++ storeop:=scaledstoreop; ++ makesimpleforcopy(list,storeop,opsize,postfix,true,tmpdest,destbasereplaced); ++ current_asmdata.getjumplabel(hl); ++ countreg:=getintregister(list,OS_32); ++ if loadop=A_LDP then ++ a_load_const_reg(list,OS_32,len div tcgsize2size[opsize]*2,countreg) ++ else ++ a_load_const_reg(list,OS_32,len div tcgsize2size[opsize],countreg); ++ a_label(list,hl); ++ a_op_const_reg(list,OP_SUB,OS_32,1,countreg); ++ if loadop=A_LDP then ++ begin ++ regs[1]:=getintregister(list,opsize); ++ regs[2]:=getintregister(list,opsize); ++ gendualloadstore(list,loadop,regs[1],regs[2],tmpsource,postfix,opsize); ++ gendualloadstore(list,storeop,regs[1],regs[2],tmpdest,postfix,opsize); ++ end ++ else ++ begin ++ regs[1]:=getintregister(list,opsize); ++ genloadstore(list,loadop,regs[1],tmpsource,postfix,opsize); ++ genloadstore(list,storeop,regs[1],tmpdest,postfix,opsize); ++ end; ++ list.concat(taicpu.op_reg_sym_ofs(A_CBNZ,countreg,hl,0)); ++ len:=len mod tcgsize2size[opsize]; ++ end; ++ gencopyleftovers(list,tmpsource,tmpdest,len); ++ end; ++ ++ ++ procedure tcgaarch64.g_adjust_self_value(list:TAsmList;procdef: tprocdef;ioffset: tcgint); ++ begin ++ { This method is integrated into g_intf_wrapper and shouldn't be called separately } ++ InternalError(2013020102); ++ end; ++ ++ ++ procedure tcgaarch64.g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint); ++ var ++ make_global: boolean; ++ href: treference; ++ hsym: tsym; ++ paraloc: pcgparalocation; ++ op: tasmop; ++ begin ++ if not(procdef.proctypeoption in [potype_function,potype_procedure]) then ++ Internalerror(200006137); ++ if not assigned(procdef.struct) or ++ (procdef.procoptions*[po_classmethod, po_staticmethod, ++ po_methodpointer, po_interrupt, po_iocheck]<>[]) then ++ Internalerror(200006138); ++ if procdef.owner.symtabletype<>ObjectSymtable then ++ Internalerror(200109191); ++ ++ make_global:=false; ++ if (not current_module.is_unit) or create_smartlink_library or ++ (procdef.owner.defowner.owner.symtabletype=globalsymtable) then ++ make_global:=true; ++ ++ if make_global then ++ list.concat(Tai_symbol.Createname_global(labelname,AT_FUNCTION,0)) ++ else ++ list.concat(Tai_symbol.Createname(labelname,AT_FUNCTION,0)); ++ ++ { set param1 interface to self } ++ procdef.init_paraloc_info(callerside); ++ hsym:=tsym(procdef.parast.Find('self')); ++ if not(assigned(hsym) and ++ (hsym.typ=paravarsym)) then ++ internalerror(2010103101); ++ paraloc:=tparavarsym(hsym).paraloc[callerside].location; ++ if assigned(paraloc^.next) then ++ InternalError(2013020101); ++ ++ case paraloc^.loc of ++ LOC_REGISTER: ++ handle_reg_imm12_reg(list,A_SUB,paraloc^.size,paraloc^.register,ioffset,paraloc^.register,NR_IP0,false,true); ++ else ++ internalerror(2010103102); ++ end; ++ ++ if (po_virtualmethod in procdef.procoptions) and ++ not is_objectpascal_helper(procdef.struct) then ++ begin ++ if (procdef.extnumber=$ffff) then ++ Internalerror(200006139); ++ { mov 0(%rdi),%rax ; load vmt} ++ reference_reset_base(href,paraloc^.register,0,sizeof(pint)); ++ getcpuregister(list,NR_IP0); ++ a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_IP0); ++ { jmp *vmtoffs(%eax) ; method offs } ++ reference_reset_base(href,NR_IP0,tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber),sizeof(pint)); ++ op:=A_LDR; ++ make_simple_ref(list,op,OS_ADDR,PF_None,href,NR_IP0); ++ list.concat(taicpu.op_reg_ref(op,NR_IP0,href)); ++ ungetcpuregister(list,NR_IP0); ++ list.concat(taicpu.op_reg(A_BR,NR_IP0)); ++ end ++ else ++ a_jmp_name(list,procdef.mangledname); ++ list.concat(Tai_symbol_end.Createname(labelname)); ++ end; ++ ++ ++ procedure create_codegen; ++ begin ++ cg:=tcgaarch64.Create; ++ cg128:=tcg128.Create; ++ end; ++ ++end. +Index: fpc/fpcsrc/compiler/aarch64/cpubase.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/cpubase.pas ++++ fpc/fpcsrc/compiler/aarch64/cpubase.pas +@@ -1,7 +1,8 @@ + { + Copyright (c) 1998-2012 by Florian Klaempfl and Peter Vreman ++ Copyright (c) 2014 by Jonas Maebe and Florian Klaempfl + +- Contains the base types for ARM64 ++ Contains the base types for Aarch64 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +@@ -68,14 +69,22 @@ unit cpubase; + { Available Superregisters } + {$i ra64sup.inc} + ++ RS_IP0 = RS_X16; ++ RS_IP1 = RS_X17; ++ + R_SUBWHOLE = R_SUBQ; + + { Available Registers } + {$i ra64con.inc} + ++ NR_IP0 = NR_X16; ++ NR_IP1 = NR_X17; ++ + { Integer Super registers first and last } + first_int_supreg = RS_X0; +- first_int_imreg = $20; ++ { xzr and sp take up a separate super register because some instructions ++ are ambiguous otherwise } ++ first_int_imreg = $21; + + { Integer Super registers first and last } + first_fpu_supreg = RS_S0; +@@ -92,7 +101,7 @@ unit cpubase; + The value of this constant is equal to the constant + PARM_BOUNDARY / BITS_PER_UNIT in the GCC source. + } +- std_param_align = 4; ++ std_param_align = 8; + + { TODO: Calculate bsstart} + regnumber_count_bsstart = 128; +@@ -109,7 +118,7 @@ unit cpubase; + {$i ra64dwa.inc} + ); + { registers which may be destroyed by calls } +- VOLATILE_INTREGISTERS = [RS_X0..RS_X18,RS_X29..RS_X30]; ++ VOLATILE_INTREGISTERS = [RS_X0..RS_X18,RS_X30]; + VOLATILE_MMREGISTERS = [RS_D0..RS_D7,RS_D16..RS_D31]; + + type +@@ -126,16 +135,23 @@ unit cpubase; + TOpPostfix = (PF_None, + { update condition flags } + PF_S, +- { load/store } +- PF_B,PF_SB,PF_H,PF_SH ++ { load/store sizes } ++ PF_B,PF_SB,PF_H,PF_SH,PF_W,PF_SW + ); + + TOpPostfixes = set of TOpPostfix; + + const +- oppostfix2str : array[TOpPostfix] of string[2] = ('', ++ tcgsizep2size: array[OS_NO..OS_F128] of byte = ++ {OS_NO } ++ (0, ++ {OS_8,OS_16,OS_32,OS_64,OS_128,OS_S8,OS_S16,OS_S32,OS_S64,OS_S128} ++ 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, ++ {OS_F32,OS_F64,OS_F80,OS_C64,OS_F128,} ++ 2, 3, 0, 3, 4); ++ oppostfix2str: array[TOpPostfix] of string[2] = ('', + 's', +- 'b','sb','h','sh'); ++ 'b','sb','h','sh','w','sw'); + + {***************************************************************************** + Conditions +@@ -150,13 +166,15 @@ unit cpubase; + TAsmConds = set of TAsmCond; + + const ++ C_CS = C_HS; ++ C_CC = C_LO; + cond2str : array[TAsmCond] of string[2]=('', + 'eq','ne','hs','lo','mi','pl','vs','vc','hi','ls', + 'ge','lt','gt','le','al','nv' + ); + + uppercond2str : array[TAsmCond] of string[2]=('', +- 'EQ','NE','hs','LO','MI','PL','VS','VC','HI','LS', ++ 'EQ','NE','HS','LO','MI','PL','VS','VC','HI','LS', + 'GE','LT','GT','LE','AL','NV' + ); + +@@ -168,12 +186,28 @@ unit cpubase; + TResFlags = (F_EQ,F_NE,F_CS,F_CC,F_MI,F_PL,F_VS,F_VC,F_HI,F_LS, + F_GE,F_LT,F_GT,F_LE); + ++ const ++ F_HS = F_CS; ++ F_LO = F_CC; ++ + {***************************************************************************** + Operands + *****************************************************************************} + ++ type + taddressmode = (AM_OFFSET,AM_PREINDEXED,AM_POSTINDEXED); +- tshiftmode = (SM_None,SM_LSL,SM_LSR,SM_ASR,SM_ROR); ++ ++ tshiftmode = (SM_None, ++ { shifted register instructions. LSL can also be used for ++ the index register of certain loads/stores } ++ SM_LSL,SM_LSR,SM_ASR, ++ { extended register instructions: zero/sign extension + ++ optional shift (interpreted as LSL after extension) ++ -- the index register of certain loads/stores can be ++ extended via (s|u)xtw with a shiftval of either 0 or ++ log2(transfer size of the load/store) ++ } ++ SM_UXTB,SM_UXTH,SM_UXTW,SM_UXTX,SM_SXTB,SM_SXTH,SM_SXTW,SM_SXTX); + + tupdatereg = (UR_None,UR_Update); + +@@ -184,12 +218,6 @@ unit cpubase; + shiftimm : byte; + end; + +- tcpumodeflag = (mfA, mfI, mfF); +- tcpumodeflags = set of tcpumodeflag; +- +- tspecialregflag = (srC, srX, srS, srF); +- tspecialregflags = set of tspecialregflag; +- + {***************************************************************************** + Constants + *****************************************************************************} +@@ -201,6 +229,10 @@ unit cpubase; + maxfpuregs = 32; + maxaddrregs = 0; + ++ shiftedregmodes = [SM_LSL,SM_UXTB,SM_UXTH,SM_UXTW,SM_UXTX,SM_SXTB,SM_SXTH,SM_SXTW,SM_SXTX]; ++ extendedregmodes = [SM_LSL,SM_LSR,SM_ASR]; ++ ++ + {***************************************************************************** + Operand Sizes + *****************************************************************************} +@@ -232,17 +264,23 @@ unit cpubase; + Generic Register names + *****************************************************************************} + +- NR_SP = NR_XZR; +- RS_SP = RS_XZR; +- NR_WSP = NR_WZR; +- RS_WSP = RS_WZR; ++ ++ NR_FP = NR_X29; ++ RS_FP = RS_X29; ++ NR_WFP = NR_W29; ++ RS_WFP = RS_W29; ++ ++ NR_LR = NR_X30; ++ RS_LR = RS_X30; ++ NR_WLR = NR_W30; ++ RS_WLR = RS_W30; + + { Stack pointer register } + NR_STACK_POINTER_REG = NR_SP; + RS_STACK_POINTER_REG = RS_SP; +- { Frame pointer register (initialized in tarmprocinfo.init_framepointer) } +- RS_FRAME_POINTER_REG: tsuperregister = RS_X29; +- NR_FRAME_POINTER_REG: tregister = NR_X29; ++ { Frame pointer register } ++ NR_FRAME_POINTER_REG = NR_X29; ++ RS_FRAME_POINTER_REG = RS_X29; + { Register for addressing absolute data in a position independant way, + such as in PIC code. The exact meaning is ABI specific. For + further information look at GCC source : PIC_OFFSET_TABLE_REGNUM +@@ -307,6 +345,9 @@ unit cpubase; + + function dwarf_reg(r:tregister):shortint; + ++ function is_shifter_const(d: aint; size: tcgsize): boolean; ++ ++ + implementation + + uses +@@ -329,13 +370,24 @@ unit cpubase; + function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister; + begin + case regtype of ++ R_INTREGISTER: ++ begin ++ case s of ++ { there's only Wn and Xn } ++ OS_64, ++ OS_S64: ++ cgsize2subreg:=R_SUBWHOLE; ++ else ++ cgsize2subreg:=R_SUBD; ++ end; ++ end; + R_MMREGISTER: + begin + case s of + OS_F32: +- cgsize2subreg:=R_SUBFS; ++ cgsize2subreg:=R_SUBMMS; + OS_F64: +- cgsize2subreg:=R_SUBFD; ++ cgsize2subreg:=R_SUBMMD; + else + internalerror(2009112701); + end; +@@ -349,18 +401,22 @@ unit cpubase; + function reg_cgsize(const reg: tregister): tcgsize; + begin + case getregtype(reg) of +- R_INTREGISTER : +- reg_cgsize:=OS_32; +- R_FPUREGISTER : +- reg_cgsize:=OS_F80; ++ R_INTREGISTER: ++ case getsubreg(reg) of ++ R_SUBD: ++ result:=OS_32 ++ else ++ result:=OS_64; ++ end; + R_MMREGISTER : + begin + case getsubreg(reg) of +- R_SUBFD, +- R_SUBWHOLE: ++ R_SUBMMD: + result:=OS_F64; +- R_SUBFS: ++ R_SUBMMS: + result:=OS_F32; ++ R_SUBMMWHOLE: ++ result:=OS_M128; + else + internalerror(2009112903); + end; +@@ -373,9 +429,7 @@ unit cpubase; + + function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE} + begin +- { This isn't 100% perfect because the arm allows jumps also by writing to PC=R15. +- To overcome this problem we simply forbid that FPC generates jumps by loading R15 } +- is_calljmp:= o in [A_B,A_BLR,A_RET]; ++ is_calljmp:=o in [A_B,A_BL,A_BLR,A_RET,A_CBNZ,A_CBZ,A_TBNZ,A_TBZ]; + end; + + +@@ -391,8 +445,8 @@ unit cpubase; + + function flags_to_cond(const f: TResFlags) : TAsmCond; + const +- flag_2_cond: array[F_EQ..F_LE] of TAsmCond = +- (C_EQ,C_NE,C_HI,C_LO,C_MI,C_PL,C_VS,C_VC,C_HI,C_LS, ++ flag_2_cond: array[TResFlags] of TAsmCond = ++ (C_EQ,C_NE,C_HS,C_LO,C_MI,C_PL,C_VS,C_VC,C_HI,C_LS, + C_GE,C_LT,C_GT,C_LE); + begin + if f>high(flag_2_cond) then +@@ -434,7 +488,7 @@ unit cpubase; + function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE} + const + inverse: array[TAsmCond] of TAsmCond=(C_None, +- C_NE,C_EQ,C_LO,C_HI,C_PL,C_MI,C_VC,C_VS,C_LS,C_HI, ++ C_NE,C_EQ,C_LO,C_HS,C_PL,C_MI,C_VC,C_VS,C_LS,C_HI, + C_LT,C_GE,C_LE,C_GT,C_None,C_None + ); + begin +@@ -456,4 +510,112 @@ unit cpubase; + end; + + ++ function is_shifter_const(d: aint; size: tcgsize): boolean; ++ var ++ pattern, checkpattern: qword; ++ patternlen, maxbits, replicatedlen: longint; ++ rightmostone, rightmostzero, checkbit, secondrightmostbit: longint; ++ begin ++ result:=false; ++ { patterns with all bits 0 or 1 cannot be represented this way } ++ if (d=0) then ++ exit; ++ case size of ++ OS_64, ++ OS_S64: ++ begin ++ if d=-1 then ++ exit; ++ maxbits:=64; ++ end ++ else ++ begin ++ if longint(d)=-1 then ++ exit; ++ { we'll generate a 32 bit pattern -> ignore upper sign bits in ++ case of negative longint value } ++ d:=cardinal(d); ++ maxbits:=32; ++ end; ++ end; ++ { "The Logical (immediate) instructions accept a bitmask immediate value ++ that is a 32-bit pattern or a 64-bit pattern viewed as a vector of ++ identical elements of size e = 2, 4, 8, 16, 32 or, 64 bits. Each ++ element contains the same sub-pattern, that is a single run of ++ 1 to (e - 1) nonzero bits from bit 0 followed by zero bits, then ++ rotated by 0 to (e - 1) bits." (ARMv8 ARM) ++ ++ Rather than generating all possible patterns and checking whether they ++ match our constant, we check whether the lowest 2/4/8/... bits are ++ a valid pattern, and if so whether the constant consists of a ++ replication of this pattern. Such a valid pattern has the form of ++ either (regexp notation) ++ * 1+0+1* ++ * 0+1+0* } ++ patternlen:=2; ++ while patternlen<=maxbits do ++ begin ++ { try lowest bits of d as pattern } ++ if patternlen<>64 then ++ pattern:=qword(d) and ((qword(1) shl patternlen)-1) ++ else ++ pattern:=qword(d); ++ { valid pattern? If it contains too many 1<->0 transitions, larger ++ parts of d cannot be a valid pattern either } ++ rightmostone:=BsfQWord(pattern); ++ rightmostzero:=BsfQWord(not(pattern)); ++ { pattern all ones or zeroes -> not a valid pattern (but larger ones ++ can still be valid, since we have too few transitions) } ++ if (rightmostonerightmostzero then ++ begin ++ { we have .*1*0* -> check next zero position by shifting ++ out the existing zeroes (shr rightmostone), inverting and ++ then again looking for the rightmost one position } ++ checkpattern:=not(pattern); ++ checkbit:=rightmostone; ++ end ++ else ++ begin ++ { same as above, but for .*0*1* } ++ checkpattern:=pattern; ++ checkbit:=rightmostzero; ++ end; ++ secondrightmostbit:=BsfQWord(checkpattern shr checkbit)+checkbit; ++ { if this position is >= patternlen -> ok (1 transition), ++ otherwise we now have 2 transitions and have to check for a ++ third (if there is one, abort) ++ ++ bsf returns 255 if no 1 bit is found, so in that case it's ++ also ok ++ } ++ if secondrightmostbit multiply by number of elements ++ in the array } ++ inc(elecount,tarraydef(p).elecount*tmpelecount); ++ if elecount>4 then ++ exit; ++ end; ++ else ++ result:=is_hfa_internal(tarraydef(p).elementdef,basedef,elecount); ++ end; ++ end; ++ floatdef: ++ begin ++ if not assigned(basedef) then ++ basedef:=p ++ else if basedef<>p then ++ exit; ++ inc(elecount); ++ result:=true; ++ end; ++ recorddef: ++ begin ++ for i:=0 to tabstractrecorddef(p).symtable.symlist.count-1 do ++ begin ++ sym:=tsym(tabstractrecorddef(p).symtable.symlist[i]); ++ if sym.typ<>fieldvarsym then ++ continue; ++ if not is_hfa_internal(tfieldvarsym(sym).vardef,basedef,elecount) then ++ exit ++ end; ++ result:=true; ++ end; ++ else ++ exit ++ end; + end; + + +- function Is_HFA(p : tdef) : boolean; ++ { Returns whether a def is a "homogeneous float array" at the machine level. ++ This means that in the memory layout, the def only consists of maximally ++ 4 floating point values that appear consecutively in memory } ++ function is_hfa(p: tdef; out basedef: tdef) : boolean; ++ var ++ elecount: longint; + begin + result:=false; ++ basedef:=nil; ++ elecount:=0; ++ result:=is_hfa_internal(p,basedef,elecount); ++ result:= ++ result and ++ (elecount>0) and ++ (elecount<=4) and ++ (p.size=basedef.size*elecount) + end; + + +- function getparaloc(calloption : tproccalloption; p : tdef; isvariadic: boolean) : tcgloc; ++ function getparaloc(calloption: tproccalloption; p: tdef): tcgloc; ++ var ++ hfabasedef: tdef; + begin + { Later, the LOC_REFERENCE is in most cases changed into LOC_REGISTER + if push_addr_param for the def is true +@@ -134,7 +190,10 @@ unit cpupara; + classrefdef: + getparaloc:=LOC_REGISTER; + recorddef: +- getparaloc:=LOC_REGISTER; ++ if not is_hfa(p,hfabasedef) then ++ getparaloc:=LOC_REGISTER ++ else ++ getparaloc:=LOC_MMREGISTER; + objectdef: + getparaloc:=LOC_REGISTER; + stringdef: +@@ -147,12 +206,12 @@ unit cpupara; + filedef: + getparaloc:=LOC_REGISTER; + arraydef: +- getparaloc:=LOC_REFERENCE; +- setdef: +- if is_smallset(p) then ++ if not is_hfa(p,hfabasedef) then + getparaloc:=LOC_REGISTER + else +- getparaloc:=LOC_REFERENCE; ++ getparaloc:=LOC_MMREGISTER; ++ setdef: ++ getparaloc:=LOC_REGISTER; + variantdef: + getparaloc:=LOC_REGISTER; + { avoid problems with errornous definitions } +@@ -164,7 +223,9 @@ unit cpupara; + end; + + +- function taarch64paramanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean; ++ function taarch64paramanager.push_addr_param(varspez: tvarspez; def :tdef; calloption: tproccalloption): boolean; ++ var ++ hfabasedef: tdef; + begin + result:=false; + if varspez in [vs_var,vs_out,vs_constref] then +@@ -174,19 +235,36 @@ unit cpupara; + end; + case def.typ of + objectdef: +- result:=not(Is_HFA(def) and (is_object(def) and ((varspez=vs_const) or (def.size=0)); ++ result:=is_object(def); + recorddef: +- { note: should this ever be changed, make sure that const records +- are always passed by reference for calloption=pocall_mwpascal } +- result:=(varspez=vs_const) or (def.size=0); ++ { ABI: any composite > 16 bytes that not a hfa/hva ++ Special case: MWPascal, which passes all const parameters by ++ reference for compatibility reasons ++ } ++ result:= ++ ((varspez=vs_const) and ++ (calloption=pocall_mwpascal)) or ++ (not is_hfa(def,hfabasedef) and ++ (def.size>16)); + variantdef, + formaldef: + result:=true; ++ { arrays are composites and hence treated the same as records by the ++ ABI (watch out for C, where an array is a pointer) ++ Also: all other platforms pass const arrays by reference. Do the ++ same here, because there is too much hacky code out there that ++ relies on this ("array[0..0] of x" passed as const parameter and ++ then indexed beyond its bounds) } + arraydef: +- result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or +- is_open_array(def) or +- is_array_of_const(def) or +- is_array_constructor(def); ++ result:= ++ (calloption in cdecl_pocalls) or ++ is_open_array(def) or ++ is_array_of_const(def) or ++ is_array_constructor(def) or ++ ((tarraydef(def).highrange>=tarraydef(def).lowrange) and ++ ((varspez=vs_const) or ++ (not is_hfa(def,hfabasedef) and ++ (def.size>16)))); + setdef : + result:=def.size>16; + stringdef : +@@ -195,511 +273,370 @@ unit cpupara; + end; + + +- function taarch64paramanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean; +- var +- i: longint; +- sym: tsym; +- fpufield: boolean; ++ function taarch64paramanager.ret_in_param(def: tdef; pd: tabstractprocdef): boolean; + begin + if handle_common_ret_in_param(def,pd,result) then + exit; +- case def.typ of +- recorddef: +- begin +- result:=def.size>4; +- if not result and +- (target_info.abi in [abi_default,abi_armeb]) then +- begin +- { in case of the old ARM abi (APCS), a struct is returned in +- a register only if it is simple. And what is a (non-)simple +- struct: +- +- "A non-simple type is any non-floating-point type of size +- greater than one word (including structures containing only +- floating-point fields), and certain single-word structured +- types." +- (-- ARM APCS documentation) +- +- So only floating point types or more than one word -> +- definitely non-simple (more than one word is already +- checked above). This includes unions/variant records with +- overlaid floating point and integer fields. +- +- Smaller than one word struct types are simple if they are +- "integer-like", and: +- +- "A structure is termed integer-like if its size is less than +- or equal to one word, and the offset of each of its +- addressable subfields is zero." +- (-- ARM APCS documentation) +- +- An "addressable subfield" is a field of which you can take +- the address, which in practive means any non-bitfield. +- In Pascal, there is no way to express the difference that +- you can have in C between "char" and "int :8". In this +- context, we use the fake distinction that a type defined +- inside the record itself (such as "a: 0..255;") indicates +- a bitpacked field while a field using a different type +- (such as "a: byte;") is not. +- } +- for i:=0 to trecorddef(def).symtable.SymList.count-1 do +- begin +- sym:=tsym(trecorddef(def).symtable.SymList[i]); +- if sym.typ<>fieldvarsym then +- continue; +- { bitfield -> ignore } +- if (trecordsymtable(trecorddef(def).symtable).usefieldalignment=bit_alignment) and +- (tfieldvarsym(sym).vardef.typ in [orddef,enumdef]) and +- (tfieldvarsym(sym).vardef.owner.defowner=def) then +- continue; +- { all other fields must be at offset zero } +- if tfieldvarsym(sym).fieldoffset<>0 then +- begin +- result:=true; +- exit; +- end; +- { floating point field -> also by reference } +- if tfieldvarsym(sym).vardef.typ=floatdef then +- begin +- result:=true; +- exit; +- end; +- end; +- end; +- end; +- procvardef: +- if not tprocvardef(def).is_addressonly then +- result:=true +- else +- result:=false +- else +- result:=inherited ret_in_param(def,pd); +- end; ++ { ABI: if the parameter would be passed in registers, it is returned ++ in those registers; otherwise, it's returned by reference } ++ result:=push_addr_param(vs_value,def,pd.proccalloption); + end; + + +- procedure taarch64paramanager.init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister); +- begin +- curintreg:=RS_R0; +- curfloatreg:=RS_F0; +- curmmreg:=RS_D0; +- cur_stack_offset:=0; +- sparesinglereg := NR_NO; +- end; +- +- +- function taarch64paramanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist; +- var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister; isvariadic: boolean):longint; +- ++ procedure taarch64paramanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist; isvariadic: boolean); + var +- nextintreg,nextfloatreg,nextmmreg : tsuperregister; +- paradef : tdef; +- paraloc : pcgparalocation; +- stack_offset : aword; +- hp : tparavarsym; +- loc : tcgloc; +- paracgsize : tcgsize; +- paralen : longint; +- i : integer; +- firstparaloc: boolean; +- +- procedure assignintreg; +- begin +- { In case of po_delphi_nested_cc, the parent frame pointer +- is always passed on the stack. } +- if (nextintreg<=RS_R3) and +- (not(vo_is_parentfp in hp.varoptions) or +- not(po_delphi_nested_cc in p.procoptions)) then +- begin +- paraloc^.loc:=LOC_REGISTER; +- paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE); +- inc(nextintreg); +- end +- else +- begin +- paraloc^.loc:=LOC_REFERENCE; +- paraloc^.reference.index:=NR_STACK_POINTER_REG; +- paraloc^.reference.offset:=stack_offset; +- inc(stack_offset,4); +- end; +- end; +- +- ++ hp: tparavarsym; ++ i: longint; + begin +- result:=0; +- nextintreg:=curintreg; +- nextfloatreg:=curfloatreg; +- nextmmreg:=curmmreg; +- stack_offset:=cur_stack_offset; +- + for i:=0 to paras.count-1 do + begin + hp:=tparavarsym(paras[i]); +- paradef:=hp.vardef; ++ { hidden function result parameter is passed in X8 (doesn't have to ++ be valid on return) according to the ABI + +- hp.paraloc[side].reset; +- +- { currently only support C-style array of const, +- there should be no location assigned to the vararg array itself } +- if (p.proccalloption in cstylearrayofconst) and +- is_array_of_const(paradef) then +- begin +- paraloc:=hp.paraloc[side].add_location; +- { hack: the paraloc must be valid, but is not actually used } +- paraloc^.loc:=LOC_REGISTER; +- paraloc^.register:=NR_R0; +- paraloc^.size:=OS_ADDR; +- break; +- end; +- +- if push_addr_param(hp.varspez,paradef,p.proccalloption) then +- begin +- paradef:=getpointerdef(paradef); +- loc:=LOC_REGISTER; +- paracgsize := OS_ADDR; +- paralen := tcgsize2size[OS_ADDR]; +- end +- else ++ -- don't follow the ABI for managed types, because ++ a) they are passed in registers as parameters, so we should also ++ return them in a register to be ABI-compliant (which we can't ++ because the entire compiler is built around the idea that ++ they are returned by reference, for ref-counting performance ++ and Delphi-compatibility reasons) ++ b) there are hacks in the system unit that expect that you can ++ call ++ function f: com_interface; ++ as ++ procedure p(out o: obj); ++ That can only work in case we do not use x8 to return them ++ from the function, but the regular first parameter register. ++ ++ As the ABI says this behaviour is ok for C++ classes with a ++ non-trivial copy constructor or destructor, it seems reasonable ++ for us to do this for managed types as well.} ++ if (vo_is_funcret in hp.varoptions) and ++ not is_managed_type(hp.vardef) then + begin +- if not is_special_array(paradef) then +- paralen := paradef.size +- else +- paralen := tcgsize2size[def_cgsize(paradef)]; +- loc := getparaloc(p.proccalloption,paradef,isvariadic); +- if (paradef.typ in [objectdef,arraydef,recorddef]) and +- not is_special_array(paradef) and +- (hp.varspez in [vs_value,vs_const]) then +- paracgsize := int_cgsize(paralen) +- else ++ hp.paraloc[side].reset; ++ hp.paraloc[side].size:=OS_ADDR; ++ hp.paraloc[side].alignment:=voidpointertype.alignment; ++ hp.paraloc[side].intsize:=voidpointertype.size; ++ hp.paraloc[side].def:=getpointerdef(hp.vardef); ++ with hp.paraloc[side].add_location^ do + begin +- paracgsize:=def_cgsize(paradef); +- { for things like formaldef } +- if (paracgsize=OS_NO) then +- begin +- paracgsize:=OS_ADDR; +- paralen:=tcgsize2size[OS_ADDR]; +- paradef:=voidpointertype; +- end; ++ size:=OS_ADDR; ++ def:=hp.paraloc[side].def; ++ loc:=LOC_REGISTER; ++ register:=NR_X8; + end +- end; +- +- hp.paraloc[side].size:=paracgsize; +- hp.paraloc[side].Alignment:=std_param_align; +- hp.paraloc[side].intsize:=paralen; +- hp.paraloc[side].def:=paradef; +- firstparaloc:=true; +- +-{$ifdef EXTDEBUG} +- if paralen=0 then +- internalerror(200410311); +-{$endif EXTDEBUG} +- while paralen>0 do +- begin +- paraloc:=hp.paraloc[side].add_location; +- +- if (loc=LOC_REGISTER) and (paracgsize in [OS_F32,OS_F64,OS_F80]) then +- case paracgsize of +- OS_F32: +- paraloc^.size:=OS_32; +- OS_F64: +- paraloc^.size:=OS_32; +- else +- internalerror(2005082901); +- end +- else if (paracgsize in [OS_NO,OS_64,OS_S64]) then +- paraloc^.size := OS_32 +- else +- paraloc^.size:=paracgsize; +- case loc of +- LOC_REGISTER: +- begin +- { align registers for eabi } +- if (target_info.abi in [abi_eabi,abi_eabihf]) and +- firstparaloc and +- (paradef.alignment=8) then +- begin +- if (nextintreg in [RS_R1,RS_R3]) then +- inc(nextintreg) +- else if nextintreg>RS_R3 then +- stack_offset:=align(stack_offset,8); +- end; +- { this is not abi compliant +- why? (FK) } +- if nextintreg<=RS_R3 then +- begin +- paraloc^.loc:=LOC_REGISTER; +- paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE); +- inc(nextintreg); +- end +- else +- begin +- { LOC_REFERENCE always contains everything that's left } +- paraloc^.loc:=LOC_REFERENCE; +- paraloc^.size:=int_cgsize(paralen); +- if (side=callerside) then +- paraloc^.reference.index:=NR_STACK_POINTER_REG; +- paraloc^.reference.offset:=stack_offset; +- inc(stack_offset,align(paralen,4)); +- paralen:=0; +- end; +- end; +- LOC_FPUREGISTER: +- begin +- if nextfloatreg<=RS_F3 then +- begin +- paraloc^.loc:=LOC_FPUREGISTER; +- paraloc^.register:=newreg(R_FPUREGISTER,nextfloatreg,R_SUBWHOLE); +- inc(nextfloatreg); +- end +- else +- begin +- paraloc^.loc:=LOC_REFERENCE; +- paraloc^.reference.index:=NR_STACK_POINTER_REG; +- paraloc^.reference.offset:=stack_offset; +- case paraloc^.size of +- OS_F32: +- inc(stack_offset,4); +- OS_F64: +- inc(stack_offset,8); +- OS_F80: +- inc(stack_offset,10); +- OS_F128: +- inc(stack_offset,16); +- else +- internalerror(200403201); +- end; +- end; +- end; +- LOC_MMREGISTER: +- begin +- if (nextmmreg<=RS_D7) or +- ((paraloc^.size = OS_F32) and +- (sparesinglereg<>NR_NO)) then +- begin +- paraloc^.loc:=LOC_MMREGISTER; +- case paraloc^.size of +- OS_F32: +- if sparesinglereg = NR_NO then +- begin +- paraloc^.register:=newreg(R_MMREGISTER,nextmmreg,R_SUBFS); +- sparesinglereg:=newreg(R_MMREGISTER,nextmmreg-RS_S0+RS_S1,R_SUBFS); +- inc(nextmmreg); +- end +- else +- begin +- paraloc^.register:=sparesinglereg; +- sparesinglereg := NR_NO; +- end; +- OS_F64: +- begin +- paraloc^.register:=newreg(R_MMREGISTER,nextmmreg,R_SUBFD); +- inc(nextmmreg); +- end; +- else +- internalerror(2012031601); +- end; +- end +- else +- begin +- { once a floating point parameters has been placed +- on the stack we must not pass any more in vfp regs +- even if there is a single precision register still +- free} +- sparesinglereg := NR_NO; +- { LOC_REFERENCE always contains everything that's left } +- paraloc^.loc:=LOC_REFERENCE; +- paraloc^.size:=int_cgsize(paralen); +- if (side=callerside) then +- paraloc^.reference.index:=NR_STACK_POINTER_REG; +- paraloc^.reference.offset:=stack_offset; +- inc(stack_offset,align(paralen,4)); +- paralen:=0; +- end; +- end; +- LOC_REFERENCE: +- begin +- if push_addr_param(hp.varspez,paradef,p.proccalloption) then +- begin +- paraloc^.size:=OS_ADDR; +- assignintreg +- end +- else +- begin +- { align stack for eabi } +- if (target_info.abi in [abi_eabi,abi_eabihf]) and +- firstparaloc and +- (paradef.alignment=8) then +- stack_offset:=align(stack_offset,8); +- +- paraloc^.size:=paracgsize; +- paraloc^.loc:=LOC_REFERENCE; +- paraloc^.reference.index:=NR_STACK_POINTER_REG; +- paraloc^.reference.offset:=stack_offset; +- inc(stack_offset,align(paralen,4)); +- paralen:=0 +- end; +- end; +- else +- internalerror(2002071002); +- end; +- if side=calleeside then +- begin +- if paraloc^.loc=LOC_REFERENCE then +- begin +- paraloc^.reference.index:=NR_FRAME_POINTER_REG; +- { on non-Darwin, the framepointer contains the value +- of the stack pointer on entry. On Darwin, the +- framepointer points to the previously saved +- framepointer (which is followed only by the saved +- return address -> framepointer + 4 = stack pointer +- on entry } +- if not(target_info.system in systems_darwin) then +- inc(paraloc^.reference.offset,4) +- else +- inc(paraloc^.reference.offset,8); +- end; +- end; +- dec(paralen,tcgsize2size[paraloc^.size]); +- firstparaloc:=false +- end; ++ end ++ else ++ alloc_para(hp.paraloc[side],p,hp.varspez,side,hp.vardef,isvariadic, ++ (vo_is_parentfp in hp.varoptions) and ++ (po_delphi_nested_cc in p.procoptions)); + end; +- curintreg:=nextintreg; +- curfloatreg:=nextfloatreg; +- curmmreg:=nextmmreg; +- cur_stack_offset:=stack_offset; +- result:=cur_stack_offset; + end; + + + function taarch64paramanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara; + var +- paraloc : pcgparalocation; +- retcgsize : tcgsize; ++ retcgsize: tcgsize; + begin + if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then + exit; + +- paraloc:=result.add_location; +- { Return in FPU register? } +- if result.def.typ=floatdef then ++ { in this case, it must be returned in registers as if it were passed ++ as the first parameter } ++ init_para_alloc_values; ++ alloc_para(result,p,vs_value,side,result.def,false,false); ++ { sanity check (LOC_VOID for empty records) } ++ if not assigned(result.location) or ++ not(result.location^.loc in [LOC_REGISTER,LOC_MMREGISTER,LOC_VOID]) then ++ internalerror(2014113001); ++ end; ++ ++ function taarch64paramanager.param_use_paraloc(const cgpara: tcgpara): boolean; ++ begin ++ { we always set up a stack frame -> we can always access the parameters ++ this way } ++ result:= ++ (cgpara.location^.loc=LOC_REFERENCE) and ++ not assigned(cgpara.location^.next); ++ end; ++ ++ ++ procedure taarch64paramanager.init_para_alloc_values; ++ begin ++ curintreg:=RS_FIRST_INT_PARAM_SUPREG; ++ curmmreg:=RS_FIRST_MM_PARAM_SUPREG; ++ curstackoffset:=0; ++ end; ++ ++ ++ procedure taarch64paramanager.alloc_para(out result: tcgpara; p: tabstractprocdef; varspez: tvarspez; side: tcallercallee; paradef: tdef; isvariadic, isdelphinestedcc: boolean); ++ var ++ hfabasedef, locdef: tdef; ++ paraloc: pcgparalocation; ++ paralen, stackslotlen: asizeint; ++ loc: tcgloc; ++ paracgsize, locsize: tcgsize; ++ firstparaloc: boolean; ++ begin ++ result.reset; ++ ++ { currently only support C-style array of const, ++ there should be no location assigned to the vararg array itself } ++ if (p.proccalloption in cstylearrayofconst) and ++ is_array_of_const(paradef) then + begin +- if target_info.abi = abi_eabihf then +- begin +- paraloc^.loc:=LOC_MMREGISTER; +- case retcgsize of +- OS_64, +- OS_F64: +- begin +- paraloc^.register:=NR_MM_RESULT_REG; +- end; +- OS_32, +- OS_F32: +- begin +- paraloc^.register:=NR_S0; +- end; +- else +- internalerror(2012032501); +- end; +- paraloc^.size:=retcgsize; +- end +- else if (p.proccalloption in [pocall_softfloat]) or +- (cs_fp_emulation in current_settings.moduleswitches) or +- (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16,fpu_fpv4_s16]) then +- begin +- case retcgsize of +- OS_64, +- OS_F64: +- begin +- paraloc^.loc:=LOC_REGISTER; +- if target_info.endian = endian_big then +- paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG +- else +- paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG; +- paraloc^.size:=OS_32; +- paraloc:=result.add_location; +- paraloc^.loc:=LOC_REGISTER; +- if target_info.endian = endian_big then +- paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG +- else +- paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG; +- paraloc^.size:=OS_32; +- end; +- OS_32, +- OS_F32: +- begin +- paraloc^.loc:=LOC_REGISTER; +- paraloc^.register:=NR_FUNCTION_RETURN_REG; +- paraloc^.size:=OS_32; +- end; +- else +- internalerror(2005082603); +- end; +- end +- else +- begin +- paraloc^.loc:=LOC_FPUREGISTER; +- paraloc^.register:=NR_FPU_RESULT_REG; +- paraloc^.size:=retcgsize; +- end; ++ paraloc:=result.add_location; ++ { hack: the paraloc must be valid, but is not actually used } ++ paraloc^.loc:=LOC_REGISTER; ++ paraloc^.register:=NR_X0; ++ paraloc^.size:=OS_ADDR; ++ exit; ++ end; ++ ++ if push_addr_param(varspez,paradef,p.proccalloption) then ++ begin ++ paradef:=getpointerdef(paradef); ++ loc:=LOC_REGISTER; ++ paracgsize:=OS_ADDR; ++ paralen:=tcgsize2size[OS_ADDR]; + end +- { Return in register } + else + begin +- if retcgsize in [OS_64,OS_S64] then +- begin +- paraloc^.loc:=LOC_REGISTER; +- if target_info.endian = endian_big then +- paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG +- else +- paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG; +- paraloc^.size:=OS_32; +- paraloc:=result.add_location; +- paraloc^.loc:=LOC_REGISTER; +- if target_info.endian = endian_big then +- paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG +- else +- paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG; +- paraloc^.size:=OS_32; +- end ++ if not is_special_array(paradef) then ++ paralen:=paradef.size ++ else ++ paralen:=tcgsize2size[def_cgsize(paradef)]; ++ loc:=getparaloc(p.proccalloption,paradef); ++ if (paradef.typ in [objectdef,arraydef,recorddef]) and ++ not is_special_array(paradef) and ++ (varspez in [vs_value,vs_const]) then ++ paracgsize:=int_cgsize(paralen) + else + begin +- paraloc^.loc:=LOC_REGISTER; +- paraloc^.register:=NR_FUNCTION_RETURN_REG; +- if (result.intsize<>3) then +- paraloc^.size:=retcgsize +- else +- paraloc^.size:=OS_32; +- end; ++ paracgsize:=def_cgsize(paradef); ++ { for things like formaldef } ++ if paracgsize=OS_NO then ++ begin ++ paracgsize:=OS_ADDR; ++ paralen:=tcgsize2size[OS_ADDR]; ++ paradef:=voidpointertype; ++ end; ++ end + end; ++ ++ { get hfa basedef if applicable } ++ if not is_hfa(paradef,hfabasedef) then ++ hfabasedef:=nil; ++ ++ result.size:=paracgsize; ++ result.alignment:=std_param_align; ++ result.intsize:=paralen; ++ result.def:=paradef; ++ ++ { empty record: skipped (explicitly defined by Apple ABI, undefined ++ by general ABI; libffi also skips them in all cases) } ++ if not is_special_array(paradef) and ++ (paradef.size=0) then ++ begin ++ paraloc:=result.add_location; ++ paraloc^.loc:=LOC_VOID; ++ paraloc^.def:=paradef; ++ paraloc^.size:=OS_NO; ++ exit; ++ end; ++ ++ { sufficient registers left? } ++ case loc of ++ LOC_REGISTER: ++ begin ++ { In case of po_delphi_nested_cc, the parent frame pointer ++ is always passed on the stack. } ++ if isdelphinestedcc then ++ loc:=LOC_REFERENCE ++ else if curintreg+((paralen-1) shr 3)>RS_LAST_INT_PARAM_SUPREG then ++ begin ++ { not enough integer registers left -> no more register ++ parameters, copy all to stack ++ } ++ curintreg:=succ(RS_LAST_INT_PARAM_SUPREG); ++ loc:=LOC_REFERENCE; ++ end; ++ end; ++ LOC_MMREGISTER: ++ begin; ++ { every hfa element must be passed in a separate register } ++ if (assigned(hfabasedef) and ++ (curmmreg+(paralen div hfabasedef.size)>RS_LAST_MM_PARAM_SUPREG)) or ++ (curmmreg+((paralen-1) shr 3)>RS_LAST_MM_PARAM_SUPREG) then ++ begin ++ { not enough mm registers left -> no more register ++ parameters, copy all to stack ++ } ++ curmmreg:=succ(RS_LAST_MM_PARAM_SUPREG); ++ loc:=LOC_REFERENCE; ++ end; ++ end; ++ end; ++ ++ { allocate registers/stack locations } ++ firstparaloc:=true; ++ repeat ++ paraloc:=result.add_location; ++ ++ { set paraloc size/def } ++ if assigned(hfabasedef) then ++ begin ++ locsize:=def_cgsize(hfabasedef); ++ locdef:=hfabasedef; ++ end ++ { make sure we don't lose whether or not the type is signed } ++ else if (loc=LOC_REGISTER) and ++ (paradef.typ<>orddef) then ++ begin ++ locsize:=int_cgsize(paralen); ++ locdef:=get_paraloc_def(paradef,paralen,firstparaloc); ++ end ++ else ++ begin ++ locsize:=paracgsize; ++ locdef:=paradef; ++ end; ++ if locsize in [OS_NO,OS_128,OS_S128] then ++ begin ++ if paralen>4 then ++ begin ++ paraloc^.size:=OS_INT; ++ paraloc^.def:=u64inttype; ++ end ++ else ++ begin ++ { for 3-byte records } ++ paraloc^.size:=OS_32; ++ paraloc^.def:=u32inttype; ++ end; ++ end ++ else ++ begin ++ paraloc^.size:=locsize; ++ paraloc^.def:=locdef; ++ end; ++ ++ { paraloc loc } ++ paraloc^.loc:=loc; ++ ++ { assign register/stack address } ++ case loc of ++ LOC_REGISTER: ++ begin ++ paraloc^.register:=newreg(R_INTREGISTER,curintreg,cgsize2subreg(R_INTREGISTER,paraloc^.size)); ++ inc(curintreg); ++ dec(paralen,tcgsize2size[paraloc^.size]); ++ ++ { "The general ABI specifies that it is the callee's ++ responsibility to sign or zero-extend arguments having fewer ++ than 32 bits, and that unused bits in a register are ++ unspecified. In iOS, however, the caller must perform such ++ extensions, up to 32 bits." } ++ if (target_info.abi=abi_aarch64_darwin) and ++ (side=callerside) and ++ is_ordinal(paradef) and ++ (paradef.size<4) then ++ paraloc^.size:=OS_32; ++ ++ { in case it's a composite, "The argument is passed as though ++ it had been loaded into the registers from a double-word- ++ aligned address with an appropriate sequence of LDR ++ instructions loading consecutive registers from memory" -> ++ in case of big endian, values in not completely filled ++ registers must be shifted to the top bits } ++ if (target_info.endian=endian_big) and ++ not(paraloc^.size in [OS_64,OS_S64]) and ++ (paradef.typ in [setdef,recorddef,arraydef,objectdef]) then ++ paraloc^.shiftval:=-(8-tcgsize2size[paraloc^.size]); ++ end; ++ LOC_MMREGISTER: ++ begin ++ paraloc^.register:=newreg(R_MMREGISTER,curmmreg,cgsize2subreg(R_MMREGISTER,paraloc^.size)); ++ inc(curmmreg); ++ dec(paralen,tcgsize2size[paraloc^.size]); ++ end; ++ LOC_REFERENCE: ++ begin ++ paraloc^.size:=paracgsize; ++ paraloc^.loc:=LOC_REFERENCE; ++ ++ { the current stack offset may not be properly aligned in ++ case we're on Darwin have allocated a non-variadic argument ++ < 8 bytes previously } ++ if target_info.abi=abi_aarch64_darwin then ++ curstackoffset:=align(curstackoffset,paraloc^.def.alignment); ++ ++ { on Darwin, non-variadic arguments take up their actual size ++ on the stack; on other platforms, they take up a multiple of ++ 8 bytes } ++ if (target_info.abi=abi_aarch64_darwin) and ++ not isvariadic then ++ stackslotlen:=paralen ++ else ++ stackslotlen:=align(paralen,8); ++ ++ { from the ABI: if arguments occupy partial stack space, they ++ have to occupy the lowest significant bits of a register ++ containing that value which is then stored to memory -> ++ in case of big endian, skip the alignment bytes (if any) } ++ if target_info.endian=endian_little then ++ paraloc^.reference.offset:=curstackoffset ++ else ++ paraloc^.reference.offset:=curstackoffset+stackslotlen-paralen; ++ if side=callerside then ++ paraloc^.reference.index:=NR_STACK_POINTER_REG ++ else ++ begin ++ paraloc^.reference.index:=NR_FRAME_POINTER_REG; ++ inc(paraloc^.reference.offset,16); ++ end; ++ inc(curstackoffset,stackslotlen); ++ paralen:=0 ++ end; ++ else ++ internalerror(2002071002); ++ end; ++ firstparaloc:=false; ++ { <=0 for sign/zero-extended locations } ++ until paralen<=0; + end; + + +- function taarch64paramanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint; +- var +- cur_stack_offset: aword; +- curintreg, curfloatreg, curmmreg: tsuperregister; +- sparesinglereg:tregister; ++ function taarch64paramanager.create_paraloc_info(p: tabstractprocdef; side: tcallercallee):longint; + begin +- init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg); ++ init_para_alloc_values; + +- result:=create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,false); ++ create_paraloc_info_intern(p,side,p.paras,false); ++ result:=curstackoffset; + + create_funcretloc_info(p,side); + end; + + +- function taarch64paramanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint; +- var +- cur_stack_offset: aword; +- curintreg, curfloatreg, curmmreg: tsuperregister; +- sparesinglereg:tregister; +- begin +- init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg); +- +- result:=create_paraloc_info_intern(p,callerside,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,true); +- if (p.proccalloption in cstylearrayofconst) then +- { just continue loading the parameters in the registers } +- result:=create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,true) ++ function taarch64paramanager.create_varargs_paraloc_info(p: tabstractprocdef; varargspara: tvarargsparalist):longint; ++ begin ++ init_para_alloc_values; ++ ++ { non-variadic parameters } ++ create_paraloc_info_intern(p,callerside,p.paras,false); ++ if p.proccalloption in cstylearrayofconst then ++ begin ++ { on Darwin, we cannot use any registers for variadic parameters } ++ if target_info.abi=abi_aarch64_darwin then ++ begin ++ curintreg:=succ(RS_LAST_INT_PARAM_SUPREG); ++ curmmreg:=succ(RS_LAST_MM_PARAM_SUPREG); ++ end; ++ { continue loading the parameters } ++ create_paraloc_info_intern(p,callerside,varargspara,true); ++ result:=curstackoffset; ++ end + else + internalerror(200410231); + end; +Index: fpc/fpcsrc/compiler/aarch64/cpupi.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/cpupi.pas +@@ -0,0 +1,68 @@ ++{ ++ Copyright (c) 2002 by Florian Klaempfl ++ ++ This unit contains the CPU specific part of tprocinfo ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ **************************************************************************** ++} ++unit cpupi; ++ ++{$i fpcdefs.inc} ++ ++interface ++ ++ uses ++ procinfo, ++ psub; ++ ++ type ++ taarch64procinfo=class(tcgprocinfo) ++ constructor create(aparent: tprocinfo); override; ++ procedure set_first_temp_offset; override; ++ end; ++ ++implementation ++ ++ uses ++ tgobj, ++ cpubase; ++ ++ constructor taarch64procinfo.create(aparent: tprocinfo); ++ begin ++ inherited; ++ { use the stack pointer as framepointer, because ++ 1) we exactly know the offsets of the temps from the stack pointer ++ after pass 1 (based on the require parameter stack size for called ++ routines), while we don't know it for the frame pointer (it depends ++ on the number of saved registers) ++ 2) temp offsets from the stack pointer are positive while those from ++ the frame pointer are negative, and we can directly encode much ++ bigger positive offsets in the instructions ++ } ++ framepointer:=NR_STACK_POINTER_REG; ++ end; ++ ++ procedure taarch64procinfo.set_first_temp_offset; ++ begin ++ { leave room for allocated parameters } ++ tg.setfirsttemp(align(maxpushedparasize,16)); ++ end; ++ ++ ++begin ++ cprocinfo:=taarch64procinfo; ++end. +Index: fpc/fpcsrc/compiler/aarch64/cputarg.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/cputarg.pas +@@ -0,0 +1,70 @@ ++{ ++ Copyright (c) 2001-2002 by Peter Vreman ++ ++ Includes the AArch64 dependent target units ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ **************************************************************************** ++} ++unit cputarg; ++ ++{$i fpcdefs.inc} ++ ++interface ++ ++ ++implementation ++ ++ uses ++ systems { prevent a syntax error when nothing is included } ++ ++{************************************** ++ Targets ++**************************************} ++ ++ {$ifndef NOTARGETLINUX} ++ ,t_linux ++ {$endif} ++ {$ifndef NOTARGETBSD} ++ ,t_bsd ++ {$endif} ++ ++{************************************** ++ Assemblers ++**************************************} ++ ++ {$ifndef NOAGCPUGAS} ++ ,agcpugas ++ {$endif} ++ ++{************************************** ++ Assembler Readers ++**************************************} ++ ++ {$ifndef NoRaarmgas} ++ ,racpugas ++ {$endif NoRaarmgas} ++ ++{************************************** ++ Debuginfo ++**************************************} ++ ++ {$ifndef NoDbgDwarf} ++ ,dbgdwarf ++ {$endif NoDbgDwarf} ++ ; ++ ++end. +Index: fpc/fpcsrc/compiler/aarch64/hlcgcpu.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/hlcgcpu.pas +@@ -0,0 +1,156 @@ ++{ ++ Copyright (c) 1998-2010 by Florian Klaempfl and Jonas Maebe ++ Member of the Free Pascal development team ++ ++ This unit contains routines to create a pass-through high-level code ++ generator. This is used by most regular code generators. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ **************************************************************************** ++} ++ ++unit hlcgcpu; ++ ++{$i fpcdefs.inc} ++ ++interface ++ ++ uses ++ symtype, ++ aasmdata, ++ cgbase,cgutils, ++ hlcgobj, hlcg2ll; ++ ++ type ++ thlcgaarch64 = class(thlcg2ll) ++ procedure a_load_subsetreg_reg(list: TAsmList; subsetsize, tosize: tdef; const sreg: tsubsetregister; destreg: tregister); override; ++ procedure a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tdef; const fromsreg, tosreg: tsubsetregister); override; ++ protected ++ procedure a_load_regconst_subsetreg_intern(list: TAsmList; fromsize, subsetsize: tdef; fromreg: tregister; const sreg: tsubsetregister; slopt: tsubsetloadopt); override; ++ end; ++ ++ procedure create_hlcodegen; ++ ++implementation ++ ++ uses ++ defutil, ++ cpubase,aasmcpu, ++ cgobj,cgcpu; ++ ++ procedure thlcgaarch64.a_load_subsetreg_reg(list: TAsmList; subsetsize, tosize: tdef; const sreg: tsubsetregister; destreg: tregister); ++ var ++ op: tasmop; ++ tocgsize: tcgsize; ++ tmpdestreg: tregister; ++ begin ++ tocgsize:=def_cgsize(tosize); ++ if (sreg.startbit<>0) or ++ not(sreg.bitlen in [32,64]) then ++ begin ++ if is_signed(subsetsize) then ++ op:=A_SBFX ++ else ++ op:=A_UBFX; ++ { source and destination register of SBFX/UBFX have to be the same size } ++ if (sreg.subsetregsize in [OS_64,OS_S64]) and ++ not(tocgsize in [OS_64,OS_S64]) then ++ tmpdestreg:=cg.getintregister(list,OS_64) ++ else if not(sreg.subsetregsize in [OS_64,OS_S64]) and ++ (tocgsize in [OS_64,OS_S64]) then ++ tmpdestreg:=cg.getintregister(list,OS_32) ++ else ++ tmpdestreg:=destreg; ++ list.concat(taicpu.op_reg_reg_const_const(op,tmpdestreg,sreg.subsetreg,sreg.startbit,sreg.bitlen)); ++ { need to sign extend further or truncate? } ++ if (sreg.subsetregsize=OS_S64) and ++ not(tocgsize in [OS_64,OS_S64]) then ++ cg.a_load_reg_reg(list,OS_S64,tocgsize,tmpdestreg,destreg) ++ else if is_signed(subsetsize) and ++ (tocgsize in [OS_8,OS_16]) then ++ cg.a_load_reg_reg(list,OS_32,tocgsize,tmpdestreg,destreg) ++ else if tmpdestreg<>destreg then ++ cg.a_load_reg_reg(list,def_cgsize(subsetsize),tocgsize,tmpdestreg,destreg) ++ end ++ else ++ cg.a_load_reg_reg(list,def_cgsize(subsetsize),tocgsize,sreg.subsetreg,destreg); ++ end; ++ ++ ++ procedure makeregssamesize(list: tasmlist; fromsize, tosize: tcgsize; orgfromreg, orgtoreg: tregister; out newfromreg, newtoreg: tregister); ++ begin ++ if (fromsize in [OS_S64,OS_64])<> ++ (tosize in [OS_S64,OS_64]) then ++ begin ++ newfromreg:=cg.makeregsize(list,orgfromreg,OS_64); ++ newtoreg:=cg.makeregsize(list,orgtoreg,OS_64); ++ end ++ else ++ begin ++ newfromreg:=orgfromreg; ++ newtoreg:=orgtoreg; ++ end; ++ end; ++ ++ ++ procedure thlcgaarch64.a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tdef; const fromsreg, tosreg: tsubsetregister); ++ var ++ fromreg, toreg: tregister; ++ ++ begin ++ { BFM can only insert a bitfield that starts at position 0 in the source ++ source or destination register } ++ if (tosreg.startbit=0) and ++ (fromsreg.bitlen>=tosreg.bitlen) then ++ begin ++ makeregssamesize(list,fromsreg.subsetregsize,tosreg.subsetregsize,fromsreg.subsetreg,tosreg.subsetreg,fromreg,toreg); ++ list.concat(taicpu.op_reg_reg_const_const(A_BFXIL,toreg,fromreg,fromsreg.startbit,tosreg.bitlen)) ++ end ++ else if (fromsreg.startbit=0) and ++ (fromsreg.bitlen>=tosreg.bitlen) then ++ begin ++ makeregssamesize(list,fromsreg.subsetregsize,tosreg.subsetregsize,fromsreg.subsetreg,tosreg.subsetreg,fromreg,toreg); ++ list.concat(taicpu.op_reg_reg_const_const(A_BFI,toreg,fromreg,tosreg.startbit,tosreg.bitlen)) ++ end ++ else ++ inherited; ++ end; ++ ++ ++ procedure thlcgaarch64.a_load_regconst_subsetreg_intern(list: TAsmList; fromsize, subsetsize: tdef; fromreg: tregister; const sreg: tsubsetregister; slopt: tsubsetloadopt); ++ var ++ toreg: tregister; ++ begin ++ if slopt in [SL_SETZERO,SL_SETMAX] then ++ inherited ++ else if not(sreg.bitlen in [32,64]) then ++ begin ++ makeregssamesize(list,def_cgsize(fromsize),sreg.subsetregsize,fromreg,sreg.subsetreg,fromreg,toreg); ++ list.concat(taicpu.op_reg_reg_const_const(A_BFI,toreg,fromreg,sreg.startbit,sreg.bitlen)) ++ end ++ else ++ a_load_reg_reg(list,fromsize,subsetsize,fromreg,sreg.subsetreg); ++ end; ++ ++ ++ procedure create_hlcodegen; ++ begin ++ hlcg:=thlcgaarch64.create; ++ create_codegen; ++ end; ++ ++ ++end. +Index: fpc/fpcsrc/compiler/aarch64/ncpuadd.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/ncpuadd.pas +@@ -0,0 +1,402 @@ ++{ ++ Copyright (c) 2014 Jonas Maebe ++ ++ Code generation for add nodes on AArch64 ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ **************************************************************************** ++} ++unit ncpuadd; ++ ++{$i fpcdefs.inc} ++ ++interface ++ ++ uses ++ node,ncgadd,cpubase; ++ ++ type ++ taarch64addnode = class(tcgaddnode) ++ private ++ function GetResFlags(unsigned:Boolean):TResFlags; ++ function GetFPUResFlags:TResFlags; ++ protected ++ procedure second_addfloat;override; ++ procedure second_cmpfloat;override; ++ procedure second_cmpboolean;override; ++ procedure second_cmpsmallset;override; ++ procedure second_cmpordinal;override; ++ procedure second_addordinal;override; ++ procedure second_add64bit; override; ++ procedure second_cmp64bit; override; ++ public ++ function use_generic_mul32to64: boolean; override; ++ end; ++ ++ implementation ++ ++ uses ++ systems, ++ cutils,verbose, ++ paramgr,procinfo, ++ aasmtai,aasmdata,aasmcpu,defutil, ++ cgbase,cgcpu,cgutils, ++ cpupara, ++ ncon,nset,nadd, ++ hlcgobj, ncgutil,cgobj; ++ ++{***************************************************************************** ++ taarch64addnode ++*****************************************************************************} ++ ++ function taarch64addnode.GetResFlags(unsigned:Boolean):TResFlags; ++ begin ++ case NodeType of ++ equaln: ++ GetResFlags:=F_EQ; ++ unequaln: ++ GetResFlags:=F_NE; ++ else ++ if not(unsigned) then ++ begin ++ if nf_swapped in flags then ++ case NodeType of ++ ltn: ++ GetResFlags:=F_GT; ++ lten: ++ GetResFlags:=F_GE; ++ gtn: ++ GetResFlags:=F_LT; ++ gten: ++ GetResFlags:=F_LE; ++ else ++ internalerror(2014082010); ++ end ++ else ++ case NodeType of ++ ltn: ++ GetResFlags:=F_LT; ++ lten: ++ GetResFlags:=F_LE; ++ gtn: ++ GetResFlags:=F_GT; ++ gten: ++ GetResFlags:=F_GE; ++ else ++ internalerror(2014082011); ++ end; ++ end ++ else ++ begin ++ if nf_swapped in Flags then ++ case NodeType of ++ ltn: ++ GetResFlags:=F_HI; ++ lten: ++ GetResFlags:=F_HS; ++ gtn: ++ GetResFlags:=F_LO; ++ gten: ++ GetResFlags:=F_LS; ++ else ++ internalerror(2014082012); ++ end ++ else ++ case NodeType of ++ ltn: ++ GetResFlags:=F_LO; ++ lten: ++ GetResFlags:=F_LS; ++ gtn: ++ GetResFlags:=F_HI; ++ gten: ++ GetResFlags:=F_HS; ++ else ++ internalerror(2014082013); ++ end; ++ end; ++ end; ++ end; ++ ++ ++ function taarch64addnode.GetFPUResFlags:TResFlags; ++ begin ++ case NodeType of ++ equaln: ++ result:=F_EQ; ++ unequaln: ++ result:=F_NE; ++ else ++ begin ++ if nf_swapped in Flags then ++ case NodeType of ++ ltn: ++ result:=F_GT; ++ lten: ++ result:=F_GE; ++ gtn: ++ result:=F_LO; ++ gten: ++ result:=F_LS; ++ else ++ internalerror(2014082014); ++ end ++ else ++ case NodeType of ++ ltn: ++ result:=F_LO; ++ lten: ++ result:=F_LS; ++ gtn: ++ result:=F_GT; ++ gten: ++ result:=F_GE; ++ else ++ internalerror(2014082015); ++ end; ++ end; ++ end; ++ end; ++ ++ ++ procedure taarch64addnode.second_addfloat; ++ var ++ op : TAsmOp; ++ begin ++ pass_left_right; ++ if nf_swapped in flags then ++ swapleftright; ++ ++ { force fpureg as location, left right doesn't matter ++ as both will be in a fpureg } ++ hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); ++ hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.resultdef,true); ++ ++ location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef)); ++ location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size); ++ ++ case nodetype of ++ addn : ++ begin ++ op:=A_FADD; ++ end; ++ muln : ++ begin ++ op:=A_FMUL; ++ end; ++ subn : ++ begin ++ op:=A_FSUB; ++ end; ++ slashn : ++ begin ++ op:=A_FDIV; ++ end; ++ else ++ internalerror(200306014); ++ end; ++ ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op, ++ location.register,left.location.register,right.location.register)); ++ end; ++ ++ ++ procedure taarch64addnode.second_cmpfloat; ++ begin ++ pass_left_right; ++ if nf_swapped in flags then ++ swapleftright; ++ ++ { force fpureg as location, left right doesn't matter ++ as both will be in a fpureg } ++ hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); ++ hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.resultdef,true); ++ ++ location_reset(location,LOC_FLAGS,OS_NO); ++ location.resflags:=getfpuresflags; ++ ++ { signalling compare so we can get exceptions } ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FCMPE, ++ left.location.register,right.location.register)); ++ end; ++ ++ ++ procedure taarch64addnode.second_cmpboolean; ++ begin ++ pass_left_right; ++ force_reg_left_right(true,true); ++ ++ if right.location.loc=LOC_CONSTANT then ++ begin ++ if right.location.value>=0 then ++ Tcgaarch64(cg).handle_reg_imm12_reg(current_asmdata.CurrAsmList,A_CMP,left.location.size,left.location.register,right.location.value,NR_XZR,NR_NO,false,false) ++ else ++ { avoid overflow if value=low(int64) } ++{$push}{$r-}{$q-} ++ Tcgaarch64(cg).handle_reg_imm12_reg(current_asmdata.CurrAsmList,A_CMN,left.location.size,left.location.register,-right.location.value,NR_XZR,NR_NO,false,false) ++{$pop} ++ end ++ else ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,left.location.register,right.location.register)); ++ ++ location_reset(location,LOC_FLAGS,OS_NO); ++ location.resflags:=getresflags(true); ++ end; ++ ++ ++ procedure taarch64addnode.second_cmpsmallset; ++ var ++ tmpreg : tregister; ++ op: tasmop; ++ begin ++ pass_left_right; ++ ++ location_reset(location,LOC_FLAGS,OS_NO); ++ ++ force_reg_left_right(true,true); ++ ++ if right.location.loc=LOC_CONSTANT then ++ begin ++ { when doing a cmp/cmn on 32 bit, we care whether the *lower 32 bit* ++ is a positive/negative value -> sign extend } ++ if not(right.location.size in [OS_64,OS_S64]) then ++ right.location.value:=longint(right.location.value); ++ if right.location.value>=0 then ++ op:=A_CMP ++ else ++ op:=A_CMN; ++ end ++ else ++ { for DFA } ++ op:=A_NONE; ++ ++ case nodetype of ++ equaln, ++ unequaln: ++ begin ++ if right.location.loc=LOC_CONSTANT then ++ tcgaarch64(cg).handle_reg_imm12_reg(current_asmdata.CurrAsmList,op,def_cgsize(resultdef),left.location.register,abs(right.location.value),NR_XZR,NR_NO,false,false) ++ else ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,left.location.register,right.location.register)); ++ location.resflags:=getresflags(true); ++ end; ++ lten, ++ gten: ++ begin ++ if (not(nf_swapped in flags) and ++ (nodetype=lten)) or ++ ((nf_swapped in flags) and ++ (nodetype=gten)) then ++ swapleftright; ++ { we can't handle left as a constant yet } ++ if left.location.loc=LOC_CONSTANT then ++ hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true); ++ tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,left.location.size); ++ if right.location.loc=LOC_CONSTANT then ++ begin ++ hlcg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_AND,resultdef,right.location.value,left.location.register,tmpreg); ++ tcgaarch64(cg).handle_reg_imm12_reg(current_asmdata.CurrAsmList,op,def_cgsize(resultdef),tmpreg,abs(right.location.value),NR_XZR,NR_NO,false,false) ++ end ++ else ++ begin ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_AND,tmpreg,left.location.register,right.location.register)); ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,tmpreg,right.location.register)); ++ end; ++ location.resflags:=F_EQ; ++ end; ++ else ++ internalerror(2012042701); ++ end; ++ end; ++ ++ ++ procedure taarch64addnode.second_cmpordinal; ++ var ++ unsigned : boolean; ++ begin ++ pass_left_right; ++ force_reg_left_right(true,true); ++ ++ unsigned:=not(is_signed(left.resultdef)) or ++ not(is_signed(right.resultdef)); ++ ++ if right.location.loc = LOC_CONSTANT then ++ begin ++ if right.location.value>=0 then ++ Tcgaarch64(cg).handle_reg_imm12_reg(current_asmdata.CurrAsmList,A_CMP,left.location.size,left.location.register,right.location.value,NR_XZR,NR_NO,false,false) ++ else ++{$push}{$r-}{$q-} ++ Tcgaarch64(cg).handle_reg_imm12_reg(current_asmdata.CurrAsmList,A_CMN,left.location.size,left.location.register,-right.location.value,NR_XZR,NR_NO,false,false) ++{$pop} ++ end ++ else ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,left.location.register,right.location.register)); ++ ++ location_reset(location,LOC_FLAGS,OS_NO); ++ location.resflags:=getresflags(unsigned); ++ end; ++ ++ ++ procedure taarch64addnode.second_addordinal; ++ const ++ multops: array[boolean] of TAsmOp = (A_SMULL,A_UMULL); ++ var ++ unsigned: boolean; ++ begin ++ { 32x32->64 multiplication } ++ if (nodetype=muln) and ++ is_32bit(left.resultdef) and ++ is_32bit(right.resultdef) and ++ is_64bit(resultdef) then ++ begin ++ unsigned:=not(is_signed(left.resultdef)) or ++ not(is_signed(right.resultdef)); ++ pass_left_right; ++ force_reg_left_right(true,true); ++ { force_reg_left_right can leave right as a LOC_CONSTANT (we can't ++ say "a constant register is okay, but an ordinal constant isn't) } ++ if right.location.loc=LOC_CONSTANT then ++ hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true); ++ location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); ++ location.register:=cg.getintregister(current_asmdata.CurrAsmList,def_cgsize(resultdef)); ++ current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(multops[unsigned],location.register,left.location.register,right.location.register)); ++ end ++ else ++ inherited second_addordinal; ++ end; ++ ++ ++ procedure taarch64addnode.second_add64bit; ++ begin ++ second_addordinal; ++ end; ++ ++ ++ procedure taarch64addnode.second_cmp64bit; ++ begin ++ second_cmpordinal; ++ end; ++ ++ ++ function taarch64addnode.use_generic_mul32to64: boolean; ++ begin ++ result:=false; ++ end; ++ ++ ++begin ++ caddnode:=taarch64addnode; ++end. +Index: fpc/fpcsrc/compiler/aarch64/ncpucnv.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/ncpucnv.pas +@@ -0,0 +1,201 @@ ++{ ++ Copyright (c) 2014 by Jonas Maebe ++ ++ Generate AArch64 assembler for type converting nodes ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ ****************************************************************************} ++unit ncpucnv; ++ ++{$i fpcdefs.inc} ++ ++interface ++ ++ uses ++ node,ncnv,ncgcnv; ++ ++ type ++ taarch64typeconvnode = class(TCgTypeConvNode) ++ protected ++ function typecheck_int_to_real: tnode; override; ++ function first_int_to_real: tnode; override; ++ ++ { procedure second_int_to_int;override; } ++ { procedure second_string_to_string;override; } ++ { procedure second_cstring_to_pchar;override; } ++ { procedure second_string_to_chararray;override; } ++ { procedure second_array_to_pointer;override; } ++ { procedure second_pointer_to_array;override; } ++ { procedure second_chararray_to_string;override; } ++ { procedure second_char_to_string;override; } ++ procedure second_int_to_real;override; ++ { procedure second_real_to_real;override; } ++ { procedure second_cord_to_pointer;override; } ++ { procedure second_proc_to_procvar;override; } ++ { procedure second_bool_to_int;override; } ++ procedure second_int_to_bool;override; ++ { procedure second_load_smallset;override; } ++ { procedure second_ansistring_to_pchar;override; } ++ { procedure second_pchar_to_string;override; } ++ { procedure second_class_to_intf;override; } ++ { procedure second_char_to_char;override; } ++ end; ++ ++implementation ++ ++ uses ++ verbose,globals, ++ symdef,aasmdata,aasmbase, ++ defutil, ++ cgbase,cgutils,procinfo, ++ cpubase,aasmcpu, ++ pass_2,cgobj, ++ hlcgobj; ++ ++ ++{***************************************************************************** ++ FirstTypeConv ++*****************************************************************************} ++ ++ function taarch64typeconvnode.typecheck_int_to_real: tnode; ++ begin ++ { aarch64 supports converting everything to floating point, even fixed ++ point! Unfortunately, it only supports fixed point with a power-of-2 ++ fraction, which is not the case for currency. ++ ++ Generate the division by 10000 via nodes so the 10000.0 constant can ++ be reused. } ++ if is_currency(resultdef) and ++ not(nf_is_currency in flags) then ++ begin ++ { convert the equivalent int64 value to double without conversion ++ (internal typecast -> will set nf_is_currency flag) } ++ result:=ctypeconvnode.create_internal(left,s64floattype); ++ { turn into currency with conversion, which will divide by 10000 ++ (regular typecast) } ++ result:=ctypeconvnode.create(result,s64currencytype); ++ exit; ++ end; ++ { The only other thing we have to take care of: convert values < 32 bit ++ to 32 bit } ++ if left.resultdef.size<4 then ++ begin ++ if is_signed(left.resultdef) then ++ inserttypeconv(left,s32inttype) ++ else ++ inserttypeconv(left,u32inttype) ++ end; ++ result:=inherited; ++ end; ++ ++ ++ function taarch64typeconvnode.first_int_to_real: tnode; ++ begin ++ result:=nil; ++ expectloc:=LOC_MMREGISTER; ++ end; ++ ++ ++{***************************************************************************** ++ SecondTypeConv ++*****************************************************************************} ++ ++ procedure taarch64typeconvnode.second_int_to_real; ++ var ++ op: tasmop; ++ begin ++ location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef)); ++ location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size); ++ hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true); ++ if not(left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then ++ internalerror(2014120401); ++ case left.location.size of ++ OS_32, ++ OS_64: ++ op:=A_UCVTF; ++ OS_S32, ++ OS_S64, ++ { for currency and comp } ++ OS_F64: ++ op:=A_SCVTF; ++ else ++ internalerror(2014120402); ++ end; ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,location.register,left.location.register)); ++ { no scaling for currency, that's handled in pass_typecheck } ++ end; ++ ++ ++ procedure taarch64typeconvnode.second_int_to_bool; ++ var ++ resflags: tresflags; ++ hlabel,oldTrueLabel,oldFalseLabel : tasmlabel; ++ begin ++ if (nf_explicit in flags) and ++ not(left.expectloc in [LOC_FLAGS,LOC_JUMP]) then ++ begin ++ inherited; ++ exit; ++ end; ++ ++ { can't use the generic code, as it assumes that OP_OR automatically sets ++ the flags. We can also do things more efficiently directly } ++ ++ oldTrueLabel:=current_procinfo.CurrTrueLabel; ++ oldFalseLabel:=current_procinfo.CurrFalseLabel; ++ current_asmdata.getjumplabel(current_procinfo.CurrTrueLabel); ++ current_asmdata.getjumplabel(current_procinfo.CurrFalseLabel); ++ secondpass(left); ++ if codegenerror then ++ exit; ++ ++ case left.location.loc of ++ LOC_CREFERENCE, ++ LOC_REFERENCE, ++ LOC_REGISTER, ++ LOC_CREGISTER, ++ LOC_JUMP: ++ begin ++ hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true); ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CMP,left.location.register,0)); ++ resflags:=F_NE; ++ end; ++ LOC_FLAGS : ++ resflags:=left.location.resflags; ++ else ++ internalerror(2014122902); ++ end; ++ { load flags to register } ++ location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); ++ location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size); ++ if is_cbool(resultdef) then ++ begin ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_cond(A_CSETM,location.register,flags_to_cond(resflags))); ++ { truncate? (in case cbools are ever made unsigned) } ++ if resultdef.size<4 then ++ cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,location.size,location.register,location.register); ++ end ++ else ++ cg.g_flags2reg(current_asmdata.CurrAsmList,location.size,resflags,location.register); ++ cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS); ++ current_procinfo.CurrTrueLabel:=oldTrueLabel; ++ current_procinfo.CurrFalseLabel:=oldFalseLabel; ++ end; ++ ++ ++begin ++ ctypeconvnode:=taarch64typeconvnode; ++end. +Index: fpc/fpcsrc/compiler/aarch64/ncpuinl.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/ncpuinl.pas +@@ -0,0 +1,184 @@ ++{ ++ Copyright (c) 1998-2002 by Florian Klaempfl ++ ++ Generates ARM inline nodes ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ **************************************************************************** ++} ++unit ncpuinl; ++ ++{$i fpcdefs.inc} ++ ++interface ++ ++ uses ++ node,ninl,ncginl; ++ ++ type ++ taarch64inlinenode = class(tcgInlineNode) ++ function first_abs_real: tnode; override; ++ function first_sqr_real: tnode; override; ++ function first_sqrt_real: tnode; override; ++ function first_round_real: tnode; override; ++ function first_trunc_real: tnode; override; ++ procedure second_abs_real; override; ++ procedure second_sqr_real; override; ++ procedure second_sqrt_real; override; ++ procedure second_abs_long; override; ++ procedure second_round_real; override; ++ procedure second_trunc_real; override; ++ procedure second_get_frame; override; ++ private ++ procedure load_fpu_location; ++ end; ++ ++ ++implementation ++ ++ uses ++ globtype,verbose,globals, ++ cpuinfo, defutil,symdef,aasmdata,aasmcpu, ++ cgbase,cgutils,pass_1,pass_2, ++ cpubase,ncgutil,cgobj,cgcpu, hlcgobj; ++ ++{***************************************************************************** ++ taarch64inlinenode ++*****************************************************************************} ++ ++ procedure taarch64inlinenode.load_fpu_location; ++ begin ++ secondpass(left); ++ hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); ++ location_copy(location,left.location); ++ location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size); ++ location.loc:=LOC_MMREGISTER; ++ end; ++ ++ ++ function taarch64inlinenode.first_abs_real : tnode; ++ begin ++ expectloc:=LOC_MMREGISTER; ++ result:=nil; ++ end; ++ ++ ++ function taarch64inlinenode.first_sqr_real : tnode; ++ begin ++ expectloc:=LOC_MMREGISTER; ++ result:=nil; ++ end; ++ ++ ++ function taarch64inlinenode.first_sqrt_real : tnode; ++ begin ++ expectloc:=LOC_MMREGISTER; ++ result:=nil; ++ end; ++ ++ ++ function taarch64inlinenode.first_round_real: tnode; ++ begin ++ expectloc:=LOC_MMREGISTER; ++ result:=nil; ++ end; ++ ++ ++ function taarch64inlinenode.first_trunc_real: tnode; ++ begin ++ expectloc:=LOC_MMREGISTER; ++ result:=nil; ++ end; ++ ++ ++ procedure taarch64inlinenode.second_abs_real; ++ begin ++ load_fpu_location; ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FABS,location.register,left.location.register)); ++ end; ++ ++ ++ procedure taarch64inlinenode.second_sqr_real; ++ begin ++ load_fpu_location; ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_FMUL,location.register,left.location.register,left.location.register)); ++ end; ++ ++ ++ procedure taarch64inlinenode.second_sqrt_real; ++ begin ++ load_fpu_location; ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSQRT,location.register,left.location.register)); ++ end; ++ ++ ++ procedure taarch64inlinenode.second_abs_long; ++ var ++ opsize : tcgsize; ++ hp : taicpu; ++ begin ++ secondpass(left); ++ opsize:=def_cgsize(left.resultdef); ++ hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true); ++ location:=left.location; ++ location.register:=cg.getintregister(current_asmdata.CurrAsmList,opsize); ++ ++ current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_NEG,location.register,left.location.register),PF_S)); ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_cond(A_CSEL,location.register,location.register,left.location.register,C_GE)); ++ end; ++ ++ ++ procedure taarch64inlinenode.second_round_real; ++ var ++ hreg: tregister; ++ begin ++ secondpass(left); ++ hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); ++ location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); ++ location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size); ++ hreg:=cg.getmmregister(current_asmdata.CurrAsmList,left.location.size); ++ { round as floating point using current rounding mode } ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FRINTX,hreg,left.location.register)); ++ { convert to signed integer rounding towards zero (there's no "round to ++ integer using current rounding mode") } ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FCVTZS,location.register,hreg)); ++ end; ++ ++ ++ procedure taarch64inlinenode.second_trunc_real; ++ begin ++ secondpass(left); ++ hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); ++ location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); ++ location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size); ++ { convert to signed integer rounding towards zero } ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FCVTZS,location.register,left.location.register)); ++ end; ++ ++ ++ procedure taarch64inlinenode.second_get_frame; ++ begin ++ location_reset(location,LOC_CREGISTER,OS_ADDR); ++ { this routine is used to get the frame pointer for backtracing ++ purposes. current_procinfo.framepointer is set to SP because that one ++ is used to access temps. On most platforms these two frame pointers ++ are the same, but not on AArch64. } ++ location.register:=NR_FRAME_POINTER_REG; ++ end; ++ ++begin ++ cinlinenode:=taarch64inlinenode; ++end. +Index: fpc/fpcsrc/compiler/aarch64/ncpumat.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/ncpumat.pas +@@ -0,0 +1,196 @@ ++{ ++ Copyright (c) 1998-2002, 2014 by Florian Klaempfl and Jonas Maebe ++ ++ Generate AArch64 assembler for math nodes ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ **************************************************************************** ++} ++unit ncpumat; ++ ++{$i fpcdefs.inc} ++ ++interface ++ ++ uses ++ node,nmat,ncgmat; ++ ++ type ++ taarch64moddivnode = class(tmoddivnode) ++ function pass_1: tnode; override; ++ procedure pass_generate_code;override; ++ end; ++ ++ taarch64notnode = class(tcgnotnode) ++ procedure second_boolean;override; ++ end; ++ ++ taarch64unaryminusnode = class(tcgunaryminusnode) ++ procedure second_float; override; ++ end; ++ ++implementation ++ ++ uses ++ globtype,systems,constexp, ++ cutils,verbose,globals, ++ symconst,symdef, ++ aasmbase,aasmcpu,aasmtai,aasmdata, ++ defutil, ++ cgbase,cgobj,hlcgobj,pass_2,procinfo, ++ ncon, ++ cpubase, ++ ncgutil,cgcpu,cgutils; ++ ++{***************************************************************************** ++ taarch64moddivnode ++*****************************************************************************} ++ ++ function taarch64moddivnode.pass_1: tnode; ++ begin ++ result:=inherited pass_1; ++ if not assigned(result) then ++ include(current_procinfo.flags,pi_do_call); ++ end; ++ ++ ++ procedure taarch64moddivnode.pass_generate_code; ++ var ++ op : tasmop; ++ tmpreg, ++ numerator, ++ divider, ++ resultreg : tregister; ++ hl : tasmlabel; ++ overflowloc: tlocation; ++ begin ++ secondpass(left); ++ secondpass(right); ++ ++ { set result location } ++ location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); ++ location.register:=cg.getintregister(current_asmdata.CurrAsmList,def_cgsize(resultdef)); ++ resultreg:=location.register; ++ ++ { put numerator in register } ++ hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true); ++ numerator:=left.location.register; ++ ++ { load divider in a register } ++ hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true); ++ divider:=right.location.register; ++ ++ { start division } ++ if is_signed(left.resultdef) then ++ op:=A_SDIV ++ else ++ op:=A_UDIV; ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,numerator,divider)); ++ ++ { no divide-by-zero detection available in hardware, emulate (if it's a ++ constant, this will have been detected earlier already) } ++ if (right.nodetype<>ordconstn) then ++ begin ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CMP, ++ right.location.register,0)); ++ ++ current_asmdata.getjumplabel(hl); ++ current_asmdata.CurrAsmList.concat(taicpu.op_cond_sym(A_B,C_NE,hl)); ++ cg.a_call_name(current_asmdata.CurrAsmList,'FPC_DIVBYZERO',false); ++ cg.a_label(current_asmdata.CurrAsmList,hl); ++ end; ++ ++ { in case of overflow checking, also check for low(int64) div (-1) ++ (no hardware support for this either) } ++ if (cs_check_overflow in current_settings.localswitches) and ++ is_signed(left.resultdef) and ++ ((right.nodetype<>ordconstn) or ++ (tordconstnode(right).value=-1)) then ++ begin ++ { num=ffff... and div=8000... <=> ++ num xor not(div xor 8000...) = 0 ++ (and we have the "eon" operation, which performs "xor not(...)" } ++ tmpreg:=hlcg.getintregister(current_asmdata.CurrAsmList,left.resultdef); ++ hlcg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_XOR,left.resultdef,low(int64),left.location.register,tmpreg); ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_EON, ++ tmpreg,left.location.register,tmpreg)); ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CMP,tmpreg,0)); ++ { now the zero/equal flag is set in case we divided low(int64) by ++ (-1) } ++ location_reset(overflowloc,LOC_FLAGS,OS_NO); ++ overflowloc.resflags:=F_EQ; ++ cg.g_overflowcheck_loc(current_asmdata.CurrAsmList,location,resultdef,overflowloc); ++ end; ++ ++ { in case of modulo, multiply result again by the divider and subtract ++ from the numerator } ++ if nodetype=modn then ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_reg(A_MSUB,resultreg, ++ resultreg,divider,numerator)); ++ end; ++ ++ ++{***************************************************************************** ++ taarch64notnode ++*****************************************************************************} ++ ++ procedure taarch64notnode.second_boolean; ++ begin ++ if not handle_locjump then ++ begin ++ secondpass(left); ++ case left.location.loc of ++ LOC_FLAGS : ++ begin ++ location_copy(location,left.location); ++ inverse_flags(location.resflags); ++ end; ++ LOC_REGISTER, LOC_CREGISTER, ++ LOC_REFERENCE, LOC_CREFERENCE, ++ LOC_SUBSETREG, LOC_CSUBSETREG, ++ LOC_SUBSETREF, LOC_CSUBSETREF: ++ begin ++ hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true); ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CMP, ++ left.location.register,0)); ++ location_reset(location,LOC_FLAGS,OS_NO); ++ location.resflags:=F_EQ; ++ end; ++ else ++ internalerror(2003042401); ++ end; ++ end; ++ end; ++ ++ ++{***************************************************************************** ++ taarch64unaryminusnode ++*****************************************************************************} ++ ++ procedure taarch64unaryminusnode.second_float; ++ begin ++ secondpass(left); ++ hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); ++ location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef)); ++ location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size); ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FNEG,location.register,left.location.register)); ++ end; ++ ++begin ++ cmoddivnode:=taarch64moddivnode; ++ cnotnode:=taarch64notnode; ++ cunaryminusnode:=taarch64unaryminusnode; ++end. +Index: fpc/fpcsrc/compiler/aarch64/ncpumem.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/ncpumem.pas +@@ -0,0 +1,142 @@ ++{ ++ Copyright (c) 2014 by Jonas Maebe ++ ++ Generate AArch64 code for in memory related nodes ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ **************************************************************************** ++} ++unit ncpumem; ++ ++{$i fpcdefs.inc} ++ ++interface ++ ++ uses ++ globtype, ++ cgbase, ++ symtype, ++ node,nmem,ncgmem; ++ ++ type ++ taarch64loadparentfpnode = class(tcgloadparentfpnode) ++ procedure pass_generate_code; override; ++ end; ++ ++ taarch64vecnode = class(tcgvecnode) ++ protected ++ function valid_index_size(size: tcgsize): boolean; override; ++ public ++ procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); override; ++ end; ++ ++implementation ++ ++ uses ++ cutils,verbose, ++ defutil, ++ aasmdata,cpubase, ++ cgutils, ++ cgobj; ++ ++ { taarch64loadparentfpnode } ++ ++ procedure taarch64loadparentfpnode.pass_generate_code; ++ begin ++ inherited pass_generate_code; ++ { see the comments in tcgaarch64.g_proc_entry } ++ if (location.loc in [LOC_REGISTER,LOC_CREGISTER]) and ++ (location.register=NR_STACK_POINTER_REG) then ++ if (kind=lpf_forpara) then ++ location.register:=NR_FRAME_POINTER_REG ++ else ++ begin ++ { load stack pointer in a different register, as many instructions ++ cannot directly work with the stack pointer. The register ++ allocator can merge them if possible } ++ location.register:=cg.getaddressregister(current_asmdata.CurrAsmList); ++ cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,NR_STACK_POINTER_REG,location.register); ++ location.loc:=LOC_REGISTER; ++ end; ++ end; ++ ++ ++ { taarch64vecnode } ++ ++ function taarch64vecnode.valid_index_size(size: tcgsize): boolean; ++ begin ++ { all sizes are ok if we handle the "reference reg mul", because ++ a) we use a 64 bit register for 64 bit values, and a 32 bit one (that ++ we can sign/zero-extend inside the reference) for smaller values ++ b) for values < 32 bit, the entire 32 bit register always contains the ++ sign/zero-extended version of the value } ++ result:= ++ not is_packed_array(left.resultdef) and ++ (get_mul_size in [1,2,4,8,16]); ++ end; ++ ++ ++ procedure taarch64vecnode.update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); ++ var ++ base: tregister; ++ oldoffset: asizeint; ++ shift: byte; ++ begin ++ { we can only scale the index by shl 0..4 } ++ if not(l in [1,2,4,8,16]) then ++ begin ++ inherited; ++ exit; ++ end; ++ { we need a base set and an index available } ++ if (location.reference.base=NR_NO) or ++ (location.reference.index<>NR_NO) then ++ begin ++ { don't integrate the offset yet, make_simple_ref() may be able to ++ handle it more efficiently later (unless an offset is all we have ++ -> optimization for someone that wants to add support for AArch64 ++ embedded targets) } ++ oldoffset:=location.reference.offset; ++ location.reference.offset:=0; ++ base:=cg.getaddressregister(current_asmdata.CurrAsmList); ++ cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,location.reference,base); ++ reference_reset_base(location.reference,base,oldoffset,location.reference.alignment); ++ end; ++ shift:=BsfDWord(l); ++ location.reference.index:=maybe_const_reg; ++ { sign/zero-extend? } ++ if regsize.size=8 then ++ if shift<>0 then ++ location.reference.shiftmode:=SM_LSL ++ else ++ location.reference.shiftmode:=SM_NONE ++ else if is_signed(regsize) then ++ location.reference.shiftmode:=SM_SXTW ++ else if shift<>0 then ++ location.reference.shiftmode:=SM_UXTW ++ else ++ { the upper 32 bits are always already zero-extended -> just use 64 bit ++ register } ++ location.reference.index:=cg.makeregsize(current_asmdata.CurrAsmList,location.reference.index,OS_64); ++ location.reference.shiftimm:=shift; ++ location.reference.alignment:=newalignment(location.reference.alignment,l); ++ end; ++ ++ ++begin ++ cloadparentfpnode:=taarch64loadparentfpnode; ++ cvecnode:=taarch64vecnode; ++end. +Index: fpc/fpcsrc/compiler/aarch64/ncpuset.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/ncpuset.pas +@@ -0,0 +1,175 @@ ++{ ++ Copyright (c) 2015 by Jonas Maebe ++ ++ Generate AArch64 assembler for in set/case nodes ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ **************************************************************************** ++} ++unit ncpuset; ++ ++{$i fpcdefs.inc} ++ ++interface ++ ++ uses ++ node,nset,ncgset,cpubase,cgbase,cgobj,aasmbase,aasmtai,aasmdata,globtype; ++ ++ type ++ taarch64casenode = class(tcgcasenode) ++ protected ++ procedure optimizevalues(var max_linear_list: aint; var max_dist: aword);override; ++ function has_jumptable: boolean;override; ++ procedure genjumptable(hp: pcaselabel ;min_, max_: aint);override; ++ end; ++ ++ ++implementation ++ ++ uses ++ systems, ++ verbose,globals,constexp, ++ symconst,symdef,defutil, ++ paramgr, ++ cpuinfo, ++ pass_2,cgcpu, ++ ncon, ++ tgobj,ncgutil,regvars,rgobj,aasmcpu, ++ procinfo, ++ cgutils; ++ ++{***************************************************************************** ++ TCGCASENODE ++*****************************************************************************} ++ ++ ++ procedure taarch64casenode.optimizevalues(var max_linear_list: aint; var max_dist: aword); ++ begin ++ max_linear_list:=10; ++ end; ++ ++ ++ function taarch64casenode.has_jumptable: boolean; ++ begin ++ has_jumptable:=true; ++ end; ++ ++ ++ procedure taarch64casenode.genjumptable(hp: pcaselabel; min_, max_: aint); ++ var ++ last: TConstExprInt; ++ tablelabel: TAsmLabel; ++ basereg,indexreg,jumpreg: TRegister; ++ href: TReference; ++ opcgsize: tcgsize; ++ sectype: TAsmSectiontype; ++ jtitemconsttype: taiconst_type; ++ ++ procedure genitem(list:TAsmList;t : pcaselabel); ++ var ++ i : aint; ++ begin ++ if assigned(t^.less) then ++ genitem(list,t^.less); ++ { fill possible hole } ++ i:=last.svalue+1; ++ while i<=t^._low.svalue-1 do ++ begin ++ list.concat(Tai_const.Create_rel_sym(jtitemconsttype,tablelabel,elselabel)); ++ inc(i); ++ end; ++ i:=t^._low.svalue; ++ while i<=t^._high.svalue do ++ begin ++ list.concat(Tai_const.Create_rel_sym(jtitemconsttype,tablelabel,blocklabel(t^.blockid))); ++ inc(i); ++ end; ++ last:=t^._high; ++ if assigned(t^.greater) then ++ genitem(list,t^.greater); ++ end; ++ ++ begin ++ if not(target_info.system in systems_darwin) then ++ jtitemconsttype:=aitconst_32bit ++ else ++ { see https://gmplib.org/list-archives/gmp-bugs/2012-December/002836.html } ++ jtitemconsttype:=aitconst_darwin_dwarf_delta32; ++ ++ last:=min_; ++ opcgsize:=def_cgsize(opsize); ++ { a <= x <= b <-> unsigned(x-a) <= (b-a) } ++ cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SUB,opcgsize,aint(min_),hregister); ++ if not(jumptable_no_range) then ++ begin ++ { case expr greater than max_ => goto elselabel } ++ cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opcgsize,OC_A,aint(max_)-aint(min_),hregister,elselabel); ++ min_:=0; ++ end; ++ { local label in order to avoid using GOT } ++ current_asmdata.getlabel(tablelabel,alt_data); ++ indexreg:=cg.makeregsize(current_asmdata.CurrAsmList,hregister,OS_ADDR); ++ cg.a_load_reg_reg(current_asmdata.CurrAsmList,opcgsize,OS_ADDR,hregister,indexreg); ++ { load table address } ++ reference_reset_symbol(href,tablelabel,0,4); ++ basereg:=cg.getaddressregister(current_asmdata.CurrAsmList); ++ cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,href,basereg); ++ { load table slot, 32-bit sign extended } ++ reference_reset_base(href,basereg,0,4); ++ href.index:=indexreg; ++ href.shiftmode:=SM_LSL; ++ href.shiftimm:=2; ++ jumpreg:=cg.getaddressregister(current_asmdata.CurrAsmList); ++ cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_S32,OS_ADDR,href,jumpreg); ++ { add table address } ++ cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_ADDR,basereg,jumpreg); ++ { and finally jump } ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_BR,jumpreg)); ++ { generate jump table } ++ if not(target_info.system in systems_darwin) then ++ sectype:=sec_rodata ++ else ++ begin ++ { on Mac OS X, dead code stripping ("smart linking") happens based on ++ global symbols: every global/static symbol (symbols that do not ++ start with "L") marks the start of a new "subsection" that is ++ discarded by the linker if there are no references to this symbol. ++ This means that if you put the jump table in the rodata section, it ++ will become part of the block of data associated with the previous ++ non-L-label in the rodata section and stay or be thrown away ++ depending on whether that block of data is referenced. Therefore, ++ jump tables must be added in the code section and since aktlocaldata ++ is inserted right after the routine, it will become part of the ++ same subsection that contains the routine's code } ++ sectype:=sec_code; ++ end; ++ new_section(current_procinfo.aktlocaldata,sectype,current_procinfo.procdef.mangledname,4); ++ if target_info.system in systems_darwin then ++ begin ++ { additionally, these tables are now marked via ".data_region jt32" ++ and ".end_data_region" } ++ current_procinfo.aktlocaldata.concat(tai_directive.Create(asd_data_region,'jt32')); ++ end; ++ current_procinfo.aktlocaldata.concat(Tai_label.Create(tablelabel)); ++ genitem(current_procinfo.aktlocaldata,hp); ++ if target_info.system in systems_darwin then ++ current_procinfo.aktlocaldata.concat(tai_directive.Create(asd_end_data_region,'')); ++ end; ++ ++ ++begin ++ ccasenode:=taarch64casenode; ++end. +Index: fpc/fpcsrc/compiler/aarch64/ra64con.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/ra64con.inc ++++ fpc/fpcsrc/compiler/aarch64/ra64con.inc +@@ -64,6 +64,8 @@ NR_W30 = tregister($0104001E); + NR_X30 = tregister($0105001E); + NR_WZR = tregister($0104001F); + NR_XZR = tregister($0105001F); ++NR_WSP = tregister($01040020); ++NR_SP = tregister($01050020); + NR_B0 = tregister($04010000); + NR_H0 = tregister($04030000); + NR_S0 = tregister($04090000); +@@ -225,3 +227,6 @@ NR_S31 = tregister($0409001F); + NR_D31 = tregister($040a001F); + NR_Q31 = tregister($0405001F); + NR_NZCV = tregister($05000000); ++NR_FPCR = tregister($05000001); ++NR_FPSR = tregister($05000002); ++NR_TPIDR_EL0 = tregister($05000003); +Index: fpc/fpcsrc/compiler/aarch64/ra64dwa.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/ra64dwa.inc ++++ fpc/fpcsrc/compiler/aarch64/ra64dwa.inc +@@ -64,164 +64,169 @@ + 30, + 31, + 31, ++31, ++31, ++64, ++64, ++64, ++64, ++64, ++65, ++65, ++65, ++65, ++65, ++66, ++66, ++66, ++66, ++66, ++67, ++67, ++67, ++67, ++67, ++68, ++68, ++68, ++68, ++68, ++69, ++69, ++69, ++69, ++69, ++70, ++70, ++70, ++70, ++70, ++71, ++71, ++71, ++71, ++71, ++72, ++72, ++72, ++72, ++72, ++73, ++73, ++73, ++73, ++73, ++74, ++74, ++74, ++74, ++74, ++75, ++75, ++75, ++75, ++75, ++76, ++76, ++76, ++76, ++76, ++77, ++77, ++77, ++77, ++77, ++78, ++78, ++78, ++78, ++78, ++79, ++79, ++79, ++79, ++79, ++80, ++80, ++80, ++80, ++80, ++81, ++81, ++81, ++81, ++81, ++82, ++82, ++82, ++82, ++82, ++83, ++83, ++83, ++83, ++83, ++84, ++84, ++84, ++84, ++84, ++85, ++85, ++85, ++85, ++85, ++86, ++86, ++86, ++86, ++86, ++87, ++87, ++87, ++87, ++87, ++88, ++88, ++88, ++88, ++88, ++89, ++89, ++89, ++89, ++89, ++90, ++90, ++90, ++90, ++90, ++91, ++91, ++91, ++91, ++91, ++92, ++92, ++92, ++92, ++92, ++93, ++93, ++93, ++93, ++93, ++94, ++94, ++94, ++94, ++94, ++95, ++95, ++95, ++95, ++95, + 0, + 0, + 0, +-0, +-0, +-1, +-1, +-1, +-1, +-1, +-2, +-2, +-2, +-2, +-2, +-3, +-3, +-3, +-3, +-3, +-4, +-4, +-4, +-4, +-4, +-5, +-5, +-5, +-5, +-5, +-6, +-6, +-6, +-6, +-6, +-7, +-7, +-7, +-7, +-7, +-8, +-8, +-8, +-8, +-8, +-9, +-9, +-9, +-9, +-9, +-10, +-10, +-10, +-10, +-10, +-11, +-11, +-11, +-11, +-11, +-12, +-12, +-12, +-12, +-12, +-13, +-13, +-13, +-13, +-13, +-14, +-14, +-14, +-14, +-14, +-15, +-15, +-15, +-15, +-15, +-16, +-16, +-16, +-16, +-16, +-17, +-17, +-17, +-17, +-17, +-18, +-18, +-18, +-18, +-18, +-19, +-19, +-19, +-19, +-19, +-20, +-20, +-20, +-20, +-20, +-21, +-21, +-21, +-21, +-21, +-22, +-22, +-22, +-22, +-22, +-23, +-23, +-23, +-23, +-23, +-24, +-24, +-24, +-24, +-24, +-25, +-25, +-25, +-25, +-25, +-26, +-26, +-26, +-26, +-26, +-27, +-27, +-27, +-27, +-27, +-28, +-28, +-28, +-28, +-28, +-29, +-29, +-29, +-29, +-29, +-30, +-30, +-30, +-30, +-30, +-31, +-31, +-31, +-31, +-31, + 0 +Index: fpc/fpcsrc/compiler/aarch64/ra64nor.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/ra64nor.inc ++++ fpc/fpcsrc/compiler/aarch64/ra64nor.inc +@@ -1,2 +1,2 @@ + { don't edit, this file is generated from a64reg.dat } +-226 ++231 +Index: fpc/fpcsrc/compiler/aarch64/ra64num.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/ra64num.inc ++++ fpc/fpcsrc/compiler/aarch64/ra64num.inc +@@ -64,6 +64,8 @@ tregister($0104001E), + tregister($0105001E), + tregister($0104001F), + tregister($0105001F), ++tregister($01040020), ++tregister($01050020), + tregister($04010000), + tregister($04030000), + tregister($04090000), +@@ -224,4 +226,7 @@ tregister($0403001F), + tregister($0409001F), + tregister($040a001F), + tregister($0405001F), +-tregister($05000000) ++tregister($05000000), ++tregister($05000001), ++tregister($05000002), ++tregister($05000003) +Index: fpc/fpcsrc/compiler/aarch64/ra64rni.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/ra64rni.inc ++++ fpc/fpcsrc/compiler/aarch64/ra64rni.inc +@@ -32,6 +32,7 @@ + 59, + 61, + 63, ++65, + 2, + 4, + 6, +@@ -64,102 +65,7 @@ + 60, + 62, + 64, +-65, +-70, +-75, +-80, +-85, +-90, +-95, +-100, +-105, +-110, +-115, +-120, +-125, +-130, +-135, +-140, +-145, +-150, +-155, +-160, +-165, +-170, +-175, +-180, +-185, +-190, +-195, +-200, +-205, +-210, +-215, +-220, + 66, +-71, +-76, +-81, +-86, +-91, +-96, +-101, +-106, +-111, +-116, +-121, +-126, +-131, +-136, +-141, +-146, +-151, +-156, +-161, +-166, +-171, +-176, +-181, +-186, +-191, +-196, +-201, +-206, +-211, +-216, +-221, +-69, +-74, +-79, +-84, +-89, +-94, +-99, +-104, +-109, +-114, +-119, +-124, +-129, +-134, +-139, +-144, +-149, +-154, +-159, +-164, +-169, +-174, +-179, +-184, +-189, +-194, +-199, +-204, +-209, +-214, +-219, +-224, + 67, + 72, + 77, +@@ -224,4 +130,103 @@ + 213, + 218, + 223, +-225 ++71, ++76, ++81, ++86, ++91, ++96, ++101, ++106, ++111, ++116, ++121, ++126, ++131, ++136, ++141, ++146, ++151, ++156, ++161, ++166, ++171, ++176, ++181, ++186, ++191, ++196, ++201, ++206, ++211, ++216, ++221, ++226, ++69, ++74, ++79, ++84, ++89, ++94, ++99, ++104, ++109, ++114, ++119, ++124, ++129, ++134, ++139, ++144, ++149, ++154, ++159, ++164, ++169, ++174, ++179, ++184, ++189, ++194, ++199, ++204, ++209, ++214, ++219, ++224, ++70, ++75, ++80, ++85, ++90, ++95, ++100, ++105, ++110, ++115, ++120, ++125, ++130, ++135, ++140, ++145, ++150, ++155, ++160, ++165, ++170, ++175, ++180, ++185, ++190, ++195, ++200, ++205, ++210, ++215, ++220, ++225, ++227, ++228, ++229, ++230 +Index: fpc/fpcsrc/compiler/aarch64/ra64sri.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/ra64sri.inc ++++ fpc/fpcsrc/compiler/aarch64/ra64sri.inc +@@ -1,8 +1,39 @@ + { don't edit, this file is generated from a64reg.dat } + 0, +-65, ++67, ++72, ++117, ++122, ++127, ++132, ++137, ++142, ++147, ++152, ++157, ++162, ++77, ++167, ++172, ++177, ++182, ++187, ++192, ++197, ++202, ++207, ++212, ++82, ++217, ++222, ++87, ++92, ++97, ++102, ++107, ++112, + 70, +-115, ++75, + 120, + 125, + 130, +@@ -12,8 +43,8 @@ + 150, + 155, + 160, +-75, + 165, ++80, + 170, + 175, + 180, +@@ -23,15 +54,18 @@ + 200, + 205, + 210, +-80, + 215, +-220, + 85, ++220, ++225, + 90, + 95, + 100, + 105, + 110, ++115, ++228, ++229, + 68, + 73, + 118, +@@ -64,9 +98,9 @@ + 103, + 108, + 113, +-66, ++227, + 71, +-116, ++76, + 121, + 126, + 131, +@@ -76,8 +110,8 @@ + 151, + 156, + 161, +-76, + 166, ++81, + 171, + 176, + 181, +@@ -87,16 +121,16 @@ + 201, + 206, + 211, +-81, + 216, +-221, + 86, ++221, ++226, + 91, + 96, + 101, + 106, + 111, +-225, ++116, + 69, + 74, + 119, +@@ -129,38 +163,8 @@ + 104, + 109, + 114, +-67, +-72, +-117, +-122, +-127, +-132, +-137, +-142, +-147, +-152, +-157, +-162, +-77, +-167, +-172, +-177, +-182, +-187, +-192, +-197, +-202, +-207, +-212, +-82, +-217, +-222, +-87, +-92, +-97, +-102, +-107, +-112, ++66, ++230, + 1, + 3, + 21, +@@ -192,6 +196,7 @@ + 15, + 17, + 19, ++65, + 63, + 2, + 4, +Index: fpc/fpcsrc/compiler/aarch64/ra64sta.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/ra64sta.inc ++++ fpc/fpcsrc/compiler/aarch64/ra64sta.inc +@@ -64,164 +64,169 @@ + 30, + 31, + 31, ++31, ++31, ++64, ++64, ++64, ++64, ++64, ++65, ++65, ++65, ++65, ++65, ++66, ++66, ++66, ++66, ++66, ++67, ++67, ++67, ++67, ++67, ++68, ++68, ++68, ++68, ++68, ++69, ++69, ++69, ++69, ++69, ++70, ++70, ++70, ++70, ++70, ++71, ++71, ++71, ++71, ++71, ++72, ++72, ++72, ++72, ++72, ++73, ++73, ++73, ++73, ++73, ++74, ++74, ++74, ++74, ++74, ++75, ++75, ++75, ++75, ++75, ++76, ++76, ++76, ++76, ++76, ++77, ++77, ++77, ++77, ++77, ++78, ++78, ++78, ++78, ++78, ++79, ++79, ++79, ++79, ++79, ++80, ++80, ++80, ++80, ++80, ++81, ++81, ++81, ++81, ++81, ++82, ++82, ++82, ++82, ++82, ++83, ++83, ++83, ++83, ++83, ++84, ++84, ++84, ++84, ++84, ++85, ++85, ++85, ++85, ++85, ++86, ++86, ++86, ++86, ++86, ++87, ++87, ++87, ++87, ++87, ++88, ++88, ++88, ++88, ++88, ++89, ++89, ++89, ++89, ++89, ++90, ++90, ++90, ++90, ++90, ++91, ++91, ++91, ++91, ++91, ++92, ++92, ++92, ++92, ++92, ++93, ++93, ++93, ++93, ++93, ++94, ++94, ++94, ++94, ++94, ++95, ++95, ++95, ++95, ++95, + 0, + 0, + 0, +-0, +-0, +-1, +-1, +-1, +-1, +-1, +-2, +-2, +-2, +-2, +-2, +-3, +-3, +-3, +-3, +-3, +-4, +-4, +-4, +-4, +-4, +-5, +-5, +-5, +-5, +-5, +-6, +-6, +-6, +-6, +-6, +-7, +-7, +-7, +-7, +-7, +-8, +-8, +-8, +-8, +-8, +-9, +-9, +-9, +-9, +-9, +-10, +-10, +-10, +-10, +-10, +-11, +-11, +-11, +-11, +-11, +-12, +-12, +-12, +-12, +-12, +-13, +-13, +-13, +-13, +-13, +-14, +-14, +-14, +-14, +-14, +-15, +-15, +-15, +-15, +-15, +-16, +-16, +-16, +-16, +-16, +-17, +-17, +-17, +-17, +-17, +-18, +-18, +-18, +-18, +-18, +-19, +-19, +-19, +-19, +-19, +-20, +-20, +-20, +-20, +-20, +-21, +-21, +-21, +-21, +-21, +-22, +-22, +-22, +-22, +-22, +-23, +-23, +-23, +-23, +-23, +-24, +-24, +-24, +-24, +-24, +-25, +-25, +-25, +-25, +-25, +-26, +-26, +-26, +-26, +-26, +-27, +-27, +-27, +-27, +-27, +-28, +-28, +-28, +-28, +-28, +-29, +-29, +-29, +-29, +-29, +-30, +-30, +-30, +-30, +-30, +-31, +-31, +-31, +-31, +-31, + 0 +Index: fpc/fpcsrc/compiler/aarch64/ra64std.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/ra64std.inc ++++ fpc/fpcsrc/compiler/aarch64/ra64std.inc +@@ -64,6 +64,8 @@ + 'x30', + 'wzr', + 'xzr', ++'wsp', ++'sp', + 'b0', + 'h0', + 's0', +@@ -224,4 +226,7 @@ + 's31', + 'd31', + 'q31', +-'nzcv' ++'nzcv', ++'fpcr', ++'fpsr', ++'tpidr_el0' +Index: fpc/fpcsrc/compiler/aarch64/ra64sup.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/aarch64/ra64sup.inc ++++ fpc/fpcsrc/compiler/aarch64/ra64sup.inc +@@ -64,6 +64,8 @@ RS_W30 = $1E; + RS_X30 = $1E; + RS_WZR = $1F; + RS_XZR = $1F; ++RS_WSP = $20; ++RS_SP = $20; + RS_B0 = $00; + RS_H0 = $00; + RS_S0 = $00; +@@ -225,3 +227,6 @@ RS_S31 = $1F; + RS_D31 = $1F; + RS_Q31 = $1F; + RS_NZCV = $00; ++RS_FPCR = $01; ++RS_FPSR = $02; ++RS_TPIDR_EL0 = $03; +Index: fpc/fpcsrc/compiler/aarch64/racpu.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/racpu.pas +@@ -0,0 +1,88 @@ ++{ ++ Copyright (c) 1998-2003 by Carl Eric Codere and Peter Vreman ++ Copyright (c) 2014 by Jonas Maebe ++ ++ Handles the common AArch64 assembler reader routines ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ **************************************************************************** ++} ++unit racpu; ++ ++{$i fpcdefs.inc} ++ ++ interface ++ ++ uses ++ cgbase, ++ cpubase, ++ aasmtai,aasmdata, ++ rautils; ++ ++ type ++ TAArch64Operand=class(TOperand) ++ end; ++ ++ TAArch64Instruction=class(TInstruction) ++ oppostfix : toppostfix; ++ function ConcatInstruction(p:TAsmList) : tai;override; ++ function Is64bit: boolean; ++ function cgsize: tcgsize; ++ end; ++ ++ implementation ++ ++ uses ++ verbose, ++ aasmcpu; ++ ++ function TAArch64Instruction.ConcatInstruction(p:TAsmList) : tai; ++ begin ++ result:=inherited ConcatInstruction(p); ++ taicpu(result).oppostfix:=oppostfix; ++ end; ++ ++ ++ function TAArch64Instruction.Is64bit: boolean; ++ begin ++ result:= ++ (operands[1].opr.typ=OPR_REGISTER) and ++ (getsubreg(operands[1].opr.reg)=R_SUBQ); ++ end; ++ ++ function TAArch64Instruction.cgsize: tcgsize; ++ begin ++ if ops<1 then ++ internalerror(2014122001); ++ if operands[1].opr.typ<>OPR_REGISTER then ++ internalerror(2014122002); ++ result:=reg_cgsize(operands[1].opr.reg); ++ { a 32 bit integer register could actually be 16 or 8 bit } ++ if result=OS_32 then ++ case oppostfix of ++ PF_B: ++ result:=OS_8; ++ PF_SB: ++ result:=OS_S8; ++ PF_H: ++ result:=OS_16; ++ PF_SH: ++ result:=OS_S16; ++ end; ++ end; ++ ++ ++end. +Index: fpc/fpcsrc/compiler/aarch64/racpugas.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/racpugas.pas +@@ -0,0 +1,1053 @@ ++{ ++ Copyright (c) 1998-2002 by Carl Eric Codere and Peter Vreman ++ Copyright (c) 2014 by Jonas Maebe ++ ++ Does the parsing for the AArch64 GNU AS styled inline assembler. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ **************************************************************************** ++} ++Unit racpugas; ++ ++{$i fpcdefs.inc} ++ ++ Interface ++ ++ uses ++ raatt,racpu, ++ cpubase; ++ ++ type ++ taarch64attreader = class(tattreader) ++ actoppostfix : TOpPostfix; ++ function is_asmopcode(const s: string):boolean;override; ++ function is_register(const s:string):boolean;override; ++ procedure handleopcode;override; ++ procedure BuildReference(oper: taarch64operand; is64bit: boolean); ++ procedure BuildOperand(oper: taarch64operand; is64bit: boolean); ++ function TryBuildShifterOp(instr: taarch64instruction; opnr: longint) : boolean; ++ procedure BuildOpCode(instr: taarch64instruction); ++ procedure ReadSym(oper: taarch64operand; is64bit: boolean); ++ procedure ConvertCalljmp(instr: taarch64instruction); ++ function ToConditionCode(const hs: string; is_operand: boolean): tasmcond; ++ end; ++ ++ ++ Implementation ++ ++ uses ++ { helpers } ++ cutils, ++ { global } ++ globtype,verbose, ++ systems,aasmbase,aasmtai,aasmdata,aasmcpu, ++ { symtable } ++ symconst,symsym, ++ procinfo, ++ rabase,rautils, ++ cgbase,cgutils; ++ ++ ++ function taarch64attreader.is_register(const s:string):boolean; ++ type ++ treg2str = record ++ name : string[3]; ++ reg : tregister; ++ end; ++ ++ const ++ extraregs : array[0..3] of treg2str = ( ++ (name: 'FP' ; reg: NR_FP), ++ (name: 'LR' ; reg: NR_LR), ++ (name: 'IP0'; reg: NR_IP0), ++ (name: 'IP1'; reg: NR_IP1)); ++ ++ var ++ i : longint; ++ ++ begin ++ result:=inherited is_register(s); ++ { reg found? ++ possible aliases are always 2 or 3 chars ++ } ++ if result or not(length(s) in [2,3]) then ++ exit; ++ for i:=low(extraregs) to high(extraregs) do ++ begin ++ if s=extraregs[i].name then ++ begin ++ actasmregister:=extraregs[i].reg; ++ result:=true; ++ actasmtoken:=AS_REGISTER; ++ exit; ++ end; ++ end; ++ end; ++ ++ ++ procedure taarch64attreader.ReadSym(oper: taarch64operand; is64bit: boolean); ++ var ++ tempstr, mangledname : string; ++ typesize,l,k: aint; ++ begin ++ tempstr:=actasmpattern; ++ Consume(AS_ID); ++ { typecasting? } ++ if (actasmtoken=AS_LPAREN) and ++ SearchType(tempstr,typesize) then ++ begin ++ oper.hastype:=true; ++ Consume(AS_LPAREN); ++ BuildOperand(oper,is64bit); ++ Consume(AS_RPAREN); ++ if oper.opr.typ in [OPR_REFERENCE,OPR_LOCAL] then ++ oper.SetSize(typesize,true); ++ end ++ else ++ if not oper.SetupVar(tempstr,false) then ++ Message1(sym_e_unknown_id,tempstr); ++ { record.field ? } ++ if actasmtoken=AS_DOT then ++ begin ++ BuildRecordOffsetSize(tempstr,l,k,mangledname,false); ++ if (mangledname<>'') then ++ Message(asmr_e_invalid_reference_syntax); ++ inc(oper.opr.ref.offset,l); ++ end; ++ end; ++ ++ ++ Procedure taarch64attreader.BuildReference(oper: taarch64operand; is64bit: boolean); ++ ++ procedure do_error; ++ begin ++ Message(asmr_e_invalid_reference_syntax); ++ RecoverConsume(false); ++ end; ++ ++ ++ procedure test_end(require_rbracket : boolean); ++ begin ++ if require_rbracket then begin ++ if not(actasmtoken=AS_RBRACKET) then ++ begin ++ do_error; ++ exit; ++ end ++ else ++ Consume(AS_RBRACKET); ++ if (actasmtoken=AS_NOT) then ++ begin ++ oper.opr.ref.addressmode:=AM_PREINDEXED; ++ Consume(AS_NOT); ++ end; ++ end; ++ if not(actasmtoken in [AS_SEPARATOR,AS_end]) then ++ do_error ++ else ++ begin ++{$IFDEF debugasmreader} ++ writeln('TEST_end_FINAL_OK. Created the following ref:'); ++ writeln('oper.opr.ref.shiftimm=',oper.opr.ref.shiftimm); ++ writeln('oper.opr.ref.shiftmode=',ord(oper.opr.ref.shiftmode)); ++ writeln('oper.opr.ref.index=',ord(oper.opr.ref.index)); ++ writeln('oper.opr.ref.base=',ord(oper.opr.ref.base)); ++ writeln('oper.opr.ref.signindex=',ord(oper.opr.ref.signindex)); ++ writeln('oper.opr.ref.addressmode=',ord(oper.opr.ref.addressmode)); ++ writeln; ++{$endIF debugasmreader} ++ end; ++ end; ++ ++ ++ function is_shifter_ref_operation(var a : tshiftmode) : boolean; ++ begin ++ a:=SM_NONE; ++ if (actasmpattern='LSL') then ++ a:=SM_LSL ++ else if (actasmpattern='UXTW') then ++ a:=SM_UXTW ++ else if (actasmpattern='SXTW') then ++ a:=SM_SXTW ++ else if (actasmpattern='SXTX') then ++ a:=SM_SXTX; ++ is_shifter_ref_operation:=not(a=SM_NONE); ++ end; ++ ++ ++ procedure read_index_shift(require_rbracket : boolean); ++ var ++ shift: aint; ++ begin ++ case actasmtoken of ++ AS_COMMA : ++ begin ++ Consume(AS_COMMA); ++ if not(actasmtoken=AS_ID) then ++ do_error; ++ if is_shifter_ref_operation(oper.opr.ref.shiftmode) then ++ begin ++ Consume(actasmtoken); ++ if actasmtoken=AS_HASH then ++ begin ++ Consume(AS_HASH); ++ shift:=BuildConstExpression(false,true); ++ if not(shift in [0,2+ord(is64bit)]) then ++ do_error; ++ oper.opr.ref.shiftimm:=shift; ++ test_end(require_rbracket); ++ end; ++ end ++ else ++ begin ++ do_error; ++ exit; ++ end; ++ end; ++ AS_RBRACKET : ++ if require_rbracket then ++ test_end(require_rbracket) ++ else ++ begin ++ do_error; ++ exit; ++ end; ++ AS_SEPARATOR,AS_END : ++ if not require_rbracket then ++ test_end(false) ++ else ++ do_error; ++ else ++ begin ++ do_error; ++ exit; ++ end; ++ end; ++ end; ++ ++ ++ procedure read_index(require_rbracket : boolean); ++ var ++ recname : string; ++ o_int,s_int : aint; ++ begin ++ case actasmtoken of ++ AS_REGISTER : ++ begin ++ if getsupreg(actasmregister)=RS_XZR then ++ Message1(asmr_e_invalid_ref_register,actasmpattern); ++ oper.opr.ref.index:=actasmregister; ++ Consume(AS_REGISTER); ++ read_index_shift(require_rbracket); ++ exit; ++ end; ++ AS_HASH : // constant ++ begin ++ Consume(AS_HASH); ++(* ++ if actasmtoken=AS_COLON then ++ begin ++ consume(AS_COLON); ++ { GNU-style lower 12 bits of address of non-GOT-based ++ access } ++ if (actasmpattern='LO12') then ++ begin ++ consume(actasmtoken); ++ consume(AS_COLON); ++ if not oper.SetupVar(actasmpattern,false) then ++ begin ++ do_error; ++ exit ++ end; ++ consume(AS_ID); ++ oper.opr.ref.refaddr:=addr_??? (not gotpageoffset); ++ end ++ else ++ begin ++ do_error; ++ exit ++ end; ++ end ++ else ++*) ++ begin ++ o_int:=BuildConstExpression(false,true); ++ inc(oper.opr.ref.offset,o_int); ++ end; ++ test_end(require_rbracket); ++ exit; ++ end; ++ AS_ID : ++ begin ++ recname:=actasmpattern; ++ Consume(AS_ID); ++ { Apple-style got page offset } ++ if actasmtoken=AS_AT then ++ begin ++ if not oper.SetupVar(recname,false) then ++ begin ++ do_error; ++ exit ++ end; ++ consume(AS_AT); ++ if actasmpattern='GOTPAGEOFF' then ++ begin ++ consume(actasmtoken); ++ oper.opr.ref.refaddr:=addr_gotpageoffset; ++ end ++ else if actasmpattern='PAGEOFF' then ++ begin ++ consume(actasmtoken); ++ oper.opr.ref.refaddr:=addr_pageoffset; ++ end ++ else ++ begin ++ do_error; ++ exit ++ end; ++ end ++ else ++ begin ++ BuildRecordOffsetSize(recname,o_int,s_int,recname,false); ++ inc(oper.opr.ref.offset,o_int); ++ end; ++ test_end(require_rbracket); ++ exit; ++ end; ++ AS_AT: ++ begin ++ do_error; ++ exit; ++ end; ++ AS_RBRACKET : ++ begin ++ if require_rbracket then ++ begin ++ test_end(require_rbracket); ++ exit; ++ end ++ else ++ begin ++ do_error; // unexpected rbracket ++ exit; ++ end; ++ end; ++ AS_SEPARATOR,AS_end : ++ begin ++ if not require_rbracket then ++ begin ++ test_end(false); ++ exit; ++ end ++ else ++ begin ++ do_error; ++ exit; ++ end; ++ end; ++ else ++ begin ++ // unexpected token ++ do_error; ++ exit; ++ end; ++ end; // case ++ end; ++ ++ ++ procedure try_prepostindexed; ++ begin ++ Consume(AS_RBRACKET); ++ case actasmtoken of ++ AS_COMMA : ++ begin // post-indexed ++ Consume(AS_COMMA); ++ oper.opr.ref.addressmode:=AM_POSTINDEXED; ++ read_index(false); ++ exit; ++ end; ++ AS_NOT : ++ begin // pre-indexed ++ Consume(AS_NOT); ++ oper.opr.ref.addressmode:=AM_PREINDEXED; ++ test_end(false); ++ exit; ++ end; ++ else ++ begin ++ test_end(false); ++ exit; ++ end; ++ end; // case ++ end; ++ ++ begin ++ Consume(AS_LBRACKET); ++ oper.opr.ref.addressmode:=AM_OFFSET; // assume "neither PRE nor POST inc" ++ if actasmtoken=AS_REGISTER then ++ begin ++ if getsupreg(actasmregister)=RS_XZR then ++ Message1(asmr_e_invalid_ref_register,actasmpattern); ++ oper.opr.ref.base:=actasmregister; ++ Consume(AS_REGISTER); ++ case actasmtoken of ++ AS_RBRACKET : ++ begin ++ try_prepostindexed; ++ exit; ++ end; ++ AS_COMMA : ++ begin ++ Consume(AS_COMMA); ++ read_index(true); ++ exit; ++ end; ++ else ++ begin ++ Message(asmr_e_invalid_reference_syntax); ++ RecoverConsume(false); ++ end; ++ end; ++ end ++ else ++ Begin ++ case actasmtoken of ++ AS_ID : ++ begin ++ { TODO: local variables and parameters } ++ Message(asmr_e_invalid_reference_syntax); ++ RecoverConsume(false); ++ exit; ++ end; ++ else ++ begin // elsecase ++ Message(asmr_e_invalid_reference_syntax); ++ RecoverConsume(false); ++ exit; ++ end; ++ end; ++ end; ++ end; ++ ++ ++ function taarch64attreader.TryBuildShifterOp(instr: taarch64instruction; opnr: longint): boolean; ++ ++ procedure handlepara(sm : tshiftmode); ++ begin ++ consume(AS_ID); ++ fillchar(instr.operands[opnr].opr,sizeof(instr.operands[opnr].opr),0); ++ instr.operands[opnr].opr.typ:=OPR_SHIFTEROP; ++ instr.operands[opnr].opr.shifterop.shiftmode:=sm; ++ if (sm=SM_LSL) or ++ (actasmtoken=AS_HASH) then ++ begin ++ consume(AS_HASH); ++ instr.operands[opnr].opr.shifterop.shiftimm:=BuildConstExpression(false,false); ++ end; ++ end; ++ ++ const ++ shiftmode2str: array[SM_LSL..SM_SXTX] of string[4] = ++ ('LSL','LSR','ASR', ++ 'UXTB','UXTH','UXTW','UXTX', ++ 'SXTB','SXTH','SXTW','SXTX'); ++ var ++ sm: tshiftmode; ++ i: longint; ++ usessp, ++ useszr: boolean; ++ begin ++ result:=false; ++ if (actasmtoken=AS_ID) then ++ begin ++ for sm:=low(shiftmode2str) to high(shiftmode2str) do ++ if actasmpattern=shiftmode2str[sm] then ++ begin ++ handlepara(sm); ++ if instr.operands[1].opr.typ=OPR_REGISTER then ++ begin ++ { the possible shifter ops depend on whether this ++ instruction uses sp and/or zr } ++ usessp:=false; ++ useszr:=false; ++ for i:=low(instr.operands) to pred(opnr) do ++ begin ++ if (instr.operands[1].opr.typ=OPR_REGISTER) then ++ case getsupreg(instr.operands[1].opr.reg) of ++ RS_XZR: ++ useszr:=true; ++ RS_SP: ++ usessp:=true; ++ end; ++ end; ++ result:=valid_shifter_operand(instr.opcode,useszr,usessp,instr.Is64bit,sm,instr.operands[opnr].opr.shifterop.shiftimm); ++ end ++ end; ++ end; ++ end; ++ ++ ++ function taarch64attreader.ToConditionCode(const hs: string; is_operand: boolean): tasmcond; ++ begin ++ case actopcode of ++ A_CSEL,A_CSINC,A_CSINV,A_CSNEG,A_CSET,A_CSETM, ++ A_CINC,A_CINV,A_CNEG,A_CCMN,A_CCMP, ++ A_B: ++ begin ++ { search for condition, conditions are always 2 chars } ++ if (is_operand<>(actopcode=A_B)) and ++ (length(hs)>1) then ++ begin ++ { workaround for DFA bug } ++ result:=low(tasmcond); ++ for result:=low(tasmcond) to high(tasmcond) do ++ begin ++ if hs=uppercond2str[result] then ++ exit; ++ end; ++ end; ++ end; ++ end; ++ result:=C_None;; ++ end; ++ ++ ++ Procedure taarch64attreader.BuildOperand(oper: taarch64operand; is64bit: boolean); ++ var ++ expr: string; ++ typesize, l: aint; ++ ++ procedure MaybeAddGotAddrMode; ++ begin ++ if actasmtoken=AS_AT then ++ begin ++ consume(AS_AT); ++ if actasmpattern='GOTPAGE' then ++ oper.opr.ref.refaddr:=addr_gotpage ++ else if actasmpattern='GOTPAGEOFF' then ++ oper.opr.ref.refaddr:=addr_gotpageoffset ++ else if actasmpattern='PAGE' then ++ oper.opr.ref.refaddr:=addr_page ++ else if actasmpattern='PAGEOFF' then ++ oper.opr.ref.refaddr:=addr_pageoffset ++ else ++ Message(asmr_e_expr_illegal); ++ consume(actasmtoken); ++ end ++ else ++ oper.opr.ref.refaddr:=addr_pic; ++ end; ++ ++ procedure AddLabelOperand(hl:tasmlabel); ++ begin ++ if not(actasmtoken in [AS_PLUS,AS_MINUS,AS_LPAREN]) and ++ is_calljmp(actopcode) then ++ begin ++ oper.opr.typ:=OPR_SYMBOL; ++ oper.opr.symbol:=hl; ++ end ++ else if (actopcode=A_ADR) or ++ (actopcode=A_ADRP) then ++ begin ++ oper.InitRef; ++ MaybeAddGotAddrMode; ++ oper.opr.ref.symbol:=hl; ++ if (actasmtoken in [AS_PLUS, AS_MINUS]) then ++ begin ++ l:=BuildConstExpression(true,false); ++ oper.opr.ref.offset:=l; ++ end; ++ end; ++ end; ++ ++ ++ procedure MaybeRecordOffset; ++ var ++ mangledname: string; ++ hasdot : boolean; ++ l, ++ toffset, ++ tsize : aint; ++ begin ++ if not(actasmtoken in [AS_DOT,AS_PLUS,AS_MINUS]) then ++ exit; ++ l:=0; ++ hasdot:=(actasmtoken=AS_DOT); ++ if hasdot then ++ begin ++ if expr<>'' then ++ begin ++ BuildRecordOffsetSize(expr,toffset,tsize,mangledname,false); ++ if (oper.opr.typ<>OPR_CONSTANT) and ++ (mangledname<>'') then ++ Message(asmr_e_wrong_sym_type); ++ inc(l,toffset); ++ oper.SetSize(tsize,true); ++ end; ++ end; ++ if actasmtoken in [AS_PLUS,AS_MINUS] then ++ inc(l,BuildConstExpression(true,false)); ++ case oper.opr.typ of ++ OPR_LOCAL : ++ begin ++ { don't allow direct access to fields of parameters, because that ++ will generate buggy code. Allow it only for explicit typecasting } ++ if hasdot and ++ (not oper.hastype) and ++ (tabstractnormalvarsym(oper.opr.localsym).owner.symtabletype=parasymtable) and ++ (current_procinfo.procdef.proccalloption<>pocall_register) then ++ Message(asmr_e_cannot_access_field_directly_for_parameters); ++ inc(oper.opr.localsymofs,l) ++ end; ++ OPR_CONSTANT : ++ inc(oper.opr.val,l); ++ OPR_REFERENCE : ++ if (mangledname<>'') then ++ begin ++ if (oper.opr.val<>0) then ++ Message(asmr_e_wrong_sym_type); ++ oper.opr.typ:=OPR_SYMBOL; ++ oper.opr.symbol:=current_asmdata.RefAsmSymbol(mangledname); ++ end ++ else ++ inc(oper.opr.val,l); ++ OPR_SYMBOL: ++ Message(asmr_e_invalid_symbol_ref); ++ else ++ internalerror(200309221); ++ end; ++ end; ++ ++ ++ function MaybeBuildReference(is64bit: boolean):boolean; ++ { Try to create a reference, if not a reference is found then false ++ is returned } ++ begin ++ MaybeBuildReference:=true; ++ case actasmtoken of ++ AS_INTNUM, ++ AS_MINUS, ++ AS_PLUS: ++ Begin ++ oper.opr.ref.offset:=BuildConstExpression(True,False); ++ if actasmtoken<>AS_LPAREN then ++ Message(asmr_e_invalid_reference_syntax) ++ else ++ BuildReference(oper,is64bit); ++ end; ++ AS_LPAREN: ++ BuildReference(oper,is64bit); ++ AS_ID: { only a variable is allowed ... } ++ Begin ++ ReadSym(oper,is64bit); ++ case actasmtoken of ++ AS_end, ++ AS_SEPARATOR, ++ AS_COMMA: ; ++ AS_LPAREN: ++ BuildReference(oper,is64bit); ++ else ++ Begin ++ Message(asmr_e_invalid_reference_syntax); ++ Consume(actasmtoken); ++ end; ++ end; {end case } ++ end; ++ else ++ MaybeBuildReference:=false; ++ end; { end case } ++ end; ++ ++ ++ var ++ tempreg: tregister; ++ hl: tasmlabel; ++ icond: tasmcond; ++ Begin ++ expr:=''; ++ case actasmtoken of ++ AS_LBRACKET: { Memory reference or constant expression } ++ Begin ++ oper.InitRef; ++ BuildReference(oper,is64bit); ++ end; ++ ++ AS_HASH: { Constant expression } ++ Begin ++ Consume(AS_HASH); ++ BuildConstantOperand(oper); ++ end; ++ ++ (* ++ AS_INTNUM, ++ AS_MINUS, ++ AS_PLUS: ++ Begin ++ { Constant memory offset } ++ { This must absolutely be followed by ( } ++ oper.InitRef; ++ oper.opr.ref.offset:=BuildConstExpression(True,False); ++ if actasmtoken<>AS_LPAREN then ++ begin ++ ofs:=oper.opr.ref.offset; ++ BuildConstantOperand(oper); ++ inc(oper.opr.val,ofs); ++ end ++ else ++ BuildReference(oper,is64bit); ++ end; ++ *) ++ AS_ID: { A constant expression, or a Variable ref. } ++ Begin ++ { Condition code? } ++ icond:=ToConditionCode(actasmpattern,true); ++ if icond<>C_None then ++ begin ++ oper.opr.typ:=OPR_COND; ++ oper.opr.cc:=icond; ++ consume(AS_ID); ++ end ++ else ++ { Local Label ? } ++ if is_locallabel(actasmpattern) then ++ begin ++ CreateLocalLabel(actasmpattern,hl,false); ++ Consume(AS_ID); ++ AddLabelOperand(hl); ++ end ++ else ++ { Check for label } ++ if SearchLabel(actasmpattern,hl,false) then ++ begin ++ Consume(AS_ID); ++ AddLabelOperand(hl); ++ end ++ else ++ { probably a variable or normal expression } ++ { or a procedure (such as in CALL ID) } ++ begin ++ { is it a constant ? } ++ if SearchIConstant(actasmpattern,l) then ++ begin ++ if not (oper.opr.typ in [OPR_NONE,OPR_CONSTANT]) then ++ Message(asmr_e_invalid_operand_type); ++ BuildConstantOperand(oper); ++ end ++ else ++ begin ++ expr:=actasmpattern; ++ Consume(AS_ID); ++ { typecasting? } ++ if (actasmtoken=AS_LPAREN) and ++ SearchType(expr,typesize) then ++ begin ++ oper.hastype:=true; ++ Consume(AS_LPAREN); ++ BuildOperand(oper,is64bit); ++ Consume(AS_RPAREN); ++ if oper.opr.typ in [OPR_REFERENCE,OPR_LOCAL] then ++ oper.SetSize(typesize,true); ++ end ++ else ++ begin ++ if not(oper.SetupVar(expr,false)) then ++ Begin ++ { look for special symbols ... } ++ if expr= '__HIGH' then ++ begin ++ consume(AS_LPAREN); ++ if not oper.setupvar('high'+actasmpattern,false) then ++ Message1(sym_e_unknown_id,'high'+actasmpattern); ++ consume(AS_ID); ++ consume(AS_RPAREN); ++ end ++ else ++ if expr = '__RESULT' then ++ oper.SetUpResult ++ else ++ if expr = '__SELF' then ++ oper.SetupSelf ++ else ++ if expr = '__OLDEBP' then ++ oper.SetupOldEBP ++ else ++ Message1(sym_e_unknown_id,expr); ++ end ++ else ++ MaybeAddGotAddrMode; ++ end; ++ end; ++ if actasmtoken=AS_DOT then ++ MaybeRecordOffset; ++ { add a constant expression? } ++ if (actasmtoken=AS_PLUS) then ++ begin ++ l:=BuildConstExpression(true,false); ++ case oper.opr.typ of ++ OPR_CONSTANT : ++ inc(oper.opr.val,l); ++ OPR_LOCAL : ++ inc(oper.opr.localsymofs,l); ++ OPR_REFERENCE : ++ inc(oper.opr.ref.offset,l); ++ else ++ internalerror(200309202); ++ end; ++ end ++ end; ++ { Do we have a indexing reference, then parse it also } ++ if actasmtoken=AS_LPAREN then ++ BuildReference(oper,is64bit); ++ end; ++ ++ { Register, a variable reference or a constant reference } ++ AS_REGISTER: ++ Begin ++ { save the type of register used. } ++ tempreg:=actasmregister; ++ Consume(AS_REGISTER); ++ if (actasmtoken in [AS_end,AS_SEPARATOR,AS_COMMA]) then ++ Begin ++ if not (oper.opr.typ in [OPR_NONE,OPR_REGISTER]) then ++ Message(asmr_e_invalid_operand_type); ++ oper.opr.typ:=OPR_REGISTER; ++ oper.opr.reg:=tempreg; ++ end ++ else ++ Message(asmr_e_syn_operand); ++ end; ++ ++ AS_end, ++ AS_SEPARATOR, ++ AS_COMMA: ; ++ else ++ Begin ++ Message(asmr_e_syn_operand); ++ Consume(actasmtoken); ++ end; ++ end; { end case } ++ end; ++ ++{***************************************************************************** ++ taarch64attreader ++*****************************************************************************} ++ ++ procedure taarch64attreader.BuildOpCode(instr: taarch64instruction); ++ var ++ operandnum : longint; ++ Begin ++ { opcode } ++ if (actasmtoken<>AS_OPCODE) then ++ Begin ++ Message(asmr_e_invalid_or_missing_opcode); ++ RecoverConsume(true); ++ exit; ++ end; ++ { Fill the instr object with the current state } ++ with instr do ++ begin ++ Opcode:=ActOpcode; ++ condition:=ActCondition; ++ oppostfix:=actoppostfix; ++ end; ++ Consume(AS_OPCODE); ++ ++ { We are reading operands, so opcode will be an AS_ID } ++ operandnum:=1; ++ { Zero operand opcode ? } ++ if actasmtoken in [AS_SEPARATOR,AS_end] then ++ begin ++ instr.Ops:=0; ++ exit; ++ end; ++ { Read the operands } ++ repeat ++ case actasmtoken of ++ AS_COMMA: { Operand delimiter } ++ Begin ++ { operandnum and not operandnum+1, because tinstruction is ++ one-based and taicpu is zero-based) ++ } ++ if can_be_shifter_operand(instr.opcode,operandnum) then ++ begin ++ Consume(AS_COMMA); ++ if not TryBuildShifterOp(instr,operandnum+1) then ++ Message(asmr_e_illegal_shifterop_syntax); ++ Inc(operandnum); ++ end ++ else ++ begin ++ if operandnum>Max_Operands then ++ Message(asmr_e_too_many_operands) ++ else ++ Inc(operandnum); ++ Consume(AS_COMMA); ++ end; ++ end; ++ AS_SEPARATOR, ++ AS_end : { End of asm operands for this opcode } ++ begin ++ break; ++ end; ++ else ++ begin ++ BuildOperand(taarch64operand(instr.operands[operandnum]),instr.Is64bit); ++ instr.Ops:=operandnum; ++ if instr.operands[operandnum].opr.typ=OPR_REFERENCE then ++ if simple_ref_type(instr.opcode,instr.cgsize,instr.oppostfix,instr.operands[operandnum].opr.ref)<>sr_simple then ++ Message(asmr_e_invalid_reference_syntax); ++ ; ++ end; ++ end; { end case } ++ until false; ++ end; ++ ++ ++ function taarch64attreader.is_asmopcode(const s: string):boolean; ++ ++ const ++ { sorted by length so longer postfixes will match first } ++ postfix2strsorted : array[1..7] of string[3] = ( ++ 'SB','SH','SW', ++ 'B','H','W', ++ 'S'); ++ ++ postfixsorted : array[1..7] of TOpPostfix = ( ++ PF_SB,PF_SH,PF_SW, ++ PF_B,PF_H,PF_W, ++ PF_S); ++ ++ var ++ j : longint; ++ hs : string; ++ maxlen : longint; ++ icond : tasmcond; ++ Begin ++ { making s a value parameter would break other assembler readers } ++ hs:=s; ++ is_asmopcode:=false; ++ ++ { clear opcode } ++ actopcode:=A_None; ++ actcondition:=C_None; ++ ++ { b.cond ? } ++ if (length(hs)=4) and ++ (hs[1]='B') and ++ (hs[2]='.') then ++ begin ++ actopcode:=A_B; ++ actasmtoken:=AS_OPCODE; ++ actcondition:=ToConditionCode(copy(hs,3,length(actasmpattern)-2),false); ++ if actcondition<>C_None then ++ is_asmopcode:=true; ++ exit; ++ end; ++ ++ maxlen:=max(length(hs),7); ++ actopcode:=A_NONE; ++ for j:=maxlen downto 1 do ++ begin ++ actopcode:=tasmop(PtrUInt(iasmops.Find(copy(hs,1,j)))); ++ if actopcode<>A_NONE then ++ begin ++ actasmtoken:=AS_OPCODE; ++ { strip op code } ++ delete(hs,1,j); ++ break; ++ end; ++ end; ++ if actopcode=A_NONE then ++ exit; ++ ++ { check for postfix } ++ if length(hs)>0 then ++ begin ++ for j:=low(postfixsorted) to high(postfixsorted) do ++ begin ++ if copy(hs,1,length(postfix2strsorted[j]))=postfix2strsorted[j] then ++ begin ++ actoppostfix:=postfixsorted[j]; ++ { strip postfix } ++ delete(hs,1,length(postfix2strsorted[j])); ++ break; ++ end; ++ end; ++ end; ++ { if we stripped all postfixes, it's a valid opcode } ++ is_asmopcode:=length(hs)=0; ++ end; ++ ++ ++ procedure taarch64attreader.ConvertCalljmp(instr: taarch64instruction); ++ var ++ newopr : toprrec; ++ begin ++ if instr.Operands[1].opr.typ=OPR_REFERENCE then ++ begin ++ newopr.typ:=OPR_SYMBOL; ++ newopr.symbol:=instr.Operands[1].opr.ref.symbol; ++ newopr.symofs:=instr.Operands[1].opr.ref.offset; ++ if (instr.Operands[1].opr.ref.base<>NR_NO) or ++ (instr.Operands[1].opr.ref.index<>NR_NO) or ++ (instr.Operands[1].opr.ref.refaddr<>addr_pic) then ++ Message(asmr_e_syn_operand); ++ instr.Operands[1].opr:=newopr; ++ end; ++ end; ++ ++ procedure taarch64attreader.handleopcode; ++ var ++ instr: taarch64instruction; ++ begin ++ instr:=taarch64instruction.Create(taarch64operand); ++ BuildOpcode(instr); ++ if is_calljmp(instr.opcode) then ++ ConvertCalljmp(instr); ++ { ++ instr.AddReferenceSizes; ++ instr.SetInstructionOpsize; ++ instr.CheckOperandSizes; ++ } ++ instr.ConcatInstruction(curlist); ++ instr.Free; ++ actoppostfix:=PF_None; ++ end; ++ ++ ++{***************************************************************************** ++ Initialize ++*****************************************************************************} ++ ++const ++ asmmode_arm_att_info : tasmmodeinfo = ++ ( ++ id : asmmode_arm_gas; ++ idtxt : 'GAS'; ++ casmreader : taarch64attreader; ++ ); ++ ++ asmmode_arm_standard_info : tasmmodeinfo = ++ ( ++ id : asmmode_standard; ++ idtxt : 'STANDARD'; ++ casmreader : taarch64attreader; ++ ); ++ ++initialization ++ RegisterAsmMode(asmmode_arm_att_info); ++ RegisterAsmMode(asmmode_arm_standard_info); ++end. +Index: fpc/fpcsrc/compiler/aarch64/rgcpu.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/compiler/aarch64/rgcpu.pas +@@ -0,0 +1,171 @@ ++{ ++ Copyright (c) 1998-2002 by Florian Klaempfl ++ ++ This unit implements the SPARC specific class for the register ++ allocator ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ ****************************************************************************} ++unit rgcpu; ++ ++{$i fpcdefs.inc} ++ ++ interface ++ ++ uses ++ aasmbase,aasmcpu,aasmtai,aasmdata, ++ cgbase,cgutils, ++ cpubase, ++ globtype, ++ rgobj; ++ ++ type ++ trgcpu=class(trgobj) ++ procedure do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);override; ++ procedure do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);override; ++ protected ++ procedure do_spill_op(list: tasmlist; op: tasmop; pos: tai; const spilltemp: treference; tempreg: tregister); ++ end; ++ ++ trgintcpu=class(trgcpu) ++ procedure add_cpu_interferences(p: tai); override; ++ end; ++ ++ ++implementation ++ ++ uses ++ verbose,cutils, ++ cgobj; ++ ++ procedure trgcpu.do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister); ++ begin ++ do_spill_op(list,A_LDR,pos,spilltemp,tempreg); ++ end; ++ ++ ++ procedure trgcpu.do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister); ++ begin ++ do_spill_op(list,A_STR,pos,spilltemp,tempreg); ++ end; ++ ++ ++ procedure trgcpu.do_spill_op(list: tasmlist; op: tasmop; pos: tai; const spilltemp: treference; tempreg: tregister); ++ var ++ helpins : tai; ++ tmpref : treference; ++ helplist : TAsmList; ++ hreg : tregister; ++ isload : boolean; ++ begin ++ isload:=op=A_LDR; ++ { offset out of range for regular load/store? } ++ if simple_ref_type(op,reg_cgsize(tempreg),PF_None,spilltemp)<>sr_simple then ++ begin ++ helplist:=TAsmList.create; ++ ++ if getregtype(tempreg)=R_INTREGISTER then ++ hreg:=tempreg ++ else ++ hreg:=cg.getaddressregister(helplist); ++ ++ cg.a_load_const_reg(helplist,OS_ADDR,spilltemp.offset,hreg); ++ reference_reset_base(tmpref,spilltemp.base,0,sizeof(pint)); ++ tmpref.index:=hreg; ++ if isload then ++ helpins:=spilling_create_load(tmpref,tempreg) ++ else ++ helpins:=spilling_create_store(tempreg,tmpref); ++ helplist.concat(helpins); ++ add_cpu_interferences(helpins); ++ list.insertlistafter(pos,helplist); ++ helplist.free; ++ end ++ else if isload then ++ inherited do_spill_read(list,pos,spilltemp,tempreg) ++ else ++ inherited do_spill_written(list,pos,spilltemp,tempreg) ++ end; ++ ++ ++ procedure trgintcpu.add_cpu_interferences(p: tai); ++ var ++ i, j: longint; ++ begin ++ if p.typ=ait_instruction then ++ begin ++ { add interferences for instructions that can have SP as a register ++ operand } ++ case taicpu(p).opcode of ++ A_MOV: ++ { all operands can be SP } ++ exit; ++ A_ADD, ++ A_SUB, ++ A_CMP, ++ A_CMN: ++ { ok as destination or first source in immediate or extended ++ register form } ++ if (taicpu(p).oper[taicpu(p).ops-1]^.typ<>top_shifterop) or ++ valid_shifter_operand(taicpu(p).opcode,false,true, ++ reg_cgsize(taicpu(p).oper[0]^.reg) in [OS_64,OS_S64], ++ taicpu(p).oper[taicpu(p).ops-1]^.shifterop^.shiftmode, ++ taicpu(p).oper[taicpu(p).ops-1]^.shifterop^.shiftimm) then ++ begin ++ if taicpu(p).oper[taicpu(p).ops-1]^.typ=top_shifterop then ++ i:=taicpu(p).ops-2 ++ else ++ i:=taicpu(p).ops-1; ++ if (taicpu(p).oper[i]^.typ=top_reg) then ++ add_edge(getsupreg(taicpu(p).oper[i]^.reg),RS_SP); ++ exit; ++ end; ++ A_AND, ++ A_EOR, ++ A_ORR, ++ A_TST: ++ { ok in immediate form } ++ if taicpu(p).oper[taicpu(p).ops-1]^.typ=top_const then ++ exit; ++ end; ++ { add interferences for other registers } ++ for i:=0 to taicpu(p).ops-1 do ++ begin ++ case taicpu(p).oper[i]^.typ of ++ top_reg: ++ if getregtype(taicpu(p).oper[i]^.reg)=R_INTREGISTER then ++ add_edge(getsupreg(taicpu(p).oper[i]^.reg),RS_SP); ++ top_ref: ++ begin ++ { sp can always be base, never be index } ++ if taicpu(p).oper[i]^.ref^.index<>NR_NO then ++ add_edge(getsupreg(taicpu(p).oper[i]^.ref^.index),RS_SP); ++ { in case of write back, the base register must be ++ different from the loaded/stored register } ++ if (taicpu(p).oper[i]^.ref^.addressmode in [AM_PREINDEXED,AM_POSTINDEXED]) and ++ (taicpu(p).oper[i]^.ref^.base<>NR_NO) then ++ begin ++ for j:=pred(i) downto 0 do ++ if taicpu(p).oper[j]^.typ=TOP_REG then ++ add_edge(getsupreg(taicpu(p).oper[j]^.reg),getsupreg(taicpu(p).oper[i]^.ref^.base)); ++ end; ++ end; ++ end; ++ end; ++ end; ++ end; ++ ++end. +Index: fpc/fpcsrc/compiler/aasmtai.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/aasmtai.pas ++++ fpc/fpcsrc/compiler/aasmtai.pas +@@ -80,7 +80,6 @@ interface + ait_labeled_instruction, + {$endif m68k} + {$ifdef arm} +- ait_thumb_func, + ait_thumb_set, + {$endif arm} + ait_set, +@@ -198,7 +197,6 @@ interface + 'labeled_instr', + {$endif m68k} + {$ifdef arm} +- 'thumb_func', + 'thumb_set', + {$endif arm} + 'set', +@@ -221,11 +219,11 @@ interface + {$ifdef arm} + { ARM only } + ,top_regset +- ,top_conditioncode + ,top_modeflags + ,top_specialreg + {$endif arm} + {$if defined(arm) or defined(aarch64)} ++ ,top_conditioncode + ,top_shifterop + {$endif defined(arm) or defined(aarch64)} + {$ifdef m68k} +@@ -268,12 +266,12 @@ interface + top_local : (localoper:plocaloper); + {$ifdef arm} + top_regset : (regset:^tcpuregisterset; regtyp: tregistertype; subreg: tsubregister; usermode: boolean); +- top_conditioncode : (cc : TAsmCond); + top_modeflags : (modeflags : tcpumodeflags); + top_specialreg : (specialreg:tregister; specialflags:tspecialregflags); + {$endif arm} + {$if defined(arm) or defined(aarch64)} + top_shifterop : (shifterop : pshifterop); ++ top_conditioncode : (cc : TAsmCond); + {$endif defined(arm) or defined(aarch64)} + {$ifdef m68k} + top_regset : (dataregset,addrregset:^tcpuregisterset); +@@ -310,7 +308,6 @@ interface + ait_cutobject,ait_marker,ait_varloc,ait_align,ait_section,ait_comment, + ait_const,ait_directive, + {$ifdef arm} +- ait_thumb_func, + ait_thumb_set, + {$endif arm} + ait_set,ait_weak, +@@ -356,7 +353,11 @@ interface + { for Jasmin } + asd_jclass,asd_jinterface,asd_jsuper,asd_jfield,asd_jlimit,asd_jline, + { .ent/.end for MIPS and Alpha } +- asd_ent,asd_ent_end ++ asd_ent,asd_ent_end, ++ { supported by recent clang-based assemblers for data-in-code } ++ asd_data_region, asd_end_data_region, ++ { .thumb_func for ARM } ++ asd_thumb_func + ); + + TAsmSehDirective=( +@@ -385,7 +386,11 @@ interface + { for Jasmin } + 'class','interface','super','field','limit','line', + { .ent/.end for MIPS and Alpha } +- 'ent','end' ++ 'ent','end', ++ { supported by recent clang-based assemblers for data-in-code } ++ 'data_region','end_data_region', ++ { .thumb_func for ARM } ++ 'thumb_func' + ); + sehdirectivestr : array[TAsmSehDirective] of string[16]=( + '.seh_proc','.seh_endproc', +@@ -2552,6 +2557,9 @@ implementation + {$ifdef ARM} + and not(r.base=NR_R15) + {$endif ARM} ++{$ifdef aarch64} ++ and not(r.refaddr in [addr_full,addr_gotpageoffset,addr_gotpage]) ++{$endif aarch64} + then + internalerror(200502052); + typ:=top_ref; +Index: fpc/fpcsrc/compiler/aggas.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/aggas.pas ++++ fpc/fpcsrc/compiler/aggas.pas +@@ -532,6 +532,8 @@ implementation + system_powerpc64_darwin, + system_x86_64_darwin, + system_arm_darwin, ++ system_aarch64_darwin, ++ system_x86_64_iphonesim, + system_powerpc_aix, + system_powerpc64_aix: + begin +@@ -567,7 +569,8 @@ implementation + AsmWriteln('__TEXT,__picsymbolstub4,symbol_stubs,none,16') + else + AsmWriteln('__TEXT,__symbol_stub4,symbol_stubs,none,12') +- { darwin/x86-64 uses RIP-based GOT addressing, no symbol stubs } ++ { darwin/(x86-64/AArch64) uses PC-based GOT addressing, no ++ explicit symbol stubs } + else + internalerror(2006031101); + end; +@@ -1352,10 +1355,6 @@ implementation + AsmWriteLn(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value)); + end; + {$ifdef arm} +- ait_thumb_func: +- begin +- AsmWriteLn(#9'.thumb_func'); +- end; + ait_thumb_set: + begin + AsmWriteLn(#9'.thumb_set '+tai_thumb_set(hp).sym^+', '+tai_thumb_set(hp).value^); +Index: fpc/fpcsrc/compiler/aoptobj.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/aoptobj.pas ++++ fpc/fpcsrc/compiler/aoptobj.pas +@@ -361,7 +361,7 @@ Unit AoptObj; + + function JumpTargetOp(ai: taicpu): poper; inline; + begin +-{$ifdef MIPS} ++{$if defined(MIPS)} + { MIPS branches can have 1,2 or 3 operands, target label is the last one. } + result:=ai.oper[ai.ops-1]; + {$else MIPS} +@@ -1179,9 +1179,9 @@ Unit AoptObj; + function IsJumpToLabel(hp: taicpu): boolean; + begin + result:=(hp.opcode=aopt_uncondjmp) and +-{$ifdef arm} ++{$if defined(arm) or defined(aarch64)} + (hp.condition=c_None) and +-{$endif arm} ++{$endif arm or aarch64} + (JumpTargetOp(hp)^.typ = top_ref) and + (JumpTargetOp(hp)^.ref^.symbol is TAsmLabel); + end; +@@ -1260,6 +1260,14 @@ Unit AoptObj; + exit; + if not GetFinalDestination(taicpu(p1),succ(level)) then + exit; ++{$if defined(aarch64)} ++ { can't have conditional branches to ++ global labels on AArch64, because the ++ offset may become too big } ++ if not(taicpu(hp).condition in [C_None,C_AL,C_NV]) and ++ (tasmlabel(JumpTargetOp(taicpu(p1))^.ref^.symbol).bind<>AB_LOCAL) then ++ exit; ++{$endif aarch64} + tasmlabel(JumpTargetOp(hp)^.ref^.symbol).decrefs; + JumpTargetOp(hp)^.ref^.symbol:=JumpTargetOp(taicpu(p1))^.ref^.symbol; + tasmlabel(JumpTargetOp(hp)^.ref^.symbol).increfs; +@@ -1398,9 +1406,15 @@ Unit AoptObj; + FindLabel(tasmlabel(JumpTargetOp(taicpu(p))^.ref^.symbol), hp2) then + begin + if (taicpu(p).opcode=aopt_condjmp) +- {$ifdef arm} ++ {$if defined(arm) or defined(aarch64)} + and (taicpu(p).condition<>C_None) +- {$endif arm} ++ {$endif arm or aarch64} ++ {$if defined(aarch64)} ++ { can't have conditional branches to ++ global labels on AArch64, because the ++ offset may become too big } ++ and (tasmlabel(JumpTargetOp(taicpu(hp1))^.ref^.symbol).bind=AB_LOCAL) ++ {$endif aarch64} + then + begin + taicpu(p).condition:=inverse_cond(taicpu(p).condition); +Index: fpc/fpcsrc/compiler/arm/aasmcpu.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/aasmcpu.pas ++++ fpc/fpcsrc/compiler/arm/aasmcpu.pas +@@ -30,7 +30,8 @@ uses + aasmbase,aasmtai,aasmdata,aasmsym, + ogbase, + symtype, +- cpubase,cpuinfo,cgbase,cgutils; ++ cpubase,cpuinfo,cgbase,cgutils, ++ sysutils; + + const + { "mov reg,reg" source operand number } +@@ -54,7 +55,8 @@ uses + $00000200; + + OT_SIZE_MASK = $000003FF; { all the size attributes } +- OT_NON_SIZE = longint(not OT_SIZE_MASK); ++ OT_NON_SIZE = $0FFFF800; ++ OT_OPT_SIZE = $F0000000; + + OT_SIGNED = $00000100; { the operand need to be signed -128-127 } + +@@ -73,6 +75,7 @@ uses + OT_IMM80 = $00002010; + OT_IMMTINY = $00002100; + OT_IMMSHIFTER= $00002200; ++ OT_IMMEDIATEZERO = $10002200; + OT_IMMEDIATE24 = OT_IMM24; + OT_SHIFTIMM = OT_SHIFTEROP or OT_IMMSHIFTER; + OT_SHIFTIMMEDIATE = OT_SHIFTIMM; +@@ -85,9 +88,12 @@ uses + OT_REG8 = $00201001; + OT_REG16 = $00201002; + OT_REG32 = $00201004; ++ OT_REGLO = $10201004; { lower reg (r0-r7) } ++ OT_REGSP = $20201004; + OT_REG64 = $00201008; + OT_VREG = $00201010; { vector register } + OT_REGF = $00201020; { coproc register } ++ OT_REGS = $00201040; { special register with mask } + OT_MEMORY = $00204000; { register number in 'basereg' } + OT_MEM8 = $00204001; + OT_MEM16 = $00204002; +@@ -96,20 +102,24 @@ uses + OT_MEM80 = $00204010; + { word/byte load/store } + OT_AM2 = $00010000; +- { misc ld/st operations } ++ { misc ld/st operations, thumb reg indexed } + OT_AM3 = $00020000; +- { multiple ld/st operations } ++ { multiple ld/st operations or thumb imm indexed } + OT_AM4 = $00040000; +- { co proc. ld/st operations } ++ { co proc. ld/st operations or thumb sp+imm indexed } + OT_AM5 = $00080000; +- OT_AMMASK = $000f0000; ++ { exclusive ld/st operations or thumb pc+imm indexed } ++ OT_AM6 = $00100000; ++ OT_AMMASK = $001f0000; + { IT instruction } +- OT_CONDITION = $00100000; ++ OT_CONDITION = $00200000; ++ OT_MODEFLAGS = $00400000; + + OT_MEMORYAM2 = OT_MEMORY or OT_AM2; + OT_MEMORYAM3 = OT_MEMORY or OT_AM3; + OT_MEMORYAM4 = OT_MEMORY or OT_AM4; + OT_MEMORYAM5 = OT_MEMORY or OT_AM5; ++ OT_MEMORYAM6 = OT_MEMORY or OT_AM6; + + OT_FPUREG = $01000000; { floating point stack registers } + OT_REG_SMASK = $00070000; { special register operands: these may be treated differently } +@@ -128,9 +138,34 @@ uses + IF_NONE = $00000000; + + IF_ARMMASK = $000F0000; +- IF_ARM7 = $00070000; +- IF_FPMASK = $00F00000; +- IF_FPA = $00100000; ++ IF_ARM32 = $00010000; ++ IF_THUMB = $00020000; ++ IF_THUMB32 = $00040000; ++ IF_WIDE = $00080000; ++ ++ IF_ARMvMASK = $0FF00000; ++ IF_ARMv4 = $00100000; ++ IF_ARMv4T = $00200000; ++ IF_ARMv5 = $00300000; ++ IF_ARMv5T = $00400000; ++ IF_ARMv5TE = $00500000; ++ IF_ARMv5TEJ = $00600000; ++ IF_ARMv6 = $00700000; ++ IF_ARMv6K = $00800000; ++ IF_ARMv6T2 = $00900000; ++ IF_ARMv6Z = $00A00000; ++ IF_ARMv6M = $00B00000; ++ IF_ARMv7 = $00C00000; ++ IF_ARMv7A = $00D00000; ++ IF_ARMv7R = $00E00000; ++ IF_ARMv7M = $00F00000; ++ IF_ARMv7EM = $01000000; ++ ++ IF_FPMASK = $F0000000; ++ IF_FPA = $10000000; ++ IF_VFPv2 = $20000000; ++ IF_VFPv3 = $40000000; ++ IF_VFPv4 = $80000000; + + { if the instruction can change in a second pass } + IF_PASS2 = longint($80000000); +@@ -142,9 +177,9 @@ uses + tinsentry = record + opcode : tasmop; + ops : byte; +- optypes : array[0..3] of longint; ++ optypes : array[0..5] of longint; + code : array[0..maxinfolen] of char; +- flags : longint; ++ flags : longword; + end; + + pinsentry=^tinsentry; +@@ -228,11 +263,18 @@ uses + procedure ppubuildderefimploper(var o:toper);override; + procedure ppuderefoper(var o:toper);override; + private ++ { pass1 info } ++ inIT, ++ lastinIT: boolean; ++ { arm version info } ++ fArmVMask, ++ fArmMask : longint; + { next fields are filled in pass1, so pass2 is faster } + inssize : shortint; + insoffset : longint; + LastInsOffset : longint; { need to be public to be reset } + insentry : PInsEntry; ++ procedure BuildArmMasks; + function InsEnd:longint; + procedure create_ot(objdata:TObjData); + function Matches(p:PInsEntry):longint; +@@ -247,10 +289,6 @@ uses + { nothing to add } + end; + +- tai_thumb_func = class(tai) +- constructor create; +- end; +- + function spilling_create_load(const ref:treference;r:tregister):Taicpu; + function spilling_create_store(r:tregister; const ref:treference):Taicpu; + +@@ -614,9 +652,10 @@ implementation + result:=( + ((opcode=A_MOV) and (regtype = R_INTREGISTER)) or + ((opcode=A_MVF) and (regtype = R_FPUREGISTER)) or +- ((opcode in [A_FCPYS, A_FCPYD]) and (regtype = R_MMREGISTER)) ++ ((opcode in [A_FCPYS, A_FCPYD]) and (regtype = R_MMREGISTER)) or ++ ((opcode in [A_VMOV]) and (regtype = R_MMREGISTER) and (oppostfix in [PF_F32,PF_F64])) + ) and +- (oppostfix in [PF_None,PF_D]) and ++ ((oppostfix in [PF_None,PF_D]) or (opcode = A_VMOV)) and + (condition=C_None) and + (ops=2) and + (oper[0]^.typ=top_reg) and +@@ -626,8 +665,6 @@ implementation + + + function spilling_create_load(const ref:treference;r:tregister):Taicpu; +- var +- op: tasmop; + begin + case getregtype(r) of + R_INTREGISTER : +@@ -638,19 +675,7 @@ implementation + } + result:=taicpu.op_reg_const_ref(A_LFM,r,1,ref); + R_MMREGISTER : +- begin +- case getsubreg(r) of +- R_SUBFD: +- op:=A_FLDD; +- R_SUBFS: +- op:=A_FLDS; +- R_SUBNONE: +- op:=A_VLDR; +- else +- internalerror(2009112905); +- end; +- result:=taicpu.op_reg_ref(op,r,ref); +- end; ++ result:=taicpu.op_reg_ref(A_VLDR,r,ref); + else + internalerror(200401041); + end; +@@ -658,8 +683,6 @@ implementation + + + function spilling_create_store(r:tregister; const ref:treference):Taicpu; +- var +- op: tasmop; + begin + case getregtype(r) of + R_INTREGISTER : +@@ -670,19 +693,7 @@ implementation + } + result:=taicpu.op_reg_const_ref(A_SFM,r,1,ref); + R_MMREGISTER : +- begin +- case getsubreg(r) of +- R_SUBFD: +- op:=A_FSTD; +- R_SUBFS: +- op:=A_FSTS; +- R_SUBNONE: +- op:=A_VSTR; +- else +- internalerror(2009112904); +- end; +- result:=taicpu.op_reg_ref(op,r,ref); +- end; ++ result:=taicpu.op_reg_ref(A_VSTR,r,ref); + else + internalerror(200401041); + end; +@@ -1302,6 +1313,41 @@ implementation + end; + end; + ++ curtai:=tai(curtai.Next); ++ end; ++ end; ++ ++ ++ procedure ensurethumbencodings(list: TAsmList); ++ var ++ curtai: tai; ++ op2reg: TRegister; ++ begin ++ { Do Thumb 16bit transformations to form valid instruction forms } ++ curtai:=tai(list.first); ++ while assigned(curtai) do ++ begin ++ case curtai.typ of ++ ait_instruction: ++ begin ++ case taicpu(curtai).opcode of ++ A_ADD, ++ A_AND,A_EOR,A_ORR,A_BIC, ++ A_LSL,A_LSR,A_ASR,A_ROR, ++ A_ADC,A_SBC: ++ begin ++ if (taicpu(curtai).ops = 3) and ++ (taicpu(curtai).oper[2]^.typ=top_reg) and ++ (taicpu(curtai).oper[0]^.reg=taicpu(curtai).oper[1]^.reg) and ++ (taicpu(curtai).oper[0]^.reg<>NR_STACK_POINTER_REG) then ++ begin ++ taicpu(curtai).oper[1]^.reg:=taicpu(curtai).oper[2]^.reg; ++ taicpu(curtai).ops:=2; ++ end; ++ end; ++ end; ++ end; ++ end; + + curtai:=tai(curtai.Next); + end; +@@ -1401,14 +1447,175 @@ implementation + end; + end; + ++ procedure fix_invalid_imms(list: TAsmList); ++ var ++ curtai: tai; ++ sh: byte; ++ begin ++ curtai:=tai(list.First); ++ while assigned(curtai) do ++ begin ++ case curtai.typ of ++ ait_instruction: ++ begin ++ if (taicpu(curtai).opcode in [A_AND,A_BIC]) and ++ (taicpu(curtai).ops=3) and ++ (taicpu(curtai).oper[2]^.typ=top_const) and ++ (not is_shifter_const(taicpu(curtai).oper[2]^.val,sh)) and ++ is_shifter_const((not taicpu(curtai).oper[2]^.val) and $FFFFFFFF,sh) then ++ begin ++ case taicpu(curtai).opcode of ++ A_AND: taicpu(curtai).opcode:=A_BIC; ++ A_BIC: taicpu(curtai).opcode:=A_AND; ++ end; ++ taicpu(curtai).oper[2]^.val:=(not taicpu(curtai).oper[2]^.val) and $FFFFFFFF; ++ end ++ else if (taicpu(curtai).opcode in [A_SUB,A_ADD]) and ++ (taicpu(curtai).ops=3) and ++ (taicpu(curtai).oper[2]^.typ=top_const) and ++ (not is_shifter_const(taicpu(curtai).oper[2]^.val,sh)) and ++ is_shifter_const(-taicpu(curtai).oper[2]^.val,sh) then ++ begin ++ case taicpu(curtai).opcode of ++ A_ADD: taicpu(curtai).opcode:=A_SUB; ++ A_SUB: taicpu(curtai).opcode:=A_ADD; ++ end; ++ taicpu(curtai).oper[2]^.val:=-taicpu(curtai).oper[2]^.val; ++ end; ++ end; ++ end; ++ ++ curtai:=tai(curtai.Next); ++ end; ++ end; ++ ++ ++ procedure gather_it_info(list: TAsmList); ++ var ++ curtai: tai; ++ in_it: boolean; ++ it_count: longint; ++ begin ++ in_it:=false; ++ it_count:=0; ++ ++ curtai:=tai(list.First); ++ while assigned(curtai) do ++ begin ++ case curtai.typ of ++ ait_instruction: ++ begin ++ case taicpu(curtai).opcode of ++ A_IT..A_ITTTT: ++ begin ++ if in_it then ++ Message1(asmw_e_invalid_opcode_and_operands, 'ITxx instruction is inside another ITxx instruction') ++ else ++ begin ++ in_it:=true; ++ it_count:=GetITLevels(taicpu(curtai).opcode); ++ end; ++ end; ++ else ++ begin ++ taicpu(curtai).inIT:=in_it; ++ taicpu(curtai).lastinIT:=in_it and (it_count=1); ++ ++ if in_it then ++ begin ++ dec(it_count); ++ if it_count <= 0 then ++ in_it:=false; ++ end; ++ end; ++ end; ++ end; ++ end; ++ ++ curtai:=tai(curtai.Next); ++ end; ++ end; ++ ++ ++ { Expands pseudo instructions ( mov r1,r2,lsl #4 -> lsl r1,r2,#4) } ++ procedure expand_instructions(list: TAsmList); ++ var ++ curtai: tai; ++ begin ++ curtai:=tai(list.First); ++ while assigned(curtai) do ++ begin ++ case curtai.typ of ++ ait_instruction: ++ begin ++ case taicpu(curtai).opcode of ++ A_MOV: ++ begin ++ if (taicpu(curtai).ops=3) and ++ (taicpu(curtai).oper[2]^.typ=top_shifterop) then ++ begin ++ case taicpu(curtai).oper[2]^.shifterop^.shiftmode of ++ SM_LSL: taicpu(curtai).opcode:=A_LSL; ++ SM_LSR: taicpu(curtai).opcode:=A_LSR; ++ SM_ASR: taicpu(curtai).opcode:=A_ASR; ++ SM_ROR: taicpu(curtai).opcode:=A_ROR; ++ SM_RRX: taicpu(curtai).opcode:=A_RRX; ++ end; ++ ++ if taicpu(curtai).oper[2]^.shifterop^.shiftmode=SM_RRX then ++ taicpu(curtai).ops:=2; ++ ++ if taicpu(curtai).oper[2]^.shifterop^.rs=NR_NO then ++ taicpu(curtai).loadconst(2, taicpu(curtai).oper[2]^.shifterop^.shiftimm) ++ else ++ taicpu(curtai).loadreg(2, taicpu(curtai).oper[2]^.shifterop^.rs); ++ end; ++ end; ++ A_NEG: ++ begin ++ taicpu(curtai).opcode:=A_RSB; ++ ++ if taicpu(curtai).ops=2 then ++ begin ++ taicpu(curtai).loadconst(2,0); ++ taicpu(curtai).ops:=3; ++ end ++ else ++ begin ++ taicpu(curtai).loadconst(1,0); ++ taicpu(curtai).ops:=2; ++ end; ++ end; ++ A_SWI: ++ begin ++ taicpu(curtai).opcode:=A_SVC; ++ end; ++ end; ++ end; ++ end; ++ ++ curtai:=tai(curtai.Next); ++ end; ++ end; ++ ++ + procedure finalizearmcode(list, listtoinsert: TAsmList); + begin ++ expand_instructions(list); ++ + { Do Thumb-2 16bit -> 32bit transformations } + if GenerateThumb2Code then + begin ++ ensurethumbencodings(list); + ensurethumb2encodings(list); + foldITInstructions(list); +- end; ++ end ++ else if GenerateThumbCode then ++ ensurethumbencodings(list); ++ ++ gather_it_info(list); ++ ++ fix_invalid_imms(list); + + insertpcrelativedata(list, listtoinsert); + end; +@@ -1605,6 +1812,12 @@ implementation + if (ot and OT_FPUREG)=OT_FPUREG then + s:=s+'fpureg' + else ++ if (ot and OT_REGS)=OT_REGS then ++ s:=s+'sreg' ++ else ++ if (ot and OT_REGF)=OT_REGF then ++ s:=s+'creg' ++ else + if (ot and OT_REGISTER)=OT_REGISTER then + begin + s:=s+'reg'; +@@ -1628,9 +1841,17 @@ implementation + s:=s+'mem'; + addsize:=true; + if (ot and OT_AM2)<>0 then ++ s:=s+' am2 ' ++ else if (ot and OT_AM6)<>0 then + s:=s+' am2 '; + end + else ++ if (ot and OT_SHIFTEROP)=OT_SHIFTEROP then ++ begin ++ s:=s+'shifterop'; ++ addsize:=false; ++ end ++ else + s:=s+'???'; + { size } + if addsize then +@@ -1705,7 +1926,12 @@ implementation + current_filepos:=fileinfo; + + { tranlate LDR+postfix to complete opcode } +- if (opcode=A_LDR) and (oppostfix<>PF_None) then ++ if (opcode=A_LDR) and (oppostfix=PF_D) then ++ begin ++ opcode:=A_LDRD; ++ oppostfix:=PF_None; ++ end ++ else if (opcode=A_LDR) and (oppostfix<>PF_None) then + begin + if (oppostfix in [low(ldr2op)..high(ldr2op)]) then + opcode:=ldr2op[oppostfix] +@@ -1716,6 +1942,11 @@ implementation + { postfix has been added to opcode } + oppostfix:=PF_None; + end ++ else if (opcode=A_STR) and (oppostfix=PF_D) then ++ begin ++ opcode:=A_STRD; ++ oppostfix:=PF_None; ++ end + else if (opcode=A_STR) and (oppostfix<>PF_None) then + begin + if (oppostfix in [low(str2op)..high(str2op)]) then +@@ -1771,6 +2002,58 @@ implementation + end; + + ++ procedure taicpu.BuildArmMasks; ++ const ++ Masks: array[tcputype] of longint = ++ ( ++ IF_NONE, ++ IF_ARMv4, ++ IF_ARMv4, ++ IF_ARMv4T or IF_ARMv4, ++ IF_ARMv4T or IF_ARMv4 or IF_ARMv5, ++ IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T, ++ IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T or IF_ARMv5TE, ++ IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T or IF_ARMv5TE or IF_ARMv5TEJ, ++ IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T or IF_ARMv5TE or IF_ARMv5TEJ or IF_armv6, ++ IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T or IF_ARMv5TE or IF_ARMv5TEJ or IF_armv6 or IF_ARMv6K, ++ IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T or IF_ARMv5TE or IF_ARMv5TEJ or IF_armv6 or IF_ARMv6K or IF_ARMv6T2, ++ IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T or IF_ARMv5TE or IF_ARMv5TEJ or IF_armv6 or IF_ARMv6K or IF_ARMv6T2 or IF_ARMv6Z, ++ IF_ARMv4T or IF_ARMv5T or IF_ARMv6M, ++ IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T or IF_ARMv5TE or IF_ARMv5TEJ or IF_armv6 or IF_ARMv6K or IF_ARMv6T2 or IF_ARMv6Z or IF_ARMv7, ++ IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T or IF_ARMv5TE or IF_ARMv5TEJ or IF_armv6 or IF_ARMv6K or IF_ARMv6T2 or IF_ARMv6Z or IF_ARMv7 or IF_ARMv7A, ++ IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T or IF_ARMv5TE or IF_ARMv5TEJ or IF_armv6 or IF_ARMv6K or IF_ARMv6T2 or IF_ARMv6Z or IF_ARMv7 or IF_ARMv7A or IF_ARMv7R, ++ IF_ARMv4T or IF_ARMv5T or IF_ARMv6T2 or IF_ARMv7M, ++ IF_ARMv4T or IF_ARMv5T or IF_ARMv6T2 or IF_ARMv7M or IF_ARMv7EM ++ ); ++ ++ FPUMasks: array[tfputype] of longword = ++ ( ++ IF_NONE, ++ IF_NONE, ++ IF_NONE, ++ IF_FPA, ++ IF_FPA, ++ IF_FPA, ++ IF_VFPv2, ++ IF_VFPv2 or IF_VFPv3, ++ IF_VFPv2 or IF_VFPv3, ++ IF_NONE, ++ IF_VFPv2 or IF_VFPv3 or IF_VFPv4 ++ ); ++ begin ++ fArmVMask:=Masks[current_settings.cputype] or FPUMasks[current_settings.fputype]; ++ ++ if current_settings.instructionset=is_thumb then ++ begin ++ fArmMask:=IF_THUMB; ++ if CPUARM_HAS_THUMB2 in cpu_capabilities[current_settings.cputype] then ++ fArmMask:=fArmMask or IF_THUMB32; ++ end ++ else ++ fArmMask:=IF_ARM32; ++ end; ++ ++ + function taicpu.InsEnd:longint; + begin + Result:=0; { unimplemented } +@@ -1798,9 +2081,19 @@ implementation + begin + case getregtype(reg) of + R_INTREGISTER: +- ot:=OT_REG32 or OT_SHIFTEROP; ++ begin ++ ot:=OT_REG32 or OT_SHIFTEROP; ++ if getsupreg(reg)<8 then ++ ot:=ot or OT_REGLO ++ else if reg=NR_STACK_POINTER_REG then ++ ot:=ot or OT_REGSP; ++ end; + R_FPUREGISTER: + ot:=OT_FPUREG; ++ R_MMREGISTER: ++ ot:=OT_VREG; ++ R_SPECIALREGISTER: ++ ot:=OT_REGF; + else + internalerror(2005090901); + end; +@@ -1831,7 +2124,30 @@ implementation + ref^.base:=NR_PC; + + { determine possible address modes } ++ if GenerateThumbCode or ++ GenerateThumb2Code then ++ begin ++ if (ref^.base=NR_PC) then ++ ot:=ot or OT_AM6 ++ else if (ref^.base=NR_STACK_POINTER_REG) then ++ ot:=ot or OT_AM5 ++ else if ref^.index=NR_NO then ++ ot:=ot or OT_AM4 ++ else ++ ot:=ot or OT_AM3; ++ end; ++ + if (ref^.base<>NR_NO) and ++ (opcode in [A_LDREX,A_LDREXB,A_LDREXH,A_LDREXD, ++ A_STREX,A_STREXB,A_STREXH,A_STREXD]) and ++ ( ++ (ref^.addressmode=AM_OFFSET) and ++ (ref^.index=NR_NO) and ++ (ref^.shiftmode=SM_None) and ++ (ref^.offset=0) ++ ) then ++ ot:=ot or OT_AM6 ++ else if (ref^.base<>NR_NO) and + ( + ( + (ref^.index=NR_NO) and +@@ -1846,14 +2162,17 @@ implementation + ( + (ref^.index<>NR_NO) and + (ref^.shiftmode<>SM_None) and +- (ref^.shiftimm<=31) and ++ (ref^.shiftimm<=32) and + (ref^.offset=0) + ) + ) then + ot:=ot or OT_AM2; + + if (ref^.index<>NR_NO) and +- (oppostfix in [PF_IA,PF_IB,PF_DA,PF_DB,PF_FD,PF_FA,PF_ED,PF_EA]) and ++ (oppostfix in [PF_None,PF_IA,PF_IB,PF_DA,PF_DB,PF_FD,PF_FA,PF_ED,PF_EA, ++ PF_IAD,PF_DBD,PF_FDD,PF_EAD, ++ PF_IAS,PF_DBS,PF_FDS,PF_EAS, ++ PF_IAX,PF_DBX,PF_FDX,PF_EAX]) and + ( + (ref^.base=NR_NO) and + (ref^.shiftmode=SM_None) and +@@ -1887,7 +2206,11 @@ implementation + top_const : + begin + ot:=OT_IMMEDIATE; +- if is_shifter_const(val,dummy) then ++ if (val=0) then ++ ot:=ot_immediatezero ++ else if is_shifter_const(val,dummy) then ++ ot:=OT_IMMSHIFTER ++ else if GenerateThumb2Code and is_thumb32_imm(val) then + ot:=OT_IMMSHIFTER + else + ot:=OT_IMM32 +@@ -1902,6 +2225,18 @@ implementation + begin + ot:=OT_SHIFTEROP; + end; ++ top_conditioncode: ++ begin ++ ot:=OT_CONDITION; ++ end; ++ top_specialreg: ++ begin ++ ot:=OT_REGS; ++ end; ++ top_modeflags: ++ begin ++ ot:=OT_MODEFLAGS; ++ end; + else + internalerror(2004022623); + end; +@@ -1935,7 +2270,6 @@ implementation + {siz : array[0..3] of longint;} + begin + Matches:=100; +- writeln(getstring,'---'); + + { Check the opcode and operands } + if (p^.opcode<>opcode) or (p^.ops<>ops) then +@@ -1944,6 +2278,27 @@ implementation + exit; + end; + ++ { check ARM instruction version } ++ if (p^.flags and fArmVMask)=0 then ++ begin ++ Matches:=0; ++ exit; ++ end; ++ ++ { check ARM instruction type } ++ if (p^.flags and fArmMask)=0 then ++ begin ++ Matches:=0; ++ exit; ++ end; ++ ++ { Check wideformat flag } ++ if wideformat and ((p^.flags and IF_WIDE)=0) then ++ begin ++ matches:=0; ++ exit; ++ end; ++ + { Check that no spurious colons or TOs are present } + for i:=0 to p^.ops-1 do + if (oper[i]^.ot and (not p^.optypes[i]) and (OT_COLON or OT_TO))<>0 then +@@ -1965,6 +2320,12 @@ implementation + Matches:=0; + exit; + end ++ else if ((p^.optypes[i] and OT_OPT_SIZE)<>0) and ++ ((p^.optypes[i] and OT_OPT_SIZE)<>(oper[i]^.ot and OT_OPT_SIZE)) then ++ begin ++ Matches:=0; ++ exit; ++ end + else + Matches:=1; + end; +@@ -1977,7 +2338,7 @@ implementation + { update condition flags + or floating point single } + if (oppostfix=PF_S) and +- not(p^.code[0] in [#$04]) then ++ not(p^.code[0] in [#$04..#$0F,#$14..#$16,#$29,#$30,#$60..#$6B,#$80..#$82,#$A0..#$A2,#$44,#$94,#$42,#$92]) then + begin + Matches:=0; + exit; +@@ -1985,7 +2346,13 @@ implementation + + { floating point size } + if (oppostfix in [PF_D,PF_E,PF_P,PF_EP]) and +- not(p^.code[0] in []) then ++ not(p^.code[0] in [ ++ // FPA ++ #$A0..#$A2, ++ // old-school VFP ++ #$42,#$92, ++ // vldm/vstm ++ #$44,#$94]) then + begin + Matches:=0; + exit; +@@ -1997,7 +2364,9 @@ implementation + // ldr,str,ldrb,strb + #$17, + // stm,ldm +- #$26 ++ #$26,#$69,#$8C, ++ // vldm/vstm ++ #$44,#$94 + ]) then + begin + Matches:=0; +@@ -2017,6 +2386,57 @@ implementation + exit; + end; + ++ { Check thumb flags } ++ if p^.code[0] in [#$60..#$61] then ++ begin ++ if (p^.code[0]=#$60) and ++ (GenerateThumb2Code and ++ ((not inIT) and (oppostfix<>PF_S)) or ++ (inIT and (condition=C_None))) then ++ begin ++ Matches:=0; ++ exit; ++ end ++ else if (p^.code[0]=#$61) and ++ (oppostfix=PF_S) then ++ begin ++ Matches:=0; ++ exit; ++ end; ++ end ++ else if p^.code[0]=#$62 then ++ begin ++ if (GenerateThumb2Code and ++ (condition<>C_None) and ++ (not inIT) and ++ (not lastinIT)) then ++ begin ++ Matches:=0; ++ exit; ++ end; ++ end ++ else if p^.code[0]=#$63 then ++ begin ++ if inIT then ++ begin ++ Matches:=0; ++ exit; ++ end; ++ end ++ else if p^.code[0]=#$64 then ++ begin ++ if (opcode=A_MUL) then ++ begin ++ if (ops=3) and ++ ((oper[2]^.typ<>top_reg) or ++ (oper[0]^.reg<>oper[2]^.reg)) then ++ begin ++ matches:=0; ++ exit; ++ end; ++ end; ++ end; ++ + { Check operand sizes } + { as default an untyped size can get all the sizes, this is different + from nasm, but else we need to do a lot checking which opcodes want +@@ -2112,6 +2532,8 @@ implementation + begin + { create the .ot fields } + create_ot(objdata); ++ ++ BuildArmMasks; + { set the file postion } + current_filepos:=fileinfo; + end +@@ -2148,1013 +2570,2895 @@ implementation + + + procedure taicpu.gencode(objdata:TObjData); ++ const ++ CondVal : array[TAsmCond] of byte=( ++ $E, $0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $A, ++ $B, $C, $D, $E, 0); + var +- bytes : dword; ++ bytes, rd, rm, rn, d, m, n : dword; ++ bytelen : longint; ++ dp_operation : boolean; + i_field : byte; ++ currsym : TObjSymbol; ++ offset : longint; ++ refoper : poper; ++ msb : longint; ++ r: byte; + + procedure setshifterop(op : byte); ++ var ++ r : byte; ++ imm : dword; ++ count : integer; + begin + case oper[op]^.typ of + top_const: + begin + i_field:=1; +- bytes:=bytes or dword(oper[op]^.val and $fff); ++ if oper[op]^.val and $ff=oper[op]^.val then ++ bytes:=bytes or dword(oper[op]^.val) ++ else ++ begin ++ { calc rotate and adjust imm } ++ count:=0; ++ r:=0; ++ imm:=dword(oper[op]^.val); ++ repeat ++ imm:=RolDWord(imm, 2); ++ inc(r); ++ inc(count); ++ if count > 32 then ++ begin ++ message1(asmw_e_invalid_opcode_and_operands, 'invalid shifter imm'); ++ exit; ++ end; ++ until (imm and $ff)=imm; ++ bytes:=bytes or (r shl 8) or imm; ++ end; + end; + top_reg: + begin + i_field:=0; +- bytes:=bytes or (getsupreg(oper[op]^.reg) shl 16); ++ bytes:=bytes or getsupreg(oper[op]^.reg); + + { does a real shifter op follow? } +- if (op+1<=op) and (oper[op+1]^.typ=top_shifterop) then +- begin +- end; ++ if (op+1SM_RRX then ++ bytes:=bytes or (ord(shiftmode) - ord(SM_LSL)) shl 5 ++ else ++ bytes:=bytes or (3 shl 5); ++ if getregtype(rs) <> R_INVALIDREGISTER then ++ begin ++ bytes:=bytes or (1 shl 4); ++ bytes:=bytes or (getsupreg(rs) shl 8); ++ end ++ end; + end; + else + internalerror(2005091103); + end; + end; + ++ function MakeRegList(reglist: tcpuregisterset): word; ++ var ++ i, w: word; ++ begin ++ result:=0; ++ w:=1; ++ for i:=RS_R0 to RS_R15 do ++ begin ++ if i in reglist then ++ result:=result or w; ++ w:=w shl 1 ++ end; ++ end; ++ ++ function getcoproc(reg: tregister): byte; ++ begin ++ if reg=NR_p15 then ++ result:=15 ++ else ++ begin ++ Message1(asmw_e_invalid_opcode_and_operands,'Invalid coprocessor port'); ++ result:=0; ++ end; ++ end; ++ ++ function getcoprocreg(reg: tregister): byte; ++ begin ++ result:=getsupreg(reg)-getsupreg(NR_CR0); ++ end; ++ ++ function getmmreg(reg: tregister): byte; ++ begin ++ case reg of ++ NR_D0: result:=0; ++ NR_D1: result:=1; ++ NR_D2: result:=2; ++ NR_D3: result:=3; ++ NR_D4: result:=4; ++ NR_D5: result:=5; ++ NR_D6: result:=6; ++ NR_D7: result:=7; ++ NR_D8: result:=8; ++ NR_D9: result:=9; ++ NR_D10: result:=10; ++ NR_D11: result:=11; ++ NR_D12: result:=12; ++ NR_D13: result:=13; ++ NR_D14: result:=14; ++ NR_D15: result:=15; ++ NR_D16: result:=16; ++ NR_D17: result:=17; ++ NR_D18: result:=18; ++ NR_D19: result:=19; ++ NR_D20: result:=20; ++ NR_D21: result:=21; ++ NR_D22: result:=22; ++ NR_D23: result:=23; ++ NR_D24: result:=24; ++ NR_D25: result:=25; ++ NR_D26: result:=26; ++ NR_D27: result:=27; ++ NR_D28: result:=28; ++ NR_D29: result:=29; ++ NR_D30: result:=30; ++ NR_D31: result:=31; ++ ++ NR_S0: result:=0; ++ NR_S1: result:=1; ++ NR_S2: result:=2; ++ NR_S3: result:=3; ++ NR_S4: result:=4; ++ NR_S5: result:=5; ++ NR_S6: result:=6; ++ NR_S7: result:=7; ++ NR_S8: result:=8; ++ NR_S9: result:=9; ++ NR_S10: result:=10; ++ NR_S11: result:=11; ++ NR_S12: result:=12; ++ NR_S13: result:=13; ++ NR_S14: result:=14; ++ NR_S15: result:=15; ++ NR_S16: result:=16; ++ NR_S17: result:=17; ++ NR_S18: result:=18; ++ NR_S19: result:=19; ++ NR_S20: result:=20; ++ NR_S21: result:=21; ++ NR_S22: result:=22; ++ NR_S23: result:=23; ++ NR_S24: result:=24; ++ NR_S25: result:=25; ++ NR_S26: result:=26; ++ NR_S27: result:=27; ++ NR_S28: result:=28; ++ NR_S29: result:=29; ++ NR_S30: result:=30; ++ NR_S31: result:=31; ++ else ++ result:=0; ++ end; ++ end; ++ ++ procedure encodethumbimm(imm: longword); ++ var ++ imm12, tmp: tcgint; ++ shift: integer; ++ found: boolean; ++ begin ++ found:=true; ++ if (imm and $FF) = imm then ++ imm12:=imm ++ else if ((imm shr 16)=(imm and $FFFF)) and ++ ((imm and $FF00FF00) = 0) then ++ imm12:=(imm and $ff) or ($1 shl 8) ++ else if ((imm shr 16)=(imm and $FFFF)) and ++ ((imm and $00FF00FF) = 0) then ++ imm12:=((imm shr 8) and $ff) or ($2 shl 8) ++ else if ((imm shr 16)=(imm and $FFFF)) and ++ (((imm shr 8) and $FF)=(imm and $FF)) then ++ imm12:=(imm and $ff) or ($3 shl 8) ++ else ++ begin ++ found:=false; ++ imm12:=0; ++ for shift:=1 to 31 do ++ begin ++ tmp:=RolDWord(imm,shift); ++ if ((tmp and $FF)=tmp) and ++ ((tmp and $80)=$80) then ++ begin ++ imm12:=(tmp and $7F) or (shift shl 7); ++ found:=true; ++ break; ++ end; ++ end; ++ end; ++ ++ if found then ++ begin ++ bytes:=bytes or (imm12 and $FF); ++ bytes:=bytes or (((imm12 shr 8) and $7) shl 12); ++ bytes:=bytes or (((imm12 shr 11) and $1) shl 26); ++ end ++ else ++ Message1(asmw_e_value_exceeds_bounds, IntToStr(imm)); ++ end; ++ ++ procedure setthumbshift(op: byte; is_sat: boolean = false); ++ var ++ shift,typ: byte; ++ begin ++ shift:=0; ++ typ:=0; ++ case oper[op]^.shifterop^.shiftmode of ++ SM_LSL: begin typ:=0; shift:=oper[op]^.shifterop^.shiftimm; end; ++ SM_LSR: begin typ:=1; shift:=oper[op]^.shifterop^.shiftimm; if shift=32 then shift:=0; end; ++ SM_ASR: begin typ:=2; shift:=oper[op]^.shifterop^.shiftimm; if shift=32 then shift:=0; end; ++ SM_ROR: begin typ:=3; shift:=oper[op]^.shifterop^.shiftimm; if shift=0 then message(asmw_e_invalid_opcode_and_operands); end; ++ SM_RRX: begin typ:=3; shift:=0; end; ++ end; ++ ++ if is_sat then ++ begin ++ bytes:=bytes or ((typ and 1) shl 5); ++ bytes:=bytes or ((typ shr 1) shl 21); ++ end ++ else ++ bytes:=bytes or (typ shl 4); ++ bytes:=bytes or (shift and $3) shl 6; ++ bytes:=bytes or ((shift and $1C) shr 2) shl 12; ++ end; ++ + begin + bytes:=$0; ++ bytelen:=4; + i_field:=0; + { evaluate and set condition code } ++ bytes:=bytes or (CondVal[condition] shl 28); + + { condition code allowed? } + + { setup rest of the instruction } + case insentry^.code[0] of +- #$08: ++ #$01: // B/BL + begin + { set instruction code } +- bytes:=bytes or (ord(insentry^.code[1]) shl 26); +- bytes:=bytes or (ord(insentry^.code[2]) shl 21); ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ { set offset } ++ if oper[0]^.typ=top_const then ++ bytes:=bytes or ((oper[0]^.val shr 2) and $ffffff) ++ else ++ begin ++ currsym:=objdata.symbolref(oper[0]^.ref^.symbol); ++ if (currsym.bind<>AB_LOCAL) and (currsym.objsection<>objdata.CurrObjSec) then ++ begin ++ objdata.writereloc(oper[0]^.ref^.offset,0,currsym,RELOC_RELATIVE_24); ++ bytes:=bytes or $fffffe; // TODO: Not sure this is right, but it matches the output of gas ++ end ++ else ++ bytes:=bytes or (((currsym.offset-insoffset-8) shr 2) and $ffffff); ++ end; ++ end; ++ #$02: ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ { set code } ++ bytes:=bytes or (oper[0]^.val and $FFFFFF); ++ end; ++ #$03: ++ begin // BLX/BX ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); + ++ bytes:=bytes or getsupreg(oper[0]^.reg); ++ end; ++ #$04..#$07: // SUB ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ { set destination } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ { set Rn } ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 16); ++ { create shifter op } ++ setshifterop(2); ++ { set I field } ++ bytes:=bytes or (i_field shl 25); ++ { set S if necessary } ++ if oppostfix=PF_S then ++ bytes:=bytes or (1 shl 20); ++ end; ++ #$08,#$0A,#$0B: // MOV ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); + { set destination } + bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); +- + { create shifter op } + setshifterop(1); +- +- { set i field } ++ { set I field } ++ bytes:=bytes or (i_field shl 25); ++ { set S if necessary } ++ if oppostfix=PF_S then ++ bytes:=bytes or (1 shl 20); ++ end; ++ #$0C,#$0E,#$0F: // CMP ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ { set destination } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16); ++ { create shifter op } ++ setshifterop(1); ++ { set I field } + bytes:=bytes or (i_field shl 25); ++ { always set S bit } ++ bytes:=bytes or (1 shl 20); ++ end; ++ #$10: // MRS ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ { set destination } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ ++ case oper[1]^.reg of ++ NR_APSR,NR_CPSR:; ++ NR_SPSR: ++ begin ++ bytes:=bytes or (1 shl 22); ++ end; ++ else ++ Message(asmw_e_invalid_opcode_and_operands); ++ end; ++ end; ++ #$12,#$13: // MSR ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ { set destination } ++ ++ if oper[0]^.typ=top_specialreg then ++ begin ++ if (oper[0]^.specialreg<>NR_CPSR) and ++ (oper[0]^.specialreg<>NR_SPSR) then ++ Message1(asmw_e_invalid_opcode_and_operands, '"Invalid special reg"'); ++ ++ if srC in oper[0]^.specialflags then ++ bytes:=bytes or (1 shl 16); ++ if srX in oper[0]^.specialflags then ++ bytes:=bytes or (1 shl 17); ++ if srS in oper[0]^.specialflags then ++ bytes:=bytes or (1 shl 18); ++ if srF in oper[0]^.specialflags then ++ bytes:=bytes or (1 shl 19); ++ ++ { Set R bit } ++ if oper[0]^.specialreg=NR_SPSR then ++ bytes:=bytes or (1 shl 22); ++ end ++ else ++ case oper[0]^.reg of ++ NR_APSR_nzcvq: bytes:=bytes or (2 shl 18); ++ NR_APSR_g: bytes:=bytes or (1 shl 18); ++ NR_APSR_nzcvqg: bytes:=bytes or (3 shl 18); ++ else ++ Message1(asmw_e_invalid_opcode_and_operands, 'Invalid combination APSR bits used'); ++ end; ++ ++ setshifterop(1); ++ end; ++ #$14: // MUL/MLA r1,r2,r3 ++ begin ++ { set instruction code } ++ bytes:=bytes or ord(insentry^.code[1]) shl 24; ++ bytes:=bytes or ord(insentry^.code[2]) shl 16; ++ bytes:=bytes or ord(insentry^.code[3]); ++ { set regs } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 16; ++ bytes:=bytes or getsupreg(oper[1]^.reg); ++ bytes:=bytes or getsupreg(oper[2]^.reg) shl 8; ++ ++ if oppostfix in [PF_S] then ++ bytes:=bytes or (1 shl 20); ++ end; ++ #$15: // MUL/MLA r1,r2,r3,r4 ++ begin ++ { set instruction code } ++ bytes:=bytes or ord(insentry^.code[1]) shl 24; ++ bytes:=bytes or ord(insentry^.code[2]) shl 16; ++ bytes:=bytes or ord(insentry^.code[3]) shl 4; ++ { set regs } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 16; ++ bytes:=bytes or getsupreg(oper[1]^.reg); ++ bytes:=bytes or getsupreg(oper[2]^.reg) shl 8; ++ if ops>3 then ++ bytes:=bytes or getsupreg(oper[3]^.reg) shl 12 ++ else ++ bytes:=bytes or ord(insentry^.code[4]) shl 12; ++ ++ if oppostfix in [PF_R,PF_X] then ++ bytes:=bytes or (1 shl 5); ++ ++ if oppostfix in [PF_S] then ++ bytes:=bytes or (1 shl 20); ++ end; ++ #$16: // MULL r1,r2,r3,r4 ++ begin ++ { set instruction code } ++ bytes:=bytes or ord(insentry^.code[1]) shl 24; ++ bytes:=bytes or ord(insentry^.code[2]) shl 16; ++ bytes:=bytes or ord(insentry^.code[3]) shl 4; ++ { set regs } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ ++ if (ops=3) and (opcode=A_PKHTB) then ++ begin ++ bytes:=bytes or getsupreg(oper[1]^.reg); ++ bytes:=bytes or getsupreg(oper[2]^.reg) shl 16; ++ end ++ else ++ begin ++ bytes:=bytes or getsupreg(oper[1]^.reg) shl 16; ++ bytes:=bytes or getsupreg(oper[2]^.reg); ++ end; ++ ++ if ops=4 then ++ begin ++ if oper[3]^.typ=top_shifterop then ++ begin ++ if opcode in [A_PKHBT,A_PKHTB] then ++ begin ++ if ((opcode=A_PKHTB) and ++ (oper[3]^.shifterop^.shiftmode <> SM_ASR)) or ++ ((opcode=A_PKHBT) and ++ (oper[3]^.shifterop^.shiftmode <> SM_LSL)) or ++ (oper[3]^.shifterop^.rs<>NR_NO) then ++ Message1(asmw_e_invalid_opcode_and_operands,GetString); ++ ++ bytes:=bytes or ((oper[3]^.shifterop^.shiftimm and $1F) shl 7); ++ end ++ else ++ begin ++ if (oper[3]^.shifterop^.shiftmode<>sm_ror) or ++ (oper[3]^.shifterop^.rs<>NR_NO) or ++ (not (oper[3]^.shifterop^.shiftimm in [0,8,16,24])) then ++ Message1(asmw_e_invalid_opcode_and_operands,GetString); ++ ++ bytes:=bytes or (((oper[3]^.shifterop^.shiftimm shr 3) and $3) shl 10); ++ end; ++ end ++ else ++ bytes:=bytes or getsupreg(oper[3]^.reg) shl 8; ++ end; + +- { set s if necessary } ++ if PF_S=oppostfix then ++ bytes:=bytes or (1 shl 20); ++ if PF_X=oppostfix then ++ bytes:=bytes or (1 shl 5); ++ end; ++ #$17: // LDR/STR ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ { set Rn and Rd } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ bytes:=bytes or getsupreg(oper[1]^.ref^.base) shl 16; ++ if getregtype(oper[1]^.ref^.index)=R_INVALIDREGISTER then ++ begin ++ { set offset } ++ offset:=0; ++ currsym:=objdata.symbolref(oper[1]^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=offset+oper[1]^.ref^.offset; ++ if offset>=0 then ++ { set U flag } ++ bytes:=bytes or (1 shl 23) ++ else ++ offset:=-offset; ++ bytes:=bytes or (offset and $FFF); ++ end ++ else ++ begin ++ { set U flag } ++ if oper[1]^.ref^.signindex>=0 then ++ bytes:=bytes or (1 shl 23); ++ { set I flag } ++ bytes:=bytes or (1 shl 25); ++ bytes:=bytes or getsupreg(oper[1]^.ref^.index); ++ { set shift } ++ with oper[1]^.ref^ do ++ if shiftmode<>SM_None then ++ begin ++ bytes:=bytes or ((shiftimm and $1F) shl 7); ++ if shiftmode<>SM_RRX then ++ bytes:=bytes or (ord(shiftmode) - ord(SM_LSL)) shl 5 ++ else ++ bytes:=bytes or (3 shl 5); ++ end ++ end; ++ { set W bit } ++ if oper[1]^.ref^.addressmode=AM_PREINDEXED then ++ bytes:=bytes or (1 shl 21); ++ { set P bit if necessary } ++ if oper[1]^.ref^.addressmode<>AM_POSTINDEXED then ++ bytes:=bytes or (1 shl 24); ++ end; ++ #$18: // LDREX/STREX ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set Rn and Rd } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ if (ops=3) then ++ begin ++ if opcode<>A_LDREXD then ++ bytes:=bytes or getsupreg(oper[1]^.reg); ++ ++ bytes:=bytes or (getsupreg(oper[2]^.ref^.base) shl 16); ++ end ++ else if (ops=4) then // STREXD ++ begin ++ if opcode<>A_LDREXD then ++ bytes:=bytes or getsupreg(oper[1]^.reg); ++ ++ bytes:=bytes or (getsupreg(oper[3]^.ref^.base) shl 16); ++ end ++ else ++ bytes:=bytes or (getsupreg(oper[1]^.ref^.base) shl 16); ++ end; ++ #$19: // LDRD/STRD ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set Rn and Rd } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ ++ refoper:=oper[1]; ++ if ops=3 then ++ refoper:=oper[2]; ++ ++ bytes:=bytes or getsupreg(refoper^.ref^.base) shl 16; ++ if getregtype(refoper^.ref^.index)=R_INVALIDREGISTER then ++ begin ++ bytes:=bytes or (1 shl 22); ++ { set offset } ++ offset:=0; ++ currsym:=objdata.symbolref(refoper^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=offset+refoper^.ref^.offset; ++ if offset>=0 then ++ { set U flag } ++ bytes:=bytes or (1 shl 23) ++ else ++ offset:=-offset; ++ bytes:=bytes or (offset and $F); ++ bytes:=bytes or ((offset and $F0) shl 4); ++ end ++ else ++ begin ++ { set U flag } ++ if refoper^.ref^.signindex>=0 then ++ bytes:=bytes or (1 shl 23); ++ bytes:=bytes or getsupreg(refoper^.ref^.index); ++ end; ++ { set W bit } ++ if refoper^.ref^.addressmode=AM_PREINDEXED then ++ bytes:=bytes or (1 shl 21); ++ { set P bit if necessary } ++ if refoper^.ref^.addressmode<>AM_POSTINDEXED then ++ bytes:=bytes or (1 shl 24); ++ end; ++ #$1A: // QADD/QSUB ++ begin ++ { set instruction code } ++ bytes:=bytes or ord(insentry^.code[1]) shl 24; ++ bytes:=bytes or ord(insentry^.code[2]) shl 16; ++ bytes:=bytes or ord(insentry^.code[3]) shl 4; ++ { set regs } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ bytes:=bytes or getsupreg(oper[1]^.reg) shl 0; ++ bytes:=bytes or getsupreg(oper[2]^.reg) shl 16; ++ end; ++ #$1B: ++ begin ++ { set instruction code } ++ bytes:=bytes or ord(insentry^.code[1]) shl 24; ++ bytes:=bytes or ord(insentry^.code[2]) shl 16; ++ bytes:=bytes or ord(insentry^.code[3]) shl 4; ++ { set regs } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ bytes:=bytes or getsupreg(oper[1]^.reg); ++ if ops=3 then ++ begin ++ if (oper[2]^.shifterop^.shiftmode<>sm_ror) or ++ (oper[2]^.shifterop^.rs<>NR_NO) or ++ (not (oper[2]^.shifterop^.shiftimm in [0,8,16,24])) then ++ Message1(asmw_e_invalid_opcode_and_operands,GetString); ++ ++ bytes:=bytes or (((oper[2]^.shifterop^.shiftimm shr 3) and $3) shl 10); ++ end; ++ end; ++ #$1C: // MCR/MRC ++ begin ++ { set instruction code } ++ bytes:=bytes or ord(insentry^.code[1]) shl 24; ++ bytes:=bytes or ord(insentry^.code[2]) shl 16; ++ bytes:=bytes or ord(insentry^.code[3]) shl 4; ++ { set regs and operands } ++ bytes:=bytes or getcoproc(oper[0]^.reg) shl 8; ++ bytes:=bytes or ((oper[1]^.val and $7) shl 21); ++ bytes:=bytes or getsupreg(oper[2]^.reg) shl 12; ++ bytes:=bytes or getcoprocreg(oper[3]^.reg) shl 16; ++ bytes:=bytes or getcoprocreg(oper[4]^.reg); ++ if ops > 5 then ++ bytes:=bytes or ((oper[5]^.val and $7) shl 5); ++ end; ++ #$1D: // MCRR/MRRC ++ begin ++ { set instruction code } ++ bytes:=bytes or ord(insentry^.code[1]) shl 24; ++ bytes:=bytes or ord(insentry^.code[2]) shl 16; ++ bytes:=bytes or ord(insentry^.code[3]) shl 4; ++ { set regs and operands } ++ bytes:=bytes or getcoproc(oper[0]^.reg) shl 8; ++ bytes:=bytes or ((oper[1]^.val and $7) shl 4); ++ bytes:=bytes or getsupreg(oper[2]^.reg) shl 12; ++ bytes:=bytes or getsupreg(oper[3]^.reg) shl 16; ++ bytes:=bytes or getcoprocreg(oper[4]^.reg); ++ end; ++ #$1E: // LDRHT/STRHT ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set Rn and Rd } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ ++ refoper:=oper[1]; ++ ++ bytes:=bytes or getsupreg(refoper^.ref^.base) shl 16; ++ if getregtype(refoper^.ref^.index)=R_INVALIDREGISTER then ++ begin ++ bytes:=bytes or (1 shl 22); ++ { set offset } ++ offset:=0; ++ currsym:=objdata.symbolref(refoper^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=offset+refoper^.ref^.offset; ++ ++ if offset>=0 then ++ { set U flag } ++ bytes:=bytes or (1 shl 23) ++ else ++ offset:=-offset; ++ bytes:=bytes or (offset and $F); ++ bytes:=bytes or ((offset and $F0) shl 4); ++ end ++ else ++ begin ++ { set U flag } ++ if refoper^.ref^.signindex>=0 then ++ bytes:=bytes or (1 shl 23); ++ bytes:=bytes or getsupreg(refoper^.ref^.index); ++ end; ++ end; ++ #$22: // LDRH/STRH ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 16); ++ bytes:=bytes or ord(insentry^.code[2]); ++ { src/dest register (Rd) } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ { base register (Rn) } ++ bytes:=bytes or getsupreg(oper[1]^.ref^.base) shl 16; ++ if getregtype(oper[1]^.ref^.index)=R_INVALIDREGISTER then ++ begin ++ bytes:=bytes or (1 shl 22); // with immediate offset ++ offset:=oper[1]^.ref^.offset; ++ if offset>=0 then ++ { set U flag } ++ bytes:=bytes or (1 shl 23) ++ else ++ offset:=-offset; ++ bytes:=bytes or (offset and $F); ++ bytes:=bytes or ((offset and $F0) shl 4); ++ end ++ else ++ begin ++ { set U flag } ++ if oper[1]^.ref^.signindex>=0 then ++ bytes:=bytes or (1 shl 23); ++ bytes:=bytes or getsupreg(oper[1]^.ref^.index); ++ end; ++ { set W bit } ++ if oper[1]^.ref^.addressmode=AM_PREINDEXED then ++ bytes:=bytes or (1 shl 21); ++ { set P bit if necessary } ++ if oper[1]^.ref^.addressmode<>AM_POSTINDEXED then ++ bytes:=bytes or (1 shl 24); ++ end; ++ #$25: // PLD/PLI ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set Rn and Rd } ++ bytes:=bytes or getsupreg(oper[0]^.ref^.base) shl 16; ++ if getregtype(oper[0]^.ref^.index)=R_INVALIDREGISTER then ++ begin ++ { set offset } ++ offset:=0; ++ currsym:=objdata.symbolref(oper[0]^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=offset+oper[0]^.ref^.offset; ++ if offset>=0 then ++ begin ++ { set U flag } ++ bytes:=bytes or (1 shl 23); ++ bytes:=bytes or offset ++ end ++ else ++ begin ++ offset:=-offset; ++ bytes:=bytes or offset ++ end; ++ end ++ else ++ begin ++ bytes:=bytes or (1 shl 25); ++ { set U flag } ++ if oper[0]^.ref^.signindex>=0 then ++ bytes:=bytes or (1 shl 23); ++ bytes:=bytes or getsupreg(oper[0]^.ref^.index); ++ { set shift } ++ with oper[0]^.ref^ do ++ if shiftmode<>SM_None then ++ begin ++ bytes:=bytes or ((shiftimm and $1F) shl 7); ++ if shiftmode<>SM_RRX then ++ bytes:=bytes or (ord(shiftmode) - ord(SM_LSL)) shl 5 ++ else ++ bytes:=bytes or (3 shl 5); ++ end ++ end; ++ end; ++ #$26: // LDM/STM ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 20); ++ ++ if ops>1 then ++ begin ++ if oper[0]^.typ=top_ref then ++ begin ++ { set W bit } ++ if oper[0]^.ref^.addressmode=AM_PREINDEXED then ++ bytes:=bytes or (1 shl 21); ++ { set Rn } ++ bytes:=bytes or (getsupreg(oper[0]^.ref^.index) shl 16); ++ end ++ else { typ=top_reg } ++ begin ++ { set Rn } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16); ++ end; ++ ++ if oper[1]^.usermode then ++ begin ++ if (oper[0]^.typ=top_ref) then ++ begin ++ if (opcode=A_LDM) and ++ (RS_PC in oper[1]^.regset^) then ++ begin ++ // Valid exception return ++ end ++ else ++ Message(asmw_e_invalid_opcode_and_operands); ++ end; ++ ++ bytes:=bytes or (1 shl 22); ++ end; ++ { reglist } ++ bytes:=bytes or MakeRegList(oper[1]^.regset^); ++ end ++ else ++ begin ++ { push/pop } ++ { Set W and Rn to SP } ++ if opcode=A_PUSH then ++ bytes:=bytes or (1 shl 21); ++ bytes:=bytes or ($D shl 16); ++ { reglist } ++ bytes:=bytes or MakeRegList(oper[0]^.regset^); ++ end; ++ { set P bit } ++ if (opcode=A_LDM) and (oppostfix in [PF_ED,PF_EA,PF_IB,PF_DB]) ++ or (opcode=A_STM) and (oppostfix in [PF_FA,PF_FD,PF_IB,PF_DB]) ++ or (opcode=A_PUSH) then ++ bytes:=bytes or (1 shl 24); ++ { set U bit } ++ if (opcode=A_LDM) and (oppostfix in [PF_None,PF_ED,PF_FD,PF_IB,PF_IA]) ++ or (opcode=A_STM) and (oppostfix in [PF_None,PF_FA,PF_EA,PF_IB,PF_IA]) ++ or (opcode=A_POP) then ++ bytes:=bytes or (1 shl 23); ++ end; ++ #$27: // SWP/SWPB ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 20); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 4); ++ { set regs } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ bytes:=bytes or getsupreg(oper[1]^.reg); ++ if ops=3 then ++ bytes:=bytes or (getsupreg(oper[2]^.ref^.base) shl 16); ++ end; ++ #$28: // BX/BLX ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ { set offset } ++ if oper[0]^.typ=top_const then ++ bytes:=bytes or ((oper[0]^.val shr 2) and $ffffff) ++ else ++ begin ++ currsym:=objdata.symbolref(oper[0]^.ref^.symbol); ++ if (currsym.bind<>AB_LOCAL) and (currsym.objsection<>objdata.CurrObjSec) then ++ begin ++ bytes:=bytes or $fffffe; // TODO: Not sure this is right, but it matches the output of gas ++ objdata.writereloc(oper[0]^.ref^.offset,0,currsym,RELOC_RELATIVE_24_THUMB); ++ end ++ else ++ begin ++ offset:=((currsym.offset-insoffset-8) and $3fffffe); ++ ++ { Turn BLX into BL if the destination isn't odd, could happen with recursion } ++ if not odd(offset shr 1) then ++ bytes:=(bytes and $EB000000) or $EB000000; ++ ++ bytes:=bytes or ((offset shr 2) and $ffffff); ++ bytes:=bytes or ((offset shr 1) and $1) shl 24; ++ end; ++ end; ++ end; ++ #$29: // SUB ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ { set regs } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ { set S if necessary } + if oppostfix=PF_S then + bytes:=bytes or (1 shl 20); + end; +- #$ff: +- internalerror(2005091101); +- else +- internalerror(2005091102); +- end; +- { we're finished, write code } +- objdata.writebytes(bytes,sizeof(bytes)); +- end; ++ #$2A: ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set opers } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ if opcode in [A_SSAT, A_SSAT16] then ++ bytes:=bytes or (((oper[1]^.val-1) and $1F) shl 16) ++ else ++ bytes:=bytes or ((oper[1]^.val and $1F) shl 16); ++ bytes:=bytes or getsupreg(oper[2]^.reg); + ++ if (ops>3) and ++ (oper[3]^.typ=top_shifterop) and ++ (oper[3]^.shifterop^.rs=NR_NO) then ++ begin ++ bytes:=bytes or ((oper[3]^.shifterop^.shiftimm and $1F) shl 7); ++ if oper[3]^.shifterop^.shiftmode=SM_ASR then ++ bytes:=bytes or (1 shl 6) ++ else if oper[3]^.shifterop^.shiftmode<>SM_LSL then ++ Message1(asmw_e_invalid_opcode_and_operands,GetString); ++ end; ++ end; ++ #$2B: // SETEND ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set endian specifier } ++ bytes:=bytes or ((oper[0]^.val and 1) shl 9); ++ end; ++ #$2C: // MOVW ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ { set destination } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ { set imm } ++ bytes:=bytes or (oper[1]^.val and $FFF); ++ bytes:=bytes or ((oper[1]^.val and $F000) shl 4); ++ end; ++ #$2D: // BFX ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); + +-{$ifdef dummy} +-(* +-static void gencode (long segment, long offset, int bits, +- insn *ins, char *codes, long insn_end) +-{ +- int has_S_code; /* S - setflag */ +- int has_B_code; /* B - setflag */ +- int has_T_code; /* T - setflag */ +- int has_W_code; /* ! => W flag */ +- int has_F_code; /* ^ => S flag */ +- int keep; +- unsigned char c; +- unsigned char bytes[4]; +- long data, size; +- static int cc_code[] = /* bit pattern of cc */ +- { /* order as enum in */ +- 0x0E, 0x03, 0x02, 0x00, /* nasm.h */ +- 0x0A, 0x0C, 0x08, 0x0D, +- 0x09, 0x0B, 0x04, 0x01, +- 0x05, 0x07, 0x06, +- }; +- +- +-#ifdef DEBUG +-static char *CC[] = +- { /* condition code names */ +- "AL", "CC", "CS", "EQ", +- "GE", "GT", "HI", "LE", +- "LS", "LT", "MI", "NE", +- "PL", "VC", "VS", "", +- "S" +-}; +- +- +- has_S_code = (ins->condition & C_SSETFLAG); +- has_B_code = (ins->condition & C_BSETFLAG); +- has_T_code = (ins->condition & C_TSETFLAG); +- has_W_code = (ins->condition & C_EXSETFLAG); +- has_F_code = (ins->condition & C_FSETFLAG); +- ins->condition = (ins->condition & 0x0F); +- +- +- if (rt_debug) +- { +- printf ("gencode: instruction: %s%s", insn_names[ins->opcode], +- CC[ins->condition & 0x0F]); +- if (has_S_code) +- printf ("S"); +- if (has_B_code) +- printf ("B"); +- if (has_T_code) +- printf ("T"); +- if (has_W_code) +- printf ("!"); +- if (has_F_code) +- printf ("^"); +- +- printf ("\n"); +- +- c = *codes; +- +- printf (" (%d) decode - '0x%02X'\n", ins->operands, c); +- +- +- bytes[0] = 0xB; +- bytes[1] = 0xE; +- bytes[2] = 0xE; +- bytes[3] = 0xF; +- } ++ if ops=3 then ++ begin ++ msb:=(oper[1]^.val+oper[2]^.val-1); + +- // First condition code in upper nibble +- if (ins->condition < C_NONE) +- { +- c = cc_code[ins->condition] << 4; +- } +- else +- { +- c = cc_code[C_AL] << 4; // is often ALWAYS but not always +- } ++ { set destination } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ { set immediates } ++ bytes:=bytes or ((oper[1]^.val and $1F) shl 7); ++ bytes:=bytes or ((msb and $1F) shl 16); ++ end ++ else ++ begin ++ if opcode in [A_BFC,A_BFI] then ++ msb:=(oper[2]^.val+oper[3]^.val-1) ++ else ++ msb:=oper[3]^.val-1; + ++ { set destination } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ bytes:=bytes or getsupreg(oper[1]^.reg); ++ { set immediates } ++ bytes:=bytes or ((oper[2]^.val and $1F) shl 7); ++ bytes:=bytes or ((msb and $1F) shl 16); ++ end; ++ end; ++ #$2E: // Cache stuff ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set code } ++ bytes:=bytes or (oper[0]^.val and $F); ++ end; ++ #$2F: // Nop ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ end; ++ #$30: // Shifts ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set destination } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ bytes:=bytes or getsupreg(oper[1]^.reg); ++ if ops>2 then ++ begin ++ { set shift } ++ if oper[2]^.typ=top_reg then ++ bytes:=bytes or (getsupreg(oper[2]^.reg) shl 8) ++ else ++ bytes:=bytes or ((oper[2]^.val and $1F) shl 7); ++ end; ++ { set S if necessary } ++ if oppostfix=PF_S then ++ bytes:=bytes or (1 shl 20); ++ end; ++ #$31: // BKPT ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 0); ++ { set imm } ++ bytes:=bytes or (oper[0]^.val and $FFF0) shl 4; ++ bytes:=bytes or (oper[0]^.val and $F); ++ end; ++ #$32: // CLZ/REV ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set regs } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ bytes:=bytes or getsupreg(oper[1]^.reg); ++ end; ++ #$33: ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ { set regs } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); + +- switch (keep = *codes) +- { +- case 1: +- // B, BL +- ++codes; +- c |= *codes++; +- bytes[0] = c; +- +- if (ins->oprs[0].segment != segment) +- { +- // fais une relocation +- c = 1; +- data = 0; // Let the linker locate ?? +- } +- else +- { +- c = 0; +- data = ins->oprs[0].offset - (offset + 8); +- +- if (data % 4) +- { +- errfunc (ERR_NONFATAL, "offset not aligned on 4 bytes"); +- } +- } ++ if oper[1]^.typ=top_ref then ++ begin ++ { set offset } ++ offset:=0; ++ currsym:=objdata.symbolref(oper[1]^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=offset+oper[1]^.ref^.offset; ++ if offset>=0 then ++ begin ++ { set U flag } ++ bytes:=bytes or (1 shl 23); ++ bytes:=bytes or offset ++ end ++ else ++ begin ++ bytes:=bytes or (1 shl 22); ++ offset:=-offset; ++ bytes:=bytes or offset ++ end; ++ end ++ else ++ begin ++ if is_shifter_const(oper[1]^.val,r) then ++ begin ++ setshifterop(1); ++ bytes:=bytes or (1 shl 23); ++ end ++ else ++ begin ++ bytes:=bytes or (1 shl 22); ++ oper[1]^.val:=-oper[1]^.val; ++ setshifterop(1); ++ end; ++ end; ++ end; ++ #$40,#$90: // VMOV ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ ++ { set regs } ++ Rd:=0; ++ Rn:=0; ++ Rm:=0; + +- if (data >= 0x1000) +- { +- errfunc (ERR_NONFATAL, "too long offset"); +- } ++ case oppostfix of ++ PF_None: ++ begin ++ if ops=4 then ++ begin ++ if (getregtype(oper[0]^.reg)=R_MMREGISTER) and ++ (getregtype(oper[2]^.reg)=R_INTREGISTER) then ++ begin ++ Rd:=getmmreg(oper[0]^.reg); ++ Rm:=getsupreg(oper[2]^.reg); ++ Rn:=getsupreg(oper[3]^.reg); ++ end ++ else if (getregtype(oper[0]^.reg)=R_INTREGISTER) and ++ (getregtype(oper[2]^.reg)=R_MMREGISTER) then ++ begin ++ Rm:=getsupreg(oper[0]^.reg); ++ Rn:=getsupreg(oper[1]^.reg); ++ Rd:=getmmreg(oper[2]^.reg); ++ end ++ else ++ message(asmw_e_invalid_opcode_and_operands); ++ ++ bytes:=bytes or (((Rd and $1E) shr 1) shl 0); ++ bytes:=bytes or ((Rd and $1) shl 5); ++ ++ bytes:=bytes or (Rm shl 12); ++ bytes:=bytes or (Rn shl 16); ++ end ++ else if ops=3 then ++ begin ++ if (getregtype(oper[0]^.reg)=R_MMREGISTER) and ++ (getregtype(oper[1]^.reg)=R_INTREGISTER) then ++ begin ++ Rd:=getmmreg(oper[0]^.reg); ++ Rm:=getsupreg(oper[1]^.reg); ++ Rn:=getsupreg(oper[2]^.reg); ++ end ++ else if (getregtype(oper[0]^.reg)=R_INTREGISTER) and ++ (getregtype(oper[2]^.reg)=R_MMREGISTER) then ++ begin ++ Rm:=getsupreg(oper[0]^.reg); ++ Rn:=getsupreg(oper[1]^.reg); ++ Rd:=getmmreg(oper[2]^.reg); ++ end ++ else ++ message(asmw_e_invalid_opcode_and_operands); ++ ++ bytes:=bytes or ((Rd and $F) shl 0); ++ bytes:=bytes or ((Rd and $10) shl 1); ++ ++ bytes:=bytes or (Rm shl 12); ++ bytes:=bytes or (Rn shl 16); ++ end ++ else if ops=2 then ++ begin ++ if (getregtype(oper[0]^.reg)=R_MMREGISTER) and ++ (getregtype(oper[1]^.reg)=R_INTREGISTER) then ++ begin ++ Rd:=getmmreg(oper[0]^.reg); ++ Rm:=getsupreg(oper[1]^.reg); ++ end ++ else if (getregtype(oper[0]^.reg)=R_INTREGISTER) and ++ (getregtype(oper[1]^.reg)=R_MMREGISTER) then ++ begin ++ Rm:=getsupreg(oper[0]^.reg); ++ Rd:=getmmreg(oper[1]^.reg); ++ end ++ else ++ message(asmw_e_invalid_opcode_and_operands); + +- data = data >> 2; +- bytes[1] = (data >> 16) & 0xFF; +- bytes[2] = (data >> 8) & 0xFF; +- bytes[3] = (data ) & 0xFF; +- +- if (c == 1) +- { +-// out (offset, segment, &bytes[0], OUT_RAWDATA+1, NO_SEG, NO_SEG); +- out (offset, segment, &bytes[0], OUT_REL3ADR+4, ins->oprs[0].segment, NO_SEG); +- } +- else +- { +- out (offset, segment, &bytes[0], OUT_RAWDATA+4, NO_SEG, NO_SEG); +- } +- return; ++ bytes:=bytes or (((Rd and $1E) shr 1) shl 16); ++ bytes:=bytes or ((Rd and $1) shl 7); + +- case 2: +- // SWI +- ++codes; +- c |= *codes++; +- bytes[0] = c; +- data = ins->oprs[0].offset; +- bytes[1] = (data >> 16) & 0xFF; +- bytes[2] = (data >> 8) & 0xFF; +- bytes[3] = (data) & 0xFF; +- out (offset, segment, &bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +- return; +- case 3: +- // BX +- ++codes; +- c |= *codes++; +- bytes[0] = c; +- bytes[1] = *codes++; +- bytes[2] = *codes++; +- bytes[3] = *codes++; +- c = regval (&ins->oprs[0],1); +- if (c == 15) // PC +- { +- errfunc (ERR_WARNING, "'BX' with R15 has undefined behaviour"); +- } +- else if (c > 15) +- { +- errfunc (ERR_NONFATAL, "Illegal register specified for 'BX'"); +- } ++ bytes:=bytes or (Rm shl 12); ++ end; ++ end; ++ PF_F32: ++ begin ++ if (getregtype(oper[0]^.reg)<>R_MMREGISTER) or ++ (getregtype(oper[1]^.reg)<>R_MMREGISTER) then ++ Message(asmw_e_invalid_opcode_and_operands); + +- bytes[3] |= (c & 0x0F); +- out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +- return; +- +- case 4: // AND Rd,Rn,Rm +- case 5: // AND Rd,Rn,Rm,Rs +- case 6: // AND Rd,Rn,Rm,imm +- case 7: // AND Rd,Rn,imm +- ++codes; +-#ifdef DEBUG +- if (rt_debug) +- { +- printf (" decode - '0x%02X'\n", keep); +- printf (" code - '0x%02X'\n", (unsigned char) ( *codes)); +- } +-#endif +- bytes[0] = c | *codes; +- ++codes; +- +- bytes[1] = *codes; +- if (has_S_code) +- bytes[1] |= 0x10; +- c = regval (&ins->oprs[1],1); +- // Rn in low nibble +- bytes[1] |= c; +- +- // Rd in high nibble +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- +- if (keep != 7) +- { +- // Rm in low nibble +- bytes[3] = regval (&ins->oprs[2],1); +- } ++ Rd:=getmmreg(oper[0]^.reg); ++ Rm:=getmmreg(oper[1]^.reg); + +- // Shifts if any +- if (keep == 5 || keep == 6) +- { +- // Shift in bytes 2 and 3 +- if (keep == 5) +- { +- // Rs +- c = regval (&ins->oprs[3],1); +- bytes[2] |= c; +- +- c = 0x10; // Set bit 4 in byte[3] +- } +- if (keep == 6) +- { +- c = (ins->oprs[3].offset) & 0x1F; +- +- // #imm +- bytes[2] |= c >> 1; +- if (c & 0x01) +- { +- bytes[3] |= 0x80; +- } +- c = 0; // Clr bit 4 in byte[3] +- } +- // +- c |= shiftval (&ins->oprs[3]) << 5; ++ bytes:=bytes or (((Rd and $1E) shr 1) shl 12); ++ bytes:=bytes or ((Rd and $1) shl 22); + +- bytes[3] |= c; +- } ++ bytes:=bytes or (((Rm and $1E) shr 1) shl 0); ++ bytes:=bytes or ((Rm and $1) shl 5); ++ end; ++ PF_F64: ++ begin ++ if (getregtype(oper[0]^.reg)<>R_MMREGISTER) or ++ (getregtype(oper[1]^.reg)<>R_MMREGISTER) then ++ Message(asmw_e_invalid_opcode_and_operands); + +- // reg,reg,imm +- if (keep == 7) +- { +- int shimm; +- +- shimm = imm_shift (ins->oprs[2].offset); +- +- if (shimm == -1) +- { +- errfunc (ERR_NONFATAL, "cannot create that constant"); +- } +- bytes[3] = shimm & 0xFF; +- bytes[2] |= (shimm & 0xF00) >> 8; +- } ++ Rd:=getmmreg(oper[0]^.reg); ++ Rm:=getmmreg(oper[1]^.reg); + +- out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +- return; ++ bytes:=bytes or (1 shl 8); + +- case 8: // MOV Rd,Rm +- case 9: // MOV Rd,Rm,Rs +- case 0xA: // MOV Rd,Rm,imm +- case 0xB: // MOV Rd,imm +- ++codes; +-#ifdef DEBUG +- if (rt_debug) +- { +- printf (" decode - '0x%02X'\n", keep); +- printf (" code - '0x%02X'\n", (unsigned char) ( *codes)); +- } +-#endif +- bytes[0] = c | *codes; +- ++codes; +- +- bytes[1] = *codes; +- if (has_S_code) +- bytes[1] |= 0x10; +- +- // Rd in high nibble +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- +- if (keep != 0x0B) +- { +- // Rm in low nibble +- bytes[3] = regval (&ins->oprs[1],1); +- } ++ bytes:=bytes or ((Rd and $F) shl 12); ++ bytes:=bytes or (((Rd and $10) shr 4) shl 22); + +- // Shifts if any +- if (keep == 0x09 || keep == 0x0A) +- { +- // Shift in bytes 2 and 3 +- if (keep == 0x09) +- { +- // Rs +- c = regval (&ins->oprs[2],1); +- bytes[2] |= c; +- +- c = 0x10; // Set bit 4 in byte[3] +- } +- if (keep == 0x0A) +- { +- c = (ins->oprs[2].offset) & 0x1F; +- +- // #imm +- bytes[2] |= c >> 1; +- if (c & 0x01) +- { +- bytes[3] |= 0x80; +- } +- c = 0; // Clr bit 4 in byte[3] +- } +- // +- c |= shiftval (&ins->oprs[2]) << 5; ++ bytes:=bytes or (Rm and $F); ++ bytes:=bytes or ((Rm and $10) shl 1); ++ end; ++ end; ++ end; ++ #$41,#$91: // VMRS/VMSR ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set regs } ++ if (opcode=A_VMRS) or ++ (opcode=A_FMRX) then ++ begin ++ case oper[1]^.reg of ++ NR_FPSID: Rn:=$0; ++ NR_FPSCR: Rn:=$1; ++ NR_MVFR1: Rn:=$6; ++ NR_MVFR0: Rn:=$7; ++ NR_FPEXC: Rn:=$8; ++ else ++ Rn:=0; ++ message(asmw_e_invalid_opcode_and_operands); ++ end; + +- bytes[3] |= c; +- } ++ bytes:=bytes or (Rn shl 16); + +- // reg,imm +- if (keep == 0x0B) +- { +- int shimm; +- +- shimm = imm_shift (ins->oprs[1].offset); +- +- if (shimm == -1) +- { +- errfunc (ERR_NONFATAL, "cannot create that constant"); +- } +- bytes[3] = shimm & 0xFF; +- bytes[2] |= (shimm & 0xF00) >> 8; +- } ++ if oper[0]^.reg=NR_APSR_nzcv then ++ bytes:=bytes or ($F shl 12) ++ else ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ end ++ else ++ begin ++ case oper[0]^.reg of ++ NR_FPSID: Rn:=$0; ++ NR_FPSCR: Rn:=$1; ++ NR_FPEXC: Rn:=$8; ++ else ++ Rn:=0; ++ message(asmw_e_invalid_opcode_and_operands); ++ end; + +- out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +- return; ++ bytes:=bytes or (Rn shl 16); + ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 12); ++ end; ++ end; ++ #$42,#$92: // VMUL ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set regs } ++ if ops=3 then ++ begin ++ Rd:=getmmreg(oper[0]^.reg); ++ Rn:=getmmreg(oper[1]^.reg); ++ Rm:=getmmreg(oper[2]^.reg); ++ end ++ else if ops=1 then ++ begin ++ Rd:=getmmreg(oper[0]^.reg); ++ Rn:=0; ++ Rm:=0; ++ end ++ else if oper[1]^.typ=top_const then ++ begin ++ Rd:=getmmreg(oper[0]^.reg); ++ Rn:=0; ++ Rm:=0; ++ end ++ else ++ begin ++ Rd:=getmmreg(oper[0]^.reg); ++ Rn:=0; ++ Rm:=getmmreg(oper[1]^.reg); ++ end; + +- case 0xC: // CMP Rn,Rm +- case 0xD: // CMP Rn,Rm,Rs +- case 0xE: // CMP Rn,Rm,imm +- case 0xF: // CMP Rn,imm +- ++codes; ++ if (oppostfix=PF_F32) or (insentry^.code[5]=#1) then ++ begin ++ D:=rd and $1; Rd:=Rd shr 1; ++ N:=rn and $1; Rn:=Rn shr 1; ++ M:=rm and $1; Rm:=Rm shr 1; ++ end ++ else ++ begin ++ D:=(rd shr 4) and $1; Rd:=Rd and $F; ++ N:=(rn shr 4) and $1; Rn:=Rn and $F; ++ M:=(rm shr 4) and $1; Rm:=Rm and $F; + +- bytes[0] = c | *codes++; ++ bytes:=bytes or (1 shl 8); ++ end; + +- bytes[1] = *codes; ++ bytes:=bytes or (Rd shl 12); ++ bytes:=bytes or (Rn shl 16); ++ bytes:=bytes or (Rm shl 0); ++ ++ bytes:=bytes or (D shl 22); ++ bytes:=bytes or (N shl 7); ++ bytes:=bytes or (M shl 5); ++ end; ++ #$43,#$93: // VCVT ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set regs } ++ Rd:=getmmreg(oper[0]^.reg); ++ Rm:=getmmreg(oper[1]^.reg); + +- // Implicit S code +- bytes[1] |= 0x10; ++ if (ops=2) and ++ (oppostfix in [PF_F32F64,PF_F64F32]) then ++ begin ++ if oppostfix=PF_F32F64 then ++ begin ++ bytes:=bytes or (1 shl 8); + +- c = regval (&ins->oprs[0],1); +- // Rn in low nibble +- bytes[1] |= c; ++ D:=rd and $1; Rd:=Rd shr 1; ++ M:=(rm shr 4) and $1; Rm:=Rm and $F; ++ end ++ else ++ begin ++ D:=(rd shr 4) and $1; Rd:=Rd and $F; ++ M:=rm and $1; Rm:=Rm shr 1; ++ end; + +- // No destination +- bytes[2] = 0; ++ bytes:=bytes and $FFF0FFFF; ++ bytes:=bytes or ($7 shl 16); + +- if (keep != 0x0B) +- { +- // Rm in low nibble +- bytes[3] = regval (&ins->oprs[1],1); +- } ++ bytes:=bytes or (Rd shl 12); ++ bytes:=bytes or (Rm shl 0); + +- // Shifts if any +- if (keep == 0x0D || keep == 0x0E) +- { +- // Shift in bytes 2 and 3 +- if (keep == 0x0D) +- { +- // Rs +- c = regval (&ins->oprs[2],1); +- bytes[2] |= c; +- +- c = 0x10; // Set bit 4 in byte[3] +- } +- if (keep == 0x0E) +- { +- c = (ins->oprs[2].offset) & 0x1F; +- +- // #imm +- bytes[2] |= c >> 1; +- if (c & 0x01) +- { +- bytes[3] |= 0x80; +- } +- c = 0; // Clr bit 4 in byte[3] +- } +- // +- c |= shiftval (&ins->oprs[2]) << 5; ++ bytes:=bytes or (D shl 22); ++ bytes:=bytes or (M shl 5); ++ end ++ else if (ops=2) and ++ (oppostfix=PF_None) then ++ begin ++ d:=0; ++ case getsubreg(oper[0]^.reg) of ++ R_SUBNONE: ++ rd:=getsupreg(oper[0]^.reg); ++ R_SUBFS: ++ begin ++ rd:=getmmreg(oper[0]^.reg); + +- bytes[3] |= c; +- } ++ d:=rd and 1; ++ rd:=rd shr 1; ++ end; ++ R_SUBFD: ++ begin ++ rd:=getmmreg(oper[0]^.reg); + +- // reg,imm +- if (keep == 0x0F) +- { +- int shimm; +- +- shimm = imm_shift (ins->oprs[1].offset); +- +- if (shimm == -1) +- { +- errfunc (ERR_NONFATAL, "cannot create that constant"); +- } +- bytes[3] = shimm & 0xFF; +- bytes[2] |= (shimm & 0xF00) >> 8; +- } ++ d:=(rd shr 4) and 1; ++ rd:=rd and $F; ++ end; ++ end; + +- out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +- return; ++ m:=0; ++ case getsubreg(oper[1]^.reg) of ++ R_SUBNONE: ++ rm:=getsupreg(oper[1]^.reg); ++ R_SUBFS: ++ begin ++ rm:=getmmreg(oper[1]^.reg); + +- case 0x10: // MRS Rd, +- ++codes; ++ m:=rm and 1; ++ rm:=rm shr 1; ++ end; ++ R_SUBFD: ++ begin ++ rm:=getmmreg(oper[1]^.reg); + +- bytes[0] = c | *codes++; ++ m:=(rm shr 4) and 1; ++ rm:=rm and $F; ++ end; ++ end; + +- bytes[1] = *codes++; ++ bytes:=bytes or (Rd shl 12); ++ bytes:=bytes or (Rm shl 0); + +- // Rd +- c = regval (&ins->oprs[0],1); ++ bytes:=bytes or (D shl 22); ++ bytes:=bytes or (M shl 5); ++ end ++ else if ops=2 then ++ begin ++ case oppostfix of ++ PF_S32F64, ++ PF_U32F64, ++ PF_F64S32, ++ PF_F64U32: ++ bytes:=bytes or (1 shl 8); ++ end; + +- bytes[2] = c << 4; ++ if oppostfix in [PF_S32F32,PF_S32F64,PF_U32F32,PF_U32F64] then ++ begin ++ case oppostfix of ++ PF_S32F64, ++ PF_S32F32: ++ bytes:=bytes or (1 shl 16); ++ end; + +- bytes[3] = 0; ++ bytes:=bytes or (1 shl 18); + +- c = ins->oprs[1].basereg; ++ D:=rd and $1; Rd:=Rd shr 1; + +- if (c == R_CPSR || c == R_SPSR) +- { +- if (c == R_SPSR) +- { +- bytes[1] |= 0x40; +- } +- } +- else +- { +- errfunc (ERR_NONFATAL, "CPSR or SPSR expected"); +- } ++ if oppostfix in [PF_S32F64,PF_U32F64] then ++ begin ++ M:=(rm shr 4) and $1; Rm:=Rm and $F; ++ end ++ else ++ begin ++ M:=rm and $1; Rm:=Rm shr 1; ++ end; ++ end ++ else ++ begin ++ case oppostfix of ++ PF_F64S32, ++ PF_F32S32: ++ bytes:=bytes or (1 shl 7); ++ else ++ bytes:=bytes and $FFFFFF7F; ++ end; + +- out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); ++ M:=rm and $1; Rm:=Rm shr 1; + +- return; ++ if oppostfix in [PF_F64S32,PF_F64U32] then ++ begin ++ D:=(rd shr 4) and $1; Rd:=Rd and $F; ++ end ++ else ++ begin ++ D:=rd and $1; Rd:=Rd shr 1; ++ end ++ end; + +- case 0x11: // MSR ,Rm +- case 0x12: // MSR ,Rm +- case 0x13: // MSR ,#expression +- ++codes; ++ bytes:=bytes or (Rd shl 12); ++ bytes:=bytes or (Rm shl 0); + +- bytes[0] = c | *codes++; ++ bytes:=bytes or (D shl 22); ++ bytes:=bytes or (M shl 5); ++ end ++ else ++ begin ++ if rd<>rm then ++ message(asmw_e_invalid_opcode_and_operands); + +- bytes[1] = *codes++; ++ case oppostfix of ++ PF_S32F32,PF_U32F32, ++ PF_F32S32,PF_F32U32, ++ PF_S32F64,PF_U32F64, ++ PF_F64S32,PF_F64U32: ++ begin ++ if not (oper[2]^.val in [1..32]) then ++ message1(asmw_e_invalid_opcode_and_operands, 'fbits not within 1-32'); + +- bytes[2] = *codes; ++ bytes:=bytes or (1 shl 7); ++ rn:=32; ++ end; ++ PF_S16F64,PF_U16F64, ++ PF_F64S16,PF_F64U16, ++ PF_S16F32,PF_U16F32, ++ PF_F32S16,PF_F32U16: ++ begin ++ if not (oper[2]^.val in [0..16]) then ++ message1(asmw_e_invalid_opcode_and_operands, 'fbits not within 0-16'); + ++ rn:=16; ++ end; ++ else ++ Rn:=0; ++ message(asmw_e_invalid_opcode_and_operands); ++ end; + +- if (keep == 0x11 || keep == 0x12) +- { +- // Rm +- c = regval (&ins->oprs[1],1); ++ case oppostfix of ++ PF_S16F64,PF_U16F64, ++ PF_S32F64,PF_U32F64, ++ PF_F64S16,PF_F64U16, ++ PF_F64S32,PF_F64U32: ++ begin ++ bytes:=bytes or (1 shl 8); ++ D:=(rd shr 4) and $1; Rd:=Rd and $F; ++ end; ++ else ++ begin ++ D:=rd and $1; Rd:=Rd shr 1; ++ end; ++ end; + +- bytes[3] = c; +- } +- else +- { +- int shimm; ++ case oppostfix of ++ PF_U16F64,PF_U16F32, ++ PF_U32F32,PF_U32F64, ++ PF_F64U16,PF_F32U16, ++ PF_F32U32,PF_F64U32: ++ bytes:=bytes or (1 shl 16); ++ end; + +- shimm = imm_shift (ins->oprs[1].offset); ++ if oppostfix in [PF_S32F32,PF_S32F64,PF_U32F32,PF_U32F64,PF_S16F32,PF_S16F64,PF_U16F32,PF_U16F64] then ++ bytes:=bytes or (1 shl 18); + +- if (shimm == -1) +- { +- errfunc (ERR_NONFATAL, "cannot create that constant"); +- } +- bytes[3] = shimm & 0xFF; +- bytes[2] |= (shimm & 0xF00) >> 8; +- } ++ bytes:=bytes or (Rd shl 12); ++ bytes:=bytes or (D shl 22); + +- c = ins->oprs[0].basereg; ++ rn:=rn-oper[2]^.val; + +- if ( keep == 0x11) +- { +- if ( c == R_CPSR || c == R_SPSR) +- { +- if ( c== R_SPSR) +- { +- bytes[1] |= 0x40; +- } +- } +- else +- { +- errfunc (ERR_NONFATAL, "CPSR or SPSR expected"); +- } +- } +- else +- { +- if ( c == R_CPSR_FLG || c == R_SPSR_FLG) +- { +- if ( c== R_SPSR_FLG) +- { +- bytes[1] |= 0x40; +- } +- } +- else +- { +- errfunc (ERR_NONFATAL, "CPSR_flg or SPSR_flg expected"); +- } +- } +- break; ++ bytes:=bytes or ((rn and $1) shl 5); ++ bytes:=bytes or ((rn and $1E) shr 1); ++ end; ++ end; ++ #$44,#$94: // VLDM/VSTM/VPUSH/VPOP ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ { set regs } ++ if ops=2 then ++ begin ++ if oper[0]^.typ=top_ref then ++ begin ++ Rn:=getsupreg(oper[0]^.ref^.index); + +- case 0x14: // MUL Rd,Rm,Rs +- case 0x15: // MULA Rd,Rm,Rs,Rn +- ++codes; ++ if oper[0]^.ref^.addressmode<>AM_OFFSET then ++ begin ++ { set W } ++ bytes:=bytes or (1 shl 21); ++ end ++ else if oppostfix in [PF_DB,PF_DBS,PF_DBD,PF_DBX] then ++ message1(asmw_e_invalid_opcode_and_operands, 'Invalid postfix without writeback'); ++ end ++ else ++ begin ++ Rn:=getsupreg(oper[0]^.reg); + +- bytes[0] = c | *codes++; ++ if oppostfix in [PF_DB,PF_DBS,PF_DBD,PF_DBX] then ++ message1(asmw_e_invalid_opcode_and_operands, 'Invalid postfix without writeback'); ++ end; + +- bytes[1] = *codes++; ++ bytes:=bytes or (Rn shl 16); + +- bytes[3] = *codes; ++ { Set PU bits } ++ case oppostfix of ++ PF_None, ++ PF_IA,PF_IAS,PF_IAD,PF_IAX: ++ bytes:=bytes or (1 shl 23); ++ PF_DB,PF_DBS,PF_DBD,PF_DBX: ++ bytes:=bytes or (2 shl 23); ++ end; + +- // Rd +- bytes[1] |= regval (&ins->oprs[0],1); +- if (has_S_code) +- bytes[1] |= 0x10; ++ case oppostfix of ++ PF_IAX,PF_DBX,PF_FDX,PF_EAX: ++ begin ++ bytes:=bytes or (1 shl 8); ++ bytes:=bytes or (1 shl 0); // Offset is odd ++ end; ++ end; + +- // Rm +- bytes[3] |= regval (&ins->oprs[1],1); ++ dp_operation:=(oper[1]^.subreg=R_SUBFD); ++ if oper[1]^.regset^=[] then ++ message1(asmw_e_invalid_opcode_and_operands, 'Regset cannot be empty'); ++ ++ rd:=0; ++ for r:=0 to 31 do ++ if r in oper[1]^.regset^ then ++ begin ++ rd:=r; ++ break; ++ end; + +- // Rs +- bytes[2] = regval (&ins->oprs[2],1); ++ rn:=32-rd; ++ for r:=rd+1 to 31 do ++ if not(r in oper[1]^.regset^) then ++ begin ++ rn:=r-rd; ++ break; ++ end; + +- if (keep == 0x15) +- { +- bytes[2] |= regval (&ins->oprs[3],1) << 4; +- } +- break; ++ if dp_operation then ++ begin ++ bytes:=bytes or (1 shl 8); + +- case 0x16: // SMLAL RdHi,RdLo,Rm,Rs +- ++codes; ++ bytes:=bytes or (rn*2); + +- bytes[0] = c | *codes++; ++ bytes:=bytes or ((rd and $F) shl 12); ++ bytes:=bytes or (((rd and $10) shr 4) shl 22); ++ end ++ else ++ begin ++ bytes:=bytes or rn; + +- bytes[1] = *codes++; ++ bytes:=bytes or ((rd and $1) shl 22); ++ bytes:=bytes or (((rd and $1E) shr 1) shl 12); ++ end; ++ end ++ else { VPUSH/VPOP } ++ begin ++ dp_operation:=(oper[0]^.subreg=R_SUBFD); ++ if oper[0]^.regset^=[] then ++ message1(asmw_e_invalid_opcode_and_operands, 'Regset cannot be empty'); ++ ++ rd:=0; ++ for r:=0 to 31 do ++ if r in oper[0]^.regset^ then ++ begin ++ rd:=r; ++ break; ++ end; + +- bytes[3] = *codes; ++ rn:=32-rd; ++ for r:=rd+1 to 31 do ++ if not(r in oper[0]^.regset^) then ++ begin ++ rn:=r-rd; ++ break; ++ end; + +- // RdHi +- bytes[1] |= regval (&ins->oprs[1],1); +- if (has_S_code) +- bytes[1] |= 0x10; ++ if dp_operation then ++ begin ++ bytes:=bytes or (1 shl 8); + +- // RdLo +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- // Rm +- bytes[3] |= regval (&ins->oprs[2],1); ++ bytes:=bytes or (rn*2); + +- // Rs +- bytes[2] |= regval (&ins->oprs[3],1); ++ bytes:=bytes or ((rd and $F) shl 12); ++ bytes:=bytes or (((rd and $10) shr 4) shl 22); ++ end ++ else ++ begin ++ bytes:=bytes or rn; + +- break; ++ bytes:=bytes or ((rd and $1) shl 22); ++ bytes:=bytes or (((rd and $1E) shr 1) shl 12); ++ end; ++ end; ++ end; ++ #$45,#$95: // VLDR/VSTR ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ { set regs } ++ rd:=getmmreg(oper[0]^.reg); + +- case 0x17: // LDR Rd, expression +- ++codes; ++ if getsubreg(oper[0]^.reg)=R_SUBFD then ++ begin ++ bytes:=bytes or (1 shl 8); + +- bytes[0] = c | *codes++; ++ bytes:=bytes or ((rd and $F) shl 12); ++ bytes:=bytes or (((rd and $10) shr 4) shl 22); ++ end ++ else ++ begin ++ bytes:=bytes or (((rd and $1E) shr 1) shl 12); ++ bytes:=bytes or ((rd and $1) shl 22); ++ end; + +- bytes[1] = *codes++; ++ { set ref } ++ bytes:=bytes or getsupreg(oper[1]^.ref^.base) shl 16; ++ if getregtype(oper[1]^.ref^.index)=R_INVALIDREGISTER then ++ begin ++ { set offset } ++ offset:=0; ++ currsym:=objdata.symbolref(oper[1]^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=offset+oper[1]^.ref^.offset; + +- // Rd +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- if (has_B_code) +- bytes[1] |= 0x40; +- if (has_T_code) +- { +- errfunc (ERR_NONFATAL, "'T' not allowed in pre-index mode"); +- } +- if (has_W_code) +- { +- errfunc (ERR_NONFATAL, "'!' not allowed"); +- } ++ offset:=offset div 4; + +- // Rn - implicit R15 +- bytes[1] |= 0xF; ++ if offset>=0 then ++ begin ++ { set U flag } ++ bytes:=bytes or (1 shl 23); ++ bytes:=bytes or offset ++ end ++ else ++ begin ++ offset:=-offset; ++ bytes:=bytes or offset ++ end; ++ end ++ else ++ message(asmw_e_invalid_opcode_and_operands); ++ end; ++ #$46: { System instructions } ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ { set regs } ++ if (oper[0]^.typ=top_modeflags) then ++ begin ++ if mfA in oper[0]^.modeflags then bytes:=bytes or (1 shl 8); ++ if mfI in oper[0]^.modeflags then bytes:=bytes or (1 shl 7); ++ if mfF in oper[0]^.modeflags then bytes:=bytes or (1 shl 6); ++ end; + +- if (ins->oprs[1].segment != segment) +- { +- errfunc (ERR_NONFATAL, "label not in same segment"); +- } ++ if (ops=2) then ++ bytes:=bytes or (oper[1]^.val and $1F) ++ else if (ops=1) and ++ (oper[0]^.typ=top_const) then ++ bytes:=bytes or (oper[0]^.val and $1F); ++ end; ++ #$60: { Thumb } ++ begin ++ bytelen:=2; ++ bytes:=0; + +- data = ins->oprs[1].offset - (offset + 8); ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 8); ++ bytes:=bytes or ord(insentry^.code[2]); ++ { set regs } ++ if ops=2 then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7); ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 3); ++ if (oper[1]^.typ=top_reg) then ++ bytes:=bytes or ((getsupreg(oper[1]^.reg) and $7) shl 6) ++ else ++ bytes:=bytes or ((oper[1]^.val and $1F) shl 6); ++ end ++ else if ops=3 then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 3); ++ if (oper[2]^.typ=top_reg) then ++ bytes:=bytes or ((getsupreg(oper[2]^.reg) and $7) shl 6) ++ else ++ bytes:=bytes or ((oper[2]^.val and $1F) shl 6); ++ end ++ else if ops=1 then ++ begin ++ if oper[0]^.typ=top_const then ++ bytes:=bytes or (oper[0]^.val and $FF); ++ end; ++ end; ++ #$61: { Thumb } ++ begin ++ bytelen:=2; ++ bytes:=0; + +- if (data < 0) +- { +- data = -data; +- } +- else +- { +- bytes[1] |= 0x80; +- } ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 8); ++ bytes:=bytes or ord(insentry^.code[2]); ++ { set regs } ++ if ops=2 then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7); ++ bytes:=bytes or ((getsupreg(oper[0]^.reg) and $8) shr 3) shl 7; + +- if (data >= 0x1000) +- { +- errfunc (ERR_NONFATAL, "too long offset"); +- } ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 3); ++ end ++ else if ops=1 then ++ begin ++ if oper[0]^.typ=top_const then ++ bytes:=bytes or (oper[0]^.val and $FF); ++ end; ++ end; ++ #$62..#$63: { Thumb branches } ++ begin ++ bytelen:=2; ++ bytes:=0; + +- bytes[2] |= ((data & 0xF00) >> 8); +- bytes[3] = data & 0xFF; +- break; +- +- case 0x18: // LDR Rd, [Rn] +- ++codes; +- +- bytes[0] = c | *codes++; +- +- bytes[1] = *codes++; +- +- // Rd +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- if (has_B_code) +- bytes[1] |= 0x40; +- if (has_T_code) +- { +- bytes[1] |= 0x20; // write-back +- } +- else +- { +- bytes[0] |= 0x01; // implicit pre-index mode +- } ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 8); ++ bytes:=bytes or ord(insentry^.code[2]); + +- if (has_W_code) +- { +- bytes[1] |= 0x20; // write-back +- } ++ if insentry^.code[0]=#$63 then ++ bytes:=bytes or (CondVal[condition] shl 8); + +- // Rn +- c = regval (&ins->oprs[1],1); +- bytes[1] |= c; ++ if oper[0]^.typ=top_const then ++ begin ++ if insentry^.code[0]=#$63 then ++ bytes:=bytes or (((oper[0]^.val shr 1)-1) and $FF) ++ else ++ bytes:=bytes or (((oper[0]^.val shr 1)-1) and $3FF); ++ end ++ else if oper[0]^.typ=top_reg then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 3); ++ end ++ else if oper[0]^.typ=top_ref then ++ begin ++ offset:=0; ++ currsym:=objdata.symbolref(oper[0]^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=offset+oper[0]^.ref^.offset; + +- if (c == 0x15) // R15 +- data = -8; +- else +- data = 0; ++ if insentry^.code[0]=#$63 then ++ bytes:=bytes or (((offset+4) shr 1) and $FF) ++ else ++ bytes:=bytes or (((offset+4) shr 1) and $7FF); ++ end ++ end; ++ #$64: { Thumb: Special encodings } ++ begin ++ bytelen:=2; ++ bytes:=0; + +- if (data < 0) +- { +- data = -data; +- } +- else +- { +- bytes[1] |= 0x80; +- } ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 8); ++ bytes:=bytes or ord(insentry^.code[2]); + +- bytes[2] |= ((data & 0xF00) >> 8); +- bytes[3] = data & 0xFF; +- break; +- +- case 0x19: // LDR Rd, [Rn,#expression] +- case 0x20: // LDR Rd, [Rn,Rm] +- case 0x21: // LDR Rd, [Rn,Rm,shift] +- ++codes; +- +- bytes[0] = c | *codes++; +- +- bytes[1] = *codes++; +- +- // Rd +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- if (has_B_code) +- bytes[1] |= 0x40; +- +- // Rn +- c = regval (&ins->oprs[1],1); +- bytes[1] |= c; +- +- if (ins->oprs[ins->operands-1].bracket) // FIXME: Bracket on last operand -> pre-index <-- +- { +- bytes[0] |= 0x01; // pre-index mode +- if (has_W_code) +- { +- bytes[1] |= 0x20; +- } +- if (has_T_code) +- { +- errfunc (ERR_NONFATAL, "'T' not allowed in pre-index mode"); +- } +- } +- else +- { +- if (has_T_code) // Forced write-back in post-index mode +- { +- bytes[1] |= 0x20; +- } +- if (has_W_code) +- { +- errfunc (ERR_NONFATAL, "'!' not allowed in post-index mode"); +- } +- } + +- if (keep == 0x19) +- { +- data = ins->oprs[2].offset; +- +- if (data < 0) +- { +- data = -data; +- } +- else +- { +- bytes[1] |= 0x80; +- } +- +- if (data >= 0x1000) +- { +- errfunc (ERR_NONFATAL, "too long offset"); +- } ++ case opcode of ++ A_SUB: ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7); ++ if (ops=3) and ++ (oper[2]^.typ=top_const) then ++ bytes:=bytes or ((oper[2]^.val shr 2) and $7F) ++ else if (ops=2) and ++ (oper[1]^.typ=top_const) then ++ bytes:=bytes or ((oper[1]^.val shr 2) and $7F); ++ end; ++ A_MUL: ++ if (ops in [2,3]) then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 3); ++ end; ++ A_ADD: ++ begin ++ if ops=2 then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl $3); ++ end ++ else if (oper[0]^.reg<>NR_STACK_POINTER_REG) and ++ (oper[2]^.typ=top_const) then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7) shl 8; ++ bytes:=bytes or ((oper[2]^.val shr 2) and $7F); ++ end ++ else if (oper[0]^.reg<>NR_STACK_POINTER_REG) and ++ (oper[2]^.typ=top_reg) then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7); ++ bytes:=bytes or ((getsupreg(oper[0]^.reg) and $8) shr 3) shl 7; ++ end ++ else ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7); ++ bytes:=bytes or ((oper[2]^.val shr 2) and $7F); ++ end; ++ end; ++ end; ++ end; ++ #$65: { Thumb load/store } ++ begin ++ bytelen:=2; ++ bytes:=0; + +- bytes[2] |= ((data & 0xF00) >> 8); +- bytes[3] = data & 0xFF; +- } +- else +- { +- if (ins->oprs[2].minus == 0) +- { +- bytes[1] |= 0x80; +- } +- c = regval (&ins->oprs[2],1); +- bytes[3] = c; +- +- if (keep == 0x21) +- { +- c = ins->oprs[3].offset; +- if (c > 0x1F) +- { +- errfunc (ERR_NONFATAL, "too large shiftvalue"); +- c = c & 0x1F; +- } +- +- bytes[2] |= c >> 1; +- if (c & 0x01) +- { +- bytes[3] |= 0x80; +- } +- bytes[3] |= shiftval (&ins->oprs[3]) << 5; +- } +- } ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 8); ++ bytes:=bytes or ord(insentry^.code[2]); ++ { set regs } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7); ++ bytes:=bytes or (getsupreg(oper[1]^.ref^.base) shl 3); ++ bytes:=bytes or (getsupreg(oper[1]^.ref^.index) shl 6); ++ end; ++ #$66: { Thumb load/store } ++ begin ++ bytelen:=2; ++ bytes:=0; + +- break; ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 8); ++ bytes:=bytes or ord(insentry^.code[2]); ++ { set regs } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7); ++ bytes:=bytes or (getsupreg(oper[1]^.ref^.base) shl 3); ++ bytes:=bytes or (((oper[1]^.ref^.offset shr ord(insentry^.code[3])) and $1F) shl 6); ++ end; ++ #$67: { Thumb load/store } ++ begin ++ bytelen:=2; ++ bytes:=0; + +- case 0x22: // LDRH Rd, expression +- ++codes; ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 8); ++ bytes:=bytes or ord(insentry^.code[2]); ++ { set regs } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ if oper[1]^.typ=top_ref then ++ bytes:=bytes or ((oper[1]^.ref^.offset shr ord(insentry^.code[3])) and $FF) ++ else ++ bytes:=bytes or ((oper[1]^.val shr ord(insentry^.code[3])) and $FF); ++ end; ++ #$68: { Thumb CB[N]Z } ++ begin ++ bytelen:=2; ++ bytes:=0; + +- bytes[0] = c | 0x01; // Implicit pre-index ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 8); ++ { set opers } ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7); + +- bytes[1] = *codes++; ++ if oper[1]^.typ=top_ref then ++ begin ++ offset:=0; ++ currsym:=objdata.symbolref(oper[1]^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=offset+oper[1]^.ref^.offset; + +- // Rd +- bytes[2] = regval (&ins->oprs[0],1) << 4; ++ offset:=offset div 2; ++ end ++ else ++ offset:=oper[1]^.val div 2; + +- // Rn - implicit R15 +- bytes[1] |= 0xF; ++ bytes:=bytes or ((offset) and $1F) shl 3; ++ bytes:=bytes or ((offset shr 5) and 1) shl 9; ++ end; ++ #$69: { Thumb: Push/Pop/Stm/Ldm } ++ begin ++ bytelen:=2; ++ bytes:=0; + +- if (ins->oprs[1].segment != segment) +- { +- errfunc (ERR_NONFATAL, "label not in same segment"); +- } ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 8); + +- data = ins->oprs[1].offset - (offset + 8); ++ case opcode of ++ A_PUSH: ++ begin ++ for r:=0 to 7 do ++ if r in oper[0]^.regset^ then ++ bytes:=bytes or (1 shl r); ++ if RS_R14 in oper[0]^.regset^ then ++ bytes:=bytes or (1 shl 8); ++ end; ++ A_POP: ++ begin ++ for r:=0 to 7 do ++ if r in oper[0]^.regset^ then ++ bytes:=bytes or (1 shl r); ++ if RS_R15 in oper[0]^.regset^ then ++ bytes:=bytes or (1 shl 8); ++ end; ++ A_STM: ++ begin ++ for r:=0 to 7 do ++ if r in oper[1]^.regset^ then ++ bytes:=bytes or (1 shl r); + +- if (data < 0) +- { +- data = -data; +- } +- else +- { +- bytes[1] |= 0x80; +- } ++ if oper[0]^.typ=top_ref then ++ bytes:=bytes or (getsupreg(oper[0]^.ref^.base) shl 8) ++ else ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ end; ++ A_LDM: ++ begin ++ for r:=0 to 7 do ++ if r in oper[1]^.regset^ then ++ bytes:=bytes or (1 shl r); + +- if (data >= 0x100) +- { +- errfunc (ERR_NONFATAL, "too long offset"); +- } +- bytes[3] = *codes++; ++ if oper[0]^.typ=top_ref then ++ bytes:=bytes or (getsupreg(oper[0]^.ref^.base) shl 8) ++ else ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ end; ++ end; ++ end; ++ #$6A: { Thumb: IT } ++ begin ++ bytelen:=2; ++ bytes:=0; + +- bytes[2] |= ((data & 0xF0) >> 4); +- bytes[3] |= data & 0xF; +- break; ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 8); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 0); + +- case 0x23: // LDRH Rd, Rn +- ++codes; ++ bytes:=bytes or (CondVal[oper[0]^.cc] shl 4); + +- bytes[0] = c | 0x01; // Implicit pre-index ++ i_field:=(bytes shr 4) and 1; ++ i_field:=(i_field shl 1) or i_field; ++ i_field:=(i_field shl 2) or i_field; + +- bytes[1] = *codes++; ++ bytes:=bytes or ((i_field and ord(insentry^.code[3])) xor (ord(insentry^.code[3]) shr 4)); ++ end; ++ #$6B: { Thumb: Data processing (misc) } ++ begin ++ bytelen:=2; ++ bytes:=0; + +- // Rd +- bytes[2] = regval (&ins->oprs[0],1) << 4; ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 8); ++ bytes:=bytes or ord(insentry^.code[2]); ++ { set regs } ++ if ops>=2 then ++ begin ++ if oper[1]^.typ=top_const then ++ begin ++ bytes:=bytes or ((getsupreg(oper[0]^.reg) and $7) shl 8); ++ bytes:=bytes or (oper[1]^.val and $FF); ++ end ++ else if oper[1]^.typ=top_reg then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) and $7); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 3); ++ end; ++ end ++ else if ops=1 then ++ begin ++ if oper[0]^.typ=top_const then ++ bytes:=bytes or (oper[0]^.val and $FF); ++ end; ++ end; ++ #$6C: { Thumb: CPS } ++ begin ++ bytelen:=2; ++ bytes:=0; + +- // Rn +- c = regval (&ins->oprs[1],1); +- bytes[1] |= c; ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 8); ++ bytes:=bytes or ord(insentry^.code[2]); ++ ++ if mfA in oper[0]^.modeflags then bytes:=bytes or (1 shl 2); ++ if mfI in oper[0]^.modeflags then bytes:=bytes or (1 shl 1); ++ if mfF in oper[0]^.modeflags then bytes:=bytes or (1 shl 0); ++ end; ++ #$80: { Thumb-2: Dataprocessing } ++ begin ++ bytes:=0; ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); + +- if (c == 0x15) // R15 +- data = -8; +- else +- data = 0; ++ if ops=1 then ++ begin ++ if oper[0]^.typ=top_reg then ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16) ++ else if oper[0]^.typ=top_const then ++ bytes:=bytes or (oper[0]^.val and $F); ++ end ++ else if (ops=2) and ++ (opcode in [A_CMP,A_CMN,A_TEQ,A_TST]) then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16); + +- if (data < 0) +- { +- data = -data; +- } +- else +- { +- bytes[1] |= 0x80; +- } ++ if oper[1]^.typ=top_const then ++ encodethumbimm(oper[1]^.val) ++ else if oper[1]^.typ=top_reg then ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 0); ++ end ++ else if (ops=3) and ++ (opcode in [A_CMP,A_CMN,A_TEQ,A_TST]) then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 0); + +- if (data >= 0x100) +- { +- errfunc (ERR_NONFATAL, "too long offset"); +- } +- bytes[3] = *codes++; ++ if oper[2]^.typ=top_shifterop then ++ setthumbshift(2) ++ else if oper[2]^.typ=top_reg then ++ bytes:=bytes or (getsupreg(oper[2]^.reg) shl 12); ++ end ++ else if (ops=2) and ++ (opcode in [A_REV,A_RBIT,A_REV16,A_REVSH,A_CLZ]) then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 16); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 0); ++ end ++ else if ops=2 then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16); + +- bytes[2] |= ((data & 0xF0) >> 4); +- bytes[3] |= data & 0xF; +- break; +- +- case 0x24: // LDRH Rd, Rn, expression +- case 0x25: // LDRH Rd, Rn, Rm +- ++codes; +- +- bytes[0] = c; +- +- bytes[1] = *codes++; +- +- // Rd +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- +- // Rn +- c = regval (&ins->oprs[1],1); +- bytes[1] |= c; +- +- if (ins->oprs[ins->operands-1].bracket) // FIXME: Bracket on last operand -> pre-index <-- +- { +- bytes[0] |= 0x01; // pre-index mode +- if (has_W_code) +- { +- bytes[1] |= 0x20; +- } +- } +- else +- { +- if (has_W_code) +- { +- errfunc (ERR_NONFATAL, "'!' not allowed in post-index mode"); +- } +- } ++ if oper[1]^.typ=top_const then ++ encodethumbimm(oper[1]^.val) ++ else if oper[1]^.typ=top_reg then ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 0); ++ end ++ else if ops=3 then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 16); + +- bytes[3] = *codes++; ++ if oper[2]^.typ=top_const then ++ encodethumbimm(oper[2]^.val) ++ else if oper[2]^.typ=top_reg then ++ bytes:=bytes or (getsupreg(oper[2]^.reg) shl 0); ++ end ++ else if ops=4 then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 16); ++ bytes:=bytes or (getsupreg(oper[2]^.reg) shl 0); ++ ++ if oper[3]^.typ=top_shifterop then ++ setthumbshift(3) ++ else if oper[3]^.typ=top_reg then ++ bytes:=bytes or (getsupreg(oper[3]^.reg) shl 12); ++ end; + +- if (keep == 0x24) +- { +- data = ins->oprs[2].offset; +- +- if (data < 0) +- { +- data = -data; +- } +- else +- { +- bytes[1] |= 0x80; +- } +- +- if (data >= 0x100) +- { +- errfunc (ERR_NONFATAL, "too long offset"); +- } ++ if oppostfix=PF_S then ++ bytes:=bytes or (1 shl 20) ++ else if oppostfix=PF_X then ++ bytes:=bytes or (1 shl 4) ++ else if oppostfix=PF_R then ++ bytes:=bytes or (1 shl 4); ++ end; ++ #$81: { Thumb-2: Dataprocessing misc } ++ begin ++ bytes:=0; ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); + +- bytes[2] |= ((data & 0xF0) >> 4); +- bytes[3] |= data & 0xF; +- } +- else +- { +- if (ins->oprs[2].minus == 0) +- { +- bytes[1] |= 0x80; +- } +- c = regval (&ins->oprs[2],1); +- bytes[3] |= c; ++ if ops=3 then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 16); + +- } +- break; ++ if oper[2]^.typ=top_const then ++ begin ++ bytes:=bytes or (oper[2]^.val and $FF); ++ bytes:=bytes or ((oper[2]^.val and $700) shr 8) shl 12; ++ bytes:=bytes or ((oper[2]^.val and $800) shr 11) shl 26; ++ end; ++ end ++ else if ops=2 then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); + +- case 0x26: // LDM/STM Rn, {reg-list} +- ++codes; ++ offset:=0; ++ if oper[1]^.typ=top_const then ++ begin ++ offset:=oper[1]^.val; ++ end ++ else if oper[1]^.typ=top_ref then ++ begin ++ currsym:=objdata.symbolref(oper[1]^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=offset+oper[1]^.ref^.offset; + +- bytes[0] = c; ++ offset:=offset; ++ end; + +- bytes[0] |= ( *codes >> 4) & 0xF; +- bytes[1] = ( *codes << 4) & 0xF0; +- ++codes; ++ bytes:=bytes or (offset and $FF); ++ bytes:=bytes or ((offset and $700) shr 8) shl 12; ++ bytes:=bytes or ((offset and $800) shr 11) shl 26; ++ bytes:=bytes or ((offset and $F000) shr 12) shl 16; ++ end; + +- if (has_W_code) +- { +- bytes[1] |= 0x20; +- } +- if (has_F_code) +- { +- bytes[1] |= 0x40; +- } ++ if oppostfix=PF_S then ++ bytes:=bytes or (1 shl 20); ++ end; ++ #$82: { Thumb-2: Shifts } ++ begin ++ bytes:=0; ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); + +- // Rn +- bytes[1] |= regval (&ins->oprs[0],1); ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ if oper[1]^.typ=top_reg then ++ begin ++ offset:=2; ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 0); ++ end ++ else ++ begin ++ offset:=1; ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 0); ++ end; + +- data = ins->oprs[1].basereg; ++ if oper[offset]^.typ=top_const then ++ begin ++ bytes:=bytes or (oper[offset]^.val and $3) shl 6; ++ bytes:=bytes or (oper[offset]^.val and $1C) shl 10; ++ end ++ else if oper[offset]^.typ=top_reg then ++ bytes:=bytes or (getsupreg(oper[offset]^.reg) shl 16); ++ ++ if (ops>=(offset+2)) and ++ (oper[offset+1]^.typ=top_const) then ++ bytes:=bytes or (oper[offset+1]^.val and $1F); + +- bytes[2] = ((data >> 8) & 0xFF); +- bytes[3] = (data & 0xFF); ++ if oppostfix=PF_S then ++ bytes:=bytes or (1 shl 20); ++ end; ++ #$84: { Thumb-2: Shifts(width-1) } ++ begin ++ bytes:=0; ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); + +- break; ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ if oper[1]^.typ=top_reg then ++ begin ++ offset:=2; ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 16); ++ end ++ else ++ offset:=1; + +- case 0x27: // SWP Rd, Rm, [Rn] +- ++codes; ++ if oper[offset]^.typ=top_const then ++ begin ++ bytes:=bytes or (oper[offset]^.val and $3) shl 6; ++ bytes:=bytes or (oper[offset]^.val and $1C) shl 10; ++ end; + +- bytes[0] = c; ++ if (ops>=(offset+2)) and ++ (oper[offset+1]^.typ=top_const) then ++ begin ++ if opcode in [A_BFI,A_BFC] then ++ i_field:=oper[offset+1]^.val+oper[offset]^.val-1 ++ else ++ i_field:=oper[offset+1]^.val-1; + +- bytes[0] |= *codes++; ++ bytes:=bytes or (i_field and $1F); ++ end; + +- bytes[1] = regval (&ins->oprs[2],1); +- if (has_B_code) +- { +- bytes[1] |= 0x40; +- } +- bytes[2] = regval (&ins->oprs[0],1) << 4; +- bytes[3] = *codes++; +- bytes[3] |= regval (&ins->oprs[1],1); +- break; +- +- default: +- errfunc (ERR_FATAL, "unknown decoding of instruction"); +- +- bytes[0] = c; +- // And a fix nibble +- ++codes; +- bytes[0] |= *codes++; +- +- if ( *codes == 0x01) // An I bit +- { +- +- } +- if ( *codes == 0x02) // An I bit +- { ++ if oppostfix=PF_S then ++ bytes:=bytes or (1 shl 20); ++ end; ++ #$83: { Thumb-2: Saturation } ++ begin ++ bytes:=0; ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ bytes:=bytes or (oper[1]^.val and $1F); ++ bytes:=bytes or (getsupreg(oper[2]^.reg) shl 16); + +- } +- ++codes; +- } +- out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG); +-} ++ if ops=4 then ++ setthumbshift(3,true); ++ end; ++ #$85: { Thumb-2: Long multiplications } ++ begin ++ bytes:=0; ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); + +-*) +-{$endif dummy} ++ if ops=4 then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 8); ++ bytes:=bytes or (getsupreg(oper[2]^.reg) shl 16); ++ bytes:=bytes or (getsupreg(oper[3]^.reg) shl 0); ++ end; + +- constructor tai_thumb_func.create; +- begin +- inherited create; +- typ:=ait_thumb_func; +- end; ++ if oppostfix=PF_S then ++ bytes:=bytes or (1 shl 20) ++ else if oppostfix=PF_X then ++ bytes:=bytes or (1 shl 4); ++ end; ++ #$86: { Thumb-2: Extension ops } ++ begin ++ bytes:=0; ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ ++ if ops=2 then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 0); ++ end ++ else if ops=3 then ++ begin ++ if oper[2]^.typ=top_shifterop then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 0); ++ bytes:=bytes or ((oper[2]^.shifterop^.shiftimm shr 3) shl 4); ++ end ++ else ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 16); ++ bytes:=bytes or (getsupreg(oper[2]^.reg) shl 0); ++ end; ++ end ++ else if ops=4 then ++ begin ++ if oper[3]^.typ=top_shifterop then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 16); ++ bytes:=bytes or (getsupreg(oper[2]^.reg) shl 0); ++ bytes:=bytes or ((oper[3]^.shifterop^.shiftimm shr 3) shl 4); ++ end; ++ end; ++ end; ++ #$87: { Thumb-2: PLD/PLI } ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set Rn and Rd } ++ bytes:=bytes or getsupreg(oper[0]^.ref^.base) shl 16; ++ if getregtype(oper[0]^.ref^.index)=R_INVALIDREGISTER then ++ begin ++ { set offset } ++ offset:=0; ++ currsym:=objdata.symbolref(oper[0]^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=offset+oper[0]^.ref^.offset; ++ if offset>=0 then ++ begin ++ { set U flag } ++ bytes:=bytes or (1 shl 23); ++ bytes:=bytes or (offset and $FFF); ++ end ++ else ++ begin ++ bytes:=bytes or ($3 shl 10); ++ ++ offset:=-offset; ++ bytes:=bytes or (offset and $FF); ++ end; ++ end ++ else ++ begin ++ bytes:=bytes or getsupreg(oper[0]^.ref^.index); ++ { set shift } ++ with oper[0]^.ref^ do ++ if shiftmode=SM_LSL then ++ bytes:=bytes or ((shiftimm and $1F) shl 4); ++ end; ++ end; ++ #$88: { Thumb-2: LDR/STR } ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or (ord(insentry^.code[4]) shl 0); ++ { set Rn and Rd } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ bytes:=bytes or getsupreg(oper[1]^.ref^.base) shl 16; ++ if getregtype(oper[1]^.ref^.index)=R_INVALIDREGISTER then ++ begin ++ { set offset } ++ offset:=0; ++ currsym:=objdata.symbolref(oper[1]^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=(offset+oper[1]^.ref^.offset) shr ord(insentry^.code[5]); ++ if offset>=0 then ++ begin ++ if not (opcode in [A_LDRT,A_LDRSBT,A_LDRSHT,A_LDRBT,A_LDRHT]) then ++ bytes:=bytes or (1 shl 23); ++ { set U flag } ++ if (oper[1]^.ref^.addressmode<>AM_OFFSET) then ++ bytes:=bytes or (1 shl 9); ++ bytes:=bytes or offset ++ end ++ else ++ begin ++ bytes:=bytes or (1 shl 11); ++ ++ offset:=-offset; ++ bytes:=bytes or offset ++ end; ++ end ++ else ++ begin ++ { set I flag } ++ bytes:=bytes or (1 shl 25); ++ bytes:=bytes or getsupreg(oper[1]^.ref^.index); ++ { set shift } ++ with oper[1]^.ref^ do ++ if shiftmode<>SM_None then ++ bytes:=bytes or ((shiftimm and $1F) shl 4); ++ end; ++ ++ if not (opcode in [A_LDRT,A_LDRSBT,A_LDRSHT,A_LDRBT,A_LDRHT]) then ++ begin ++ { set W bit } ++ if oper[1]^.ref^.addressmode<>AM_OFFSET then ++ bytes:=bytes or (1 shl 8); ++ { set P bit if necessary } ++ if oper[1]^.ref^.addressmode<>AM_POSTINDEXED then ++ bytes:=bytes or (1 shl 10); ++ end; ++ end; ++ #$89: { Thumb-2: LDRD/STRD } ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or (ord(insentry^.code[4]) shl 0); ++ { set Rn and Rd } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ bytes:=bytes or getsupreg(oper[1]^.reg) shl 8; ++ bytes:=bytes or getsupreg(oper[2]^.ref^.base) shl 16; ++ if getregtype(oper[2]^.ref^.index)=R_INVALIDREGISTER then ++ begin ++ { set offset } ++ offset:=0; ++ currsym:=objdata.symbolref(oper[2]^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=(offset+oper[2]^.ref^.offset) div 4; ++ if offset>=0 then ++ begin ++ { set U flag } ++ bytes:=bytes or (1 shl 23); ++ bytes:=bytes or offset ++ end ++ else ++ begin ++ offset:=-offset; ++ bytes:=bytes or offset ++ end; ++ end ++ else ++ begin ++ message(asmw_e_invalid_opcode_and_operands); ++ end; ++ { set W bit } ++ if oper[2]^.ref^.addressmode<>AM_OFFSET then ++ bytes:=bytes or (1 shl 21); ++ { set P bit if necessary } ++ if oper[2]^.ref^.addressmode<>AM_POSTINDEXED then ++ bytes:=bytes or (1 shl 24); ++ end; ++ #$8A: { Thumb-2: LDREX } ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or (ord(insentry^.code[4]) shl 0); ++ { set Rn and Rd } ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ ++ if (ops=2) and (opcode in [A_LDREX]) then ++ begin ++ bytes:=bytes or getsupreg(oper[1]^.ref^.base) shl 16; ++ if getregtype(oper[1]^.ref^.index)=R_INVALIDREGISTER then ++ begin ++ { set offset } ++ offset:=0; ++ currsym:=objdata.symbolref(oper[1]^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=(offset+oper[1]^.ref^.offset) div 4; ++ if offset>=0 then ++ begin ++ bytes:=bytes or offset ++ end ++ else ++ begin ++ message(asmw_e_invalid_opcode_and_operands); ++ end; ++ end ++ else ++ begin ++ message(asmw_e_invalid_opcode_and_operands); ++ end; ++ end ++ else if (ops=2) then ++ begin ++ bytes:=bytes or getsupreg(oper[1]^.ref^.base) shl 16; ++ end ++ else ++ begin ++ bytes:=bytes or getsupreg(oper[1]^.reg) shl 8; ++ bytes:=bytes or getsupreg(oper[2]^.ref^.base) shl 16; ++ end; ++ end; ++ #$8B: { Thumb-2: STREX } ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or (ord(insentry^.code[4]) shl 0); ++ { set Rn and Rd } ++ if (ops=3) and (opcode in [A_STREX]) then ++ begin ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 8; ++ bytes:=bytes or getsupreg(oper[1]^.reg) shl 12; ++ bytes:=bytes or getsupreg(oper[2]^.ref^.base) shl 16; ++ if getregtype(oper[2]^.ref^.index)=R_INVALIDREGISTER then ++ begin ++ { set offset } ++ offset:=0; ++ currsym:=objdata.symbolref(oper[2]^.ref^.symbol); ++ if assigned(currsym) then ++ offset:=currsym.offset-insoffset-8; ++ offset:=(offset+oper[2]^.ref^.offset) div 4; ++ if offset>=0 then ++ begin ++ bytes:=bytes or offset ++ end ++ else ++ begin ++ message(asmw_e_invalid_opcode_and_operands); ++ end; ++ end ++ else ++ begin ++ message(asmw_e_invalid_opcode_and_operands); ++ end; ++ end ++ else if (ops=3) then ++ begin ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 0; ++ bytes:=bytes or getsupreg(oper[1]^.reg) shl 12; ++ bytes:=bytes or getsupreg(oper[2]^.ref^.base) shl 16; ++ end ++ else ++ begin ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 0; ++ bytes:=bytes or getsupreg(oper[1]^.reg) shl 12; ++ bytes:=bytes or getsupreg(oper[2]^.reg) shl 8; ++ bytes:=bytes or getsupreg(oper[3]^.ref^.base) shl 16; ++ end; ++ end; ++ #$8C: { Thumb-2: LDM/STM } ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or (ord(insentry^.code[4]) shl 0); ++ ++ if oper[0]^.typ=top_reg then ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16) ++ else ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.ref^.base) shl 16); ++ if oper[0]^.ref^.addressmode<>AM_OFFSET then ++ bytes:=bytes or (1 shl 21); ++ end; ++ ++ for r:=0 to 15 do ++ if r in oper[1]^.regset^ then ++ bytes:=bytes or (1 shl r); ++ ++ case oppostfix of ++ PF_None,PF_IA,PF_FD: bytes:=bytes or ($1 shl 23); ++ PF_DB,PF_EA: bytes:=bytes or ($2 shl 23); ++ end; ++ end; ++ #$8D: { Thumb-2: BL/BLX } ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 8); ++ { set offset } ++ if oper[0]^.typ=top_const then ++ offset:=(oper[0]^.val shr 1) and $FFFFFF ++ else ++ begin ++ currsym:=objdata.symbolref(oper[0]^.ref^.symbol); ++ if (currsym.bind<>AB_LOCAL) and (currsym.objsection<>objdata.CurrObjSec) then ++ begin ++ objdata.writereloc(oper[0]^.ref^.offset,0,currsym,RELOC_RELATIVE_24_THUMB); ++ offset:=$FFFFFE ++ end ++ else ++ offset:=((currsym.offset-insoffset-8) shr 1) and $FFFFFF; ++ end; ++ ++ bytes:=bytes or ((offset shr 00) and $7FF) shl 0; ++ bytes:=bytes or ((offset shr 11) and $3FF) shl 16; ++ bytes:=bytes or (((offset shr 21) xor (offset shr 23) xor 1) and $1) shl 11; ++ bytes:=bytes or (((offset shr 22) xor (offset shr 23) xor 1) and $1) shl 13; ++ bytes:=bytes or ((offset shr 23) and $1) shl 26; ++ end; ++ #$8E: { Thumb-2: TBB/TBH } ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ { set Rn and Rm } ++ bytes:=bytes or getsupreg(oper[0]^.ref^.base) shl 16; ++ ++ if getregtype(oper[0]^.ref^.index)=R_INVALIDREGISTER then ++ message(asmw_e_invalid_effective_address) ++ else ++ begin ++ bytes:=bytes or getsupreg(oper[0]^.ref^.index); ++ ++ if (opcode=A_TBH) and ++ (oper[0]^.ref^.shiftmode<>SM_LSL) and ++ (oper[0]^.ref^.shiftimm<>1) then ++ message(asmw_e_invalid_effective_address); ++ end; ++ end; ++ #$8F: { Thumb-2: CPSxx } ++ begin ++ { set opcode } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ ++ if (oper[0]^.typ=top_modeflags) then ++ begin ++ if mfA in oper[0]^.modeflags then bytes:=bytes or (1 shl 7); ++ if mfI in oper[0]^.modeflags then bytes:=bytes or (1 shl 6); ++ if mfF in oper[0]^.modeflags then bytes:=bytes or (1 shl 5); ++ end; ++ ++ if (ops=2) then ++ bytes:=bytes or (oper[1]^.val and $1F) ++ else if (ops=1) and ++ (oper[0]^.typ=top_const) then ++ bytes:=bytes or (oper[0]^.val and $1F); ++ end; ++ #$96: { Thumb-2: MSR/MRS } ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ ++ if opcode=A_MRS then ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8); ++ ++ case oper[1]^.reg of ++ NR_MSP: bytes:=bytes or $08; ++ NR_PSP: bytes:=bytes or $09; ++ ++ NR_IPSR: bytes:=bytes or $05; ++ NR_EPSR: bytes:=bytes or $06; ++ NR_APSR: bytes:=bytes or $00; ++ ++ NR_PRIMASK: bytes:=bytes or $10; ++ NR_BASEPRI: bytes:=bytes or $11; ++ NR_BASEPRI_MAX: bytes:=bytes or $12; ++ NR_FAULTMASK: bytes:=bytes or $13; ++ NR_CONTROL: bytes:=bytes or $14; ++ else ++ Message(asmw_e_invalid_opcode_and_operands); ++ end; ++ end ++ else ++ begin ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 16); ++ ++ case oper[0]^.reg of ++ NR_APSR, ++ NR_APSR_nzcvqg: bytes:=bytes or $C00; ++ NR_APSR_g: bytes:=bytes or $400; ++ NR_APSR_nzcvq: bytes:=bytes or $800; ++ ++ NR_MSP: bytes:=bytes or $08; ++ NR_PSP: bytes:=bytes or $09; ++ ++ NR_PRIMASK: bytes:=bytes or $10; ++ NR_BASEPRI: bytes:=bytes or $11; ++ NR_BASEPRI_MAX: bytes:=bytes or $12; ++ ++ NR_FAULTMASK: bytes:=bytes or $13; ++ NR_CONTROL: bytes:=bytes or $14; ++ else ++ Message(asmw_e_invalid_opcode_and_operands); ++ end; ++ end; ++ end; ++ #$A0: { FPA: CPDT(LDF/STF) } ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or (ord(insentry^.code[3]) shl 8); ++ bytes:=bytes or ord(insentry^.code[4]); ++ ++ if ops=2 then ++ begin ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ ++ bytes:=bytes or getsupreg(oper[1]^.ref^.base) shl 16; ++ bytes:=bytes or ((oper[1]^.ref^.offset shr 2) and $FF); ++ if oper[1]^.ref^.offset>=0 then ++ bytes:=bytes or (1 shl 23); ++ ++ if oper[1]^.ref^.addressmode<>AM_OFFSET then ++ bytes:=bytes or (1 shl 21); ++ if oper[1]^.ref^.addressmode=AM_PREINDEXED then ++ bytes:=bytes or (1 shl 24); ++ ++ case oppostfix of ++ PF_D: bytes:=bytes or (0 shl 22) or (1 shl 15); ++ PF_E: bytes:=bytes or (1 shl 22) or (0 shl 15); ++ PF_P: bytes:=bytes or (1 shl 22) or (1 shl 15); ++ end; ++ end ++ else ++ begin ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ ++ case oper[1]^.val of ++ 1: bytes:=bytes or (1 shl 15); ++ 2: bytes:=bytes or (1 shl 22); ++ 3: bytes:=bytes or (1 shl 22) or (1 shl 15); ++ 4: ; ++ else ++ message1(asmw_e_invalid_opcode_and_operands, 'Invalid count for LFM/SFM'); ++ end; ++ ++ bytes:=bytes or getsupreg(oper[2]^.ref^.base) shl 16; ++ bytes:=bytes or ((oper[2]^.ref^.offset shr 2) and $FF); ++ if oper[2]^.ref^.offset>=0 then ++ bytes:=bytes or (1 shl 23); ++ ++ if oper[2]^.ref^.addressmode<>AM_OFFSET then ++ bytes:=bytes or (1 shl 21); ++ if oper[2]^.ref^.addressmode=AM_PREINDEXED then ++ bytes:=bytes or (1 shl 24); ++ end; ++ end; ++ #$A1: { FPA: CPDO } ++ begin ++ { set instruction code } ++ bytes:=bytes or ($E shl 24); ++ bytes:=bytes or (ord(insentry^.code[1]) shl 15); ++ bytes:=bytes or ((ord(insentry^.code[2]) shr 1) shl 20); ++ bytes:=bytes or (1 shl 8); ++ ++ bytes:=bytes or getsupreg(oper[0]^.reg) shl 12; ++ if ops=2 then ++ begin ++ if oper[1]^.typ=top_reg then ++ bytes:=bytes or getsupreg(oper[1]^.reg) shl 0 ++ else ++ case oper[1]^.val of ++ 0: bytes:=bytes or $8; ++ 1: bytes:=bytes or $9; ++ 2: bytes:=bytes or $A; ++ 3: bytes:=bytes or $B; ++ 4: bytes:=bytes or $C; ++ 5: bytes:=bytes or $D; ++ //0.5: bytes:=bytes or $E; ++ 10: bytes:=bytes or $F; ++ else ++ Message(asmw_e_invalid_opcode_and_operands); ++ end; ++ end ++ else ++ begin ++ bytes:=bytes or getsupreg(oper[1]^.reg) shl 16; ++ if oper[2]^.typ=top_reg then ++ bytes:=bytes or getsupreg(oper[2]^.reg) shl 0 ++ else ++ case oper[2]^.val of ++ 0: bytes:=bytes or $8; ++ 1: bytes:=bytes or $9; ++ 2: bytes:=bytes or $A; ++ 3: bytes:=bytes or $B; ++ 4: bytes:=bytes or $C; ++ 5: bytes:=bytes or $D; ++ //0.5: bytes:=bytes or $E; ++ 10: bytes:=bytes or $F; ++ else ++ Message(asmw_e_invalid_opcode_and_operands); ++ end; ++ end; ++ ++ case roundingmode of ++ RM_P: bytes:=bytes or (1 shl 5); ++ RM_M: bytes:=bytes or (2 shl 5); ++ RM_Z: bytes:=bytes or (3 shl 5); ++ end; ++ ++ case oppostfix of ++ PF_S: bytes:=bytes or (0 shl 19) or (0 shl 7); ++ PF_D: bytes:=bytes or (0 shl 19) or (1 shl 7); ++ PF_E: bytes:=bytes or (1 shl 19) or (0 shl 7); ++ else ++ message1(asmw_e_invalid_opcode_and_operands, 'Precision cannot be undefined'); ++ end; ++ end; ++ #$A2: { FPA: CPDO } ++ begin ++ { set instruction code } ++ bytes:=bytes or (ord(insentry^.code[1]) shl 24); ++ bytes:=bytes or (ord(insentry^.code[2]) shl 16); ++ bytes:=bytes or ($11 shl 4); ++ ++ case opcode of ++ A_FLT: ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 12); ++ ++ case roundingmode of ++ RM_P: bytes:=bytes or (1 shl 5); ++ RM_M: bytes:=bytes or (2 shl 5); ++ RM_Z: bytes:=bytes or (3 shl 5); ++ end; ++ ++ case oppostfix of ++ PF_S: bytes:=bytes or (0 shl 19) or (0 shl 7); ++ PF_D: bytes:=bytes or (0 shl 19) or (1 shl 7); ++ PF_E: bytes:=bytes or (1 shl 19) or (0 shl 7); ++ else ++ message1(asmw_e_invalid_opcode_and_operands, 'Precision cannot be undefined'); ++ end; ++ end; ++ A_FIX: ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ bytes:=bytes or (getsupreg(oper[1]^.reg) shl 0); ++ ++ case roundingmode of ++ RM_P: bytes:=bytes or (1 shl 5); ++ RM_M: bytes:=bytes or (2 shl 5); ++ RM_Z: bytes:=bytes or (3 shl 5); ++ end; ++ end; ++ A_WFS,A_RFS,A_WFC,A_RFC: ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12); ++ end; ++ A_CMF,A_CNF,A_CMFE,A_CNFE: ++ begin ++ bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16); ++ ++ if oper[1]^.typ=top_reg then ++ bytes:=bytes or getsupreg(oper[1]^.reg) shl 0 ++ else ++ case oper[1]^.val of ++ 0: bytes:=bytes or $8; ++ 1: bytes:=bytes or $9; ++ 2: bytes:=bytes or $A; ++ 3: bytes:=bytes or $B; ++ 4: bytes:=bytes or $C; ++ 5: bytes:=bytes or $D; ++ //0.5: bytes:=bytes or $E; ++ 10: bytes:=bytes or $F; ++ else ++ Message(asmw_e_invalid_opcode_and_operands); ++ end; ++ end; ++ end; ++ end; ++ #$fe: // No written data ++ begin ++ exit; ++ end; ++ #$ff: ++ internalerror(2005091101); ++ else ++ begin ++ writeln(ord(insentry^.code[0]), ' - ', opcode); ++ internalerror(2005091102); ++ end; ++ end; ++ ++ { Todo: Decide whether the code above should take care of writing data in an order that makes senes } ++ if (insentry^.code[0] in [#$80..#$96]) and (bytelen=4) then ++ bytes:=((bytes shr 16) and $FFFF) or ((bytes and $FFFF) shl 16); ++ ++ { we're finished, write code } ++ objdata.writebytes(bytes,bytelen); ++ end; + + begin + cai_align:=tai_align; +Index: fpc/fpcsrc/compiler/arm/agarmgas.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/agarmgas.pas ++++ fpc/fpcsrc/compiler/arm/agarmgas.pas +@@ -42,11 +42,14 @@ unit agarmgas; + end; + + TArmInstrWriter=class(TCPUInstrWriter) ++ unified_syntax: boolean; ++ + procedure WriteInstruction(hp : tai);override; + end; + + TArmAppleGNUAssembler=class(TAppleGNUassembler) + constructor create(smart: boolean); override; ++ procedure WriteExtraHeader; override; + end; + + +@@ -93,6 +96,8 @@ unit agarmgas; + begin + inherited create(smart); + InstrWriter := TArmInstrWriter.create(self); ++ if GenerateThumb2Code then ++ TArmInstrWriter(InstrWriter).unified_syntax:=true; + end; + + +@@ -109,6 +114,8 @@ unit agarmgas; + result:='-mfpu=vfpv3-d16 '+result; + if (current_settings.fputype = fpu_fpv4_s16) then + result:='-mfpu=fpv4-sp-d16 '+result; ++ if (current_settings.fputype = fpu_vfpv4) then ++ result:='-mfpu=vfpv4 '+result; + + if GenerateThumb2Code then + result:='-march='+cputype_to_gas_march[current_settings.cputype]+' -mthumb -mthumb-interwork '+result +@@ -126,7 +133,7 @@ unit agarmgas; + procedure TArmGNUAssembler.WriteExtraHeader; + begin + inherited WriteExtraHeader; +- if GenerateThumb2Code then ++ if TArmInstrWriter(InstrWriter).unified_syntax then + AsmWriteLn(#9'.syntax unified'); + end; + +@@ -138,6 +145,15 @@ unit agarmgas; + begin + inherited create(smart); + InstrWriter := TArmInstrWriter.create(self); ++ TArmInstrWriter(InstrWriter).unified_syntax:=true; ++ end; ++ ++ ++ procedure TArmAppleGNUAssembler.WriteExtraHeader; ++ begin ++ inherited WriteExtraHeader; ++ if TArmInstrWriter(InstrWriter).unified_syntax then ++ AsmWriteLn(#9'.syntax unified'); + end; + + +@@ -208,7 +224,7 @@ unit agarmgas; + var + hs : string; + first : boolean; +- r : tsuperregister; ++ r, rs : tsuperregister; + begin + case o.typ of + top_reg: +@@ -230,14 +246,44 @@ unit agarmgas; + begin + getopstr:='{'; + first:=true; +- for r:=RS_R0 to RS_R15 do +- if r in o.regset^ then +- begin +- if not(first) then +- getopstr:=getopstr+','; +- getopstr:=getopstr+gas_regname(newreg(o.regtyp,r,o.subreg)); +- first:=false; +- end; ++ if R_SUBFS=o.subreg then ++ begin ++ for r:=0 to 31 do // S0 to S31 ++ if r in o.regset^ then ++ begin ++ if not(first) then ++ getopstr:=getopstr+','; ++ if odd(r) then ++ rs:=(r shr 1)+RS_S1 ++ else ++ rs:=(r shr 1)+RS_S0; ++ getopstr:=getopstr+gas_regname(newreg(o.regtyp,rs,o.subreg)); ++ first:=false; ++ end; ++ end ++ else if R_SUBFD=o.subreg then ++ begin ++ for r:=0 to 31 do ++ if r in o.regset^ then ++ begin ++ if not(first) then ++ getopstr:=getopstr+','; ++ rs:=r+RS_D0; ++ getopstr:=getopstr+gas_regname(newreg(o.regtyp,rs,o.subreg)); ++ first:=false; ++ end; ++ end ++ else ++ begin ++ for r:=RS_R0 to RS_R15 do ++ if r in o.regset^ then ++ begin ++ if not(first) then ++ getopstr:=getopstr+','; ++ getopstr:=getopstr+gas_regname(newreg(o.regtyp,r,o.subreg)); ++ first:=false; ++ end; ++ end; + getopstr:=getopstr+'}'; + if o.usermode then + getopstr:=getopstr+'^'; +@@ -289,15 +335,17 @@ unit agarmgas; + sep: string[3]; + begin + op:=taicpu(hp).opcode; ++ postfix:=''; + if GenerateThumb2Code then + begin +- postfix:=''; + if taicpu(hp).wideformat then + postfix:='.w'; +- ++ end; ++ if unified_syntax then ++ begin + if taicpu(hp).ops = 0 then + s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix] +- else if (taicpu(hp).opcode>=A_VABS) and (taicpu(hp).opcode<=A_VSUB) then ++ else if taicpu(hp).oppostfix in [PF_8..PF_U32F64] then + s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix] + else + s:=#9+gas_op2str[op]+oppostfix2str[taicpu(hp).oppostfix]+cond2str[taicpu(hp).condition]+postfix; // Conditional infixes are deprecated in unified syntax +@@ -314,7 +362,7 @@ unit agarmgas; + // writeln(taicpu(hp).fileinfo.line); + + { LDM and STM use references as first operand but they are written like a register } +- if (i=0) and (op in [A_LDM,A_STM,A_FSTM,A_FLDM]) then ++ if (i=0) and (op in [A_LDM,A_STM,A_FSTM,A_FLDM,A_VSTM,A_VLDM]) then + begin + case taicpu(hp).oper[0]^.typ of + top_ref: +Index: fpc/fpcsrc/compiler/arm/aoptcpu.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/aoptcpu.pas ++++ fpc/fpcsrc/compiler/arm/aoptcpu.pas +@@ -2353,7 +2353,7 @@ Implementation + { set of opcode which might or do write to memory } + { TODO : extend armins.dat to contain r/w info } + opcode_could_mem_write = [A_B,A_BL,A_BLX,A_BKPT,A_BX,A_STR,A_STRB,A_STRBT, +- A_STRH,A_STRT,A_STF,A_SFM,A_STM,A_FSTS,A_FSTD]; ++ A_STRH,A_STRT,A_STF,A_SFM,A_STM,A_FSTS,A_FSTD,A_VSTR,A_VSTM]; + + + { adjust the register live information when swapping the two instructions p and hp1, +Index: fpc/fpcsrc/compiler/arm/armatt.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/armatt.inc ++++ fpc/fpcsrc/compiler/arm/armatt.inc +@@ -1,12 +1,9 @@ + { don't edit, this file is generated from armins.dat } + ( + 'none', +-'abs', +-'acs', +-'asn', +-'atn', + 'adc', + 'add', ++'addw', + 'adf', + 'adr', + 'and', +@@ -17,24 +14,18 @@ + 'bkpt', + 'bx', + 'cdp', +-'cmf', +-'cmfe', + 'cmn', + 'cmp', ++'cmf', ++'cmfe', ++'stf', ++'ldf', ++'lfm', + 'clz', +-'cnf', +-'cos', + 'cps', + 'cpsid', + 'cpsie', +-'dvf', + 'eor', +-'exp', +-'fdv', +-'flt', +-'fix', +-'fml', +-'frd', + 'ldc', + 'ldm', + 'ldrbt', +@@ -44,41 +35,32 @@ + 'ldrsb', + 'ldrsh', + 'ldrt', +-'ldf', +-'lfm', +-'lgn', +-'log', + 'mcr', ++'mcr2', ++'mrc', ++'mrc2', ++'mcrr', ++'mcrr2', ++'mrrc', ++'mrrc2', + 'mla', + 'mov', +-'mrc', + 'mrs', + 'msr', +-'mnf', +-'muf', + 'mul', + 'mvf', + 'mvn', ++'vmov', + 'nop', ++'orn', + 'orr', +-'rdf', +-'rfs', +-'rfc', +-'rmf', +-'rpw', + 'rsb', + 'rsc', +-'rsf', +-'rnd', +-'pol', + 'sbc', + 'sfm', + 'sin', + 'smlal', + 'smull', +-'sqt', +-'suf', +-'stf', + 'stm', + 'str', + 'strb', +@@ -89,16 +71,14 @@ + 'swi', + 'swp', + 'swpb', +-'tan', + 'teq', + 'tst', + 'umlal', + 'umull', + 'wfs', + 'ldrd', +-'mcrr', +-'mrrc', + 'pld', ++'pldw', + 'qadd', + 'qdadd', + 'qdsub', +@@ -113,6 +93,12 @@ + 'smlaltt', + 'smlawb', + 'smlawt', ++'vldm', ++'vstm', ++'vpop', ++'vpush', ++'vldr', ++'vstr', + 'smulbb', + 'smulbt', + 'smultb', +@@ -120,67 +106,13 @@ + 'smulwb', + 'smulwt', + 'strd', +-'fabsd', +-'fabss', +-'faddd', +-'fadds', +-'fcmpd', +-'fcmped', +-'fcmpes', +-'fcmpezd', +-'fcmpezs', +-'fcmps', +-'fcmpzd', +-'fcmpzs', +-'fcpyd', +-'fcpys', +-'fcvtds', +-'fcvtsd', +-'fdivd', +-'fdivs', +-'fldd', +-'fldm', +-'flds', +-'fmacd', +-'fmacs', +-'fmdhr', +-'fmdlr', +-'fmrdh', +-'fmrdl', +-'fmrs', +-'fmrx', +-'fmscd', +-'fmscs', +-'fmsr', +-'fmstat', +-'fmuld', +-'fmuls', +-'fmxr', +-'fnegd', +-'fnegs', +-'fnmacd', +-'fnmacs', +-'fnmscd', +-'fnmscs', +-'fnmuld', +-'fnmuls', +-'fsitod', +-'fsitos', +-'fsqrtd', +-'fsqrts', ++'ldrht', ++'strht', ++'ldrsbt', ++'ldrsht', + 'fstd', + 'fstm', + 'fsts', +-'fsubd', +-'fsubs', +-'ftosid', +-'ftosis', +-'ftouid', +-'ftouis', +-'fuitod', +-'fuitos', +-'fmdrr', +-'fmrrd', + 'bfc', + 'bfi', + 'clrex', +@@ -188,8 +120,13 @@ + 'ldrexb', + 'ldrexd', + 'ldrexh', ++'strex', ++'strexb', ++'strexd', ++'strexh', + 'mls', +-'pkh', ++'pkhbt', ++'pkhtb', + 'pli', + 'qadd16', + 'qadd8', +@@ -212,6 +149,8 @@ + 'lsr', + 'lsl', + 'ror', ++'rrx', ++'umaal', + 'shadd16', + 'shadd8', + 'shasx', +@@ -233,49 +172,102 @@ + 'ssax', + 'ssub16', + 'ssub8', +-'strex', +-'strexb', +-'strexd', +-'strexh', + 'sxtab', + 'sxtab16', + 'sxtah', ++'ubfx', ++'uxtab', ++'uxtab16', ++'uxtah', + 'sxtb', + 'sxtb16', ++'sxth', + 'uxtb', ++'uxtb16', + 'uxth', +-'sxth', + 'uadd16', + 'uadd8', + 'uasx', +-'ubfx', + 'uhadd16', + 'uhadd8', + 'uhasx', + 'uhsax', + 'uhsub16', + 'uhsub8', +-'umaal', + 'uqadd16', + 'uqadd8', + 'uqasx', + 'uqsax', + 'uqsub16', + 'uqsub8', +-'uqsad8', +-'uqsada8', ++'usad8', ++'usada8', + 'usat', + 'usat16', + 'usax', + 'usub16', + 'usub8', +-'uxtab', +-'uxtab16', +-'uxtah', +-'uxtb16', + 'wfe', + 'wfi', + 'yield', ++'fabsd', ++'fabss', ++'faddd', ++'fadds', ++'fcmpd', ++'fcmps', ++'fcmped', ++'fcmpes', ++'fcmpzd', ++'fcmpzs', ++'fcmpezd', ++'fcmpezs', ++'fcpyd', ++'fcpys', ++'fcvtds', ++'fcvtsd', ++'fdivd', ++'fdivs', ++'fldd', ++'fldm', ++'flds', ++'fmacd', ++'fmacs', ++'fmdhr', ++'fmdlr', ++'fmrdh', ++'fmrdl', ++'fmrs', ++'fmrx', ++'fmscd', ++'fmscs', ++'fmsr', ++'fmstat', ++'fmuld', ++'fmuls', ++'fmxr', ++'fnegd', ++'fnegs', ++'fnmacd', ++'fnmacs', ++'fnmscd', ++'fnmscs', ++'fnmuld', ++'fnmuls', ++'fsitod', ++'fsitos', ++'fsqrtd', ++'fsqrts', ++'fsubd', ++'fsubs', ++'ftosid', ++'ftosis', ++'ftouid', ++'ftouis', ++'fuitod', ++'fuitos', ++'fmdrr', ++'fmrrd', + 'pop', + 'push', + 'sdiv', +@@ -306,29 +298,59 @@ + 'vcmp', + 'vcmpe', + 'vcvt', ++'vcvtr', + 'vdiv', +-'vldm', +-'vldr', +-'vmov', + 'vmrs', + 'vmsr', +-'vmul', + 'vmla', + 'vmls', ++'vmul', + 'vnmla', + 'vnmls', ++'vnmul', + 'vfma', + 'vfms', + 'vfnma', + 'vfnms', + 'vneg', +-'vnmul', +-'vpop', +-'vpush', + 'vsqrt', +-'vstm', +-'vstr', + 'vsub', ++'dmb', ++'isb', ++'dsb', ++'smc', + 'neg', +-'svc' ++'svc', ++'bxj', ++'udf', ++'tan', ++'sqt', ++'suf', ++'rsf', ++'rnd', ++'pol', ++'rdf', ++'rfs', ++'rfc', ++'wfc', ++'rmf', ++'rpw', ++'mnf', ++'muf', ++'abs', ++'acs', ++'asn', ++'atn', ++'cnf', ++'cnfe', ++'cos', ++'dvf', ++'exp', ++'fdv', ++'flt', ++'fix', ++'fml', ++'frd', ++'lgn', ++'log' + ); +Index: fpc/fpcsrc/compiler/arm/armatts.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/armatts.inc ++++ fpc/fpcsrc/compiler/arm/armatts.inc +@@ -330,5 +330,27 @@ attsufNONE, + attsufNONE, + attsufNONE, + attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, ++attsufNONE, + attsufNONE + ); +Index: fpc/fpcsrc/compiler/arm/armins.dat +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/armins.dat ++++ fpc/fpcsrc/compiler/arm/armins.dat +@@ -85,713 +85,1756 @@ + [NONE] + void void none + +-[ABScc] +- +-[ACScc] ++[ADCcc] ++reglo,reglo \x6B\x41\x40 THUMB,ARMv4T + +-[ASNcc] ++reg32,immshifter \x80\xF1\x40\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32 \x80\xEB\x40\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x80\xEB\x40\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,immshifter \x80\xF1\x40\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x80\xEB\x40\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32,shifterop \x80\xEB\x40\x0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32,reg32 \4\x0\xA0 ARM32,ARMv4 ++reg32,reg32,reg32,shifterop \6\x0\xA0 ARM32,ARMv4 ++reg32,reg32,immshifter \7\x2\xA0 ARM32,ARMv4 + +-[ATNcc] ++[ADDcc] ++reg32,reg32 \x61\x44\x0 THUMB,ARMv4T ++reglo,reglo,reglo \x60\x18\x0 THUMB,ARMv4T + +-[ADCcc] +-reg32,reg32,reg32 \4\x0\xA0 ARM7 +-reg32,reg32,reg32,reg32 \5\x0\xA0 ARM7 +-reg32,reg32,reg32,imm \6\x0\xA0 ARM7 +-reg32,reg32,imm \7\x2\xA0 ARM7 ++reglo,immshifter \x60\x1C\x0 THUMB,ARMv4T ++reglo,reglo,immshifter \x60\x1C\x0 THUMB,ARMv4T ++reglo,immshifter \x6B\x30\x0 THUMB,ARMv4T ++ ++reglo,regsp,immshifter \x64\xA8\x00 THUMB,ARMv4T ++regsp,regsp,immshifter \x64\xB0\x00 THUMB,ARMv4T ++reg32,regsp,reg32 \x64\x44\x68 THUMB,ARMv4T ++regsp,reg32 \x64\x44\x85 THUMB,ARMv4T ++ ++reg32,immshifter \x80\xF1\x0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32 \x80\xEB\x0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x80\xEB\x0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,immshifter \x80\xF1\x0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32 \x80\xEB\x0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32,shifterop \x80\xEB\x0\x0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32,reg32 \4\x0\x80 ARM32,ARMv4 ++reg32,reg32,reg32,shifterop \6\x0\x80 ARM32,ARMv4 ++reg32,reg32,immshifter \7\x2\x80 ARM32,ARMv4 + +-[ADDcc] +-reg32,reg32,reg32 \4\x0\x80 ARM7 +-reg32,reg32,reg32,reg32 \5\x0\x80 ARM7 +-reg32,reg32,reg32,imm \6\x0\x80 ARM7 +-reg32,reg32,imm \7\x2\x80 ARM7 ++[ADDWcc] ++reg32,reg32,immshifter \x81\xF2\x0\x0\x0 THUMB32,ARMv6T2 + + [ADFcc] ++fpureg,fpureg,fpureg \xA1\0\x0 ARM32,FPA ++fpureg,fpureg,immshifter \xA1\0\x0 ARM32,FPA + + [ADRcc] ++;reg32,immshifter \x33\x2\x0F ARM32,ARMv4 ++;reg32,imm32 \x33\x2\x0F ARM32,ARMv4 ++reglo,immshifter \x67\xA0\x0\2 THUMB,ARMv4T ++reglo,memam6 \x67\xA0\x0\2 THUMB,ARMv4T ++ ++reg32,imm32 \x81\xF2\xAF\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,immshifter \x81\xF2\xAF\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,memam2 \x81\xF2\xAF\x0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,memam2 \x33\x2\x0F ARM32,ARMv4 + + [ANDcc] +-reg32,reg32,reg32 \4\x0\x00 ARM7 +-reg32,reg32,reg32,reg32 \5\x0\x00 ARM7 +-reg32,reg32,reg32,imm \6\x0\x00 ARM7 +-reg32,reg32,imm \7\x2\x00 ARM7 ++reglo,reglo \x6B\x40\x00 THUMB,ARMv4T ++ ++reg32,immshifter \x80\xF0\x0\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32 \x80\xEA\x0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x80\xEA\x0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,immshifter \x80\xF0\x0\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x80\xEA\x0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32,shifterop \x80\xEA\x0\x0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32,reg32 \x4\x0\x00 ARM32,ARMv4 ++reg32,reg32,reg32,shifterop \x6\x0\x00 ARM32,ARMv4 ++reg32,reg32,immshifter \x7\x2\x00 ARM32,ARMv4 + + [Bcc] +-mem32 \1\x0A ARM7 +-imm24 \1\x0A ARM7 ++imm24 \x62\xE0\x0 THUMB,ARMv4T ++immshifter \x62\xE0\x0 THUMB,ARMv4T ++mem32 \x62\xE0\x0 THUMB,ARMv4T ++ ++imm24 \x63\xD0\x0 THUMB,ARMv4T ++immshifter \x63\xD0\x0 THUMB,ARMv4T ++mem32 \x63\xD0\x0 THUMB,ARMv4T ++ ++imm24 \x1\x0A ARM32,ARMv4 ++mem32 \x1\x0A ARM32,ARMv4 + + [BICcc] +-reg32,reg32,reg32 \4\x1\xC0 ARM7 +-reg32,reg32,reg32,reg32 \5\x1\xC0 ARM7 +-reg32,reg32,reg32,imm \6\x1\xC0 ARM7 +-reg32,reg32,imm \7\x3\xC0 ARM7 ++reglo,reglo \x6B\x43\x80 THUMB,ARMv4T ++ ++reg32,immshifter \x80\xF0\x20\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32 \x80\xEA\x20\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x80\xEA\x20\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,immshifter \x80\xF0\x20\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x80\xEA\x20\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32,shifterop \x80\xEA\x20\x0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32,reg32 \x6\x1\xC0 ARM32,ARMv4 ++reg32,reg32,reg32,shifterop \x6\x1\xC0 ARM32,ARMv4 ++reg32,reg32,immshifter \x7\x3\xC0 ARM32,ARMv4 + + [BLcc] +-mem32 \1\x0B ARM7 +-imm24 \1\x0B ARM7 ++imm24 \x8D\xF0\xD0 THUMB,THUMB32,ARMv4T ++immshifter \x8D\xF0\xD0 THUMB,THUMB32,ARMv4T ++mem32 \x8D\xF0\xD0 THUMB,THUMB32,ARMv4T ++ ++imm24 \x1\x0B ARM32,ARMv4 ++mem32 \x1\x0B ARM32,ARMv4 + + [BLX] +-mem32 \xff ARM7 +-imm24 \xff ARM7 ++reg32 \x62\x47\x80 THUMB,ARMv4T ++ ++immshifter \x8D\xF0\xC0 THUMB32,ARMv6T2 ++imm24 \x8D\xF0\xC0 THUMB32,ARMv6T2 ++mem32 \x8D\xF0\xC0 THUMB32,ARMv6T2 ++ ++imm24 \x28\xFA ARM32,ARMv5T ++mem32 \x28\xFA ARM32,ARMv5T ++reg32 \3\x01\x2F\xFF\x30 ARM32,ARMv5T + + [BKPTcc] ++immshifter \x60\xBE\x0 THUMB,ARMv5T ++imm \x31\x1\x20\x70 ARM32,ARMv5T ++immshifter \x31\x1\x20\x70 ARM32,ARMv5T + + [BXcc] +-reg32 \3\x01\x2F\xFF\x10 ARM7 ++reg32 \x62\x47\x0 THUMB,ARMv4T + +-[CDP] +-reg8,reg8 \300\1\x10\101 ARM7 ++reg32 \3\x01\x2F\xFF\x10 ARM32,ARMv4T + +-[CMFcc] +- +-[CMFEcc] ++[CDP] ++reg8,reg8 \300\1\x10\101 ARM32,ARMv4 + + [CMNcc] +-reg32,reg32 \xC\x1\x60 ARM7 +-reg32,reg32,reg32 \xD\x1\x60 ARM7 +-reg32,reg32,imm \xE\x1\x60 ARM7 +-reg32,imm \xF\x3\x60 ARM7 ++reglo,reglo \x6B\x42\xC0 THUMB,ARMv4T ++ ++reg32,immshifter \x80\xF1\x10\x0F\x00 THUMB32,ARMv6T2 ++reg32,reg32 \x80\xEB\x10\x0F\x00 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x80\xEB\x10\x0F\x00 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32 \xC\x1\x60 ARM32,ARMv4 ++reg32,reg32,shifterop \xE\x1\x60 ARM32,ARMv4 ++reg32,immshifter \xF\x1\x60 ARM32,ARMv4 + + [CMPcc] +-reg32,reg32 \xC\x1\x40 ARM7 +-reg32,reg32,reg32 \xD\x1\x40 ARM7 +-reg32,reg32,imm \xE\x1\x40 ARM7 +-reg32,imm \xF\x3\x40 ARM7 ++reglo,reglo \x6B\x42\x80 THUMB,ARMv4T ++reg32,reg32 \x61\x45\x0 THUMB,ARMv4T + +-[CLZcc] +-reg32,reg32 \x27\x01\x01 ARM7 ++reglo,immshifter \x6B\x28\x0 THUMB,ARMv4T + +-[CNFcc] ++reg32,immshifter \x80\xF1\xB0\x0F\x00 THUMB32,WIDE,ARMv6T2 ++reg32,reg32 \x80\xEB\xB0\x0F\x00 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x80\xEB\xB0\x0F\x00 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32 \xC\x1\x40 ARM32,ARMv4 ++reg32,reg32,shifterop \xE\x1\x40 ARM32,ARMv4 ++reg32,immshifter \xF\x3\x40 ARM32,ARMv4 + +-[COScc] ++[CMFcc] ++fpureg,fpureg \xA2\xE\x90 ARM32,FPA ++fpureg,immshifter \xA2\xE\x90 ARM32,FPA + +-[CPS] +-[CPSID] +-[CPSIE] ++[CMFEcc] ++fpureg,fpureg \xA2\xE\xC0 ARM32,FPA ++fpureg,immshifter \xA2\xE\xC0 ARM32,FPA + +-[DVFcc] ++[STFcc] ++fpureg,memam2 \xA0\xC\x00\x1\x0 ARM32,FPA + +-[EORcc] +-reg32,reg32,reg32 \4\x0\x20 ARM7 +-reg32,reg32,reg32,reg32 \5\x0\x20 ARM7 +-reg32,reg32,reg32,imm \6\x0\x20 ARM7 +-reg32,reg32,imm \7\x2\x20 ARM7 ++[LDFcc] ++fpureg,memam2 \xA0\xC\x10\x1\x0 ARM32,FPA + +-[EXPcc] ++[LFMcc] ++fpureg,imm32,memam2 \xA0\xC\x10\x2\x0 ARM32,FPA ++fpureg,immshifter,memam2 \xA0\xC\x10\x2\x0 ARM32,FPA + +-[FDVcc] ++[CLZcc] ++reg32,reg32 \x80\xFA\xB0\xF0\x80 THUMB32,ARMv6T2 ++reg32,reg32 \x32\x01\x6F\xF\x10 ARM32,ARMv4 + +-[FLTcc] ++[CPS] ++immshifter \x8F\xF3\xAF\x81\x00 THUMB32,ARMv6T2 ++immshifter \x46\xF1\x2\x0\x0 ARM32,ARMv6 + +-[FIXcc] ++[CPSID] ++modeflags \x6C\xB6\x70 THUMB,ARMv6 ++modeflags \x8F\xF3\xAF\x86\x00 THUMB32,WIDE,ARMv6T2 ++modeflags,immshifter \x8F\xF3\xAF\x87\x00 THUMB32,WIDE,ARMv6T2 ++modeflags \x46\xF1\xC\x0\x0 ARM32,ARMv6 ++modeflags,immshifter \x46\xF1\xE\x0\x0 ARM32,ARMv6 + +-[FMLcc] ++[CPSIE] ++modeflags \x6C\xB6\x60 THUMB,ARMv6 ++modeflags \x8F\xF3\xAF\x84\x00 THUMB32,WIDE,ARMv6T2 ++modeflags,immshifter \x8F\xF3\xAF\x85\x00 THUMB32,WIDE,ARMv6T2 ++modeflags \x46\xF1\x8\x0\x0 ARM32,ARMv6 ++modeflags,immshifter \x46\xF1\xA\x0\x0 ARM32,ARMv6 + +-[FRDcc] ++[EORcc] ++reglo,reglo \x6B\x40\x40 THUMB,ARMv4T ++ ++reg32,immshifter \x80\xF0\x80\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32 \x80\xEA\x80\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x80\xEA\x80\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,immshifter \x80\xF0\x80\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x80\xEA\x80\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32,shifterop \x80\xEA\x80\x0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32,reg32 \4\x0\x20 ARM32,ARMv4 ++reg32,reg32,reg32,shifterop \6\x0\x20 ARM32,ARMv4 ++reg32,reg32,immshifter \7\x2\x20 ARM32,ARMv4 + + [LDC] +-reg32,reg32 \321\300\1\x11\101 ARM7 ++reg32,reg32 \321\300\1\x11\101 ARM32,ARMv4 + + [LDMcc] +-memam4,reglist \x26\x81 ARM7 ++memam4,reglist \x69\xC8 THUMB,ARMv4T ++reglo,reglist \x69\xC8 THUMB,ARMv4T ++ ++memam4,reglist \x8C\xE8\x10\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reglist \x8C\xE8\x10\x0\x0 THUMB32,WIDE,ARMv6T2 ++ ++memam4,reglist \x26\x81 ARM32,ARMv4 ++reg32,reglist \x26\x81 ARM32,ARMv4 + + [LDRBTcc] ++reg32,memam2 \x88\xF8\x10\xE\x0\0 THUMB32,ARMv6T2 ++reg32,memam2 \x17\x04\x70 ARM32,ARMv4 ++reg32,immshifter \x17\x04\x70 ARM32,ARMv4 + + [LDRBcc] +-reg32,memam2 \x17\x07\x10 ARM7 ++reglo,memam3 \x65\x5C\x0\0 THUMB,ARMv4T ++reglo,memam4 \x66\x78\x0\0 THUMB,ARMv4T ++reg32,memam2 \x88\xF8\x10\x0\x0\0 THUMB32,WIDE,ARMv6T2 ++reg32,memam2 \x17\x04\x50 ARM32,ARMv4 + + [LDRcc] +-reg32,memam2 \x17\x05\x10 ARM7 +-; reg32,imm32 \x17\x05\x10 ARM7 +-; reg32,reg32 \x18\x04\x10 ARM7 +-; reg32,reg32,imm32 \x19\x04\x10 ARM7 +-; reg32,reg32,reg32 \x20\x06\x10 ARM7 +-; reg32,reg32,reg32,imm32 \x21\x06\x10 ARM7 ++reglo,memam3 \x65\x58\x0\2 THUMB,ARMv4T ++reglo,memam4 \x66\x68\x0\2 THUMB,ARMv4T ++reglo,memam5 \x67\x98\x0\2 THUMB,ARMv4T ++reglo,memam6 \x67\x48\x0\2 THUMB,ARMv4T ++reg32,memam2 \x88\xF8\x50\x0\x0\0 THUMB32,WIDE,ARMv6T2 ++reg32,memam2 \x17\x04\x10 ARM32,ARMv4 + + [LDRHcc] +-reg32,imm32 \x22\x50\xB0 ARM7 +-reg32,reg32 \x23\x50\xB0 ARM7 +-reg32,reg32,imm32 \x24\x50\xB0 ARM7 +-reg32,reg32,reg32 \x25\x10\xB0 ARM7 ++reglo,memam3 \x65\x5A\x0\1 THUMB,ARMv4T ++reglo,memam4 \x66\x88\x0\1 THUMB,ARMv4T ++reg32,memam2 \x88\xF8\x30\x0\x0\0 THUMB32,WIDE,ARMv6T2 ++reg32,memam2 \x22\x10\xB0 ARM32,ARMv4 + + [LDRSBcc] +-reg32,imm32 \x22\x50\xD0 ARM7 +-reg32,reg32 \x23\x50\xD0 ARM7 +-reg32,reg32,imm32 \x24\x50\xD0 ARM7 +-reg32,reg32,reg32 \x25\x10\xD0 ARM7 ++reglo,memam3 \x65\x56\x0\0 THUMB,ARMv4T ++reg32,memam2 \x88\xF9\x10\x0\x0\0 THUMB32,ARMv6T2 ++reg32,memam2 \x22\x10\xD0 ARM32,ARMv4 ++reg32,reg32 \x23\x50\xD0 ARM32,ARMv4 ++reg32,reg32,imm32 \x24\x50\xD0 ARM32,ARMv4 ++reg32,reg32,reg32 \x25\x10\xD0 ARM32,ARMv4 + + [LDRSHcc] +-reg32,imm32 \x22\x50\xF0 ARM7 +-reg32,reg32 \x23\x50\xF0 ARM7 +-reg32,reg32,imm32 \x24\x50\xF0 ARM7 +-reg32,reg32,reg32 \x25\x10\xF0 ARM7 ++reglo,memam3 \x65\x5E\x0\1 THUMB,ARMv4T ++reg32,memam2 \x88\xF9\x30\x0\x0\0 THUMB32,ARMv6T2 ++reg32,memam2 \x22\x10\xF0 ARM32,ARMv4 + + [LDRTcc] ++reg32,memam2 \x88\xF8\x50\xE\x0\0 THUMB32,ARMv6T2 ++reg32,memam2 \x17\x04\x30 ARM32,ARMv4 + +-[LDFcc] ++[MCRcc] ++regf,immshifter,reg32,regf,regf \x1C\xE\x0\x1 ARM32,ARMv4 ++regf,immshifter,reg32,regf,regf,immshifter \x1C\xE\x0\x1 ARM32,ARMv4 ++ ++[MCR2cc] ++regf,immshifter,reg32,regf,regf \x1C\xFE\x0\x1 ARM32,ARMv5T ++regf,immshifter,reg32,regf,regf,immshifter \x1C\xFE\x0\x1 ARM32,ARMv5T ++ ++[MRCcc] ++regf,immshifter,reg32,regf,regf \x1C\xE\x10\x1 ARM32,ARMv4 ++regf,immshifter,reg32,regf,regf,immshifter \x1C\xE\x10\x1 ARM32,ARMv4 ++ ++[MRC2cc] ++regf,immshifter,reg32,regf,regf \x1C\xFE\x10\x1 ARM32,ARMv5T ++regf,immshifter,reg32,regf,regf,immshifter \x1C\xFE\x10\x1 ARM32,ARMv5T + +-[LFMcc] +-reg32,imm8,fpureg \xF0\x02\x01 FPA ++[MCRRcc] ++regf,immshifter,reg32,reg32,regf \x1D\xC\x40\x0 ARM32,ARMv5TE + +-[LGNcc] ++[MCRR2cc] ++regf,immshifter,reg32,reg32,regf \x1D\xFC\x40\x0 ARM32,ARMv6 + +-[LOGcc] ++[MRRCcc] ++regf,immshifter,reg32,reg32,regf \x1D\xC\x50\x0 ARM32,ARMv5TE + +-[MCR] +-; reg32,mem32 \320\301\1\x13\110 ARM7 ++[MRRC2cc] ++regf,immshifter,reg32,reg32,regf \x1D\xFC\x50\x0 ARM32,ARMv6 + + [MLAcc] +-reg32,reg32,reg32,reg32 \x15\x00\x20\x90 ARM7 ++reg32,reg32,reg32,reg32 \x80\xFB\x0\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x15\x00\x20\x9 ARM32,ARMv4 + + [MOVcc] +-; reg32,shifterop \x8\x0\0xd ARM7 +-; reg32,immshifter \x8\x0\0xd ARM7 +-; reg32,reg32,reg32 \x9\x1\xA0 ARM7 +-; reg32,reg32,imm \xA\x1\xA0 ARM7 +-; reg32,imm \xB\x3\xA0 ARM7 ++reglo,reglo \x6B\x0\x0 THUMB,ARMv4T ++reg32,reg32 \x61\x46\x00 THUMB,ARMv4T ++ ++reglo,immshifter \x6B\x20\x0 THUMB,ARMv4T ++ ++reg32,immshifter \x80\xF0\x4F\x0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32 \x80\xEA\x4F\x0\x0 THUMB32,WIDE,ARMv6T2 + +-[MRC] +-; reg32,reg32 \321\301\1\x13\110 ARM7 ++reg32,shifterop \x8\x1\xA0 ARM32,ARMv4 ++reg32,reg32,shifterop \xA\x1\xA0 ARM32,ARMv4 ++reg32,immshifter \xB\x1\xA0 ARM32,ARMv4 + + [MRScc] +-reg32,reg32 \x10\x01\x0F ARM7 ++reg32,regf \x96\xF3\xEF\x80\x0 THUMB32,ARMv6 ++reg32,regf \x10\x01\x0F ARM32,ARMv4 + + [MSRcc] +-reg32,reg32 \x11\x01\x29\xF0 ARM7 +-regf,reg32 \x12\x01\x28\xF0 ARM7 +-regf,imm \x13\x03\x28\xF0 ARM7 ++regf,reg32 \x96\xF3\x80\x80\x0 THUMB32,ARMv6 + +-[MNFcc] +- +-[MUFcc] ++regf,reg32 \x12\x01\x20\xF0 ARM32,ARMv4 ++regf,immshifter \x13\x03\x20\xF0 ARM32,ARMv4 ++regs,immshifter \x13\x03\x20\xF0 ARM32,ARMv4 + + [MULcc] +-reg32,reg32,reg32 \x14\x00\x00\x90 ARM7 ++reglo,reglo \x64\x43\x40 THUMB,ARMv4T ++reglo,reglo,reglo \x64\x43\x40 THUMB,ARMv4T ++reg32,reg32 \x80\xFB\x00\xF0\x00 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x80\xFB\x00\xF0\x00 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x14\x00\x00\x90 ARM32,ARMv4 + + [MVFcc] +-fpureg,fpureg \xF2 FPA +-fpureg,immfpu \xF2 FPA ++fpureg,fpureg \xA1\1\x1 ARM32,FPA ++fpureg,immshifter \xA1\1\x1 ARM32,FPA + + [MVNcc] +-; reg32,reg32 \x8\x0\0xf ARM7 +-; reg32,reg32,reg32 \x9\x1\xE0 ARM7 +-; reg32,reg32,imm \xA\x1\xE0 ARM7 +-; reg32,imm \xB\x3\xE0 ARM7 +- +-[NOP] +- +-[ORRcc] +-reg32,reg32,reg32 \4\x1\x80 ARM7 +-reg32,reg32,reg32,reg32 \5\x1\x80 ARM7 +-reg32,reg32,reg32,imm \6\x1\x80 ARM7 +-reg32,reg32,imm \7\x3\x80 ARM7 ++reglo,reglo \x6B\x43\xc0 THUMB,ARMv4T + +-[RDFcc] ++reg32,immshifter \x80\xF0\x6F\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32 \x80\xEA\x6F\x0\x0 THUMB32,WIDE,ARMv6T2 + +-[RFScc] ++reg32,reg32 \x8\x1\xE0 ARM32,ARMv4 ++reg32,reg32,shifterop \xA\x1\xE0 ARM32,ARMv4 ++reg32,immshifter \xB\x1\xE0 ARM32,ARMv4 ++ ++[VMOVcc] ++vreg,vreg \x90\xEE\xB0\xA\x40 THUMB32,VFPv2 ++vreg,vreg \x40\xE\xB0\xA\x40 ARM32,VFPv2 ++ ++reg32,vreg \x90\xEE\x10\xA\x10 THUMB32,VFPv2 ++vreg,reg32 \x90\xEE\x00\xA\x10 THUMB32,VFPv2 ++reg32,vreg \x40\xE\x10\xA\x10 ARM32,VFPv2 ++vreg,reg32 \x40\xE\x00\xA\x10 ARM32,VFPv2 ++ ++reg32,reg32,vreg,vreg \x90\xEC\x50\xA\x10 THUMB32,VFPv2 ++vreg,vreg,reg32,reg32 \x90\xEC\x40\xA\x10 THUMB32,VFPv2 ++reg32,reg32,vreg,vreg \x40\xC\x50\xA\x10 ARM32,VFPv2 ++vreg,vreg,reg32,reg32 \x40\xC\x40\xA\x10 ARM32,VFPv2 ++ ++reg32,reg32,vreg \x90\xEC\x50\xB\x10 THUMB32,VFPv2 ++vreg,reg32,reg32 \x90\xEC\x40\xB\x10 THUMB32,VFPv2 ++reg32,reg32,vreg \x40\xC\x50\xB\x10 ARM32,VFPv2 ++vreg,reg32,reg32 \x40\xC\x40\xB\x10 ARM32,VFPv2 + +-[RFCcc] ++[NOP] ++void \x61\xBF\x0 THUMB,ARMv6T2 ++void \x2F\x03\x20\xF0\x0 ARM32,ARMv6K ++; Before ARMv6K use mov r0,r0 ++void \x2F\xE1\xA0\x0\x0 ARM32,ARMv4 ++ ++[ORNcc] ++reg32,immshifter \x80\xF0\x60\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32 \x80\xEA\x60\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,shifterop \x80\xEA\x60\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,immshifter \x80\xF0\x60\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x80\xEA\x60\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32,shifterop \x80\xEA\x60\x0\x0 THUMB32,ARMv6T2 + +-[RMFcc] ++[ORRcc] ++reglo,reglo \x6B\x43\x00 THUMB,ARMv4T + +-[RPWcc] ++reg32,immshifter \x80\xF0\x40\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32 \x80\xEA\x40\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x80\xEA\x40\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,immshifter \x80\xF0\x40\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x80\xEA\x40\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32,shifterop \x80\xEA\x40\x0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32,reg32 \4\x1\x80 ARM32,ARMv4 ++reg32,reg32,reg32,reg32 \5\x1\x80 ARM32,ARMv4 ++reg32,reg32,reg32,shifterop \6\x1\x80 ARM32,ARMv4 ++reg32,reg32,immshifter \7\x3\x80 ARM32,ARMv4 + + [RSBcc] +-reg32,reg32,reg32 \4\x0\x60 ARM7 +-reg32,reg32,reg32,reg32 \5\x0\x60 ARM7 +-reg32,reg32,reg32,imm \6\x0\x60 ARM7 +-reg32,reg32,imm \7\x2\x60 ARM7 +- +-[RSCcc] +-reg32,reg32,reg32 \4\x0\xE0 ARM7 +-reg32,reg32,reg32,reg32 \5\x0\xE0 ARM7 +-reg32,reg32,reg32,imm \6\x0\xE0 ARM7 +-reg32,reg32,imm \7\x2\xE0 ARM7 ++reglo,reglo,immzero \x6B\x42\x40 THUMB,ARMv4T + +-[RSFcc] ++reg32,immshifter \x80\xF1\xC0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32 \x80\xEB\xC0\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,shifterop \x80\xEB\xC0\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,immshifter \x80\xF1\xC0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32 \x80\xEB\xC0\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32,shifterop \x80\xEB\xC0\x0\x0 THUMB32,ARMv6T2 ++ ++reg32,reg32,reg32 \6\x0\x60 ARM32,ARMv4 ++reg32,reg32,reg32,shifterop \6\x0\x60 ARM32,ARMv4 ++reg32,reg32,immshifter \7\x0\x60 ARM32,ARMv4 + +-[RNDcc] +- +-[POLcc] ++[RSCcc] ++reg32,reg32,reg32 \4\x0\xE0 ARM32,ARMv4 ++reg32,reg32,reg32,reg32 \5\x0\xE0 ARM32,ARMv4 ++reg32,reg32,reg32,shifterop \6\x0\xE0 ARM32,ARMv4 ++reg32,reg32,immshifter \7\x2\xE0 ARM32,ARMv4 + + [SBCcc] +-reg32,reg32,reg32 \4\x0\xC0 ARM7 +-reg32,reg32,reg32,reg32 \5\x0\xC0 ARM7 +-reg32,reg32,reg32,imm \6\x0\xC0 ARM7 +-reg32,reg32,imm \7\x2\xC0 ARM7 ++reglo,reglo \x6B\x41\x80 THUMB,ARMv4T ++ ++reg32,immshifter \x80\xF1\x60\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32 \x80\xEB\x60\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x80\xEB\x60\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,immshifter \x80\xF1\x60\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x80\xEB\x60\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32,shifterop \x80\xEB\x60\x0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32,reg32 \4\x0\xC0 ARM32,ARMv4 ++reg32,reg32,reg32,reg32 \5\x0\xC0 ARM32,ARMv4 ++reg32,reg32,reg32,imm \6\x0\xC0 ARM32,ARMv4 ++reg32,reg32,reg32,shifterop \6\x0\xC0 ARM32,ARMv4 ++reg32,reg32,immshifter \7\x2\xC0 ARM32,ARMv4 + + [SFMcc] +-reg32,imm8,fpureg \xF0\x02\x00 FPA ++fpureg,imm32,memam2 \xA0\xC\x00\x2\x0 ARM32,FPA ++fpureg,immshifter,memam2 \xA0\xC\x00\x2\x0 ARM32,FPA + + [SINcc] ++fpureg,fpureg \xA1\1\x11 ARM32,FPA ++fpureg,immshifter \xA1\1\x11 ARM32,FPA + + [SMLALcc] +-reg32,reg32,reg32,reg32 \x16\x00\xE0\x90 ARM7 ++reg32,reg32,reg32,reg32 \x85\xFB\xC0\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x16\x00\xE0\x9 ARM32,ARMv4 + + [SMULLcc] +-reg32,reg32,reg32,reg32 \x16\x00\xC0\x90 ARM7 +- +-[SQTcc] ++reg32,reg32,reg32,reg32 \x85\xFB\x80\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x16\x00\xC0\x9 ARM32,ARMv4 + +-[SUFcc] ++[STMcc] ++memam4,reglist \x69\xC0 THUMB,ARMv4T ++reglo,reglist \x69\xC0 THUMB,ARMv4T + +-[STFcc] ++memam4,reglist \x8C\xE8\x00\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reglist \x8C\xE8\x00\x0\x0 THUMB32,WIDE,ARMv6T2 + +-[STMcc] +-memam4,reglist \x26\x80 ARM7 ++memam4,reglist \x26\x80 ARM32,ARMv4 ++reg32,reglist \x26\x80 ARM32,ARMv4 + + [STRcc] +-reg32,memam2 \x17\x04\x00 ARM7 +-; reg32,imm32 \x17\x05\x00 ARM7 +-; reg32,reg32 \x18\x04\x00 ARM7 +-; reg32,reg32,imm32 \x19\x04\x00 ARM7 +-; reg32,reg32,reg32 \x20\x06\x00 ARM7 +-; reg32,reg32,reg32,imm32 \x21\x06\x00 ARM7 ++reglo,memam3 \x65\x50\x0\2 THUMB,ARMv4T ++reglo,memam4 \x66\x60\x0\2 THUMB,ARMv4T ++reglo,memam5 \x67\x90\x0\2 THUMB,ARMv4T ++reg32,memam2 \x88\xF8\x40\x0\x0\0 THUMB32,WIDE,ARMv6T2 ++reg32,memam2 \x17\x04\x00 ARM32,ARMv4 + + [STRBcc] +-reg32,memam2 \x17\x06\x00 ARM7 ++reglo,memam3 \x65\x54\x0\0 THUMB,ARMv4T ++reglo,memam4 \x66\x70\x0\0 THUMB,ARMv4T ++reg32,memam2 \x88\xF8\x00\x0\x0\0 THUMB32,WIDE,ARMv6T2 ++reg32,memam2 \x17\x04\x40 ARM32,ARMv4 + + [STRBTcc] ++reg32,memam2 \x88\xF8\x00\xE\x0\0 THUMB32,ARMv6T2 ++reg32,memam2 \x17\x04\x60 ARM32,ARMv4 ++reg32,immshifter \x17\x04\x60 ARM32,ARMv4 + +-; A dummy since it is parsed as STR{cond}H + [STRHcc] +-reg32,imm32 \x22\x40\xB0 ARM7 +-reg32,reg32 \x23\x40\xB0 ARM7 +-reg32,reg32,imm32 \x24\x40\xB0 ARM7 +-reg32,reg32,reg32 \x25\x00\xB0 ARM7 ++reglo,memam3 \x65\x52\x0\1 THUMB,ARMv4T ++reglo,memam4 \x66\x80\x0\1 THUMB,ARMv4T ++reg32,memam2 \x88\xF8\x20\x0\x0\0 THUMB32,WIDE,ARMv6T2 ++reg32,memam2 \x22\x00\xB0 ARM32,ARMv4 + + [STRTcc] ++reg32,memam2 \x88\xF8\x40\xE\x0\0 THUMB32,ARMv6T2 ++reg32,memam2 \x17\x04\x20 ARM32,ARMv4 + + [SUBcc] +-reg32,reg32,shifterop \4\x0\x40 ARM7 +-reg32,reg32,immshifter \4\x0\x40 ARM7 +-reg32,reg32,reg32 \4\x0\x40 ARM7 +-; reg32,reg32,reg32,reg32 \5\x0\x40 ARM7 +-; reg32,reg32,reg32,imm \6\x0\x40 ARM7 +-; reg32,reg32,imm \7\x2\x40 ARM7 ++regsp,immshifter \x64\xB0\x80 THUMB,ARMv4T ++regsp,regsp,immshifter \x64\xB0\x80 THUMB,ARMv4T ++reglo,reglo \x60\x1A\x0 THUMB,ARMv4T ++reglo,reglo,reglo \x60\x1A\x0 THUMB,ARMv4T ++ ++reglo,immshifter \x60\x1E\x0 THUMB,ARMv4T ++reglo,reglo,immshifter \x60\x1E\x0 THUMB,ARMv4T ++reglo,imm8 \x6B\x38\x0 THUMB,ARMv4T ++reglo,immshifter \x6B\x38\x0 THUMB,ARMv4T ++ ++reg32,immshifter \x80\xF1\xA0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32 \x80\xEB\xA0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x80\xEB\xA0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,immshifter \x80\xF1\xA0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32 \x80\xEB\xA0\x0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32,shifterop \x80\xEB\xA0\x0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32,shifterop \x4\x0\x40 ARM32,ARMv4 ++reg32,reg32,immshifter \x4\x0\x40 ARM32,ARMv4 ++reg32,reg32,reg32 \x4\x0\x40 ARM32,ARMv4 ++reg32,reg32,reg32,shifterop \x6\x0\x40 ARM32,ARMv4 + + [SWIcc] +-imm \2\x0F ARM7 ++; Old alias for SVC + + [SWPcc] +-reg32,reg32,reg32 \x27\x01\x90 ARM7 ++reg32,reg32,memam2 \x27\x10\x09 ARM32,ARMv4 + + [SWPBcc] +-reg32,reg32,reg32 \x27\x01\x90 ARM7 +- +-[TANcc] ++reg32,reg32,memam2 \x27\x14\x09 ARM32,ARMv4 + + [TEQcc] +-reg32,reg32 \xC\x1\x20 ARM7 +-reg32,reg32,reg32 \xD\x1\x20 ARM7 +-reg32,reg32,imm \xE\x1\x20 ARM7 +-reg32,imm \xF\x3\x20 ARM7 ++reg32,immshifter \x80\xF0\x90\x0F\x00 THUMB32,ARMv6T2 ++reg32,reg32 \x80\xEA\x90\x0F\x00 THUMB32,ARMv6T2 ++reg32,reg32,shifterop \x80\xEA\x90\x0F\x00 THUMB32,ARMv6T2 ++ ++reg32,reg32 \xC\x1\x20 ARM32,ARMv4 ++reg32,reg32,reg32 \xD\x1\x20 ARM32,ARMv4 ++reg32,reg32,shifterop \xE\x1\x20 ARM32,ARMv4 ++reg32,immshifter \xF\x3\x20 ARM32,ARMv4 + + [TSTcc] +-reg32,reg32 \xC\x1\x00 ARM7 +-reg32,reg32,reg32 \xD\x1\x00 ARM7 +-reg32,reg32,imm \xE\x1\x00 ARM7 +-reg32,imm \xF\x3\x00 ARM7 ++reglo,reglo \x6B\x42\x00 THUMB,ARMv4T ++ ++reg32,immshifter \x80\xF0\x10\x0F\x00 THUMB32,ARMv6T2 ++reg32,reg32 \x80\xEA\x10\x0F\x00 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x80\xEA\x10\x0F\x00 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32 \xC\x1\x00 ARM32,ARMv4 ++reg32,reg32,reg32 \xD\x1\x00 ARM32,ARMv4 ++reg32,reg32,shifterop \xE\x1\x00 ARM32,ARMv4 ++reg32,immshifter \xF\x3\x00 ARM32,ARMv4 + + [UMLALcc] +-reg32,reg32,reg32,reg32 \x16\x00\xA0\x90 ARM7 ++reg32,reg32,reg32,reg32 \x85\xFB\xE0\x0\x00 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x16\x00\xA0\x9 ARM32,ARMv4 + + [UMULLcc] +-reg32,reg32,reg32,reg32 \x16\x00\x80\x90 ARM7 ++reg32,reg32,reg32,reg32 \x85\xFB\xA0\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x16\x00\x80\x9 ARM32,ARMv4 + + [WFScc] ++reg32 \xA2\xE\x2 ARM32,FPA + + ; EDSP instructions + [LDRDcc] +- +-[MCRRcc] +- +-[MRRCcc] ++reg32,reg32,memam2 \x89\xE8\x50\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,memam2 \x19\x0\x0\x0\xD0 ARM32,ARMv4 + + [PLD] ++memam2 \x87\xF8\x10\xF0\x0 THUMB32,ARMv6T2 ++memam2 \x25\xF5\x50\xF0\x0 ARM32,ARMv5TE ++ ++[PLDW] ++memam2 \x87\xF8\x30\xF0\x0 THUMB32,ARMv7 ++memam2 \x25\xF5\x10\xF0\x0 ARM32,ARMv7 + + [QADDcc] ++reg32,reg32,reg32 \x82\xFA\x80\xF0\x80 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x1A\x01\x00\x05 ARM32,ARMv5TE + + [QDADDcc] ++reg32,reg32,reg32 \x82\xFA\x80\xF0\x90 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x1A\x01\x40\x05 ARM32,ARMv5TE + + [QDSUBcc] ++reg32,reg32,reg32 \x82\xFA\x80\xF0\xB0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x1A\x01\x60\x05 ARM32,ARMv5TE + + [QSUBcc] ++reg32,reg32,reg32 \x82\xFA\x80\xF0\xA0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x1A\x01\x20\x05 ARM32,ARMv5TE + + [SMLABBcc] ++reg32,reg32,reg32,reg32 \x15\x01\x00\x8 ARM32,ARMv5TE + + [SMLABTcc] ++reg32,reg32,reg32,reg32 \x15\x01\x00\xC ARM32,ARMv5TE + + [SMLATBcc] ++reg32,reg32,reg32,reg32 \x15\x01\x00\xA ARM32,ARMv5TE + + [SMLATTcc] ++reg32,reg32,reg32,reg32 \x15\x01\x00\xE ARM32,ARMv5TE + + [SMLALBBcc] ++reg32,reg32,reg32,reg32 \x16\x01\x40\x8 ARM32,ARMv5TE + + [SMLALBTcc] ++reg32,reg32,reg32,reg32 \x16\x01\x40\xC ARM32,ARMv5TE + + [SMLALTBcc] ++reg32,reg32,reg32,reg32 \x16\x01\x40\xA ARM32,ARMv5TE + + [SMLALTTcc] ++reg32,reg32,reg32,reg32 \x16\x01\x40\xE ARM32,ARMv5TE + + [SMLAWBcc] ++reg32,reg32,reg32,reg32 \x80\xFB\x30\x0\x00 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x15\x1\x20\x8 ARM32,ARMv5TE + + [SMLAWTcc] ++reg32,reg32,reg32,reg32 \x80\xFB\x30\x0\x10 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x15\x1\x20\xC ARM32,ARMv5TE ++ ++[VLDMcc] ++memam4,reglist \x94\xEC\x10\xA THUMB32,VFPv2 ++reg32,reglist \x94\xEC\x10\xA THUMB32,VFPv2 ++memam4,reglist \x44\xC\x10\xA ARM32,VFPv2 ++reg32,reglist \x44\xC\x10\xA ARM32,VFPv2 ++ ++[VSTMcc] ++memam4,reglist \x94\xEC\x00\xA THUMB32,VFPv2 ++reg32,reglist \x94\xEC\x00\xA THUMB32,VFPv2 ++memam4,reglist \x44\xC\x00\xA ARM32,VFPv2 ++reg32,reglist \x44\xC\x00\xA ARM32,VFPv2 ++ ++[VPOP] ++reglist \x94\xEC\xBD\xA THUMB32,VFPv2 ++reglist \x44\xC\xBD\xA ARM32,VFPv2 ++ ++[VPUSH] ++reglist \x94\xED\x2D\xA THUMB32,VFPv2 ++reglist \x44\xD\x2D\xA ARM32,VFPv2 ++ ++[VLDRcc] ++vreg,memam2 \x95\xED\x10\xA THUMB32,VFPv2 ++vreg,memam2 \x45\xD\x10\xA ARM32,VFPv2 ++ ++[VSTRcc] ++vreg,memam2 \x95\xED\x0\xA THUMB32,VFPv2 ++vreg,memam2 \x45\xD\x0\xA ARM32,VFPv2 + + [SMULBBcc] ++reg32,reg32,reg32 \x15\x01\x60\x8\x0 ARM32,ARMv5TE + + [SMULBTcc] ++reg32,reg32,reg32 \x15\x01\x60\xC\x0 ARM32,ARMv5TE + + [SMULTBcc] ++reg32,reg32,reg32 \x15\x01\x60\xA\x0 ARM32,ARMv5TE + + [SMULTTcc] ++reg32,reg32,reg32 \x15\x01\x60\xE\x0 ARM32,ARMv5TE + + [SMULWBcc] ++reg32,reg32,reg32 \x14\x1\x20\xA0 ARM32,ARMv5TE + + [SMULWTcc] ++reg32,reg32,reg32 \x14\x1\x20\xE0 ARM32,ARMv5TE + + [STRDcc] ++reg32,reg32,memam2 \x89\xE8\x40\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,memam2 \x19\x0\x0\x0\xF0 ARM32,ARMv4 + +-; +-; vfp instructions +-; +-[FABSDcc] +- +-[FABSScc] +- +-[FADDDcc] +- +-[FADDScc] +- +-[FCMPDcc] +- +-[FCMPEDcc] +- +-[FCMPEScc] +- +-[FCMPEZDcc] +- +-[FCMPEZScc] +- +-[FCMPScc] +- +-[FCMPZDcc] +- +-[FCMPZScc] +- +-[FCPYDcc] +- +-[FCPYScc] +- +-[FCVTDScc] +- +-[FCVTSDcc] +- +-[FDIVDcc] +- +-[FDIVScc] +- +-[FLDDcc] +- +-[FLDMcc] +- +-[FLDScc] +- +-[FMACDcc] +- +-[FMACScc] +- +-[FMDHRcc] +- +-[FMDLRcc] +- +-[FMRDHcc] +- +-[FMRDLcc] +- +-[FMRScc] +- +-[FMRXcc] +- +-[FMSCDcc] +- +-[FMSCScc] +- +-[FMSRcc] +- +-[FMSTATcc] +- +-[FMULDcc] +- +-[FMULScc] +- +-[FMXRcc] +- +-[FNEGDcc] +- +-[FNEGScc] +- +-[FNMACDcc] +- +-[FNMACScc] +- +-[FNMSCDcc] +- +-[FNMSCScc] +- +-[FNMULDcc] +- +-[FNMULScc] +- +-[FSITODcc] +- +-[FSITOScc] +- +-[FSQRTDcc] +- +-[FSQRTScc] ++[LDRHTcc] ++reg32,memam2 \x88\xF8\x30\xE\x0\0 THUMB32,ARMv6T2 ++reg32,memam2 \x19\x0\x30\x0\xB0 ARM32,ARMv4 ++ ++[STRHTcc] ++reg32,memam2 \x88\xF8\x20\xE\x0\0 THUMB32,ARMv6T2 ++ ++reg32,memam2 \x88\xF8\x20\xE\x0\0 THUMB32,ARMv6T2 ++reg32,memam2 \x1E\x0\x20\x0\xB0 ARM32,ARMv4 ++ ++[LDRSBTcc] ++reg32,memam2 \x88\xF9\x10\xE\x0\0 THUMB32,ARMv6T2 ++reg32,memam2 \x1E\x0\x30\x0\xD0 ARM32,ARMv4 ++ ++[LDRSHTcc] ++reg32,memam2 \x88\xF9\x30\xE\x0\0 THUMB32,ARMv6T2 ++reg32,memam2 \x1E\x0\x30\x0\xF0 ARM32,ARMv4 + + [FSTDcc] ++vreg,memam2 \x95\xED\x0\xA THUMB32,VFPv2 ++vreg,memam2 \x45\xD\x0\xA ARM32,VFPv2 + + [FSTMcc] ++memam4,reglist \x94\xEC\x00\xA THUMB32,VFPv2 ++reg32,reglist \x94\xEC\x00\xA THUMB32,VFPv2 ++memam4,reglist \x44\xC\x00\xA ARM32,VFPv2 ++reg32,reglist \x44\xC\x00\xA ARM32,VFPv2 + + [FSTScc] ++vreg,memam2 \x95\xED\x0\xA THUMB32,VFPv2 ++vreg,memam2 \x45\xD\x0\xA ARM32,VFPv2 + +-[FSUBDcc] +- +-[FSUBScc] ++; ARMv6 + +-[FTOSIDcc] ++[BFCcc] ++reg32,immshifter,immshifter \x84\xF3\x6F\x0\x0 THUMB32,ARMv6T2 ++reg32,immshifter,imm32 \x84\xF3\x6F\x0\x0 THUMB32,ARMv6T2 + +-[FTOSIScc] ++reg32,immshifter,immshifter \x2D\x7\xC0\x0\x1F ARM32,ARMv4 ++reg32,immshifter,imm32 \x2D\x7\xC0\x0\x1F ARM32,ARMv4 + +-[FTOUIDcc] ++[BFIcc] ++reg32,reg32,immshifter,immshifter \x84\xF3\x60\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,immshifter,imm32 \x84\xF3\x60\x0\x0 THUMB32,ARMv6T2 + +-[FTOUIScc] ++reg32,reg32,immshifter,immshifter \x2D\x7\xC0\x0\x10 ARM32,ARMv4 ++reg32,reg32,immshifter,imm32 \x2D\x7\xC0\x0\x10 ARM32,ARMv4 + +-[FUITODcc] ++[CLREX] ++void \x80\xF3\xBF\x8F\x2F THUMB32,ARMv7 ++void \x2F\xF5\x7F\xF0\x1F ARM32,ARMv6K + +-[FUITOScc] ++[LDREXcc] ++reg32,memam6 \x8A\xE8\x50\x0F\x00 THUMB32,ARMv6T2 ++reg32,memam6 \x18\x01\x90\x0F\x9F ARM32,ARMv4 + +-[FMDRRcc] ++[LDREXBcc] ++reg32,memam6 \x8A\xE8\xD0\x0F\x4F THUMB32,ARMv7 ++reg32,memam6 \x18\x01\xD0\x0F\x9F ARM32,ARMv4 + +-[FMRRDcc] ++[LDREXDcc] ++reg32,reg32,memam6 \x8A\xE8\xD0\x00\x7F THUMB32,ARMv7 ++reg32,reg32,memam6 \x18\x01\xB0\x0F\x9F ARM32,ARMv4 + +-; ARMv6 ++[LDREXHcc] ++reg32,memam6 \x8A\xE8\xD0\x0F\x5F THUMB32,ARMv7 ++reg32,memam6 \x18\x01\xF0\x0F\x9F ARM32,ARMv4 + +-[BFCcc] ++[STREXcc] ++reg32,reg32,memam6 \x8B\xE8\x40\x00\x00 THUMB32,ARMv6T2 ++reg32,reg32,memam6 \x18\x01\x80\x0F\x90 ARM32,ARMv4 + +-[BFIcc] ++[STREXBcc] ++reg32,reg32,memam6 \x8B\xE8\xC0\x0F\x40 THUMB32,ARMv7 ++reg32,reg32,memam6 \x18\x01\xC0\x0F\x90 ARM32,ARMv4 + +-[CLREX] ++[STREXDcc] ++reg32,reg32,reg32,memam6 \x8B\xE8\xC0\x00\x70 THUMB32,ARMv7 ++reg32,reg32,reg32,memam6 \x18\x01\xA0\x0F\x90 ARM32,ARMv4 + +-[LDREXcc] +-[LDREXBcc] +-[LDREXDcc] +-[LDREXHcc] ++[STREXHcc] ++reg32,reg32,memam6 \x8B\xE8\xC0\x0F\x50 THUMB32,ARMv7 ++reg32,reg32,memam6 \x18\x01\xE0\x0F\x90 ARM32,ARMv4 + + [MLScc] ++reg32,reg32,reg32,reg32 \x80\xFB\x0\x0\x10 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x15\x00\x60\x9 ARM32,ARMv6T2 ++ ++[PKHBTcc] ++reg32,reg32,reg32 \x80\xEA\xC0\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32,shifterop \x80\xEA\xC0\x0\x0 THUMB32,ARMv6T2 ++ ++reg32,reg32,reg32 \x16\x6\x80\x1 ARM32,ARMv6 ++reg32,reg32,reg32,shifterop \x16\x6\x80\x1 ARM32,ARMv6 ++ ++[PKHTBcc] ++reg32,reg32,reg32 \x80\xEA\xC0\x0\x10 THUMB32,ARMv6T2 ++reg32,reg32,reg32,shifterop \x80\xEA\xC0\x0\x10 THUMB32,ARMv6T2 + +-[PKHcc] ++reg32,reg32,reg32 \x16\x6\x80\x1 ARM32,ARMv6 ++reg32,reg32,reg32,shifterop \x16\x6\x80\x5 ARM32,ARMv6 + + [PLI] ++memam2 \x87\xF9\x10\xF0\x0 THUMB32,ARMv7 ++memam2 \x25\xF4\x50\xF0\x0 ARM32,ARMv7 + + [QADD16cc] ++reg32,reg32,reg32 \x80\xFA\x90\xF0\x10 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x20\xF1 ARM32,ARMv6 + [QADD8cc] ++reg32,reg32,reg32 \x80\xFA\x80\xF0\x10 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x20\xF9 ARM32,ARMv6 + [QASXcc] ++reg32,reg32,reg32 \x80\xFA\xA0\xF0\x10 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x20\xF3 ARM32,ARMv6 + [QSAXcc] ++reg32,reg32,reg32 \x80\xFA\xE0\xF0\x10 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x20\xF5 ARM32,ARMv6 + [QSUB16cc] ++reg32,reg32,reg32 \x80\xFA\xD0\xF0\x10 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x20\xF7 ARM32,ARMv6 + [QSUB8cc] ++reg32,reg32,reg32 \x80\xFA\xC0\xF0\x10 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x20\xFF ARM32,ARMv6 + + [RBITcc] ++reg32,reg32 \x80\xFA\x90\xF0\xA0 THUMB32,ARMv6T2 ++reg32,reg32 \x32\x6\xFF\xF\x30 ARM32,ARMv6T2 + + [REVcc] ++reglo,reglo \x61\xBA\x00 THUMB,ARMv6 ++reg32,reg32 \x80\xFA\x90\xF0\x80 THUMB32,WIDE,ARMv6T2 ++reg32,reg32 \x32\x6\xBF\xF\x30 ARM32,ARMv6 ++ + [REV16cc] ++reglo,reglo \x61\xBA\x40 THUMB,ARMv6 ++reg32,reg32 \x80\xFA\x90\xF0\x90 THUMB32,WIDE,ARMv6T2 ++reg32,reg32 \x32\x6\xBF\xF\xB0 ARM32,ARMv6 ++ + [REVSHcc] ++reglo,reglo \x61\xBA\xC0 THUMB,ARMv6 ++reg32,reg32 \x80\xFA\x90\xF0\xB0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32 \x32\x6\xFF\xF\xB0 ARM32,ARMv6 + + [SADD16cc] ++reg32,reg32,reg32 \x80\xFA\90\xF0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x10\xF1 ARM32,ARMv6 ++ + [SADD8cc] ++reg32,reg32,reg32 \x80\xFA\80\xF0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x10\xF9 ARM32,ARMv6 ++ + [SASXcc] ++reg32,reg32,reg32 \x80\xFA\A0\xF0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x10\xF3 ARM32,ARMv6 + + [SBFXcc] ++reg32,reg32,immshifter,immshifter \x84\xF3\x40\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,immshifter,immshifter \x2D\x7\xA0\x0\x50 ARM32,ARMv6T2 + + [SELcc] ++reg32,reg32,reg32 \x80\xFA\xA0\xF0\x80 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x80\xFB ARM32,ARMv6 + + [SETEND] ++immshifter \x2B\xF1\x01\x0\x0 ARM32,ARMv6 + + [SEVcc] ++void \x64\xBF\x40 THUMB,ARMv7 ++void \x2F\x3\x20\xF0\x4 ARM32,ARMv6K + + [ASRcc] ++reglo,immshifter \x60\x1\x0 THUMB,ARMv4T ++reglo,reglo,immshifter \x60\x1\x0 THUMB,ARMv4T ++reglo,reglo \x6B\x41\x0 THUMB,ARMv4T ++ ++reg32,immshifter \x82\xEA\x4F\x0\x20 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,immshifter \x82\xEA\x4F\x0\x20 THUMB32,WIDE,ARMv6T2 ++reg32,reg32 \x80\xFA\x40\xF0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32 \x80\xFA\x40\xF0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32,reg32 \x30\x1\xA0\x0\x50 ARM32,ARMv4 ++reg32,reg32,immshifter \x30\x1\xA0\x0\x40 ARM32,ARMv4 + + [LSRcc] ++reglo,immshifter \x60\x8\x0 THUMB,ARMv4T ++reglo,reglo,immshifter \x60\x8\x0 THUMB,ARMv4T ++reglo,reglo \x6B\x40\xC0 THUMB,ARMv4T ++ ++reg32,immshifter \x82\xEA\x4F\x0\x10 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,immshifter \x82\xEA\x4F\x0\x10 THUMB32,WIDE,ARMv6T2 ++reg32,reg32 \x80\xFA\x20\xF0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32 \x80\xFA\x20\xF0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32,reg32 \x30\x1\xA0\x0\x30 ARM32,ARMv4 ++reg32,reg32,immshifter \x30\x1\xA0\x0\x20 ARM32,ARMv4 + + [LSLcc] ++reglo,immshifter \x60\x0\x0 THUMB,ARMv4T ++reglo,reglo,immshifter \x60\x0\x0 THUMB,ARMv4T ++reglo,reglo \x6B\x40\x80 THUMB,ARMv4T ++ ++reg32,immshifter \x82\xEA\x4F\x0\x00 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,immshifter \x82\xEA\x4F\x0\x00 THUMB32,WIDE,ARMv6T2 ++reg32,reg32 \x80\xFA\x60\xF0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32 \x80\xFA\x60\xF0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32,reg32 \x30\x1\xA0\x0\x10 ARM32,ARMv4 ++reg32,reg32,immshifter \x30\x1\xA0\x0\x00 ARM32,ARMv4 + + [RORcc] ++reglo,reglo \x6B\x41\xC0 THUMB,ARMv4T ++ ++reg32,immshifter \x82\xEA\x4F\x0\x30 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,immshifter \x82\xEA\x4F\x0\x30 THUMB32,WIDE,ARMv6T2 ++reg32,reg32 \x80\xFA\x60\xF0\x0 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,reg32 \x80\xFA\x60\xF0\x0 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32,reg32 \x30\x1\xA0\x0\x70 ARM32,ARMv4 ++reg32,reg32,immshifter \x30\x1\xA0\x0\x60 ARM32,ARMv4 ++ ++[RRXcc] ++reg32,reg32 \x80\xEA\x4F\x00\x30 THUMB32,ARMv6T2 ++reg32,reg32 \x30\x1\xA0\x0\x60 ARM32,ARMv4 ++ ++[UMAALcc] ++reg32,reg32,reg32,reg32 \x85\xFB\xE0\x0\x60 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x16\x0\x40\x9 ARM32,ARMv6 + + [SHADD16cc] ++reg32,reg32,reg32 \x80\xFA\x90\xF0\x20 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x30\xF1 ARM32,ARMv6 ++ + [SHADD8cc] ++reg32,reg32,reg32 \x80\xFA\x80\xF0\x20 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x30\xF9 ARM32,ARMv6 ++ + [SHASXcc] ++reg32,reg32,reg32 \x80\xFA\xA0\xF0\x20 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x30\xF3 ARM32,ARMv6 ++ + [SHSAXcc] ++reg32,reg32,reg32 \x80\xFA\xE0\xF0\x20 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x30\xF5 ARM32,ARMv6 ++ + [SHSUB16cc] ++reg32,reg32,reg32 \x80\xFA\xD0\xF0\x20 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x30\xF7 ARM32,ARMv6 ++ + [SHSUB8cc] ++reg32,reg32,reg32 \x80\xFA\xC0\xF0\x20 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x30\xFF ARM32,ARMv6 + + [SMLADcc] ++reg32,reg32,reg32,reg32 \x80\xFB\x20\x0\x00 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x15\x7\x00\x1 ARM32,ARMv6 ++ + [SMLALDcc] ++reg32,reg32,reg32,reg32 \x85\xFB\xC0\x0\xC0 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x16\x7\x40\x1 ARM32,ARMv4 ++ + [SMLSDcc] ++reg32,reg32,reg32,reg32 \x80\xFB\x40\x0\x00 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x15\x7\x00\x5 ARM32,ARMv6 ++ + [SMLSLDcc] ++reg32,reg32,reg32,reg32 \x85\xFB\xD0\x0\xC0 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x16\x7\x40\x5 ARM32,ARMv6 ++ + [SMMLAcc] ++reg32,reg32,reg32,reg32 \x80\xFB\x50\x0\x00 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x15\x7\x50\x1 ARM32,ARMv6 ++ + [SMMLScc] ++reg32,reg32,reg32,reg32 \x80\xFB\x60\x0\x00 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x15\x7\x50\xD ARM32,ARMv6 ++ + [SMMULcc] ++reg32,reg32,reg32 \x80\xFB\x50\xF0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x15\x7\x50\x1\xF ARM32,ARMv6 ++ + [SMUADcc] ++reg32,reg32,reg32 \x80\xFB\x20\xF0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x15\x7\x00\x1\xF ARM32,ARMv6 ++ + [SMUSDcc] ++reg32,reg32,reg32 \x80\xFB\x40\xF0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x15\x7\x00\x5\xF ARM32,ARMv6 + + [SRScc] + + [SSATcc] ++reg32,immshifter,reg32 \x83\xF3\x00\x0\x0 THUMB32,ARMv6T2 ++reg32,immshifter,reg32,shifterop \x83\xF3\x00\x0\x0 THUMB32,ARMv6T2 ++ ++reg32,immshifter,reg32 \x2A\x6\xA0\x0\x10 ARM32,ARMv6 ++reg32,immshifter,reg32,shifterop \x2A\x6\xA0\x0\x10 ARM32,ARMv6 ++ + [SSAT16cc] ++reg32,immshifter,reg32 \x83\xF3\x20\x0\x0 THUMB32,ARMv6T2 ++reg32,immshifter,reg32 \x2A\x6\xA0\xF\x30 ARM32,ARMv6 ++ + [SSAXcc] ++reg32,reg32,reg32 \x80\xFA\xE0\xF0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x10\xF5 ARM32,ARMv6 + + [SSUB16cc] +-[SSUB8cc] ++reg32,reg32,reg32 \x80\xFA\xD0\xF0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x10\xF7 ARM32,ARMv6 + +-[STREXcc] +-[STREXBcc] +-[STREXDcc] +-[STREXHcc] ++[SSUB8cc] ++reg32,reg32,reg32 \x80\xFA\xC0\xF0\x0 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x10\xFF ARM32,ARMv6 + + [SXTABcc] ++reg32,reg32,reg32 \x86\xFA\x40\xF0\x80 THUMB32,ARMv6T2 ++reg32,reg32,reg32,shifterop \x86\xFA\x40\xF0\x80 THUMB32,ARMv6T2 ++ ++reg32,reg32,reg32 \x16\x06\xA0\x07 ARM32,ARMv6 ++reg32,reg32,reg32,shifterop \x16\x06\xA0\x07 ARM32,ARMv6 ++ + [SXTAB16cc] ++reg32,reg32,reg32 \x86\xFA\x20\xF0\x80 THUMB32,ARMv6T2 ++reg32,reg32,reg32,shifterop \x86\xFA\x20\xF0\x80 THUMB32,ARMv6T2 ++ ++reg32,reg32,reg32 \x16\x06\x80\x07 ARM32,ARMv6 ++reg32,reg32,reg32,shifterop \x16\x06\x80\x07 ARM32,ARMv6 ++ + [SXTAHcc] ++reg32,reg32,reg32 \x86\xFA\x00\xF0\x80 THUMB32,ARMv6T2 ++reg32,reg32,reg32,shifterop \x86\xFA\x00\xF0\x80 THUMB32,ARMv6T2 ++ ++reg32,reg32,reg32 \x16\x06\xB0\x07 ARM32,ARMv6 ++reg32,reg32,reg32,shifterop \x16\x06\xB0\x07 ARM32,ARMv6 ++ ++[UBFXcc] ++reg32,reg32,immshifter,immshifter \x84\xF3\xC0\x0\x0 THUMB32,ARMv6T2 ++reg32,reg32,immshifter,immshifter \x2D\x7\xE0\x0\x50 ARM32,ARMv4 ++ ++[UXTABcc] ++reg32,reg32,reg32 \x86\xFA\x50\xF0\x80 THUMB32,ARMv6T2 ++reg32,reg32,reg32,shifterop \x86\xFA\x50\xF0\x80 THUMB32,ARMv6T2 ++ ++reg32,reg32,reg32 \x16\x6\xE0\x7 ARM32,ARMv6 ++reg32,reg32,reg32,shifterop \x16\x6\xE0\x7 ARM32,ARMv6 ++ ++[UXTAB16cc] ++reg32,reg32,reg32 \x86\xFA\x30\xF0\x80 THUMB32,ARMv6T2 ++reg32,reg32,reg32,shifterop \x86\xFA\x30\xF0\x80 THUMB32,ARMv6T2 ++ ++reg32,reg32,reg32 \x86\xFA\x40\xF0\x80 THUMB32,ARMv6T2 ++reg32,reg32,reg32,shifterop \x86\xFA\x40\xF0\x80 THUMB32,ARMv6T2 ++ ++reg32,reg32,reg32 \x16\x6\xC0\x7 ARM32,ARMv6 ++reg32,reg32,reg32,shifterop \x16\x6\xC0\x7 ARM32,ARMv6 ++ ++[UXTAHcc] ++reg32,reg32,reg32 \x86\xFA\x10\xF0\x80 THUMB32,ARMv6T2 ++reg32,reg32,reg32,shifterop \x86\xFA\x10\xF0\x80 THUMB32,ARMv6T2 ++ ++reg32,reg32,reg32 \x16\x6\xF0\x7 ARM32,ARMv6 ++reg32,reg32,reg32,shifterop \x16\x6\xF0\x7 ARM32,ARMv6 ++ + [SXTBcc] ++reglo,reglo \x61\xB2\x40 THUMB,ARMv6 ++ ++reg32,reg32 \x86\xFA\x4F\xF0\x80 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x86\xFA\x4F\xF0\x80 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32 \x1B\x6\xAF\x7 ARM32,ARMv6 ++reg32,reg32,shifterop \x1B\x6\xAF\x7 ARM32,ARMv6 ++ + [SXTB16cc] ++reg32,reg32 \x86\xFA\x2F\xF0\x80 THUMB32,ARMv6T2 ++reg32,reg32,shifterop \x86\xFA\x2F\xF0\x80 THUMB32,ARMv6T2 ++ ++reg32,reg32 \x1B\x6\x8F\x7 ARM32,ARMv6 ++reg32,reg32,shifterop \x1B\x6\x8F\x7 ARM32,ARMv6 ++ ++[SXTHcc] ++reglo,reglo \x61\xB2\x00 THUMB,ARMv6 ++ ++reg32,reg32 \x86\xFA\x0F\xF0\x80 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x86\xFA\x0F\xF0\x80 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32 \x1B\x6\xBF\x7 ARM32,ARMv6 ++reg32,reg32,shifterop \x1B\x6\xBF\x7 ARM32,ARMv6 + + [UXTBcc] ++reglo,reglo \x61\xB2\xC0 THUMB,ARMv6 ++ ++reg32,reg32 \x86\xFA\x5F\xF0\x80 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x86\xFA\x5F\xF0\x80 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32 \x1B\x6\xEF\x7 ARM32,ARMv6 ++reg32,reg32,shifterop \x1B\x6\xEF\x7 ARM32,ARMv6 ++ ++[UXTB16cc] ++reg32,reg32 \x86\xFA\x3F\xF0\x80 THUMB32,ARMv6T2 ++reg32,reg32,shifterop \x86\xFA\x3F\xF0\x80 THUMB32,ARMv6T2 ++ ++reg32,reg32 \x1B\x6\xCF\x7 ARM32,ARMv6 ++reg32,reg32,shifterop \x1B\x6\xCF\x7 ARM32,ARMv6 ++ + [UXTHcc] ++reglo,reglo \x61\xB2\x80 THUMB,ARMv6 + +-[SXTHcc] ++reg32,reg32 \x86\xFA\x1F\xF0\x80 THUMB32,WIDE,ARMv6T2 ++reg32,reg32,shifterop \x86\xFA\x1F\xF0\x80 THUMB32,WIDE,ARMv6T2 ++ ++reg32,reg32 \x1B\x6\xFF\x7 ARM32,ARMv6 ++reg32,reg32,shifterop \x1B\x6\xFF\x7 ARM32,ARMv6 + + [UADD16cc] ++reg32,reg32,reg32 \x80\xFA\x90\xF0\x40 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x50\xF1 ARM32,ARMv6 ++ + [UADD8cc] +-[UASXcc] ++reg32,reg32,reg32 \x80\xFA\x80\xF0\x40 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x50\xF9 ARM32,ARMv6 + +-[UBFXcc] ++[UASXcc] ++reg32,reg32,reg32 \x80\xFA\xA0\xF0\x40 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x50\xF3 ARM32,ARMv6 + + [UHADD16cc] ++reg32,reg32,reg32 \x80\xFA\x90\xF0\x60 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x70\xF1 ARM32,ARMv6 ++ + [UHADD8cc] ++reg32,reg32,reg32 \x80\xFA\x80\xF0\x60 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x70\xF9 ARM32,ARMv6 ++ + [UHASXcc] ++reg32,reg32,reg32 \x80\xFA\xA0\xF0\x60 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x70\xF3 ARM32,ARMv6 ++ + [UHSAXcc] ++reg32,reg32,reg32 \x80\xFA\xE0\xF0\x60 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x70\xF5 ARM32,ARMv6 ++ + [UHSUB16cc] +-[UHSUB8cc] ++reg32,reg32,reg32 \x80\xFA\xD0\xF0\x60 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x70\xF7 ARM32,ARMv6 + +-[UMAALcc] ++[UHSUB8cc] ++reg32,reg32,reg32 \x80\xFA\xC0\xF0\x60 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x70\xFF ARM32,ARMv6 + + [UQADD16cc] ++reg32,reg32,reg32 \x80\xFA\x90\xF0\x50 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x60\xF1 ARM32,ARMv6 ++ + [UQADD8] ++reg32,reg32,reg32 \x80\xFA\x80\xF0\x50 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x60\xF9 ARM32,ARMv6 ++ + [UQASXcc] ++reg32,reg32,reg32 \x80\xFA\xA0\xF0\x50 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x60\xF3 ARM32,ARMv6 ++ + [UQSAXcc] ++reg32,reg32,reg32 \x80\xFA\xE0\xF0\x50 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x60\xF5 ARM32,ARMv6 + + [UQSUB16cc] ++reg32,reg32,reg32 \x80\xFA\xD0\xF0\x50 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x60\xF7 ARM32,ARMv6 ++ + [UQSUB8cc] +-[UQSAD8cc] +-[UQSADA8cc] ++reg32,reg32,reg32 \x80\xFA\xC0\xF0\x50 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x60\xFF ARM32,ARMv6 ++ ++[USAD8cc] ++reg32,reg32,reg32 \x80\xFB\x70\xF0\x00 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x15\x07\x80\x01\xF ARM32,ARMv6 ++ ++[USADA8cc] ++reg32,reg32,reg32,reg32 \x80\xFB\x70\x0\x00 THUMB32,ARMv6T2 ++reg32,reg32,reg32,reg32 \x15\x07\x80\x01 ARM32,ARMv6 + + [USATcc] ++reg32,immshifter,reg32 \x83\xF3\x80\x0\x0 THUMB32,ARMv6T2 ++reg32,immshifter,reg32,shifterop \x83\xF3\x80\x0\x0 THUMB32,ARMv6T2 ++ ++reg32,immshifter,reg32 \x2A\x6\xE0\x0\x10 ARM32,ARMv6 ++reg32,immshifter,reg32,shifterop \x2A\x6\xE0\x0\x10 ARM32,ARMv6 ++ + [USAT16cc] ++reg32,immshifter,reg32 \x83\xF3\xA0\x0\x0 THUMB32,ARMv6T2 ++reg32,immshifter,reg32 \x2A\x6\xE0\xF\x30 ARM32,ARMv6 ++ + [USAXcc] ++reg32,reg32,reg32 \x80\xFA\xE0\xF0\x40 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x50\xF5 ARM32,ARMv6 + + [USUB16cc] +-[USUB8cc] ++reg32,reg32,reg32 \x80\xFA\xD0\xF0\x40 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x50\xF7 ARM32,ARMv6 + +-[UXTABcc] +-[UXTAB16cc] +-[UXTAHcc] +-[UXTB16cc] ++[USUB8cc] ++reg32,reg32,reg32 \x80\xFA\xC0\xF0\x40 THUMB32,ARMv6T2 ++reg32,reg32,reg32 \x16\x06\x50\xFF ARM32,ARMv6 + + [WFEcc] ++void \x64\xBF\x20 THUMB,ARMv7 ++void \x2F\x3\x20\xF0\x2 ARM32,ARMv6K ++ + [WFIcc] ++void \x64\xBF\x30 THUMB,ARMv7 ++void \x2F\x3\x20\xF0\x3 ARM32,ARMv6K ++ + [YIELDcc] ++void \x64\xBF\x10 THUMB,ARMv7 ++void \x2F\x3\x20\xF0\x1 ARM32,ARMv6K ++ ++; ++; vfp instructions ++; ++[FABSDcc] ++vreg,vreg \x92\xEE\xB0\xA\xC0\0 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB0\xA\xC0\0 ARM32,VFPv2 ++ ++[FABSScc] ++vreg,vreg \x92\xEE\xB0\xA\xC0\1 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB0\xA\xC0\1 ARM32,VFPv2 ++ ++[FADDDcc] ++vreg,vreg,vreg \x92\xEE\x30\xA\x0\0 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x30\xA\x0\0 ARM32,VFPv2 ++ ++[FADDScc] ++vreg,vreg,vreg \x92\xEE\x30\xA\x0\1 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x30\xA\x0\1 ARM32,VFPv2 ++ ++[FCMPDcc] ++vreg,vreg \x92\xEE\xB4\xA\x40\0 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB4\xA\x40\0 ARM32,VFPv2 ++ ++[FCMPScc] ++vreg,vreg \x92\xEE\xB4\xA\x40\1 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB4\xA\x40\1 ARM32,VFPv2 ++ ++[FCMPEDcc] ++vreg,vreg \x92\xEE\xB4\xA\xC0\0 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB4\xA\xC0\0 ARM32,VFPv2 ++ ++[FCMPEScc] ++vreg,vreg \x92\xEE\xB4\xA\xC0\1 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB4\xA\xC0\1 ARM32,VFPv2 ++ ++[FCMPZDcc] ++vreg \x92\xEE\xB5\xA\x40\0 THUMB32,VFPv2 ++vreg \x42\xE\xB5\xA\x40\0 ARM32,VFPv2 ++ ++[FCMPZScc] ++vreg \x92\xEE\xB5\xA\x40\1 THUMB32,VFPv2 ++vreg \x42\xE\xB5\xA\x40\1 ARM32,VFPv2 ++ ++[FCMPEZDcc] ++vreg \x92\xEE\xB5\xA\xC0\0 THUMB32,VFPv2 ++vreg \x42\xE\xB5\xA\xC0\0 ARM32,VFPv2 ++ ++[FCMPEZScc] ++vreg \x92\xEE\xB5\xA\xC0\1 THUMB32,VFPv2 ++vreg \x42\xE\xB5\xA\xC0\1 ARM32,VFPv2 ++ ++[FCPYDcc] ++vreg,vreg \x43\xEE\xB0\xB\x40 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xB0\xB\x40 ARM32,VFPv2 ++ ++[FCPYScc] ++vreg,vreg \x43\xEE\xB0\xA\x40 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xB0\xA\x40 ARM32,VFPv2 ++ ++[FCVTDScc] ++vreg,vreg \x43\xEE\xB7\xA\xC0 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xB7\xA\xC0 ARM32,VFPv2 ++ ++[FCVTSDcc] ++vreg,vreg \x43\xEE\xB7\xB\xC0 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xB7\xB\xC0 ARM32,VFPv2 ++ ++[FDIVDcc] ++vreg,vreg,vreg \x92\xEE\x80\xA\x0\0 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x80\xA\x0\0 ARM32,VFPv2 ++ ++[FDIVScc] ++vreg,vreg,vreg \x92\xEE\x80\xA\x0\1 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x80\xA\x0\1 ARM32,VFPv2 ++ ++[FLDDcc] ++vreg,memam2 \x95\xED\x10\xA THUMB32,VFPv2 ++vreg,memam2 \x45\xD\x10\xA ARM32,VFPv2 ++ ++[FLDMcc] ++memam4,reglist \x94\xEC\x10\xA THUMB32,VFPv2 ++reg32,reglist \x94\xEC\x10\xA THUMB32,VFPv2 ++memam4,reglist \x44\xC\x10\xA ARM32,VFPv2 ++reg32,reglist \x44\xC\x10\xA ARM32,VFPv2 ++ ++[FLDScc] ++vreg,memam2 \x95\xED\x10\xA THUMB32,VFPv2 ++vreg,memam2 \x45\xD\x10\xA ARM32,VFPv2 ++ ++[FMACDcc] ++vreg,vreg,vreg \x92\xEE\x0\xA\x00\0 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x0\xA\x00\0 ARM32,VFPv2 ++ ++[FMACScc] ++vreg,vreg,vreg \x92\xEE\x0\xA\x00\1 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x0\xA\x00\1 ARM32,VFPv2 ++ ++[FMDHRcc] ++ ++[FMDLRcc] ++ ++[FMRDHcc] ++ ++[FMRDLcc] ++ ++[FMRScc] ++reg32,vreg \x90\xEE\x10\xA\x10 THUMB32,VFPv2 ++reg32,vreg \x40\xE\x10\xA\x10 ARM32,VFPv2 ++ ++[FMRXcc] ++reg32,regf \x91\xEE\xF0\xA\x10 THUMB32,VFPv2 ++regf,regf \x91\xEE\xF0\xA\x10 THUMB32,VFPv2 ++reg32,regf \x41\xE\xF0\xA\x10 ARM32,VFPv2 ++regf,regf \x41\xE\xF0\xA\x10 ARM32,VFPv2 ++ ++[FMSCDcc] ++vreg,vreg,vreg \x92\xEE\x10\xA\x00\0 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x10\xA\x00\0 ARM32,VFPv2 ++ ++[FMSCScc] ++vreg,vreg,vreg \x92\xEE\x10\xA\x00\1 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x10\xA\x00\1 ARM32,VFPv2 ++ ++[FMSRcc] ++vreg,reg32 \x90\xEE\x00\xA\x10 THUMB32,VFPv2 ++vreg,reg32 \x40\xE\x00\xA\x10 ARM32,VFPv2 ++ ++[FMSTATcc] ++void \x80\xEE\xF1\xFA\x10 THUMB32,VFPv2 ++void \x2F\xE\xF1\xFA\x10 ARM32,VFPv2 ++ ++[FMULDcc] ++vreg,vreg,vreg \x92\xEE\x20\xA\x0\0 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x20\xA\x0\0 ARM32,VFPv2 ++ ++[FMULScc] ++vreg,vreg,vreg \x92\xEE\x20\xA\x0\1 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x20\xA\x0\1 ARM32,VFPv2 ++ ++[FMXRcc] ++regf,reg32 \x91\xEE\xE0\xA\x10 THUMB32,VFPv2 ++regf,reg32 \x41\xE\xE0\xA\x10 ARM32,VFPv2 ++ ++[FNEGDcc] ++vreg,vreg \x92\xEE\xB1\xA\x40\0 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB1\xA\x40\0 ARM32,VFPv2 ++ ++[FNEGScc] ++vreg,vreg \x92\xEE\xB1\xA\x40\1 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB1\xA\x40\1 ARM32,VFPv2 ++ ++[FNMACDcc] ++vreg,vreg,vreg \x92\xEE\x00\xA\x40\0 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x00\xA\x40\0 ARM32,VFPv2 ++ ++[FNMACScc] ++vreg,vreg,vreg \x92\xEE\x00\xA\x40\1 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x00\xA\x40\1 ARM32,VFPv2 ++ ++[FNMSCDcc] ++vreg,vreg,vreg \x92\xEE\x10\xA\x40\0 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x10\xA\x40\0 ARM32,VFPv2 ++ ++[FNMSCScc] ++vreg,vreg,vreg \x92\xEE\x10\xA\x40\1 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x10\xA\x40\1 ARM32,VFPv2 ++ ++[FNMULDcc] ++vreg,vreg,vreg \x92\xEE\x20\xA\x40\0 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x20\xA\x40\0 ARM32,VFPv2 ++ ++[FNMULScc] ++vreg,vreg,vreg \x92\xEE\x20\xA\x40\1 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x20\xA\x40\1 ARM32,VFPv2 ++ ++[FSITODcc] ++vreg,vreg \x43\xEE\xB8\xB\xC0 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xB8\xB\xC0 ARM32,VFPv2 ++ ++[FSITOScc] ++vreg,vreg \x43\xEE\xB8\xA\xC0 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xB8\xA\xC0 ARM32,VFPv2 ++ ++[FSQRTDcc] ++vreg,vreg \x92\xEE\xB1\xA\xC0\0 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB1\xA\xC0\0 ARM32,VFPv2 ++ ++[FSQRTScc] ++vreg,vreg \x92\xEE\xB1\xA\xC0\1 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB1\xA\xC0\1 ARM32,VFPv2 ++ ++[FSUBDcc] ++vreg,vreg,vreg \x92\xEE\x30\xA\x40\0 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x30\xA\x40\0 ARM32,VFPv2 ++ ++[FSUBScc] ++vreg,vreg,vreg \x92\xEE\x30\xA\x40\1 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x30\xA\x40\1 ARM32,VFPv2 ++ ++[FTOSIDcc] ++vreg,vreg \x43\xEE\xBD\xB\x40 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xBD\xB\x40 ARM32,VFPv2 ++ ++[FTOSIScc] ++vreg,vreg \x43\xEE\xBD\xA\x40 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xBD\xA\x40 ARM32,VFPv2 ++ ++[FTOUIDcc] ++vreg,vreg \x43\xEE\xBC\xB\x40 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xBC\xB\x40 ARM32,VFPv2 ++ ++[FTOUIScc] ++vreg,vreg \x43\xEE\xBC\xA\x40 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xBC\xA\x40 ARM32,VFPv2 ++ ++[FUITODcc] ++vreg,vreg \x43\xEE\xB8\xB\x40 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xB8\xB\x40 ARM32,VFPv2 ++ ++[FUITOScc] ++vreg,vreg \x43\xEE\xB8\xA\x40 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xB8\xA\x40 ARM32,VFPv2 ++ ++[FMDRRcc] ++ ++[FMRRDcc] + + ; Thumb-2 + + [POP] ++reglist \x69\xBC THUMB,ARMv4T ++reglist \x26\x8B ARM32,ARMv4 + + [PUSH] ++reglist \x69\xB4 THUMB,ARMv4T ++reglist \x26\x80 ARM32,ARMv4 + + [SDIVcc] ++reg32,reg32,reg32 \x80\xFB\x90\xF0\xF0 THUMB32,ARMv7R,ARMv7M ++reg32,reg32,reg32 \x15\x07\x10\x01\xF ARM32,ARMv7 + + [UDIVcc] ++reg32,reg32,reg32 \x80\xFB\xB0\xF0\xF0 THUMB32,ARMv7R,ARMv7M ++reg32,reg32,reg32 \x15\x07\x30\x01\xF ARM32,ARMv7 + + [MOVTcc] ++reg32,imm \x81\xF2\xC0\x0\x0 THUMB32,ARMv6T2 ++reg32,immshifter \x81\xF2\xC0\x0\x0 THUMB32,ARMv6T2 ++ ++reg32,imm \x2C\x3\x40 ARM32,ARMv6T2 ++reg32,immshifter \x2C\x3\x40 ARM32,ARMv6T2 + + [IT] ++condition \x6A\xBF\x08\x00 THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITE] ++condition \x6A\xBF\x04\x88 THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITT] ++condition \x6A\xBF\x04\x08 THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITEE] ++condition \x6A\xBF\x02\xCC THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITTE] ++condition \x6A\xBF\x02\x4C THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITET] ++condition \x6A\xBF\x02\x8C THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITTT] ++condition \x6A\xBF\x02\x0C THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITEEE] ++condition \x6A\xBF\x01\xEE THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITTEE] ++condition \x6A\xBF\x01\x6E THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITETE] ++condition \x6A\xBF\x01\xAE THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITTTE] ++condition \x6A\xBF\x01\x2E THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITEET] ++condition \x6A\xBF\x01\xCE THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITTET] ++condition \x6A\xBF\x01\x4E THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITETT] ++condition \x6A\xBF\x01\x8E THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + + [ITTTT] ++condition \x6A\xBF\x01\x0E THUMB,ARMv6T2 ++condition \xFE ARM32,ARMv4 + +-[TBB] +-[TBH] ++[TBBcc] ++memam2 \x8E\xE8\xD0\xF0\x00 THUMB32,ARMv6T2 ++ ++[TBHcc] ++memam2 \x8E\xE8\xD0\xF0\x10 THUMB32,ARMv6T2 + + [MOVW] ++reg32,imm32 \x2C\x3\x0 ARM32,ARMv6T2 ++reg32,immshifter \x2C\x3\x0 ARM32,ARMv6T2 ++ ++reg32,imm32 \x81\xF2\x40\x0\x0 THUMB32,ARMv6T2 ++reg32,immshifter \x81\xF2\x40\x0\x0 THUMB32,ARMv6T2 + + [CBZ] ++reglo,immshifter \x68\xB1 THUMB,ARMv6T2 ++reglo,memam2 \x68\xB1 THUMB,ARMv6T2 ++ + [CBNZ] ++reglo,immshifter \x68\xB9 THUMB,ARMv6T2 ++reglo,memam2 \x68\xB9 THUMB,ARMv6T2 ++ ++; VFP ++[VABScc] ++vreg,vreg \x92\xEE\xB0\xA\xC0 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB0\xA\xC0 ARM32,VFPv2 ++ ++[VADDcc] ++vreg,vreg,vreg \x92\xEE\x30\xA\x0 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x30\xA\x0 ARM32,VFPv2 ++ ++[VCMPcc] ++vreg,vreg \x92\xEE\xB4\xA\x40 THUMB32,VFPv2 ++vreg,immshifter \x92\xEE\xB5\xA\x40 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB4\xA\x40 ARM32,VFPv2 ++vreg,immshifter \x42\xE\xB5\xA\x40 ARM32,VFPv2 ++ ++[VCMPEcc] ++vreg,vreg \x92\xEE\xB4\xA\xC0 THUMB32,VFPv2 ++vreg,immshifter \x92\xEE\xB5\xA\xC0 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB4\xA\xC0 ARM32,VFPv2 ++vreg,immshifter \x42\xE\xB5\xA\xC0 ARM32,VFPv2 ++ ++[VCVTcc] ++vreg,vreg \x93\xEE\xB8\xA\xC0 THUMB32,VFPv2 ++vreg,vreg,immshifter \x93\xEE\xBA\xA\x40 THUMB32,VFPv3 ++vreg,vreg \x43\xE\xB8\xA\xC0 ARM32,VFPv2 ++vreg,vreg,immshifter \x43\xE\xBA\xA\x40 ARM32,VFPv3 ++ ++[VCVTRcc] ++vreg,vreg \x93\xEE\xB8\xA\x40 THUMB32,VFPv2 ++vreg,vreg \x43\xE\xB8\xA\x40 ARM32,VFPv2 ++ ++[VDIVcc] ++vreg,vreg,vreg \x92\xEE\x80\xA\x0 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x80\xA\x0 ARM32,VFPv2 ++ ++[VMRScc] ++reg32,regf \x91\xEE\xF0\xA\x10 THUMB32,VFPv2 ++regf,regf \x91\xEE\xF0\xA\x10 THUMB32,VFPv2 ++reg32,regf \x41\xE\xF0\xA\x10 ARM32,VFPv2 ++regf,regf \x41\xE\xF0\xA\x10 ARM32,VFPv2 ++ ++[VMSRcc] ++regf,reg32 \x91\xEE\xE0\xA\x10 THUMB32,VFPv2 ++regf,reg32 \x41\xE\xE0\xA\x10 ARM32,VFPv2 ++ ++[VMLAcc] ++vreg,vreg,vreg \x92\xEE\x0\xA\x00 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x0\xA\x00 ARM32,VFPv2 ++ ++[VMLScc] ++vreg,vreg,vreg \x92\xEE\x0\xA\x40 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x0\xA\x40 ARM32,VFPv2 ++ ++[VMULcc] ++vreg,vreg,vreg \x92\xEE\x20\xA\x0 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x20\xA\x0 ARM32,VFPv2 ++ ++[VNMLAcc] ++vreg,vreg,vreg \x92\xEE\x10\xA\x40 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x10\xA\x40 ARM32,VFPv2 ++ ++[VNMLScc] ++vreg,vreg,vreg \x92\xEE\x10\xA\x00 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x10\xA\x00 ARM32,VFPv2 ++ ++[VNMULcc] ++vreg,vreg,vreg \x92\xEE\x20\xA\x40 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x20\xA\x40 ARM32,VFPv2 + +-; FPv4-s16 - ARMv7M floating point +-[VABS] +-[VADD] +-[VCMP] +-[VCMPE] +-[VCVT] +-[VDIV] +-[VLDM] +-[VLDR] +-[VMOV] +-[VMRS] +-[VMSR] +-[VMUL] +-[VMLA] +-[VMLS] +-[VNMLA] +-[VNMLS] + [VFMA] ++vreg,vreg,vreg \x92\xEE\xA0\xA\x00 THUMB32,VFPv4 ++vreg,vreg,vreg \x42\xE\xA0\xA\x00 ARM32,VFPv4 ++ + [VFMS] ++vreg,vreg,vreg \x92\xEE\xA0\xA\x40 THUMB32,VFPv4 ++vreg,vreg,vreg \x42\xE\xA0\xA\x40 ARM32,VFPv4 ++ + [VFNMA] ++vreg,vreg,vreg \x92\xEE\x90\xA\x00 THUMB32,VFPv4 ++vreg,vreg,vreg \x42\xE\x90\xA\x00 ARM32,VFPv4 ++ + [VFNMS] +-[VNEG] +-[VNMUL] +-[VPOP] +-[VPUSH] ++vreg,vreg,vreg \x92\xEE\x90\xA\x40 THUMB32,VFPv4 ++vreg,vreg,vreg \x42\xE\x90\xA\x40 ARM32,VFPv4 ++ ++[VNEGcc] ++vreg,vreg \x92\xEE\xB1\xA\x40 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB1\xA\x40 ARM32,VFPv2 ++ + [VSQRT] +-[VSTM] +-[VSTR] ++vreg,vreg \x92\xEE\xB1\xA\xC0 THUMB32,VFPv2 ++vreg,vreg \x42\xE\xB1\xA\xC0 ARM32,VFPv2 ++ + [VSUB] ++vreg,vreg,vreg \x92\xEE\x30\xA\x40 THUMB32,VFPv2 ++vreg,vreg,vreg \x42\xE\x30\xA\x40 ARM32,VFPv2 ++ ++[DMBcc] ++immshifter \x80\xF3\xBF\x8F\x50 THUMB32,ARMv7 ++immshifter \x2E\xF5\x7F\xF0\x50 ARM32,ARMv7 ++ ++[ISBcc] ++immshifter \x80\xF3\xBF\x8F\x60 THUMB32,ARMv7 ++immshifter \x2E\xF5\x7F\xF0\x60 ARM32,ARMv7 ++ ++[DSBcc] ++immshifter \x80\xF3\xBF\x8F\x40 THUMB32,ARMv7 ++immshifter \x2E\xF5\x7F\xF0\x40 ARM32,ARMv7 ++ ++[SMCcc] ++immshifter \x2E\x01\x60\x00\x70 ARM32,ARMv7 ++imm32 \x2E\x01\x60\x00\x70 ARM32,ARMv7 + + ; Thumb armv6-m (gcc) +-[NEG] +-[SVC] ++[NEGcc] ++ ++[SVCcc] ++immshifter \x61\xDF\x0 THUMB,ARMv4T ++imm32 \x61\xDF\x0 THUMB,ARMv4T ++ ++immshifter \x2\x0F ARM32,ARMv4 ++imm32 \x2\x0F ARM32,ARMv4 ++ ++[BXJcc] ++reg32 \x80\xF3\xC0\x8F\x0 THUMB32,ARMv6T2 ++reg32 \x3\x01\x2F\xFF\x20 ARM32,ARMv5TEJ ++ ++; Undefined mnemonic ++[UDF] ++immshifter \x61\xDE\x0 THUMB,ARMv4T ++void void ARM32,ARMv4T ++ ++; FPA ++ ++ ++[TANcc] ++fpureg,fpureg \xA1\1\x15 ARM32,FPA ++fpureg,immshifter \xA1\1\x15 ARM32,FPA ++ ++[SQTcc] ++fpureg,fpureg \xA1\1\x9 ARM32,FPA ++fpureg,immshifter \xA1\1\x9 ARM32,FPA ++ ++[SUFcc] ++fpureg,fpureg,fpureg \xA1\0\x4 ARM32,FPA ++fpureg,fpureg,immshifter \xA1\0\x4 ARM32,FPA ++ ++[RSFcc] ++fpureg,fpureg,fpureg \xA1\0\x6 ARM32,FPA ++fpureg,fpureg,immshifter \xA1\0\x6 ARM32,FPA ++ ++[RNDcc] ++fpureg,fpureg \xA1\1\x7 ARM32,FPA ++fpureg,immshifter \xA1\1\x7 ARM32,FPA ++ ++[POLcc] ++fpureg,fpureg,fpureg \xA1\0\x18 ARM32,FPA ++fpureg,fpureg,immshifter \xA1\0\x18 ARM32,FPA ++ ++[RDFcc] ++fpureg,fpureg,fpureg \xA1\0\xA ARM32,FPA ++fpureg,fpureg,immshifter \xA1\0\xA ARM32,FPA ++ ++[RFScc] ++reg32 \xA2\xE\x3 ARM32,FPA ++ ++[RFCcc] ++reg32 \xA2\xE\x5 ARM32,FPA ++ ++[WFCcc] ++reg32 \xA2\xE\x4 ARM32,FPA ++ ++[RMFcc] ++fpureg,fpureg,fpureg \xA1\0\x10 ARM32,FPA ++fpureg,fpureg,immshifter \xA1\0\x10 ARM32,FPA ++ ++[RPWcc] ++fpureg,fpureg,fpureg \xA1\0\xC ARM32,FPA ++fpureg,fpureg,immshifter \xA1\0\xC ARM32,FPA ++ ++[MNFcc] ++fpureg,fpureg \xA1\1\x3 ARM32,FPA ++fpureg,immshifter \xA1\1\x3 ARM32,FPA + ++[MUFcc] ++fpureg,fpureg,fpureg \xA1\0\x2 ARM32,FPA ++fpureg,fpureg,immshifter \xA1\0\x2 ARM32,FPA ++ ++[ABScc] ++fpureg,fpureg \xA1\1\x5 ARM32,FPA ++fpureg,immshifter \xA1\1\x5 ARM32,FPA ++ ++[ACScc] ++fpureg,fpureg \xA1\1\x19 ARM32,FPA ++fpureg,immshifter \xA1\1\x19 ARM32,FPA ++ ++[ASNcc] ++fpureg,fpureg \xA1\1\x17 ARM32,FPA ++fpureg,immshifter \xA1\1\x17 ARM32,FPA ++ ++[ATNcc] ++fpureg,fpureg \xA1\1\x1B ARM32,FPA ++fpureg,immshifter \xA1\1\x1B ARM32,FPA ++ ++[CNFcc] ++fpureg,fpureg \xA2\xE\xB0 ARM32,FPA ++fpureg,immshifter \xA2\xE\xB0 ARM32,FPA ++ ++[CNFEcc] ++fpureg,fpureg \xA2\xE\xF0 ARM32,FPA ++fpureg,immshifter \xA2\xE\xF0 ARM32,FPA ++ ++[COScc] ++fpureg,fpureg \xA1\1\x13 ARM32,FPA ++fpureg,immshifter \xA1\1\x13 ARM32,FPA ++ ++[DVFcc] ++fpureg,fpureg,fpureg \xA1\0\x8 ARM32,FPA ++fpureg,fpureg,immshifter \xA1\0\x8 ARM32,FPA ++ ++[EXPcc] ++fpureg,fpureg \xA1\1\xF ARM32,FPA ++fpureg,immshifter \xA1\1\xF ARM32,FPA ++ ++[FDVcc] ++fpureg,fpureg,fpureg \xA1\0\x14 ARM32,FPA ++fpureg,fpureg,immshifter \xA1\0\x14 ARM32,FPA ++ ++[FLTcc] ++fpureg,reg32 \xA2\xE\x00 ARM32,FPA ++ ++[FIXcc] ++reg32,fpureg \xA2\xE\x10 ARM32,FPA ++ ++[FMLcc] ++fpureg,fpureg,fpureg \xA1\0\x12 ARM32,FPA ++fpureg,fpureg,immshifter \xA1\0\x12 ARM32,FPA ++ ++[FRDcc] ++fpureg,fpureg,fpureg \xA1\0\x16 ARM32,FPA ++fpureg,fpureg,immshifter \xA1\0\x16 ARM32,FPA ++ ++[LGNcc] ++fpureg,fpureg \xA1\1\xD ARM32,FPA ++fpureg,immshifter \xA1\1\xD ARM32,FPA ++ ++[LOGcc] ++fpureg,fpureg \xA1\1\xB ARM32,FPA ++fpureg,immshifter \xA1\1\xB ARM32,FPA +\ No newline at end of file +Index: fpc/fpcsrc/compiler/arm/armnop.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/armnop.inc ++++ fpc/fpcsrc/compiler/arm/armnop.inc +@@ -1,2 +1,2 @@ + { don't edit, this file is generated from armins.dat } +-105; ++952; +Index: fpc/fpcsrc/compiler/arm/armop.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/armop.inc ++++ fpc/fpcsrc/compiler/arm/armop.inc +@@ -1,12 +1,9 @@ + { don't edit, this file is generated from armins.dat } + ( + A_NONE, +-A_ABS, +-A_ACS, +-A_ASN, +-A_ATN, + A_ADC, + A_ADD, ++A_ADDW, + A_ADF, + A_ADR, + A_AND, +@@ -17,24 +14,18 @@ A_BLX, + A_BKPT, + A_BX, + A_CDP, +-A_CMF, +-A_CMFE, + A_CMN, + A_CMP, ++A_CMF, ++A_CMFE, ++A_STF, ++A_LDF, ++A_LFM, + A_CLZ, +-A_CNF, +-A_COS, + A_CPS, + A_CPSID, + A_CPSIE, +-A_DVF, + A_EOR, +-A_EXP, +-A_FDV, +-A_FLT, +-A_FIX, +-A_FML, +-A_FRD, + A_LDC, + A_LDM, + A_LDRBT, +@@ -44,41 +35,32 @@ A_LDRH, + A_LDRSB, + A_LDRSH, + A_LDRT, +-A_LDF, +-A_LFM, +-A_LGN, +-A_LOG, + A_MCR, ++A_MCR2, ++A_MRC, ++A_MRC2, ++A_MCRR, ++A_MCRR2, ++A_MRRC, ++A_MRRC2, + A_MLA, + A_MOV, +-A_MRC, + A_MRS, + A_MSR, +-A_MNF, +-A_MUF, + A_MUL, + A_MVF, + A_MVN, ++A_VMOV, + A_NOP, ++A_ORN, + A_ORR, +-A_RDF, +-A_RFS, +-A_RFC, +-A_RMF, +-A_RPW, + A_RSB, + A_RSC, +-A_RSF, +-A_RND, +-A_POL, + A_SBC, + A_SFM, + A_SIN, + A_SMLAL, + A_SMULL, +-A_SQT, +-A_SUF, +-A_STF, + A_STM, + A_STR, + A_STRB, +@@ -89,16 +71,14 @@ A_SUB, + A_SWI, + A_SWP, + A_SWPB, +-A_TAN, + A_TEQ, + A_TST, + A_UMLAL, + A_UMULL, + A_WFS, + A_LDRD, +-A_MCRR, +-A_MRRC, + A_PLD, ++A_PLDW, + A_QADD, + A_QDADD, + A_QDSUB, +@@ -113,6 +93,12 @@ A_SMLALTB, + A_SMLALTT, + A_SMLAWB, + A_SMLAWT, ++A_VLDM, ++A_VSTM, ++A_VPOP, ++A_VPUSH, ++A_VLDR, ++A_VSTR, + A_SMULBB, + A_SMULBT, + A_SMULTB, +@@ -120,67 +106,13 @@ A_SMULTT, + A_SMULWB, + A_SMULWT, + A_STRD, +-A_FABSD, +-A_FABSS, +-A_FADDD, +-A_FADDS, +-A_FCMPD, +-A_FCMPED, +-A_FCMPES, +-A_FCMPEZD, +-A_FCMPEZS, +-A_FCMPS, +-A_FCMPZD, +-A_FCMPZS, +-A_FCPYD, +-A_FCPYS, +-A_FCVTDS, +-A_FCVTSD, +-A_FDIVD, +-A_FDIVS, +-A_FLDD, +-A_FLDM, +-A_FLDS, +-A_FMACD, +-A_FMACS, +-A_FMDHR, +-A_FMDLR, +-A_FMRDH, +-A_FMRDL, +-A_FMRS, +-A_FMRX, +-A_FMSCD, +-A_FMSCS, +-A_FMSR, +-A_FMSTAT, +-A_FMULD, +-A_FMULS, +-A_FMXR, +-A_FNEGD, +-A_FNEGS, +-A_FNMACD, +-A_FNMACS, +-A_FNMSCD, +-A_FNMSCS, +-A_FNMULD, +-A_FNMULS, +-A_FSITOD, +-A_FSITOS, +-A_FSQRTD, +-A_FSQRTS, ++A_LDRHT, ++A_STRHT, ++A_LDRSBT, ++A_LDRSHT, + A_FSTD, + A_FSTM, + A_FSTS, +-A_FSUBD, +-A_FSUBS, +-A_FTOSID, +-A_FTOSIS, +-A_FTOUID, +-A_FTOUIS, +-A_FUITOD, +-A_FUITOS, +-A_FMDRR, +-A_FMRRD, + A_BFC, + A_BFI, + A_CLREX, +@@ -188,8 +120,13 @@ A_LDREX, + A_LDREXB, + A_LDREXD, + A_LDREXH, ++A_STREX, ++A_STREXB, ++A_STREXD, ++A_STREXH, + A_MLS, +-A_PKH, ++A_PKHBT, ++A_PKHTB, + A_PLI, + A_QADD16, + A_QADD8, +@@ -212,6 +149,8 @@ A_ASR, + A_LSR, + A_LSL, + A_ROR, ++A_RRX, ++A_UMAAL, + A_SHADD16, + A_SHADD8, + A_SHASX, +@@ -233,49 +172,102 @@ A_SSAT16, + A_SSAX, + A_SSUB16, + A_SSUB8, +-A_STREX, +-A_STREXB, +-A_STREXD, +-A_STREXH, + A_SXTAB, + A_SXTAB16, + A_SXTAH, ++A_UBFX, ++A_UXTAB, ++A_UXTAB16, ++A_UXTAH, + A_SXTB, + A_SXTB16, ++A_SXTH, + A_UXTB, ++A_UXTB16, + A_UXTH, +-A_SXTH, + A_UADD16, + A_UADD8, + A_UASX, +-A_UBFX, + A_UHADD16, + A_UHADD8, + A_UHASX, + A_UHSAX, + A_UHSUB16, + A_UHSUB8, +-A_UMAAL, + A_UQADD16, + A_UQADD8, + A_UQASX, + A_UQSAX, + A_UQSUB16, + A_UQSUB8, +-A_UQSAD8, +-A_UQSADA8, ++A_USAD8, ++A_USADA8, + A_USAT, + A_USAT16, + A_USAX, + A_USUB16, + A_USUB8, +-A_UXTAB, +-A_UXTAB16, +-A_UXTAH, +-A_UXTB16, + A_WFE, + A_WFI, + A_YIELD, ++A_FABSD, ++A_FABSS, ++A_FADDD, ++A_FADDS, ++A_FCMPD, ++A_FCMPS, ++A_FCMPED, ++A_FCMPES, ++A_FCMPZD, ++A_FCMPZS, ++A_FCMPEZD, ++A_FCMPEZS, ++A_FCPYD, ++A_FCPYS, ++A_FCVTDS, ++A_FCVTSD, ++A_FDIVD, ++A_FDIVS, ++A_FLDD, ++A_FLDM, ++A_FLDS, ++A_FMACD, ++A_FMACS, ++A_FMDHR, ++A_FMDLR, ++A_FMRDH, ++A_FMRDL, ++A_FMRS, ++A_FMRX, ++A_FMSCD, ++A_FMSCS, ++A_FMSR, ++A_FMSTAT, ++A_FMULD, ++A_FMULS, ++A_FMXR, ++A_FNEGD, ++A_FNEGS, ++A_FNMACD, ++A_FNMACS, ++A_FNMSCD, ++A_FNMSCS, ++A_FNMULD, ++A_FNMULS, ++A_FSITOD, ++A_FSITOS, ++A_FSQRTD, ++A_FSQRTS, ++A_FSUBD, ++A_FSUBS, ++A_FTOSID, ++A_FTOSIS, ++A_FTOUID, ++A_FTOUIS, ++A_FUITOD, ++A_FUITOS, ++A_FMDRR, ++A_FMRRD, + A_POP, + A_PUSH, + A_SDIV, +@@ -306,29 +298,59 @@ A_VADD, + A_VCMP, + A_VCMPE, + A_VCVT, ++A_VCVTR, + A_VDIV, +-A_VLDM, +-A_VLDR, +-A_VMOV, + A_VMRS, + A_VMSR, +-A_VMUL, + A_VMLA, + A_VMLS, ++A_VMUL, + A_VNMLA, + A_VNMLS, ++A_VNMUL, + A_VFMA, + A_VFMS, + A_VFNMA, + A_VFNMS, + A_VNEG, +-A_VNMUL, +-A_VPOP, +-A_VPUSH, + A_VSQRT, +-A_VSTM, +-A_VSTR, + A_VSUB, ++A_DMB, ++A_ISB, ++A_DSB, ++A_SMC, + A_NEG, +-A_SVC ++A_SVC, ++A_BXJ, ++A_UDF, ++A_TAN, ++A_SQT, ++A_SUF, ++A_RSF, ++A_RND, ++A_POL, ++A_RDF, ++A_RFS, ++A_RFC, ++A_WFC, ++A_RMF, ++A_RPW, ++A_MNF, ++A_MUF, ++A_ABS, ++A_ACS, ++A_ASN, ++A_ATN, ++A_CNF, ++A_CNFE, ++A_COS, ++A_DVF, ++A_EXP, ++A_FDV, ++A_FLT, ++A_FIX, ++A_FML, ++A_FRD, ++A_LGN, ++A_LOG + ); +Index: fpc/fpcsrc/compiler/arm/armreg.dat +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/armreg.dat ++++ fpc/fpcsrc/compiler/arm/armreg.dat +@@ -87,7 +87,7 @@ S28,$04,$06,$0E,s28,0,0 + S29,$04,$06,$2E,s29,0,0 + D14,$04,$07,$0E,d14,0,0 + S30,$04,$06,$0F,s30,0,0 +-S31,$04,$06,$2F,s21,0,0 ++S31,$04,$06,$2F,s31,0,0 + D15,$04,$07,$0F,d15,0,0 + D16,$04,$07,$10,d16,0,0 + D17,$04,$07,$11,d17,0,0 +@@ -145,4 +145,11 @@ BASEPRI,$05,$00,$1F,basepri,0,0 + BASEPRI_MAX,$05,$00,$20,basepri_max,0,0 + FAULTMASK,$05,$00,$21,faultmask,0,0 + CONTROL,$05,$00,$22,control,0,0 +- ++; VFP registers ++FPSID,$05,$00,$23,fpsid,0,0 ++MVFR1,$05,$00,$24,mvfr1,0,0 ++MVFR0,$05,$00,$25,mvfr0,0,0 ++FPEXC,$05,$00,$26,fpexc,0,0 ++APSR_nzcvq,$05,$00,$27,apsr_nzcvq,0,0 ++APSR_g,$05,$00,$28,apsr_g,0,0 ++APSR_nzcvqg,$05,$00,$29,apsr_nzcvqg,0,0 +Index: fpc/fpcsrc/compiler/arm/armtab.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/armtab.inc ++++ fpc/fpcsrc/compiler/arm/armtab.inc +@@ -3,736 +3,6665 @@ + ( + opcode : A_NONE; + ops : 0; +- optypes : (ot_none,ot_none,ot_none,ot_none); ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); + code : #0; + flags : if_none + ), + ( + opcode : A_ADC; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#65#64; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ADC; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#241#64#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADC; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#235#64#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADC; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #4#0#160; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#235#64#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADC; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #128#241#64#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADC; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#235#64#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_ADC; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); +- code : #5#0#160; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #128#235#64#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADC; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #4#0#160; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_ADC; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); + code : #6#0#160; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_ADC; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); + code : #7#2#160; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #97#68#0; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_ADD; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #4#0#128; +- flags : if_arm7 ++ optypes : (ot_reglo,ot_reglo,ot_reglo,ot_none,ot_none,ot_none); ++ code : #96#24#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #96#28#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 3; ++ optypes : (ot_reglo,ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #96#28#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #107#48#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 3; ++ optypes : (ot_reglo,ot_regsp,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #100#168#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 3; ++ optypes : (ot_regsp,ot_regsp,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #100#176#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 3; ++ optypes : (ot_reg32,ot_regsp,ot_reg32,ot_none,ot_none,ot_none); ++ code : #100#68#104; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 2; ++ optypes : (ot_regsp,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #100#68#133; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#241#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#235#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#235#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #128#241#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#235#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_ADD; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); +- code : #5#0#128; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #128#235#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #4#0#128; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_ADD; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); + code : #6#0#128; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_ADD; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); + code : #7#2#128; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ADDW; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #129#242#0#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none); ++ code : #161#0#0; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_ADF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #161#0#0; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_ADR; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #103#160#0#2; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ADR; ++ ops : 2; ++ optypes : (ot_reglo,ot_memoryam6,ot_none,ot_none,ot_none,ot_none); ++ code : #103#160#0#2; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ADR; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,ot_none,ot_none,ot_none); ++ code : #129#242#175#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADR; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #129#242#175#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADR; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #129#242#175#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ADR; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #51#2#15; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_AND; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#64#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_AND; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#240#0#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_AND; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#234#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_AND; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #4#0#0; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#234#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_AND; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #128#240#0#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_AND; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#234#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_AND; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); +- code : #5#0#0; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #128#234#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_AND; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #4#0#0; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_AND; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); + code : #6#0#0; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_AND; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); + code : #7#2#0; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_B; ++ ops : 1; ++ optypes : (ot_immediate24,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #98#224#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_B; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #98#224#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_B; ++ ops : 1; ++ optypes : (ot_memory or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #98#224#0; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_B; + ops : 1; +- optypes : (ot_memory or ot_bits32,ot_none,ot_none,ot_none); ++ optypes : (ot_immediate24,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #99#208#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_B; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #99#208#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_B; ++ ops : 1; ++ optypes : (ot_memory or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #99#208#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_B; ++ ops : 1; ++ optypes : (ot_immediate24,ot_none,ot_none,ot_none,ot_none,ot_none); + code : #1#10; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_B; + ops : 1; +- optypes : (ot_immediate24,ot_none,ot_none,ot_none); ++ optypes : (ot_memory or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none); + code : #1#10; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_BIC; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#67#128; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_BIC; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#240#32#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_BIC; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#234#32#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_BIC; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#234#32#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_BIC; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #128#240#32#0#0; ++ flags : if_thumb32 or if_armv6t2 + ), + ( + opcode : A_BIC; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #4#1#192; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#234#32#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_BIC; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); +- code : #5#1#192; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #128#234#32#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_BIC; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #6#1#192; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_BIC; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); + code : #6#1#192; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_BIC; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); + code : #7#3#192; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_BL; + ops : 1; +- optypes : (ot_memory or ot_bits32,ot_none,ot_none,ot_none); ++ optypes : (ot_immediate24,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #141#240#208; ++ flags : if_thumb or if_thumb32 or if_armv4t ++ ), ++ ( ++ opcode : A_BL; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #141#240#208; ++ flags : if_thumb or if_thumb32 or if_armv4t ++ ), ++ ( ++ opcode : A_BL; ++ ops : 1; ++ optypes : (ot_memory or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #141#240#208; ++ flags : if_thumb or if_thumb32 or if_armv4t ++ ), ++ ( ++ opcode : A_BL; ++ ops : 1; ++ optypes : (ot_immediate24,ot_none,ot_none,ot_none,ot_none,ot_none); + code : #1#11; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_BL; + ops : 1; +- optypes : (ot_immediate24,ot_none,ot_none,ot_none); ++ optypes : (ot_memory or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none); + code : #1#11; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_BLX; + ops : 1; +- optypes : (ot_memory or ot_bits32,ot_none,ot_none,ot_none); +- code : #15#15; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #98#71#128; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_BLX; + ops : 1; +- optypes : (ot_immediate24,ot_none,ot_none,ot_none); +- code : #15#15; +- flags : if_arm7 ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #141#240#192; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_BLX; ++ ops : 1; ++ optypes : (ot_immediate24,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #141#240#192; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_BLX; ++ ops : 1; ++ optypes : (ot_memory or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #141#240#192; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_BLX; ++ ops : 1; ++ optypes : (ot_immediate24,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #40#250; ++ flags : if_arm32 or if_armv5t ++ ), ++ ( ++ opcode : A_BLX; ++ ops : 1; ++ optypes : (ot_memory or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #40#250; ++ flags : if_arm32 or if_armv5t ++ ), ++ ( ++ opcode : A_BLX; ++ ops : 1; ++ optypes : (ot_reg32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #3#1#47#255#48; ++ flags : if_arm32 or if_armv5t ++ ), ++ ( ++ opcode : A_BKPT; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #96#190#0; ++ flags : if_thumb or if_armv5t ++ ), ++ ( ++ opcode : A_BKPT; ++ ops : 1; ++ optypes : (ot_immediate,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #49#1#32#112; ++ flags : if_arm32 or if_armv5t ++ ), ++ ( ++ opcode : A_BKPT; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #49#1#32#112; ++ flags : if_arm32 or if_armv5t ++ ), ++ ( ++ opcode : A_BX; ++ ops : 1; ++ optypes : (ot_reg32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #98#71#0; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_BX; + ops : 1; +- optypes : (ot_reg32,ot_none,ot_none,ot_none); ++ optypes : (ot_reg32,ot_none,ot_none,ot_none,ot_none,ot_none); + code : #3#1#47#255#16; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4t + ), + ( + opcode : A_CDP; + ops : 2; +- optypes : (ot_reg8,ot_reg8,ot_none,ot_none); ++ optypes : (ot_reg8,ot_reg8,ot_none,ot_none,ot_none,ot_none); + code : #192#1#16#65; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_CMN; + ops : 2; +- optypes : (ot_reg32,ot_reg32,ot_none,ot_none); +- code : #12#1#96; +- flags : if_arm7 ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#66#192; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_CMN; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#241#16#15#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_CMN; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#235#16#15#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_CMN; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #13#1#96; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#235#16#15#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_CMN; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #12#1#96; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_CMN; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); + code : #14#1#96; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_CMN; + ops : 2; +- optypes : (ot_reg32,ot_immediate,ot_none,ot_none); +- code : #15#3#96; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #15#1#96; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_CMP; + ops : 2; +- optypes : (ot_reg32,ot_reg32,ot_none,ot_none); +- code : #12#1#64; +- flags : if_arm7 ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#66#128; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_CMP; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #97#69#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_CMP; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #107#40#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_CMP; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#241#176#15#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_CMP; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#235#176#15#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_CMP; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #13#1#64; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#235#176#15#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_CMP; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #12#1#64; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_CMP; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); + code : #14#1#64; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_CMP; + ops : 2; +- optypes : (ot_reg32,ot_immediate,ot_none,ot_none); ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); + code : #15#3#64; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_CMF; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#144; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_CMF; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#144; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_CMFE; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#192; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_CMFE; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#192; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_STF; ++ ops : 2; ++ optypes : (ot_fpureg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #160#12#0#1#0; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_LDF; ++ ops : 2; ++ optypes : (ot_fpureg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #160#12#16#1#0; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_LFM; ++ ops : 3; ++ optypes : (ot_fpureg,ot_immediate or ot_bits32,ot_memoryam2,ot_none,ot_none,ot_none); ++ code : #160#12#16#2#0; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_LFM; ++ ops : 3; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_memoryam2,ot_none,ot_none,ot_none); ++ code : #160#12#16#2#0; ++ flags : if_arm32 or if_fpa + ), + ( + opcode : A_CLZ; + ops : 2; +- optypes : (ot_reg32,ot_reg32,ot_none,ot_none); +- code : #39#1#1; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#250#176#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_CLZ; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #50#1#111#15#16; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_CPS; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #143#243#175#129#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_CPS; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #70#241#2#0#0; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_CPSID; ++ ops : 1; ++ optypes : (ot_modeflags,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #108#182#112; ++ flags : if_thumb or if_armv6 ++ ), ++ ( ++ opcode : A_CPSID; ++ ops : 1; ++ optypes : (ot_modeflags,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #143#243#175#134#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_CPSID; ++ ops : 2; ++ optypes : (ot_modeflags,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #143#243#175#135#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_CPSID; ++ ops : 1; ++ optypes : (ot_modeflags,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #70#241#12#0#0; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_CPSID; ++ ops : 2; ++ optypes : (ot_modeflags,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #70#241#14#0#0; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_CPSIE; ++ ops : 1; ++ optypes : (ot_modeflags,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #108#182#96; ++ flags : if_thumb or if_armv6 ++ ), ++ ( ++ opcode : A_CPSIE; ++ ops : 1; ++ optypes : (ot_modeflags,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #143#243#175#132#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_CPSIE; ++ ops : 2; ++ optypes : (ot_modeflags,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #143#243#175#133#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_CPSIE; ++ ops : 1; ++ optypes : (ot_modeflags,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #70#241#8#0#0; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_CPSIE; ++ ops : 2; ++ optypes : (ot_modeflags,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #70#241#10#0#0; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_EOR; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#64#64; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_EOR; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#240#128#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_EOR; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#234#128#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_EOR; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #4#0#32; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#234#128#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_EOR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #128#240#128#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_EOR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#234#128#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_EOR; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); +- code : #5#0#32; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #128#234#128#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_EOR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #4#0#32; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_EOR; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); + code : #6#0#32; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_EOR; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); + code : #7#2#32; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_LDC; + ops : 2; +- optypes : (ot_reg32,ot_reg32,ot_none,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); + code : #209#192#1#17#65; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_LDM; + ops : 2; +- optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none); ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #105#200; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LDM; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #105#200; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LDM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #140#232#16#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_LDM; ++ ops : 2; ++ optypes : (ot_reg32,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #140#232#16#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_LDM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #38#129; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LDM; ++ ops : 2; ++ optypes : (ot_reg32,ot_reglist,ot_none,ot_none,ot_none,ot_none); + code : #38#129; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LDRBT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#16#14#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_LDRBT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #23#4#112; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LDRBT; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #23#4#112; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_LDRB; + ops : 2; +- optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none); +- code : #23#7#16; +- flags : if_arm7 ++ optypes : (ot_reglo,ot_memoryam3,ot_none,ot_none,ot_none,ot_none); ++ code : #101#92#0#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LDRB; ++ ops : 2; ++ optypes : (ot_reglo,ot_memoryam4,ot_none,ot_none,ot_none,ot_none); ++ code : #102#120#0#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LDRB; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#16#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_LDRB; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #23#4#80; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LDR; ++ ops : 2; ++ optypes : (ot_reglo,ot_memoryam3,ot_none,ot_none,ot_none,ot_none); ++ code : #101#88#0#2; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LDR; ++ ops : 2; ++ optypes : (ot_reglo,ot_memoryam4,ot_none,ot_none,ot_none,ot_none); ++ code : #102#104#0#2; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_LDR; + ops : 2; +- optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none); +- code : #23#5#16; +- flags : if_arm7 ++ optypes : (ot_reglo,ot_memoryam5,ot_none,ot_none,ot_none,ot_none); ++ code : #103#152#0#2; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LDR; ++ ops : 2; ++ optypes : (ot_reglo,ot_memoryam6,ot_none,ot_none,ot_none,ot_none); ++ code : #103#72#0#2; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LDR; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#80#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_LDR; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #23#4#16; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_LDRH; + ops : 2; +- optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,ot_none); +- code : #34#80#176; +- flags : if_arm7 ++ optypes : (ot_reglo,ot_memoryam3,ot_none,ot_none,ot_none,ot_none); ++ code : #101#90#0#1; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_LDRH; + ops : 2; +- optypes : (ot_reg32,ot_reg32,ot_none,ot_none); +- code : #35#80#176; +- flags : if_arm7 ++ optypes : (ot_reglo,ot_memoryam4,ot_none,ot_none,ot_none,ot_none); ++ code : #102#136#0#1; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_LDRH; +- ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,ot_none); +- code : #36#80#176; +- flags : if_arm7 ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#48#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_LDRH; +- ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #37#16#176; +- flags : if_arm7 ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #34#16#176; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_LDRSB; + ops : 2; +- optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,ot_none); +- code : #34#80#208; +- flags : if_arm7 ++ optypes : (ot_reglo,ot_memoryam3,ot_none,ot_none,ot_none,ot_none); ++ code : #101#86#0#0; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_LDRSB; + ops : 2; +- optypes : (ot_reg32,ot_reg32,ot_none,ot_none); ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#249#16#0#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_LDRSB; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #34#16#208; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LDRSB; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); + code : #35#80#208; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_LDRSB; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,ot_none,ot_none,ot_none); + code : #36#80#208; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_LDRSB; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); + code : #37#16#208; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_LDRSH; + ops : 2; +- optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,ot_none); +- code : #34#80#240; +- flags : if_arm7 ++ optypes : (ot_reglo,ot_memoryam3,ot_none,ot_none,ot_none,ot_none); ++ code : #101#94#0#1; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_LDRSH; + ops : 2; +- optypes : (ot_reg32,ot_reg32,ot_none,ot_none); +- code : #35#80#240; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#249#48#0#0#0; ++ flags : if_thumb32 or if_armv6t2 + ), + ( + opcode : A_LDRSH; +- ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,ot_none); +- code : #36#80#240; +- flags : if_arm7 ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #34#16#240; ++ flags : if_arm32 or if_armv4 + ), + ( +- opcode : A_LDRSH; +- ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #37#16#240; +- flags : if_arm7 ++ opcode : A_LDRT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#80#14#0#0; ++ flags : if_thumb32 or if_armv6t2 + ), + ( +- opcode : A_LFM; +- ops : 3; +- optypes : (ot_reg32,ot_immediate or ot_bits8,ot_fpureg,ot_none); +- code : #240#2#1; +- flags : if_fpa ++ opcode : A_LDRT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #23#4#48; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MCR; ++ ops : 5; ++ optypes : (ot_regf,ot_immediateshifter,ot_reg32,ot_regf,ot_regf,ot_none); ++ code : #28#14#0#1; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MCR; ++ ops : 6; ++ optypes : (ot_regf,ot_immediateshifter,ot_reg32,ot_regf,ot_regf,ot_immediateshifter); ++ code : #28#14#0#1; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MCR2; ++ ops : 5; ++ optypes : (ot_regf,ot_immediateshifter,ot_reg32,ot_regf,ot_regf,ot_none); ++ code : #28#254#0#1; ++ flags : if_arm32 or if_armv5t ++ ), ++ ( ++ opcode : A_MCR2; ++ ops : 6; ++ optypes : (ot_regf,ot_immediateshifter,ot_reg32,ot_regf,ot_regf,ot_immediateshifter); ++ code : #28#254#0#1; ++ flags : if_arm32 or if_armv5t ++ ), ++ ( ++ opcode : A_MRC; ++ ops : 5; ++ optypes : (ot_regf,ot_immediateshifter,ot_reg32,ot_regf,ot_regf,ot_none); ++ code : #28#14#16#1; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MRC; ++ ops : 6; ++ optypes : (ot_regf,ot_immediateshifter,ot_reg32,ot_regf,ot_regf,ot_immediateshifter); ++ code : #28#14#16#1; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MRC2; ++ ops : 5; ++ optypes : (ot_regf,ot_immediateshifter,ot_reg32,ot_regf,ot_regf,ot_none); ++ code : #28#254#16#1; ++ flags : if_arm32 or if_armv5t ++ ), ++ ( ++ opcode : A_MRC2; ++ ops : 6; ++ optypes : (ot_regf,ot_immediateshifter,ot_reg32,ot_regf,ot_regf,ot_immediateshifter); ++ code : #28#254#16#1; ++ flags : if_arm32 or if_armv5t ++ ), ++ ( ++ opcode : A_MCRR; ++ ops : 5; ++ optypes : (ot_regf,ot_immediateshifter,ot_reg32,ot_reg32,ot_regf,ot_none); ++ code : #29#12#64#0; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_MCRR2; ++ ops : 5; ++ optypes : (ot_regf,ot_immediateshifter,ot_reg32,ot_reg32,ot_regf,ot_none); ++ code : #29#252#64#0; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_MRRC; ++ ops : 5; ++ optypes : (ot_regf,ot_immediateshifter,ot_reg32,ot_reg32,ot_regf,ot_none); ++ code : #29#12#80#0; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_MRRC2; ++ ops : 5; ++ optypes : (ot_regf,ot_immediateshifter,ot_reg32,ot_reg32,ot_regf,ot_none); ++ code : #29#252#80#0; ++ flags : if_arm32 or if_armv6 + ), + ( + opcode : A_MLA; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); +- code : #21#0#32#144; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #128#251#0#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_MLA; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#0#32#9; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MOV; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#0#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_MOV; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #97#70#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_MOV; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #107#32#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_MOV; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#240#79#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_MOV; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#234#79#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_MOV; ++ ops : 2; ++ optypes : (ot_reg32,ot_shifterop,ot_none,ot_none,ot_none,ot_none); ++ code : #8#1#160; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MOV; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #10#1#160; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MOV; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #11#1#160; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_MRS; + ops : 2; +- optypes : (ot_reg32,ot_reg32,ot_none,ot_none); ++ optypes : (ot_reg32,ot_regf,ot_none,ot_none,ot_none,ot_none); ++ code : #150#243#239#128#0; ++ flags : if_thumb32 or if_armv6 ++ ), ++ ( ++ opcode : A_MRS; ++ ops : 2; ++ optypes : (ot_reg32,ot_regf,ot_none,ot_none,ot_none,ot_none); + code : #16#1#15; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_MSR; + ops : 2; +- optypes : (ot_reg32,ot_reg32,ot_none,ot_none); +- code : #17#1#41#240; +- flags : if_arm7 ++ optypes : (ot_regf,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #150#243#128#128#0; ++ flags : if_thumb32 or if_armv6 + ), + ( + opcode : A_MSR; + ops : 2; +- optypes : (ot_regf,ot_reg32,ot_none,ot_none); +- code : #18#1#40#240; +- flags : if_arm7 ++ optypes : (ot_regf,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #18#1#32#240; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_MSR; + ops : 2; +- optypes : (ot_regf,ot_immediate,ot_none,ot_none); +- code : #19#3#40#240; +- flags : if_arm7 ++ optypes : (ot_regf,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #19#3#32#240; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MSR; ++ ops : 2; ++ optypes : (ot_regs,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #19#3#32#240; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MUL; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #100#67#64; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_MUL; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); ++ optypes : (ot_reglo,ot_reglo,ot_reglo,ot_none,ot_none,ot_none); ++ code : #100#67#64; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_MUL; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#251#0#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_MUL; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#251#0#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_MUL; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); + code : #20#0#0#144; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_MVF; + ops : 2; +- optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none); +- code : #242; +- flags : if_fpa ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#1; ++ flags : if_arm32 or if_fpa + ), + ( + opcode : A_MVF; + ops : 2; +- optypes : (ot_fpureg,ot_immediatefpu,ot_none,ot_none); +- code : #242; +- flags : if_fpa ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#1; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_MVN; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#67#192; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_MVN; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#240#111#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_MVN; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#234#111#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_MVN; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #8#1#224; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MVN; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #10#1#224; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MVN; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #11#1#224; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #144#238#176#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #64#14#176#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 2; ++ optypes : (ot_reg32,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #144#238#16#10#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 2; ++ optypes : (ot_vreg,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #144#238#0#10#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 2; ++ optypes : (ot_reg32,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #64#14#16#10#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 2; ++ optypes : (ot_vreg,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #64#14#0#10#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_vreg,ot_vreg,ot_none,ot_none); ++ code : #144#236#80#10#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 4; ++ optypes : (ot_vreg,ot_vreg,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #144#236#64#10#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_vreg,ot_vreg,ot_none,ot_none); ++ code : #64#12#80#10#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 4; ++ optypes : (ot_vreg,ot_vreg,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #64#12#64#10#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_vreg,ot_none,ot_none,ot_none); ++ code : #144#236#80#11#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 3; ++ optypes : (ot_vreg,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #144#236#64#11#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_vreg,ot_none,ot_none,ot_none); ++ code : #64#12#80#11#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMOV; ++ ops : 3; ++ optypes : (ot_vreg,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #64#12#64#11#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_NOP; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #97#191#0; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_NOP; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #47#3#32#240#0; ++ flags : if_arm32 or if_armv6k ++ ), ++ ( ++ opcode : A_NOP; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #47#225#160#0#0; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ORN; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#240#96#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_ORN; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#234#96#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_ORN; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#234#96#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_ORN; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #128#240#96#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_ORN; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#234#96#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_ORN; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #128#234#96#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_ORR; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#67#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ORR; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#240#64#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_ORR; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#234#64#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_ORR; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#234#64#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ORR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #128#240#64#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_ORR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#234#64#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ORR; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #128#234#64#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ORR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); + code : #4#1#128; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_ORR; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); + code : #5#1#128; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_ORR; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); + code : #6#1#128; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_ORR; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); + code : #7#3#128; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_RSB; ++ ops : 3; ++ optypes : (ot_reglo,ot_reglo,ot_immediatezero,ot_none,ot_none,ot_none); ++ code : #107#66#64; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_RSB; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#241#192#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_RSB; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#235#192#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_RSB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#235#192#0#0; ++ flags : if_thumb32 or if_armv6t2 + ), + ( + opcode : A_RSB; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #4#0#96; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #128#241#192#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_RSB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#235#192#0#0; ++ flags : if_thumb32 or if_armv6t2 + ), + ( + opcode : A_RSB; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); +- code : #5#0#96; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #128#235#192#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_RSB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #6#0#96; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_RSB; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); + code : #6#0#96; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_RSB; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); +- code : #7#2#96; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #7#0#96; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_RSC; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); + code : #4#0#224; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_RSC; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); + code : #5#0#224; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_RSC; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); + code : #6#0#224; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_RSC; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); + code : #7#2#224; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_SBC; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#65#128; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_SBC; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#241#96#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SBC; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#235#96#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_SBC; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#235#96#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SBC; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #128#241#96#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SBC; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#235#96#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SBC; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #128#235#96#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SBC; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); + code : #4#0#192; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_SBC; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); + code : #5#0#192; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_SBC; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate,ot_none,ot_none); ++ code : #6#0#192; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_SBC; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_immediate); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); + code : #6#0#192; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_SBC; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); + code : #7#2#192; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_SFM; + ops : 3; +- optypes : (ot_reg32,ot_immediate or ot_bits8,ot_fpureg,ot_none); +- code : #240#2#0; +- flags : if_fpa ++ optypes : (ot_fpureg,ot_immediate or ot_bits32,ot_memoryam2,ot_none,ot_none,ot_none); ++ code : #160#12#0#2#0; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_SFM; ++ ops : 3; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_memoryam2,ot_none,ot_none,ot_none); ++ code : #160#12#0#2#0; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_SIN; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#17; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_SIN; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#17; ++ flags : if_arm32 or if_fpa + ), + ( + opcode : A_SMLAL; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); +- code : #22#0#224#144; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #133#251#192#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMLAL; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #22#0#224#9; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_SMULL; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); +- code : #22#0#192#144; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #133#251#128#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMULL; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #22#0#192#9; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_STM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #105#192; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_STM; + ops : 2; +- optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none); ++ optypes : (ot_reglo,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #105#192; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_STM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #140#232#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_STM; ++ ops : 2; ++ optypes : (ot_reg32,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #140#232#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_STM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); + code : #38#128; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_STM; ++ ops : 2; ++ optypes : (ot_reg32,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #38#128; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_STR; ++ ops : 2; ++ optypes : (ot_reglo,ot_memoryam3,ot_none,ot_none,ot_none,ot_none); ++ code : #101#80#0#2; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_STR; ++ ops : 2; ++ optypes : (ot_reglo,ot_memoryam4,ot_none,ot_none,ot_none,ot_none); ++ code : #102#96#0#2; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_STR; ++ ops : 2; ++ optypes : (ot_reglo,ot_memoryam5,ot_none,ot_none,ot_none,ot_none); ++ code : #103#144#0#2; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_STR; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#64#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_STR; + ops : 2; +- optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none); ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); + code : #23#4#0; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_STRB; ++ ops : 2; ++ optypes : (ot_reglo,ot_memoryam3,ot_none,ot_none,ot_none,ot_none); ++ code : #101#84#0#0; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_STRB; + ops : 2; +- optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none); +- code : #23#6#0; +- flags : if_arm7 ++ optypes : (ot_reglo,ot_memoryam4,ot_none,ot_none,ot_none,ot_none); ++ code : #102#112#0#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_STRB; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#0#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_STRB; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #23#4#64; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_STRBT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#0#14#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_STRBT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #23#4#96; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_STRBT; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #23#4#96; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_STRH; + ops : 2; +- optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,ot_none); +- code : #34#64#176; +- flags : if_arm7 ++ optypes : (ot_reglo,ot_memoryam3,ot_none,ot_none,ot_none,ot_none); ++ code : #101#82#0#1; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_STRH; + ops : 2; +- optypes : (ot_reg32,ot_reg32,ot_none,ot_none); +- code : #35#64#176; +- flags : if_arm7 ++ optypes : (ot_reglo,ot_memoryam4,ot_none,ot_none,ot_none,ot_none); ++ code : #102#128#0#1; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_STRH; +- ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate or ot_bits32,ot_none); +- code : #36#64#176; +- flags : if_arm7 ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#32#0#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 + ), + ( + opcode : A_STRH; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #34#0#176; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_STRT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#64#14#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_STRT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #23#4#32; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 2; ++ optypes : (ot_regsp,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #100#176#128; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_SUB; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #37#0#176; +- flags : if_arm7 ++ optypes : (ot_regsp,ot_regsp,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #100#176#128; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #96#26#0; ++ flags : if_thumb or if_armv4t + ), + ( + opcode : A_SUB; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none); ++ optypes : (ot_reglo,ot_reglo,ot_reglo,ot_none,ot_none,ot_none); ++ code : #96#26#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #96#30#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 3; ++ optypes : (ot_reglo,ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #96#30#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediate or ot_bits8,ot_none,ot_none,ot_none,ot_none); ++ code : #107#56#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #107#56#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#241#160#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#235#160#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#235#160#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #128#241#160#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#235#160#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #128#235#160#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SUB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); + code : #4#0#64; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_SUB; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); + code : #4#0#64; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_SUB; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); + code : #4#0#64; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( +- opcode : A_SWI; +- ops : 1; +- optypes : (ot_immediate,ot_none,ot_none,ot_none); +- code : #2#15; +- flags : if_arm7 ++ opcode : A_SUB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #6#0#64; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_SWP; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #39#1#144; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none); ++ code : #39#16#9; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_SWPB; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); +- code : #39#1#144; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none); ++ code : #39#20#9; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_TEQ; + ops : 2; +- optypes : (ot_reg32,ot_reg32,ot_none,ot_none); ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#240#144#15#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_TEQ; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#234#144#15#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_TEQ; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#234#144#15#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_TEQ; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); + code : #12#1#32; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_TEQ; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); + code : #13#1#32; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_TEQ; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); + code : #14#1#32; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_TEQ; + ops : 2; +- optypes : (ot_reg32,ot_immediate,ot_none,ot_none); ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); + code : #15#3#32; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_TST; + ops : 2; +- optypes : (ot_reg32,ot_reg32,ot_none,ot_none); ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#66#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_TST; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #128#240#16#15#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_TST; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#234#16#15#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_TST; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #128#234#16#15#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_TST; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); + code : #12#1#0; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_TST; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); + code : #13#1#0; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_TST; + ops : 3; +- optypes : (ot_reg32,ot_reg32,ot_immediate,ot_none); ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); + code : #14#1#0; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_TST; + ops : 2; +- optypes : (ot_reg32,ot_immediate,ot_none,ot_none); ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); + code : #15#3#0; +- flags : if_arm7 ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_UMLAL; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #133#251#224#0#0; ++ flags : if_thumb32 or if_armv6t2 + ), + ( + opcode : A_UMLAL; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); +- code : #22#0#160#144; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #22#0#160#9; ++ flags : if_arm32 or if_armv4 + ), + ( + opcode : A_UMULL; + ops : 4; +- optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32); +- code : #22#0#128#144; +- flags : if_arm7 ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #133#251#160#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UMULL; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #22#0#128#9; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_WFS; ++ ops : 1; ++ optypes : (ot_reg32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#2; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_LDRD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none); ++ code : #137#232#80#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_LDRD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none); ++ code : #25#0#0#0#208; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_PLD; ++ ops : 1; ++ optypes : (ot_memoryam2,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #135#248#16#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_PLD; ++ ops : 1; ++ optypes : (ot_memoryam2,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #37#245#80#240#0; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_PLDW; ++ ops : 1; ++ optypes : (ot_memoryam2,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #135#248#48#240#0; ++ flags : if_thumb32 or if_armv7 ++ ), ++ ( ++ opcode : A_PLDW; ++ ops : 1; ++ optypes : (ot_memoryam2,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #37#245#16#240#0; ++ flags : if_arm32 or if_armv7 ++ ), ++ ( ++ opcode : A_QADD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #130#250#128#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_QADD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #26#1#0#5; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_QDADD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #130#250#128#240#144; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_QDADD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #26#1#64#5; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_QDSUB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #130#250#128#240#176; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_QDSUB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #26#1#96#5; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_QSUB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #130#250#128#240#160; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_QSUB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #26#1#32#5; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMLABB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#1#0#8; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMLABT; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#1#0#12; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMLATB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#1#0#10; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMLATT; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#1#0#14; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMLALBB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #22#1#64#8; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMLALBT; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #22#1#64#12; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMLALTB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #22#1#64#10; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMLALTT; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #22#1#64#14; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMLAWB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #128#251#48#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMLAWB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#1#32#8; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMLAWT; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #128#251#48#0#16; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMLAWT; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#1#32#12; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_VLDM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #148#236#16#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VLDM; ++ ops : 2; ++ optypes : (ot_reg32,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #148#236#16#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VLDM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #68#12#16#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VLDM; ++ ops : 2; ++ optypes : (ot_reg32,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #68#12#16#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VSTM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #148#236#0#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VSTM; ++ ops : 2; ++ optypes : (ot_reg32,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #148#236#0#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VSTM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #68#12#0#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VSTM; ++ ops : 2; ++ optypes : (ot_reg32,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #68#12#0#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VPOP; ++ ops : 1; ++ optypes : (ot_reglist,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #148#236#189#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VPOP; ++ ops : 1; ++ optypes : (ot_reglist,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #68#12#189#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VPUSH; ++ ops : 1; ++ optypes : (ot_reglist,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #148#237#45#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VPUSH; ++ ops : 1; ++ optypes : (ot_reglist,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #68#13#45#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VLDR; ++ ops : 2; ++ optypes : (ot_vreg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #149#237#16#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VLDR; ++ ops : 2; ++ optypes : (ot_vreg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #69#13#16#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VSTR; ++ ops : 2; ++ optypes : (ot_vreg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #149#237#0#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VSTR; ++ ops : 2; ++ optypes : (ot_vreg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #69#13#0#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_SMULBB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #21#1#96#8#0; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMULBT; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #21#1#96#12#0; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMULTB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #21#1#96#10#0; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMULTT; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #21#1#96#14#0; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMULWB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #20#1#32#160; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_SMULWT; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #20#1#32#224; ++ flags : if_arm32 or if_armv5te ++ ), ++ ( ++ opcode : A_STRD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none); ++ code : #137#232#64#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_STRD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none); ++ code : #25#0#0#0#240; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LDRHT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#48#14#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_LDRHT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #25#0#48#0#176; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_STRHT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#32#14#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_STRHT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#248#32#14#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_STRHT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #30#0#32#0#176; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LDRSBT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#249#16#14#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_LDRSBT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #30#0#48#0#208; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LDRSHT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #136#249#48#14#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_LDRSHT; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #30#0#48#0#240; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_FSTD; ++ ops : 2; ++ optypes : (ot_vreg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #149#237#0#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSTD; ++ ops : 2; ++ optypes : (ot_vreg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #69#13#0#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSTM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #148#236#0#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSTM; ++ ops : 2; ++ optypes : (ot_reg32,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #148#236#0#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSTM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #68#12#0#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSTM; ++ ops : 2; ++ optypes : (ot_reg32,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #68#12#0#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSTS; ++ ops : 2; ++ optypes : (ot_vreg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #149#237#0#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSTS; ++ ops : 2; ++ optypes : (ot_vreg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #69#13#0#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_BFC; ++ ops : 3; ++ optypes : (ot_reg32,ot_immediateshifter,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #132#243#111#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_BFC; ++ ops : 3; ++ optypes : (ot_reg32,ot_immediateshifter,ot_immediate or ot_bits32,ot_none,ot_none,ot_none); ++ code : #132#243#111#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_BFC; ++ ops : 3; ++ optypes : (ot_reg32,ot_immediateshifter,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #45#7#192#0#31; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_BFC; ++ ops : 3; ++ optypes : (ot_reg32,ot_immediateshifter,ot_immediate or ot_bits32,ot_none,ot_none,ot_none); ++ code : #45#7#192#0#31; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_BFI; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_immediateshifter,ot_none,ot_none); ++ code : #132#243#96#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_BFI; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_immediate or ot_bits32,ot_none,ot_none); ++ code : #132#243#96#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_BFI; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_immediateshifter,ot_none,ot_none); ++ code : #45#7#192#0#16; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_BFI; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_immediate or ot_bits32,ot_none,ot_none); ++ code : #45#7#192#0#16; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_CLREX; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #128#243#191#143#47; ++ flags : if_thumb32 or if_armv7 ++ ), ++ ( ++ opcode : A_CLREX; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #47#245#127#240#31; ++ flags : if_arm32 or if_armv6k ++ ), ++ ( ++ opcode : A_LDREX; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none,ot_none); ++ code : #138#232#80#15#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_LDREX; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none,ot_none); ++ code : #24#1#144#15#159; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LDREXB; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none,ot_none); ++ code : #138#232#208#15#79; ++ flags : if_thumb32 or if_armv7 ++ ), ++ ( ++ opcode : A_LDREXB; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none,ot_none); ++ code : #24#1#208#15#159; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LDREXD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none); ++ code : #138#232#208#0#127; ++ flags : if_thumb32 or if_armv7 ++ ), ++ ( ++ opcode : A_LDREXD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none); ++ code : #24#1#176#15#159; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LDREXH; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none,ot_none); ++ code : #138#232#208#15#95; ++ flags : if_thumb32 or if_armv7 ++ ), ++ ( ++ opcode : A_LDREXH; ++ ops : 2; ++ optypes : (ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none,ot_none); ++ code : #24#1#240#15#159; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_STREX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none); ++ code : #139#232#64#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_STREX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none); ++ code : #24#1#128#15#144; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_STREXB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none); ++ code : #139#232#192#15#64; ++ flags : if_thumb32 or if_armv7 ++ ), ++ ( ++ opcode : A_STREXB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none); ++ code : #24#1#192#15#144; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_STREXD; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_memoryam6,ot_none,ot_none); ++ code : #139#232#192#0#112; ++ flags : if_thumb32 or if_armv7 ++ ), ++ ( ++ opcode : A_STREXD; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_memoryam6,ot_none,ot_none); ++ code : #24#1#160#15#144; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_STREXH; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none); ++ code : #139#232#192#15#80; ++ flags : if_thumb32 or if_armv7 ++ ), ++ ( ++ opcode : A_STREXH; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_memoryam6,ot_none,ot_none,ot_none); ++ code : #24#1#224#15#144; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_MLS; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #128#251#0#0#16; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_MLS; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#0#96#9; ++ flags : if_arm32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_PKHBT; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#234#192#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_PKHBT; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #128#234#192#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_PKHBT; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#128#1; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_PKHBT; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #22#6#128#1; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_PKHTB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#234#192#0#16; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_PKHTB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #128#234#192#0#16; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_PKHTB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#128#1; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_PKHTB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #22#6#128#5; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_PLI; ++ ops : 1; ++ optypes : (ot_memoryam2,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #135#249#16#240#0; ++ flags : if_thumb32 or if_armv7 ++ ), ++ ( ++ opcode : A_PLI; ++ ops : 1; ++ optypes : (ot_memoryam2,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #37#244#80#240#0; ++ flags : if_arm32 or if_armv7 ++ ), ++ ( ++ opcode : A_QADD16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#144#240#16; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_QADD16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#32#241; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_QADD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#128#240#16; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_QADD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#32#249; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_QASX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#160#240#16; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_QASX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#32#243; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_QSAX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#224#240#16; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_QSAX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#32#245; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_QSUB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#208#240#16; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_QSUB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#32#247; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_QSUB8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#192#240#16; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_QSUB8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#32#255; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_RBIT; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#250#144#240#160; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_RBIT; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #50#6#255#15#48; ++ flags : if_arm32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_REV; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #97#186#0; ++ flags : if_thumb or if_armv6 ++ ), ++ ( ++ opcode : A_REV; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#250#144#240#128; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_REV; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #50#6#191#15#48; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_REV16; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #97#186#64; ++ flags : if_thumb or if_armv6 ++ ), ++ ( ++ opcode : A_REV16; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#250#144#240#144; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_REV16; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #50#6#191#15#176; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_REVSH; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #97#186#192; ++ flags : if_thumb or if_armv6 ++ ), ++ ( ++ opcode : A_REVSH; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#250#144#240#176; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_REVSH; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #50#6#255#15#176; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SADD16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#72#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SADD16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#16#241; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SADD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#64#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SADD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#16#249; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SASX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#80#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SASX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#16#243; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SBFX; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_immediateshifter,ot_none,ot_none); ++ code : #132#243#64#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SBFX; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_immediateshifter,ot_none,ot_none); ++ code : #45#7#160#0#80; ++ flags : if_arm32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SEL; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#160#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SEL; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#128#251; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SETEND; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #43#241#1#0#0; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SEV; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #100#191#64; ++ flags : if_thumb or if_armv7 ++ ), ++ ( ++ opcode : A_SEV; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #47#3#32#240#4; ++ flags : if_arm32 or if_armv6k ++ ), ++ ( ++ opcode : A_ASR; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #96#1#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ASR; ++ ops : 3; ++ optypes : (ot_reglo,ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #96#1#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ASR; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#65#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ASR; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #130#234#79#0#32; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ASR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #130#234#79#0#32; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ASR; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#250#64#240#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ASR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#64#240#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ASR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #48#1#160#0#80; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ASR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #48#1#160#0#64; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LSR; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #96#8#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LSR; ++ ops : 3; ++ optypes : (ot_reglo,ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #96#8#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LSR; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#64#192; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LSR; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #130#234#79#0#16; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_LSR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #130#234#79#0#16; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_LSR; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#250#32#240#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_LSR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#32#240#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_LSR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #48#1#160#0#48; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LSR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #48#1#160#0#32; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LSL; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #96#0#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LSL; ++ ops : 3; ++ optypes : (ot_reglo,ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #96#0#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LSL; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#64#128; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_LSL; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #130#234#79#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_LSL; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #130#234#79#0#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_LSL; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#250#96#240#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_LSL; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#96#240#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_LSL; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #48#1#160#0#16; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_LSL; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #48#1#160#0#0; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ROR; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #107#65#192; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_ROR; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #130#234#79#0#48; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ROR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #130#234#79#0#48; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ROR; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#250#96#240#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ROR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#96#240#0; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_ROR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #48#1#160#0#112; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ROR; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #48#1#160#0#96; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_RRX; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #128#234#79#0#48; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_RRX; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #48#1#160#0#96; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_UMAAL; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #133#251#224#0#96; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UMAAL; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #22#0#64#9; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SHADD16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#144#240#32; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SHADD16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#48#241; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SHADD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#128#240#32; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SHADD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#48#249; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SHASX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#160#240#32; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SHASX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#48#243; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SHSAX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#224#240#32; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SHSAX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#48#245; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SHSUB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#208#240#32; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SHSUB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#48#247; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SHSUB8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#192#240#32; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SHSUB8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#48#255; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SMLAD; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #128#251#32#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMLAD; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#7#0#1; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SMLALD; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #133#251#192#0#192; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMLALD; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #22#7#64#1; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_SMLSD; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #128#251#64#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMLSD; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#7#0#5; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SMLSLD; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #133#251#208#0#192; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMLSLD; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #22#7#64#5; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SMMLA; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #128#251#80#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMMLA; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#7#80#1; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SMMLS; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #128#251#96#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMMLS; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#7#80#13; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SMMUL; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#251#80#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMMUL; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #21#7#80#1#15; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SMUAD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#251#32#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMUAD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #21#7#0#1#15; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SMUSD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#251#64#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SMUSD; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #21#7#0#5#15; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SSAT; ++ ops : 3; ++ optypes : (ot_reg32,ot_immediateshifter,ot_reg32,ot_none,ot_none,ot_none); ++ code : #131#243#0#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SSAT; ++ ops : 4; ++ optypes : (ot_reg32,ot_immediateshifter,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #131#243#0#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SSAT; ++ ops : 3; ++ optypes : (ot_reg32,ot_immediateshifter,ot_reg32,ot_none,ot_none,ot_none); ++ code : #42#6#160#0#16; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SSAT; ++ ops : 4; ++ optypes : (ot_reg32,ot_immediateshifter,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #42#6#160#0#16; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SSAT16; ++ ops : 3; ++ optypes : (ot_reg32,ot_immediateshifter,ot_reg32,ot_none,ot_none,ot_none); ++ code : #131#243#32#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SSAT16; ++ ops : 3; ++ optypes : (ot_reg32,ot_immediateshifter,ot_reg32,ot_none,ot_none,ot_none); ++ code : #42#6#160#15#48; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SSAX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#224#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SSAX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#16#245; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SSUB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#208#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SSUB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#16#247; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SSUB8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#192#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SSUB8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#16#255; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SXTAB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #134#250#64#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SXTAB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #134#250#64#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SXTAB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#160#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SXTAB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #22#6#160#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SXTAB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #134#250#32#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SXTAB16; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #134#250#32#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SXTAB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#128#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SXTAB16; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #22#6#128#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SXTAH; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #134#250#0#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SXTAH; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #134#250#0#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SXTAH; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#176#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SXTAH; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #22#6#176#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UBFX; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_immediateshifter,ot_none,ot_none); ++ code : #132#243#192#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UBFX; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_immediateshifter,ot_none,ot_none); ++ code : #45#7#224#0#80; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_UXTAB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #134#250#80#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTAB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #134#250#80#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTAB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#224#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UXTAB; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #22#6#224#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UXTAB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #134#250#48#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTAB16; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #134#250#48#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTAB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #134#250#64#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTAB16; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #134#250#64#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTAB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#192#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UXTAB16; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #22#6#192#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UXTAH; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #134#250#16#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTAH; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #134#250#16#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTAH; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#240#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UXTAH; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #22#6#240#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SXTB; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #97#178#64; ++ flags : if_thumb or if_armv6 ++ ), ++ ( ++ opcode : A_SXTB; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #134#250#79#240#128; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SXTB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #134#250#79#240#128; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SXTB; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #27#6#175#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SXTB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #27#6#175#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SXTB16; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #134#250#47#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SXTB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #134#250#47#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_SXTB16; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #27#6#143#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SXTB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #27#6#143#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SXTH; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #97#178#0; ++ flags : if_thumb or if_armv6 ++ ), ++ ( ++ opcode : A_SXTH; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #134#250#15#240#128; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SXTH; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #134#250#15#240#128; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_SXTH; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #27#6#191#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_SXTH; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #27#6#191#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UXTB; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #97#178#192; ++ flags : if_thumb or if_armv6 ++ ), ++ ( ++ opcode : A_UXTB; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #134#250#95#240#128; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #134#250#95#240#128; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTB; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #27#6#239#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UXTB; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #27#6#239#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UXTB16; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #134#250#63#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #134#250#63#240#128; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTB16; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #27#6#207#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UXTB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #27#6#207#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UXTH; ++ ops : 2; ++ optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none); ++ code : #97#178#128; ++ flags : if_thumb or if_armv6 ++ ), ++ ( ++ opcode : A_UXTH; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #134#250#31#240#128; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTH; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #134#250#31#240#128; ++ flags : if_thumb32 or if_wide or if_armv6t2 ++ ), ++ ( ++ opcode : A_UXTH; ++ ops : 2; ++ optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #27#6#255#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UXTH; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_shifterop,ot_none,ot_none,ot_none); ++ code : #27#6#255#7; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UADD16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#144#240#64; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UADD16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#80#241; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UADD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#128#240#64; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UADD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#80#249; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UASX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#160#240#64; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UASX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#80#243; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UHADD16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#144#240#96; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UHADD16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#112#241; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UHADD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#128#240#96; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UHADD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#112#249; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UHASX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#160#240#96; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UHASX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#112#243; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UHSAX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#224#240#96; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UHSAX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#112#245; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UHSUB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#208#240#96; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UHSUB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#112#247; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UHSUB8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#192#240#96; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UHSUB8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#112#255; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UQADD16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#144#240#80; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UQADD16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#96#241; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UQADD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#128#240#80; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UQADD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#96#249; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UQASX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#160#240#80; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UQASX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#96#243; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UQSAX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#224#240#80; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UQSAX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#96#245; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UQSUB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#208#240#80; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UQSUB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#96#247; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_UQSUB8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#192#240#80; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_UQSUB8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#96#255; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_USAD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#251#112#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_USAD8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #21#7#128#1#15; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_USADA8; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #128#251#112#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_USADA8; ++ ops : 4; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none); ++ code : #21#7#128#1; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_USAT; ++ ops : 3; ++ optypes : (ot_reg32,ot_immediateshifter,ot_reg32,ot_none,ot_none,ot_none); ++ code : #131#243#128#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_USAT; ++ ops : 4; ++ optypes : (ot_reg32,ot_immediateshifter,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #131#243#128#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_USAT; ++ ops : 3; ++ optypes : (ot_reg32,ot_immediateshifter,ot_reg32,ot_none,ot_none,ot_none); ++ code : #42#6#224#0#16; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_USAT; ++ ops : 4; ++ optypes : (ot_reg32,ot_immediateshifter,ot_reg32,ot_shifterop,ot_none,ot_none); ++ code : #42#6#224#0#16; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_USAT16; ++ ops : 3; ++ optypes : (ot_reg32,ot_immediateshifter,ot_reg32,ot_none,ot_none,ot_none); ++ code : #131#243#160#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_USAT16; ++ ops : 3; ++ optypes : (ot_reg32,ot_immediateshifter,ot_reg32,ot_none,ot_none,ot_none); ++ code : #42#6#224#15#48; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_USAX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#224#240#64; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_USAX; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#80#245; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_USUB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#208#240#64; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_USUB16; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#80#247; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_USUB8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#250#192#240#64; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_USUB8; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #22#6#80#255; ++ flags : if_arm32 or if_armv6 ++ ), ++ ( ++ opcode : A_WFE; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #100#191#32; ++ flags : if_thumb or if_armv7 ++ ), ++ ( ++ opcode : A_WFE; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #47#3#32#240#2; ++ flags : if_arm32 or if_armv6k ++ ), ++ ( ++ opcode : A_WFI; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #100#191#48; ++ flags : if_thumb or if_armv7 ++ ), ++ ( ++ opcode : A_WFI; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #47#3#32#240#3; ++ flags : if_arm32 or if_armv6k ++ ), ++ ( ++ opcode : A_YIELD; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #100#191#16; ++ flags : if_thumb or if_armv7 ++ ), ++ ( ++ opcode : A_YIELD; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #47#3#32#240#1; ++ flags : if_arm32 or if_armv6k ++ ), ++ ( ++ opcode : A_FABSD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#176#10#192#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FABSD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#176#10#192#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FABSS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#176#10#192#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FABSS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#176#10#192#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FADDD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#48#10#0#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FADDD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#48#10#0#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FADDS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#48#10#0#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FADDS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#48#10#0#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#180#10#64#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#180#10#64#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#180#10#64#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#180#10#64#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPED; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#180#10#192#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPED; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#180#10#192#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPES; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#180#10#192#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPES; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#180#10#192#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPZD; ++ ops : 1; ++ optypes : (ot_vreg,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#181#10#64#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPZD; ++ ops : 1; ++ optypes : (ot_vreg,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#181#10#64#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPZS; ++ ops : 1; ++ optypes : (ot_vreg,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#181#10#64#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPZS; ++ ops : 1; ++ optypes : (ot_vreg,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#181#10#64#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPEZD; ++ ops : 1; ++ optypes : (ot_vreg,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#181#10#192#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPEZD; ++ ops : 1; ++ optypes : (ot_vreg,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#181#10#192#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPEZS; ++ ops : 1; ++ optypes : (ot_vreg,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#181#10#192#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCMPEZS; ++ ops : 1; ++ optypes : (ot_vreg,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#181#10#192#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCPYD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#238#176#11#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCPYD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#176#11#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCPYS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#238#176#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCPYS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#176#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCVTDS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#238#183#10#192; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCVTDS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#183#10#192; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCVTSD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#238#183#11#192; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FCVTSD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#183#11#192; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FDIVD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#128#10#0#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FDIVD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#128#10#0#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FDIVS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#128#10#0#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FDIVS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#128#10#0#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FLDD; ++ ops : 2; ++ optypes : (ot_vreg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #149#237#16#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FLDD; ++ ops : 2; ++ optypes : (ot_vreg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #69#13#16#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FLDM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #148#236#16#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FLDM; ++ ops : 2; ++ optypes : (ot_reg32,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #148#236#16#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FLDM; ++ ops : 2; ++ optypes : (ot_memoryam4,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #68#12#16#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FLDM; ++ ops : 2; ++ optypes : (ot_reg32,ot_reglist,ot_none,ot_none,ot_none,ot_none); ++ code : #68#12#16#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FLDS; ++ ops : 2; ++ optypes : (ot_vreg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #149#237#16#10; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FLDS; ++ ops : 2; ++ optypes : (ot_vreg,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #69#13#16#10; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMACD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#0#10#0#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMACD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#0#10#0#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMACS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#0#10#0#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMACS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#0#10#0#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMRS; ++ ops : 2; ++ optypes : (ot_reg32,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #144#238#16#10#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMRS; ++ ops : 2; ++ optypes : (ot_reg32,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #64#14#16#10#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMRX; ++ ops : 2; ++ optypes : (ot_reg32,ot_regf,ot_none,ot_none,ot_none,ot_none); ++ code : #145#238#240#10#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMRX; ++ ops : 2; ++ optypes : (ot_regf,ot_regf,ot_none,ot_none,ot_none,ot_none); ++ code : #145#238#240#10#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMRX; ++ ops : 2; ++ optypes : (ot_reg32,ot_regf,ot_none,ot_none,ot_none,ot_none); ++ code : #65#14#240#10#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMRX; ++ ops : 2; ++ optypes : (ot_regf,ot_regf,ot_none,ot_none,ot_none,ot_none); ++ code : #65#14#240#10#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMSCD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#16#10#0#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMSCD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#16#10#0#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMSCS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#16#10#0#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMSCS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#16#10#0#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMSR; ++ ops : 2; ++ optypes : (ot_vreg,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #144#238#0#10#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMSR; ++ ops : 2; ++ optypes : (ot_vreg,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #64#14#0#10#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMSTAT; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #128#238#241#250#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMSTAT; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #47#14#241#250#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMULD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#32#10#0#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMULD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#32#10#0#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMULS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#32#10#0#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMULS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#32#10#0#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMXR; ++ ops : 2; ++ optypes : (ot_regf,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #145#238#224#10#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FMXR; ++ ops : 2; ++ optypes : (ot_regf,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #65#14#224#10#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNEGD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#177#10#64#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNEGD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#177#10#64#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNEGS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#177#10#64#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNEGS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#177#10#64#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNMACD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#0#10#64#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNMACD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#0#10#64#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNMACS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#0#10#64#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNMACS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#0#10#64#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNMSCD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#16#10#64#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNMSCD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#16#10#64#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNMSCS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#16#10#64#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNMSCS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#16#10#64#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNMULD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#32#10#64#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNMULD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#32#10#64#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNMULS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#32#10#64#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FNMULS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#32#10#64#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSITOD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#238#184#11#192; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSITOD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#184#11#192; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSITOS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#238#184#10#192; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSITOS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#184#10#192; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSQRTD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#177#10#192#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSQRTD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#177#10#192#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSQRTS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#177#10#192#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSQRTS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#177#10#192#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSUBD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#48#10#64#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSUBD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#48#10#64#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSUBS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#48#10#64#1; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FSUBS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#48#10#64#1; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FTOSID; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#238#189#11#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FTOSID; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#189#11#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FTOSIS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#238#189#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FTOSIS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#189#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FTOUID; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#238#188#11#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FTOUID; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#188#11#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FTOUIS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#238#188#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FTOUIS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#188#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FUITOD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#238#184#11#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FUITOD; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#184#11#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FUITOS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#238#184#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_FUITOS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#184#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_POP; ++ ops : 1; ++ optypes : (ot_reglist,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #105#188; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_POP; ++ ops : 1; ++ optypes : (ot_reglist,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #38#139; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_PUSH; ++ ops : 1; ++ optypes : (ot_reglist,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #105#180; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_PUSH; ++ ops : 1; ++ optypes : (ot_reglist,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #38#128; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_SDIV; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#251#144#240#240; ++ flags : if_thumb32 or if_armv7r or if_armv7m ++ ), ++ ( ++ opcode : A_SDIV; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #21#7#16#1#15; ++ flags : if_arm32 or if_armv7 ++ ), ++ ( ++ opcode : A_UDIV; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #128#251#176#240#240; ++ flags : if_thumb32 or if_armv7r or if_armv7m ++ ), ++ ( ++ opcode : A_UDIV; ++ ops : 3; ++ optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none); ++ code : #21#7#48#1#15; ++ flags : if_arm32 or if_armv7 ++ ), ++ ( ++ opcode : A_MOVT; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediate,ot_none,ot_none,ot_none,ot_none); ++ code : #129#242#192#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_MOVT; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #129#242#192#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_MOVT; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediate,ot_none,ot_none,ot_none,ot_none); ++ code : #44#3#64; ++ flags : if_arm32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_MOVT; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #44#3#64; ++ flags : if_arm32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_IT; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#8#0; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_IT; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#4#136; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITT; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#4#8; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITT; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITEE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#2#204; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITEE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITTE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#2#76; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITTE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITET; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#2#140; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITET; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITTT; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#2#12; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITTT; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITEEE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#1#238; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITEEE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITTEE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#1#110; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITTEE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITETE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#1#174; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITETE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITTTE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#1#46; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITTTE; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITEET; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#1#206; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITEET; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITTET; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#1#78; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITTET; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITETT; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#1#142; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITETT; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_ITTTT; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #106#191#1#14; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_ITTTT; ++ ops : 1; ++ optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #254; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_TBB; ++ ops : 1; ++ optypes : (ot_memoryam2,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #142#232#208#240#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_TBH; ++ ops : 1; ++ optypes : (ot_memoryam2,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #142#232#208#240#16; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_MOVW; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,ot_none,ot_none,ot_none); ++ code : #44#3#0; ++ flags : if_arm32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_MOVW; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #44#3#0; ++ flags : if_arm32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_MOVW; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediate or ot_bits32,ot_none,ot_none,ot_none,ot_none); ++ code : #129#242#64#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_MOVW; ++ ops : 2; ++ optypes : (ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #129#242#64#0#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_CBZ; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #104#177; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_CBZ; ++ ops : 2; ++ optypes : (ot_reglo,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #104#177; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_CBNZ; ++ ops : 2; ++ optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #104#185; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_CBNZ; ++ ops : 2; ++ optypes : (ot_reglo,ot_memoryam2,ot_none,ot_none,ot_none,ot_none); ++ code : #104#185; ++ flags : if_thumb or if_armv6t2 ++ ), ++ ( ++ opcode : A_VABS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#176#10#192; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VABS; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#176#10#192; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VADD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#48#10#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VADD; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#48#10#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VCMP; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#180#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VCMP; ++ ops : 2; ++ optypes : (ot_vreg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#181#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VCMP; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#180#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VCMP; ++ ops : 2; ++ optypes : (ot_vreg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#181#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VCMPE; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#180#10#192; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VCMPE; ++ ops : 2; ++ optypes : (ot_vreg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#181#10#192; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VCMPE; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#180#10#192; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VCMPE; ++ ops : 2; ++ optypes : (ot_vreg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#181#10#192; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VCVT; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #147#238#184#10#192; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VCVT; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #147#238#186#10#64; ++ flags : if_thumb32 or if_vfpv3 ++ ), ++ ( ++ opcode : A_VCVT; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#184#10#192; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VCVT; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #67#14#186#10#64; ++ flags : if_arm32 or if_vfpv3 ++ ), ++ ( ++ opcode : A_VCVTR; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #147#238#184#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VCVTR; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #67#14#184#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VDIV; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#128#10#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VDIV; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#128#10#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMRS; ++ ops : 2; ++ optypes : (ot_reg32,ot_regf,ot_none,ot_none,ot_none,ot_none); ++ code : #145#238#240#10#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMRS; ++ ops : 2; ++ optypes : (ot_regf,ot_regf,ot_none,ot_none,ot_none,ot_none); ++ code : #145#238#240#10#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMRS; ++ ops : 2; ++ optypes : (ot_reg32,ot_regf,ot_none,ot_none,ot_none,ot_none); ++ code : #65#14#240#10#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMRS; ++ ops : 2; ++ optypes : (ot_regf,ot_regf,ot_none,ot_none,ot_none,ot_none); ++ code : #65#14#240#10#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMSR; ++ ops : 2; ++ optypes : (ot_regf,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #145#238#224#10#16; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMSR; ++ ops : 2; ++ optypes : (ot_regf,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #65#14#224#10#16; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMLA; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#0#10#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMLA; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#0#10#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMLS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#0#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMLS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#0#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMUL; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#32#10#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VMUL; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#32#10#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VNMLA; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#16#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VNMLA; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#16#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VNMLS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#16#10#0; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VNMLS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#16#10#0; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VNMUL; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#32#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VNMUL; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#32#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VFMA; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#160#10#0; ++ flags : if_thumb32 or if_vfpv4 ++ ), ++ ( ++ opcode : A_VFMA; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#160#10#0; ++ flags : if_arm32 or if_vfpv4 ++ ), ++ ( ++ opcode : A_VFMS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#160#10#64; ++ flags : if_thumb32 or if_vfpv4 ++ ), ++ ( ++ opcode : A_VFMS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#160#10#64; ++ flags : if_arm32 or if_vfpv4 ++ ), ++ ( ++ opcode : A_VFNMA; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#144#10#0; ++ flags : if_thumb32 or if_vfpv4 ++ ), ++ ( ++ opcode : A_VFNMA; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#144#10#0; ++ flags : if_arm32 or if_vfpv4 ++ ), ++ ( ++ opcode : A_VFNMS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#144#10#64; ++ flags : if_thumb32 or if_vfpv4 ++ ), ++ ( ++ opcode : A_VFNMS; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#144#10#64; ++ flags : if_arm32 or if_vfpv4 ++ ), ++ ( ++ opcode : A_VNEG; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#177#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VNEG; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#177#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VSQRT; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #146#238#177#10#192; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VSQRT; ++ ops : 2; ++ optypes : (ot_vreg,ot_vreg,ot_none,ot_none,ot_none,ot_none); ++ code : #66#14#177#10#192; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VSUB; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #146#238#48#10#64; ++ flags : if_thumb32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_VSUB; ++ ops : 3; ++ optypes : (ot_vreg,ot_vreg,ot_vreg,ot_none,ot_none,ot_none); ++ code : #66#14#48#10#64; ++ flags : if_arm32 or if_vfpv2 ++ ), ++ ( ++ opcode : A_DMB; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #128#243#191#143#80; ++ flags : if_thumb32 or if_armv7 ++ ), ++ ( ++ opcode : A_DMB; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #46#245#127#240#80; ++ flags : if_arm32 or if_armv7 ++ ), ++ ( ++ opcode : A_ISB; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #128#243#191#143#96; ++ flags : if_thumb32 or if_armv7 ++ ), ++ ( ++ opcode : A_ISB; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #46#245#127#240#96; ++ flags : if_arm32 or if_armv7 ++ ), ++ ( ++ opcode : A_DSB; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #128#243#191#143#64; ++ flags : if_thumb32 or if_armv7 ++ ), ++ ( ++ opcode : A_DSB; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #46#245#127#240#64; ++ flags : if_arm32 or if_armv7 ++ ), ++ ( ++ opcode : A_SMC; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #46#1#96#0#112; ++ flags : if_arm32 or if_armv7 ++ ), ++ ( ++ opcode : A_SMC; ++ ops : 1; ++ optypes : (ot_immediate or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #46#1#96#0#112; ++ flags : if_arm32 or if_armv7 ++ ), ++ ( ++ opcode : A_SVC; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #97#223#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_SVC; ++ ops : 1; ++ optypes : (ot_immediate or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #97#223#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_SVC; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #2#15; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_SVC; ++ ops : 1; ++ optypes : (ot_immediate or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #2#15; ++ flags : if_arm32 or if_armv4 ++ ), ++ ( ++ opcode : A_BXJ; ++ ops : 1; ++ optypes : (ot_reg32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #128#243#192#143#0; ++ flags : if_thumb32 or if_armv6t2 ++ ), ++ ( ++ opcode : A_BXJ; ++ ops : 1; ++ optypes : (ot_reg32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #3#1#47#255#32; ++ flags : if_arm32 or if_armv5tej ++ ), ++ ( ++ opcode : A_UDF; ++ ops : 1; ++ optypes : (ot_immediateshifter,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #97#222#0; ++ flags : if_thumb or if_armv4t ++ ), ++ ( ++ opcode : A_UDF; ++ ops : 0; ++ optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #0; ++ flags : if_arm32 or if_armv4t ++ ), ++ ( ++ opcode : A_TAN; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#21; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_TAN; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#21; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_SQT; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#9; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_SQT; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#9; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_SUF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none); ++ code : #161#0#4; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_SUF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #161#0#4; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_RSF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none); ++ code : #161#0#6; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_RSF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #161#0#6; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_RND; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#7; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_RND; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#7; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_POL; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none); ++ code : #161#0#24; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_POL; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #161#0#24; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_RDF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none); ++ code : #161#0#10; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_RDF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #161#0#10; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_RFS; ++ ops : 1; ++ optypes : (ot_reg32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#3; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_RFC; ++ ops : 1; ++ optypes : (ot_reg32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#5; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_WFC; ++ ops : 1; ++ optypes : (ot_reg32,ot_none,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#4; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_RMF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none); ++ code : #161#0#16; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_RMF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #161#0#16; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_RPW; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none); ++ code : #161#0#12; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_RPW; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #161#0#12; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_MNF; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#3; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_MNF; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#3; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_MUF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none); ++ code : #161#0#2; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_MUF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #161#0#2; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_ABS; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#5; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_ABS; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#5; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_ACS; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#25; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_ACS; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#25; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_ASN; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#23; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_ASN; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#23; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_ATN; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#27; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_ATN; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#27; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_CNF; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#176; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_CNF; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#176; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_CNFE; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#240; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_CNFE; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#240; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_COS; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#19; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_COS; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#19; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_DVF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none); ++ code : #161#0#8; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_DVF; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #161#0#8; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_EXP; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#15; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_EXP; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#15; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_FDV; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none); ++ code : #161#0#20; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_FDV; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #161#0#20; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_FLT; ++ ops : 2; ++ optypes : (ot_fpureg,ot_reg32,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#0; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_FIX; ++ ops : 2; ++ optypes : (ot_reg32,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #162#14#16; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_FML; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none); ++ code : #161#0#18; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_FML; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #161#0#18; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_FRD; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none); ++ code : #161#0#22; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_FRD; ++ ops : 3; ++ optypes : (ot_fpureg,ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none); ++ code : #161#0#22; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_LGN; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#13; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_LGN; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#13; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_LOG; ++ ops : 2; ++ optypes : (ot_fpureg,ot_fpureg,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#11; ++ flags : if_arm32 or if_fpa ++ ), ++ ( ++ opcode : A_LOG; ++ ops : 2; ++ optypes : (ot_fpureg,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none); ++ code : #161#1#11; ++ flags : if_arm32 or if_fpa + ) + ); +Index: fpc/fpcsrc/compiler/arm/cgcpu.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/cgcpu.pas ++++ fpc/fpcsrc/compiler/arm/cgcpu.pas +@@ -104,7 +104,7 @@ unit cgcpu; + + procedure a_opmm_reg_reg(list: TAsmList; Op: TOpCG; size : tcgsize;src,dst: tregister;shuffle : pmmshuffle); override; + { Transform unsupported methods into Internal errors } +- procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: TCGSize; src, dst: TRegister); override; ++ procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: TCGSize; src, dst: TRegister); override; + + { try to generate optimized 32 Bit multiplication, returns true if successful generated } + function try_optimized_mul32_const_reg_reg(list: TAsmList; a: tcgint; src, dst: tregister) : boolean; +@@ -1703,7 +1703,7 @@ unit cgcpu; + end; + + +- procedure tbasecgarm.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: TCGSize; src, dst: TRegister); ++ procedure tbasecgarm.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: TCGSize; src, dst: TRegister); + begin + if reverse then + begin +@@ -2032,11 +2032,11 @@ unit cgcpu; + ref.index:=ref.base; + ref.base:=NR_NO; + { FSTMX is deprecated on ARMv6 and later } +- if (current_settings.cputypereg) then +@@ -3053,7 +3041,6 @@ unit cgcpu; + intreg, + tmpmmreg : tregister; + reg64 : tregister64; +- op : tasmop; + begin + if assigned(shuffle) and + not(shufflescalar(shuffle)) then +@@ -3105,15 +3092,7 @@ unit cgcpu; + end + else + begin +- case fromsize of +- OS_F32: +- op:=A_FSTS; +- OS_F64: +- op:=A_FSTD; +- else +- internalerror(2009112418); +- end; +- handle_load_store(list,op,PF_None,tmpmmreg,ref); ++ handle_load_store(list,A_VSTR,PF_None,tmpmmreg,ref); + end; + end; + +@@ -3129,7 +3108,7 @@ unit cgcpu; + if assigned(shuffle) and + not shufflescalar(shuffle) then + internalerror(2009112516); +- list.concat(taicpu.op_reg_reg(A_FMSR,mmreg,intreg)); ++ list.concat(taicpu.op_reg_reg(A_VMOV,mmreg,intreg)); + end; + + +@@ -3144,7 +3123,7 @@ unit cgcpu; + if assigned(shuffle) and + not shufflescalar(shuffle) then + internalerror(2009112514); +- list.concat(taicpu.op_reg_reg(A_FMRS,intreg,mmreg)); ++ list.concat(taicpu.op_reg_reg(A_VMOV,intreg,mmreg)); + end; + + +@@ -3166,9 +3145,9 @@ unit cgcpu; + a_load_const_reg(list,OS_32,0,tmpreg); + case size of + OS_F32: +- list.concat(taicpu.op_reg_reg(A_FMSR,dst,tmpreg)); ++ list.concat(taicpu.op_reg_reg(A_VMOV,dst,tmpreg)); + OS_F64: +- list.concat(taicpu.op_reg_reg_reg(A_FMDRR,dst,tmpreg,tmpreg)); ++ list.concat(taicpu.op_reg_reg_reg(A_VMOV,dst,tmpreg,tmpreg)); + else + internalerror(2009112908); + end; +@@ -3290,7 +3269,7 @@ unit cgcpu; + Internalerror(200109191); + + if GenerateThumbCode or GenerateThumb2Code then +- list.concat(tai_thumb_func.create); ++ list.concat(tai_directive.Create(asd_thumb_func,'')); + + make_global:=false; + if (not current_module.is_unit) or +@@ -3433,7 +3412,7 @@ unit cgcpu; + conversions } + if (mmsize<>OS_F64) then + internalerror(2009112405); +- list.concat(taicpu.op_reg_reg_reg(A_FMDRR,mmreg,intreg.reglo,intreg.reghi)); ++ list.concat(taicpu.op_reg_reg_reg(A_VMOV,mmreg,intreg.reglo,intreg.reghi)); + end; + + +@@ -3443,7 +3422,7 @@ unit cgcpu; + conversions } + if (mmsize<>OS_F64) then + internalerror(2009112406); +- list.concat(taicpu.op_reg_reg_reg(A_FMRRD,intreg.reglo,intreg.reghi,mmreg)); ++ list.concat(taicpu.op_reg_reg_reg(A_VMOV,intreg.reglo,intreg.reghi,mmreg)); + end; + + +@@ -4378,7 +4357,13 @@ unit cgcpu; + rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE, + [RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7],first_fpu_imreg,[]); + +- if current_settings.fputype in [fpu_fpv4_s16,fpu_vfpv3_d16] then ++ if current_settings.fputype=fpu_vfpv3 then ++ rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBFD, ++ [RS_D0,RS_D1,RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7, ++ RS_D16,RS_D17,RS_D18,RS_D19,RS_D20,RS_D21,RS_D22,RS_D23,RS_D24,RS_D25,RS_D26,RS_D27,RS_D28,RS_D29,RS_D30,RS_D31, ++ RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15 ++ ],first_mm_imreg,[]) ++ else if current_settings.fputype in [fpu_fpv4_s16,fpu_vfpv3_d16] then + rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBFD, + [RS_D0,RS_D1,RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7, + RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15 +@@ -5301,19 +5286,13 @@ unit cgcpu; + + procedure tthumb2cgarm.a_loadmm_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister; shuffle: pmmshuffle); + begin +- if fromsize=OS_F32 then +- handle_load_store(list,A_VLDR,PF_F32,reg,ref) +- else +- handle_load_store(list,A_VLDR,PF_F64,reg,ref); ++ handle_load_store(list,A_VLDR,PF_None,reg,ref); + end; + + + procedure tthumb2cgarm.a_loadmm_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference; shuffle: pmmshuffle); + begin +- if fromsize=OS_F32 then +- handle_load_store(list,A_VSTR,PF_F32,reg,ref) +- else +- handle_load_store(list,A_VSTR,PF_F64,reg,ref); ++ handle_load_store(list,A_VSTR,PF_None,reg,ref); + end; + + +Index: fpc/fpcsrc/compiler/arm/cpubase.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/cpubase.pas ++++ fpc/fpcsrc/compiler/arm/cpubase.pas +@@ -93,7 +93,7 @@ unit cpubase; + first_mm_imreg = $30; + + { TODO: Calculate bsstart} +- regnumber_count_bsstart = 64; ++ regnumber_count_bsstart = 128; + + regnumber_table : array[tregisterindex] of tregister = ( + {$i rarmnum.inc} +@@ -130,6 +130,10 @@ unit cpubase; + PF_S, + { floating point size } + PF_D,PF_E,PF_P,PF_EP, ++ { exchange } ++ PF_X, ++ { rounding } ++ PF_R, + { load/store } + PF_B,PF_SB,PF_BT,PF_H,PF_SH,PF_T, + { multiple load/store address modes } +@@ -138,10 +142,18 @@ unit cpubase; + PF_IAD,PF_DBD,PF_FDD,PF_EAD, + PF_IAS,PF_DBS,PF_FDS,PF_EAS, + PF_IAX,PF_DBX,PF_FDX,PF_EAX, +- { FPv4 postfixes } +- PF_32,PF_64,PF_F32,PF_F64, +- PF_F32S32,PF_F32U32, +- PF_S32F32,PF_U32F32 ++ { VFP postfixes } ++ PF_8,PF_16,PF_32,PF_64, ++ PF_I8,PF_I16,PF_I32,PF_I64, ++ PF_S8,PF_S16,PF_S32,PF_S64, ++ PF_U8,PF_U16,PF_U32,PF_U64, ++ PF_P8, // polynomial ++ PF_F32,PF_F64, ++ PF_F32F64,PF_F64F32, ++ PF_F32S16,PF_F32U16,PF_S16F32,PF_U16F32, ++ PF_F64S16,PF_F64U16,PF_S16F64,PF_U16F64, ++ PF_F32S32,PF_F32U32,PF_S32F32,PF_U32F32, ++ PF_F64S32,PF_F64U32,PF_S32F64,PF_U32F64 + ); + + TOpPostfixes = set of TOpPostfix; +@@ -157,14 +169,24 @@ unit cpubase; + oppostfix2str : array[TOpPostfix] of string[8] = ('', + 's', + 'd','e','p','ep', ++ 'x', ++ 'r', + 'b','sb','bt','h','sh','t', + 'ia','ib','da','db','fd','fa','ed','ea', + 'iad','dbd','fdd','ead', + 'ias','dbs','fds','eas', + 'iax','dbx','fdx','eax', +- '.32','.64','.f32','.f64', +- '.f32.s32','.f32.u32', +- '.s32.f32','.u32.f32'); ++ '.8','.16','.32','.64', ++ '.i8','.i16','.i32','.i64', ++ '.s8','.s16','.s32','.s64', ++ '.u8','.u16','.u32','.u64', ++ '.p8', ++ '.f32','.f64', ++ '.f32.f64','.f64.f32', ++ '.f32.s16','.f32.u16','.s16.f32','.u16.f32', ++ '.f64.s16','.f64.u16','.s16.f64','.u16.f64', ++ '.f32.s32','.f32.u32','.s32.f32','.u32.f32', ++ '.f64.s32','.f64.u32','.s32.f64','.u32.f64'); + + roundingmode2str : array[TRoundingMode] of string[1] = ('', + 'p','m','z'); +@@ -569,7 +591,6 @@ unit cpubase; + var + t : aint; + i : longint; +- imm : byte; + begin + {Loading 0-255 is simple} + if (d and $FF) = d then +@@ -584,10 +605,20 @@ unit cpubase; + ) then + result:=true + {Can an 8-bit value be shifted accordingly?} +- else if is_shifter_const(d,imm) then +- result:=true + else +- result:=false; ++ begin ++ result:=false; ++ for i:=1 to 31 do ++ begin ++ t:=RolDWord(d,i); ++ if ((t and $FF)=t) and ++ ((t and $80)=$80) then ++ begin ++ result:=true; ++ exit; ++ end; ++ end; ++ end; + end; + + function is_continuous_mask(d : aint;var lsb, width: byte) : boolean; +Index: fpc/fpcsrc/compiler/arm/cpuelf.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/cpuelf.pas ++++ fpc/fpcsrc/compiler/arm/cpuelf.pas +@@ -325,8 +325,15 @@ implementation + result:=R_ARM_ABS32; + RELOC_RELATIVE: + result:=R_ARM_REL32; ++ RELOC_RELATIVE_24: ++ result:=R_ARM_JUMP24; ++ RELOC_RELATIVE_24_THUMB: ++ result:=R_ARM_CALL; ++ RELOC_RELATIVE_CALL_THUMB: ++ result:=R_ARM_THM_CALL; + else + result:=0; ++ writeln(objrel.typ); + InternalError(2012110602); + end; + end; +@@ -666,9 +673,14 @@ implementation + begin + if (reltyp=R_ARM_CALL) then + { change BL to BLX, dest bit 1 goes to instruction bit 24 } +- address:=(address and $FE000000) or (((tmp-curloc) and 2) shl 23) or $10000000 ++ address:=(address and $FE000000) or (((tmp-curloc) and 2) shl 23) or $F0000000 + else + InternalError(2014092001); ++ end ++ else if (address and $FF000000)=$FA000000 then ++ begin ++ { Change BLX to BL } ++ address:=(address and $EA000000) or $01000000; + end; + tmp:=tmp-curloc; + // TODO: check overflow +@@ -902,6 +914,11 @@ implementation + end; + + ++ function elf_arm_encodeflags: longword; ++ begin ++ result:=EF_ARM_EABI_VER5; ++ end; ++ + {***************************************************************************** + Initialize + *****************************************************************************} +@@ -924,9 +941,26 @@ implementation + encodereloc: @elf_arm_encodeReloc; + loadreloc: @elf_arm_loadReloc; + loadsection: @elf_arm_loadSection; ++ encodeflags: @elf_arm_encodeflags; + ); + ++ as_arm_elf32_info : tasminfo = ++ ( ++ id : as_arm_elf32; ++ idtxt : 'ELF'; ++ asmbin : ''; ++ asmcmd : ''; ++ supported_targets : [system_arm_embedded,system_arm_darwin, ++ system_arm_linux,system_arm_gba, ++ system_arm_nds]; ++ flags : [af_outputbinary,af_smartlink_sections,af_supports_dwarf]; ++ labelprefix : '.L'; ++ comment : ''; ++ dollarsign: '$'; ++ ); ++ + initialization ++ RegisterAssembler(as_arm_elf32_info,TElfAssembler); + ElfTarget:=elf_target_arm; + ElfExeOutputClass:=TElfExeOutputARM; + +Index: fpc/fpcsrc/compiler/arm/cpuinfo.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/cpuinfo.pas ++++ fpc/fpcsrc/compiler/arm/cpuinfo.pas +@@ -67,7 +67,8 @@ Type + fpu_vfpv2, + fpu_vfpv3, + fpu_vfpv3_d16, +- fpu_fpv4_s16 ++ fpu_fpv4_s16, ++ fpu_vfpv4 + ); + + tcontrollertype = +@@ -399,7 +400,8 @@ Const + 'VFPV2', + 'VFPV3', + 'VFPV3_D16', +- 'FPV4_S16' ++ 'FPV4_S16', ++ 'VFPV4' + ); + + +@@ -746,7 +748,7 @@ Const + { cpu_armv3 } [], + { cpu_armv4 } [CPUARM_HAS_UMULL], + { cpu_armv4t } [CPUARM_HAS_BX,CPUARM_HAS_UMULL], +- { cpu_armv5 } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_UMULL], ++ { cpu_armv5 } [CPUARM_HAS_CLZ,CPUARM_HAS_UMULL], + { cpu_armv5t } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_UMULL], + { cpu_armv5te } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL], + { cpu_armv5tej } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL], +Index: fpc/fpcsrc/compiler/arm/narmadd.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/narmadd.pas ++++ fpc/fpcsrc/compiler/arm/narmadd.pas +@@ -162,6 +162,7 @@ interface + var + op : TAsmOp; + singleprec: boolean; ++ pf: TOpPostfix; + begin + pass_left_right; + if (nf_swapped in flags) then +@@ -210,33 +211,25 @@ interface + location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size); + + singleprec:=tfloatdef(left.resultdef).floattype=s32real; ++ if singleprec then ++ pf:=PF_F32 ++ else ++ pf:=PF_F64; + case nodetype of + addn : +- if singleprec then +- op:=A_FADDS +- else +- op:=A_FADDD; ++ op:=A_VADD; + muln : +- if singleprec then +- op:=A_FMULS +- else +- op:=A_FMULD; ++ op:=A_VMUL; + subn : +- if singleprec then +- op:=A_FSUBS +- else +- op:=A_FSUBD; ++ op:=A_VSUB; + slashn : +- if singleprec then +- op:=A_FDIVS +- else +- op:=A_FDIVD; ++ op:=A_VDIV; + else + internalerror(2009111401); + end; + +- current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op, +- location.register,left.location.register,right.location.register)); ++ current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(op, ++ location.register,left.location.register,right.location.register),pf)); + end; + fpu_fpv4_s16: + begin +@@ -275,6 +268,7 @@ interface + procedure tarmaddnode.second_cmpfloat; + var + op: TAsmOp; ++ pf: TOpPostfix; + begin + pass_left_right; + if (nf_swapped in flags) then +@@ -310,19 +304,20 @@ interface + hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true); + hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.resultdef,true); + ++ if nodetype in [equaln,unequaln] then ++ op:=A_VCMP ++ else ++ op:=A_VCMPE; ++ + if (tfloatdef(left.resultdef).floattype=s32real) then +- if nodetype in [equaln,unequaln] then +- op:=A_FCMPS +- else +- op:=A_FCMPES +- else if nodetype in [equaln,unequaln] then +- op:=A_FCMPD ++ pf:=PF_F32 + else +- op:=A_FCMPED; +- current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, +- left.location.register,right.location.register)); ++ pf:=PF_F64; ++ ++ current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(op, ++ left.location.register,right.location.register), pf)); + cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS); +- current_asmdata.CurrAsmList.concat(taicpu.op_none(A_FMSTAT)); ++ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_VMRS,NR_APSR_nzcv,NR_FPSCR)); + location.resflags:=GetFpuResFlags; + end; + fpu_fpv4_s16: +Index: fpc/fpcsrc/compiler/arm/narmcnv.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/narmcnv.pas ++++ fpc/fpcsrc/compiler/arm/narmcnv.pas +@@ -170,9 +170,9 @@ implementation + + procedure tarmtypeconvnode.second_int_to_real; + const +- signedprec2vfpop: array[boolean,OS_F32..OS_F64] of tasmop = +- ((A_FUITOS,A_FUITOD), +- (A_FSITOS,A_FSITOD)); ++ signedprec2vfppf: array[boolean,OS_F32..OS_F64] of toppostfix = ++ ((PF_F32U32,PF_F64U32), ++ (PF_F32S32,PF_F64S32)); + var + instr : taicpu; + href : treference; +@@ -253,8 +253,9 @@ implementation + location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size) + else + location.register:=left.location.register; +- current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg( +- signedprec2vfpop[signed,location.size],location.register,left.location.register)); ++ current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VCVT, ++ location.register,left.location.register), ++ signedprec2vfppf[signed,location.size])); + end; + fpu_fpv4_s16: + begin +Index: fpc/fpcsrc/compiler/arm/narminl.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/narminl.pas ++++ fpc/fpcsrc/compiler/arm/narminl.pas +@@ -234,7 +234,7 @@ implementation + procedure tarminlinenode.second_abs_real; + var + singleprec: boolean; +- op: TAsmOp; ++ pf: TOpPostfix; + begin + load_fpu_location(singleprec); + case current_settings.fputype of +@@ -247,10 +247,10 @@ implementation + fpu_vfpv3_d16: + begin + if singleprec then +- op:=A_FABSS ++ pf:=PF_F32 + else +- op:=A_FABSD; +- current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,location.register,left.location.register)); ++ pf:=PF_F64; ++ current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VABS,location.register,left.location.register),pf)); + end; + fpu_fpv4_s16: + current_asmdata.CurrAsmList.Concat(setoppostfix(taicpu.op_reg_reg(A_VABS,location.register,left.location.register), PF_F32)); +@@ -270,7 +270,7 @@ implementation + procedure tarminlinenode.second_sqr_real; + var + singleprec: boolean; +- op: TAsmOp; ++ pf: TOpPostfix; + begin + load_fpu_location(singleprec); + case current_settings.fputype of +@@ -283,10 +283,10 @@ implementation + fpu_vfpv3_d16: + begin + if singleprec then +- op:=A_FMULS ++ pf:=PF_F32 + else +- op:=A_FMULD; +- current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,left.location.register)); ++ pf:=PF_F64; ++ current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_VMUL,location.register,left.location.register,left.location.register),pf)); + end; + fpu_fpv4_s16: + current_asmdata.CurrAsmList.Concat(setoppostfix(taicpu.op_reg_reg_reg(A_VMUL,location.register,left.location.register,left.location.register), PF_F32)); +@@ -299,7 +299,7 @@ implementation + procedure tarminlinenode.second_sqrt_real; + var + singleprec: boolean; +- op: TAsmOp; ++ pf: TOpPostfix; + begin + load_fpu_location(singleprec); + case current_settings.fputype of +@@ -312,13 +312,13 @@ implementation + fpu_vfpv3_d16: + begin + if singleprec then +- op:=A_FSQRTS ++ pf:=PF_F32 + else +- op:=A_FSQRTD; +- current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,location.register,left.location.register)); ++ pf:=PF_F64; ++ current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VSQRT,location.register,left.location.register),pf)); + end; + fpu_fpv4_s16: +- current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_VSQRT,location.register,left.location.register)); ++ current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VSQRT,location.register,left.location.register), PF_F32)); + else + internalerror(2009111402); + end; +Index: fpc/fpcsrc/compiler/arm/narmmat.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/narmmat.pas ++++ fpc/fpcsrc/compiler/arm/narmmat.pas +@@ -411,6 +411,7 @@ implementation + procedure tarmunaryminusnode.second_float; + var + op: tasmop; ++ pf: TOpPostfix; + begin + secondpass(left); + case current_settings.fputype of +@@ -432,12 +433,14 @@ implementation + location:=left.location; + if (left.location.loc=LOC_CMMREGISTER) then + location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size); +- if (location.size=OS_F32) then +- op:=A_FNEGS ++ ++ if (tfloatdef(left.resultdef).floattype=s32real) then ++ pf:=PF_F32 + else +- op:=A_FNEGD; +- current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, +- location.register,left.location.register)); ++ pf:=PF_F64; ++ ++ current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG, ++ location.register,left.location.register), pf)); + end; + fpu_fpv4_s16: + begin +Index: fpc/fpcsrc/compiler/arm/narmmem.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/narmmem.pas ++++ fpc/fpcsrc/compiler/arm/narmmem.pas +@@ -27,6 +27,7 @@ interface + + uses + globtype, ++ symtype, + cgbase,cpubase,nmem,ncgmem; + + type +@@ -36,7 +37,7 @@ interface + + + tarmvecnode = class(tcgvecnode) +- procedure update_reference_reg_mul(maybe_const_reg: tregister; l: aint);override; ++ procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint);override; + end; + + implementation +@@ -70,7 +71,7 @@ implementation + TARMVECNODE + *****************************************************************************} + +- procedure tarmvecnode.update_reference_reg_mul(maybe_const_reg:tregister;l:aint); ++ procedure tarmvecnode.update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); + var + hreg: tregister; + hl : longint; +@@ -79,7 +80,7 @@ implementation + (GenerateThumbCode) or + { simple constant? } + (l=1) or ispowerof2(l,hl) or ispowerof2(l+1,hl) or ispowerof2(l-1,hl) then +- inherited update_reference_reg_mul(maybe_const_reg,l) ++ inherited update_reference_reg_mul(maybe_const_reg,regsize,l) + else if (location.reference.base<>NR_NO) then + begin + hreg:=cg.getaddressregister(current_asmdata.CurrAsmList); +Index: fpc/fpcsrc/compiler/arm/raarmgas.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/raarmgas.pas ++++ fpc/fpcsrc/compiler/arm/raarmgas.pas +@@ -30,6 +30,7 @@ Unit raarmgas; + cpubase; + + type ++ + tarmattreader = class(tattreader) + actoppostfix : TOpPostfix; + actwideformat : boolean; +@@ -45,6 +46,13 @@ Unit raarmgas; + procedure ReadSym(oper : tarmoperand); + procedure ConvertCalljmp(instr : tarminstruction); + procedure HandleTargetDirective; override; ++ protected ++ function is_unified: boolean; virtual; ++ end; ++ ++ tarmunifiedattreader = class(tarmattreader) ++ protected ++ function is_unified: boolean; override; + end; + + +@@ -63,15 +71,21 @@ Unit raarmgas; + cgbase,cgutils; + + ++ function tarmunifiedattreader.is_unified: boolean; ++ begin ++ result:=true; ++ end; ++ ++ + function tarmattreader.is_register(const s:string):boolean; + type + treg2str = record +- name : string[2]; ++ name : string[3]; + reg : tregister; + end; + + const +- extraregs : array[0..19] of treg2str = ( ++ extraregs : array[0..19+16] of treg2str = ( + (name: 'A1'; reg : NR_R0), + (name: 'A2'; reg : NR_R1), + (name: 'A3'; reg : NR_R2), +@@ -91,7 +105,25 @@ Unit raarmgas; + (name: 'IP'; reg : NR_R12), + (name: 'SP'; reg : NR_R13), + (name: 'LR'; reg : NR_R14), +- (name: 'PC'; reg : NR_R15)); ++ (name: 'PC'; reg : NR_R15), ++ ++ (name: 'C0'; reg : NR_CR0), ++ (name: 'C1'; reg : NR_CR1), ++ (name: 'C2'; reg : NR_CR2), ++ (name: 'C3'; reg : NR_CR3), ++ (name: 'C4'; reg : NR_CR4), ++ (name: 'C5'; reg : NR_CR5), ++ (name: 'C6'; reg : NR_CR6), ++ (name: 'C7'; reg : NR_CR7), ++ (name: 'C8'; reg : NR_CR8), ++ (name: 'C9'; reg : NR_CR9), ++ (name: 'C10'; reg : NR_CR10), ++ (name: 'C11'; reg : NR_CR11), ++ (name: 'C12'; reg : NR_CR12), ++ (name: 'C13'; reg : NR_CR13), ++ (name: 'C14'; reg : NR_CR14), ++ (name: 'C15'; reg : NR_CR15) ++ ); + + var + i : longint; +@@ -101,7 +133,7 @@ Unit raarmgas; + { reg found? + possible aliases are always 2 char + } +- if result or (length(s)<>2) then ++ if result or (not (length(s) in [2,3])) then + exit; + for i:=low(extraregs) to high(extraregs) do + begin +@@ -241,7 +273,9 @@ Unit raarmgas; + do_error; + oper.opr.ref.shiftimm := shift; + test_end(require_rbracket); +- end; ++ end ++ else ++ test_end(require_rbracket); + end + else + begin +@@ -528,7 +562,7 @@ Unit raarmgas; + else if (actasmpattern='ROR') then + handlepara(SM_ROR) + else if (actasmpattern='RRX') then +- handlepara(SM_ROR) ++ handlepara(SM_RRX) + else + result:=false; + end +@@ -785,6 +819,18 @@ Unit raarmgas; + end; + + ++ function getregsetindex(reg: tregister): integer; ++ begin ++ if getsubreg(reg)=R_SUBFS then ++ begin ++ result:=getsupreg(reg)*2; ++ if result>32 then ++ result:=result-63; ++ end ++ else ++ result:=getsupreg(reg); ++ end; ++ + var + tempreg : tregister; + ireg : tsuperregister; +@@ -958,7 +1004,7 @@ Unit raarmgas; + oper.opr.typ:=OPR_REGISTER; + oper.opr.reg:=tempreg; + end +- else if (actasmtoken=AS_NOT) and (actopcode in [A_LDM,A_STM,A_FLDM,A_FSTM]) then ++ else if (actasmtoken=AS_NOT) and (actopcode in [A_LDM,A_STM,A_FLDM,A_FSTM,A_VLDM,A_VSTM]) then + begin + consume(AS_NOT); + oper.opr.typ:=OPR_REFERENCE; +@@ -976,11 +1022,11 @@ Unit raarmgas; + registerset:=[]; + regtype:=R_INVALIDREGISTER; + subreg:=R_SUBNONE; +- while true do ++ while actasmtoken<>AS_RSBRACKET do + begin + if actasmtoken=AS_REGISTER then + begin +- include(registerset,getsupreg(actasmregister)); ++ include(registerset,getregsetindex(actasmregister)); + if regtype<>R_INVALIDREGISTER then + begin + if (getregtype(actasmregister)<>regtype) or +@@ -997,7 +1043,7 @@ Unit raarmgas; + if actasmtoken=AS_MINUS then + begin + consume(AS_MINUS); +- for ireg:=getsupreg(tempreg) to getsupreg(actasmregister) do ++ for ireg:=getregsetindex(tempreg) to getregsetindex(actasmregister) do + include(registerset,ireg); + consume(AS_REGISTER); + end; +@@ -1137,8 +1183,19 @@ Unit raarmgas; + case actasmtoken of + AS_COMMA: { Operand delimiter } + Begin +- if ((instr.opcode in [A_MOV, A_MVN, A_CMP, A_CMN, A_TST, A_TEQ]) and (operandnum=2)) or +- ((operandnum=3) and not(instr.opcode in [A_UMLAL,A_UMULL,A_SMLAL,A_SMULL,A_MLA,A_MRC,A_MCR,A_MCRR,A_MRRC])) then ++ if ((instr.opcode in [A_MOV,A_MVN,A_CMP,A_CMN,A_TST,A_TEQ, ++ A_UXTB,A_UXTH,A_UXTB16, ++ A_SXTB,A_SXTH,A_SXTB16]) and ++ (operandnum=2)) or ++ ((operandnum=3) and not(instr.opcode in [A_UMLAL,A_UMULL,A_SMLAL,A_SMULL,A_MLA,A_UMAAL,A_MLS, ++ A_SMLABB,A_SMLABT,A_SMLATB,A_SMLATT,A_SMMLA,A_SMMLS,A_SMLAD,A_SMLALD,A_SMLSD, ++ A_SMLALBB,A_SMLALBT,A_SMLALTB,A_SMLALTT,A_SMLSLD, ++ A_SMLAWB,A_SMLAWT, ++ A_MRC,A_MCR,A_MCRR,A_MRRC,A_MRC2,A_MCR2,A_MCRR2,A_MRRC2, ++ A_STREXD,A_STRD, ++ A_USADA8, ++ A_VMOV, ++ A_SBFX,A_UBFX,A_BFI])) then + begin + Consume(AS_COMMA); + if not(TryBuildShifterOp(instr.Operands[operandnum+1] as tarmoperand)) then +@@ -1160,7 +1217,8 @@ Unit raarmgas; + break; + end; + else +- if (instr.opcode = A_MSR) and (operandnum = 1) then ++ if ((instr.opcode = A_MRS) and (operandnum = 2)) or ++ ((instr.opcode = A_MSR) and (operandnum = 1)) then + BuildSpecialreg(instr.Operands[operandnum] as tarmoperand) + else + BuildOperand(instr.Operands[operandnum] as tarmoperand); +@@ -1174,25 +1232,34 @@ Unit raarmgas; + + const + { sorted by length so longer postfixes will match first } +- postfix2strsorted : array[1..31] of string[3] = ( +- 'IAD','DBD','FDD','EAD', +- 'IAS','DBS','FDS','EAS', +- 'IAX','DBX','FDX','EAX', +- 'EP','SB','BT','SH', +- 'IA','IB','DA','DB','FD','FA','ED','EA', +- 'B','D','E','P','T','H','S'); +- +- postfixsorted : array[1..31] of TOpPostfix = ( +- PF_IAD,PF_DBD,PF_FDD,PF_EAD, +- PF_IAS,PF_DBS,PF_FDS,PF_EAS, +- PF_IAX,PF_DBX,PF_FDX,PF_EAX, +- PF_EP,PF_SB,PF_BT,PF_SH, +- PF_IA,PF_IB,PF_DA,PF_DB,PF_FD,PF_FA,PF_ED,PF_EA, +- PF_B,PF_D,PF_E,PF_P,PF_T,PF_H,PF_S); ++ postfix2strsorted : array[1..70] of string[9] = ( ++ '.F32.S32','.F32.U32','.S32.F32','.U32.F32','.F64.S32','.F64.U32','.S32.F64','.U32.F64', ++ '.F32.S16','.F32.U16','.S16.F32','.U16.F32','.F64.S16','.F64.U16','.S16.F64','.U16.F64', ++ '.F32.F64','.F64.F32', ++ '.I16','.I32','.I64','.S16','.S32','.S64','.U16','.U32','.U64','.F32','.F64', ++ 'IAD','DBD','FDD','EAD','IAS','DBS','FDS','EAS','IAX','DBX','FDX','EAX', ++ '.16','.32','.64','.I8','.S8','.U8','.P8', ++ 'EP','SB','BT','SH','IA','IB','DA','DB','FD','FA','ED','EA', ++ '.8','S','D','E','P','X','R','B','H','T'); ++ ++ postfixsorted : array[1..70] of TOpPostfix = ( ++ PF_F32S32,PF_F32U32,PF_S32F32,PF_U32F32,PF_F64S32,PF_F64U32,PF_S32F64,PF_U32F64, ++ PF_F32S16,PF_F32U16,PF_S16F32,PF_U16F32,PF_F64S16,PF_F64U16,PF_S16F64,PF_U16F64, ++ PF_F32F64,PF_F64F32, ++ PF_I16,PF_I32, ++ PF_I64,PF_S16,PF_S32,PF_S64,PF_U16,PF_U32,PF_U64,PF_F32, ++ PF_F64,PF_IAD,PF_DBD,PF_FDD,PF_EAD, ++ PF_IAS,PF_DBS,PF_FDS,PF_EAS,PF_IAX, ++ PF_DBX,PF_FDX,PF_EAX,PF_16,PF_32, ++ PF_64,PF_I8,PF_S8,PF_U8,PF_P8, ++ PF_EP,PF_SB,PF_BT,PF_SH,PF_IA, ++ PF_IB,PF_DA,PF_DB,PF_FD,PF_FA, ++ PF_ED,PF_EA,PF_8,PF_S,PF_D,PF_E, ++ PF_P,PF_X,PF_R,PF_B,PF_H,PF_T); + + var +- j : longint; +- hs : string; ++ j, j2 : longint; ++ hs,hs2 : string; + maxlen : longint; + icond : tasmcond; + Begin +@@ -1220,61 +1287,126 @@ Unit raarmgas; + end; + end; + end; +- maxlen:=max(length(hs),5); ++ maxlen:=min(length(hs),6); + actopcode:=A_NONE; +- for j:=maxlen downto 1 do ++ j2:=maxlen; ++ hs2:=hs; ++ while j2>=1 do + begin +- actopcode:=tasmop(PtrUInt(iasmops.Find(copy(hs,1,j)))); +- if actopcode<>A_NONE then ++ hs:=hs2; ++ while j2>=1 do + begin +- actasmtoken:=AS_OPCODE; +- { strip op code } +- delete(hs,1,j); +- break; ++ actopcode:=tasmop(PtrUInt(iasmops.Find(copy(hs,1,j2)))); ++ if actopcode<>A_NONE then ++ begin ++ actasmtoken:=AS_OPCODE; ++ { strip op code } ++ delete(hs,1,j2); ++ dec(j2); ++ break; ++ end; ++ dec(j2); + end; +- end; +- if actopcode=A_NONE then +- exit; + +- { search for condition, conditions are always 2 chars } +- if length(hs)>1 then +- begin +- for icond:=low(tasmcond) to high(tasmcond) do ++ if actopcode=A_NONE then ++ exit; ++ ++ if is_unified then + begin +- if copy(hs,1,2)=uppercond2str[icond] then ++ { check for postfix } ++ if (length(hs)>0) and (actoppostfix=PF_None) then + begin +- actcondition:=icond; +- { strip condition } +- delete(hs,1,2); +- break; ++ for j:=low(postfixsorted) to high(postfixsorted) do ++ begin ++ if copy(hs,1,length(postfix2strsorted[j]))=postfix2strsorted[j] then ++ begin ++ if not ((length(hs)-length(postfix2strsorted[j])) in [0,2,4]) then ++ continue; ++ ++ actoppostfix:=postfixsorted[j]; ++ { strip postfix } ++ delete(hs,1,length(postfix2strsorted[j])); ++ break; ++ end; ++ end; + end; +- end; +- end; +- { check for postfix } +- if length(hs)>0 then +- begin +- for j:=low(postfixsorted) to high(postfixsorted) do ++ { search for condition, conditions are always 2 chars } ++ if length(hs)>1 then ++ begin ++ for icond:=low(tasmcond) to high(tasmcond) do ++ begin ++ if copy(hs,1,2)=uppercond2str[icond] then ++ begin ++ actcondition:=icond; ++ { strip condition } ++ delete(hs,1,2); ++ break; ++ end; ++ end; ++ end; ++ { check for postfix } ++ if (length(hs)>0) and (actoppostfix=PF_None) then ++ begin ++ for j:=low(postfixsorted) to high(postfixsorted) do ++ begin ++ if copy(hs,1,length(postfix2strsorted[j]))=postfix2strsorted[j] then ++ begin ++ if not ((length(hs)-length(postfix2strsorted[j])) = 0) then ++ continue; ++ ++ actoppostfix:=postfixsorted[j]; ++ { strip postfix } ++ delete(hs,1,length(postfix2strsorted[j])); ++ break; ++ end; ++ end; ++ end; ++ end ++ else + begin +- if copy(hs,1,length(postfix2strsorted[j]))=postfix2strsorted[j] then ++ { search for condition, conditions are always 2 chars } ++ if length(hs)>1 then + begin +- actoppostfix:=postfixsorted[j]; +- { strip postfix } +- delete(hs,1,length(postfix2strsorted[j])); +- break; ++ for icond:=low(tasmcond) to high(tasmcond) do ++ begin ++ if copy(hs,1,2)=uppercond2str[icond] then ++ begin ++ actcondition:=icond; ++ { strip condition } ++ delete(hs,1,2); ++ break; ++ end; ++ end; ++ end; ++ { check for postfix } ++ if (length(hs)>0) and (actoppostfix=PF_None) then ++ begin ++ for j:=low(postfixsorted) to high(postfixsorted) do ++ begin ++ if copy(hs,1,length(postfix2strsorted[j]))=postfix2strsorted[j] then ++ begin ++ actoppostfix:=postfixsorted[j]; ++ { strip postfix } ++ delete(hs,1,length(postfix2strsorted[j])); ++ break; ++ end; ++ end; + end; + end; +- end; +- { check for format postfix } +- if length(hs)>0 then +- begin +- if upcase(copy(hs,1,2)) = '.W' then ++ { check for format postfix } ++ if length(hs)>0 then + begin +- actwideformat:=true; +- delete(hs,1,2); ++ if copy(hs,1,2) = '.W' then ++ begin ++ actwideformat:=true; ++ delete(hs,1,2); ++ end; + end; ++ { if we stripped all postfixes, it's a valid opcode } ++ is_asmopcode:=length(hs)=0; ++ if is_asmopcode = true then ++ break; + end; +- { if we stripped all postfixes, it's a valid opcode } +- is_asmopcode:=length(hs)=0; + end; + + +@@ -1313,12 +1445,17 @@ Unit raarmgas; + else if actasmpattern='.thumb_func' then + begin + consume(AS_TARGET_DIRECTIVE); +- curList.concat(tai_thumb_func.create); ++ curList.concat(tai_directive.create(asd_thumb_func,'')); + end + else + inherited HandleTargetDirective; + end; + ++ function tarmattreader.is_unified: boolean; ++ begin ++ result:=false; ++ end; ++ + + procedure tarmattreader.handleopcode; + var +@@ -1348,10 +1485,17 @@ const + asmmode_arm_att_info : tasmmodeinfo = + ( + id : asmmode_arm_gas; +- idtxt : 'GAS'; ++ idtxt : 'DIVIDED'; + casmreader : tarmattreader; + ); + ++ asmmode_arm_att_unified_info : tasmmodeinfo = ++ ( ++ id : asmmode_arm_gas_unified; ++ idtxt : 'UNIFIED'; ++ casmreader : tarmunifiedattreader; ++ ); ++ + asmmode_arm_standard_info : tasmmodeinfo = + ( + id : asmmode_standard; +@@ -1361,5 +1505,6 @@ const + + initialization + RegisterAsmMode(asmmode_arm_att_info); ++ RegisterAsmMode(asmmode_arm_att_unified_info); + RegisterAsmMode(asmmode_arm_standard_info); + end. +Index: fpc/fpcsrc/compiler/arm/rarmcon.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/rarmcon.inc ++++ fpc/fpcsrc/compiler/arm/rarmcon.inc +@@ -123,3 +123,10 @@ NR_BASEPRI = tregister($0500001F); + NR_BASEPRI_MAX = tregister($05000020); + NR_FAULTMASK = tregister($05000021); + NR_CONTROL = tregister($05000022); ++NR_FPSID = tregister($05000023); ++NR_MVFR1 = tregister($05000024); ++NR_MVFR0 = tregister($05000025); ++NR_FPEXC = tregister($05000026); ++NR_APSR_nzcvq = tregister($05000027); ++NR_APSR_g = tregister($05000028); ++NR_APSR_nzcvqg = tregister($05000029); +Index: fpc/fpcsrc/compiler/arm/rarmdwa.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/rarmdwa.inc ++++ fpc/fpcsrc/compiler/arm/rarmdwa.inc +@@ -122,4 +122,11 @@ + 0, + 0, + 0, ++0, ++0, ++0, ++0, ++0, ++0, ++0, + 0 +Index: fpc/fpcsrc/compiler/arm/rarmnor.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/rarmnor.inc ++++ fpc/fpcsrc/compiler/arm/rarmnor.inc +@@ -1,2 +1,2 @@ + { don't edit, this file is generated from armreg.dat } +-124 ++131 +Index: fpc/fpcsrc/compiler/arm/rarmnum.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/rarmnum.inc ++++ fpc/fpcsrc/compiler/arm/rarmnum.inc +@@ -122,4 +122,11 @@ tregister($0500001E), + tregister($0500001F), + tregister($05000020), + tregister($05000021), +-tregister($05000022) ++tregister($05000022), ++tregister($05000023), ++tregister($05000024), ++tregister($05000025), ++tregister($05000026), ++tregister($05000027), ++tregister($05000028), ++tregister($05000029) +Index: fpc/fpcsrc/compiler/arm/rarmrni.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/rarmrni.inc ++++ fpc/fpcsrc/compiler/arm/rarmrni.inc +@@ -122,4 +122,11 @@ + 120, + 121, + 122, +-123 ++123, ++124, ++125, ++126, ++127, ++128, ++129, ++130 +Index: fpc/fpcsrc/compiler/arm/rarmsri.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/rarmsri.inc ++++ fpc/fpcsrc/compiler/arm/rarmsri.inc +@@ -1,7 +1,10 @@ + { don't edit, this file is generated from armreg.dat } + 0, + 110, ++129, + 92, ++128, ++130, + 120, + 121, + 123, +@@ -65,11 +68,15 @@ + 23, + 24, + 122, ++127, + 90, ++124, + 114, + 113, + 111, + 117, ++126, ++125, + 109, + 119, + 118, +@@ -104,7 +111,6 @@ + 53, + 28, + 55, +-71, + 56, + 58, + 59, +@@ -116,6 +122,7 @@ + 68, + 29, + 70, ++71, + 31, + 32, + 34, +Index: fpc/fpcsrc/compiler/arm/rarmsta.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/rarmsta.inc ++++ fpc/fpcsrc/compiler/arm/rarmsta.inc +@@ -122,4 +122,11 @@ + 0, + 0, + 0, ++0, ++0, ++0, ++0, ++0, ++0, ++0, + 0 +Index: fpc/fpcsrc/compiler/arm/rarmstd.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/rarmstd.inc ++++ fpc/fpcsrc/compiler/arm/rarmstd.inc +@@ -70,7 +70,7 @@ + 's29', + 'd14', + 's30', +-'s21', ++'s31', + 'd15', + 'd16', + 'd17', +@@ -122,4 +122,11 @@ + 'basepri', + 'basepri_max', + 'faultmask', +-'control' ++'control', ++'fpsid', ++'mvfr1', ++'mvfr0', ++'fpexc', ++'apsr_nzcvq', ++'apsr_g', ++'apsr_nzcvqg' +Index: fpc/fpcsrc/compiler/arm/rarmsup.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/arm/rarmsup.inc ++++ fpc/fpcsrc/compiler/arm/rarmsup.inc +@@ -123,3 +123,10 @@ RS_BASEPRI = $1F; + RS_BASEPRI_MAX = $20; + RS_FAULTMASK = $21; + RS_CONTROL = $22; ++RS_FPSID = $23; ++RS_MVFR1 = $24; ++RS_MVFR0 = $25; ++RS_FPEXC = $26; ++RS_APSR_nzcvq = $27; ++RS_APSR_g = $28; ++RS_APSR_nzcvqg = $29; +Index: fpc/fpcsrc/compiler/assemble.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/assemble.pas ++++ fpc/fpcsrc/compiler/assemble.pas +@@ -83,6 +83,7 @@ interface + lastsectype : TAsmSectionType; + procedure WriteSourceLine(hp: tailineinfo); + procedure WriteTempalloc(hp: tai_tempalloc); ++ Function DoPipe:boolean; + public + {# Returns the complete path and executable name of the assembler + program. +@@ -271,7 +272,7 @@ Implementation + TExternalAssembler + *****************************************************************************} + +- Function DoPipe:boolean; ++ Function TExternalAssembler.DoPipe:boolean; + begin + DoPipe:=(cs_asm_pipe in current_settings.globalswitches) and + (([cs_asm_extern,cs_asm_leave,cs_link_on_target] * current_settings.globalswitches) = []) and +@@ -1224,6 +1225,10 @@ Implementation + asd_reference: + { ignore for now, but should be added} + ; ++{$ifdef ARM} ++ asd_thumb_func: ++ ObjData.ThumbFunc:=true; ++{$endif ARM} + else + internalerror(2010011101); + end; +@@ -1368,6 +1373,9 @@ Implementation + asd_reference: + { ignore for now, but should be added} + ; ++ asd_thumb_func: ++ { ignore for now, but should be added} ++ ; + else + internalerror(2010011102); + end; +@@ -1391,6 +1399,7 @@ Implementation + objsymend : TObjSymbol; + zerobuf : array[0..63] of byte; + relative_reloc: boolean; ++ tmp : word; + begin + fillchar(zerobuf,sizeof(zerobuf),0); + fillchar(objsym,sizeof(objsym),0); +@@ -1514,6 +1523,11 @@ Implementation + aitconst_darwin_dwarf_delta32, + aitconst_darwin_dwarf_delta64: + ObjData.writebytes(Tai_const(hp).value,tai_const(hp).size); ++ aitconst_half16bit: ++ begin ++ tmp:=Tai_const(hp).value div 2; ++ ObjData.writebytes(tmp,2); ++ end + else + internalerror(200603254); + end; +Index: fpc/fpcsrc/compiler/cgbase.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/cgbase.pas ++++ fpc/fpcsrc/compiler/cgbase.pas +@@ -101,6 +101,12 @@ interface + ,addr_dgroup // the data segment group + ,addr_seg // used for getting the segment of an object, e.g. 'mov ax, SEG symbol' + {$ENDIF} ++ {$IFDEF AARCH64} ++ ,addr_page ++ ,addr_pageoffset ++ ,addr_gotpage ++ ,addr_gotpageoffset ++ {$ENDIF AARCH64} + ); + + +@@ -329,6 +335,13 @@ interface + OS_M8,OS_M16,OS_M32,OS_M64,OS_M128,OS_M256,OS_M8,OS_M16,OS_M32, + OS_M64,OS_M128,OS_M256); + ++ tcgsize2signed : array[tcgsize] of tcgsize = (OS_NO, ++ OS_S8,OS_S16,OS_S32,OS_S64,OS_S128,OS_S8,OS_S16,OS_S32,OS_S64,OS_S128, ++ OS_F32,OS_F64,OS_F80,OS_C64,OS_F128, ++ OS_M8,OS_M16,OS_M32,OS_M64,OS_M128,OS_M256,OS_M8,OS_M16,OS_M32, ++ OS_M64,OS_M128,OS_M256); ++ ++ + tcgloc2str : array[TCGLoc] of string[12] = ( + 'LOC_INVALID', + 'LOC_VOID', +Index: fpc/fpcsrc/compiler/cghlcpu.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/cghlcpu.pas ++++ fpc/fpcsrc/compiler/cghlcpu.pas +@@ -65,14 +65,14 @@ uses + procedure a_cmp_reg_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel); override; + procedure a_call_reg(list: TAsmList; reg: tregister); override; + procedure a_call_name(list: TAsmList; const s: string; weak: boolean); override; +- procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: tcgsize; src, dst: TRegister); override; ++ procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tcgsize; src, dst: TRegister); override; + end; + + implementation + + { thlbasecgcpu } + +- procedure thlbasecgcpu.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: tcgsize; src, dst: TRegister); ++ procedure thlbasecgcpu.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tcgsize; src, dst: TRegister); + begin + internalerror(2012042801); + end; +Index: fpc/fpcsrc/compiler/cgobj.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/cgobj.pas ++++ fpc/fpcsrc/compiler/cgobj.pas +@@ -247,7 +247,7 @@ unit cgobj; + procedure a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);virtual; abstract; + + { bit scan instructions } +- procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: tcgsize; src, dst: TRegister); virtual; ++ procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tcgsize; src, dst: TRegister); virtual; + + { Multiplication with doubling result size. + dstlo or dsthi may be NR_NO, in which case corresponding half of result is discarded. } +@@ -865,7 +865,14 @@ implementation + ref : treference; + tmpreg : tregister; + begin +- cgpara.check_simple_location; ++ if assigned(cgpara.location^.next) then ++ begin ++ tg.gethltemp(list,cgpara.def,cgpara.def.size,tt_persistent,ref); ++ a_load_reg_ref(list,size,size,r,ref); ++ a_load_ref_cgpara(list,size,ref,cgpara); ++ tg.ungettemp(list,ref); ++ exit; ++ end; + paramanager.alloccgpara(list,cgpara); + if cgpara.location^.shiftval<0 then + begin +@@ -2525,7 +2532,7 @@ implementation + end; + + +- procedure tcg.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: tcgsize; src, dst: TRegister); ++ procedure tcg.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tcgsize; src, dst: TRegister); + begin + internalerror(2014070601); + end; +Index: fpc/fpcsrc/compiler/cgutils.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/cgutils.pas ++++ fpc/fpcsrc/compiler/cgutils.pas +@@ -63,6 +63,12 @@ unit cgutils; + addressmode : taddressmode; + shiftmode : tshiftmode; + {$endif arm} ++{$ifdef aarch64} ++ symboldata : tlinkedlistitem; ++ shiftimm : byte; ++ addressmode : taddressmode; ++ shiftmode : tshiftmode; ++{$endif aarch64} + {$ifdef avr} + addressmode : taddressmode; + {$endif avr} +Index: fpc/fpcsrc/compiler/fpcdefs.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/fpcdefs.inc ++++ fpc/fpcsrc/compiler/fpcdefs.inc +@@ -242,6 +242,7 @@ + {$define cpurox} + {$define cputargethasfixedstack} + {$define cpurefshaveindexreg} ++ {$define SUPPORT_GET_FRAME} + {$endif aarch64} + + {$IFDEF MACOS} +Index: fpc/fpcsrc/compiler/hlcg2ll.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/hlcg2ll.pas ++++ fpc/fpcsrc/compiler/hlcg2ll.pas +@@ -171,7 +171,7 @@ unit hlcg2ll; + procedure a_loadaddr_ref_reg(list : TAsmList;fromsize, tosize : tdef;const ref : treference;r : tregister);override; + + { bit scan instructions } +- procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: tdef; src, dst: tregister); override; ++ procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tdef; src, dst: tregister); override; + + { fpu move instructions } + procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tdef; reg1, reg2: tregister); override; +@@ -586,9 +586,9 @@ implementation + cg.a_loadaddr_ref_reg(list,ref,r); + end; + +- procedure thlcg2ll.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: tdef; src, dst: tregister); ++ procedure thlcg2ll.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tdef; src, dst: tregister); + begin +- cg.a_bit_scan_reg_reg(list,reverse,def_cgsize(size),src,dst); ++ cg.a_bit_scan_reg_reg(list,reverse,def_cgsize(srcsize),def_cgsize(dstsize),src,dst); + end; + + procedure thlcg2ll.a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tdef; reg1, reg2: tregister); +Index: fpc/fpcsrc/compiler/hlcgobj.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/hlcgobj.pas ++++ fpc/fpcsrc/compiler/hlcgobj.pas +@@ -301,7 +301,7 @@ unit hlcgobj; + public + + { bit scan instructions (still need transformation to thlcgobj) } +- procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: tdef; src, dst: tregister); virtual; abstract; ++ procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tdef; src, dst: tregister); virtual; abstract; + + { fpu move instructions } + procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tdef; reg1, reg2: tregister); virtual; abstract; +@@ -536,9 +536,9 @@ unit hlcgobj; + public + + procedure gen_load_para_value(list:TAsmList);virtual; +- protected + { helpers called by gen_load_para_value } + procedure g_copyvalueparas(p:TObject;arg:pointer);virtual; ++ protected + procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation;const cgpara: tcgpara;locintsize: longint);virtual; + procedure init_paras(p:TObject;arg:pointer); + protected +@@ -4140,7 +4140,7 @@ implementation + begin + {$ifdef arm} + if GenerateThumbCode or GenerateThumb2Code then +- list.concat(tai_thumb_func.create); ++ list.concat(tai_directive.create(asd_thumb_func,'')); + {$endif arm} + { "double link" all procedure entry symbols via .reference } + { directives on darwin, because otherwise the linker } +@@ -4523,7 +4523,11 @@ implementation + if (tparavarsym(p).varspez=vs_value) then + begin + include(current_procinfo.flags,pi_needs_implicit_finally); +- location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).localloc,href,is_open_array(tparavarsym(p).vardef),sizeof(pint)); ++ location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).localloc,href, ++ is_open_array(tparavarsym(p).vardef) or ++ ((target_info.system in systems_caller_copy_addr_value_para) and ++ paramanager.push_addr_param(vs_value,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption)), ++ sizeof(pint)); + if is_open_array(tparavarsym(p).vardef) then + begin + if paramanager.push_high_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption) then +@@ -4543,7 +4547,8 @@ implementation + end; + end; + { open arrays can contain elements requiring init/final code, so the else has been removed here } +- if (tparavarsym(p).varspez=vs_value) and ++ if not(target_info.system in systems_caller_copy_addr_value_para) and ++ (tparavarsym(p).varspez=vs_value) and + (is_open_array(tparavarsym(p).vardef) or + is_array_of_const(tparavarsym(p).vardef)) then + begin +@@ -4581,7 +4586,11 @@ implementation + if not((tparavarsym(p).vardef.typ=variantdef) and + paramanager.push_addr_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption)) then + begin +- location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,is_open_array(tparavarsym(p).vardef),sizeof(pint)); ++ location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href, ++ is_open_array(tparavarsym(p).vardef) or ++ ((target_info.system in systems_caller_copy_addr_value_para) and ++ paramanager.push_addr_param(vs_value,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption)), ++ sizeof(pint)); + if is_open_array(tparavarsym(p).vardef) then + begin + if paramanager.push_high_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption) then +@@ -4682,8 +4691,11 @@ implementation + begin + list:=TAsmList(arg); + if (tsym(p).typ=paravarsym) and +- (tparavarsym(p).varspez=vs_value) and +- (paramanager.push_addr_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption)) then ++ ((vo_has_local_copy in tparavarsym(p).varoptions) or ++ (not(target_info.system in systems_caller_copy_addr_value_para) and ++ (is_open_array(tparavarsym(p).vardef) or ++ is_array_of_const(tparavarsym(p).vardef)) and ++ (tparavarsym(p).varspez=vs_value))) then + begin + { we have no idea about the alignment at the caller side } + location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,true,1); +Index: fpc/fpcsrc/compiler/i386/cpuelf.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/i386/cpuelf.pas ++++ fpc/fpcsrc/compiler/i386/cpuelf.pas +@@ -496,6 +496,7 @@ implementation + encodereloc: @elf_i386_encodeReloc; + loadreloc: @elf_i386_loadReloc; + loadsection: nil; ++ encodeflags: nil; + ); + + as_i386_elf32_info : tasminfo = +Index: fpc/fpcsrc/compiler/i8086/n8086mem.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/i8086/n8086mem.pas ++++ fpc/fpcsrc/compiler/i8086/n8086mem.pas +@@ -27,6 +27,7 @@ interface + + uses + globtype, ++ symtype, + cgbase,cpuinfo,cpubase, + node,nmem,ncgmem,nx86mem,ni86mem; + +@@ -45,7 +46,7 @@ interface + ti8086vecnode = class(tcgvecnode) + protected + function first_arraydef: tnode;override; +- procedure update_reference_reg_mul(maybe_const_reg:tregister;l:aint);override; ++ procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint);override; + end; + + implementation +@@ -53,7 +54,7 @@ implementation + uses + systems,globals,constexp, + cutils,verbose, +- symbase,symconst,symdef,symtable,symtype,symsym,symx86,symcpu, ++ symbase,symconst,symdef,symtable,symsym,symx86,symcpu, + parabase,paramgr, + aasmtai,aasmdata, + nld,ncon,nadd,ncal,ncnv, +@@ -212,13 +213,13 @@ implementation + end; + + +- procedure ti8086vecnode.update_reference_reg_mul(maybe_const_reg:tregister;l:aint); ++ procedure ti8086vecnode.update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); + var + saveseg: TRegister; + begin + saveseg:=location.reference.segment; + location.reference.segment:=NR_NO; +- inherited update_reference_reg_mul(maybe_const_reg,l); ++ inherited; + location.reference.segment:=saveseg; + end; + +Index: fpc/fpcsrc/compiler/jvm/hlcgcpu.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/jvm/hlcgcpu.pas ++++ fpc/fpcsrc/compiler/jvm/hlcgcpu.pas +@@ -114,7 +114,7 @@ uses + procedure gen_exit_code(list: TAsmList); override; + + { unimplemented/unnecessary routines } +- procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: tdef; src, dst: tregister); override; ++ procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tdef; src, dst: tregister); override; + procedure a_loadmm_loc_reg(list: TAsmList; fromsize, tosize: tdef; const loc: tlocation; const reg: tregister; shuffle: pmmshuffle); override; + procedure a_loadmm_reg_reg(list: TAsmList; fromsize, tosize: tdef; reg1, reg2: tregister; shuffle: pmmshuffle); override; + procedure a_loadmm_ref_reg(list: TAsmList; fromsize, tosize: tdef; const ref: treference; reg: tregister; shuffle: pmmshuffle); override; +@@ -1884,7 +1884,7 @@ implementation + { nothing } + end; + +- procedure thlcgjvm.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: tdef; src, dst: tregister); ++ procedure thlcgjvm.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tdef; src, dst: tregister); + begin + internalerror(2012090201); + end; +Index: fpc/fpcsrc/compiler/m68k/n68kmem.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/m68k/n68kmem.pas ++++ fpc/fpcsrc/compiler/m68k/n68kmem.pas +@@ -27,12 +27,13 @@ interface + + uses + globtype, ++ symtype, + cgbase,cpuinfo,cpubase, + node,nmem,ncgmem; + + type + t68kvecnode = class(tcgvecnode) +- procedure update_reference_reg_mul(maybe_const_reg:tregister;l:aint);override; ++ procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); override; + //procedure pass_generate_code;override; + end; + +@@ -59,7 +60,7 @@ implementation + { the live range of the LOC_CREGISTER will most likely overlap the } + { the live range of the target LOC_(C)REGISTER) } + { The passed register may be a LOC_CREGISTER as well. } +- procedure t68kvecnode.update_reference_reg_mul(maybe_const_reg:tregister;l:aint); ++ procedure t68kvecnode.update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); + var + hreg: tregister; + scaled: boolean; +Index: fpc/fpcsrc/compiler/mips/cpuelf.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/mips/cpuelf.pas ++++ fpc/fpcsrc/compiler/mips/cpuelf.pas +@@ -1026,6 +1026,7 @@ implementation + encodereloc: @elf_mips_encodeReloc; + loadreloc: @elf_mips_loadReloc; + loadsection: @elf_mips_loadSection; ++ encodeflags: nil; + ); + + initialization +Index: fpc/fpcsrc/compiler/msg/errore.msg +=================================================================== +--- fpc.orig/fpcsrc/compiler/msg/errore.msg ++++ fpc/fpcsrc/compiler/msg/errore.msg +@@ -3443,6 +3443,7 @@ new features, etc.): + # 4 = x86_64 + # 6 = 680x0 targets + # 8 = 8086 (16-bit) targets ++# a = AArch64 + # A = ARM + # e = in extended debug mode only + # F = help for the 'fpc' binary (independent of the target compiler) +@@ -3713,6 +3714,7 @@ F*2P_Set target CPU (arm,avr,i386,jvm + 3*2Twince_Windows CE + 4*2Tdarwin_Darwin/Mac OS X + 4*2Tfreebsd_FreeBSD ++4*2Tiphonesim_ iPhoneSimulator + 4*2Tlinux_Linux + 4*2Tnetbsd_NetBSD + 4*2Topenbsd_OpenBSD +@@ -3723,6 +3725,7 @@ F*2P_Set target CPU (arm,avr,i386,jvm + 6*2Tlinux_Linux + 6*2Tpalmos_PalmOS + 8*2Tmsdos_MS-DOS (and compatible) ++a*2Tdarwin_Darwin/iOS + A*2Tandroid_Android + A*2Tdarwin_Darwin/iPhoneOS/iOS + A*2Tembedded_Embedded +@@ -3777,6 +3780,7 @@ A*2WA_Specify native type application (W + 3*2Wb_Create a bundle instead of a library (Darwin) + P*2Wb_Create a bundle instead of a library (Darwin) + p*2Wb_Create a bundle instead of a library (Darwin) ++a*2Wb_Create a bundle instead of a library (Darwin) + A*2Wb_Create a bundle instead of a library (Darwin) + 4*2Wb_Create a bundle instead of a library (Darwin) + 3*2WB_Create a relocatable image (Windows, Symbian) +@@ -3794,6 +3798,7 @@ P*2WC_Specify console type application ( + A*2WD_Use DEFFILE to export functions of DLL or EXE (Windows) + 3*2We_Use external resources (Darwin) + 4*2We_Use external resources (Darwin) ++a*2We_Use external resources (Darwin) + A*2We_Use external resources (Darwin) + P*2We_Use external resources (Darwin) + p*2We_Use external resources (Darwin) +@@ -3804,6 +3809,7 @@ A*2WG_Specify graphic type application ( + P*2WG_Specify graphic type application (Classic Mac OS) + 3*2Wi_Use internal resources (Darwin) + 4*2Wi_Use internal resources (Darwin) ++a*2Wi_Use internal resources (Darwin) + A*2Wi_Use internal resources (Darwin) + P*2Wi_Use internal resources (Darwin) + p*2Wi_Use internal resources (Darwin) +@@ -3827,6 +3833,8 @@ A*2Wpxxxx_Specify the controller type; s + m*2Wpxxxx_Specify the controller type; see fpc -i or fpc -iu for possible values + V*2Wpxxxx_Specify the controller type; see fpc -i or fpc -iu for possible values + 3*2WP_Minimum iOS deployment version: 3.0, 5.0.1, ... (iphonesim) ++4*2WP_Minimum iOS deployment version: 8.0, 8.0.2, ... (iphonesim) ++a*2WP_Minimum iOS deployment version: 7.0, 7.1.2, ... (Darwin) + A*2WP_Minimum iOS deployment version: 3.0, 5.0.1, ... (Darwin) + 3*2WR_Generate relocation code (Windows) + 4*2WR_Generate relocation code (Windows) +Index: fpc/fpcsrc/compiler/msgidx.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/msgidx.inc ++++ fpc/fpcsrc/compiler/msgidx.inc +@@ -1001,7 +1001,7 @@ const + option_info=11024; + option_help_pages=11025; + +- MsgTxtSize = 74662; ++ MsgTxtSize = 74840; + + MsgIdxMax : array[1..20] of longint=( + 26,99,339,123,96,57,126,27,202,64, +Index: fpc/fpcsrc/compiler/ncal.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ncal.pas ++++ fpc/fpcsrc/compiler/ncal.pas +@@ -200,6 +200,10 @@ interface + fparainit, + fparacopyback: tnode; + procedure handlemanagedbyrefpara(orgparadef: tdef);virtual;abstract; ++ { on some targets, value parameters that are passed by reference must ++ be copied to a temp location by the caller (and then a reference to ++ this temp location must be passed) } ++ procedure copy_value_by_ref_para; + public + callparaflags : tcallparaflags; + parasym : tparavarsym; +@@ -591,6 +595,208 @@ implementation + TCALLPARANODE + ****************************************************************************} + ++ procedure tcallparanode.copy_value_by_ref_para; ++ var ++ initstat, ++ copybackstat, ++ finistat: tstatementnode; ++ finiblock: tblocknode; ++ paratemp: ttempcreatenode; ++ arraysize, ++ arraybegin: tnode; ++ lefttemp: ttempcreatenode; ++ vardatatype, ++ temparraydef: tdef; ++ begin ++ { this routine is for targets where by-reference value parameters need ++ to be copied by the caller. It's basically the node-level equivalent ++ of thlcgobj.g_copyvalueparas } ++ ++ { in case of an array constructor, we don't need a copy since the array ++ constructor itself is already constructed on the fly (and hence if ++ it's modified by the caller, that's no problem) } ++ if not is_array_constructor(left.resultdef) then ++ begin ++ fparainit:=internalstatements(initstat); ++ fparacopyback:=internalstatements(copybackstat); ++ finiblock:=internalstatements(finistat); ++ paratemp:=nil; ++ ++ { making a copy of an open array, an array of const or a dynamic ++ array requires dynamic memory allocation since we don't know the ++ size at compile time } ++ if is_open_array(left.resultdef) or ++ is_array_of_const(left.resultdef) or ++ (is_dynamic_array(left.resultdef) and ++ is_open_array(parasym.vardef)) then ++ begin ++ paratemp:=ctempcreatenode.create(voidpointertype,voidpointertype.size,tt_persistent,true); ++ if is_dynamic_array(left.resultdef) then ++ begin ++ { note that in insert_typeconv, this dynamic array was ++ already converted into an open array (-> dereferenced) ++ and then its resultdef was restored to the original ++ dynamic array one -> get the address before treating it ++ as a dynamic array here } ++ { first restore the actual resultdef of left } ++ temparraydef:=left.resultdef; ++ left.resultdef:=parasym.vardef; ++ { get its address } ++ lefttemp:=ctempcreatenode.create(voidpointertype,voidpointertype.size,tt_persistent,true); ++ addstatement(initstat,lefttemp); ++ addstatement(finistat,ctempdeletenode.create(lefttemp)); ++ addstatement(initstat, ++ cassignmentnode.create( ++ ctemprefnode.create(lefttemp), ++ caddrnode.create_internal(left) ++ ) ++ ); ++ { restore the resultdef } ++ left.resultdef:=temparraydef; ++ { now treat that address (correctly) as the original ++ dynamic array to get its start and length } ++ arraybegin:=cvecnode.create( ++ ctypeconvnode.create_explicit(ctemprefnode.create(lefttemp), ++ left.resultdef), ++ genintconstnode(0) ++ ); ++ arraysize:=caddnode.create(muln, ++ geninlinenode(in_length_x,false, ++ ctypeconvnode.create_explicit(ctemprefnode.create(lefttemp), ++ left.resultdef) ++ ), ++ genintconstnode(tarraydef(left.resultdef).elementdef.size) ++ ); ++ end ++ else ++ begin ++ { no problem here that left is used multiple times, as ++ sizeof() will simply evaluate to the high parameter } ++ arraybegin:=left.getcopy; ++ arraysize:=geninlinenode(in_sizeof_x,false,left); ++ end; ++ addstatement(initstat,paratemp); ++ { paratemp:=getmem(sizeof(para)) } ++ addstatement(initstat, ++ cassignmentnode.create( ++ ctemprefnode.create(paratemp), ++ ccallnode.createintern('fpc_getmem', ++ ccallparanode.create( ++ arraysize.getcopy,nil ++ ) ++ ) ++ ) ++ ); ++ { move(para,temp,sizeof(arr)) (no "left.getcopy" below because ++ we replace left afterwards) } ++ addstatement(initstat, ++ ccallnode.createintern('MOVE', ++ ccallparanode.create( ++ arraysize, ++ ccallparanode.create( ++ cderefnode.create(ctemprefnode.create(paratemp)), ++ ccallparanode.create( ++ arraybegin,nil ++ ) ++ ) ++ ) ++ ) ++ ); ++ { no reference count increases, that's still done on the callee ++ side because for compatibility with targets that perform this ++ copy on the callee side, that should only be done for non- ++ assember functions (and we can't know that 100% certain here, ++ e.g. in case of external declarations) (*) } ++ ++ { free the memory again after the call: freemem(paratemp) } ++ addstatement(finistat, ++ ccallnode.createintern('fpc_freemem', ++ ccallparanode.create( ++ ctemprefnode.create(paratemp),nil ++ ) ++ ) ++ ); ++ { replace the original parameter with a dereference of the ++ temp typecasted to the same type as the original parameter ++ (don't free left, it has been reused above) } ++ left:=ctypeconvnode.create_internal( ++ cderefnode.create(ctemprefnode.create(paratemp)), ++ left.resultdef); ++ end ++ else if is_shortstring(parasym.vardef) then ++ begin ++ { the shortstring parameter may have a different size than the ++ parameter type -> assign and truncate/extend } ++ paratemp:=ctempcreatenode.create(parasym.vardef,parasym.vardef.size,tt_persistent,false); ++ addstatement(initstat,paratemp); ++ { assign shortstring } ++ addstatement(initstat, ++ cassignmentnode.create( ++ ctemprefnode.create(paratemp),left ++ ) ++ ); ++ { replace parameter with temp (don't free left, it has been ++ reused above) } ++ left:=ctemprefnode.create(paratemp); ++ end ++ else if parasym.vardef.typ=variantdef then ++ begin ++ vardatatype:=search_system_type('TVARDATA').typedef; ++ paratemp:=ctempcreatenode.create(vardatatype,vardatatype.size,tt_persistent,false); ++ addstatement(initstat,paratemp); ++ addstatement(initstat, ++ ccallnode.createintern('fpc_variant_copy_overwrite', ++ ccallparanode.create( ++ ctypeconvnode.create_explicit(ctemprefnode.create(paratemp), ++ vardatatype ++ ), ++ ccallparanode.create(ctypeconvnode.create_explicit(left, ++ vardatatype), ++ nil ++ ) ++ ) ++ ) ++ ); ++ { replace parameter with temp (don't free left, it has been ++ reused above) } ++ left:=ctypeconvnode.create_explicit(ctemprefnode.create(paratemp),parasym.vardef); ++ end ++ else if is_managed_type(left.resultdef) then ++ begin ++ { don't increase/decrease the reference count here, will be done by ++ the callee (see (*) above) -> typecast to array of byte ++ for the assignment to the temp } ++ temparraydef:=getarraydef(u8inttype,left.resultdef.size); ++ paratemp:=ctempcreatenode.create(temparraydef,temparraydef.size,tt_persistent,false); ++ addstatement(initstat,paratemp); ++ addstatement(initstat, ++ cassignmentnode.create( ++ ctemprefnode.create(paratemp), ++ ctypeconvnode.create_internal(left,temparraydef) ++ ) ++ ); ++ left:=ctypeconvnode.create_explicit(ctemprefnode.create(paratemp),left.resultdef); ++ end ++ else ++ begin ++ paratemp:=ctempcreatenode.create(left.resultdef,left.resultdef.size,tt_persistent,false); ++ addstatement(initstat,paratemp); ++ addstatement(initstat, ++ cassignmentnode.create(ctemprefnode.create(paratemp),left) ++ ); ++ { replace parameter with temp (don't free left, it has been ++ reused above) } ++ left:=ctemprefnode.create(paratemp); ++ end; ++ addstatement(finistat,ctempdeletenode.create(paratemp)); ++ addstatement(copybackstat,finiblock); ++ firstpass(fparainit); ++ firstpass(left); ++ firstpass(fparacopyback); ++ end; ++ end; ++ ++ + constructor tcallparanode.create(expr,next : tnode); + + begin +@@ -720,6 +926,7 @@ implementation + tcallparanode(right).firstcallparan; + if not assigned(left.resultdef) then + get_paratype; ++ + if assigned(parasym) and + (target_info.system in systems_managed_vm) and + (parasym.varspez in [vs_var,vs_out,vs_constref]) and +@@ -728,6 +935,27 @@ implementation + (left.nodetype<>nothingn) then + handlemanagedbyrefpara(left.resultdef); + ++ { for targets that have to copy "value parameters by reference" on the ++ caller side ++ ++ aktcallnode may not be assigned in case firstcallparan is called for ++ fake parameters to inline nodes (in that case, we don't have a real ++ call and hence no "caller side" either) ++ } ++ if assigned(aktcallnode) and ++ (target_info.system in systems_caller_copy_addr_value_para) and ++ ((assigned(parasym) and ++ (parasym.varspez=vs_value)) or ++ (cpf_varargs_para in callparaflags)) and ++ (left.nodetype<>nothingn) and ++ not(vo_has_local_copy in parasym.varoptions) and ++ ((not is_open_array(parasym.vardef) and ++ not is_array_of_const(parasym.vardef)) or ++ not(aktcallnode.procdefinition.proccalloption in cdecl_pocalls)) and ++ paramanager.push_addr_param(vs_value,parasym.vardef, ++ aktcallnode.procdefinition.proccalloption) then ++ copy_value_by_ref_para; ++ + { does it need to load RTTI? } + if assigned(parasym) and (parasym.varspez=vs_out) and + (cs_create_pic in current_settings.moduleswitches) and +@@ -2090,6 +2318,8 @@ implementation + + { A) set the appropriate objc_msgSend* variant to call } + ++ { The AArch64 abi does not require special handling for struct returns } ++{$ifndef aarch64} + { record returned via implicit pointer } + if paramanager.ret_in_param(resultdef,procdefinition) then + begin +@@ -2108,11 +2338,13 @@ implementation + else if (resultdef.typ=floatdef) and + not(cnf_inherited in callnodeflags) then + msgsendname:='OBJC_MSGSEND_FPRET' +-{$endif} ++{$endif i386} + { default } +- else if not(cnf_inherited in callnodeflags) then ++ else ++{$endif aarch64} ++ if not(cnf_inherited in callnodeflags) then + msgsendname:='OBJC_MSGSEND' +-{$if defined(onlymacosx10_6) or defined(arm) } ++{$if defined(onlymacosx10_6) or defined(arm) or defined(aarch64)} + else if (target_info.system in systems_objc_nfabi) then + msgsendname:='OBJC_MSGSENDSUPER2' + {$endif onlymacosx10_6 or arm} +@@ -2573,10 +2805,10 @@ implementation + if not assigned(right) then + begin + if assigned(procdefinition.owner.defowner) then +- para.left:=cloadparentfpnode.create(tprocdef(procdefinition.owner.defowner)) ++ para.left:=cloadparentfpnode.create(tprocdef(procdefinition.owner.defowner),lpf_forpara) + { exceptfilters called from main level are not owned } + else if procdefinition.proctypeoption=potype_exceptfilter then +- para.left:=cloadparentfpnode.create(current_procinfo.procdef) ++ para.left:=cloadparentfpnode.create(current_procinfo.procdef,lpf_forpara) + else + internalerror(200309287); + end +@@ -2870,8 +3102,6 @@ implementation + statements : tstatementnode; + converted_result_data : ttempcreatenode; + calltype: tdispcalltype; +- label +- errorexit; + begin + result:=nil; + candidates:=nil; +@@ -2879,460 +3109,462 @@ implementation + oldcallnode:=aktcallnode; + aktcallnode:=self; + +- { determine length of parameter list } +- pt:=tcallparanode(left); +- paralength:=0; +- while assigned(pt) do +- begin +- inc(paralength); +- pt:=tcallparanode(pt.right); +- end; +- +- { determine the type of the parameters } +- if assigned(left) then +- begin +- tcallparanode(left).get_paratype; +- if codegenerror then +- goto errorexit; +- end; +- +- if assigned(methodpointer) then +- typecheckpass(methodpointer); ++ try ++ { determine length of parameter list } ++ pt:=tcallparanode(left); ++ paralength:=0; ++ while assigned(pt) do ++ begin ++ inc(paralength); ++ pt:=tcallparanode(pt.right); ++ end; + +- { procedure variable ? } +- if assigned(right) then +- begin +- set_varstate(right,vs_read,[vsf_must_be_valid]); +- typecheckpass(right); ++ { determine the type of the parameters } ++ if assigned(left) then ++ begin ++ tcallparanode(left).get_paratype; + if codegenerror then +- exit; ++ exit; ++ end; + +- procdefinition:=tabstractprocdef(right.resultdef); ++ if assigned(methodpointer) then ++ typecheckpass(methodpointer); + +- { Compare parameters from right to left } +- paraidx:=procdefinition.Paras.count-1; +- { Skip default parameters } +- if not(po_varargs in procdefinition.procoptions) then +- begin +- { ignore hidden parameters } +- while (paraidx>=0) and (vo_is_hidden_para in tparavarsym(procdefinition.paras[paraidx]).varoptions) do +- dec(paraidx); +- for i:=1 to procdefinition.maxparacount-paralength do +- begin +- if paraidx<0 then +- internalerror(200402265); +- if not assigned(tparavarsym(procdefinition.paras[paraidx]).defaultconstsym) then +- begin +- CGMessage1(parser_e_wrong_parameter_size,''); +- goto errorexit; +- end; ++ { procedure variable ? } ++ if assigned(right) then ++ begin ++ set_varstate(right,vs_read,[vsf_must_be_valid]); ++ typecheckpass(right); ++ if codegenerror then ++ exit; ++ ++ procdefinition:=tabstractprocdef(right.resultdef); ++ ++ { Compare parameters from right to left } ++ paraidx:=procdefinition.Paras.count-1; ++ { Skip default parameters } ++ if not(po_varargs in procdefinition.procoptions) then ++ begin ++ { ignore hidden parameters } ++ while (paraidx>=0) and (vo_is_hidden_para in tparavarsym(procdefinition.paras[paraidx]).varoptions) do + dec(paraidx); +- end; +- end; +- while (paraidx>=0) and (vo_is_hidden_para in tparavarsym(procdefinition.paras[paraidx]).varoptions) do +- dec(paraidx); +- pt:=tcallparanode(left); +- lastpara:=paralength; +- while (paraidx>=0) and assigned(pt) do +- begin +- { only goto next para if we're out of the varargs } +- if not(po_varargs in procdefinition.procoptions) or +- (lastpara<=procdefinition.maxparacount) then +- begin +- repeat +- dec(paraidx); +- until (paraidx<0) or not(vo_is_hidden_para in tparavarsym(procdefinition.paras[paraidx]).varoptions); +- end; +- pt:=tcallparanode(pt.right); +- dec(lastpara); +- end; +- if assigned(pt) or +- ((paraidx>=0) and +- not assigned(tparavarsym(procdefinition.paras[paraidx]).defaultconstsym)) then +- begin +- if assigned(pt) then +- current_filepos:=pt.fileinfo; +- CGMessage1(parser_e_wrong_parameter_size,''); +- goto errorexit; +- end; +- end +- else +- { not a procedure variable } +- begin +- { do we know the procedure to call ? } +- if not(assigned(procdefinition)) then +- begin +- { ignore possible private for properties or in delphi mode for anon. inherited (FK) } +- ignorevisibility:=(nf_isproperty in flags) or +- ((m_delphi in current_settings.modeswitches) and (cnf_anon_inherited in callnodeflags)); +- candidates:=tcallcandidates.create(symtableprocentry,symtableproc,left,ignorevisibility, +- not(nf_isproperty in flags),cnf_objc_id_call in callnodeflags,cnf_unit_specified in callnodeflags, +- callnodeflags*[cnf_anon_inherited,cnf_inherited]=[],cnf_anon_inherited in callnodeflags); +- +- { no procedures found? then there is something wrong +- with the parameter size or the procedures are +- not accessible } +- if candidates.count=0 then +- begin +- { when it's an auto inherited call and there +- is no procedure found, but the procedures +- were defined with overload directive and at +- least two procedures are defined then we ignore +- this inherited by inserting a nothingn. Only +- do this ugly hack in Delphi mode as it looks more +- like a bug. It's also not documented } +- if (m_delphi in current_settings.modeswitches) and +- (cnf_anon_inherited in callnodeflags) and +- (symtableprocentry.owner.symtabletype=ObjectSymtable) and +- (po_overload in tprocdef(symtableprocentry.ProcdefList[0]).procoptions) and +- (symtableprocentry.ProcdefList.Count>=2) then +- result:=cnothingnode.create +- else +- begin +- { in tp mode we can try to convert to procvar if +- there are no parameters specified } +- if not(assigned(left)) and +- not(cnf_inherited in callnodeflags) and +- ((m_tp_procvar in current_settings.modeswitches) or +- (m_mac_procvar in current_settings.modeswitches)) and +- (not assigned(methodpointer) or +- (methodpointer.nodetype <> typen)) then +- begin +- hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc); +- if assigned(methodpointer) then +- tloadnode(hpt).set_mp(methodpointer.getcopy); +- typecheckpass(hpt); +- result:=hpt; +- end +- else +- begin +- CGMessagePos1(fileinfo,parser_e_wrong_parameter_size,symtableprocentry.realname); +- symtableprocentry.write_parameter_lists(nil); +- end; +- end; +- candidates.free; +- goto errorexit; +- end; ++ for i:=1 to procdefinition.maxparacount-paralength do ++ begin ++ if paraidx<0 then ++ internalerror(200402265); ++ if not assigned(tparavarsym(procdefinition.paras[paraidx]).defaultconstsym) then ++ begin ++ CGMessage1(parser_e_wrong_parameter_size,''); ++ exit; ++ end; ++ dec(paraidx); ++ end; ++ end; ++ while (paraidx>=0) and (vo_is_hidden_para in tparavarsym(procdefinition.paras[paraidx]).varoptions) do ++ dec(paraidx); ++ pt:=tcallparanode(left); ++ lastpara:=paralength; ++ while (paraidx>=0) and assigned(pt) do ++ begin ++ { only goto next para if we're out of the varargs } ++ if not(po_varargs in procdefinition.procoptions) or ++ (lastpara<=procdefinition.maxparacount) then ++ begin ++ repeat ++ dec(paraidx); ++ until (paraidx<0) or not(vo_is_hidden_para in tparavarsym(procdefinition.paras[paraidx]).varoptions); ++ end; ++ pt:=tcallparanode(pt.right); ++ dec(lastpara); ++ end; ++ if assigned(pt) or ++ ((paraidx>=0) and ++ not assigned(tparavarsym(procdefinition.paras[paraidx]).defaultconstsym)) then ++ begin ++ if assigned(pt) then ++ current_filepos:=pt.fileinfo; ++ CGMessage1(parser_e_wrong_parameter_size,''); ++ exit; ++ end; ++ end ++ else ++ { not a procedure variable } ++ begin ++ { do we know the procedure to call ? } ++ if not(assigned(procdefinition)) then ++ begin ++ { ignore possible private for properties or in delphi mode for anon. inherited (FK) } ++ ignorevisibility:=(nf_isproperty in flags) or ++ ((m_delphi in current_settings.modeswitches) and (cnf_anon_inherited in callnodeflags)); ++ candidates:=tcallcandidates.create(symtableprocentry,symtableproc,left,ignorevisibility, ++ not(nf_isproperty in flags),cnf_objc_id_call in callnodeflags,cnf_unit_specified in callnodeflags, ++ callnodeflags*[cnf_anon_inherited,cnf_inherited]=[],cnf_anon_inherited in callnodeflags); ++ ++ { no procedures found? then there is something wrong ++ with the parameter size or the procedures are ++ not accessible } ++ if candidates.count=0 then ++ begin ++ { when it's an auto inherited call and there ++ is no procedure found, but the procedures ++ were defined with overload directive and at ++ least two procedures are defined then we ignore ++ this inherited by inserting a nothingn. Only ++ do this ugly hack in Delphi mode as it looks more ++ like a bug. It's also not documented } ++ if (m_delphi in current_settings.modeswitches) and ++ (cnf_anon_inherited in callnodeflags) and ++ (symtableprocentry.owner.symtabletype=ObjectSymtable) and ++ (po_overload in tprocdef(symtableprocentry.ProcdefList[0]).procoptions) and ++ (symtableprocentry.ProcdefList.Count>=2) then ++ result:=cnothingnode.create ++ else ++ begin ++ { in tp mode we can try to convert to procvar if ++ there are no parameters specified } ++ if not(assigned(left)) and ++ not(cnf_inherited in callnodeflags) and ++ ((m_tp_procvar in current_settings.modeswitches) or ++ (m_mac_procvar in current_settings.modeswitches)) and ++ (not assigned(methodpointer) or ++ (methodpointer.nodetype <> typen)) then ++ begin ++ hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc); ++ if assigned(methodpointer) then ++ tloadnode(hpt).set_mp(methodpointer.getcopy); ++ typecheckpass(hpt); ++ result:=hpt; ++ end ++ else ++ begin ++ CGMessagePos1(fileinfo,parser_e_wrong_parameter_size,symtableprocentry.realname); ++ symtableprocentry.write_parameter_lists(nil); ++ end; ++ end; ++ candidates.free; ++ exit; ++ end; + +- { Retrieve information about the candidates } +- candidates.get_information; ++ { Retrieve information about the candidates } ++ candidates.get_information; + {$ifdef EXTDEBUG} +- { Display info when multiple candidates are found } +- if candidates.count>1 then +- candidates.dump_info(V_Debug); ++ { Display info when multiple candidates are found } ++ if candidates.count>1 then ++ candidates.dump_info(V_Debug); + {$endif EXTDEBUG} + +- { Choose the best candidate and count the number of +- candidates left } +- cand_cnt:=candidates.choose_best(procdefinition, +- assigned(left) and +- not assigned(tcallparanode(left).right) and +- (tcallparanode(left).left.resultdef.typ=variantdef)); +- +- { All parameters are checked, check if there are any +- procedures left } +- if cand_cnt>0 then +- begin +- { Multiple candidates left? } +- if cand_cnt>1 then +- begin +- CGMessage(type_e_cant_choose_overload_function); ++ { Choose the best candidate and count the number of ++ candidates left } ++ cand_cnt:=candidates.choose_best(procdefinition, ++ assigned(left) and ++ not assigned(tcallparanode(left).right) and ++ (tcallparanode(left).left.resultdef.typ=variantdef)); ++ ++ { All parameters are checked, check if there are any ++ procedures left } ++ if cand_cnt>0 then ++ begin ++ { Multiple candidates left? } ++ if cand_cnt>1 then ++ begin ++ CGMessage(type_e_cant_choose_overload_function); + {$ifdef EXTDEBUG} +- candidates.dump_info(V_Hint); ++ candidates.dump_info(V_Hint); + {$else EXTDEBUG} +- candidates.list(false); ++ candidates.list(false); + {$endif EXTDEBUG} +- { we'll just use the first candidate to make the +- call } +- end; ++ { we'll just use the first candidate to make the ++ call } ++ end; + +- { assign procdefinition } +- if symtableproc=nil then +- symtableproc:=procdefinition.owner; +- end +- else +- begin +- { No candidates left, this must be a type error, +- because wrong size is already checked. procdefinition +- is filled with the first (random) definition that is +- found. We use this definition to display a nice error +- message that the wrong type is passed } +- candidates.find_wrong_para; +- candidates.list(true); ++ { assign procdefinition } ++ if symtableproc=nil then ++ symtableproc:=procdefinition.owner; ++ end ++ else ++ begin ++ { No candidates left, this must be a type error, ++ because wrong size is already checked. procdefinition ++ is filled with the first (random) definition that is ++ found. We use this definition to display a nice error ++ message that the wrong type is passed } ++ candidates.find_wrong_para; ++ candidates.list(true); + {$ifdef EXTDEBUG} +- candidates.dump_info(V_Hint); ++ candidates.dump_info(V_Hint); + {$endif EXTDEBUG} + +- { We can not proceed, release all procs and exit } +- candidates.free; +- goto errorexit; +- end; ++ { We can not proceed, release all procs and exit } ++ candidates.free; ++ exit; ++ end; + +- candidates.free; +- end; { end of procedure to call determination } +- end; ++ candidates.free; ++ end; { end of procedure to call determination } ++ end; + +- { check for hints (deprecated etc) } +- if procdefinition.typ = procdef then +- check_hints(tprocdef(procdefinition).procsym,tprocdef(procdefinition).symoptions,tprocdef(procdefinition).deprecatedmsg); +- +- { add reference to corresponding procsym; may not be the one +- originally found/passed to the constructor because of overloads } +- if procdefinition.typ = procdef then +- addsymref(tprocdef(procdefinition).procsym); ++ { check for hints (deprecated etc) } ++ if procdefinition.typ = procdef then ++ check_hints(tprocdef(procdefinition).procsym,tprocdef(procdefinition).symoptions,tprocdef(procdefinition).deprecatedmsg); ++ ++ { add reference to corresponding procsym; may not be the one ++ originally found/passed to the constructor because of overloads } ++ if procdefinition.typ = procdef then ++ addsymref(tprocdef(procdefinition).procsym); + +- { add needed default parameters } +- if (paralength=procdefinition.Paras.count then +- internalerror(200306181); +- if not(vo_is_hidden_para in tparavarsym(procdefinition.paras[paraidx]).varoptions) then +- inc(i); +- inc(paraidx); +- end; +- while (paraidx=procdefinition.Paras.count then ++ internalerror(200306181); ++ if not(vo_is_hidden_para in tparavarsym(procdefinition.paras[paraidx]).varoptions) then ++ inc(i); + inc(paraidx); +- until (paraidx>=procdefinition.paras.count) or +- not(vo_is_hidden_para in tparavarsym(procdefinition.paras[paraidx]).varoptions); +- end; +- end; +- +- { recursive call? } +- if assigned(current_procinfo) and +- (procdefinition=current_procinfo.procdef) then +- include(current_procinfo.flags,pi_is_recursive); ++ end; ++ while (paraidx=procdefinition.paras.count) or ++ not(vo_is_hidden_para in tparavarsym(procdefinition.paras[paraidx]).varoptions); ++ end; ++ end; + +- { handle predefined procedures } +- is_const:=(po_internconst in procdefinition.procoptions) and +- ((block_type in [bt_const,bt_type,bt_const_type,bt_var_type]) or +- (assigned(left) and ((tcallparanode(left).left.nodetype in [realconstn,ordconstn]) +- and (not assigned(tcallparanode(left).right) or (tcallparanode(left).right.nodetype in [realconstn,ordconstn]))))); +- if (procdefinition.proccalloption=pocall_internproc) or is_const then +- begin +- if assigned(left) then +- begin +- { convert types to those of the prototype, this is required by functions like ror, rol, sar +- some use however a dummy type (Typedfile) so this would break them } +- if not(tprocdef(procdefinition).extnumber in [fpc_in_Reset_TypedFile,fpc_in_Rewrite_TypedFile]) then +- begin +- { bind parasyms to the callparanodes and insert hidden parameters } +- bind_parasym; ++ { recursive call? } ++ if assigned(current_procinfo) and ++ (procdefinition=current_procinfo.procdef) then ++ include(current_procinfo.flags,pi_is_recursive); ++ ++ { handle predefined procedures } ++ is_const:=(po_internconst in procdefinition.procoptions) and ++ ((block_type in [bt_const,bt_type,bt_const_type,bt_var_type]) or ++ (assigned(left) and ((tcallparanode(left).left.nodetype in [realconstn,ordconstn]) ++ and (not assigned(tcallparanode(left).right) or (tcallparanode(left).right.nodetype in [realconstn,ordconstn]))))); ++ if (procdefinition.proccalloption=pocall_internproc) or is_const then ++ begin ++ if assigned(left) then ++ begin ++ { convert types to those of the prototype, this is required by functions like ror, rol, sar ++ some use however a dummy type (Typedfile) so this would break them } ++ if not(tprocdef(procdefinition).extnumber in [fpc_in_Reset_TypedFile,fpc_in_Rewrite_TypedFile]) then ++ begin ++ { bind parasyms to the callparanodes and insert hidden parameters } ++ bind_parasym; + +- { insert type conversions for parameters } +- if assigned(left) then +- tcallparanode(left).insert_typeconv; +- end; ++ { insert type conversions for parameters } ++ if assigned(left) then ++ tcallparanode(left).insert_typeconv; ++ end; + +- { ptr and settextbuf need two args } +- if assigned(tcallparanode(left).right) then +- begin +- hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,left); +- left:=nil; +- end +- else +- begin +- hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,tcallparanode(left).left); +- tcallparanode(left).left:=nil; +- end; +- end +- else +- hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,nil); +- result:=hpt; +- goto errorexit; +- end; ++ { ptr and settextbuf need two args } ++ if assigned(tcallparanode(left).right) then ++ begin ++ hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,left); ++ left:=nil; ++ end ++ else ++ begin ++ hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,tcallparanode(left).left); ++ tcallparanode(left).left:=nil; ++ end; ++ end ++ else ++ hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,nil); ++ result:=hpt; ++ exit; ++ end; + +- { ensure that the result type is set } +- if not(cnf_typedefset in callnodeflags) then +- begin +- { constructors return their current class type, not the type where the +- constructor is declared, this can be different because of inheritance } +- if (procdefinition.proctypeoption=potype_constructor) and +- assigned(methodpointer) and +- assigned(methodpointer.resultdef) and +- (methodpointer.resultdef.typ=classrefdef) then +- resultdef:=tclassrefdef(methodpointer.resultdef).pointeddef +- else +- { Member call to a (inherited) constructor from the class, the return +- value is always self, so we change it to voidtype to generate an +- error and to prevent users from generating non-working code +- when they expect to clone the current instance, see bug 3662 (PFV) } ++ { ensure that the result type is set } ++ if not(cnf_typedefset in callnodeflags) then ++ begin ++ { constructors return their current class type, not the type where the ++ constructor is declared, this can be different because of inheritance } + if (procdefinition.proctypeoption=potype_constructor) and +- is_class(tprocdef(procdefinition).struct) and + assigned(methodpointer) and +- (methodpointer.nodetype=loadn) and +- (loadnf_is_self in tloadnode(methodpointer).loadnodeflags) then +- resultdef:=voidtype ++ assigned(methodpointer.resultdef) and ++ (methodpointer.resultdef.typ=classrefdef) then ++ resultdef:=tclassrefdef(methodpointer.resultdef).pointeddef + else +- resultdef:=procdefinition.returndef; +- end +- else +- resultdef:=typedef; +- +- { Check object/class for methods } +- if assigned(methodpointer) then +- begin +- { direct call to inherited abstract method, then we +- can already give a error in the compiler instead +- of a runtime error } +- if (cnf_inherited in callnodeflags) and +- (po_abstractmethod in procdefinition.procoptions) then +- begin +- if (m_delphi in current_settings.modeswitches) and +- (cnf_anon_inherited in callnodeflags) then +- begin +- CGMessage(cg_h_inherited_ignored); +- result:=cnothingnode.create; +- exit; +- end ++ { Member call to a (inherited) constructor from the class, the return ++ value is always self, so we change it to voidtype to generate an ++ error and to prevent users from generating non-working code ++ when they expect to clone the current instance, see bug 3662 (PFV) } ++ if (procdefinition.proctypeoption=potype_constructor) and ++ is_class(tprocdef(procdefinition).struct) and ++ assigned(methodpointer) and ++ (methodpointer.nodetype=loadn) and ++ (loadnf_is_self in tloadnode(methodpointer).loadnodeflags) then ++ resultdef:=voidtype + else +- CGMessage(cg_e_cant_call_abstract_method); +- end; ++ resultdef:=procdefinition.returndef; ++ end ++ else ++ resultdef:=typedef; ++ ++ { Check object/class for methods } ++ if assigned(methodpointer) then ++ begin ++ { direct call to inherited abstract method, then we ++ can already give a error in the compiler instead ++ of a runtime error } ++ if (cnf_inherited in callnodeflags) and ++ (po_abstractmethod in procdefinition.procoptions) then ++ begin ++ if (m_delphi in current_settings.modeswitches) and ++ (cnf_anon_inherited in callnodeflags) then ++ begin ++ CGMessage(cg_h_inherited_ignored); ++ result:=cnothingnode.create; ++ exit; ++ end ++ else ++ CGMessage(cg_e_cant_call_abstract_method); ++ end; ++ ++ { directly calling an interface/protocol/category/class helper ++ method via its type is not possible (always must be called via ++ the actual instance) } ++ if (methodpointer.nodetype=typen) and ++ (is_interface(methodpointer.resultdef) or ++ is_objc_protocol_or_category(methodpointer.resultdef)) then ++ CGMessage1(type_e_class_type_expected,methodpointer.resultdef.typename); ++ ++ { if an inherited con- or destructor should be } ++ { called in a con- or destructor then a warning } ++ { will be made } ++ { con- and destructors need a pointer to the vmt } ++ if (cnf_inherited in callnodeflags) and ++ (procdefinition.proctypeoption in [potype_constructor,potype_destructor]) and ++ is_object(methodpointer.resultdef) and ++ not(current_procinfo.procdef.proctypeoption in [potype_constructor,potype_destructor]) then ++ CGMessage(cg_w_member_cd_call_from_method); ++ ++ if methodpointer.nodetype<>typen then ++ begin ++ { Remove all postfix operators } ++ hpt:=methodpointer; ++ while assigned(hpt) and (hpt.nodetype in [subscriptn,vecn]) do ++ hpt:=tunarynode(hpt).left; ++ ++ if ((hpt.nodetype=loadvmtaddrn) or ++ ((hpt.nodetype=loadn) and assigned(tloadnode(hpt).resultdef) and (tloadnode(hpt).resultdef.typ=classrefdef))) and ++ not (procdefinition.proctypeoption=potype_constructor) and ++ not (po_classmethod in procdefinition.procoptions) and ++ not (po_staticmethod in procdefinition.procoptions) then ++ { error: we are calling instance method from the class method/static method } ++ CGMessage(parser_e_only_class_members); ++ ++ if (procdefinition.proctypeoption=potype_constructor) and ++ assigned(symtableproc) and ++ (symtableproc.symtabletype=withsymtable) and ++ (tnode(twithsymtable(symtableproc).withrefnode).nodetype=temprefn) then ++ CGmessage(cg_e_cannot_call_cons_dest_inside_with); ++ ++ { skip (absolute and other simple) type conversions -- only now, ++ because the checks above have to take type conversions into ++ e.g. class reference types account } ++ hpt:=actualtargetnode(@hpt)^; ++ ++ { R.Init then R will be initialized by the constructor, ++ Also allow it for simple loads } ++ if (procdefinition.proctypeoption=potype_constructor) or ++ ((hpt.nodetype=loadn) and ++ (((methodpointer.resultdef.typ=objectdef) and ++ not(oo_has_virtual in tobjectdef(methodpointer.resultdef).objectoptions)) or ++ (methodpointer.resultdef.typ=recorddef) ++ ) ++ ) then ++ { a constructor will and a method may write something to } ++ { the fields } ++ set_varstate(methodpointer,vs_readwritten,[]) ++ else ++ set_varstate(methodpointer,vs_read,[vsf_must_be_valid]); ++ end; ++ ++ { if we are calling the constructor check for abstract ++ methods. Ignore inherited and member calls, because the ++ class is then already created } ++ if (procdefinition.proctypeoption=potype_constructor) and ++ not(cnf_inherited in callnodeflags) and ++ not(cnf_member_call in callnodeflags) then ++ verifyabstractcalls; ++ end ++ else ++ begin ++ { When this is method the methodpointer must be available } ++ if (right=nil) and ++ (procdefinition.owner.symtabletype in [ObjectSymtable,recordsymtable]) and ++ not procdefinition.no_self_node then ++ internalerror(200305061); ++ end; + +- { directly calling an interface/protocol/category/class helper +- method via its type is not possible (always must be called via +- the actual instance) } +- if (methodpointer.nodetype=typen) and +- (is_interface(methodpointer.resultdef) or +- is_objc_protocol_or_category(methodpointer.resultdef)) then +- CGMessage1(type_e_class_type_expected,methodpointer.resultdef.typename); +- +- { if an inherited con- or destructor should be } +- { called in a con- or destructor then a warning } +- { will be made } +- { con- and destructors need a pointer to the vmt } +- if (cnf_inherited in callnodeflags) and +- (procdefinition.proctypeoption in [potype_constructor,potype_destructor]) and +- is_object(methodpointer.resultdef) and +- not(current_procinfo.procdef.proctypeoption in [potype_constructor,potype_destructor]) then +- CGMessage(cg_w_member_cd_call_from_method); ++ { Set flag that the procedure uses varargs, also if they are not passed it is still ++ needed for x86_64 to pass the number of SSE registers used } ++ if po_varargs in procdefinition.procoptions then ++ include(callnodeflags,cnf_uses_varargs); ++ ++ { set the appropriate node flag if the call never returns } ++ if po_noreturn in procdefinition.procoptions then ++ include(callnodeflags,cnf_call_never_returns); ++ ++ { Change loading of array of const to varargs } ++ if assigned(left) and ++ is_array_of_const(tparavarsym(procdefinition.paras[procdefinition.paras.count-1]).vardef) and ++ (procdefinition.proccalloption in cdecl_pocalls) then ++ convert_carg_array_of_const; ++ ++ { bind parasyms to the callparanodes and insert hidden parameters } ++ bind_parasym; ++ ++ { insert type conversions for parameters } ++ if assigned(left) then ++ tcallparanode(left).insert_typeconv; + +- if methodpointer.nodetype<>typen then ++ { dispinterface methode invoke? } ++ if assigned(methodpointer) and is_dispinterface(methodpointer.resultdef) then + begin +- { Remove all postfix operators } +- hpt:=methodpointer; +- while assigned(hpt) and (hpt.nodetype in [subscriptn,vecn]) do +- hpt:=tunarynode(hpt).left; +- +- if ((hpt.nodetype=loadvmtaddrn) or +- ((hpt.nodetype=loadn) and assigned(tloadnode(hpt).resultdef) and (tloadnode(hpt).resultdef.typ=classrefdef))) and +- not (procdefinition.proctypeoption=potype_constructor) and +- not (po_classmethod in procdefinition.procoptions) and +- not (po_staticmethod in procdefinition.procoptions) then +- { error: we are calling instance method from the class method/static method } +- CGMessage(parser_e_only_class_members); +- +- if (procdefinition.proctypeoption=potype_constructor) and +- assigned(symtableproc) and +- (symtableproc.symtabletype=withsymtable) and +- (tnode(twithsymtable(symtableproc).withrefnode).nodetype=temprefn) then +- CGmessage(cg_e_cannot_call_cons_dest_inside_with); +- +- { skip (absolute and other simple) type conversions -- only now, +- because the checks above have to take type conversions into +- e.g. class reference types account } +- hpt:=actualtargetnode(@hpt)^; +- +- { R.Init then R will be initialized by the constructor, +- Also allow it for simple loads } +- if (procdefinition.proctypeoption=potype_constructor) or +- ((hpt.nodetype=loadn) and +- (((methodpointer.resultdef.typ=objectdef) and +- not(oo_has_virtual in tobjectdef(methodpointer.resultdef).objectoptions)) or +- (methodpointer.resultdef.typ=recorddef) +- ) +- ) then +- { a constructor will and a method may write something to } +- { the fields } +- set_varstate(methodpointer,vs_readwritten,[]) ++ case procdefinition.proctypeoption of ++ potype_propgetter: calltype:=dct_propget; ++ potype_propsetter: calltype:=dct_propput; + else +- set_varstate(methodpointer,vs_read,[vsf_must_be_valid]); +- end; +- +- { if we are calling the constructor check for abstract +- methods. Ignore inherited and member calls, because the +- class is then already created } +- if (procdefinition.proctypeoption=potype_constructor) and +- not(cnf_inherited in callnodeflags) and +- not(cnf_member_call in callnodeflags) then +- verifyabstractcalls; +- end +- else +- begin +- { When this is method the methodpointer must be available } +- if (right=nil) and +- (procdefinition.owner.symtabletype in [ObjectSymtable,recordsymtable]) and +- not procdefinition.no_self_node then +- internalerror(200305061); +- end; +- +- { Set flag that the procedure uses varargs, also if they are not passed it is still +- needed for x86_64 to pass the number of SSE registers used } +- if po_varargs in procdefinition.procoptions then +- include(callnodeflags,cnf_uses_varargs); +- +- { set the appropriate node flag if the call never returns } +- if po_noreturn in procdefinition.procoptions then +- include(callnodeflags,cnf_call_never_returns); +- +- { Change loading of array of const to varargs } +- if assigned(left) and +- is_array_of_const(tparavarsym(procdefinition.paras[procdefinition.paras.count-1]).vardef) and +- (procdefinition.proccalloption in cdecl_pocalls) then +- convert_carg_array_of_const; +- +- { bind parasyms to the callparanodes and insert hidden parameters } +- bind_parasym; +- +- { insert type conversions for parameters } +- if assigned(left) then +- tcallparanode(left).insert_typeconv; ++ calltype:=dct_method; ++ end; ++ { if the result is used, we've to insert a call to convert the type to be on the "safe side" } ++ if (cnf_return_value_used in callnodeflags) and not is_void(procdefinition.returndef) then ++ begin ++ result:=internalstatements(statements); ++ converted_result_data:=ctempcreatenode.create(procdefinition.returndef,sizeof(procdefinition.returndef), ++ tt_persistent,true); ++ addstatement(statements,converted_result_data); ++ addstatement(statements,cassignmentnode.create(ctemprefnode.create(converted_result_data), ++ ctypeconvnode.create_internal( ++ translate_disp_call(methodpointer,parameters,calltype,'',tprocdef(procdefinition).dispid,procdefinition.returndef), ++ procdefinition.returndef))); ++ addstatement(statements,ctempdeletenode.create_normal_temp(converted_result_data)); ++ addstatement(statements,ctemprefnode.create(converted_result_data)); ++ end ++ else ++ result:=translate_disp_call(methodpointer,parameters,calltype,'',tprocdef(procdefinition).dispid,voidtype); + +- { dispinterface methode invoke? } +- if assigned(methodpointer) and is_dispinterface(methodpointer.resultdef) then +- begin +- case procdefinition.proctypeoption of +- potype_propgetter: calltype:=dct_propget; +- potype_propsetter: calltype:=dct_propput; +- else +- calltype:=dct_method; ++ { don't free reused nodes } ++ methodpointer:=nil; ++ parameters:=nil; + end; +- { if the result is used, we've to insert a call to convert the type to be on the "safe side" } +- if (cnf_return_value_used in callnodeflags) and not is_void(procdefinition.returndef) then +- begin +- result:=internalstatements(statements); +- converted_result_data:=ctempcreatenode.create(procdefinition.returndef,sizeof(procdefinition.returndef), +- tt_persistent,true); +- addstatement(statements,converted_result_data); +- addstatement(statements,cassignmentnode.create(ctemprefnode.create(converted_result_data), +- ctypeconvnode.create_internal( +- translate_disp_call(methodpointer,parameters,calltype,'',tprocdef(procdefinition).dispid,procdefinition.returndef), +- procdefinition.returndef))); +- addstatement(statements,ctempdeletenode.create_normal_temp(converted_result_data)); +- addstatement(statements,ctemprefnode.create(converted_result_data)); +- end +- else +- result:=translate_disp_call(methodpointer,parameters,calltype,'',tprocdef(procdefinition).dispid,voidtype); + +- { don't free reused nodes } +- methodpointer:=nil; +- parameters:=nil; +- end; +- +- errorexit: +- aktcallnode:=oldcallnode; ++ finally ++ aktcallnode:=oldcallnode; ++ end; + end; + + +@@ -3590,123 +3822,131 @@ implementation + + var + para: tcallparanode; ++ oldcallnode: tcallnode; + begin + result:=nil; + +- { as pass_1 is never called on the methodpointer node, we must check +- here that it's not a helper type } +- if assigned(methodpointer) and +- (methodpointer.nodetype=typen) and +- is_objectpascal_helper(ttypenode(methodpointer).typedef) and +- not ttypenode(methodpointer).helperallowed then +- Message(parser_e_no_category_as_types); +- +- { can we get rid of the call? } +- if (cs_opt_remove_emtpy_proc in current_settings.optimizerswitches) and +- not(cnf_return_value_used in callnodeflags) and +- (procdefinition.typ=procdef) and +- tprocdef(procdefinition).isempty and +- { allow only certain proc options } +- ((tprocdef(procdefinition).procoptions-[po_none,po_classmethod,po_staticmethod, +- po_interrupt,po_iocheck,po_assembler,po_msgstr,po_msgint,po_exports,po_external,po_overload, +- po_nostackframe,po_has_mangledname,po_has_public_name,po_forward,po_global, +- po_inline,po_compilerproc,po_has_importdll,po_has_importname,po_kylixlocal,po_dispid,po_delphi_nested_cc, +- po_rtlproc,po_ignore_for_overload_resolution,po_auto_raised_visibility])=[]) then +- begin +- { check parameters for side effects } +- para:=tcallparanode(left); +- while assigned(para) do +- begin +- if (para.parasym.typ = paravarsym) and +- ((para.parasym.refs>0) or +- { array of consts are converted later on so we need to skip them here +- else no error detection is done } +- is_array_of_const(para.parasym.vardef) or +- not(cs_opt_dead_values in current_settings.optimizerswitches) or +- might_have_sideeffects(para.left)) then +- break; +- para:=tcallparanode(para.right); +- end; +- { finally, remove it if no parameter with side effect has been found } +- if para=nil then +- begin +- result:=cnothingnode.create; +- exit; +- end; +- end; ++ oldcallnode:=aktcallnode; ++ aktcallnode:=self; + +- { convert Objective-C calls into a message call } +- if (procdefinition.typ=procdef) and +- (po_objc in tprocdef(procdefinition).procoptions) then +- begin +- if not(cnf_objc_processed in callnodeflags) then +- objc_convert_to_message_send; +- end +- else +- begin +- { The following don't apply to obj-c: obj-c methods can never be +- inlined because they're always virtual and the destination can +- change at run, and for the same reason we also can't perform +- WPO on them (+ they have no constructors) } +- +- { Check if the call can be inlined, sets the cnf_do_inline flag } +- check_inlining; +- +- { must be called before maybe_load_in_temp(methodpointer), because +- it converts the methodpointer into a temp in case it's a call +- (and we want to know the original call) +- } +- register_created_object_types; +- end; ++ try ++ { as pass_1 is never called on the methodpointer node, we must check ++ here that it's not a helper type } ++ if assigned(methodpointer) and ++ (methodpointer.nodetype=typen) and ++ is_objectpascal_helper(ttypenode(methodpointer).typedef) and ++ not ttypenode(methodpointer).helperallowed then ++ Message(parser_e_no_category_as_types); ++ ++ { can we get rid of the call? } ++ if (cs_opt_remove_emtpy_proc in current_settings.optimizerswitches) and ++ not(cnf_return_value_used in callnodeflags) and ++ (procdefinition.typ=procdef) and ++ tprocdef(procdefinition).isempty and ++ { allow only certain proc options } ++ ((tprocdef(procdefinition).procoptions-[po_none,po_classmethod,po_staticmethod, ++ po_interrupt,po_iocheck,po_assembler,po_msgstr,po_msgint,po_exports,po_external,po_overload, ++ po_nostackframe,po_has_mangledname,po_has_public_name,po_forward,po_global, ++ po_inline,po_compilerproc,po_has_importdll,po_has_importname,po_kylixlocal,po_dispid,po_delphi_nested_cc, ++ po_rtlproc,po_ignore_for_overload_resolution,po_auto_raised_visibility])=[]) then ++ begin ++ { check parameters for side effects } ++ para:=tcallparanode(left); ++ while assigned(para) do ++ begin ++ if (para.parasym.typ = paravarsym) and ++ ((para.parasym.refs>0) or ++ { array of consts are converted later on so we need to skip them here ++ else no error detection is done } ++ is_array_of_const(para.parasym.vardef) or ++ not(cs_opt_dead_values in current_settings.optimizerswitches) or ++ might_have_sideeffects(para.left)) then ++ break; ++ para:=tcallparanode(para.right); ++ end; ++ { finally, remove it if no parameter with side effect has been found } ++ if para=nil then ++ begin ++ result:=cnothingnode.create; ++ exit; ++ end; ++ end; + +- { Maybe optimize the loading of the methodpointer using a temp. When the methodpointer +- is a calln this is even required to not execute the calln twice. +- This needs to be done after the resulttype pass, because in the resulttype we can still convert the +- calln to a loadn (PFV) } +- if assigned(methodpointer) then +- maybe_load_in_temp(methodpointer); +- +- { Create destination (temp or assignment-variable reuse) for function result if it not yet set } +- maybe_create_funcret_node; +- +- { Insert the self,vmt,function result in the parameters } +- gen_hidden_parameters; +- +- { Remove useless nodes from init/final blocks } +- { (simplify depends on typecheck info) } +- if assigned(callinitblock) then +- begin +- typecheckpass(tnode(callinitblock)); +- doinlinesimplify(tnode(callinitblock)); +- end; +- if assigned(callcleanupblock) then +- begin +- typecheckpass(tnode(callcleanupblock)); +- doinlinesimplify(tnode(callcleanupblock)); +- end; ++ { convert Objective-C calls into a message call } ++ if (procdefinition.typ=procdef) and ++ (po_objc in tprocdef(procdefinition).procoptions) then ++ begin ++ if not(cnf_objc_processed in callnodeflags) then ++ objc_convert_to_message_send; ++ end ++ else ++ begin ++ { The following don't apply to obj-c: obj-c methods can never be ++ inlined because they're always virtual and the destination can ++ change at run, and for the same reason we also can't perform ++ WPO on them (+ they have no constructors) } ++ ++ { Check if the call can be inlined, sets the cnf_do_inline flag } ++ check_inlining; ++ ++ { must be called before maybe_load_in_temp(methodpointer), because ++ it converts the methodpointer into a temp in case it's a call ++ (and we want to know the original call) ++ } ++ register_created_object_types; ++ end; + +- { If a constructor calls another constructor of the same or of an +- inherited class, some targets (jvm) have to generate different +- entry code for the constructor. } +- if (current_procinfo.procdef.proctypeoption=potype_constructor) and +- (procdefinition.typ=procdef) and +- (tprocdef(procdefinition).proctypeoption=potype_constructor) and +- ([cnf_member_call,cnf_inherited] * callnodeflags <> []) then +- current_procinfo.ConstructorCallingConstructor:=true; +- +- { object check helper will load VMT -> needs GOT } +- if (cs_check_object in current_settings.localswitches) and +- (cs_create_pic in current_settings.moduleswitches) then +- include(current_procinfo.flags,pi_needs_got); +- +- { Continue with checking a normal call or generate the inlined code } +- if cnf_do_inline in callnodeflags then +- result:=pass1_inline +- else +- begin +- mark_unregable_parameters; +- result:=pass1_normal; +- end; ++ { Maybe optimize the loading of the methodpointer using a temp. When the methodpointer ++ is a calln this is even required to not execute the calln twice. ++ This needs to be done after the resulttype pass, because in the resulttype we can still convert the ++ calln to a loadn (PFV) } ++ if assigned(methodpointer) then ++ maybe_load_in_temp(methodpointer); ++ ++ { Create destination (temp or assignment-variable reuse) for function result if it not yet set } ++ maybe_create_funcret_node; ++ ++ { Insert the self,vmt,function result in the parameters } ++ gen_hidden_parameters; ++ ++ { Remove useless nodes from init/final blocks } ++ { (simplify depends on typecheck info) } ++ if assigned(callinitblock) then ++ begin ++ typecheckpass(tnode(callinitblock)); ++ doinlinesimplify(tnode(callinitblock)); ++ end; ++ if assigned(callcleanupblock) then ++ begin ++ typecheckpass(tnode(callcleanupblock)); ++ doinlinesimplify(tnode(callcleanupblock)); ++ end; ++ ++ { If a constructor calls another constructor of the same or of an ++ inherited class, some targets (jvm) have to generate different ++ entry code for the constructor. } ++ if (current_procinfo.procdef.proctypeoption=potype_constructor) and ++ (procdefinition.typ=procdef) and ++ (tprocdef(procdefinition).proctypeoption=potype_constructor) and ++ ([cnf_member_call,cnf_inherited] * callnodeflags <> []) then ++ current_procinfo.ConstructorCallingConstructor:=true; ++ ++ { object check helper will load VMT -> needs GOT } ++ if (cs_check_object in current_settings.localswitches) and ++ (cs_create_pic in current_settings.moduleswitches) then ++ include(current_procinfo.flags,pi_needs_got); ++ ++ { Continue with checking a normal call or generate the inlined code } ++ if cnf_do_inline in callnodeflags then ++ result:=pass1_inline ++ else ++ begin ++ mark_unregable_parameters; ++ result:=pass1_normal; ++ end; ++ finally ++ aktcallnode:=oldcallnode; ++ end; + end; + + +Index: fpc/fpcsrc/compiler/ncgcnv.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ncgcnv.pas ++++ fpc/fpcsrc/compiler/ncgcnv.pas +@@ -176,6 +176,11 @@ interface + if (nf_explicit in flags) and + not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then + begin ++ { overriding methods must be able to know in advance whether this ++ code path will be taken by checking expectloc, so they can call ++ the inherited method in that case } ++ if left.expectloc in [LOC_FLAGS,LOC_JUMP] then ++ internalerror(2014122901); + location_copy(location,left.location); + newsize:=def_cgsize(resultdef); + { change of size? change sign only if location is LOC_(C)REGISTER? Then we have to sign/zero-extend } +Index: fpc/fpcsrc/compiler/ncginl.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ncginl.pas ++++ fpc/fpcsrc/compiler/ncginl.pas +@@ -749,16 +749,12 @@ implementation + secondpass(left); + + opsize:=tcgsize2unsigned[left.location.size]; +- if opsize < OS_32 then +- opsize:=OS_32; +- +- if (left.location.loc <> LOC_REGISTER) or +- (left.location.size <> opsize) then ++ if not(left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,cgsize_orddef(opsize),true); + +- location_reset(location,LOC_REGISTER,opsize); +- location.register := cg.getintregister(current_asmdata.CurrAsmList,opsize); +- cg.a_bit_scan_reg_reg(current_asmdata.CurrAsmList,reverse,opsize,left.location.register,location.register); ++ location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); ++ location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size); ++ cg.a_bit_scan_reg_reg(current_asmdata.CurrAsmList,reverse,opsize,location.size,left.location.register,location.register); + end; + + +Index: fpc/fpcsrc/compiler/ncgld.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ncgld.pas ++++ fpc/fpcsrc/compiler/ncgld.pas +@@ -768,9 +768,17 @@ implementation + (right.resultdef.typ=floatdef) and + (left.location.size<>right.location.size) then + begin +- hlcg.a_loadfpu_ref_ref(current_asmdata.CurrAsmList, +- right.resultdef,left.resultdef, +- right.location.reference,left.location.reference) ++ { assume that all float types can be handed by the ++ fpu if one can be handled by the fpu } ++ if not use_vectorfpu(left.resultdef) or ++ not use_vectorfpu(right.resultdef) then ++ hlcg.a_loadfpu_ref_ref(current_asmdata.CurrAsmList, ++ right.resultdef,left.resultdef, ++ right.location.reference,left.location.reference) ++ else ++ hlcg.a_loadmm_ref_ref(current_asmdata.CurrAsmList, ++ right.resultdef,left.resultdef, ++ right.location.reference,left.location.reference,mms_movescalar) + end + else + begin +Index: fpc/fpcsrc/compiler/ncgmat.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ncgmat.pas ++++ fpc/fpcsrc/compiler/ncgmat.pas +@@ -457,9 +457,9 @@ implementation + procedure tcgshlshrnode.second_integer; + var + op : topcg; +- opdef,right_opdef : tdef; ++ opdef: tdef; + hcountreg : tregister; +- opsize,right_opsize : tcgsize; ++ opsize : tcgsize; + shiftval : longint; + begin + { determine operator } +@@ -472,44 +472,51 @@ implementation + {$ifdef cpunodefaultint} + opsize:=left.location.size; + opdef:=left.resultdef; +- right_opsize:=opsize; +- right_opdef:=opdef; + {$else cpunodefaultint} +- { load left operators in a register } +- if is_signed(left.resultdef) then +- begin +- right_opsize:=OS_SINT; +- right_opdef:=ossinttype; +- {$ifdef cpu16bitalu} +- if left.resultdef.size > 2 then +- begin +- opsize:=OS_S32; +- opdef:=s32inttype; +- end +- else +- {$endif cpu16bitalu} +- begin +- opsize:=OS_SINT; +- opdef:=ossinttype +- end; +- end +- else +- begin +- right_opsize:=OS_INT; +- right_opdef:=osuinttype; +- {$ifdef cpu16bitalu} +- if left.resultdef.size > 2 then +- begin +- opsize:=OS_32; +- opdef:=u32inttype; +- end +- else +- {$endif cpu16bitalu} +- begin +- opsize:=OS_INT; +- opdef:=osuinttype; +- end; +- end; ++ if left.resultdef.size<=4 then ++ begin ++ if is_signed(left.resultdef) then ++ begin ++ if (sizeof(aint)<4) and ++ (left.resultdef.size<=sizeof(aint)) then ++ begin ++ opsize:=OS_SINT; ++ opdef:=sinttype; ++ end ++ else ++ begin ++ opdef:=s32inttype; ++ opsize:=OS_S32 ++ end ++ end ++ else ++ begin ++ if (sizeof(aint)<4) and ++ (left.resultdef.size<=sizeof(aint)) then ++ begin ++ opsize:=OS_INT; ++ opdef:=uinttype; ++ end ++ else ++ begin ++ opdef:=u32inttype; ++ opsize:=OS_32; ++ end ++ end ++ end ++ else ++ begin ++ if is_signed(left.resultdef) then ++ begin ++ opdef:=s64inttype; ++ opsize:=OS_S64; ++ end ++ else ++ begin ++ opdef:=u64inttype; ++ opsize:=OS_64; ++ end; ++ end; + {$endif cpunodefaultint} + + if not(left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) or +@@ -538,14 +545,8 @@ implementation + is done since most target cpu which will use this + node do not support a shift count in a mem. location (cec) + } +- if not(right.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then +- begin +- hcountreg:=hlcg.getintregister(current_asmdata.CurrAsmList,right_opdef); +- hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,right.resultdef,right_opdef,right.location,hcountreg); +- end +- else +- hcountreg:=right.location.register; +- hlcg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,op,opdef,hcountreg,left.location.register,location.register); ++ hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,opdef,true); ++ hlcg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,op,opdef,right.location.register,left.location.register,location.register); + end; + { shl/shr nodes return the same type as left, which can be different + from opdef } +Index: fpc/fpcsrc/compiler/ncgmem.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ncgmem.pas ++++ fpc/fpcsrc/compiler/ncgmem.pas +@@ -27,7 +27,8 @@ unit ncgmem; + interface + + uses +- globtype,cgbase,cpuinfo,cpubase, ++ globtype,cgbase,cgutils,cpuinfo,cpubase, ++ symtype, + node,nmem; + + type +@@ -67,10 +68,12 @@ interface + This routine should update location.reference correctly, + so it points to the correct address. + } +- procedure update_reference_reg_mul(maybe_const_reg:tregister;l:aint);virtual; +- procedure update_reference_reg_packed(maybe_const_reg:tregister;l:aint);virtual; ++ procedure update_reference_reg_mul(maybe_const_reg: tregister;regsize: tdef; l: aint);virtual; ++ procedure update_reference_reg_packed(maybe_const_reg: tregister; regsize: tdef; l: aint);virtual; ++ procedure update_reference_offset(var ref: treference; index, mulsize: aint); virtual; + procedure second_wideansistring;virtual; + procedure second_dynamicarray;virtual; ++ function valid_index_size(size: tcgsize): boolean;virtual; + public + procedure pass_generate_code;override; + end; +@@ -81,11 +84,11 @@ implementation + uses + systems, + cutils,cclasses,verbose,globals,constexp, +- symconst,symbase,symtype,symdef,symsym,symcpu,symtable,defutil,paramgr, ++ symconst,symbase,symdef,symsym,symcpu,symtable,defutil,paramgr, + aasmbase,aasmtai,aasmdata, + procinfo,pass_2,parabase, + pass_1,nld,ncon,nadd,ncnv,nutils, +- cgutils,cgobj,hlcgobj, ++ cgobj,hlcgobj, + tgobj,ncgutil,objcgutl, + defcmp + ; +@@ -525,8 +528,8 @@ implementation + } + asmsym:=current_asmdata.RefAsmSymbol(vs.mangledname); + reference_reset_symbol(tmpref,asmsym,0,sizeof(pint)); +- location.reference.index:=cg.getaddressregister(current_asmdata.CurrAsmList); +- cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,location.reference.index); ++ location.reference.index:=hlcg.getintregister(current_asmdata.CurrAsmList,ptruinttype); ++ hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,ptruinttype,ptruinttype,tmpref,location.reference.index); + { always packrecords C -> natural alignment } + location.reference.alignment:=vs.vardef.alignment; + end +@@ -619,7 +622,7 @@ implementation + { the live range of the LOC_CREGISTER will most likely overlap the } + { the live range of the target LOC_(C)REGISTER) } + { The passed register may be a LOC_CREGISTER as well. } +- procedure tcgvecnode.update_reference_reg_mul(maybe_const_reg:tregister;l:aint); ++ procedure tcgvecnode.update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); + var + hreg: tregister; + begin +@@ -649,7 +652,7 @@ implementation + + + { see remarks for tcgvecnode.update_reference_reg_mul above } +- procedure tcgvecnode.update_reference_reg_packed(maybe_const_reg:tregister;l:aint); ++ procedure tcgvecnode.update_reference_reg_packed(maybe_const_reg: tregister; regsize: tdef; l:aint); + var + sref: tsubsetreference; + offsetreg, hreg: tregister; +@@ -667,7 +670,7 @@ implementation + {$endif not cpu64bitalu} + ) then + begin +- update_reference_reg_mul(maybe_const_reg,l div 8); ++ update_reference_reg_mul(maybe_const_reg,regsize,l div 8); + exit; + end; + if (l > 8*sizeof(aint)) then +@@ -678,7 +681,7 @@ implementation + cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_IMUL,OS_INT,l,hreg); + { keep alignment for index } + sref.ref.alignment := left.resultdef.alignment; +- if not ispowerof2(sref.ref.alignment,temp) then ++ if not ispowerof2(packedbitsloadsize(l),temp) then + internalerror(2006081201); + alignpower:=temp; + offsetreg := cg.getaddressregister(current_asmdata.CurrAsmList); +@@ -705,6 +708,12 @@ implementation + end; + + ++ procedure tcgvecnode.update_reference_offset(var ref: treference; index, mulsize: aint); ++ begin ++ inc(ref.offset,index*mulsize); ++ end; ++ ++ + procedure tcgvecnode.second_wideansistring; + begin + end; +@@ -714,6 +723,13 @@ implementation + end; + + ++ function tcgvecnode.valid_index_size(size: tcgsize): boolean; ++ begin ++ result:= ++ tcgsize2signed[size]=tcgsize2signed[OS_ADDR]; ++ end; ++ ++ + procedure tcgvecnode.rangecheck_array; + var + hightree : tnode; +@@ -859,6 +875,7 @@ implementation + paraloc2 : tcgpara; + subsetref : tsubsetreference; + temp : longint; ++ indexdef : tdef; + begin + paraloc1.init; + paraloc2.init; +@@ -916,7 +933,7 @@ implementation + + { in ansistrings/widestrings S[1] is pchar(S)[0] } + if not(cs_zerobasedstrings in current_settings.localswitches) then +- dec(location.reference.offset,offsetdec); ++ update_reference_offset(location.reference,-1,offsetdec); + end + else if is_dynamic_array(left.resultdef) then + begin +@@ -971,7 +988,7 @@ implementation + or is_64bitint(resultdef) + {$endif not cpu64bitalu} + ) then +- dec(location.reference.offset,bytemulsize*tarraydef(left.resultdef).lowrange); ++ update_reference_offset(location.reference,-tarraydef(left.resultdef).lowrange,bytemulsize); + + if right.nodetype=ordconstn then + begin +@@ -992,10 +1009,10 @@ implementation + { only orddefs are bitpacked } + not is_ordinal(resultdef))) then + begin +- extraoffset:=bytemulsize*tordconstnode(right).value.svalue; +- inc(location.reference.offset,extraoffset); +- { adjust alignment after to this change } +- location.reference.alignment:=newalignment(location.reference.alignment,extraoffset); ++ extraoffset:=tordconstnode(right).value.svalue; ++ update_reference_offset(location.reference,extraoffset,bytemulsize); ++ { adjust alignment after this change } ++ location.reference.alignment:=newalignment(location.reference.alignment,extraoffset*bytemulsize); + { don't do this for floats etc.; needed to properly set the } + { size for bitpacked arrays (e.g. a bitpacked array of } + { enums who are size 2 but fit in one byte -> in the array } +@@ -1008,10 +1025,10 @@ implementation + begin + subsetref.ref := location.reference; + subsetref.ref.alignment := left.resultdef.alignment; +- if not ispowerof2(subsetref.ref.alignment,temp) then ++ if not ispowerof2(packedbitsloadsize(resultdef.packedbitsize),temp) then + internalerror(2006081212); + alignpow:=temp; +- inc(subsetref.ref.offset,((mulsize * (tordconstnode(right).value.svalue-tarraydef(left.resultdef).lowrange)) shr (3+alignpow)) shl alignpow); ++ update_reference_offset(subsetref.ref,(mulsize * (tordconstnode(right).value.svalue-tarraydef(left.resultdef).lowrange)) shr (3+alignpow),1 shl alignpow); + subsetref.bitindexreg := NR_NO; + subsetref.startbit := (mulsize * (tordconstnode(right).value.svalue-tarraydef(left.resultdef).lowrange)) and ((1 shl (3+alignpow))-1); + subsetref.bitlen := resultdef.packedbitsize; +@@ -1056,8 +1073,7 @@ implementation + replacenode(rightp^,taddnode(rightp^).left); + end; + end; +- inc(location.reference.offset, +- mulsize*extraoffset); ++ update_reference_offset(location.reference,extraoffset,mulsize); + end; + { calculate from left to right } + if not(location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then +@@ -1075,8 +1091,14 @@ implementation + secondpass(right); + + { if mulsize = 1, we won't have to modify the index } +- if not(right.location.loc in [LOC_CREGISTER,LOC_REGISTER]) or (right.location.size<>OS_ADDR) then +- hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,ptruinttype,true); ++ if not(right.location.loc in [LOC_CREGISTER,LOC_REGISTER]) or ++ not valid_index_size(right.location.size) then ++ begin ++ hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,ptruinttype,true); ++ indexdef:=ptruinttype ++ end ++ else ++ indexdef:=right.resultdef; + + if isjump then + begin +@@ -1098,9 +1120,9 @@ implementation + { insert the register and the multiplication factor in the + reference } + if not is_packed_array(left.resultdef) then +- update_reference_reg_mul(right.location.register,mulsize) ++ update_reference_reg_mul(right.location.register,indexdef,mulsize) + else +- update_reference_reg_packed(right.location.register,mulsize); ++ update_reference_reg_packed(right.location.register,indexdef,mulsize); + end; + + location.size:=newsize; +Index: fpc/fpcsrc/compiler/ncgutil.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ncgutil.pas ++++ fpc/fpcsrc/compiler/ncgutil.pas +@@ -598,82 +598,6 @@ implementation + Init/Finalize Code + ****************************************************************************} + +- procedure copyvalueparas(p:TObject;arg:pointer); +- var +- href : treference; +- hreg : tregister; +- list : TAsmList; +- hsym : tparavarsym; +- l : longint; +- localcopyloc : tlocation; +- sizedef : tdef; +- begin +- list:=TAsmList(arg); +- if (tsym(p).typ=paravarsym) and +- (tparavarsym(p).varspez=vs_value) and +- (paramanager.push_addr_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption)) then +- begin +- { we have no idea about the alignment at the caller side } +- hlcg.location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,true,1); +- if is_open_array(tparavarsym(p).vardef) or +- is_array_of_const(tparavarsym(p).vardef) then +- begin +- { cdecl functions don't have a high pointer so it is not possible to generate +- a local copy } +- if not(current_procinfo.procdef.proccalloption in cdecl_pocalls) then +- begin +- hsym:=tparavarsym(get_high_value_sym(tparavarsym(p))); +- if not assigned(hsym) then +- internalerror(200306061); +- sizedef:=getpointerdef(tparavarsym(p).vardef); +- hreg:=hlcg.getaddressregister(list,sizedef); +- if not is_packed_array(tparavarsym(p).vardef) then +- hlcg.g_copyvaluepara_openarray(list,href,hsym.initialloc,tarraydef(tparavarsym(p).vardef),hreg) +- else +- internalerror(2006080401); +-// cg.g_copyvaluepara_packedopenarray(list,href,hsym.intialloc,tarraydef(tparavarsym(p).vardef).elepackedbitsize,hreg); +- hlcg.a_load_reg_loc(list,sizedef,sizedef,hreg,tparavarsym(p).initialloc); +- end; +- end +- else +- begin +- { Allocate space for the local copy } +- l:=tparavarsym(p).getsize; +- localcopyloc.loc:=LOC_REFERENCE; +- localcopyloc.size:=int_cgsize(l); +- tg.GetLocal(list,l,tparavarsym(p).vardef,localcopyloc.reference); +- { Copy data } +- if is_shortstring(tparavarsym(p).vardef) then +- begin +- { this code is only executed before the code for the body and the entry/exit code is generated +- so we're allowed to include pi_do_call here; after pass1 is run, this isn't allowed anymore +- } +- include(current_procinfo.flags,pi_do_call); +- hlcg.g_copyshortstring(list,href,localcopyloc.reference,tstringdef(tparavarsym(p).vardef)); +- end +- else if tparavarsym(p).vardef.typ = variantdef then +- begin +- { this code is only executed before the code for the body and the entry/exit code is generated +- so we're allowed to include pi_do_call here; after pass1 is run, this isn't allowed anymore +- } +- include(current_procinfo.flags,pi_do_call); +- hlcg.g_copyvariant(list,href,localcopyloc.reference,tvariantdef(tparavarsym(p).vardef)) +- end +- else +- begin +- { pass proper alignment info } +- localcopyloc.reference.alignment:=tparavarsym(p).vardef.alignment; +- cg.g_concatcopy(list,href,localcopyloc.reference,tparavarsym(p).vardef.size); +- end; +- { update localloc of varsym } +- tg.Ungetlocal(list,tparavarsym(p).localloc.reference); +- tparavarsym(p).localloc:=localcopyloc; +- tparavarsym(p).initialloc:=localcopyloc; +- end; +- end; +- end; +- +- + { generates the code for incrementing the reference count of parameters and + initialize out parameters } + procedure init_paras(p:TObject;arg:pointer); +@@ -698,7 +622,11 @@ implementation + if not((tparavarsym(p).vardef.typ=variantdef) and + paramanager.push_addr_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption)) then + begin +- hlcg.location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,is_open_array(tparavarsym(p).vardef),sizeof(pint)); ++ hlcg.location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href, ++ is_open_array(tparavarsym(p).vardef) or ++ ((target_info.system in systems_caller_copy_addr_value_para) and ++ paramanager.push_addr_param(vs_value,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption)), ++ sizeof(pint)); + if is_open_array(tparavarsym(p).vardef) then + begin + { open arrays do not contain correct element count in their rtti, +@@ -864,12 +792,11 @@ implementation + end; + + var +- paraloc : pcgparalocation; +- href : treference; +- sizeleft : aint; +-{$if defined(sparc) or defined(arm) or defined(mips)} +- tempref : treference; +-{$endif defined(sparc) or defined(arm) or defined(mips)} ++ paraloc : pcgparalocation; ++ href : treference; ++ sizeleft : aint; ++ alignment : longint; ++ tempref : treference; + {$ifdef mips} + tmpreg : tregister; + {$endif mips} +@@ -1085,7 +1012,38 @@ implementation + end + {$endif defined(cpu8bitalu)} + else +- internalerror(200410105); ++ begin ++ { this can happen if a parameter is spread over ++ multiple paralocs, e.g. if a record with two single ++ fields must be passed in two single precision ++ registers } ++ { does it fit in the register of destloc? } ++ sizeleft:=para.intsize; ++ if sizeleft<>vardef.size then ++ internalerror(2014122806); ++ if sizeleft<>tcgsize2size[destloc.size] then ++ internalerror(200410105); ++ { store everything first to memory, then load it in ++ destloc } ++ tg.gettemp(list,sizeleft,sizeleft,tt_persistent,tempref); ++ gen_alloc_regloc(list,destloc); ++ while sizeleft>0 do ++ begin ++ if not assigned(paraloc) then ++ internalerror(2014122807); ++ unget_para(paraloc^); ++ cg.a_load_cgparaloc_ref(list,paraloc^,tempref,sizeleft,newalignment(para.alignment,para.intsize-sizeleft)); ++ if (paraloc^.size=OS_NO) and ++ assigned(paraloc^.next) then ++ internalerror(2014122805); ++ inc(tempref.offset,tcgsize2size[paraloc^.size]); ++ dec(sizeleft,tcgsize2size[paraloc^.size]); ++ paraloc:=paraloc^.next; ++ end; ++ dec(tempref.offset,para.intsize); ++ cg.a_load_ref_reg(list,para.size,para.size,tempref,destloc.register); ++ tg.ungettemp(list,tempref); ++ end; + end + else + begin +@@ -1214,10 +1172,17 @@ implementation + else + {$endif not cpu64bitalu} + begin +- unget_para(paraloc^); +- gen_alloc_regloc(list,destloc); +- { from register to register -> alignment is irrelevant } +- cg.a_load_cgparaloc_anyreg(list,destloc.size,paraloc^,destloc.register,0); ++ if not assigned(paraloc^.next) then ++ begin ++ unget_para(paraloc^); ++ gen_alloc_regloc(list,destloc); ++ { from register to register -> alignment is irrelevant } ++ cg.a_load_cgparaloc_anyreg(list,destloc.size,paraloc^,destloc.register,0); ++ end ++ else ++ begin ++ internalerror(200410108); ++ end; + { data could come in two memory locations, for now + we simply ignore the sanity check (FK) + if assigned(paraloc^.next) then +@@ -1293,7 +1258,7 @@ implementation + { generate copies of call by value parameters, must be done before + the initialization and body is parsed because the refcounts are + incremented using the local copies } +- current_procinfo.procdef.parast.SymList.ForEachCall(@copyvalueparas,list); ++ current_procinfo.procdef.parast.SymList.ForEachCall(@hlcg.g_copyvalueparas,list); + if not(po_assembler in current_procinfo.procdef.procoptions) then + begin + { initialize refcounted paras, and trash others. Needed here +Index: fpc/fpcsrc/compiler/ncnv.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ncnv.pas ++++ fpc/fpcsrc/compiler/ncnv.pas +@@ -2375,6 +2375,10 @@ implementation + (left.resultdef.typ=objectdef))) or + {$endif} + ( ++ is_void(left.resultdef) and ++ (left.nodetype=derefn) ++ ) or ++ ( + not(is_open_array(left.resultdef)) and + not(is_array_constructor(left.resultdef)) and + not(is_array_of_const(left.resultdef)) and +@@ -2388,10 +2392,6 @@ implementation + { the softfloat code generates casts to record } + (nf_internal in flags) + )) +- ) or +- ( +- is_void(left.resultdef) and +- (left.nodetype=derefn) + ) + ) then + CGMessage2(type_e_illegal_type_conversion,left.resultdef.typename,resultdef.typename) +Index: fpc/fpcsrc/compiler/ninl.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ninl.pas ++++ fpc/fpcsrc/compiler/ninl.pas +@@ -2631,6 +2631,10 @@ implementation + if (left.resultdef.typ<>undefineddef) and + paramanager.push_high_param(vs_value,left.resultdef,current_procinfo.procdef.proccalloption) then + begin ++ { this should be an open array or array of const, both of ++ which can only be simple load nodes of parameters } ++ if left.nodetype<>loadn then ++ internalerror(2014120701); + hightree:=load_high_value_node(tparavarsym(tloadnode(left).symtableentry)); + if assigned(hightree) then + begin +Index: fpc/fpcsrc/compiler/nld.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/nld.pas ++++ fpc/fpcsrc/compiler/nld.pas +@@ -326,7 +326,7 @@ implementation + begin + if assigned(left) then + internalerror(200309289); +- left:=cloadparentfpnode.create(tprocdef(symtable.defowner)); ++ left:=cloadparentfpnode.create(tprocdef(symtable.defowner),lpf_forload); + { we can't inline the referenced parent procedure } + exclude(tprocdef(symtable.defowner).procoptions,po_inline); + { reference in nested procedures, variable needs to be in memory } +@@ -484,7 +484,7 @@ implementation + begin + { parent frame pointer pointer as "self" } + left.free; +- left:=cloadparentfpnode.create(tprocdef(p.owner.defowner)); ++ left:=cloadparentfpnode.create(tprocdef(p.owner.defowner),lpf_forpara); + end; + end + { we should never go from nested to non-nested } +Index: fpc/fpcsrc/compiler/nmem.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/nmem.pas ++++ fpc/fpcsrc/compiler/nmem.pas +@@ -45,10 +45,18 @@ interface + end; + tloadvmtaddrnodeclass = class of tloadvmtaddrnode; + ++ tloadparentfpkind = ( ++ { as parameter to a nested routine (current routine's frame) } ++ lpf_forpara, ++ { to load a local from a parent routine in the current nested routine ++ (some parent routine's frame) } ++ lpf_forload ++ ); + tloadparentfpnode = class(tunarynode) + parentpd : tprocdef; + parentpdderef : tderef; +- constructor create(pd:tprocdef);virtual; ++ kind: tloadparentfpkind; ++ constructor create(pd: tprocdef; fpkind: tloadparentfpkind);virtual; + constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override; + procedure ppuwrite(ppufile:tcompilerppufile);override; + procedure buildderefimpl;override; +@@ -240,7 +248,8 @@ implementation + include(current_procinfo.flags,pi_needs_got); + if left.nodetype<>typen then + begin +- if (is_objc_class_or_protocol(left.resultdef) or ++ if (target_info.system=system_aarch64_darwin) and ++ (is_objc_class_or_protocol(left.resultdef) or + is_objcclassref(left.resultdef)) then + begin + { on non-fragile ABI platforms, the ISA pointer may be opaque +@@ -294,7 +303,7 @@ implementation + TLOADPARENTFPNODE + *****************************************************************************} + +- constructor tloadparentfpnode.create(pd:tprocdef); ++ constructor tloadparentfpnode.create(pd: tprocdef; fpkind: tloadparentfpkind); + begin + inherited create(loadparentfpn,nil); + if not assigned(pd) then +@@ -302,6 +311,7 @@ implementation + if (pd.parast.symtablelevel>current_procinfo.procdef.parast.symtablelevel) then + internalerror(200309284); + parentpd:=pd; ++ kind:=fpkind; + end; + + +@@ -309,6 +319,7 @@ implementation + begin + inherited ppuload(t,ppufile); + ppufile.getderef(parentpdderef); ++ kind:=tloadparentfpkind(ppufile.getbyte); + end; + + +@@ -316,6 +327,7 @@ implementation + begin + inherited ppuwrite(ppufile); + ppufile.putderef(parentpdderef); ++ ppufile.putbyte(byte(kind)); + end; + + +@@ -337,7 +349,8 @@ implementation + begin + result:= + inherited docompare(p) and +- (tloadparentfpnode(p).parentpd=parentpd); ++ (tloadparentfpnode(p).parentpd=parentpd) and ++ (tloadparentfpnode(p).kind=kind); + end; + + +@@ -347,6 +360,7 @@ implementation + begin + p:=tloadparentfpnode(inherited dogetcopy); + p.parentpd:=parentpd; ++ p.kind:=kind; + dogetcopy:=p; + end; + +Index: fpc/fpcsrc/compiler/objcgutl.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/objcgutl.pas ++++ fpc/fpcsrc/compiler/objcgutl.pas +@@ -91,7 +91,7 @@ implementation + end; + + +- { Used by PowerPC/64, ARM, and x86_64 } ++ { Used by PowerPC/64, ARM, x86_64 and AArch64 } + tobjcrttiwriter_nonfragile = class(tobjcrttiwriter) + protected + ObjCEmptyCacheVar, +Index: fpc/fpcsrc/compiler/objcutil.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/objcutil.pas ++++ fpc/fpcsrc/compiler/objcutil.pas +@@ -153,13 +153,13 @@ end; + { in case we are in a category method, we need the metaclass of the + superclass class extended by this category (= metaclass of superclass of superclass) + for the fragile abi, and the metaclass of the superclass for the non-fragile ABI } +-{$if defined(onlymacosx10_6) or defined(arm) } ++{$if defined(onlymacosx10_6) or defined(arm) or defined(aarch64)} + { NOTE: those send2 methods are only available on Mac OS X 10.6 and later! + (but also on all iPhone SDK revisions we support) } + if (target_info.system in systems_objc_nfabi) then + result:=cloadvmtaddrnode.create(ctypenode.create(tobjectdef(tclassrefdef(def).pointeddef).childof)) + else +-{$endif onlymacosx10_6 or arm} ++{$endif onlymacosx10_6 or arm aarch64} + result:=cloadvmtaddrnode.create(ctypenode.create(tobjectdef(tclassrefdef(def).pointeddef).childof.childof)); + tloadvmtaddrnode(result).forcall:=true; + result:=cloadvmtaddrnode.create(result); +@@ -183,14 +183,14 @@ end; + tloadvmtaddrnode(result).forcall:=true; + end; + +-{$if defined(onlymacosx10_6) or defined(arm) } ++{$if defined(onlymacosx10_6) or defined(arm) or defined(aarch64)} + { For the non-fragile ABI, the superclass send2 method itself loads the + superclass. For the fragile ABI, we have to do this ourselves. + + NOTE: those send2 methods are only available on Mac OS X 10.6 and later! + (but also on all iPhone SDK revisions we support) } + if not(target_info.system in systems_objc_nfabi) then +-{$endif onlymacosx10_6 or arm} ++{$endif onlymacosx10_6 or arm or aarch64} + result:=objcloadbasefield(result,'SUPERCLASS'); + typecheckpass(result); + end; +Index: fpc/fpcsrc/compiler/ogbase.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ogbase.pas ++++ fpc/fpcsrc/compiler/ogbase.pas +@@ -68,6 +68,8 @@ interface + {$endif i386} + {$ifdef arm} + RELOC_RELATIVE_24, ++ RELOC_RELATIVE_24_THUMB, ++ RELOC_RELATIVE_CALL_THUMB, + {$endif arm} + { Relative relocation } + RELOC_RELATIVE, +@@ -170,6 +172,10 @@ interface + { Darwin asm is using indirect symbols resolving } + indsymbol : TObjSymbol; + ++{$ifdef ARM} ++ ThumbFunc : boolean; ++{$endif ARM} ++ + constructor create(AList:TFPHashObjectList;const AName:string); + function address:aword; + procedure SetAddress(apass:byte;aobjsec:TObjSection;abind:TAsmsymbind;atyp:Tasmsymtype); +@@ -287,6 +293,9 @@ interface + public + CurrPass : byte; + ExecStack : boolean; ++{$ifdef ARM} ++ ThumbFunc : boolean; ++{$endif ARM} + constructor create(const n:string);virtual; + destructor destroy;override; + { Sections } +@@ -982,6 +991,9 @@ implementation + FCachedAsmSymbolList:=TFPObjectList.Create(false); + { section class type for creating of new sections } + FCObjSection:=TObjSection; ++{$ifdef ARM} ++ ThumbFunc:=false; ++{$endif ARM} + end; + + +@@ -1166,6 +1178,11 @@ implementation + result:=TObjSymbol(FObjSymbolList.Find(aname)); + if not assigned(result) then + result:=TObjSymbol.Create(FObjSymbolList,aname); ++ ++{$ifdef ARM} ++ result.ThumbFunc:=ThumbFunc; ++ ThumbFunc:=false; ++{$endif ARM} + end; + + +Index: fpc/fpcsrc/compiler/ogcoff.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ogcoff.pas ++++ fpc/fpcsrc/compiler/ogcoff.pas +@@ -261,9 +261,9 @@ interface + TLSDIR_SIZE = $18; + {$endif i386} + {$ifdef arm} +- COFF_MAGIC = $1c0; + COFF_OPT_MAGIC = $10b; + TLSDIR_SIZE = $18; ++ function COFF_MAGIC: word; + {$endif arm} + {$ifdef x86_64} + COFF_MAGIC = $8664; +@@ -422,6 +422,11 @@ implementation + IMAGE_REL_ARM_BLX11 = $0009; + IMAGE_REL_ARM_SECTION = $000E; { Section table index } + IMAGE_REL_ARM_SECREL = $000F; { Offset within section } ++ IMAGE_REL_ARM_MOV32A = $0010; { 32-bit VA applied to MOVW+MOVT pair, added to existing imm (ARM) } ++ IMAGE_REL_ARM_MOV32T = $0011; { 32-bit VA applied to MOVW+MOVT pair, added to existing imm (THUMB) } ++ IMAGE_REL_ARM_BRANCH20T = $0012; { Thumb: 20 most significant bits of 32 bit B cond instruction } ++ IMAGE_REL_ARM_BRANCH24T = $0014; { Thumb: 24 most significant bits of 32 bit B uncond instruction } ++ IMAGE_REL_ARM_BLX23T = $0015; { 23 most significant bits of 32 bit BL/BLX instruction. Transformed to BLX if target is Thumb } + {$endif arm} + + {$ifdef i386} +@@ -913,6 +918,14 @@ const pemagic : array[0..3] of byte = ( + if (relocval<>$3f) and (relocval<>0) then + internalerror(200606085); { offset overflow } + end; ++ RELOC_RELATIVE_24_THUMB: ++ begin ++ relocval:=longint(relocval - objsec.mempos - objreloc.dataoffset) shr 1 - 4; ++ address:=address or ((relocval shr 1) and $ffffff) or ((relocval and 1) shl 24); ++ relocval:=relocval shr 25; ++ if (relocval<>$3f) and (relocval<>0) then ++ internalerror(200606085); { offset overflow } ++ end; + {$endif arm} + {$ifdef x86_64} + { 64 bit coff only } +@@ -1009,10 +1022,9 @@ const pemagic : array[0..3] of byte = ( + result:=aname + else + begin +- { non-PECOFF targets lack rodata support. +- TODO: WinCE likely supports it, but needs testing. } ++ { non-PECOFF targets lack rodata support } + if (atype in [sec_rodata,sec_rodata_norel]) and +- not (target_info.system in systems_windows) then ++ not (target_info.system in systems_all_windows) then + atype:=sec_data; + secname:=coffsecnames[atype]; + if create_smartlink_sections and +@@ -1038,8 +1050,7 @@ const pemagic : array[0..3] of byte = ( + begin + if (aType in [sec_rodata,sec_rodata_norel]) then + begin +- { TODO: WinCE needs testing } +- if (target_info.system in systems_windows) then ++ if (target_info.system in systems_all_windows) then + aType:=sec_rodata_norel + else + aType:=sec_data; +@@ -1279,6 +1290,10 @@ const pemagic : array[0..3] of byte = ( + rel.reloctype:=IMAGE_REL_ARM_ADDR32NB; + RELOC_SECREL32 : + rel.reloctype:=IMAGE_REL_ARM_SECREL; ++ RELOC_RELATIVE_24 : ++ rel.reloctype:=IMAGE_REL_ARM_BRANCH24; ++ RELOC_RELATIVE_24_THUMB: ++ rel.reloctype:=IMAGE_REL_ARM_BLX24; + {$endif arm} + {$ifdef i386} + RELOC_RELATIVE : +@@ -1597,6 +1612,8 @@ const pemagic : array[0..3] of byte = ( + rel_type:=RELOC_RELATIVE_24; + IMAGE_REL_ARM_SECREL: + rel_type:=RELOC_SECREL32; ++ IMAGE_REL_ARM_BLX24: ++ rel_type:=RELOC_RELATIVE_24_THUMB; + {$endif arm} + {$ifdef i386} + IMAGE_REL_I386_PCRLONG : +@@ -2962,6 +2979,15 @@ const pemagic : array[0..3] of byte = ( + DLLReader.Free; + end; + ++{$ifdef arm} ++ function COFF_MAGIC: word; ++ begin ++ if GenerateThumb2Code and (current_settings.cputype>=cpu_armv7) then ++ COFF_MAGIC:=$1c4 // IMAGE_FILE_MACHINE_ARMNT ++ else ++ COFF_MAGIC:=$1c0; // IMAGE_FILE_MACHINE_ARM ++ end; ++{$endif arm} + + {***************************************************************************** + Initialize +@@ -3045,7 +3071,7 @@ const pemagic : array[0..3] of byte = ( + asmbin : ''; + asmcmd : ''; + supported_targets : [system_arm_wince]; +- flags : [af_outputbinary]; ++ flags : [af_outputbinary,af_smartlink_sections]; + labelprefix : '.L'; + comment : ''; + dollarsign: '$'; +Index: fpc/fpcsrc/compiler/ogelf.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ogelf.pas ++++ fpc/fpcsrc/compiler/ogelf.pas +@@ -181,6 +181,7 @@ interface + TEncodeRelocProc=function(objrel:TObjRelocation):byte; + TLoadRelocProc=procedure(objrel:TObjRelocation); + TLoadSectionProc=function(objinput:TElfObjInput;objdata:TObjData;const shdr:TElfsechdr;shindex:longint):boolean; ++ TEncodeFlagsProc=function:longword; + TDynamicReloc=( + dr_relative, + dr_glob_dat, +@@ -199,6 +200,7 @@ interface + encodereloc: TEncodeRelocProc; + loadreloc: TLoadRelocProc; + loadsection: TLoadSectionProc; ++ encodeflags: TEncodeFlagsProc; + end; + + +@@ -966,6 +968,12 @@ implementation + elfsym.st_name:=nameidx; + elfsym.st_size:=objsym.size; + elfsym.st_value:=objsym.address; ++ ++{$ifdef ARM} ++ if objsym.ThumbFunc then ++ inc(elfsym.st_value); ++{$endif ARM} ++ + case objsym.bind of + AB_LOCAL : + begin +@@ -1272,6 +1280,8 @@ implementation + header.e_shnum:=nsections; + header.e_ehsize:=sizeof(telfheader); + header.e_shentsize:=sizeof(telfsechdr); ++ if assigned(ElfTarget.encodeflags) then ++ header.e_flags:=ElfTarget.encodeflags(); + MaybeSwapHeader(header); + writer.write(header,sizeof(header)); + writer.writezeros($40-sizeof(header)); { align } +@@ -2043,6 +2053,8 @@ implementation + header.e_shnum:=ExeSectionList.Count+1; + header.e_phnum:=segmentlist.count; + header.e_ehsize:=sizeof(telfheader); ++ if assigned(ElfTarget.encodeflags) then ++ header.e_flags:=ElfTarget.encodeflags(); + if assigned(EntrySym) then + header.e_entry:=EntrySym.Address; + header.e_shentsize:=sizeof(telfsechdr); +Index: fpc/fpcsrc/compiler/options.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/options.pas ++++ fpc/fpcsrc/compiler/options.pas +@@ -646,6 +646,9 @@ begin + {$ifdef i8086} + '8', + {$endif} ++{$ifdef aarch64} ++ 'a', ++{$endif} + {$ifdef arm} + 'A', + {$endif} +@@ -895,7 +898,7 @@ begin + if MacVersionSet then + exit; + { check for deployment target set via environment variable } +- if not(target_info.system in [system_i386_iphonesim,system_arm_darwin]) then ++ if not(target_info.system in [system_i386_iphonesim,system_arm_darwin,system_aarch64_darwin,system_x86_64_iphonesim]) then + begin + envstr:=GetEnvironmentVariable('MACOSX_DEPLOYMENT_TARGET'); + if envstr<>'' then +@@ -939,6 +942,12 @@ begin + set_system_compvar('IPHONE_OS_VERSION_MIN_REQUIRED','30000'); + iPhoneOSVersionMin:='3.0'; + end; ++ system_aarch64_darwin, ++ system_x86_64_iphonesim: ++ begin ++ set_system_compvar('IPHONE_OS_VERSION_MIN_REQUIRED','70000'); ++ iPhoneOSVersionMin:='7.0'; ++ end + else + internalerror(2012031001); + end; +@@ -1487,10 +1496,16 @@ begin + Message2(option_obsolete_switch_use_new,'-Fg','-Fl'); + 'l' : + begin +- if ispara then +- ParaLibraryPath.AddPath(sysrootpath,More,false) ++ if path_absolute(More) then ++ if ispara then ++ ParaLibraryPath.AddPath(sysrootpath,More,false) ++ else ++ LibrarySearchPath.AddPath(sysrootpath,More,true) + else +- LibrarySearchPath.AddPath(sysrootpath,More,true); ++ if ispara then ++ ParaLibraryPath.AddPath('',More,false) ++ else ++ LibrarySearchPath.AddPath('',More,true); + end; + 'L' : + begin +@@ -2210,7 +2225,7 @@ begin + end; + 'M': + begin +- if (target_info.system in (systems_darwin-[system_i386_iphonesim])) and ++ if (target_info.system in (systems_darwin-[system_i386_iphonesim,system_arm_darwin,system_aarch64_darwin,system_x86_64_iphonesim])) and + ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED',copy(More,2,255),false) then + begin + break; +@@ -2243,7 +2258,7 @@ begin + end; + 'P': + begin +- if (target_info.system in [system_i386_iphonesim,system_arm_darwin]) and ++ if (target_info.system in [system_i386_iphonesim,system_arm_darwin,system_aarch64_darwin,system_x86_64_iphonesim]) and + ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED',copy(More,2,255),true) then + begin + break; +@@ -3218,9 +3233,9 @@ begin + + { abs(long) is handled internally on all CPUs } + def_system_macro('FPC_HAS_INTERNAL_ABS_LONG'); +-{$if defined(x86_64) or defined(powerpc64)} ++{$if defined(x86_64) or defined(powerpc64) or defined(cpuaarch64)} + def_system_macro('FPC_HAS_INTERNAL_ABS_INT64'); +-{$endif x86_64 or powerpc64} ++{$endif x86_64 or powerpc64 or aarch64} + + def_system_macro('FPC_HAS_UNICODESTRING'); + def_system_macro('FPC_RTTI_PACKSET1'); +@@ -3403,6 +3418,12 @@ begin + mm_huge: def_system_macro('FPC_MM_HUGE'); + end; + {$endif i8086} ++{$ifdef aarch64} ++ def_system_macro('CPUAARCH64'); ++ def_system_macro('CPU64'); ++ def_system_macro('FPC_CURRENCY_IS_INT64'); ++ def_system_macro('FPC_COMP_IS_INT64'); ++{$endif aarch64} + + if tf_cld in target_info.flags then + if not UpdateTargetSwitchStr('CLD', init_settings.targetswitches, true) then +@@ -3689,14 +3710,15 @@ begin + case target_info.system of + system_arm_darwin: + begin +- { set default cpu type to ARMv6 for Darwin unless specified otherwise, and fpu +- to VFPv2 } ++ { set default cpu type to ARMv7 for Darwin unless specified otherwise, and fpu ++ to VFPv3 (that's what all 32 bit ARM iOS devices use nowadays) ++ } + if not option.CPUSetExplicitly then +- init_settings.cputype:=cpu_armv6; ++ init_settings.cputype:=cpu_armv7; + if not option.OptCPUSetExplicitly then +- init_settings.optimizecputype:=cpu_armv6; ++ init_settings.optimizecputype:=cpu_armv7; + if not option.FPUSetExplicitly then +- init_settings.fputype:=fpu_vfpv2; ++ init_settings.fputype:=fpu_vfpv3; + end; + system_arm_android: + begin +@@ -3796,7 +3818,7 @@ if (target_info.abi = abi_eabihf) then + {$endif} + def_system_macro('FPC_HAS_TYPE_SINGLE'); + def_system_macro('FPC_HAS_TYPE_DOUBLE'); +-{$if not defined(i386) and not defined(x86_64) and not defined(i8086)} ++{$if not defined(i386) and not defined(x86_64) and not defined(i8086) and not defined(aarch64)} + def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE'); + {$endif} + {$if defined(m68k)} +@@ -3836,7 +3858,7 @@ if (target_info.abi = abi_eabihf) then + {$endif ARM} + + { inline bsf/bsr implementation } +-{$if defined(i386) or defined(x86_64)} ++{$if defined(i386) or defined(x86_64) or defined(aarch64)} + def_system_macro('FPC_HAS_INTERNAL_BSF'); + def_system_macro('FPC_HAS_INTERNAL_BSR'); + {$endif} +Index: fpc/fpcsrc/compiler/pparautl.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/pparautl.pas ++++ fpc/fpcsrc/compiler/pparautl.pas +@@ -308,11 +308,21 @@ implementation + { We need a local copy for a value parameter when only the + address is pushed. Open arrays and Array of Const are + an exception because they are allocated at runtime and the +- address that is pushed is patched } ++ address that is pushed is patched. ++ ++ Arrays passed to cdecl routines are special: they are pointers in ++ C and hence must be passed as such. Due to historical reasons, if ++ a cdecl routine is implemented in Pascal, we still make a copy on ++ the callee side. Do this the same on platforms that normally must ++ make a copy on the caller side, as otherwise the behaviour will ++ be different (and less perfomant) for routines implemented in C } + if (varspez=vs_value) and + paramanager.push_addr_param(varspez,vardef,pd.proccalloption) and + not(is_open_array(vardef) or +- is_array_of_const(vardef)) then ++ is_array_of_const(vardef)) and ++ (not(target_info.system in systems_caller_copy_addr_value_para) or ++ ((pd.proccalloption in cdecl_pocalls) and ++ (vardef.typ=arraydef))) then + include(varoptions,vo_has_local_copy); + + { needs high parameter ? } +Index: fpc/fpcsrc/compiler/ppu.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/ppu.pas ++++ fpc/fpcsrc/compiler/ppu.pas +@@ -188,7 +188,8 @@ const + { 12 } 16 {'avr'}, + { 13 } 32 {'mipsel'}, + { 14 } 32 {'jvm'}, +- { 15 } 16 {'i8086'} ++ { 15 } 16 {'i8086'}, ++ { 16 } 64 {'aarch64'} + ); + CpuAluBitSize : array[tsystemcpu] of longint = + ( +@@ -207,7 +208,8 @@ const + { 12 } 8 {'avr'}, + { 13 } 32 {'mipsel'}, + { 14 } 64 {'jvm'}, +- { 15 } 16 {'i8086'} ++ { 15 } 16 {'i8086'}, ++ { 16 } 64 {'aarch64'} + ); + {$endif generic_cpu} + +Index: fpc/fpcsrc/compiler/psub.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/psub.pas ++++ fpc/fpcsrc/compiler/psub.pas +@@ -161,6 +161,12 @@ implementation + Message(parser_h_inlining_disabled); + exit; + end; ++ if pi_calls_c_varargs in current_procinfo.flags then ++ begin ++ Message1(parser_h_not_supported_for_inline,'called C-style varargs functions'); ++ Message(parser_h_inlining_disabled); ++ exit; ++ end; + { the compiler cannot handle inherited in inlined subroutines because + it tries to search for self in the symtable, however, the symtable + is not available } +Index: fpc/fpcsrc/compiler/psystem.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/psystem.pas ++++ fpc/fpcsrc/compiler/psystem.pas +@@ -268,6 +268,10 @@ implementation + create_fpu_types; + s64currencytype:=corddef.create(scurrency,low(int64),high(int64)); + {$endif arm} ++{$ifdef aarch64} ++ create_fpu_types; ++ s64currencytype:=corddef.create(scurrency,low(int64),high(int64)); ++{$endif aarch64} + {$ifdef avr} + s32floattype:=cfloatdef.create(s32real); + s64floattype:=cfloatdef.create(s64real); +@@ -734,7 +738,6 @@ implementation + // aiclass[ait_labeled_instruction]:=tai_labeled_instruction; + {$endif SPARC} + {$ifdef arm} +- aiclass[ait_thumb_func]:=tai_thumb_func; + aiclass[ait_thumb_set]:=tai_thumb_set; + {$endif arm} + aiclass[ait_set]:=tai_set; +Index: fpc/fpcsrc/compiler/raatt.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/raatt.pas ++++ fpc/fpcsrc/compiler/raatt.pas +@@ -287,12 +287,24 @@ unit raatt; + end; + {$endif POWERPC} + {$if defined(ARM)} +- { Thumb-2 instructions can have a .W postfix to indicate 32bit instructions ++ { ++ Thumb-2 instructions can have a .W postfix to indicate 32bit instructions, ++ Also in unified syntax sizes and types are indicated with something like a .
prefix for example + } + case c of + '.': + begin +- actasmpattern:=actasmpattern+c; ++ if len>1 then ++ begin ++ while c in ['A'..'Z','a'..'z','0'..'9','_','.'] do ++ begin ++ inc(len); ++ actasmpattern[len]:=c; ++ c:=current_scanner.asmgetchar; ++ end; ++ actasmpattern[0]:=chr(len); ++ end; ++ {actasmpattern:=actasmpattern+c; + c:=current_scanner.asmgetchar; + + if upcase(c) = 'W' then +@@ -301,10 +313,22 @@ unit raatt; + c:=current_scanner.asmgetchar; + end + else +- internalerror(2010122301); ++ internalerror(2010122301);} + end + end; + {$endif ARM} ++{$ifdef aarch64} ++ { b.cond } ++ case c of ++ '.': ++ begin ++ repeat ++ actasmpattern:=actasmpattern+c; ++ c:=current_scanner.asmgetchar; ++ until not(c in ['a'..'z','A'..'Z']); ++ end; ++ end; ++{$endif aarch64} + { Opcode ? } + If is_asmopcode(upper(actasmpattern)) then + Begin +@@ -1282,10 +1306,16 @@ unit raatt; + while (actasmtoken=AS_DOT) do + begin + Consume(AS_DOT); +- if actasmtoken=AS_ID then +- s:=s+'.'+actasmpattern; +- if not Consume(AS_ID) then ++ ++ { a record field could have the same name as a register } ++ if actasmtoken in [AS_ID,AS_REGISTER] then ++ begin ++ s:=s+'.'+actasmpattern; ++ consume(actasmtoken) ++ end ++ else + begin ++ Consume(AS_ID); + RecoverConsume(true); + break; + end; +Index: fpc/fpcsrc/compiler/rautils.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/rautils.pas ++++ fpc/fpcsrc/compiler/rautils.pas +@@ -69,6 +69,10 @@ type + OPR_MODEFLAGS : (flags : tcpumodeflags); + OPR_SPECIALREG: (specialreg : tregister; specialregflags : tspecialregflags); + {$endif arm} ++{$ifdef aarch64} ++ OPR_SHIFTEROP : (shifterop : tshifterop); ++ OPR_COND : (cc : tasmcond); ++{$endif aarch64} + end; + + TOperand = class +@@ -1062,15 +1066,17 @@ end; + {$ifdef ARM} + OPR_REGSET: + ai.loadregset(i-1,regtype,subreg,regset,usermode); +- OPR_SHIFTEROP: +- ai.loadshifterop(i-1,shifterop); +- OPR_COND: +- ai.loadconditioncode(i-1,cc); + OPR_MODEFLAGS: + ai.loadmodeflags(i-1,flags); + OPR_SPECIALREG: + ai.loadspecialreg(i-1,specialreg,specialregflags); + {$endif ARM} ++{$if defined(arm) or defined(aarch64)} ++ OPR_SHIFTEROP: ++ ai.loadshifterop(i-1,shifterop); ++ OPR_COND: ++ ai.loadconditioncode(i-1,cc); ++{$endif arm or aarch64} + { ignore wrong operand } + OPR_NONE: + ; +Index: fpc/fpcsrc/compiler/sparc/cpuelf.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/sparc/cpuelf.pas ++++ fpc/fpcsrc/compiler/sparc/cpuelf.pas +@@ -114,6 +114,7 @@ implementation + encodereloc: @elf_sparc_encodeReloc; + loadreloc: @elf_sparc_loadReloc; + loadsection: nil; ++ encodeflags: nil; + ); + + as_sparc_elf32_info : tasminfo = +Index: fpc/fpcsrc/compiler/symdef.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/symdef.pas ++++ fpc/fpcsrc/compiler/symdef.pas +@@ -2830,6 +2830,7 @@ implementation + sc80real: + if target_info.system in [system_i386_darwin, + system_i386_iphonesim,system_x86_64_darwin, ++ system_x86_64_iphonesim, + system_x86_64_linux,system_x86_64_freebsd, + system_x86_64_openbsd,system_x86_64_netbsd, + system_x86_64_solaris,system_x86_64_embedded, +@@ -7504,7 +7505,7 @@ implementation + begin + if assigned(objc_fastenumeration) then + exit; +- if not(target_info.system in [system_arm_darwin,system_i386_iphonesim]) then ++ if not(target_info.system in [system_arm_darwin,system_i386_iphonesim,system_aarch64_darwin,system_x86_64_iphonesim]) then + cocoaunit:='COCOAALL' + else + cocoaunit:='IPHONEALL'; +@@ -7532,6 +7533,11 @@ implementation + {$define use_vectorfpuimplemented} + use_vectorfpu:=(current_settings.fputype in vfp_scalar); + {$endif arm} ++{$ifdef aarch64} ++{$define use_vectorfpuimplemented} ++ use_vectorfpu:=true; ++{$endif aarch64} ++ + {$ifndef use_vectorfpuimplemented} + use_vectorfpu:=false; + {$endif} +Index: fpc/fpcsrc/compiler/systems/i_bsd.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/systems/i_bsd.pas ++++ fpc/fpcsrc/compiler/systems/i_bsd.pas +@@ -952,6 +952,69 @@ unit i_bsd; + ); + + ++ system_x86_64_iphonesim_info : tsysteminfo = ++ ( ++ system : system_x86_64_iphonesim; ++ name : 'Darwin/iPhoneSim for x86_64'; ++ shortname : 'iPhoneSim'; ++ flags : [tf_p_ext_support,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_default,tf_has_winlike_resources]; ++ cpu : cpu_x86_64; ++ unit_env : 'BSDUNITS'; ++ extradefines : 'UNIX;BSD;HASUNIX;DARWIN'; // also define darwin for code compatibility ++ exeext : ''; ++ defext : '.def'; ++ scriptext : '.sh'; ++ smartext : '.sl'; ++ unitext : '.ppu'; ++ unitlibext : '.ppl'; ++ asmext : '.s'; ++ objext : '.o'; ++ resext : '.res'; ++ resobjext : '.or'; ++ sharedlibext : '.dylib'; ++ staticlibext : '.a'; ++ staticlibprefix : 'libp'; ++ sharedlibprefix : 'lib'; ++ sharedClibext : '.dylib'; ++ staticClibext : '.a'; ++ staticClibprefix : 'lib'; ++ sharedClibprefix : 'lib'; ++ importlibprefix : 'libimp'; ++ importlibext : '.a'; ++ Cprefix : '_'; ++ newline : #10; ++ dirsep : '/'; ++ assem : as_clang; ++ assemextern : as_clang; ++ link : ld_none; ++ linkextern : ld_bsd; ++ ar : ar_gnu_ar; ++ res : res_macho; ++ dbg : dbg_dwarf2; ++ script : script_unix; ++ endian : endian_little; ++ alignment : ++ ( ++ procalign : 8; ++ loopalign : 4; ++ jumpalign : 0; ++ constalignmin : 0; ++ constalignmax : 8; ++ varalignmin : 0; ++ varalignmax : 16; ++ localalignmin : 4; ++ localalignmax : 16; ++ recordalignmin : 0; ++ recordalignmax : 16; ++ maxCrecordalign : 16 ++ ); ++ first_parm_offset : 16; ++ stacksize : 262144; ++ stackalign : 16; ++ abi : abi_default; ++ ); ++ ++ + system_arm_darwin_info : tsysteminfo = + ( + system : system_arm_darwin; +@@ -984,8 +1047,8 @@ unit i_bsd; + Cprefix : '_'; + newline : #10; + dirsep : '/'; +- assem : as_darwin; +- assemextern : as_darwin; ++ assem : as_clang; ++ assemextern : as_clang; + link : ld_none; + linkextern : ld_bsd; + ar : ar_gnu_ar; +@@ -1014,6 +1077,71 @@ unit i_bsd; + abi : abi_default + ); + ++ ++ system_aarch64_darwin_info : tsysteminfo = ++ ( ++ system : system_aarch64_darwin; ++ name : 'Darwin for AArch64'; ++ shortname : 'Darwin'; ++ flags : [tf_p_ext_support,tf_requires_proper_alignment,tf_files_case_sensitive,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_default,tf_has_winlike_resources]; ++ cpu : cpu_aarch64; ++ unit_env : 'BSDUNITS'; ++ extradefines : 'UNIX;BSD;HASUNIX'; ++ exeext : ''; ++ defext : '.def'; ++ scriptext : '.sh'; ++ smartext : '.sl'; ++ unitext : '.ppu'; ++ unitlibext : '.ppl'; ++ asmext : '.s'; ++ objext : '.o'; ++ resext : '.res'; ++ resobjext : '.or'; ++ sharedlibext : '.dylib'; ++ staticlibext : '.a'; ++ staticlibprefix : 'libp'; ++ sharedlibprefix : 'lib'; ++ sharedClibext : '.dylib'; ++ staticClibext : '.a'; ++ staticClibprefix : 'lib'; ++ sharedClibprefix : 'lib'; ++ importlibprefix : 'libimp'; ++ importlibext : '.a'; ++ Cprefix : '_'; ++ newline : #10; ++ dirsep : '/'; ++ assem : as_clang; ++ assemextern : as_clang; ++ link : ld_none; ++ linkextern : ld_bsd; ++ ar : ar_gnu_ar; ++ res : res_macho; ++ dbg : dbg_dwarf2; ++ script : script_unix; ++ endian : endian_little; ++ alignment : ++ ( ++ procalign : 8; ++ loopalign : 4; ++ jumpalign : 0; ++ constalignmin : 0; ++ constalignmax : 8; ++ varalignmin : 0; ++ varalignmax : 16; ++ localalignmin : 4; ++ localalignmax : 16; ++ recordalignmin : 0; ++ recordalignmax : 16; ++ maxCrecordalign : 16 ++ ); ++ first_parm_offset : 16; ++ stacksize : 8*1024*1024; ++ stackalign : 16; ++ abi : abi_aarch64_darwin; ++ ); ++ ++ ++ + implementation + + initialization +@@ -1071,4 +1199,9 @@ initialization + set_source_info(system_arm_darwin_info); + {$endif Darwin} + {$endif cpuarm} ++{$ifdef cpuaarch64} ++ {$ifdef Darwin} ++ set_source_info(system_aarch64_darwin_info); ++ {$endif Darwin} ++{$endif cpuaarch64} + end. +Index: fpc/fpcsrc/compiler/systems/i_linux.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/systems/i_linux.pas ++++ fpc/fpcsrc/compiler/systems/i_linux.pas +@@ -811,6 +811,73 @@ unit i_linux; + {$endif FPC_ARMEL} + {$endif FPC_ARMHF} + ++ system_aarch64_linux_info : tsysteminfo = ++ ( ++ system : system_aarch64_linux; ++ name : 'Linux for AArch64'; ++ shortname : 'Linux'; ++ flags : [tf_needs_symbol_size, ++ tf_needs_symbol_type, ++ tf_files_case_sensitive, ++ tf_requires_proper_alignment, ++ tf_smartlink_sections,tf_pic_uses_got, ++ tf_has_winlike_resources]; ++ cpu : cpu_aarch64; ++ unit_env : 'LINUXUNITS'; ++ extradefines : 'UNIX;HASUNIX'; ++ exeext : ''; ++ defext : '.def'; ++ scriptext : '.sh'; ++ smartext : '.sl'; ++ unitext : '.ppu'; ++ unitlibext : '.ppl'; ++ asmext : '.s'; ++ objext : '.o'; ++ resext : '.res'; ++ resobjext : '.or'; ++ sharedlibext : '.so'; ++ staticlibext : '.a'; ++ staticlibprefix : 'libp'; ++ sharedlibprefix : 'lib'; ++ sharedClibext : '.so'; ++ staticClibext : '.a'; ++ staticClibprefix : 'lib'; ++ sharedClibprefix : 'lib'; ++ importlibprefix : 'libimp'; ++ importlibext : '.a'; ++ Cprefix : ''; ++ newline : #10; ++ dirsep : '/'; ++ assem : as_gas; ++ assemextern : as_gas; ++ link : ld_none; ++ linkextern : ld_linux; ++ ar : ar_gnu_ar; ++ res : res_elf; ++ dbg : dbg_dwarf2; ++ script : script_unix; ++ endian : endian_little; ++ alignment : ++ ( ++ procalign : 8; ++ loopalign : 4; ++ jumpalign : 0; ++ constalignmin : 0; ++ constalignmax : 8; ++ varalignmin : 0; ++ varalignmax : 16; ++ localalignmin : 4; ++ localalignmax : 16; ++ recordalignmin : 0; ++ recordalignmax : 16; ++ maxCrecordalign : 16 ++ ); ++ first_parm_offset : 16; ++ stacksize : 8*1024*1024; ++ stackalign : 16; ++ abi : abi_default; ++ ); ++ + system_mipseb_linux_info : tsysteminfo = + ( + system : system_mipseb_LINUX; +@@ -987,6 +1054,11 @@ initialization + set_source_info(system_arm_linux_info); + {$endif linux} + {$endif CPUARM} ++{$ifdef cpuaarch64} ++ {$ifdef linux} ++ set_source_info(system_aarch64_linux_info); ++ {$endif linux} ++{$endif cpuaarch64} + {$ifdef CPUMIPSEB} + {$ifdef linux} + set_source_info(system_mipseb_linux_info); +Index: fpc/fpcsrc/compiler/systems/i_win.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/systems/i_win.pas ++++ fpc/fpcsrc/compiler/systems/i_win.pas +@@ -198,7 +198,7 @@ unit i_win; + Cprefix : ''; + newline : #13#10; + dirsep : '\'; +- assem : as_gas; ++ assem : as_arm_pecoffwince; + assemextern : as_gas; + link : ld_int_windows; + linkextern : ld_windows; +Index: fpc/fpcsrc/compiler/systems/t_bsd.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/systems/t_bsd.pas ++++ fpc/fpcsrc/compiler/systems/t_bsd.pas +@@ -230,28 +230,49 @@ begin + begin + if not(cs_profile in current_settings.moduleswitches) then + begin +- { 10.8 and later: no crt1.* } +- if CompareVersionStrings(MacOSXVersionMin,'10.8')>=0 then +- exit(''); +- { x86: crt1.10.6.o -> crt1.10.5.o -> crt1.o } +- { others: crt1.10.5 -> crt1.o } +-{$if defined(i386) or defined(x86_64)} +- if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then +- exit('crt1.10.6.o'); +-{$endif} +- if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then +- exit('crt1.10.5.o'); +-{$if defined(arm)} +- { iOS: +- iOS 6 and later: nothing +- iOS 3.1 - 5.x: crt1.3.1.o +- pre-iOS 3.1: crt1.o +- } +- if (CompareVersionStrings(iPhoneOSVersionMin,'6.0')>=0) then +- exit(''); +- if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then +- exit('crt1.3.1.o'); +-{$endif} ++ case target_info.system of ++ system_powerpc_darwin, ++ system_powerpc64_darwin, ++ system_i386_darwin, ++ system_x86_64_darwin: ++ begin ++ { 10.8 and later: no crt1.* } ++ if CompareVersionStrings(MacOSXVersionMin,'10.8')>=0 then ++ exit(''); ++ { x86: crt1.10.6.o -> crt1.10.5.o -> crt1.o } ++ { others: crt1.10.5 -> crt1.o } ++ if (target_info.system in [system_i386_darwin,system_x86_64_darwin]) and ++ (CompareVersionStrings(MacOSXVersionMin,'10.6')>=0) then ++ exit('crt1.10.6.o'); ++ if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then ++ exit('crt1.10.5.o'); ++ end; ++ system_arm_darwin: ++ begin ++ { iOS: ++ iOS 6 and later: nothing ++ iOS 3.1 - 5.x: crt1.3.1.o ++ pre-iOS 3.1: crt1.o ++ } ++ if (CompareVersionStrings(iPhoneOSVersionMin,'6.0')>=0) then ++ exit(''); ++ if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then ++ exit('crt1.3.1.o'); ++ end; ++ system_i386_iphonesim, ++ system_x86_64_iphonesim: ++ begin ++ { "recent versions" must not use anything (https://github.com/llvm-mirror/clang/commit/e6d04f3d152a22077022cf9287d4c538a0918ab0 ) ++ What those recent versions could be, is anyone's guess. It ++ still seems to work with 8.1 and no longer with 8.3, so use ++ 8.1 as a cut-off point } ++ if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then ++ exit(''); ++ end; ++ system_aarch64_darwin: ++ { never anything } ++ exit(''); ++ end; + { nothing special -> default } + result:='crt1.o'; + end +@@ -268,34 +289,68 @@ begin + begin + if (apptype=app_bundle) then + begin +- { < 10.6: bundle1.o +- >= 10.6: nothing } +- if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then +- exit(''); +- { iOS: < 3.1: bundle1.o +- >= 3.1: nothing } +-{$if defined(arm)} +- if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then +- exit(''); +-{$endif} ++ case target_info.system of ++ system_powerpc_darwin, ++ system_powerpc64_darwin, ++ system_i386_darwin, ++ system_x86_64_darwin: ++ begin ++ { < 10.6: bundle1.o ++ >= 10.6: nothing } ++ if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then ++ exit(''); ++ end; ++ system_arm_darwin, ++ system_aarch64_darwin: ++ begin ++ { iOS: < 3.1: bundle1.o ++ >= 3.1: nothing } ++ if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then ++ exit(''); ++ end; ++ system_i386_iphonesim, ++ system_x86_64_iphonesim: ++ begin ++ { see rule for crt1.o } ++ if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then ++ exit(''); ++ end; ++ end; + result:='bundle1.o'; + end + else + begin +- { >= 10.6: nothing +- = 10.5: dylib1.10.5.o +- < 10.5: dylib1.o +- } +- if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then +- exit(''); +- if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then +- exit('dylib1.10.5.o'); +- { iOS: < 3.1: dylib1.o +- >= 3.1: nothing } +-{$if defined(arm)} +- if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then +- exit(''); +-{$endif} ++ case target_info.system of ++ system_powerpc_darwin, ++ system_powerpc64_darwin, ++ system_i386_darwin, ++ system_x86_64_darwin: ++ begin ++ { >= 10.6: nothing ++ = 10.5: dylib1.10.5.o ++ < 10.5: dylib1.o ++ } ++ if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then ++ exit(''); ++ if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then ++ exit('dylib1.10.5.o'); ++ end; ++ system_arm_darwin, ++ system_aarch64_darwin: ++ begin ++ { iOS: < 3.1: dylib1.o ++ >= 3.1: nothing } ++ if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then ++ exit(''); ++ end; ++ system_i386_iphonesim, ++ system_x86_64_iphonesim: ++ begin ++ { see rule for crt1.o } ++ if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then ++ exit(''); ++ end; ++ end; + result:='dylib1.o'; + end; + end; +@@ -417,12 +472,17 @@ begin + LinkRes.Add('i386'); + system_powerpc64_darwin: + LinkRes.Add('ppc64'); +- system_x86_64_darwin: ++ system_x86_64_darwin, ++ system_x86_64_iphonesim: + LinkRes.Add('x86_64'); + system_arm_darwin: + { current versions of the linker require the sub-architecture type + to be specified } + LinkRes.Add(lower(cputypestr[current_settings.cputype])); ++ system_aarch64_darwin: ++ LinkRes.Add('arm64'); ++ else ++ internalerror(2014121801); + end; + if MacOSXVersionMin<>'' then + begin +@@ -934,6 +994,9 @@ initialization + RegisterImport(system_x86_64_darwin,timportlibdarwin); + RegisterExport(system_x86_64_darwin,texportlibdarwin); + RegisterTarget(system_x86_64_darwin_info); ++ RegisterImport(system_x86_64_iphonesim,timportlibdarwin); ++ RegisterExport(system_x86_64_iphonesim,texportlibdarwin); ++ RegisterTarget(system_x86_64_iphonesim_info); + {$endif} + {$ifdef i386} + RegisterImport(system_i386_freebsd,timportlibbsd); +@@ -976,6 +1039,11 @@ initialization + RegisterExport(system_arm_darwin,texportlibdarwin); + RegisterTarget(system_arm_darwin_info); + {$endif arm} ++{$ifdef aarch64} ++ RegisterImport(system_aarch64_darwin,timportlibdarwin); ++ RegisterExport(system_aarch64_darwin,texportlibdarwin); ++ RegisterTarget(system_aarch64_darwin_info); ++{$endif aarch64} + + RegisterRes(res_elf_info,TWinLikeResourceFile); + RegisterRes(res_macho_info,TWinLikeResourceFile); +Index: fpc/fpcsrc/compiler/systems/t_linux.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/systems/t_linux.pas ++++ fpc/fpcsrc/compiler/systems/t_linux.pas +@@ -198,6 +198,10 @@ end; + {$endif FPC_ARMHF} + {$endif arm} + ++{$ifdef aarch64} ++const defdynlinker='/lib/ld-linux-aarch64.so.1'; ++{$endif aarch64} ++ + {$ifdef mips} + const defdynlinker='/lib/ld.so.1'; + {$endif mips} +@@ -288,6 +292,7 @@ const + {$ifdef POWERPC64} platform_select='-b elf64-powerpc -m elf64ppc';{$endif} + {$ifdef sparc} platform_select='-b elf32-sparc -m elf32_sparc';{$endif} + {$ifdef arm} platform_select='';{$endif} {unknown :( } ++{$ifdef aarch64} platform_select='';{$endif} {unknown :( } + {$ifdef m68k} platform_select='';{$endif} {unknown :( } + {$ifdef mips} + {$ifdef mipsel} +@@ -712,6 +717,236 @@ begin + add('}'); + {$endif x86_64} + ++{$ifdef AArch64} ++{$define LINKERSCRIPT_INCLUDED} ++ if isdll or (sysrootpath='') then begin ++ { On other architectures, supplying a complete linker script ++ without the -T option just results in: ++ warning: link.res contains output sections; did you forget -T? ++ However, with a recent aarch64 linker the result is: ++ /usr/bin/ld: internal error ../../ld/ldlang.c 5221 ++ So in these cases, where -T will not be used, we supply a ++ minimal linker script with just the FPC-specific part: } ++ add('SECTIONS'); ++ add('{'); ++ add(' .data :'); ++ add(' {'); ++ { extra by FPC } ++ add(' KEEP (*(.fpc .fpc.n_version .fpc.n_links))'); ++ add(' }'); ++ add('}'); ++ end else begin ++ { Complete linker script for aarch64-linux: } ++ add('SECTIONS'); ++ add('{'); ++ add(' /* Read-only sections, merged into text segment: */'); ++ add(' PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;'); ++ add(' .interp : { *(.interp) }'); ++ add(' .note.gnu.build-id : { *(.note.gnu.build-id) }'); ++ add(' .hash : { *(.hash) }'); ++ add(' .gnu.hash : { *(.gnu.hash) }'); ++ add(' .dynsym : { *(.dynsym) }'); ++ add(' .dynstr : { *(.dynstr) }'); ++ add(' .gnu.version : { *(.gnu.version) }'); ++ add(' .gnu.version_d : { *(.gnu.version_d) }'); ++ add(' .gnu.version_r : { *(.gnu.version_r) }'); ++ add(' .rela.dyn :'); ++ add(' {'); ++ add(' *(.rela.init)'); ++ add(' *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)'); ++ add(' *(.rela.fini)'); ++ add(' *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)'); ++ add(' *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)'); ++ add(' *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)'); ++ add(' *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)'); ++ add(' *(.rela.ctors)'); ++ add(' *(.rela.dtors)'); ++ add(' *(.rela.got)'); ++ add(' *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)'); ++ add(' *(.rela.ifunc)'); ++ add(' }'); ++ add(' .rela.plt :'); ++ add(' {'); ++ add(' *(.rela.plt)'); ++ add(' PROVIDE_HIDDEN (__rela_iplt_start = .);'); ++ add(' *(.rela.iplt)'); ++ add(' PROVIDE_HIDDEN (__rela_iplt_end = .);'); ++ add(' }'); ++ add(' .init :'); ++ add(' {'); ++ add(' KEEP (*(SORT_NONE(.init)))'); ++ add(' } =0'); ++ add(' .plt : ALIGN(16) { *(.plt) *(.iplt) }'); ++ add(' .text :'); ++ add(' {'); ++ add(' *(.text.unlikely .text.*_unlikely .text.unlikely.*)'); ++ add(' *(.text.exit .text.exit.*)'); ++ add(' *(.text.startup .text.startup.*)'); ++ add(' *(.text.hot .text.hot.*)'); ++ add(' *(.text .stub .text.* .gnu.linkonce.t.*)'); ++ add(' /* .gnu.warning sections are handled specially by elf32.em. */'); ++ add(' *(.gnu.warning)'); ++ add(' } =0'); ++ add(' .fini :'); ++ add(' {'); ++ add(' KEEP (*(SORT_NONE(.fini)))'); ++ add(' } =0'); ++ add(' PROVIDE (__etext = .);'); ++ add(' PROVIDE (_etext = .);'); ++ add(' PROVIDE (etext = .);'); ++ add(' .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }'); ++ add(' .rodata1 : { *(.rodata1) }'); ++ add(' .eh_frame_hdr : { *(.eh_frame_hdr) }'); ++ add(' .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }'); ++ add(' .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table'); ++ add(' .gcc_except_table.*) }'); ++ add(' /* These sections are generated by the Sun/Oracle C++ compiler. */'); ++ add(' .exception_ranges : ONLY_IF_RO { *(.exception_ranges'); ++ add(' .exception_ranges*) }'); ++ add(' /* Adjust the address for the data segment. We want to adjust up to'); ++ add(' the same address within the page on the next page up. */'); ++ add(' . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));'); ++ add(' /* Exception handling */'); ++ add(' .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }'); ++ add(' .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }'); ++ add(' .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }'); ++ add(' /* Thread Local Storage sections */'); ++ add(' .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }'); ++ add(' .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }'); ++ add(' .preinit_array :'); ++ add(' {'); ++ add(' PROVIDE_HIDDEN (__preinit_array_start = .);'); ++ add(' KEEP (*(.preinit_array))'); ++ add(' PROVIDE_HIDDEN (__preinit_array_end = .);'); ++ add(' }'); ++ add(' .init_array :'); ++ add(' {'); ++ add(' PROVIDE_HIDDEN (__init_array_start = .);'); ++ add(' KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))'); ++ add(' KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))'); ++ add(' PROVIDE_HIDDEN (__init_array_end = .);'); ++ add(' }'); ++ add(' .fini_array :'); ++ add(' {'); ++ add(' PROVIDE_HIDDEN (__fini_array_start = .);'); ++ add(' KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))'); ++ add(' KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))'); ++ add(' PROVIDE_HIDDEN (__fini_array_end = .);'); ++ add(' }'); ++ add(' .ctors :'); ++ add(' {'); ++ add(' /* gcc uses crtbegin.o to find the start of'); ++ add(' the constructors, so we make sure it is'); ++ add(' first. Because this is a wildcard, it'); ++ add(' doesn''t matter if the user does not'); ++ add(' actually link against crtbegin.o; the'); ++ add(' linker won''t look for a file to match a'); ++ add(' wildcard. The wildcard also means that it'); ++ add(' doesn''t matter which directory crtbegin.o'); ++ add(' is in. */'); ++ add(' KEEP (*crtbegin.o(.ctors))'); ++ add(' KEEP (*crtbegin?.o(.ctors))'); ++ add(' /* We don''t want to include the .ctor section from'); ++ add(' the crtend.o file until after the sorted ctors.'); ++ add(' The .ctor section from the crtend file contains the'); ++ add(' end of ctors marker and it must be last */'); ++ add(' KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))'); ++ add(' KEEP (*(SORT(.ctors.*)))'); ++ add(' KEEP (*(.ctors))'); ++ add(' }'); ++ add(' .dtors :'); ++ add(' {'); ++ add(' KEEP (*crtbegin.o(.dtors))'); ++ add(' KEEP (*crtbegin?.o(.dtors))'); ++ add(' KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))'); ++ add(' KEEP (*(SORT(.dtors.*)))'); ++ add(' KEEP (*(.dtors))'); ++ add(' }'); ++ add(' .jcr : { KEEP (*(.jcr)) }'); ++ add(' .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }'); ++ add(' .dynamic : { *(.dynamic) }'); ++ add(' .got : { *(.got) *(.igot) }'); ++ add(' . = DATA_SEGMENT_RELRO_END (24, .);'); ++ add(' .got.plt : { *(.got.plt) *(.igot.plt) }'); ++ add(' .data :'); ++ add(' {'); ++ add(' PROVIDE (__data_start = .);'); ++ ++ { extra by FPC } ++ add(' KEEP (*(.fpc .fpc.n_version .fpc.n_links))'); ++ ++ add(' *(.data .data.* .gnu.linkonce.d.*)'); ++ add(' SORT(CONSTRUCTORS)'); ++ add(' }'); ++ add(' .data1 : { *(.data1) }'); ++ add(' _edata = .; PROVIDE (edata = .);'); ++ add(' . = .;'); ++ add(' __bss_start = .;'); ++ add(' __bss_start__ = .;'); ++ add(' .bss :'); ++ add(' {'); ++ add(' *(.dynbss)'); ++ add(' *(.bss .bss.* .gnu.linkonce.b.*)'); ++ add(' *(COMMON)'); ++ add(' /* Align here to ensure that the .bss section occupies space up to'); ++ add(' _end. Align after .bss to ensure correct alignment even if the'); ++ add(' .bss section disappears because there are no input sections.'); ++ add(' FIXME: Why do we need it? When there is no .bss section, we don''t'); ++ add(' pad the .data section. */'); ++ add(' . = ALIGN(. != 0 ? 64 / 8 : 1);'); ++ add(' }'); ++ add(' _bss_end__ = . ; __bss_end__ = . ;'); ++ add(' . = ALIGN(64 / 8);'); ++ add(' . = SEGMENT_START("ldata-segment", .);'); ++ add(' . = ALIGN(64 / 8);'); ++ add(' __end__ = . ;'); ++ add(' _end = .; PROVIDE (end = .);'); ++ add(' . = DATA_SEGMENT_END (.);'); ++ add(' /* Stabs debugging sections. */'); ++ add(' .stab 0 : { *(.stab) }'); ++ add(' .stabstr 0 : { *(.stabstr) }'); ++ add(' .stab.excl 0 : { *(.stab.excl) }'); ++ add(' .stab.exclstr 0 : { *(.stab.exclstr) }'); ++ add(' .stab.index 0 : { *(.stab.index) }'); ++ add(' .stab.indexstr 0 : { *(.stab.indexstr) }'); ++ add(' .comment 0 : { *(.comment) }'); ++ add(' /* DWARF debug sections.'); ++ add(' Symbols in the DWARF debugging sections are relative to the beginning'); ++ add(' of the section so we begin them at 0. */'); ++ add(' /* DWARF 1 */'); ++ add(' .debug 0 : { *(.debug) }'); ++ add(' .line 0 : { *(.line) }'); ++ add(' /* GNU DWARF 1 extensions */'); ++ add(' .debug_srcinfo 0 : { *(.debug_srcinfo) }'); ++ add(' .debug_sfnames 0 : { *(.debug_sfnames) }'); ++ add(' /* DWARF 1.1 and DWARF 2 */'); ++ add(' .debug_aranges 0 : { *(.debug_aranges) }'); ++ add(' .debug_pubnames 0 : { *(.debug_pubnames) }'); ++ add(' /* DWARF 2 */'); ++ add(' .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }'); ++ add(' .debug_abbrev 0 : { *(.debug_abbrev) }'); ++ add(' .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }'); ++ add(' .debug_frame 0 : { *(.debug_frame) }'); ++ add(' .debug_str 0 : { *(.debug_str) }'); ++ add(' .debug_loc 0 : { *(.debug_loc) }'); ++ add(' .debug_macinfo 0 : { *(.debug_macinfo) }'); ++ add(' /* SGI/MIPS DWARF 2 extensions */'); ++ add(' .debug_weaknames 0 : { *(.debug_weaknames) }'); ++ add(' .debug_funcnames 0 : { *(.debug_funcnames) }'); ++ add(' .debug_typenames 0 : { *(.debug_typenames) }'); ++ add(' .debug_varnames 0 : { *(.debug_varnames) }'); ++ add(' /* DWARF 3 */'); ++ add(' .debug_pubtypes 0 : { *(.debug_pubtypes) }'); ++ add(' .debug_ranges 0 : { *(.debug_ranges) }'); ++ add(' /* DWARF Extension. */'); ++ add(' .debug_macro 0 : { *(.debug_macro) }'); ++ add(' .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }'); ++ add(' .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }'); ++ add(' /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }'); ++ add('}'); ++ end; ++{$endif AArch64} ++ + {$ifdef ARM} + if target_info.abi in [abi_eabi,abi_eabihf] then + begin +@@ -1553,6 +1788,11 @@ initialization + RegisterExport(system_arm_linux,texportliblinux); + RegisterTarget(system_arm_linux_info); + {$endif ARM} ++{$ifdef aarch64} ++ RegisterImport(system_aarch64_linux,timportliblinux); ++ RegisterExport(system_aarch64_linux,texportliblinux); ++ RegisterTarget(system_aarch64_linux_info); ++{$endif aarch64} + {$ifdef MIPS} + {$ifdef MIPSEL} + RegisterImport(system_mipsel_linux,timportliblinux); +Index: fpc/fpcsrc/compiler/systems.inc +=================================================================== +--- fpc.orig/fpcsrc/compiler/systems.inc ++++ fpc/fpcsrc/compiler/systems.inc +@@ -49,7 +49,8 @@ + cpu_avr, { 12 } + cpu_mipsel, { 13 } + cpu_jvm, { 14 } +- cpu_i8086 { 15 } ++ cpu_i8086, { 15 } ++ cpu_aarch64 { 16 } + ); + + tasmmode= (asmmode_none +@@ -68,6 +69,7 @@ + ,asmmode_avr_gas + ,asmmode_i8086_intel + ,asmmode_i8086_att ++ ,asmmode_arm_gas_unified + ); + + (* IMPORTANT NOTE: +@@ -165,7 +167,10 @@ + system_mipsel_embedded, { 82 } + system_i386_aros, { 83 } + system_x86_64_aros, { 84 } +- system_x86_64_dragonfly { 85 } ++ system_x86_64_dragonfly, { 85 } ++ system_aarch64_darwin, { 86 } ++ system_x86_64_iphonesim, { 87 } ++ system_aarch64_linux { 88 } + ); + + type +@@ -211,6 +216,7 @@ + ,as_i8086_nasm + ,as_i8086_nasmobj + ,as_gas_powerpc_xcoff ++ ,as_arm_elf32 + ,as_clang + ); + +@@ -283,6 +289,7 @@ + ,abi_powerpc_sysv,abi_powerpc_aix + ,abi_eabi,abi_armeb,abi_eabihf + ,abi_old_win32_gnu ++ ,abi_aarch64_darwin + ); + + +Index: fpc/fpcsrc/compiler/systems.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/systems.pas ++++ fpc/fpcsrc/compiler/systems.pas +@@ -216,7 +216,7 @@ interface + systems_android = [system_arm_android, system_i386_android, system_mipsel_android]; + systems_linux = [system_i386_linux,system_x86_64_linux,system_powerpc_linux,system_powerpc64_linux, + system_arm_linux,system_sparc_linux,system_alpha_linux,system_m68k_linux, +- system_x86_6432_linux,system_mipseb_linux,system_mipsel_linux]; ++ system_x86_6432_linux,system_mipseb_linux,system_mipsel_linux,system_aarch64_linux]; + systems_dragonfly = [system_x86_64_dragonfly]; + systems_freebsd = [system_i386_freebsd, + system_x86_64_freebsd]; +@@ -242,7 +242,8 @@ interface + { all darwin systems } + systems_darwin = [system_powerpc_darwin,system_i386_darwin, + system_powerpc64_darwin,system_x86_64_darwin, +- system_arm_darwin,system_i386_iphonesim]; ++ system_arm_darwin,system_i386_iphonesim, ++ system_aarch64_darwin,system_x86_64_iphonesim]; + + {all solaris systems } + systems_solaris = [system_sparc_solaris, system_i386_solaris, +@@ -285,7 +286,7 @@ interface + systems_objc_supported = systems_darwin; + + { systems using the non-fragile Objective-C ABI } +- systems_objc_nfabi = [system_powerpc64_darwin,system_x86_64_darwin,system_arm_darwin,system_i386_iphonesim]; ++ systems_objc_nfabi = [system_powerpc64_darwin,system_x86_64_darwin,system_arm_darwin,system_i386_iphonesim,system_aarch64_darwin,system_x86_64_iphonesim]; + + { all systems supporting exports from programs or units } + systems_unit_program_exports = [system_i386_win32, +@@ -335,6 +336,10 @@ interface + system_jvm_android32 + ]; + ++ { all systems where a value parameter passed by reference must be copied ++ on the caller side rather than on the callee side } ++ systems_caller_copy_addr_value_para = [system_aarch64_darwin]; ++ + { pointer checking (requires special code in FPC_CHECKPOINTER, + and can never work for libc-based targets or any other program + linking to an external library) +@@ -348,7 +353,8 @@ interface + + cpu2str : array[TSystemCpu] of string[10] = + ('','i386','m68k','alpha','powerpc','sparc','vm','ia64','x86_64', +- 'mips','arm', 'powerpc64', 'avr', 'mipsel','jvm', 'i8086'); ++ 'mips','arm', 'powerpc64', 'avr', 'mipsel','jvm', 'i8086', ++ 'aarch64'); + + abiinfo : array[tabi] of tabiinfo = ( + (name: 'DEFAULT'; supported: true), +@@ -357,7 +363,8 @@ interface + (name: 'EABI' ; supported:{$ifdef FPC_ARMEL}true{$else}false{$endif}), + (name: 'ARMEB' ; supported:{$ifdef FPC_ARMEB}true{$else}false{$endif}), + (name: 'EABIHF' ; supported:{$ifdef FPC_ARMHF}true{$else}false{$endif}), +- (name: 'OLDWIN32GNU'; supported:{$ifdef I386}true{$else}false{$endif}) ++ (name: 'OLDWIN32GNU'; supported:{$ifdef I386}true{$else}false{$endif}), ++ (name: 'AARCH64IOS'; supported:{$ifdef aarch64}true{$else}false{$endif}) + ); + + var +@@ -923,6 +930,21 @@ begin + {$ifdef i8086} + default_target(system_i8086_msdos); + {$endif i8086} ++ ++{$ifdef aarch64} ++ {$ifdef cpuaarch64} ++ default_target(source_info.system); ++ {$else cpuaarch64} ++ {$ifdef darwin} ++ {$define default_target_set} ++ default_target(system_aarch64_darwin); ++ {$endif darwin} ++ {$ifndef default_target_set} ++ default_target(system_aarch64_linux); ++ {$define default_target_set} ++ {$endif} ++ {$endif cpuaarch64} ++{$endif aarch64} + end; + + +Index: fpc/fpcsrc/compiler/tgobj.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/tgobj.pas ++++ fpc/fpcsrc/compiler/tgobj.pas +@@ -179,7 +179,7 @@ implementation + tempfreelist:=nil; + templist:=nil; + { we could create a new child class for this but I don't if it is worth the effort (FK) } +-{$if defined(powerpc) or defined(powerpc64) or defined(avr) or defined(jvm)} ++{$if defined(powerpc) or defined(powerpc64) or defined(avr) or defined(jvm) or defined(aarch64)} + direction:=1; + {$else} + direction:=-1; +Index: fpc/fpcsrc/compiler/utils/Makefile.fpc +=================================================================== +--- fpc.orig/fpcsrc/compiler/utils/Makefile.fpc ++++ fpc/fpcsrc/compiler/utils/Makefile.fpc +@@ -3,7 +3,7 @@ + # + + [target] +-programs=fpc ppufiles ppudump ppumove mkarmins mkx86ins ++programs=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins + rst=fpcsubst + + [clean] +Index: fpc/fpcsrc/compiler/utils/fpc.pp +=================================================================== +--- fpc.orig/fpcsrc/compiler/utils/fpc.pp ++++ fpc/fpcsrc/compiler/utils/fpc.pp +@@ -143,6 +143,10 @@ program fpc; + ppcbin:='ppcarm'; + processorname:='arm'; + {$endif arm} ++{$ifdef aarch64} ++ ppcbin:='ppca64'; ++ processorname:='aarch64'; ++{$endif arm} + {$ifdef sparc} + ppcbin:='ppcsparc'; + processorname:='sparc'; +@@ -202,7 +206,9 @@ program fpc; + else + if processorstr <> processorname then + begin +- if processorstr='arm' then ++ if processorstr='aarch64' then ++ cpusuffix:='a64' ++ else if processorstr='arm' then + cpusuffix:='arm' + else if processorstr='i386' then + cpusuffix:='386' +Index: fpc/fpcsrc/compiler/utils/mka64ins.pp +=================================================================== +--- fpc.orig/fpcsrc/compiler/utils/mka64ins.pp ++++ fpc/fpcsrc/compiler/utils/mka64ins.pp +@@ -14,7 +14,7 @@ + **********************************************************************} + {$mode objfpc} + +-program mkarmins; ++program mka64ins; + + const + Version = '0.9'; +@@ -153,7 +153,7 @@ begin + writeln('creating ',fn); + assign(f,fn); + rewrite(f); +- writeln(f,'{ don''t edit, this file is generated from armins.dat }'); ++ writeln(f,'{ don''t edit, this file is generated from a64ins.dat }'); + writeln(f,'('); + end; + +Index: fpc/fpcsrc/compiler/utils/mkarmins.pp +=================================================================== +--- fpc.orig/fpcsrc/compiler/utils/mkarmins.pp ++++ fpc/fpcsrc/compiler/utils/mkarmins.pp +@@ -186,7 +186,7 @@ var + opcode, + codes, + flags : string; +- optypes : array[1..4] of string; ++ optypes : array[1..6] of string; + begin + writeln('Narm Instruction Table Converter Version ',Version); + insns:=0; +@@ -298,6 +298,8 @@ begin + optypes[2]:=''; + optypes[3]:=''; + optypes[4]:=''; ++ optypes[5]:=''; ++ optypes[6]:=''; + codes:=''; + flags:=''; + skip:=false; +@@ -324,8 +326,8 @@ begin + else + break; + until false; +- for j:=1 to 4-ops do +- optypes[4-j+1]:='ot_none'; ++ for j:=1 to 6-ops do ++ optypes[6-j+1]:='ot_none'; + { codes } + skipspace; + j:=0; +@@ -385,7 +387,7 @@ begin + writeln(insfile,' ('); + writeln(insfile,' opcode : ',opcode,';'); + writeln(insfile,' ops : ',ops,';'); +- writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],',',optypes[4],');'); ++ writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],',',optypes[4],',',optypes[5],',',optypes[6],');'); + writeln(insfile,' code : ',codes,';'); + writeln(insfile,' flags : ',flags); + write(insfile,' )'); +Index: fpc/fpcsrc/compiler/utils/ppuutils/ppudump.pp +=================================================================== +--- fpc.orig/fpcsrc/compiler/utils/ppuutils/ppudump.pp ++++ fpc/fpcsrc/compiler/utils/ppuutils/ppudump.pp +@@ -76,7 +76,8 @@ const + { 12 } 'avr', + { 13 } 'mipsel', + { 14 } 'jvm', +- { 15 } 'i8086' ++ { 15 } 'i8086', ++ { 16 } 'aarch64' + ); + + { List of all supported system-cpu couples } +@@ -109,7 +110,7 @@ const + { 24 } 'OpenBSD-i386', + { 25 } 'OpenBSD-m68k', + { 26 } 'Linux-x86-64', +- { 27 } 'MacOSX-ppc', ++ { 27 } 'Darwin-ppc', + { 28 } 'OS/2 via EMX', + { 29 } 'NetBSD-powerpc', + { 30 } 'OpenBSD-powerpc', +@@ -128,7 +129,7 @@ const + { 43 } 'Linux-powerpc64', + { 44 } 'Darwin-i386', + { 45 } 'PalmOS-arm', +- { 46 } 'MacOSX-powerpc64', ++ { 46 } 'Darwin-powerpc64', + { 47 } 'NDS-arm', + { 48 } 'Embedded-i386', + { 49 } 'Embedded-m68k', +@@ -143,7 +144,7 @@ const + { 58 } 'Embedded-powerpc64', + { 59 } 'Symbian-i386', + { 60 } 'Symbian-arm', +- { 61 } 'MacOSX-x64', ++ { 61 } 'Darwin-x64', + { 62 } 'Embedded-avr', + { 63 } 'Haiku-i386', + { 64 } 'Darwin-ARM', +@@ -167,7 +168,10 @@ const + { 82 } 'Embedded-mipsel', + { 83 } 'AROS-i386', + { 84 } 'AROS-x86-64', +- { 85 } 'DragonFly-x86-64' ++ { 85 } 'DragonFly-x86-64', ++ { 86 } 'Darwin-AArch64', ++ { 87 } 'iPhoneSim-x86-64', ++ { 88 } 'Linux-AArch64' + ); + + const +Index: fpc/fpcsrc/compiler/version.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/version.pas ++++ fpc/fpcsrc/compiler/version.pas +@@ -77,6 +77,9 @@ interface + {$ifdef cpumipsel} + source_cpu_string = 'mipsel'; + {$endif cpumipsel} ++{$ifdef cpuaarch64} ++ source_cpu_string = 'aarch64'; ++{$endif cpuaarch64} + + function version_string:string; + function full_version_string:string; +Index: fpc/fpcsrc/compiler/x86/agx86att.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/x86/agx86att.pas ++++ fpc/fpcsrc/compiler/x86/agx86att.pas +@@ -511,7 +511,7 @@ interface + idtxt : 'AS-DARWIN'; + asmbin : 'as'; + asmcmd : '-o $OBJ $EXTRAOPT $ASM -arch x86_64'; +- supported_targets : [system_x86_64_darwin]; ++ supported_targets : [system_x86_64_darwin,system_x86_64_iphonesim]; + flags : [af_needar,af_smartlink_sections,af_supports_dwarf]; + labelprefix : 'L'; + comment : '# '; +@@ -524,7 +524,7 @@ interface + idtxt : 'CLANG'; + asmbin : 'clang'; + asmcmd : '-c -o $OBJ $EXTRAOPT -arch x86_64 $DARWINVERSION -x assembler $ASM'; +- supported_targets : [system_x86_64_darwin]; ++ supported_targets : [system_x86_64_darwin,system_x86_64_iphonesim]; + flags : [af_needar,af_smartlink_sections,af_supports_dwarf]; + labelprefix : 'L'; + comment : '# '; +Index: fpc/fpcsrc/compiler/x86/cgx86.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/x86/cgx86.pas ++++ fpc/fpcsrc/compiler/x86/cgx86.pas +@@ -82,7 +82,7 @@ unit cgx86; + procedure a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);override; + + { bit scan instructions } +- procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: TCGSize; src, dst: TRegister); override; ++ procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: TCGSize; src, dst: TRegister); override; + + { fpu move instructions } + procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override; +@@ -507,7 +507,7 @@ unit cgx86; + end + else + { Always use RIP relative symbol addressing for Windows and Darwin targets. } +- if (target_info.system in (systems_all_windows+[system_x86_64_darwin])) and (ref.base<>NR_RIP) then ++ if (target_info.system in (systems_all_windows+[system_x86_64_darwin,system_x86_64_iphonesim])) and (ref.base<>NR_RIP) then + begin + if (ref.refaddr=addr_no) and (ref.base=NR_NO) and (ref.index=NR_NO) then + begin +@@ -810,7 +810,7 @@ unit cgx86; + reference_reset_symbol(r,sym,0,sizeof(pint)); + if (cs_create_pic in current_settings.moduleswitches) and + { darwin's assembler doesn't want @PLT after call symbols } +- not(target_info.system in [system_x86_64_darwin,system_i386_iphonesim]) then ++ not(target_info.system in [system_x86_64_darwin,system_i386_iphonesim,system_x86_64_iphonesim]) then + begin + {$ifdef i386} + include(current_procinfo.flags,pi_needs_got); +@@ -1048,7 +1048,7 @@ unit cgx86; + a_op_const_reg(list,OP_ADD,OS_ADDR,offset,r); + end + {$ifdef x86_64} +- else if (target_info.system in (systems_all_windows+[system_x86_64_darwin])) ++ else if (target_info.system in (systems_all_windows+[system_x86_64_darwin,system_x86_64_iphonesim])) + or (cs_create_pic in current_settings.moduleswitches) + then + begin +@@ -2012,20 +2012,36 @@ unit cgx86; + end; + end; + +- procedure tcgx86.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: TCGSize; src, dst: TRegister); ++ procedure tcgx86.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: TCGSize; src, dst: TRegister); + var ++ tmpreg: tregister; + opsize: topsize; + l : TAsmLabel; + begin +- opsize:=tcgsize2opsize[size]; ++ { no bsf/bsr for byte } ++ if srcsize in [OS_8,OS_S8] then ++ begin ++ tmpreg:=getintregister(list,OS_INT); ++ a_load_reg_reg(list,srcsize,OS_INT,src,tmpreg); ++ src:=tmpreg; ++ srcsize:=OS_INT; ++ end; ++ { source and destination register must have the same size } ++ if tcgsize2size[srcsize]<>tcgsize2size[dstsize] then ++ tmpreg:=getintregister(list,srcsize) ++ else ++ tmpreg:=dst; ++ opsize:=tcgsize2opsize[srcsize]; + if not reverse then +- list.concat(taicpu.op_reg_reg(A_BSF,opsize,src,dst)) ++ list.concat(taicpu.op_reg_reg(A_BSF,opsize,src,tmpreg)) + else +- list.concat(taicpu.op_reg_reg(A_BSR,opsize,src,dst)); ++ list.concat(taicpu.op_reg_reg(A_BSR,opsize,src,tmpreg)); + current_asmdata.getjumplabel(l); + a_jmp_cond(list,OC_NE,l); +- list.concat(taicpu.op_const_reg(A_MOV,opsize,$ff,dst)); ++ list.concat(taicpu.op_const_reg(A_MOV,opsize,$ff,tmpreg)); + a_label(list,l); ++ if tmpreg<>dst then ++ a_load_reg_reg(list,srcsize,dstsize,tmpreg,dst); + end; + + {*************** compare instructructions ****************} +@@ -2690,7 +2706,8 @@ unit cgx86; + a_call_name(list,'MCOUNT',false); + end; + system_x86_64_linux, +- system_x86_64_darwin: ++ system_x86_64_darwin, ++ system_x86_64_iphonesim: + begin + a_call_name(list,'mcount',false); + end; +@@ -3044,7 +3061,7 @@ unit cgx86; + { create pic'ed? } + if (cs_create_pic in current_settings.moduleswitches) and + { darwin/x86_64's assembler doesn't want @PLT after call symbols } +- not(target_info.system in [system_x86_64_darwin,system_i386_iphonesim]) then ++ not(target_info.system in [system_x86_64_darwin,system_i386_iphonesim,system_x86_64_iphonesim]) then + ref.refaddr:=addr_pic + else + ref.refaddr:=addr_full; +Index: fpc/fpcsrc/compiler/x86/nx86mem.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/x86/nx86mem.pas ++++ fpc/fpcsrc/compiler/x86/nx86mem.pas +@@ -27,6 +27,7 @@ interface + uses + globtype, + cgbase,cpuinfo,cpubase, ++ symtype, + node,nmem,ncgmem; + + type +@@ -35,7 +36,7 @@ interface + end; + + tx86vecnode = class(tcgvecnode) +- procedure update_reference_reg_mul(maybe_const_reg:tregister;l:aint);override; ++ procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint);override; + end; + + implementation +@@ -86,7 +87,7 @@ implementation + { the live range of the LOC_CREGISTER will most likely overlap the } + { the live range of the target LOC_(C)REGISTER) } + { The passed register may be a LOC_CREGISTER as well. } +- procedure tx86vecnode.update_reference_reg_mul(maybe_const_reg:tregister;l:aint); ++ procedure tx86vecnode.update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); + var + l2 : integer; + hreg : tregister; +Index: fpc/fpcsrc/compiler/x86_64/cgcpu.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/x86_64/cgcpu.pas ++++ fpc/fpcsrc/compiler/x86_64/cgcpu.pas +@@ -476,7 +476,7 @@ unit cgcpu; + reference_reset_symbol(r,sym,0,sizeof(pint)); + if (cs_create_pic in current_settings.moduleswitches) and + { darwin/x86_64's assembler doesn't want @PLT after call symbols } +- (target_info.system<>system_x86_64_darwin) then ++ not(target_info.system in systems_darwin) then + r.refaddr:=addr_pic + else + r.refaddr:=addr_full; +Index: fpc/fpcsrc/compiler/x86_64/cpuelf.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/x86_64/cpuelf.pas ++++ fpc/fpcsrc/compiler/x86_64/cpuelf.pas +@@ -664,6 +664,7 @@ implementation + encodereloc: @elf_x86_64_encodeReloc; + loadreloc: @elf_x86_64_loadReloc; + loadsection: nil; ++ encodeflags: nil; + ); + + +Index: fpc/fpcsrc/packages/fcl-res/Makefile.fpc.fpcmake +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-res/Makefile.fpc.fpcmake ++++ fpc/fpcsrc/packages/fcl-res/Makefile.fpc.fpcmake +@@ -13,7 +13,7 @@ units=acceleratorsresource bitmapresourc + groupresource icocurtypes machoconsts machoreader machotypes machowriter \ + resdatastream resfactory resmerger resource resourcetree resreader reswriter \ + stringtableresource strtable tlbreader versionconsts versionresource versiontypes \ +- winpeimagereader ++ winpeimagereader xcoffwriter + rsts=versiontypes stringtableresource resource resfactory + + +Index: fpc/fpcsrc/packages/fcl-res/src/elfconsts.pp +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-res/src/elfconsts.pp ++++ fpc/fpcsrc/packages/fcl-res/src/elfconsts.pp +@@ -22,7 +22,7 @@ interface + type + TElfMachineType = (emtnone, emtsparc, emti386, emtm68k, emtppc, emtppc64, + emtarm, emtarmeb, emtia64, emtx86_64, emtalpha, +- emtmips, emtmipsel); ++ emtmips, emtmipsel, emtaarch64); + const + ELFMAGIC = chr($7f)+'ELF'; + +@@ -71,6 +71,7 @@ const + EM_IA_64 = 50; + EM_MIPS_X = 51; // GNU readelf returns machine name "Stanford MIPS-X" + EM_X86_64 = 62; ++ EM_AARCH64 = 183; + EM_ALPHA = $9026; //unofficial, but used by gnu toolchain + + //machine-specific flags +@@ -130,6 +131,7 @@ const + R_PPC_ADDR32 = 1; + R_PPC64_ADDR64 = 38; + R_ARM_ABS32 = 2; ++ R_AARCH64_ABS64 = 257; + R_68K_32 = 1; + R_SPARC_32 = 3; + R_ALPHA_REFQUAD = 2; +Index: fpc/fpcsrc/packages/fcl-res/src/elfdefaulttarget.inc +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-res/src/elfdefaulttarget.inc ++++ fpc/fpcsrc/packages/fcl-res/src/elfdefaulttarget.inc +@@ -33,6 +33,9 @@ + fMachineType:=emtarmeb; + {$ENDIF} + {$ENDIF} ++ {$IFDEF CPUAARCH64} ++ fMachineType:=emtaarch64; ++ {$ENDIF} + {$IFDEF CPU68K} + fMachineType:=emtm68k; + {$ENDIF} +Index: fpc/fpcsrc/packages/fcl-res/src/elfreader.pp +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-res/src/elfreader.pp ++++ fpc/fpcsrc/packages/fcl-res/src/elfreader.pp +@@ -282,6 +282,7 @@ begin + fMachineType:=emtarm + else + fMachineType:=emtarmeb; ++ EM_AARCH64: fMachineType:=emtaarch64; + EM_ALPHA : fMachineType:=emtalpha; + EM_IA_64 : fMachineType:=emtia64; + EM_X86_64 : fMachineType:=emtx86_64; +Index: fpc/fpcsrc/packages/fcl-res/src/elfsubwriter.inc +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-res/src/elfsubwriter.inc ++++ fpc/fpcsrc/packages/fcl-res/src/elfsubwriter.inc +@@ -27,7 +27,7 @@ type + _TElfRelocTable_= class + private + fList : TFPList; +- fRelocType : byte; ++ fRelocType : longword; + fEntrySize : integer; + fSectionType : integer; + fSectionName : string; +@@ -418,6 +418,7 @@ begin + EM_386 : begin RelocType:=R_386_32; SectionType:=SHT_REL; end; + EM_PPC : begin RelocType:=R_PPC_ADDR32; SectionType:=SHT_RELA; end; + EM_ARM : begin RelocType:=R_ARM_ABS32; SectionType:=SHT_REL; end; ++ EM_AARCH64: begin RelocType:=R_AARCH64_ABS64; SectionType:=SHT_RELA; end; + EM_68K : begin RelocType:=R_68K_32; SectionType:=SHT_RELA; end; + EM_SPARC : begin RelocType:=R_SPARC_32; SectionType:=SHT_RELA; end; + EM_X86_64 : begin RelocType:=R_x86_64_64; SectionType:=SHT_RELA; end; +Index: fpc/fpcsrc/packages/fcl-res/src/elfwriter.pp +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-res/src/elfwriter.pp ++++ fpc/fpcsrc/packages/fcl-res/src/elfwriter.pp +@@ -155,7 +155,7 @@ type + + type + TElfRelocInfo = record +- RelocType : byte; ++ RelocType : longword; + SectionType : integer; + end; + (* +@@ -551,6 +551,7 @@ begin + emtppc64 : begin fMachineTypeInt:=EM_PPC64; fBits:=ELFCLASS64; fOrder:=ELFDATA2MSB; end; + emtarm : begin fMachineTypeInt:=EM_ARM; fBits:=ELFCLASS32; fOrder:=ELFDATA2LSB; end; + emtarmeb : begin fMachineTypeInt:=EM_ARM; fBits:=ELFCLASS32; fOrder:=ELFDATA2MSB; end; ++ emtaarch64: begin fMachineTypeInt:=EM_AARCH64; fBits:=ELFCLASS64; fOrder:=ELFDATA2LSB; end; + emtalpha : begin fMachineTypeInt:=EM_ALPHA; fBits:=ELFCLASS64; fOrder:=ELFDATA2LSB; end; + emtia64 : begin fMachineTypeInt:=EM_IA_64; fBits:=ELFCLASS64; fOrder:=ELFDATA2LSB; end; + emtx86_64 : begin fMachineTypeInt:=EM_X86_64; fBits:=ELFCLASS64; fOrder:=ELFDATA2LSB; end; +Index: fpc/fpcsrc/packages/fcl-res/src/machoconsts.pp +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-res/src/machoconsts.pp ++++ fpc/fpcsrc/packages/fcl-res/src/machoconsts.pp +@@ -48,6 +48,7 @@ const + CPU_TYPE_I386 = 7; + CPU_TYPE_X86_64 = CPU_TYPE_I386 or CPU_ARCH_ABI64; + CPU_TYPE_ARM = 12; ++ CPU_TYPE_ARM64 = CPU_TYPE_ARM or CPU_ARCH_ABI64; + CPU_TYPE_POWERPC = 18; + CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC or CPU_ARCH_ABI64; + +@@ -61,6 +62,8 @@ const + CPU_SUBTYPE_ARM_V5TEJ = 7; + CPU_SUBTYPE_ARM_XSCALE = 8; + CPU_SUBTYPE_ARM_V7 = 9; ++ CPU_SUBTYPE_ARM64_ALL = 0; ++ CPU_SUBTYPE_ARM64_V8 = 1; + + //Mach-O object types + MH_OBJECT = $1; // relocatable object file +@@ -180,6 +183,8 @@ const + N_SECT = $e; // defined in section number n_sect + N_PBUD = $c; // prebound undefined (defined in a dylib) + N_INDR = $a; // indirect ++ ++ NO_SECT = $0; // symbol is not in any section + + //Relocations: masks for flag + R_SYMBOLNUM_BE = $FFFFFF00; +@@ -206,6 +211,9 @@ const + // relocation types - ARM + ARM_RELOC_VANILLA = 0; // generic relocation + ++ // relocation types - AARCH64 ++ ARM64_RELOC_UNSIGNED = 0; // for pointers ++ + implementation + + end. +Index: fpc/fpcsrc/packages/fcl-res/src/machodefaulttarget.inc +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-res/src/machodefaulttarget.inc ++++ fpc/fpcsrc/packages/fcl-res/src/machodefaulttarget.inc +@@ -29,6 +29,9 @@ + {$IFDEF CPUARM} + fMachineType:=mmtarm; + {$ENDIF} ++ {$IFDEF CPUAARCH64} ++ fMachineType:=mmtarm64; ++ {$ENDIF} + + fBits:=MACH_ERRBIT; + {$IFDEF CPU32} +Index: fpc/fpcsrc/packages/fcl-res/src/machoreader.pp +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-res/src/machoreader.pp ++++ fpc/fpcsrc/packages/fcl-res/src/machoreader.pp +@@ -219,7 +219,8 @@ begin + CPU_TYPE_X86_64 : fMachineType:=mmtx86_64; + CPU_TYPE_POWERPC : fMachineType:=mmtpowerpc; + CPU_TYPE_POWERPC64 : fMachineType:=mmtpowerpc64; +- CPU_TYPE_ARM : fMachineType:=mmtarm ++ CPU_TYPE_ARM : fMachineType:=mmtarm; ++ CPU_TYPE_ARM64 : fMachineType:=mmtarm64 + else exit; + end; + +Index: fpc/fpcsrc/packages/fcl-res/src/machosubwriter.inc +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-res/src/machosubwriter.inc ++++ fpc/fpcsrc/packages/fcl-res/src/machosubwriter.inc +@@ -17,10 +17,11 @@ type + _TMachOSymbolTable_ = class(TMachOSymbolTable) + protected + function AddSymbol(aName : string; sect : byte; addr : longword; +- glob : boolean) : integer; override; ++ glob, undef : boolean) : integer; override; + protected + public + procedure WriteToStream(aStream : TStream); override; ++ procedure SetSymbolOffset(symbolnum : integer; offset: longword); override; + end; + + _TMachOSubWriter_ = class(TAbstractMachOSubWriter) +@@ -34,7 +35,6 @@ type + procedure AllocateSpaceForLoadCommands(aStream : TStream); override; + + procedure FixLoadCommands(aStream : TStream; aResources : TResources); override; +- procedure FixResHeader(aStream : TStream); override; + public + constructor Create(aParent : TMachOResourceWriter; const aMachineType + : TMachOMachineType; const aSubMachineType: TMachoSubMachineType; +@@ -44,13 +44,17 @@ type + { _TMachOSymbolTable_ } + + function _TMachOSymbolTable_.AddSymbol(aName: string; sect: byte; addr: longword; +- glob: boolean): integer; ++ glob, undef: boolean): integer; + var p : _PNlist_; + begin + p:=GetMem(sizeof(_TNlist_)); + p^.strx:=fStringTable.Add(aName); +- p^._type:=N_SECT; +- if glob then p^._type:=p^._type or N_EXT; ++ if not undef then ++ p^._type:=N_SECT ++ else ++ p^._type:=N_UNDF; ++ if glob then ++ p^._type:=p^._type or N_EXT; + p^.desc:=0; + p^.sect:=sect; + p^.value:=addr; +@@ -61,10 +65,20 @@ end; + procedure _TMachOSymbolTable_.WriteToStream(aStream: TStream); + var nlist : _TNlist_; + i : integer; ++ sawglobal: boolean; + begin ++ { first write local symbols, then global ones, as ilocalsym is hardcoded to ++ be index 0. Can't reorder here because we may already have used symbol ++ numbers to generate relocations -> give an error if a global symbol ++ comes before any local symbols } ++ sawglobal:=false; + for i:=0 to fList.Count-1 do + begin + nlist:=_PNlist_(fList[i])^; ++ if (nlist._type and N_EXT)<>0 then ++ sawglobal:=true ++ else if sawglobal then ++ raise EMachOResourceWriterSymbolTableWrongOrderException.Create(''); + if fOppositeEndianess then + begin + nlist.strx:=SwapEndian(nlist.strx); +@@ -75,6 +89,14 @@ begin + end; + end; + ++procedure _TMachOSymbolTable_.SetSymbolOffset(symbolnum: integer; offset: longword); ++var ++ p : _PNlist_; ++begin ++ p:=_PNlist_(flist[symbolnum]); ++ p^.value:=offset; ++end; ++ + { _TMachOSubWriter_ } + + procedure _TMachOSubWriter_.SwapSection(var aSection: _TSection_); +@@ -109,8 +131,13 @@ begin + hdr.count:=aResources.Count; + hdr.usedhandles:=0; + hdr.handles:=0; +- fRelocations.Add(0,1); +- fRelocations.Add(sizeof(hdr.rootptr)+sizeof(hdr.count)+sizeof(hdr.usedhandles),2); ++ { the first pointer (rootptr at offset 0) goes to the root node, which comes ++ right after the header (the addend has been set to sizeof(hdr) -> add the ++ address of the fpc.resources section to it via a relocations} ++ fRelocations.Add(0,ffpcresourcessym); ++ { the last pointer (handles at offset sizeof(fields before it)) goes to the ++ fpc.reshandles section } ++ fRelocations.Add(sizeof(hdr.rootptr)+sizeof(hdr.count)+sizeof(hdr.usedhandles),ffpcreshandlessym); + if fOppositeEndianess then + begin + hdr.rootptr:=SwapEndian(hdr.rootptr); +@@ -124,6 +151,7 @@ end; + + procedure _TMachOSubWriter_.WriteNodeInfos(aStream: TStream); + begin ++ { offset inside the object } + fCurOfs:=sizeof(_TResHdr_); + WriteNodeInfo(aStream,fRoot); + WriteSubNodes(aStream,fRoot); +@@ -138,7 +166,7 @@ begin + else + begin + infonode.nameid:=fResStrTable.StartOfs+aNode.NameRVA; +- fRelocations.Add(fCurOfs,1); ++ fRelocations.Add(fCurOfs,ffpcresourcessym); + end; + infonode.ncount:=aNode.NamedCount; + if aNode.IsLeaf then +@@ -154,7 +182,7 @@ begin + end; + fRelocations.Add( + fCurOfs+sizeof(infonode.nameid)+sizeof(infonode.ncount)+ +- sizeof(infonode.idcountsize),1); ++ sizeof(infonode.idcountsize),ffpcresourcessym); + if fOppositeEndianess then + begin + infonode.nameid:=SwapEndian(infonode.nameid); +@@ -171,7 +199,7 @@ var buf : pbyte; + begin + fHeader.sizeofcmds:= + //segment+res section+bss section +- sizeof(_TSegmentCommand_)+sizeof(_TSection_)*2+ ++ sizeof(_TSegmentCommand_)+sizeof(_TSection_)*3+ + //symbol table and dynamic symbol table commands + sizeof(TSymtabCommand)+sizeof(TDySymtabCommand)+ + //common header of the three commands +@@ -190,21 +218,35 @@ var ldcommand : TLoadCommand; + segcommand : _TSegmentCommand_; + symcommand : TSymtabCommand; + dysymcommand : TDySymtabCommand; +- ressection,bsssection : _TSection_; ++ ressection,bsssection,textsection : _TSection_; + begin + ldcommand.cmd:=fSegType; +- ldcommand.cmdsize:=sizeof(TLoadCommand)+sizeof(segcommand)+sizeof(ressection)*2; ++ ldcommand.cmdsize:=sizeof(TLoadCommand)+sizeof(segcommand)+sizeof(ressection)*3; + + FillByte(segcommand.name[0],16,0); + segcommand.vmaddr:=0; + segcommand.vmsize:=fDataCurOfs+sizeof(_ptrtype_)*aResources.Count; + segcommand.fileoff:=fSectionStart; + segcommand.filesize:=fDataCurOfs; +- segcommand.maxprot:=VM_PROT_READ or VM_PROT_WRITE; +- segcommand.initprot:=VM_PROT_READ or VM_PROT_WRITE; +- segcommand.nsects:=2; ++ segcommand.maxprot:=VM_PROT_READ or VM_PROT_WRITE or VM_PROT_EXECUTE; ++ segcommand.initprot:=VM_PROT_READ or VM_PROT_WRITE or VM_PROT_EXECUTE; ++ segcommand.nsects:=3; + segcommand.flags:=0; + ++ fillbyte(textsection,sizeof(textsection),0); ++ textsection.sectname:='__text'; ++ textsection.segname:='__TEXT'; ++ textsection.addr:=0; ++ textsection.size:=0; ++ textsection.offset:=segcommand.fileoff; ++ textsection.align:=0; ++ textsection.reloff:=0; ++ textsection.nreloc:=0; ++ textsection.flags:=S_ATTR_PURE_INSTRUCTIONS; ++ textsection.reserved1:=0; ++ textsection.reserved2:=0; ++ ++ fillbyte(ressection,sizeof(ressection),0); + ressection.sectname:=RsrcSectName; + ressection.segname:=DataSegName; + ressection.addr:=0; +@@ -217,6 +259,7 @@ begin + ressection.reserved1:=0; + ressection.reserved2:=0; + ++ fillbyte(bsssection,sizeof(bsssection),0); + bsssection.sectname:=HandlesSectName; + bsssection.segname:=DataSegName; + bsssection.addr:=fDataCurOfs; +@@ -243,12 +286,14 @@ begin + segcommand.nsects:=SwapEndian(segcommand.nsects); + segcommand.flags:=SwapEndian(segcommand.flags); + ++ SwapSection(textsection); + SwapSection(ressection); + SwapSection(bsssection); + end; + + aStream.WriteBuffer(ldcommand,sizeof(ldcommand)); + aStream.WriteBuffer(segcommand,sizeof(segcommand)); ++ aStream.WriteBuffer(textsection,sizeof(textsection)); + aStream.WriteBuffer(ressection,sizeof(ressection)); + aStream.WriteBuffer(bsssection,sizeof(bsssection)); + +@@ -258,7 +303,7 @@ begin + symcommand.symoff:=fSymbolTable.StartOfs; + symcommand.nsyms:=fSymbolTable.Count; + symcommand.stroff:=fMachOStringTable.StartOfs; +- symcommand.strsize:=NextAligned(fDataAlignment,fMachOStringTable.Size); ++ symcommand.strsize:=NextAligned(4,fMachOStringTable.Size); + + if fOppositeEndianess then + begin +@@ -325,17 +370,6 @@ begin + aStream.WriteBuffer(dysymcommand,sizeof(dysymcommand)); + end; + +-procedure _TMachOSubWriter_.FixResHeader(aStream : TStream); +-var hdr : _TResHdr_; +-begin +- hdr.handles:=fDataCurOfs; +- if fOppositeEndianess then +- hdr.handles:=SwapEndian(hdr.handles); +- aStream.Seek(sizeof(hdr.rootptr)+sizeof(hdr.count)+sizeof(hdr.usedhandles), +- soFromCurrent); +- aStream.WriteBuffer(hdr.handles,sizeof(hdr.handles)); +-end; +- + constructor _TMachOSubWriter_.Create(aParent : TMachOResourceWriter; + const aMachineType : TMachOMachineType; const aSubMachineType: TMachoSubMachineType; const aOppositeEndianess : boolean); + begin +Index: fpc/fpcsrc/packages/fcl-res/src/machotypes.pp +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-res/src/machotypes.pp ++++ fpc/fpcsrc/packages/fcl-res/src/machotypes.pp +@@ -19,17 +19,20 @@ unit machotypes; + + interface + ++{$packrecords c} ++ + type +- TMachOMachineType = (mmtpowerpc, mmtpowerpc64, mmti386, mmtx86_64, mmtarm); ++ TMachOMachineType = (mmtpowerpc, mmtpowerpc64, mmti386, mmtx86_64, mmtarm, mmtarm64); + TMachOSubMachineTypePowerPC = (msmppc_all); + TMachOSubMachineTypePowerPC64 = (msmppc64_all); + TMachOSubMachineType386 = (msm386_all); + TMachOSubMachineTypex64 = (msmx64_all); + TMachOSubMachineTypeArm = (msmarm_all,msmarm_v4t,msmarm_v6,msmarm_v5tej,msmarm_xscale,msmarm_v7); ++ TMachOSubMachineTypeAarch64 = (msmaarch64_all); + TSegSectName = array[0..15] of char; + + type +- TMachHdr = packed record ++ TMachHdr = record + magic : longword; + cputype : longint; + cpusubtype : longint; +@@ -39,14 +42,14 @@ type + flags : longword; + end; + +- TLoadCommand = packed record ++ TLoadCommand = record + cmd : longword; + cmdsize : longword; + end; + + //note: all commands don't include first two longwords + +- TSegmentCommand32 = packed record ++ TSegmentCommand32 = record + name : TSegSectName; + vmaddr : longword; + vmsize : longword; +@@ -58,7 +61,7 @@ type + flags : longword; + end; + +- TSegmentCommand64 = packed record ++ TSegmentCommand64 = record + name : TSegSectName; + vmaddr : qword; + vmsize : qword; +@@ -70,7 +73,7 @@ type + flags : longword; + end; + +- TSection32 = packed record ++ TSection32 = record + sectname : TSegSectName; + segname : TSegSectName; + addr : longword; +@@ -84,7 +87,7 @@ type + reserved2 : longword; + end; + +- TSection64 = packed record ++ TSection64 = record + sectname : TSegSectName; + segname : TSegSectName; + addr : qword; +@@ -99,14 +102,14 @@ type + reserved3 : longword; + end; + +- TSymtabCommand = packed record ++ TSymtabCommand = record + symoff : longword; + nsyms : longword; + stroff : longword; + strsize : longword; + end; + +- TDySymtabCommand = packed record ++ TDySymtabCommand = record + ilocalsym : longword; + nlocalsym : longword; + iextdefsym : longword; +@@ -127,7 +130,7 @@ type + nlocrel : longword; + end; + +- TNList32 = packed record ++ TNList32 = record + strx : longword; + _type : byte; + sect : byte; +@@ -136,7 +139,7 @@ type + end; + PNList32 = ^TNList32; + +- TNList64 = packed record ++ TNList64 = record + strx : longword; + _type : byte; + sect : byte; +@@ -145,7 +148,7 @@ type + end; + PNList64 = ^TNList64; + +- TRelocationInfo = packed record ++ TRelocationInfo = record + address : longword; + flags : longword; + end; +Index: fpc/fpcsrc/packages/fcl-res/src/machowriter.pp +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-res/src/machowriter.pp ++++ fpc/fpcsrc/packages/fcl-res/src/machowriter.pp +@@ -25,6 +25,7 @@ uses + type + EMachOResourceWriterException = class(EResourceWriterException); + EMachOResourceWriterUnknownBitSizeException = class(EMachOResourceWriterException); ++ EMachOResourceWriterSymbolTableWrongOrderException = class(EMachOResourceWriterException); + + type + +@@ -37,6 +38,7 @@ type + msm386_all: (f386SubType: TMachOSubMachineType386); + msmx64_all: (fX64SubType: TMachOSubMachineTypex64); + mmtarm: (fArmSubType: TMachOSubMachineTypeArm); ++ mmtarm64: (fArm64SubType: TMachOSubMachineTypeAarch64); + end; + + TMachOResourceWriter = class(TAbstractResourceWriter) +@@ -85,7 +87,7 @@ type + public + constructor Create(aMachineType : TMachOMachineType; aOppositeEndianess : boolean); + destructor Destroy; override; +- procedure Add(addr : longword; sectnum : longword); ++ procedure Add(addr: longword; symnum: longword); + procedure Clear; + procedure WriteToStream(aStream : TStream); + property Count : integer read GetCount; +@@ -104,15 +106,17 @@ type + fOppositeEndianess : boolean; + function GetCount : integer; + function AddSymbol(aName : string; sect : byte; addr : longword; +- glob : boolean) : integer; virtual; abstract; ++ glob, undef : boolean) : integer; virtual; abstract; + protected + public + constructor Create(aStringTable : TObjectStringTable); + destructor Destroy; override; +- function AddLocal(aName : string; sect : byte; addr : longword) : integer; +- function AddGlobal(aName : string; sect : byte; addr : longword) : integer; ++ function AddLocal(const aName : string; sect : byte; addr : longword) : integer; ++ function AddGlobal(const aName : string; sect : byte; addr : longword) : integer; ++ function AddExternal(const aName : string) : integer; + procedure Clear; + procedure WriteToStream(aStream : TStream); virtual; abstract; ++ procedure SetSymbolOffset(symbolnum : integer; offset: longword); virtual; abstract; + property Count : integer read GetCount; + property LocalCount : integer read fLocalCount; + property GlobalCount : integer read fGlobalCount; +@@ -140,6 +144,8 @@ type + fCurOfs : longword; + fDataCurOfs : longword; + fSectionStart : longword; ++ ffpcresourcessym, ++ ffpcreshandlessym : integer; + + function NextAligned(aBound, aValue : longword) : longword; + procedure Align(aBound : integer; aStream : TStream); +@@ -240,17 +246,23 @@ begin + fList.Free; + end; + +-function TMachOSymbolTable.AddLocal(aName: string; sect: byte; addr: longword ++function TMachOSymbolTable.AddLocal(const aName: string; sect: byte; addr: longword + ): integer; + begin +- Result:=AddSymbol(aName,sect,addr,false); ++ Result:=AddSymbol(aName,sect,addr,false,false); + inc(fLocalCount); + end; + +-function TMachOSymbolTable.AddGlobal(aName: string; sect: byte; addr: longword ++function TMachOSymbolTable.AddGlobal(const aName: string; sect: byte; addr: longword + ): integer; + begin +- Result:=AddSymbol(aName,sect,addr,true); ++ Result:=AddSymbol(aName,sect,addr,true,false); ++ inc(fGlobalCount); ++end; ++ ++function TMachOSymbolTable.AddExternal(const aName: string): integer; ++begin ++ Result:=AddSymbol(aName,NO_SECT,0,false,true); + inc(fGlobalCount); + end; + +@@ -301,6 +313,11 @@ begin + fRelocType:=ARM_RELOC_VANILLA; + fRelocSize:=2; + end; ++ mmtarm64 : begin ++ fEndianess:=MACH_LITTLE_ENDIAN; ++ fRelocType:=ARM64_RELOC_UNSIGNED; ++ fRelocSize:=3; ++ end; + end; + fOppositeEndianess:=aOppositeEndianess; + end; +@@ -311,7 +328,7 @@ begin + fList.Free; + end; + +-procedure TMachORelocations.Add(addr: longword; sectnum: longword); ++procedure TMachORelocations.Add(addr: longword; symnum: longword); + var p : PRelocationInfo; + begin + p:=GetMem(sizeof(TRelocationInfo)); +@@ -319,15 +336,19 @@ begin + //bit fields make things difficult... + if fEndianess=MACH_BIG_ENDIAN then + begin +- p^.flags:=sectnum shl 8; ++ p^.flags:=symnum shl 8; + p^.flags:=p^.flags or (fRelocSize shl 5); //length + p^.flags:=p^.flags or fRelocType; ++ { reference via symbol } ++ p^.flags:=p^.flags or R_EXTERN_BE; + end + else + begin +- p^.flags:=sectnum and R_SYMBOLNUM_LE; ++ p^.flags:=symnum and R_SYMBOLNUM_LE; + p^.flags:=p^.flags or (fRelocSize shl 25); //length + p^.flags:=p^.flags or (fRelocType shl 28); ++ { reference via symbol } ++ p^.flags:=p^.flags or R_EXTERN_LE; + end; + fList.Add(p); + end; +@@ -491,6 +512,7 @@ const + armsm2int: array[TMachOSubMachineTypeArm] of longint = (CPU_SUBTYPE_ARM_ALL, + CPU_SUBTYPE_ARM_V4T,CPU_SUBTYPE_ARM_V6,CPU_SUBTYPE_ARM_V5TEJ, + CPU_SUBTYPE_ARM_XSCALE,CPU_SUBTYPE_ARM_V7); ++ arm64sm2int: array[TMachOSubMachineTypeAarch64] of longint = (CPU_SUBTYPE_ARM64_ALL); + begin + aStream.Position:=0; + case fMachineType of +@@ -519,6 +541,11 @@ begin + fHeader.cputype:=CPU_TYPE_ARM; + fHeader.cpusubtype:=armsm2int[fSubMachineType.fArmSubType]; + end; ++ mmtarm64 : begin ++ fHeader.magic:=MH_MAGIC_64; ++ fHeader.cputype:=CPU_TYPE_ARM64; ++ fHeader.cpusubtype:=arm64sm2int[fSubMachineType.fArm64SubType]; ++ end; + end; + fHeader.filetype:=MH_OBJECT; + fHeader.ncmds:=3; +@@ -544,22 +571,39 @@ begin + AllocateSpaceForLoadCommands(aStream); + fSectionStart:=aStream.Position; + fRoot:=TRootResTreeNode(fParent.GetTree(aResources)); ++ { on AArch64, if you want to refer to a section from another one, you ++ have to do it via an explicit symbol reference. ++ ++ } ++ { dummy text section symbol } ++ fSymbolTable.AddLocal('ltmp0',1,0); ++ { dummy fpc.resources symbol } ++ fSymbolTable.AddLocal('ltmp1',2,0); ++ { the offset needs to be the offset in the file, *not* relative to the start ++ of the section. We don't know here yet how large the fpcresources section ++ will be -> fix up later } ++ ffpcreshandlessym:=fSymbolTable.AddGlobal('__fpc_reshandles_internal',3,0); ++ { don't add this before any local symbols, as local symbols must be written ++ first. We can't reorder while writing the symbol table, because we already ++ need the symbol numbers above } ++ ffpcresourcessym:=fSymbolTable.AddGlobal('FPC_RESSYMBOL',2,0); ++ + PrescanResourceTree; + WriteResHeader(aStream,aResources); + WriteNodeInfos(aStream); + WriteResStringTable(aStream); + WriteRawData(aStream); +-// fSymbolTable.AddGlobal('FPCRES_SECTION',1,0); +- fSymbolTable.AddGlobal('FPC_RESSYMBOL',1,0); + fRelocations.StartOfs:=aStream.Position; + WriteRelocations(aStream); ++ ++ { fix up offset of fpcreshandles symbol } ++ fSymbolTable.SetSymbolOffset(ffpcreshandlessym,fDataCurOfs); + fSymbolTable.StartOfs:=aStream.Position; + WriteSymbolTable(aStream); + fMachOStringTable.StartOfs:=aStream.Position; + WriteMachOStringTable(aStream); + FixHeader(aStream); + FixLoadCommands(aStream,aResources); +- FixResHeader(aStream); + end; + + constructor TAbstractMachOSubWriter.Create(aParent : TMachOResourceWriter; +@@ -602,6 +646,7 @@ begin + mmti386 : begin fBits:=MACH_32BIT; fEndianess:=MACH_LITTLE_ENDIAN; end; + mmtx86_64 : begin fBits:=MACH_64BIT; fEndianess:=MACH_LITTLE_ENDIAN; end; + mmtarm : begin fBits:=MACH_32BIT; fEndianess:=MACH_LITTLE_ENDIAN; end; ++ mmtarm64 : begin fBits:=MACH_64BIT; fEndianess:=MACH_LITTLE_ENDIAN; end; + end; + fMachineType:=aMachineType; + fOppositeEndianess:=fNativeEndianess<>fEndianess; +Index: fpc/fpcsrc/packages/fpmkunit/src/fpmkunit.pp +=================================================================== +--- fpc.orig/fpcsrc/packages/fpmkunit/src/fpmkunit.pp ++++ fpc/fpcsrc/packages/fpmkunit/src/fpmkunit.pp +@@ -110,7 +110,7 @@ Type + // Please keep this order, see OSCPUSupported below + TCpu=(cpuNone, + i386,m68k,powerpc,sparc,x86_64,arm,powerpc64,avr,armeb, +- mips,mipsel,jvm,i8086 ++ mips,mipsel,jvm,i8086,aarch64 + ); + TCPUS = Set of TCPU; + +@@ -184,45 +184,45 @@ Const + + { This table is kept OS,Cpu because it is easier to maintain (PFV) } + OSCPUSupported : array[TOS,TCpu] of boolean = ( +- { os none i386 m68k ppc sparc x86_64 arm ppc64 avr armeb mips mipsel jvm i8086} +- { none } ( false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { linux } ( false, true, true, true, true, true, true, true, false, true , true , true , false, false), +- { go32v2 } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false), +- { win32 } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false), +- { os2 } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false), +- { freebsd } ( false, true, true, false, false, true, false, false, false, false, false, false, false, false), +- { beos } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false), +- { netbsd } ( false, true, true, true, true, true, false, false, false, false, false, false, false, false), +- { amiga } ( false, false, true, true, false, false, false, false, false, false, false, false, false, false), +- { atari } ( false, false, true, false, false, false, false, false, false, false, false, false, false, false), +- { solaris } ( false, true, false, false, true, true, false, false, false, false, false, false, false, false), +- { qnx } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false), +- { netware } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false), +- { openbsd } ( false, true, true, false, false, true, false, false, false, false, false, false, false, false), +- { wdosx } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false), +- { palmos } ( false, false, true, false, false, false, true, false, false, false, false, false, false, false), +- { macos } ( false, false, false, true, false, false, false, false, false, false, false, false, false, false), +- { darwin } ( false, true, false, true, false, true, true, true, false, false, false, false, false, false), +- { emx } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false), +- { watcom } ( false, true, false, false, false ,false, false, false, false, false, false, false, false, false), +- { morphos } ( false, false, false, true, false ,false, false, false, false, false, false, false, false, false), +- { netwlibc }( false, true, false, false, false, false, false, false, false, false, false, false, false, false), +- { win64 } ( false, false, false, false, false, true, false, false, false, false, false, false, false, false), +- { wince }( false, true, false, false, false, false, true, false, false, false, false, false, false, false), +- { gba } ( false, false, false, false, false, false, true, false, false, false, false, false, false, false), +- { nds } ( false, false, false, false, false, false, true, false, false, false, false, false, false, false), +- { embedded }( false, true, true, true, true, true, true, true, true, true , false, false, false, false), +- { symbian } ( false, true, false, false, false, false, true, false, false, false, false, false, false, false), +- { haiku } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false), +- { iphonesim}( false, true, false, false, false, false, false, false, false, false, false, false, false, false), +- { aix } ( false, false, false, true, false, false, false, true, false, false, false, false, false, false), +- { java } ( false, false, false, false, false, false, false, false, false, false, false, false, true , false), +- { android } ( false, true, false, false, false, false, true, false, false, false, false, true, true , false), +- { nativent }( false, true, false, false, false, false, false, false, false, false, false, false, false, false), +- { msdos } ( false, false, false, false, false, false, false, false, false, false, false, false, false, true ), +- { wii } ( false, false, false, true , false, false, false, false, false, false, false, false, false, false), +- { aros } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { dragonfly}( false, false, false, false, false, true, false, false, false, false, false, false, false, false ) ++ { os none i386 m68k ppc sparc x86_64 arm ppc64 avr armeb mips mipsel jvm i8086 aarch64 } ++ { none } ( false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { linux } ( false, true, true, true, true, true, true, true, false, true , true , true , false, false, true ), ++ { go32v2 } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { win32 } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { os2 } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { freebsd } ( false, true, true, false, false, true, false, false, false, false, false, false, false, false, false), ++ { beos } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { netbsd } ( false, true, true, true, true, true, false, false, false, false, false, false, false, false, false), ++ { amiga } ( false, false, true, true, false, false, false, false, false, false, false, false, false, false, false), ++ { atari } ( false, false, true, false, false, false, false, false, false, false, false, false, false, false, false), ++ { solaris } ( false, true, false, false, true, true, false, false, false, false, false, false, false, false, false), ++ { qnx } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { netware } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { openbsd } ( false, true, true, false, false, true, false, false, false, false, false, false, false, false, false), ++ { wdosx } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { palmos } ( false, false, true, false, false, false, true, false, false, false, false, false, false, false, false), ++ { macos } ( false, false, false, true, false, false, false, false, false, false, false, false, false, false, false), ++ { darwin } ( false, true, false, true, false, true, true, true, false, false, false, false, false, false, true ), ++ { emx } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { watcom } ( false, true, false, false, false ,false, false, false, false, false, false, false, false, false, false), ++ { morphos } ( false, false, false, true, false ,false, false, false, false, false, false, false, false, false, false), ++ { netwlibc }( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { win64 } ( false, false, false, false, false, true, false, false, false, false, false, false, false, false, false), ++ { wince }( false, true, false, false, false, false, true, false, false, false, false, false, false, false, false), ++ { gba } ( false, false, false, false, false, false, true, false, false, false, false, false, false, false, false), ++ { nds } ( false, false, false, false, false, false, true, false, false, false, false, false, false, false, false), ++ { embedded }( false, true, true, true, true, true, true, true, true, true , false, false, false, false, false), ++ { symbian } ( false, true, false, false, false, false, true, false, false, false, false, false, false, false, false), ++ { haiku } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { iphonesim}( false, true, false, false, false, true, false, false, false, false, false, false, false, false, false), ++ { aix } ( false, false, false, true, false, false, false, true, false, false, false, false, false, false, false), ++ { java } ( false, false, false, false, false, false, false, false, false, false, false, false, true , false, false), ++ { android } ( false, true, false, false, false, false, true, false, false, false, false, true, true , false, false), ++ { nativent }( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { msdos } ( false, false, false, false, false, false, false, false, false, false, false, false, false, true , false), ++ { wii } ( false, false, false, true , false, false, false, false, false, false, false, false, false, false, false), ++ { aros } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { dragonfly}( false, false, false, false, false, true, false, false, false, false, false, false, false, false, false) + ); + + // Useful +@@ -2645,6 +2645,7 @@ begin + x86_64: result := GetGccDirArch('cpux86_64','-m64'); + powerpc: result := GetGccDirArch('cpupowerpc','-m32'); + powerpc64:result := GetGccDirArch('cpupowerpc64','-m64'); ++ aarch64: result := GetGccDirArch('cpuaarch64',''); + end {case} + else if OS = darwin then + case CPU of +@@ -2652,6 +2653,8 @@ begin + x86_64: result := GetGccDirArch('cpux86_64','-arch x86_64'); + powerpc: result := GetGccDirArch('cpupowerpc','-arch ppc'); + powerpc64:result := GetGccDirArch('cpupowerpc64','-arch ppc64'); ++ { this target uses clang } ++ aarch64: result := '' + end; {case} + end; + +Index: fpc/fpcsrc/packages/iosxlocale/Makefile.fpc.fpcmake +=================================================================== +--- fpc.orig/fpcsrc/packages/iosxlocale/Makefile.fpc.fpcmake ++++ fpc/fpcsrc/packages/iosxlocale/Makefile.fpc.fpcmake +@@ -7,7 +7,7 @@ name=univint + version=3.0.4 + + [target] +-units=iosxlocale ++units=iosxlocale iosxwstr + + [libs] + libversion=2.0.0 +Index: fpc/fpcsrc/packages/iosxlocale/fpmake.pp +=================================================================== +--- fpc.orig/fpcsrc/packages/iosxlocale/fpmake.pp ++++ fpc/fpcsrc/packages/iosxlocale/fpmake.pp +@@ -22,6 +22,7 @@ begin + P.OSes:=[darwin,iphonesim]; + + T:=P.Targets.AddUnit('iosxlocale.pp'); ++ T:=P.Targets.AddUnit('iosxwstr.pp'); + + {$ifndef ALLPACKAGES} + Run; +Index: fpc/fpcsrc/packages/iosxlocale/src/iosxwstr.pp +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/packages/iosxlocale/src/iosxwstr.pp +@@ -0,0 +1,665 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 2015 by Jonas Maebe, ++ member of the Free Pascal development team. ++ ++ CoreFoundation-based wide string support ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ **********************************************************************} ++ ++{$mode objfpc} ++{$implicitexceptions off} ++ ++unit iosxwstr; ++ ++interface ++ ++{$linkframework CoreFoundation} ++ ++ procedure SetCFWidestringManager; ++ ++implementation ++ ++ uses ++ unixcp, ++ { for access to libiconv-based routines } ++ cwstring, ++ MacTypes, ++ CFBase,CFString,CFStringEncodingExt,CFLocale; ++ ++ procedure fpc_rangeerror; [external name 'FPC_RANGEERROR']; ++ ++ var ++ CWStringWideStringManager: TUnicodeStringManager; ++ ++ procedure InitThread; ++ begin ++ { we don't need anything special, but since we may use cwstring itself, ++ call through to it } ++ CWStringWideStringManager.ThreadInitProc; ++ end; ++ ++ ++ procedure FiniThread; ++ begin ++ { we don't need anything special, but since we may use cwstring itself, ++ call through to it } ++ CWStringWideStringManager.ThreadFiniProc; ++ end; ++ ++ ++ function get_cfencoding_for_cp(cp: TSystemCodePage): CFStringEncoding; ++ var ++ defscp: TSystemCodePage; ++ begin ++ { translate placeholder code pages } ++ if (cp=CP_ACP) or ++ (cp=CP_OEMCP) then ++ cp:=DefaultSystemCodePage; ++ result:=CFStringConvertWindowsCodepageToEncoding(cp); ++ end; ++ ++ ++ procedure GetAnsiDataFromCFString(str: CFstringRef; cfcp: CFStringEncoding; estimated_length: SizeInt; var dest: RawByteString); ++ var ++ range: CFRange; ++ encodedlen,convertedchars: CFIndex; ++ strlen: SizeInt; ++ begin ++ { first rough estimate for the length } ++ setlength(dest,estimated_length); ++ { try to convert } ++ range.location:=0; ++ strlen:=CFStringGetLength(str); ++ range.length:=strlen; ++ convertedchars:=CFStringGetBytes(str,range,cfcp,ByteParameter('?'),false,UInt8Ptr(dest),estimated_length,encodedlen); ++ { failed -> bail out } ++ if convertedchars<0 then ++ begin ++ CFRelease(str); ++ runerror(231); ++ end ++ { if partially succesful, recreate with the required len } ++ else if convertedcharsstrlen then ++ begin ++ CFRelease(str); ++ runerror(231); ++ end; ++ end; ++ { truncate } ++ setlength(dest,encodedlen); ++ end; ++ ++ ++ function CFStringCreateFromAnsiData(data: pchar; len: SizeInt; cp: TSystemCodePage): CFStringRef; ++ var ++ strlen,encodedlen: CFIndex; ++ range: CFRange; ++ cfcp: CFStringEncoding; ++ begin ++ result:=nil; ++ { get source cf codepage } ++ cfcp:=get_cfencoding_for_cp(cp); ++ { unsupported encoding -> try libiconv instead } ++ if cfcp=kCFStringEncodingInvalidId then ++ exit; ++ { make a cfstring from the original data } ++ result:=CFStringCreateWithBytesNoCopy(nil,UnivPtr(data),len,cfcp,false,kCFAllocatorNull); ++ end; ++ ++ ++ function CFStringCreateFromAnsiDataOptionallyViaUnicodeString(data: pchar; len: SizeInt; cp: TSystemCodePage; out wtemp: UnicodeString): CFStringRef; ++ begin ++ result:=CFStringCreateFromAnsiData(data,len,cp); ++ { failed -> translate via libiconv and then create using the unicodestring ++ characters; since we use the no-copy constructor for performance ++ reasons, the unicodestring has to survive this routine } ++ if not assigned(result) then ++ begin ++ CWStringWideStringManager.Ansi2UnicodeMoveProc(data,cp,wtemp,len); ++ result:=CFStringCreateWithCharactersNoCopy(nil,UniCharPtr(wtemp),len,kCFAllocatorNull); ++ end; ++ end; ++ ++ ++ function CFStringCreateFromWideData(data: pwidechar; len: SizeInt): CFStringRef; inline; ++ begin ++ { make a cfstring from the utf-16 data } ++ result:=CFStringCreateWithCharactersNoCopy(nil,UniCharPtr(data),len,kCFAllocatorNull); ++ end; ++ ++ ++ function CFStringCreateFromWideDataOptionallyViaUUTF8String(data: pwidechar; len: SizeInt; out temp: RawByteString): CFStringRef; ++ begin ++ result:=CFStringCreateFromWideData(data,len); ++ { failed -> translate to UTF-8 via libiconv to filter out any ++ potentially invalid characters and then create using the unicodestring ++ characters; since we use the no-copy constructor for performance ++ reasons, the unicodestring has to survive this routine } ++ if not assigned(result) then ++ begin ++ CWStringWideStringManager.Unicode2AnsiMoveProc(data,temp,CP_UTF8,len); ++ result:=CFStringCreateWithBytesNoCopy(nil,UnivPtr(temp),length(temp),kCFStringEncodingUTF8,false,kCFAllocatorNull); ++ if not assigned(result) then ++ runerror(231) ++ end; ++ end; ++ ++ ++ procedure Wide2AnsiMove(source:pwidechar; var dest:RawByteString; cp:TSystemCodePage; len:SizeInt); ++ var ++ str: CFStringRef; ++ strlen,estimatedlen: CFIndex; ++ cfcp: CFStringEncoding; ++ begin ++ str:=nil; ++ { get target cf codepage } ++ cfcp:=get_cfencoding_for_cp(cp); ++ { unsupported encoding -> default move } ++ if cfcp<>kCFStringEncodingInvalidId then ++ { make a cfstring from the utf-16 data } ++ str:=CFStringCreateFromWideData(source,len); ++ { You cannot create a CFString for a sequence that contains an error :/ ++ We want to replace the error positions with '?' -> fall back to libiconv ++ } ++ if not assigned(str) then ++ begin ++ CWStringWideStringManager.Unicode2AnsiMoveProc(source,dest,cp,len); ++ exit; ++ end; ++ ++ GetAnsiDataFromCFString(str,cfcp,len*3,dest); ++ { set code page } ++ SetCodePage(dest,cp,false); ++ { release cfstring } ++ CFRelease(str); ++ end; ++ ++ ++ procedure Ansi2WideMove(source:pchar; cp:TSystemCodePage; var dest:widestring; len:SizeInt); ++ var ++ str: CFStringRef; ++ strlen,encodedlen: CFIndex; ++ range: CFRange; ++ cfcp: CFStringEncoding; ++ begin ++ str:=CFStringCreateFromAnsiData(source,len,cp); ++ { You cannot create a CFString for a sequence that contains an error :/ ++ We want to replace the error positions with '?' -> fall back to libiconv ++ } ++ if not assigned(str) then ++ begin ++ CWStringWideStringManager.Ansi2UnicodeMoveProc(source,cp,dest,len); ++ exit; ++ end; ++ ++ { convert } ++ range.location:=0; ++ strlen:=CFStringGetLength(str); ++ range.length:=strlen; ++ setlength(dest,strlen); ++ CFStringGetCharacters(str,range,UniCharPtr(dest)); ++ { release cfstring } ++ CFRelease(str); ++ end; ++ ++ ++ function LowerWideString(const s : WideString) : WideString; ++ var ++ str: CFStringRef; ++ mstr: CFMutableStringRef; ++ range: CFRange; ++ encodedlen: CFIndex; ++ locale: CFLocaleRef; ++ temp: RawByteString; ++ begin ++ { empty string -> exit } ++ if s='' then ++ begin ++ result:=''; ++ exit; ++ end; ++ { create cfstring from the string data } ++ str:=CFStringCreateFromWideDataOptionallyViaUUTF8String(pwidechar(s),length(s),temp); ++ { convert to mutable cfstring } ++ mstr:=CFStringCreateMutableCopy(nil,0,str); ++ { lowercase } ++ locale:=CFLocaleCopyCurrent; ++ CFStringLowercase(mstr,locale); ++ CFRelease(locale); ++ { extract the data again } ++ range.location:=0; ++ range.length:=CFStringGetLength(CFStringRef(mstr)); ++ setlength(result,range.length); ++ CFStringGetCharacters(mstr,range,UniCharPtr(result)); ++ CFRelease(mstr); ++ CFRelease(str); ++ end; ++ ++ ++ function UpperWideString(const s : WideString) : WideString; ++ var ++ str: CFStringRef; ++ mstr: CFMutableStringRef; ++ range: CFRange; ++ encodedlen: CFIndex; ++ locale: CFLocaleRef; ++ temp: RawByteString; ++ begin ++ { empty string -> exit } ++ if s='' then ++ begin ++ result:=''; ++ exit; ++ end; ++ { create cfstring from the string data } ++ str:=CFStringCreateFromWideDataOptionallyViaUUTF8String(pwidechar(s),length(s),temp); ++ { convert to mutable cfstring } ++ mstr:=CFStringCreateMutableCopy(nil,0,str); ++ { lowercase } ++ locale:=CFLocaleCopyCurrent; ++ CFStringUppercase(mstr,locale); ++ CFRelease(locale); ++ { extract the data again } ++ range.location:=0; ++ range.length:=CFStringGetLength(CFStringRef(mstr)); ++ setlength(result,range.length); ++ CFStringGetCharacters(mstr,range,UniCharPtr(result)); ++ CFRelease(mstr); ++ CFRelease(str); ++ end; ++ ++ ++ function UpperLowerAnsiString(const s: AnsiString; upper: boolean): AnsiString; ++ var ++ str: CFStringRef; ++ mstr: CFMutableStringRef; ++ cfcp: CFStringEncoding; ++ locale: CFLocaleRef; ++ wtemp: UnicodeString; ++ range: CFRange; ++ begin ++ if s='' then ++ begin ++ result:=''; ++ exit ++ end; ++ str:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(pchar(s),length(s),StringCodePage(s),wtemp); ++ { unsupported encoding for either CF or iconv -> return original string } ++ if not assigned(str) then ++ begin ++ result:=s; ++ exit; ++ end; ++ { convert to mutable cfstring } ++ mstr:=CFStringCreateMutableCopy(nil,0,str); ++ CFRelease(str); ++ { upper/lowercase } ++ locale:=CFLocaleCopyCurrent; ++ if upper then ++ CFStringUppercase(mstr,locale) ++ else ++ CFStringLowercase(mstr,locale); ++ CFRelease(locale); ++ { convert back to ansistring } ++ cfcp:=get_cfencoding_for_cp(StringCodePage(s)); ++ if cfcp<>kCFStringEncodingInvalidId then ++ begin ++ GetAnsiDataFromCFString(CFStringRef(mstr),cfcp,length(s),RawByteString(result)); ++ SetCodePage(RawByteString(result),StringCodePage(s),false); ++ end ++ else ++ begin ++ { unsupported encoding -> use libiconv instead via UTF-16 ++ intermediate } ++ range.location:=0; ++ range.length:=CFStringGetLength(mstr); ++ SetLength(wtemp,range.length); ++ CFStringGetCharacters(mstr,range,UniCharPtr(wtemp)); ++ CWStringWideStringManager.Wide2AnsiMoveProc(pwidechar(wtemp),RawByteString(result),StringCodePage(s),range.length); ++ end; ++ CFRelease(mstr); ++ end; ++ ++ ++ function LowerAnsiString(const s: AnsiString): AnsiString; ++ begin ++ result:=UpperLowerAnsiString(s,false); ++ end; ++ ++ ++ function UpperAnsiString(const s: AnsiString): AnsiString; ++ begin ++ result:=UpperLowerAnsiString(s,true); ++ end; ++ ++ ++ function CompareCFStrings(const s1, s2: CFStringRef; case_insensitive: boolean): longint; ++ var ++ flags: CFStringCompareFlags; ++ begin ++ flags:=0; ++ if case_insensitive then ++ flags:=flags or kCFCompareCaseInsensitive; ++ result:=CFStringCompare(s1,s2,flags) ++ end; ++ ++ ++ function CompareWideString(const s1, s2 : WideString) : PtrInt; ++ var ++ cfstr1, cfstr2: CFStringRef; ++ temp1, temp2: RawByteString; ++ begin ++ cfstr1:=CFStringCreateFromWideDataOptionallyViaUUTF8String(pwidechar(s1),length(s1),temp1); ++ cfstr2:=CFStringCreateFromWideDataOptionallyViaUUTF8String(pwidechar(s2),length(s2),temp2); ++ result:=CompareCFStrings(cfstr1,cfstr2,false); ++ CFRelease(cfstr1); ++ CFRelease(cfstr2); ++ end; ++ ++ function CompareTextWideString(const s1, s2 : WideString): PtrInt; ++ var ++ cfstr1, cfstr2: CFStringRef; ++ temp1, temp2: RawByteString; ++ begin ++ cfstr1:=CFStringCreateFromWideDataOptionallyViaUUTF8String(pwidechar(s1),length(s1),temp1); ++ cfstr2:=CFStringCreateFromWideDataOptionallyViaUUTF8String(pwidechar(s2),length(s2),temp2); ++ result:=CompareCFStrings(cfstr1,cfstr2,true); ++ CFRelease(cfstr1); ++ CFRelease(cfstr2); ++ end; ++ ++ ++ function InternalCodePointLength(const Str: PChar; cfcp: CFStringEncoding; maxlookahead: ptrint): PtrInt; ++ var ++ cfstr: CFStringRef; ++ begin ++ result:=0; ++ { try creating a string with the first 1, 2, ... bytes until we find a ++ valid one } ++ while (str[result]<>#0) and ++ (result skip } ++ if tmplen=-1 then ++ tmplen:=1; ++ inc(s,tmplen); ++ inc(result); ++ until s[0]=#0; ++ end; ++ ++ ++ function CodePointLength(const Str: PChar; maxlookahead: ptrint): PtrInt; ++ var ++ cfstr: CFStringRef; ++ cfcp: CFStringEncoding; ++ begin ++ result:=0; ++ if str[0]=#0 then ++ exit; ++ cfcp:=get_cfencoding_for_cp(DefaultSystemCodePage); ++ if cfcp=kCFStringEncodingInvalidId then ++ begin ++ { if we would return -1, then the caller would keep trying with ++ longer and longer sequences, but that wouldn't change anything } ++ result:=1; ++ exit ++ end; ++ result:=InternalCodePointLength(str,cfcp,maxlookahead); ++ end; ++ ++ ++ function CompareStrAnsiString(const s1, s2: ansistring): PtrInt; ++ var ++ cfstr1, cfstr2: CFStringRef; ++ wtemp1, wtemp2: UnicodeString; ++ begin ++ cfstr1:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(pchar(s1),length(s1),StringCodePage(s1),wtemp1); ++ cfstr2:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(pchar(s2),length(s2),StringCodePage(s2),wtemp2); ++ result:=CompareCFStrings(cfstr1,cfstr2,false); ++ CFRelease(cfstr1); ++ CFRelease(cfstr2); ++ end; ++ ++ ++ function StrCompAnsi(s1,s2 : PChar): PtrInt; ++ var ++ cfstr1, cfstr2: CFStringRef; ++ wtemp1, wtemp2: UnicodeString; ++ begin ++ cfstr1:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(s1,strlen(s1),DefaultSystemCodePage,wtemp1); ++ cfstr2:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(s2,strlen(s2),DefaultSystemCodePage,wtemp2); ++ result:=CompareCFStrings(cfstr1,cfstr2,false); ++ CFRelease(cfstr1); ++ CFRelease(cfstr2); ++ end; ++ ++ ++ function AnsiCompareText(const S1, S2: ansistring): PtrInt; ++ var ++ cfstr1, cfstr2: CFStringRef; ++ wtemp1, wtemp2: UnicodeString; ++ begin ++ cfstr1:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(pchar(s1),length(s1),DefaultSystemCodePage,wtemp1); ++ cfstr2:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(pchar(s2),length(s2),DefaultSystemCodePage,wtemp2); ++ result:=CompareCFStrings(cfstr1,cfstr2,true); ++ CFRelease(cfstr1); ++ CFRelease(cfstr2); ++ end; ++ ++ ++ function AnsiStrIComp(S1, S2: PChar): PtrInt; ++ var ++ cfstr1, cfstr2: CFStringRef; ++ wtemp1, wtemp2: UnicodeString; ++ begin ++ cfstr1:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(s1,strlen(s1),DefaultSystemCodePage,wtemp1); ++ cfstr2:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(s2,strlen(s2),DefaultSystemCodePage,wtemp2); ++ result:=CompareCFStrings(cfstr1,cfstr2,true); ++ CFRelease(cfstr1); ++ CFRelease(cfstr2); ++ end; ++ ++ ++ function AnsiStrLComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt; ++ var ++ cfstr1, cfstr2: CFStringRef; ++ wtemp1, wtemp2: UnicodeString; ++ begin ++ cfstr1:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(s1,MaxLen,StringCodePage(s1),wtemp1); ++ cfstr2:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(s2,MaxLen,StringCodePage(s2),wtemp2); ++ result:=CompareCFStrings(cfstr1,cfstr2,false); ++ CFRelease(cfstr1); ++ CFRelease(cfstr2); ++ end; ++ ++ ++ function AnsiStrLIComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt; ++ var ++ cfstr1, cfstr2: CFStringRef; ++ wtemp1, wtemp2: UnicodeString; ++ begin ++ cfstr1:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(s1,MaxLen,StringCodePage(s1),wtemp1); ++ cfstr2:=CFStringCreateFromAnsiDataOptionallyViaUnicodeString(s2,MaxLen,StringCodePage(s2),wtemp2); ++ result:=CompareCFStrings(cfstr1,cfstr2,true); ++ CFRelease(cfstr1); ++ CFRelease(cfstr2); ++ end; ++ ++ ++ procedure ansi2pchar(const s: ansistring; const orgp: pchar; out p: pchar); ++ var ++ newlen: sizeint; ++ begin ++ newlen:=length(s); ++ if newlen>strlen(orgp) then ++ fpc_rangeerror; ++ p:=orgp; ++ if (newlen>0) then ++ move(s[1],p[0],newlen); ++ p[newlen]:=#0; ++ end; ++ ++ ++ function AnsiStrLower(Str: PChar): PChar; ++ var ++ temp: ansistring; ++ begin ++ temp:=loweransistring(str); ++ ansi2pchar(temp,str,result); ++ end; ++ ++ ++ function AnsiStrUpper(Str: PChar): PChar; ++ var ++ temp: ansistring; ++ begin ++ temp:=upperansistring(str); ++ ansi2pchar(temp,str,result); ++ end; ++ ++ ++ function GetStandardCodePage(const stdcp: TStandardCodePageEnum): TSystemCodePage; ++ var ++ langinfo: pchar; ++ begin ++ { don't use CFStringGetSystemEncoding, that one returns MacRoman on e.g. ++ an English system, which is definitely not what we want. Since there are ++ no "ansi" interfaces on OS X and all APIs support all characters, always ++ use UTF-8. Additionally,  Darwin always uses UTF-8 for file system ++ operations } ++ result:=CP_UTF8; ++ end; ++ ++ ++ procedure SetStdIOCodePage(var T: Text); inline; ++ begin ++ case TextRec(T).Mode of ++ fmInput:TextRec(T).CodePage:=GetStandardCodePage(scpConsoleInput); ++ fmOutput:TextRec(T).CodePage:=GetStandardCodePage(scpConsoleOutput); ++ end; ++ end; ++ ++ ++ procedure SetStdIOCodePages; inline; ++ begin ++ SetStdIOCodePage(Input); ++ SetStdIOCodePage(Output); ++ SetStdIOCodePage(ErrOutput); ++ SetStdIOCodePage(StdOut); ++ SetStdIOCodePage(StdErr); ++ end; ++ ++ ++ procedure SetCFWideStringManager; ++ var ++ CFWideStringManager : TUnicodeStringManager; ++ begin ++ GetUnicodeStringManager(CWStringWideStringManager); ++ CFWideStringManager:=CWStringWideStringManager; ++ with CFWideStringManager do ++ begin ++ Wide2AnsiMoveProc:=@Wide2AnsiMove; ++ Ansi2WideMoveProc:=@Ansi2WideMove; ++ ++ UpperWideStringProc:=@UpperWideString; ++ LowerWideStringProc:=@LowerWideString; ++ ++ CompareWideStringProc:=@CompareWideString; ++ CompareTextWideStringProc:=@CompareTextWideString; ++ ++ CharLengthPCharProc:=@CharLengthPChar; ++ CodePointLengthProc:=@CodePointLength; ++ ++ UpperAnsiStringProc:=@UpperAnsiString; ++ LowerAnsiStringProc:=@LowerAnsiString; ++ CompareStrAnsiStringProc:=@CompareStrAnsiString; ++ CompareTextAnsiStringProc:=@AnsiCompareText; ++ StrCompAnsiStringProc:=@StrCompAnsi; ++ StrICompAnsiStringProc:=@AnsiStrIComp; ++ StrLCompAnsiStringProc:=@AnsiStrLComp; ++ StrLICompAnsiStringProc:=@AnsiStrLIComp; ++ StrLowerAnsiStringProc:=@AnsiStrLower; ++ StrUpperAnsiStringProc:=@AnsiStrUpper; ++ ThreadInitProc:=@InitThread; ++ ThreadFiniProc:=@FiniThread; ++ { Unicode } ++ Unicode2AnsiMoveProc:=@Wide2AnsiMove; ++ Ansi2UnicodeMoveProc:=@Ansi2WideMove; ++ UpperUnicodeStringProc:=@UpperWideString; ++ LowerUnicodeStringProc:=@LowerWideString; ++ CompareUnicodeStringProc:=@CompareWideString; ++ CompareTextUnicodeStringProc:=@CompareTextWideString; ++ { CodePage } ++ GetStandardCodePageProc:=@GetStandardCodePage; ++ end; ++ SetUnicodeStringManager(CFWideStringManager); ++ end; ++ ++ ++initialization ++ SetCFWideStringManager; ++ ++ { set the DefaultSystemCodePage } ++ DefaultSystemCodePage:=GetStandardCodePage(scpAnsi); ++ DefaultFileSystemCodePage:=GetStandardCodePage(scpFileSystemSingleByte); ++ DefaultRTLFileSystemCodePage:=DefaultFileSystemCodePage; ++ ++ SetStdIOCodePages; ++ ++ { don't call init, we don't need to do anything and the cwstring routine we ++ call through has already been called from the init code of cwstring itself ++ InitThread; ++ } ++finalization ++ { don't call for the same reason as not calling FiniThread ++ FiniThread; ++ } ++ { restore previous widestring manager so that subsequent calls ++ into the widestring manager won't trigger the finalized functionality } ++ SetWideStringManager(CWStringWideStringManager); ++end. +Index: fpc/fpcsrc/packages/rtl-extra/src/linux/unixsock.inc +=================================================================== +--- fpc.orig/fpcsrc/packages/rtl-extra/src/linux/unixsock.inc ++++ fpc/fpcsrc/packages/rtl-extra/src/linux/unixsock.inc +@@ -13,7 +13,7 @@ + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + } + +-{$if not defined(cpux86_64) and not defined(NO_SYSCALL_SOCKETCALL)} ++{$if not defined(cpux86_64) and not defined(cpuaarch64) and not defined(NO_SYSCALL_SOCKETCALL)} + {$define NEED_SOCKETCALL} + {$endif} + +Index: fpc/fpcsrc/packages/rtl-extra/src/unix/ipc.pp +=================================================================== +--- fpc.orig/fpcsrc/packages/rtl-extra/src/unix/ipc.pp ++++ fpc/fpcsrc/packages/rtl-extra/src/unix/ipc.pp +@@ -876,7 +876,7 @@ uses Syscall; + + {$ifndef FPC_USE_LIBC} + {$if defined(Linux)} +- {$if defined(cpux86_64) or defined(NO_SYSCALL_IPC)} ++ {$if defined(cpux86_64) or defined(cpuaarch64) or defined(NO_SYSCALL_IPC)} + {$i ipcsys.inc} + {$else} + {$i ipccall.inc} +Index: fpc/fpcsrc/rtl/aarch64/aarch64.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/aarch64/aarch64.inc +@@ -0,0 +1,322 @@ ++{ ++ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 2014 by Jonas Maebe, member of ++ the Free Pascal development team. ++ ++ Processor dependent implementation for the system unit for ++ AArch64 ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ ++{$IFNDEF LINUX} ++ {$DEFINE USE_DCBZ} ++{$ENDIF LINUX} ++ ++{**************************************************************************** ++ AArch64 specific stuff ++****************************************************************************} ++const ++ fpu_ioe = 1 shl 8; ++ fpu_dze = 1 shl 9; ++ fpu_ofe = 1 shl 10; ++ fpu_ufe = 1 shl 11; ++ fpu_ixe = 1 shl 12; ++ fpu_ide = 1 shl 15; ++ fpu_exception_mask = fpu_ioe or fpu_dze or fpu_ofe or fpu_ufe or fpu_ixe or fpu_ide; ++ fpu_exception_mask_to_status_mask_shift = 8; ++ ++function getfpcr: dword; nostackframe; assembler; ++ asm ++ mrs x0,fpcr ++ end; ++ ++ ++procedure setfpcr(val: dword); nostackframe; assembler; ++ asm ++ msr fpcr,x0 ++ end; ++ ++ ++function getfpsr: dword; nostackframe; assembler; ++ asm ++ mrs x0,fpsr ++ end; ++ ++ ++procedure setfpsr(val: dword); nostackframe; assembler; ++ asm ++ msr fpsr, x0 ++ end; ++ ++ ++procedure fpc_enable_fpu_exceptions; ++ begin ++ { clear all "exception happened" flags we care about} ++ setfpsr(getfpsr and not(fpu_exception_mask shr fpu_exception_mask_to_status_mask_shift)); ++ { enable invalid operations and division by zero exceptions. } ++ setfpcr(getfpcr or fpu_exception_mask); ++ end; ++ ++procedure fpc_cpuinit; ++ begin ++ { don't let libraries influence the FPU cw set by the host program } ++ if not IsLibrary then ++ fpc_enable_fpu_exceptions; ++ end; ++ ++ ++{**************************************************************************** ++ Move / Fill ++****************************************************************************} ++ ++ ++{**************************************************************************** ++ String ++****************************************************************************} ++ ++{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} ++function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler; nostackframe; ++ asm ++ cbz x0, .Lcaller_addr_invalid ++ ldur x0, [x0] ++ cbz x0, .Lcaller_addr_invalid ++ ldur x0, [x0, #8] ++ .Lcaller_addr_invalid: ++ end; ++ ++ ++{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} ++function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler; nostackframe; ++ asm ++ cbz x0, .Lcaller_addr_invalid ++ ldur x0, [x0] ++ .Lcaller_addr_invalid: ++ end; ++ ++ ++{$define FPC_SYSTEM_HAS_SPTR} ++Function Sptr : Pointer;assembler; nostackframe; ++ asm ++ mov x0, sp ++ end; ++ ++ ++{**************************************************************************** ++ Str() ++****************************************************************************} ++ ++{ int_str: generic implementation is used for now } ++ ++ ++{**************************************************************************** ++ Multithreading ++****************************************************************************} ++ ++{ perform a thread-safe inc/dec } ++ ++{$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT} ++function declocked(var l : longint) : boolean;assembler;nostackframe; ++ { input: address of l in x0 } ++ { output: boolean indicating whether l is zero after decrementing } ++ asm ++ .LDecLockedLoop: ++ ldxr w1,[x0] ++ sub w1,w1,#1 ++ stxr w2,w1,[x0] ++ cbnz w2,.LDecLockedLoop ++ cset w0, eq ++ end; ++ ++ ++{$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT} ++procedure inclocked(var l : longint);assembler;nostackframe; ++ asm ++ .LIncLockedLoop: ++ ldxr w1,[x0] ++ add w1,w1,#1 ++ stxr w2,w1,[x0] ++ cbnz w2,.LIncLockedLoop ++ end; ++ ++ ++{$define FPC_SYSTEM_HAS_DECLOCKED_INT64} ++function declocked(var l : int64) : boolean;assembler;nostackframe; ++ { input: address of l in x0 } ++ { output: boolean indicating whether l is zero after decrementing } ++ asm ++ .LDecLockedLoop: ++ ldxr x1,[x0] ++ subs x1,x1,#1 ++ stxr w2,x1,[x0] ++ cbnz w2,.LDecLockedLoop ++ cset w0, eq ++ end; ++ ++ ++{$define FPC_SYSTEM_HAS_INCLOCKED_INT64} ++procedure inclocked(var l : int64);assembler;nostackframe; ++ asm ++ .LIncLockedLoop: ++ ldxr x1,[x0] ++ add x1,x1,#1 ++ stxr w2,x1,[x0] ++ cbnz w2,.LIncLockedLoop ++ end; ++ ++ ++function InterLockedDecrement (var Target: longint) : longint; assembler; nostackframe; ++ { input: address of target in x0 } ++ { output: target-1 in x0 } ++ { side-effect: target := target-1 } ++ asm ++ .LInterDecLockedLoop: ++ ldxr w1,[x0] ++ sub w1,w1,#1 ++ stxr w2,w1,[x0] ++ cbnz w2,.LInterDecLockedLoop ++ mov w0,w1 ++ end; ++ ++ ++function InterLockedIncrement (var Target: longint) : longint; assembler; nostackframe; ++ { input: address of target in x0 } ++ { output: target+1 in x0 } ++ { side-effect: target := target+1 } ++ asm ++ .LInterIncLockedLoop: ++ ldxr w1,[x0] ++ add w1,w1,#1 ++ stxr w2,w1,[x0] ++ cbnz w2,.LInterIncLockedLoop ++ mov w0,w1 ++ end; ++ ++ ++function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler; nostackframe; ++ { input: address of target in x0, source in w1 } ++ { output: target in x0 } ++ { side-effect: target := source } ++ asm ++ .LInterLockedXchgLoop: ++ ldxr w2,[x0] ++ stxr w3,w1,[x0] ++ cbnz w3,.LInterLockedXchgLoop ++ mov w0,w2 ++ end; ++ ++ ++function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; assembler; nostackframe; ++ asm ++ .LInterLockedXchgAddLoop: ++ ldxr w2,[x0] ++ add w4,w2,w1 ++ stxr w3,w4,[x0] ++ cbnz w3,.LInterLockedXchgAddLoop ++ mov w0,w2 ++ end; ++ ++ ++function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint; assembler; nostackframe; ++ { input: address of target in x0, newvalue in w1, comparand in w2 } ++ { output: value stored in target before entry of the function } ++ { side-effect: NewValue stored in target if (target = comparand) } ++ asm ++ .LInterlockedCompareExchangeLoop: ++ ldxr w3,[x0] ++ cmp w3,w2 ++ csel w4,w1,w3,eq ++ stxr w5,w4,[x0] ++ cbnz w5,.LInterlockedCompareExchangeLoop ++ mov w0,w3 ++ end; ++ ++ ++function InterLockedDecrement64 (var Target: int64) : int64; assembler; nostackframe; ++ asm ++ .LInterDecLockedLoop: ++ ldxr x1,[x0] ++ sub x1,x1,#1 ++ stxr w2,x1,[x0] ++ cbnz w2,.LInterDecLockedLoop ++ mov x0,x1 ++ end; ++ ++ ++function InterLockedIncrement64 (var Target: int64) : int64; assembler; nostackframe; ++ asm ++ .LInterIncLockedLoop: ++ ldxr x1,[x0] ++ add x1,x1,#1 ++ stxr w2,x1,[x0] ++ cbnz w2,.LInterIncLockedLoop ++ mov x0,x1 ++ end; ++ ++ ++function InterLockedExchange64 (var Target: int64;Source : int64) : int64; assembler; nostackframe; ++ asm ++ .LInterLockedXchgLoop: ++ ldxr x2,[x0] ++ stxr w3,x1,[x0] ++ cbnz w3,.LInterLockedXchgLoop ++ mov x0,x2 ++ end; ++ ++ ++function InterLockedExchangeAdd64 (var Target: int64;Source : int64) : int64; assembler; nostackframe; ++ asm ++ .LInterLockedXchgAddLoop: ++ ldxr x2,[x0] ++ add x4,x2,x1 ++ stxr w3,x4,[x0] ++ cbnz w3,.LInterLockedXchgAddLoop ++ mov x0,x2 ++ end; ++ ++ ++function InterLockedCompareExchange64(var Target: int64; NewValue, Comperand : int64): int64; assembler; nostackframe; ++ asm ++ .LInterlockedCompareExchangeLoop: ++ ldxr x3,[x0] ++ cmp x3,x2 ++ csel x4,x1,x3,eq ++ stxr w5,x4,[x0] ++ cbnz w5,.LInterlockedCompareExchangeLoop ++ mov x0,x3 ++ end; ++ ++ ++{$ifndef FPC_SYSTEM_HAS_MEM_BARRIER} ++{$define FPC_SYSTEM_HAS_MEM_BARRIER} ++procedure ReadBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif} ++ asm ++ { dmb ishld } ++ dmb #9 ++ end; ++ ++procedure ReadDependencyBarrier;{$ifdef SYSTEMINLINE}inline;{$endif} ++begin ++ { reads imply barrier on earlier reads depended on } ++end; ++ ++procedure ReadWriteBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif} ++asm ++ { dmb ish } ++ dmb #11 ++end; ++ ++procedure WriteBarrier;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif} ++asm ++ { dmb ishst } ++ dmb #10 ++end; ++ ++{$endif} +Index: fpc/fpcsrc/rtl/aarch64/int64p.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/aarch64/int64p.inc +@@ -0,0 +1,15 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 1999-2000 by the Free Pascal development team ++ ++ This file contains some helper routines for int64 and qword ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++{ only dummy on AArch64 since it has a 64 bit integer unit } +Index: fpc/fpcsrc/rtl/aarch64/makefile.cpu +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/aarch64/makefile.cpu +@@ -0,0 +1,7 @@ ++# ++# Here we set processor dependent include file names. ++# ++ ++CPUNAMES=aarch64 int64p math set setjump setjumph strings stringss ++CPUINCNAMES=$(addsuffix .inc,$(CPUNAMES)) ++# +Index: fpc/fpcsrc/rtl/aarch64/math.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/aarch64/math.inc +@@ -0,0 +1,86 @@ ++{ ++ Implementation of mathematical routines for x86_64 ++ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 1999-2005 by the Free Pascal development team ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ ++ ++{**************************************************************************** ++ Floating point type routines ++ ****************************************************************************} ++ ++ {$ifndef FPC_SYSTEM_HAS_ABS} ++ {$define FPC_SYSTEM_HAS_ABS} ++ function fpc_abs_real(d : ValReal) : ValReal;compilerproc; ++ begin ++ { Function is handled internal in the compiler } ++ runerror(207); ++ result:=0; ++ end; ++ {$endif FPC_SYSTEM_HAS_ABS} ++ ++ ++ {$ifndef FPC_SYSTEM_HAS_SQR} ++ {$define FPC_SYSTEM_HAS_SQR} ++ function fpc_sqr_real(d : ValReal) : ValReal;compilerproc; ++ begin ++ { Function is handled internal in the compiler } ++ runerror(207); ++ result:=0; ++ end; ++ {$endif FPC_SYSTEM_HAS_SQR} ++ ++ ++ {$ifndef FPC_SYSTEM_HAS_SQRT} ++ {$define FPC_SYSTEM_HAS_SQRT} ++ function fpc_sqrt_real(d : ValReal) : ValReal;compilerproc; ++ begin ++ { Function is handled internal in the compiler } ++ runerror(207); ++ result:=0; ++ end; ++ {$endif FPC_SYSTEM_HAS_SQRT} ++ ++ ++ {$ifndef FPC_SYSTEM_HAS_INT} ++ {$define FPC_SYSTEM_HAS_INT} ++ function fpc_int_real(d : ValReal) : ValReal;assembler;nostackframe;compilerproc; ++ asm ++ { round as floating point towards zero } ++ frintz d0,d0 ++ end; ++ {$endif FPC_SYSTEM_HAS_INT} ++ ++ ++ {$ifndef FPC_SYSTEM_HAS_TRUNC} ++ {$define FPC_SYSTEM_HAS_TRUNC} ++ function fpc_trunc_real(d : ValReal) : int64;assembler;nostackframe;compilerproc; ++ asm ++ { round to signed integer towards zero } ++ fcvtzs x0,d0 ++ end; ++ {$endif FPC_SYSTEM_HAS_TRUNC} ++ ++ ++ {$ifndef FPC_SYSTEM_HAS_ROUND} ++ {$define FPC_SYSTEM_HAS_ROUND} ++ function fpc_round_real(d : ValReal) : int64;assembler;nostackframe;compilerproc; ++ asm ++ { round as floating point using current rounding mode } ++ frintx d0,d0 ++ { convert to signed integer rounding towards zero (there's no "round to ++ integer using current rounding mode") } ++ fcvtzs x0,d0 ++ end; ++ {$endif FPC_SYSTEM_HAS_ROUND} ++ ++ +Index: fpc/fpcsrc/rtl/aarch64/mathu.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/aarch64/mathu.inc +@@ -0,0 +1,157 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 2014 by Jonas Maebe ++ member of the Free Pascal development team ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++**********************************************************************} ++ ++{$asmmode gas} ++ ++function getfpcr: dword; nostackframe; assembler; ++ asm ++ mrs x0,fpcr ++ end; ++ ++ ++procedure setfpcr(val: dword); nostackframe; assembler; ++ asm ++ msr fpcr,x0 ++ end; ++ ++ ++function getfpsr: dword; nostackframe; assembler; ++ asm ++ mrs x0,fpsr ++ end; ++ ++ ++procedure setfpsr(val: dword); nostackframe; assembler; ++ asm ++ msr fpsr, x0 ++ end; ++ ++ ++function GetRoundMode: TFPURoundingMode; ++ const ++ bits2rm: array[0..3] of TFPURoundingMode = (rmNearest,rmUp,rmDown,rmTruncate); ++ begin ++ result:=TFPURoundingMode(bits2rm[(getfpcr shr 22) and 3]) ++ end; ++ ++ ++function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode; ++ const ++ rm2bits: array[TFPURoundingMode] of byte = (0,2,1,3); ++ begin ++ softfloat_rounding_mode:=RoundMode; ++ SetRoundMode:=RoundMode; ++ setfpcr((getfpcr and $ff3fffff) or (rm2bits[RoundMode] shl 22)); ++ end; ++ ++ ++function GetPrecisionMode: TFPUPrecisionMode; ++ begin ++ result:=pmDouble; ++ end; ++ ++ ++function SetPrecisionMode(const Precision: TFPUPrecisionMode): TFPUPrecisionMode; ++ begin ++ result:=pmDouble; ++ end; ++ ++ ++const ++ fpu_ioe = 1 shl 8; ++ fpu_dze = 1 shl 9; ++ fpu_ofe = 1 shl 10; ++ fpu_ufe = 1 shl 11; ++ fpu_ixe = 1 shl 12; ++ fpu_ide = 1 shl 15; ++ fpu_exception_mask = fpu_ioe or fpu_dze or fpu_ofe or fpu_ufe or fpu_ixe or fpu_ide; ++ fpu_exception_mask_to_status_mask_shift = 8; ++ ++ ++function GetExceptionMask: TFPUExceptionMask; ++ var ++ fpcr: dword; ++ begin ++ fpcr:=getfpcr; ++ result:=[]; ++ if ((fpcr and fpu_ioe)=0) then ++ result := result+[exInvalidOp]; ++ if ((fpcr and fpu_ofe)=0) then ++ result := result+[exOverflow]; ++ if ((fpcr and fpu_ufe)=0) then ++ result := result+[exUnderflow]; ++ if ((fpcr and fpu_dze)=0) then ++ result := result+[exZeroDivide]; ++ if ((fpcr and fpu_ixe)=0) then ++ result := result+[exPrecision]; ++ if ((fpcr and fpu_ide)=0) then ++ result := result+[exDenormalized]; ++ end; ++ ++ ++function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask; ++ var ++ newfpcr: dword; ++ begin ++ softfloat_exception_mask:=mask; ++ newfpcr:=fpu_exception_mask; ++ if exInvalidOp in Mask then ++ newfpcr:=newfpcr and not(fpu_ioe); ++ if exOverflow in Mask then ++ newfpcr:=newfpcr and not(fpu_ofe); ++ if exUnderflow in Mask then ++ newfpcr:=newfpcr and not(fpu_ufe); ++ if exZeroDivide in Mask then ++ newfpcr:=newfpcr and not(fpu_dze); ++ if exPrecision in Mask then ++ newfpcr:=newfpcr and not(fpu_ixe); ++ if exDenormalized in Mask then ++ newfpcr:=newfpcr and not(fpu_ide); ++ { clear "exception happened" flags } ++ ClearExceptions(false); ++ { set new exception mask } ++ setfpcr((getfpcr and not(fpu_exception_mask)) or newfpcr); ++ { unsupported mask bits will remain 0 -> read exception mask again } ++ result:=GetExceptionMask; ++ softfloat_exception_mask:=result; ++ end; ++ ++ ++procedure ClearExceptions(RaisePending: Boolean); ++ var ++ fpsr: dword; ++ f: TFPUException; ++ begin ++ fpsr:=getfpsr; ++ if raisepending then ++ begin ++ if (fpsr and (fpu_dze shr fpu_exception_mask_to_status_mask_shift)) <> 0 then ++ float_raise(exZeroDivide); ++ if (fpsr and (fpu_ofe shr fpu_exception_mask_to_status_mask_shift)) <> 0 then ++ float_raise(exOverflow); ++ if (fpsr and (fpu_ufe shr fpu_exception_mask_to_status_mask_shift)) <> 0 then ++ float_raise(exUnderflow); ++ if (fpsr and (fpu_ioe shr fpu_exception_mask_to_status_mask_shift)) <> 0 then ++ float_raise(exInvalidOp); ++ if (fpsr and (fpu_ixe shr fpu_exception_mask_to_status_mask_shift)) <> 0 then ++ float_raise(exPrecision); ++ if (fpsr and (fpu_ide shr fpu_exception_mask_to_status_mask_shift)) <> 0 then ++ float_raise(exDenormalized); ++ { now the soft float exceptions } ++ for f in softfloat_exception_flags do ++ float_raise(f); ++ end; ++ softfloat_exception_flags:=[]; ++ setfpsr(fpsr and not(fpu_exception_mask shr fpu_exception_mask_to_status_mask_shift)); ++ end; +Index: fpc/fpcsrc/rtl/aarch64/set.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/aarch64/set.inc +@@ -0,0 +1,15 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 2002 by the Free Pascal development team ++ ++ Include file with set operations called by the compiler ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ +Index: fpc/fpcsrc/rtl/aarch64/setjump.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/aarch64/setjump.inc +@@ -0,0 +1,59 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 2015 by Jonas Maebe and other members of the ++ Free Pascal development team ++ ++ SetJmp/Longjmp implementation for AArch64 ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ ++ **********************************************************************} ++ ++function fpc_setjmp(var S: jmp_buf): longint; assembler; [public, alias:'FPC_SETJMP']; nostackframe; compilerproc; ++ asm ++ mov x3, sp ++ stp x19, x20, [x0, #jmp_buf.x19] ++ stp x21, x22, [x0, #jmp_buf.x21] ++ stp x23, x24, [x0, #jmp_buf.x23] ++ stp x25, x26, [x0, #jmp_buf.x25] ++ stp x27, x28, [x0, #jmp_buf.x27] ++ stp x29, x30, [x0, #jmp_buf.x29] ++ str x3, [x0, #jmp_buf.xsp] ++ ++ stp d8, d9, [x0, #jmp_buf.d8] ++ stp d10, d11, [x0, #jmp_buf.d10] ++ stp d12, d13, [x0, #jmp_buf.d12] ++ stp d14, d15, [x0, #jmp_buf.d14] ++ ++ mov x0, xzr ++ end; ++ ++ ++procedure fpc_longjmp(var S: jmp_buf ;value: longint); assembler; [public, alias:'FPC_LONGJMP']; nostackframe; compilerproc; ++ asm ++ ldr x3, [x0, #jmp_buf.xsp] ++ ++ ldp x19, x20, [x0, #jmp_buf.x19] ++ ldp x21, x22, [x0, #jmp_buf.x21] ++ ldp x23, x24, [x0, #jmp_buf.x23] ++ ldp x25, x26, [x0, #jmp_buf.x25] ++ ldp x27, x28, [x0, #jmp_buf.x27] ++ ldp x29, x30, [x0, #jmp_buf.x29] ++ ++ mov sp, x3 ++ ++ ldp d8, d9, [x0, #jmp_buf.d8] ++ ldp d10, d11, [x0, #jmp_buf.d10] ++ ldp d12, d13, [x0, #jmp_buf.d12] ++ ldp d14, d15, [x0, #jmp_buf.d14] ++ ++ mov x0, x1 ++ end; ++ ++ +Index: fpc/fpcsrc/rtl/aarch64/setjumph.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/aarch64/setjumph.inc +@@ -0,0 +1,45 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 2000-2002 by Jonas Maebe and other members of the ++ Free Pascal development team ++ ++ SetJmp/Longjmp declarations ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ ++type ++ jmp_buf = record ++ x19: qword; ++ x20: qword; ++ x21: qword; ++ x22: qword; ++ x23: qword; ++ x24: qword; ++ x25: qword; ++ x26: qword; ++ x27: qword; ++ x28: qword; ++ x29: qword; ++ x30: qword; ++ xsp: qword; ++ d8: qword; ++ d9: qword; ++ d10: qword; ++ d11: qword; ++ d12: qword; ++ d13: qword; ++ d14: qword; ++ d15: qword; ++ end; ++ pjmp_buf = ^jmp_buf; ++ ++function setjmp(var S : jmp_buf) : longint;[external name 'FPC_SETJMP']; ++procedure longjmp(var S : jmp_buf;value : longint);[external name 'FPC_LONGJMP']; ++ +Index: fpc/fpcsrc/rtl/aarch64/strings.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/aarch64/strings.inc +@@ -0,0 +1,17 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 2003 by Florian Klaempfl, member of the ++ Free Pascal development team ++ ++ Processor dependent part of strings.pp, that can be shared with ++ sysutils unit. ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ +Index: fpc/fpcsrc/rtl/aarch64/stringss.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/aarch64/stringss.inc +@@ -0,0 +1,18 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 1999-2000 by Jonas Maebe, member of the ++ Free Pascal development team ++ ++ Processor dependent part of strings.pp, not shared with ++ sysutils unit. ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ ++ +Index: fpc/fpcsrc/rtl/arm/arm.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/arm/arm.inc ++++ fpc/fpcsrc/rtl/arm/arm.inc +@@ -15,8 +15,6 @@ + + **********************************************************************} + +-{$asmmode gas} +- + {$ifndef FPC_SYSTEM_HAS_MOVE} + {$define FPC_SYSTEM_FPC_MOVE} + {$endif FPC_SYSTEM_HAS_MOVE} +Index: fpc/fpcsrc/rtl/arm/thumb2.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/arm/thumb2.inc ++++ fpc/fpcsrc/rtl/arm/thumb2.inc +@@ -15,7 +15,7 @@ + + **********************************************************************} + +-{$asmmode gas} ++{$asmmode divided} + + {$ifndef FPC_SYSTEM_HAS_MOVE} + {$define FPC_SYSTEM_FPC_MOVE} +Index: fpc/fpcsrc/rtl/bsd/ostypes.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/bsd/ostypes.inc ++++ fpc/fpcsrc/rtl/bsd/ostypes.inc +@@ -30,8 +30,8 @@ + {$endif} + {$endif} + +-{$if (defined(darwin) and defined(cpuarm)) or defined(iphonesim)} +- {$define darwinarm} ++{$if (defined(darwin) and (defined(cpuarm) or defined(cpuaarch64))) or defined(iphonesim)} ++ {$define darwin_new_iostructs} + {$endif} + + // CONST SYS_NMLN=65; +@@ -88,7 +88,7 @@ TYPE + st_qspare2 : cint64; + {$else dragonfly} + st_dev : dev_t; // inode's device +-{$ifdef darwinarm} ++{$ifdef darwin_new_iostructs} + st_mode : mode_t; // inode protection mode + st_nlink : nlink_t; // number of hard links + st_ino : ino_t; // inode's number +@@ -115,7 +115,7 @@ TYPE + st_mtimensec : clong; // nsec of last data modification + st_ctime : time_t; // time of last file status change + st_ctimensec : clong; // nsec of last file status change +-{$ifdef darwinarm} ++{$ifdef darwin_new_iostructs} + st_birthtime : time_t; // File creation time + st_birthtimensec : clong; // nsec of file creation time + {$endif} +@@ -144,7 +144,7 @@ TYPE + pStat = ^stat; + + { directory services } +-{$ifndef darwinarm} ++{$ifndef darwin_new_iostructs} + dirent = record + d_fileno : cuint32; // file number of entry + d_reclen : cuint16; // length of this record +@@ -152,7 +152,7 @@ TYPE + d_namlen : cuint8; // length of string in d_name + d_name : array[0..(255 + 1)-1] of char; // name must be no longer than this + end; +-{$else not darwinarm} ++{$else not darwin_new_iostructs} + {$packrecords 4} + { available on Mac OS X 10.6 and later, and used by all iPhoneOS versions } + dirent = record +@@ -164,7 +164,7 @@ TYPE + d_name : array[0..PATH_MAX-1] of char; // name must be no longer than this + end; + {$packrecords c} +-{$endif darwinarm} ++{$endif darwin_new_iostructs} + TDirent = dirent; + pDirent = ^dirent; + +Index: fpc/fpcsrc/rtl/darwin/aarch64/sig_cpu.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/darwin/aarch64/sig_cpu.inc +@@ -0,0 +1,47 @@ ++ ++{$IFDEF FPC} ++{$PACKRECORDS C} ++{$ENDIF} ++ ++ ++ ++ type ++ __darwin_arm_exception_state64 = record ++ __far : cuint64; ++ __esr : cuint32; ++ __exception : cuint32; ++ end; ++ ++ __darwin_arm_thread_state64 = record ++ __r : array[0..28] of cuint64; ++ __fp : cuint64; ++ __lr : cuint64; ++ __sp : cuint64; ++ __pc : cuint64; ++ __cpsr : cuint32; ++ end; ++ ++ __darwin_arm_neon_state64 = record ++ { actually an array of cuint128 } ++ __r : array[0..31] of record l1,l2: cuint64; end; ++ __fpsr : cuint32; ++ __fpcr : cuint32; ++ { array of cuint128 is aligned/padded to multiple of 16 bytes } ++ pad: cuint64; ++ end; ++ ++ __darwin_arm_debug_state64 = record ++ __bvr : array[0..15] of cuint64; ++ __bcr : array[0..15] of cuint64; ++ __wvr : array[0..15] of cuint64; ++ __wcr : array[0..15] of cuint64; ++ __mdscr_el1: cuint64; ++ end; ++ ++ mcontext_t = record ++ __es : __darwin_arm_exception_state64; ++ __ss : __darwin_arm_thread_state64; ++ __fs : __darwin_arm_neon_state64; ++ end; ++ ++ +Index: fpc/fpcsrc/rtl/darwin/aarch64/sighnd.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/darwin/aarch64/sighnd.inc +@@ -0,0 +1,61 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ (c) 2008 by Jonas Maebe ++ member of the Free Pascal development team. ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ Signalhandler for Darwin/arm ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY;without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++} ++ ++ ++procedure SignalToRunerror(Sig: cint; info : PSigInfo; SigContext:PSigContext); public name '_FPC_DEFAULTSIGHANDLER'; cdecl; ++var ++ res : word; ++begin ++ res:=0; ++ case sig of ++ SIGFPE : ++ begin ++ Case Info^.si_code Of ++ FPE_FLTDIV, ++ FPE_INTDIV : Res:=200; { floating point divide by zero } ++ FPE_FLTOVF : Res:=205; { floating point overflow } ++ FPE_FLTUND : Res:=206; { floating point underflow } ++ FPE_FLTRES, { floating point inexact result } ++ FPE_FLTINV : Res:=207; { invalid floating point operation } ++ Else ++ Res:=207; {coprocessor error} ++ end; ++ { clear "exception happened" flags } ++ SigContext^.uc_mcontext^.__fs.__fpsr:=SigContext^.uc_mcontext^.__fs.__fpsr and not(fpu_exception_mask shr fpu_exception_mask_to_status_mask_shift); ++ end; ++ SIGBUS: ++ res:=214; ++ SIGILL, ++ SIGSEGV : ++ res:=216; ++ SIGINT: ++ res:=217; ++ SIGQUIT: ++ res:=233; ++ end; ++ {$ifdef FPC_USE_SIGPROCMASK} ++ reenable_signal(sig); ++ {$endif } ++ ++ { return to trampoline } ++ if res <> 0 then ++ begin ++ SigContext^.uc_mcontext^.__ss.__r[0] := res; ++ SigContext^.uc_mcontext^.__ss.__r[1] := SigContext^.uc_mcontext^.__ss.__pc; ++ SigContext^.uc_mcontext^.__ss.__r[2] := SigContext^.uc_mcontext^.__ss.__fp; ++ pointer(SigContext^.uc_mcontext^.__ss.__pc) := @HandleErrorAddrFrame; ++ end; ++end; ++ +Index: fpc/fpcsrc/rtl/darwin/extres_multiarch.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/darwin/extres_multiarch.inc ++++ fpc/fpcsrc/rtl/darwin/extres_multiarch.inc +@@ -30,27 +30,21 @@ const + {$ENDIF} + FPCRES_EXT = '.fpcres'; + FPCRES_ARCH = +- {$IFDEF CPUI386} ++ {$if defined(cpui386)} + '.i386'; +- {$ELSE} +- {$IFDEF CPUX86_64} +- '.x86_64'; +- {$ELSE} +- {$IFDEF CPUPOWERPC32} +- '.powerpc'; +- {$ELSE} +- {$IFDEF CPUPOWERPC64} +- '.powerpc64'; +- {$ELSE} +- {$IFDEF CPUARM} +- '.arm'; +- {$ELSE} +- ''; +- {$ENDIF} +- {$ENDIF} +- {$ENDIF} +- {$ENDIF} +- {$ENDIF} ++ {$elseif defined(cpux86_64)} ++ '.x86_64'; ++ {$elseif defined(cpupowerpc32)} ++ '.powerpc'; ++ {$elseif defined(cpupowerpc64)} ++ '.powerpc64'; ++ {$elseif defined(cpuarm)} ++ '.arm'; ++ {$elseif defined(cpuaarch64)} ++ '.aarch64'; ++ {$else} ++ {$error add support for cpu architecture} ++ {$endif} + + type + TExtHeader = packed record +Index: fpc/fpcsrc/rtl/darwin/ptypes.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/darwin/ptypes.inc ++++ fpc/fpcsrc/rtl/darwin/ptypes.inc +@@ -35,7 +35,7 @@ type + pGid = ^gid_t; + TIOCtlRequest = cuLong; + +-{$if not defined(cpuarm) and not defined(iphonesim)} ++{$if not defined(cpuarm) and not defined(aarch64) and not defined(iphonesim)} + ino_t = cuint32; { used for file serial numbers } + {$else} + ino_t = cuint64; +@@ -144,7 +144,7 @@ type + val: array[0..1] of cint32; + end; + +-{$if defined(cpuarm) or defined(iphonesim)} ++{$if defined(cpuarm) or defined(cpuaarch64) or defined(iphonesim)} + { structure used on iPhoneOS and available on Mac OS X 10.6 and later } + tstatfs = record + bsize : cuint32; +Index: fpc/fpcsrc/rtl/darwin/signal.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/darwin/signal.inc ++++ fpc/fpcsrc/rtl/darwin/signal.inc +@@ -193,7 +193,11 @@ + {$ifdef cpuarm} + {$include arm/sig_cpu.inc} + {$else cpuarm} ++{$ifdef cpuaarch64} ++ {$include aarch64/sig_cpu.inc} ++{$else cpuaarch64} + {$error Unsupported cpu type!} ++{$endif cpuaarch64} + {$endif cpuarm} + {$endif cpux86_64} + {$endif cpui386} +Index: fpc/fpcsrc/rtl/inc/ctypes.pp +=================================================================== +--- fpc.orig/fpcsrc/rtl/inc/ctypes.pp ++++ fpc/fpcsrc/rtl/inc/ctypes.pp +@@ -110,6 +110,10 @@ type + {$define longdouble_is_double} + {$ifend} + ++{$if defined(darwin) and defined(cpuaarch64)} ++ {$define longdouble_is_double} ++{$ifend} ++ + {$ifndef FPUNONE} + {$if defined(longdouble_is_double) or not defined(FPC_HAS_CEXTENDED)} + clongdouble=double; +Index: fpc/fpcsrc/rtl/inc/objc.pp +=================================================================== +--- fpc.orig/fpcsrc/rtl/inc/objc.pp ++++ fpc/fpcsrc/rtl/inc/objc.pp +@@ -3,7 +3,7 @@ unit objc; + + {$ifdef darwin} + {$define targethandled} +-{$if defined(iphonesim) or defined(cpuarm) or defined(cpux86_64) or defined(cpupowerpc64)} ++{$if defined(iphonesim) or defined(cpuarm) or defined(cpux86_64) or defined(cpupowerpc64) or defined(cpuaarch64)} + {$i objcnf.inc} + {$endif} + +Index: fpc/fpcsrc/rtl/inc/objcnf.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/inc/objcnf.inc ++++ fpc/fpcsrc/rtl/inc/objcnf.inc +@@ -172,12 +172,16 @@ type + function objc_msgSend(self: id; op: SEL): id; cdecl; varargs; external libname; + function objc_msgSendSuper(const super: pobjc_super; op: SEL): id; cdecl; varargs; external libname; + function objc_msgSendSuper2(const super: pobjc_super; op: SEL): id; cdecl; varargs; weakexternal libname; { Mac OS X 10.6 and later } +- { The following two are declared as procedures with the hidden result pointer +- as their first parameter. This corresponds to the declaration below as far +- as the code generator is concerned (and is easier to handle in the compiler). } ++{ the AArch64 ABI does not require special handling of struct returns, so no ++ special handlers are provided/required } ++{$ifndef cpuaarch64} ++{ The following two are declared as procedures with the hidden result pointer ++ as their first parameter. This corresponds to the declaration below as far ++ as the code generator is concerned (and is easier to handle in the compiler). } + function objc_msgSend_stret(self: id; op: SEL): tdummyrecbyaddrresult; cdecl; varargs; external libname; + function objc_msgSendSuper_stret(const super: pobjc_super; op: SEL): tdummyrecbyaddrresult; cdecl; varargs; external libname; + function objc_msgSendSuper2_stret(const super: pobjc_super; op: SEL): tdummyrecbyaddrresult; cdecl; varargs; weakexternal libname; ++{$endif cpuaarch64} + { This one actually also exists to return extended on x86_64, but + we don't support that yet + } +@@ -230,7 +234,9 @@ type + function class_getInstanceMethod(cls:pobjc_class; name:SEL):Method; cdecl; external libname; + function class_getClassMethod(cls:pobjc_class; name:SEL):Method; cdecl; external libname; + function class_getMethodImplementation(cls:pobjc_class; name:SEL):IMP; cdecl; external libname; ++{$ifndef cpuaarch64} + function class_getMethodImplementation_stret(cls:pobjc_class; name:SEL):IMP; cdecl; external libname; ++{$endif cpuaarch64} + function class_respondsToSelector(cls:pobjc_class; sel:SEL):BOOL; cdecl; external libname; + function class_copyMethodList(cls:pobjc_class; outCount:pdword):PMethod; cdecl; external libname; + +Index: fpc/fpcsrc/rtl/inc/system.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/inc/system.inc ++++ fpc/fpcsrc/rtl/inc/system.inc +@@ -264,6 +264,13 @@ function do_isdevice(handle:thandle):boo + {$endif cpumips} + {$endif not cpumipsel} + ++{$ifdef cpuaarch64} ++ {$ifdef SYSPROCDEFINED} ++ {$Error Can't determine processor type !} ++ {$endif} ++ {$i aarch64.inc} { Case dependent, don't change } ++ {$define SYSPROCDEFINED} ++{$endif cpuaarch64} + + {$ifndef SYSPROCDEFINED} + {$Error Can't determine processor type !} +Index: fpc/fpcsrc/rtl/inc/systemh.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/inc/systemh.inc ++++ fpc/fpcsrc/rtl/inc/systemh.inc +@@ -332,6 +332,22 @@ Type + FarPointer = Pointer; + {$endif CPUAVR} + ++{$ifdef CPUAARCH64} ++ {$define DEFAULT_DOUBLE} ++ ++ {$define SUPPORT_SINGLE} ++ {$define SUPPORT_DOUBLE} ++ ++ ValReal = Double; ++ ++ { map comp to int64, but this doesn't mean we compile the comp support in! } ++ Comp = Int64; ++ PComp = ^Comp; ++ ++ FarPointer = Pointer; ++{$endif CPUAARCH64} ++ ++ + {$ifdef CPU64} + SizeInt = Int64; + SizeUInt = QWord; +@@ -861,13 +877,13 @@ function NtoLE(const AValue: QWord): QWo + {$define FPC_HAS_INTERNAL_ROX_WORD} + {$endif defined(cpux86_64) or defined(cpui386)} + +-{$if defined(cpux86_64) or defined(cpui386) or defined(arm) or defined(powerpc) or defined(powerpc64)} ++{$if defined(cpux86_64) or defined(cpui386) or defined(arm) or defined(powerpc) or defined(powerpc64) or defined(cpuaarch64)} + {$define FPC_HAS_INTERNAL_ROX_DWORD} +-{$endif defined(cpux86_64) or defined(cpui386) or defined(arm) or defined(powerpc) or defined(powerpc64)} ++{$endif defined(cpux86_64) or defined(cpui386) or defined(arm) or defined(powerpc) or defined(powerpc64) or defined(cpuaarch64)} + +-{$if defined(cpux86_64) or defined(powerpc64)} ++{$if defined(cpux86_64) or defined(powerpc64) or defined(cpuaarch64)} + {$define FPC_HAS_INTERNAL_ROX_QWORD} +-{$endif defined(cpux86_64) or defined(powerpc64)} ++{$endif defined(cpux86_64) or defined(powerpc64) or defined(cpuaarch64)} + + {$endif FPC_HAS_INTERNAL_ROX} + +@@ -942,9 +958,9 @@ function RolQWord(Const AValue : QWord;c + {$define FPC_HAS_INTERNAL_SAR_DWORD} + { $endif defined(cpux86_64) or defined(cpui386) or defined(arm) or defined(powerpc) or defined(powerpc64) or defined(mips) or defined(mipsel)} + +-{$if defined(cpux86_64) or defined(powerpc64)} ++{$if defined(cpux86_64) or defined(powerpc64) or defined(cpuaarch64)} + {$define FPC_HAS_INTERNAL_SAR_QWORD} +-{$endif defined(cpux86_64) or defined(powerpc64)} ++{$endif defined(cpux86_64) or defined(powerpc64) or defined(cpuaarch64)} + + {$endif FPC_HAS_INTERNAL_SAR} + +@@ -976,23 +992,23 @@ function fpc_SarInt64(Const AValue : Int + {$endif FPC_HAS_INTERNAL_SAR_QWORD} + + {$ifdef FPC_HAS_INTERNAL_BSF} +-{$if defined(cpui386) or defined(cpux86_64) or defined(cpuarm)} ++{$if defined(cpui386) or defined(cpux86_64) or defined(cpuarm) or defined(cpuaarch64)} + {$define FPC_HAS_INTERNAL_BSF_BYTE} + {$define FPC_HAS_INTERNAL_BSF_WORD} + {$define FPC_HAS_INTERNAL_BSF_DWORD} + {$endif} +-{$if defined(cpux86_64)} ++{$if defined(cpux86_64) or defined(cpuaarch64)} + {$define FPC_HAS_INTERNAL_BSF_QWORD} + {$endif} + {$endif} + + {$ifdef FPC_HAS_INTERNAL_BSR} +-{$if defined(cpui386) or defined(cpux86_64) or defined(cpuarm)} ++{$if defined(cpui386) or defined(cpux86_64) or defined(cpuarm) or defined(cpuaarch64)} + {$define FPC_HAS_INTERNAL_BSR_BYTE} + {$define FPC_HAS_INTERNAL_BSR_WORD} + {$define FPC_HAS_INTERNAL_BSR_DWORD} + {$endif} +-{$if defined(cpux86_64)} ++{$if defined(cpux86_64) or defined(cpuaarch64)} + {$define FPC_HAS_INTERNAL_BSR_QWORD} + {$endif} + {$endif} +Index: fpc/fpcsrc/rtl/linux/aarch64/bsyscall.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/aarch64/bsyscall.inc +@@ -0,0 +1 @@ ++{ nothing } +Index: fpc/fpcsrc/rtl/linux/aarch64/cprt0.as +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/aarch64/cprt0.as +@@ -0,0 +1,81 @@ ++/* ++ Start-up code for Free Pascal Compiler when linking with C library. ++ ++ Written by Edmund Grimley Evans in 2015 and released into the public domain. ++*/ ++ ++ .text ++ .align 2 ++ ++ .globl _start ++ .type _start,#function ++_start: ++ /* Initialise FP to zero */ ++ mov x29,#0 ++ ++ /* This is rtld_fini */ ++ mov x5,x0 ++ ++ /* Get argc, argv, envp */ ++ ldr x1,[sp] ++ add x2,sp,#8 ++ add x11,x1,#1 ++ add x11,x2,x11,lsl #3 ++ ++ /* Save argc, argv, envp, and initial stack pointer */ ++ adrp x10,:got:operatingsystem_parameter_argc ++ ldr x10,[x10,#:got_lo12:operatingsystem_parameter_argc] ++ str x1,[x10] ++ adrp x10,:got:operatingsystem_parameter_argv ++ ldr x10,[x10,#:got_lo12:operatingsystem_parameter_argv] ++ str x2,[x10] ++ adrp x10,:got:operatingsystem_parameter_envp ++ ldr x10,[x10,#:got_lo12:operatingsystem_parameter_envp] ++ str x11,[x10] ++ adrp x10,:got:__stkptr ++ ldr x10,[x10,#:got_lo12:__stkptr] ++ mov x6,sp ++ str x6,[x10] ++ ++ /* __libc_start_main(main, argc, argv, ++ init, fini, rtld_fini, stack_end) */ ++ adrp x0,:got:PASCALMAIN ++ ldr x0,[x0,#:got_lo12:PASCALMAIN] ++ adrp x3,:got:__libc_csu_init ++ ldr x3,[x3,#:got_lo12:__libc_csu_init] ++ adrp x4,:got:__libc_csu_fini ++ ldr x4,[x4,#:got_lo12:__libc_csu_fini] ++ bl __libc_start_main ++ ++ /* This should never happen */ ++ b abort ++ ++ .globl _haltproc ++ .type _haltproc,#function ++_haltproc: ++ adrp x0,:got:operatingsystem_result ++ ldr x0,[x0,#:got_lo12:operatingsystem_result] ++ ldr w0,[x0] ++ mov w8,#94 // syscall_nr_exit_group ++ svc #0 ++ b _haltproc ++ ++ /* Define a symbol for the first piece of initialized data. */ ++ .data ++ .align 3 ++ .globl __data_start ++__data_start: ++ .long 0 ++ .weak data_start ++ data_start = __data_start ++ ++ .bss ++ .align 3 ++ ++ .comm __stkptr,8 ++ ++ .comm operatingsystem_parameter_envp,8 ++ .comm operatingsystem_parameter_argc,8 ++ .comm operatingsystem_parameter_argv,8 ++ ++ .section .note.GNU-stack,"",%progbits +Index: fpc/fpcsrc/rtl/linux/aarch64/dllprt0.as +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/aarch64/dllprt0.as +@@ -0,0 +1,72 @@ ++/* ++ Start-up code for Free Pascal Compiler in a shared library, ++ not linking with C library. ++ ++ Written by Edmund Grimley Evans in 2015 and released into the public domain. ++*/ ++ ++ .text ++ .align 2 ++ ++ .globl _startlib ++ .type _startlib,#function ++_startlib: ++ .globl FPC_SHARED_LIB_START ++ .type FPC_SHARED_LIB_START,#function ++FPC_SHARED_LIB_START: ++ stp x29,x30,[sp,#-16]! ++ ++ /* Save argc, argv and envp */ ++ adrp x9,:got:operatingsystem_parameter_argc ++ ldr x9,[x9,#:got_lo12:operatingsystem_parameter_argc] ++ str x0,[x9] ++ adrp x9,:got:operatingsystem_parameter_argv ++ ldr x9,[x9,#:got_lo12:operatingsystem_parameter_argv] ++ str x1,[x9] ++ adrp x9,:got:operatingsystem_parameter_envp ++ ldr x9,[x9,#:got_lo12:operatingsystem_parameter_envp] ++ str x2,[x9] ++ ++ /* Save initial stackpointer */ ++ adrp x9,:got:__stkptr ++ ldr x9,[x9,#:got_lo12:__stkptr] ++ mov x10,sp ++ str x10,[x9] ++ ++ /* Call main */ ++ bl PASCALMAIN ++ ++ /* Return */ ++ ldp x29,x30,[sp],#16 ++ ret ++ ++ .globl _haltproc ++ .type _haltproc,#function ++_haltproc: ++ adrp x0,:got:operatingsystem_result ++ ldr x0,[x0,#:got_lo12:operatingsystem_result] ++ ldr w0,[x0] ++ mov w8,#94 // syscall_nr_exit_group ++ svc #0 ++ b _haltproc ++ ++ /* Define a symbol for the first piece of initialized data. */ ++ .data ++ .align 3 ++ .globl __data_start ++__data_start: ++ .long 0 ++ .weak data_start ++ data_start = __data_start ++ ++ .bss ++ .align 3 ++ ++ .comm __dl_fini,8 ++ .comm __stkptr,8 ++ ++ .comm operatingsystem_parameter_envp,8 ++ .comm operatingsystem_parameter_argc,8 ++ .comm operatingsystem_parameter_argv,8 ++ ++ .section .note.GNU-stack,"",%progbits +Index: fpc/fpcsrc/rtl/linux/aarch64/gprt0.as +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/aarch64/gprt0.as +@@ -0,0 +1,10 @@ ++/* ++ Start-up code for Free Pascal Compiler when linking with C library ++ with profiling support. ++ ++ Written by Edmund Grimley Evans in 2015 and released into the public domain. ++*/ ++ ++ .text ++ .align 2 ++ b xx_aarch64_gprt0_unimplemented +Index: fpc/fpcsrc/rtl/linux/aarch64/prt0.as +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/aarch64/prt0.as +@@ -0,0 +1,77 @@ ++/* ++ Start-up code for Free Pascal Compiler, not in a shared library, ++ not linking with C library. ++ ++ Written by Edmund Grimley Evans in 2015 and released into the public domain. ++*/ ++ ++ .text ++ .align 2 ++ ++ .globl _dynamic_start ++ .type _dynamic_start,#function ++_dynamic_start: ++ ldr x10,=__dl_fini ++ str x0,[x10] ++ b _start ++ ++ .globl _start ++ .type _start,#function ++_start: ++ /* Initialise FP to zero */ ++ mov x29,#0 ++ ++ /* Get argc, argv, envp */ ++ ldr x1,[sp] ++ add x2,sp,#8 ++ add x11,x1,#1 ++ add x11,x2,x11,lsl #3 ++ ++ /* Save argc, argv, envp, and initial stack pointer */ ++ ldr x10,=operatingsystem_parameter_argc ++ str x1,[x10] ++ ldr x10,=operatingsystem_parameter_argv ++ str x2,[x10] ++ ldr x10,=operatingsystem_parameter_envp ++ str x11,[x10] ++ ldr x10,=__stkptr ++ mov x6,sp ++ str x6,[x10] ++ ++ /* Call main */ ++ bl PASCALMAIN ++ ++ .globl _haltproc ++ .type _haltproc,#function ++_haltproc: ++ ldr x10,=__dl_fini ++ ldr x0,[x10] ++ cbz x0,.Lexit ++ blr x0 ++.Lexit: ++ ldr x10,=operatingsystem_result ++ ldr w0,[x10] ++ mov w8,#94 // syscall_nr_exit_group ++ svc #0 ++ b _haltproc ++ ++ /* Define a symbol for the first piece of initialized data. */ ++ .data ++ .align 3 ++ .globl __data_start ++__data_start: ++ .long 0 ++ .weak data_start ++ data_start = __data_start ++ ++ .bss ++ .align 3 ++ ++ .comm __dl_fini,8 ++ .comm __stkptr,8 ++ ++ .comm operatingsystem_parameter_envp,8 ++ .comm operatingsystem_parameter_argc,8 ++ .comm operatingsystem_parameter_argv,8 ++ ++ .section .note.GNU-stack,"",%progbits +Index: fpc/fpcsrc/rtl/linux/aarch64/sighnd.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/aarch64/sighnd.inc +@@ -0,0 +1,44 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 1999-2000 by Michael Van Canneyt, ++ member of the Free Pascal development team. ++ ++ Signal handler is arch dependant due to processor to language ++ exception conversion. ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ ++procedure SignalToRunerror(Sig: longint; SigInfo: PSigInfo; UContext: PUContext); public name '_FPC_DEFAULTSIGHANDLER'; cdecl; ++ ++var ++ res : word; ++begin ++ res:=0; ++ case sig of ++ SIGFPE: ++ res:=207; ++ SIGILL: ++ res:=216; ++ SIGSEGV : ++ res:=216; ++ SIGBUS: ++ res:=214; ++ SIGINT: ++ res:=217; ++ SIGQUIT: ++ res:=233; ++ end; ++ reenable_signal(sig); ++ { give runtime error at the position where the signal was raised } ++ if res<>0 then ++ HandleErrorAddrFrame(res, ++ pointer(uContext^.uc_mcontext.pc), ++ pointer(uContext^.uc_mcontext.regs[29])); ++end; +Index: fpc/fpcsrc/rtl/linux/aarch64/sighndh.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/aarch64/sighndh.inc +@@ -0,0 +1,47 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 1999-2000 by Jonas Maebe, ++ member of the Free Pascal development team. ++ ++ TSigContext and associated structures. ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ ++{$packrecords C} ++ ++type ++ PSigContext = ^TSigContext; ++ TSigContext = record ++ fault_address : cULong; ++ regs : array[0..30] of cULong; ++ sp : cULong; ++ pc : cULong; ++ pstate : cULong; ++ __pad : cULong; ++ { The following field should be 16-byte-aligned. Currently the ++ directive for specifying alignment is buggy, so the preceding ++ field was added so that the record has the right size. } ++ __reserved : array[0..4095] of cUChar; ++ end; ++ ++ stack_t = record ++ ss_sp : pointer; ++ ss_flags : cInt; ++ ss_size : size_t; ++ end; ++ ++ PUContext = ^TUContext; ++ TUContext = record ++ uc_flags : cULong; ++ uc_link : PUContext; ++ uc_stack : stack_t; ++ uc_mcontext : TSigContext; ++ uc_sigmask : sigset_t; ++ end; +Index: fpc/fpcsrc/rtl/linux/aarch64/stat.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/aarch64/stat.inc +@@ -0,0 +1,72 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 1999-2000 by Jonas Maebe, (c) 2005 Thomas Schatzl, ++ members of the Free Pascal development team. ++ ++ Contains the definition of the stat type for the PowerPC64 platform. ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ ++{ This structure was adapted from ++ ++ include/uapi/asm-generic/stat.h ++ ++ in Linux 4.0. Note that the stat record is the same for direct ++ syscalls as for when linking to libc. ++} ++ ++{$PACKRECORDS C} ++ stat = record ++ case integer of ++ 0 : ( ++ st_dev : cULong; ++ st_ino : cULong; ++ st_mode : cUInt; ++ st_nlink : cUInt; ++ st_uid : cUInt; ++ st_gid : cUInt; ++ st_rdev : cULong; ++ __pad1a : cULong; ++ st_size : cLong; ++ st_blksize : cInt; ++ __pad2a : cInt; ++ st_blocks : cLong; ++ st_atime : cLong; ++ st_atime_nsec : cULong; ++ st_mtime : cLong; ++ st_mtime_nsec : cULong; ++ st_ctime : cLong; ++ st_ctime_nsec : cULong; ++ __unused4a : cUInt; ++ __unused5a : cUInt; ++ ); ++ 1 : ( ++ dev : cULong deprecated; ++ ino : cULong deprecated; ++ mode : cUInt deprecated; ++ nlink : cUInt deprecated; ++ uid : cUInt deprecated; ++ gid : cUInt deprecated; ++ rdev : cULong deprecated; ++ __pad1b : cULong deprecated; ++ size : cLong deprecated; ++ blksize : cInt deprecated; ++ __pad2b : cInt deprecated; ++ blocks : cLong deprecated; ++ atime : cLong deprecated; ++ atime_nsec : cULong deprecated; ++ mtime : cLong deprecated; ++ mtime_nsec : cULong deprecated; ++ ctime : cLong deprecated; ++ ctime_nsec : cULong deprecated; ++ __unused4b : cUInt deprecated; ++ __unused5b : cUInt deprecated; ++ ); ++ end; +Index: fpc/fpcsrc/rtl/linux/aarch64/syscall.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/aarch64/syscall.inc +@@ -0,0 +1,127 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ ++ Perform syscall with 0..6 arguments. ++ If syscall return value is negative, negate it, set errno, and return -1. ++ ++ Written by Edmund Grimley Evans in 2015 and released into the public domain. ++} ++ ++function FpSysCall(sysnr:TSysParam):TSysResult; ++assembler; nostackframe; [public,alias:'FPC_SYSCALL0']; ++asm ++ mov w8,w0 ++ svc #0 ++ tbz x0,#63,.Ldone ++ str x30,[sp,#-16]! ++ neg x0,x0 ++ bl seterrno ++ ldr x30,[sp],#16 ++ mov x0,#-1 ++.Ldone: ++end; ++ ++function FpSysCall(sysnr,param1:TSysParam):TSysResult; ++assembler; nostackframe; [public,alias:'FPC_SYSCALL1']; ++asm ++ mov w8,w0 ++ mov x0,x1 ++ svc #0 ++ tbz x0,#63,.Ldone ++ str x30,[sp,#-16]! ++ neg x0,x0 ++ bl seterrno ++ ldr x30,[sp],#16 ++ mov x0,#-1 ++.Ldone: ++end; ++ ++function FpSysCall(sysnr,param1,param2:TSysParam):TSysResult; ++assembler; nostackframe; [public,alias:'FPC_SYSCALL2']; ++asm ++ mov w8,w0 ++ mov x0,x1 ++ mov x1,x2 ++ svc #0 ++ tbz x0,#63,.Ldone ++ str x30,[sp,#-16]! ++ neg x0,x0 ++ bl seterrno ++ ldr x30,[sp],#16 ++ mov x0,#-1 ++.Ldone: ++end; ++ ++function FpSysCall(sysnr,param1,param2,param3:TSysParam):TSysResult; ++assembler; nostackframe; [public,alias:'FPC_SYSCALL3']; ++asm ++ mov w8,w0 ++ mov x0,x1 ++ mov x1,x2 ++ mov x2,x3 ++ svc #0 ++ tbz x0,#63,.Ldone ++ str x30,[sp,#-16]! ++ neg x0,x0 ++ bl seterrno ++ ldr x30,[sp],#16 ++ mov x0,#-1 ++.Ldone: ++end; ++ ++function FpSysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult; ++assembler; nostackframe; [public,alias:'FPC_SYSCALL4']; ++asm ++ mov w8,w0 ++ mov x0,x1 ++ mov x1,x2 ++ mov x2,x3 ++ mov x3,x4 ++ svc #0 ++ tbz x0,#63,.Ldone ++ str x30,[sp,#-16]! ++ neg x0,x0 ++ bl seterrno ++ ldr x30,[sp],#16 ++ mov x0,#-1 ++.Ldone: ++end; ++ ++function FpSysCall(sysnr,param1,param2,param3,param4,param5:TSysParam):TSysResult; ++assembler; nostackframe; [public,alias:'FPC_SYSCALL5']; ++asm ++ mov w8,w0 ++ mov x0,x1 ++ mov x1,x2 ++ mov x2,x3 ++ mov x3,x4 ++ mov x4,x5 ++ svc #0 ++ tbz x0,#63,.Ldone ++ str x30,[sp,#-16]! ++ neg x0,x0 ++ bl seterrno ++ ldr x30,[sp],#16 ++ mov x0,#-1 ++.Ldone: ++end; ++ ++function FpSysCall(sysnr,param1,param2,param3,param4,param5,param6:TSysParam):TSysResult; ++assembler; nostackframe; [public,alias:'FPC_SYSCALL6']; ++asm ++ mov w8,w0 ++ mov x0,x1 ++ mov x1,x2 ++ mov x2,x3 ++ mov x3,x4 ++ mov x4,x5 ++ mov x5,x6 ++ svc #0 ++ tbz x0,#63,.Ldone ++ str x30,[sp,#-16]! ++ neg x0,x0 ++ bl seterrno ++ ldr x30,[sp],#16 ++ mov x0,#-1 ++.Ldone: ++end; +Index: fpc/fpcsrc/rtl/linux/aarch64/syscallh.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/aarch64/syscallh.inc +@@ -0,0 +1,35 @@ ++{ ++ Copyright (c) 2002 by Marco van de Voort ++ ++ Header for syscalls in system unit. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, ++ MA 02110-1301, USA. ++ ++ **************************************************************************** ++ ++} ++ ++Type ++ TSysResult = Int64; ++ TSysParam = Int64; ++ ++function Do_SysCall(sysnr:TSysParam):TSysResult; external name 'FPC_SYSCALL0'; ++function Do_SysCall(sysnr,param1:TSysParam):TSysResult; external name 'FPC_SYSCALL1'; ++function Do_SysCall(sysnr,param1,param2:TSysParam):TSysResult; external name 'FPC_SYSCALL2'; ++function Do_SysCall(sysnr,param1,param2,param3:TSysParam):TSysResult; external name 'FPC_SYSCALL3'; ++function Do_SysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult; external name 'FPC_SYSCALL4'; ++function Do_SysCall(sysnr,param1,param2,param3,param4,param5:TSysParam):TSysResult; external name 'FPC_SYSCALL5'; ++function Do_SysCall(sysnr,param1,param2,param3,param4,param5,param6:TSysParam):TSysResult; external name 'FPC_SYSCALL6'; +Index: fpc/fpcsrc/rtl/linux/aarch64/sysnr.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/aarch64/sysnr.inc +@@ -0,0 +1 @@ ++{$i ../sysnr-gen.inc} +Index: fpc/fpcsrc/rtl/linux/bunxsysc.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/linux/bunxsysc.inc ++++ fpc/fpcsrc/rtl/linux/bunxsysc.inc +@@ -297,7 +297,11 @@ end; + function fpgetpgrp : pid_t; + + begin ++{$if defined(generic_linux_syscalls)} ++ fpgetpgrp:=do_syscall(syscall_nr_getpgid,0); ++{$else} + fpgetpgrp:=do_syscall(syscall_nr_getpgrp); ++{$endif} + end; + + function fpsetsid : pid_t; +@@ -327,29 +331,59 @@ Function fplink(existing:pchar;newone:pc + In effect, new will be the same file as old. + } + begin ++{$if defined(generic_linux_syscalls)} ++ fpLink:=Do_Syscall(syscall_nr_linkat,AT_FDCWD,TSysParam(existing),AT_FDCWD,TSysParam(newone),0); ++{$else} + fpLink:=Do_Syscall(syscall_nr_link,TSysParam(existing),TSysParam(newone)); ++{$endif} + end; + + Function fpmkfifo(path:pchar;mode:mode_t):cint; + + begin + ++{$if defined(generic_linux_syscalls)} ++fpmkfifo:=do_syscall(syscall_nr_mknodat,AT_FDCWD,TSysParam(path),TSysParam(mode or S_IFIFO),TSysParam(0)); ++{$else} + fpmkfifo:=do_syscall(syscall_nr_mknod,TSysParam(path),TSysParam(mode or S_IFIFO),TSysParam(0)); ++{$endif} + end; + + Function fpchmod(path:pchar;mode:mode_t):cint; + + begin ++{$if defined(generic_linux_syscalls)} ++ fpchmod:=do_syscall(syscall_nr_fchmodat,AT_FDCWD,TSysParam(path),TSysParam(mode),0); ++{$else} + fpchmod:=do_syscall(syscall_nr_chmod,TSysParam(path),TSysParam(mode)); ++{$endif} + end; + + Function fpchown(path:pchar;owner:uid_t;group:gid_t):cint; + + begin ++{$if defined(generic_linux_syscalls)} ++ fpChOwn:=do_syscall(syscall_nr_fchownat,AT_FDCWD,TSysParam(path),TSysParam(owner),TSysParam(group),0); ++{$else} + fpChOwn:=do_syscall(syscall_nr_chown,TSysParam(path),TSysParam(owner),TSysParam(group)); ++{$endif} + end; + +-{$ifndef NO_SYSCALL_UTIME} ++{$if defined(generic_linux_syscalls)} ++ ++Function fpUtime(path:pchar;times:putimbuf):cint; ++var ++ tsa: Array[0..1] of timespec; ++begin ++ tsa[0].tv_sec := times^.actime; ++ tsa[0].tv_nsec := 0; ++ tsa[1].tv_sec := times^.modtime; ++ tsa[1].tv_nsec := 0; ++ fputime:=do_syscall(syscall_nr_utimensat,AT_FDCWD,TSysParam(path), ++ TSysParam(@tsa),0); ++end; ++ ++{$elseif not defined(NO_SYSCALL_UTIME)} + + Function fpUtime(path:pchar;times:putimbuf):cint; + +@@ -377,7 +411,11 @@ end; + Function fppipe(var fildes : tfildes):cint; + + begin ++{$if defined(generic_linux_syscalls)} ++ fppipe:=do_syscall(syscall_nr_pipe2,TSysParam(@fildes),0); ++{$else} + fppipe:=do_syscall(syscall_nr_pipe,TSysParam(@fildes)); ++{$endif} + end; + {$endif FPC_BASEUNIX_HAS_FPPIPE} + +@@ -422,6 +460,18 @@ Function fpSelect(N:cint;readfds,writefd + Select checks whether the file descriptor sets in readfs/writefs/exceptfs + have changed. + } ++{$if defined(generic_linux_syscalls)} ++ ++var ts : timespec; ++begin ++ ts.tv_sec := timeout^.tv_sec; ++ ts.tv_nsec := timeout^.tv_usec * 1000; ++ fpSelect:=do_syscall(syscall_nr_pselect6,n, ++ tsysparam(readfds),tsysparam(writefds), ++ tsysparam(exceptfds),tsysparam(@ts),0); ++end; ++ ++{$else} + + begin + {$ifdef cpux86_64} +@@ -436,10 +486,27 @@ begin + {$endif bunxfunc_fpselect_implemented} + end; + ++{$endif} ++ + function fpPoll(fds: ppollfd; nfds: cuint; timeout: clong): cint; ++{$if defined(generic_linux_syscalls)} ++var ts : timespec; ++begin ++ if timeout<0 then ++ fpPoll:=do_syscall(syscall_nr_ppoll,tsysparam(fds),tsysparam(nfds),0,0) ++ else ++ begin ++ ts.tv_sec := timeout div 1000; ++ ts.tv_nsec := (timeout mod 1000) * 1000000; ++ fpPoll:=do_syscall(syscall_nr_ppoll,tsysparam(fds),tsysparam(nfds), ++ tsysparam(@ts),0); ++ end ++end; ++{$else} + begin + fpPoll:=do_syscall(syscall_nr_poll,tsysparam(fds),tsysparam(nfds),tsysparam(timeout)); + end; ++{$endif} + + Function fpLstat(path:pchar;Info:pstat):cint; + { +@@ -447,6 +514,9 @@ Function fpLstat(path:pchar;Info:pstat): + } + + begin ++{$if defined(generic_linux_syscalls)} ++ fpLStat:=do_syscall(syscall_nr_fstatat,AT_FDCWD,TSysParam(path),TSysParam(info),0) ++{$else} + fpLStat:=do_syscall( + {$ifdef cpu64} + syscall_nr_lstat, +@@ -454,6 +524,7 @@ begin + syscall_nr_lstat64, + {$endif} + TSysParam(path),TSysParam(info)); ++{$endif} + end; + + +@@ -465,12 +536,12 @@ function fpNice(N:cint):cint; + Doesn't exist in BSD. Linux emu uses setpriority in a construct as below: + } + +-{$ifdef cpux86_64} ++{$if defined(generic_linux_syscalls) or defined(cpux86_64)} + var + oldprio : cint; + {$endif} + begin +-{$ifdef cpux86_64} ++{$if defined(generic_linux_syscalls) or defined(cpux86_64)} + oldprio:=fpGetPriority(Prio_Process,0); + fpNice:=fpSetPriority(Prio_Process,0,oldprio+N); + if fpNice=0 then +@@ -536,7 +607,11 @@ Function fpSymlink(oldname,newname:pchar + } + + begin ++{$if defined(generic_linux_syscalls)} ++ fpsymlink:=do_syscall(syscall_nr_symlinkat,TSysParam(oldname),AT_FDCWD,TSysParam(newname)); ++{$else} + fpsymlink:=do_syscall(syscall_nr_symlink,TSysParam(oldname),TSysParam(newname)); ++{$endif} + end; + + function Fppread(fd: cint; buf: pchar; nbytes : size_t; offset:Toff): ssize_t; [public, alias : 'FPC_SYSC_PREAD']; +Index: fpc/fpcsrc/rtl/linux/linux.pp +=================================================================== +--- fpc.orig/fpcsrc/rtl/linux/linux.pp ++++ fpc/fpcsrc/rtl/linux/linux.pp +@@ -17,6 +17,8 @@ + **********************************************************************} + unit Linux; + ++{$i osdefs.inc} ++ + {$packrecords c} + {$ifdef FPC_USE_LIBC} + {$linklib rt} // for clock* functions +@@ -527,7 +529,11 @@ end; + + function epoll_create(size: cint): cint; + begin ++{$if defined(generic_linux_syscalls)} ++ epoll_create := do_syscall(syscall_nr_epoll_create1,0) ++{$else} + epoll_create := do_syscall(syscall_nr_epoll_create,tsysparam(size)); ++{$endif} + end; + + function epoll_ctl(epfd, op, fd: cint; event: pepoll_event): cint; +@@ -538,8 +544,13 @@ end; + + function epoll_wait(epfd: cint; events: pepoll_event; maxevents, timeout: cint): cint; + begin ++{$if defined(generic_linux_syscalls)} ++ epoll_wait := do_syscall(syscall_nr_epoll_pwait, tsysparam(epfd), ++ tsysparam(events), tsysparam(maxevents), tsysparam(timeout),0); ++{$else} + epoll_wait := do_syscall(syscall_nr_epoll_wait, tsysparam(epfd), + tsysparam(events), tsysparam(maxevents), tsysparam(timeout)); ++{$endif} + end; + + function capget(header:Puser_cap_header;data:Puser_cap_data):cint; +@@ -695,7 +706,11 @@ end; + function inotify_init1(flags:cint):cint; + + begin ++{$if defined(generic_linux_syscalls)} ++ inotify_init1:=do_SysCall(syscall_nr_inotify_init1,tsysparam(flags)); ++{$else} + inotify_init1:=do_SysCall(syscall_nr_inotify_init,tsysparam(flags)); ++{$endif} + end; + + function inotify_add_watch(fd:cint; name:Pchar; mask:cuint32):cint; +Index: fpc/fpcsrc/rtl/linux/oldlinux.pp +=================================================================== +--- fpc.orig/fpcsrc/rtl/linux/oldlinux.pp ++++ fpc/fpcsrc/rtl/linux/oldlinux.pp +@@ -1924,9 +1924,16 @@ Function Sys_Mkdir(Filename:pchar;mode:l + var + regs : SysCallregs; + begin ++{$if defined(generic_linux_syscalls)} ++ regs.reg2:=AT_FDCWD; ++ regs.reg3:=longint(filename); ++ regs.reg4:=mode; ++ Sys_MkDir:=SysCall(SysCall_nr_mkdirat,regs); ++{$else} + regs.reg2:=longint(filename); + regs.reg3:=mode; + Sys_MkDir:=SysCall(SysCall_nr_mkdir,regs); ++{$endif} + end; + + +@@ -1935,8 +1942,15 @@ Function Sys_Rmdir(Filename:pchar):longi + var + regs : SysCallregs; + begin ++{$if defined(generic_linux_syscalls)} ++ regs.reg2:=AT_FDCWD; ++ regs.reg3:=longint(filename); ++ regs.reg4:=AT_REMOVEDIR; ++ Sys_Rmdir:=SysCall(SysCall_nr_unlinkat,regs); ++{$else} + regs.reg2:=longint(filename); + Sys_Rmdir:=SysCall(SysCall_nr_rmdir,regs); ++{$endif} + end; + + +@@ -2744,7 +2758,18 @@ var + begin + sr.reg2:=oldfile; + sr.reg3:=newfile; ++{$if defined(generic_linux_syscalls)} ++ sr.reg4:=0; ++ if oldfile<>newfile then ++ SysCall(Syscall_nr_dup3,sr) ++ else ++ begin ++ sr.reg3:=F_GetFd; ++ SysCall(Syscall_nr_fcntl,sr); ++ end; ++{$else} + SysCall(Syscall_nr_dup2,sr); ++{$endif} + linuxerror:=errno; + Dup2:=(LinuxError=0); + end; +@@ -2782,7 +2807,12 @@ var + regs : SysCallregs; + begin + regs.reg2:=longint(@pip); ++{$if defined(generic_linux_syscalls)} ++ regs.reg3:=0; ++ SysCall(SysCall_nr_pipe2,regs); ++{$else} + SysCall(SysCall_nr_pipe,regs); ++{$endif} + pipe_in:=pip[1]; + pipe_out:=pip[2]; + linuxerror:=errno; +Index: fpc/fpcsrc/rtl/linux/osdefs.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/linux/osdefs.inc ++++ fpc/fpcsrc/rtl/linux/osdefs.inc +@@ -85,3 +85,7 @@ + {$endif FPC_ABI_EABI} + {$endif cpuarm} + ++{$ifdef cpuaarch64} ++ {$define generic_linux_syscalls} ++ {$undef usestime} ++{$endif cpuaarch64} +Index: fpc/fpcsrc/rtl/linux/ossysc.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/linux/ossysc.inc ++++ fpc/fpcsrc/rtl/linux/ossysc.inc +@@ -20,7 +20,7 @@ + *****************************************************************************} + + function Fptime(tloc:pTime_t): Time_t; [public, alias : 'FPC_SYSC_TIME']; +-{$ifdef FPC_USEGETTIMEOFDAY} ++{$if defined(generic_linux_syscalls) or defined(FPC_USEGETTIMEOFDAY)} + VAR tv : timeval; + tz : timezone; + retval : longint; +@@ -49,7 +49,11 @@ end; + function Fpopen(path: pchar; flags : cint; mode: mode_t):cint; [public, alias : 'FPC_SYSC_OPEN']; + + Begin ++{$if defined(generic_linux_syscalls)} ++ Fpopen:=do_syscall(syscall_nr_openat,AT_FDCWD,TSysParam(path),TSysParam(flags or O_LARGEFILE),TSysParam(mode)); ++{$else} + Fpopen:=do_syscall(syscall_nr_open,TSysParam(path),TSysParam(flags or O_LARGEFILE),TSysParam(mode)); ++{$endif} + End; + + function Fpclose(fd : cint): cint; [public, alias : 'FPC_SYSC_CLOSE']; +@@ -98,20 +102,32 @@ end; + function Fpunlink(path: pchar): cint; [public, alias : 'FPC_SYSC_UNLINK']; + + begin ++{$if defined(generic_linux_syscalls)} ++ Fpunlink:=do_syscall(syscall_nr_unlinkat,AT_FDCWD,TSysParam(path),0); ++{$else} + Fpunlink:=do_syscall(syscall_nr_unlink,TSysParam(path)); ++{$endif} + end; + + function Fprename(old : pchar; newpath: pchar): cint; [public, alias : 'FPC_SYSC_RENAME']; + + begin ++{$if defined(generic_linux_syscalls)} ++ Fprename:=do_syscall(syscall_nr_renameat,AT_FDCWD,TSysParam(old),AT_FDCWD,TSysParam(newpath)); ++{$else} + Fprename:=do_syscall(syscall_nr_rename,TSysParam(old),TSysParam(newpath)); ++{$endif} + end; + + function Fpstat(path: pchar; var buf: stat):cint; [public, alias : 'FPC_SYSC_STAT']; + + begin + {$if defined(cpu64)} +- Fpstat:=do_syscall(syscall_nr_stat,TSysParam(path),TSysParam(@buf)); ++ {$if defined(generic_linux_syscalls)} ++ Fpstat:=do_syscall(syscall_nr_fstatat,AT_FDCWD,TSysParam(path),TSysParam(@buf),0); ++ {$else} ++ Fpstat:=do_syscall(syscall_nr_stat,TSysParam(path),TSysParam(@buf)); ++ {$endif} + {$else} + Fpstat:=do_syscall(syscall_nr_stat64,TSysParam(path),TSysParam(@buf)); + {$endif} +@@ -130,13 +146,21 @@ end; + function Fpmkdir(path : pchar; mode: mode_t):cint; [public, alias : 'FPC_SYSC_MKDIR']; + + begin ++{$if defined(generic_linux_syscalls)} ++ Fpmkdir:=do_syscall(syscall_nr_mkdirat,AT_FDCWD,TSysParam(path),TSysParam(mode)); ++{$else} + Fpmkdir:=do_syscall(syscall_nr_mkdir,TSysParam(path),TSysParam(mode)); ++{$endif} + end; + + function Fprmdir(path : pchar): cint; [public, alias : 'FPC_SYSC_RMDIR']; + + begin ++{$if defined(generic_linux_syscalls)} ++ Fprmdir:=do_syscall(syscall_nr_unlinkat,AT_FDCWD,TSysParam(path),AT_REMOVEDIR); ++{$else} + Fprmdir:=do_syscall(syscall_nr_rmdir,TSysParam(path)); ++{$endif} + end; + + function Fpopendir(dirname : pchar): pdir; [public, alias : 'FPC_SYSC_OPENDIR']; +@@ -363,7 +387,11 @@ function Fpfstat(fd : cint; var sb : sta + + begin + {$if defined(cpu64)} +- FpFStat:=do_SysCall(syscall_nr_fstat,TSysParam(fd),TSysParam(@sb)); ++ {$if defined(generic_linux_syscalls)} ++ FpFStat:=do_SysCall(syscall_nr_fstat,TSysParam(fd),TSysParam(@sb)); ++ {$else} ++ FpFStat:=do_SysCall(syscall_nr_fstat,TSysParam(fd),TSysParam(@sb)); ++ {$endif} + {$else} + FpFStat:=do_SysCall(syscall_nr_fstat64,TSysParam(fd),TSysParam(@sb)); + {$endif} +@@ -380,9 +408,14 @@ function Fpfork : pid_t; [public, alias + A negative value indicates that an error has occurred, the error is returned in + LinuxError. + } +- ++var ++ pid : Int64; + Begin ++{$if defined(generic_linux_syscalls)} ++ Fpfork:=Do_syscall(syscall_nr_clone,clone_flags_fork,0,0,0,TSysParam(@pid)); ++{$else} + Fpfork:=Do_syscall(SysCall_nr_fork); ++{$endif} + End; + {$endif FPC_SYSTEM_HAS_FPFORK} + +@@ -425,7 +458,7 @@ function Fpwaitpid(pid : pid_t; stat_loc + } + + begin +-{$ifdef WAIT4} ++{$if defined(generic_linux_syscalls) or defined(WAIT4)} + FpWaitPID:=do_syscall(syscall_nr_Wait4,PID,TSysParam(Stat_loc),options,0); + {$else WAIT4} + FpWaitPID:=do_syscall(syscall_nr_WaitPID,PID,TSysParam(Stat_loc),options); +@@ -447,7 +480,11 @@ function Fpaccess(pathname : pchar; amod + } + + begin ++{$if defined(generic_linux_syscalls)} ++ FpAccess:=do_syscall(syscall_nr_faccessat,AT_FDCWD,TSysParam(pathname),amode,0); ++{$else} + FpAccess:=do_syscall(syscall_nr_access,TSysParam(pathname),amode); ++{$endif} + end; + + (* overloaded +@@ -481,7 +518,16 @@ end; + Function FpDup2(fildes,fildes2:cint):cint; [public, alias : 'FPC_SYSC_DUP2']; + + begin ++{$if defined(generic_linux_syscalls)} ++ if fildes<>fildes2 then ++ Fpdup2:=do_syscall(syscall_nr_dup3,TSysParam(fildes),TSysParam(fildes2),0) ++ else if do_syscall(syscall_nr_fcntl,TSysParam(fildes),1)<>-1 then ++ Fpdup2:=fildes2 ++ else ++ Fpdup2:=-1; ++{$else} + Fpdup2:=do_syscall(syscall_nr_dup2,TSysParam(fildes),TSysParam(fildes2)); ++{$endif} + end; + + +@@ -572,7 +618,11 @@ end; + Function FpReadLink(name,linkname:pchar;maxlen:size_t):cint; [public, alias : 'FPC_SYSC_READLINK']; + + begin ++{$if defined(generic_linux_syscalls)} ++ Fpreadlink:=do_syscall(syscall_nr_readlinkat,AT_FDCWD,TSysParam(name),TSysParam(linkname),maxlen); ++{$else} + Fpreadlink:=do_syscall(syscall_nr_readlink, TSysParam(name),TSysParam(linkname),maxlen); ++{$endif} + end; + + +Index: fpc/fpcsrc/rtl/linux/ostypes.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/linux/ostypes.inc ++++ fpc/fpcsrc/rtl/linux/ostypes.inc +@@ -290,7 +290,12 @@ CONST + {$endif not cpumips} + {$endif not cpusparc} + +-{$if defined(cpuarm) or defined(cpualpha) or defined(cpublackfin) or defined(cpum68k)} ++ AT_FDCWD = -100; ++ AT_REMOVEDIR = $200; ++ clone_flags_fork = $01200011; ++ { SIGCHLD | CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID } ++ ++{$if defined(cpuarm) or defined(cpualpha) or defined(cpublackfin) or defined(cpum68k) or defined(aarch64)} + O_LARGEFILE = $20000; + {$endif} + {$if defined(cpusparc) or defined(cpusparc64)} +Index: fpc/fpcsrc/rtl/linux/pmutext.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/pmutext.inc +@@ -0,0 +1,58 @@ ++{ ++ This file is part of the Free Pascal run time library. ++ Copyright (c) 1999-2000 by Peter Vreman ++ member of the Free Pascal development team. ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ ++{ definition of pthread_mutex_t, because needed in both ptypes.inc and } ++{ in sysosh.inc } ++ ++{ use a macro rather than a constant, so this name doesn't get exported ++ from the system unit interface; macro's have to be on at this point ++ because they're use to propagate the MUTEXTYPENAME here } ++ ++{$if defined(CPUMIPS) or defined(cpuaarch64)} ++{$define USE_PTHREAD_SIZEOF} ++ ++{$if defined(cpuaarch64)} ++ {$define __SIZEOF_PTHREAD_MUTEX_T := 48} ++{$elseif defined(CPU64)} ++ {$define __SIZEOF_PTHREAD_MUTEX_T := 40} ++{$else CPU64} ++ {$define __SIZEOF_PTHREAD_MUTEX_T := 24} ++{$endif CPU64} ++ ++{$endif MIPS} ++ ++ MUTEXTYPENAME = record ++ case byte of ++{$ifdef USE_PTHREAD_SIZEOF} ++ 0 : ( ++ __size : array[0..__SIZEOF_PTHREAD_MUTEX_T-1] of char; ++ __align : sizeint; ++ ); ++{$endif} ++ 1 : ( ++ __m_reserved: longint; ++ __m_count: longint; ++ __m_owner: pointer; ++ __m_kind: longint; ++ __m_lock: record ++ __status: sizeint; ++ __spinlock: longint; ++ end; ++ ); ++ end; ++ ++{$ifdef __SIZEOF_PTHREAD_MUTEX_T} ++{$undef __SIZEOF_PTHREAD_MUTEX_T} ++{$endif __SIZEOF_PTHREAD_MUTEX_T} ++{$macro off} +\ No newline at end of file +Index: fpc/fpcsrc/rtl/linux/ptypes.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/linux/ptypes.inc ++++ fpc/fpcsrc/rtl/linux/ptypes.inc +@@ -30,12 +30,21 @@ and all three 32-bit systems returned co + introduction) + } + +-{$ifdef CPUMIPS} ++{$if defined(CPUMIPS) or defined(cpuaarch64)} + {$define USE_PTHREAD_SIZEOF} +-{$ifdef CPU64} ++{$if defined(cpuaarch64)} ++const ++ __SIZEOF_PTHREAD_ATTR_T = 64; ++ __SIZEOF_PTHREAD_MUTEXATTR_T = 8; ++ __SIZEOF_PTHREAD_COND_T = 48; ++ __SIZEOF_PTHREAD_CONDATTR_T = 8; ++ __SIZEOF_PTHREAD_RWLOCK_T = 56; ++ __SIZEOF_PTHREAD_RWLOCKATTR_T = 8; ++ __SIZEOF_PTHREAD_BARRIER_T = 32; ++ __SIZEOF_PTHREAD_BARRIERATTR_T = 8; ++{$elseif defined(CPU64)} + const + __SIZEOF_PTHREAD_ATTR_T = 56; +- __SIZEOF_PTHREAD_MUTEX_T = 40; + __SIZEOF_PTHREAD_MUTEXATTR_T = 4; + __SIZEOF_PTHREAD_COND_T = 48; + __SIZEOF_PTHREAD_CONDATTR_T = 4; +@@ -46,7 +55,6 @@ const + {$else : not CPU64, i.e. CPU32} + const + __SIZEOF_PTHREAD_ATTR_T = 36; +- __SIZEOF_PTHREAD_MUTEX_T = 24; + __SIZEOF_PTHREAD_MUTEXATTR_T = 4; + __SIZEOF_PTHREAD_COND_T = 48; + __SIZEOF_PTHREAD_CONDATTR_T = 4; +@@ -55,7 +63,7 @@ const + __SIZEOF_PTHREAD_BARRIER_T = 20; + __SIZEOF_PTHREAD_BARRIERATTR_T = 4; + {$endif CPU32} +-{$endif MIPS} ++{$endif} + + {$I ctypes.inc} + {$packrecords c} +@@ -256,24 +264,11 @@ Type + __spinlock: cint; + end; + +- pthread_mutex_t = record +- {$ifdef USE_PTHREAD_SIZEOF} +- case byte of +- 0 : ( +- __size : array[0..__SIZEOF_PTHREAD_MUTEX_T-1] of char; +- __align : clong; +- ); +- 1 : ( +- {$endif} +- __m_reserved: cint; +- __m_count: cint; +- __m_owner: pointer; +- __m_kind: cint; +- __m_lock: _pthread_fastlock; +- {$ifdef USE_PTHREAD_SIZEOF} +- ); +- {$endif} +- end; ++{$macro on} ++{$define MUTEXTYPENAME := pthread_mutex_t} ++{$i pmutext.inc} ++{$undef MUTEXTYPENAME} ++{$macro off} + + pthread_mutexattr_t = record + {$ifdef USE_PTHREAD_SIZEOF} +Index: fpc/fpcsrc/rtl/linux/sysnr-gen.inc +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/rtl/linux/sysnr-gen.inc +@@ -0,0 +1,277 @@ ++ ++{ ++ System call numbers taken from include/uapi/asm-generic/unistd.h ++ in a 4.0 Linux kernel. They are therefore architecture-independent, ++ though only the newest architectures use this generic list. ++} ++ ++Const ++ syscall_nr_io_setup = 0; ++ syscall_nr_io_destroy = 1; ++ syscall_nr_io_submit = 2; ++ syscall_nr_io_cancel = 3; ++ syscall_nr_io_getevents = 4; ++ syscall_nr_setxattr = 5; ++ syscall_nr_lsetxattr = 6; ++ syscall_nr_fsetxattr = 7; ++ syscall_nr_getxattr = 8; ++ syscall_nr_lgetxattr = 9; ++ syscall_nr_fgetxattr = 10; ++ syscall_nr_listxattr = 11; ++ syscall_nr_llistxattr = 12; ++ syscall_nr_flistxattr = 13; ++ syscall_nr_removexattr = 14; ++ syscall_nr_lremovexattr = 15; ++ syscall_nr_fremovexattr = 16; ++ syscall_nr_getcwd = 17; ++ syscall_nr_lookup_dcookie = 18; ++ syscall_nr_eventfd2 = 19; ++ syscall_nr_epoll_create1 = 20; ++ syscall_nr_epoll_ctl = 21; ++ syscall_nr_epoll_pwait = 22; ++ syscall_nr_dup = 23; ++ syscall_nr_dup3 = 24; ++ syscall_nr_fcntl = 25; ++ syscall_nr_inotify_init1 = 26; ++ syscall_nr_inotify_add_watch = 27; ++ syscall_nr_inotify_rm_watch = 28; ++ syscall_nr_ioctl = 29; ++ syscall_nr_ioprio_set = 30; ++ syscall_nr_ioprio_get = 31; ++ syscall_nr_flock = 32; ++ syscall_nr_mknodat = 33; ++ syscall_nr_mkdirat = 34; ++ syscall_nr_unlinkat = 35; ++ syscall_nr_symlinkat = 36; ++ syscall_nr_linkat = 37; ++ syscall_nr_renameat = 38; ++ syscall_nr_umount2 = 39; ++ syscall_nr_mount = 40; ++ syscall_nr_pivot_root = 41; ++ syscall_nr_nfsservctl = 42; ++ syscall_nr_statfs = 43; ++ syscall_nr_fstatfs = 44; ++ syscall_nr_truncate = 45; ++ syscall_nr_ftruncate = 46; ++ syscall_nr_fallocate = 47; ++ syscall_nr_faccessat = 48; ++ syscall_nr_chdir = 49; ++ syscall_nr_fchdir = 50; ++ syscall_nr_chroot = 51; ++ syscall_nr_fchmod = 52; ++ syscall_nr_fchmodat = 53; ++ syscall_nr_fchownat = 54; ++ syscall_nr_fchown = 55; ++ syscall_nr_openat = 56; ++ syscall_nr_close = 57; ++ syscall_nr_vhangup = 58; ++ syscall_nr_pipe2 = 59; ++ syscall_nr_quotactl = 60; ++ syscall_nr_getdents64 = 61; ++ syscall_nr_lseek = 62; ++ syscall_nr_read = 63; ++ syscall_nr_write = 64; ++ syscall_nr_readv = 65; ++ syscall_nr_writev = 66; ++ syscall_nr_pread64 = 67; ++ syscall_nr_pwrite64 = 68; ++ syscall_nr_preadv = 69; ++ syscall_nr_pwritev = 70; ++ syscall_nr_sendfile = 71; ++ syscall_nr_pselect6 = 72; ++ syscall_nr_ppoll = 73; ++ syscall_nr_signalfd4 = 74; ++ syscall_nr_vmsplice = 75; ++ syscall_nr_splice = 76; ++ syscall_nr_tee = 77; ++ syscall_nr_readlinkat = 78; ++ syscall_nr_fstatat = 79; ++ syscall_nr_fstat = 80; ++ syscall_nr_sync = 81; ++ syscall_nr_fsync = 82; ++ syscall_nr_fdatasync = 83; ++ syscall_nr_sync_file_range = 84; ++ syscall_nr_timerfd_create = 85; ++ syscall_nr_timerfd_settime = 86; ++ syscall_nr_timerfd_gettime = 87; ++ syscall_nr_utimensat = 88; ++ syscall_nr_acct = 89; ++ syscall_nr_capget = 90; ++ syscall_nr_capset = 91; ++ syscall_nr_personality = 92; ++ syscall_nr_exit = 93; ++ syscall_nr_exit_group = 94; ++ syscall_nr_waitid = 95; ++ syscall_nr_set_tid_address = 96; ++ syscall_nr_unshare = 97; ++ syscall_nr_futex = 98; ++ syscall_nr_set_robust_list = 99; ++ syscall_nr_get_robust_list = 100; ++ syscall_nr_nanosleep = 101; ++ syscall_nr_getitimer = 102; ++ syscall_nr_setitimer = 103; ++ syscall_nr_kexec_load = 104; ++ syscall_nr_init_module = 105; ++ syscall_nr_delete_module = 106; ++ syscall_nr_timer_create = 107; ++ syscall_nr_timer_gettime = 108; ++ syscall_nr_timer_getoverrun = 109; ++ syscall_nr_timer_settime = 110; ++ syscall_nr_timer_delete = 111; ++ syscall_nr_clock_settime = 112; ++ syscall_nr_clock_gettime = 113; ++ syscall_nr_clock_getres = 114; ++ syscall_nr_clock_nanosleep = 115; ++ syscall_nr_syslog = 116; ++ syscall_nr_ptrace = 117; ++ syscall_nr_sched_setparam = 118; ++ syscall_nr_sched_setscheduler = 119; ++ syscall_nr_sched_getscheduler = 120; ++ syscall_nr_sched_getparam = 121; ++ syscall_nr_sched_setaffinity = 122; ++ syscall_nr_sched_getaffinity = 123; ++ syscall_nr_sched_yield = 124; ++ syscall_nr_sched_get_priority_max = 125; ++ syscall_nr_sched_get_priority_min = 126; ++ syscall_nr_sched_rr_get_interval = 127; ++ syscall_nr_restart_syscall = 128; ++ syscall_nr_kill = 129; ++ syscall_nr_tkill = 130; ++ syscall_nr_tgkill = 131; ++ syscall_nr_sigaltstack = 132; ++ syscall_nr_rt_sigsuspend = 133; ++ syscall_nr_rt_sigaction = 134; ++ syscall_nr_rt_sigprocmask = 135; ++ syscall_nr_rt_sigpending = 136; ++ syscall_nr_rt_sigtimedwait = 137; ++ syscall_nr_rt_sigqueueinfo = 138; ++ syscall_nr_rt_sigreturn = 139; ++ syscall_nr_setpriority = 140; ++ syscall_nr_getpriority = 141; ++ syscall_nr_reboot = 142; ++ syscall_nr_setregid = 143; ++ syscall_nr_setgid = 144; ++ syscall_nr_setreuid = 145; ++ syscall_nr_setuid = 146; ++ syscall_nr_setresuid = 147; ++ syscall_nr_getresuid = 148; ++ syscall_nr_setresgid = 149; ++ syscall_nr_getresgid = 150; ++ syscall_nr_setfsuid = 151; ++ syscall_nr_setfsgid = 152; ++ syscall_nr_times = 153; ++ syscall_nr_setpgid = 154; ++ syscall_nr_getpgid = 155; ++ syscall_nr_getsid = 156; ++ syscall_nr_setsid = 157; ++ syscall_nr_getgroups = 158; ++ syscall_nr_setgroups = 159; ++ syscall_nr_uname = 160; ++ syscall_nr_sethostname = 161; ++ syscall_nr_setdomainname = 162; ++ syscall_nr_getrlimit = 163; ++ syscall_nr_setrlimit = 164; ++ syscall_nr_getrusage = 165; ++ syscall_nr_umask = 166; ++ syscall_nr_prctl = 167; ++ syscall_nr_getcpu = 168; ++ syscall_nr_gettimeofday = 169; ++ syscall_nr_settimeofday = 170; ++ syscall_nr_adjtimex = 171; ++ syscall_nr_getpid = 172; ++ syscall_nr_getppid = 173; ++ syscall_nr_getuid = 174; ++ syscall_nr_geteuid = 175; ++ syscall_nr_getgid = 176; ++ syscall_nr_getegid = 177; ++ syscall_nr_gettid = 178; ++ syscall_nr_sysinfo = 179; ++ syscall_nr_mq_open = 180; ++ syscall_nr_mq_unlink = 181; ++ syscall_nr_mq_timedsend = 182; ++ syscall_nr_mq_timedreceive = 183; ++ syscall_nr_mq_notify = 184; ++ syscall_nr_mq_getsetattr = 185; ++ syscall_nr_msgget = 186; ++ syscall_nr_msgctl = 187; ++ syscall_nr_msgrcv = 188; ++ syscall_nr_msgsnd = 189; ++ syscall_nr_semget = 190; ++ syscall_nr_semctl = 191; ++ syscall_nr_semtimedop = 192; ++ syscall_nr_semop = 193; ++ syscall_nr_shmget = 194; ++ syscall_nr_shmctl = 195; ++ syscall_nr_shmat = 196; ++ syscall_nr_shmdt = 197; ++ syscall_nr_socket = 198; ++ syscall_nr_socketpair = 199; ++ syscall_nr_bind = 200; ++ syscall_nr_listen = 201; ++ syscall_nr_accept = 202; ++ syscall_nr_connect = 203; ++ syscall_nr_getsockname = 204; ++ syscall_nr_getpeername = 205; ++ syscall_nr_sendto = 206; ++ syscall_nr_recvfrom = 207; ++ syscall_nr_setsockopt = 208; ++ syscall_nr_getsockopt = 209; ++ syscall_nr_shutdown = 210; ++ syscall_nr_sendmsg = 211; ++ syscall_nr_recvmsg = 212; ++ syscall_nr_readahead = 213; ++ syscall_nr_brk = 214; ++ syscall_nr_munmap = 215; ++ syscall_nr_mremap = 216; ++ syscall_nr_add_key = 217; ++ syscall_nr_request_key = 218; ++ syscall_nr_keyctl = 219; ++ syscall_nr_clone = 220; ++ syscall_nr_execve = 221; ++ syscall_nr_mmap = 222; ++ syscall_nr_fadvise64 = 223; ++ syscall_nr_swapon = 224; ++ syscall_nr_swapoff = 225; ++ syscall_nr_mprotect = 226; ++ syscall_nr_msync = 227; ++ syscall_nr_mlock = 228; ++ syscall_nr_munlock = 229; ++ syscall_nr_mlockall = 230; ++ syscall_nr_munlockall = 231; ++ syscall_nr_mincore = 232; ++ syscall_nr_madvise = 233; ++ syscall_nr_remap_file_pages = 234; ++ syscall_nr_mbind = 235; ++ syscall_nr_get_mempolicy = 236; ++ syscall_nr_set_mempolicy = 237; ++ syscall_nr_migrate_pages = 238; ++ syscall_nr_move_pages = 239; ++ syscall_nr_rt_tgsigqueueinfo = 240; ++ syscall_nr_perf_event_open = 241; ++ syscall_nr_accept4 = 242; ++ syscall_nr_recvmmsg = 243; ++ syscall_nr_arch_specific_syscall = 244; ++ ++ syscall_nr_wait4 = 260; ++ syscall_nr_prlimit64 = 261; ++ syscall_nr_fanotify_init = 262; ++ syscall_nr_fanotify_mark = 263; ++ syscall_nr_name_to_handle_at = 264; ++ syscall_nr_open_by_handle_at = 265; ++ syscall_nr_clock_adjtime = 266; ++ syscall_nr_syncfs = 267; ++ syscall_nr_setns = 268; ++ syscall_nr_sendmmsg = 269; ++ syscall_nr_process_vm_readv = 270; ++ syscall_nr_process_vm_writev = 271; ++ syscall_nr_kcmp = 272; ++ syscall_nr_finit_module = 273; ++ syscall_nr_sched_setattr = 274; ++ syscall_nr_sched_getattr = 275; ++ syscall_nr_renameat2 = 276; ++ syscall_nr_seccomp = 277; ++ syscall_nr_getrandom = 278; ++ syscall_nr_memfd_create = 279; ++ syscall_nr_bpf = 280; ++ syscall_nr_execveat = 281; ++ syscall_nr_syscalls = 282; +Index: fpc/fpcsrc/rtl/linux/sysosh.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/linux/sysosh.inc ++++ fpc/fpcsrc/rtl/linux/sysosh.inc +@@ -23,18 +23,12 @@ type + { pthread_t is defined as an "unsigned long" } + TThreadID = PtrUInt; + +- { pthread_mutex_t } + PRTLCriticalSection = ^TRTLCriticalSection; +- TRTLCriticalSection = record +- __m_reserved: longint; +- __m_count: longint; +- __m_owner: pointer; +- __m_kind: longint; +- __m_lock: record +- __status: sizeint; +- __spinlock: longint; +- end; +- end; ++{$macro on} ++{$define MUTEXTYPENAME := TRTLCriticalSection} ++{$i pmutext.inc} ++{$undef MUTEXTYPENAME} ++{$macro off} + + + +Index: fpc/fpcsrc/rtl/linux/termios.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/linux/termios.inc ++++ fpc/fpcsrc/rtl/linux/termios.inc +@@ -22,6 +22,271 @@ Const + NCCS = 32; + NCC = 8; + ++{$ifdef cpuaarch64} ++ ++{ from Linux 4.0, include/uapi/asm-generic/ioctls.h } ++ ++ { For Terminal handling } ++ TCGETS = $5401; ++ TCSETS = $5402; ++ TCSETSW = $5403; ++ TCSETSF = $5404; ++ TCGETA = $5405; ++ TCSETA = $5406; ++ TCSETAW = $5407; ++ TCSETAF = $5408; ++ TCSBRK = $5409; ++ TCXONC = $540A; ++ TCFLSH = $540B; ++ TIOCEXCL = $540C; ++ TIOCNXCL = $540D; ++ TIOCSCTTY = $540E; ++ TIOCGPGRP = $540F; ++ TIOCSPGRP = $5410; ++ TIOCOUTQ = $5411; ++ TIOCSTI = $5412; ++ TIOCGWINSZ = $5413; ++ TIOCSWINSZ = $5414; ++ TIOCMGET = $5415; ++ TIOCMBIS = $5416; ++ TIOCMBIC = $5417; ++ TIOCMSET = $5418; ++ TIOCGSOFTCAR = $5419; ++ TIOCSSOFTCAR = $541A; ++ FIONREAD = $541B; ++ TIOCINQ = FIONREAD; ++ TIOCLINUX = $541C; ++ TIOCCONS = $541D; ++ TIOCGSERIAL = $541E; ++ TIOCSSERIAL = $541F; ++ TIOCPKT = $5420; ++ FIONBIO = $5421; ++ TIOCNOTTY = $5422; ++ TIOCSETD = $5423; ++ TIOCGETD = $5424; ++ TCSBRKP = $5425; ++ ++ TIOCSBRK = $5427; ++ TIOCCBRK = $5428; ++ TIOCGSID = $5429; ++ ++ TIOCGRS485 = $542E; ++ TIOCSRS485 = $542F; ++ ++ TCGETX = $5432; ++ TCSETX = $5433; ++ TCSETXF = $5434; ++ TCSETXW = $5435; ++ TIOCVHANGUP = $5437; ++ ++ FIONCLEX = $5450; ++ FIOCLEX = $5451; ++ FIOASYNC = $5452; ++ TIOCSERCONFIG = $5453; ++ TIOCSERGWILD = $5454; ++ TIOCSERSWILD = $5455; ++ TIOCGLCKTRMIOS = $5456; ++ TIOCSLCKTRMIOS = $5457; ++ TIOCSERGSTRUCT = $5458; ++ TIOCSERGETLSR = $5459; ++ TIOCSERGETMULTI = $545A; ++ TIOCSERSETMULTI = $545B; ++ TIOCMIWAIT = $545C; ++ TIOCGICOUNT = $545D; ++ ++ FIOQSIZE = $5460; ++ ++ TIOCPKT_DATA = 0; ++ TIOCPKT_FLUSHREAD = 1; ++ TIOCPKT_FLUSHWRITE = 2; ++ TIOCPKT_STOP = 4; ++ TIOCPKT_START = 8; ++ TIOCPKT_NOSTOP = 16; ++ TIOCPKT_DOSTOP = 32; ++ TIOCPKT_IOCTL = 64; ++ ++ TIOCSER_TEMT = $01; ++ ++{ from Linux 4.0, include/uapi/asm-generic/termbits.h } ++ ++ { c_cc characters } ++ VINTR = 0; ++ VQUIT = 1; ++ VERASE = 2; ++ VKILL = 3; ++ VEOF = 4; ++ VTIME = 5; ++ VMIN = 6; ++ VSWTC = 7; ++ VSTART = 8; ++ VSTOP = 9; ++ VSUSP = 10; ++ VEOL = 11; ++ VREPRINT = 12; ++ VDISCARD = 13; ++ VWERASE = 14; ++ VLNEXT = 15; ++ VEOL2 = 16; ++ ++ { c_iflag bits } ++ IGNBRK = &0000001; ++ BRKINT = &0000002; ++ IGNPAR = &0000004; ++ PARMRK = &0000010; ++ INPCK = &0000020; ++ ISTRIP = &0000040; ++ INLCR = &0000100; ++ IGNCR = &0000200; ++ ICRNL = &0000400; ++ IUCLC = &0001000; ++ IXON = &0002000; ++ IXANY = &0004000; ++ IXOFF = &0010000; ++ IMAXBEL = &0020000; ++ IUTF8 = &0040000; ++ ++ { c_oflag bits } ++ OPOST = &0000001; ++ OLCUC = &0000002; ++ ONLCR = &0000004; ++ OCRNL = &0000010; ++ ONOCR = &0000020; ++ ONLRET = &0000040; ++ OFILL = &0000100; ++ OFDEL = &0000200; ++ NLDLY = &0000400; ++ NL0 = &0000000; ++ NL1 = &0000400; ++ CRDLY = &0003000; ++ CR0 = &0000000; ++ CR1 = &0001000; ++ CR2 = &0002000; ++ CR3 = &0003000; ++ TABDLY = &0014000; ++ TAB0 = &0000000; ++ TAB1 = &0004000; ++ TAB2 = &0010000; ++ TAB3 = &0014000; ++ XTABS = &0014000; ++ BSDLY = &0020000; ++ BS0 = &0000000; ++ BS1 = &0020000; ++ VTDLY = &0040000; ++ VT0 = &0000000; ++ VT1 = &0040000; ++ FFDLY = &0100000; ++ FF0 = &0000000; ++ FF1 = &0100000; ++ ++ { c_cflag bits } ++ CBAUD = &0010017; ++ B0 = &0000000; ++ B50 = &0000001; ++ B75 = &0000002; ++ B110 = &0000003; ++ B134 = &0000004; ++ B150 = &0000005; ++ B200 = &0000006; ++ B300 = &0000007; ++ B600 = &0000010; ++ B1200 = &0000011; ++ B1800 = &0000012; ++ B2400 = &0000013; ++ B4800 = &0000014; ++ B9600 = &0000015; ++ B19200 = &0000016; ++ B38400 = &0000017; ++ EXTA = B19200; ++ EXTB = B38400; ++ CSIZE = &0000060; ++ CS5 = &0000000; ++ CS6 = &0000020; ++ CS7 = &0000040; ++ CS8 = &0000060; ++ CSTOPB = &0000100; ++ CREAD = &0000200; ++ PARENB = &0000400; ++ PARODD = &0001000; ++ HUPCL = &0002000; ++ CLOCAL = &0004000; ++ CBAUDEX = &0010000; ++ BOTHER = &0010000; ++ B57600 = &0010001; ++ B115200 = &0010002; ++ B230400 = &0010003; ++ B460800 = &0010004; ++ B500000 = &0010005; ++ B576000 = &0010006; ++ B921600 = &0010007; ++ B1000000 = &0010010; ++ B1152000 = &0010011; ++ B1500000 = &0010012; ++ B2000000 = &0010013; ++ B2500000 = &0010014; ++ B3000000 = &0010015; ++ B3500000 = &0010016; ++ B4000000 = &0010017; ++ ++ CIBAUD = &002003600000; ++ CMSPAR = &010000000000; ++ CRTSCTS = &020000000000; ++ ++ IBSHIFT = 16; ++ ++ { c_lflag bits } ++ ISIG = &0000001; ++ ICANON = &0000002; ++ XCASE = &0000004; ++ ECHO = &0000010; ++ ECHOE = &0000020; ++ ECHOK = &0000040; ++ ECHONL = &0000100; ++ NOFLSH = &0000200; ++ TOSTOP = &0000400; ++ ECHOCTL = &0001000; ++ ECHOPRT = &0002000; ++ ECHOKE = &0004000; ++ FLUSHO = &0010000; ++ PENDIN = &0040000; ++ IEXTEN = &0100000; ++ EXTPROC = &0200000; ++ ++ { TCFlow } ++ TCOOFF = 0; ++ TCOON = 1; ++ TCIOFF = 2; ++ TCION = 3; ++ ++ { TCFlush } ++ TCIFLUSH = 0; ++ TCOFLUSH = 1; ++ TCIOFLUSH = 2; ++ ++ { TCSetAttr } ++ TCSANOW = 0; ++ TCSADRAIN = 1; ++ TCSAFLUSH = 2; ++ ++{ from Linux 4.0, include/uapi/asm-generic/termios.h } ++ ++ { c_line bits } ++ TIOCM_LE = $001; ++ TIOCM_DTR = $002; ++ TIOCM_RTS = $004; ++ TIOCM_ST = $008; ++ TIOCM_SR = $010; ++ TIOCM_CTS = $020; ++ TIOCM_CAR = $040; ++ TIOCM_RNG = $080; ++ TIOCM_DSR = $100; ++ TIOCM_CD = TIOCM_CAR; ++ TIOCM_RI = TIOCM_RNG; ++ TIOCM_OUT1 = $2000; ++ TIOCM_OUT2 = $4000; ++ TIOCM_LOOP = $8000; ++ ++{$endif cpuaarch64} ++ + {$ifdef cpupowerpc} + TCGETS = $402c7413; + TCSETS = $802c7414; +Index: fpc/fpcsrc/rtl/unix/cthreads.pp +=================================================================== +--- fpc.orig/fpcsrc/rtl/unix/cthreads.pp ++++ fpc/fpcsrc/rtl/unix/cthreads.pp +@@ -140,6 +140,10 @@ Type PINTRTLEvent = ^TINTRTLEvent; + threadvarblocksize:=align(threadvarblocksize,16); + {$endif cpupowerpc64} + ++ {$ifdef cpuaarch64} ++ threadvarblocksize:=align(threadvarblocksize,16); ++ {$endif cpuaarch64} ++ + offset:=threadvarblocksize; + + inc(threadvarblocksize,size); +Index: fpc/fpcsrc/rtl/unix/cwstring.pp +=================================================================== +--- fpc.orig/fpcsrc/rtl/unix/cwstring.pp ++++ fpc/fpcsrc/rtl/unix/cwstring.pp +@@ -230,12 +230,12 @@ procedure InitThread; + var + transliterate: cint; + iconvindex: longint; +-{$if not(defined(darwin) and defined(cpuarm)) and not defined(iphonesim)} ++{$if not(defined(darwin) and (defined(cpuarm) or defined(cpuaarch64))) and not defined(iphonesim)} + iconvname: rawbytestring; + {$endif} + begin + current_DefaultSystemCodePage:=DefaultSystemCodePage; +-{$if not(defined(darwin) and defined(cpuarm)) and not defined(iphonesim)} ++{$if not(defined(darwin) and (defined(cpuarm) or defined(cpuaarch64))) and not defined(iphonesim)} + iconvindex:=GetCodepageData(DefaultSystemCodePage); + if iconvindex<>-1 then + iconvname:=UnixCpMap[iconvindex].name +Index: fpc/fpcsrc/utils/fpcm/fpcmmain.pp +=================================================================== +--- fpc.orig/fpcsrc/utils/fpcm/fpcmmain.pp ++++ fpc/fpcsrc/utils/fpcm/fpcmmain.pp +@@ -67,7 +67,7 @@ interface + + type + TCpu=( +- c_i386,c_m68k,c_powerpc,c_sparc,c_x86_64,c_arm,c_powerpc64,c_avr,c_armeb,c_armel,c_mips,c_mipsel,c_mips64,c_mips64el,c_jvm,c_i8086 ++ c_i386,c_m68k,c_powerpc,c_sparc,c_x86_64,c_arm,c_powerpc64,c_avr,c_armeb,c_armel,c_mips,c_mipsel,c_mips64,c_mips64el,c_jvm,c_i8086,c_aarch64 + ); + + TOS=( +@@ -82,15 +82,15 @@ interface + + const + CpuStr : array[TCpu] of string=( +- 'i386','m68k','powerpc','sparc','x86_64','arm','powerpc64','avr','armeb', 'armel', 'mips', 'mipsel', 'mips64', 'mips64el', 'jvm','i8086' ++ 'i386','m68k','powerpc','sparc','x86_64','arm','powerpc64','avr','armeb', 'armel', 'mips', 'mipsel', 'mips64', 'mips64el', 'jvm','i8086','aarch64' + ); + + CpuSuffix : array[TCpu] of string=( +- '_i386','_m68k','_powerpc','_sparc','_x86_64','_arm','_powerpc64','_avr','_armeb', '_armel', '_mips', '_mipsel', '_mips64', '_mips64el', '_jvm','_i8086' ++ '_i386','_m68k','_powerpc','_sparc','_x86_64','_arm','_powerpc64','_avr','_armeb', '_armel', '_mips', '_mipsel', '_mips64', '_mips64el', '_jvm','_i8086','_aarch64' + ); + + ppcSuffix : array[TCpu] of string=( +- '386','m68k','ppc','sparc','x86_64','arm','ppc64','avr','armeb', 'armel', 'mips', 'mipsel', 'mips64', 'mips64el', 'jvm','8086' ++ '386','m68k','ppc','sparc','x86_64','arm','ppc64','avr','armeb', 'armel', 'mips', 'mipsel', 'mips64', 'mips64el', 'jvm','8086','aarch64' + ); + + OSStr : array[TOS] of string=( +@@ -113,44 +113,44 @@ interface + + { This table is kept OS,Cpu because it is easier to maintain (PFV) } + OSCpuPossible : array[TOS,TCpu] of boolean = ( +- { os i386 m68k ppc sparc x86_64 arm ppc64 avr armeb armel mips mipsel mips64 misp64el jvm i8086 } +- { linux } ( true, true, true, true, true, true, true, false, true, false, true, true, false, false, false, false), +- { go32v2 } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { win32 } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { os2 } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { freebsd } ( true, true, false, false, true, false, false, false, false, false, false, false, false, false, false, false), +- { beos } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { haiku } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { netbsd } ( true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false), +- { amiga } ( false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { atari } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { solaris } ( true, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false), +- { qnx } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { netware } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { openbsd } ( true, true, false, false, true, false, false, false, false, false, false, false, false, false, false, false), +- { wdosx } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { palmos } ( false, true, false, false, false, true, false, false, false, false, false, false, false, false, false, false), +- { macos } ( false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { darwin } ( true, false, true, false, true, true, true, false, false, false, false, false, false, false, false, false), +- { emx } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { watcom } ( true, false, false, false ,false, false, false, false, false, false, false, false, false, false, false, false), +- { morphos } ( false, false, true, false ,false, false, false, false, false, false, false, false, false, false, false, false), +- { netwlibc }( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { win64 } ( false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false), +- { wince }( true, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false), +- { gba } ( false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false), +- { nds } ( false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false), +- { embedded }( true, true, true, true, true, true, true, true, true , false, false, true , false, false, false, false), +- { symbian } ( true, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false), +- { nativent }( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { iphonesim }( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { wii } ( false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false), +- { aix } ( false, false, true, false, false, false, true, false, false, false, false, false, false, false, false, false), +- { java } ( false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false), +- { android } ( true, false, false, false, false, true, false, false, false, false, false, true, false, false, true, false), +- { msdos } ( false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true), +- { aros } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), +- {dragonfly} ( false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false) ++ { os i386 m68k ppc sparc x86_64 arm ppc64 avr armeb armel mips mipsel mips64 misp64el jvm i8086 aarch64} ++ { linux } ( true, true, true, true, true, true, true, false, true, false, true, true, false, false, false, false, true ), ++ { go32v2 } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { win32 } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { os2 } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { freebsd } ( true, true, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false), ++ { beos } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { haiku } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { netbsd } ( true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false), ++ { amiga } ( false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { atari } ( false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { solaris } ( true, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false), ++ { qnx } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { netware } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { openbsd } ( true, true, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false), ++ { wdosx } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { palmos } ( false, true, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false), ++ { macos } ( false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { darwin } ( true, false, true, false, true, true, true, false, false, false, false, false, false, false, false, false, true ), ++ { emx } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { watcom } ( true, false, false, false ,false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { morphos } ( false, false, true, false ,false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { netwlibc }( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { win64 } ( false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false), ++ { wince }( true, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false), ++ { gba } ( false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false), ++ { nds } ( false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false), ++ { embedded }( true, true, true, true, true, true, true, true, true , false, false, true , false, false, false, false, false), ++ { symbian } ( true, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false), ++ { nativent }( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { iphonesim }( true, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false), ++ { wii } ( false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ { aix } ( false, false, true, false, false, false, true, false, false, false, false, false, false, false, false, false, false), ++ { java } ( false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false), ++ { android } ( true, false, false, false, false, true, false, false, false, false, false, true, false, false, true, false, false), ++ { msdos } ( false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true , false), ++ { aros } ( true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false), ++ {dragonfly} ( false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false) + ); + + type +Index: fpc/fpcsrc/utils/fpcres/fpcres.pas +=================================================================== +--- fpc.orig/fpcsrc/utils/fpcres/fpcres.pas ++++ fpc/fpcsrc/utils/fpcres/fpcres.pas +@@ -73,7 +73,7 @@ begin + writeln(' i386, x86_64, arm (coff)'); + writeln(' i386, x86_64, powerpc, powerpc64, arm, armeb, m68k,'); + writeln(' sparc, alpha, ia64, mips, mipsel (elf)'); +- writeln(' i386, x86_64, powerpc, powerpc64, arm (mach-o)'); ++ writeln(' i386, x86_64, powerpc, powerpc64, arm, aarch64 (mach-o)'); + writeln(' bigendian, littleendian (external)'); + writeln(' --subarch, -s Set object file sub-architecture. Supported values:'); + writeln(' arm: all, v4t, v6, v5tej, xscale, v7'); +@@ -252,6 +252,7 @@ begin + mtia64 : Result.MachineType:=emtia64; + mtmips : Result.MachineType:=emtmips; + mtmipsel : Result.MachineType:=emtmipsel; ++ mtaarch64 : Result.MachineType:=emtaarch64; + end; + end; + +@@ -312,6 +313,11 @@ begin + Result.MachineType:=mmtarm; + MachOSubMachineType.fArmSubType:=ArmSubMachine2MachOSubMachine[CurrentTarget.submachine.subarm]; + end; ++ mtaarch64 : ++ begin ++ Result.MachineType:=mmtarm64; ++ MachOSubMachineType.fArm64SubType:=msmaarch64_all; ++ end; + end; + Result.SubMachineType:=MachOSubMachineType; + end; +Index: fpc/fpcsrc/utils/fpcres/target.pas +=================================================================== +--- fpc.orig/fpcsrc/utils/fpcres/target.pas ++++ fpc/fpcsrc/utils/fpcres/target.pas +@@ -22,7 +22,7 @@ interface + + type + TMachineType = (mtnone, mti386,mtx86_64,mtppc,mtppc64,mtarm,mtarmeb,mtm68k, +- mtsparc,mtalpha,mtia64,mtmips,mtmipsel, ++ mtsparc,mtalpha,mtia64,mtmips,mtmipsel,mtaarch64, + mtBigEndian,mtLittleEndian); + TMachineTypes = set of TMachineType; + +@@ -34,7 +34,7 @@ type + mtarm,mtarmeb: + (subarm: TSubMachineTypeArm); + mtnone, mti386,mtx86_64,mtppc,mtppc64,mtm68k, +- mtsparc,mtalpha,mtia64,mtmips,mtmipsel, ++ mtsparc,mtalpha,mtia64,mtmips,mtmipsel,mtaarch64, + mtBigEndian,mtLittleEndian: + (subgen: TSubMachineTypeGeneric); + end; +@@ -83,6 +83,7 @@ var + (name : 'ia64'; formats : [ofElf]), //mtia64 + (name : 'mips'; formats : [ofElf]; alias : 'mipseb'), //mtmips + (name : 'mipsel'; formats : [ofElf]), //mtmipsel ++ (name : 'aarch64'; formats : [ofElf, ofMachO]), //mtaarch64 + (name : 'bigendian'; formats : [ofExt]), //mtBigEndian + (name : 'littleendian'; formats : [ofExt]) //mtLittleEndian + ); +@@ -99,35 +100,31 @@ var + (name : 'elf'; ext : '.or'; machines : [mti386,mtx86_64,mtppc, + mtppc64,mtarm,mtarmeb, + mtm68k,mtsparc,mtalpha, +- mtia64,mtmips,mtmipsel]), ++ mtaarch64]), + (name : 'coff'; ext : '.o'; machines : [mti386,mtx86_64,mtarm, + mtppc,mtppc64]), + (name : 'xcoff'; ext : '.o'; machines : [mtppc{,mtppc64}]), + (name : 'mach-o'; ext : '.or'; machines : [mti386,mtx86_64,mtppc, +- mtppc64,mtarm]), ++ mtppc64,mtarm,mtaarch64]), + (name : 'external'; ext : '.fpcres'; machines : [mtBigEndian,mtLittleEndian]) + ); + + + CurrentTarget : TResTarget = + ( +- {$IFDEF CPUI386} ++ {$if defined(CPUI386)} + machine : mti386; + submachine : (subgen: smtgen_all); +- {$ELSE} +- {$IFDEF CPUX86_64} ++ {$elseif defined(CPUX86_64)} + machine : mtx86_64; + submachine : (subgen: smtgen_all); +- {$ELSE} +- {$IFDEF CPUPOWERPC32} ++ {$elseif defined(CPUPOWERPC32)} + machine : mtppc; + submachine : (subgen: smtgen_all); +- {$ELSE} +- {$IFDEF CPUPOWERPC64} ++ {$elseif defined(CPUPOWERPC64)} + machine : mtppc64; + submachine : (subgen: smtgen_all); +- {$ELSE} +- {$IFDEF CPUARM} ++ {$elseif defined(CPUARM)} + {$IFDEF ENDIAN_LITTLE} + machine : mtarm; + submachine : (subarm: smtarm_all); +@@ -135,44 +132,31 @@ var + machine : mtarmeb; + submachine : (subarm: smtarm_all); + {$ENDIF} +- {$ELSE} +- {$IFDEF CPU68K} ++ {$elseif defined(CPU68K)} + machine : mtm68k; + submachine : (subgen: smtgen_all); +- {$ELSE} +- {$IFDEF CPUSPARC} ++ {$elseif defined(CPUSPARC)} + machine : mtsparc; + submachine : (subgen: smtgen_all); +- {$ELSE} +- {$IFDEF CPUALPHA} ++ {$elseif defined(CPUALPHA)} + machine : mtalpha; + submachine : (subgen: smtgen_all); +- {$ELSE} +- {$IFDEF CPUIA64} ++ {$elseif defined(CPUIA64)} + machine : mtia64; + submachine : (subgen: smtgen_all); +- {$ELSE} +- {$IFDEF CPUMIPSEL} ++ {$elseif defined(CPUMIPSEL)} + machine : mtmipsel; + submachine : (subgen: smtgen_all); +- {$ELSE} +- {$IFDEF CPUMIPS} ++ {$elseif defined(CPUMIPS)} + machine : mtmips; + submachine : (subgen: smtgen_all); +- {$ELSE} ++ {$elseif defined(CPUAARCH64)} ++ machine : mtaarch64; ++ submachine : (subgen: smtgen_all); ++ {$else} + machine : mti386; //default i386 + submachine : (subgen: smtgen_all); +- {$ENDIF} +- {$ENDIF} +- {$ENDIF} +- {$ENDIF} +- {$ENDIF} +- {$ENDIF} +- {$ENDIF} +- {$ENDIF} +- {$ENDIF} +- {$ENDIF} +- {$ENDIF} ++ {$endif} + + {$IFDEF WINDOWS} + objformat : ofCoff; diff --git a/patches/after_patch_arm64_systems.pas.patch b/patches/after_patch_arm64_systems.pas.patch new file mode 100644 index 00000000..5f4d6b4c --- /dev/null +++ b/patches/after_patch_arm64_systems.pas.patch @@ -0,0 +1,17 @@ +Description: Missing part of the arm64 patch (upstream fix after the 3.0.0rc1 +release) +Source: http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/compiler/systems.pas?r1=32102&r2=32101&view=patch +Bug-Debian: https://bugs.debian.org/807479 +Index: fpc/fpcsrc/compiler/systems.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/systems.pas ++++ fpc/fpcsrc/compiler/systems.pas +@@ -338,7 +338,7 @@ interface + + { all systems where a value parameter passed by reference must be copied + on the caller side rather than on the callee side } +- systems_caller_copy_addr_value_para = [system_aarch64_darwin]; ++ systems_caller_copy_addr_value_para = [system_aarch64_darwin,system_aarch64_linux]; + + { pointer checking (requires special code in FPC_CHECKPOINTER, + and can never work for libc-based targets or any other program diff --git a/patches/armhf-fix-vstr-vld-offset.patch b/patches/armhf-fix-vstr-vld-offset.patch new file mode 100644 index 00000000..f6085324 --- /dev/null +++ b/patches/armhf-fix-vstr-vld-offset.patch @@ -0,0 +1,57 @@ +Description: Offset of vstr/vld is limited to +/- 1020 + take care of this during spilling +Origin: upstream, http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=revision&revision=35396 +Bug: http://bugs.freepascal.org/view.php?id=31287 +Bug-Debian: https://bugs.debian.org/852798 +Author: Florian Klämpfl +Last-Update: 2017-02-04 +--- a/fpcsrc/compiler/arm/rgcpu.pas ++++ b/fpcsrc/compiler/arm/rgcpu.pas +@@ -189,7 +189,7 @@ + + { Lets remove the bits we can fold in later and check if the result can be easily with an add or sub } + a:=abs(spilltemp.offset); +- if GenerateThumbCode then ++ if GenerateThumbCode or (getregtype(tempreg)=R_MMREGISTER) then + begin + {$ifdef DEBUG_SPILLING} + helplist.concat(tai_comment.create(strpnew('Spilling: Use a_load_const_reg to fix spill offset'))); +@@ -243,9 +243,10 @@ + end; + + +- function fix_spilling_offset(offset : ASizeInt) : boolean; ++ function fix_spilling_offset(regtype : TRegisterType;offset : ASizeInt) : boolean; + begin + result:=(abs(offset)>4095) or ++ ((regtype=R_MMREGISTER) and (abs(offset)>1020)) or + ((GenerateThumbCode) and ((offset<0) or (offset>1020))); + end; + +@@ -255,7 +256,7 @@ + { don't load spilled register between + mov lr,pc + mov pc,r4 +- but befure the mov lr,pc ++ but before the mov lr,pc + } + if assigned(pos.previous) and + (pos.typ=ait_instruction) and +@@ -266,7 +267,7 @@ + (taicpu(pos).oper[1]^.reg=NR_PC) then + pos:=tai(pos.previous); + +- if fix_spilling_offset(spilltemp.offset) then ++ if fix_spilling_offset(getregtype(tempreg),spilltemp.offset) then + spilling_create_load_store(list, pos, spilltemp, tempreg, false) + else + inherited do_spill_read(list,pos,spilltemp,tempreg); +@@ -275,7 +276,7 @@ + + procedure trgcpu.do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister); + begin +- if fix_spilling_offset(spilltemp.offset) then ++ if fix_spilling_offset(getregtype(tempreg),spilltemp.offset) then + spilling_create_load_store(list, pos, spilltemp, tempreg, true) + else + inherited do_spill_written(list,pos,spilltemp,tempreg); diff --git a/patches/armhf-tags.patch b/patches/armhf-tags.patch new file mode 100644 index 00000000..ff2bdc7e --- /dev/null +++ b/patches/armhf-tags.patch @@ -0,0 +1,16 @@ +Description: Add tags to make armhf binaries come out correctly. + Add elf tag to mark hardfp binaries as such. (Closes: 695547) +Author: Peter Michael Green +Bug-Debian: https://bugs.debian.org/695547 + +--- fpc-3.0.0+dfsg.orig/fpcsrc/compiler/arm/agarmgas.pas ++++ fpc-3.0.0+dfsg/fpcsrc/compiler/arm/agarmgas.pas +@@ -135,6 +135,8 @@ unit agarmgas; + inherited WriteExtraHeader; + if TArmInstrWriter(InstrWriter).unified_syntax then + AsmWriteLn(#9'.syntax unified'); ++ if target_info.abi = abi_eabihf then ++ AsmWriteLn(#9'.eabi_attribute 28, 1 @Tag_ABI_VFP_args'); + end; + + {****************************************************************************} diff --git a/patches/change-path-of-localization-files-to-fit-Debian-standar.patch b/patches/change-path-of-localization-files-to-fit-Debian-standar.patch new file mode 100644 index 00000000..269bb57b --- /dev/null +++ b/patches/change-path-of-localization-files-to-fit-Debian-standar.patch @@ -0,0 +1,103 @@ +From: Abou Al Montacir +Date: Wed, 15 Jan 2014 21:49:04 +0100 +Subject: Change path of localization fies to fit Debian standard. (Closes: Bug#73368) +Bug-Debian: http://bugs.debian.org/73368 + +Index: fpc/fpcsrc/utils/fpdoc/dglobals.pp +=================================================================== +--- fpc.orig/fpcsrc/utils/fpdoc/dglobals.pp ++++ fpc/fpcsrc/utils/fpdoc/dglobals.pp +@@ -1677,7 +1677,7 @@ procedure TranslateDocStrings(const Lang + + Const + {$ifdef unix} +- DefDir = '/usr/local/share/locale'; ++ DefDir = '/usr/share/locale'; + {$else} + DefDir = 'intl'; + {$endif} +@@ -1691,7 +1691,7 @@ begin + Dir:=DefDir; + Dir:=IncludeTrailingPathDelimiter(Dir); + {$IFDEF Unix} +- mo := TMOFile.Create(Format(Dir+'%s/LC_MESSAGES/dglobals.mo', [Lang])); ++ mo := TMOFile.Create(Format(Dir+'%s/LC_MESSAGES/dglobals-' + {$include %FPCVERSION%} + '.mo', [Lang])); + {$ELSE} + mo := TMOFile.Create(Format(Dir+'dglobals.%s.mo', [Lang])); + {$ENDIF} +Index: fpc/fpcsrc/utils/fpdoc/fpclasschart.pp +=================================================================== +--- fpc.orig/fpcsrc/utils/fpdoc/fpclasschart.pp ++++ fpc/fpcsrc/utils/fpdoc/fpclasschart.pp +@@ -687,7 +687,7 @@ Function ParseCommandLine : Integer; + + Const + {$IFDEF Unix} +- MoFileTemplate = '/usr/local/share/locale/%s/LC_MESSAGES/makeskel.mo'; ++ MoFileTemplate = '/usr/share/locale/%s/LC_MESSAGES/makeskel-' + {$include %FPCVERSION%} + '.mo'; + {$ELSE} + MoFileTemplate ='intl/makeskel.%s.mo'; + {$ENDIF} +Index: fpc/fpcsrc/utils/fpdoc/fpdoc.pp +=================================================================== +--- fpc.orig/fpcsrc/utils/fpdoc/fpdoc.pp ++++ fpc/fpcsrc/utils/fpdoc/fpdoc.pp +@@ -394,7 +394,7 @@ Procedure TFPDocApplication.DoRun; + begin + try + {$IFDEF Unix} +- gettext.TranslateResourceStrings('/usr/local/share/locale/%s/LC_MESSAGES/fpdoc.mo'); ++ gettext.TranslateResourceStrings('/usr/share/locale/%s/LC_MESSAGES/fpdoc-' + {$include %FPCVERSION%} + '.mo'); + {$ELSE} + gettext.TranslateResourceStrings('intl/fpdoc.%s.mo'); + {$ENDIF} +Index: fpc/fpcsrc/utils/fpdoc/intl/Makefile +=================================================================== +--- fpc.orig/fpcsrc/utils/fpdoc/intl/Makefile ++++ fpc/fpcsrc/utils/fpdoc/intl/Makefile +@@ -1,3 +1,5 @@ ++FPC_VERSION=$(shell ${PP} -iV) ++ + all: de + + clean: +@@ -16,8 +18,8 @@ pot: + rstconv -i ../makeskel.rst -o makeskel.pot + rstconv -i ../fpdocmk.rst -o fpdocmk.pot + +-install: +- install -D -m 0644 fpdoc.de.mo /usr/local/share/locale/de/LC_MESSAGES/fpdoc.mo +- install -D -m 0644 dglobals.de.mo /usr/local/share/locale/de/LC_MESSAGES/dglobals.mo +- install -D -m 0644 makeskel.de.mo /usr/local/share/locale/de/LC_MESSAGES/makeskel.mo +- install -D -m 0644 fpdocmk.de.mo /usr/local/share/locale/de/LC_MESSAGES/fpdocmk.mo ++install: de ++ install -D -m 0644 fpdoc.de.mo ${INSTALL_PREFIX}/share/locale/de/LC_MESSAGES/fpdoc-${FPC_VERSION}.mo ++ install -D -m 0644 dglobals.de.mo ${INSTALL_PREFIX}/share/locale/de/LC_MESSAGES/dglobals-${FPC_VERSION}.mo ++ install -D -m 0644 makeskel.de.mo ${INSTALL_PREFIX}/share/locale/de/LC_MESSAGES/makeskel-${FPC_VERSION}.mo ++ install -D -m 0644 fpdocmk.de.mo ${INSTALL_PREFIX}/share/locale/de/LC_MESSAGES/fpdocmk-${FPC_VERSION}.mo +Index: fpc/fpcsrc/utils/fpdoc/makeskel.pp +=================================================================== +--- fpc.orig/fpcsrc/utils/fpdoc/makeskel.pp ++++ fpc/fpcsrc/utils/fpdoc/makeskel.pp +@@ -584,7 +584,7 @@ Function ParseCommandLine : Integer; + + Const + {$IFDEF Unix} +- MoFileTemplate = '/usr/local/share/locale/%s/LC_MESSAGES/makeskel.mo'; ++ MoFileTemplate = '/usr/share/locale/%s/LC_MESSAGES/makeskel-' + {$include %FPCVERSION%} + '.mo'; + {$ELSE} + MoFileTemplate ='intl/makeskel.%s.mo'; + {$ENDIF} +Index: fpc/fpcsrc/utils/fpdoc/unitdiff.pp +=================================================================== +--- fpc.orig/fpcsrc/utils/fpdoc/unitdiff.pp ++++ fpc/fpcsrc/utils/fpdoc/unitdiff.pp +@@ -169,7 +169,7 @@ procedure ParseCommandLine; + + Const + {$IFDEF Unix} +- MoFileTemplate = '/usr/local/share/locale/%s/LC_MESSAGES/makeskel.mo'; ++ MoFileTemplate = '/usr/share/locale/%s/LC_MESSAGES/makeskel-' + {$include %FPCVERSION%} + '.mo'; + {$ELSE} + MoFileTemplate ='intl/makeskel.%s.mo'; + {$ENDIF} diff --git a/patches/create-directory-before-copy-in-Makefile.fpc.patch b/patches/create-directory-before-copy-in-Makefile.fpc.patch new file mode 100644 index 00000000..acfe5830 --- /dev/null +++ b/patches/create-directory-before-copy-in-Makefile.fpc.patch @@ -0,0 +1,31 @@ +Description: Prevent FTBFS by creating directories when required +Author: Paul Gevers +Index: fpc/fpcdocs/Makefile.fpc +=================================================================== +--- fpc.orig/fpcdocs/Makefile.fpc ++++ fpc/fpcdocs/Makefile.fpc +@@ -927,6 +927,7 @@ endif # USEHEVEA + fcl.chk: $(FCLXML) fcl-project.xml + $(FPDOC) $(FPDOCOPTS) --project=fcl-project.xml --format=$(HTMLFMT) --output=fcl$(HTMLSUFFIX) $(FPDOCHTMLOPTS) $(FCLCHMOPTS) + ifndef CSSFILE ++ mkdir -p fcl + cp fpdoc.cst fcl/fpdoc.css + endif + @$(ECHO) '' > fcl.chk +@@ -934,6 +935,7 @@ endif + fclres.chk: $(FCLRESXML) + $(FPDOC) $(FPDOCOPTS) $(FCLRESOPTS) --format=$(HTMLFMT) --output=fclres$(HTMLSUFFIX) $(FPDOCHTMLOPTS) $(FCLRESCHMOPTS) + ifndef CSSFILE ++ mkdir -p fclres + cp fpdoc.cst fclres/fpdoc.css + endif + @$(ECHO) '' > fclres.chk +@@ -941,7 +943,8 @@ endif + rtl.chk: $(RTLXML) rtl-project.xml + $(FPDOC) $(FPDOCOPTS) --project=rtl-project.xml --format=$(HTMLFMT) --output=rtl$(HTMLSUFFIX) $(FPDOCHTMLOPTS) $(RTLCHMOPTS) + ifndef CSSFILE ++ mkdir -p rtl + cp fpdoc.cst rtl/fpdoc.css + endif + @$(ECHO) '' > rtl.chk + diff --git a/patches/disable_building_gnome1_and_gtk1.patch b/patches/disable_building_gnome1_and_gtk1.patch new file mode 100644 index 00000000..fd015f46 --- /dev/null +++ b/patches/disable_building_gnome1_and_gtk1.patch @@ -0,0 +1,114 @@ +Description: Disable the gnome1, gtk1, fpgtk and imlib packages to build + as they depend on libraries long go removed from Debian. +Author: Paul Gevers + +Index: fpc/fpcsrc/packages/fpmake_proc.inc +=================================================================== +--- fpc.orig/fpcsrc/packages/fpmake_proc.inc ++++ fpc/fpcsrc/packages/fpmake_proc.inc +@@ -194,12 +194,6 @@ begin + {$include fftw/fpmake.pp} + end; + +-procedure add_fpgtk(const ADirectory: string); +-begin +- with Installer do +-{$include fpgtk/fpmake.pp} +-end; +- + {$include fpindexer/fpmake.pp} + + procedure add_fpmkunit(const ADirectory: string); +@@ -236,24 +230,12 @@ begin + {$include gmp/fpmake.pp} + end; + +-procedure add_gnome1(const ADirectory: string); +-begin +- with Installer do +-{$include gnome1/fpmake.pp} +-end; +- + procedure add_graph(const ADirectory: string); + begin + with Installer do + {$include graph/fpmake.pp} + end; + +-procedure add_gtk1(const ADirectory: string); +-begin +- with Installer do +-{$include gtk1/fpmake.pp} +-end; +- + procedure add_gtk2(const ADirectory: string); + begin + with Installer do +@@ -314,12 +296,6 @@ begin + {$include imagemagick/fpmake.pp} + end; + +-procedure add_imlib(const ADirectory: string); +-begin +- with Installer do +-{$include imlib/fpmake.pp} +-end; +- + procedure add_iosxlocale(const ADirectory: string); + begin + with Installer do +Index: fpc/fpcsrc/packages/fpmake_add.inc +=================================================================== +--- fpc.orig/fpcsrc/packages/fpmake_add.inc ++++ fpc/fpcsrc/packages/fpmake_add.inc +@@ -32,7 +32,6 @@ + add_fcl_web(ADirectory+IncludeTrailingPathDelimiter('fcl-web')); + add_fcl_xml(ADirectory+IncludeTrailingPathDelimiter('fcl-xml')); + add_fftw(ADirectory+IncludeTrailingPathDelimiter('fftw')); +- add_fpgtk(ADirectory+IncludeTrailingPathDelimiter('fpgtk')); + add_fpindexer(ADirectory+IncludeTrailingPathDelimiter('fpindexer')); + add_fpmkunit(ADirectory+IncludeTrailingPathDelimiter('fpmkunit')); + add_fppkg(ADirectory+IncludeTrailingPathDelimiter('fppkg')); +@@ -41,9 +40,7 @@ + add_gdbm(ADirectory+IncludeTrailingPathDelimiter('gdbm')); + add_ggi(ADirectory+IncludeTrailingPathDelimiter('ggi')); + add_gmp(ADirectory+IncludeTrailingPathDelimiter('gmp')); +- add_gnome1(ADirectory+IncludeTrailingPathDelimiter('gnome1')); + add_graph(ADirectory+IncludeTrailingPathDelimiter('graph')); +- add_gtk1(ADirectory+IncludeTrailingPathDelimiter('gtk1')); + add_gtk2(ADirectory+IncludeTrailingPathDelimiter('gtk2')); + add_hash(ADirectory+IncludeTrailingPathDelimiter('hash')); + add_hermes(ADirectory+IncludeTrailingPathDelimiter('hermes')); +@@ -54,7 +51,6 @@ + add_ibase(ADirectory+IncludeTrailingPathDelimiter('ibase')); + add_iconvenc(ADirectory+IncludeTrailingPathDelimiter('iconvenc')); + add_imagemagick(ADirectory+IncludeTrailingPathDelimiter('imagemagick')); +- add_imlib(ADirectory+IncludeTrailingPathDelimiter('imlib')); + add_iosxlocale(ADirectory+IncludeTrailingPathDelimiter('iosxlocale')); + add_jni(ADirectory+IncludeTrailingPathDelimiter('jni')); + add_ldap(ADirectory+IncludeTrailingPathDelimiter('ldap')); +Index: fpc/fpcsrc/utils/fpmake_proc.inc +=================================================================== +--- fpc.orig/fpcsrc/utils/fpmake_proc.inc ++++ fpc/fpcsrc/utils/fpmake_proc.inc +@@ -10,8 +10,6 @@ + + {$include fpdoc/fpmake.pp} + +-{$include fpmc/fpmake.pp} +- + {$include fppkg/fpmake.pp} + + {$include fprcp/fpmake.pp} +Index: fpc/fpcsrc/utils/fpmake_add.inc +=================================================================== +--- fpc.orig/fpcsrc/utils/fpmake_add.inc ++++ fpc/fpcsrc/utils/fpmake_add.inc +@@ -4,7 +4,6 @@ + add_fpcres(ADirectory+IncludeTrailingPathDelimiter('fpcres')); + add_fpcreslipo(ADirectory+IncludeTrailingPathDelimiter('fpcreslipo')); + add_fpdoc(ADirectory+IncludeTrailingPathDelimiter('fpdoc')); +- add_fpmc(ADirectory+IncludeTrailingPathDelimiter('fpmc')); + add_fppkg_util(ADirectory+IncludeTrailingPathDelimiter('fppkg')); + add_fprcp(ADirectory+IncludeTrailingPathDelimiter('fprcp')); + add_h2pas(ADirectory+IncludeTrailingPathDelimiter('h2pas')); diff --git a/patches/drop-jsminifier-from-build-as-we-strip-it.patch b/patches/drop-jsminifier-from-build-as-we-strip-it.patch new file mode 100644 index 00000000..5255bcf2 --- /dev/null +++ b/patches/drop-jsminifier-from-build-as-we-strip-it.patch @@ -0,0 +1,17 @@ +Description: the jsminifier.pp is not dfsg free. Therefore we strip it during + repack but we must prevent during build as well. +Bug: https://bugs.freepascal.org/view.php?id=32288 +Author: Paul Gevers +Index: fpc/fpcsrc/packages/fcl-js/fpmake.pp +=================================================================== +--- fpc.orig/fpcsrc/packages/fcl-js/fpmake.pp ++++ fpc/fpcsrc/packages/fcl-js/fpmake.pp +@@ -39,8 +39,6 @@ begin + T.ResourceStrings:=true; + T:=P.Targets.AddUnit('jswriter.pp'); + T.ResourceStrings:=true; +- T:=P.Targets.AddUnit('jsminifier.pp'); +- T.ResourceStrings:=true; + {$ifndef ALLPACKAGES} + Run; + end; diff --git a/patches/fix-FPCDIR-in-fpcmake.diff b/patches/fix-FPCDIR-in-fpcmake.diff new file mode 100644 index 00000000..7d663dce --- /dev/null +++ b/patches/fix-FPCDIR-in-fpcmake.diff @@ -0,0 +1,71 @@ +This patch fixes evaluation of default value for FPCDIR. (Closes: bug#662814) + +Index: fpc/fpcsrc/utils/fpcm/fpcmmain.pp +=================================================================== +--- fpc.orig/fpcsrc/utils/fpcm/fpcmmain.pp ++++ fpc/fpcsrc/utils/fpcm/fpcmmain.pp +@@ -315,6 +315,46 @@ implementation + end; + + ++{$ifdef UNIX} ++{$ifndef NO_UNIX_UNIT} ++ function ReadLink(LinkName: ansistring; Depth: byte = 0): ansistring; ++ { ++ Read a link (where it points to) ++ @Param LinkName ++ @Param Depth ++ 0 means raw link value (could be relative path) ++ 1 means expanded full path and name to liked file ++ 2..255 follow links recursively up to Depth level ++ } ++ var ++ LinkedFileName: PChar; ++ i: cInt; ++ begin ++ GetMem(LinkedFileName, PATH_MAX + 1); ++ Result := ExpandFileName(LinkName); ++ repeat ++ i := fpReadLink(PChar(Result), LinkedFileName, PATH_MAX); ++ if i >= 0 then begin ++ LinkedFileName[i] := #0; ++ if Depth > 0 then begin ++ Result := ExpandFileName(FileSearch(LinkedFileName, PathSep + ExtractFileDir(Result))); ++ Dec(Depth); ++ end else begin ++ Result := LinkedFileName; ++ end; ++ end; ++ until (i <= 0) or (Depth <= 0); ++ if i < 0 then begin ++ if FpGetErrNo <> ESysEINVAL then begin ++ Result := ''; ++ end; ++ end; ++ FreeMem(LinkedFileName, PATH_MAX + 1); ++ end; ++{$endif UNIX} ++{$endif NO_UNIX_UNIT} ++ ++ + function posidx(const substr,s : string;idx:integer):integer; + var + i,j : integer; +@@ -1215,7 +1255,7 @@ implementation + end; + if FileExists('/usr/local/bin/ppc' + ppcSuffix[cpu]) then + begin +- s:=ExtractFilePath({$ifdef ver1_0}ReadLink{$else}fpReadlink{$endif}('/usr/local/bin/ppc' + ppcSuffix[cpu])); ++ s:=ExtractFilePath(ReadLink('/usr/local/bin/ppc' + ppcSuffix[cpu], 255)); + if s<>'' then + begin + if s[length(s)]='/' then +@@ -1227,7 +1267,7 @@ implementation + begin + if FileExists('/usr/bin/ppc' + ppcSuffix[cpu]) then + begin +- s:=ExtractFilePath({$ifdef ver1_0}ReadLink{$else}fpReadLink{$endif}('/usr/bin/ppc' + ppcSuffix[cpu])); ++ s:=ExtractFilePath(ReadLink('/usr/bin/ppc' + ppcSuffix[cpu], 255)); + if s<>'' then + begin + if s[length(s)]='/' then diff --git a/patches/fix-IDE-GDB-support.patch b/patches/fix-IDE-GDB-support.patch new file mode 100644 index 00000000..dc016154 --- /dev/null +++ b/patches/fix-IDE-GDB-support.patch @@ -0,0 +1,4339 @@ +From: Abou Al Montacir +Date: Sun, 07 Jan 2018 12:40:45 +0100 +Description: Fix IDE GDB support by importing MI supoort from upstream trunk. + (Closes: Bug##528855) + +diff --git a/fpcsrc/ide/Makefile.fpc b/fpcsrc/ide/Makefile.fpc +index 2be4d0d4..1bfdbb4f 100644 +--- a/fpcsrc/ide/Makefile.fpc ++++ b/fpcsrc/ide/Makefile.fpc +@@ -31,6 +31,8 @@ FPMAKE_BIN_CLEAN=$(wildcard ./fpmake$(SRCEXEEXT)) + LOCALFPMAKE=./fpmake$(SRCEXEEXT) + # do not add -d$(CPU_TARGET) + override NOCPUDEF=1 ++# This list should be the same as in fpcbuild/Makefile.fpc and in fpcsrc/Makefile.fpc ++GDBMI_DEFAULT_OS_LIST=aix darwin freebsd haiku linux netbsd openbsd solaris win32 win64 + + [rules] + # Do not pass the Makefile's unit and binary target locations. Fpmake uses it's own. +@@ -48,15 +50,37 @@ FPMAKE_OPT+=$(FPC_TARGETOPT) + FPMAKE_OPT+=$(addprefix -o ,$(FPCOPT)) + FPMAKE_OPT+=--compiler=$(FPC) + FPMAKE_OPT+=-bu +-ifndef BUILDFULLNATIVE +-FPMAKE_OPT+=-sp +-endif + ifdef NOGDB + FPMAKE_OPT+=--NoGDB=1 ++else ++ifndef NOGDBMI ++ifneq ($(findstring $(OS_TARGET),$(GDBMI_DEFAULT_OS_LIST)),) ++GDBMI=1 ++endif ++endif # NOGDBMI ++ ++ifdef GDBMI ++FPMAKE_OPT+=--GDBMI=1 ++# If the rtl does not require libc, then ++# IDE compiled with GDBMI should be a static executable ++# and can thus be cross-compiled ++ifeq ($(findstring $(OS_TARGET),aix beos darwin haiku solaris),) ++GDBMI_IS_STATIC=1 ++endif + endif ++endif # NOGDB ++ ++ifndef GDBMI_IS_STATIC ++ifndef BUILDFULLNATIVE ++# Omit executable is only required if generated executable is not static ++FPMAKE_OPT+=-scp ++endif ++endif # GDBMI_IS_STATIC ++ + ifdef PPC_TARGET + FPMAKE_OPT+=--CompilerTarget=$(PPC_TARGET) + endif ++ + .NOTPARALLEL: + + fpmake$(SRCEXEEXT): fpmake.pp +diff --git a/fpcsrc/ide/Makefile.fpc.fpcmake b/fpcsrc/ide/Makefile.fpc.fpcmake +index 01fba71b..3e331dec 100644 +--- a/fpcsrc/ide/Makefile.fpc.fpcmake ++++ b/fpcsrc/ide/Makefile.fpc.fpcmake +@@ -6,7 +6,7 @@ + + [package] + name=ide +-version=3.0.4 ++version=3.1.1 + + [target] + dirs=compiler +diff --git a/fpcsrc/ide/compiler/Makefile.fpc b/fpcsrc/ide/compiler/Makefile.fpc +index e0d0ded2..7985b2df 100644 +--- a/fpcsrc/ide/compiler/Makefile.fpc ++++ b/fpcsrc/ide/compiler/Makefile.fpc +@@ -5,6 +5,9 @@ + [package] + main=ide + ++[require] ++packages=rtl-extra ++ + [target] + units=compunit + +@@ -51,6 +54,9 @@ endif + ifeq ($(PPC_TARGET),x86_64) + override FPCOPT+= -Fu$(COMPILERDIR)/x86 -dNOOPT + endif ++ifeq ($(PPC_TARGET),i8086) ++override FPCOPT+= -Fu$(COMPILERDIR)/x86 ++endif + ifeq ($(PPC_TARGET),powerpc) + override FPCOPT+= -Fu$(COMPILERDIR)/ppcgen + endif +@@ -61,6 +67,14 @@ endif + ifeq ($(PPC_TARGET),mipsel) + override FPCOPT+= -Fu$(COMPILERDIR)/mips + endif ++# sparc specific ++ifeq ($(PPC_TARGET),sparc) ++override FPCOPT+= -Fu$(COMPILERDIR)/sparcgen -Fi$(COMPILERDIR)/sparcgen ++endif ++# sparc64 specific ++ifeq ($(PPC_TARGET),sparc64) ++override FPCOPT+= -Fu$(COMPILERDIR)/sparcgen -Fi$(COMPILERDIR)/sparcgen ++endif + + + [rules] +diff --git a/fpcsrc/ide/fp.pas b/fpcsrc/ide/fp.pas +index 005ff19f..36bc227b 100644 +--- a/fpcsrc/ide/fp.pas ++++ b/fpcsrc/ide/fp.pas +@@ -63,7 +63,11 @@ uses + Dos,Objects, + BrowCol,Version, + {$ifndef NODEBUG} +- gdbint, ++ {$ifdef GDBMI} ++ gdbmiint, ++ {$else GDBMI} ++ gdbint, ++ {$endif GDBMI} + {$endif NODEBUG} + FVConsts, + Drivers,Views,App,Dialogs,HistList, +@@ -79,6 +83,9 @@ uses + FPTools, + {$ifndef NODEBUG} + FPDebug,FPRegs, ++{$ifdef GDBMI} ++ gdbmiproc, ++{$endif GDBMI} + {$endif} + FPTemplt,FPRedir,FPDesk, + FPCodTmp,FPCodCmp, +@@ -196,6 +203,16 @@ begin + Delete(Param,1,1); { eat optional separator } + IniFileName:=Param; + end; ++{$ifdef GDBMI} ++ 'G' : { custom GDB exec file (GDBMI mode only) } ++ if BeforeINI then ++ begin ++ delete(param,1,1); // delete C ++ if (length(Param)>=1) and (Param[1] in['=',':']) then ++ Delete(Param,1,1); { eat optional separator } ++ GDBProgramName:=Param; ++ end; ++{$endif def GDBMI} + 'R' : { enter the directory last exited from (BP comp.) } + begin + Param:=copy(Param,2,255); +@@ -359,18 +376,26 @@ BEGIN + { Startup info } + writeln(bullet+' Free Pascal IDE Version '+VersionStr+' ['+{$i %date%}+']'); + writeln(bullet+' Compiler Version '+Full_Version_String); ++ ++ { Process params before printing GDB version because of /G option } ++ ProcessParams(true); ++ + {$ifndef NODEBUG} + writeln(bullet+' GDB Version '+GDBVersion); + {$ifdef Windows} + {$ifndef USE_MINGW_GDB} +- writeln(bullet+' Cygwin "',GetCygwinFullName,'" version ',GetCygwinVersionString); +- CheckCygwinVersion; ++ {$ifdef GDBMI} ++ { No reason to talk about cygwin DLL if we don't use it } ++ if using_cygwin_gdb then ++ {$endif GDBMI} ++ begin ++ writeln(bullet+' Cygwin "',GetCygwinFullName,'" version ',GetCygwinVersionString); ++ CheckCygwinVersion; ++ end; + {$endif} + {$endif Windows} + {$endif NODEBUG} + +- ProcessParams(true); +- + {$ifdef DEBUG} + StartTime:=getrealtime; + {$endif DEBUG} +diff --git a/fpcsrc/ide/fpcompil.pas b/fpcsrc/ide/fpcompil.pas +index 9a0bd7f8..54d0ffd1 100644 +--- a/fpcsrc/ide/fpcompil.pas ++++ b/fpcsrc/ide/fpcompil.pas +@@ -620,7 +620,7 @@ begin + else + begin + if Status.CurrentSource='' then +- StatusS:='' ++ StatusS:=' ' + else + begin + StatusS:=ShrinkPath(SmartPath(DirAndNameOf(Status.Currentsourcepath+Status.CurrentSource)), +diff --git a/fpcsrc/ide/fpconst.pas b/fpcsrc/ide/fpconst.pas +index 1d1f2235..07f9480f 100644 +--- a/fpcsrc/ide/fpconst.pas ++++ b/fpcsrc/ide/fpconst.pas +@@ -55,9 +55,11 @@ const + {$endif cpu68k} + {$endif i386} + {$ifdef SUPPORT_REMOTE} +- {$define USE_SPECIAL_BASENAME} +- { this uses PPC_TARGET env. variable from Makefile } +- FPBaseName = 'fp_'+{$i %PPC_TARGET%}; ++ {$ifndef USE_SPECIAL_BASENAME} ++ { this uses PPC_TARGET env. variable from Makefile } ++ FPBaseName = 'fp_'+{$i %PPC_TARGET%}; ++ {$define USE_SPECIAL_BASENAME} ++ {$endif ndef USE_SPECIAL_BASENAME} + {$endif SUPPORT_REMOTE} + {$endif not USE_FPBASENAME} + {$ifndef USE_SPECIAL_BASENAME} +diff --git a/fpcsrc/ide/fpdebug.pas b/fpcsrc/ide/fpdebug.pas +index 6222d449..64d93490 100644 +--- a/fpcsrc/ide/fpdebug.pas ++++ b/fpcsrc/ide/fpdebug.pas +@@ -26,7 +26,11 @@ uses + {$endif Windows} + Objects,Dialogs,Drivers,Views, + {$ifndef NODEBUG} +- GDBCon,GDBInt, ++ {$ifdef GDBMI} ++ GDBMICon,GDBMIInt, ++ {$else GDBMI} ++ GDBCon,GDBInt, ++ {$endif GDBMI} + {$endif NODEBUG} + Menus, + WViews,WEditor, +@@ -36,6 +40,9 @@ type + {$ifndef NODEBUG} + PDebugController=^TDebugController; + TDebugController=object(TGDBController) ++ private ++ function GetFPCBreakErrorParameters(var ExitCode: LongInt; var ExitAddr, ExitFrame: CORE_ADDR): Boolean; ++ public + InvalidSourceLine : boolean; + + { if true the current debugger raw will stay in middle of +@@ -50,8 +57,6 @@ type + NoSwitch : boolean; + HasExe : boolean; + RunCount : longint; +- WindowWidth : longint; +- TBreakNumber : longint; + FPCBreakErrorNumber : longint; + {$ifdef SUPPORT_REMOTE} + isRemoteDebugging, +@@ -61,11 +66,9 @@ type + {$endif SUPPORT_REMOTE} + constructor Init; + procedure SetExe(const exefn:string); +- procedure SetTBreak(tbreakstring : string); +- procedure SetWidth(AWidth : longint); + procedure SetSourceDirs; + destructor Done; +- procedure DoSelectSourceline(const fn:string;line:longint);virtual; ++ function DoSelectSourceline(const fn:string;line,BreakIndex:longint): Boolean;virtual; + { procedure DoStartSession;virtual; + procedure DoBreakSession;virtual;} + procedure DoEndSession(code:longint);virtual; +@@ -563,7 +566,11 @@ begin + {$ifdef Windows} + {$ifndef USE_MINGW_GDB} // see mantis 11968 because of mingw build. MvdV + { for Windows we should convert e:\ into //e/ PM } +- if (length(st)>2) and (st[2]=':') and (st[3]='/') then ++ if ++ {$ifdef GDBMI} ++ using_cygwin_gdb and ++ {$endif} ++ (length(st)>2) and (st[2]=':') and (st[3]='/') then + st:=CygDrivePrefix+'/'+st[1]+copy(st,3,length(st)); + {$endif} + { support spaces in the name by escaping them but without changing '\ ' into '\\ ' } +@@ -656,15 +663,14 @@ begin + NoSwitch:=False; + HasExe:=false; + Debugger:=@self; +- WindowWidth:=-1; + switch_to_user:=true; + GetDir(0,OrigPwd); +- Command('set print object off'); ++ SetCommand('print object off'); + {$ifdef SUPPORT_REMOTE} + isFirstRemote:=true; + {$ifdef FPC_ARMEL32} + { GDB needs advice on exact file type } +- Command('set gnutarget elf32-littlearm'); ++ SetCommand('gnutarget elf32-littlearm'); + {$endif FPC_ARMEL32} + {$endif SUPPORT_REMOTE} + end; +@@ -675,14 +681,19 @@ begin + f := GDBFileName(GetShortName(exefn)); + if (f<>'') and ExistsFile(exefn) then + begin +- LoadFile(f); ++ if not LoadFile(f) then ++ begin ++ HasExe:=false; ++ if GetError<>'' then ++ f:=GetError; ++ MessageBox(#3'Failed to load file '#13#3+f,nil,mfOKbutton); ++ exit; ++ end; + HasExe:=true; + { Procedure HandleErrorAddrFrame + (Errno : longint;addr,frame : longint); +- [public,alias:'FPC_BREAK_ERROR']; +- Command('b HANDLEERRORADDRFRAME'); } +- Command('b FPC_BREAK_ERROR'); +- FPCBreakErrorNumber:=last_breakpoint_number; ++ [public,alias:'FPC_BREAK_ERROR'];} ++ FPCBreakErrorNumber:=BreakpointInsert('FPC_BREAK_ERROR', []); + {$ifdef FrameNameKnown} + { this fails in GDB 5.1 because + GDB replies that there is an attempt to dereference +@@ -701,25 +712,23 @@ begin + begin + HasExe:=false; + reset_command:=true; ++{$ifdef GDBMI} ++ Command('-file-exec-and-symbols'); ++{$else GDBMI} + Command('file'); ++{$endif GDBMI} + reset_command:=false; + end; + end; + + +-procedure TDebugController.SetTBreak(tbreakstring : string); +-begin +- Command('tbreak '+tbreakstring); +- TBreakNumber:=Last_breakpoint_number; +-end; +- +-procedure TDebugController.SetWidth(AWidth : longint); +-begin +- WindowWidth:=AWidth; +- Command('set width '+inttostr(WindowWidth)); +-end; +- + procedure TDebugController.SetSourceDirs; ++ const ++{$ifdef GDBMI} ++ AddSourceDirCommand = '-environment-directory'; ++{$else GDBMI} ++ AddSourceDirCommand = 'dir'; ++{$endif GDBMI} + var f,s: ansistring; + i : longint; + Dir : SearchRec; +@@ -736,7 +745,7 @@ begin + end; + DefaultReplacements(s); + if (pos('*',s)=0) and ExistsDir(s) then +- Command('dir '+GDBFileName(GetShortName(s))) ++ Command(AddSourceDirCommand+' '+GDBFileName(GetShortName(s))) + { we should also handle the /* cases of -Fu option } + else if pos('*',s)>0 then + begin +@@ -746,7 +755,7 @@ begin + while Dos.DosError=0 do + begin + if ((Dir.attr and Directory) <> 0) and ExistsDir(s+Dir.Name) then +- Command('dir '+GDBFileName(GetShortName(s+Dir.Name))); ++ Command(AddSourceDirCommand+' '+GDBFileName(GetShortName(s+Dir.Name))); + Dos.FindNext(Dir); + end; + Dos.FindClose(Dir); +@@ -820,6 +829,12 @@ end; + + + procedure TDebugController.Run; ++const ++{$ifdef GDBMI} ++ SetTTYCommand = '-inferior-tty-set'; ++{$else GDBMI} ++ SetTTYCommand = 'tty'; ++{$endif GDBMI} + {$ifdef Unix} + var + Debuggeefile : text; +@@ -916,9 +931,9 @@ begin + {$ifdef Windows} + { Run the debugge in another console } + if DebuggeeTTY<>'' then +- Command('set new-console on') ++ SetCommand('new-console on') + else +- Command('set new-console off'); ++ SetCommand('new-console off'); + NoSwitch:=DebuggeeTTY<>''; + {$endif Windows} + {$ifdef Unix} +@@ -931,12 +946,12 @@ begin + ResetOK:=IOResult=0; + If ResetOK and (IsATTY(textrec(Debuggeefile).handle)<>-1) then + begin +- Command('tty '+DebuggeeTTY); ++ Command(SetTTYCommand+' '+DebuggeeTTY); + TTYUsed:=true; + end + else + begin +- Command('tty '); ++ Command(SetTTYCommand+' '); + TTYUsed:=false; + end; + if ResetOK then +@@ -949,7 +964,7 @@ begin + else + begin + if TTYName(input)<>'' then +- Command('tty '+TTYName(input)); ++ Command(SetTTYCommand+' '+TTYName(input)); + NoSwitch := false; + end; + {$endif Unix} +@@ -958,9 +973,6 @@ begin + {$endif SUPPORT_REMOTE} + { Switch to user screen to get correct handles } + UserScreen; +- { Don't try to print GDB messages while in User Screen mode } +- If assigned(GDBWindow) then +- GDBWindow^.Editor^.Lock; + {$ifdef SUPPORT_REMOTE} + if isRemoteDebugging then + begin +@@ -982,8 +994,6 @@ begin + SetDir(StartupDir); + end; + DebuggerScreen; +- If assigned(GDBWindow) then +- GDBWindow^.Editor^.UnLock; + IDEApp.SetCmdState([cmResetDebugger,cmUntilReturn],true); + IDEApp.UpdateRunMenu(true); + UpdateDebugViews; +@@ -1010,7 +1020,7 @@ end; + + procedure TDebugController.UntilReturn; + begin +- Command('finish'); ++ inherited UntilReturn; + UpdateDebugViews; + { We could try to get the return value ! + Not done yet } +@@ -1087,6 +1097,14 @@ begin + gdberrorbuf.reset; + end; + ++{$ifdef GDB_RAW_OUTPUT} ++ If StrLen(GetRaw)>0 then ++ begin ++ GDBWindow^.WriteOutputText(GetRaw); ++ if in_command=0 then ++ gdbrawbuf.reset; ++ end; ++{$endif GDB_RAW_OUTPUT} + If StrLen(GetOutput)>0 then + begin + GDBWindow^.WriteOutputText(GetOutput); +@@ -1107,6 +1125,10 @@ begin + { We should do something special for errors !! } + If StrLen(GetError)>0 then + GDBWindow^.WriteErrorText(GetError); ++{$ifdef GDB_RAW_OUTPUT} ++ If StrLen(GetRaw)>0 then ++ GDBWindow^.WriteOutputText(GetRaw); ++{$endif GDB_RAW_OUTPUT} + GDBWindow^.WriteOutputText(GetOutput); + GDBWindow^.Editor^.TextEnd; + end; +@@ -1192,41 +1214,8 @@ begin + end; + + function TDebugController.GetValue(Const expr : string) : pchar; +-var +- p,p2,p3 : pchar; +-begin +- if WindowWidth<>-1 then +- Command('set width 0xffffffff'); +- Command('p '+expr); +- p:=GetOutput; +- p3:=nil; +- if assigned(p) and (p[strlen(p)-1]=#10) then +- begin +- p3:=p+strlen(p)-1; +- p3^:=#0; +- end; +- if assigned(p) then +- p2:=strpos(p,'=') +- else +- p2:=nil; +- if assigned(p2) then +- p:=p2+1; +- while p^ in [' ',TAB] do +- inc(p); +- { get rid of type } +- if p^ = '(' then +- p:=strpos(p,')')+1; +- while p^ in [' ',TAB] do +- inc(p); +- if assigned(p) then +- GetValue:=StrNew(p) +- else +- GetValue:=StrNew(GetError); +- if assigned(p3) then +- p3^:=#10; +- got_error:=false; +- if WindowWidth<>-1 then +- Command('set width '+IntToStr(WindowWidth)); ++begin ++ GetValue:=StrNew(PChar(PrintCommand(expr))); + end; + + function TDebugController.GetFramePointer : CORE_ADDR; +@@ -1235,8 +1224,7 @@ var + p : longint; + begin + {$ifdef FrameNameKnown} +- Command('p /d '+FrameName); +- st:=strpas(GetOutput); ++ st:=PrintFormattedCommand(FrameName,pfdecimal); + p:=pos('=',st); + while (p0 then +@@ -1318,41 +1337,33 @@ begin + + if (BreakIndex=FPCBreakErrorNumber) then + begin +- { Procedure HandleErrorAddrFrame +- (Errno : longint;addr,frame : longint); +- [public,alias:'FPC_BREAK_ERROR']; } +-{$ifdef FrameNameKnown} +- ExitCode:=GetLongintAt(GetFramePointer+FirstArgOffset); +- ExitAddr:=GetPointerAt(GetFramePointer+SecondArgOffset); +- ExitFrame:=GetPointerAt(GetFramePointer+ThirdArgOffset); +- if (ExitCode=0) and (ExitAddr=0) then +- begin +- Desktop^.Unlock; +- Command('continue'); +- exit; +- end; +- { forget all old frames } +- clear_frames; +- { record new frames } +- Command('backtrace'); +- for i:=0 to frame_count-1 do +- begin +- with frames[i]^ do +- begin +- if ExitAddr=address then +- begin +- Command('f '+IntToStr(i)); +- if assigned(file_name) then +- begin +- s:=strpas(file_name); +- line:=line_number; +- stop_addr:=address; +- end; +- break; +- end; +- end; +- end; +-{$endif FrameNameKnown} ++ if GetFPCBreakErrorParameters(ExitCode, ExitAddr, ExitFrame) then ++ begin ++ Backtrace; ++ for i:=0 to frame_count-1 do ++ begin ++ with frames[i]^ do ++ begin ++ if ExitAddr=address then ++ begin ++ if SelectFrameCommand(i) and ++ assigned(file_name) then ++ begin ++ s:=strpas(file_name); ++ line:=line_number; ++ stop_addr:=address; ++ end; ++ break; ++ end; ++ end; ++ end; ++ end ++ else ++ begin ++ Desktop^.Unlock; ++ DoSelectSourceLine := False; ++ exit; ++ end; + end; + { Update Disassembly position } + if Assigned(DisassemblyWindow) then +@@ -1455,13 +1466,8 @@ begin + (PB^.typ<>bt_file_line) and (PB^.typ<>bt_function) and + (PB^.typ<>bt_address) then + begin +- Command('p '+GetStr(PB^.Name)); +- S:=GetPChar(GetOutput); ++ S:=PrintCommand(GetStr(PB^.Name)); + got_error:=false; +- If Pos('=',S)>0 then +- S:=Copy(S,Pos('=',S)+1,255); +- If S[Length(S)]=#10 then +- Delete(S,Length(S),1); + if Assigned(PB^.OldValue) then + DisposeStr(PB^.OldValue); + PB^.OldValue:=PB^.CurrentValue; +@@ -1480,6 +1486,7 @@ begin + #3+' value = '+GetStr(PB^.CurrentValue),nil); + end; + end; ++ DoSelectSourceLine := True; + end; + + procedure TDebugController.DoUserSignal; +@@ -1542,6 +1549,8 @@ begin + end; + ChangeDebuggeeWindowTitleTo(Stopped_State); + {$endif Windows} ++ If assigned(GDBWindow) then ++ GDBWindow^.Editor^.UnLock; + end; + + +@@ -1581,6 +1590,9 @@ begin + end; + ChangeDebuggeeWindowTitleTo(Running_State); + {$endif Windows} ++ { Don't try to print GDB messages while in User Screen mode } ++ If assigned(GDBWindow) then ++ GDBWindow^.Editor^.Lock; + end; + + {$endif NODEBUG} +@@ -1756,32 +1768,32 @@ procedure TBreakpoint.Insert; + var + p,p2 : pchar; + st : string; ++ bkpt_no: LongInt = 0; + begin + {$ifndef NODEBUG} + If not assigned(Debugger) then Exit; + Remove; +- Debugger^.last_breakpoint_number:=0; + if (GDBState=bs_deleted) and (state=bs_enabled) then + begin + if (typ=bt_file_line) and assigned(FileName) then +- Debugger^.Command('break '+GDBFileName(NameAndExtOf(GetStr(FileName)))+':'+IntToStr(Line)) ++ bkpt_no := Debugger^.BreakpointInsert(GDBFileName(NameAndExtOf(GetStr(FileName)))+':'+IntToStr(Line), []) + else if (typ=bt_function) and assigned(name) then +- Debugger^.Command('break '+name^) ++ bkpt_no := Debugger^.BreakpointInsert(name^, []) + else if (typ=bt_address) and assigned(name) then +- Debugger^.Command('break *0x'+name^) ++ bkpt_no := Debugger^.BreakpointInsert('*0x'+name^, []) + else if (typ=bt_watch) and assigned(name) then +- Debugger^.Command('watch '+name^) ++ bkpt_no := Debugger^.WatchpointInsert(name^, wtWrite) + else if (typ=bt_awatch) and assigned(name) then +- Debugger^.Command('awatch '+name^) ++ bkpt_no := Debugger^.WatchpointInsert(name^, wtReadWrite) + else if (typ=bt_rwatch) and assigned(name) then +- Debugger^.Command('rwatch '+name^); +- if Debugger^.last_breakpoint_number<>0 then ++ bkpt_no := Debugger^.WatchpointInsert(name^, wtRead); ++ if bkpt_no<>0 then + begin +- GDBIndex:=Debugger^.last_breakpoint_number; ++ GDBIndex:=bkpt_no; + GDBState:=bs_enabled; +- Debugger^.Command('cond '+IntToStr(GDBIndex)+' '+GetStr(Conditions)); ++ Debugger^.BreakpointCondition(GDBIndex, GetStr(Conditions)); + If IgnoreCount>0 then +- Debugger^.Command('ignore '+IntToStr(GDBIndex)+' '+IntToStr(IgnoreCount)); ++ Debugger^.BreakpointSetIgnoreCount(GDBIndex, IgnoreCount); + If Assigned(Commands) then + begin + {Commands are not handled yet } +@@ -1842,7 +1854,7 @@ begin + {$ifndef NODEBUG} + If not assigned(Debugger) then Exit; + if GDBIndex>0 then +- Debugger^.Command('delete '+IntToStr(GDBIndex)); ++ Debugger^.BreakpointDelete(GDBIndex); + GDBIndex:=0; + GDBState:=bs_deleted; + {$endif NODEBUG} +@@ -1853,7 +1865,7 @@ begin + {$ifndef NODEBUG} + If not assigned(Debugger) then Exit; + if GDBIndex>0 then +- Debugger^.Command('enable '+IntToStr(GDBIndex)) ++ Debugger^.BreakpointEnable(GDBIndex) + else + Insert; + GDBState:=bs_disabled; +@@ -1865,7 +1877,7 @@ begin + {$ifndef NODEBUG} + If not assigned(Debugger) then Exit; + if GDBIndex>0 then +- Debugger^.Command('disable '+IntToStr(GDBIndex)); ++ Debugger^.BreakpointDisable(GDBIndex); + GDBState:=bs_disabled; + {$endif NODEBUG} + end; +@@ -2844,27 +2856,16 @@ procedure TWatch.rename(s : string); + + procedure TWatch.Get_new_value; + {$ifndef NODEBUG} +- var p, q : pchar; +- i, j, curframe, startframe : longint; +- s,s2 : string; ++ var i, curframe, startframe : longint; ++ s,s2,orig_s_result : AnsiString; + loop_higher, found : boolean; +- last_removed : char; + +- function GetValue(var s : string) : boolean; ++ function GetValue(var s : AnsiString) : boolean; + begin +- Debugger^.command('p '+s); +- if not Debugger^.Error then +- begin +- s:=StrPas(Debugger^.GetOutput); +- GetValue:=true; +- end +- else +- begin +- s:=StrPas(Debugger^.GetError); +- GetValue:=false; +- { do not open a messagebox for such errors } +- Debugger^.got_error:=false; +- end; ++ s:=Debugger^.PrintCommand(s); ++ GetValue := not Debugger^.Error; ++ { do not open a messagebox for such errors } ++ Debugger^.got_error:=false; + end; + + begin +@@ -2892,6 +2893,7 @@ procedure TWatch.Get_new_value; + end; + end; + found:=GetValue(s); ++ orig_s_result:=s; + Debugger^.got_error:=false; + loop_higher:=not found; + if not found then +@@ -2914,16 +2916,12 @@ procedure TWatch.Get_new_value; + if not Debugger^.set_current_frame(curframe) then + loop_higher:=false; + {$ifdef FrameNameKnown} +- s2:='/x '+FrameName; ++ s2:=FrameName; + {$else not FrameNameKnown} +- s2:='/x $ebp'; ++ s2:='$ebp'; + {$endif FrameNameKnown} +- getValue(s2); +- j:=pos('=',s2); +- if j>0 then +- s2:=copy(s2,j+1,length(s2)); +- while s2[1] in [' ',TAB] do +- delete(s2,1,1); ++ if not getValue(s2) then ++ loop_higher:=false; + if pos(s2,s)>0 then + loop_higher :=false; + until not loop_higher; +@@ -2936,14 +2934,9 @@ procedure TWatch.Get_new_value; + loop_higher:=false; + end; + if found then +- p:=StrNew(Debugger^.GetOutput) ++ current_value:=StrNew(PChar('= ' + s)) + else +- begin +- { get a reasonable output at least } +- s:=GetStr(expr); +- GetValue(s); +- p:=StrNew(Debugger^.GetError); +- end; ++ current_value:=StrNew(PChar(orig_s_result)); + Debugger^.got_error:=false; + { We should try here to find the expr in parent + procedure if there are +@@ -2955,31 +2948,6 @@ procedure TWatch.Get_new_value; + if curframe<>startframe then + Debugger^.set_current_frame(startframe); + +- q:=nil; +- if assigned(p) and (p[0]='$') then +- q:=StrPos(p,'='); +- if not assigned(q) then +- q:=p; +- if assigned(q) then +- i:=strlen(q) +- else +- i:=0; +- if (i>0) and (q[i-1]=#10) then +- begin +- while (i>1) and ((q[i-2]=' ') or (q[i-2]=#9)) do +- dec(i); +- last_removed:=q[i-1]; +- q[i-1]:=#0; +- end +- else +- last_removed:=#0; +- if assigned(q) then +- current_value:=strnew(q) +- else +- current_value:=strnew(''); +- if last_removed<>#0 then +- q[i-1]:=last_removed; +- strdispose(p); + GDBRunCount:=Debugger^.RunCount; + end; + {$else NODEBUG} +@@ -3523,12 +3491,8 @@ end; + exit; + DeskTop^.Lock; + Clear; +- { forget all old frames } +- Debugger^.clear_frames; + +- if Debugger^.WindowWidth<>-1 then +- Debugger^.Command('set width 0xffffffff'); +- Debugger^.Command('backtrace'); ++ Debugger^.Backtrace; + { generate list } + { all is in tframeentry } + for i:=0 to Debugger^.frame_count-1 do +@@ -3539,7 +3503,7 @@ end; + AddItem(new(PMessageItem,init(0,GetPChar(function_name)+GetPChar(args), + AddModuleName(GetPChar(file_name)),line_number,1))) + else +- AddItem(new(PMessageItem,init(0,HexStr(address,8)+' '+GetPChar(function_name)+GetPChar(args), ++ AddItem(new(PMessageItem,init(0,HexStr(address,SizeOf(address)*2)+' '+GetPChar(function_name)+GetPChar(args), + AddModuleName(''),line_number,1))); + W:=SearchOnDesktop(GetPChar(file_name),false); + { First reset all Debugger rows } +@@ -3568,8 +3532,6 @@ end; + end; + if Assigned(list) and (List^.Count > 0) then + FocusItem(0); +- if Debugger^.WindowWidth<>-1 then +- Debugger^.Command('set width '+IntToStr(Debugger^.WindowWidth)); + DeskTop^.Unlock; + {$endif NODEBUG} + end; +@@ -3585,7 +3547,7 @@ end; + { select frame for watches } + If not assigned(Debugger) then + exit; +- Debugger^.Command('f '+IntToStr(Focused)); ++ Debugger^.SelectFrameCommand(Focused); + { for local vars } + Debugger^.RereadWatches; + {$endif NODEBUG} +@@ -3599,7 +3561,7 @@ end; + { select frame for watches } + If not assigned(Debugger) then + exit; +- Debugger^.Command('f '+IntToStr(Focused)); ++ Debugger^.SelectFrameCommand(Focused); + { for local vars } + Debugger^.RereadWatches; + {$endif} +diff --git a/fpcsrc/ide/fpdesk.pas b/fpcsrc/ide/fpdesk.pas +index 0ff9f243..957187c5 100644 +--- a/fpcsrc/ide/fpdesk.pas ++++ b/fpcsrc/ide/fpdesk.pas +@@ -356,7 +356,8 @@ end; + function DeskUseSyntaxHighlight(Editor: PFileEditor): boolean; + var b : boolean; + begin +- b:= (*(Editor^.IsFlagSet(efSyntaxHighlight)) and *) ((Editor^.FileName='') or MatchesFileList(NameAndExtOf(Editor^.FileName),HighlightExts)); ++ b:= (*(Editor^.IsFlagSet(efSyntaxHighlight)) and *) ((Editor^.FileName='') or ++ MatchesMaskList(NameAndExtOf(Editor^.FileName),HighlightExts)); + DeskUseSyntaxHighlight:=b; + end; + +@@ -368,10 +369,14 @@ var S: PMemoryStream; + Title: string; + XDataOfs: word; + XData: array[0..1024] of byte; ++ + procedure GetData(var B; Size: word); + begin +- Move(XData[XDataOfs],B,Size); +- Inc(XDataOfs,Size); ++ if Size>0 Then ++ Begin ++ Move(XData[XDataOfs],B,Size); ++ Inc(XDataOfs,Size); ++ End; + end; + procedure ProcessWindowInfo; + var W: PWindow; +@@ -381,6 +386,9 @@ var W: PWindow; + TP,TP2: TPoint; + L: longint; + R: TRect; ++ ZZ: byte; ++ Z: TRect; ++ Len : Byte; + begin + XDataOfs:=0; + Desktop^.Lock; +@@ -388,8 +396,9 @@ begin + case WI.HelpCtx of + hcSourceWindow : + begin +- GetData(St[0],1); +- GetData(St[1],ord(St[0])); ++ GetData(len,1); ++ SetLength(St,Len); ++ GetData(St[1],Len); + W:=ITryToOpenFile(@WI.Bounds,St,0,0,false,false,true); + if Assigned(W)=false then + begin +@@ -531,6 +540,29 @@ begin + end + else + W^.Hide; ++ ZZ:=0; ++ Desktop^.GetExtent(Z); ++ if R.A.Y>Z.B.Y-7 then ++ begin ++ R.A.Y:=Z.B.Y-7; ++ ZZ:=1; ++ end; ++ if R.A.X>Z.B.X-4 then ++ begin ++ R.A.X:=Z.B.X-4; ++ ZZ:=1; ++ end; ++ if R.A.Y<0 then ++ begin ++ R.A.Y:=0; ++ ZZ:=1; ++ end; ++ if R.A.X<0 then ++ begin ++ R.A.X:=0; ++ ZZ:=1; ++ end; ++ if ZZ<>0 then W^.MoveTo(R.A.X,R.A.Y); + W^.Number:=WI.WinNb; + Desktop^.Unlock; + end; +@@ -553,7 +585,7 @@ begin + S^.Read(WI,sizeof(WI)); + if S^.Status=stOK then + begin +- Title[0]:=chr(WI.TitleLen); ++ SetLength(Title,WI.TitleLen); + S^.Read(Title[1],WI.TitleLen); + if WI.ExtraDataSize>0 then + S^.Read(XData,WI.ExtraDataSize); +diff --git a/fpcsrc/ide/fpide.pas b/fpcsrc/ide/fpide.pas +index 2d89e5ec..b95c2305 100644 +--- a/fpcsrc/ide/fpide.pas ++++ b/fpcsrc/ide/fpide.pas +@@ -794,14 +794,14 @@ end; + + function IDEUseSyntaxHighlight(Editor: PFileEditor): boolean; + begin +- IDEUseSyntaxHighlight:=(Editor^.IsFlagSet(efSyntaxHighlight)) and ((Editor^.FileName='') or MatchesFileList(NameAndExtOf(Editor^.FileName),HighlightExts)); ++ IDEUseSyntaxHighlight:=(Editor^.IsFlagSet(efSyntaxHighlight)) and ((Editor^.FileName='') or MatchesMaskList(NameAndExtOf(Editor^.FileName),HighlightExts)); + end; + + function IDEUseTabsPattern(Editor: PFileEditor): boolean; + begin + { the commented code lead all new files + to become with TAB use enabled which is wrong in my opinion PM } +- IDEUseTabsPattern:={(Editor^.FileName='') or }MatchesFileList(NameAndExtOf(Editor^.FileName),TabsPattern); ++ IDEUseTabsPattern:={(Editor^.FileName='') or }MatchesMaskList(NameAndExtOf(Editor^.FileName),TabsPattern); + end; + + constructor TIDEApp.Init; +diff --git a/fpcsrc/ide/fpini.pas b/fpcsrc/ide/fpini.pas +index f9116835..cb5d740f 100644 +--- a/fpcsrc/ide/fpini.pas ++++ b/fpcsrc/ide/fpini.pas +@@ -431,7 +431,9 @@ begin + { First read the primary file, which can also set the parameters which can + be overruled with the parameter loading } + SetPrimaryFile(INIFile^.GetEntry(secCompile,iePrimaryFile,PrimaryFile)); ++{$ifndef GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE} + DebuggeeTTY := INIFile^.GetEntry(secRun,ieDebuggeeRedir,DebuggeeTTY); ++{$endif not GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE} + {$ifdef SUPPORT_REMOTE} + RemoteMachine :=INIFile^.GetEntry(secRun,ieRemoteMachine,RemoteMachine); + RemotePort :=INIFile^.GetEntry(secRun,ieRemotePort,RemotePort); +@@ -653,8 +655,10 @@ begin + INIFile^.SetEntry(secRun,ieRunDir,GetRunDir); + INIFile^.SetEntry(secRun,ieRunParameters,GetRunParameters); + INIFile^.SetEntry(secFiles,iePrinterDevice,GetPrinterDevice); ++{$ifndef GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE} + { If DebuggeeTTY<>'' then } + INIFile^.SetEntry(secRun,ieDebuggeeRedir,DebuggeeTTY); ++{$endif not GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE} + {$ifdef SUPPORT_REMOTE} + INIFile^.SetEntry(secRun,ieRemoteMachine,RemoteMachine); + INIFile^.SetEntry(secRun,ieRemotePort,RemotePort); +diff --git a/fpcsrc/ide/fpmake.pp b/fpcsrc/ide/fpmake.pp +index 60c437ea..63b31aa1 100644 +--- a/fpcsrc/ide/fpmake.pp ++++ b/fpcsrc/ide/fpmake.pp +@@ -9,6 +9,7 @@ uses + + const + NoGDBOption: boolean = false; ++ GDBMIOption: boolean = false; + + procedure ide_check_gdb_availability(Sender: TObject); + +@@ -75,7 +76,15 @@ begin + P := sender as TPackage; + with installer do + begin +- if not (NoGDBOption) then ++ if GDBMIOption then ++ begin ++ BuildEngine.log(vlCommand, 'Compiling IDE with GDB/MI debugger support, LibGDB is not needed'); ++ P.Options.Add('-dGDBMI'); ++ { AIX also requires -CTsmalltoc for gdbmi } ++ if Defaults.OS=aix then ++ P.Options.Add('-CTsmalltoc'); ++ end ++ else if not (NoGDBOption) then + begin + // Detection of GDB. + GDBLibDir := DetectLibGDBDir; +@@ -141,11 +150,15 @@ Var + begin + AddCustomFpmakeCommandlineOption('CompilerTarget','Target CPU for the IDE''s compiler'); + AddCustomFpmakeCommandlineOption('NoGDB','If value=1 or ''Y'', no GDB support'); ++ AddCustomFpmakeCommandlineOption('GDBMI','If value=1 or ''Y'', builds IDE with GDB/MI support (no need for LibGDB)'); + With Installer do + begin + s := GetCustomFpmakeCommandlineOptionValue('NoGDB'); + if (s='1') or (s='Y') then + NoGDBOption := true; ++ s := GetCustomFpmakeCommandlineOptionValue('GDBMI'); ++ if (s='1') or (s='Y') then ++ GDBMIOption := true; + s :=GetCustomFpmakeCommandlineOptionValue('CompilerTarget'); + if s <> '' then + CompilerTarget:=StringToCPU(s) +@@ -153,7 +166,7 @@ begin + CompilerTarget:=Defaults.CPU; + + P:=AddPackage('ide'); +- P.Version:='3.0.4'; ++ P.Version:='3.1.1'; + {$ifdef ALLPACKAGES} + P.Directory:=ADirectory; + {$endif ALLPACKAGES} +@@ -163,9 +176,12 @@ begin + P.Dependencies.Add('chm'); + { This one is only needed if DEBUG is set } + P.Dependencies.Add('regexpr'); +- if not (NoGDBOption) then ++ if not (NoGDBOption) and not (GDBMIOption) then + P.Dependencies.Add('gdbint',AllOSes-AllAmigaLikeOSes); ++ if GDBMIOption then ++ P.Dependencies.Add('fcl-process'); + P.Dependencies.Add('graph',[go32v2]); ++ P.Dependencies.Add('ami-extra',AllAmigaLikeOSes); + + P.SupportBuildModes:=[bmOneByOne]; + +@@ -182,15 +198,27 @@ begin + P.Options.Add('-Fi../compiler/'+CPUToString(CompilerTarget)); + P.Options.Add('-Fi../compiler'); + +- if CompilerTarget in [x86_64, i386] then ++ if CompilerTarget in [x86_64, i386, i8086] then + P.Options.Add('-Fu../compiler/x86'); + if CompilerTarget in [powerpc, powerpc64] then + P.Options.Add('-Fu../compiler/ppcgen'); ++ if CompilerTarget in [sparc] then ++ begin ++ P.Options.Add('-Fu../compiler/sparcgen'); ++ P.Options.add('-Fi../compiler/sparcgen'); ++ end; + if CompilerTarget = x86_64 then + P.Options.Add('-dNOOPT'); + if CompilerTarget = mipsel then + P.Options.Add('-Fu../compiler/mips'); + ++ { powerpc64-aix compiled IDE needs -CTsmalltoc option } ++ if (Defaults.OS=aix) and (Defaults.CPU=powerpc64) then ++ P.Options.Add('-CTsmalltoc'); ++ { Handle SPECIALLINK environment variable if available } ++ s:=GetEnvironmentVariable('SPECIALLINK'); ++ if s<>'' then ++ P.Options.Add(s); + P.Options.Add('-Sg'); + P.IncludePath.Add('compiler'); + +diff --git a/fpcsrc/ide/fpmopts.inc b/fpcsrc/ide/fpmopts.inc +index 0f7edefd..bf90ae9f 100644 +--- a/fpcsrc/ide/fpmopts.inc ++++ b/fpcsrc/ide/fpmopts.inc +@@ -547,6 +547,10 @@ begin + else + L:=0; + CB2^.SetData(L); ++{$ifdef GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE} ++ { EnableMask type is longint, avoid range check error here } ++ CB2^.EnableMask := CB2^.EnableMask and longint($7ffffffe); ++{$endif GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE} + R2.Move(0,-1); + Insert(New(PLabel, Init(R2,label_debugger_redirection, CB2))); + {$endif Windows} +diff --git a/fpcsrc/ide/fpregs.pas b/fpcsrc/ide/fpregs.pas +index b4fff2c4..b218eff3 100644 +--- a/fpcsrc/ide/fpregs.pas ++++ b/fpcsrc/ide/fpregs.pas +@@ -42,7 +42,15 @@ uses + cs,ds,es,ss,fs,gs : word; + eflags : dword; + {$endif cpui386} +-{$ifdef cpum68k} ++{$ifdef x86_64} ++{$define cpu_known} ++ rax,rbx,rcx,rdx,rsi,rdi,rbp,rsp, ++ r8,r9,r10,r11,r12,r13,r14,r15, ++ rip : qword; ++ cs,ds,es,ss,fs,gs : word; ++ eflags : dword; ++{$endif x86_64} ++{$ifdef cpuim68k} + {$define cpu_known} + d0,d1,d2,d3,d4,d5,d6,d7 : dword; + a0,a1,a2,a3,a4,a5,fp,sp : dword; +@@ -73,6 +81,7 @@ uses + InDraw : boolean; + GDBCount : longint; + first : boolean; ++ LastOK : boolean; + constructor Init(var Bounds: TRect); + procedure Draw;virtual; + destructor Done; virtual; +@@ -90,12 +99,12 @@ uses + + TFPURegs = record + {$ifndef test_generic_cpu} +-{$ifdef cpui386} ++{$if defined(i386) or defined(x86_64)} + st0,st1,st2,st3,st4,st5,st6,st7 :string; + ftag,fop,fctrl,fstat,fiseg,foseg : word; + fioff,fooff : cardinal; +-{$endif cpui386} +-{$ifdef cpum68k} ++{$endif cpui386 or x86_64} ++{$ifdef cpuim68k} + fp0,fp1,fp2,fp3,fp4,fp5,fp6,fp7 : string; + fpcontrol,fpstatus,fpiaddr : dword; + {$endif cpum68k} +@@ -120,6 +129,7 @@ uses + UseInfoFloat : boolean; + {$endif not cpu_known} + first : boolean; ++ LastOK : boolean; + constructor Init(var Bounds: TRect); + procedure Draw;virtual; + destructor Done; virtual; +@@ -157,11 +167,11 @@ uses + + TVectorRegs = record + {$ifndef test_generic_cpu} +-{$ifdef cpui386} ++{$if defined(i386) or defined(x86_64)} + xmm : array[0..7] of string; + mmx : array[0..7] of string; + mxcsr : string; +-{$endif cpui386} ++{$endif cpui386 or x86_64} + {$ifdef cpupowerpc} + m : array[0..31] of string; + {$endif cpupowerpc} +@@ -181,6 +191,7 @@ uses + UseInfoVector : boolean; + {$endif not cpu_known} + first : boolean; ++ LastOK : boolean; + constructor Init(var Bounds: TRect); + procedure Draw;virtual; + destructor Done; virtual; +@@ -212,7 +223,11 @@ implementation + uses + Strings, + {$ifndef NODEBUG} +- GDBCon,GDBInt, ++ {$ifdef GDBMI} ++ GDBMICon, GDBMIInt, ++ {$else GDBMI} ++ GDBCon,GDBInt, ++ {$endif GDBMI} + {$endif NODEBUG} + App,Menus, + WViews,WEditor, +@@ -265,6 +280,8 @@ const + dialog_registers = 'Register View'; + dialog_fpu = 'FPU View'; + dialog_vector = 'Vector Unit View'; ++ msg_registervaluesnotavailable = ''; ++ msg_registerwindowerror = ''; + + {**************************************************************************** + TRegistersView +@@ -275,23 +292,126 @@ const + var + p,po : pchar; + p1 : pchar; +- reg,value : string; + buffer : array[0..255] of char; +- v : dword; +- code : word; + i : byte; + + begin + GetIntRegs:=false; + {$ifndef NODEBUG} ++{$ifdef cpu_known} ++{$ifdef cpui386} ++ GetIntRegs := ++ Debugger^.GetIntRegister('eax', rs.eax) and ++ Debugger^.GetIntRegister('ebx', rs.ebx) and ++ Debugger^.GetIntRegister('ecx', rs.ecx) and ++ Debugger^.GetIntRegister('edx', rs.edx) and ++ Debugger^.GetIntRegister('esi', rs.esi) and ++ Debugger^.GetIntRegister('edi', rs.edi) and ++ Debugger^.GetIntRegister('ebp', rs.ebp) and ++ Debugger^.GetIntRegister('esp', rs.esp) and ++ Debugger^.GetIntRegister('eip', rs.eip) and ++ { under Windows flags are on a register named ps !! PM } ++ (Debugger^.GetIntRegister('eflags', rs.eflags) or Debugger^.GetIntRegister('ps', rs.eflags)) and ++ Debugger^.GetIntRegister('cs', rs.cs) and ++ Debugger^.GetIntRegister('ds', rs.ds) and ++ Debugger^.GetIntRegister('es', rs.es) and ++ Debugger^.GetIntRegister('fs', rs.fs) and ++ Debugger^.GetIntRegister('gs', rs.gs) and ++ Debugger^.GetIntRegister('ss', rs.ss); ++{$endif cpui386} ++{$ifdef x86_64} ++ GetIntRegs := ++ Debugger^.GetIntRegister('rax', rs.rax) and ++ Debugger^.GetIntRegister('rbx', rs.rbx) and ++ Debugger^.GetIntRegister('rcx', rs.rcx) and ++ Debugger^.GetIntRegister('rdx', rs.rdx) and ++ Debugger^.GetIntRegister('rsi', rs.rsi) and ++ Debugger^.GetIntRegister('rdi', rs.rdi) and ++ Debugger^.GetIntRegister('rbp', rs.rbp) and ++ Debugger^.GetIntRegister('rsp', rs.rsp) and ++ Debugger^.GetIntRegister('r8', rs.r8) and ++ Debugger^.GetIntRegister('r9', rs.r9) and ++ Debugger^.GetIntRegister('r10', rs.r10) and ++ Debugger^.GetIntRegister('r11', rs.r11) and ++ Debugger^.GetIntRegister('r12', rs.r12) and ++ Debugger^.GetIntRegister('r13', rs.r13) and ++ Debugger^.GetIntRegister('r14', rs.r14) and ++ Debugger^.GetIntRegister('r15', rs.r15) and ++ Debugger^.GetIntRegister('rip', rs.rip) and ++ { under Windows flags are on a register named ps !! PM } ++ (Debugger^.GetIntRegister('eflags', rs.eflags) or Debugger^.GetIntRegister('ps', rs.eflags)) and ++ Debugger^.GetIntRegister('cs', rs.cs) and ++ Debugger^.GetIntRegister('ds', rs.ds) and ++ Debugger^.GetIntRegister('es', rs.es) and ++ Debugger^.GetIntRegister('fs', rs.fs) and ++ Debugger^.GetIntRegister('gs', rs.gs) and ++ Debugger^.GetIntRegister('ss', rs.ss); ++{$endif x86_64} ++{$ifdef cpuim68k} ++ GetIntRegs := ++ Debugger^.GetIntRegister('d0', rs.d0) and ++ Debugger^.GetIntRegister('d1', rs.d1) and ++ Debugger^.GetIntRegister('d2', rs.d2) and ++ Debugger^.GetIntRegister('d3', rs.d3) and ++ Debugger^.GetIntRegister('d4', rs.d4) and ++ Debugger^.GetIntRegister('d5', rs.d5) and ++ Debugger^.GetIntRegister('d6', rs.d6) and ++ Debugger^.GetIntRegister('d7', rs.d7) and ++ Debugger^.GetIntRegister('a0', rs.a0) and ++ Debugger^.GetIntRegister('a1', rs.a1) and ++ Debugger^.GetIntRegister('a2', rs.a2) and ++ Debugger^.GetIntRegister('a3', rs.a3) and ++ Debugger^.GetIntRegister('a4', rs.a4) and ++ Debugger^.GetIntRegister('a5', rs.a5) and ++ Debugger^.GetIntRegister('fp', rs.fp) and ++ Debugger^.GetIntRegister('sp', rs.sp) and ++ Debugger^.GetIntRegister('ps', rs.ps) and ++ Debugger^.GetIntRegister('pc', rs.pc); ++{$endif cpum68k} ++{$ifdef cpupowerpc} ++ GetIntRegs := true; ++ for i:=0 to 31 do ++ GetIntRegs := GetIntRegs and Debugger^.GetIntRegister('r'+inttostr(i), rs.r[i]); ++ { other regs ++ pc,ps,cr,lr,ctr,xer : dword; } ++ GetIntRegs := GetIntRegs and ++ Debugger^.GetIntRegister('pc', rs.pc) and ++ Debugger^.GetIntRegister('ps', rs.ps) and ++ Debugger^.GetIntRegister('lr', rs.lr) and ++ Debugger^.GetIntRegister('ctr', rs.ctr) and ++ Debugger^.GetIntRegister('xer', rs.xer); ++{$endif cpupowerpc} ++{$ifdef cpusparc} ++ GetIntRegs := true; ++ for i:=0 to 7 do ++ GetIntRegs := GetIntRegs and Debugger^.GetIntRegister('o'+inttostr(i), rs.o[i]); ++ for i:=0 to 7 do ++ if i = 6 then ++ GetIntRegs := GetIntRegs and (Debugger^.GetIntRegister('i6', rs.i[6]) or Debugger^.GetIntRegister('fp', rs.i[6])) ++ else ++ GetIntRegs := GetIntRegs and Debugger^.GetIntRegister('i'+inttostr(i), rs.i[i]); ++ for i:=0 to 7 do ++ GetIntRegs := GetIntRegs and Debugger^.GetIntRegister('l'+inttostr(i), rs.l[i]); ++ for i:=0 to 7 do ++ GetIntRegs := GetIntRegs and Debugger^.GetIntRegister('g'+inttostr(i), rs.g[i]); ++ ++ GetIntRegs := GetIntRegs and ++ Debugger^.GetIntRegister('y', rs.y) and ++ Debugger^.GetIntRegister('psr', rs.psr) and ++ Debugger^.GetIntRegister('wim', rs.wim) and ++ Debugger^.GetIntRegister('tbs', rs.tbr) and ++ Debugger^.GetIntRegister('pc', rs.pc) and ++ Debugger^.GetIntRegister('npc', rs.npc) and ++ Debugger^.GetIntRegister('fsr', rs.fsr) and ++ Debugger^.GetIntRegister('csr', rs.csr); ++{$endif cpusparc} ++{$else cpu_known} + Debugger^.Command('info registers'); + if Debugger^.Error then + exit + else + begin +-{$ifndef cpu_known} + i:=0; +-{$endif not cpu_known} + po:=StrNew(Debugger^.GetOutput); + p:=po; + if assigned(p) then +@@ -300,7 +420,6 @@ const + p1:=strscan(p,' '); + while assigned(p1) do + begin +-{$ifndef cpu_known} + p1:=strscan(p,#10); + if assigned(p1) then + begin +@@ -309,162 +428,6 @@ const + if i',7); ++ WriteStr(1,0,msg_registervaluesnotavailable,7); + {$else NODEBUG} +- If not assigned(Debugger) then ++ If (not assigned(Debugger)) or (not Debugger^.IsRunning) then + begin +- WriteStr(1,0,'',7); ++ WriteStr(1,0,msg_registervaluesnotavailable,7); + exit; + end; + if InDraw then exit; +@@ -538,6 +510,7 @@ const + begin + OldReg:=NewReg; + OK:=GetIntRegs(rs); ++ LastOK:=OK; + NewReg:=rs; + { get inital values } + if first then +@@ -550,7 +523,7 @@ const + else + begin + rs:=NewReg; +- OK:=true; ++ OK:=LastOK; + end; + if OK then + begin +@@ -603,7 +576,71 @@ const + SetColor(rs.eflags and $400,OldReg.eflags and $400); + WriteStr(22,7,'d='+chr(byte((rs.eflags and $400)<>0)+48),color); + {$endif cpui386} +-{$ifdef cpum68k} ++{$ifdef x86_64} ++ SetColor(rs.rax,OldReg.rax); ++ WriteStr(1,0,'RAX '+HexStr(rs.rax,16),color); ++ SetColor(rs.rbx,OldReg.rbx); ++ WriteStr(1,1,'RBX '+HexStr(rs.rbx,16),color); ++ SetColor(rs.rcx,OldReg.rcx); ++ WriteStr(1,2,'RCX '+HexStr(rs.rcx,16),color); ++ SetColor(rs.rdx,OldReg.rdx); ++ WriteStr(1,3,'RDX '+HexStr(rs.rdx,16),color); ++ SetColor(rs.rsi,OldReg.rsi); ++ WriteStr(1,4,'RSI '+HexStr(rs.rsi,16),color); ++ SetColor(rs.rdi,OldReg.rdi); ++ WriteStr(1,5,'RDI '+HexStr(rs.rdi,16),color); ++ SetColor(rs.rbp,OldReg.rbp); ++ WriteStr(1,6,'RBP '+HexStr(rs.rbp,16),color); ++ SetColor(rs.rsp,OldReg.rsp); ++ WriteStr(1,7,'RSP '+HexStr(rs.rsp,16),color); ++ SetColor(rs.r8,OldReg.r8); ++ WriteStr(1,8,'R8 '+HexStr(rs.r8,16),color); ++ SetColor(rs.r9,OldReg.r9); ++ WriteStr(1,9,'R9 '+HexStr(rs.r9,16),color); ++ SetColor(rs.r10,OldReg.r10); ++ WriteStr(1,10,'R10 '+HexStr(rs.r10,16),color); ++ SetColor(rs.r11,OldReg.r11); ++ WriteStr(1,11,'R11 '+HexStr(rs.r11,16),color); ++ SetColor(rs.r12,OldReg.r12); ++ WriteStr(1,12,'R12 '+HexStr(rs.r12,16),color); ++ SetColor(rs.r13,OldReg.r13); ++ WriteStr(1,13,'R13 '+HexStr(rs.r13,16),color); ++ SetColor(rs.r14,OldReg.r14); ++ WriteStr(1,14,'R14 '+HexStr(rs.r14,16),color); ++ SetColor(rs.r15,OldReg.r15); ++ WriteStr(1,15,'R15 '+HexStr(rs.r15,16),color); ++ SetColor(rs.rip,OldReg.rip); ++ WriteStr(1,16,'RIP '+HexStr(rs.rip,16),color); ++ SetColor(rs.cs,OldReg.cs); ++ WriteStr(22,11,'CS '+HexStr(rs.cs,4),color); ++ SetColor(rs.ds,OldReg.ds); ++ WriteStr(22,12,'DS '+HexStr(rs.ds,4),color); ++ SetColor(rs.es,OldReg.es); ++ WriteStr(22,13,'ES '+HexStr(rs.es,4),color); ++ SetColor(rs.fs,OldReg.fs); ++ WriteStr(22,14,'FS '+HexStr(rs.fs,4),color); ++ SetColor(rs.gs,OldReg.gs); ++ WriteStr(22,15,'GS '+HexStr(rs.gs,4),color); ++ SetColor(rs.ss,OldReg.ss); ++ WriteStr(22,16,'SS '+HexStr(rs.ss,4),color); ++ SetColor(rs.eflags and $1,OldReg.eflags and $1); ++ WriteStr(24,0,'c='+chr(byte((rs.eflags and $1)<>0)+48),color); ++ SetColor(rs.eflags and $20,OldReg.eflags and $20); ++ WriteStr(24,1,'z='+chr(byte((rs.eflags and $20)<>0)+48),color); ++ SetColor(rs.eflags and $80,OldReg.eflags and $80); ++ WriteStr(24,2,'s='+chr(byte((rs.eflags and $80)<>0)+48),color); ++ SetColor(rs.eflags and $800,OldReg.eflags and $800); ++ WriteStr(24,3,'o='+chr(byte((rs.eflags and $800)<>0)+48),color); ++ SetColor(rs.eflags and $4,OldReg.eflags and $4); ++ WriteStr(24,4,'p='+chr(byte((rs.eflags and $4)<>0)+48),color); ++ SetColor(rs.eflags and $200,OldReg.eflags and $200); ++ WriteStr(24,5,'i='+chr(byte((rs.eflags and $200)<>0)+48),color); ++ SetColor(rs.eflags and $10,OldReg.eflags and $10); ++ WriteStr(24,6,'a='+chr(byte((rs.eflags and $10)<>0)+48),color); ++ SetColor(rs.eflags and $400,OldReg.eflags and $400); ++ WriteStr(24,7,'d='+chr(byte((rs.eflags and $400)<>0)+48),color); ++{$endif x86_64} ++{$ifdef cpuim68k} + SetColor(rs.d0,OldReg.d0); + WriteStr(1,0,'d0 '+HexStr(longint(rs.d0),8),color); + SetColor(rs.d1,OldReg.d1); +@@ -717,7 +754,7 @@ const + {$endif cpu_known} + end + else +- WriteStr(0,0,'',7); ++ WriteStr(0,0,msg_registerwindowerror,7); + InDraw:=false; + {$endif NODEBUG} + end; +@@ -743,13 +780,17 @@ const + R.A.X:=R.B.X-28; + R.B.Y:=R.A.Y+11; + {$endif cpui386} +-{$ifdef cpum68k} ++{$ifdef x86_64} ++ R.A.X:=R.B.X-32; ++ R.B.Y:=R.A.Y+19; ++{$endif x86_64} ++{$ifdef cpuim68k} + R.A.X:=R.B.X-28; + R.B.Y:=R.A.Y+11; + {$endif cpum68k} + {$ifdef cpupowerpc} +- R.A.X:=R.B.X-28; +- R.B.Y:=R.A.Y+22; ++ R.A.X:=R.B.X-30; ++ R.B.Y:=R.A.Y+21; + {$endif cpupowerpc} + {$ifdef cpusparc} + R.A.X:=R.B.X-30; +@@ -883,7 +924,7 @@ const + if v[i]=#9 then + v[i]:=' '; + val(v,res,err); +-{$ifdef cpui386} ++{$if defined(i386) or defined(x86_64)} + if reg='st0' then + rs.st0:=v + else if reg='st1' then +@@ -916,8 +957,8 @@ const + rs.fooff:=res + else if reg='fop' then + rs.fop:=res; +-{$endif cpui386} +-{$ifdef cpum68k} ++{$endif cpui386 or x86_64} ++{$ifdef cpuim68k} + if reg='fp0' then + rs.fp0:=v + else if reg='fp1' then +@@ -1021,11 +1062,11 @@ const + begin + inherited draw; + {$ifdef NODEBUG} +- WriteStr(1,0,'',7); ++ WriteStr(1,0,msg_registervaluesnotavailable,7); + {$else NODEBUG} +- If not assigned(Debugger) then ++ If (not assigned(Debugger)) or (not Debugger^.IsRunning) then + begin +- WriteStr(1,0,'',7); ++ WriteStr(1,0,msg_registervaluesnotavailable,7); + exit; + end; + if InDraw then +@@ -1039,6 +1080,7 @@ const + ,UseInfoFloat + {$endif not cpu_known} + ); ++ LastOK:=OK; + NewReg:=rs; + { get inital values } + if first then +@@ -1051,12 +1093,12 @@ const + else + begin + rs:=newreg; +- OK:=true; ++ OK:=LastOK; + end; + if OK then + begin + {$ifdef cpu_known} +-{$ifdef cpui386} ++{$if defined(i386) or defined(x86_64)} + top:=(rs.fstat shr 11) and 7; + SetColor(rs.st0,OldReg.st0); + WriteStr(1,0,'ST0 '+TypeStr[(rs.ftag shr (2*((0+top) and 7))) and 3]+rs.st0,color); +@@ -1094,8 +1136,8 @@ const + else + color:=7; + WriteStr(1,11,'FO '+hexstr(rs.foseg,4)+':'+hexstr(rs.fooff,8),color); +-{$endif cpui386} +-{$ifdef cpum68k} ++{$endif cpui386 or x86_64} ++{$ifdef cpuim68k} + SetColor(rs.fp0,OldReg.fp0); + WriteStr(1,0,'fp0 '+rs.fp0,color); + SetColor(rs.fp1,OldReg.fp1); +@@ -1148,7 +1190,7 @@ const + {$endif cpu_known} + end + else +- WriteStr(0,0,'',7); ++ WriteStr(0,0,msg_registerwindowerror,7); + InDraw:=false; + {$endif NODEBUG} + end; +@@ -1170,11 +1212,11 @@ const + + begin + Desktop^.GetExtent(R); +-{$ifdef cpui386} ++{$if defined(i386) or defined(x86_64)} + R.A.X:=R.B.X-44; + R.B.Y:=R.A.Y+14; +-{$endif cpui386} +-{$ifdef cpum68k} ++{$endif cpui386 or x86_64} ++{$ifdef cpuim68k} + R.A.X:=R.B.X-44; + R.B.Y:=R.A.Y+14; + {$endif cpum68k} +@@ -1194,7 +1236,7 @@ const + Flags:=wfClose or wfMove or wfgrow; + Palette:=wpCyanWindow; + HelpCtx:=hcFPURegisters; +- R.Assign(1,1,Size.X-2,Size.Y-2); ++ R.Assign(1,1,Size.X-2,Size.Y-1); + RV:=new(PFPUView,init(R)); + Insert(RV); + If assigned(FPUWindow) then +@@ -1312,7 +1354,7 @@ const + if v[i]=#9 then + v[i]:=' '; + val(v,res,err); +-{$ifdef cpui386} ++{$if defined(i386) or defined(x86_64)} + if reg[1]='x' then + for i:=0 to 7 do + begin +@@ -1327,7 +1369,7 @@ const + if reg='mm'+inttostr(i) then + rs.mmx[i]:=v; + end; +-{$endif cpui386} ++{$endif cpui386 or x86_64} + {$ifdef cpupowerpc} + { !!!! fixme } + if reg[1]='v' then +@@ -1405,11 +1447,11 @@ const + begin + inherited draw; + {$ifdef NODEBUG} +- WriteStr(1,0,'',7); ++ WriteStr(1,0,msg_registervaluesnotavailable,7); + {$else NODEBUG} +- If not assigned(Debugger) then ++ If (not assigned(Debugger)) or (not Debugger^.IsRunning) then + begin +- WriteStr(1,0,'',7); ++ WriteStr(1,0,msg_registervaluesnotavailable,7); + exit; + end; + if InDraw then +@@ -1423,6 +1465,7 @@ const + ,UseInfoVector + {$endif not cpu_known} + ); ++ LastOK:=OK; + NewReg:=rs; + { get inital values } + if first then +@@ -1435,12 +1478,12 @@ const + else + begin + rs:=newreg; +- OK:=true; ++ OK:=LastOK; + end; + if OK then + begin + {$ifdef cpu_known} +-{$ifdef cpui386} ++{$if defined(i386) or defined(x86_64)} + for i:=0 to 7 do + begin + SetColor(rs.xmm[i],OldReg.xmm[i]); +@@ -1455,7 +1498,7 @@ const + SetColor(rs.mmx[i],OldReg.mmx[i]); + WriteStr(1,i+9,'mmx'+IntToStr(i)+' '+rs.mmx[i],color); + end; +-{$endif cpui386} ++{$endif cpui386 or x86_64} + {$ifdef cpupowerpc} + for i:=0 to 31 do + begin +@@ -1478,7 +1521,7 @@ const + {$endif cpu_known} + end + else +- WriteStr(0,0,'',7); ++ WriteStr(0,0,msg_registerwindowerror,7); + InDraw:=false; + {$endif NODEBUG} + end; +@@ -1500,11 +1543,11 @@ const + + begin + Desktop^.GetExtent(R); +-{$ifdef cpui386} ++{$if defined(i386) or defined(x86_64)} + R.A.X:=R.B.X-60; + R.B.Y:=R.A.Y+20; +-{$endif cpui386} +-{$ifdef cpum68k} ++{$endif cpui386 or x86_64} ++{$ifdef cpuim68k} + R.A.X:=R.B.X-60; + R.B.Y:=R.A.Y+14; + {$endif cpum68k} +@@ -1524,7 +1567,7 @@ const + Flags:=wfClose or wfMove or wfgrow; + Palette:=wpCyanWindow; + HelpCtx:=hcVectorRegisters; +- R.Assign(1,1,Size.X-2,Size.Y-2); ++ R.Assign(1,1,Size.X-2,Size.Y-1); + RV:=new(PVectorView,init(R)); + Insert(RV); + If assigned(VectorWindow) then +diff --git a/fpcsrc/ide/fpusrscr.pas b/fpcsrc/ide/fpusrscr.pas +index 1dd6c1aa..03550950 100644 +--- a/fpcsrc/ide/fpusrscr.pas ++++ b/fpcsrc/ide/fpusrscr.pas +@@ -955,9 +955,10 @@ const + procedure UpdateFileHandles; + begin + {StdInputHandle:=longint(GetStdHandle(STD_INPUT_HANDLE));} +- StdOutputHandle:=longint(GetStdHandle(cardinal(STD_OUTPUT_HANDLE))); ++ StdOutputHandle:=THandle(GetStdHandle(cardinal(STD_OUTPUT_HANDLE))); + {StdErrorHandle:=longint(GetStdHandle(STD_ERROR_HANDLE));} + TextRec(Output).Handle:=StdOutputHandle; ++ VideoSetConsoleOutHandle(StdOutputHandle); + TextRec(StdOut).Handle:=StdOutputHandle; + {TextRec(StdErr).Handle:=StdErrorHandle;} + end; +diff --git a/fpcsrc/ide/fpvars.pas b/fpcsrc/ide/fpvars.pas +index 02ec192b..32a609aa 100644 +--- a/fpcsrc/ide/fpvars.pas ++++ b/fpcsrc/ide/fpvars.pas +@@ -145,7 +145,11 @@ const ClipboardWindow : PClipboardWindow = nil; + '"$REMOTEEXECCOMMAND" $DOITINBACKGROUND'; + {$endif SUPPORT_REMOTE} + ++{$ifdef GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE} ++ DebuggeeTTY : string = 'on'; ++{$else GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE} + DebuggeeTTY : string = ''; ++{$endif GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE} + + ActionCommands : array[acFirstAction..acLastAction] of word = + (cmHelpTopicSearch,cmGotoCursor,cmToggleBreakpoint, +diff --git a/fpcsrc/ide/fpviews.pas b/fpcsrc/ide/fpviews.pas +index 903f5bb3..4de85159 100644 +--- a/fpcsrc/ide/fpviews.pas ++++ b/fpcsrc/ide/fpviews.pas +@@ -26,6 +26,14 @@ uses + WEditor,WCEdit, + WUtils,WHelp,WHlpView,WViews,WANSI, + Comphook, ++{$ifndef NODEBUG} ++ { Needed here for CORE_ADDR definition } ++ {$ifdef GDBMI} ++ gdbmiint, ++ {$else GDBMI} ++ gdbint, ++ {$endif GDBMI} ++{$endif NODEBUG} + FPConst,FPUsrScr; + + type +@@ -224,7 +232,7 @@ type + + PDisasLine = ^TDisasLine; + TDisasLine = object(TLine) +- address : cardinal;{ should be target size of address for cross debuggers } ++ address : CORE_ADDR;{ should be target size of address for cross debuggers } + end; + + PDisasLineCollection = ^TDisasLineCollection; +@@ -241,13 +249,13 @@ type + procedure ReleaseSource; + destructor Done;virtual; + procedure AddSourceLine(const AFileName: string;line : longint); virtual; +- procedure AddAssemblyLine(const S: string;AAddress : cardinal); virtual; +- function GetCurrentLine(address : cardinal) : PDisasLine; ++ procedure AddAssemblyLine(const S: string;AAddress : CORE_ADDR); virtual; ++ function GetCurrentLine(address : CORE_ADDR) : PDisasLine; + private + Source : PSourceWindow; + OwnsSource : Boolean; + DisasLines : PDisasLineCollection; +- MinAddress,MaxAddress : cardinal; ++ MinAddress,MaxAddress : CORE_ADDR; + CurL : PDisasLine; + end; + +@@ -257,12 +265,12 @@ type + Indicator : PIndicator; + constructor Init(var Bounds: TRect); + procedure LoadFunction(Const FuncName : string); +- procedure LoadAddress(Addr : cardinal); ++ procedure LoadAddress(Addr : CORE_ADDR); + function ProcessPChar(p : pchar) : boolean; + procedure HandleEvent(var Event: TEvent); virtual; + procedure WriteSourceString(Const S : string;line : longint); +- procedure WriteDisassemblyString(Const S : string;address : cardinal); +- procedure SetCurAddress(address : cardinal); ++ procedure WriteDisassemblyString(Const S : string;address : CORE_ADDR); ++ procedure SetCurAddress(address : CORE_ADDR); + procedure UpdateCommands; virtual; + function GetPalette: PPalette;virtual; + destructor Done; virtual; +@@ -556,9 +564,6 @@ uses + {$ifdef USE_EXTERNAL_COMPILER} + fpintf, { superseeds version_string of version unit } + {$endif USE_EXTERNAL_COMPILER} +-{$ifndef NODEBUG} +- gdbint, +-{$endif NODEBUG} + {$ifdef VESA}Vesa,{$endif} + FPSwitch,FPSymbol,FPDebug,FPVars,FPUtils,FPCompil,FPHelp, + FPTools,FPIDE,FPCodTmp,FPCodCmp; +@@ -2490,8 +2495,10 @@ begin + Editor^.AddLine(''); + Insert(Editor); + {$ifndef NODEBUG} ++ {$ifndef GDBMI} + if assigned(Debugger) then +- Debugger^.SetWidth(Size.X-1); ++ Debugger^.SetCommand('width ' + IntToStr(Size.X-1)); ++ {$endif GDBMI} + {$endif NODEBUG} + Editor^.silent:=false; + Editor^.AutoRepeat:=true; +@@ -2575,7 +2582,10 @@ begin + While assigned(p) and (p^<>#0) do + begin + pe:=strscan(p,#10); +- if pe<>nil then ++ { if pe-p is more than High(s), discard for this round } ++ if (pe<>nil) and (pe-p > high(s)) then ++ pe:=nil; ++ if (pe<>nil) then + pe^:=#0; + s:=strpas(p); + If IsError then +@@ -2586,16 +2596,16 @@ begin + if pe<>nil then + pe^:=#10; + if pe=nil then +- p:=nil +- else + begin +- if pe-p > High(s) then +- p:=p+High(s)-1 ++ if strlen(p)0 then +- inherited AddLine('$'+hexstr(AAddress,sizeof(PtrUInt)*2)+S) ++ inherited AddLine('$'+hexstr(AAddress,sizeof(CORE_ADDR)*2)+S) + else + inherited AddLine(S); + PL:=DisasLines^.At(DisasLines^.count-1); +@@ -2703,7 +2713,7 @@ begin + MaxAddress:=AAddress; + end; + +-function TDisassemblyEditor.GetCurrentLine(address : cardinal) : PDisasLine; ++function TDisassemblyEditor.GetCurrentLine(address : CORE_ADDR) : PDisasLine; + + function IsCorrectLine(PL : PDisasLine) : boolean; + begin +@@ -2757,9 +2767,9 @@ var + begin + {$ifndef NODEBUG} + If not assigned(Debugger) then Exit; +- Debugger^.Command('set print sym on'); +- Debugger^.Command('set width 0xffffffff'); +- Debugger^.Command('disas '+FuncName); ++ Debugger^.SetCommand('print symbol on'); ++ Debugger^.SetCommand('width 0xffffffff'); ++ Debugger^.Command('disas /m '+FuncName); + p:=StrNew(Debugger^.GetOutput); + ProcessPChar(p); + if (Debugger^.IsRunning) and (FuncName='') then +@@ -2767,15 +2777,15 @@ begin + {$endif NODEBUG} + end; + +-procedure TDisassemblyWindow.LoadAddress(Addr : cardinal); ++procedure TDisassemblyWindow.LoadAddress(Addr : CORE_ADDR); + var + p : pchar; + begin + {$ifndef NODEBUG} + If not assigned(Debugger) then Exit; +- Debugger^.Command('set print sym on'); +- Debugger^.Command('set width 0xffffffff'); +- Debugger^.Command('disas 0x'+HexStr(Addr,8)); ++ Debugger^.SetCommand('print symbol on'); ++ Debugger^.SetCommand('width 0xffffffff'); ++ Debugger^.Command('disas /m 0x'+HexStr(Addr,sizeof(Addr)*2)); + p:=StrNew(Debugger^.GetOutput); + ProcessPChar(p); + if Debugger^.IsRunning and +@@ -2791,7 +2801,7 @@ var + p1: pchar; + pline : pchar; + pos1, pos2, CurLine, PrevLine : longint; +- CurAddr : cardinal; ++ CurAddr : CORE_ADDR; + err : word; + curaddress, cursymofs, CurFile, + PrevFile, line : string; +@@ -2812,7 +2822,7 @@ begin + pline:=strscan(p,#10); + if assigned(pline) then + pline^:=#0; +- line:=strpas(p); ++ line:=trim(strpas(p)); + CurAddr:=0; + if assigned(pline) then + begin +@@ -2822,11 +2832,17 @@ begin + else + p:=nil; + { now process the line } ++ { Remove current position marker } ++ if copy(line,1,3)='=> ' then ++ begin ++ system.delete(line,1,3); ++ end; ++ + { line is hexaddr assembly } + pos1:=pos('<',line); + if pos1>0 then + begin +- curaddress:=copy(line,1,pos1-1); ++ curaddress:=trim(copy(line,1,pos1-1)); + if copy(curaddress,1,2)='0x' then + curaddress:='$'+copy(curaddress,3,length(curaddress)-2); + val(curaddress,CurAddr,err); +@@ -2883,12 +2899,12 @@ begin + Editor^.AddSourceLine(S,line); + end; + +-procedure TDisassemblyWindow.WriteDisassemblyString(Const S : string;address : cardinal); ++procedure TDisassemblyWindow.WriteDisassemblyString(Const S : string;address : CORE_ADDR); + begin + Editor^.AddAssemblyLine(S,address); + end; + +-procedure TDisassemblyWindow.SetCurAddress(address : cardinal); ++procedure TDisassemblyWindow.SetCurAddress(address : CORE_ADDR); + begin + if (addressEditor^.MaxAddress) then + LoadAddress(address); +@@ -4229,7 +4245,7 @@ end; + constructor TFPAboutDialog.Init; + var R,R2: TRect; + C: PUnsortedStringCollection; +- I: integer; ++ I,nblines: integer; + OSStr: string; + procedure AddLine(S: string); + begin +@@ -4256,13 +4272,28 @@ begin + if pos('Fake',GDBVersion)=0 then + begin + R2.Move(0,1); ++ nblines:=1; ++ for i:=1 to length(GDBVersion) do ++ if GDBVersion[i]=#13 then ++ inc(nblines); ++ R2.B.Y:=R2.A.Y+nblines; ++ if nblines>1 then ++ GrowTo(Size.X,Size.Y+nblines-1); ++ {$ifdef GDBMI} ++ if GDBVersionOK then ++ Insert(New(PStaticText, Init(R2, FormatStrStr2(^C'(%s %s, using MI interface)',label_about_debugger,GDBVersion)))) ++ else ++ Insert(New(PStaticText, Init(R2, FormatStrStr(^C'%s',GDBVersion)))); ++ {$else} + Insert(New(PStaticText, Init(R2, FormatStrStr2(^C'(%s %s)',label_about_debugger,GDBVersion)))); +- R2.Move(0,1); ++ {$endif} ++ R2.Move(0,nblines); ++ R2.B.Y:=R2.A.Y+1; + end + else + {$endif NODEBUG} + R2.Move(0,2); +- Insert(New(PStaticText, Init(R2, ^C'Copyright (C) 1998-2016 by'))); ++ Insert(New(PStaticText, Init(R2, ^C'Copyright (C) 1998-2017 by'))); + R2.Move(0,2); + Insert(New(PStaticText, Init(R2, ^C'B‚rczi G bor'))); + R2.Move(0,1); +@@ -4291,6 +4322,9 @@ begin + AddLine(^C'Peter Vreman'); + AddLine(^C'Pierre Muller'); + AddLine(''); ++ AddLine(^C'< GDBMI development >'); ++ AddLine(^C'Nikolay Nikolov'); ++ AddLine(''); + + GetExtent(R); + R.Grow(-1,-1); Inc(R.A.Y,3); +@@ -4386,7 +4420,7 @@ begin + Message(W,evCommand,cmAddChar,pointer(ptrint(ord(Report^.AsciiChar)))); + ClearEvent(Event); + end; +- ++ + cmSearchWindow+1..cmSearchWindow+99 : + if (Event.Command-cmSearchWindow=Number) then + ClearEvent(Event); +diff --git a/fpcsrc/ide/gdbmicon.pas b/fpcsrc/ide/gdbmicon.pas +new file mode 100644 +index 00000000..c190894f +--- /dev/null ++++ b/fpcsrc/ide/gdbmicon.pas +@@ -0,0 +1,545 @@ ++{ ++ Copyright (c) 2015 by Nikolay Nikolov ++ Copyright (c) 1998 by Peter Vreman ++ ++ This is a replacement for GDBCon, implemented on top of GDB/MI, ++ instead of LibGDB. This allows integration of GDB/MI support in the ++ text mode IDE. ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ ++unit gdbmicon; ++ ++{$MODE fpc}{$H-} ++ ++{$I globdir.inc} ++ ++interface ++ ++uses ++ gdbmiint, gdbmiwrap; ++ ++type ++ TBreakpointFlags = set of (bfTemporary, bfHardware); ++ TWatchpointType = (wtWrite, wtReadWrite, wtRead); ++ TPrintFormatType = (pfbinary, pfdecimal, pfhexadecimal, pfoctal, pfnatural); ++ ++ TGDBController = object(TGDBInterface) ++ private ++ FRegisterNames: array of AnsiString; ++ procedure UpdateRegisterNames; ++ function GetGdbRegisterNo(const RegName: string): LongInt; ++ function GetRegisterAsString(const RegName, Format: string; var Value: string): Boolean; ++ procedure RunExecCommand(const Cmd: string); ++ protected ++ TBreakNumber, ++ start_break_number: LongInt; ++ in_command: LongInt; ++ ++ procedure CommandBegin(const s: string); virtual; ++ procedure CommandEnd(const s: string); virtual; ++ ++ public ++ constructor Init; ++ destructor Done; ++ ++ procedure Command(const s: string); ++ procedure Reset; virtual; ++ { tracing } ++ procedure StartTrace; ++ procedure Run; virtual; ++ procedure TraceStep; ++ procedure TraceNext; ++ procedure TraceStepI; ++ procedure TraceNextI; ++ procedure Continue; virtual; ++ procedure UntilReturn; virtual; ++ { registers } ++ function GetIntRegister(const RegName: string; var Value: UInt64): Boolean; ++ function GetIntRegister(const RegName: string; var Value: Int64): Boolean; ++ function GetIntRegister(const RegName: string; var Value: UInt32): Boolean; ++ function GetIntRegister(const RegName: string; var Value: Int32): Boolean; ++ function GetIntRegister(const RegName: string; var Value: UInt16): Boolean; ++ function GetIntRegister(const RegName: string; var Value: Int16): Boolean; ++ { set command } ++ function SetCommand(Const SetExpr : string) : boolean; ++ { print } ++ function PrintCommand(const expr : string): AnsiString; ++ function PrintFormattedCommand(const expr : string; Format : TPrintFormatType): AnsiString; ++ { breakpoints } ++ function BreakpointInsert(const location: string; BreakpointFlags: TBreakpointFlags): LongInt; ++ function WatchpointInsert(const location: string; WatchpointType: TWatchpointType): LongInt; ++ function BreakpointDelete(BkptNo: LongInt): Boolean; ++ function BreakpointEnable(BkptNo: LongInt): Boolean; ++ function BreakpointDisable(BkptNo: LongInt): Boolean; ++ function BreakpointCondition(BkptNo: LongInt; const ConditionExpr: string): Boolean; ++ function BreakpointSetIgnoreCount(BkptNo: LongInt; const IgnoreCount: LongInt): Boolean; ++ procedure SetTBreak(tbreakstring : string); ++ { frame commands } ++ procedure Backtrace; ++ function SelectFrameCommand(level :longint) : boolean; ++ function LoadFile(var fn: string): Boolean; ++ procedure SetDir(const s: string); ++ procedure SetArgs(const s: string); ++ end; ++ ++implementation ++ ++uses ++{$ifdef Windows} ++ Windebug, ++{$endif Windows} ++ strings; ++ ++procedure UnixDir(var s : string); ++var i : longint; ++begin ++ for i:=1 to length(s) do ++ if s[i]='\' then ++{$ifdef windows} ++ { Don't touch at '\ ' used to escapes spaces in windows file names PM } ++ if (i=length(s)) or (s[i+1]<>' ') then ++{$endif windows} ++ s[i]:='/'; ++{$ifdef windows} ++ { if we are using cygwin, we need to convert e:\ into /cygdriveprefix/e/ PM } ++ if using_cygwin_gdb and (length(s)>2) and (s[2]=':') and (s[3]='/') then ++ s:=CygDrivePrefix+'/'+s[1]+copy(s,3,length(s)); ++{$endif windows} ++end; ++ ++constructor TGDBController.Init; ++begin ++ inherited Init; ++end; ++ ++destructor TGDBController.Done; ++begin ++ inherited Done; ++end; ++ ++procedure TGDBController.CommandBegin(const s: string); ++begin ++end; ++ ++procedure TGDBController.Command(const s: string); ++begin ++ Inc(in_command); ++ CommandBegin(s); ++ GDBOutputBuf.Reset; ++ GDBErrorBuf.Reset; ++{$ifdef GDB_RAW_OUTPUT} ++ GDBRawBuf.reset; ++{$endif GDB_RAW_OUTPUT} ++ i_gdb_command(s); ++ CommandEnd(s); ++ Dec(in_command); ++end; ++ ++procedure TGDBController.CommandEnd(const s: string); ++begin ++end; ++ ++procedure TGDBController.UpdateRegisterNames; ++var ++ I: LongInt; ++ ResultList: TGDBMI_ListValue; ++begin ++ SetLength(FRegisterNames, 0); ++ Command('-data-list-register-names'); ++ if not GDB.ResultRecord.Success then ++ exit; ++ ResultList := GDB.ResultRecord.Parameters['register-names'].AsList; ++ SetLength(FRegisterNames, ResultList.Count); ++ for I := 0 to ResultList.Count - 1 do ++ FRegisterNames[I] := ResultList.ValueAt[I].AsString; ++end; ++ ++function TGDBController.GetGdbRegisterNo(const RegName: string): LongInt; ++var ++ I: LongInt; ++begin ++ for I := Low(FRegisterNames) to High(FRegisterNames) do ++ if FRegisterNames[I] = RegName then ++ begin ++ GetGdbRegisterNo := I; ++ exit; ++ end; ++ GetGdbRegisterNo := -1; ++end; ++ ++procedure TGDBController.Reset; ++begin ++end; ++ ++procedure TGDBController.StartTrace; ++begin ++ Command('-break-insert -t PASCALMAIN'); ++ if not GDB.ResultRecord.Success then ++ exit; ++ start_break_number := GDB.ResultRecord.Parameters['bkpt'].AsTuple['number'].AsLongInt; ++ Run; ++end; ++ ++procedure TGDBController.RunExecCommand(const Cmd: string); ++begin ++ UserScreen; ++ Command(Cmd); ++ if not GDB.ResultRecord.Success then ++ begin ++ DebuggerScreen; ++ got_error := True; ++ exit; ++ end; ++ WaitForProgramStop; ++end; ++ ++procedure TGDBController.Run; ++begin ++ RunExecCommand('-exec-run'); ++end; ++ ++procedure TGDBController.TraceStep; ++begin ++ RunExecCommand('-exec-step'); ++end; ++ ++procedure TGDBController.TraceNext; ++begin ++ RunExecCommand('-exec-next'); ++end; ++ ++procedure TGDBController.TraceStepI; ++begin ++ RunExecCommand('-exec-step-instruction'); ++end; ++ ++procedure TGDBController.TraceNextI; ++begin ++ RunExecCommand('-exec-next-instruction'); ++end; ++ ++procedure TGDBController.Continue; ++begin ++ RunExecCommand('-exec-continue'); ++end; ++ ++procedure TGDBController.UntilReturn; ++begin ++ RunExecCommand('-exec-finish'); ++end; ++ ++function TGDBController.GetRegisterAsString(const RegName, Format: string; var Value: string): Boolean; ++var ++ RegNo: LongInt; ++ RegNoStr: string; ++begin ++ GetRegisterAsString := False; ++ Value := ''; ++ ++ RegNo := GetGdbRegisterNo(RegName); ++ if RegNo = -1 then ++ exit; ++ Str(RegNo, RegNoStr); ++ Command('-data-list-register-values ' + Format + ' ' + RegNoStr); ++ if not GDB.ResultRecord.Success then ++ exit; ++ Value := GDB.ResultRecord.Parameters['register-values'].AsList.ValueAt[0].AsTuple['value'].AsString; ++ GetRegisterAsString := True; ++end; ++ ++function TGDBController.GetIntRegister(const RegName: string; var Value: UInt64): Boolean; ++var ++ RegValueStr: string; ++ Code: LongInt; ++begin ++ GetIntRegister := False; ++ Value := 0; ++ if not GetRegisterAsString(RegName, 'x', RegValueStr) then ++ exit; ++ Val(RegValueStr, Value, Code); ++ if Code <> 0 then ++ exit; ++ GetIntRegister := True; ++end; ++ ++function TGDBController.GetIntRegister(const RegName: string; var Value: Int64): Boolean; ++var ++ U64Value: UInt64; ++begin ++ GetIntRegister := GetIntRegister(RegName, U64Value); ++ Value := Int64(U64Value); ++end; ++ ++function TGDBController.GetIntRegister(const RegName: string; var Value: UInt32): Boolean; ++var ++ U64Value: UInt64; ++begin ++ GetIntRegister := GetIntRegister(RegName, U64Value); ++ Value := UInt32(U64Value); ++ if (U64Value shr 32) <> 0 then ++ GetIntRegister := False; ++end; ++ ++function TGDBController.GetIntRegister(const RegName: string; var Value: Int32): Boolean; ++var ++ U32Value: UInt32; ++begin ++ GetIntRegister := GetIntRegister(RegName, U32Value); ++ Value := Int32(U32Value); ++end; ++ ++function TGDBController.GetIntRegister(const RegName: string; var Value: UInt16): Boolean; ++var ++ U64Value: UInt64; ++begin ++ GetIntRegister := GetIntRegister(RegName, U64Value); ++ Value := UInt16(U64Value); ++ if (U64Value shr 16) <> 0 then ++ GetIntRegister := False; ++end; ++ ++function TGDBController.GetIntRegister(const RegName: string; var Value: Int16): Boolean; ++var ++ U16Value: UInt16; ++begin ++ GetIntRegister := GetIntRegister(RegName, U16Value); ++ Value := Int16(U16Value); ++end; ++ ++ ++{ set command } ++function TGDBController.SetCommand(Const SetExpr : string) : boolean; ++begin ++ SetCommand:=false; ++ Command('-gdb-set '+SetExpr); ++ if error then ++ exit; ++ SetCommand:=true; ++end; ++ ++ ++{ print } ++function TGDBController.PrintCommand(const expr : string): AnsiString; ++begin ++ Command('-data-evaluate-expression '+QuoteString(expr)); ++ if GDB.ResultRecord.Success then ++ PrintCommand:=GDB.ResultRecord.Parameters['value'].AsString ++ else ++ PrintCommand:=AnsiString(GetError); ++end; ++ ++const ++ PrintFormatName : Array[TPrintFormatType] of string[11] = ++ ('binary', 'decimal', 'hexadecimal', 'octal', 'natural'); ++ ++function TGDBController.PrintFormattedCommand(const expr : string; Format : TPrintFormatType): ansistring; ++begin ++ Command('-var-evaluate-expression -f '+PrintFormatName[Format]+' '+QuoteString(expr)); ++ if GDB.ResultRecord.Success then ++ PrintFormattedCommand:=GDB.ResultRecord.Parameters['value'].AsString ++ else ++ PrintFormattedCommand:=AnsiString(GetError); ++end; ++ ++function TGDBController.BreakpointInsert(const location: string; BreakpointFlags: TBreakpointFlags): LongInt; ++var ++ Options: string = ''; ++begin ++ if bfTemporary in BreakpointFlags then ++ Options := Options + '-t '; ++ if bfHardware in BreakpointFlags then ++ Options := Options + '-h '; ++ Command('-break-insert ' + Options + location); ++ if GDB.ResultRecord.Success then ++ BreakpointInsert := GDB.ResultRecord.Parameters['bkpt'].AsTuple['number'].AsLongInt ++ else ++ BreakpointInsert := 0; ++end; ++ ++function TGDBController.WatchpointInsert(const location: string; WatchpointType: TWatchpointType): LongInt; ++begin ++ case WatchpointType of ++ wtWrite: ++ Command('-break-watch ' + location); ++ wtReadWrite: ++ Command('-break-watch -a ' + location); ++ wtRead: ++ Command('-break-watch -r ' + location); ++ end; ++ if GDB.ResultRecord.Success then ++ case WatchpointType of ++ wtWrite: ++ WatchpointInsert := GDB.ResultRecord.Parameters['wpt'].AsTuple['number'].AsLongInt; ++ wtReadWrite: ++ WatchpointInsert := GDB.ResultRecord.Parameters['hw-awpt'].AsTuple['number'].AsLongInt; ++ wtRead: ++ WatchpointInsert := GDB.ResultRecord.Parameters['hw-rwpt'].AsTuple['number'].AsLongInt; ++ end ++ else ++ WatchpointInsert := 0; ++end; ++ ++function TGDBController.BreakpointDelete(BkptNo: LongInt): Boolean; ++var ++ BkptNoStr: string; ++begin ++ Str(BkptNo, BkptNoStr); ++ Command('-break-delete ' + BkptNoStr); ++ BreakpointDelete := GDB.ResultRecord.Success; ++end; ++ ++function TGDBController.BreakpointEnable(BkptNo: LongInt): Boolean; ++var ++ BkptNoStr: string; ++begin ++ Str(BkptNo, BkptNoStr); ++ Command('-break-enable ' + BkptNoStr); ++ BreakpointEnable := GDB.ResultRecord.Success; ++end; ++ ++function TGDBController.BreakpointDisable(BkptNo: LongInt): Boolean; ++var ++ BkptNoStr: string; ++begin ++ Str(BkptNo, BkptNoStr); ++ Command('-break-disable ' + BkptNoStr); ++ BreakpointDisable := GDB.ResultRecord.Success; ++end; ++ ++function TGDBController.BreakpointCondition(BkptNo: LongInt; const ConditionExpr: string): Boolean; ++var ++ BkptNoStr: string; ++begin ++ Str(BkptNo, BkptNoStr); ++ Command('-break-condition ' + BkptNoStr + ' ' + ConditionExpr); ++ BreakpointCondition := GDB.ResultRecord.Success; ++end; ++ ++function TGDBController.BreakpointSetIgnoreCount(BkptNo: LongInt; const IgnoreCount: LongInt): Boolean; ++var ++ BkptNoStr, IgnoreCountStr: string; ++begin ++ Str(BkptNo, BkptNoStr); ++ Str(IgnoreCount, IgnoreCountStr); ++ Command('-break-after ' + BkptNoStr + ' ' + IgnoreCountStr); ++ BreakpointSetIgnoreCount := GDB.ResultRecord.Success; ++end; ++ ++procedure TGDBController.SetTBreak(tbreakstring : string); ++begin ++ Command('-break-insert -t ' + tbreakstring); ++ TBreakNumber := GDB.ResultRecord.Parameters['bkpt'].AsTuple['number'].AsLongInt; ++end; ++ ++procedure TGDBController.Backtrace; ++var ++ FrameList,FrameArgList,ArgList: TGDBMI_ListValue; ++ I,J,arg_count: LongInt; ++ s : ansistring; ++begin ++ { forget all old frames } ++ clear_frames; ++ ++ Command('-stack-list-frames'); ++ if not GDB.ResultRecord.Success then ++ exit; ++ ++ FrameList := GDB.ResultRecord.Parameters['stack'].AsList; ++ frame_count := FrameList.Count; ++ frames := AllocMem(SizeOf(PFrameEntry) * frame_count); ++ for I := 0 to frame_count - 1 do ++ frames[I] := New(PFrameEntry, Init); ++ for I := 0 to FrameList.Count - 1 do ++ begin ++ frames[I]^.address := FrameList.ValueAt[I].AsTuple['addr'].AsCoreAddr; ++ frames[I]^.level := FrameList.ValueAt[I].AsTuple['level'].AsLongInt; ++ if Assigned(FrameList.ValueAt[I].AsTuple['line']) then ++ frames[I]^.line_number := FrameList.ValueAt[I].AsTuple['line'].AsLongInt; ++ if Assigned(FrameList.ValueAt[I].AsTuple['func']) then ++ frames[I]^.function_name := StrNew(PChar(FrameList.ValueAt[I].AsTuple['func'].AsString)); ++ if Assigned(FrameList.ValueAt[I].AsTuple['fullname']) then ++ frames[I]^.file_name := StrNew(PChar(FrameList.ValueAt[I].AsTuple['fullname'].AsString)); ++ end; ++ Command('-stack-list-arguments 1'); ++ if not GDB.ResultRecord.Success then ++ exit; ++ ++ FrameArgList := GDB.ResultRecord.Parameters['stack-args'].AsList; ++ arg_count:=FrameArgList.Count; ++ if arg_count>frame_count then ++ arg_count:=frame_count; ++ for I := 0 to arg_count - 1 do ++ begin ++ ArgList:=FrameArgList.ValueAt[I].AsTuple['args'].AsList; ++ s:='('; ++ for J:=0 to ArgList.Count-1 do ++ begin ++ if J>0 then s:=s+', '; ++ s:=s+ArgList.ValueAt[J].AsTuple['name'].AsString; ++ if Assigned(ArgList.ValueAt[J].AsTuple['value']) then ++ s:=s+':='+ArgList.ValueAt[J].AsTuple['value'].ASString; ++ end; ++ s:=s+')'; ++ frames[I]^.args:=StrNew(pchar(s)); ++ end; ++end; ++ ++function TGDBController.SelectFrameCommand(level :longint) : boolean; ++var ++ LevelStr : String; ++begin ++ Str(Level, LevelStr); ++ Command('-stack-select-frame '+LevelStr); ++ SelectFrameCommand:=not error; ++end; ++ ++function TGDBController.LoadFile(var fn: string): Boolean; ++var ++ cmd: string; ++begin ++ getdir(0,cmd); ++ UnixDir(cmd); ++ Command('-environment-cd ' + cmd); ++ GDBOutputBuf.Reset; ++ GDBErrorBuf.Reset; ++{$ifdef GDB_RAW_OUTPUT} ++ GDBRawBuf.reset; ++{$endif GDB_RAW_OUTPUT} ++ UnixDir(fn); ++ Command('-file-exec-and-symbols ' + fn); ++ if not GDB.ResultRecord.Success then ++ begin ++ LoadFile:=false; ++ exit; ++ end; ++ { the register list may change *after* loading a file, because there } ++ { are gdb versions that support multiple archs, e.g. i386 and x86_64 } ++ UpdateRegisterNames; { so that's why we update it here } ++ LoadFile := True; ++end; ++ ++procedure TGDBController.SetDir(const s: string); ++var ++ hs: string; ++begin ++ hs:=s; ++ UnixDir(hs); ++ { Avoid error message if s is empty } ++ if hs<>'' then ++ Command('-environment-cd ' + hs); ++end; ++ ++procedure TGDBController.SetArgs(const s: string); ++begin ++ Command('-exec-arguments ' + s); ++end; ++ ++end. +diff --git a/fpcsrc/ide/gdbmiint.pas b/fpcsrc/ide/gdbmiint.pas +new file mode 100644 +index 00000000..874d6be8 +--- /dev/null ++++ b/fpcsrc/ide/gdbmiint.pas +@@ -0,0 +1,650 @@ ++{ ++ Copyright (c) 2015 by Nikolay Nikolov ++ Copyright (c) 1998 by Peter Vreman ++ ++ This is a replacement for GDBInt, implemented on top of GDB/MI, ++ instead of LibGDB. This allows integration of GDB/MI support in the ++ text mode IDE. ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ ++unit gdbmiint; ++ ++{$MODE fpc}{$H-} ++ ++{$I globdir.inc} ++ ++interface ++ ++uses ++ gdbmiwrap; ++ ++type ++ CORE_ADDR = gdbmiwrap.CORE_ADDR; ++ ++ PPFrameEntry = ^PFrameEntry; ++ PFrameEntry = ^TFrameEntry; ++ TFrameEntry = object ++ private ++ procedure Reset; ++ procedure Clear; ++ public ++ file_name: PChar; ++ function_name: PChar; ++ args: PChar; ++ line_number: LongInt; ++ address: CORE_ADDR; ++ level : longint; ++ constructor Init; ++ destructor Done; ++ end; ++ ++ TGDBBuffer = object ++ private ++ buf: PChar; ++ size, idx: LongInt; ++ procedure Resize(nsize: LongInt); ++ procedure Append(p: PChar); ++ procedure LAppend(p: PChar; len: LongInt); ++ public ++ constructor Init; ++ destructor Done; ++ procedure Reset; ++ end; ++ ++ TGDBInterface = object ++ private ++ user_screen_shown: Boolean; ++{$ifdef GDB_RAW_OUTPUT} ++ output_raw : boolean; ++{$endif GDB_RAW_OUTPUT} ++ protected ++ GDB: TGDBWrapper; ++ ++ procedure i_gdb_command(const S: string); ++ procedure WaitForProgramStop; ++ procedure ProcessResponse; ++ public ++ GDBErrorBuf: TGDBBuffer; ++ GDBOutputBuf: TGDBBuffer; ++{$ifdef GDB_RAW_OUTPUT} ++ { Separate Raw buffer to display everything inside GDB Window ++ but without parsing it twice } ++ GDBRawBuf: TGDBBuffer; ++{$endif GDB_RAW_OUTPUT} ++ got_error: Boolean; ++ reset_command: Boolean; ++ Debuggee_started: Boolean; ++ init_count : longint; ++ { frames and frame info while recording a frame } ++ frames: PPFrameEntry; ++ frame_count: LongInt; ++ command_level: LongInt; ++ signal_name: PChar; ++ signal_string: PChar; ++ current_pc: CORE_ADDR; ++ switch_to_user: Boolean; ++ ++ { init } ++ constructor Init; ++ destructor Done; ++ { from gdbcon } ++ function GetOutput: PChar; ++ function GetError: PChar; ++{$ifdef DEBUG} ++ function GetRaw: PChar; ++{$endif DEBUG} ++ { Lowlevel } ++ procedure Set_debuggee_started; ++ function error: Boolean; ++ function error_num: LongInt; ++ function get_current_frame: PtrInt; ++ function set_current_frame(level: LongInt): Boolean; ++ procedure clear_frames; ++ { Highlevel } ++ procedure DebuggerScreen; ++ procedure UserScreen; ++ procedure FlushAll; virtual; ++ function Query(question: PChar; args: PChar): LongInt; virtual; ++ { Hooks } ++ function DoSelectSourceline(const fn: string; line, BreakIndex: longint): Boolean;virtual; ++ procedure DoStartSession; virtual; ++ procedure DoBreakSession; virtual; ++ procedure DoEndSession(code: LongInt); virtual; ++ procedure DoUserSignal; virtual; ++ procedure DoDebuggerScreen; virtual; ++ procedure DoUserScreen; virtual; ++ function AllowQuit: Boolean; virtual; ++ end; ++ ++const ++ use_gdb_file: Boolean = False; ++ ++var ++ gdb_file: Text; ++ ++function GDBVersion: string; ++function GDBVersionOK: boolean; ++function inferior_pid : longint; ++ ++{$ifdef windows} ++{ We need to do some path conversions if we are using Cygwin GDB } ++var ++ using_cygwin_gdb : boolean; ++{$endif windows} ++implementation ++ ++uses ++ strings; ++ ++constructor TFrameEntry.Init; ++begin ++ Reset; ++end; ++ ++destructor TFrameEntry.Done; ++begin ++ Clear; ++end; ++ ++procedure TFrameEntry.Reset; ++begin ++ file_name := nil; ++ function_name := nil; ++ args := nil; ++ line_number := 0; ++ address := 0; ++ level := 0; ++end; ++ ++procedure TFrameEntry.Clear; ++begin ++ if Assigned(file_name) then ++ StrDispose(file_name); ++ if Assigned(function_name) then ++ StrDispose(function_name); ++ if Assigned(args) then ++ StrDispose(args); ++ Reset; ++end; ++ ++const ++ BlockSize = 2048; ++ ++constructor TGDBBuffer.Init; ++begin ++ buf := nil; ++ size := 0; ++ Resize(BlockSize); ++ Reset; ++end; ++ ++destructor TGDBBuffer.Done; ++begin ++ if Assigned(buf) then ++ FreeMem(buf, size); ++end; ++ ++procedure TGDBBuffer.Reset; ++begin ++ idx := 0; ++ buf[0] := #0; ++end; ++ ++procedure TGDBBuffer.Resize(nsize: LongInt); ++var ++ np: PChar; ++begin ++ nsize := ((nsize + BlockSize - 1) div BlockSize) * BlockSize; ++ GetMem(np, nsize); ++ if Assigned(buf) then ++ begin ++ Move(buf^, np^, size); ++ FreeMem(buf, size); ++ end; ++ buf := np; ++ size := nsize; ++end; ++ ++procedure TGDBBuffer.Append(p: PChar); ++var ++ len: LongInt; ++begin ++ if not Assigned(p) then ++ exit; ++ len := StrLen(p); ++ LAppend(p, len); ++end; ++ ++procedure TGDBBuffer.LAppend(p: PChar; len: LongInt); ++begin ++ if not Assigned(p) then ++ exit; ++ if (len + idx + 1) > size then ++ Resize(len + idx + 1); ++ Move(p^, buf[idx], len); ++ Inc(idx, len); ++ buf[idx] := #0; ++end; ++ ++constructor TGDBInterface.Init; ++begin ++ GDBErrorBuf.Init; ++ GDBOutputBuf.Init; ++ GDB := TGDBWrapper.Create; ++ command_level := 0; ++ Debuggee_started:=false; ++ init_count:=0; ++{$ifdef GDB_RAW_OUTPUT} ++ output_raw:=true; ++ GDBRawBuf.Init; ++{$endif GDB_RAW_OUTPUT} ++{ other standard commands used for fpc debugging } ++ i_gdb_command('-gdb-set print demangle off'); ++ i_gdb_command('-gdb-set gnutarget auto'); ++ i_gdb_command('-gdb-set language auto'); ++ i_gdb_command('-gdb-set print vtbl on'); ++ i_gdb_command('-gdb-set print object on'); ++ i_gdb_command('-gdb-set print null-stop'); ++end; ++ ++destructor TGDBInterface.Done; ++begin ++ clear_frames; ++ GDB.Free; ++ GDBErrorBuf.Done; ++ GDBOutputBuf.Done; ++{$ifdef GDB_RAW_OUTPUT} ++ GDBRawBuf.Done; ++{$endif GDB_RAW_OUTPUT} ++end; ++ ++function TGDBInterface.GetOutput: PChar; ++begin ++ GetOutput := GDBOutputBuf.buf; ++end; ++ ++{$ifdef GDB_RAW_OUTPUT} ++function TGDBInterface.GetRaw: PChar; ++begin ++ GetRaw := GDBRawBuf.buf; ++end; ++{$endif GDB_RAW_OUTPUT} ++ ++function TGDBInterface.GetError: PChar; ++var ++ p: PChar; ++begin ++ p := GDBErrorBuf.buf; ++ if (p^=#0) and got_error then ++ GetError := PChar(PtrInt(GDBOutputBuf.buf) + GDBOutputBuf.idx) ++ else ++ GetError := p; ++end; ++ ++procedure TGDBInterface.Set_debuggee_started; ++begin ++ if not Debuggee_started then ++ begin ++ inc(init_count); ++ Debuggee_started:=true; ++ end; ++end; ++ ++procedure TGDBInterface.i_gdb_command(const S: string); ++var ++ I: LongInt; ++begin ++ Inc(command_level); ++ got_error := False; ++ GDB.Command(S); ++{$ifdef GDB_RAW_OUTPUT} ++ if output_raw then ++ for I := 0 to GDB.RawResponse.Count - 1 do ++ GDBRawBuf.Append(PChar(GDB.RawResponse[I])); ++{$endif GDB_RAW_OUTPUT} ++ ++ for I := 0 to GDB.ConsoleStream.Count - 1 do ++ GDBOutputBuf.Append(PChar(GDB.ConsoleStream[I])); ++ if GDB.ResultRecord.AsyncClass='error' then ++ begin ++ got_error := True; ++ if Assigned(GDB.ResultRecord.Parameters['msg']) then ++ GDBErrorBuf.Append(PChar(GDB.ResultRecord.Parameters['msg'].AsString)); ++ end; ++ ProcessResponse; ++ Dec(command_level); ++end; ++ ++procedure TGDBInterface.WaitForProgramStop; ++label ++ Ignore; ++var ++ StopReason: string; ++ LocalSignalString,LocalSignalName: String; ++ FileName: string = ''; ++ LineNumber: LongInt = 0; ++ Addr: CORE_ADDR; ++ BreakpointNo: LongInt; ++ ExitCode: LongInt; ++begin ++Ignore: ++ GDB.WaitForProgramStop; ++ if not GDB.Alive then ++ begin ++ DebuggerScreen; ++ current_pc := 0; ++ Debuggee_started := False; ++ exit; ++ end; ++ ProcessResponse; ++ StopReason := GDB.ExecAsyncOutput.Parameters['reason'].AsString; ++ case StopReason of ++ 'watchpoint-scope': ++ begin ++ { A watchpoint has gone out of scope (e.g. if it was a local variable). TODO: should we stop ++ the program and notify the user or maybe silently disable it in the breakpoint list and ++ continue execution? The libgdb.a version of the debugger just silently ignores this case. ++ ++ We have: GDB.ExecAsyncOutput.Parameters['wpnum'].AsLongInt } ++ i_gdb_command('-exec-continue'); ++ if not GDB.ResultRecord.Success then ++ begin ++ DebuggerScreen; ++ got_error := True; ++ exit; ++ end; ++ goto Ignore; ++ end; ++ 'signal-received': ++ begin ++ { TODO: maybe show information to the user about the signal ++ we have: ++ GDB.ExecAsyncOutput.Parameters['signal-name'].AsString (e.g. 'SIGTERM') ++ GDB.ExecAsyncOutput.PArameters['signal-meaning'].AsString (e.g. 'Terminated') ++ } ++ LocalSignalName:=GDB.ExecAsyncOutput.Parameters['signal-name'].AsString; ++ LocalSignalString:=GDB.ExecAsyncOutput.PArameters['signal-meaning'].AsString; ++ signal_name:=@LocalSignalName; ++ signal_string:=@LocalSignalString; ++ if (user_screen_shown) then ++ begin ++ DebuggerScreen; ++ DoUserSignal; ++ UserScreen; ++ end ++ else ++ DoUserSignal; ++ i_gdb_command('-exec-continue'); ++ if not GDB.ResultRecord.Success then ++ begin ++ DebuggerScreen; ++ got_error := True; ++ exit; ++ end; ++ goto Ignore; ++ end; ++ 'breakpoint-hit', ++ 'watchpoint-trigger', ++ 'access-watchpoint-trigger', ++ 'read-watchpoint-trigger', ++ 'end-stepping-range', ++ 'function-finished': ++ begin ++ if StopReason = 'breakpoint-hit' then ++ BreakpointNo := GDB.ExecAsyncOutput.Parameters['bkptno'].AsLongInt ++ else if StopReason = 'watchpoint-trigger' then ++ BreakpointNo := GDB.ExecAsyncOutput.Parameters['wpt'].AsTuple['number'].AsLongInt ++ else if StopReason = 'access-watchpoint-trigger' then ++ BreakpointNo := GDB.ExecAsyncOutput.Parameters['hw-awpt'].AsTuple['number'].AsLongInt ++ else if StopReason = 'read-watchpoint-trigger' then ++ BreakpointNo := GDB.ExecAsyncOutput.Parameters['hw-rwpt'].AsTuple['number'].AsLongInt ++ else ++ BreakpointNo := 0; ++ ++ Addr := GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['addr'].AsCoreAddr; ++ if Assigned(GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['fullname']) then ++ FileName := GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['fullname'].AsString; ++ if Assigned(GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['line']) then ++ LineNumber := GDB.ExecAsyncOutput.Parameters['frame'].AsTuple['line'].AsLongInt; ++ ++ { this kills GDB.ExecAsyncOutput, because it may execute other gdb commands, so ++ make sure we have read all parameters that we need to local variables before that } ++ DebuggerScreen; ++ ++ set_debuggee_started; ++ current_pc := Addr; ++ if not DoSelectSourceLine(FileName, LineNumber, BreakpointNo) then ++ begin ++ UserScreen; ++ i_gdb_command('-exec-continue'); ++ if not GDB.ResultRecord.Success then ++ begin ++ DebuggerScreen; ++ got_error := True; ++ exit; ++ end; ++ goto Ignore; ++ end; ++ end; ++ 'exited-signalled': ++ begin ++ DebuggerScreen; ++ current_pc := 0; ++ Debuggee_started := False; ++ { TODO: maybe show information to the user about the signal ++ we have: ++ GDB.ExecAsyncOutput.Parameters['signal-name'].AsString (e.g. 'SIGTERM') ++ GDB.ExecAsyncOutput.PArameters['signal-meaning'].AsString (e.g. 'Terminated') ++ } ++ DoEndSession(1); ++ end; ++ 'exited': ++ begin ++ ExitCode := LongInt(GDB.ExecAsyncOutput.Parameters['exit-code'].AsLongWord); ++ DebuggerScreen; ++ current_pc := 0; ++ Debuggee_started := False; ++ DoEndSession(ExitCode); ++ end; ++ 'exited-normally': ++ begin ++ DebuggerScreen; ++ current_pc := 0; ++ Debuggee_started := False; ++ DoEndSession(0); ++ end; ++ end; ++end; ++ ++procedure TGDBInterface.ProcessResponse; ++//var ++// NAO: TGDBMI_AsyncOutput; ++// Code: LongInt; ++begin ++// for NAO in GDB.NotifyAsyncOutput do ++// begin ++// if NAO.AsyncClass = 'breakpoint-created' then ++// begin ++// Writeln('BREAKPOINT created!'); ++// Val(NAO.Parameters['bkpt'].AsTuple['number'].AsString, last_breakpoint_number, Code); ++// Writeln('last_breakpoint_number=', last_breakpoint_number); ++// end; ++// end; ++end; ++ ++function TGDBInterface.error: Boolean; ++begin ++ error := got_error or not GDB.Alive; ++end; ++ ++function TGDBInterface.error_num: LongInt; ++begin ++ error_num := 0; { TODO } ++end; ++ ++function TGDBInterface.get_current_frame: PtrInt; ++begin ++ i_gdb_command('-stack-info-frame'); ++ if GDB.ResultRecord.Success then ++ get_current_frame := GDB.ResultRecord.Parameters['frame'].AsTuple['level'].AsLongInt ++ else ++ get_current_frame := 0; ++end; ++ ++function TGDBInterface.set_current_frame(level: LongInt): Boolean; ++var ++ s: string; ++begin ++ str(level,s); ++ { Note: according to the gdb docs, '-stack-select-frame' is deprecated in favor of passing the '--frame' option to every command } ++ i_gdb_command('-stack-select-frame '+s); ++ set_current_frame := GDB.ResultRecord.Success; ++end; ++ ++procedure TGDBInterface.clear_frames; ++var ++ I: LongInt; ++begin ++ for I := 0 to frame_count - 1 do ++ Dispose(frames[I], Done); ++ if Assigned(frames) then ++ begin ++ FreeMem(frames, SizeOf(Pointer) * frame_count); ++ frames := nil; ++ end; ++ frame_count := 0; ++end; ++ ++procedure TGDBInterface.DebuggerScreen; ++begin ++ if user_screen_shown then ++ DoDebuggerScreen; ++ user_screen_shown := False; ++end; ++ ++procedure TGDBInterface.UserScreen; ++begin ++ if switch_to_user then ++ begin ++ if not user_screen_shown then ++ DoUserScreen; ++ user_screen_shown := True; ++ end; ++end; ++ ++procedure TGDBInterface.FlushAll; ++begin ++end; ++ ++function TGDBInterface.Query(question: PChar; args: PChar): LongInt; ++begin ++ Query := 0; ++end; ++ ++function TGDBInterface.DoSelectSourceline(const fn: string; line, BreakIndex: LongInt): Boolean; ++begin ++end; ++ ++procedure TGDBInterface.DoStartSession; ++begin ++end; ++ ++procedure TGDBInterface.DoBreakSession; ++begin ++end; ++ ++procedure TGDBInterface.DoEndSession(code: LongInt); ++begin ++end; ++ ++procedure TGDBInterface.DoUserSignal; ++begin ++end; ++ ++procedure TGDBInterface.DoDebuggerScreen; ++begin ++end; ++ ++procedure TGDBInterface.DoUserScreen; ++begin ++end; ++ ++function TGDBInterface.AllowQuit: Boolean; ++begin ++ AllowQuit := True; ++end; ++ ++function inferior_pid : longint; ++begin ++ inferior_pid:=0; {inferior_ptid.pid; } ++end; ++ ++ ++var ++ CachedGDBVersion: string; ++ CachedGDBVersionOK : boolean; ++ ++function GDBVersion: string; ++var ++ GDB: TGDBWrapper; ++{$ifdef windows} ++ i : longint; ++ line :string; ++{$endif windows} ++begin ++ if CachedGDBVersion <> '' then ++ begin ++ GDBVersion := CachedGDBVersion; ++ exit; ++ end; ++ GDBVersion := ''; ++ GDB := TGDBWrapper.Create; ++ GDB.Command('-gdb-version'); ++ if GDB.ConsoleStream.Count > 0 then ++ GDBVersion := GDB.ConsoleStream[0]; ++ if (GDBVersion <> '') and (GDBVersion[Length(GDBVersion)]=#10) then ++ Delete(GDBVersion, Length(GDBVersion), 1); ++{$ifdef windows} ++ i:=0; ++ using_cygwin_gdb:=false; ++ while i < GDB.ConsoleStream.Count do ++ begin ++ line:=GDB.ConsoleStream[i]; ++ if pos('This GDB was configured',line) > 0 then ++ using_cygwin_gdb:=pos('cygwin',line) > 0; ++ inc(i); ++ end; ++{$endif windows} ++ GDB.Free; ++ CachedGDBVersion := GDBVersion; ++ if GDBVersion = '' then ++ begin ++ GDBVersion := 'GDB missing or does not work'#13 ++ +#3'Consider using -G command line option'#13 ++ +#3'or set FPIDE_GDBPROC environment variable'#13 ++ +#3'to specify full path to GDB'; ++ CachedGDBVersionOK := false; ++ end; ++end; ++ ++function GDBVersionOK: boolean; ++var ++ S : string; ++begin ++ { Be sure GDBVersion is called } ++ S:=GDBVersion; ++ GDBVersionOK := CachedGDBVersionOK; ++end; ++ ++begin ++ CachedGDBVersion := ''; ++ CachedGDBVersionOK := true; ++end. +diff --git a/fpcsrc/ide/gdbmiproc.pas b/fpcsrc/ide/gdbmiproc.pas +new file mode 100644 +index 00000000..4b2b0970 +--- /dev/null ++++ b/fpcsrc/ide/gdbmiproc.pas +@@ -0,0 +1,156 @@ ++{ ++ Copyright (c) 2015 by Nikolay Nikolov ++ ++ This unit implements a class, which launches gdb in GDB/MI mode ++ and allows sending textual commands to it and receiving the response ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ ++unit GDBMIProc; ++ ++{$MODE objfpc}{$H+} ++ ++{$I globdir.inc} ++ ++interface ++ ++uses ++ SysUtils, Classes, Process; ++ ++type ++ TGDBProcess = class ++ private ++ FProcess: TProcess; ++ FDebugLog: TextFile; ++ ++ function IsAlive: Boolean; ++ procedure GDBWrite(const S: string); ++ procedure DebugLn(const S: string); ++ procedure DebugErrorLn(const S: string); ++ public ++ constructor Create; ++ destructor Destroy; override; ++ function GDBReadLn: string; ++ procedure GDBWriteLn(const S: string); ++ property Alive: Boolean read IsAlive; ++ end; ++ ++var ++ GdbProgramName: string = 'gdb'; ++ ++implementation ++ ++uses ++ fputils; ++ ++var ++ DebugLogEnabled: Boolean = False; ++ ++function TGDBProcess.IsAlive: Boolean; ++begin ++ Result := Assigned(FProcess) and FProcess.Running; ++end; ++ ++function TGDBProcess.GDBReadLn: string; ++var ++ C: Char; ++begin ++ Result := ''; ++ while FProcess.Running do ++ begin ++ FProcess.Output.Read(C, 1); ++{$ifdef windows} ++ { On windows we expect both #13#10 and #10 } ++ if C = #13 then ++ begin ++ FProcess.Output.Read(C, 1); ++ if C <> #10 then ++ { #13 not followed by #10, what should we do? } ++ Result := Result + #13; ++ end; ++{$endif windows} ++ if C = #10 then ++ begin ++ DebugLn(Result); ++ exit; ++ end; ++ Result := Result + C; ++ end; ++end; ++ ++constructor TGDBProcess.Create; ++begin ++ if DebugLogEnabled then ++ begin ++ AssignFile(FDebugLog, 'gdblog.txt'); ++ Rewrite(FDebugLog); ++ CloseFile(FDebugLog); ++ end; ++ FProcess := TProcess.Create(nil); ++ FProcess.Options := [poUsePipes, poStdErrToOutput]; ++ if (ExeExt<>'') and (pos(ExeExt,LowerCaseStr(GdbProgramName))=0) then ++ FProcess.Executable := GdbProgramName+ExeExt ++ else ++ FProcess.Executable := GdbProgramName; ++ FProcess.Parameters.Add('--interpreter=mi'); ++ try ++ FProcess.Execute; ++ except ++ on e: Exception do ++ begin ++ DebugErrorLn('Could not start GDB: ' + e.Message); ++ FreeAndNil(FProcess); ++ end; ++ end; ++end; ++ ++destructor TGDBProcess.Destroy; ++begin ++ FProcess.Free; ++ inherited Destroy; ++end; ++ ++procedure TGDBProcess.DebugLn(const S: string); ++begin ++ if DebugLogEnabled then ++ begin ++ Append(FDebugLog); ++ Writeln(FDebugLog, S); ++ CloseFile(FDebugLog); ++ end; ++end; ++ ++procedure TGDBProcess.DebugErrorLn(const S: string); ++begin ++ DebugLn('ERROR: ' + S); ++end; ++ ++procedure TGDBProcess.GDBWrite(const S: string); ++begin ++ FProcess.Input.Write(S[1], Length(S)); ++end; ++ ++procedure TGDBProcess.GDBWriteln(const S: string); ++begin ++ if not IsAlive then ++ begin ++ DebugErrorLn('Trying to send command to a dead GDB: ' + S); ++ exit; ++ end; ++ DebugLn(S); ++ GDBWrite(S + #10); ++end; ++ ++begin ++ if GetEnvironmentVariable('FPIDE_GDBLOG') = '1' then ++ DebugLogEnabled := True; ++ if GetEnvironmentVariable('FPIDE_GDBPROG') <> '' then ++ GdbProgramName := GetEnvironmentVariable('FPIDE_GDBPROG'); ++end. +diff --git a/fpcsrc/ide/gdbmiwrap.pas b/fpcsrc/ide/gdbmiwrap.pas +new file mode 100644 +index 00000000..2198aef4 +--- /dev/null ++++ b/fpcsrc/ide/gdbmiwrap.pas +@@ -0,0 +1,559 @@ ++{ ++ Copyright (c) 2015 by Nikolay Nikolov ++ ++ This unit provides a wrapper around GDB and implements parsing of ++ the GDB/MI command result records. ++ ++ See the file COPYING.FPC, included in this distribution, ++ for details about the copyright. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ **********************************************************************} ++ ++unit gdbmiwrap; ++ ++{$MODE objfpc}{$H+} ++{$ASSERTIONS on} ++ ++{$I globdir.inc} ++ ++interface ++ ++uses ++ SysUtils, Classes, GDBMIProc; ++ ++type ++{$ifdef TARGET_IS_64BIT} ++ { force 64bit if target compilation CPU is 64-bit address CPU } ++ CORE_ADDR = Qword; ++{$else} ++ CORE_ADDR = PtrUInt; ++{$endif} ++ ++ TGDBMI_TupleValue = class; ++ TGDBMI_ListValue = class; ++ TGDBMI_Value = class ++ function AsString: string; ++ function AsInt64: Int64; ++ function AsQWord: QWord; ++ function AsLongInt: LongInt; ++ function AsLongWord: LongWord; ++ function AsCoreAddr: CORE_ADDR; ++ function AsTuple: TGDBMI_TupleValue; ++ function AsList: TGDBMI_ListValue; ++ end; ++ ++ { "C string\n" } ++ TGDBMI_StringValue = class(TGDBMI_Value) ++ FStringValue: string; ++ public ++ constructor Create(const S: string); ++ property StringValue: string read FStringValue; ++ end; ++ ++ (* {...} or [...] *) ++ TGDBMI_TupleOrListValue = class(TGDBMI_Value) ++ private ++ FNames: array of string; ++ FValues: array of TGDBMI_Value; ++ function GetValue(const AName: string): TGDBMI_Value; ++ public ++ destructor Destroy; override; ++ procedure Clear; ++ procedure Add(AName: string; AValue: TGDBMI_Value); ++ function HasNames: Boolean; ++ function IsEmpty: Boolean; ++ property Values [const AName: string]: TGDBMI_Value read GetValue; default; ++ end; ++ ++ (* {} or {variable=value,variable=value,variable=value} *) ++ TGDBMI_TupleValue = class(TGDBMI_TupleOrListValue) ++ end; ++ ++ { [] or [value,value,value] or [variable=value,variable=value,variable=value] } ++ TGDBMI_ListValue = class(TGDBMI_TupleOrListValue) ++ private ++ function GetCount: LongInt; ++ function GetValueAt(AIndex: LongInt): TGDBMI_Value; ++ public ++ property Count: LongInt read GetCount; ++ property ValueAt [AIndex: LongInt]: TGDBMI_Value read GetValueAt; ++ end; ++ ++ TGDBMI_AsyncOutput = class ++ FAsyncClass: string; ++ FParameters: TGDBMI_TupleValue; ++ public ++ constructor Create; ++ destructor Destroy; override; ++ procedure Clear; ++ property AsyncClass: string read FAsyncClass write FAsyncClass; ++ property Parameters: TGDBMI_TupleValue read FParameters; ++ end; ++ ++ TGDBMI_ResultRecord = class(TGDBMI_AsyncOutput) ++ public ++ function Success: Boolean; ++ end; ++ ++ TGDBMI_AsyncOutput_List = array of TGDBMI_AsyncOutput; ++ ++ TGDBWrapper = class ++ private ++ FProcess: TGDBProcess; ++ FRawResponse: TStringList; ++ FConsoleStream: TStringList; ++ FExecAsyncOutput: TGDBMI_AsyncOutput; ++ FResultRecord: TGDBMI_ResultRecord; ++ ++ function IsAlive: Boolean; ++ procedure ReadResponse; ++ public ++ NotifyAsyncOutput: TGDBMI_AsyncOutput_List; ++ ++ constructor Create; ++ destructor Destroy; override; ++ procedure Command(S: string); ++ procedure WaitForProgramStop; ++ property RawResponse: TStringList read FRawResponse; ++ property ConsoleStream: TStringList read FConsoleStream; ++ property ExecAsyncOutput: TGDBMI_AsyncOutput read FExecAsyncOutput; ++ property ResultRecord: TGDBMI_ResultRecord read FResultRecord write FResultRecord; ++ property Alive: Boolean read IsAlive; ++ end; ++ ++function QuoteString(S: string): string; ++function C2PascalNumberPrefix(const S: string): string; ++ ++implementation ++ ++function QuoteString(S: string): string; ++var ++ I: LongInt; ++begin ++ I := 1; ++ Result := ''; ++ while I <= Length(S) do ++ begin ++ case S[I] of ++ '''': Result := Result + '\'''; ++ '"': Result := Result + '\"'; ++ #10: Result := Result + '\n'; ++ #13: Result := Result + '\r'; ++ #9: Result := Result + '\t'; ++ #11: Result := Result + '\v'; ++ #8: Result := Result + '\b'; ++ #12: Result := Result + '\f'; ++ #7: Result := Result + '\a'; ++ '\': Result := Result + '\\'; ++ '?': Result := Result + '\?'; ++ else ++ Result := Result + S[I]; ++ end; ++ Inc(I); ++ end; ++ Result := '"' + Result + '"'; ++end; ++ ++function C2PascalNumberPrefix(const S: string): string; ++begin ++ { hex: 0x -> $ } ++ if (Length(S) >= 3) and (s[1] = '0') and ((s[2] = 'x') or (s[2] = 'X')) then ++ exit('$' + Copy(S, 3, Length(S) - 2)); ++ ++ { oct: 0 -> & } ++ if (Length(S) >= 2) and (s[1] = '0') and ((s[2] >= '0') and (s[2] <= '7')) then ++ exit('&' + Copy(S, 2, Length(S) - 1)); ++ ++ Result := S; ++end; ++ ++function TGDBMI_Value.AsString: string; ++begin ++ Result := (self as TGDBMI_StringValue).StringValue; ++end; ++ ++function TGDBMI_Value.AsInt64: Int64; ++begin ++ Result := StrToInt64(C2PascalNumberPrefix(AsString)); ++end; ++ ++function TGDBMI_Value.AsQWord: QWord; ++begin ++ Result := StrToQWord(C2PascalNumberPrefix(AsString)); ++end; ++ ++function TGDBMI_Value.AsLongInt: LongInt; ++begin ++ Result := StrToInt(C2PascalNumberPrefix(AsString)); ++end; ++ ++function TGDBMI_Value.AsLongWord: LongWord; ++const ++ SInvalidInteger = '"%s" is an invalid integer'; ++var ++ S: string; ++ Error: LongInt; ++begin ++ S := C2PascalNumberPrefix(AsString); ++ Val(S, Result, Error); ++ if Error <> 0 then ++ raise EConvertError.CreateFmt(SInvalidInteger,[S]); ++end; ++ ++function TGDBMI_Value.AsCoreAddr: CORE_ADDR; ++begin ++{$if defined(TARGET_IS_64BIT)} ++ Result := AsQWord; ++{$elseif defined(CPU64)} ++ Result := AsQWord; ++{$else} ++ Result := AsLongWord; ++{$endif} ++end; ++ ++function TGDBMI_Value.AsTuple: TGDBMI_TupleValue; ++begin ++ Result := self as TGDBMI_TupleValue; ++end; ++ ++function TGDBMI_Value.AsList: TGDBMI_ListValue; ++begin ++ Result := self as TGDBMI_ListValue; ++end; ++ ++constructor TGDBMI_StringValue.Create(const S: string); ++begin ++ FStringValue := S; ++end; ++ ++destructor TGDBMI_TupleOrListValue.Destroy; ++begin ++ Clear; ++ inherited Destroy; ++end; ++ ++procedure TGDBMI_TupleOrListValue.Clear; ++var ++ I: LongInt; ++begin ++ SetLength(FNames, 0); ++ for I := Low(FValues) to High(FValues) do ++ FreeAndNil(FValues[I]); ++ SetLength(FValues, 0); ++end; ++ ++procedure TGDBMI_TupleOrListValue.Add(AName: string; AValue: TGDBMI_Value); ++begin ++ Assert(AValue <> nil); ++ Assert(IsEmpty or (HasNames = (AName <> ''))); ++ if AName <> '' then ++ begin ++ SetLength(FNames, Length(FNames) + 1); ++ FNames[Length(FNames) - 1] := AName; ++ end; ++ SetLength(FValues, Length(FValues) + 1); ++ FValues[Length(FValues) - 1] := AValue; ++end; ++ ++function TGDBMI_TupleOrListValue.HasNames: Boolean; ++begin ++ Result := Length(FNames) > 0; ++end; ++ ++function TGDBMI_TupleOrListValue.IsEmpty: Boolean; ++begin ++ Result := Length(FValues) = 0; ++end; ++ ++function TGDBMI_TupleOrListValue.GetValue(const AName: string): TGDBMI_Value; ++var ++ I: LongInt; ++begin ++ for I := Low(FNames) to High(FNames) do ++ if FNames[I] = AName then ++ begin ++ Result := FValues[I]; ++ exit; ++ end; ++ Result := nil; ++end; ++ ++function TGDBMI_ListValue.GetCount: LongInt; ++begin ++ Result := Length(FValues); ++end; ++ ++function TGDBMI_ListValue.GetValueAt(AIndex: LongInt): TGDBMI_Value; ++begin ++ Assert((AIndex >= Low(FValues)) and (AIndex <= High(FValues))); ++ Result := FValues[AIndex]; ++end; ++ ++constructor TGDBMI_AsyncOutput.Create; ++begin ++ FParameters := TGDBMI_TupleValue.Create; ++end; ++ ++destructor TGDBMI_AsyncOutput.Destroy; ++begin ++ FParameters.Free; ++ inherited Destroy; ++end; ++ ++procedure TGDBMI_AsyncOutput.Clear; ++begin ++ AsyncClass := ''; ++ Parameters.Clear; ++end; ++ ++function TGDBMI_ResultRecord.Success: Boolean; ++begin ++ { according to the GDB docs, 'done' and 'running' should be treated identically by clients } ++ Result := (AsyncClass='done') or (AsyncClass='running'); ++end; ++ ++function ParseCString(const CStr: string; var NextCharPos: LongInt): string; ++begin ++ if (NextCharPos <= Length(CStr)) and (CStr[NextCharPos] = '"') then ++ Inc(NextCharPos); ++ Result := ''; ++ while NextCharPos <= Length(CStr) do ++ begin ++ if CStr[NextCharPos] = '"' then ++ begin ++ Inc(NextCharPos); ++ exit; ++ end ++ else if CStr[NextCharPos] = '\' then ++ begin ++ Inc(NextCharPos); ++ if NextCharPos <= Length(CStr) then ++ case CStr[NextCharPos] of ++ '''': Result := Result + ''''; ++ '"': Result := Result + '"'; ++ 'n': Result := Result + #10; ++ 'r': Result := Result + #13; ++ 't': Result := Result + #9; ++ 'v': Result := Result + #11; ++ 'b': Result := Result + #8; ++ 'f': Result := Result + #12; ++ 'a': Result := Result + #7; ++ '\': Result := Result + '\'; ++ '?': Result := Result + '?'; ++ {\0, \000, \xhhh} ++ end; ++ end ++ else ++ Result := Result + CStr[NextCharPos]; ++ Inc(NextCharPos); ++ end; ++end; ++ ++function ParseIdentifier(const S: string; var NextCharPos: LongInt): string; ++begin ++ Result := ''; ++ while (NextCharPos <= Length(S)) and (S[NextCharPos] in ['A'..'Z', 'a'..'z', '0'..'9', '-']) do ++ begin ++ Result := Result + S[NextCharPos]; ++ Inc(NextCharPos); ++ end; ++end; ++ ++function ParseValue(const S: string; var NextCharPos: LongInt): TGDBMI_Value; ++var ++ CStr: string; ++ Tuple: TGDBMI_TupleValue; ++ List: TGDBMI_ListValue; ++ ++ Name: string; ++ Value: TGDBMI_Value; ++begin ++ Assert(NextCharPos <= Length(S)); ++ case S[NextCharPos] of ++ '"': ++ begin ++ CStr := ParseCString(S, NextCharPos); ++ Result := TGDBMI_StringValue.Create(CStr); ++ end; ++ '{': ++ begin ++ Inc(NextCharPos); ++ Assert(NextCharPos <= Length(S)); ++ Tuple := TGDBMI_TupleValue.Create; ++ Result := Tuple; ++ while (NextCharPos <= Length(S)) and (S[NextCharPos] <> '}') do ++ begin ++ Name := ParseIdentifier(S, NextCharPos); ++ Assert(NextCharPos <= Length(S)); ++ Assert(S[NextCharPos] = '='); ++ Inc(NextCharPos); ++ Value := ParseValue(S, NextCharPos); ++ Tuple.Add(Name, Value); ++ Assert(NextCharPos <= Length(S)); ++ Assert(S[NextCharPos] in [',', '}']); ++ if S[NextCharPos] = ',' then ++ Inc(NextCharPos); ++ end; ++ if (NextCharPos <= Length(S)) and (S[NextCharPos] = '}') then ++ Inc(NextCharPos); ++ end; ++ '[': ++ begin ++ Inc(NextCharPos); ++ Assert(NextCharPos <= Length(S)); ++ List := TGDBMI_ListValue.Create; ++ Result := List; ++ if S[NextCharPos] in ['"', '{', '['] then ++ begin ++ { list of values, no names } ++ while (NextCharPos <= Length(S)) and (S[NextCharPos] <> ']') do ++ begin ++ Value := ParseValue(S, NextCharPos); ++ List.Add('', Value); ++ Assert(NextCharPos <= Length(S)); ++ Assert(S[NextCharPos] in [',', ']']); ++ if S[NextCharPos] = ',' then ++ Inc(NextCharPos); ++ end; ++ end ++ else ++ begin ++ { list of name=value pairs (like a tuple) } ++ while (NextCharPos <= Length(S)) and (S[NextCharPos] <> ']') do ++ begin ++ Name := ParseIdentifier(S, NextCharPos); ++ Assert(NextCharPos <= Length(S)); ++ Assert(S[NextCharPos] = '='); ++ Inc(NextCharPos); ++ Value := ParseValue(S, NextCharPos); ++ List.Add(Name, Value); ++ Assert(NextCharPos <= Length(S)); ++ Assert(S[NextCharPos] in [',', ']']); ++ if S[NextCharPos] = ',' then ++ Inc(NextCharPos); ++ end; ++ end; ++ if (NextCharPos <= Length(S)) and (S[NextCharPos] = ']') then ++ Inc(NextCharPos); ++ end; ++ else ++ Assert(False); ++ end; ++end; ++ ++procedure ParseAsyncOutput(const S: string; AsyncOutput: TGDBMI_AsyncOutput; var NextCharPos: LongInt); ++var ++ Name: string; ++ Value: TGDBMI_Value; ++begin ++ AsyncOutput.Clear; ++ AsyncOutput.AsyncClass := ParseIdentifier(S, NextCharPos); ++ while NextCharPos <= Length(S) do ++ begin ++ Assert(S[NextCharPos] = ','); ++ Inc(NextCharPos); ++ Name := ParseIdentifier(S, NextCharPos); ++ Assert(NextCharPos <= Length(S)); ++ Assert(S[NextCharPos] = '='); ++ Inc(NextCharPos); ++ Value := ParseValue(S, NextCharPos); ++ AsyncOutput.Parameters.Add(Name, Value); ++ end; ++end; ++ ++function TGDBWrapper.IsAlive: Boolean; ++begin ++ Result := Assigned(FProcess) and FProcess.Alive; ++end; ++ ++procedure TGDBWrapper.ReadResponse; ++var ++ S: string; ++ I: LongInt; ++ NextCharPos: LongInt; ++ NAO: TGDBMI_AsyncOutput; ++begin ++ FRawResponse.Clear; ++ FConsoleStream.Clear; ++ ExecAsyncOutput.Clear; ++ for I := Low(NotifyAsyncOutput) to High(NotifyAsyncOutput) do ++ FreeAndNil(NotifyAsyncOutput[I]); ++ SetLength(NotifyAsyncOutput, 0); ++ if not FProcess.Alive then ++ exit; ++ repeat ++ S := FProcess.GDBReadLn; ++ FRawResponse.Add(S); ++ if Length(S) >= 1 then ++ case S[1] of ++ '~': ++ begin ++ NextCharPos := 2; ++ FConsoleStream.Add(ParseCString(S, NextCharPos)); ++ end; ++ '*': ++ begin ++ NextCharPos := 2; ++ ParseAsyncOutput(S, ExecAsyncOutput, NextCharPos); ++ end; ++ '^': ++ begin ++ NextCharPos := 2; ++ ParseAsyncOutput(S, ResultRecord, NextCharPos); ++ end; ++ '=': ++ begin ++ NextCharPos := 2; ++ NAO := TGDBMI_AsyncOutput.Create; ++ try ++ ParseAsyncOutput(S, NAO, NextCharPos); ++ SetLength(NotifyAsyncOutput, Length(NotifyAsyncOutput) + 1); ++ NotifyAsyncOutput[Length(NotifyAsyncOutput) - 1] := NAO; ++ NAO := nil; ++ finally ++ NAO.Free; ++ end; ++ end; ++ end; ++ until (S = '(gdb) ') or (S = '(gdb)') or not FProcess.Alive; ++end; ++ ++constructor TGDBWrapper.Create; ++begin ++ FRawResponse := TStringList.Create; ++ FConsoleStream := TStringList.Create; ++ FProcess := TGDBProcess.Create; ++ FExecAsyncOutput := TGDBMI_AsyncOutput.Create; ++ FResultRecord := TGDBMI_ResultRecord.Create; ++ ReadResponse; ++end; ++ ++destructor TGDBWrapper.Destroy; ++begin ++ if Alive then ++ Command('-gdb-exit'); ++ FProcess.Free; ++ FResultRecord.Free; ++ FExecAsyncOutput.Free; ++ FConsoleStream.Free; ++ FRawResponse.Free; ++end; ++ ++procedure TGDBWrapper.Command(S: string); ++begin ++ FProcess.GDBWriteLn(S); ++ ReadResponse; ++end; ++ ++procedure TGDBWrapper.WaitForProgramStop; ++begin ++ repeat ++ ReadResponse; ++ until (ExecAsyncOutput.AsyncClass = 'stopped') or not FProcess.Alive; ++end; ++ ++end. +diff --git a/fpcsrc/ide/globdir.inc b/fpcsrc/ide/globdir.inc +index 520779f3..b8370a77 100644 +--- a/fpcsrc/ide/globdir.inc ++++ b/fpcsrc/ide/globdir.inc +@@ -195,3 +195,29 @@ + {$ifdef FPC_ARMHF} + {$define FPC_ARMEL32} + {$endif FPC_ARMHF} ++ ++{ Set TARGET_IS_64BIT for corresponding compilation targets } ++{$ifdef X86_64} ++ {$define TARGET_IS_64BIT} ++{$endif} ++{$ifdef IA64} ++ {$define TARGET_IS_64BIT} ++{$endif} ++{$ifdef ALPHA} ++ {$define TARGET_IS_64BIT} ++{$endif} ++{$ifdef POWERPC64} ++ {$define TARGET_IS_64BIT} ++{$endif} ++{$ifdef AARCH64} ++ {$define TARGET_IS_64BIT} ++{$endif} ++ ++{$ifdef GDBMI} ++ {$ifdef DEBUG} ++ {$define GDB_RAW_OUTPUT} ++ {$endif DEBUG} ++ {$ifdef Windows} ++ {$define GDB_WINDOWS_ALWAYS_USE_ANOTHER_CONSOLE} ++ {$endif Windows} ++{$endif GDBMI} +diff --git a/fpcsrc/ide/weditor.pas b/fpcsrc/ide/weditor.pas +index a777ee23..4b967438 100644 +--- a/fpcsrc/ide/weditor.pas ++++ b/fpcsrc/ide/weditor.pas +@@ -1076,7 +1076,7 @@ begin + BMFScan := NotFoundValue; + exit; + end; +- s2[0]:=chr(len); { sets the length to that of the search String } ++ SetLength(s2,len); { sets the length to that of the search String } + found:=False; + numb:=pred(len); + While (not found) and (numb=0) do +@@ -4802,8 +4802,13 @@ begin + end; + + procedure TCustomCodeEditor.BreakLine; ++var ++ SCP: TPoint; + begin +- NotImplemented; Exit; ++ { Like insert new line, but leave current pos unchanged } ++ SCP:=CurPos; ++ InsertNewLine; ++ SetCurPtr(SCP.X,SCP.Y); + end; + + procedure TCustomCodeEditor.BackSpace; +@@ -6800,8 +6805,7 @@ begin + S:=GetLineText(Line); + { Remove all traling spaces PM } + if not Editor^.IsFlagSet(efKeepTrailingSpaces) then +- While (Length(S)>0) and (S[Length(S)]=' ') do +- Dec(S[0]); ++ s:=RTrim(S,False); // removes trailing #0 too + { if FlagSet(efUseTabCharacters) then + S:=CompressUsingTabs(S,TabSize); + } +diff --git a/fpcsrc/ide/windebug.pas b/fpcsrc/ide/windebug.pas +index 1e06f126..8a067a7d 100644 +--- a/fpcsrc/ide/windebug.pas ++++ b/fpcsrc/ide/windebug.pas +@@ -36,7 +36,11 @@ implementation + {$ifndef NODEBUG} + + uses +- gdbint, ++ {$ifdef GDBMI} ++ gdbmiint, ++ {$else GDBMI} ++ gdbint, ++ {$endif GDBMI} + strings, + windows; + +diff --git a/fpcsrc/ide/wresourc.pas b/fpcsrc/ide/wresourc.pas +index 7005666a..b31bb34a 100644 +--- a/fpcsrc/ide/wresourc.pas ++++ b/fpcsrc/ide/wresourc.pas +@@ -780,6 +780,9 @@ begin + Fail; + End; + MyStream:=true; ++ {$ifdef HASAMIGA} ++ Flush; ++ {$endif} + end; + + constructor TResourceFile.LoadFile(AFileName: string); diff --git a/patches/fix-IDE-data-file-location.patch b/patches/fix-IDE-data-file-location.patch new file mode 100644 index 00000000..6ebba629 --- /dev/null +++ b/patches/fix-IDE-data-file-location.patch @@ -0,0 +1,69 @@ +Description: Align fp IDE template file paths with Debian standards + The fp IDE looks for template files in /usr/bin where itself is installed. + However this is not conform with Debian stadard for file locations. + This patch fixes this by making the IDE looking for templates in the base + installation directory. +Author: Abou Al Montacir +Index: fpc/fpcsrc/ide/fpmake.pp +=================================================================== +--- fpc.orig/fpcsrc/ide/fpmake.pp ++++ fpc/fpcsrc/ide/fpmake.pp +@@ -204,16 +204,16 @@ begin + T.Directory:='compiler'; + T.Install:=false; + +- P.InstallFiles.Add('fp.ans','$(bininstalldir)'); +- P.InstallFiles.Add('gplprog.pt','$(bininstalldir)'); +- P.InstallFiles.Add('gplunit.pt','$(bininstalldir)'); +- P.InstallFiles.Add('program.pt','$(bininstalldir)'); +- P.InstallFiles.Add('unit.pt','$(bininstalldir)'); +- P.InstallFiles.Add('cvsco.tdf','$(bininstalldir)'); +- P.InstallFiles.Add('cvsdiff.tdf','$(bininstalldir)'); +- P.InstallFiles.Add('cvsup.tdf','$(bininstalldir)'); +- P.InstallFiles.Add('grep.tdf','$(bininstalldir)'); +- P.InstallFiles.Add('tpgrep.tdf','$(bininstalldir)'); ++ P.InstallFiles.Add('fp.ans','$(baseinstalldir)/ide'); ++ P.InstallFiles.Add('gplprog.pt','$(baseinstalldir)/ide'); ++ P.InstallFiles.Add('gplunit.pt','$(baseinstalldir)/ide'); ++ P.InstallFiles.Add('program.pt','$(baseinstalldir)/ide'); ++ P.InstallFiles.Add('unit.pt','$(baseinstalldir)/ide'); ++ P.InstallFiles.Add('cvsco.tdf','$(baseinstalldir)/ide'); ++ P.InstallFiles.Add('cvsdiff.tdf','$(baseinstalldir)/ide'); ++ P.InstallFiles.Add('cvsup.tdf','$(baseinstalldir)/ide'); ++ P.InstallFiles.Add('grep.tdf','$(baseinstalldir)/ide'); ++ P.InstallFiles.Add('tpgrep.tdf','$(baseinstalldir)/ide'); + P.InstallFiles.Add('fp32.ico', [win32, win64], '$(bininstalldir)'); + + with P.Sources do +Index: fpc/fpcsrc/ide/fpini.pas +=================================================================== +--- fpc.orig/fpcsrc/ide/fpini.pas ++++ fpc/fpcsrc/ide/fpini.pas +@@ -178,12 +178,12 @@ begin + end; + {$endif WINDOWS} + {$else} +- SystemIDEDir:=FExpand(DirOf(system.paramstr(0))+'../lib/fpc/'+version_string+'/ide/text'); ++ SystemIDEDir:=FExpand(DirOf(system.paramstr(0))+'../lib/fpc/'+version_string+'/ide'); + If Not ExistsDir(SystemIDEdir) Then + begin +- SystemIDEDir:=FExpand(DirOf(system.paramstr(0))+'../lib64/fpc/'+version_string+'/ide/text'); ++ SystemIDEDir:=FExpand(DirOf(system.paramstr(0))+'../lib64/fpc/'+version_string+'/ide'); + If Not ExistsDir(SystemIDEdir) Then +- SystemIDEDir:='/usr/lib/fpc/'+version_string+'/ide/text'; ++ SystemIDEDir:='/usr/lib/fpc/'+version_string+'/ide'; + end; + IDEdir:=CompleteDir(FExpand('~/.fp')); + If Not ExistsDir(IDEdir) Then +Index: fpc/fpcsrc/ide/fptemplt.pas +=================================================================== +--- fpc.orig/fpcsrc/ide/fptemplt.pas ++++ fpc/fpcsrc/ide/fptemplt.pas +@@ -280,6 +280,7 @@ begin + New(Templates, Init(10,10)); + ScanDir('.'); + ScanDir(IDEDir); ++ ScanDir(SystemIDEDir); + end; + + diff --git a/patches/fix-encoding-of-localization-files-to-be-utf8.patch b/patches/fix-encoding-of-localization-files-to-be-utf8.patch new file mode 100644 index 00000000..bbc2b139 --- /dev/null +++ b/patches/fix-encoding-of-localization-files-to-be-utf8.patch @@ -0,0 +1,334 @@ +From: Abou Al Montacir +Date: Wed, 15 Jan 2014 21:49:04 +0100 +Subject: Change path of localization fies to fit Debian standard. (Closes: Bug#73368) +Bug-Debian: http://bugs.debian.org/73368 + +Index: fpc/fpcsrc/utils/fpdoc/intl/dglobals.de.po +=================================================================== +--- fpc.orig/fpcsrc/utils/fpdoc/intl/dglobals.de.po ++++ fpc/fpcsrc/utils/fpdoc/intl/dglobals.de.po +@@ -1,6 +1,6 @@ + #: dglobals:sdocpackagetitle + msgid "Reference for package '%s'" +-msgstr "Referenz für Paket '%s'" ++msgstr "Referenz für Paket '%s'" + + #: dglobals:sdocprograms + msgid "Programs" +@@ -12,7 +12,7 @@ msgstr "Units" + + #: dglobals:sdocunittitle + msgid "Reference for unit '%s'" +-msgstr "Referenz für Unit '%s'" ++msgstr "Referenz für Unit '%s'" + + #: dglobals:sdocinterfacesection + msgid "Interface section" +@@ -60,11 +60,11 @@ msgstr "Variablen" + + #: dglobals:sdocunitoverview + msgid "Overview of unit '%s'" +-msgstr "Überblick über Unit '%s'" ++msgstr "Überblick über Unit '%s'" + + #: dglobals:sdocoverview + msgid "Overview" +-msgstr "Überblick" ++msgstr "Überblick" + + #: dglobals:sdocsearch + msgid "Search" +@@ -104,11 +104,11 @@ msgstr "Bemerkung: " + + #: dglobals:sdocmethodoverview + msgid "Method overview" +-msgstr "Überblick über die Methoden" ++msgstr "Überblick über die Methoden" + + #: dglobals:sdocpropertyoverview + msgid "Property overview" +-msgstr "Überblick über die Eigenschaften" ++msgstr "Überblick über die Eigenschaften" + + #: dglobals:sdocpage + msgid "Page" +@@ -152,11 +152,11 @@ msgstr "Wert" + + #: dglobals:sdocexplanation + msgid "Explanation" +-msgstr "Erklärung" ++msgstr "Erklärung" + + #: dglobals:sdocvaluesforenum + msgid "Enumeration values for type %s" +-msgstr "Aufzählungswerte für Typ %s" ++msgstr "Aufzählungswerte für Typ %s" + + #: dglobals.sdocup + msgid "Up" +@@ -164,7 +164,7 @@ msgstr "Hoch" + + #: dglobals.sdocnext + msgid "Next" +-msgstr "Nächste" ++msgstr "Nächste" + + #: dglobals.sdocprevious + msgid "Previous" +Index: fpc/fpcsrc/utils/fpdoc/intl/dwriter.de.po +=================================================================== +--- fpc.orig/fpcsrc/utils/fpdoc/intl/dwriter.de.po ++++ fpc/fpcsrc/utils/fpdoc/intl/dwriter.de.po +@@ -4,23 +4,23 @@ msgstr "Beim Schreiben der Datei \"%s\" + + #: dwriter:serrinvalidshortdescr + msgid "Invalid short description" +-msgstr "Ungültige Kurzbeschreibung" ++msgstr "Ungültige Kurzbeschreibung" + + #: dwriter:serrinvaliddescr + msgid "Invalid description (illegal XML element: \"%s\")" +-msgstr "Ungültige Beschreibung (illegales XML-Element: \"%s\")" ++msgstr "Ungültige Beschreibung (illegales XML-Element: \"%s\")" + + #: dwriter:serrinvalidparacontent + msgid "Invalid paragraph content" +-msgstr "Ungültiger Absatzinhalt (in

-Element)" ++msgstr "Ungültiger Absatzinhalt (in

-Element)" + + #: dwriter:serrinvalidelementinlist + msgid "Invalid element in list - only \"li\" allowed" +-msgstr "Ungültiges Element in Liste - nur \"li\" ist erlaubt" ++msgstr "Ungültiges Element in Liste - nur \"li\" ist erlaubt" + + #: dwriter:serrinvalidlistcontent + msgid "Invalid list content" +-msgstr "Ungültiger Listeninhalt" ++msgstr "Ungültiger Listeninhalt" + + #: dwriter:serrlistisempty + msgid "List is empty - need at least one \"li\" element" +@@ -28,11 +28,11 @@ msgstr "Liste ist leer - brauche mindest + + #: dwriter:serrinvalidremarkcontent + msgid "Invalid content (illegal XML element: \"%s\")" +-msgstr "Ungültiger -Inhalt (illegales XML-Element: \"%s\")" ++msgstr "Ungültiger -Inhalt (illegales XML-Element: \"%s\")" + + #: dwriter:serrinvaliddefinitiontermcontent + msgid "Invalid content in definition term" +-msgstr "Ungültiger Inhalt in Definitionsterm" ++msgstr "Ungültiger Inhalt in Definitionsterm" + + #: dwriter:serrdefinitionentrymissing + msgid "Definition entry after definition term is missing" +@@ -40,11 +40,11 @@ msgstr "Definitionseintrag nach Definiti + + #: dwriter:serrtableinvalidbordervalue + msgid "Invalid \"border\" value for " +-msgstr "Ungültiger \"border\"-Wert für
" ++msgstr "Ungültiger \"border\"-Wert für
" + + #: dwriter:serrinvalidtablecontent + msgid "Invalid table content" +-msgstr "Ungültiger Tabelleninhalt" ++msgstr "Ungültiger Tabelleninhalt" + + #: dwriter:serrtablerowempty + msgid "Table row is empty (no \"td\" elements found)" +@@ -52,7 +52,7 @@ msgstr "Tabellenzeile ist leer (keine \" + + #: dwriter:serrinvalidcontentbeforesectiontitle + msgid "Invalid content before section title" +-msgstr "Ungültiger Inhalt vor Abschnittstitel" ++msgstr "Ungültiger Inhalt vor Abschnittstitel" + + #: dwriter:serrsectiontitleexpected + msgid "Section title (\"title\" element) expected" +@@ -76,5 +76,5 @@ msgstr "Warnung: Ziel-ID von " +-msgstr "Benötige einen Ausgabedateinamen, bitte geben Sie einen mit --output= an" ++msgstr "Benötige einen Ausgabedateinamen, bitte geben Sie einen mit --output= an" + + #: fpdoc:swritingpages + msgid "Writing %d pages..." +Index: fpc/fpcsrc/utils/fpdoc/intl/fpdocmk.de.po +=================================================================== +--- fpc.orig/fpcsrc/utils/fpdoc/intl/fpdocmk.de.po ++++ fpc/fpcsrc/utils/fpdoc/intl/fpdocmk.de.po +@@ -18,33 +18,33 @@ msgstr "" + + #: fpdocmk:stitle + msgid "FPDocMK - Makefile.fpc processor for Free Pascal Documentation Tool" +-msgstr "FPDocMK - Makefile.fpc-Prozessor für das " ++msgstr "FPDocMK - Makefile.fpc-Prozessor für das " + "Free-Pascal-Dokumentationswerkzeug" + + #: fpdocmk:scopyright + msgid "(c) 2003 Areca Systems GmbH / Sebastian Guenther, sg@freepascal.org" +-msgstr "(c) 2003 Areca Systems GmbH / Sebastian Günther, sg@freepascal.org" ++msgstr "(c) 2003 Areca Systems GmbH / Sebastian Günther, sg@freepascal.org" + + #: fpdocmk:scmdlinehelp + msgid "See documentation for usage." +-msgstr "Lesen Sie die Dokumentation für Infos zur Benutzung." ++msgstr "Lesen Sie die Dokumentation für Infos zur Benutzung." + + #: fpdocmk:scmdlineinvalidoption + msgid "Ignoring unknown option \"%s\"" +-msgstr "Ignoriere unbekannte Option »%s«" ++msgstr "Ignoriere unbekannte Option »%s«" + + #: fpdocmk:scmdlineinvalidformat + msgid "Invalid format \"%s\" specified" +-msgstr "Ungültiges Format »%s« gewählt" ++msgstr "Ungültiges Format »%s« gewählt" + + #: fpdocmk:scmdlineoutputoptionmissing + msgid "Need an output path or filename, please specify one with --output=" +-msgstr "Benötige einen Ausgabepfad oder -dateinamen; " ++msgstr "Benötige einen Ausgabepfad oder -dateinamen; " + "bitte geben Sie mit --output= einen an." + + #: fpdocmk:sneedpackagename + msgid "No package name specified. Please specify one using the --package option." +-msgstr "Kein Paketname gewählt. Bitte geben Sie mit der Option --package " ++msgstr "Kein Paketname gewählt. Bitte geben Sie mit der Option --package " + "einen an." + + #: fpdocmk:sdone +Index: fpc/fpcsrc/utils/fpdoc/intl/fpdocstr.de.po +=================================================================== +--- fpc.orig/fpcsrc/utils/fpdoc/intl/fpdocstr.de.po ++++ fpc/fpcsrc/utils/fpdoc/intl/fpdocstr.de.po +@@ -50,11 +50,11 @@ msgstr "Alias-Typ" + + #: fpdocstr:sptreetypealiastype + msgid "\"type\" alias type" +-msgstr "Alias-Typ »type«" ++msgstr "Alias-Typ »type«" + + #: fpdocstr:sptreeclassoftype + msgid "\"class of\" type" +-msgstr "»class-of«-Typ" ++msgstr "»class-of«-Typ" + + #: fpdocstr:sptreerangetype + msgid "Range type" +@@ -66,11 +66,11 @@ msgstr "Array-Typ" + + #: fpdocstr:sptreeenumvalue + msgid "Enumeration value" +-msgstr "Aufzählungswert" ++msgstr "Aufzählungswert" + + #: fpdocstr:sptreeenumtype + msgid "Enumeration type" +-msgstr "Aufzählungstyp" ++msgstr "Aufzählungstyp" + + #: fpdocstr:sptreesettype + msgid "Set type" +@@ -118,7 +118,7 @@ msgstr "Eigenschaft" + + #: fpdocstr:sptreeoverloadedprocedure + msgid "Overloaded procedure" +-msgstr "Überladene Prozedur" ++msgstr "Überladene Prozedur" + + #: fpdocstr:sptreeprocedure + msgid "Procedure" +@@ -138,7 +138,7 @@ msgstr "Destruktor" + + #: fpdocstr:sdocpackagetitle + msgid "Reference for package '%s'" +-msgstr "Referenz für das Paket »%s«" ++msgstr "Referenz für das Paket »%s«" + + #: fpdocstr:sdocprograms + msgid "Programs" +@@ -150,7 +150,7 @@ msgstr "Units" + + #: fpdocdef:sdocunittitle + msgid "Reference for unit '%s'" +-msgstr "Referenz für Unit »%s«" ++msgstr "Referenz für Unit »%s«" + + #: fpdocdef:sdocinterfacesection + msgid "Interface section" +@@ -166,7 +166,7 @@ msgstr "Verwendete Units" + + #: fpdocdef:sdocusedunitsbyunitxy + msgid "Used units by unit '%s'" +-msgstr "Von Unit »%s« verwendete Units" ++msgstr "Von Unit »%s« verwendete Units" + + #: fpdocdef:sdocconststypesvars + msgid "Constants, types and variables" +@@ -198,7 +198,7 @@ msgstr "Variablen" + + #: fpdocdef:sdocoverview + msgid "Overview" +-msgstr "Überblick" ++msgstr "Überblick" + + #: fpdocdef:sdocsearch + msgid "Search" +@@ -234,11 +234,11 @@ msgstr "Bemerkung: " + + #: fpdocstr:sdocmethodoverview + msgid "Method overview" +-msgstr "Überblick über die Methoden" ++msgstr "Überblick über die Methoden" + + #: fpdocstr:sdocpropertyoverview + msgid "Property overview" +-msgstr "Überblick über die Eigenschaften" ++msgstr "Überblick über die Eigenschaften" + + #: fpdocstr:sdocpage + msgid "Page" +Index: fpc/fpcsrc/utils/fpdoc/intl/makeskel.de.po +=================================================================== +--- fpc.orig/fpcsrc/utils/fpdoc/intl/makeskel.de.po ++++ fpc/fpcsrc/utils/fpdoc/intl/makeskel.de.po +@@ -1,10 +1,10 @@ + #: makeskel:stitle + msgid "MakeSkel - FPDoc skeleton XML description file generator" +-msgstr "MakeSkel - Skelett-Generator für FPDoc-XML-Beschreibungsdateien" ++msgstr "MakeSkel - Skelett-Generator für FPDoc-XML-Beschreibungsdateien" + + #: makeskel:scopyright + msgid "(c) 2000 - 2003 Areca Systems GmbH / Sebastian Guenther, sg@freepascal.org" +-msgstr "(c) 2000 - 2003 Areca Systems GmbH / Sebastian Günther, sg@freepascal.org" ++msgstr "(c) 2000 - 2003 Areca Systems GmbH / Sebastian Günther, sg@freepascal.org" + + #: makeskel:scmdlinehelp + msgid "See documentation for usage." diff --git a/patches/fix-spelling-errors-3.patch b/patches/fix-spelling-errors-3.patch new file mode 100644 index 00000000..10e7f69d --- /dev/null +++ b/patches/fix-spelling-errors-3.patch @@ -0,0 +1,29 @@ +Description: some more Lintian detection spelling misstakes +Author: Paul Gevers + +Index: fpc/fpcsrc/compiler/msg/errore.msg +=================================================================== +--- fpc.orig/fpcsrc/compiler/msg/errore.msg ++++ fpc/fpcsrc/compiler/msg/errore.msg +@@ -3064,7 +3064,7 @@ unit_u_check_time=10037_U_PPU Check file + #% the same conditionals are set for the recompiliation. The compiler has + #% found a conditional that was used the last time the unit was compiled, but + #% the conditional is currently not defined. +-unit_w_cant_compile_unit_with_changed_incfile=10040_W_Can't recompile unit $1, but found modifed include files ++unit_w_cant_compile_unit_with_changed_incfile=10040_W_Can't recompile unit $1, but found modified include files + % A unit was found to have modified include files, but + % some source files were not found, so recompilation is impossible. + unit_u_source_modified=10041_U_File $1 is newer than the one used for creating PPU file $2 +Index: fpc/fpcsrc/utils/fpcm/fpcmake.ini +=================================================================== +--- fpc.orig/fpcsrc/utils/fpcm/fpcmake.ini ++++ fpc/fpcsrc/utils/fpcm/fpcmake.ini +@@ -109,7 +109,7 @@ ifdef inUnix + PATHSEP=/ + else + PATHSEP:=$(subst /,\,/) +-# cygwin bash or sh can not handle backslashs ++# cygwin bash or sh can not handle backslashes + ifdef inCygWin + PATHSEP=/ + endif diff --git a/patches/fix-units-path-to-be-multi-arch-safe.patch b/patches/fix-units-path-to-be-multi-arch-safe.patch new file mode 100644 index 00000000..5e9938a8 --- /dev/null +++ b/patches/fix-units-path-to-be-multi-arch-safe.patch @@ -0,0 +1,71 @@ +From: Abou Al Montacir +Date: Sun, 12 Nov 2017 22:24:15 +0100 +Description: Change path of unit files to make it support MA co-installation. + (Closes: Bug#73368) +Bug-Debian: http://bugs.debian.org/73368 + +diff --git fpc.orig/fpcsrc/compiler/systems.pas fpc/fpcsrc/compiler/systems.pas +index 79339cc7..5a9ded18 100644 +--- fpc.orig/fpcsrc/compiler/systems.pas ++++ fpc/fpcsrc/compiler/systems.pas +@@ -357,7 +357,7 @@ interface + 'aarch64'); + + abiinfo : array[tabi] of tabiinfo = ( +- (name: 'DEFAULT'; supported: true), ++ (name: 'BASE'; supported: true), + (name: 'SYSV' ; supported:{$if defined(powerpc) or defined(powerpc64)}true{$else}false{$endif}), + (name: 'AIX' ; supported:{$if defined(powerpc) or defined(powerpc64)}true{$else}false{$endif}), + (name: 'EABI' ; supported:{$ifdef FPC_ARMEL}true{$else}false{$endif}), +diff --git a/fpcsrc/utils/fpcm/fpcmake.ini b/fpcsrc/utils/fpcm/fpcmake.ini +index 313b2807..2f27ade3 100644 +--- a/fpcsrc/utils/fpcm/fpcmake.ini ++++ b/fpcsrc/utils/fpcm/fpcmake.ini +@@ -330,6 +330,11 @@ endif + + export OS_TARGET OS_SOURCE ARCH CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE + ++ifndef DEB_HOST_MULTIARCH ++DEB_HOST_MULTIARCH=$(shell dpkg-architecture -qDEB_HOST_MULTIARCH) ++endif ++export DEB_HOST_MULTIARCH ++ + [fpmakefpcdetect] + ##################################################################### + # FPC Binary and Version Detection +@@ -407,7 +412,7 @@ ifeq ($(FPCDIR),wrong) + ifdef inUnix + override FPCDIR=/usr/local/lib/fpc/$(FPC_VERSION) + ifeq ($(wildcard $(FPCDIR)/units),) +-override FPCDIR=/usr/lib/fpc/$(FPC_VERSION) ++override FPCDIR=/usr/lib/${DEB_HOST_MULTIARCH}/fpc/$(FPC_VERSION) + endif + else + override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH)))))) +@@ -635,7 +640,7 @@ endif + ifndef INSTALL_BASEDIR + ifdef UNIXHier + ifdef INSTALL_FPCPACKAGE +-INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/fpc/$(FPC_VERSION) ++INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/${DEB_HOST_MULTIARCH}/fpc/$(FPC_VERSION) + else + INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/$(PACKAGE_NAME) + endif +@@ -678,7 +683,7 @@ endif + # Where to install shared libraries + ifndef INSTALL_LIBDIR + ifdef UNIXHier +-INSTALL_LIBDIR:=$(INSTALL_PREFIX)/lib ++INSTALL_LIBDIR:=$(INSTALL_PREFIX)/lib/${DEB_HOST_MULTIARCH} + else + INSTALL_LIBDIR:=$(INSTALL_UNITDIR) + endif +@@ -788,7 +793,7 @@ INSTALL_DATADIR=$(INSTALL_BASEDIR) + endif + + ifndef INSTALL_SHAREDDIR +-INSTALL_SHAREDDIR=$(INSTALL_PREFIX)/lib ++INSTALL_SHAREDDIR=$(INSTALL_PREFIX)/lib/${DEB_HOST_MULTIARCH} + endif + + ##################################################################### diff --git a/patches/fix_FTBFS_on_linux_not_amd64.patch b/patches/fix_FTBFS_on_linux_not_amd64.patch new file mode 100644 index 00000000..c24e4c6a --- /dev/null +++ b/patches/fix_FTBFS_on_linux_not_amd64.patch @@ -0,0 +1,26 @@ +Description: FPC 3.0.0rc1 FTBFS on all archs except ARMEL & AMD64 because + the linker can't find the appropriate symbols +Author: Edmund Grimley Evans +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=800811 +Source: http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/compiler/systems/t_linux.pas?r1=31675&r2=31980 + +Index: fpc/fpcsrc/compiler/systems/t_linux.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/systems/t_linux.pas ++++ fpc/fpcsrc/compiler/systems/t_linux.pas +@@ -151,6 +151,15 @@ begin + {$ifdef i386} + LibrarySearchPath.AddPath(sysrootpath,'/usr/lib/i386-linux-gnu',true); + {$endif i386} ++{$ifdef powerpc} ++ LibrarySearchPath.AddPath(sysrootpath,'/usr/lib/powerpc-linux-gnu',true); ++{$endif powerpc} ++{$ifdef powerpc64} ++ LibrarySearchPath.AddPath(sysrootpath,'/usr/lib/powerpc64-linux-gnu',true); ++{$endif powerpc64} ++{$ifdef aarch64} ++ LibrarySearchPath.AddPath(sysrootpath,'/usr/lib/aarch64-linux-gnu',true); ++{$endif aarch64} + end; + + {$ifdef m68k} diff --git a/patches/fix_make_files_generation.patch b/patches/fix_make_files_generation.patch new file mode 100644 index 00000000..72629148 --- /dev/null +++ b/patches/fix_make_files_generation.patch @@ -0,0 +1,96 @@ +From: Abou Al Montacir +Date: Sun, 04 Dec 2017 23:55:22 +0100 +Description: Fix sub directories in Makefile.fpc to allor recursive generation. + +diff --git a/fpcsrc/Makefile.fpc b/fpcsrc/Makefile.fpc +index 1435e4da..2878c9ab 100644 +--- a/fpcsrc/Makefile.fpc ++++ b/fpcsrc/Makefile.fpc +@@ -7,7 +7,7 @@ name=fpc + version=3.0.4 + + [target] +-dirs=compiler rtl utils packages ide installer ++dirs=compiler rtl utils packages ide installer tests + + [require] + nortl=y +diff --git a/fpcsrc/ide/Makefile.fpc b/fpcsrc/ide/Makefile.fpc +index 2be4d0d4..00d72705 100644 +--- a/fpcsrc/ide/Makefile.fpc ++++ b/fpcsrc/ide/Makefile.fpc +@@ -1,6 +1,9 @@ + # + # Makefile.fpc for running fpmake + # ++[target] ++dirs=fakegdb compiler ++ + [require] + packages=rtl fpmkunit + +diff --git a/fpcsrc/packages/Makefile.fpc b/fpcsrc/packages/Makefile.fpc +index 3174426c..9a9fc3ad 100644 +--- a/fpcsrc/packages/Makefile.fpc ++++ b/fpcsrc/packages/Makefile.fpc +@@ -2,6 +2,9 @@ + # + # Makefile.fpc for Free Pascal Packages + # ++[target] ++dirs= paszlib fcl-process hash libtar fpmkunit ++ + [require] + packages=rtl + +diff --git a/fpcsrc/utils/Makefile.fpc b/fpcsrc/utils/Makefile.fpc +index a24242b9..575cefb6 100644 +--- a/fpcsrc/utils/Makefile.fpc ++++ b/fpcsrc/utils/Makefile.fpc +@@ -1,6 +1,9 @@ + # + # Makefile.fpc for running fpmake + # ++[target] ++dirs=fpcm debugsvr dxegen fpcmkcfg fpcreslipo fpcres fpdoc fppkg fprcp h2pas importtl instantfpc mksymbian pas2fpm pas2jni pas2js pas2ut rmwait tply unicode ++ + [require] + packages=rtl fpmkunit fcl-json + +diff --git a/fpcsrc/utils/fpcm/fpmake.pp b/fpcsrc/utils/fpcm/fpmake.pp +index 7a7b0ba4..639d8040 100644 +--- a/fpcsrc/utils/fpcm/fpmake.pp ++++ b/fpcsrc/utils/fpcm/fpmake.pp +@@ -223,7 +223,7 @@ begin + {$endif ALLPACKAGES} + P.Version:='3.0.4'; + +- P.Dependencies.Add('fcl-base'); ++ //P.Dependencies.Add('fcl-base'); + + T:=P.Targets.AddProgram('fpcmake.pp'); + +diff --git a/fpcsrc/tests/Makefile.fpc b/fpcsrc/tests/Makefile.fpc +index 949dbc8d..b98444d8 100644 +--- a/fpcsrc/tests/Makefile.fpc ++++ b/fpcsrc/tests/Makefile.fpc +@@ -10,6 +10,7 @@ fpcdir=.. + rule=allexectests + + [target] ++dirs=tstunits utils + programs=gparmake + + [rules] +diff --git a/fpcsrc/tests/utils/Makefile.fpc b/fpcsrc/tests/utils/Makefile.fpc +index 89d39c75..f5592172 100644 +--- a/fpcsrc/tests/utils/Makefile.fpc ++++ b/fpcsrc/tests/utils/Makefile.fpc +@@ -13,6 +13,7 @@ fpcdir=../.. + nortl=y + + [target] ++dirs=testsuite + programs=dotest fptime fail testfail digest concat $(DBDIGEST) $(MSDOSPROG) + programs_win32=prepup + programs_win64=prepup diff --git a/patches/fix_mips_mipsel_lazarus_FTBFS.patch b/patches/fix_mips_mipsel_lazarus_FTBFS.patch new file mode 100644 index 00000000..74ba7818 --- /dev/null +++ b/patches/fix_mips_mipsel_lazarus_FTBFS.patch @@ -0,0 +1,19 @@ +Description: Lazarus FTBFS on mips and mipsel with: + Error: Architecture mips is not available for elf format + lazbuild.lpr(1871) Error: (9029) Error while compiling resources + It seems like those archs are just missing to be defined +Author: Peter Green and Paul Gevers + +Index: fpc/fpcsrc/utils/fpcres/target.pas +=================================================================== +--- fpc.orig/fpcsrc/utils/fpcres/target.pas ++++ fpc/fpcsrc/utils/fpcres/target.pas +@@ -100,7 +100,7 @@ var + (name : 'elf'; ext : '.or'; machines : [mti386,mtx86_64,mtppc, + mtppc64,mtarm,mtarmeb, + mtm68k,mtsparc,mtalpha, +- mtaarch64]), ++ mtaarch64,mtmips,mtmipsel]), + (name : 'coff'; ext : '.o'; machines : [mti386,mtx86_64,mtarm, + mtppc,mtppc64]), + (name : 'xcoff'; ext : '.o'; machines : [mtppc{,mtppc64}]), diff --git a/patches/fix_powerpc_ftbfs_with_new_glibc.patch b/patches/fix_powerpc_ftbfs_with_new_glibc.patch new file mode 100644 index 00000000..08144279 --- /dev/null +++ b/patches/fix_powerpc_ftbfs_with_new_glibc.patch @@ -0,0 +1,41 @@ +Description: fp-compiler is not installable on powerpc since glibc 2.23 and + segfaults, this patch is a combination of patches. +Source: http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/rtl/unix/dl.pp?r1=34368&r2=34365&pathrev=34368 +Source: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=826300#131 +Author: florian +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=826300 +Bug: http://bugs.freepascal.org/view.php?id=29594 + +Index: fpc/fpcsrc/rtl/unix/dl.pp +=================================================================== +--- fpc.orig/fpcsrc/rtl/unix/dl.pp ++++ fpc/fpcsrc/rtl/unix/dl.pp +@@ -31,8 +31,9 @@ const + {$define ELF} // ELF symbol versioning. + {$endif} + +-{$if defined(linux) and defined(cpuarm)} +-{ arm-linux seems to require this } ++{$if defined(linux) and (defined(cpuarm) or defined(cpupowerpc))} ++{ some linux targets seem to require this, if libc is not linked ++ the wrong start up code is used } + {$linklib c} + {$endif} + +--- a/fpcsrc/rtl/linux/powerpc/cprt0.as ++++ b/fpcsrc/rtl/linux/powerpc/cprt0.as +@@ -88,12 +88,8 @@ main_stub: + .globl _haltproc + .type _haltproc, @function + _haltproc: +- lis 11, ___fpc_ret@ha +- lwz 1, ___fpc_ret@l(11) +- addi 1, 1, 16 +- lwz 0, 0(1) +- mtlr 0 +- blr ++ bl _exit ++ b _haltproc + + # li 0, 1 /* exit call */ + # lis 3, operatingsystem_result@h diff --git a/patches/fix_source_location_for_documentation.patch b/patches/fix_source_location_for_documentation.patch new file mode 100644 index 00000000..e5a919a0 --- /dev/null +++ b/patches/fix_source_location_for_documentation.patch @@ -0,0 +1,285 @@ +Index: fpc/fpcdocs/fcl-project.xml +=================================================================== +--- fpc.orig/fpcdocs/fcl-project.xml ++++ fpc/fpcdocs/fcl-project.xml +@@ -14,44 +14,44 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -95,7 +95,7 @@ + + + +- ++ + + + +Index: fpc/fpcdocs/rtl-project.xml +=================================================================== +--- fpc.orig/fpcdocs/rtl-project.xml ++++ fpc/fpcdocs/rtl-project.xml +@@ -14,95 +14,95 @@ + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + diff --git a/patches/fix_tests_for_make_print_directory.patch b/patches/fix_tests_for_make_print_directory.patch new file mode 100644 index 00000000..f28f7714 --- /dev/null +++ b/patches/fix_tests_for_make_print_directory.patch @@ -0,0 +1,18 @@ +Description: apparently the default Make incantation on Debian prints the + change of directory, which causes the test suite to fail on + "Error: Can't open make[1]:.pp" +Author: Paul Gevers + +Index: fpc/fpcsrc/tests/Makefile.fpc +=================================================================== +--- fpc.orig/fpcsrc/tests/Makefile.fpc ++++ fpc/fpcsrc/tests/Makefile.fpc +@@ -508,7 +508,7 @@ $(MAKEINC): $(GPARMAKE) $(TEST_OUTPUTDIR + # used subdirectory. Note also that the index must be increasing for each + # new call with a gap insuring that all the previous files have lower index + # even if CHUNKSIZE is equal to 1. +- $(MAKE) -s -f createlst.mak "TESTDIRS=$(TESTDIRS)" > testfilelist.lst ++ $(MAKE) --no-print-directory -s -f createlst.mak "TESTDIRS=$(TESTDIRS)" > testfilelist.lst + $(Q)$(GPARMAKE) $(MAKEINC) test 1 $(CHUNKSIZE) @testfilelist.lst + $(Q)$(GPARMAKE) -a $(MAKEINC) tbs 10000 $(CHUNKSIZE) $(sort $(wildcard tbs/t*.pp)) + $(Q)$(GPARMAKE) -a $(MAKEINC) tbf 15000 $(CHUNKSIZE) $(sort $(wildcard tbf/t*.pp)) diff --git a/patches/fix_texpfncase_test.patch b/patches/fix_texpfncase_test.patch new file mode 100644 index 00000000..ca2e732c --- /dev/null +++ b/patches/fix_texpfncase_test.patch @@ -0,0 +1,26 @@ +From 2c185394f13c44992c7348b64b3514030781668b Mon Sep 17 00:00:00 2001 +From: pierre +Date: Mon, 2 Feb 2015 21:49:36 +0000 +Subject: [PATCH] Fix for failures on FileNameCaseSensitive systems + +git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@29609 3ad0048d-3df7-0310-abae-a5850022a9f2 +--- + tests/test/units/sysutils/texpfncase.pp | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/tests/test/units/sysutils/texpfncase.pp b/tests/test/units/sysutils/texpfncase.pp +index 3a6e1cac73..a4adf805e7 100644 +--- a/fpcsrc/tests/test/units/sysutils/texpfncase.pp ++++ b/fpcsrc/tests/test/units/sysutils/texpfncase.pp +@@ -57,8 +57,9 @@ procedure TestExpFNC (const FN1, ExpReturn: string; ExpMatch: TFilenameCaseMatch + Match: TFilenameCaseMatch; + begin + FN2 := ExpandFileNameCase (FN1, Match); +- if ((ExpReturn <> '') and (FN2 <> ExpReturn) or (Match <> ExpMatch)) and +- not(FileNameCaseSensitive and (Match=mkAmbiguous) and (UpperCase(FN2)<>UpperCase(ExpReturn))) then ++ if (Match <> ExpMatch) or ((ExpReturn <> '') and (FN2 <> ExpReturn) and ++ ((Match <> mkAmbiguous) or not (FileNameCaseSensitive) or ++ (UpperCase (FN2) <> UpperCase (ExpReturn)))) then + begin + Inc (Failed); + WriteLn ('Error: Input = ', FN1, ', Output = ', FN2, ' (expected ', ExpReturn, '), MatchFound = ', diff --git a/patches/further-arm64-fixes.patch b/patches/further-arm64-fixes.patch new file mode 100644 index 00000000..3bcb908c --- /dev/null +++ b/patches/further-arm64-fixes.patch @@ -0,0 +1,118 @@ +Description: + Further arm64 changes taken from the fixes_3_0_ios branch after add-arm64-patch + . + This seems to fix the startup crash of the textmode ide. + . + Generated with + . + svn diff http://svn.freepascal.org/svn/fpc/branches/fixes_3_0_ios@32015 http://svn.freepascal.org/svn/fpc/branches/fixes_3_0_ios@34101 > ../fpc-svnbranchdiff +cat ../fpc-svnbranchdiff | filterdiff -p0 '-icompiler/aarch64/*' --addoldprefix=a/fpcsrc/ --addnewprefix=b/fpcsrc/ | filterdiff -p1 -xfpcsrc/compiler/aarch64/symcpu.pas > debian/patches/further-arm64-fixes.patch + . + The changes in symcpu.pas were excluded because they +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=830906 + +--- a/fpcsrc/compiler/aarch64/cgcpu.pas (revision 32015) ++++ b/fpcsrc/compiler/aarch64/cgcpu.pas (revision 34101) +@@ -813,7 +813,7 @@ + if fromsize in [OS_64,OS_S64] then + begin + { split into two 32 bit loads } +- hreg1:=makeregsize(register,OS_32); ++ hreg1:=getintregister(list,OS_32); + hreg2:=getintregister(list,OS_32); + if target_info.endian=endian_big then + begin +@@ -832,6 +832,7 @@ + inc(href.offset,4); + a_load_ref_reg(list,OS_32,OS_32,href,hreg2); + end; ++ a_load_reg_reg(list,OS_32,OS_64,hreg1,register); + list.concat(taicpu.op_reg_reg_const_const(A_BFI,register,makeregsize(hreg2,OS_64),32,32)); + end + else +@@ -1116,8 +1117,9 @@ + if fromsize in [OS_64,OS_S64] then + begin + { split into two 32 bit stores } +- hreg1:=makeregsize(register,OS_32); ++ hreg1:=getintregister(list,OS_32); + hreg2:=getintregister(list,OS_32); ++ a_load_reg_reg(list,OS_32,OS_32,makeregsize(register,OS_32),hreg1); + a_op_const_reg_reg(list,OP_SHR,OS_64,32,register,makeregsize(hreg2,OS_64)); + if target_info.endian=endian_big then + begin +@@ -1341,7 +1343,7 @@ + + procedure tcgaarch64.a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: topcg; size: tcgsize; src1, src2, dst: tregister; setflags : boolean; var ovloc : tlocation); + var +- tmpreg1: tregister; ++ tmpreg1, tmpreg2: tregister; + begin + ovloc.loc:=LOC_VOID; + { overflow can only occur with 64 bit calculations on 64 bit cpus } +@@ -1361,9 +1363,7 @@ + ovloc.resflags:=F_CC + else + ovloc.resflags:=F_VS; +- { finished; since we won't call through to a_op_reg_reg_reg, +- adjust the result here if necessary } +- maybeadjustresult(list,op,size,dst); ++ { finished } + exit; + end; + OP_MUL: +@@ -1378,17 +1378,22 @@ + end; + OP_IMUL: + begin +- { check whether the sign bit of the (128 bit) result is the +- same as "sign bit of src1" xor "signbit of src2" (if so, no +- overflow and the xor-product of all sign bits is 0) } ++ { check whether the upper 64 bits of the 128 bit multiplication ++ result have the same value as the replicated sign bit of the ++ lower 64 bits } + tmpreg1:=getintregister(list,OS_64); + list.concat(taicpu.op_reg_reg_reg(A_SMULH,tmpreg1,src2,src1)); +- list.concat(taicpu.op_reg_reg_reg(A_EOR,tmpreg1,tmpreg1,src1)); +- list.concat(taicpu.op_reg_reg_reg(A_EOR,tmpreg1,tmpreg1,src2)); +- list.concat(taicpu.op_reg_const(A_TST,tmpreg1,$80000000)); ++ { calculate lower 64 bits (afterwards, because dst may be ++ equal to src1 or src2) } ++ a_op_reg_reg_reg(list,op,size,src1,src2,dst); ++ { replicate sign bit } ++ tmpreg2:=getintregister(list,OS_64); ++ a_op_const_reg_reg(list,OP_SAR,OS_S64,63,dst,tmpreg2); ++ list.concat(taicpu.op_reg_reg(A_CMP,tmpreg1,tmpreg2)); + ovloc.loc:=LOC_FLAGS; + ovloc.resflags:=F_NE; +- { still have to perform the actual multiplication } ++ { finished } ++ exit; + end; + OP_IDIV, + OP_DIV: +--- a/fpcsrc/compiler/aarch64/ncpucnv.pas (revision 32015) ++++ b/fpcsrc/compiler/aarch64/ncpucnv.pas (revision 34101) +@@ -163,6 +163,10 @@ + exit; + + case left.location.loc of ++ LOC_SUBSETREG, ++ LOC_CSUBSETREG, ++ LOC_SUBSETREF, ++ LOC_CSUBSETREF, + LOC_CREFERENCE, + LOC_REFERENCE, + LOC_REGISTER, +--- a/fpcsrc/compiler/aarch64/hlcgcpu.pas (revision 32015) ++++ b/fpcsrc/compiler/aarch64/hlcgcpu.pas (revision 34101) +@@ -136,7 +136,8 @@ + begin + if slopt in [SL_SETZERO,SL_SETMAX] then + inherited +- else if not(sreg.bitlen in [32,64]) then ++ else if not(sreg.bitlen in [32,64]) or ++ (sreg.startbit<>0) then + begin + makeregssamesize(list,def_cgsize(fromsize),sreg.subsetregsize,fromreg,sreg.subsetreg,fromreg,toreg); + list.concat(taicpu.op_reg_reg_const_const(A_BFI,toreg,fromreg,sreg.startbit,sreg.bitlen)) diff --git a/patches/honor_SOURCE_DATE_EPOCH_in_date.patch b/patches/honor_SOURCE_DATE_EPOCH_in_date.patch new file mode 100644 index 00000000..b348d22b --- /dev/null +++ b/patches/honor_SOURCE_DATE_EPOCH_in_date.patch @@ -0,0 +1,51 @@ +Description: Reproducible builds requires that the build time stamp is not + recorded in binaries. In FPC they are fuild in via the $INCLUDE %DATE% + directive which calls getdatestr in globals.pas. To allow reproducible builds + we should honor the SOURCE_DATE_EPOCH environment variable. To not depend on + the dateutil unit, we include the required code from that package here. +Author: Paul Gevers +Author: Abou Al Montacir + +Index: fpc/fpcsrc/compiler/globals.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/globals.pas ++++ fpc/fpcsrc/compiler/globals.pas +@@ -510,6 +510,7 @@ interface + starttime : real; + + function getdatestr:string; ++ Function UnixToDateTime(const AValue: Int64): TDateTime; + function gettimestr:string; + function filetimestring( t : longint) : string; + function getrealtime : real; +@@ -766,11 +767,29 @@ implementation + } + var + Year,Month,Day: Word; ++ SourceDateEpoch: string; + begin +- DecodeDate(Date,year,month,day); ++ SourceDateEpoch := GetEnvironmentVariable('SOURCE_DATE_EPOCH'); ++ if Length(SourceDateEpoch)>0 then ++ DecodeDate(UnixToDateTime(StrToInt64(SourceDateEpoch)),year,month,day) ++ else ++ DecodeDate(Date,year,month,day); + getdatestr:=L0(Year)+'/'+L0(Month)+'/'+L0(Day); + end; + ++ Function UnixToDateTime(const AValue: Int64): TDateTime; ++ { Code copied from fpcsrc/packages/rtl-objpas/src/inc/dateutil.inc and ++ fpcsrc/rtl/objpas/sysutils/datih.inc } ++ const ++ TDateTimeEpsilon = 2.2204460493e-16 ; ++ UnixEpoch = TDateTime(-2415018.5) + TDateTime(2440587.5) ; ++ begin ++ Result:=UnixEpoch + AValue/SecsPerDay; ++ if (UnixEpoch>=0) and (Result<-TDateTimeEpsilon) then ++ Result:=int(Result-1.0+TDateTimeEpsilon)-frac(1.0+frac(Result)) ++ else if (UnixEpoch<=-1.0) and (Result>-1.0+TDateTimeEpsilon) then ++ Result:=int(Result+1.0-TDateTimeEpsilon)+frac(1.0-abs(frac(1.0+Result))); ++ end; + + function filetimestring( t : longint) : string; + { diff --git a/patches/let_ppudump_honor_TZ_var.patch b/patches/let_ppudump_honor_TZ_var.patch new file mode 100644 index 00000000..fe8c8471 --- /dev/null +++ b/patches/let_ppudump_honor_TZ_var.patch @@ -0,0 +1,82 @@ +Description: for diffoscope (part of the reproducible builds project) it is + required that dates shown by ppudump don't depend on the local timezone. In + order to achieve that ppudump should honor the TZ environment + variable. Upstream updated the code to achieve that. +Source: http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/rtl/unix/timezone.inc?r1=32369&r2=32368&view=patch + +Index: fpc/fpcsrc/rtl/unix/timezone.inc +=================================================================== +--- fpc.orig/fpcsrc/rtl/unix/timezone.inc ++++ fpc/fpcsrc/rtl/unix/timezone.inc +@@ -119,6 +119,19 @@ begin + GetLocalTimezone(timer,lc,lh); + end; + ++Const ++ DefaultTimeZoneDir = '/usr/share/zoneinfo'; ++ ++function TimeZoneDir : ShortString; ++ ++begin ++ // Observe TZDIR environment variable. ++ TimeZoneDir:=fpgetenv('TZDIR'); ++ if TimeZoneDir='' then ++ TimeZoneDir:=DefaultTimeZoneDir; ++ if TimeZoneDir[length(TimeZoneDir)]<>'/' then ++ TimeZoneDir:=TimeZoneDir+'/'; ++end; + + procedure ReadTimezoneFile(fn:shortstring); + +@@ -192,14 +205,7 @@ begin + if fn='' then + fn:='localtime'; + if fn[1]<>'/' then +- begin +- tzdir:=fpgetenv('TZDIR'); +- if tzdir='' then +- tzdir:='/usr/share/zoneinfo'; +- if tzdir[length(tzdir)]<>'/' then +- tzdir:=tzdir+'/'; +- fn:=tzdir+fn; +- end; ++ fn:=TimeZoneDir+fn; + f:=fpopen(fn,Open_RdOnly); + if f<0 then + exit; +@@ -269,7 +275,7 @@ Const + AltTimeZoneFile = '/usr/lib/zoneinfo/localtime'; // Other + iOSTimeZoneFile = '/var/db/timezone/localtime'; // iOS + {$ifdef BSD} +- BSDTimeZonefile = '/usr/share/zoneinfo'; // BSD usually is POSIX ++ BSDTimeZonefile = DefaultTimeZoneDir; // BSD usually is POSIX + // compliant though + {$ENDIF} + +@@ -278,10 +284,25 @@ Const + function GetTimezoneFile:shortstring; + var + f,len : longint; +- s : shortstring; ++ fn,s : shortstring; + info : stat; + begin + GetTimezoneFile:=''; ++ // Observe TZ variable. ++ fn:=fpgetenv('TZ'); ++ if (fn<>'') then ++ if (fn[1]=':') then ++ begin ++ Delete(fn,1,1); ++ if (fn<>'') then ++ begin ++ if (fn[1]<>'/') then ++ Exit(TimeZoneDir+fn); ++ Exit(fn); ++ end; ++ end; ++ if (fn='') then ++ fn:=TimeZoneLocationFile; + f:=fpopen(TimeZoneLocationFile,Open_RdOnly); + if f>0 then + begin diff --git a/patches/ppdep-fix-else-handling.patch b/patches/ppdep-fix-else-handling.patch new file mode 100644 index 00000000..5a4ec4e2 --- /dev/null +++ b/patches/ppdep-fix-else-handling.patch @@ -0,0 +1,18 @@ +Description: Off-by one error +Author: Michalis Kamburelis +Bug: http://bugs.freepascal.org/view.php?id=31007 +Bug-Debian: https://bugs.debian.org/845504 + +Index: fpc/fpcsrc/utils/ppdep.pp +=================================================================== +--- fpc.orig/fpcsrc/utils/ppdep.pp ++++ fpc/fpcsrc/utils/ppdep.pp +@@ -344,7 +344,7 @@ begin + hs^:=''; + end + else +- if (Copy(hs^,2,6)='$ELSE') then ++ if (Copy(hs^,2,5)='$ELSE') then + begin + skip[level]:=skip[level-1] or (not skip[level]); + hs^:=''; diff --git a/patches/prevent_date_in_fpcMakefiles.patch b/patches/prevent_date_in_fpcMakefiles.patch new file mode 100644 index 00000000..d3acc785 --- /dev/null +++ b/patches/prevent_date_in_fpcMakefiles.patch @@ -0,0 +1,18 @@ +Description: Timestamps in fpc Makefiles are hindering reproducible builds + Don't add the Date to the header of Makefiles generated by fpcmake +Author: Paul Gevers +Forwarded: no + +Index: fpc/fpcsrc/utils/fpcm/fpcmwr.pp +=================================================================== +--- fpc.orig/fpcsrc/utils/fpcm/fpcmwr.pp ++++ fpc/fpcsrc/utils/fpcm/fpcmwr.pp +@@ -722,7 +722,7 @@ implementation + begin + { Header } + Add('#'); +- Add('# Don''t edit, this file is generated by '+TitleDate); ++ Add('# Don''t edit, this file is generated by '+Title); + Add('#'); + if FInput.HasVariable('default_rule') then + Add('default: '+FInput.GetVariable('default_rule',false)) diff --git a/patches/prevent_date_in_fpcdocs.patch b/patches/prevent_date_in_fpcdocs.patch new file mode 100644 index 00000000..deba8017 --- /dev/null +++ b/patches/prevent_date_in_fpcdocs.patch @@ -0,0 +1,17 @@ +Description: Timestamps in fpc documentation are hindering reproducible builds + Don't add the date to the footer of docs generated by fpdoc +Author: Paul Gevers +Forwarded: no +Index: fpc/fpcdocs/Makefile.fpc +=================================================================== +--- fpc.orig/fpcdocs/Makefile.fpc ++++ fpc/fpcdocs/Makefile.fpc +@@ -115,7 +115,7 @@ ifeq ($(HIDEPROTECTED),YES) + FCLOPTS+= --hide-protected + endif + +-FPDOCHTMLOPTS=--footer-date="mmm dd yyyy" ++FPDOCHTMLOPTS= + + ifeq (chm,$(HTMLFMT)) + HTMLSUFFIX:=.chm diff --git a/patches/relpath.patch b/patches/relpath.patch new file mode 100644 index 00000000..bd954691 --- /dev/null +++ b/patches/relpath.patch @@ -0,0 +1,76 @@ +This patch adds an utility for computing relative path according to a given +base directory. This is useful for libraries that are to install .lpk in +order to be used with lazarus. As these libraries may be compiled without +need to build depend on Lazarus, we add it in fp-utils package which is likely +to be used by any big project which build depends on fp-compiler. + +Index: fpc/fpcsrc/utils/relpath.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/utils/relpath.pas +@@ -0,0 +1,16 @@ ++program relpath; ++uses ++ SysUtils; ++ ++var ++ BaseDir: string; ++ TargetDir: string; ++begin ++ TargetDir := ParamStr(1); ++ BaseDir := ParamStr(2); ++ if BaseDir = '' ++ then begin ++ BaseDir := GetCurrentDir; ++ end; ++ WriteLn(ExtractRelativePath(IncludeTrailingPathDelimiter(BaseDir), TargetDir)); ++end. +Index: fpc/install/man/man1/relpath.1 +=================================================================== +--- /dev/null ++++ fpc/install/man/man1/relpath.1 +@@ -0,0 +1,32 @@ ++.TH relpath 1 "7 May 2013" "Free Pascal" "Relative path computing tool" ++.SH NAME ++relpath \- The Free Pascal file deletion tool. ++ ++.SH SYNOPSIS ++ ++.B relpath ++[\fIfile or directory\fR] [\fIbase directory\fR] ++ ++.SH DESCRIPTION ++ ++.B relpath ++This is an utility for computing relative path according to a given base ++directory. This is useful for libraries that are to install .lpk in order to be ++used with lazarus. As these libraries may be compiled without need to build ++depend on Lazarus, we add it in fp-utils package which is likely to be used by ++any big project which build depends on fp-compiler. ++ ++.SH USAGE ++ ++.B relpath ++takes the following arguments: ++.TP ++.B file or directory ++The target file or directory for which relative path should be computed. ++.TP ++.B base directory ++The base directory according to which the relative patch should be computed. ++ ++.SH SEE ALSO ++.IP ++.BR readlink (1) +Index: fpc/fpcsrc/utils/fpmake.pp +=================================================================== +--- fpc.orig/fpcsrc/utils/fpmake.pp ++++ fpc/fpcsrc/utils/fpmake.pp +@@ -84,6 +84,7 @@ begin + P.Targets.AddProgram('mkinsadd.pp'); + P.Targets.AddProgram('postw32.pp'); + P.Targets.AddProgram('rmcvsdir.pp'); ++ P.Targets.AddProgram('relpath.pas'); + P.Targets.AddProgram('grab_vcsa.pp',[linux]); + T:=P.Targets.AddProgram('fpcsubst.pp'); + T.Dependencies.AddUnit('usubst'); diff --git a/patches/remove-depreciated-ncursus-variables-declaration.patch b/patches/remove-depreciated-ncursus-variables-declaration.patch new file mode 100644 index 00000000..5178fea6 --- /dev/null +++ b/patches/remove-depreciated-ncursus-variables-declaration.patch @@ -0,0 +1,25 @@ +Description: Removed declaration of legacy ncursus variables. + These variables are now internal and no more exported by new ncursus libraries. +Author: Abou Al Montacir +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=789091 + +diff --git a/fpcsrc/packages/ncurses/src/form.pp b/fpcsrc/packages/ncurses/src/form.pp +index a930b75a..136a8d2f 100644 +--- a/fpcsrc/packages/ncurses/src/form.pp ++++ b/fpcsrc/packages/ncurses/src/form.pp +@@ -232,15 +232,6 @@ var + TYPE_IPV4 : PFIELDTYPE external libform name 'TYPE_IPV4'; + {$endif darwin} + +-(* Default objects *) +-{$ifndef darwin} +- _nc_Default_Form : PFORM;cvar;external; +- _nc_Default_Field : PFIELD;cvar;external; +-{$else darwin} +- _nc_Default_Form : PFORM external libform name '_nc_Default_Form'; +- _nc_Default_Field : PFIELD external libform name '_nc_Default_Field'; +-{$endif darwin} +- + (* FIELDTYPE routines *) + function new_fieldtype(field_check: TFieldCheck; char_check:TCharCheck):PFIELDTYPE; cdecl;external libform; + diff --git a/patches/rename-instantfpc-to-ifpc.patch b/patches/rename-instantfpc-to-ifpc.patch new file mode 100644 index 00000000..60c2f4de --- /dev/null +++ b/patches/rename-instantfpc-to-ifpc.patch @@ -0,0 +1,174 @@ +This patch renames instantfpc to ifpc (Instant Free Pascal Compiler) and adds +man files for it. + +Index: fpc/install/man/man1/ifpc.1 +=================================================================== +--- /dev/null ++++ fpc/install/man/man1/ifpc.1 +@@ -0,0 +1,54 @@ ++.TH ifpc 1 "18 May 2013" "Free Pascal" "Instant pascal code interpreter" ++.SH NAME ++ifpc \- The Free Pascal Interpreter. ++ ++.SH SYNOPSIS ++ ++.B ifpc ++[\fI\-h\fR] [\fI\-v\fR] [\fIcompiler options\fR] <\fIsource file\fR> ++[\fIprogram parameters\fR] ++ ++.SH DESCRIPTION ++ ++.B ifpc ++This is a pascal code interpreter program. It compiles source and runs the ++ generated program. ++ ++Source is compared with the cache. If cache is not valid then then source is ++copied to cache with the shebang line commented and cached source is compiled. ++If compilation fails the fpc output is written to stdout and and exit code 1 ++is returned ++If compilation was successful the program is executed. ++If the compiler options contains \-B the program is always recompiled. ++If the environment option INSTANTFPCOPTIONS is set it is passed to compiler as ++the first parameters. ++ ++.SH USAGE ++ ++.B ifpc ++takes the following arguments: ++.TP ++.B \-h ++Prints this help message and exit. ++.TP ++.B \-v ++Prints version and exit. ++.TP ++.B \-\-get\-cache ++Prints current cache directory and exit. ++.TP ++.B \-\-set\-cache= ++Set the cache to be used. Otherwise using environment variable INSTANTFPCCACHE. ++.TP ++.B \-\-compiler= ++Normally fpc is searched in PATH and used as compiler. ++.TP ++.B \-\-skip\-run ++Do not execute the program. Useful to test if script compiles ++.TP ++.B \-B ++Always recompile. ++ ++.SH SEE ALSO ++.IP ++.BR fpc (1) +Index: fpc/fpcsrc/utils/instantfpc/instantfpc.pas +=================================================================== +--- fpc.orig/fpcsrc/utils/instantfpc/instantfpc.pas ++++ fpc/fpcsrc/utils/instantfpc/instantfpc.pas +@@ -28,39 +28,40 @@ const + Version = '1.3'; + // 1.3 compile in a separate directory, so that parallel invocations do not overwrite link.res files + ++var ++ BinPath, BinName: string; + + Procedure Usage(Err : string); +- + begin + if (Err<>'') then + Writeln('Error : ',Err); +- writeln('instantfpc '+Version); ++ writeln(BinName, ' ', Version); + writeln; + writeln('Run pascal source files as scripts.'); + writeln('Normal usage is to add to a program source file a first line'); +- writeln('("shebang") "#!/usr/bin/instantfpc".'); ++ writeln('("shebang") "#!', BinPath, BinName, '".'); + writeln('Then you can execute the source directly in the terminal/console.'); + writeln; +- writeln('instantfpc -h'); ++ writeln(BinName, ' -h'); + writeln(' Print this help message and exit.'); + writeln; +- writeln('instantfpc -v'); ++ writeln(BinName, ' -v'); + writeln(' Print version and exit.'); + writeln; +- writeln('instantfpc [compiler options] [program parameters]'); ++ writeln(BinName, ' [compiler options] [program parameters]'); + writeln(' Compiles source and runs program.'); + writeln(' Source is compared with the cache. If cache is not valid then'); + writeln(' source is copied to cache with the shebang line commented and'); + writeln(' cached source is compiled.'); + writeln(' If compilation fails the fpc output is written to stdout and'); +- writeln(' instantfpc exits with error code 1.'); ++ writeln(' ', BinName, ' exits with error code 1.'); + writeln(' If compilation was successful the program is executed.'); + writeln(' If the compiler options contains -B the program is always'); + writeln(' compiled.'); + writeln(' If the environment option INSTANTFPCOPTIONS is set it is'); + writeln(' passed to the compiler as first parameters.'); + writeln; +- writeln('instantfpc --get-cache'); ++ writeln(BinName, ' --get-cache'); + writeln(' Prints current cache directory and exit.'); + writeln; + writeln('Options:'); +@@ -106,7 +107,7 @@ begin + if (P='') then exit; + if p='-v' then + begin +- writeln('instantfpc '+Version); ++ writeln(BinName, ' ', Version); + Halt(1); + end + else if p='-h' then +@@ -139,6 +140,8 @@ begin + { For example: + /usr/bin/instantfpc -MObjFpc -Sh ./envvars.pas param1 + } ++ BinPath := ExtractFilePath(ParamStr(0)); ++ BinName := 'ifpc'; + for i:=1 to Paramcount do + begin + p:=ParamStr(i); +Index: fpc/fpcsrc/utils/instantfpc/Makefile.fpc +=================================================================== +--- fpc.orig/fpcsrc/utils/instantfpc/Makefile.fpc ++++ fpc/fpcsrc/utils/instantfpc/Makefile.fpc +@@ -3,7 +3,7 @@ + # + + [package] +-name=instantfpc ++name=ifpc + version=3.0.4 + + [require] +Index: fpc/fpcsrc/utils/instantfpc/ifpc.pas +=================================================================== +--- /dev/null ++++ fpc/fpcsrc/utils/instantfpc/ifpc.pas +@@ -0,0 +1 @@ ++{$INCLUDE instantfpc.pas} +Index: fpc/fpcsrc/utils/instantfpc/fpmake.pp +=================================================================== +--- fpc.orig/fpcsrc/utils/instantfpc/fpmake.pp ++++ fpc/fpcsrc/utils/instantfpc/fpmake.pp +@@ -15,7 +15,7 @@ begin + With Installer do + begin + P:=AddPackage('utils-instantfpc'); +- P.ShortName:='instantfpc'; ++ P.ShortName:='ifpc'; + + P.Author := ''; + P.License := 'LGPL with modification'; +@@ -32,7 +32,7 @@ begin + + P.OSes := [win32,win64,wince,haiku,linux,freebsd,openbsd,netbsd,darwin,iphonesim,solaris,aix]; + +- T:=P.Targets.AddProgram('instantfpc.pas'); ++ T:=P.Targets.AddProgram('ifpc.pas'); + T.Dependencies.AddUnit('instantfptools'); + + P.Targets.AddUnit('instantfptools.pas').Install:=False; diff --git a/patches/series b/patches/series new file mode 100644 index 00000000..cf55c0e9 --- /dev/null +++ b/patches/series @@ -0,0 +1,32 @@ +version.diff +fix-FPCDIR-in-fpcmake.diff +relpath.patch +rename-instantfpc-to-ifpc.patch +use-bfd-explicitly.diff +change-path-of-localization-files-to-fit-Debian-standar.patch +fix-encoding-of-localization-files-to-be-utf8.patch +prevent_date_in_fpcMakefiles.patch +prevent_date_in_fpcdocs.patch +disable_building_gnome1_and_gtk1.patch +fix-IDE-data-file-location.patch +fix_FTBFS_on_linux_not_amd64.patch +add-arm64-support.patch +honor_SOURCE_DATE_EPOCH_in_date.patch +let_ppudump_honor_TZ_var.patch +after_patch_arm64_systems.pas.patch +armhf-tags.patch +fix_powerpc_ftbfs_with_new_glibc.patch +further-arm64-fixes.patch +ppdep-fix-else-handling.patch +armhf-fix-vstr-vld-offset.patch +fix_source_location_for_documentation.patch +fix-spelling-errors-3.patch +fix_tests_for_make_print_directory.patch +fix_mips_mipsel_lazarus_FTBFS.patch +remove-depreciated-ncursus-variables-declaration.patch +drop-jsminifier-from-build-as-we-strip-it.patch +create-directory-before-copy-in-Makefile.fpc.patch +fix_texpfncase_test.patch +fix-units-path-to-be-multi-arch-safe.patch +fix_make_files_generation.patch +fix-IDE-GDB-support.patch diff --git a/patches/use-bfd-explicitly.diff b/patches/use-bfd-explicitly.diff new file mode 100644 index 00000000..1128831d --- /dev/null +++ b/patches/use-bfd-explicitly.diff @@ -0,0 +1,32 @@ +Description: Use ld.bfd explicitly + Freepascal is broken with ld.gold, previously we conflicted with binutils-gold + but that makes us uninstallable with the new binutils. + + So instead we take the approach of patching fpc to use ld.bfd directly +Author: Peter Michael Green +Bug-Debian: http://bugs.debian.org/620815 +Bug-Debian: http://bugs.debian.org/624525 +Bug-Debian: http://bugs.debian.org/717651 + +Index: fpc/fpcsrc/compiler/systems/t_linux.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/systems/t_linux.pas ++++ fpc/fpcsrc/compiler/systems/t_linux.pas +@@ -1097,7 +1097,7 @@ begin + if HasExports then + cmdstr:=cmdstr+' -E'; + +- success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false); ++ success:=DoExec(FindUtil(utilsprefix+BinStr)+'.bfd',CmdStr,true,false); + + { Create external .dbg file with debuginfo } + if success and (cs_link_separate_dbg_file in current_settings.globalswitches) then +@@ -1152,7 +1152,7 @@ begin + Replace(cmdstr,'$INIT',InitStr); + Replace(cmdstr,'$FINI',FiniStr); + Replace(cmdstr,'$SONAME',SoNameStr); +- success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false); ++ success:=DoExec(FindUtil(utilsprefix+binstr)+'.bfd',cmdstr,true,false); + + { Strip the library ? } + if success and (cs_link_strip in current_settings.globalswitches) then diff --git a/patches/version.diff b/patches/version.diff new file mode 100644 index 00000000..2a17d62a --- /dev/null +++ b/patches/version.diff @@ -0,0 +1,29 @@ +This patch adds Debian build version to compiler full version. + +Index: fpc/fpcsrc/compiler/version.pas +=================================================================== +--- fpc.orig/fpcsrc/compiler/version.pas ++++ fpc/fpcsrc/compiler/version.pas +@@ -84,6 +84,9 @@ function full_version_string:string; + + implementation + ++const ++ FullVersionString={$INCLUDE version.inc}; ++ + function version_string:string; + begin + version_string := version_nr+'.'+release_nr+'.'+patch_nr; +@@ -92,11 +95,7 @@ end; + + function full_version_string:string; + begin +- full_version_string := version_nr+'.'+release_nr+'.'+patch_nr+minorpatch +-{$ifdef REVINC} +- +'-r'+{$i revision.inc} +-{$endif REVINC} +- ; ++ full_version_string := FullVersionString; + end; + + end. diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 00000000..c0b46843 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1 @@ +[type: gettext/rfc822deb] fp-compiler.templates.in diff --git a/po/cs.po b/po/cs.po new file mode 100644 index 00000000..20053a96 --- /dev/null +++ b/po/cs.po @@ -0,0 +1,127 @@ +# Czech PO debconf template translation of fpc. +# Copyright (C) 2012 Michal Simunek +# This file is distributed under the same license as the fpc package. +# Michal Simunek , 2012 - 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: fpc 2.6.2-6\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2014-06-12 10:02+0200\n" +"Last-Translator: Michal Simunek \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "Přejmenovat \"/etc/fpc.cfg\" na \"/etc/fpc.cfg.bak\"?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"FPC nyní podporuje možnost mít na stejném systému nainstalováno vícero " +"verzí. Příkazem update-alternatives lze nastavit výchozí verze pro\n" +" * fpc (kompilátor);\n" +" * fpc.cfg (konfigurační soubor);\n" +" * fp-utils (pomocné nástroje)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Bez ohledu na to, že si můžete vybrat výchozí verzi, jsou konfigurační " +"soubory vždy zpětně kompatibilní, takže by mělo být vždy bezpečné použít " +"nejnovější verzi." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"Pokud chcete, aby se v systému pro konfigurační soubor FPC používal systém " +"alternativ, musíte přijmout přejmenování souboru \"/etc/fpc.cfg\"; jinak " +"bude nutné, aby jste si jej spravovali sami." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Výchozí kompilátor zdrojových souborů .rc pro MS Windows:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"FPC podporuje kompilování programů založených na zdrojových souborech MS " +"Windows ve formátu .rc." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"V případě, že chcete mít možnost kompilovat projekty používající soubory ." +"rc, budete v první řadě muset ručně nainstalovat balíček mingw32-binutils. " +"mingw32-binutils je navrhován kompilátorem fp-compiler, ale automaticky jej " +"neinstaluje." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Pokud chcete vložit vlastní kompilátor souborů .rc, který se na tomto " +"seznamu nenachází, nebo pokud tuto funkci chcete prostě zakázat, zvolte " +"prosím \"Select manually\"." + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Pokud výchozí kompilátor souborů .rc nechcete používat, ponechte políčko " +"prázdné." diff --git a/po/da.po b/po/da.po new file mode 100644 index 00000000..8dd4af06 --- /dev/null +++ b/po/da.po @@ -0,0 +1,126 @@ +# Danish translation fpc. +# Copyright (c) 2014 fpc & nedenstÃ¥ende oversættere. +# This file is distributed under the same license as the fpc package. +# Joe Hansen , 2012, 2013, 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: fpc\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2014-10-04 17:30+01:00\n" +"Last-Translator: Joe Hansen \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "Omdøb »/etc/fpc.cfg« til »/etc/fpc.cfg.bak«?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"FPC understøtter nu at der er installeret flere versioner pÃ¥ det samme " +"system. Kommandoen update-alternatives kan bruges til at angive en " +"standardversion for\n" +" * fpc (kompileren);\n" +" * fpc.cfg (konfigurationsfilen);\n" +" * fp-utils (hjælpeværktøjerne)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Uanset versionen du vælger som standard, sÃ¥ er konfigurationsfilerne altid " +"bagud kompatible, sÃ¥ det bør være sikkert at bruge den seneste version." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"For at bruge systemet for alternativerne pÃ¥ den for hele systemet brugte FPC-" +"konfigurationsfil, sÃ¥ skal du acceptere omdøbelse af »/etc/fpc.cfg«; ellers " +"skal du selv hÃ¥ndtere dette manuelt." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "Vælg manuelt" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Standard for MS Windows .rc-ressourcekompiler:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"FPC understøtter kompilering af programmer, som indlejrer ressourcer som MS " +"Windows .rc-format-filer pÃ¥ alle platforme hvor MinGW windres-værktøjet er " +"tilgængeligt." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"For at kunne kompilere projekter med brug af .rc-filer, sÃ¥ skal du først " +"manuelt installere pakken mingw32-binutils. Mingw32-binutils foreslÃ¥s af fp-" +"compiler men installeres ikke automatisk." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Hvis du ønsker at indtaste en tilpasset .rc-fil-kompiler, som ikke fremgÃ¥r " +"af denne liste eller hvis du simpelthen ønsker at deaktivere denne funktion, " +"sÃ¥ vælg »Vælg manuelt«." + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Hvis du ikke ønsker at bruge en standard .rc-fil-kompiler, sÃ¥ efterland tom." diff --git a/po/de.po b/po/de.po new file mode 100644 index 00000000..954a8604 --- /dev/null +++ b/po/de.po @@ -0,0 +1,128 @@ +# Translation of the fpc debconf template to German. +# Copyright (C) 1999 Peter Vreman. +# This file is distributed under the same license as the fpc package. +# Copyright of this file Chris Leick 2012-2014. +# +msgid "" +msgstr "" +"Project-Id-Version: fpc 2.6.4+dfsg-4\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2014-10-02 18:05+0100\n" +"Last-Translator: Chris Leick \n" +"Language-Team: de \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "»/etc/fpc.cfg« in »/etc/fpc.cfg.bak« umbenennen?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"FPC unterstützt nun mehrere auf demselben System installierte Versionen. Der " +"Befehl »update-alternatives« kann zum Setzen einer Standardversion für\n" +" * fpc (den Compiler),\n" +" * fpc.cfg (die Konfigurationsdatei) und\n" +" * fp-utils (die Hilfswerkzeuge)\n" +"benutzt werden." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Egal welche Version als Vorgabe gewählt wird, die Konfigurationsdateien sind " +"immer abwärtskompatibel, so dass die Verwendung der neuesten Version stets " +"sicher möglich sein sollte." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"Um das Alternatives-System auf die systemweite Konfigurationsdatei " +"anzuwenden, müssen Sie dem Umbenennen von »/etc/fpc.cfg« zustimmen, " +"andernfalls müssen Sie dies selbst verwalten." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "Manuelle Auswahl" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Standard-Compiler für .rc-Ressourcen unter MS Windows:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"FPC unterstützt Kompilierprogramme, die Ressourcen als Dateien im .rc-Format " +"von MS Windows auf allen Plattformen einbetten, auf denen das MinGW-Windres-" +"Werkzeug verfügbar ist." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"Um Projekte mittels .rc-Dateien kompilieren zu können, müssen Sie zuerst das " +"Paket »mingw32-binutils« manuell installieren. »mingw32-binutils« wird durch " +"»fp-compiler« vorgeschlagen, aber nicht automatisch bezogen." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Falls Sie einen benutzerdefinierten Compiler für .rc-Dateien eingeben " +"möchten, der nicht in dieser Liste erscheint oder falls Sie diese " +"Funktionalität deaktivieren wollen, wählen Sie bitte »Manuelle Auswahl«." + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Falls Sie keinen Standard-Compiler für .rc-Dateien verwenden möchten, lassen " +"Sie dies leer." diff --git a/po/es.po b/po/es.po new file mode 100644 index 00000000..d0e6aca3 --- /dev/null +++ b/po/es.po @@ -0,0 +1,155 @@ +# fpc translation to Spanish +# Copyright (C) 2012 Software in the Public Interest, SPI Inc. +# This file is distributed under the same license as the fpc package. +# +# Changes: +# - Initial translation +# Matías Bellone , 2012 +# +# - Updates +# Matías Bellone , 2013 +# +# Traductores, si no conoce el formato PO, merece la pena leer la +# documentación de gettext, especialmente las secciones dedicadas a este +# formato, por ejemplo ejecutando: +# info -n '(gettext)PO Files' +# info -n '(gettext)Header Entry' +# +# Equipo de traducción al español, por favor lean antes de traducir +# los siguientes documentos: +# +# - El proyecto de traducción de Debian al español +# http://www.debian.org/intl/spanish/ +# especialmente las notas y normas de traducción en +# http://www.debian.org/intl/spanish/notas +# +# - La guía de traducción de po's de debconf: +# /usr/share/doc/po-debconf/README-trans +# o http://www.debian.org/intl/l10n/po-debconf/README-trans +# +# Si tiene dudas o consultas sobre esta traducción consulte con el último +# traductor (campo Last-Translator) y ponga en copia a la lista de +# traducción de Debian al español () +# +msgid "" +msgstr "" +"Project-Id-Version: fpc\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2013-12-03 19:06-0300\n" +"Last-Translator: Matías Bellone \n" +"Language-Team: Debian L10N Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "¿Desea renombrar «/etc/fpc.cfg» a «/etc/fpc.cfg.bak»?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"FPC ahora puede tener múltiples versiones instaladas en el mismo sistema. " +"Puede utilizar la orden «update-alternatives» para definir la versión " +"predeterminada de: * fpc (el compilador);\n" +" * fpc.cfg (el archivo de configuración);\n" +" * fp-utils (las heramientas de ayuda)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Los archivos de configuración siempre son compatibles con versiones " +"anteriores sin importar la versión que elija como predeterminada, por lo que " +"siempre debería ser seguro utilizar la última versión." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"Debe aceptar cambiar el nombre de «/etc/fpc.cfg» para utilizar el sistema de " +"alternativas en la configuración de FPC para todo el equipo, de lo contrario " +"deberá administrarlo a mano por su cuenta." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "Seleccionar manualmente" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Compilador predeterminado de recursos .rc de MS Windows:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"FPC puede compilar programas que incluyen recursos en archivos con formato ." +"rc de MS Windows en todas las plataformas en las que esté disponible la " +"herramienta «windres» de MinGW." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"Para poder compilar proyectos que utilizan archivos .rc, primero debe " +"instalar el paquete mingw32-binutils. El paquete fp-compiler sugiere el " +"paquete mingw32-binutils, pero no se lo instalará automáticamente." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Si desea utilizar un compilador de archivos .rc personalizado que no se " +"encuentra en esta lista o si desea desactivar esta funcionalidad, seleccione " +"«Seleccionar manualmente»." + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Si no desea utilizar un compilador de archivos .rc predeterminado, deje este " +"valor vacío." diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 00000000..c7f47fae --- /dev/null +++ b/po/fr.po @@ -0,0 +1,131 @@ +# Translation of fpc debconf templates to French +# Copyright (C) 2012, 2013 Debian French l10n team +# This file is distributed under the same license as the fpc package. +# +# David Prévot , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: fpc\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2013-11-14 17:34-0400\n" +"Last-Translator: David Prévot \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Lokalize 1.4\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "Faut-il renommer « /etc/fpc.cfg » en « /etc/fpc.cfg.bak » ?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"Plusieurs versions de FPC peuvent maintenant être installées sur le même " +"système. La commande update-alternatives permet de définir une version par " +"défaut pour :\n" +" - fpc (le compilateur) ;\n" +" - fpc.cfg (le fichier de configuration) ;\n" +" - fp-utils (les outils d'assistance)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Quelle que soit la version choisie par défaut, les fichiers de configuration " +"sont toujours rétrocompatibles, il devrait donc être toujours possible " +"d'utiliser la dernière version." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"Afin d’utiliser le système d’alternatives pour le fichier de configuration " +"global de FPC, vous devez accepter de renommer « /etc/fpc.cfg », sinon vous " +"devrez gérer cela vous-même." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "Sélectionnez vous-même" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Compilateur de ressources .rc MS Windows par défaut :" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"FPC permet de compiler des programmes contenant des ressources au format .rc " +"de MS Windows sur toutes les plateformes où l’outil MinGW windres est " +"disponible." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"Pour pouvoir compiler des projets utilisant des fichiers .rc, vous devez " +"d’abord installer vous-même le paquet mingw32-binutils. Ce paquet est en " +"effet seulement suggéré par fp-compiler et n’est donc pas installé par " +"défaut." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Pour sélectionner un compilateur de fichiers .rc personnalisé qui n’est pas " +"présent dans cette liste, ou simplement pour désactiver cette " +"fonctionnalité, veuillez choisir « Sélectionnez vous-même »." + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Si vous ne voulez pas utiliser de compilateur de fichiers .rc par défaut, " +"laissez ce champ vide." diff --git a/po/hu.po b/po/hu.po new file mode 100644 index 00000000..7b13b22c --- /dev/null +++ b/po/hu.po @@ -0,0 +1,125 @@ +# Italian translation of fpc debconf messages. +# Copyright (C) 2012, Beatrice Torracca +# This file is distributed under the same license as the fpc package. +# Beatrice Torracca , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: \n" +"Last-Translator: Péter Gábor \n" +"Language-Team: Magyar (Hungarian)\n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "\"/etc/fpc.cfg\" átnevezése erre: \"/etc/fpc.cfg.bak\"?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"Az FPC támogatja több változat egyidejű telepítését ugyanarra a gépre. Az " +"update-alternatives parancs használható az alapértelmezett változat " +"kiválasztására a következőkhöz:\n" +" * fpc (a fordító);\n" +" * fpc.cfg (a beállítások fájlja);\n" +" * fp-utils (a segédeszközök)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Bármely változatot szeretné alapértelmezetté tenni, a beállítási fájlok " +"mindig visszafelé kompatibilisek, így nyugodtan használhatja a legutóbbit." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"Az alternatív FPC beállítások rendszerének egész rendszerre kiterjedő " +"használatához el kell fogadnia a(z) \"/etc/fpc.cfg\" fájl átnevezését; " +"máskülönben saját kezűleg kell ezt kiviteleznie." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Alapértelmezett MS Windows .rc erőforrásfordító:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"Az FPC támogatja olyan programok fordítását, melyek beágyazott MS Windows ." +"rc formátumú erőforrásfájlokat tartalmaznak, minden olyan platformon ahol a " +"MinGW windres eszköz elérhető." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"Olyan projektek fordításához, melyek .rc fájlokat használnak, kézzel kell " +"telepítenie a mingw32-binutils csomagot. A mingw32-binutils ajánlott az fp-" +"compiler csomaghoz, de nincs automatikusan telepítve." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Ha egyéni .rc fájl fordítót szeretne, mely nem szerepel e listában vagy " +"egyszerűen nem szeretné használni e lehetőséget, válassza a \"Kézi " +"kiválasztás\"-t!" + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "Ha nincs szüksége alapértelmezett .rc fájl fordítóra, hagyja üresen!" diff --git a/po/it.po b/po/it.po new file mode 100644 index 00000000..2df5374e --- /dev/null +++ b/po/it.po @@ -0,0 +1,129 @@ +# Italian translation of fpc debconf messages. +# Copyright (C) 2014, fpc's package copyright holder +# This file is distributed under the same license as the fpc package. +# Beatrice Torracca , 2012, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: fpc\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2014-10-01 13:31+0200\n" +"Last-Translator: Beatrice Torracca \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Virtaal 0.7.1\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "Rinominare «/etc/fpc.cfg» in «/etc/fpc.cfg.bak»?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"FPC permette adesso di avere più versioni installate sullo stesso sistema. " +"Il comando update-alternatives può essere usato per impostare una versione " +"predefinita per\n" +" * fpc (il compilatore);\n" +" * fpc.cfg (il file di configurazione);\n" +" * fp-utils (gli strumenti ausiliari)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Indipendentemente da quale versione si scelga come predefinita, i file di " +"configurazione sono sempre compatibili all'indietro, perciò dovrebbe in ogni " +"caso essere sicuro scegliere di usare la versione più recente." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"Per usare il sistema di alternative per il file di configurazione FPC a " +"livello di sistema, si deve accettare di rinominare «/etc/fpc.cfg»; in caso " +"contrario si dovrà gestire la cosa da soli manualmente." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "Selezione manuale" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Compilatore predefinito di risorse .rc di MS Windows:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"FPC permette la compilazione di programmi che incorporano risorse come file " +"in formato .rc di MS Windows su tutte le piattaforme su cui è disponibile lo " +"strumento MinGW windres." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"Per poter compilare i progetti che usano file .rc, è necessario installare " +"prima manualmente il pacchetto mingw32-binutils. mingw32-binutils è " +"suggerito da fp-compiler, ma non viene richiamato automaticamente." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Se si desidera indicare un compilatore di file .rc personalizzato che non " +"appare in questo elenco o se si desidera semplicemente disabilitare questa " +"funzionalità, selezionare «Selezione manuale»" + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Se non si desidera usare un compilatore di file .rc predefinito, lasciare " +"vuoto questo campo." diff --git a/po/ja.po b/po/ja.po new file mode 100644 index 00000000..74997d6e --- /dev/null +++ b/po/ja.po @@ -0,0 +1,126 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the fpc package. +# victory , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: fpc\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2014-09-22 03:49+0900\n" +"Last-Translator: victory \n" +"Language-Team: Japanese \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "「/etc/fpc.cfg」を「/etc/fpc.cfg.bak」に変更しますか?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"FPC は現在同一システムに複数バージョンが混在することをサポートしています。" +"update-alternatives コマンドを使って、以下のファイルにデフォルトのバージョン" +"をセットすることが可能です\n" +" * fpc (コンパイラ)\n" +" * fpc.cfg (設定ファイル)\n" +" * fp-utils (補助ツール)" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"デフォルトにどのバージョンを選んでも、設定ファイルは常に後方互換なので、最新" +"版の使用はいつでも安全です。" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"システムワイドの FPC 設定ファイルにより代替システムを使用する場合、「/etc/" +"fpc.cfg」ファイルの改名を受け入れないといけません。受け入れない場合は手作業で" +"自ら管理する必要があります。" + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "手作業で指定する" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "デフォルトの MS Windows .rc リソースコンパイラ:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"FPC は MS Windows の .rc 形式のファイルにリソースを埋め込んだプログラムの、" +"MinGW windres ツールが利用できるあらゆるプラットフォーム上でのコンパイルをサ" +"ポートしています。" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +".rc ファイルを使っているプロジェクトをコンパイルできるようにするためにはまず " +"mingw32-binutils パッケージを手作業でインストールする必要があります。mingw32-" +"binutils は fp-compiler で提案されていますが自動的にインストールはされませ" +"ん。" + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"一覧に表示されない独自の .rc ファイルのコンパイラを指定したい、あるいはこの機" +"能を単に無効化したい場合は、「手作業で指定する」を選択ください。" + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"デフォルトの .rc ファイルコンパイラを使いたくない場合は空白にしてください。" diff --git a/po/nl.po b/po/nl.po new file mode 100644 index 00000000..faf35641 --- /dev/null +++ b/po/nl.po @@ -0,0 +1,130 @@ +# Dutch translation of the fpc debconf templates. +# Copyright (C) 2014 Debian Pascal team +# This file is distributed under the same license as the fpc package. +# Paul Gevers , 2014 +# +msgid "" +msgstr "" +"Project-Id-Version: fpc\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2014-09-29 21:12+0100\n" +"Last-Translator: Paul Gevers \n" +"Language-Team: Debian Dutch l10n Team \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Dutch\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "Hernoem \"/etc/fpc.cfg\" naar \"/etc/fpc.cfg.bak\"?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"FPC ondersteunt het nu dat meerdere versies simultaan geïnstalleerd zijn. " +"Het commando update-alternatives kan gebruikt worden om de standaardversie " +"in te stellen voor:\n" +" * fpc (de compiler)\n" +" * fpc.cfg (het configuratiebestand)\n" +" * fp-utils (de hulpgereedschappen)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Welke versie u ook als standaard kiest, de configuratiebestanden zijn altijd " +"achterwaarts verenigbaar. Het zou dus altijd veilig moeten zijn om de " +"laatste versie te gebruiken." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"Als u het alternatieven-systeem wilt gebuiken voor het systeembrede " +"configuratiebestand van FPC, dan is het noodzakelijk dat u het hernoemen van " +"\"/etc/fpc.cfg\" accepteert. Als u dat niet doet, zult u dit handmatig " +"moeten afhandelen." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "Handmatig selecteren" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Standaardcompiler voor MS-Windows .rc-bronnen:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"Op alle platformen waar MinGW windres beschikbaar is, ondersteunt FPC het " +"compileren van programma's die bronnen inbouwen als MS-Windowsbestanden van " +"het \".rc\" formaat." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"Om projecten te kunnen compileren die gebruik maken van .rc-bestanden, is " +"het nodig dat het pakket mingw32-binutils is geïnstalleerd. mingw32-binutils " +"wordt gesuggereerd door fp-compiler maar wordt niet automatisch geselecteerd " +"voor installatie." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Selecteer \"Handmatig selecteren\" als u een compiler voor .rc-bestanden " +"wilt invoeren die niet in de lijst voorkomt of als u deze functionaliteit " +"simpelweg wilt uitschakelen." + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Laat dit leeg als u geen standaardcompiler voor .rc-bestanden wilt gebruiken." diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 00000000..b7aabd6c --- /dev/null +++ b/po/pl.po @@ -0,0 +1,132 @@ +# Translation of fpc debconf templates to Polish. +# Copyright (C) 2012 +# This file is distributed under the same license as the fpc package. +# +# Michał Kułach , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: fpc\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2013-11-20 20:50+0100\n" +"Last-Translator: Michał Kułach \n" +"Language-Team: Polish \n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 1.4\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "Zmienić nazwę pliku \"/etc/fpc.cfg\" na \"/etc/fpc.cfg.bak\"?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"FPC obsługuje obecnie instalację wielu wersji w tym samym systemie. " +"Polecenie update-alternatives może zostać użyte do wybrania domyślnej wersji " +"do\n" +" * fpc (kompilatora),\n" +" * fpc.cfg (pliku konfiguracyjnego),\n" +" * fp-utils (narzędzi pomocniczych)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Niezależnie od wyboru wersji domyślnej, pliki konfiguracyjne są zawsze " +"wstecznie kompatybilne, więc korzystanie z najnowszej wersji powinno być " +"całkowicie bezpieczne." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"Aby używać systemu alternatyw na poziomie systemowego pliku konfiguracyjnego " +"FPC, konieczne jest zaakceptowanie zmiany nazwy \"/etc/fpc.cfg\" - w " +"przeciwnym razie konieczne będzie samodzielne zarządzanie wspomnianym " +"plikiem." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "Wybierz ręcznie" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Domyślny kompilator zasobu .rc MS Windows:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"FPC obsługuje programy kompilujące które osadzają zasoby w formacie .rc MS " +"Windows na wszystkich platformach na których dostępne jest narzędzie MinGW " +"windres." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"Aby móc kompilować projekty za pomocą plików .rc konieczna jest uprzednia " +"ręczna instalacja pakietu mingw32-binutils. Jest to zależność pakietu " +"mingw32-binutils na poziomie \"poleca\", lecz nie jest ona wybierana " +"automatycznie." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Aby wprowadzić własny kompilator plików .rc nie uwidoczniony na tej liście " +"lub aby wyłączyć tę funkcję, proszę wybrać \"Wybierz ręcznie\"." + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Jeśli nie chce się używać domyślnego kompilatora plików .rc, należy " +"pozostawić to pole puste." diff --git a/po/pt.po b/po/pt.po new file mode 100644 index 00000000..649c3dbe --- /dev/null +++ b/po/pt.po @@ -0,0 +1,131 @@ +# Portuguese translation for fpc's debconf messages +# Copyright (C) 2012 the fpc's copyright holder +# This file is distributed under the same license as the fpc package. +# +# Rui Branco , 2012. +# Américo Monteiro , 2013. +msgid "" +msgstr "" +"Project-Id-Version: fpc >2.6.2-6\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2013-11-27 21:05+0000\n" +"Last-Translator: Américo Monteiro \n" +"Language-Team: Portuguese \n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 1.4\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "Alterar o nome de \"/etc/fpc.cfg\" para \"/etc/fpc.cfg.bak\"?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"O FPC suporta agora múltiplas versões instaladas no mesmo sistema. O comando " +"update-alternatives pode ser utilizado para definir a versão predefinida " +"para\n" +" * fpc (o compilador)\n" +" * fpc.cfg (o ficheiro do configuração)\n" +" * fp-utils (as ferramentas de ajuda)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Qualquer que seja a versão que escolha como predefinição, os ficheiros de " +"configuração são sempre compatíveis com anteriores, deste modo deverá ser " +"sempre seguro usar a versão mais recente." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"De modo a usar o sistema de alternativas abrangendo todo o sistema, deverá " +"aceitar a mudança de nome do ficheiro de configuração do FPC, para \"/etc/" +"fpc.cfg\"; de outro modo terá que você fazê-lo manualmente." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "Seleccionar Manualmente" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Compilador predefinido de recursos .rc do MS Windows:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"O FPC suporta compilar programas que têm embebidos recursos como ficheiros " +"de formato .rc do MS Windows em todas as plataformas onde a ferramenta MinGW " +"windres esteja disponível." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"De modo a ser capaz de compilar projectos que usem ficheiros .rc, primeiro " +"precisa de instalar manualmente o pacote mingw32-binutils. O mingw32-" +"binutils é sugerido pelo fp-compiler mas não adicionado automaticamente." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Se desejar adicionar um compilador personalizado de ficheiros .rc que não " +"aparece nesta lista ou se simplesmente deseja desactivar esta " +"funcionalidade, por favor escolha \"Seleccionar Manualmente\"." + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Se não deseja usar um compilador predefinido de ficheiros .rc, deixe isto em " +"vazio." diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100644 index 00000000..8510e078 --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,128 @@ +# Debconf translations for fpc. +# Copyright (C) 2014 fpc's COPYRIGHT HOLDER +# This file is distributed under the same license as the fpc package. +# José de Figueiredo , 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: fpc\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2015-02-14 23:20-0300\n" +"Last-Translator: José de Figueiredo \n" +"Language-Team: Brazilian Portuguese \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "Renomear \"/etc/fpc.cfg\" para \"/etc/fpc.cfg.bak\"?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"Agora o FPC suporta ter múltiplas versões instaladas no mesmo sistema. O " +"comando update-alternatives pode ser usado para escolher uma versão padrão " +"para:\n" +" * fpc (o compilador);\n" +" * fpc.cfg (o arquivo de configuração);\n" +" * fp-utils (as ferramentas de apoio)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Para qualquer versão que você escolher como padrão, os arquivos de " +"configuração serão sempre retro-compatíveis, por isso deve ser sempre seguro " +"usar a última versão." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"Para utilizar o sistema de alternativas no arquivo global do sistema de " +"configuração do FPC, você precisa aceitar renomear \"/etc/fpc.cfg\"; caso " +"contrário, você precisará gerenciar isto manualmente por si mesmo." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "Selecionar manualmente" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Compilador de recurso .rc MS Windows padrão:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"O FPC tem suporte a compilar programas que incorporam recursos como arquivos " +"no formato .rc do MS Windows em todas as plataformas onde a ferramenta MinGW " +"windres estiver disponível." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"Para poder compilar projetos usando arquivos .rc, primeiro você precisa " +"instalar manualmente o pacote mingw32-binutils. O mingw32-binutils é " +"sugerido pelo fp-compiler, mas não é trazido automaticamente." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Se você quiser informar um compilador de arquivos .rc personalizado que não " +"aparece nesta lista ou se você simplesmente quiser desabilitar esta " +"característica, por favor, selecione \"Selecionar manualmente\"." + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Se você não quer usar um compilador de arquivos .rc padrão, deixe em branco." diff --git a/po/ru.po b/po/ru.po new file mode 100644 index 00000000..e4a984d8 --- /dev/null +++ b/po/ru.po @@ -0,0 +1,128 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the fpc package. +# +# Yuri Kozlov , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: fpc 2.6.2-6\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2013-11-12 19:34+0400\n" +"Last-Translator: Yuri Kozlov \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 1.4\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "Переименовать «/etc/fpc.cfg» в «/etc/fpc.cfg.bak»?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"Теперь в систему можно установить сразу несколько версий FPC. Для выбора " +"версии по умолчанию можно использовать команду update-alternatives. Можно " +"выбрать разный:\n" +" * fpc (компилятор);\n" +" * fpc.cfg (файл настройки);\n" +" * fp-utils (вспомогательные инструменты)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Какую бы версию вы не выбрали, файлы настройки всегда обратно совместимы, " +"поэтому можно всегда без опаски выбирать самую новую версию." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"Чтобы использовать систему альтернатив системный файла настройки FPC нужно " +"разрешить переименовывать в «/etc/fpc.cfg»; в противном случае вам каждый " +"раз нужно будет делать это вручную." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "Указать вручную" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Компилятор ресурсов MS Windows .rc по умолчанию:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"FPC поддерживает программы компиляции, которые встраивают файлы ресурсов " +"(такие как MS Windows .rc) на всех платформах, где доступна программа MinGW " +"windres." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"Чтобы можно было компилировать проекты с файлами .rc, во-первых, вам нужно " +"вручную установить mingw32-binutils. Наличие пакета mingw32-binutils " +"предполагается fp-compiler, но он не вытягивается автоматически." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Если вы хотите указать другой компилятор файлов .rc, которого нет в списке " +"или хотите совсем отключить эту возможность, выберите «Указать вручную»." + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Если вы не хотите использовать компилятор файлов .rc по умолчанию, оставьте " +"это поле пустым." diff --git a/po/sk.po b/po/sk.po new file mode 100644 index 00000000..1bdbdeed --- /dev/null +++ b/po/sk.po @@ -0,0 +1,133 @@ +# Slovak translations for fpc package +# Slovenské preklady pre balík fpc. +# Copyright (C) 2012 THE fpc'S COPYRIGHT HOLDER +# This file is distributed under the same license as the fpc package. +# Slavko , 2012, 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: fpc 2.6.2-6\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2013-11-23 20:22+0100\n" +"Last-Translator: Slavko \n" +"Language-Team: slovenčina \n" +"Language: sk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-POFile-SpellExtra: fp-utils fpc FPC cfg etc update-alternatives bak\n" +"X-Generator: Gtranslator 2.91.6\n" +"X-POFile-SpellExtra: resource windres mingw32-binutils MinGW rc\n" +"X-POFile-SpellExtra: fp-compiler\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "PremenovaÅ¥ „/etc/fpc.cfg” na „/etc/fpc.cfg.bak”?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"FPC teraz podporuje viacero nainÅ¡talovaných verzií na jednom stroji. Na " +"nastavenie predvolenej verzie možno použiÅ¥ príkaz update-alternatives pre\n" +" * fpc (kompilátor);\n" +" * fpc.cfg (konfiguračný súbor);\n" +" * fp-utils (pomocné nástroje)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Ako predvolenú môžete zvoliÅ¥ ktorúkoľvek verziu, konfiguračné súbory sú vždy " +"spätne kompatibilné, takže by malo byÅ¥ vždy bezpečné používaÅ¥ najnovÅ¡iu " +"verziu." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"Aby ste mohli používaÅ¥ systém alternatív na systémový konfiguračný súbor " +"FPC, musíte potvrdiÅ¥ premenovanie „/etc/fpc.cfg”; inak to budete musieÅ¥ " +"spravovaÅ¥ manuálne." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "VybraÅ¥ manuálne" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Predvolený kompilátor .rc resource MS Windows:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"FPC podporuje programy na zostavovanie, ktoré zahrnú zdroje ako súbory vo " +"formáte MS Windows .rc na vÅ¡etkých platformách, kde je dostupný nástroj " +"MinGW windres." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"Aby ste mohli zostavovaÅ¥ projekty pomocou pomocou súborov .rc, musíte najprv " +"manuálne nainÅ¡talovaÅ¥ balík mingw32-binutils. Balík mingw32-binutils je " +"navrhovaný balíkom fp-compiler, ale nie je zvolený automaticky." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Ak chcete zadaÅ¥ vlastný kompilátor súboru .rc, ktorý nie je v tomto zozname, " +"alebo ak chcete jednoducho vypnúť túto vlastnosÅ¥, prosím, vyberte možnosÅ¥ " +"„VybraÅ¥ manuálne”." + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Ak nechcete používaÅ¥ predvolený kompilátor súboru .rc, nechajte toto pole " +"prázdne." diff --git a/po/sv.po b/po/sv.po new file mode 100644 index 00000000..6a1b64f2 --- /dev/null +++ b/po/sv.po @@ -0,0 +1,128 @@ +# Translation of fpc debconf template to Swedish +# Copyright (C) 2014 Martin Bagge +# This file is distributed under the same license as the fpc package. +# +# Martin Bagge , 2012, 2014 +msgid "" +msgstr "" +"Project-Id-Version: fpc\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: 2014-09-30 13:13+0100\n" +"Last-Translator: Martin Bagge / brother \n" +"Language-Team: Swedish \n" +"Language: Swedish\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "Byt namn pÃ¥ \"/etc/fpc.cfg\" till \"/etc/fpc.cfg.bak\"?" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" +"FPC har nu stöd för att ha flera versioner installerade pÃ¥ samma system. " +"Kommandot update-alternatives kan användas för att sätta en standardversion " +"för\n" +" * fpc (kompileraren);\n" +" * fpc.cfg (inställningsfilen);\n" +" * fp-utils (hjälpverktygen)." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" +"Inställningsfilerna fungerar pÃ¥ äldre versioner oberoende vilken version du " +"anger som standard, därför är senaste versionen som standard ett säkert val." + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" +"För att kunna använda alternativsystemet för systemets inställningsfil för " +"FPC mÃ¥ste du tillÃ¥ta att \"/etc/fpc.cfg\" byter namn annars behöver du " +"hantera detta manuellt." + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "Manuell hantering" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "Standardkompilator för MS Windows .rc-resurser:" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" +"FPC har stöd för kompilering av program som bäddar in resurser som MS " +"Windows .rc-format-filer pÃ¥ alla plattformar där MinGW windres-verktyg finns " +"tillgängligt." + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" +"För att kunna kompilera projekt med .rc-filer behöver du först manuellt " +"installera paketet mingw32-binutils. mingw32-binutils föreslÃ¥s av fp-" +"compiler men installeras inte automatiskt." + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" +"Om du vill ange en alternativ kompilator för .rc-filer som inte visas i " +"denna lista eller om du helt enkelt vill avaktivera den här funktionen ange " +"\"Manuell hantering\"." + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" +"Vill du inte använda en standardkompilator för .rc-filer kan detta fält " +"lämnas tomt." diff --git a/po/templates.pot b/po/templates.pot new file mode 100644 index 00000000..9aa7cb39 --- /dev/null +++ b/po/templates.pot @@ -0,0 +1,106 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: fpc\n" +"Report-Msgid-Bugs-To: fpc@packages.debian.org\n" +"POT-Creation-Date: 2015-06-19 17:31+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "Rename \"/etc/fpc.cfg\" to \"/etc/fpc.cfg.bak\"?" +msgstr "" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"FPC now supports having multiple versions installed on the same system. The " +"update-alternatives command can be used to set a default version for\n" +" * fpc (the compiler);\n" +" * fpc.cfg (the configuration file);\n" +" * fp-utils (the helper tools)." +msgstr "" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"Whatever version you may choose as default, the configuration files are " +"always backward compatible, so it should always be safe to use the latest " +"version." +msgstr "" + +#. Type: boolean +#. Description +#: ../fp-compiler.templates.in:2001 +msgid "" +"In order to use the alternatives system on the system wide FPC configuration " +"file you must accept renaming \"/etc/fpc.cfg\"; otherwise you will need to " +"manage this manually by yourself." +msgstr "" + +#. Type: select +#. Choices +#. This string should be in sync with the translation in the description +#: ../fp-compiler.templates.in:3001 +msgid "Select manually" +msgstr "" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "Default MS Windows .rc resource compiler:" +msgstr "" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"FPC supports compiling programs that embed resources as MS Windows .rc-" +"format files on all platforms where the MinGW windres tool is available." +msgstr "" + +#. Type: select +#. Description +#. Type: string +#. Description +#: ../fp-compiler.templates.in:3002 ../fp-compiler.templates.in:4001 +msgid "" +"In order to be able to compile projects using .rc files, you need first to " +"manually install the package mingw32-binutils. mingw32-binutils is suggested " +"by fp-compiler but not pulled in automatically." +msgstr "" + +#. Type: select +#. Description +#. "Select manually" should be in sync with the text elsewhere in the +#. translation +#: ../fp-compiler.templates.in:3002 +msgid "" +"If you want to enter a custom .rc file compiler that does not appear in this " +"list or if you simply want to disable this feature, please select \"Select " +"manually\"." +msgstr "" + +#. Type: string +#. Description +#: ../fp-compiler.templates.in:4001 +msgid "If you don't want to use a default .rc file compiler, leave this blank." +msgstr "" diff --git a/rules b/rules new file mode 100755 index 00000000..8212ed52 --- /dev/null +++ b/rules @@ -0,0 +1,548 @@ +#!/usr/bin/make -f +# debian/rules for Free Pascal + +DEB_PACKAGE_NAME = fpc +export DEB_BUILD_MAINT_OPTIONS := hardening=+bindnow +export DH_ALWAYS_EXCLUDE := COPYING:LICENSE +export LANG:=C + +# Documentation type to use pdf/html +ifeq (${DEBDOCTYPE},) +DOCTYPE=html +# HTML Converter l2h/4ht/hevea or html for (default) +CONVERTER=hevea +else +DOCTYPE=${DEBDOCTYPE} +CONVERTER=${DOCTYPE} +endif +# Undefine FPC if it was set +unexport FPC +# Build new compiler name +CPU_SOURCE=$(shell dpkg-architecture -qDEB_BUILD_ARCH_CPU) +CPU_TARGET=$(shell dpkg-architecture -qDEB_HOST_ARCH_CPU) +# Take care that Debian uses amd64 while FPC perfers x86_64 instead +CPU_SOURCE := $(subst amd64,x86_64,${CPU_SOURCE}) +CPU_TARGET := $(subst amd64,x86_64,${CPU_TARGET}) +# Take care that Debian uses arm64 while FPC perfers aarch64 instead +CPU_SOURCE := $(subst arm64,aarch64,${CPU_SOURCE}) +CPU_TARGET := $(subst arm64,aarch64,${CPU_TARGET}) +# Take care that debian uses ppc64 while FPC prefers powerpc64 instead +CPU_SOURCE := $(subst ppc64,powerpc64,${CPU_SOURCE}) +CPU_TARGET := $(subst ppc64,powerpc64,${CPU_TARGET}) +# Shuld get rid of this one day, as it is done automatically by FPC make files +ifeq ($(CPU_TARGET),m68k) +PPSUF=68k +endif +ifeq ($(CPU_TARGET),i386) +PPSUF=386 +endif +ifeq ($(CPU_TARGET),x86_64) +PPSUF=x64 +endif +ifeq ($(CPU_TARGET),powerpc) +PPSUF=ppc +endif +ifeq ($(CPU_TARGET),powerpc64) +PPSUF=ppc64 +endif +ifeq ($(CPU_TARGET),alpha) +PPSUF=axp +endif +ifeq ($(CPU_TARGET),arm) +PPSUF=arm +endif +ifeq ($(CPU_TARGET),aarch64) +PPSUF=a64 +endif +ifeq ($(CPU_TARGET),sparc) +PPSUF=sparc +endif +ifeq ($(CPU_TARGET),mips) +PPSUF=mips +endif +ifeq ($(CPU_TARGET),mipsel) +PPSUF=mipsel +endif + +ifneq ($(CPU_SOURCE),$(CPU_TARGET)) +PPPRE=ppcross +else +PPPRE=ppc +endif + +PPNEW=$(PPPRE)$(PPSUF) +# Take care that Debian uses kfreebsd while FPC prefers freebsd +OS_TARGET=$(subst kfreebsd,freebsd,$(shell dpkg-architecture -qDEB_HOST_ARCH_OS)) +# FPC uses FPCTARGET to identify the target for which the binaries are +# produced. This is generally a couple of target CPU and target OS names +# separated by a dash. +FPCTARGET=$(CPU_TARGET)-$(OS_TARGET) +# Get version information from changelog file +DEB_VERSION:=$(shell dpkg-parsechangelog --show-field Version) +DEB_DATE:=$(shell date --utc --date="`dpkg-parsechangelog --show-field Date`" +%Y/%m/%d) +DEB_UPSTREAM_VERSION:=$(shell echo $(DEB_VERSION) | cut -f 1 -d -) +export DEB_UPSTREAM_MAIN_VERSION:=$(shell echo ${DEB_UPSTREAM_VERSION} | sed -e 's/^\([0-9\.]*\).*/\1/') +DEB_BUILD=$(lastword $(subst -, ,${DEB_VERSION})) +ifndef PACKAGESUFFIX +export PACKAGESUFFIX=-${DEB_UPSTREAM_MAIN_VERSION} +endif +# Get directories +INSTALL_DIR=${CURDIR}/debian/tmp +BIN_DIR=${INSTALL_DIR}/usr/bin +# Debian policy is to install libraries that are multi-arch coinstallable in +# /usr/lib/${DEB_HOST_MULTIARCH} +LIB_DIR=${INSTALL_DIR}/usr/lib/${DEB_HOST_MULTIARCH}/${DEB_PACKAGE_NAME}/${DEB_UPSTREAM_MAIN_VERSION} +DOC_DIR=${INSTALL_DIR}/usr/share/doc +SRC_DIR=${INSTALL_DIR}/usr/share/fpcsrc/${DEB_UPSTREAM_MAIN_VERSION} +EXAMPLE_TEMP=${INSTALL_DIR}/usr/share/doc/fpc-${DEB_UPSTREAM_MAIN_VERSION} +STY_DIR=${INSTALL_DIR}/usr/share/texmf/tex/latex/fpc-${DEB_UPSTREAM_MAIN_VERSION} +# Override standard GNUE make variables +ifndef MKDIR +MKDIR=mkdir -p +endif +ifndef CP +CP=cp -Rfpl +endif +ifndef MV +MV=mv +endif +RM:=rm -rf +# Build fpcmake from sources if none is specified. +ifndef FPCMAKE +# Upstream wants that one uses latest FPC make utility to produce make files +# from FPC make files. This is required because, especially in old days, FPC +# make utility used to evolve so that old tool versions were not able to +# process new FPC make files. So it is always safe to start first by building +# this tool from sources and then use it to build make files to build compiler, +# RTL and packages. +FPCMAKE=fpcsrc/utils/fpcm/bin/${FPCTARGET}/fpcmake +endif +# Undefine FPCDIR if it was set +unexport FPCDIR +NEWPP=$(CURDIR)/fpcsrc/compiler/$(PPNEW) +NEWFPDOC=$(CURDIR)/fpcsrc/utils/fpdoc/fpdoc +# Set default compilation options +DEB_BUILD_FPC_OPT=debian/deb-build-fpc.cfg +DEB_HOST_FPC_OPT=debian/deb-host-fpc.cfg +BUILDOPTS=PP=$(NEWPP) OPT='@${CURDIR}/${DEB_HOST_FPC_OPT}' +ifdef CROSSOPT +BUILDOPTS+= CROSSOPT=${CROSSOPT} +endif +INSTALLOPTS=INSTALL_PREFIX=$(INSTALL_DIR)/usr PP=$(NEWPP) + +export GDBLIBDIR=/usr/lib + +ifeq ($(CPU_TARGET),arm) + DEBIANARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH) + # Disable optimization for the first runs as there may be bugs associated + # with that, preventing proper building new versions (cf bug 800811) + # + # Unsure if the -d option is still needed, this code was originally used to + # bootstrap other arm flavors + CYCLEOPTS:=OPT='@${CURDIR}/${DEB_HOST_FPC_OPT} -dFPC_$(DEBIANARCH)' OPTLEVEL1=-O- +else + CYCLEOPTS:=OPT='@${CURDIR}/${DEB_HOST_FPC_OPT}' +endif + +# Set default compilation options +DEB_HOST_MULTIARCH ?=$(shell dpkg-architecture -qDEB_HOST_MULTIARCH) +DEB_BUILD_MULTIARCH ?=$(shell dpkg-architecture -qDEB_BUILD_MULTIARCH) + +FPMAKE_BUILDOPTS=FPMAKE_SKIP_CONFIG='-n @${CURDIR}/${DEB_BUILD_FPC_OPT}' + +LDFLAGS=$(strip $(shell DEB_BUILD_MAINT_OPTIONS=$(DEB_BUILD_MAINT_OPTIONS) \ + dpkg-buildflags --get LDFLAGS | \ + sed -e 's/-Wl,//g' -e 's/,/ /g' -e 's1-specs=/usr/share/dpkg/.*\.specs11')) + +# Until we switch to shorthand dh, we need to set this ourselves for +# reproducible builds +export SOURCE_DATE_EPOCH = $(shell date -d "$$(dpkg-parsechangelog -SDate)" +%s) + +#export DH_VERBOSE=1 + +################### +# Clean +# + +# The default clean target is very heavy for an already clean tree because it +# regenerates all the Makefiles from Makefile.fpc files to be able to call all +# the upstream distclean targets. Therefor the clean target is split into +# multiple components and you can fool the makefiles target when ZERO generated +# Makefiles are found by setting the variable MAY_FOOL_CLEAN to anything but +# the empty string. This is propably a reasonable trade-off under all +# circumstances, but to prevent anything bad from happening during official +# builds, it is not the default. +clean: check-makefiles clean-all-but-makefiles clean-makefiles + # Make sure the debconf translations are always up-to-date + debconf-updatepo + # Make sure the list with timestamps is up-to-date + [ ! $$(which fp-fix-timestamps) ] || fp-fix-timestamps update + dh_clean + +# See comment above clean target. Fool make-file when approriate +check-makefiles: +ifdef MAY_FOOL_CLEAN + for fpcfile in `find . -name Makefile.fpc` ; do \ + if [ -f `dirname $$fpcfile`/Makefile ] ; then \ + GOINGTOFOOLCLEAN=false ; \ + fi ; \ + done ; \ + if [ "$$GOINGTOFOOLCLEAN" != false ] ; then \ + echo Beware of empty Makefiles: we are going to fool the makefiles target now ; \ + for fpcfile in `find . -name Makefile.fpc` ; do \ + touch `dirname $$fpcfile`/Makefile ; \ + done ; \ + touch makefiles-stamp ; \ + fi +endif + +# In essence, this is the real clean target, except it doesn't remove the +# generated Makefiles. It should do ALL the other cleaning though. +clean-all-but-makefiles: makefiles + dh_testdir + + # Remove the gnome1, gtk1, fpgtk and imlib packages + # as they depend on libraries long go removed from Debian. + rm -rf fpcsrc/packages/gnome1 + rm -rf fpcsrc/packages/gtk1 + rm -rf fpcsrc/packages/imlib + rm -rf fpcsrc/packages/fpgtk + # The following packages depend on (at least) fpgtk and were + # not build in Debian anyways. The makefiles target fails to run + # if we remove the above, but not these because fpcmake checks + # for all Makefile.fpc files and notices that the dependency is + # not fullfilled. + rm -rf fpcsrc/utils/fpdoc/fpde + rm -rf fpcsrc/utils/fpmc + + # Call upstream clean targets + [ ! -s fpcsrc/Makefile ] || $(MAKE) -C fpcsrc compiler_distclean + [ ! -s fpcsrc/Makefile ] || $(MAKE) -C fpcsrc rtl_distclean + [ ! -s fpcsrc/Makefile ] || $(MAKE) -C fpcsrc packages_distclean + [ ! -s fpcsrc/Makefile ] || $(MAKE) -C fpcsrc ide_distclean + [ ! -s fpcsrc/Makefile ] || $(MAKE) -C fpcsrc utils_distclean + [ ! -s fpcdocs/Makefile ] || $(MAKE) -C fpcdocs clean + # Just in case they forgot something + find -regex '.*\.\(a\|or?\|so\.*\|ppu\|compiled\)' -delete + # Not all empty directories are cleaned up properly by the upstream + find . -type d -empty -delete + + # Revert hardcoded dates + sed --in-place "s/EncodeDate([^(^)]*)/Now/" fpcsrc/packages/fpmkunit/src/fpmkunit.pp + sed --in-place "s/\\\\date\\\{.*\\\}/\\\\date\\\{\`date +'%B %Y'\`\\\}/" fpcdocs/Makefile.fpc + + # Remove build config files; because we use a variable, lets not put it in + # d/clean + rm -f $(DEB_BUILD_FPC_OPT) + rm -f $(DEB_HOST_FPC_OPT) + + dh_clean + +FPCMAKEFILES=fpcsrc/Makefile.fpc $(shell find demo fpcdocs -name Makefile.fpc) + +makefiles: makefiles-stamp +makefiles-stamp: $(patsubst %.fpc,%,${FPCMAKEFILES}) + # Make files are now generated. + touch $@ + +%Makefile:%Makefile.fpc ${FPCMAKE} + # Regenerate make files using fpcmake. + ${FPCMAKE} -r -Tall -q $< + +clean-makefiles: + # Remove auto-generated Makefiles. + ${RM} makefiles-stamp + find . -name Makefile.fpc -execdir sh -c '${RM} $$(basename {} .fpc)' ';' + + +################### +# Debian files +# + +debian-files: debian-files-stamp +debian-files-stamp:debian/fixdeb debian/*.in + @echo "--- Creating/fixing *.install files" + DEB_SUBST_PACKAGESUFFIX=${PACKAGESUFFIX} \ + DEB_SUBST_PPCBIN=${PPNEW} \ + DEB_SUBST_TARGET=${FPCTARGET} \ + DEB_SUBST_DEB_HOST_MULTIARCH=${DEB_HOST_MULTIARCH} \ + $< debian/*.in + # Because we use dh-exec to track units that don't need to install + # everywhere, we need the .install files to be executable + chmod a+x debian/*.install + touch debian-files-stamp + + +################### +# Source +# + +prepare-source: prepare-source-stamp +prepare-source-stamp: + dh_testdir + dh_prep + # Add version.inc: + echo \'$(DEB_VERSION)\' > fpcsrc/compiler/version.inc + # To obtain reproducible builds, we need to force a date in several + # locations + # Timestamp in prog.html & ref.html & user.html + # Note: replace directly with correct string + sed --in-place "s/\`date +'%B %Y'\`/$(shell LC_ALL=C date --utc --date=${DEB_DATE} +'%B %Y')/" fpcdocs/Makefile.fpc + # Checksum in fastcgi/fpunits.cfg & fcl-web/fpunits.cfg + # Note: revert in clean target + sed --in-place "s/Now/EncodeDate($(shell date --utc --date=${DEB_DATE} +'%Y, %m, %d'))/" fpcsrc/packages/fpmkunit/src/fpmkunit.pp + + # Now that we are done with all changes to files in the packaging, let's + # make sure that all the timestamps are reproducible. + echo -n "fpcsrc/compiler/version.inc " >> debian/source/timestamps + LC_ALL=C date --utc --iso-8601=minutes --date=${DEB_DATE} >> debian/source/timestamps + debian/fp-fix-timestamps touch + #Remove last line agains + sed --in-place '$$d' debian/source/timestamps + + touch prepare-source-stamp + +# Annoying thing is we need to do this very early to save lots of overhead. If +# it can be done on a clean tree, right after prepare-source we don't need +# cleaning, right. +install-source: prepare-source install-source-stamp +install-source-stamp: + @echo "--- Copying the source code" + dh_testdir + ${MKDIR} ${SRC_DIR} + ${CP} -t ${SRC_DIR} \ + $(CURDIR)/fpcsrc/compiler \ + $(CURDIR)/fpcsrc/packages \ + $(CURDIR)/fpcsrc/rtl + touch install-source-stamp + + +################### +# Arch packages +# + +build-arch: debian-files install-source makefiles build-arch-stamp +build-arch-stamp: ${DEB_BUILD_FPC_OPT} ${DEB_HOST_FPC_OPT} + @echo "--- Building" + dh_testdir + # First make a new Compiler using a make cycle + $(MAKE) -C fpcsrc compiler_cycle $(CYCLEOPTS) + # Then build RTL using new compiler + $(MAKE) -C fpcsrc rtl_clean rtl_smart $(BUILDOPTS) + # Finally build packages and tools using new compiler and new RTL + $(MAKE) -C fpcsrc packages_smart ${BUILDOPTS} ${FPMAKE_BUILDOPTS} + $(MAKE) -C fpcsrc ide_all $(BUILDOPTS) + $(MAKE) -C fpcsrc utils_all ${BUILDOPTS} + # *.fpm files contain the build directory, which results in unreproducible + # builds. As this is useless anyways, let's canonize the text. + find . -name "*.fpm" -exec sed --in-place "s#${CURDIR}/##" {} \; + touch build-arch-stamp + +install-arch: build-arch install-arch-stamp +install-arch-stamp: + @echo "--- Installing" + dh_testdir + dh_testroot + dh_installdirs + # create all necessary directories + ${MKDIR} ${BIN_DIR} + ${MKDIR} ${LIB_DIR} + ${MKDIR} ${STY_DIR} + # Specify the compiler to use so installing will use the correct versioned dir + $(MAKE) -C fpcsrc compiler_distinstall $(INSTALLOPTS) + $(MAKE) -C fpcsrc rtl_distinstall $(INSTALLOPTS) + $(MAKE) -C fpcsrc packages_distinstall $(INSTALLOPTS) + $(MAKE) -C fpcsrc ide_distinstall $(INSTALLOPTS) INSTALL_DOCDIR=$(DOC_DIR)/fp-ide/${DEB_UPSTREAM_MAIN_VERSION} + $(MAKE) -C fpcsrc utils_distinstall $(INSTALLOPTS) + $(MAKE) -C fpcsrc/utils/fpdoc/intl install $(INSTALLOPTS) + ${CP} -t ${LIB_DIR} \ + ${INSTALL_DIR}/usr/lib/fpc/lexyacc + ${CP} -t ${BIN_DIR} debian/fpc-depends + # Copy examples to the correct doc dir + /bin/bash debian/moveexamples ${EXAMPLE_TEMP} ${DOC_DIR} ${DEB_UPSTREAM_MAIN_VERSION} + # Rename executables + for f in ${BIN_DIR}/* ; do ${MV} $$f $${f}-${DEB_UPSTREAM_MAIN_VERSION} ; done + # Move fp-compiler executables to /usr/bin/ + for f in fpc fpcmkcfg fpcres ; do \ + ${MV} ${BIN_DIR}/$${f}-${DEB_UPSTREAM_MAIN_VERSION} ${BIN_DIR}/${DEB_HOST_MULTIARCH}-$${f}-${DEB_UPSTREAM_MAIN_VERSION} ; \ + done + # Install RTL demos + $(MAKE) -C demo sourceinstall $(INSTALLOPTS) INSTALL_SOURCEDIR=$(DOC_DIR)/fp-compiler/${DEB_UPSTREAM_MAIN_VERSION} + # Install whatsnew and readme + $(MAKE) -C install/doc installdoc $(INSTALLOPTS) INSTALL_DOCDIR=$(DOC_DIR)/fp-compiler/${DEB_UPSTREAM_MAIN_VERSION} + # Install fpdoc latex styles, but only those that are not already in + # texlive-latex-recommended + ${CP} -t ${STY_DIR} \ + ${CURDIR}/fpcdocs/fakehtml.sty \ + ${CURDIR}/fpcdocs/fpc.sty + touch install-arch-stamp + +arrange-arch: install-arch arrange-arch-stamp install-man +arrange-arch-stamp: + dh_testdir + dh_testroot + # Expected here: + # usr/lib/fpc/lexyacc/yyparse.cod + # usr/lib/fpc/lexyacc/yylex.cod + # usr/bin/unihelper- + # usr/bin/ptop.rsj- + # usr/bin/mkx86ins- + # usr/bin/mkinsad- + # usr/bin/mkarmins- + # usr/bin/mka64ins- + # usr/bin/makeskel.rsj- + # usr/bin/cldrparser- + dh_install -s --list-missing + touch arrange-arch-stamp + +# This is a policy required target, for our purpose, it needs to trigger +# debian-files and install-source at least if that didn't happen yet. +build-indep: debian-files install-source build-doc +install-indep: install-doc install-man + +install-man: install-man-stamp +install-man-stamp: + # Generate man pages for newly supported arches + cd install/man/man1 ; \ + for arch in 68k a64 mips mipsel ppc64 ; do \ + cp -p ppcx64.1 ppc$${arch}.1 ; \ + sed --in-place s/x64/$${arch}/ ppc$${arch}.1 ; \ + done + + # Install man pages + $(MAKE) -C install/man installman $(INSTALLOPTS) + for s in ${INSTALL_DIR}/usr/man/man[1-9] ; do cd $${s} && ( gzip -d *.gz || true ) && for f in *.[1-9] ; do ${MV} $${f} $${f%%.*}-${DEB_UPSTREAM_MAIN_VERSION}."$${f#*.}" ; done ; done || true + pod2man -c 'Free pascal for Debian GNU/Linux' -d ${DEB_DATE} debian/fpc-depends > \ + debian/fpc-depends-${DEB_UPSTREAM_MAIN_VERSION}.1 + txt2man -s1 debian/fp-fix-timestamps.txt > debian/fp-fix-timestamps.1 + dh_installman + ${RM} ${INSTALL_DIR}/usr/man + touch install-man-stamp + +################### +# Documentation +# + +build-doc: makefiles build-doc-stamp +build-doc-stamp: + @echo "--- Building Documentation" + dh_testdir + ${MKDIR} fpcsrc/compiler/utils/units/${FPCTARGET} + # Until the whole locale is properly set to include at least UTF-8 in some + # more generic way than on a per d/rules file basis, we need to set the + # locale here to get reproducible builds (because of sorting in index + # pages) and to fix some characters in some documentation files that are + # non-ascii. + LC_ALL=C.UTF-8 $(MAKE) -C fpcdocs $(CONVERTER) + touch build-doc-stamp + +install-doc: build-doc install-doc-stamp +install-doc-stamp: + @echo "--- Installing Documentation" + dh_testdir + dh_testroot + ${MAKE} -C fpcdocs ${DOCTYPE}install INSTALL_PREFIX=${INSTALL_DIR}/usr INSTALL_DOCDIR=${DOC_DIR}/fp-docs/${DEB_UPSTREAM_MAIN_VERSION} + + # The following lines are taken from https://wiki.debian.org/dedup.debian.net + # Replace duplicate files with symlinks + rdfind -outputname /dev/null -makesymlinks true ${DOC_DIR} + # Fix those symlinks to make them relative + symlinks -r -s -c ${DOC_DIR} + + touch install-doc-stamp + + +################### +# Generic +# + +build: build-arch build-indep +install: install-arch install-indep +binary: binary-arch binary-indep + + +################### +# Deb building +# + +binary-indep: install-indep + @echo "--- Building: arch-indep packages" + dh_testdir + dh_testroot + dh_installdocs -i -X.in + dh_installchangelogs -i + dh_install -i --list-missing + find debian/fpc-source${PACKAGESUFFIX}/usr/share/fpcsrc/ -type f \ + -not -regex '.*\.\(fpc\|inc\|pas\|pp\)' -delete + find debian/fpc-source${PACKAGESUFFIX}/usr/share/fpcsrc/ -type d \ + -empty -delete + dh_lintian -i + dh_compress -i -X.pdf + dh_fixperms + dh_installdebconf -i + dh_installdeb -i + dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i $(DEB_DH_BUILDDEB_ARGS) + +binary-arch: arrange-arch + @echo "--- Building: arch packages" + dh_testdir + dh_testroot + dh_link + dh_installdocs -a -X.in + dh_installchangelogs -a + dh_installexamples -a + dh_strip -s + dh_lintian -a + dh_compress -a + dh_fixperms + dh_installdebconf -a + dh_installdeb -a + dh_shlibdeps -s + dh_gencontrol -s + dh_md5sums -s + dh_builddeb -s $(DEB_DH_BUILDDEB_ARGS) + +.PHONY: arrange-arch binary binary-arch binary-indep build build-arch \ + build-doc build-indep check-makefiles clean clean-all-but-makefiles \ + clean-makefiles debian-files get-orig-source install install-arch \ + install-doc install-indep install-man install-source makefiles \ + prepare-source get-orig-source gen-control run-tests + +# Package new upstream release +get-orig-source: + -uscan --upstream-version=0 --rename --force-download + +# Generate debian.control file +gen-control: debian/control.in + +# Run upstream test suite +run-tests: + dpkg-source --before-build ${CURDIR} + debian/tests/run-upstream-testsuite + +debian/%:debian/fixdeb debian/changelog debian/%.in + DEB_SUBST_PACKAGESUFFIX=${PACKAGESUFFIX} \ + DEB_SUBST_PPCBIN=${PPNEW} \ + DEB_SUBST_TARGET=${FPCTARGET} \ + DEB_SUBST_DEB_HOST_MULTIARCH=${DEB_HOST_MULTIARCH} \ + $< --gen-control $@.in + +${FPCMAKE}:fpcsrc/utils/fpcm/Makefile ${DEB_BUILD_FPC_OPT} + ${MAKE} -C fpcsrc/rtl OPT=@${CURDIR}/${DEB_BUILD_FPC_OPT} + ${MAKE} -C fpcsrc/packages/fpmkunit bootstrap OPT=@${CURDIR}/${DEB_BUILD_FPC_OPT} + ${MAKE} -C ${ $@ + echo '-k${LDFLAGS}' >> $@ + echo '-Fl/usr/lib/${DEB_BUILD_MULTIARCH}' >> $@ + +${DEB_HOST_FPC_OPT}: + echo '# FPC configuration file for host system applications' > $@ + echo '-k${LDFLAGS}' >> $@ + echo '-Fl/usr/lib/${DEB_HOST_MULTIARCH}' >> $@ diff --git a/source/format b/source/format new file mode 100644 index 00000000..163aaf8d --- /dev/null +++ b/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/source/lintian-overrides b/source/lintian-overrides new file mode 100644 index 00000000..9cf4fbbd --- /dev/null +++ b/source/lintian-overrides @@ -0,0 +1,3 @@ +# In 3.0.0+dfsg-5 elbrus added fp-fix-timestamps that expects d/source/timestamps +# lintian bug: http://bugs.debian.org/825222 +fpc source: unknown-file-in-debian-source timestamps diff --git a/source/timestamps b/source/timestamps new file mode 100644 index 00000000..edf249bf --- /dev/null +++ b/source/timestamps @@ -0,0 +1,227 @@ +fpcsrc/compiler/aarch64/a64att.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/a64atts.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/a64op.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/a64tab.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/aasmcpu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/agcpugas.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/aoptcpub.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/cgcpu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/cpubase.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/cpuinfo.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/cpunode.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/cpupara.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/cpupi.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/cputarg.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/hlcgcpu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ncpuadd.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ncpucnv.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ncpuinl.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ncpumat.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ncpumem.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ncpuset.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ra64con.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ra64dwa.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ra64nor.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ra64num.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ra64rni.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ra64sri.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ra64sta.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ra64std.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/ra64sup.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/racpu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/racpugas.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aarch64/rgcpu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aasmtai.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aggas.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/aoptobj.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/aasmcpu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/agarmgas.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/aoptcpu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/armatt.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/armatts.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/armnop.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/armop.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/armtab.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/cgcpu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/cpubase.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/cpuelf.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/cpuinfo.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/narmadd.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/narmcnv.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/narminl.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/narmmat.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/narmmem.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/raarmgas.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/rarmcon.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/rarmdwa.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/rarmnor.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/rarmnum.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/rarmrni.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/rarmsri.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/rarmsta.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/rarmstd.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/rarmsup.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/arm/rgcpu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/assemble.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/cgbase.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/cghlcpu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/cgobj.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/cgutils.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/fpcdefs.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/globals.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/hlcg2ll.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/hlcgobj.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/i386/cpuelf.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/i8086/n8086mem.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/jvm/hlcgcpu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/m68k/n68kmem.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/mips/cpuelf.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/msgidx.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/ncal.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/ncgcnv.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/ncginl.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/ncgld.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/ncgmat.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/ncgmem.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/ncgutil.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/ncnv.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/ninl.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/nld.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/nmem.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/objcgutl.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/objcutil.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/ogbase.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/ogcoff.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/ogelf.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/options.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/pparautl.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/ppu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/psub.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/psystem.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/raatt.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/rautils.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/sparc/cpuelf.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/symdef.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/systems.inc 2017-02-24T10:42+00:00 +fpcsrc/compiler/systems.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/systems/i_bsd.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/systems/i_linux.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/systems/i_win.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/systems/t_bsd.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/systems/t_linux.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/tgobj.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/utils/fpc.pp 2017-02-24T10:42+00:00 +fpcsrc/compiler/utils/mka64ins.pp 2017-02-24T10:42+00:00 +fpcsrc/compiler/utils/mkarmins.pp 2017-02-24T10:42+00:00 +fpcsrc/compiler/utils/ppuutils/ppudump.pp 2017-02-24T10:42+00:00 +fpcsrc/compiler/version.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/x86/agx86att.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/x86/cgx86.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/x86/nx86mem.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/x86_64/cgcpu.pas 2017-02-24T10:42+00:00 +fpcsrc/compiler/x86_64/cpuelf.pas 2017-02-24T10:42+00:00 +fpcsrc/ide/fp.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/fpcompil.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/fpconst.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/fpdebug.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/fpdesk.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/fpide.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/fpini.pas 2017-02-24T10:42+00:00 +fpcsrc/ide/fpmake.pp 2017-02-24T10:42+00:00 +fpcsrc/ide/fpmopts.inc 2018-01-12T09:24+00:00 +fpcsrc/ide/fpregs.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/fptemplt.pas 2017-02-24T10:42+00:00 +fpcsrc/ide/fpusrscr.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/fpvars.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/fpviews.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/gdbmicon.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/gdbmiint.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/gdbmiproc.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/gdbmiwrap.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/globdir.inc 2018-01-12T09:24+00:00 +fpcsrc/ide/weditor.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/windebug.pas 2018-01-12T09:24+00:00 +fpcsrc/ide/wresourc.pas 2018-01-12T09:24+00:00 +fpcsrc/packages/fcl-js/fpmake.pp 2018-01-12T09:24+00:00 +fpcsrc/packages/fcl-res/src/elfconsts.pp 2017-02-24T10:42+00:00 +fpcsrc/packages/fcl-res/src/elfdefaulttarget.inc 2017-02-24T10:42+00:00 +fpcsrc/packages/fcl-res/src/elfreader.pp 2017-02-24T10:42+00:00 +fpcsrc/packages/fcl-res/src/elfsubwriter.inc 2017-02-24T10:42+00:00 +fpcsrc/packages/fcl-res/src/elfwriter.pp 2017-02-24T10:42+00:00 +fpcsrc/packages/fcl-res/src/machoconsts.pp 2017-02-24T10:42+00:00 +fpcsrc/packages/fcl-res/src/machodefaulttarget.inc 2017-02-24T10:42+00:00 +fpcsrc/packages/fcl-res/src/machoreader.pp 2017-02-24T10:42+00:00 +fpcsrc/packages/fcl-res/src/machosubwriter.inc 2017-02-24T10:42+00:00 +fpcsrc/packages/fcl-res/src/machotypes.pp 2017-02-24T10:42+00:00 +fpcsrc/packages/fcl-res/src/machowriter.pp 2017-02-24T10:42+00:00 +fpcsrc/packages/fpmake_add.inc 2017-02-24T10:42+00:00 +fpcsrc/packages/fpmake_proc.inc 2017-02-24T10:42+00:00 +fpcsrc/packages/fpmkunit/src/fpmkunit.pp 2017-02-24T10:42+00:00 +fpcsrc/packages/iosxlocale/fpmake.pp 2017-02-24T10:42+00:00 +fpcsrc/packages/iosxlocale/src/iosxwstr.pp 2017-02-24T10:42+00:00 +fpcsrc/packages/ncurses/src/form.pp 2018-01-12T09:24+00:00 +fpcsrc/packages/rtl-extra/src/linux/unixsock.inc 2017-02-24T10:42+00:00 +fpcsrc/packages/rtl-extra/src/unix/ipc.pp 2017-02-24T10:42+00:00 +fpcsrc/rtl/aarch64/aarch64.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/aarch64/int64p.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/aarch64/math.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/aarch64/mathu.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/aarch64/set.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/aarch64/setjump.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/aarch64/setjumph.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/aarch64/strings.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/aarch64/stringss.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/arm/arm.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/arm/thumb2.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/bsd/ostypes.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/darwin/aarch64/sig_cpu.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/darwin/aarch64/sighnd.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/darwin/extres_multiarch.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/darwin/ptypes.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/darwin/signal.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/inc/ctypes.pp 2017-02-24T10:42+00:00 +fpcsrc/rtl/inc/objc.pp 2017-02-24T10:42+00:00 +fpcsrc/rtl/inc/objcnf.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/inc/system.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/inc/systemh.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/aarch64/bsyscall.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/aarch64/sighnd.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/aarch64/sighndh.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/aarch64/stat.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/aarch64/syscall.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/aarch64/syscallh.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/aarch64/sysnr.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/bunxsysc.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/linux.pp 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/oldlinux.pp 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/osdefs.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/ossysc.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/ostypes.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/pmutext.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/ptypes.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/sysnr-gen.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/sysosh.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/linux/termios.inc 2017-02-24T10:42+00:00 +fpcsrc/rtl/unix/cthreads.pp 2017-02-24T10:42+00:00 +fpcsrc/rtl/unix/cwstring.pp 2017-02-24T10:42+00:00 +fpcsrc/rtl/unix/dl.pp 2017-02-24T10:42+00:00 +fpcsrc/rtl/unix/timezone.inc 2017-02-24T10:42+00:00 +fpcsrc/tests/test/units/sysutils/texpfncase.pp 2018-01-12T09:24+00:00 +fpcsrc/utils/fpcm/fpcmmain.pp 2017-02-24T10:42+00:00 +fpcsrc/utils/fpcm/fpcmwr.pp 2017-02-24T10:42+00:00 +fpcsrc/utils/fpcm/fpmake.pp 2018-01-12T09:24+00:00 +fpcsrc/utils/fpcres/fpcres.pas 2017-02-24T10:42+00:00 +fpcsrc/utils/fpcres/target.pas 2017-02-24T10:42+00:00 +fpcsrc/utils/fpdoc/dglobals.pp 2017-02-24T10:42+00:00 +fpcsrc/utils/fpdoc/fpclasschart.pp 2017-02-24T10:42+00:00 +fpcsrc/utils/fpdoc/fpdoc.pp 2017-02-24T10:42+00:00 +fpcsrc/utils/fpdoc/makeskel.pp 2017-02-24T10:42+00:00 +fpcsrc/utils/fpdoc/unitdiff.pp 2017-02-24T10:42+00:00 +fpcsrc/utils/fpmake.pp 2017-02-24T10:42+00:00 +fpcsrc/utils/fpmake_add.inc 2017-02-24T10:42+00:00 +fpcsrc/utils/fpmake_proc.inc 2017-02-24T10:42+00:00 +fpcsrc/utils/instantfpc/fpmake.pp 2017-02-24T10:42+00:00 +fpcsrc/utils/instantfpc/ifpc.pas 2017-02-24T10:42+00:00 +fpcsrc/utils/instantfpc/instantfpc.pas 2017-02-24T10:42+00:00 +fpcsrc/utils/ppdep.pp 2017-02-24T10:42+00:00 +fpcsrc/utils/relpath.pas 2017-02-24T10:42+00:00 diff --git a/tests/control b/tests/control new file mode 100644 index 00000000..971d88e9 --- /dev/null +++ b/tests/control @@ -0,0 +1,12 @@ +Tests: run-upstream-testsuite +# Building the testsuite requires at least Makefiles to be made +Restrictions: rw-build-tree, allow-stderr +# Running the testsuite as root can change the system time; not sure +# if this warrants a: +# Restrictions: breaks-testbed +# +# binutils is the only relevant difference that I could find between +# autopkgtest.u.c and ci.d.n (maybe needed for webtbs/tw0876) +# build-essential is needed to build some c/c++ objects used for testing +# zlib1g-dev is needed for at least test/packages/zlib/tzlib1.pp +Depends: @, binutils, build-essential, zlib1g-dev diff --git a/tests/ref_fail_aarch64-linux b/tests/ref_fail_aarch64-linux new file mode 100644 index 00000000..126fbfb8 --- /dev/null +++ b/tests/ref_fail_aarch64-linux @@ -0,0 +1,44 @@ +test/cg/tcalext +test/cg/tcalext3 +test/cg/tcalext4 +test/cg/tcalext5 +test/cg/tcalext6 +test/cg/tcppcl1 +test/cg/tcppcl2 +test/opt/tdfa11 +test/opt/tdfa8 +test/packages/webtbs/tw14265 +test/tcpstr2a +test/texception4 +test/thlp29 +test/timplements4a +test/timplements4b +test/tsafecall1 +test/tsafecall2 +test/tsafecall3 +test/tsafecall4 +test/tset6 +test/tunistr7 +test/twide7 +test/units/math/tmask +test/units/math/tmask2 +tbs/tb0072 +tbs/tb0193 +tbs/tb0262 +tbf/tb0117 +webtbs/tw0876 +Note: This test needs C libraries +webtbs/tw11563 +webtbs/tw2242 +webtbs/tw24863 +webtbs/tw26773 +webtbs/tw3157 +webtbs/tw3160a +webtbs/tw3160b +webtbs/tw3160c +webtbs/tw3161 +webtbs/tw3893 +webtbs/tw3930 +webtbs/tw4100 +webtbs/tw4809 +webtbf/tw3930a diff --git a/tests/ref_fail_arm-linux b/tests/ref_fail_arm-linux new file mode 100644 index 00000000..4f2079f0 --- /dev/null +++ b/tests/ref_fail_arm-linux @@ -0,0 +1,34 @@ +test/cg/tcalext6 +test/opt/tdfa11 +test/opt/tdfa8 +test/packages/webtbs/tw14265 +test/tcpstr2a +test/texception4 +test/thlp29 +test/timplements4a +test/timplements4b +test/tsafecall1 +test/tsafecall2 +test/tsafecall3 +test/tsafecall4 +test/tset6 +test/tunistr7 +test/twide7 +test/units/fmtbcd/tfmtbcd +test/units/math/tmask +test/units/math/tmask2 +tbs/tb0262 +tbs/tb0621 +webtbs/tw11563 +webtbs/tw16161 +webtbs/tw22744 +webtbs/tw24863 +webtbs/tw3157 +webtbs/tw3160a +webtbs/tw3160b +webtbs/tw3160c +webtbs/tw3161 +webtbs/tw3930 +webtbs/tw4100 +webtbs/tw4809 +webtbf/tw3930a diff --git a/tests/ref_fail_i386-linux b/tests/ref_fail_i386-linux new file mode 100644 index 00000000..a4828a71 --- /dev/null +++ b/tests/ref_fail_i386-linux @@ -0,0 +1,19 @@ +test/cg/tcalext6 +test/opt/tdfa11 +test/opt/tdfa8 +test/packages/webtbs/tw14265 +test/tcpstr2a +test/thlp29 +test/timplements4a +test/timplements4b +test/tset6 +test/tunistr7 +test/twide7 +test/units/sysutils/texpfncase +webtbs/tw12214 +webtbs/tw16161 +webtbs/tw22744 +webtbs/tw24863 +webtbs/tw3930 +webtbs/tw4809 +webtbf/tw3930a diff --git a/tests/ref_fail_x86_64-linux b/tests/ref_fail_x86_64-linux new file mode 100644 index 00000000..5bbe9635 --- /dev/null +++ b/tests/ref_fail_x86_64-linux @@ -0,0 +1,41 @@ +# upstream references: http://www.freepascal.org/testsuite/cgi-bin/testsuite.cgi +# Next line fails on autopkgtest.u.c but not on my laptop or ci.d.n +test/cg/tcalext6 +# code comment: this test test needs dynamic dfa to work properly +test/opt/tdfa11 +# code comment: this test will work only as soon as we have global dfa +test/opt/tdfa8 +test/packages/webtbs/tw14265 +# pass instead of fail +test/tcpstr2a +test/thlp29 +test/timplements4a +test/timplements4b +# fails upstream with "-Fd" but not with "-Cg -O2 -Fd" +test/tlib2a +test/tset6 +# doesn't fail upstream +test/tunistr7 +# doesn't fail upstream +test/twide7 +# doesn't fail upstream +tbs/tb0528 +# Next line fails on autopkgtest.u.c but not on my laptop or ci.d.n +# code comment: This test needs C libraries +webtbs/tw0876 +webtbs/tw16161 +webtbs/tw17236 +webtbs/tw24197 +webtbs/tw24863 +webtbs/tw3930 +# pass instead of fail +webtbs/tw4809 +# fails upstream with "-Fd" but not with "-Cg -O2 -Fd" +webtbs/tw7838a +# fails upstream with "-Fd" but not with "-Cg -O2 -Fd" +webtbs/tw7838b +# fails upstream with "-Fd" but not with "-Cg -O2 -Fd" +# assembler test that doesn't fail... +webtbf/tw22665b +# Maybe only fails under Kylix +webtbf/tw3930a diff --git a/tests/run-upstream-testsuite b/tests/run-upstream-testsuite new file mode 100755 index 00000000..58a0abb9 --- /dev/null +++ b/tests/run-upstream-testsuite @@ -0,0 +1,75 @@ +#!/bin/sh +# This script was made by Paul Gevers +# It is licensed under the same license as the fpc package + +set -e # Make sure the test fails if a command fails + +FULL_TARGET=`fpc -iSP`-`fpc -iSO` # x86_64-linux +FPC_VER=`fpc -iV` +DEB_HOST_MULTIARCH=`dpkg-architecture -qDEB_HOST_MULTIARCH` +# Make sure we use the installed fpcmake +export FPCMAKE=`which fpcmake`-${FPC_VER} +TESTUNITDIRROOT=fpcsrc/tests/tstunits +TESTUNITDIR=${TESTUNITDIRROOT}/${FULL_TARGET} +LIBDIR=/usr/lib/${DEB_HOST_MULTIARCH}/fpc/${FPC_VER} +UTESTS=fpcsrc/tests/utils/testsuite/utests +if [ -f fpcsrc/tests/Makefile ] ; then + MAKEMAKEFILES=false +else + MAKEMAKEFILES=true +fi + +[ "$MAKEMAKEFILES" = "true" ] && debian/rules makefiles +# Generate missing configuration file for testsuite +[ -f ${UTESTS}.cfg ] || grep '^ Def' ${UTESTS}.pp > ${UTESTS}.cfg + +# If the make target is run without intervention, the units target is build and +# installed, while we want to test with the installed units. +[ -d ${TESTUNITDIR} ] || mkdir ${TESTUNITDIR} +for FILE in ${LIBDIR}/units/$FULL_TARGET/*/*.[op]* ; do + [ -h ${TESTUNITDIR}/${FILE##*/} ] || ln -s ${FILE} ${TESTUNITDIR} +done +echo Compiled > ${TESTUNITDIRROOT}/rtl-stamp.${FULL_TARGET} +echo Compiled > ${TESTUNITDIRROOT}/fpcunit-stamp.${FULL_TARGET} +echo Compiled > ${TESTUNITDIRROOT}/packages-stamp.${FULL_TARGET} + +# Some tests need additional objects, lets make them first (why are they not +# automatically build?) +mkdir -p fpcsrc/tests/test/cg/obj/${FULL_TARGET##*-}/${FULL_TARGET%%-*} #linux/x86_64 +make -C fpcsrc/tests create_c_objects TEST_FPC=`which fpc` TEST_CCOMPILER=gcc +# Run the real test suite; this doesn't fail on its own +LC_ALL=C.UTF-8 make -C fpcsrc/tests all TEST_FPC=`which fpc` +# The next line just creates some nice output +make -C fpcsrc/tests digest TEST_FPC=`which fpc` + +# Let's save some of the output +if [ -n "${ADT_ARTIFACTS}" ] ; then + cp -p fpcsrc/tests/output/${FULL_TARGET}/faillist ${ADT_ARTIFACTS} + cp -p fpcsrc/tests/output/${FULL_TARGET}/log ${ADT_ARTIFACTS} + cp -p fpcsrc/tests/output/${FULL_TARGET}/longlog ${ADT_ARTIFACTS} +fi + +# Compare the new results with known results if we have them +REF_FILE=debian/tests/ref_fail_${FULL_TARGET} +if [ -f ${REF_FILE} ] ; then + echo + echo Difference between expected failures and current failures: + diff ${REF_FILE} fpcsrc/tests/output/${FULL_TARGET}/faillist || true + echo + echo "Checking (and fail if so) for new failures:" + if diff ${REF_FILE} fpcsrc/tests/output/${FULL_TARGET}/faillist | grep \>\ >/dev/null ; then + echo "Unexpected failures" + return 1 + else + echo "No new failures" + fi +else + echo "No reference file found for $FULL_TARGET. Please consider adding one." +fi + +# For debugging, add clean target +if [ -n "$CLEAN" ] ; then + make -C fpcsrc/tests digest TEST_FPC=`which fpc` + debian/rules clean-makefiles + rm debian/deb-build-fpc.cfg +fi diff --git a/watch b/watch new file mode 100644 index 00000000..2d092190 --- /dev/null +++ b/watch @@ -0,0 +1,8 @@ +version=3 +# Original line if repacking is needed... +opts=uversionmangle=s/(RC)/\L$1/;\ +s/(\d)((rc|pre|dev|beta|alpha|b|a))/$1~$2/;\ +s/\-\d//;\ +s/\-src//,\ +dversionmangle=s/\+dfsg// \ +http://sf.net/freepascal/ fpcbuild-(.*).tar.gz debian debian/orig-tar.sh