Index: Makefile.riscpkg =================================================================== RCS file: Makefile.riscpkg diff -N Makefile.riscpkg --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Makefile.riscpkg 15 Feb 2005 14:34:29 -0000 1.2 @@ -0,0 +1,29 @@ +# This file is part of the RISC OS Packaging Project distribution of GCC. +# Copyright © 2005 Graham Shaw. +# Distribution and use are subject to the same terms as GCC as a whole. + +VERSION = 2_95_3 + +all: + mkdir -p libiberty/stage1 + make -C libiberty/stage1 -f ../Makefile.riscpkg stage=stage1 + mkdir -p gcc/autogen + make -C gcc/autogen -f ../Makefile.riscpkg stage=autogen + mkdir -p gcc/stage1 + make -C gcc/stage1 -f ../Makefile.riscpkg dirs + make -C gcc/stage1 -f ../Makefile.riscpkg stage=stage1 + mkdir -p libiberty/stage2 + make -C libiberty/stage2 -f ../Makefile.riscpkg stage=stage2 + mkdir -p gcc/stage2 + make -C gcc/stage2 -f ../Makefile.riscpkg dirs + make -C gcc/stage2 -f ../Makefile.riscpkg stage=stage2 + mkdir -p libiberty/stage3 + make -C libiberty/stage3 -f ../Makefile.riscpkg stage=stage3 + mkdir -p gcc/stage3 + make -C gcc/stage3 -f ../Makefile.riscpkg dirs + make -C gcc/stage3 -f ../Makefile.riscpkg stage=stage3 + mkdir -p libio/stage3 + make -C libio/stage3 -f ../Makefile.riscpkg stage=stage3 + mkdir -p libstdc++/stage3 + mkdir -p libstdc++/stage3/std + make -C libstdc++/stage3 -f ../Makefile.riscpkg stage=stage3 Index: !GCC/!Boot,feb =================================================================== RCS file: !GCC/!Boot,feb diff -N !GCC/!Boot,feb --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ !GCC/!Boot,feb 19 Feb 2005 19:08:32 -0000 1.4 @@ -0,0 +1,11 @@ +| This file is part of the RISC OS Packaging Project distribution of GCC. +| Copyright © 2005 Graham Shaw. +| Distribution and use are subject to the GNU General Public License, +| a copy of which may be found in the file ".GPL-2". + +If "" = "" Then Set GCC$Dir +If "" = "" Then Set GCC$Path . +IfThere .bin.gcc Then If "" = "" Then Set Alias$gcc /.bin.gcc %%*0 +IfThere .bin.g++ Then If "" = "" Then Set Alias$g++ /.bin.g++ %%*0 +IfThere .bin.cpp Then If "" = "" Then Set Alias$cpp /.bin.cpp %%*0 +IconSprites .!Sprites Index: !GCC/!Run,feb =================================================================== RCS file: !GCC/!Run,feb diff -N !GCC/!Run,feb --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ !GCC/!Run,feb 19 Feb 2005 19:08:32 -0000 1.4 @@ -0,0 +1,11 @@ +| This file is part of the RISC OS Packaging Project distribution of GCC. +| Copyright © 2005 Graham Shaw. +| Distribution and use are subject to the GNU General Public License, +| a copy of which may be found in the file ".GPL-2". + +Set GCC$Dir +Set GCC$Path . +IfThere .bin.gcc Then Set Alias$gcc /.bin.gcc %%*0 +IfThere .bin.g++ Then Set Alias$g++ /.bin.g++ %%*0 +IfThere .bin.cpp Then Set Alias$cpp /.bin.cpp %%*0 +IconSprites .!Sprites Index: !GCC/!Sprites.uue =================================================================== RCS file: !GCC/!Sprites.uue diff -N !GCC/!Sprites.uue --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ !GCC/!Sprites.uue 15 Feb 2005 19:30:47 -0000 1.1 @@ -0,0 +1,12 @@ +begin 707 !GCC/!Sprites,ff9 +M`0```!````"0`0``@`$``"%G8V,```````````0````0``````````<````L +M````+`````P````````````````````````````````S```````````````` +M`#,`````````L+L`"P`+"P`+````````````,P`+``"[``L+``L````S```` +M``````NP"PL+"PL`"P```````````#,`"P`+"[`+"P`+````,P````````"P +MNP`+``NPNP`````````````S`````````````````#,`````````.GPL-2". + +If "" = "" Then Set LibIberty$Dir +If "" = "" Then Set LibIberty$Path .,.include. +IconSprites .!Sprites Index: !LibIberty/!Run,feb =================================================================== RCS file: !LibIberty/!Run,feb diff -N !LibIberty/!Run,feb --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ !LibIberty/!Run,feb 19 Feb 2005 19:44:34 -0000 1.1 @@ -0,0 +1,8 @@ +| This file is part of the RISC OS Packaging Project distribution of GCC. +| Copyright © 2005 Graham Shaw. +| Distribution and use are subject to the GNU General Public License, +| a copy of which may be found in the file ".GPL-2". + +Set LibIberty$Dir +Set LibIberty$Path .,.include. +IconSprites .!Sprites Index: !LibIberty/!Sprites.uue =================================================================== RCS file: !LibIberty/!Sprites.uue diff -N !LibIberty/!Sprites.uue --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ !LibIberty/!Sprites.uue 19 Feb 2005 19:44:34 -0000 1.1 @@ -0,0 +1,12 @@ +begin 707 !LibIberty/!Sprites,ff9 +M`0```!````"0`0``@`$``"%L:6)I8F5R='D```0````0``````````<````L +M````+`````P````````````````````````````````S```````````````` +M`#,`````````!P``!P``````````````````,P`'``<'```````````S```` +M``````<``'<#`````````````````#,`!P`'!P<`````````,P````````!W +M!P=W`P`````````````````S`````````````````#,`````````=P<'```` +M```'````````````,P!P``<```````<````S`````````'``=P-S`W,#=W!P +M`````````#,`<``'!S<'!P`'<'``,P````````!W!W<#.GPL-2". + +If "" = "" Then Set LibStdCxx$Dir +If "" = "" Then Set LibStdCxx$Path .,.include. +IconSprites .!Sprites Index: !LibStdC++/!Run,feb =================================================================== RCS file: !LibStdC++/!Run,feb diff -N !LibStdC++/!Run,feb --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ !LibStdC++/!Run,feb 20 Feb 2005 20:21:21 -0000 1.2 @@ -0,0 +1,8 @@ +| This file is part of the RISC OS Packaging Project distribution of GCC. +| Copyright © 2005 Graham Shaw. +| Distribution and use are subject to the GNU General Public License, +| a copy of which may be found in the file ".GPL-2". + +Set LibStdCxx$Dir +Set LibStdCxx$Path .,.include. +IconSprites .!Sprites Index: !LibStdC++/!Sprites.uue =================================================================== RCS file: !LibStdC++/!Sprites.uue diff -N !LibStdC++/!Sprites.uue --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ !LibStdC++/!Sprites.uue 19 Feb 2005 19:48:06 -0000 1.2 @@ -0,0 +1,12 @@ +begin 707 !LibStdC++/!Sprites,ff9 +M`0```!````"0`0``@`$``"%L:6)S=&1C*RL```0````0``````````<````L +M````+`````P````````````````````````````````S```````````````` +M`#,`````````!P`'!P!S1W```'``````````,P`'```'``<@<```<``S```` +M``````<`!W<#<`=P=S!W`````````#,`!P`'!P<"<'``<'``,P````````!W +M!P=W`W0W,' +Standards-Version: 0.1.0 +Version: 2.95.3-0 +Description: The GCC Software Development Kit for RISC OS. + GCC is the GNU Compiler Collection. It includes front ends for C, + C++, Objective-C, Fortran, Java and Ada, as well as standard + libraries for these languages. + . + GCCSDK is a port of GCC to RISC OS. Additions include an + APCS-compatible back end, tools for manipulating AOF files, and + the compatibility library UnixLib. + +Package: GCC-Common +Description: Common files required for the GNU Compiler Collection. + +Package: CPP +Depends: CPP-2.95 +Description: The GNU C Preprocessor front end. + +Package: CPP-2.95 +Depends: CPP (>= 2.95.3) +Description: The GNU C Preprocessor back end, version 2.95. + +Package: GCC +Depends: CPP-2.95, GCC-2.95 +Recommends: Ld-GCCSDK (>= 2.22), As +Description: The GNU C Compiler front end. + +Package: GCC-2.95 +Depends: GCC (>= 2.95.3) +Recommends: UnixLib-Dev (>= 4.0) +Description: The GNU C Compiler back end, version 2.95. + +Package: G++ +Depends: CPP-2.95, GCC-2.95, G++-2.95 +Recommends: Ld-GCCSDK, As +Description: The GNU C++ Compiler front end. + +Package: G++-2.95 +Depends: G++ (>= 2.95.3), LibStdC++-Dev (>= 2.10) +Description: The GNU C++ Compiler back end, version 2.95. + +Package: LibIberty-Dev +Description: A collection of subroutines from the GNU project. + +Package: LibStdC++-Dev +Description: The GNU C++ Standard Library +Version: 2.10.0-0 Index: RiscPkg/Copyright =================================================================== RCS file: RiscPkg/Copyright diff -N RiscPkg/Copyright --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ RiscPkg/Copyright 19 Feb 2005 19:46:24 -0000 1.2 @@ -0,0 +1,101 @@ +This is the RISC OS Packaging Project distribution of GCC (version 2.95). + +GCC is published by the Free Software Foundation. + +GCC was originally written by Richard Stallman, with the first +release occurring in 1987. A list of current maintainers can +be found in the file 'MAINTAINERS' within the GCC-2.95 source +package. + +The upstream sources were downloaded from the URL: + +ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3.tar.gz + +on 7th February 2005. + +RISC OS-specific patches were obtained from GCCSDK, +which is maintained by Nick Burrett. They were exported +by anonymous CVS from: + +:pserver:anoncvs@gccsdk.riscos.info:/usr/local/cvsroot + +from the release_2_95 branch. + +There is a homepage for GCC at the URL: + +http://gcc.gnu.org/ + +and for GCCSDK at the URL: + +http://gccsdk.riscos.info/ + +Distribution and use are subject to the GNU General Public License, +a copy of which may be found in the file ".GPL-2". + +The following exception to the General Public Licence applies to the +run-time libraries libgcc, libio, libiostream, libstdc++, libobjc +and libchill: + +== begin == +As a special exception, if you link this library with other files, +some of which are compiled with GCC, to produce an executable, +this library does not by itself cause the resulting executable +to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. +== end == + +Large parts of the library libstdc++ were written by Silicon Graphics +Computer Systems and/or the Hewlett-Packard Company and are subject +to the following licences: + +== begin == +Copyright (c) 1996,1997,1998 +Silicon Graphics Computer Systems, Inc. + +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. Silicon Graphics makes no +representations about the suitability of this software for any +purpose. It is provided "as is" without express or implied warranty. +== end == + +== begin == +Copyright (c) 1994 +Hewlett-Packard Company + +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. Hewlett-Packard Company makes no +representations about the suitability of this software for any +purpose. It is provided "as is" without express or implied warranty. +== end == + +The library libf2c is subject to the following licence: + +== begin == +Copyright 1990 - 1997 by AT&T, Lucent Technologies and Bellcore. + +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 the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the names of AT&T, Bell Laboratories, +Lucent or Bellcore or any of their entities not be used in +advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +AT&T, Lucent and Bellcore disclaim all warranties with regard to +this software, including all implied warranties of +merchantability and fitness. In no event shall AT&T, Lucent or +Bellcore 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. +== end == Index: RiscPkg/G++-2.95.inc =================================================================== RCS file: RiscPkg/G++-2.95.inc diff -N RiscPkg/G++-2.95.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ RiscPkg/G++-2.95.inc 20 Feb 2005 20:23:48 -0000 1.1 @@ -0,0 +1,2 @@ +RiscPkg.* +Apps.Programming.!GCC.gcc-lib.arm-riscos.2/95/3.cc1plus Index: RiscPkg/G++.inc =================================================================== RCS file: RiscPkg/G++.inc diff -N RiscPkg/G++.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ RiscPkg/G++.inc 20 Feb 2005 20:23:48 -0000 1.1 @@ -0,0 +1,3 @@ +RiscPkg.* +SysVars.Alias=24g++ +Apps.Programming.!GCC.bin.g++ Index: RiscPkg/GCC-2.95.inc =================================================================== RCS file: RiscPkg/GCC-2.95.inc diff -N RiscPkg/GCC-2.95.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ RiscPkg/GCC-2.95.inc 20 Feb 2005 20:23:48 -0000 1.1 @@ -0,0 +1,5 @@ +RiscPkg.* +Apps.Programming.!GCC.gcc-lib.arm-riscos.2/95/3.cc1 +Apps.Programming.!GCC.gcc-lib.arm-riscos.2/95/3.a.libgcc +Apps.Programming.!GCC.gcc-lib.arm-riscos.2/95/3.include.* +Apps.Programming.!GCC.gcc-lib.arm-riscos.2/95/3.include.h.* Index: RiscPkg/GCC-Common.inc =================================================================== RCS file: RiscPkg/GCC-Common.inc diff -N RiscPkg/GCC-Common.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ RiscPkg/GCC-Common.inc 20 Feb 2005 20:23:48 -0000 1.1 @@ -0,0 +1,8 @@ +RiscPkg.* +Sprites.!gcc +SysVars.GCC=24Dir +SysVars.GCC=24Path +Apps.Programming.!GCC.!Boot +Apps.Programming.!GCC.!Run +Apps.Programming.!GCC.!Sprites +Apps.Programming.!GCC.!Sprites22 Index: RiscPkg/GCC.inc =================================================================== RCS file: RiscPkg/GCC.inc diff -N RiscPkg/GCC.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ RiscPkg/GCC.inc 20 Feb 2005 20:23:48 -0000 1.1 @@ -0,0 +1,3 @@ +RiscPkg.* +SysVars.Alias=24gcc +Apps.Programming.!GCC.bin.gcc Index: RiscPkg/LibIberty-Dev.inc =================================================================== RCS file: RiscPkg/LibIberty-Dev.inc diff -N RiscPkg/LibIberty-Dev.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ RiscPkg/LibIberty-Dev.inc 20 Feb 2005 20:23:48 -0000 1.1 @@ -0,0 +1,7 @@ +RiscPkg.* +Sprites.!libiberty +SysVars.LibIberty=24Dir +SysVars.LibIberty=24Path +Apps.Library.!LibIberty.!* +Apps.Library.!LibIberty.a.libiberty +Apps.Library.!LibIberty.include.h.* Index: RiscPkg/LibStdC++-Dev.inc =================================================================== RCS file: RiscPkg/LibStdC++-Dev.inc diff -N RiscPkg/LibStdC++-Dev.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ RiscPkg/LibStdC++-Dev.inc 24 Feb 2005 00:33:35 -0000 1.2 @@ -0,0 +1,15 @@ +RiscPkg.* +Sprites.!libstdc++ +SysVars.LibStdCxx=24Dir +SysVars.LibStdCxx=24Path +Apps.Library.!LibStdC++.!Boot +Apps.Library.!LibStdC++.!Run +Apps.Library.!LibStdC++.!Sprites +Apps.Library.!LibStdC++.!Sprites22 +Apps.Library.!LibStdC++.a.libiostream +Apps.Library.!LibStdC++.a.libio +Apps.Library.!LibStdC++.a.libstdc++ +Apps.Library.!LibStdC++.include.* +Apps.Library.!LibStdC++.include.h.* +Apps.Library.!LibStdC++.include.std.h.* +Apps.Library.!LibStdC++.include.std.cc.* Index: RiscPkg/Rules =================================================================== RCS file: RiscPkg/Rules diff -N RiscPkg/Rules --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ RiscPkg/Rules 20 Feb 2005 20:23:48 -0000 1.1 @@ -0,0 +1,139 @@ +GCC_VERSION = 2.95.3-0 +LIBSTDCXX_VERSION = 2.10.0-0 + +GCC_DIR = Apps/Programming/!GCC +BIN_DIR = $(GCC_DIR)/bin +LIB_DIR = $(GCC_DIR)/gcc-lib +TARGET_DIR = $(LIB_DIR)/arm-riscos/2.95.3 +INCLUDE_DIR = $(TARGET_DIR)/include +LIBIBERTY_DIR = Apps/Library/!LibIberty +LIBSTDCXX_DIR = Apps/Library/!LibStdC++ + +PACKAGES = \ + GCC-Common_$(GCC_VERSION) \ + CPP_$(GCC_VERSION) \ + CPP-2.95_$(GCC_VERSION) \ + GCC_$(GCC_VERSION) \ + GCC-2.95_$(GCC_VERSION) \ + G++_$(GCC_VERSION) \ + G++-2.95_$(GCC_VERSION) \ + LibIberty-Dev_$(GCC_VERSION) \ + LibStdC++-Dev_$(LIBSTDCXX_VERSION) + +SPRITES = \ + !GCC/!Sprites \ + !GCC/!Sprites22 \ + !LibIberty/!Sprites \ + !LibIberty/!Sprites22 \ + !LibStdC++/!Sprites \ + !LibStdC++/!Sprites22 + +_GCC_HDRS = iso646.h stdarg.h stdbool.h varargs.h +GCC_HDRS = $(addprefix gcc/ginclude/,$(_GCC_HDRS)) +_GXX_HDRS = exception new typeinfo new.h +GXX_HDRS = $(addprefix gcc/cp/inc/,$(_GXX_HDRS)) +_IO_FILTER = _G_config.h +IO_FILTER = $(addprefix libio/,$(_IO_FILTER))) +IO_HDRS = $(filter-out $(IO_FILTER),$(wildcard libio/*.h)) +_CXX_FILTER = CVS config std stl tests testsuite stage3 \ + %.cc Makefile% configure% ChangeLog NEWS +CXX_FILTER = $(addprefix libstdc++/,$(_CXX_FILTER)) +CXX_HDRS = $(filter-out $(CXX_FILTER),$(wildcard libstdc++/*)) +_STD_FILTER = CVS valarray_array.tcc +STD_FILTER = $(addprefix libstdc++/std/,$(_STD_FILTER)) +STD_HDRS = $(filter-out $(STD_FILTER),$(wildcard libstdc++/std/*)) +_STL_FILTER = CVS README ChangeLog +STL_FILTER = $(addprefix libstdc++/stl/,$(_STL_FILTER)) +STL_HDRS = $(filter-out $(STL_FILTER),$(wildcard libstdc++/stl/*)) + +.PHONY: all +all: uudecode + make -f Makefile.riscpkg + rm -rf Temp + mkdir -p Temp/RiscPkg + mkdir -p Temp/Apps/Programming + cp RiscPkg/Copyright Temp/RiscPkg/ + cp -R !GCC Temp/Apps/Programming/ + mkdir -p Temp/$(BIN_DIR) + cp gcc/stage3/xcpp Temp/$(BIN_DIR)/cpp + cp gcc/stage3/xgcc Temp/$(BIN_DIR)/gcc + cp gcc/stage3/xg++ Temp/$(BIN_DIR)/g++ + mkdir -p Temp/$(TARGET_DIR) + cp gcc/stage3/cpp0 Temp/$(TARGET_DIR)/ + cp gcc/stage3/cc1 Temp/$(TARGET_DIR)/ + cp gcc/stage3/cc1plus Temp/$(TARGET_DIR)/ + cp gcc/stage3/libgcc.a Temp/$(TARGET_DIR)/ + mkdir -p Temp/$(INCLUDE_DIR) + cp $(GCC_HDRS) Temp/$(INCLUDE_DIR)/ + cp $(GXX_HDRS) Temp/$(INCLUDE_DIR)/ + + mkdir -p Temp/$(LIBIBERTY_DIR) + cp -R !LibIberty Temp/Apps/Library + cp libiberty/stage3/libiberty.a Temp/$(LIBIBERTY_DIR) + mkdir -p Temp/$(LIBIBERTY_DIR)/include + cp $(wildcard include/*.h) Temp/$(LIBIBERTY_DIR)/include + + mkdir -p Temp/$(LIBSTDCXX_DIR) + cp -R !LibStdC++ Temp/Apps/Library/ + cp libio/stage3/libiostream.a Temp/$(LIBSTDCXX_DIR) + cp libio/stage3/libio.a Temp/$(LIBSTDCXX_DIR) + cp libstdc++/stage3/libstdc++.a Temp/$(LIBSTDCXX_DIR) + mkdir -p Temp/$(LIBSTDCXX_DIR)/include + cp $(IO_HDRS) Temp/$(LIBSTDCXX_DIR)/include/ + cp $(CXX_HDRS) Temp/$(LIBSTDCXX_DIR)/include/ + cp $(STL_HDRS) Temp/$(LIBSTDCXX_DIR)/include/ + mkdir -p Temp/$(LIBSTDCXX_DIR)/include/std + cp $(STD_HDRS) Temp/$(LIBSTDCXX_DIR)/include/std/ + + chmod -R 444 Temp/Apps + cp -R SysVars Temp/SysVars/ + cp -R Sprites Temp/Sprites/ + mkdir -p Packages + make -C Temp -f ../RiscPkg/Rules $(PACKAGES) + rm -rf Temp + +.PHONY: $(PACKAGES) +$(PACKAGES): %: + riscpkg-gencontrol $(firstword $(subst _, ,$@)) < ../RiscPkg/Control > RiscPkg/Control + rm -f ../Packages/$@ + zip -r ^.Packages.$(subst .,/,$@) * -i@^.RiscPkg.$(subst .,/,$(firstword $(subst _, ,$@)))/inc + +# ---------------------------------------- +# $(uu) == encode +# ---------------------------------------- + +.PHONY: uuencode + +ifeq (encode,$(uu)) + +uuencode: $(addsuffix .uue,$(SPRITES)) + +%.uue: % + uuencode $^,ff9 $^,ff9 > $@ + +else + +uuencode: + make -f RiscPkg/Rules uuencode uu=encode + +endif + +# ---------------------------------------- +# $(uu) == decode +# ---------------------------------------- + +.PHONY: uudecode + +ifeq (decode,$(uu)) + +uudecode: $(SPRITES) + +%: %.uue + uudecode -o $@,ff9 $^ + +else + +uudecode: + make -f RiscPkg/Rules uudecode uu=decode + +endif Index: Sprites/!gcc =================================================================== RCS file: Sprites/!gcc diff -N Sprites/!gcc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Sprites/!gcc 16 Feb 2005 18:24:23 -0000 1.1 @@ -0,0 +1 @@ +.!Sprites \ No newline at end of file Index: Sprites/!libiberty =================================================================== RCS file: Sprites/!libiberty diff -N Sprites/!libiberty --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Sprites/!libiberty 19 Feb 2005 19:44:34 -0000 1.1 @@ -0,0 +1 @@ +.!Sprites \ No newline at end of file Index: Sprites/!libstdc++ =================================================================== RCS file: Sprites/!libstdc++ diff -N Sprites/!libstdc++ --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Sprites/!libstdc++ 16 Feb 2005 18:24:23 -0000 1.1 @@ -0,0 +1 @@ +.!Sprites \ No newline at end of file Index: SysVars/Alias=24cpp =================================================================== RCS file: SysVars/Alias=24cpp diff -N SysVars/Alias=24cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ SysVars/Alias=24cpp 16 Feb 2005 18:24:23 -0000 1.1 @@ -0,0 +1 @@ +/.bin.cpp %*0 \ No newline at end of file Index: SysVars/Alias=24g++ =================================================================== RCS file: SysVars/Alias=24g++ diff -N SysVars/Alias=24g++ --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ SysVars/Alias=24g++ 16 Feb 2005 18:24:23 -0000 1.1 @@ -0,0 +1 @@ +/.bin.g++ %*0 \ No newline at end of file Index: SysVars/Alias=24gcc =================================================================== RCS file: SysVars/Alias=24gcc diff -N SysVars/Alias=24gcc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ SysVars/Alias=24gcc 16 Feb 2005 18:24:23 -0000 1.1 @@ -0,0 +1 @@ +/.bin.gcc %*0 \ No newline at end of file Index: SysVars/GCC=24Dir =================================================================== RCS file: SysVars/GCC=24Dir diff -N SysVars/GCC=24Dir --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ SysVars/GCC=24Dir 16 Feb 2005 18:24:23 -0000 1.1 @@ -0,0 +1 @@ + \ No newline at end of file Index: SysVars/GCC=24Path =================================================================== RCS file: SysVars/GCC=24Path diff -N SysVars/GCC=24Path --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ SysVars/GCC=24Path 16 Feb 2005 18:24:23 -0000 1.1 @@ -0,0 +1 @@ +. \ No newline at end of file Index: SysVars/LibIberty=24Dir =================================================================== RCS file: SysVars/LibIberty=24Dir diff -N SysVars/LibIberty=24Dir --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ SysVars/LibIberty=24Dir 19 Feb 2005 19:52:01 -0000 1.2 @@ -0,0 +1 @@ + \ No newline at end of file Index: SysVars/LibIberty=24Path =================================================================== RCS file: SysVars/LibIberty=24Path diff -N SysVars/LibIberty=24Path --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ SysVars/LibIberty=24Path 19 Feb 2005 19:44:34 -0000 1.1 @@ -0,0 +1 @@ +.,.include. \ No newline at end of file Index: SysVars/LibStdCxx=24Dir =================================================================== RCS file: SysVars/LibStdCxx=24Dir diff -N SysVars/LibStdCxx=24Dir --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ SysVars/LibStdCxx=24Dir 20 Feb 2005 20:21:21 -0000 1.1 @@ -0,0 +1 @@ + \ No newline at end of file Index: SysVars/LibStdCxx=24Path =================================================================== RCS file: SysVars/LibStdCxx=24Path diff -N SysVars/LibStdCxx=24Path --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ SysVars/LibStdCxx=24Path 20 Feb 2005 20:21:21 -0000 1.1 @@ -0,0 +1 @@ +.,.include. \ No newline at end of file Index: gcc/Makefile.riscpkg =================================================================== RCS file: gcc/Makefile.riscpkg diff -N gcc/Makefile.riscpkg --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gcc/Makefile.riscpkg 20 Feb 2005 20:22:10 -0000 1.3 @@ -0,0 +1,376 @@ +# This file is part of the RISC OS Packaging Project distribution of GCC. +# Copyright © 2005 Graham Shaw. +# Distribution and use are subject to the same terms as GCC as a whole. + +include fixdeps:Rules/make + +topdir=../.. +srcdir=.. + +srcpath = $(srcdir)/autogen:$(srcdir) +vpath %.h $(srcpath) +vpath %.c $(srcpath) +vpath %.cc $(srcpath) +vpath config/% $(srcpath) + +MD = $(srcdir)/config/arm/arm.md +CCFLAGS = -mthrowback -munixlib -mpoke-function-name -O2 +CXXFLAGS = -mthrowback -munixlib -mpoke-function-name -O2 + +# ---------------------------------------- +# $(stage) == autogen +# ---------------------------------------- + +ifeq ($(stage),autogen) + +CPPFLAGS = -I. \ + -I$(srcdir) \ + -I$(topdir)/include \ + -I$(srcdir)/config \ + -DHOST_ARM_RISCOS -DIN_GCC + +ifneq (,$(wildcard /libiberty:/*)) +LIBS = -llibiberty:a.libiberty +else +LIBS = -liberty +endif + +GEN_MD_H = \ + insn-attr.h \ + insn-flags.h \ + insn-codes.h \ + insn-config.h + +GEN_MD_C = \ + insn-attrtab.c \ + insn-emit.c \ + insn-output.c \ + insn-recog.c \ + insn-extract.c \ + insn-peep.c \ + insn-opinit.c + +GEN_MD := $(GEN_MD_H) $(GEN_MD_C) + +GEN_MD_BIN := \ + $(patsubst insn-%.h,gen%,$(GEN_MD_H)) \ + $(patsubst insn-%.c,gen%,$(GEN_MD_C)) + +GEN_ALL = \ + $(GEN_MD) \ + tree.h \ + genrtl.h + +.PHONY: all +all: $(GEN_ALL) tconfig.h + +OBJ_BIN = rtl.o bitmap.o +EXTRA_OBJ_genattrtab = rtlanal.o +EXTRA_OBJ_genrecog = print-rtl.o +ALL_OBJ_BIN = $(OBJ_BIN) rtlanal.o print-rtl.o + +$(GEN_MD_BIN): %: %.o $(ALL_OBJ_BIN) + $(LD) -o $@ $< $(OBJ_BIN) $(EXTRA_OBJ_$@) $(LIBS) + +$(GEN_MD_BIN:=.o): hconfig.h genrtl.h + +$(GEN_MD_H): insn-%.h: $(MD) gen% + ./gen$* $(MD) > insn-$*.h +$(GEN_MD_C): insn-%.c: $(MD) gen% + ./gen$* $(MD) > insn-$*.c + +hconfig.h: config.h + cp $< $@ + +tconfig.h: config.h + cp $< $@ + +genrtl.h gentrl.c: gengenrtl + ./gengenrtl genrtl.h genrtl.c + +tree.h: tree-check.h +tree-check.h: gencheck + ./gencheck > tree-check.h + +endif + +# ---------------------------------------- +# $(stage) == stage1, stage2 or stage3 +# ---------------------------------------- + +ifneq (,$(findstring stage,$(stage))) + +LD = drlink -rescan + +ifeq (stage1,$(stage)) +LIBS = unixlib:unixlib.a \ + $(topdir)/libiberty/stage1/libiberty.a +endif + +ifeq (stage2,$(stage)) +CC = $(srcdir)/stage1/xgcc -B$(srcdir)/stage1/ +CXX = $(CC) +LIBS = unixlib:unixlib.a \ + $(topdir)/libiberty/stage2/libiberty.a +endif + +ifeq (stage3,$(stage)) +CC = $(srcdir)/stage2/xgcc -B$(srcdir)/stage2/ +CXX = $(CC) +LIBS = unixlib:unixlib.a \ + $(topdir)/libiberty/stage3/libiberty.a +endif + +TARGET_NAME = arm-riscos +VERSION = 2.95.3 + +TARGET_PATH = /gcc:/gcc-lib/$(TARGET_NAME)/$(VERSION) +GCC_INCLUDE_DIR = $(TARGET_PATH)/include +GXX_INCLUDE_DIR = /libstdcxx:/include +SYSTEM_INCLUDE_DIR = /unixlib:/include + +CPPFLAGS = \ + -nostdinc \ + -I/unixlib: \ + -I$(topdir)/gcc/ginclude \ + -I$(topdir)/gcc/cp/inc \ + -I$(topdir)/include \ + -I$(srcdir)/autogen \ + -I$(srcdir) \ + -I$(srcdir)/config \ + -DTARGET_RISCOSAOF \ + -DHOST_ARM_RISCOS \ + -DHAVE_CONFIG_H \ + -DIN_GCC \ + -DDEFAULT_TARGET_VERSION=\"$(VERSION)\" \ + -DDEFAULT_TARGET_MACHINE=\"$(TARGET_NAME)\" \ + -DTARGET_NAME=\"$(TARGET_NAME)\" \ + -DPREFIX=\"/nowhere/\" \ + -DSTANDARD_EXEC_PREFIX=\"/gcc-lib/\" \ + -DGCC_INCLUDE_DIR=\"$(GCC_INCLUDE_DIR)\" \ + -DGXX_INCLUDE_DIR=\"$(GXX_INCLUDE_DIR)\" \ + -DSYSTEM_INCLUDE_DIR=\"$(SYSTEM_INCLUDE_DIR)\" \ + -DDONT_USE_BUILTIN_SETJMP \ + -DJMP_BUF_SIZE=27 + + +GCC_OBJS = \ + gcc.o \ + gccspec.o \ + prefix.o \ + version.o + +CPP_OBJS = \ + cccp.o \ + cexp.o \ + prefix.o \ + version.o + +CPP0_OBJS = \ + cppmain.o \ + cpplib.o \ + cpphash.o \ + cppalloc.o \ + cpperror.o \ + cppexp.o \ + cppfiles.o \ + cppinit.o \ + cppulp.o \ + prefix.o \ + version.o + +RISCOS_OBJS = \ + config/arm/riscos.o \ + config/arm/arm.o + +# Language-specific object files for C and Objective C. +C_AND_OBJC_OBJS = c-lex.o c-pragma.o c-decl.o c-typeck.o c-convert.o \ + c-aux-info.o c-common.o c-iterate.o + +# Language-specific object files for C. +C_OBJS = c-parse.o c-lang.o $(C_AND_OBJC_OBJS) + +# Language-independent object files. +OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \ + function.o stmt.o except.o expr.o calls.o expmed.o explow.o optabs.o \ + varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o genrtl.o real.o \ + dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o gcse.o \ + integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o varray.o \ + regclass.o regmove.o local-alloc.o global.o reload.o reload1.o caller-save.o \ + insn-peep.o reorg.o $(SCHED_PREFIX)sched.o final.o recog.o reg-stack.o \ + insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o lcm.o \ + profile.o insn-attrtab.o $(out_object_file) getpwd.o $(EXTRA_OBJS) convert.o \ + dyn-string.o graph.o sbitmap.o resource.o hash.o + +LIBGCC2_OBJS = \ + _main.o \ + _gcc_bcmp.o \ + _dummy.o \ + eh.o \ + eprintf.o \ + pure.o \ + bb.o \ + +LIB1AOF_OBJS = \ + div0.o \ + arm_alloca.o \ + clear_icache.o \ + ctors.o \ + cmpdi2.o \ + ucmpdi2.o \ + modsi3.o \ + umodsi3.o \ + divsi3.o \ + udivsi3.o \ + moddi3.o \ + umoddi3.o \ + divdi3.o \ + udivdi3.o \ + floatdidf.o \ + fixunsxfdi.o \ + fixunsdfdi.o \ + fixunssfdi.o \ + fixsfdi.o \ + ffs.o \ + ashldi3.o \ + ashrdi3.o \ + lshrdi3.o \ + muldi3.o \ + builtin_next_arg.o \ + +FP_BIT_DOUBLE = \ + pack_df.o \ + unpack_df.o \ + addsub_df.o \ + mul_df.o \ + div_df.o \ + fpcmp_parts_df.o \ + compare_df.o \ + eq_df.o \ + ne_df.o \ + gt_df.o \ + ge_df.o \ + lt_df.o \ + le_df.o \ + si_to_df.o \ + df_to_si.o \ + df_to_usi.o \ + negate_df.o \ + make_df.o \ + df_to_sf.o + +FP_BIT_SINGLE = \ + pack_sf.o \ + unpack_sf.o \ + addsub_sf.o \ + mul_sf.o \ + div_sf.o \ + fpcmp_parts_sf.o \ + compare_sf.o \ + eq_sf.o \ + ne_sf.o \ + gt_sf.o \ + ge_sf.o \ + lt_sf.o \ + le_sf.o \ + si_to_sf.o \ + sf_to_usi.o \ + sf_to_si.o \ + negate_sf.o \ + make_sf.o \ + sf_to_df.o + +NEW1_OBJS = \ + cp/op_new.o \ + cp/op_newnt.o + +NEW2_OBJS = \ + cp/op_vnew.o \ + cp/op_vnewnt.o \ + cp/op_delete.o \ + cp/op_delnt.o \ + cp/op_vdel.o \ + cp/op_vdelnt.o + +ifeq (stage3,$(stage)) +LIBGPP_OBJS = \ + $(NEW1_OBJS) \ + $(NEW2_OBJS) \ + cp/tinfo.o \ + cp/tinfo2.o \ + cp/new.o \ + cp/exception.o +endif + +LIBGCC_OBJS = \ + $(LIBGCC2_OBJS) \ + $(LIB1AOF_OBJS) \ + $(FP_BIT_DOUBLE) \ + $(FP_BIT_SINGLE) \ + libgcc_fix.o + +ifeq (stage1,$(stage)) +all: xgcc cpp0 cc1 libgcc.a +else +ifeq (stage2,$(stage)) +all: xgcc cpp0 cc1 cc1plus libgcc.a +else +all: xcpp xgcc xg++ cpp0 cc1 cc1plus libgcc.a +endif +endif + +xcpp: $(CPP_OBJS) libgcc.a + $(LD) -o $@ $^ $(LIBS) + +xgcc: $(GCC_OBJS) libgcc.a + $(LD) -o $@ $^ $(LIBS) + +cpp0: $(CPP0_OBJS) libgcc.a + $(LD) -o $@ $^ $(LIBS) + +cc1: $(C_OBJS) $(OBJS) $(RISCOS_OBJS) libgcc.a + $(LD) -o $@ $^ $(LIBS) + +libgcc.a: $(LIBGCC_OBJS) $(LIBGPP_OBJS) + mkdir -p a + $(AR) -c a.libgcc $(LIBGCC_OBJS:%.o=o.%) + $(AR) -r a.libgcc $(LIBGPP_OBJS:cp/%.o=cp.o.%) + +$(LIBGCC2_OBJS): %.o: libgcc2.c + $(CC) -c $(CCFLAGS) $(CPPFLAGS) -o $@ $< -DL_$* + +$(LIB1AOF_OBJS): %.o: config/arm/lib1aof.s + $(CC) -c -xassembler-with-cpp $(CPPFLAGS) -o $@ $< -DL_$* + +FPBIT_DEFS_D = -DFINE_GRAINED_LIBRARIES +$(FP_BIT_DOUBLE): %.o: config/fp-bit.c + $(CC) -c $(CCFLAGS) $(CPPFLAGS) -o $@ $< -DL_$* $(FPBIT_DEFS_D) + +FPBIT_DEFS_S = -DFINE_GRAINED_LIBRARIES -DFLOAT +$(FP_BIT_SINGLE): %.o: config/fp-bit.c + $(CC) -c $(CCFLAGS) $(CPPFLAGS) -o $@ $< -DL_$* $(FPBIT_DEFS_S) + +$(NEW1_OBJS): cp/%.o: cp/new1.cc + $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $< -DL_$* + +$(NEW2_OBJS): cp/%.o: cp/new2.cc + $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $< -DL_$* + +libgcc_fix.o: config/arm/libgcc_fix.s + $(CC) -c -xassembler-with-cpp $(CPPFLAGS) -o $@ $< + +include $(srcdir)/cp/Makefile.riscpkg + +include $(CPP_OBJS:.o=.d) +include $(GCC_OBJS:.o=.d) +include $(CPP0_OBJS:.o=.d) +include $(RISCOS_OBJS:.o=.d) +include $(C_OBJS:.o=.d) +include $(OBJS:.o=.d) +include libgcc2.d + +endif + +dirs: + mkdir -p config/arm + mkdir -p cp Index: gcc/config.h =================================================================== RCS file: gcc/config.h diff -N gcc/config.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gcc/config.h 9 Feb 2005 06:23:01 -0000 1.1 @@ -0,0 +1,372 @@ +/* config.h. Hand-edited from config.in by Graham Shaw to match + * features provided by GCC and UnixLib. */ + +/* Define if you can safely include both and . */ +#define STRING_WITH_STRINGS 1 + +/* Define if printf supports "%p". */ +#define HAVE_PRINTF_PTR 1 + +/* Define if you want expensive run-time checks. */ +#undef ENABLE_CHECKING + +/* Define to 1 if NLS is requested. */ +#undef ENABLE_NLS + +/* Define as 1 if you have catgets and don't want to use GNU gettext. */ +#undef HAVE_CATGETS + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +#undef HAVE_GETTEXT + +/* Define if your cpp understands the stringify operator. */ +#define HAVE_CPP_STRINGIFY 1 + +/* Define if your compiler understands volatile. */ +#define HAVE_VOLATILE 1 + +/* Define if your assembler supports specifying the maximum number + of bytes to skip when using the GAS .p2align command. */ +#undef HAVE_GAS_MAX_SKIP_P2ALIGN + +/* Define if your assembler supports .balign and .p2align. */ +#undef HAVE_GAS_BALIGN_AND_P2ALIGN + +/* Define if your assembler supports .subsection and .subsection -1 starts + emitting at the beginning of your section */ +#undef HAVE_GAS_SUBSECTION_ORDERING + +/* Define if your assembler uses the old HImode fild and fist notation. */ +#undef HAVE_GAS_FILDS_FISTS + +/* Define if you have a working header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if your locale.h file contains LC_MESSAGES. */ +#define HAVE_LC_MESSAGES 1 + +/* Define as 1 if you have the stpcpy function. */ +#define HAVE_STPCPY 1 + +/* Whether malloc must be declared even if is included. */ +#undef NEED_DECLARATION_MALLOC + +/* Whether realloc must be declared even if is included. */ +#undef NEED_DECLARATION_REALLOC + +/* Whether calloc must be declared even if is included. */ +#undef NEED_DECLARATION_CALLOC + +/* Whether free must be declared even if is included. */ +#undef NEED_DECLARATION_FREE + +/* Whether bcopy must be declared even if is included. */ +#undef NEED_DECLARATION_BCOPY + +/* Whether bcmp must be declared even if is included. */ +#undef NEED_DECLARATION_BCMP + +/* Whether bzero must be declared even if is included. */ +#undef NEED_DECLARATION_BZERO + +/* Whether index must be declared even if is included. */ +#undef NEED_DECLARATION_INDEX + +/* Whether rindex must be declared even if is included. */ +#undef NEED_DECLARATION_RINDEX + +/* Whether getenv must be declared even if is included. */ +#undef NEED_DECLARATION_GETENV + +/* Whether atol must be declared even if is included. */ +#undef NEED_DECLARATION_ATOL + +/* Whether atof must be declared even if is included. */ +#undef NEED_DECLARATION_ATOF + +/* Whether sbrk must be declared even if is included. */ +#undef NEED_DECLARATION_SBRK + +/* Whether abort must be declared even if is included. */ +#undef NEED_DECLARATION_ABORT + +/* Whether strerror must be declared even if is included. */ +#undef NEED_DECLARATION_STRERROR + +/* Whether strsignal must be declared even if is included. */ +#undef NEED_DECLARATION_STRSIGNAL + +/* Whether strstr must be declared even if is included. */ +#undef NEED_DECLARATION_STRSTR + +/* Whether getcwd must be declared even if is included. */ +#undef NEED_DECLARATION_GETCWD + +/* Whether getwd must be declared even if is included. */ +#undef NEED_DECLARATION_GETWD + +/* Whether getrlimit must be declared even if is included. */ +#undef NEED_DECLARATION_GETRLIMIT + +/* Whether setrlimit must be declared even if is included. */ +#undef NEED_DECLARATION_SETRLIMIT + +/* Whether putc_unlocked must be declared even if is included. */ +#undef NEED_DECLARATION_PUTC_UNLOCKED + +/* Whether fputs_unlocked must be declared even if is included. */ +#undef NEED_DECLARATION_FPUTS_UNLOCKED + +/* Define to enable the use of a default assembler. */ +#undef DEFAULT_ASSEMBLER + +/* Define to enable the use of a default linker. */ +#undef DEFAULT_LINKER + +/* Define if host mkdir takes a single argument. */ +#undef MKDIR_TAKES_ONE_ARG + +/* Define to the name of the distribution. */ +#define PACKAGE "gcc" + +/* Define to the version of the distribution. */ +#define VERSION "2.95.3" + +/* Define if using alloca.c. */ +#undef C_ALLOCA + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +#undef CRAY_STACKSEG_END + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have and it should be used (not on Ultrix). */ +#define HAVE_ALLOCA_H 1 + +/* Define if you don't have vprintf but do have _doprnt. */ +#undef HAVE_DOPRNT + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have . */ +#undef HAVE_VFORK_H + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define to `long' if doesn't define. */ +#undef off_t + +/* Define to `int' if doesn't define. */ +#undef pid_t + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +#undef STACK_DIRECTION + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if `sys_siglist' is declared by . */ +#define SYS_SIGLIST_DECLARED 1 + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define vfork as fork if vfork does not work. */ +#undef vfork + +/* Define if you have the __argz_count function. */ +#undef HAVE___ARGZ_COUNT + +/* Define if you have the __argz_next function. */ +#undef HAVE___ARGZ_NEXT + +/* Define if you have the __argz_stringify function. */ +#undef HAVE___ARGZ_STRINGIFY + +/* Define if you have the atoll function. */ +#define HAVE_ATOLL 1 + +/* Define if you have the atoq function. */ +#undef HAVE_ATOQ + +/* Define if you have the bcmp function. */ +#define HAVE_BCMP 1 + +/* Define if you have the bcopy function. */ +#define HAVE_BCOPY 1 + +/* Define if you have the bsearch function. */ +#define HAVE_BSEARCH 1 + +/* Define if you have the bzero function. */ +#define HAVE_BZERO 1 + +/* Define if you have the dcgettext function. */ +#undef HAVE_DCGETTEXT + +/* Define if you have the fputc_unlocked function. */ +#undef HAVE_FPUTC_UNLOCKED + +/* Define if you have the fputs_unlocked function. */ +#undef HAVE_FPUTS_UNLOCKED + +/* Define if you have the getcwd function. */ +#define HAVE_GETCWD 1 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the getrlimit function. */ +#define HAVE_GETRLIMIT 1 + +/* Define if you have the gettimeofday function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define if you have the index function. */ +#define HAVE_INDEX 1 + +/* Define if you have the isascii function. */ +#define HAVE_ISASCII 1 + +/* Define if you have the kill function. */ +#define HAVE_KILL 1 + +/* Define if you have the munmap function. */ +#undef HAVE_MUNMAP + +/* Define if you have the popen function. */ +#define HAVE_POPEN 1 + +/* Define if you have the putc_unlocked function. */ +#undef HAVE_PUTC_UNLOCKED + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the rindex function. */ +#define HAVE_RINDEX 1 + +/* Define if you have the setenv function. */ +#define HAVE_SETENV 1 + +/* Define if you have the setlocale function. */ +#define HAVE_SETLOCALE 1 + +/* Define if you have the setrlimit function. */ +#define HAVE_SETRLIMIT 1 + +/* Define if you have the stpcpy function. */ +#define HAVE_STPCPY 1 + +/* Define if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define if you have the strchr function. */ +#define HAVE_STRCHR 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strrchr function. */ +#define HAVE_STRRCHR 1 + +/* Define if you have the strsignal function. */ +#define HAVE_STRSIGNAL 1 + +/* Define if you have the strtoul function. */ +#define HAVE_STRTOUL 1 + +/* Define if you have the sysconf function. */ +#define HAVE_SYSCONF 1 + +/* Define if you have the header file. */ +#undef HAVE_ARGZ_H + +/* Define if you have the header file. */ +#undef HAVE_DIRECT_H + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define if you have the header file. */ +#undef HAVE_NL_TYPES_H + +/* Define if you have the header file. */ +#undef HAVE_STAB_H + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIMES_H 1 + +/* Define if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the i library (-li). */ +#undef HAVE_LIBI + +#include "gansidecl.h" +#include "config/arm/xm-riscos.h" +#include "hwint.h" Index: gcc/except.c =================================================================== RCS file: /var/cvs/GCC-2.95/gcc/except.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- gcc/except.c 7 Feb 2005 22:50:17 -0000 1.1.1.1 +++ gcc/except.c 24 Feb 2005 00:48:06 -0000 1.2 @@ -1343,7 +1343,7 @@ but there is no allocation routine that allocates at the level of the last binding contour. */ arg = assign_stack_local (BLKmode, - GET_MODE_SIZE (Pmode)*(size+1), + GET_MODE_SIZE (Pmode)*(size+2), 0); arg = change_address (arg, Pmode, NULL_RTX); Index: gcc/expr.c =================================================================== RCS file: /var/cvs/GCC-2.95/gcc/expr.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- gcc/expr.c 7 Feb 2005 22:50:17 -0000 1.1.1.1 +++ gcc/expr.c 8 Feb 2005 01:20:33 -0000 1.2 @@ -8516,6 +8516,36 @@ count--; #endif +#if defined(HAVE_BUILTIN_RETURN_ADDR_FUNC) || defined(HAVE_BUILTIN_FRAME_ADDR_FUNC) + { + char *func = NULL; + + /* If HAVE_BUILTIN_RETURN_ADDR_FUNC or HAVE_BUILTIN_FRAME_ADDR_FUNC + are defined, and evaluate to something, then call + __builtin_return_address as a function. */ +#ifdef HAVE_BUILTIN_RETURN_ADDR_FUNC + if (fndecl_code == BUILT_IN_RETURN_ADDRESS + && HAVE_BUILTIN_RETURN_ADDR_FUNC) + func = "__builtin_return_address"; +#endif +#ifdef HAVE_BUILTIN_FRAME_ADDR_FUNC + if (fndecl_code == BUILT_IN_FRAME_ADDRESS + && HAVE_BUILTIN_FRAME_ADDR_FUNC) + func = "__builtin_frame_address"; +#endif + + if (func != NULL) + { + rtx function_call; + + tem = gen_reg_rtx (Pmode); + function_call = gen_rtx (SYMBOL_REF, Pmode, func); + emit_library_call_value (function_call, tem, 0, Pmode, 1, + GEN_INT (count), SImode); + } + } +#endif + /* Scan back COUNT frames to the specified frame. */ for (i = 0; i < count; i++) { Index: gcc/gencheck.h =================================================================== RCS file: gcc/gencheck.h diff -N gcc/gencheck.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gcc/gencheck.h 15 Feb 2005 16:44:55 -0000 1.3 @@ -0,0 +1 @@ +#include "cp/cp-tree.def" Index: gcc/global.c =================================================================== RCS file: /var/cvs/GCC-2.95/gcc/global.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- gcc/global.c 7 Feb 2005 22:50:17 -0000 1.1.1.1 +++ gcc/global.c 8 Feb 2005 01:20:33 -0000 1.2 @@ -291,7 +291,12 @@ int need_fp = (! flag_omit_frame_pointer #ifdef EXIT_IGNORE_STACK +#ifdef PREVENT_FP_CLOBBER + || (current_function_calls_alloca && EXIT_IGNORE_STACK + && ! PREVENT_FP_CLOBBER) +#else || (current_function_calls_alloca && EXIT_IGNORE_STACK) +#endif #endif || FRAME_POINTER_REQUIRED); Index: gcc/multilib.h =================================================================== RCS file: gcc/multilib.h diff -N gcc/multilib.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gcc/multilib.h 9 Feb 2005 06:23:01 -0000 1.1 @@ -0,0 +1,35 @@ +/* Multilib support for ARM/RISC OS. + Written by Nick Burrett 255L) width = 255L; /* arbitrary */ sprintf (fmt, "%%.%lds", width); fprintf (stderr, fmt, _(msgid)); +#ifdef ERROR_THROWBACK + sprintf (msg, fmt, _(msgid)); +#endif } if (*p == '%') /* Print the name. */ @@ -1736,6 +1747,9 @@ ? (*decl_printable_name) (decl, 2) : "((anonymous))"); fputs (n, stderr); +#ifdef ERROR_THROWBACK + strcat (msg, n); +#endif while (*p) { ++p; @@ -1745,9 +1759,20 @@ } if (*p) /* Print the rest of the message. */ - vmessage ((char *)NULL, p, ap); - + { +#ifdef ERROR_THROWBACK + char tmp[256]; + + vsprintf (tmp, p, ap); + strcat (msg, tmp); +#endif + vmessage ((char *)NULL, p, ap); + } fputc ('\n', stderr); +#ifdef ERROR_THROWBACK + ERROR_THROWBACK (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), + (warn) ? "warning" : NULL, msg, 0); +#endif } /* Figure file and line of the given INSN. */ @@ -5447,7 +5472,15 @@ print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n"); } +#ifdef ERROR_THROWBACK_INITIALISE + ERROR_THROWBACK_INITIALISE; +#endif + compile_file (filename); + +#ifdef ERROR_THROWBACK_FINALISE + ERROR_THROWBACK_FINALISE; +#endif #if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX) if (flag_print_mem) Index: gcc/varasm.c =================================================================== RCS file: /var/cvs/GCC-2.95/gcc/varasm.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- gcc/varasm.c 7 Feb 2005 22:50:19 -0000 1.1.1.1 +++ gcc/varasm.c 15 Feb 2005 14:34:29 -0000 1.2 @@ -1694,7 +1694,15 @@ TREE_SYMBOL_REFERENCED (id) = 1; if (name[0] == '*') + { +#if defined(TARGET_RISCOSAOF) + /* A quick hack for C++ RTTI until I've fixed the relevant bug. */ + if (name[1] != '|') + fprintf (file, "|%s|", &name[1]); + else +#endif fputs (&name[1], file); + } else ASM_OUTPUT_LABELREF (file, name); } Index: gcc/config/arm/arm.c =================================================================== RCS file: /var/cvs/GCC-2.95/gcc/config/arm/arm.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- gcc/config/arm/arm.c 7 Feb 2005 22:50:22 -0000 1.1.1.1 +++ gcc/config/arm/arm.c 8 Feb 2005 01:20:33 -0000 1.2 @@ -70,6 +70,8 @@ static void emit_sfm PROTO ((int, int)); static enum arm_cond_code get_arm_condition_code PROTO ((rtx)); static int const_ok_for_op RTX_CODE_PROTO ((HOST_WIDE_INT, Rcode)); +static int arm_leaf_function_p PROTO ((void)); +static int arm_stack_check_needed PROTO ((void)); /* True if we are currently building a constant table. */ int making_const_table; @@ -148,6 +150,10 @@ but all of these can be `put after' return insns */ int lr_save_eliminated; +/* Set to one if the current function is a leaf function. Set to zero if + it isn't. Set to -1 if the function type hasn't been decided. */ +static int arm_leaf_function = -1; + /* Set to 1 when a return insn is output, this means that the epilogue is not needed. */ static int return_used_this_function; @@ -295,7 +301,7 @@ a warning though, and we prefer the CPU over the architecture. */ if (insn_flags != 0 && (insn_flags ^ sel->flags)) - warning ("switch -mcpu=%s conflicts with -mtune= switch", + warning ("switch -mcpu=%s conflicts with -march= switch", ptr->string); insn_flags = sel->flags; @@ -566,8 +572,9 @@ if (!reload_completed || current_function_pretend_args_size || current_function_anonymous_args - || ((get_frame_size () + current_function_outgoing_args_size != 0) - && !(TARGET_APCS && frame_pointer_needed))) + || (current_function_calls_alloca && ! TARGET_APCS) + || (current_function_outgoing_args_size && ! TARGET_APCS) + || (get_frame_size () && ! arm_apcs_frame_needed ())) return 0; /* Can't be done if interworking with Thumb, and any registers have been @@ -4059,6 +4066,8 @@ break; default: + fprintf (stderr, "dump_table: size = %d\n", + GET_MODE_SIZE (p->mode)); abort (); break; } @@ -4381,16 +4390,18 @@ must follow the register list. */ void -print_multi_reg (stream, instr, mask, hat) - FILE *stream; - char *instr; - int mask, hat; +print_multi_reg (stream, instr, base_reg, mask, hat, write_back) + FILE * stream; + char * instr; + int base_reg, mask, hat, write_back; { int i; int not_first = FALSE; - fputc ('\t', stream); - fprintf (stream, instr, REGISTER_PREFIX); + fprintf (stream, "\t%s\t%s%s", instr, REGISTER_PREFIX, reg_names[base_reg]); + + if (write_back) + fputc ('!', stream); fputs (", {", stream); for (i = 0; i < 16; i++) if (mask & (1 << i)) @@ -5135,6 +5146,15 @@ fputs ("\"\n", stream); } +/* Return non-zero if this is a leaf function. */ +static int +arm_leaf_function_p () +{ + if (arm_leaf_function < 0) + arm_leaf_function = leaf_function_p (); + + return arm_leaf_function; +} /* Try to determine whether a pattern really clobbers the link register. This information is useful when peepholing, so that lr need not be pushed @@ -5260,7 +5280,8 @@ if (GET_CODE (next) == BARRIER) break; - if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == USE + /* There can be multiple USE statements. */ + while (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == USE && (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET) && (REGNO (SET_DEST (XVECEXP (PATTERN (insn), 0, 0))) == REGNO (XEXP (PATTERN (next), 0)))) @@ -5288,13 +5309,14 @@ int reverse; { char instr[100]; - int reg, live_regs = 0; + int reg, live_regs_mask = 0; int volatile_func = (optimize > 0 && TREE_THIS_VOLATILE (current_function_decl)); + int frame_needed; return_used_this_function = 1; - if (volatile_func) + if (TARGET_ABORT_NORETURN && volatile_func) { rtx ops[2]; /* If this function was declared non-returning, and we have found a tail @@ -5313,63 +5335,51 @@ if (current_function_calls_alloca && ! really_return) abort(); - - for (reg = 0; reg <= 10; reg++) - if (regs_ever_live[reg] && ! call_used_regs[reg]) - live_regs++; if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]) - live_regs++; + live_regs_mask |= 1 << PIC_OFFSET_TABLE_REGNUM; - if (live_regs || (regs_ever_live[14] && ! lr_save_eliminated)) - live_regs++; - - if (frame_pointer_needed) - live_regs += 4; + frame_needed = arm_apcs_frame_needed (); + if (frame_needed) + { + for (reg = 0; reg <= 10; reg ++) + if (regs_ever_live[reg] && ! call_used_regs[reg]) + live_regs_mask |= 1 << reg; - if (live_regs) + /* If we are really returning then restore regs pc, sp and fp + otherwise restore fp, sp and lr. */ + if (! lr_save_eliminated) + live_regs_mask |= really_return ? 0xa800 : 0x6800; + } + else { - if (lr_save_eliminated || ! regs_ever_live[14]) - live_regs++; + for (reg = 0; reg <= 12; reg ++) + if (regs_ever_live[reg] && ! call_used_regs[reg]) + live_regs_mask |= 1 << reg; - if (frame_pointer_needed) - strcpy (instr, + if (live_regs_mask + || (regs_ever_live[14] && ! lr_save_eliminated)) + live_regs_mask |= 1 << (really_return ? 15 : 14); + } + + if (live_regs_mask) + { + if (frame_needed) + strcpy (instr, reverse ? "ldm%?%D0ea\t%|fp, {" : "ldm%?%d0ea\t%|fp, {"); else strcpy (instr, reverse ? "ldm%?%D0fd\t%|sp!, {" : "ldm%?%d0fd\t%|sp!, {"); - for (reg = 0; reg <= 10; reg++) - if (regs_ever_live[reg] - && (! call_used_regs[reg] - || (flag_pic && reg == PIC_OFFSET_TABLE_REGNUM))) - { + for (reg = 0; live_regs_mask; reg ++, live_regs_mask >>= 1) + if (live_regs_mask & 1) + { strcat (instr, "%|"); - strcat (instr, reg_names[reg]); - if (--live_regs) - strcat (instr, ", "); - } + strcat (instr, reg_names[reg]); + if (live_regs_mask >> 1) + strcat (instr, ", "); + } - if (frame_pointer_needed) - { - strcat (instr, "%|"); - strcat (instr, reg_names[11]); - strcat (instr, ", "); - strcat (instr, "%|"); - strcat (instr, reg_names[13]); - strcat (instr, ", "); - strcat (instr, "%|"); - strcat (instr, TARGET_THUMB_INTERWORK || (! really_return) - ? reg_names[14] : reg_names[15] ); - } - else - { - strcat (instr, "%|"); - if (TARGET_THUMB_INTERWORK && really_return) - strcat (instr, reg_names[12]); - else - strcat (instr, really_return ? reg_names[15] : reg_names[14]); - } strcat (instr, (TARGET_APCS_32 || !really_return) ? "}" : "}^"); output_asm_insn (instr, &operand); @@ -5454,24 +5464,114 @@ ASM_OUTPUT_INT (stream, x); } -/* The amount of stack adjustment that happens here, in output_return and in - output_epilogue must be exactly the same as was calculated during reload, - or things will point to the wrong place. The only time we can safely - ignore this constraint is when a function has no arguments on the stack, - no stack frame requirement and no live registers execpt for `lr'. If we - can guarantee that by making all function calls into tail calls and that - lr is not clobbered in any other way, then there is no need to push lr - onto the stack. */ - +/* Obtain the last bit set. */ + +static HOST_WIDE_INT +last_bit_set (value) + HOST_WIDE_INT value; +{ + HOST_WIDE_INT shift = 31; + + while (((1 << shift) & value) == 0) + { + if (shift < 0) + abort (); + shift--; + } + + return shift; +} + +/* Front end to output_add_immediate. */ + +static void +output_add_imm (reg1, reg2, imm) + int reg1, reg2, imm; +{ + rtx operands[3]; + + operands[0] = gen_rtx (REG, SImode, reg1); + operands[1] = gen_rtx (REG, SImode, reg2); + operands[2] = GEN_INT (imm); + output_add_immediate (operands); +} + +/* Output the full function prologue, in accordance with the ARM + Procedure Call Standard (APCS). + + There are currently 16 APCS variants, divided into four categories. + a) 26-bit program counter (PC) or 32-bit PC. + b) Implicit or explicit stack limit checking + c) Pass floating point registers on the stack or in FP args + d) Reentrant and non-reentrant + + Variants (c) and (d) are currently not implemented. + + The following example shows what the entry and exit sequences for a + function are likely to look like + entry: + mov ip, sp + stmfd sp!, {arg_regs, work_regs, fp, ip, lr, pc} + sub fp, ip, #4 + + exit: + ldmea fp, {work_regs, fp, sp, pc}^ + + For variadic functions, we make a contiguous argument list by using + a slightly modified entry sequence: + mov ip, sp + stmfd sp!, {a1, a2, a3, a4} + stmfd sp!, {work_regs, fp, ip, lr, pc} + sub fp, ip, #4 + + If we enable stack limit checking, the entry sequence for a + non-variadic function becomes: + mov ip, sp + stmfd sp!, {arg_regs, work_regs, fp, ip, lr, pc} + sub fp, ip, #4 + cmp sp, sl + bllt |__rt_stkovf_split_small| + sub sp, sp, # + + + The check for stack limit violation is made at the end of the function + prologue, by which time ip is available as a work register. If the + stack check fails, one of two standard run-time functions are called. + These functions will either + a) terminate the application + b) extend the existing stack check (decrementing sl) + c) allocate a new stack chunk, altering sp and sl + to point to it. + + For functions that are going to use less than 256 bytes of stack: + cmp sp, sl + bllt |__rt_stkovf_split_small| + sub sp, sp, # + + After this call, fp and sp might point to different stack chunks. + + For functions that are going to use more than 256 bytes of stack: + sub ip, sp, # + cmp ip, sl + bllt |__arm_stkovf_split_big| + sub sp, sp, # + + After this call, fp and sp might point to different stack chunks. + + The above describes the basic layout of an APCS prologue. However, it + is not always necessary to conform to this exact style. Often the + entry sequence can be optimised according to the characteristics of the + current function (e.g. no stack use, leaf function etc.). */ + void output_func_prologue (f, frame_size) FILE *f; int frame_size; { - int reg, live_regs_mask = 0; + int reg, live_regs_mask = 0, live_regs = 0, live_float_regs = 0; int volatile_func = (optimize > 0 && TREE_THIS_VOLATILE (current_function_decl)); - + int frame_needed; /* Nonzero if we must stuff some register arguments onto the stack as if they were passed there. */ int store_arg_regs = 0; @@ -5484,13 +5584,22 @@ return_used_this_function = 0; lr_save_eliminated = 0; - - fprintf (f, "\t%s args = %d, pretend = %d, frame = %d\n", + frame_size += current_function_outgoing_args_size; + + frame_needed = arm_apcs_frame_needed (); + + fprintf (f, "\t%s args = %d, pretend = %d, frame = %d, alloca = %d\n", ASM_COMMENT_START, current_function_args_size, - current_function_pretend_args_size, frame_size); - fprintf (f, "\t%s frame_needed = %d, current_function_anonymous_args = %d\n", - ASM_COMMENT_START, frame_pointer_needed, - current_function_anonymous_args); + current_function_pretend_args_size, frame_size, + current_function_calls_alloca); + fprintf (f, "\t%s frame_needed = %d, anonymous_args = %d, regs_live[14] = %d\n", + ASM_COMMENT_START, frame_needed, + current_function_anonymous_args, + current_function_has_nonlocal_label, regs_ever_live[14]); + fprintf (f, "\t%s nonlocal_label = %d, nonlocal_goto = %d, clobbers lr = %d\n", + ASM_COMMENT_START, current_function_has_nonlocal_label, + current_function_has_nonlocal_goto, + function_really_clobbers_lr (get_insns ())); if (volatile_func) fprintf (f, "\t%s Volatile function.\n", ASM_COMMENT_START); @@ -5498,44 +5607,307 @@ if (current_function_anonymous_args && current_function_pretend_args_size) store_arg_regs = 1; - for (reg = 0; reg <= 10; reg++) - if (regs_ever_live[reg] && ! call_used_regs[reg]) - live_regs_mask |= (1 << reg); + lr_save_eliminated = 0; - if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]) - live_regs_mask |= (1 << PIC_OFFSET_TABLE_REGNUM); + if (frame_needed) + { + /* For volatile functions, we do not need to save any call used + registers. */ + if (!volatile_func) + for (reg = 0; reg <= 10; reg++) + if (regs_ever_live[reg] && ! call_used_regs[reg]) + live_regs++, live_regs_mask |= (1 << reg); + + /* We can be sure that lr does not need to be saved if any of the + following conditions are satisfied: + a) not optimising + b) no registers to save + c) function does not have more than 4 arguments + d) function does not call alloca + e) function does not require any stack space + f) function does not clobber lr + g) function does not use a static chain + h) floating point registers don't need to be saved. */ + if (!(optimize == 0 + || live_regs_mask + || current_function_calls_alloca +#ifdef STATIC_CHAIN_INCOMING_REGNUM + || current_function_needs_context +#endif + || current_function_args_size + || frame_size != 0 + || function_really_clobbers_lr (get_insns ()))) + lr_save_eliminated = 1; - if (frame_pointer_needed) - live_regs_mask |= 0xD800; - else if (regs_ever_live[14]) + /* Check if any floating point registers need to be saved. */ + if (!volatile_func) + for (reg = 16; reg <= 23; reg++) + if (regs_ever_live[reg] && !call_used_regs[reg]) + { + lr_save_eliminated = 0; + break; + } + + if (!lr_save_eliminated) +#ifdef STATIC_CHAIN_INCOMING_REGNUM + if (current_function_needs_context) + { + if (current_function_pretend_args_size) + { + /* Saving registers r0-r3 and having a static chain means + that we have to fixup the saved sp in the stack frame + later. Set the live register mask to save fp, sp, lr + and pc. */ + live_regs_mask |= 0xe800; + } + else + { + /* Push registers sp, lr and pc onto the stack. */ + print_multi_reg (f, "stmfd", STACK_POINTER_REGNUM, + 0xe000, FALSE, 1); + + /* Set the live register mask to save fp. */ + live_regs_mask |= 0x0800; + } + } + else +#endif + { + live_regs_mask |= 0xd800; +#ifdef AOF_ASSEMBLER + if (flag_pic) + fprintf (f, "\tmov\t%s%s, %s%s\n", + REGISTER_PREFIX, reg_names[12] /* ip */, + REGISTER_PREFIX, + reg_names[PIC_OFFSET_TABLE_REGNUM]); + else +#endif + fprintf (f, "\tmov\t%s%s, %s%s\n", + REGISTER_PREFIX, reg_names[12] /* ip */, + REGISTER_PREFIX, + reg_names[STACK_POINTER_REGNUM]); + } + } + else { - if (! current_function_args_size - && ! function_really_clobbers_lr (get_insns ())) + /* We're not setting up an APCS stack frame. */ + if (!volatile_func) + for (reg = 0; reg <= 12; reg++) + if (regs_ever_live[reg] && ! call_used_regs[reg]) + live_regs++, live_regs_mask |= 1 << reg; + + /* We can be sure that lr does not need to be saved if any of the + following conditions are satisfied: + a) no registers to save + b) function does not use a static chain. */ + + if (live_regs_mask +#ifdef STATIC_CHAIN_INCOMING_REGNUM + || current_function_needs_context +#endif + || function_really_clobbers_lr (get_insns ())) + live_regs_mask |= 1 << 14; + else lr_save_eliminated = 1; + } + + if (lr_save_eliminated && regs_ever_live[14]) + fprintf (f,"\t%s I don't think this function clobbers lr\n", + ASM_COMMENT_START); + + if (current_function_pretend_args_size) + { + if (store_arg_regs) + print_multi_reg (f, "stmfd", STACK_POINTER_REGNUM, + ((0xf0 >> (current_function_pretend_args_size / 4)) + & 0xf), FALSE, 1); else - live_regs_mask |= 0x4000; + fprintf (f, "\tsub\t%s%s, %s%s, #%d\n", + REGISTER_PREFIX, reg_names[STACK_POINTER_REGNUM], + REGISTER_PREFIX, reg_names[STACK_POINTER_REGNUM], + current_function_pretend_args_size); } + /* Save the stack frame. */ if (live_regs_mask) - { - /* if a di mode load/store multiple is used, and the base register - is r3, then r4 can become an ever live register without lr - doing so, in this case we need to push lr as well, or we - will fail to get a proper return. */ + print_multi_reg (f, "stmfd", STACK_POINTER_REGNUM, + live_regs_mask, FALSE, 1); - live_regs_mask |= 0x4000; - lr_save_eliminated = 0; + /* Store any call-used floating point registers. */ + if (! volatile_func) + { + if (arm_fpu_arch == FP_SOFT2) + { + for (reg = 23; reg > 15; reg--) + if (regs_ever_live[reg] && !call_used_regs[reg]) + { + fprintf (f, "\tstfe\t%s%s, [%s%s, #-12]!\n", + REGISTER_PREFIX, reg_names[reg], + REGISTER_PREFIX, reg_names[STACK_POINTER_REGNUM]); + live_float_regs++; + } + } + else + { + int start_reg = 23; + for (reg = 23; reg > 15; reg--) + { + if (regs_ever_live[reg] && !call_used_regs[reg]) + { + if (start_reg - reg == 3) + { + fprintf (f, "\tsfmfd\t%s%s, 4, [%s%s]!\n", + REGISTER_PREFIX, reg_names[reg], + REGISTER_PREFIX, reg_names[STACK_POINTER_REGNUM]); + start_reg = reg - 1; + live_float_regs += 4; + } + } + else + { + if (start_reg != reg) + { + fprintf (f, "\tsfmfd\t%s%s, %d, [%s%s]!\n", + REGISTER_PREFIX, reg_names[reg + 1], + start_reg - reg, REGISTER_PREFIX, + reg_names[STACK_POINTER_REGNUM]); + live_float_regs += start_reg - reg; + } + start_reg = reg - 1; + } + } + if (start_reg != reg) + { + fprintf (f, "\tsfmfd\t%s%s, %d, [%s%s]!\n", + REGISTER_PREFIX, reg_names[reg + 1], + start_reg - reg, REGISTER_PREFIX, + reg_names[STACK_POINTER_REGNUM]); + live_float_regs += start_reg - reg; + } + } } - if (lr_save_eliminated) - fprintf (f,"\t%s I don't think this function clobbers lr\n", - ASM_COMMENT_START); + /* This is setup for returning when we have altered sp. */ + if (live_regs_mask && frame_needed) +#ifdef STATIC_CHAIN_INCOMING_REGNUM + if (current_function_needs_context) + { + /* add fp, sp, #. */ + output_add_imm (11 /* fp */, STACK_POINTER_REGNUM, + 12 + 4 * live_regs + 12 * live_float_regs); + fprintf (f, "\tmov\t%s%s, %s%s\n", + REGISTER_PREFIX, reg_names[STATIC_CHAIN_INCOMING_REGNUM], + REGISTER_PREFIX, reg_names[STATIC_CHAIN_REGNUM]); + } + else +#endif + { + /* sub fp, ip, #4 + (4 * stacked args). */ + output_add_imm (11 /* fp */, 12 /* ip */, + -4 - current_function_pretend_args_size); + } +#ifdef STATIC_CHAIN_INCOMING_REGNUM + else + if (current_function_needs_context) + fprintf (f, "\tmov\t%s%s, %s%s\n", + REGISTER_PREFIX, reg_names[STATIC_CHAIN_INCOMING_REGNUM], + REGISTER_PREFIX, reg_names[STATIC_CHAIN_REGNUM]); +#endif +#ifdef STATIC_CHAIN_INCOMING_REGNUM + /* Fixup the value of sp saved in the stack earlier which was wrong, + when we need to save some of a1-a4 and we have a static chain. */ + /* XXX No guarantees for support_apcs_float. */ + if (frame_needed && current_function_needs_context + && current_function_pretend_args_size) + { + /* add ip, fp, #. */ + output_add_imm (12 /* ip */, 11 /* fp */, + 4 + current_function_pretend_args_size); #ifdef AOF_ASSEMBLER if (flag_pic) - fprintf (f, "\tmov\t%sip, %s%s\n", REGISTER_PREFIX, REGISTER_PREFIX, - reg_names[PIC_OFFSET_TABLE_REGNUM]); + fprintf (f, "\tstr\t%s%s, [%s%s, #-8]\n", + REGISTER_PREFIX, reg_names[PIC_OFFSET_TABLE_REGNUM], + REGISTER_PREFIX, reg_names[ARG_POINTER_REGNUM]); + else +#endif + fprintf (f, "\tstr\t%s%s, [%s%s, #-8]\n", + REGISTER_PREFIX, reg_names[12] /* ip */, + REGISTER_PREFIX, reg_names[ARG_POINTER_REGNUM]); + } +#endif + + /* Output the stack checking code if needed. */ + if (arm_stack_check_needed () && !lr_save_eliminated) + { + rtx op; + int regno = STACK_POINTER_REGNUM; + + if (frame_size > 256) + { + /* Align stack check size so we can perform the subtraction + in just one instruction. */ + int align, stack_check_size; + + /* Use ip as a scratch register for the stack limit checks. */ + regno = 12; /* ip */ + + /* Align size is a power of 8 less than the highest power + in that particular range. */ + + align = last_bit_set (frame_size); + if (frame_size > (1 << align)) + align ++; + align = (align + 1) & ~1; + align = 1 << (align - 8); + stack_check_size = (frame_size + 1) & ~(align - 1); + output_add_imm (regno, STACK_POINTER_REGNUM, -stack_check_size); + } + + /* Different run-time environments may define their own stack + check support function names by re-defining ARM_STKOVF_SPLIT_BIG + and ARM_STKOVF_SPLIT_SMALL. */ + fprintf (f, "\tcmp\t%s%s, %s%s\n", + REGISTER_PREFIX, reg_names[regno], + REGISTER_PREFIX, reg_names[10] /* sl */); + op = gen_rtx (SYMBOL_REF, Pmode, + (frame_size > 256) ? ARM_STKOVF_SPLIT_BIG + : ARM_STKOVF_SPLIT_SMALL); + assemble_external_libcall (op); + output_asm_insn ("bllt\t%a0", &op); + } + if (frame_size) + { + /* Create the space needed for the data to be stored on the + stack. */ + output_add_imm (STACK_POINTER_REGNUM, + STACK_POINTER_REGNUM, -frame_size); + } + +#if HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM + /* If we are not optimising the function, or we are calling + builtin_alloca, then make v6/r9 point to the bottom of the stack. */ +#ifdef PREVENT_FP_CLOBBER + /* If we have defined PREVENT_FP_CLOBBER to prevent the assumed + clobbering of the stack pointer when builtin_alloca is called, + we do not need to make v6/r9 point to the stack. If we are going + to receive non-local gotos then we need to set v6 up. */ + if (! optimize + || (! PREVENT_FP_CLOBBER && current_function_calls_alloca) + || current_function_has_nonlocal_label + || current_function_has_nonlocal_goto) + fprintf (f, "\tmov\t%s%s, %s%s\n", + REGISTER_PREFIX, reg_names[FRAME_POINTER_REGNUM], + REGISTER_PREFIX, reg_names[STACK_POINTER_REGNUM]); +#else + if (! optimize || current_function_calls_alloca + || current_function_has_nonlocal_label + || current_function_has_nonlocal_goto) + fprintf (f, "\tmov\t%R%s, %s%s\n", + REGISTER_PREFIX, reg_names[FRAME_POINTER_REGNUM], + REGISTER_PREFIX, reg_names[STACK_POINTER_REGNUM]); +#endif #endif } @@ -5552,11 +5924,13 @@ int volatile_func = (optimize > 0 && TREE_THIS_VOLATILE (current_function_decl)); + frame_size += current_function_outgoing_args_size; /* NAB */ + if (use_return_insn (FALSE) && return_used_this_function) { - if ((frame_size + current_function_outgoing_args_size) != 0 - && !(frame_pointer_needed && TARGET_APCS)) + if (frame_size && ! TARGET_APCS) abort (); + goto epilogue_done; } @@ -5574,21 +5948,21 @@ goto epilogue_done; } - for (reg = 0; reg <= 10; reg++) - if (regs_ever_live[reg] && ! call_used_regs[reg]) - { - live_regs_mask |= (1 << reg); - floats_offset += 4; - } - if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]) { live_regs_mask |= (1 << PIC_OFFSET_TABLE_REGNUM); floats_offset += 4; } - if (frame_pointer_needed) + if (arm_apcs_frame_needed ()) { + for (reg = 0; reg <= 10; reg++) + if (regs_ever_live[reg] && ! call_used_regs[reg]) + { + live_regs_mask |= (1 << reg); + floats_offset += 4; + } + if (arm_fpu_arch == FP_SOFT2) { for (reg = 23; reg > 15; reg--) @@ -5634,28 +6008,38 @@ REGISTER_PREFIX, reg_names[reg + 1], start_reg - reg, REGISTER_PREFIX, floats_offset); } - + if (TARGET_THUMB_INTERWORK) { live_regs_mask |= 0x6800; - print_multi_reg (f, "ldmea\t%sfp", live_regs_mask, FALSE); + print_multi_reg (f, "ldmea", 11, live_regs_mask, FALSE, 0); fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX); } else { live_regs_mask |= 0xA800; - print_multi_reg (f, "ldmea\t%sfp", live_regs_mask, - TARGET_APCS_32 ? FALSE : TRUE); + print_multi_reg (f, "ldmea", 11, live_regs_mask, + TARGET_APCS_32 ? FALSE : TRUE, 0); } } else { + for (reg = 0; reg <= 12; reg++) + if (regs_ever_live[reg] && ! call_used_regs[reg]) + { + live_regs_mask |= (1 << reg); + floats_offset += 4; + } + /* Restore stack pointer if necessary. */ - if (frame_size + current_function_outgoing_args_size != 0) + if (current_function_calls_alloca || frame_size) { - operands[0] = operands[1] = stack_pointer_rtx; - operands[2] = GEN_INT (frame_size - + current_function_outgoing_args_size); + operands[0] = stack_pointer_rtx; + if (current_function_calls_alloca) + operands[1] = gen_rtx_REG (SImode, FRAME_POINTER_REGNUM); + else + operands[1] = stack_pointer_rtx; + operands[2] = GEN_INT (frame_size); output_add_immediate (operands); } @@ -5708,7 +6092,8 @@ live_regs_mask |= 0x4000; if (live_regs_mask != 0) - print_multi_reg (f, "ldmfd\t%ssp!", live_regs_mask, FALSE); + print_multi_reg (f, "ldmfd", STACK_POINTER_REGNUM, + live_regs_mask | 0x4000, FALSE, 1); fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX); } @@ -5717,8 +6102,9 @@ : "\tmovs\t%spc, %slr\n"), REGISTER_PREFIX, REGISTER_PREFIX, f); else - print_multi_reg (f, "ldmfd\t%ssp!", live_regs_mask | 0x8000, - TARGET_APCS_32 ? FALSE : TRUE); + print_multi_reg (f, "ldmfd", STACK_POINTER_REGNUM, + live_regs_mask | 0x8000, + TARGET_APCS_32 ? FALSE : TRUE, 1); } else { @@ -5729,7 +6115,8 @@ live_regs_mask |= 0x4000; if (live_regs_mask != 0) - print_multi_reg (f, "ldmfd\t%ssp!", live_regs_mask, FALSE); + print_multi_reg (f, "ldmfd", STACK_POINTER_REGNUM, + live_regs_mask, FALSE, 1); } if (current_function_pretend_args_size) @@ -5754,6 +6141,7 @@ /* Reset the ARM-specific per-function variables. */ current_function_anonymous_args = 0; after_arm_reorg = 0; + arm_leaf_function = -1; } static void @@ -5831,113 +6219,6 @@ void arm_expand_prologue () { - int reg; - rtx amount = GEN_INT (-(get_frame_size () - + current_function_outgoing_args_size)); - int live_regs_mask = 0; - int store_arg_regs = 0; - int volatile_func = (optimize > 0 - && TREE_THIS_VOLATILE (current_function_decl)); - - /* Naked functions don't have prologues. */ - if (arm_naked_function_p (current_function_decl)) - return; - - if (current_function_anonymous_args && current_function_pretend_args_size) - store_arg_regs = 1; - - if (! volatile_func) - { - for (reg = 0; reg <= 10; reg++) - if (regs_ever_live[reg] && ! call_used_regs[reg]) - live_regs_mask |= 1 << reg; - - if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]) - live_regs_mask |= 1 << PIC_OFFSET_TABLE_REGNUM; - - if (regs_ever_live[14]) - live_regs_mask |= 0x4000; - } - - if (frame_pointer_needed) - { - live_regs_mask |= 0xD800; - emit_insn (gen_movsi (gen_rtx_REG (SImode, 12), - stack_pointer_rtx)); - } - - if (current_function_pretend_args_size) - { - if (store_arg_regs) - emit_multi_reg_push ((0xf0 >> (current_function_pretend_args_size / 4)) - & 0xf); - else - emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (-current_function_pretend_args_size))); - } - - if (live_regs_mask) - { - /* If we have to push any regs, then we must push lr as well, or - we won't get a proper return. */ - live_regs_mask |= 0x4000; - emit_multi_reg_push (live_regs_mask); - } - - /* For now the integer regs are still pushed in output_func_epilogue (). */ - - if (! volatile_func) - { - if (arm_fpu_arch == FP_SOFT2) - { - for (reg = 23; reg > 15; reg--) - if (regs_ever_live[reg] && ! call_used_regs[reg]) - emit_insn (gen_rtx_SET - (VOIDmode, - gen_rtx_MEM (XFmode, - gen_rtx_PRE_DEC (XFmode, - stack_pointer_rtx)), - gen_rtx_REG (XFmode, reg))); - } - else - { - int start_reg = 23; - - for (reg = 23; reg > 15; reg--) - { - if (regs_ever_live[reg] && ! call_used_regs[reg]) - { - if (start_reg - reg == 3) - { - emit_sfm (reg, 4); - start_reg = reg - 1; - } - } - else - { - if (start_reg != reg) - emit_sfm (reg + 1, start_reg - reg); - start_reg = reg - 1; - } - } - - if (start_reg != reg) - emit_sfm (reg + 1, start_reg - reg); - } - } - - if (frame_pointer_needed) - emit_insn (gen_addsi3 (hard_frame_pointer_rtx, gen_rtx_REG (SImode, 12), - (GEN_INT - (-(4 + current_function_pretend_args_size))))); - - if (amount != const0_rtx) - { - emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, amount)); - emit_insn (gen_rtx_CLOBBER (VOIDmode, - gen_rtx_MEM (BLKmode, stack_pointer_rtx))); - } - /* If we are profiling, make sure no instructions are scheduled before the call to mcount. Similarly if the user has requested no scheduling in the prolog. */ @@ -6579,6 +6860,77 @@ } } +/* Given FROM and TO register numbers, say whether this elimination + is allowed. */ + +int +arm_can_eliminate (from, to) + int from, to; +{ + /* This should never happen but it does. */ + if (! optimize) + return 0; + + /* We can eliminate ARGP to STACKP if no alloca, no stack checks needed + and frame not needed. */ + if (from == ARG_POINTER_REGNUM + && to == STACK_POINTER_REGNUM + && ! arm_apcs_frame_needed ()) + return 1; + + /* FRAMEP can be eliminated to STACKP. */ + if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) + return 1; + + /* Can't do any other eliminations. */ + return 0; +} + +/* Return 1 if the function prologue really needs to setup an APCS + frame. */ +int +arm_apcs_frame_needed () +{ + /* If we are not targeting the APCS, we will not use a stack frame. */ + if (! TARGET_APCS) + return 0; + + /* If we are not optimising, or we call alloca, we will always + setup a frame. */ + if (current_function_calls_alloca || ! optimize) + return 1; + + /* A frame will need to be setup for the cases where there are external + function calls within the current function or there is a need + for definite stack checking. */ + if (! arm_leaf_function_p () || arm_stack_check_needed ()) + return 1; + + return 0; +} + +/* Return 1 if the function prologue should contain an explicit + stack check. */ +static int +arm_stack_check_needed () +{ + /* Don't do any stack checking if it was not asked for. */ + if (! TARGET_APCS_STACK) + return 0; + + /* We will always use stack checking for non-optimising + circumstances. */ + if (! optimize) + return 1; + + /* Don't do any stack checking if the function is a leaf function + and the amount of stack actually needed <= 256 bytes. */ + if (arm_leaf_function_p () && abs (get_frame_size ()) <= 256) + return 0; + + return 1; +} + #ifdef AOF_ASSEMBLER /* Special functions only needed when producing AOF syntax assembler. */ @@ -6609,12 +6961,15 @@ for (offset = 0, chainp = &aof_pic_chain; *chainp; offset += 4, chainp = &(*chainp)->next) if ((*chainp)->symname == XSTR (x, 0)) - return plus_constant (aof_pic_label, offset); + { + /* AOF assembler that doesn't support BASED areas properly. */ + return GEN_INT (offset); + } *chainp = (struct pic_chain *) xmalloc (sizeof (struct pic_chain)); (*chainp)->next = NULL; (*chainp)->symname = XSTR (x, 0); - return plus_constant (aof_pic_label, offset); + return GEN_INT (offset); } void @@ -6721,12 +7076,19 @@ /* The AOF assembler needs this to cause the startup code to be extracted from the library. Brining in __main causes the whole thing to work automagically. */ +#if 0 if (arm_main_function) { text_section (); - fputs ("\tIMPORT __main\n", f); - fputs ("\tDCD __main\n", f); + + fputs ("\tIMPORT\t", f); + assemble_name (f, "__main"); + + fputs ("\n\tDCD\t", f); + assemble_name (f, "__main"); + fputc ('\n', f); } +#endif /* Now dump the remaining imports. */ while (imports_list) Index: gcc/config/arm/arm.h =================================================================== RCS file: /var/cvs/GCC-2.95/gcc/config/arm/arm.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- gcc/config/arm/arm.h 7 Feb 2005 22:50:23 -0000 1.1.1.1 +++ gcc/config/arm/arm.h 8 Feb 2005 01:20:34 -0000 1.2 @@ -72,6 +72,7 @@ /* This is needed by the tail-calling peepholes */ extern int frame_pointer_needed; +extern int lr_save_eliminated; /* Just in case configure has failed to define anything. */ @@ -188,7 +189,7 @@ " #ifndef CPP_APCS_PC_DEFAULT_SPEC -#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_26__" +#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__" #endif #define CPP_FLOAT_SPEC "\ @@ -471,8 +472,7 @@ /* The frame pointer register used in gcc has nothing to do with debugging; that is controlled by the APCS-FRAME option. */ -/* Not fully implemented yet */ -/* #define CAN_DEBUG_WITHOUT_FP 1 */ +#define CAN_DEBUG_WITHOUT_FP 1 #define TARGET_MEM_FUNCTIONS 1 @@ -685,7 +685,7 @@ #define FIXED_REGISTERS \ { \ 0,0,0,0,0,0,0,0, \ - 0,0,0,1,0,1,0,1, \ + 0,0,1,1,0,1,0,1, \ 0,0,0,0,0,0,0,0, \ 1,1,1 \ } @@ -701,7 +701,7 @@ #define CALL_USED_REGISTERS \ { \ 1,1,1,1,0,0,0,0, \ - 0,0,0,1,1,1,1,1, \ + 0,0,1,1,1,1,1,1, \ 1,1,1,1,0,0,0,0, \ 1,1,1 \ } @@ -775,13 +775,19 @@ #define STACK_POINTER_REGNUM 13 /* Base register for access to local variables of the function. */ +#ifdef TARGET_RISCOSAOF +#define FRAME_POINTER_REGNUM 9 +#else #define FRAME_POINTER_REGNUM 25 +#endif /* Define this to be where the real frame pointer is if it is not possible to work out the offset between the frame pointer and the automatic variables until after register allocation has taken place. FRAME_POINTER_REGNUM should point to a special register that we will make sure is eliminated. */ +#ifndef TARGET_RISCOSAOF #define HARD_FRAME_POINTER_REGNUM 11 +#endif /* Value should be nonzero if functions must have frame pointers. Zero means the frame pointer need not be set up (and parms may be accessed @@ -789,16 +795,32 @@ If we have to have a frame pointer we might as well make use of it. APCS says that the frame pointer does not need to be pushed in leaf functions, or simple tail call functions. */ +#ifdef TARGET_RISCOSAOF +#undef FRAME_POINTER_REQUIRED +#define FRAME_POINTER_REQUIRED 0 +#else #define FRAME_POINTER_REQUIRED \ (current_function_has_nonlocal_label || (TARGET_APCS && !leaf_function_p ())) +#endif /* Base register for access to arguments of the function. */ +#ifdef TARGET_RISCOSAOF +#define ARG_POINTER_REGNUM 11 +#else #define ARG_POINTER_REGNUM 26 +#endif /* The native (Norcroft) Pascal compiler for the ARM passes the static chain as an invisible last argument (possible since varargs don't exist in Pascal), so the following is not true. */ +#ifdef TARGET_RISCOSAOF +/* The register number as seen by the called function is r12/ip. */ +#define STATIC_CHAIN_REGNUM 12 +/* The register number as seen by the calling function is r8/v5. */ +#define STATIC_CHAIN_INCOMING_REGNUM 8 +#else #define STATIC_CHAIN_REGNUM 8 +#endif /* Register in which address to store a structure value is passed to a function. */ @@ -1011,13 +1033,21 @@ is at the high-address end of the local variables; that is, each additional local variable allocated goes at a more negative offset in the frame. */ +#ifdef TARGET_RISCOSAOF +#undef FRAME_GROWS_DOWNWARD +#else #define FRAME_GROWS_DOWNWARD 1 +#endif /* Offset within stack frame to start allocating local variables at. If FRAME_GROWS_DOWNWARD, this is the offset to the END of the first local allocated. Otherwise, it is the offset to the BEGINNING of the first local allocated. */ +#ifdef TARGET_RISCOSAOF +#define STARTING_FRAME_OFFSET (current_function_outgoing_args_size) +#else #define STARTING_FRAME_OFFSET 0 +#endif /* If we generate an insn to push BYTES bytes, this says how many the stack pointer really advances by. */ @@ -1226,63 +1256,70 @@ be eliminated; it is replaced with either the stack or the real frame pointer. */ +#ifdef TARGET_RISCOSAOF +#define ELIMINABLE_REGS \ +{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM },\ + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }} +#else #define ELIMINABLE_REGS \ {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} +#endif /* Given FROM and TO register numbers, say whether this elimination is allowed. - Frame pointer elimination is automatically handled. - - All eliminations are permissible. Note that ARG_POINTER_REGNUM and - HARD_FRAME_POINTER_REGNUM are in fact the same thing. If we need a frame - pointer, we must eliminate FRAME_POINTER_REGNUM into - HARD_FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */ -#define CAN_ELIMINATE(FROM, TO) \ - (((TO) == STACK_POINTER_REGNUM && frame_pointer_needed) ? 0 : 1) + Frame pointer elimination is automatically handled. */ +#define CAN_ELIMINATE(FROM, TO) arm_can_eliminate ((FROM), (TO)) /* Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ { \ int volatile_func = arm_volatile_func (); \ - if ((FROM) == ARG_POINTER_REGNUM && (TO) == HARD_FRAME_POINTER_REGNUM)\ - (OFFSET) = 0; \ - else if ((FROM) == FRAME_POINTER_REGNUM \ - && (TO) == STACK_POINTER_REGNUM) \ - (OFFSET) = (current_function_outgoing_args_size \ - + ((get_frame_size () + 3) & ~3)); \ - else \ + /* The default. */ \ + (OFFSET) = 0; \ + if ((FROM) == ARG_POINTER_REGNUM || (TO) == ARG_POINTER_REGNUM) \ { \ int regno; \ - int offset = 12; \ + int offset = abs (get_frame_size ()) \ + + current_function_outgoing_args_size; \ int saved_hard_reg = 0; \ \ + /* Registers don't need to be saved in volatile functions. */ \ if (! volatile_func) \ { \ for (regno = 0; regno <= 10; regno++) \ if (regs_ever_live[regno] && ! call_used_regs[regno]) \ saved_hard_reg = 1, offset += 4; \ - /* PIC register is a fixed reg, so call_used_regs set. */ \ - if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]) \ - saved_hard_reg = 1, offset += 4; \ for (regno = 16; regno <=23; regno++) \ if (regs_ever_live[regno] && ! call_used_regs[regno]) \ offset += 12; \ } \ - if ((FROM) == FRAME_POINTER_REGNUM) \ - (OFFSET) = -offset; \ + if (arm_apcs_frame_needed ()) \ + { \ + /* Take into account fp, ip, lr and pc. */ \ + offset += 16; \ + } \ else \ { \ - if (! frame_pointer_needed) \ - offset -= 16; \ - if (! volatile_func \ - && (regs_ever_live[14] || saved_hard_reg)) \ + /* Not targetting the APCS, only need to check r11, r12 */ \ + /* and lr. */ \ + if (! volatile_func) \ + { \ + for (regno = 11; regno <= 12; regno++) \ + if (regs_ever_live[regno] && !call_used_regs[regno]) \ + saved_hard_reg = 1, offset += 4; \ + if (regs_ever_live[14] || saved_hard_reg) \ offset += 4; \ - offset += current_function_outgoing_args_size; \ - (OFFSET) = ((get_frame_size () + 3) & ~3) + offset; \ } \ + /* Frame is now 4 too large. */ \ + offset -= 4; \ + } \ + if ((FROM) == FRAME_POINTER_REGNUM) \ + (OFFSET) -= offset; \ + else \ + (OFFSET) += offset; \ } \ } @@ -1313,18 +1350,6 @@ /* Alignment required for a trampoline in units. */ #define TRAMPOLINE_ALIGN 4 - -/* Emit RTL insns to initialize the variable parts of a trampoline. - FNADDR is an RTX for the address of the function's pure code. - CXT is an RTX for the static chain value for the function. */ -#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ -{ \ - emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 8)), \ - (CXT)); \ - emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 12)), \ - (FNADDR)); \ -} - /* Addressing modes, and classification of registers for them. */ @@ -2043,6 +2068,17 @@ GET_CODE (X) == POST_DEC ? "-" : "", \ GET_MODE_SIZE (output_memory_reference_mode)); \ } \ + else if (GET_CODE (X) == SYMBOL_REF && TARGET_APCS_STACK) \ + { \ + /* Convert setjmp and longjmp to alternative names for extra \ + processing. */ \ + if (strcmp (XSTR (X, 0), "setjmp") == 0) \ + assemble_name (STREAM, "___arm_alloca_setjmp"); \ + else if (strcmp (XSTR (X, 0), "longjmp") == 0) \ + assemble_name (STREAM, "___arm_alloca_longjmp"); \ + else \ + assemble_name (STREAM, XSTR (X, 0)); \ + } \ else output_addr_const(STREAM, X); \ } @@ -2245,6 +2281,8 @@ int short_branch PROTO ((int, int)); void assemble_align PROTO((int)); /* Used in arm.md, but defined in output.c */ int multi_register_push PROTO ((Rtx, Mmode)); +void arm_poke_function_name STDIO_PROTO ((FILE *, char *)); +int arm_can_eliminate PROTO ((int, int)); #ifdef AOF_ASSEMBLER Rtx aof_pic_entry PROTO ((Rtx)); void aof_dump_pic_table STDIO_PROTO ((FILE *)); Index: gcc/config/arm/arm.md =================================================================== RCS file: /var/cvs/GCC-2.95/gcc/config/arm/arm.md,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- gcc/config/arm/arm.md 7 Feb 2005 22:50:23 -0000 1.1.1.1 +++ gcc/config/arm/arm.md 8 Feb 2005 01:20:34 -0000 1.2 @@ -5980,7 +5980,8 @@ (return)] "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN(FALSE) && !get_frame_size () && !current_function_calls_alloca - && !frame_pointer_needed && !current_function_args_size)" + && !current_function_outgoing_args_size && !current_function_args_size + && lr_save_eliminated)" "* { extern rtx arm_target_insn; @@ -6008,7 +6009,8 @@ (return)] "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN(FALSE) && !get_frame_size () && !current_function_calls_alloca - && !frame_pointer_needed && !current_function_args_size)" + && !current_function_outgoing_args_size && !current_function_args_size + && lr_save_eliminated)" "* { extern rtx arm_target_insn; @@ -6040,7 +6042,8 @@ (return)] "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN(FALSE) && !get_frame_size () && !current_function_calls_alloca - && !frame_pointer_needed && !current_function_args_size)" + && !current_function_outgoing_args_size && !current_function_args_size + && lr_save_eliminated)" "* { extern rtx arm_target_insn; @@ -6276,3 +6279,140 @@ assemble_align (32); return \"\"; ") + +;; Implementations for dyamic allocation off the stack. + +;; These patterns say how to perform an equivalent to dynamic allocation +;; off the stack. We use library routines to return malloced memory +;; then alter the frame pointer so that on function exit, all chunks +;; will be freed. This system also works for different blocks within a +;; function. + +;; We do not need to worry about the outermost block in a function since +;; function exit will tidy up all unalloced chunks. + +(define_expand "save_stack_function" + [(use (const_int 0))] + "TARGET_APCS_STACK" + "") + +(define_expand "restore_stack_function" + [(use (const_int 0))] + "TARGET_APCS_STACK" + "") + +;; On entrance to a block, with __builtin_alloca, create a unique key +;; suitable for the free code. + +(define_expand "save_stack_block" + [(match_operand:SI 0 "memory_operand" "") + (match_operand:SI 1 "s_register_operand" "")] + "TARGET_APCS_STACK" + " +{ +#if 1 + /* Inline version of __arm_alloca_block_init. */ + rtx scratch_reg = gen_reg_rtx (SImode); + rtx label = gen_rtx_SYMBOL_REF (Pmode, \"__arm_alloca_st\"); + + emit_move_insn (scratch_reg, gen_rtx_MEM (SImode, label)); + emit_insn (gen_addsi3 (scratch_reg, scratch_reg, const1_rtx)); + emit_move_insn (gen_rtx_MEM (SImode, label), scratch_reg); +#else + rtx r0_rtx = gen_rtx (REG, SImode, 0); + rtx funexp = gen_rtx (SYMBOL_REF, Pmode, \"___arm_alloca_block_init\"); + + emit_call_insn (gen_call_value (r0_rtx, + gen_rtx (MEM, FUNCTION_MODE, funexp), + const0_rtx)); + emit_move_insn (operands[0], r0_rtx); +#endif + DONE; +}") + +(define_expand "save_stack_nonlocal" + [(match_operand:SI 0 "memory_operand" "") + (match_operand:SI 1 "s_register_operand" "")] + "TARGET_APCS_STACK" + " +{ +#if 1 + /* Inline version of __arm_alloca_block_init. */ + rtx scratch_reg = gen_reg_rtx (SImode); + rtx label = gen_rtx_SYMBOL_REF (Pmode, \"__arm_alloca_st\"); + + emit_move_insn (scratch_reg, gen_rtx_MEM (SImode, label)); + emit_insn (gen_addsi3 (scratch_reg, scratch_reg, const1_rtx)); + emit_move_insn (gen_rtx_MEM (SImode, label), scratch_reg); +#else + rtx r0_rtx = gen_rtx (REG, SImode, 0); + rtx funexp = gen_rtx (SYMBOL_REF, Pmode, \"___arm_alloca_block_init\"); + + emit_call_insn (gen_call_value (r0_rtx, + gen_rtx (MEM, FUNCTION_MODE, funexp), + const0_rtx)); + emit_move_insn (operands[0], r0_rtx); +#endif + DONE; +}") + + +;; Use the unique key produced earlier to free chunks created under +;; this key. + +(define_expand "restore_stack_block" + [(set (match_dup 2) (mem:SI (match_operand:SI 0 "s_register_operand" ""))) + (set (match_dup 0) (match_operand:SI 1 "s_register_operand" "")) + (set (mem:SI (match_dup 0)) (match_dup 2))] + "TARGET_APCS_STACK" + " +{ + rtx r0_rtx = gen_rtx (REG, SImode, 0); + rtx funexp = gen_rtx (SYMBOL_REF, Pmode, \"___arm_alloca_block_free\"); + + emit_move_insn (r0_rtx, operands[1]); + emit_insn (gen_rtx (USE, VOIDmode, r0_rtx)); + emit_call_insn (gen_call (gen_rtx (MEM, FUNCTION_MODE, funexp), GEN_INT (4))); + DONE; +}") + +(define_expand "restore_stack_nonlocal" + [(match_operand:SI 0 "s_register_operand" "") + (match_operand:SI 1 "memory_operand" "")] + "TARGET_APCS_STACK" + " +{ + rtx r0_rtx = gen_rtx (REG, SImode, 0); + rtx funexp = gen_rtx (SYMBOL_REF, Pmode, \"___arm_alloca_block_free\"); + + emit_move_insn (r0_rtx, operands[1]); + emit_insn (gen_rtx (USE, VOIDmode, r0_rtx)); + emit_call_insn (gen_call (gen_rtx (MEM, FUNCTION_MODE, funexp), GEN_INT (4))); + DONE; +}") + + +;; Call the function that will reserve the necessary amount of memory + +(define_expand "allocate_stack" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (minus:SI (reg:SI 13) (match_operand:SI 1 "reg_or_int_operand" ""))) + (set (reg:SI 13) + (minus:SI (reg:SI 13) (match_dup 1))) + (clobber (reg:SI 0)) + (clobber (reg:SI 14))] + "TARGET_APCS_STACK" + " +{ + rtx r0_rtx = gen_rtx (REG, SImode, 0); + rtx funexp = gen_rtx (SYMBOL_REF, Pmode, \"___arm_alloca_alloc\"); + + emit_move_insn (r0_rtx, operands[1]); + emit_insn (gen_rtx (USE, VOIDmode, r0_rtx)); + emit_call_insn (gen_call_value (r0_rtx, + gen_rtx (MEM, FUNCTION_MODE, funexp), + GEN_INT (4))); + emit_move_insn (operands[0], r0_rtx); + + DONE; +}") Index: gcc/config/arm/lib1aof.s =================================================================== RCS file: gcc/config/arm/lib1aof.s diff -N gcc/config/arm/lib1aof.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gcc/config/arm/lib1aof.s 8 Feb 2005 01:20:34 -0000 1.1 @@ -0,0 +1,1948 @@ +/* libgcc1 and libgcc2 routines for ARM cpu (AOF format) + Copyright (C) 1998, 2000 Free Software Foundation, Inc. + Contributed by Nick Burrett (nick.burrett@btinternet.com) + and Peter Burwood (pjb@arcangel.dircon.co.uk) + + This file 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, or (at your option) + any later version. + + In addition to the permissions in the GNU General Public License, the + Free Software Foundation gives you unlimited permission to link the + compiled version of this file with other programs, and to distribute + those programs without any restriction coming from the use of this + file. (The General Public License restrictions do apply in other + respects; for example, they cover modification of the file, and + distribution when not linked into another program.) + + This file 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; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with GCC, to produce an executable, + this library does not by itself cause the resulting executable + to be covered by the GNU General Public License. + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +/* Run this through cpp */ + +a1 RN 0 +a2 RN 1 +a3 RN 2 +a4 RN 3 +v1 RN 4 +v2 RN 5 +v3 RN 6 +v4 RN 7 +v5 RN 8 +v6 RN 9 +sl RN 10 +fp RN 11 +ip RN 12 +sp RN 13 +lr RN 14 +pc RN 15 +f0 FN 0 +f1 FN 1 +f2 FN 2 +f3 FN 3 +f4 FN 4 +f5 FN 5 +f6 FN 6 +f7 FN 7 +r0 RN 0 +r1 RN 1 +r2 RN 2 +r3 RN 3 +r4 RN 4 +r12 RN 12 +r14 RN 14 + +#ifdef __APCS_26__ +#define RETURN(dst,src) movs dst, src +#define RETURNc(x,dst,src) mov##x##s dst, src +#define RETCOND ^ +#else +#define RETURN(dst,src) mov dst, src +#define RETURNc(x,dst,src) mov##x dst, src +#define RETCOND +#endif + +/* Keep these in sync with unixlib/asm_dec.s and features.h */ +__FEATURE_PTHREADS EQU 1 +__PTHREAD_ALLOCA_OFFSET EQU 8 + + AREA |C$$code|, CODE, READONLY + +#ifdef L_ashldi3 + EXPORT |__ashldi3| + +/* DItype __ashldi3 (DItype u, word_type b) + a1, a2 = u + a3 = b */ +|__ashldi3| + /* if shift = 0 then return */ + CMP a3, #0 + RETURNc(eq, pc, lr) + + /* if shift >= 32 then low word will be 0 */ + RSBS ip, a3, #32 /* bm = 32 - b */ + RSBLE ip, ip, #0 + MOVLE a2, a1, ASL ip /* high = low << -bm */ + MOVLE a1, #0 /* low = 0 */ + + MOVGT a2, a2, LSL a3 /* high = high << b */ + ORRGT a2, a2, a1, LSR ip /* high = high | low >> bm */ + MOVGT a1, a1, ASL a3 /* low = low << b */ + + RETURN(pc, lr) +#endif + +#ifdef L_ashrdi3 + EXPORT |__ashrdi3| +/* DItype __ashrdi3 (DItype u, word_type b) + a1, a2 = u + a3 = b */ +|__ashrdi3| + /* if shift = 0 then return */ + CMP a3, #0 + RETURNc(eq, pc, lr) + + /* if shift >= 32 then high word will be 1..1 or 0..0 */ + RSBS ip, a3, #32 /* bm = 32 - b */ + RSBLE ip, ip, #0 + MOVLE a1, a2, ASR ip /* low = high >> - bm */ + MOVLE a2, a2, ASR #31 /* high = high >> 31 */ + + MOVGT a1, a1, LSR a3 /* low = low >> b */ + ORRGT a1, a1, a2, ASL ip /* low = low | high << bm */ + MOVGT a2, a2, ASR a3 /* high = high >> b */ + + RETURN(pc, lr) +#endif + +#ifdef L_clear_icache + EXPORT |__clear_icache| + /* clear instruction cache + + On entry + R0 = low address of range (word aligned) + R1 = high address (word aligned, _inclusive_) */ + +X_Bit EQU &020000 +XOS_SynchroniseCodeAreas EQU &00006E + X_Bit + +|__clear_icache| + MOV a3, a2 + MOV a2, a1 + MOV a1, #1 + SWI XOS_SynchroniseCodeAreas + RETURN(pc, lr) +#endif + +#ifdef L_cmpdi2 + EXPORT |__cmpdi2| + /* compare two long long ints + enter with __cmpdi2 (DItype a, DItype b) + entry a1,a2 = u, a3,a4 = v + exit u > v = 2, u < v = 0, u = v = 1 */ +|__cmpdi2| + CMP a2, a4 + CMPEQ a1, a3 + MOVLT a1, #0 + MOVGT a1, #2 + MOVEQ a1, #1 + RETURN(pc, lr) +#endif + +#ifdef L_divdi3 + EXPORT |__divdi3| + IMPORT |__div0| + + /* (a1, a2) / (a3, a4) + result in v2 and v3 + remainder in v4 and ip */ +|__divdi3| + /* fast exits + check the numerator for zero */ + CMP a1, #0 /* low */ + CMPEQ a2, #0 /* high */ + RETURNc(eq, pc, lr) + /* test for a divide by zero */ + CMP a3, #0 /* low */ + CMPEQ a4, #0 /* high */ + BEQ |__div0| /* divide by zero. */ + /* No stack checking since we are a leaf function. + We don't need to store ip - procedure calling standard + lets it be corrupted. */ + STMFD sp!, {v2, v3, v4, v6, lr} + /* v6 = sign bit */ + ANDS v6, a4, #&80000000 + BPL |__divdi3.L00| + RSBS a3, a3, #0 /* low */ + RSC a4, a4, #0 /* high */ +|__divdi3.L00| + EORS v6, v6, a2, ASR#32 + BCC |__divdi3.L01| + RSBS a1, a1, #0 /* low */ + RSC a2, a2, #0 /* high */ +|__divdi3.L01| + /* initialise the quotient to zero */ + MOV v2, #0 /* low */ + MOV v3, #0 /* high */ + /* remainder = numerator */ + MOV v4, a1 /* low */ + MOV ip, a2 /* high */ + + /* lr is a count of the number of shifts needed */ + MOVS lr, #0 + /* shift the denominator left until the next doubling + generates a number larger than the numerator. + Count the number of shifts needed */ +|__divdi3.bit_count| + /* double the denominator, we've finished when the top bit + is set. */ + ADDS a3, a3, a3 /* low */ + ADCS a4, a4, a4 /* high */ + /* too big so we've finished */ + BCS |__divdi3.count_done| + CMP a4, ip /* high */ + CMPEQ a3, v4 /* low */ + /* if denominator is lower or the same as the numerator + signify an extra shift and carry on. */ + ADDLS lr, lr, #1 + BLS |__divdi3.bit_count| + + /* clear the carry flag */ + ADDS lr, lr, #0 + +|__divdi3.count_done| + /* we've overflowed. shift the denominator back down + to bring in the overflowed bit */ + MOVS a4, a4, RRX /* high */ + MOV a3, a3, RRX /* low */ + +|__divdi3.division| + /* numerator = remainder - denominator */ + SUBS a1, v4, a3 /* low */ + SBCS a2, ip, a4 /* high */ + /* if (remainder >= denominator) remainder = numerator */ + MOVCS v4, a1 /* low */ + MOVCS ip, a2 /* high */ + /* place next bit into the result */ + ADCS v2, v2, v2 /* low */ + ADC v3, v3, v3 /* high */ + /* shift the denominator right 1 bit */ + MOVS a4, a4, LSR #1 /* high */ + MOV a3, a3, RRX /* low */ + SUBS lr, lr, #1 + BGE |__divdi3.division| + /* result */ + MOVS v6, v6, LSL#2 + MOVCC a1, v2 + MOVCC a2, v3 + LDMCCFD sp!, {v2, v3, v4, v6, pc}RETCOND + RSBS a1, v2, #0 /* low */ + RSC a2, v3, #0 /* high */ + LDMFD sp!, {v2, v3, v4, v6, pc}RETCOND +#endif + +#ifdef L_divsi3 + EXPORT |__divsi3| + EXPORT |__divmodsi4| + IMPORT |__div0| + +|__divsi3| +|__divmodsi4| + MOVS a4, a2 + BEQ |__div0| /* divide by zero. */ + AND a3, a1, #&80000000 + EOR ip, a4, a1 + ORR a3, a3, ip, LSR #1 + RSBMI a4, a4, #0 + MOVS a2, a1 + RSBMI a2, a2, #0 + MOV ip, a4 + + CMP ip, a2, LSR #16 + MOVLS ip, ip, LSL #16 + CMP ip, a2, LSR #8 + MOVLS ip, ip, LSL #8 + CMP ip, a2, LSR #4 + MOVLS ip, ip, LSL #4 + CMP ip, a2, LSR #2 + MOVLS ip, ip, LSL #2 + CMP ip, a2, LSR #1 + MOVLS ip, ip, LSL #1 + + MOV a1, #0 +|__divsi3.divloop| + CMP a2, ip + SUBCS a2, a2, ip + ADC a1, a1, a1 + MOV ip, ip, LSR #1 + CMP ip, a4 + BCS |__divsi3.divloop| + TST a3, #&40000000 + RSBNE a1, a1, #0 + /* This line is for __divmodsi4 only */ + TST a3, #&80000000 + RSBNE a2, a2, #0 + RETURN(pc, lr) +#endif + +#ifdef L_ffs + EXPORT |ffs| + + /* return index to least significant 1-bit of a1 */ +|ffs| + /* input and output in a1, workspace a2 */ + TEQ a1, #0 /* test equality with 0 */ + SUBNE a2, a1, #1 /* subtract if not equal */ + EORNE a1, a1, a2 /* exclusive or if not equal */ + RSBNE a1, a1, a1, LSL #3 /* reverse subtract if not equal */ + RSBNE a1, a1, a1, LSL #8 + RSBNE a1, a1, a1, LSL #8 + RSBNE a1, a1, a1, LSL #8 + /* load register, if not equal, with byte */ + LDRNEB a1, [pc, a1, LSR #26] + RETURN(pc, lr) + +|ffs.table| + /* table must occur 8 bytes after LDRxxB instruction above */ + DCB 0,1,0,16,0,2,29,0,17,0,0,0,3,22,30,0 + DCB 0,0,20,18,11,0,13,0,0,4,0,7,0,23,31,0 + DCB 15,0,28,0,0,0,21,0,19,10,12,0,6,0,0,14 + DCB 27,0,0,9,0,5,0,26,0,8,25,0,24,0,32,0 + + EXPORT |__ffsdi2| +|__ffsdi2| + CMP a1, #0 /* if passed 0 */ + CMPEQ a2, #0 /* then exit */ + RETURNc(eq, pc, lr) + /* input and output in a1, workspace a2 */ + TEQ a1, #0 /* test equality with 0 */ + MOVEQ a1, a2 /* use the high word */ + MOVEQ a3, #32 /* need to add extra 32 bits */ + MOVNE a3, #0 /* use the low word */ + SUB a2, a1, #1 /* subtract if not equal */ + EOR a1, a1, a2 /* exclusive or if not equal */ + RSB a1, a1, a1, LSL #3 /* reverse subtract if not equal */ + RSB a1, a1, a1, LSL #8 + RSB a1, a1, a1, LSL #8 + RSB a1, a1, a1, LSL #8 + /* load register, if not equal, with byte */ + ADD a4, pc, #|ffs.table| - . - 8 + LDRB a1, [a4, a1, LSR #26] + ADD a1, a1, a3 + RETURN(pc, lr) +#endif + +#ifdef L_fixsfdi + EXPORT |__fixsfdi| + /* Convert single precision float to 64-bit int */ +|__fixsfdi| + cmp r0, #0 + moveq r1, #0 + RETURNc(eq, pc, lr) + + mov r2, r0, lsr #23 /* Extract the exponent */ + ands r2, r2, #&ff + bic r0, r0, r2, lsl #23 /* Clear exponent from mantissa */ + orrne r0, r0, #1<<23 /* add implicit bit */ + + tst r2, #1<<8 /* Is sign bit set */ + rsbne r0, r0, #0 /* yes; negate mantissa */ + + bic r2, r2, #1<<8 /* clear sign bit, leaving exponent */ + + subs r2, r2, #150 /* remove bias from exponent */ + movlt r0, r0, asr r2 + movlt r1, #0 + RETURNc(lt, pc, lr) + + rsb r2, r2, #0 + + /* perform 64-bit shift */ + rsbs ip, r2, #32 + rsble ip, ip, #0 /* shift >= 32 bits */ + movle r1, r0, asl ip + movle r0, #0 + movgt r1, r0, lsr ip + movgt r0, r0, asl r2 + RETURN(pc, lr) + + + /* number is represented as 1.mantissa x 2^exponent-127 */ + subs r2, r2, #127 /* remove bias from exponent */ + movmi r0, #0 /* if exponent negative then not representable */ + movmi r1, #0 + RETURNc(mi, pc, lr) /* as an integer */ + + /* the mantissa is 23 bits wide. assume we are representing the */ + /* number as mantissa x 2^23, then we may need to shift left */ + /* or right. */ + rsbs r2, r2, #23 + movpl r0, r0, asr r2 + movpl r1, #0 + RETURNc(pl, pc, lr) + + rsb r2, r2, #0 /* exponent was larger than 23 */ + + /* perform 64-bit shift */ + rsbs ip, r2, #32 + rsble ip, ip, #0 /* shift >= 32 bits */ + movle r1, r0, asl ip + movle r0, #0 + movgt r1, r0, lsr ip + movgt r0, r0, asl r2 + RETURN(pc, lr) +#endif + +#ifdef L_fixunssfdi + EXPORT |__fixunssfdi| + /* Convert single precision float to 64-bit int */ +|__fixunssfdi| + cmp r0, #0 + moveq r1, #0 + RETURNc(eq, pc, lr) + + mov r2, r0, lsr #23 /* Extract the exponent */ + bic r0, r0, r2, lsl #23 /* Clear exponent from mantissa */ + orr r0, r0, #1<<23 /* add implicit bit */ + bic r2, r2, #1<<8 /* clear sign bit, leaving exponent */ + + /* number is represented as 1.mantissa x 2^exponent-127 */ + subs r2, r2, #127 /* remove bias from exponent */ + movmi r0, #0 /* if exponent negative then not representable */ + movmi r1, #0 + RETURNc(mi, pc, lr) /* as an integer */ + + /* the mantissa is 23 bits wide. assume we are representing the */ + /* number as mantissa x 2^23, then we may need to shift left */ + /* or right. */ + rsbs r2, r2, #23 + movpl r0, r0, lsr r2 + movpl r1, #0 + RETURNc(pl, pc, lr) + + rsb r2, r2, #0 /* exponent was larger than 23 */ + + /* perform 64-bit shift */ + rsbs ip, r2, #32 + rsble ip, ip, #0 /* shift >= 32 bits */ + movle r1, r0, asl ip + movle r0, #0 + movgt r1, r0, lsr ip + movgt r0, r0, asl r2 + RETURN(pc, lr) +#endif + +#ifdef L_fixunsdfdi + EXPORT |__fixdfdi| + EXPORT |__fixunsdfdi| + +|__fixdfdi| + stmfd sp!, {r14} + mov r2, r0, lsr #31 + tst r2, #1 + bl |__fixunsdfdi| + ldmeqfd sp!, {pc}RETCOND + rsbs r0, r0, #0 + rsc r1, r1, #0 + ldmfd sp!, {pc}RETCOND + + /* Convert double precision float to 64-bit int */ +|__fixunsdfdi| + /* Check fast case, incoming integer == 0 */ + cmp r0, #0 + cmpeq r1, #0 + RETURNc(eq, pc, lr) + + /* r0 = first word */ + /* r1 = second word */ + + mov r3, r0, lsr #20 /* Extract the exponent */ + bic r2, r0, r3, lsl #20 /* clear exponent from fraction */ + orr r2, r2, #1<<20 /* add implicit bit */ + bic r12, r3, #1<<11 /* clear sign bit, leaving exponent */ + + /* number is represented as 1.mantissa x 2^exponent-1023 */ + sub r12, r12, #1024 /* remove bias from exponent */ + adds r12, r12, #1 + movmi r0, #0 /* if exponent negative then not representable */ + movmi r1, #0 /* as an integer */ + RETURNc(mi, pc, lr) + + /* at this point: r0 = exponent */ + /* r1 = second word (bottom 32-bits of fraction) */ + /* r2 = first word (top 20-bits of fraction) */ + + rsbs r12, r12, #52 + bmi fixunsdfdi_shl + + rsbs r3, r12, #32 /* r3 = 32 - shift */ + rsble r3, r3, #0 + movle r0, r2, lsr r3 /* low = high >> -bm */ + movle r1, #0 /* high = 0 */ + movgt r0, r1, lsr r12 /* low >>= exponent */ + orrgt r0, r0, r2, lsl r3 /* low |= high << r3 */ + movgt r1, r2, lsr r12 + RETURN(pc, lr) + +fixunsdfdi_shl + rsb r12, r12, #0 /* exponent was larger than 52 */ + + /* perform 64-bit shift */ + rsbs r3, r12, #32 + rsble r3, r3, #0 /* shift >= 32 bits */ + movle r1, r1, asl r3 + movle r0, #0 + movgt r2, r2, lsl r12 /* shift <= 31 bits */ + movgt r0, r1, asl r12 + orrgt r1, r2, r1, lsr r3 + RETURN(pc, lr) +#endif + +#ifdef L_fixunsxfdi + EXPORT |__fixxfdi| + EXPORT |__fixunsxfdi| + +|c..2| + DCD 0x4F000000 /* 2147483648.0 */ + +|__fixxfdi| + STMFD sp!, {a1, a2, a3} + LDFE f2, [sp], #12 + CMFE f2, #0.0 + BGE |__fixuns| + MOV a4, lr + MNFE f2, f2 + BL |__fixuns| + RSBS a1, a1, #0 + RSC a2, a2, #0 + RETURN(pc, a4) + + /* On entry: + sp = pointer to the floating point value + On exit: + r0 = lowest significant word of double integer + r1 = highest significant word of double integer */ +|__fixunsxfdi| + STMFD sp!, {a1, a2, a3} + LDFE f2, [sp], #12 + +|__fixuns| + CMFE f2, #0.0 + MOVLE a1, #0 + MOVLE a2, #0 + RETURNc(le, pc, lr) + LDFS f1, [pc, #|c..1| - . - 8] + FMLS f0, f1, #2.0 + DVFE f0, f2, f0 + CMFE f0, f1 + FIXLTZ a2, f0 + SUFGEE f0, f0, f1 + FIXGEZ a2, f0 + EORGE a2, a2, #&80000000 + MOV a1, #0 + CMP a2, #0 + RSBLT a3, a2, #0 + FLTLTE f0, a3 + MNFLTE f0, f0 + FLTGEE f0, a2 + MUFE f0, f0, f1 + MUFE f0, f0, #2.0 + SUFE f2, f2, f0 + CMFE f2, #0.0 + MNFLTE f2, f2 + MOVLT ip, #0 + MOVGE ip, #1 + CMFE f2, f1 + FIXLTZ a3, f2 + SUFGEE f2, f2, f1 + FIXGEZ a3, f2 + EORGE a3, a3, #&80000000 + CMP ip, #0 + BNE |do_add.2| + SUBS a1, a1, a3 + SBC a2, a2, #0 + RETURN(pc, lr) +|do_add.2| + ADDS a1, a1, a3 + ADC a2, a2, #0 + RETURN(pc, lr) +#endif + +#ifdef L_floatdidf + /* On entry: + r0 = lowest significant word of double integer + r1 = highest significant word of double integer + On exit: + f0 = A floating point representation of the integer */ + + /* Convert 64-bit integer to 96-bit float */ + EXPORT |__floatdixf| + /* Convert 64-bit integer to 64-bit float */ + EXPORT |__floatdidf| + /* Convert 64-bit integer to 32-bit float */ + EXPORT |__floatdisf| +|__floatdixf| +|__floatdidf| +|__floatdisf| + /* Check fast case, incoming integer == 0 */ + cmp r0, #0 + cmpeq r1, #0 + mvfeqd f0, #0.0 + RETURNc(eq, pc, lr) + + tst r1, #1<<31 + moveq r2, r0 /* bottom word */ + moveq r3, r1 /* top word */ + moveq r0, #0 /* first word of IEEE result */ + rsbne r2, r0, #0 /* negate fraction */ + rsbne r3, r1, #0 + movne r0, #1<<31 /* first word of IEEE result (with sign bit) */ + + cmp r3, #0 /* if top word if 0 then we'll use the bottom word */ + movne r12, #64 /* exponent */ + moveq r12, #32 + moveq r3, r2 + moveq r2, #0 + + /* Do a little loop unrolling */ + cmp r3, #1<<8 + movcc r3, r3, lsl #23 + orrcc r3, r3, r2, lsr #32-23 + movcc r2, r2, lsl #23 + subcc r12, r12, #23 + cmp r3, #1<<16 + movcc r3, r3, lsl #15 + orrcc r3, r3, r2, lsr #32-15 + movcc r2, r2, lsl #15 + subcc r12, r12, #15 + cmp r3, #1<<24 + movcc r3, r3, lsl #7 + orrcc r3, r3, r2, lsr #32-7 + movcc r2, r2, lsl #7 + subcc r12, r12, #7 +fltdidf_norm + tst r3, #1<<31 + bne fltdidf_norm_fin + mov r3, r3, lsl #1 + movs r2, r2, lsl #1 + orrcs r3, r3, #1 + sub r12, r12, #1 + b fltdidf_norm + +fltdidf_norm_fin + add r12, r12, #1020 /* add bias to exponent */ + add r12, r12, #2 + + /* pack into IEEE double precision format */ + orr r0, r0, r12, lsl #20 /* exponent */ + bic r3, r3, #1<<31 + orr r0, r0, r3, lsr #11 + mov r1, r2, lsr #11 + orr r1, r1, r3, lsl #21 + str r0, [sp, #-8] + str r1, [sp, #-4] + ldfd f0, [sp, #-8] + RETURN(pc, lr) +#endif + +#ifdef L_lshrdi3 + EXPORT |__lshrdi3| + + /* DItype __lshrdi3 (DItype u, word_type b) + a1, a2 = u + a3 = b */ +|__lshrdi3| + /* if shift = 0 then return */ + CMP a3, #0 + RETURNc(eq, pc, lr) + + /* if shift >= 32 then high word will be 0 */ + RSBS ip, a3, #32 /* bm = 32 - b */ + RSBLE ip, ip, #0 + MOVLE a1, a2, LSR ip /* low = high >> - bm */ + MOVLE a2, #0 /* high = 0 */ + + MOVGT a1, a1, LSR a3 /* low = low >> b */ + ORRGT a1, a1, a2, ASL ip /* low = low | high << bm */ + MOVGT a2, a2, LSR a3 /* high = high >> b */ + RETURN(pc, lr) +#endif + +#ifdef L_moddi3 + EXPORT |__moddi3| + IMPORT |__div0| + + /* (a1, a2) / (a3, a4) + result in v2 and v3 + remainder in v4 and ip */ +|__moddi3| + /* fast exits + check the numerator for zero */ + CMP a1, #0 /* low */ + CMPEQ a2, #0 /* high */ + RETURNc(eq, pc, lr) + /* test for a divide by zero */ + CMP a3, #0 /* low */ + CMPEQ a4, #0 /* high */ + BEQ |__div0| /* divide by zero. */ + /* No stack checking since we are a leaf function. + We don't need to store ip - procedure calling standard + lets it be corrupted. */ + STMFD sp!, {v2, v3, v4, v6, lr} + /* v6 = sign bit */ + ANDS v6, a4, #&80000000 + BPL |__moddi3.L00| + RSBS a3, a3, #0 /* low */ + RSC a4, a4, #0 /* high */ +|__moddi3.L00| + EORS v6, v6, a2, ASR#32 + BCC |__moddi3.L01| + RSBS a1, a1, #0 /* low */ + RSC a2, a2, #0 /* high */ +|__moddi3.L01| + /* initialise the quotient to zero */ + MOV v2, #0 /* low */ + MOV v3, #0 /* high */ + /* remainder = numerator */ + MOV v4, a1 /* low */ + MOV ip, a2 /* high */ + + /* lr is a count of the number of shifts needed */ + MOVS lr, #0 + /* shift the denominator left until the next doubling + generates a number larger than the numerator. + Count the number of shifts needed */ +|__moddi3.bit_count| + /* double the denominator, we've finished when the top bit + is set. */ + ADDS a3, a3, a3 /* low */ + ADCS a4, a4, a4 /* high */ + /* too big so we've finished */ + BCS |__moddi3.count_done| + CMP a4, ip /* high */ + CMPEQ a3, v4 /* low */ + /* if denominator is lower or the same as the numerator + signify an extra shift and carry on. */ + ADDLS lr, lr, #1 + BLS |__moddi3.bit_count| + + /* clear the carry flag */ + ADDS lr, lr, #0 + +|__moddi3.count_done| + /* we've overflowed. shift the denominator back down + to bring in the overflowed bit */ + MOVS a4, a4, RRX /* high */ + MOV a3, a3, RRX /* low */ + +|__moddi3.division| + /* numerator = remainder - denominator */ + SUBS a1, v4, a3 /* low */ + SBCS a2, ip, a4 /* high */ + /* if (remainder >= denominator) remainder = numerator */ + MOVCS v4, a1 /* low */ + MOVCS ip, a2 /* high */ + /* shift the denominator right 1 bit */ + MOVS a4, a4, LSR #1 /* high */ + MOV a3, a3, RRX /* low */ + SUBS lr, lr, #1 + BGE |__moddi3.division| + /* result */ + MOVS v6, v6, LSL#1 + MOVCC a1, v4 /* low */ + MOVCC a2, ip /* high */ + LDMCCFD sp!, {v2, v3, v4, v6, pc}RETCOND + RSBS a1, v4, #0 /* low */ + RSC a2, ip, #0 /* high */ + LDMFD sp!, {v2, v3, v4, v6, pc}RETCOND +#endif + +#ifdef L_modsi3 + EXPORT |__modsi3| + IMPORT |__div0| + + /* a1 = (a1 / a2) remainder a2 + returns remainder in a1 */ + +|__modsi3| + ANDS ip, a1, #&80000000 + RSBMI a1, a1, #0 + MOVS a2, a2 + BEQ |__div0| /* divide by zero. */ + RSBMI a2, a2, #0 + MOV a3, a2 + + CMP a3, a1, LSR #16 + MOVLS a3, a3, LSL #16 + CMP a3, a1, LSR #8 + MOVLS a3, a3, LSL #8 + CMP a3, a1, LSR #4 + MOVLS a3, a3, LSL #4 + CMP a3, a1, LSR #2 + MOVLS a3, a3, LSL #2 + CMP a3, a1, LSR #1 + MOVLS a3, a3, LSL #1 + +|__modsi3.divloop| + CMP a1, a3 + SUBCS a1, a1, a3 + MOV a3, a3, LSR #1 + CMP a3, a2 + BCS |__modsi3.divloop| + TST ip, #&80000000 + RSBNE a1, a1, #0 + RETURN(pc, lr) +#endif + +#ifdef L_muldi3 + EXPORT |__muldi3| + + /* (a1, a2) * (a3, a4) */ +|__muldi3| +#ifdef __ARM_ARCH_4__ + SMULL a1, a2, a3, a4 + RETURN(pc, lr) +#else + STMFD sp!, {v1, v2, v3, lr} + MOV v2, a1, LSR #16 + BIC ip, a1, v2, LSL #16 + MOV v1, a3, LSR #16 + BIC lr, a3, v1, LSL #16 + MUL v3, v2, v1 + MUL v2, lr, v2 + MUL v1, ip, v1 + MUL ip, lr, ip + ADDS lr, v2, v1 + ADDCS v3, v3, #&10000 + ADDS v1, ip, lr, LSL #16 + ADC v2, v3, lr, LSR #16 + MLA v2, a1, a4, v2 + MLA a2, a3, a2, v2 + MOV a1, v1 + LDMFD sp!, {v1, v2, v3, pc}RETCOND +#endif /* __ARM_ARCH_4__ */ +#endif /* L_muldi3 */ + +#ifdef L_ucmpdi2 + EXPORT |__ucmpdi2| + /* compare two unsigned long long ints + enter with __ucmpdi2 (DItype a, DItype b) + entry a1,a2 = u, a3,a4 = v + exit u > v = 2, u < v = 0, u = v = 1 */ +|__ucmpdi2| + CMP a2, a4 + CMPEQ a1, a3 + MOVCC a1, #0 + MOVHI a1, #2 + MOVEQ a1, #1 + RETURN(pc, lr) +#endif + +#ifdef L_udivdi3 + EXPORT |__udivdi3| + IMPORT |__div0| + +/* (a1, a2) / (a3, a4) + result in v2 and v3 + remainder in v4 and ip */ +|__udivdi3| + CMP a1, #0 + CMPEQ a2, #0 + RETURNc(eq, pc, lr) + CMP a3, #0 + CMPEQ a4, #0 + BEQ |__div0| /* divide by zero. */ + STMFD sp!, {v2, v3, v4, lr} + MOV v2, #0 + MOV v3, #0 + MOV v4, a1 + MOV ip, a2 + MOVS lr, #0 +|__udivdi3.bit_count| + ADDS a3, a3, a3 + ADCS a4, a4, a4 + BCS |__udivdi3.count_done| + CMP a4, ip + CMPEQ a3, v4 + ADDLS lr, lr, #1 + BLS |__udivdi3.bit_count| + ADDS lr, lr, #0 +|__udivdi3.count_done| + MOVS a4, a4, RRX + MOV a3, a3, RRX +|__udivdi3.division| + SUBS a1, v4, a3 + SBCS a2, ip, a4 + MOVCS v4, a1 + MOVCS ip, a2 + ADCS v2, v2, v2 + ADC v3, v3, v3 + MOVS a4, a4, LSR #1 + MOV a3, a3, RRX + SUBS lr, lr, #1 +