diff options
| author | Richard Purdie <richard@openedhand.com> | 2008-03-18 11:00:00 +0000 |
|---|---|---|
| committer | Richard Purdie <richard@openedhand.com> | 2008-03-18 11:00:00 +0000 |
| commit | fc8e9ffda6cc3210389cd3b7b96a82e9b5949fae (patch) | |
| tree | 7dbf4ab556fb920751a940fd153f34f1c89afdae /meta | |
| parent | 1f909ea02c693f0e51e3d5227c34cbf71ae93fa8 (diff) | |
| download | poky-fc8e9ffda6cc3210389cd3b7b96a82e9b5949fae.tar.gz | |
gcc: Drop gcc 4.0.2, nothing uses it
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@4041 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'meta')
19 files changed, 0 insertions, 25909 deletions
diff --git a/meta/packages/gcc/gcc-4.0.2.inc b/meta/packages/gcc/gcc-4.0.2.inc deleted file mode 100644 index a0a6a6ae66..0000000000 --- a/meta/packages/gcc/gcc-4.0.2.inc +++ /dev/null | |||
| @@ -1,29 +0,0 @@ | |||
| 1 | require gcc-common.inc | ||
| 2 | |||
| 3 | DEPENDS = "mpfr gmp" | ||
| 4 | |||
| 5 | SRC_URI = "${GNU_MIRROR}/gcc/gcc-${PV}/gcc-${PV}.tar.bz2 \ | ||
| 6 | file://arm-nolibfloat.patch;patch=1 \ | ||
| 7 | file://arm-softfloat.patch;patch=1 \ | ||
| 8 | file://ldflags.patch;patch=1 \ | ||
| 9 | file://GCOV_PREFIX_STRIP-cross-profile_4.1.patch;patch=1 \ | ||
| 10 | file://zecke-xgcc-cpp.patch;patch=1 " | ||
| 11 | |||
| 12 | # uclibc patches below | ||
| 13 | SRC_URI_append = " file://100-uclibc-conf.patch;patch=1 \ | ||
| 14 | file://200-uclibc-locale.patch;patch=1 \ | ||
| 15 | file://301-missing-execinfo_h.patch;patch=1 \ | ||
| 16 | file://302-c99-snprintf.patch;patch=1 \ | ||
| 17 | file://303-c99-complex-ugly-hack.patch;patch=1 \ | ||
| 18 | file://800-arm-bigendian.patch;patch=1 \ | ||
| 19 | file://zecke-host-cpp-ac-hack.patch;patch=1 \ | ||
| 20 | file://gcc-4.0.2-atmel.0.99.2.patch;patch=1 \ | ||
| 21 | " | ||
| 22 | |||
| 23 | SRC_URI_append_fail-fast = " file://zecke-no-host-includes.patch;patch=1 " | ||
| 24 | |||
| 25 | # Language Overrides | ||
| 26 | FORTRAN = "" | ||
| 27 | |||
| 28 | EXTRA_OECONF += "--disable-libssp" | ||
| 29 | |||
diff --git a/meta/packages/gcc/gcc-4.0.2/100-uclibc-conf.patch b/meta/packages/gcc/gcc-4.0.2/100-uclibc-conf.patch deleted file mode 100644 index 35445522f8..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/100-uclibc-conf.patch +++ /dev/null | |||
| @@ -1,556 +0,0 @@ | |||
| 1 | From: | ||
| 2 | http://buildroot.uclibc.org/cgi-bin/viewcvs.cgi/*checkout*/trunk/buildroot/toolchain/gcc/4.0.2/100-uclibc-conf.patch?rev=13898 | ||
| 3 | |||
| 4 | --- gcc-4.0.2/gcc/config/t-linux-uclibc | ||
| 5 | +++ gcc-4.0.2/gcc/config/t-linux-uclibc | ||
| 6 | @@ -0,0 +1,5 @@ | ||
| 7 | +# Remove glibc specific files added in t-linux | ||
| 8 | +SHLIB_MAPFILES := $(filter-out $(srcdir)/config/libgcc-glibc.ver, $(SHLIB_MAPFILES)) | ||
| 9 | + | ||
| 10 | +# Use unwind-dw2-fde instead of unwind-dw2-fde-glibc | ||
| 11 | +LIB2ADDEH := $(subst unwind-dw2-fde-glibc.c,unwind-dw2-fde.c,$(LIB2ADDEH)) | ||
| 12 | --- gcc-4.0.2/gcc/config.gcc | ||
| 13 | +++ gcc-4.0.2/gcc/config.gcc | ||
| 14 | @@ -1778,7 +1778,7 @@ | ||
| 15 | ;; | ||
| 16 | sh-*-elf* | sh[12346l]*-*-elf* | sh*-*-kaos* | \ | ||
| 17 | sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \ | ||
| 18 | - sh-*-linux* | sh[346lbe]*-*-linux* | \ | ||
| 19 | + sh*-*-linux* | sh[346lbe]*-*-linux* | \ | ||
| 20 | sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \ | ||
| 21 | sh64-*-netbsd* | sh64l*-*-netbsd*) | ||
| 22 | tmake_file="${tmake_file} sh/t-sh sh/t-elf" | ||
| 23 | @@ -2234,10 +2234,16 @@ | ||
| 24 | *) | ||
| 25 | echo "*** Configuration ${target} not supported" 1>&2 | ||
| 26 | exit 1 | ||
| 27 | ;; | ||
| 28 | esac | ||
| 29 | + | ||
| 30 | +# Rather than hook into each target, just do it after all the linux | ||
| 31 | +# targets have been processed | ||
| 32 | +case ${target} in | ||
| 33 | +*-linux-uclibc*) tm_defines="${tm_defines} USE_UCLIBC" ; tmake_file="${tmake_file} t-linux-uclibc" | ||
| 34 | +esac | ||
| 35 | |||
| 36 | case ${target} in | ||
| 37 | i[34567]86-*-linux*aout* | i[34567]86-*-linux*libc1) | ||
| 38 | tmake_file="${tmake_file} i386/t-gmm_malloc" | ||
| 39 | ;; | ||
| 40 | --- gcc-4.0.2/gcc/config/alpha/linux-elf.h | ||
| 41 | +++ gcc-4.0.2/gcc/config/alpha/linux-elf.h | ||
| 42 | @@ -27,7 +27,11 @@ | ||
| 43 | #define SUBTARGET_EXTRA_SPECS \ | ||
| 44 | { "elf_dynamic_linker", ELF_DYNAMIC_LINKER }, | ||
| 45 | |||
| 46 | +#ifdef USE_UCLIBC | ||
| 47 | +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" | ||
| 48 | +#else | ||
| 49 | #define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2" | ||
| 50 | +#endif | ||
| 51 | |||
| 52 | #define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \ | ||
| 53 | %{O*:-O3} %{!O*:-O1} \ | ||
| 54 | --- gcc-4.0.2/gcc/config/arm/linux-elf.h | ||
| 55 | +++ gcc-4.0.2/gcc/config/arm/linux-elf.h | ||
| 56 | @@ -81,14 +81,19 @@ | ||
| 57 | #define ENDFILE_SPEC \ | ||
| 58 | "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s" | ||
| 59 | |||
| 60 | +#ifdef USE_UCLIBC | ||
| 61 | +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" | ||
| 62 | +#else | ||
| 63 | +#define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2" | ||
| 64 | +#endif | ||
| 65 | #undef LINK_SPEC | ||
| 66 | #define LINK_SPEC "%{h*} %{version:-v} \ | ||
| 67 | %{b} %{Wl,*:%*} \ | ||
| 68 | %{static:-Bstatic} \ | ||
| 69 | %{shared:-shared} \ | ||
| 70 | %{symbolic:-Bsymbolic} \ | ||
| 71 | %{rdynamic:-export-dynamic} \ | ||
| 72 | - %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2} \ | ||
| 73 | + %{!dynamic-linker:-dynamic-linker " ELF_DYNAMIC_LINKER "} \ | ||
| 74 | -X \ | ||
| 75 | %{mbig-endian:-EB}" \ | ||
| 76 | SUBTARGET_EXTRA_LINK_SPEC | ||
| 77 | --- gcc-4.0.2/gcc/config/cris/linux.h | ||
| 78 | +++ gcc-4.0.2/gcc/config/cris/linux.h | ||
| 79 | @@ -79,6 +79,25 @@ | ||
| 80 | #undef CRIS_DEFAULT_CPU_VERSION | ||
| 81 | #define CRIS_DEFAULT_CPU_VERSION CRIS_CPU_NG | ||
| 82 | |||
| 83 | +#ifdef USE_UCLIBC | ||
| 84 | + | ||
| 85 | +#undef CRIS_SUBTARGET_VERSION | ||
| 86 | +#define CRIS_SUBTARGET_VERSION " - cris-axis-linux-uclibc" | ||
| 87 | + | ||
| 88 | +#undef CRIS_LINK_SUBTARGET_SPEC | ||
| 89 | +#define CRIS_LINK_SUBTARGET_SPEC \ | ||
| 90 | + "-mcrislinux\ | ||
| 91 | + -rpath-link include/asm/../..%s\ | ||
| 92 | + %{shared} %{static}\ | ||
| 93 | + %{symbolic:-Bdynamic} %{shlib:-Bdynamic} %{static:-Bstatic}\ | ||
| 94 | + %{!shared: \ | ||
| 95 | + %{!static: \ | ||
| 96 | + %{rdynamic:-export-dynamic} \ | ||
| 97 | + %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}}} \ | ||
| 98 | + %{!r:%{O2|O3: --gc-sections}}" | ||
| 99 | + | ||
| 100 | +#else /* USE_UCLIBC */ | ||
| 101 | + | ||
| 102 | #undef CRIS_SUBTARGET_VERSION | ||
| 103 | #define CRIS_SUBTARGET_VERSION " - cris-axis-linux-gnu" | ||
| 104 | |||
| 105 | @@ -93,6 +112,8 @@ | ||
| 106 | %{!shared:%{!static:%{rdynamic:-export-dynamic}}}\ | ||
| 107 | %{!r:%{O2|O3: --gc-sections}}" | ||
| 108 | |||
| 109 | +#endif /* USE_UCLIBC */ | ||
| 110 | + | ||
| 111 | |||
| 112 | /* Node: Run-time Target */ | ||
| 113 | |||
| 114 | --- gcc-4.0.2/gcc/config/i386/linux.h | ||
| 115 | +++ gcc-4.0.2/gcc/config/i386/linux.h | ||
| 116 | @@ -107,6 +107,11 @@ | ||
| 117 | #define LINK_EMULATION "elf_i386" | ||
| 118 | #define DYNAMIC_LINKER "/lib/ld-linux.so.2" | ||
| 119 | |||
| 120 | +#ifdef USE_UCLIBC | ||
| 121 | +#undef DYNAMIC_LINKER | ||
| 122 | +#define DYNAMIC_LINKER "/lib/ld-uClibc.so.0" | ||
| 123 | +#endif | ||
| 124 | + | ||
| 125 | #undef SUBTARGET_EXTRA_SPECS | ||
| 126 | #define SUBTARGET_EXTRA_SPECS \ | ||
| 127 | { "link_emulation", LINK_EMULATION },\ | ||
| 128 | --- gcc-4.0.2/gcc/config/i386/linux64.h | ||
| 129 | +++ gcc-4.0.2/gcc/config/i386/linux64.h | ||
| 130 | @@ -54,14 +54,21 @@ | ||
| 131 | When the -shared link option is used a final link is not being | ||
| 132 | done. */ | ||
| 133 | |||
| 134 | +#ifdef USE_UCLIBC | ||
| 135 | +#define ELF32_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" | ||
| 136 | +#define ELF64_DYNAMIC_LINKER "/lib/ld64-uClibc.so.0" | ||
| 137 | +#else | ||
| 138 | +#define ELF32_DYNAMIC_LINKER "/lib/ld-linux.so.2" | ||
| 139 | +#define ELF64_DYNAMIC_LINKER "/lib64/ld-linux-x86-64.so.2" | ||
| 140 | +#endif | ||
| 141 | #undef LINK_SPEC | ||
| 142 | #define LINK_SPEC "%{!m32:-m elf_x86_64} %{m32:-m elf_i386} \ | ||
| 143 | %{shared:-shared} \ | ||
| 144 | %{!shared: \ | ||
| 145 | %{!static: \ | ||
| 146 | %{rdynamic:-export-dynamic} \ | ||
| 147 | - %{m32:%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ | ||
| 148 | - %{!m32:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} \ | ||
| 149 | + %{m32:%{!dynamic-linker:-dynamic-linker " ELF32_DYNAMIC_LINKER "}} \ | ||
| 150 | + %{!m32:%{!dynamic-linker:-dynamic-linker " ELF64_DYNAMIC_LINKER "}}} \ | ||
| 151 | %{static:-static}}" | ||
| 152 | |||
| 153 | #define MULTILIB_DEFAULTS { "m64" } | ||
| 154 | --- gcc-4.0.2/gcc/config/ia64/linux.h | ||
| 155 | +++ gcc-4.0.2/gcc/config/ia64/linux.h | ||
| 156 | @@ -37,13 +37,18 @@ | ||
| 157 | /* Define this for shared library support because it isn't in the main | ||
| 158 | linux.h file. */ | ||
| 159 | |||
| 160 | +#ifdef USE_UCLIBC | ||
| 161 | +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" | ||
| 162 | +#else | ||
| 163 | +#define ELF_DYNAMIC_LINKER "/lib/ld-linux-ia64.so.2" | ||
| 164 | +#endif | ||
| 165 | #undef LINK_SPEC | ||
| 166 | #define LINK_SPEC "\ | ||
| 167 | %{shared:-shared} \ | ||
| 168 | %{!shared: \ | ||
| 169 | %{!static: \ | ||
| 170 | %{rdynamic:-export-dynamic} \ | ||
| 171 | - %{!dynamic-linker:-dynamic-linker /lib/ld-linux-ia64.so.2}} \ | ||
| 172 | + %{!dynamic-linker:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ | ||
| 173 | %{static:-static}}" | ||
| 174 | |||
| 175 | |||
| 176 | --- gcc-4.0.2/gcc/config/m68k/linux.h | ||
| 177 | +++ gcc-4.0.2/gcc/config/m68k/linux.h | ||
| 178 | @@ -127,12 +127,17 @@ | ||
| 179 | |||
| 180 | /* If ELF is the default format, we should not use /lib/elf. */ | ||
| 181 | |||
| 182 | +#ifdef USE_UCLIBC | ||
| 183 | +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" | ||
| 184 | +#else | ||
| 185 | +#define ELF_DYNAMIC_LINKER "/lib/ld.so.1" | ||
| 186 | +#endif | ||
| 187 | #undef LINK_SPEC | ||
| 188 | #define LINK_SPEC "-m m68kelf %{shared} \ | ||
| 189 | %{!shared: \ | ||
| 190 | %{!static: \ | ||
| 191 | %{rdynamic:-export-dynamic} \ | ||
| 192 | - %{!dynamic-linker*:-dynamic-linker /lib/ld.so.1}} \ | ||
| 193 | + %{!dynamic-linker*:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ | ||
| 194 | %{static}}" | ||
| 195 | |||
| 196 | /* For compatibility with linux/a.out */ | ||
| 197 | --- gcc-4.0.2/gcc/config/mips/linux.h | ||
| 198 | +++ gcc-4.0.2/gcc/config/mips/linux.h | ||
| 199 | @@ -108,14 +108,19 @@ | ||
| 200 | |||
| 201 | /* Borrowed from sparc/linux.h */ | ||
| 202 | #undef LINK_SPEC | ||
| 203 | +#ifdef USE_UCLIBC | ||
| 204 | +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" | ||
| 205 | +#else | ||
| 206 | +#define ELF_DYNAMIC_LINKER "/lib/ld.so.1" | ||
| 207 | +#endif | ||
| 208 | #define LINK_SPEC \ | ||
| 209 | "%(endian_spec) \ | ||
| 210 | %{shared:-shared} \ | ||
| 211 | %{!shared: \ | ||
| 212 | %{!ibcs: \ | ||
| 213 | %{!static: \ | ||
| 214 | %{rdynamic:-export-dynamic} \ | ||
| 215 | - %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \ | ||
| 216 | + %{!dynamic-linker:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ | ||
| 217 | %{static:-static}}}" | ||
| 218 | |||
| 219 | #undef SUBTARGET_ASM_SPEC | ||
| 220 | --- gcc-4.0.2/gcc/config/pa/pa-linux.h | ||
| 221 | +++ gcc-4.0.2/gcc/config/pa/pa-linux.h | ||
| 222 | @@ -82,13 +82,18 @@ | ||
| 223 | /* Define this for shared library support because it isn't in the main | ||
| 224 | linux.h file. */ | ||
| 225 | |||
| 226 | +#ifdef USE_UCLIBC | ||
| 227 | +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" | ||
| 228 | +#else | ||
| 229 | +#define ELF_DYNAMIC_LINKER "/lib/ld.so.1" | ||
| 230 | +#endif | ||
| 231 | #undef LINK_SPEC | ||
| 232 | #define LINK_SPEC "\ | ||
| 233 | %{shared:-shared} \ | ||
| 234 | %{!shared: \ | ||
| 235 | %{!static: \ | ||
| 236 | %{rdynamic:-export-dynamic} \ | ||
| 237 | - %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \ | ||
| 238 | + %{!dynamic-linker:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ | ||
| 239 | %{static:-static}}" | ||
| 240 | |||
| 241 | /* glibc's profiling functions don't need gcc to allocate counters. */ | ||
| 242 | --- gcc-4.0.2/gcc/config/rs6000/linux.h | ||
| 243 | +++ gcc-4.0.2/gcc/config/rs6000/linux.h | ||
| 244 | @@ -69,7 +69,11 @@ | ||
| 245 | #define LINK_START_DEFAULT_SPEC "%(link_start_linux)" | ||
| 246 | |||
| 247 | #undef LINK_OS_DEFAULT_SPEC | ||
| 248 | +#ifdef USE_UCLIBC | ||
| 249 | +#define LINK_OS_DEFAULT_SPEC "%(link_os_linux_uclibc)" | ||
| 250 | +#else | ||
| 251 | #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)" | ||
| 252 | +#endif | ||
| 253 | |||
| 254 | #define LINK_GCC_C_SEQUENCE_SPEC \ | ||
| 255 | "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" | ||
| 256 | --- gcc-4.0.2/gcc/config/rs6000/sysv4.h | ||
| 257 | +++ gcc-4.0.2/gcc/config/rs6000/sysv4.h | ||
| 258 | @@ -949,6 +949,7 @@ | ||
| 259 | mcall-linux : %(link_os_linux) ; \ | ||
| 260 | mcall-gnu : %(link_os_gnu) ; \ | ||
| 261 | mcall-netbsd : %(link_os_netbsd) ; \ | ||
| 262 | + mcall-linux-uclibc : %(link_os_linux_uclibc); \ | ||
| 263 | mcall-openbsd: %(link_os_openbsd) ; \ | ||
| 264 | : %(link_os_default) }" | ||
| 265 | |||
| 266 | @@ -1127,6 +1128,10 @@ | ||
| 267 | %{rdynamic:-export-dynamic} \ | ||
| 268 | %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}" | ||
| 269 | |||
| 270 | +#define LINK_OS_LINUX_UCLIBC_SPEC "-m elf32ppclinux %{!shared: %{!static: \ | ||
| 271 | + %{rdynamic:-export-dynamic} \ | ||
| 272 | + %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}}}" | ||
| 273 | + | ||
| 274 | #if defined(HAVE_LD_EH_FRAME_HDR) | ||
| 275 | # define LINK_EH_SPEC "%{!static:--eh-frame-hdr} " | ||
| 276 | #endif | ||
| 277 | @@ -1293,6 +1298,7 @@ | ||
| 278 | { "link_os_sim", LINK_OS_SIM_SPEC }, \ | ||
| 279 | { "link_os_freebsd", LINK_OS_FREEBSD_SPEC }, \ | ||
| 280 | { "link_os_linux", LINK_OS_LINUX_SPEC }, \ | ||
| 281 | + { "link_os_linux_uclibc", LINK_OS_LINUX_UCLIBC_SPEC }, \ | ||
| 282 | { "link_os_gnu", LINK_OS_GNU_SPEC }, \ | ||
| 283 | { "link_os_netbsd", LINK_OS_NETBSD_SPEC }, \ | ||
| 284 | { "link_os_openbsd", LINK_OS_OPENBSD_SPEC }, \ | ||
| 285 | --- gcc-4.0.2/gcc/config/s390/linux.h | ||
| 286 | +++ gcc-4.0.2/gcc/config/s390/linux.h | ||
| 287 | @@ -77,6 +77,13 @@ | ||
| 288 | #define MULTILIB_DEFAULTS { "m31" } | ||
| 289 | #endif | ||
| 290 | |||
| 291 | +#ifdef USE_UCLIBC | ||
| 292 | +#define ELF31_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" | ||
| 293 | +#define ELF64_DYNAMIC_LINKER "/lib/ld64-uClibc.so.0" | ||
| 294 | +#else | ||
| 295 | +#define ELF31_DYNAMIC_LINKER "/lib/ld.so.1" | ||
| 296 | +#define ELF64_DYNAMIC_LINKER "/lib/ld64.so.1" | ||
| 297 | +#endif | ||
| 298 | #undef LINK_SPEC | ||
| 299 | #define LINK_SPEC \ | ||
| 300 | "%{m31:-m elf_s390}%{m64:-m elf64_s390} \ | ||
| 301 | @@ -86,8 +93,8 @@ | ||
| 302 | %{!static: \ | ||
| 303 | %{rdynamic:-export-dynamic} \ | ||
| 304 | %{!dynamic-linker: \ | ||
| 305 | - %{m31:-dynamic-linker /lib/ld.so.1} \ | ||
| 306 | - %{m64:-dynamic-linker /lib/ld64.so.1}}}}" | ||
| 307 | + %{m31:-dynamic-linker " ELF31_DYNAMIC_LINKER "} \ | ||
| 308 | + %{m64:-dynamic-linker " ELF64_DYNAMIC_LINKER "}}}}" | ||
| 309 | |||
| 310 | |||
| 311 | #define TARGET_ASM_FILE_END file_end_indicate_exec_stack | ||
| 312 | --- gcc-4.0.2/gcc/config/sh/linux.h | ||
| 313 | +++ gcc-4.0.2/gcc/config/sh/linux.h | ||
| 314 | @@ -67,11 +67,16 @@ | ||
| 315 | #undef SUBTARGET_LINK_EMUL_SUFFIX | ||
| 316 | #define SUBTARGET_LINK_EMUL_SUFFIX "_linux" | ||
| 317 | #undef SUBTARGET_LINK_SPEC | ||
| 318 | +#ifdef USE_UCLIBC | ||
| 319 | +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" | ||
| 320 | +#else | ||
| 321 | +#define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2" | ||
| 322 | +#endif | ||
| 323 | #define SUBTARGET_LINK_SPEC \ | ||
| 324 | "%{shared:-shared} \ | ||
| 325 | %{!static: \ | ||
| 326 | %{rdynamic:-export-dynamic} \ | ||
| 327 | - %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ | ||
| 328 | + %{!dynamic-linker:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ | ||
| 329 | %{static:-static}" | ||
| 330 | |||
| 331 | #undef LIB_SPEC | ||
| 332 | --- gcc-4.0.2/gcc/config/sparc/linux.h | ||
| 333 | +++ gcc-4.0.2/gcc/config/sparc/linux.h | ||
| 334 | @@ -130,14 +130,19 @@ | ||
| 335 | |||
| 336 | /* If ELF is the default format, we should not use /lib/elf. */ | ||
| 337 | |||
| 338 | +#ifdef USE_UCLIBC | ||
| 339 | +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" | ||
| 340 | +#else | ||
| 341 | +#define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2" | ||
| 342 | +#endif | ||
| 343 | #undef LINK_SPEC | ||
| 344 | #define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \ | ||
| 345 | %{!mno-relax:%{!r:-relax}} \ | ||
| 346 | %{!shared: \ | ||
| 347 | %{!ibcs: \ | ||
| 348 | %{!static: \ | ||
| 349 | %{rdynamic:-export-dynamic} \ | ||
| 350 | - %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ | ||
| 351 | + %{!dynamic-linker:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ | ||
| 352 | %{static:-static}}}" | ||
| 353 | |||
| 354 | /* The sun bundled assembler doesn't accept -Yd, (and neither does gas). | ||
| 355 | --- gcc-4.0.2/gcc/config/sparc/linux64.h | ||
| 356 | +++ gcc-4.0.2/gcc/config/sparc/linux64.h | ||
| 357 | @@ -167,12 +166,17 @@ | ||
| 358 | { "link_arch_default", LINK_ARCH_DEFAULT_SPEC }, \ | ||
| 359 | { "link_arch", LINK_ARCH_SPEC }, | ||
| 360 | |||
| 361 | +#ifdef USE_UCLIBC | ||
| 362 | +#define ELF_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" | ||
| 363 | +#else | ||
| 364 | +#define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2" | ||
| 365 | +#endif | ||
| 366 | #define LINK_ARCH32_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \ | ||
| 367 | %{!shared: \ | ||
| 368 | %{!ibcs: \ | ||
| 369 | %{!static: \ | ||
| 370 | %{rdynamic:-export-dynamic} \ | ||
| 371 | - %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ | ||
| 372 | + %{!dynamic-linker:-dynamic-linker " ELF_DYNAMIC_LINKER "}} \ | ||
| 373 | %{static:-static}}} \ | ||
| 374 | " | ||
| 375 | |||
| 376 | --- gcc-4.0.2/libtool.m4 | ||
| 377 | +++ gcc-4.0.2/libtool.m4 | ||
| 378 | @@ -682,6 +682,11 @@ | ||
| 379 | lt_cv_deplibs_check_method=pass_all | ||
| 380 | ;; | ||
| 381 | |||
| 382 | +linux-uclibc*) | ||
| 383 | + lt_cv_deplibs_check_method=pass_all | ||
| 384 | + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` | ||
| 385 | + ;; | ||
| 386 | + | ||
| 387 | netbsd* | knetbsd*-gnu) | ||
| 388 | if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then | ||
| 389 | [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'] | ||
| 390 | --- gcc-4.0.2/ltconfig | ||
| 391 | +++ gcc-4.0.2/ltconfig | ||
| 392 | @@ -603,6 +603,7 @@ | ||
| 393 | |||
| 394 | # Transform linux* to *-*-linux-gnu*, to support old configure scripts. | ||
| 395 | case $host_os in | ||
| 396 | +linux-uclibc*) ;; | ||
| 397 | linux-gnu*) ;; | ||
| 398 | linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` | ||
| 399 | esac | ||
| 400 | @@ -1274,6 +1275,23 @@ | ||
| 401 | dynamic_linker='GNU/Linux ld.so' | ||
| 402 | ;; | ||
| 403 | |||
| 404 | +linux-uclibc*) | ||
| 405 | + version_type=linux | ||
| 406 | + need_lib_prefix=no | ||
| 407 | + need_version=no | ||
| 408 | + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' | ||
| 409 | + soname_spec='${libname}${release}.so$major' | ||
| 410 | + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' | ||
| 411 | + shlibpath_var=LD_LIBRARY_PATH | ||
| 412 | + shlibpath_overrides_runpath=no | ||
| 413 | + # This implies no fast_install, which is unacceptable. | ||
| 414 | + # Some rework will be needed to allow for fast_install | ||
| 415 | + # before this can be enabled. | ||
| 416 | + hardcode_into_libs=yes | ||
| 417 | + # Assume using the uClibc dynamic linker. | ||
| 418 | + dynamic_linker="uClibc ld.so" | ||
| 419 | + ;; | ||
| 420 | + | ||
| 421 | netbsd*) | ||
| 422 | need_lib_prefix=no | ||
| 423 | need_version=no | ||
| 424 | --- gcc-4.0.2/libffi/configure | ||
| 425 | +++ gcc-4.0.2/libffi/configure | ||
| 426 | @@ -3457,6 +3457,11 @@ | ||
| 427 | lt_cv_deplibs_check_method=pass_all | ||
| 428 | ;; | ||
| 429 | |||
| 430 | +linux-uclibc*) | ||
| 431 | + lt_cv_deplibs_check_method=pass_all | ||
| 432 | + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` | ||
| 433 | + ;; | ||
| 434 | + | ||
| 435 | netbsd* | knetbsd*-gnu) | ||
| 436 | if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then | ||
| 437 | lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' | ||
| 438 | --- gcc-4.0.2/libgfortran/configure | ||
| 439 | +++ gcc-4.0.2/libgfortran/configure | ||
| 440 | @@ -3681,6 +3681,11 @@ | ||
| 441 | lt_cv_deplibs_check_method=pass_all | ||
| 442 | ;; | ||
| 443 | |||
| 444 | +linux-uclibc*) | ||
| 445 | + lt_cv_deplibs_check_method=pass_all | ||
| 446 | + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` | ||
| 447 | + ;; | ||
| 448 | + | ||
| 449 | netbsd* | knetbsd*-gnu) | ||
| 450 | if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then | ||
| 451 | lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' | ||
| 452 | --- gcc-4.0.2/libjava/configure | ||
| 453 | +++ gcc-4.0.2/libjava/configure | ||
| 454 | @@ -4351,6 +4351,11 @@ | ||
| 455 | lt_cv_deplibs_check_method=pass_all | ||
| 456 | ;; | ||
| 457 | |||
| 458 | +linux-uclibc*) | ||
| 459 | + lt_cv_deplibs_check_method=pass_all | ||
| 460 | + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` | ||
| 461 | + ;; | ||
| 462 | + | ||
| 463 | netbsd* | knetbsd*-gnu) | ||
| 464 | if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then | ||
| 465 | lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' | ||
| 466 | --- gcc-4.0.2/libmudflap/configure | ||
| 467 | +++ gcc-4.0.2/libmudflap/configure | ||
| 468 | @@ -5380,6 +5380,11 @@ | ||
| 469 | lt_cv_deplibs_check_method=pass_all | ||
| 470 | ;; | ||
| 471 | |||
| 472 | +linux-uclibc*) | ||
| 473 | + lt_cv_deplibs_check_method=pass_all | ||
| 474 | + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` | ||
| 475 | + ;; | ||
| 476 | + | ||
| 477 | netbsd* | knetbsd*-gnu) | ||
| 478 | if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then | ||
| 479 | lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' | ||
| 480 | --- gcc-4.0.2/libobjc/configure | ||
| 481 | +++ gcc-4.0.2/libobjc/configure | ||
| 482 | @@ -3283,6 +3283,11 @@ | ||
| 483 | lt_cv_deplibs_check_method=pass_all | ||
| 484 | ;; | ||
| 485 | |||
| 486 | +linux-uclibc*) | ||
| 487 | + lt_cv_deplibs_check_method=pass_all | ||
| 488 | + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` | ||
| 489 | + ;; | ||
| 490 | + | ||
| 491 | netbsd* | knetbsd*-gnu) | ||
| 492 | if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then | ||
| 493 | lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' | ||
| 494 | --- gcc-4.0.2/boehm-gc/configure | ||
| 495 | +++ gcc-4.0.2/boehm-gc/configure | ||
| 496 | @@ -4320,6 +4320,11 @@ | ||
| 497 | lt_cv_deplibs_check_method=pass_all | ||
| 498 | ;; | ||
| 499 | |||
| 500 | +linux-uclibc*) | ||
| 501 | + lt_cv_deplibs_check_method=pass_all | ||
| 502 | + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` | ||
| 503 | + ;; | ||
| 504 | + | ||
| 505 | netbsd* | knetbsd*-gnu) | ||
| 506 | if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then | ||
| 507 | lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' | ||
| 508 | --- gcc-4.0.2/configure | ||
| 509 | +++ gcc-4.0.2/configure | ||
| 510 | @@ -1141,7 +1141,7 @@ | ||
| 511 | ;; | ||
| 512 | "") | ||
| 513 | case "${target}" in | ||
| 514 | - *-*-linux*-gnu | *-*-gnu* | *-*-k*bsd*-gnu) | ||
| 515 | + *-*-linux*-gnu | *-*-gnu* | *-*-k*bsd*-gnu | *-*-linux-uclibc*) | ||
| 516 | # Enable libmudflap by default in GNU and friends. | ||
| 517 | ;; | ||
| 518 | *-*-freebsd*) | ||
| 519 | --- gcc-4.0.2/configure.in | ||
| 520 | +++ gcc-4.0.2/configure.in | ||
| 521 | @@ -350,7 +350,7 @@ | ||
| 522 | ;; | ||
| 523 | "") | ||
| 524 | case "${target}" in | ||
| 525 | - *-*-linux*-gnu | *-*-gnu* | *-*-k*bsd*-gnu) | ||
| 526 | + *-*-linux*-gnu | *-*-gnu* | *-*-k*bsd*-gnu | *-*-linux-uclibc*) | ||
| 527 | # Enable libmudflap by default in GNU and friends. | ||
| 528 | ;; | ||
| 529 | *-*-freebsd*) | ||
| 530 | --- gcc-4.0.2/contrib/regression/objs-gcc.sh | ||
| 531 | +++ gcc-4.0.2/contrib/regression/objs-gcc.sh | ||
| 532 | @@ -105,6 +105,10 @@ | ||
| 533 | then | ||
| 534 | make all-gdb all-dejagnu all-ld || exit 1 | ||
| 535 | make install-gdb install-dejagnu install-ld || exit 1 | ||
| 536 | +elif [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-uclibc ] | ||
| 537 | + then | ||
| 538 | + make all-gdb all-dejagnu all-ld || exit 1 | ||
| 539 | + make install-gdb install-dejagnu install-ld || exit 1 | ||
| 540 | elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then | ||
| 541 | make bootstrap || exit 1 | ||
| 542 | make install || exit 1 | ||
| 543 | --- gcc-4.0.2/zlib/configure | ||
| 544 | +++ gcc-4.0.2/zlib/configure | ||
| 545 | @@ -3426,6 +3426,11 @@ | ||
| 546 | lt_cv_deplibs_check_method=pass_all | ||
| 547 | ;; | ||
| 548 | |||
| 549 | +linux-uclibc*) | ||
| 550 | + lt_cv_deplibs_check_method=pass_all | ||
| 551 | + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` | ||
| 552 | + ;; | ||
| 553 | + | ||
| 554 | netbsd* | knetbsd*-gnu) | ||
| 555 | if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then | ||
| 556 | lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' | ||
diff --git a/meta/packages/gcc/gcc-4.0.2/200-uclibc-locale.patch b/meta/packages/gcc/gcc-4.0.2/200-uclibc-locale.patch deleted file mode 100644 index 8be03a5446..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/200-uclibc-locale.patch +++ /dev/null | |||
| @@ -1,3240 +0,0 @@ | |||
| 1 | From: | ||
| 2 | http://buildroot.uclibc.org/cgi-bin/viewcvs.cgi/*checkout*/trunk/buildroot/toolchain/gcc/4.0.2/200-uclibc-locale.patch?rev=11715 | ||
| 3 | |||
| 4 | diff -urN gcc-4.0.0-100/libstdc++-v3/acinclude.m4 gcc-4.0.0/libstdc++-v3/acinclude.m4 | ||
| 5 | --- gcc-4.0.0-100/libstdc++-v3/acinclude.m4 2005-04-30 13:06:53.000000000 -0500 | ||
| 6 | +++ gcc-4.0.0/libstdc++-v3/acinclude.m4 2005-04-28 20:19:01.000000000 -0500 | ||
| 7 | @@ -1104,7 +1104,7 @@ | ||
| 8 | AC_MSG_CHECKING([for C locale to use]) | ||
| 9 | GLIBCXX_ENABLE(clocale,auto,[@<:@=MODEL@:>@], | ||
| 10 | [use MODEL for target locale package], | ||
| 11 | - [permit generic|gnu|ieee_1003.1-2001|yes|no|auto]) | ||
| 12 | + [permit generic|gnu|ieee_1003.1-2001|uclibc|yes|no|auto]) | ||
| 13 | |||
| 14 | # If they didn't use this option switch, or if they specified --enable | ||
| 15 | # with no specific model, we'll have to look for one. If they | ||
| 16 | @@ -1120,6 +1120,9 @@ | ||
| 17 | # Default to "generic". | ||
| 18 | if test $enable_clocale_flag = auto; then | ||
| 19 | case ${target_os} in | ||
| 20 | + *-uclibc*) | ||
| 21 | + enable_clocale_flag=uclibc | ||
| 22 | + ;; | ||
| 23 | linux* | gnu* | kfreebsd*-gnu | knetbsd*-gnu) | ||
| 24 | AC_EGREP_CPP([_GLIBCXX_ok], [ | ||
| 25 | #include <features.h> | ||
| 26 | @@ -1263,6 +1266,40 @@ | ||
| 27 | CTIME_CC=config/locale/generic/time_members.cc | ||
| 28 | CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h | ||
| 29 | ;; | ||
| 30 | + uclibc) | ||
| 31 | + AC_MSG_RESULT(uclibc) | ||
| 32 | + | ||
| 33 | + # Declare intention to use gettext, and add support for specific | ||
| 34 | + # languages. | ||
| 35 | + # For some reason, ALL_LINGUAS has to be before AM-GNU-GETTEXT | ||
| 36 | + ALL_LINGUAS="de fr" | ||
| 37 | + | ||
| 38 | + # Don't call AM-GNU-GETTEXT here. Instead, assume glibc. | ||
| 39 | + AC_CHECK_PROG(check_msgfmt, msgfmt, yes, no) | ||
| 40 | + if test x"$check_msgfmt" = x"yes" && test x"$enable_nls" = x"yes"; then | ||
| 41 | + USE_NLS=yes | ||
| 42 | + fi | ||
| 43 | + # Export the build objects. | ||
| 44 | + for ling in $ALL_LINGUAS; do \ | ||
| 45 | + glibcxx_MOFILES="$glibcxx_MOFILES $ling.mo"; \ | ||
| 46 | + glibcxx_POFILES="$glibcxx_POFILES $ling.po"; \ | ||
| 47 | + done | ||
| 48 | + AC_SUBST(glibcxx_MOFILES) | ||
| 49 | + AC_SUBST(glibcxx_POFILES) | ||
| 50 | + | ||
| 51 | + CLOCALE_H=config/locale/uclibc/c_locale.h | ||
| 52 | + CLOCALE_CC=config/locale/uclibc/c_locale.cc | ||
| 53 | + CCODECVT_CC=config/locale/uclibc/codecvt_members.cc | ||
| 54 | + CCOLLATE_CC=config/locale/uclibc/collate_members.cc | ||
| 55 | + CCTYPE_CC=config/locale/uclibc/ctype_members.cc | ||
| 56 | + CMESSAGES_H=config/locale/uclibc/messages_members.h | ||
| 57 | + CMESSAGES_CC=config/locale/uclibc/messages_members.cc | ||
| 58 | + CMONEY_CC=config/locale/uclibc/monetary_members.cc | ||
| 59 | + CNUMERIC_CC=config/locale/uclibc/numeric_members.cc | ||
| 60 | + CTIME_H=config/locale/uclibc/time_members.h | ||
| 61 | + CTIME_CC=config/locale/uclibc/time_members.cc | ||
| 62 | + CLOCALE_INTERNAL_H=config/locale/uclibc/c++locale_internal.h | ||
| 63 | + ;; | ||
| 64 | esac | ||
| 65 | |||
| 66 | # This is where the testsuite looks for locale catalogs, using the | ||
| 67 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/c++locale_internal.h gcc-4.0.0/libstdc++-v3/config/locale/uclibc/c++locale_internal.h | ||
| 68 | --- gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/c++locale_internal.h 1969-12-31 18:00:00.000000000 -0600 | ||
| 69 | +++ gcc-4.0.0/libstdc++-v3/config/locale/uclibc/c++locale_internal.h 2005-04-28 01:13:15.000000000 -0500 | ||
| 70 | @@ -0,0 +1,59 @@ | ||
| 71 | +// Prototypes for GLIBC thread locale __-prefixed functions -*- C++ -*- | ||
| 72 | + | ||
| 73 | +// Copyright (C) 2002, 2004 Free Software Foundation, Inc. | ||
| 74 | +// | ||
| 75 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 76 | +// software; you can redistribute it and/or modify it under the | ||
| 77 | +// terms of the GNU General Public License as published by the | ||
| 78 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 79 | +// any later version. | ||
| 80 | + | ||
| 81 | +// This library is distributed in the hope that it will be useful, | ||
| 82 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 83 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 84 | +// GNU General Public License for more details. | ||
| 85 | + | ||
| 86 | +// You should have received a copy of the GNU General Public License along | ||
| 87 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 88 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 89 | +// USA. | ||
| 90 | + | ||
| 91 | +// As a special exception, you may use this file as part of a free software | ||
| 92 | +// library without restriction. Specifically, if other files instantiate | ||
| 93 | +// templates or use macros or inline functions from this file, or you compile | ||
| 94 | +// this file and link it with other files to produce an executable, this | ||
| 95 | +// file does not by itself cause the resulting executable to be covered by | ||
| 96 | +// the GNU General Public License. This exception does not however | ||
| 97 | +// invalidate any other reasons why the executable file might be covered by | ||
| 98 | +// the GNU General Public License. | ||
| 99 | + | ||
| 100 | +// Written by Jakub Jelinek <jakub@redhat.com> | ||
| 101 | + | ||
| 102 | +#include <clocale> | ||
| 103 | + | ||
| 104 | +#ifdef __UCLIBC_MJN3_ONLY__ | ||
| 105 | +#warning clean this up | ||
| 106 | +#endif | ||
| 107 | + | ||
| 108 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 109 | + | ||
| 110 | +extern "C" __typeof(iswctype_l) __iswctype_l; | ||
| 111 | +extern "C" __typeof(nl_langinfo_l) __nl_langinfo_l; | ||
| 112 | +extern "C" __typeof(strcoll_l) __strcoll_l; | ||
| 113 | +extern "C" __typeof(strftime_l) __strftime_l; | ||
| 114 | +extern "C" __typeof(strtod_l) __strtod_l; | ||
| 115 | +extern "C" __typeof(strtof_l) __strtof_l; | ||
| 116 | +extern "C" __typeof(strtold_l) __strtold_l; | ||
| 117 | +extern "C" __typeof(strxfrm_l) __strxfrm_l; | ||
| 118 | +extern "C" __typeof(towlower_l) __towlower_l; | ||
| 119 | +extern "C" __typeof(towupper_l) __towupper_l; | ||
| 120 | +extern "C" __typeof(wcscoll_l) __wcscoll_l; | ||
| 121 | +extern "C" __typeof(wcsftime_l) __wcsftime_l; | ||
| 122 | +extern "C" __typeof(wcsxfrm_l) __wcsxfrm_l; | ||
| 123 | +extern "C" __typeof(wctype_l) __wctype_l; | ||
| 124 | +extern "C" __typeof(newlocale) __newlocale; | ||
| 125 | +extern "C" __typeof(freelocale) __freelocale; | ||
| 126 | +extern "C" __typeof(duplocale) __duplocale; | ||
| 127 | +extern "C" __typeof(uselocale) __uselocale; | ||
| 128 | + | ||
| 129 | +#endif // GLIBC 2.3 and later | ||
| 130 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/c_locale.cc gcc-4.0.0/libstdc++-v3/config/locale/uclibc/c_locale.cc | ||
| 131 | --- gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/c_locale.cc 1969-12-31 18:00:00.000000000 -0600 | ||
| 132 | +++ gcc-4.0.0/libstdc++-v3/config/locale/uclibc/c_locale.cc 2005-04-28 01:13:15.000000000 -0500 | ||
| 133 | @@ -0,0 +1,160 @@ | ||
| 134 | +// Wrapper for underlying C-language localization -*- C++ -*- | ||
| 135 | + | ||
| 136 | +// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. | ||
| 137 | +// | ||
| 138 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 139 | +// software; you can redistribute it and/or modify it under the | ||
| 140 | +// terms of the GNU General Public License as published by the | ||
| 141 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 142 | +// any later version. | ||
| 143 | + | ||
| 144 | +// This library is distributed in the hope that it will be useful, | ||
| 145 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 146 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 147 | +// GNU General Public License for more details. | ||
| 148 | + | ||
| 149 | +// You should have received a copy of the GNU General Public License along | ||
| 150 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 151 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 152 | +// USA. | ||
| 153 | + | ||
| 154 | +// As a special exception, you may use this file as part of a free software | ||
| 155 | +// library without restriction. Specifically, if other files instantiate | ||
| 156 | +// templates or use macros or inline functions from this file, or you compile | ||
| 157 | +// this file and link it with other files to produce an executable, this | ||
| 158 | +// file does not by itself cause the resulting executable to be covered by | ||
| 159 | +// the GNU General Public License. This exception does not however | ||
| 160 | +// invalidate any other reasons why the executable file might be covered by | ||
| 161 | +// the GNU General Public License. | ||
| 162 | + | ||
| 163 | +// | ||
| 164 | +// ISO C++ 14882: 22.8 Standard locale categories. | ||
| 165 | +// | ||
| 166 | + | ||
| 167 | +// Written by Benjamin Kosnik <bkoz@redhat.com> | ||
| 168 | + | ||
| 169 | +#include <cerrno> // For errno | ||
| 170 | +#include <locale> | ||
| 171 | +#include <stdexcept> | ||
| 172 | +#include <langinfo.h> | ||
| 173 | +#include <bits/c++locale_internal.h> | ||
| 174 | + | ||
| 175 | +#ifndef __UCLIBC_HAS_XLOCALE__ | ||
| 176 | +#define __strtol_l(S, E, B, L) strtol((S), (E), (B)) | ||
| 177 | +#define __strtoul_l(S, E, B, L) strtoul((S), (E), (B)) | ||
| 178 | +#define __strtoll_l(S, E, B, L) strtoll((S), (E), (B)) | ||
| 179 | +#define __strtoull_l(S, E, B, L) strtoull((S), (E), (B)) | ||
| 180 | +#define __strtof_l(S, E, L) strtof((S), (E)) | ||
| 181 | +#define __strtod_l(S, E, L) strtod((S), (E)) | ||
| 182 | +#define __strtold_l(S, E, L) strtold((S), (E)) | ||
| 183 | +#warning should dummy __newlocale check for C|POSIX ? | ||
| 184 | +#define __newlocale(a, b, c) NULL | ||
| 185 | +#define __freelocale(a) ((void)0) | ||
| 186 | +#define __duplocale(a) __c_locale() | ||
| 187 | +#endif | ||
| 188 | + | ||
| 189 | +namespace std | ||
| 190 | +{ | ||
| 191 | + template<> | ||
| 192 | + void | ||
| 193 | + __convert_to_v(const char* __s, float& __v, ios_base::iostate& __err, | ||
| 194 | + const __c_locale& __cloc) | ||
| 195 | + { | ||
| 196 | + if (!(__err & ios_base::failbit)) | ||
| 197 | + { | ||
| 198 | + char* __sanity; | ||
| 199 | + errno = 0; | ||
| 200 | + float __f = __strtof_l(__s, &__sanity, __cloc); | ||
| 201 | + if (__sanity != __s && errno != ERANGE) | ||
| 202 | + __v = __f; | ||
| 203 | + else | ||
| 204 | + __err |= ios_base::failbit; | ||
| 205 | + } | ||
| 206 | + } | ||
| 207 | + | ||
| 208 | + template<> | ||
| 209 | + void | ||
| 210 | + __convert_to_v(const char* __s, double& __v, ios_base::iostate& __err, | ||
| 211 | + const __c_locale& __cloc) | ||
| 212 | + { | ||
| 213 | + if (!(__err & ios_base::failbit)) | ||
| 214 | + { | ||
| 215 | + char* __sanity; | ||
| 216 | + errno = 0; | ||
| 217 | + double __d = __strtod_l(__s, &__sanity, __cloc); | ||
| 218 | + if (__sanity != __s && errno != ERANGE) | ||
| 219 | + __v = __d; | ||
| 220 | + else | ||
| 221 | + __err |= ios_base::failbit; | ||
| 222 | + } | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + template<> | ||
| 226 | + void | ||
| 227 | + __convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err, | ||
| 228 | + const __c_locale& __cloc) | ||
| 229 | + { | ||
| 230 | + if (!(__err & ios_base::failbit)) | ||
| 231 | + { | ||
| 232 | + char* __sanity; | ||
| 233 | + errno = 0; | ||
| 234 | + long double __ld = __strtold_l(__s, &__sanity, __cloc); | ||
| 235 | + if (__sanity != __s && errno != ERANGE) | ||
| 236 | + __v = __ld; | ||
| 237 | + else | ||
| 238 | + __err |= ios_base::failbit; | ||
| 239 | + } | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + void | ||
| 243 | + locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s, | ||
| 244 | + __c_locale __old) | ||
| 245 | + { | ||
| 246 | + __cloc = __newlocale(1 << LC_ALL, __s, __old); | ||
| 247 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 248 | + if (!__cloc) | ||
| 249 | + { | ||
| 250 | + // This named locale is not supported by the underlying OS. | ||
| 251 | + __throw_runtime_error(__N("locale::facet::_S_create_c_locale " | ||
| 252 | + "name not valid")); | ||
| 253 | + } | ||
| 254 | +#endif | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + void | ||
| 258 | + locale::facet::_S_destroy_c_locale(__c_locale& __cloc) | ||
| 259 | + { | ||
| 260 | + if (_S_get_c_locale() != __cloc) | ||
| 261 | + __freelocale(__cloc); | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + __c_locale | ||
| 265 | + locale::facet::_S_clone_c_locale(__c_locale& __cloc) | ||
| 266 | + { return __duplocale(__cloc); } | ||
| 267 | +} // namespace std | ||
| 268 | + | ||
| 269 | +namespace __gnu_cxx | ||
| 270 | +{ | ||
| 271 | + const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] = | ||
| 272 | + { | ||
| 273 | + "LC_CTYPE", | ||
| 274 | + "LC_NUMERIC", | ||
| 275 | + "LC_TIME", | ||
| 276 | + "LC_COLLATE", | ||
| 277 | + "LC_MONETARY", | ||
| 278 | + "LC_MESSAGES", | ||
| 279 | +#if _GLIBCXX_NUM_CATEGORIES != 0 | ||
| 280 | + "LC_PAPER", | ||
| 281 | + "LC_NAME", | ||
| 282 | + "LC_ADDRESS", | ||
| 283 | + "LC_TELEPHONE", | ||
| 284 | + "LC_MEASUREMENT", | ||
| 285 | + "LC_IDENTIFICATION" | ||
| 286 | +#endif | ||
| 287 | + }; | ||
| 288 | +} | ||
| 289 | + | ||
| 290 | +namespace std | ||
| 291 | +{ | ||
| 292 | + const char* const* const locale::_S_categories = __gnu_cxx::category_names; | ||
| 293 | +} // namespace std | ||
| 294 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/c_locale.h gcc-4.0.0/libstdc++-v3/config/locale/uclibc/c_locale.h | ||
| 295 | --- gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/c_locale.h 1969-12-31 18:00:00.000000000 -0600 | ||
| 296 | +++ gcc-4.0.0/libstdc++-v3/config/locale/uclibc/c_locale.h 2005-04-28 01:13:15.000000000 -0500 | ||
| 297 | @@ -0,0 +1,115 @@ | ||
| 298 | +// Wrapper for underlying C-language localization -*- C++ -*- | ||
| 299 | + | ||
| 300 | +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. | ||
| 301 | +// | ||
| 302 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 303 | +// software; you can redistribute it and/or modify it under the | ||
| 304 | +// terms of the GNU General Public License as published by the | ||
| 305 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 306 | +// any later version. | ||
| 307 | + | ||
| 308 | +// This library is distributed in the hope that it will be useful, | ||
| 309 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 310 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 311 | +// GNU General Public License for more details. | ||
| 312 | + | ||
| 313 | +// You should have received a copy of the GNU General Public License along | ||
| 314 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 315 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 316 | +// USA. | ||
| 317 | + | ||
| 318 | +// As a special exception, you may use this file as part of a free software | ||
| 319 | +// library without restriction. Specifically, if other files instantiate | ||
| 320 | +// templates or use macros or inline functions from this file, or you compile | ||
| 321 | +// this file and link it with other files to produce an executable, this | ||
| 322 | +// file does not by itself cause the resulting executable to be covered by | ||
| 323 | +// the GNU General Public License. This exception does not however | ||
| 324 | +// invalidate any other reasons why the executable file might be covered by | ||
| 325 | +// the GNU General Public License. | ||
| 326 | + | ||
| 327 | +// | ||
| 328 | +// ISO C++ 14882: 22.8 Standard locale categories. | ||
| 329 | +// | ||
| 330 | + | ||
| 331 | +// Written by Benjamin Kosnik <bkoz@redhat.com> | ||
| 332 | + | ||
| 333 | +#ifndef _C_LOCALE_H | ||
| 334 | +#define _C_LOCALE_H 1 | ||
| 335 | + | ||
| 336 | +#pragma GCC system_header | ||
| 337 | + | ||
| 338 | +#include <cstring> // get std::strlen | ||
| 339 | +#include <cstdio> // get std::snprintf or std::sprintf | ||
| 340 | +#include <clocale> | ||
| 341 | +#include <langinfo.h> // For codecvt | ||
| 342 | +#ifdef __UCLIBC_MJN3_ONLY__ | ||
| 343 | +#warning fix this | ||
| 344 | +#endif | ||
| 345 | +#ifdef __UCLIBC_HAS_LOCALE__ | ||
| 346 | +#include <iconv.h> // For codecvt using iconv, iconv_t | ||
| 347 | +#endif | ||
| 348 | +#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__ | ||
| 349 | +#include <libintl.h> // For messages | ||
| 350 | +#endif | ||
| 351 | + | ||
| 352 | +#ifdef __UCLIBC_MJN3_ONLY__ | ||
| 353 | +#warning what is _GLIBCXX_C_LOCALE_GNU for | ||
| 354 | +#endif | ||
| 355 | +#define _GLIBCXX_C_LOCALE_GNU 1 | ||
| 356 | + | ||
| 357 | +#ifdef __UCLIBC_MJN3_ONLY__ | ||
| 358 | +#warning fix categories | ||
| 359 | +#endif | ||
| 360 | +// #define _GLIBCXX_NUM_CATEGORIES 6 | ||
| 361 | +#define _GLIBCXX_NUM_CATEGORIES 0 | ||
| 362 | + | ||
| 363 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 364 | +namespace __gnu_cxx | ||
| 365 | +{ | ||
| 366 | + extern "C" __typeof(uselocale) __uselocale; | ||
| 367 | +} | ||
| 368 | +#endif | ||
| 369 | + | ||
| 370 | +namespace std | ||
| 371 | +{ | ||
| 372 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 373 | + typedef __locale_t __c_locale; | ||
| 374 | +#else | ||
| 375 | + typedef int* __c_locale; | ||
| 376 | +#endif | ||
| 377 | + | ||
| 378 | + // Convert numeric value of type _Tv to string and return length of | ||
| 379 | + // string. If snprintf is available use it, otherwise fall back to | ||
| 380 | + // the unsafe sprintf which, in general, can be dangerous and should | ||
| 381 | + // be avoided. | ||
| 382 | + template<typename _Tv> | ||
| 383 | + int | ||
| 384 | + __convert_from_v(char* __out, const int __size, const char* __fmt, | ||
| 385 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 386 | + _Tv __v, const __c_locale& __cloc, int __prec) | ||
| 387 | + { | ||
| 388 | + __c_locale __old = __gnu_cxx::__uselocale(__cloc); | ||
| 389 | +#else | ||
| 390 | + _Tv __v, const __c_locale&, int __prec) | ||
| 391 | + { | ||
| 392 | +# ifdef __UCLIBC_HAS_LOCALE__ | ||
| 393 | + char* __old = std::setlocale(LC_ALL, NULL); | ||
| 394 | + char* __sav = new char[std::strlen(__old) + 1]; | ||
| 395 | + std::strcpy(__sav, __old); | ||
| 396 | + std::setlocale(LC_ALL, "C"); | ||
| 397 | +# endif | ||
| 398 | +#endif | ||
| 399 | + | ||
| 400 | + const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v); | ||
| 401 | + | ||
| 402 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 403 | + __gnu_cxx::__uselocale(__old); | ||
| 404 | +#elif defined __UCLIBC_HAS_LOCALE__ | ||
| 405 | + std::setlocale(LC_ALL, __sav); | ||
| 406 | + delete [] __sav; | ||
| 407 | +#endif | ||
| 408 | + return __ret; | ||
| 409 | + } | ||
| 410 | +} | ||
| 411 | + | ||
| 412 | +#endif | ||
| 413 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/codecvt_members.cc gcc-4.0.0/libstdc++-v3/config/locale/uclibc/codecvt_members.cc | ||
| 414 | --- gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/codecvt_members.cc 1969-12-31 18:00:00.000000000 -0600 | ||
| 415 | +++ gcc-4.0.0/libstdc++-v3/config/locale/uclibc/codecvt_members.cc 2005-04-28 01:13:15.000000000 -0500 | ||
| 416 | @@ -0,0 +1,306 @@ | ||
| 417 | +// std::codecvt implementation details, GNU version -*- C++ -*- | ||
| 418 | + | ||
| 419 | +// Copyright (C) 2002, 2003 Free Software Foundation, Inc. | ||
| 420 | +// | ||
| 421 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 422 | +// software; you can redistribute it and/or modify it under the | ||
| 423 | +// terms of the GNU General Public License as published by the | ||
| 424 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 425 | +// any later version. | ||
| 426 | + | ||
| 427 | +// This library is distributed in the hope that it will be useful, | ||
| 428 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 429 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 430 | +// GNU General Public License for more details. | ||
| 431 | + | ||
| 432 | +// You should have received a copy of the GNU General Public License along | ||
| 433 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 434 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 435 | +// USA. | ||
| 436 | + | ||
| 437 | +// As a special exception, you may use this file as part of a free software | ||
| 438 | +// library without restriction. Specifically, if other files instantiate | ||
| 439 | +// templates or use macros or inline functions from this file, or you compile | ||
| 440 | +// this file and link it with other files to produce an executable, this | ||
| 441 | +// file does not by itself cause the resulting executable to be covered by | ||
| 442 | +// the GNU General Public License. This exception does not however | ||
| 443 | +// invalidate any other reasons why the executable file might be covered by | ||
| 444 | +// the GNU General Public License. | ||
| 445 | + | ||
| 446 | +// | ||
| 447 | +// ISO C++ 14882: 22.2.1.5 - Template class codecvt | ||
| 448 | +// | ||
| 449 | + | ||
| 450 | +// Written by Benjamin Kosnik <bkoz@redhat.com> | ||
| 451 | + | ||
| 452 | +#include <locale> | ||
| 453 | +#include <bits/c++locale_internal.h> | ||
| 454 | + | ||
| 455 | +namespace std | ||
| 456 | +{ | ||
| 457 | + // Specializations. | ||
| 458 | +#ifdef _GLIBCXX_USE_WCHAR_T | ||
| 459 | + codecvt_base::result | ||
| 460 | + codecvt<wchar_t, char, mbstate_t>:: | ||
| 461 | + do_out(state_type& __state, const intern_type* __from, | ||
| 462 | + const intern_type* __from_end, const intern_type*& __from_next, | ||
| 463 | + extern_type* __to, extern_type* __to_end, | ||
| 464 | + extern_type*& __to_next) const | ||
| 465 | + { | ||
| 466 | + result __ret = ok; | ||
| 467 | + state_type __tmp_state(__state); | ||
| 468 | + | ||
| 469 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 470 | + __c_locale __old = __uselocale(_M_c_locale_codecvt); | ||
| 471 | +#endif | ||
| 472 | + | ||
| 473 | + // wcsnrtombs is *very* fast but stops if encounters NUL characters: | ||
| 474 | + // in case we fall back to wcrtomb and then continue, in a loop. | ||
| 475 | + // NB: wcsnrtombs is a GNU extension | ||
| 476 | + for (__from_next = __from, __to_next = __to; | ||
| 477 | + __from_next < __from_end && __to_next < __to_end | ||
| 478 | + && __ret == ok;) | ||
| 479 | + { | ||
| 480 | + const intern_type* __from_chunk_end = wmemchr(__from_next, L'\0', | ||
| 481 | + __from_end - __from_next); | ||
| 482 | + if (!__from_chunk_end) | ||
| 483 | + __from_chunk_end = __from_end; | ||
| 484 | + | ||
| 485 | + __from = __from_next; | ||
| 486 | + const size_t __conv = wcsnrtombs(__to_next, &__from_next, | ||
| 487 | + __from_chunk_end - __from_next, | ||
| 488 | + __to_end - __to_next, &__state); | ||
| 489 | + if (__conv == static_cast<size_t>(-1)) | ||
| 490 | + { | ||
| 491 | + // In case of error, in order to stop at the exact place we | ||
| 492 | + // have to start again from the beginning with a series of | ||
| 493 | + // wcrtomb. | ||
| 494 | + for (; __from < __from_next; ++__from) | ||
| 495 | + __to_next += wcrtomb(__to_next, *__from, &__tmp_state); | ||
| 496 | + __state = __tmp_state; | ||
| 497 | + __ret = error; | ||
| 498 | + } | ||
| 499 | + else if (__from_next && __from_next < __from_chunk_end) | ||
| 500 | + { | ||
| 501 | + __to_next += __conv; | ||
| 502 | + __ret = partial; | ||
| 503 | + } | ||
| 504 | + else | ||
| 505 | + { | ||
| 506 | + __from_next = __from_chunk_end; | ||
| 507 | + __to_next += __conv; | ||
| 508 | + } | ||
| 509 | + | ||
| 510 | + if (__from_next < __from_end && __ret == ok) | ||
| 511 | + { | ||
| 512 | + extern_type __buf[MB_LEN_MAX]; | ||
| 513 | + __tmp_state = __state; | ||
| 514 | + const size_t __conv = wcrtomb(__buf, *__from_next, &__tmp_state); | ||
| 515 | + if (__conv > static_cast<size_t>(__to_end - __to_next)) | ||
| 516 | + __ret = partial; | ||
| 517 | + else | ||
| 518 | + { | ||
| 519 | + memcpy(__to_next, __buf, __conv); | ||
| 520 | + __state = __tmp_state; | ||
| 521 | + __to_next += __conv; | ||
| 522 | + ++__from_next; | ||
| 523 | + } | ||
| 524 | + } | ||
| 525 | + } | ||
| 526 | + | ||
| 527 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 528 | + __uselocale(__old); | ||
| 529 | +#endif | ||
| 530 | + | ||
| 531 | + return __ret; | ||
| 532 | + } | ||
| 533 | + | ||
| 534 | + codecvt_base::result | ||
| 535 | + codecvt<wchar_t, char, mbstate_t>:: | ||
| 536 | + do_in(state_type& __state, const extern_type* __from, | ||
| 537 | + const extern_type* __from_end, const extern_type*& __from_next, | ||
| 538 | + intern_type* __to, intern_type* __to_end, | ||
| 539 | + intern_type*& __to_next) const | ||
| 540 | + { | ||
| 541 | + result __ret = ok; | ||
| 542 | + state_type __tmp_state(__state); | ||
| 543 | + | ||
| 544 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 545 | + __c_locale __old = __uselocale(_M_c_locale_codecvt); | ||
| 546 | +#endif | ||
| 547 | + | ||
| 548 | + // mbsnrtowcs is *very* fast but stops if encounters NUL characters: | ||
| 549 | + // in case we store a L'\0' and then continue, in a loop. | ||
| 550 | + // NB: mbsnrtowcs is a GNU extension | ||
| 551 | + for (__from_next = __from, __to_next = __to; | ||
| 552 | + __from_next < __from_end && __to_next < __to_end | ||
| 553 | + && __ret == ok;) | ||
| 554 | + { | ||
| 555 | + const extern_type* __from_chunk_end; | ||
| 556 | + __from_chunk_end = static_cast<const extern_type*>(memchr(__from_next, '\0', | ||
| 557 | + __from_end | ||
| 558 | + - __from_next)); | ||
| 559 | + if (!__from_chunk_end) | ||
| 560 | + __from_chunk_end = __from_end; | ||
| 561 | + | ||
| 562 | + __from = __from_next; | ||
| 563 | + size_t __conv = mbsnrtowcs(__to_next, &__from_next, | ||
| 564 | + __from_chunk_end - __from_next, | ||
| 565 | + __to_end - __to_next, &__state); | ||
| 566 | + if (__conv == static_cast<size_t>(-1)) | ||
| 567 | + { | ||
| 568 | + // In case of error, in order to stop at the exact place we | ||
| 569 | + // have to start again from the beginning with a series of | ||
| 570 | + // mbrtowc. | ||
| 571 | + for (;; ++__to_next, __from += __conv) | ||
| 572 | + { | ||
| 573 | + __conv = mbrtowc(__to_next, __from, __from_end - __from, | ||
| 574 | + &__tmp_state); | ||
| 575 | + if (__conv == static_cast<size_t>(-1) | ||
| 576 | + || __conv == static_cast<size_t>(-2)) | ||
| 577 | + break; | ||
| 578 | + } | ||
| 579 | + __from_next = __from; | ||
| 580 | + __state = __tmp_state; | ||
| 581 | + __ret = error; | ||
| 582 | + } | ||
| 583 | + else if (__from_next && __from_next < __from_chunk_end) | ||
| 584 | + { | ||
| 585 | + // It is unclear what to return in this case (see DR 382). | ||
| 586 | + __to_next += __conv; | ||
| 587 | + __ret = partial; | ||
| 588 | + } | ||
| 589 | + else | ||
| 590 | + { | ||
| 591 | + __from_next = __from_chunk_end; | ||
| 592 | + __to_next += __conv; | ||
| 593 | + } | ||
| 594 | + | ||
| 595 | + if (__from_next < __from_end && __ret == ok) | ||
| 596 | + { | ||
| 597 | + if (__to_next < __to_end) | ||
| 598 | + { | ||
| 599 | + // XXX Probably wrong for stateful encodings | ||
| 600 | + __tmp_state = __state; | ||
| 601 | + ++__from_next; | ||
| 602 | + *__to_next++ = L'\0'; | ||
| 603 | + } | ||
| 604 | + else | ||
| 605 | + __ret = partial; | ||
| 606 | + } | ||
| 607 | + } | ||
| 608 | + | ||
| 609 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 610 | + __uselocale(__old); | ||
| 611 | +#endif | ||
| 612 | + | ||
| 613 | + return __ret; | ||
| 614 | + } | ||
| 615 | + | ||
| 616 | + int | ||
| 617 | + codecvt<wchar_t, char, mbstate_t>:: | ||
| 618 | + do_encoding() const throw() | ||
| 619 | + { | ||
| 620 | + // XXX This implementation assumes that the encoding is | ||
| 621 | + // stateless and is either single-byte or variable-width. | ||
| 622 | + int __ret = 0; | ||
| 623 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 624 | + __c_locale __old = __uselocale(_M_c_locale_codecvt); | ||
| 625 | +#endif | ||
| 626 | + if (MB_CUR_MAX == 1) | ||
| 627 | + __ret = 1; | ||
| 628 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 629 | + __uselocale(__old); | ||
| 630 | +#endif | ||
| 631 | + return __ret; | ||
| 632 | + } | ||
| 633 | + | ||
| 634 | + int | ||
| 635 | + codecvt<wchar_t, char, mbstate_t>:: | ||
| 636 | + do_max_length() const throw() | ||
| 637 | + { | ||
| 638 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 639 | + __c_locale __old = __uselocale(_M_c_locale_codecvt); | ||
| 640 | +#endif | ||
| 641 | + // XXX Probably wrong for stateful encodings. | ||
| 642 | + int __ret = MB_CUR_MAX; | ||
| 643 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 644 | + __uselocale(__old); | ||
| 645 | +#endif | ||
| 646 | + return __ret; | ||
| 647 | + } | ||
| 648 | + | ||
| 649 | + int | ||
| 650 | + codecvt<wchar_t, char, mbstate_t>:: | ||
| 651 | + do_length(state_type& __state, const extern_type* __from, | ||
| 652 | + const extern_type* __end, size_t __max) const | ||
| 653 | + { | ||
| 654 | + int __ret = 0; | ||
| 655 | + state_type __tmp_state(__state); | ||
| 656 | + | ||
| 657 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 658 | + __c_locale __old = __uselocale(_M_c_locale_codecvt); | ||
| 659 | +#endif | ||
| 660 | + | ||
| 661 | + // mbsnrtowcs is *very* fast but stops if encounters NUL characters: | ||
| 662 | + // in case we advance past it and then continue, in a loop. | ||
| 663 | + // NB: mbsnrtowcs is a GNU extension | ||
| 664 | + | ||
| 665 | + // A dummy internal buffer is needed in order for mbsnrtocws to consider | ||
| 666 | + // its fourth parameter (it wouldn't with NULL as first parameter). | ||
| 667 | + wchar_t* __to = static_cast<wchar_t*>(__builtin_alloca(sizeof(wchar_t) | ||
| 668 | + * __max)); | ||
| 669 | + while (__from < __end && __max) | ||
| 670 | + { | ||
| 671 | + const extern_type* __from_chunk_end; | ||
| 672 | + __from_chunk_end = static_cast<const extern_type*>(memchr(__from, '\0', | ||
| 673 | + __end | ||
| 674 | + - __from)); | ||
| 675 | + if (!__from_chunk_end) | ||
| 676 | + __from_chunk_end = __end; | ||
| 677 | + | ||
| 678 | + const extern_type* __tmp_from = __from; | ||
| 679 | + size_t __conv = mbsnrtowcs(__to, &__from, | ||
| 680 | + __from_chunk_end - __from, | ||
| 681 | + __max, &__state); | ||
| 682 | + if (__conv == static_cast<size_t>(-1)) | ||
| 683 | + { | ||
| 684 | + // In case of error, in order to stop at the exact place we | ||
| 685 | + // have to start again from the beginning with a series of | ||
| 686 | + // mbrtowc. | ||
| 687 | + for (__from = __tmp_from;; __from += __conv) | ||
| 688 | + { | ||
| 689 | + __conv = mbrtowc(NULL, __from, __end - __from, | ||
| 690 | + &__tmp_state); | ||
| 691 | + if (__conv == static_cast<size_t>(-1) | ||
| 692 | + || __conv == static_cast<size_t>(-2)) | ||
| 693 | + break; | ||
| 694 | + } | ||
| 695 | + __state = __tmp_state; | ||
| 696 | + __ret += __from - __tmp_from; | ||
| 697 | + break; | ||
| 698 | + } | ||
| 699 | + if (!__from) | ||
| 700 | + __from = __from_chunk_end; | ||
| 701 | + | ||
| 702 | + __ret += __from - __tmp_from; | ||
| 703 | + __max -= __conv; | ||
| 704 | + | ||
| 705 | + if (__from < __end && __max) | ||
| 706 | + { | ||
| 707 | + // XXX Probably wrong for stateful encodings | ||
| 708 | + __tmp_state = __state; | ||
| 709 | + ++__from; | ||
| 710 | + ++__ret; | ||
| 711 | + --__max; | ||
| 712 | + } | ||
| 713 | + } | ||
| 714 | + | ||
| 715 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 716 | + __uselocale(__old); | ||
| 717 | +#endif | ||
| 718 | + | ||
| 719 | + return __ret; | ||
| 720 | + } | ||
| 721 | +#endif | ||
| 722 | +} | ||
| 723 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/collate_members.cc gcc-4.0.0/libstdc++-v3/config/locale/uclibc/collate_members.cc | ||
| 724 | --- gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/collate_members.cc 1969-12-31 18:00:00.000000000 -0600 | ||
| 725 | +++ gcc-4.0.0/libstdc++-v3/config/locale/uclibc/collate_members.cc 2005-04-28 01:13:15.000000000 -0500 | ||
| 726 | @@ -0,0 +1,80 @@ | ||
| 727 | +// std::collate implementation details, GNU version -*- C++ -*- | ||
| 728 | + | ||
| 729 | +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. | ||
| 730 | +// | ||
| 731 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 732 | +// software; you can redistribute it and/or modify it under the | ||
| 733 | +// terms of the GNU General Public License as published by the | ||
| 734 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 735 | +// any later version. | ||
| 736 | + | ||
| 737 | +// This library is distributed in the hope that it will be useful, | ||
| 738 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 739 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 740 | +// GNU General Public License for more details. | ||
| 741 | + | ||
| 742 | +// You should have received a copy of the GNU General Public License along | ||
| 743 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 744 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 745 | +// USA. | ||
| 746 | + | ||
| 747 | +// As a special exception, you may use this file as part of a free software | ||
| 748 | +// library without restriction. Specifically, if other files instantiate | ||
| 749 | +// templates or use macros or inline functions from this file, or you compile | ||
| 750 | +// this file and link it with other files to produce an executable, this | ||
| 751 | +// file does not by itself cause the resulting executable to be covered by | ||
| 752 | +// the GNU General Public License. This exception does not however | ||
| 753 | +// invalidate any other reasons why the executable file might be covered by | ||
| 754 | +// the GNU General Public License. | ||
| 755 | + | ||
| 756 | +// | ||
| 757 | +// ISO C++ 14882: 22.2.4.1.2 collate virtual functions | ||
| 758 | +// | ||
| 759 | + | ||
| 760 | +// Written by Benjamin Kosnik <bkoz@redhat.com> | ||
| 761 | + | ||
| 762 | +#include <locale> | ||
| 763 | +#include <bits/c++locale_internal.h> | ||
| 764 | + | ||
| 765 | +#ifndef __UCLIBC_HAS_XLOCALE__ | ||
| 766 | +#define __strcoll_l(S1, S2, L) strcoll((S1), (S2)) | ||
| 767 | +#define __strxfrm_l(S1, S2, N, L) strxfrm((S1), (S2), (N)) | ||
| 768 | +#define __wcscoll_l(S1, S2, L) wcscoll((S1), (S2)) | ||
| 769 | +#define __wcsxfrm_l(S1, S2, N, L) wcsxfrm((S1), (S2), (N)) | ||
| 770 | +#endif | ||
| 771 | + | ||
| 772 | +namespace std | ||
| 773 | +{ | ||
| 774 | + // These are basically extensions to char_traits, and perhaps should | ||
| 775 | + // be put there instead of here. | ||
| 776 | + template<> | ||
| 777 | + int | ||
| 778 | + collate<char>::_M_compare(const char* __one, const char* __two) const | ||
| 779 | + { | ||
| 780 | + int __cmp = __strcoll_l(__one, __two, _M_c_locale_collate); | ||
| 781 | + return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0); | ||
| 782 | + } | ||
| 783 | + | ||
| 784 | + template<> | ||
| 785 | + size_t | ||
| 786 | + collate<char>::_M_transform(char* __to, const char* __from, | ||
| 787 | + size_t __n) const | ||
| 788 | + { return __strxfrm_l(__to, __from, __n, _M_c_locale_collate); } | ||
| 789 | + | ||
| 790 | +#ifdef _GLIBCXX_USE_WCHAR_T | ||
| 791 | + template<> | ||
| 792 | + int | ||
| 793 | + collate<wchar_t>::_M_compare(const wchar_t* __one, | ||
| 794 | + const wchar_t* __two) const | ||
| 795 | + { | ||
| 796 | + int __cmp = __wcscoll_l(__one, __two, _M_c_locale_collate); | ||
| 797 | + return (__cmp >> (8 * sizeof (int) - 2)) | (__cmp != 0); | ||
| 798 | + } | ||
| 799 | + | ||
| 800 | + template<> | ||
| 801 | + size_t | ||
| 802 | + collate<wchar_t>::_M_transform(wchar_t* __to, const wchar_t* __from, | ||
| 803 | + size_t __n) const | ||
| 804 | + { return __wcsxfrm_l(__to, __from, __n, _M_c_locale_collate); } | ||
| 805 | +#endif | ||
| 806 | +} | ||
| 807 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/ctype_members.cc gcc-4.0.0/libstdc++-v3/config/locale/uclibc/ctype_members.cc | ||
| 808 | --- gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/ctype_members.cc 1969-12-31 18:00:00.000000000 -0600 | ||
| 809 | +++ gcc-4.0.0/libstdc++-v3/config/locale/uclibc/ctype_members.cc 2005-04-28 01:13:15.000000000 -0500 | ||
| 810 | @@ -0,0 +1,300 @@ | ||
| 811 | +// std::ctype implementation details, GNU version -*- C++ -*- | ||
| 812 | + | ||
| 813 | +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. | ||
| 814 | +// | ||
| 815 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 816 | +// software; you can redistribute it and/or modify it under the | ||
| 817 | +// terms of the GNU General Public License as published by the | ||
| 818 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 819 | +// any later version. | ||
| 820 | + | ||
| 821 | +// This library is distributed in the hope that it will be useful, | ||
| 822 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 823 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 824 | +// GNU General Public License for more details. | ||
| 825 | + | ||
| 826 | +// You should have received a copy of the GNU General Public License along | ||
| 827 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 828 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 829 | +// USA. | ||
| 830 | + | ||
| 831 | +// As a special exception, you may use this file as part of a free software | ||
| 832 | +// library without restriction. Specifically, if other files instantiate | ||
| 833 | +// templates or use macros or inline functions from this file, or you compile | ||
| 834 | +// this file and link it with other files to produce an executable, this | ||
| 835 | +// file does not by itself cause the resulting executable to be covered by | ||
| 836 | +// the GNU General Public License. This exception does not however | ||
| 837 | +// invalidate any other reasons why the executable file might be covered by | ||
| 838 | +// the GNU General Public License. | ||
| 839 | + | ||
| 840 | +// | ||
| 841 | +// ISO C++ 14882: 22.2.1.1.2 ctype virtual functions. | ||
| 842 | +// | ||
| 843 | + | ||
| 844 | +// Written by Benjamin Kosnik <bkoz@redhat.com> | ||
| 845 | + | ||
| 846 | +#define _LIBC | ||
| 847 | +#include <locale> | ||
| 848 | +#undef _LIBC | ||
| 849 | +#include <bits/c++locale_internal.h> | ||
| 850 | + | ||
| 851 | +#ifndef __UCLIBC_HAS_XLOCALE__ | ||
| 852 | +#define __wctype_l(S, L) wctype((S)) | ||
| 853 | +#define __towupper_l(C, L) towupper((C)) | ||
| 854 | +#define __towlower_l(C, L) towlower((C)) | ||
| 855 | +#define __iswctype_l(C, M, L) iswctype((C), (M)) | ||
| 856 | +#endif | ||
| 857 | + | ||
| 858 | +namespace std | ||
| 859 | +{ | ||
| 860 | + // NB: The other ctype<char> specializations are in src/locale.cc and | ||
| 861 | + // various /config/os/* files. | ||
| 862 | + template<> | ||
| 863 | + ctype_byname<char>::ctype_byname(const char* __s, size_t __refs) | ||
| 864 | + : ctype<char>(0, false, __refs) | ||
| 865 | + { | ||
| 866 | + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) | ||
| 867 | + { | ||
| 868 | + this->_S_destroy_c_locale(this->_M_c_locale_ctype); | ||
| 869 | + this->_S_create_c_locale(this->_M_c_locale_ctype, __s); | ||
| 870 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 871 | + this->_M_toupper = this->_M_c_locale_ctype->__ctype_toupper; | ||
| 872 | + this->_M_tolower = this->_M_c_locale_ctype->__ctype_tolower; | ||
| 873 | + this->_M_table = this->_M_c_locale_ctype->__ctype_b; | ||
| 874 | +#endif | ||
| 875 | + } | ||
| 876 | + } | ||
| 877 | + | ||
| 878 | +#ifdef _GLIBCXX_USE_WCHAR_T | ||
| 879 | + ctype<wchar_t>::__wmask_type | ||
| 880 | + ctype<wchar_t>::_M_convert_to_wmask(const mask __m) const | ||
| 881 | + { | ||
| 882 | + __wmask_type __ret; | ||
| 883 | + switch (__m) | ||
| 884 | + { | ||
| 885 | + case space: | ||
| 886 | + __ret = __wctype_l("space", _M_c_locale_ctype); | ||
| 887 | + break; | ||
| 888 | + case print: | ||
| 889 | + __ret = __wctype_l("print", _M_c_locale_ctype); | ||
| 890 | + break; | ||
| 891 | + case cntrl: | ||
| 892 | + __ret = __wctype_l("cntrl", _M_c_locale_ctype); | ||
| 893 | + break; | ||
| 894 | + case upper: | ||
| 895 | + __ret = __wctype_l("upper", _M_c_locale_ctype); | ||
| 896 | + break; | ||
| 897 | + case lower: | ||
| 898 | + __ret = __wctype_l("lower", _M_c_locale_ctype); | ||
| 899 | + break; | ||
| 900 | + case alpha: | ||
| 901 | + __ret = __wctype_l("alpha", _M_c_locale_ctype); | ||
| 902 | + break; | ||
| 903 | + case digit: | ||
| 904 | + __ret = __wctype_l("digit", _M_c_locale_ctype); | ||
| 905 | + break; | ||
| 906 | + case punct: | ||
| 907 | + __ret = __wctype_l("punct", _M_c_locale_ctype); | ||
| 908 | + break; | ||
| 909 | + case xdigit: | ||
| 910 | + __ret = __wctype_l("xdigit", _M_c_locale_ctype); | ||
| 911 | + break; | ||
| 912 | + case alnum: | ||
| 913 | + __ret = __wctype_l("alnum", _M_c_locale_ctype); | ||
| 914 | + break; | ||
| 915 | + case graph: | ||
| 916 | + __ret = __wctype_l("graph", _M_c_locale_ctype); | ||
| 917 | + break; | ||
| 918 | + default: | ||
| 919 | + __ret = __wmask_type(); | ||
| 920 | + } | ||
| 921 | + return __ret; | ||
| 922 | + } | ||
| 923 | + | ||
| 924 | + wchar_t | ||
| 925 | + ctype<wchar_t>::do_toupper(wchar_t __c) const | ||
| 926 | + { return __towupper_l(__c, _M_c_locale_ctype); } | ||
| 927 | + | ||
| 928 | + const wchar_t* | ||
| 929 | + ctype<wchar_t>::do_toupper(wchar_t* __lo, const wchar_t* __hi) const | ||
| 930 | + { | ||
| 931 | + while (__lo < __hi) | ||
| 932 | + { | ||
| 933 | + *__lo = __towupper_l(*__lo, _M_c_locale_ctype); | ||
| 934 | + ++__lo; | ||
| 935 | + } | ||
| 936 | + return __hi; | ||
| 937 | + } | ||
| 938 | + | ||
| 939 | + wchar_t | ||
| 940 | + ctype<wchar_t>::do_tolower(wchar_t __c) const | ||
| 941 | + { return __towlower_l(__c, _M_c_locale_ctype); } | ||
| 942 | + | ||
| 943 | + const wchar_t* | ||
| 944 | + ctype<wchar_t>::do_tolower(wchar_t* __lo, const wchar_t* __hi) const | ||
| 945 | + { | ||
| 946 | + while (__lo < __hi) | ||
| 947 | + { | ||
| 948 | + *__lo = __towlower_l(*__lo, _M_c_locale_ctype); | ||
| 949 | + ++__lo; | ||
| 950 | + } | ||
| 951 | + return __hi; | ||
| 952 | + } | ||
| 953 | + | ||
| 954 | + bool | ||
| 955 | + ctype<wchar_t>:: | ||
| 956 | + do_is(mask __m, wchar_t __c) const | ||
| 957 | + { | ||
| 958 | + // Highest bitmask in ctype_base == 10, but extra in "C" | ||
| 959 | + // library for blank. | ||
| 960 | + bool __ret = false; | ||
| 961 | + const size_t __bitmasksize = 11; | ||
| 962 | + for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur) | ||
| 963 | + if (__m & _M_bit[__bitcur] | ||
| 964 | + && __iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype)) | ||
| 965 | + { | ||
| 966 | + __ret = true; | ||
| 967 | + break; | ||
| 968 | + } | ||
| 969 | + return __ret; | ||
| 970 | + } | ||
| 971 | + | ||
| 972 | + const wchar_t* | ||
| 973 | + ctype<wchar_t>:: | ||
| 974 | + do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __vec) const | ||
| 975 | + { | ||
| 976 | + for (; __lo < __hi; ++__vec, ++__lo) | ||
| 977 | + { | ||
| 978 | + // Highest bitmask in ctype_base == 10, but extra in "C" | ||
| 979 | + // library for blank. | ||
| 980 | + const size_t __bitmasksize = 11; | ||
| 981 | + mask __m = 0; | ||
| 982 | + for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur) | ||
| 983 | + if (__iswctype_l(*__lo, _M_wmask[__bitcur], _M_c_locale_ctype)) | ||
| 984 | + __m |= _M_bit[__bitcur]; | ||
| 985 | + *__vec = __m; | ||
| 986 | + } | ||
| 987 | + return __hi; | ||
| 988 | + } | ||
| 989 | + | ||
| 990 | + const wchar_t* | ||
| 991 | + ctype<wchar_t>:: | ||
| 992 | + do_scan_is(mask __m, const wchar_t* __lo, const wchar_t* __hi) const | ||
| 993 | + { | ||
| 994 | + while (__lo < __hi && !this->do_is(__m, *__lo)) | ||
| 995 | + ++__lo; | ||
| 996 | + return __lo; | ||
| 997 | + } | ||
| 998 | + | ||
| 999 | + const wchar_t* | ||
| 1000 | + ctype<wchar_t>:: | ||
| 1001 | + do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const | ||
| 1002 | + { | ||
| 1003 | + while (__lo < __hi && this->do_is(__m, *__lo) != 0) | ||
| 1004 | + ++__lo; | ||
| 1005 | + return __lo; | ||
| 1006 | + } | ||
| 1007 | + | ||
| 1008 | + wchar_t | ||
| 1009 | + ctype<wchar_t>:: | ||
| 1010 | + do_widen(char __c) const | ||
| 1011 | + { return _M_widen[static_cast<unsigned char>(__c)]; } | ||
| 1012 | + | ||
| 1013 | + const char* | ||
| 1014 | + ctype<wchar_t>:: | ||
| 1015 | + do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const | ||
| 1016 | + { | ||
| 1017 | + while (__lo < __hi) | ||
| 1018 | + { | ||
| 1019 | + *__dest = _M_widen[static_cast<unsigned char>(*__lo)]; | ||
| 1020 | + ++__lo; | ||
| 1021 | + ++__dest; | ||
| 1022 | + } | ||
| 1023 | + return __hi; | ||
| 1024 | + } | ||
| 1025 | + | ||
| 1026 | + char | ||
| 1027 | + ctype<wchar_t>:: | ||
| 1028 | + do_narrow(wchar_t __wc, char __dfault) const | ||
| 1029 | + { | ||
| 1030 | + if (__wc >= 0 && __wc < 128 && _M_narrow_ok) | ||
| 1031 | + return _M_narrow[__wc]; | ||
| 1032 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1033 | + __c_locale __old = __uselocale(_M_c_locale_ctype); | ||
| 1034 | +#endif | ||
| 1035 | + const int __c = wctob(__wc); | ||
| 1036 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1037 | + __uselocale(__old); | ||
| 1038 | +#endif | ||
| 1039 | + return (__c == EOF ? __dfault : static_cast<char>(__c)); | ||
| 1040 | + } | ||
| 1041 | + | ||
| 1042 | + const wchar_t* | ||
| 1043 | + ctype<wchar_t>:: | ||
| 1044 | + do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault, | ||
| 1045 | + char* __dest) const | ||
| 1046 | + { | ||
| 1047 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1048 | + __c_locale __old = __uselocale(_M_c_locale_ctype); | ||
| 1049 | +#endif | ||
| 1050 | + if (_M_narrow_ok) | ||
| 1051 | + while (__lo < __hi) | ||
| 1052 | + { | ||
| 1053 | + if (*__lo >= 0 && *__lo < 128) | ||
| 1054 | + *__dest = _M_narrow[*__lo]; | ||
| 1055 | + else | ||
| 1056 | + { | ||
| 1057 | + const int __c = wctob(*__lo); | ||
| 1058 | + *__dest = (__c == EOF ? __dfault : static_cast<char>(__c)); | ||
| 1059 | + } | ||
| 1060 | + ++__lo; | ||
| 1061 | + ++__dest; | ||
| 1062 | + } | ||
| 1063 | + else | ||
| 1064 | + while (__lo < __hi) | ||
| 1065 | + { | ||
| 1066 | + const int __c = wctob(*__lo); | ||
| 1067 | + *__dest = (__c == EOF ? __dfault : static_cast<char>(__c)); | ||
| 1068 | + ++__lo; | ||
| 1069 | + ++__dest; | ||
| 1070 | + } | ||
| 1071 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1072 | + __uselocale(__old); | ||
| 1073 | +#endif | ||
| 1074 | + return __hi; | ||
| 1075 | + } | ||
| 1076 | + | ||
| 1077 | + void | ||
| 1078 | + ctype<wchar_t>::_M_initialize_ctype() | ||
| 1079 | + { | ||
| 1080 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1081 | + __c_locale __old = __uselocale(_M_c_locale_ctype); | ||
| 1082 | +#endif | ||
| 1083 | + wint_t __i; | ||
| 1084 | + for (__i = 0; __i < 128; ++__i) | ||
| 1085 | + { | ||
| 1086 | + const int __c = wctob(__i); | ||
| 1087 | + if (__c == EOF) | ||
| 1088 | + break; | ||
| 1089 | + else | ||
| 1090 | + _M_narrow[__i] = static_cast<char>(__c); | ||
| 1091 | + } | ||
| 1092 | + if (__i == 128) | ||
| 1093 | + _M_narrow_ok = true; | ||
| 1094 | + else | ||
| 1095 | + _M_narrow_ok = false; | ||
| 1096 | + for (size_t __j = 0; | ||
| 1097 | + __j < sizeof(_M_widen) / sizeof(wint_t); ++__j) | ||
| 1098 | + _M_widen[__j] = btowc(__j); | ||
| 1099 | + | ||
| 1100 | + for (size_t __k = 0; __k <= 11; ++__k) | ||
| 1101 | + { | ||
| 1102 | + _M_bit[__k] = static_cast<mask>(_ISbit(__k)); | ||
| 1103 | + _M_wmask[__k] = _M_convert_to_wmask(_M_bit[__k]); | ||
| 1104 | + } | ||
| 1105 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1106 | + __uselocale(__old); | ||
| 1107 | +#endif | ||
| 1108 | + } | ||
| 1109 | +#endif // _GLIBCXX_USE_WCHAR_T | ||
| 1110 | +} | ||
| 1111 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/messages_members.cc gcc-4.0.0/libstdc++-v3/config/locale/uclibc/messages_members.cc | ||
| 1112 | --- gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/messages_members.cc 1969-12-31 18:00:00.000000000 -0600 | ||
| 1113 | +++ gcc-4.0.0/libstdc++-v3/config/locale/uclibc/messages_members.cc 2005-04-28 01:13:15.000000000 -0500 | ||
| 1114 | @@ -0,0 +1,100 @@ | ||
| 1115 | +// std::messages implementation details, GNU version -*- C++ -*- | ||
| 1116 | + | ||
| 1117 | +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. | ||
| 1118 | +// | ||
| 1119 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 1120 | +// software; you can redistribute it and/or modify it under the | ||
| 1121 | +// terms of the GNU General Public License as published by the | ||
| 1122 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 1123 | +// any later version. | ||
| 1124 | + | ||
| 1125 | +// This library is distributed in the hope that it will be useful, | ||
| 1126 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 1127 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 1128 | +// GNU General Public License for more details. | ||
| 1129 | + | ||
| 1130 | +// You should have received a copy of the GNU General Public License along | ||
| 1131 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 1132 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 1133 | +// USA. | ||
| 1134 | + | ||
| 1135 | +// As a special exception, you may use this file as part of a free software | ||
| 1136 | +// library without restriction. Specifically, if other files instantiate | ||
| 1137 | +// templates or use macros or inline functions from this file, or you compile | ||
| 1138 | +// this file and link it with other files to produce an executable, this | ||
| 1139 | +// file does not by itself cause the resulting executable to be covered by | ||
| 1140 | +// the GNU General Public License. This exception does not however | ||
| 1141 | +// invalidate any other reasons why the executable file might be covered by | ||
| 1142 | +// the GNU General Public License. | ||
| 1143 | + | ||
| 1144 | +// | ||
| 1145 | +// ISO C++ 14882: 22.2.7.1.2 messages virtual functions | ||
| 1146 | +// | ||
| 1147 | + | ||
| 1148 | +// Written by Benjamin Kosnik <bkoz@redhat.com> | ||
| 1149 | + | ||
| 1150 | +#include <locale> | ||
| 1151 | +#include <bits/c++locale_internal.h> | ||
| 1152 | + | ||
| 1153 | +#ifdef __UCLIBC_MJN3_ONLY__ | ||
| 1154 | +#warning fix gettext stuff | ||
| 1155 | +#endif | ||
| 1156 | +#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__ | ||
| 1157 | +extern "C" char *__dcgettext(const char *domainname, | ||
| 1158 | + const char *msgid, int category); | ||
| 1159 | +#undef gettext | ||
| 1160 | +#define gettext(msgid) __dcgettext(NULL, msgid, LC_MESSAGES) | ||
| 1161 | +#else | ||
| 1162 | +#undef gettext | ||
| 1163 | +#define gettext(msgid) (msgid) | ||
| 1164 | +#endif | ||
| 1165 | + | ||
| 1166 | +namespace std | ||
| 1167 | +{ | ||
| 1168 | + // Specializations. | ||
| 1169 | + template<> | ||
| 1170 | + string | ||
| 1171 | + messages<char>::do_get(catalog, int, int, const string& __dfault) const | ||
| 1172 | + { | ||
| 1173 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1174 | + __c_locale __old = __uselocale(_M_c_locale_messages); | ||
| 1175 | + const char* __msg = const_cast<const char*>(gettext(__dfault.c_str())); | ||
| 1176 | + __uselocale(__old); | ||
| 1177 | + return string(__msg); | ||
| 1178 | +#elif defined __UCLIBC_HAS_LOCALE__ | ||
| 1179 | + char* __old = strdup(setlocale(LC_ALL, NULL)); | ||
| 1180 | + setlocale(LC_ALL, _M_name_messages); | ||
| 1181 | + const char* __msg = gettext(__dfault.c_str()); | ||
| 1182 | + setlocale(LC_ALL, __old); | ||
| 1183 | + free(__old); | ||
| 1184 | + return string(__msg); | ||
| 1185 | +#else | ||
| 1186 | + const char* __msg = gettext(__dfault.c_str()); | ||
| 1187 | + return string(__msg); | ||
| 1188 | +#endif | ||
| 1189 | + } | ||
| 1190 | + | ||
| 1191 | +#ifdef _GLIBCXX_USE_WCHAR_T | ||
| 1192 | + template<> | ||
| 1193 | + wstring | ||
| 1194 | + messages<wchar_t>::do_get(catalog, int, int, const wstring& __dfault) const | ||
| 1195 | + { | ||
| 1196 | +# ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1197 | + __c_locale __old = __uselocale(_M_c_locale_messages); | ||
| 1198 | + char* __msg = gettext(_M_convert_to_char(__dfault)); | ||
| 1199 | + __uselocale(__old); | ||
| 1200 | + return _M_convert_from_char(__msg); | ||
| 1201 | +# elif defined __UCLIBC_HAS_LOCALE__ | ||
| 1202 | + char* __old = strdup(setlocale(LC_ALL, NULL)); | ||
| 1203 | + setlocale(LC_ALL, _M_name_messages); | ||
| 1204 | + char* __msg = gettext(_M_convert_to_char(__dfault)); | ||
| 1205 | + setlocale(LC_ALL, __old); | ||
| 1206 | + free(__old); | ||
| 1207 | + return _M_convert_from_char(__msg); | ||
| 1208 | +# else | ||
| 1209 | + char* __msg = gettext(_M_convert_to_char(__dfault)); | ||
| 1210 | + return _M_convert_from_char(__msg); | ||
| 1211 | +# endif | ||
| 1212 | + } | ||
| 1213 | +#endif | ||
| 1214 | +} | ||
| 1215 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/messages_members.h gcc-4.0.0/libstdc++-v3/config/locale/uclibc/messages_members.h | ||
| 1216 | --- gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/messages_members.h 1969-12-31 18:00:00.000000000 -0600 | ||
| 1217 | +++ gcc-4.0.0/libstdc++-v3/config/locale/uclibc/messages_members.h 2005-04-28 01:13:15.000000000 -0500 | ||
| 1218 | @@ -0,0 +1,118 @@ | ||
| 1219 | +// std::messages implementation details, GNU version -*- C++ -*- | ||
| 1220 | + | ||
| 1221 | +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. | ||
| 1222 | +// | ||
| 1223 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 1224 | +// software; you can redistribute it and/or modify it under the | ||
| 1225 | +// terms of the GNU General Public License as published by the | ||
| 1226 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 1227 | +// any later version. | ||
| 1228 | + | ||
| 1229 | +// This library is distributed in the hope that it will be useful, | ||
| 1230 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 1231 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 1232 | +// GNU General Public License for more details. | ||
| 1233 | + | ||
| 1234 | +// You should have received a copy of the GNU General Public License along | ||
| 1235 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 1236 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 1237 | +// USA. | ||
| 1238 | + | ||
| 1239 | +// As a special exception, you may use this file as part of a free software | ||
| 1240 | +// library without restriction. Specifically, if other files instantiate | ||
| 1241 | +// templates or use macros or inline functions from this file, or you compile | ||
| 1242 | +// this file and link it with other files to produce an executable, this | ||
| 1243 | +// file does not by itself cause the resulting executable to be covered by | ||
| 1244 | +// the GNU General Public License. This exception does not however | ||
| 1245 | +// invalidate any other reasons why the executable file might be covered by | ||
| 1246 | +// the GNU General Public License. | ||
| 1247 | + | ||
| 1248 | +// | ||
| 1249 | +// ISO C++ 14882: 22.2.7.1.2 messages functions | ||
| 1250 | +// | ||
| 1251 | + | ||
| 1252 | +// Written by Benjamin Kosnik <bkoz@redhat.com> | ||
| 1253 | + | ||
| 1254 | +#ifdef __UCLIBC_MJN3_ONLY__ | ||
| 1255 | +#warning fix prototypes for *textdomain funcs | ||
| 1256 | +#endif | ||
| 1257 | +#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__ | ||
| 1258 | +extern "C" char *__textdomain(const char *domainname); | ||
| 1259 | +extern "C" char *__bindtextdomain(const char *domainname, | ||
| 1260 | + const char *dirname); | ||
| 1261 | +#else | ||
| 1262 | +#undef __textdomain | ||
| 1263 | +#undef __bindtextdomain | ||
| 1264 | +#define __textdomain(D) ((void)0) | ||
| 1265 | +#define __bindtextdomain(D,P) ((void)0) | ||
| 1266 | +#endif | ||
| 1267 | + | ||
| 1268 | + // Non-virtual member functions. | ||
| 1269 | + template<typename _CharT> | ||
| 1270 | + messages<_CharT>::messages(size_t __refs) | ||
| 1271 | + : facet(__refs), _M_c_locale_messages(_S_get_c_locale()), | ||
| 1272 | + _M_name_messages(_S_get_c_name()) | ||
| 1273 | + { } | ||
| 1274 | + | ||
| 1275 | + template<typename _CharT> | ||
| 1276 | + messages<_CharT>::messages(__c_locale __cloc, const char* __s, | ||
| 1277 | + size_t __refs) | ||
| 1278 | + : facet(__refs), _M_c_locale_messages(_S_clone_c_locale(__cloc)), | ||
| 1279 | + _M_name_messages(__s) | ||
| 1280 | + { | ||
| 1281 | + char* __tmp = new char[std::strlen(__s) + 1]; | ||
| 1282 | + std::strcpy(__tmp, __s); | ||
| 1283 | + _M_name_messages = __tmp; | ||
| 1284 | + } | ||
| 1285 | + | ||
| 1286 | + template<typename _CharT> | ||
| 1287 | + typename messages<_CharT>::catalog | ||
| 1288 | + messages<_CharT>::open(const basic_string<char>& __s, const locale& __loc, | ||
| 1289 | + const char* __dir) const | ||
| 1290 | + { | ||
| 1291 | + __bindtextdomain(__s.c_str(), __dir); | ||
| 1292 | + return this->do_open(__s, __loc); | ||
| 1293 | + } | ||
| 1294 | + | ||
| 1295 | + // Virtual member functions. | ||
| 1296 | + template<typename _CharT> | ||
| 1297 | + messages<_CharT>::~messages() | ||
| 1298 | + { | ||
| 1299 | + if (_M_name_messages != _S_get_c_name()) | ||
| 1300 | + delete [] _M_name_messages; | ||
| 1301 | + _S_destroy_c_locale(_M_c_locale_messages); | ||
| 1302 | + } | ||
| 1303 | + | ||
| 1304 | + template<typename _CharT> | ||
| 1305 | + typename messages<_CharT>::catalog | ||
| 1306 | + messages<_CharT>::do_open(const basic_string<char>& __s, | ||
| 1307 | + const locale&) const | ||
| 1308 | + { | ||
| 1309 | + // No error checking is done, assume the catalog exists and can | ||
| 1310 | + // be used. | ||
| 1311 | + __textdomain(__s.c_str()); | ||
| 1312 | + return 0; | ||
| 1313 | + } | ||
| 1314 | + | ||
| 1315 | + template<typename _CharT> | ||
| 1316 | + void | ||
| 1317 | + messages<_CharT>::do_close(catalog) const | ||
| 1318 | + { } | ||
| 1319 | + | ||
| 1320 | + // messages_byname | ||
| 1321 | + template<typename _CharT> | ||
| 1322 | + messages_byname<_CharT>::messages_byname(const char* __s, size_t __refs) | ||
| 1323 | + : messages<_CharT>(__refs) | ||
| 1324 | + { | ||
| 1325 | + if (this->_M_name_messages != locale::facet::_S_get_c_name()) | ||
| 1326 | + delete [] this->_M_name_messages; | ||
| 1327 | + char* __tmp = new char[std::strlen(__s) + 1]; | ||
| 1328 | + std::strcpy(__tmp, __s); | ||
| 1329 | + this->_M_name_messages = __tmp; | ||
| 1330 | + | ||
| 1331 | + if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0) | ||
| 1332 | + { | ||
| 1333 | + this->_S_destroy_c_locale(this->_M_c_locale_messages); | ||
| 1334 | + this->_S_create_c_locale(this->_M_c_locale_messages, __s); | ||
| 1335 | + } | ||
| 1336 | + } | ||
| 1337 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/monetary_members.cc gcc-4.0.0/libstdc++-v3/config/locale/uclibc/monetary_members.cc | ||
| 1338 | --- gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/monetary_members.cc 1969-12-31 18:00:00.000000000 -0600 | ||
| 1339 | +++ gcc-4.0.0/libstdc++-v3/config/locale/uclibc/monetary_members.cc 2005-04-28 01:23:02.000000000 -0500 | ||
| 1340 | @@ -0,0 +1,692 @@ | ||
| 1341 | +// std::moneypunct implementation details, GNU version -*- C++ -*- | ||
| 1342 | + | ||
| 1343 | +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. | ||
| 1344 | +// | ||
| 1345 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 1346 | +// software; you can redistribute it and/or modify it under the | ||
| 1347 | +// terms of the GNU General Public License as published by the | ||
| 1348 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 1349 | +// any later version. | ||
| 1350 | + | ||
| 1351 | +// This library is distributed in the hope that it will be useful, | ||
| 1352 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 1353 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 1354 | +// GNU General Public License for more details. | ||
| 1355 | + | ||
| 1356 | +// You should have received a copy of the GNU General Public License along | ||
| 1357 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 1358 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 1359 | +// USA. | ||
| 1360 | + | ||
| 1361 | +// As a special exception, you may use this file as part of a free software | ||
| 1362 | +// library without restriction. Specifically, if other files instantiate | ||
| 1363 | +// templates or use macros or inline functions from this file, or you compile | ||
| 1364 | +// this file and link it with other files to produce an executable, this | ||
| 1365 | +// file does not by itself cause the resulting executable to be covered by | ||
| 1366 | +// the GNU General Public License. This exception does not however | ||
| 1367 | +// invalidate any other reasons why the executable file might be covered by | ||
| 1368 | +// the GNU General Public License. | ||
| 1369 | + | ||
| 1370 | +// | ||
| 1371 | +// ISO C++ 14882: 22.2.6.3.2 moneypunct virtual functions | ||
| 1372 | +// | ||
| 1373 | + | ||
| 1374 | +// Written by Benjamin Kosnik <bkoz@redhat.com> | ||
| 1375 | + | ||
| 1376 | +#define _LIBC | ||
| 1377 | +#include <locale> | ||
| 1378 | +#undef _LIBC | ||
| 1379 | +#include <bits/c++locale_internal.h> | ||
| 1380 | + | ||
| 1381 | +#ifdef __UCLIBC_MJN3_ONLY__ | ||
| 1382 | +#warning optimize this for uclibc | ||
| 1383 | +#warning tailor for stub locale support | ||
| 1384 | +#endif | ||
| 1385 | + | ||
| 1386 | +#ifndef __UCLIBC_HAS_XLOCALE__ | ||
| 1387 | +#define __nl_langinfo_l(N, L) nl_langinfo((N)) | ||
| 1388 | +#endif | ||
| 1389 | + | ||
| 1390 | +namespace std | ||
| 1391 | +{ | ||
| 1392 | + // Construct and return valid pattern consisting of some combination of: | ||
| 1393 | + // space none symbol sign value | ||
| 1394 | + money_base::pattern | ||
| 1395 | + money_base::_S_construct_pattern(char __precedes, char __space, char __posn) | ||
| 1396 | + { | ||
| 1397 | + pattern __ret; | ||
| 1398 | + | ||
| 1399 | + // This insanely complicated routine attempts to construct a valid | ||
| 1400 | + // pattern for use with monyepunct. A couple of invariants: | ||
| 1401 | + | ||
| 1402 | + // if (__precedes) symbol -> value | ||
| 1403 | + // else value -> symbol | ||
| 1404 | + | ||
| 1405 | + // if (__space) space | ||
| 1406 | + // else none | ||
| 1407 | + | ||
| 1408 | + // none == never first | ||
| 1409 | + // space never first or last | ||
| 1410 | + | ||
| 1411 | + // Any elegant implementations of this are welcome. | ||
| 1412 | + switch (__posn) | ||
| 1413 | + { | ||
| 1414 | + case 0: | ||
| 1415 | + case 1: | ||
| 1416 | + // 1 The sign precedes the value and symbol. | ||
| 1417 | + __ret.field[0] = sign; | ||
| 1418 | + if (__space) | ||
| 1419 | + { | ||
| 1420 | + // Pattern starts with sign. | ||
| 1421 | + if (__precedes) | ||
| 1422 | + { | ||
| 1423 | + __ret.field[1] = symbol; | ||
| 1424 | + __ret.field[3] = value; | ||
| 1425 | + } | ||
| 1426 | + else | ||
| 1427 | + { | ||
| 1428 | + __ret.field[1] = value; | ||
| 1429 | + __ret.field[3] = symbol; | ||
| 1430 | + } | ||
| 1431 | + __ret.field[2] = space; | ||
| 1432 | + } | ||
| 1433 | + else | ||
| 1434 | + { | ||
| 1435 | + // Pattern starts with sign and ends with none. | ||
| 1436 | + if (__precedes) | ||
| 1437 | + { | ||
| 1438 | + __ret.field[1] = symbol; | ||
| 1439 | + __ret.field[2] = value; | ||
| 1440 | + } | ||
| 1441 | + else | ||
| 1442 | + { | ||
| 1443 | + __ret.field[1] = value; | ||
| 1444 | + __ret.field[2] = symbol; | ||
| 1445 | + } | ||
| 1446 | + __ret.field[3] = none; | ||
| 1447 | + } | ||
| 1448 | + break; | ||
| 1449 | + case 2: | ||
| 1450 | + // 2 The sign follows the value and symbol. | ||
| 1451 | + if (__space) | ||
| 1452 | + { | ||
| 1453 | + // Pattern either ends with sign. | ||
| 1454 | + if (__precedes) | ||
| 1455 | + { | ||
| 1456 | + __ret.field[0] = symbol; | ||
| 1457 | + __ret.field[2] = value; | ||
| 1458 | + } | ||
| 1459 | + else | ||
| 1460 | + { | ||
| 1461 | + __ret.field[0] = value; | ||
| 1462 | + __ret.field[2] = symbol; | ||
| 1463 | + } | ||
| 1464 | + __ret.field[1] = space; | ||
| 1465 | + __ret.field[3] = sign; | ||
| 1466 | + } | ||
| 1467 | + else | ||
| 1468 | + { | ||
| 1469 | + // Pattern ends with sign then none. | ||
| 1470 | + if (__precedes) | ||
| 1471 | + { | ||
| 1472 | + __ret.field[0] = symbol; | ||
| 1473 | + __ret.field[1] = value; | ||
| 1474 | + } | ||
| 1475 | + else | ||
| 1476 | + { | ||
| 1477 | + __ret.field[0] = value; | ||
| 1478 | + __ret.field[1] = symbol; | ||
| 1479 | + } | ||
| 1480 | + __ret.field[2] = sign; | ||
| 1481 | + __ret.field[3] = none; | ||
| 1482 | + } | ||
| 1483 | + break; | ||
| 1484 | + case 3: | ||
| 1485 | + // 3 The sign immediately precedes the symbol. | ||
| 1486 | + if (__precedes) | ||
| 1487 | + { | ||
| 1488 | + __ret.field[0] = sign; | ||
| 1489 | + __ret.field[1] = symbol; | ||
| 1490 | + if (__space) | ||
| 1491 | + { | ||
| 1492 | + __ret.field[2] = space; | ||
| 1493 | + __ret.field[3] = value; | ||
| 1494 | + } | ||
| 1495 | + else | ||
| 1496 | + { | ||
| 1497 | + __ret.field[2] = value; | ||
| 1498 | + __ret.field[3] = none; | ||
| 1499 | + } | ||
| 1500 | + } | ||
| 1501 | + else | ||
| 1502 | + { | ||
| 1503 | + __ret.field[0] = value; | ||
| 1504 | + if (__space) | ||
| 1505 | + { | ||
| 1506 | + __ret.field[1] = space; | ||
| 1507 | + __ret.field[2] = sign; | ||
| 1508 | + __ret.field[3] = symbol; | ||
| 1509 | + } | ||
| 1510 | + else | ||
| 1511 | + { | ||
| 1512 | + __ret.field[1] = sign; | ||
| 1513 | + __ret.field[2] = symbol; | ||
| 1514 | + __ret.field[3] = none; | ||
| 1515 | + } | ||
| 1516 | + } | ||
| 1517 | + break; | ||
| 1518 | + case 4: | ||
| 1519 | + // 4 The sign immediately follows the symbol. | ||
| 1520 | + if (__precedes) | ||
| 1521 | + { | ||
| 1522 | + __ret.field[0] = symbol; | ||
| 1523 | + __ret.field[1] = sign; | ||
| 1524 | + if (__space) | ||
| 1525 | + { | ||
| 1526 | + __ret.field[2] = space; | ||
| 1527 | + __ret.field[3] = value; | ||
| 1528 | + } | ||
| 1529 | + else | ||
| 1530 | + { | ||
| 1531 | + __ret.field[2] = value; | ||
| 1532 | + __ret.field[3] = none; | ||
| 1533 | + } | ||
| 1534 | + } | ||
| 1535 | + else | ||
| 1536 | + { | ||
| 1537 | + __ret.field[0] = value; | ||
| 1538 | + if (__space) | ||
| 1539 | + { | ||
| 1540 | + __ret.field[1] = space; | ||
| 1541 | + __ret.field[2] = symbol; | ||
| 1542 | + __ret.field[3] = sign; | ||
| 1543 | + } | ||
| 1544 | + else | ||
| 1545 | + { | ||
| 1546 | + __ret.field[1] = symbol; | ||
| 1547 | + __ret.field[2] = sign; | ||
| 1548 | + __ret.field[3] = none; | ||
| 1549 | + } | ||
| 1550 | + } | ||
| 1551 | + break; | ||
| 1552 | + default: | ||
| 1553 | + __ret = pattern(); | ||
| 1554 | + } | ||
| 1555 | + return __ret; | ||
| 1556 | + } | ||
| 1557 | + | ||
| 1558 | + template<> | ||
| 1559 | + void | ||
| 1560 | + moneypunct<char, true>::_M_initialize_moneypunct(__c_locale __cloc, | ||
| 1561 | + const char*) | ||
| 1562 | + { | ||
| 1563 | + if (!_M_data) | ||
| 1564 | + _M_data = new __moneypunct_cache<char, true>; | ||
| 1565 | + | ||
| 1566 | + if (!__cloc) | ||
| 1567 | + { | ||
| 1568 | + // "C" locale | ||
| 1569 | + _M_data->_M_decimal_point = '.'; | ||
| 1570 | + _M_data->_M_thousands_sep = ','; | ||
| 1571 | + _M_data->_M_grouping = ""; | ||
| 1572 | + _M_data->_M_grouping_size = 0; | ||
| 1573 | + _M_data->_M_curr_symbol = ""; | ||
| 1574 | + _M_data->_M_curr_symbol_size = 0; | ||
| 1575 | + _M_data->_M_positive_sign = ""; | ||
| 1576 | + _M_data->_M_positive_sign_size = 0; | ||
| 1577 | + _M_data->_M_negative_sign = ""; | ||
| 1578 | + _M_data->_M_negative_sign_size = 0; | ||
| 1579 | + _M_data->_M_frac_digits = 0; | ||
| 1580 | + _M_data->_M_pos_format = money_base::_S_default_pattern; | ||
| 1581 | + _M_data->_M_neg_format = money_base::_S_default_pattern; | ||
| 1582 | + | ||
| 1583 | + for (size_t __i = 0; __i < money_base::_S_end; ++__i) | ||
| 1584 | + _M_data->_M_atoms[__i] = money_base::_S_atoms[__i]; | ||
| 1585 | + } | ||
| 1586 | + else | ||
| 1587 | + { | ||
| 1588 | + // Named locale. | ||
| 1589 | + _M_data->_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT, | ||
| 1590 | + __cloc)); | ||
| 1591 | + _M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP, | ||
| 1592 | + __cloc)); | ||
| 1593 | + _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); | ||
| 1594 | + _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); | ||
| 1595 | + _M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); | ||
| 1596 | + _M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign); | ||
| 1597 | + | ||
| 1598 | + char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc)); | ||
| 1599 | + if (!__nposn) | ||
| 1600 | + _M_data->_M_negative_sign = "()"; | ||
| 1601 | + else | ||
| 1602 | + _M_data->_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, | ||
| 1603 | + __cloc); | ||
| 1604 | + _M_data->_M_negative_sign_size = strlen(_M_data->_M_negative_sign); | ||
| 1605 | + | ||
| 1606 | + // _Intl == true | ||
| 1607 | + _M_data->_M_curr_symbol = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc); | ||
| 1608 | + _M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol); | ||
| 1609 | + _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, | ||
| 1610 | + __cloc)); | ||
| 1611 | + char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc)); | ||
| 1612 | + char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc)); | ||
| 1613 | + char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc)); | ||
| 1614 | + _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, | ||
| 1615 | + __pposn); | ||
| 1616 | + char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc)); | ||
| 1617 | + char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc)); | ||
| 1618 | + _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, | ||
| 1619 | + __nposn); | ||
| 1620 | + } | ||
| 1621 | + } | ||
| 1622 | + | ||
| 1623 | + template<> | ||
| 1624 | + void | ||
| 1625 | + moneypunct<char, false>::_M_initialize_moneypunct(__c_locale __cloc, | ||
| 1626 | + const char*) | ||
| 1627 | + { | ||
| 1628 | + if (!_M_data) | ||
| 1629 | + _M_data = new __moneypunct_cache<char, false>; | ||
| 1630 | + | ||
| 1631 | + if (!__cloc) | ||
| 1632 | + { | ||
| 1633 | + // "C" locale | ||
| 1634 | + _M_data->_M_decimal_point = '.'; | ||
| 1635 | + _M_data->_M_thousands_sep = ','; | ||
| 1636 | + _M_data->_M_grouping = ""; | ||
| 1637 | + _M_data->_M_grouping_size = 0; | ||
| 1638 | + _M_data->_M_curr_symbol = ""; | ||
| 1639 | + _M_data->_M_curr_symbol_size = 0; | ||
| 1640 | + _M_data->_M_positive_sign = ""; | ||
| 1641 | + _M_data->_M_positive_sign_size = 0; | ||
| 1642 | + _M_data->_M_negative_sign = ""; | ||
| 1643 | + _M_data->_M_negative_sign_size = 0; | ||
| 1644 | + _M_data->_M_frac_digits = 0; | ||
| 1645 | + _M_data->_M_pos_format = money_base::_S_default_pattern; | ||
| 1646 | + _M_data->_M_neg_format = money_base::_S_default_pattern; | ||
| 1647 | + | ||
| 1648 | + for (size_t __i = 0; __i < money_base::_S_end; ++__i) | ||
| 1649 | + _M_data->_M_atoms[__i] = money_base::_S_atoms[__i]; | ||
| 1650 | + } | ||
| 1651 | + else | ||
| 1652 | + { | ||
| 1653 | + // Named locale. | ||
| 1654 | + _M_data->_M_decimal_point = *(__nl_langinfo_l(__MON_DECIMAL_POINT, | ||
| 1655 | + __cloc)); | ||
| 1656 | + _M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP, | ||
| 1657 | + __cloc)); | ||
| 1658 | + _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); | ||
| 1659 | + _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); | ||
| 1660 | + _M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); | ||
| 1661 | + _M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign); | ||
| 1662 | + | ||
| 1663 | + char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc)); | ||
| 1664 | + if (!__nposn) | ||
| 1665 | + _M_data->_M_negative_sign = "()"; | ||
| 1666 | + else | ||
| 1667 | + _M_data->_M_negative_sign = __nl_langinfo_l(__NEGATIVE_SIGN, | ||
| 1668 | + __cloc); | ||
| 1669 | + _M_data->_M_negative_sign_size = strlen(_M_data->_M_negative_sign); | ||
| 1670 | + | ||
| 1671 | + // _Intl == false | ||
| 1672 | + _M_data->_M_curr_symbol = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc); | ||
| 1673 | + _M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol); | ||
| 1674 | + _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc)); | ||
| 1675 | + char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc)); | ||
| 1676 | + char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc)); | ||
| 1677 | + char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc)); | ||
| 1678 | + _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, | ||
| 1679 | + __pposn); | ||
| 1680 | + char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc)); | ||
| 1681 | + char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc)); | ||
| 1682 | + _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, | ||
| 1683 | + __nposn); | ||
| 1684 | + } | ||
| 1685 | + } | ||
| 1686 | + | ||
| 1687 | + template<> | ||
| 1688 | + moneypunct<char, true>::~moneypunct() | ||
| 1689 | + { delete _M_data; } | ||
| 1690 | + | ||
| 1691 | + template<> | ||
| 1692 | + moneypunct<char, false>::~moneypunct() | ||
| 1693 | + { delete _M_data; } | ||
| 1694 | + | ||
| 1695 | +#ifdef _GLIBCXX_USE_WCHAR_T | ||
| 1696 | + template<> | ||
| 1697 | + void | ||
| 1698 | + moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale __cloc, | ||
| 1699 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1700 | + const char*) | ||
| 1701 | +#else | ||
| 1702 | + const char* __name) | ||
| 1703 | +#endif | ||
| 1704 | + { | ||
| 1705 | + if (!_M_data) | ||
| 1706 | + _M_data = new __moneypunct_cache<wchar_t, true>; | ||
| 1707 | + | ||
| 1708 | + if (!__cloc) | ||
| 1709 | + { | ||
| 1710 | + // "C" locale | ||
| 1711 | + _M_data->_M_decimal_point = L'.'; | ||
| 1712 | + _M_data->_M_thousands_sep = L','; | ||
| 1713 | + _M_data->_M_grouping = ""; | ||
| 1714 | + _M_data->_M_grouping_size = 0; | ||
| 1715 | + _M_data->_M_curr_symbol = L""; | ||
| 1716 | + _M_data->_M_curr_symbol_size = 0; | ||
| 1717 | + _M_data->_M_positive_sign = L""; | ||
| 1718 | + _M_data->_M_positive_sign_size = 0; | ||
| 1719 | + _M_data->_M_negative_sign = L""; | ||
| 1720 | + _M_data->_M_negative_sign_size = 0; | ||
| 1721 | + _M_data->_M_frac_digits = 0; | ||
| 1722 | + _M_data->_M_pos_format = money_base::_S_default_pattern; | ||
| 1723 | + _M_data->_M_neg_format = money_base::_S_default_pattern; | ||
| 1724 | + | ||
| 1725 | + // Use ctype::widen code without the facet... | ||
| 1726 | + for (size_t __i = 0; __i < money_base::_S_end; ++__i) | ||
| 1727 | + _M_data->_M_atoms[__i] = | ||
| 1728 | + static_cast<wchar_t>(money_base::_S_atoms[__i]); | ||
| 1729 | + } | ||
| 1730 | + else | ||
| 1731 | + { | ||
| 1732 | + // Named locale. | ||
| 1733 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1734 | + __c_locale __old = __uselocale(__cloc); | ||
| 1735 | +#else | ||
| 1736 | + // Switch to named locale so that mbsrtowcs will work. | ||
| 1737 | + char* __old = strdup(setlocale(LC_ALL, NULL)); | ||
| 1738 | + setlocale(LC_ALL, __name); | ||
| 1739 | +#endif | ||
| 1740 | + | ||
| 1741 | +#ifdef __UCLIBC_MJN3_ONLY__ | ||
| 1742 | +#warning fix this... should be monetary | ||
| 1743 | +#endif | ||
| 1744 | +#ifdef __UCLIBC__ | ||
| 1745 | +# ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1746 | + _M_data->_M_decimal_point = __cloc->decimal_point_wc; | ||
| 1747 | + _M_data->_M_thousands_sep = __cloc->thousands_sep_wc; | ||
| 1748 | +# else | ||
| 1749 | + _M_data->_M_decimal_point = __global_locale->decimal_point_wc; | ||
| 1750 | + _M_data->_M_thousands_sep = __global_locale->thousands_sep_wc; | ||
| 1751 | +# endif | ||
| 1752 | +#else | ||
| 1753 | + union { char *__s; wchar_t __w; } __u; | ||
| 1754 | + __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc); | ||
| 1755 | + _M_data->_M_decimal_point = __u.__w; | ||
| 1756 | + | ||
| 1757 | + __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc); | ||
| 1758 | + _M_data->_M_thousands_sep = __u.__w; | ||
| 1759 | +#endif | ||
| 1760 | + _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); | ||
| 1761 | + _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); | ||
| 1762 | + | ||
| 1763 | + const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); | ||
| 1764 | + const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); | ||
| 1765 | + const char* __ccurr = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc); | ||
| 1766 | + | ||
| 1767 | + wchar_t* __wcs_ps = 0; | ||
| 1768 | + wchar_t* __wcs_ns = 0; | ||
| 1769 | + const char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc)); | ||
| 1770 | + try | ||
| 1771 | + { | ||
| 1772 | + mbstate_t __state; | ||
| 1773 | + size_t __len = strlen(__cpossign); | ||
| 1774 | + if (__len) | ||
| 1775 | + { | ||
| 1776 | + ++__len; | ||
| 1777 | + memset(&__state, 0, sizeof(mbstate_t)); | ||
| 1778 | + __wcs_ps = new wchar_t[__len]; | ||
| 1779 | + mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state); | ||
| 1780 | + _M_data->_M_positive_sign = __wcs_ps; | ||
| 1781 | + } | ||
| 1782 | + else | ||
| 1783 | + _M_data->_M_positive_sign = L""; | ||
| 1784 | + _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign); | ||
| 1785 | + | ||
| 1786 | + __len = strlen(__cnegsign); | ||
| 1787 | + if (!__nposn) | ||
| 1788 | + _M_data->_M_negative_sign = L"()"; | ||
| 1789 | + else if (__len) | ||
| 1790 | + { | ||
| 1791 | + ++__len; | ||
| 1792 | + memset(&__state, 0, sizeof(mbstate_t)); | ||
| 1793 | + __wcs_ns = new wchar_t[__len]; | ||
| 1794 | + mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state); | ||
| 1795 | + _M_data->_M_negative_sign = __wcs_ns; | ||
| 1796 | + } | ||
| 1797 | + else | ||
| 1798 | + _M_data->_M_negative_sign = L""; | ||
| 1799 | + _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign); | ||
| 1800 | + | ||
| 1801 | + // _Intl == true. | ||
| 1802 | + __len = strlen(__ccurr); | ||
| 1803 | + if (__len) | ||
| 1804 | + { | ||
| 1805 | + ++__len; | ||
| 1806 | + memset(&__state, 0, sizeof(mbstate_t)); | ||
| 1807 | + wchar_t* __wcs = new wchar_t[__len]; | ||
| 1808 | + mbsrtowcs(__wcs, &__ccurr, __len, &__state); | ||
| 1809 | + _M_data->_M_curr_symbol = __wcs; | ||
| 1810 | + } | ||
| 1811 | + else | ||
| 1812 | + _M_data->_M_curr_symbol = L""; | ||
| 1813 | + _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol); | ||
| 1814 | + } | ||
| 1815 | + catch (...) | ||
| 1816 | + { | ||
| 1817 | + delete _M_data; | ||
| 1818 | + _M_data = 0; | ||
| 1819 | + delete __wcs_ps; | ||
| 1820 | + delete __wcs_ns; | ||
| 1821 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1822 | + __uselocale(__old); | ||
| 1823 | +#else | ||
| 1824 | + setlocale(LC_ALL, __old); | ||
| 1825 | + free(__old); | ||
| 1826 | +#endif | ||
| 1827 | + __throw_exception_again; | ||
| 1828 | + } | ||
| 1829 | + | ||
| 1830 | + _M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS, | ||
| 1831 | + __cloc)); | ||
| 1832 | + char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc)); | ||
| 1833 | + char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc)); | ||
| 1834 | + char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc)); | ||
| 1835 | + _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, | ||
| 1836 | + __pposn); | ||
| 1837 | + char __nprecedes = *(__nl_langinfo_l(__INT_N_CS_PRECEDES, __cloc)); | ||
| 1838 | + char __nspace = *(__nl_langinfo_l(__INT_N_SEP_BY_SPACE, __cloc)); | ||
| 1839 | + _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, | ||
| 1840 | + __nposn); | ||
| 1841 | + | ||
| 1842 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1843 | + __uselocale(__old); | ||
| 1844 | +#else | ||
| 1845 | + setlocale(LC_ALL, __old); | ||
| 1846 | + free(__old); | ||
| 1847 | +#endif | ||
| 1848 | + } | ||
| 1849 | + } | ||
| 1850 | + | ||
| 1851 | + template<> | ||
| 1852 | + void | ||
| 1853 | + moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale __cloc, | ||
| 1854 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1855 | + const char*) | ||
| 1856 | +#else | ||
| 1857 | + const char* __name) | ||
| 1858 | +#endif | ||
| 1859 | + { | ||
| 1860 | + if (!_M_data) | ||
| 1861 | + _M_data = new __moneypunct_cache<wchar_t, false>; | ||
| 1862 | + | ||
| 1863 | + if (!__cloc) | ||
| 1864 | + { | ||
| 1865 | + // "C" locale | ||
| 1866 | + _M_data->_M_decimal_point = L'.'; | ||
| 1867 | + _M_data->_M_thousands_sep = L','; | ||
| 1868 | + _M_data->_M_grouping = ""; | ||
| 1869 | + _M_data->_M_grouping_size = 0; | ||
| 1870 | + _M_data->_M_curr_symbol = L""; | ||
| 1871 | + _M_data->_M_curr_symbol_size = 0; | ||
| 1872 | + _M_data->_M_positive_sign = L""; | ||
| 1873 | + _M_data->_M_positive_sign_size = 0; | ||
| 1874 | + _M_data->_M_negative_sign = L""; | ||
| 1875 | + _M_data->_M_negative_sign_size = 0; | ||
| 1876 | + _M_data->_M_frac_digits = 0; | ||
| 1877 | + _M_data->_M_pos_format = money_base::_S_default_pattern; | ||
| 1878 | + _M_data->_M_neg_format = money_base::_S_default_pattern; | ||
| 1879 | + | ||
| 1880 | + // Use ctype::widen code without the facet... | ||
| 1881 | + for (size_t __i = 0; __i < money_base::_S_end; ++__i) | ||
| 1882 | + _M_data->_M_atoms[__i] = | ||
| 1883 | + static_cast<wchar_t>(money_base::_S_atoms[__i]); | ||
| 1884 | + } | ||
| 1885 | + else | ||
| 1886 | + { | ||
| 1887 | + // Named locale. | ||
| 1888 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1889 | + __c_locale __old = __uselocale(__cloc); | ||
| 1890 | +#else | ||
| 1891 | + // Switch to named locale so that mbsrtowcs will work. | ||
| 1892 | + char* __old = strdup(setlocale(LC_ALL, NULL)); | ||
| 1893 | + setlocale(LC_ALL, __name); | ||
| 1894 | +#endif | ||
| 1895 | + | ||
| 1896 | +#ifdef __UCLIBC_MJN3_ONLY__ | ||
| 1897 | +#warning fix this... should be monetary | ||
| 1898 | +#endif | ||
| 1899 | +#ifdef __UCLIBC__ | ||
| 1900 | +# ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1901 | + _M_data->_M_decimal_point = __cloc->decimal_point_wc; | ||
| 1902 | + _M_data->_M_thousands_sep = __cloc->thousands_sep_wc; | ||
| 1903 | +# else | ||
| 1904 | + _M_data->_M_decimal_point = __global_locale->decimal_point_wc; | ||
| 1905 | + _M_data->_M_thousands_sep = __global_locale->thousands_sep_wc; | ||
| 1906 | +# endif | ||
| 1907 | +#else | ||
| 1908 | + union { char *__s; wchar_t __w; } __u; | ||
| 1909 | + __u.__s = __nl_langinfo_l(_NL_MONETARY_DECIMAL_POINT_WC, __cloc); | ||
| 1910 | + _M_data->_M_decimal_point = __u.__w; | ||
| 1911 | + | ||
| 1912 | + __u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc); | ||
| 1913 | + _M_data->_M_thousands_sep = __u.__w; | ||
| 1914 | +#endif | ||
| 1915 | + _M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc); | ||
| 1916 | + _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); | ||
| 1917 | + | ||
| 1918 | + const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc); | ||
| 1919 | + const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc); | ||
| 1920 | + const char* __ccurr = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc); | ||
| 1921 | + | ||
| 1922 | + wchar_t* __wcs_ps = 0; | ||
| 1923 | + wchar_t* __wcs_ns = 0; | ||
| 1924 | + const char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc)); | ||
| 1925 | + try | ||
| 1926 | + { | ||
| 1927 | + mbstate_t __state; | ||
| 1928 | + size_t __len; | ||
| 1929 | + __len = strlen(__cpossign); | ||
| 1930 | + if (__len) | ||
| 1931 | + { | ||
| 1932 | + ++__len; | ||
| 1933 | + memset(&__state, 0, sizeof(mbstate_t)); | ||
| 1934 | + __wcs_ps = new wchar_t[__len]; | ||
| 1935 | + mbsrtowcs(__wcs_ps, &__cpossign, __len, &__state); | ||
| 1936 | + _M_data->_M_positive_sign = __wcs_ps; | ||
| 1937 | + } | ||
| 1938 | + else | ||
| 1939 | + _M_data->_M_positive_sign = L""; | ||
| 1940 | + _M_data->_M_positive_sign_size = wcslen(_M_data->_M_positive_sign); | ||
| 1941 | + | ||
| 1942 | + __len = strlen(__cnegsign); | ||
| 1943 | + if (!__nposn) | ||
| 1944 | + _M_data->_M_negative_sign = L"()"; | ||
| 1945 | + else if (__len) | ||
| 1946 | + { | ||
| 1947 | + ++__len; | ||
| 1948 | + memset(&__state, 0, sizeof(mbstate_t)); | ||
| 1949 | + __wcs_ns = new wchar_t[__len]; | ||
| 1950 | + mbsrtowcs(__wcs_ns, &__cnegsign, __len, &__state); | ||
| 1951 | + _M_data->_M_negative_sign = __wcs_ns; | ||
| 1952 | + } | ||
| 1953 | + else | ||
| 1954 | + _M_data->_M_negative_sign = L""; | ||
| 1955 | + _M_data->_M_negative_sign_size = wcslen(_M_data->_M_negative_sign); | ||
| 1956 | + | ||
| 1957 | + // _Intl == true. | ||
| 1958 | + __len = strlen(__ccurr); | ||
| 1959 | + if (__len) | ||
| 1960 | + { | ||
| 1961 | + ++__len; | ||
| 1962 | + memset(&__state, 0, sizeof(mbstate_t)); | ||
| 1963 | + wchar_t* __wcs = new wchar_t[__len]; | ||
| 1964 | + mbsrtowcs(__wcs, &__ccurr, __len, &__state); | ||
| 1965 | + _M_data->_M_curr_symbol = __wcs; | ||
| 1966 | + } | ||
| 1967 | + else | ||
| 1968 | + _M_data->_M_curr_symbol = L""; | ||
| 1969 | + _M_data->_M_curr_symbol_size = wcslen(_M_data->_M_curr_symbol); | ||
| 1970 | + } | ||
| 1971 | + catch (...) | ||
| 1972 | + { | ||
| 1973 | + delete _M_data; | ||
| 1974 | + _M_data = 0; | ||
| 1975 | + delete __wcs_ps; | ||
| 1976 | + delete __wcs_ns; | ||
| 1977 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1978 | + __uselocale(__old); | ||
| 1979 | +#else | ||
| 1980 | + setlocale(LC_ALL, __old); | ||
| 1981 | + free(__old); | ||
| 1982 | +#endif | ||
| 1983 | + __throw_exception_again; | ||
| 1984 | + } | ||
| 1985 | + | ||
| 1986 | + _M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc)); | ||
| 1987 | + char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc)); | ||
| 1988 | + char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc)); | ||
| 1989 | + char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc)); | ||
| 1990 | + _M_data->_M_pos_format = _S_construct_pattern(__pprecedes, __pspace, | ||
| 1991 | + __pposn); | ||
| 1992 | + char __nprecedes = *(__nl_langinfo_l(__N_CS_PRECEDES, __cloc)); | ||
| 1993 | + char __nspace = *(__nl_langinfo_l(__N_SEP_BY_SPACE, __cloc)); | ||
| 1994 | + _M_data->_M_neg_format = _S_construct_pattern(__nprecedes, __nspace, | ||
| 1995 | + __nposn); | ||
| 1996 | + | ||
| 1997 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 1998 | + __uselocale(__old); | ||
| 1999 | +#else | ||
| 2000 | + setlocale(LC_ALL, __old); | ||
| 2001 | + free(__old); | ||
| 2002 | +#endif | ||
| 2003 | + } | ||
| 2004 | + } | ||
| 2005 | + | ||
| 2006 | + template<> | ||
| 2007 | + moneypunct<wchar_t, true>::~moneypunct() | ||
| 2008 | + { | ||
| 2009 | + if (_M_data->_M_positive_sign_size) | ||
| 2010 | + delete [] _M_data->_M_positive_sign; | ||
| 2011 | + if (_M_data->_M_negative_sign_size | ||
| 2012 | + && wcscmp(_M_data->_M_negative_sign, L"()") != 0) | ||
| 2013 | + delete [] _M_data->_M_negative_sign; | ||
| 2014 | + if (_M_data->_M_curr_symbol_size) | ||
| 2015 | + delete [] _M_data->_M_curr_symbol; | ||
| 2016 | + delete _M_data; | ||
| 2017 | + } | ||
| 2018 | + | ||
| 2019 | + template<> | ||
| 2020 | + moneypunct<wchar_t, false>::~moneypunct() | ||
| 2021 | + { | ||
| 2022 | + if (_M_data->_M_positive_sign_size) | ||
| 2023 | + delete [] _M_data->_M_positive_sign; | ||
| 2024 | + if (_M_data->_M_negative_sign_size | ||
| 2025 | + && wcscmp(_M_data->_M_negative_sign, L"()") != 0) | ||
| 2026 | + delete [] _M_data->_M_negative_sign; | ||
| 2027 | + if (_M_data->_M_curr_symbol_size) | ||
| 2028 | + delete [] _M_data->_M_curr_symbol; | ||
| 2029 | + delete _M_data; | ||
| 2030 | + } | ||
| 2031 | +#endif | ||
| 2032 | +} | ||
| 2033 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/numeric_members.cc gcc-4.0.0/libstdc++-v3/config/locale/uclibc/numeric_members.cc | ||
| 2034 | --- gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/numeric_members.cc 1969-12-31 18:00:00.000000000 -0600 | ||
| 2035 | +++ gcc-4.0.0/libstdc++-v3/config/locale/uclibc/numeric_members.cc 2005-04-28 01:20:20.000000000 -0500 | ||
| 2036 | @@ -0,0 +1,173 @@ | ||
| 2037 | +// std::numpunct implementation details, GNU version -*- C++ -*- | ||
| 2038 | + | ||
| 2039 | +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. | ||
| 2040 | +// | ||
| 2041 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 2042 | +// software; you can redistribute it and/or modify it under the | ||
| 2043 | +// terms of the GNU General Public License as published by the | ||
| 2044 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 2045 | +// any later version. | ||
| 2046 | + | ||
| 2047 | +// This library is distributed in the hope that it will be useful, | ||
| 2048 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 2049 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 2050 | +// GNU General Public License for more details. | ||
| 2051 | + | ||
| 2052 | +// You should have received a copy of the GNU General Public License along | ||
| 2053 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 2054 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 2055 | +// USA. | ||
| 2056 | + | ||
| 2057 | +// As a special exception, you may use this file as part of a free software | ||
| 2058 | +// library without restriction. Specifically, if other files instantiate | ||
| 2059 | +// templates or use macros or inline functions from this file, or you compile | ||
| 2060 | +// this file and link it with other files to produce an executable, this | ||
| 2061 | +// file does not by itself cause the resulting executable to be covered by | ||
| 2062 | +// the GNU General Public License. This exception does not however | ||
| 2063 | +// invalidate any other reasons why the executable file might be covered by | ||
| 2064 | +// the GNU General Public License. | ||
| 2065 | + | ||
| 2066 | +// | ||
| 2067 | +// ISO C++ 14882: 22.2.3.1.2 numpunct virtual functions | ||
| 2068 | +// | ||
| 2069 | + | ||
| 2070 | +// Written by Benjamin Kosnik <bkoz@redhat.com> | ||
| 2071 | + | ||
| 2072 | +#define _LIBC | ||
| 2073 | +#include <locale> | ||
| 2074 | +#undef _LIBC | ||
| 2075 | +#include <bits/c++locale_internal.h> | ||
| 2076 | + | ||
| 2077 | +#ifdef __UCLIBC_MJN3_ONLY__ | ||
| 2078 | +#warning tailor for stub locale support | ||
| 2079 | +#endif | ||
| 2080 | +#ifndef __UCLIBC_HAS_XLOCALE__ | ||
| 2081 | +#define __nl_langinfo_l(N, L) nl_langinfo((N)) | ||
| 2082 | +#endif | ||
| 2083 | + | ||
| 2084 | +namespace std | ||
| 2085 | +{ | ||
| 2086 | + template<> | ||
| 2087 | + void | ||
| 2088 | + numpunct<char>::_M_initialize_numpunct(__c_locale __cloc) | ||
| 2089 | + { | ||
| 2090 | + if (!_M_data) | ||
| 2091 | + _M_data = new __numpunct_cache<char>; | ||
| 2092 | + | ||
| 2093 | + if (!__cloc) | ||
| 2094 | + { | ||
| 2095 | + // "C" locale | ||
| 2096 | + _M_data->_M_grouping = ""; | ||
| 2097 | + _M_data->_M_grouping_size = 0; | ||
| 2098 | + _M_data->_M_use_grouping = false; | ||
| 2099 | + | ||
| 2100 | + _M_data->_M_decimal_point = '.'; | ||
| 2101 | + _M_data->_M_thousands_sep = ','; | ||
| 2102 | + | ||
| 2103 | + for (size_t __i = 0; __i < __num_base::_S_oend; ++__i) | ||
| 2104 | + _M_data->_M_atoms_out[__i] = __num_base::_S_atoms_out[__i]; | ||
| 2105 | + | ||
| 2106 | + for (size_t __j = 0; __j < __num_base::_S_iend; ++__j) | ||
| 2107 | + _M_data->_M_atoms_in[__j] = __num_base::_S_atoms_in[__j]; | ||
| 2108 | + } | ||
| 2109 | + else | ||
| 2110 | + { | ||
| 2111 | + // Named locale. | ||
| 2112 | + _M_data->_M_decimal_point = *(__nl_langinfo_l(DECIMAL_POINT, | ||
| 2113 | + __cloc)); | ||
| 2114 | + _M_data->_M_thousands_sep = *(__nl_langinfo_l(THOUSANDS_SEP, | ||
| 2115 | + __cloc)); | ||
| 2116 | + | ||
| 2117 | + // Check for NULL, which implies no grouping. | ||
| 2118 | + if (_M_data->_M_thousands_sep == '\0') | ||
| 2119 | + _M_data->_M_grouping = ""; | ||
| 2120 | + else | ||
| 2121 | + _M_data->_M_grouping = __nl_langinfo_l(GROUPING, __cloc); | ||
| 2122 | + _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); | ||
| 2123 | + } | ||
| 2124 | + | ||
| 2125 | + // NB: There is no way to extact this info from posix locales. | ||
| 2126 | + // _M_truename = __nl_langinfo_l(YESSTR, __cloc); | ||
| 2127 | + _M_data->_M_truename = "true"; | ||
| 2128 | + _M_data->_M_truename_size = 4; | ||
| 2129 | + // _M_falsename = __nl_langinfo_l(NOSTR, __cloc); | ||
| 2130 | + _M_data->_M_falsename = "false"; | ||
| 2131 | + _M_data->_M_falsename_size = 5; | ||
| 2132 | + } | ||
| 2133 | + | ||
| 2134 | + template<> | ||
| 2135 | + numpunct<char>::~numpunct() | ||
| 2136 | + { delete _M_data; } | ||
| 2137 | + | ||
| 2138 | +#ifdef _GLIBCXX_USE_WCHAR_T | ||
| 2139 | + template<> | ||
| 2140 | + void | ||
| 2141 | + numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc) | ||
| 2142 | + { | ||
| 2143 | + if (!_M_data) | ||
| 2144 | + _M_data = new __numpunct_cache<wchar_t>; | ||
| 2145 | + | ||
| 2146 | + if (!__cloc) | ||
| 2147 | + { | ||
| 2148 | + // "C" locale | ||
| 2149 | + _M_data->_M_grouping = ""; | ||
| 2150 | + _M_data->_M_grouping_size = 0; | ||
| 2151 | + _M_data->_M_use_grouping = false; | ||
| 2152 | + | ||
| 2153 | + _M_data->_M_decimal_point = L'.'; | ||
| 2154 | + _M_data->_M_thousands_sep = L','; | ||
| 2155 | + | ||
| 2156 | + // Use ctype::widen code without the facet... | ||
| 2157 | + for (size_t __i = 0; __i < __num_base::_S_oend; ++__i) | ||
| 2158 | + _M_data->_M_atoms_out[__i] = | ||
| 2159 | + static_cast<wchar_t>(__num_base::_S_atoms_out[__i]); | ||
| 2160 | + | ||
| 2161 | + for (size_t __j = 0; __j < __num_base::_S_iend; ++__j) | ||
| 2162 | + _M_data->_M_atoms_in[__j] = | ||
| 2163 | + static_cast<wchar_t>(__num_base::_S_atoms_in[__j]); | ||
| 2164 | + } | ||
| 2165 | + else | ||
| 2166 | + { | ||
| 2167 | + // Named locale. | ||
| 2168 | + // NB: In the GNU model wchar_t is always 32 bit wide. | ||
| 2169 | +#ifdef __UCLIBC_MJN3_ONLY__ | ||
| 2170 | +#warning fix this | ||
| 2171 | +#endif | ||
| 2172 | +#ifdef __UCLIBC__ | ||
| 2173 | +# ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 2174 | + _M_data->_M_decimal_point = __cloc->decimal_point_wc; | ||
| 2175 | + _M_data->_M_thousands_sep = __cloc->thousands_sep_wc; | ||
| 2176 | +# else | ||
| 2177 | + _M_data->_M_decimal_point = __global_locale->decimal_point_wc; | ||
| 2178 | + _M_data->_M_thousands_sep = __global_locale->thousands_sep_wc; | ||
| 2179 | +# endif | ||
| 2180 | +#else | ||
| 2181 | + union { char *__s; wchar_t __w; } __u; | ||
| 2182 | + __u.__s = __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc); | ||
| 2183 | + _M_data->_M_decimal_point = __u.__w; | ||
| 2184 | + | ||
| 2185 | + __u.__s = __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc); | ||
| 2186 | + _M_data->_M_thousands_sep = __u.__w; | ||
| 2187 | +#endif | ||
| 2188 | + | ||
| 2189 | + if (_M_data->_M_thousands_sep == L'\0') | ||
| 2190 | + _M_data->_M_grouping = ""; | ||
| 2191 | + else | ||
| 2192 | + _M_data->_M_grouping = __nl_langinfo_l(GROUPING, __cloc); | ||
| 2193 | + _M_data->_M_grouping_size = strlen(_M_data->_M_grouping); | ||
| 2194 | + } | ||
| 2195 | + | ||
| 2196 | + // NB: There is no way to extact this info from posix locales. | ||
| 2197 | + // _M_truename = __nl_langinfo_l(YESSTR, __cloc); | ||
| 2198 | + _M_data->_M_truename = L"true"; | ||
| 2199 | + _M_data->_M_truename_size = 4; | ||
| 2200 | + // _M_falsename = __nl_langinfo_l(NOSTR, __cloc); | ||
| 2201 | + _M_data->_M_falsename = L"false"; | ||
| 2202 | + _M_data->_M_falsename_size = 5; | ||
| 2203 | + } | ||
| 2204 | + | ||
| 2205 | + template<> | ||
| 2206 | + numpunct<wchar_t>::~numpunct() | ||
| 2207 | + { delete _M_data; } | ||
| 2208 | + #endif | ||
| 2209 | +} | ||
| 2210 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/time_members.cc gcc-4.0.0/libstdc++-v3/config/locale/uclibc/time_members.cc | ||
| 2211 | --- gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/time_members.cc 1969-12-31 18:00:00.000000000 -0600 | ||
| 2212 | +++ gcc-4.0.0/libstdc++-v3/config/locale/uclibc/time_members.cc 2005-04-28 01:13:15.000000000 -0500 | ||
| 2213 | @@ -0,0 +1,406 @@ | ||
| 2214 | +// std::time_get, std::time_put implementation, GNU version -*- C++ -*- | ||
| 2215 | + | ||
| 2216 | +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. | ||
| 2217 | +// | ||
| 2218 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 2219 | +// software; you can redistribute it and/or modify it under the | ||
| 2220 | +// terms of the GNU General Public License as published by the | ||
| 2221 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 2222 | +// any later version. | ||
| 2223 | + | ||
| 2224 | +// This library is distributed in the hope that it will be useful, | ||
| 2225 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 2226 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 2227 | +// GNU General Public License for more details. | ||
| 2228 | + | ||
| 2229 | +// You should have received a copy of the GNU General Public License along | ||
| 2230 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 2231 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 2232 | +// USA. | ||
| 2233 | + | ||
| 2234 | +// As a special exception, you may use this file as part of a free software | ||
| 2235 | +// library without restriction. Specifically, if other files instantiate | ||
| 2236 | +// templates or use macros or inline functions from this file, or you compile | ||
| 2237 | +// this file and link it with other files to produce an executable, this | ||
| 2238 | +// file does not by itself cause the resulting executable to be covered by | ||
| 2239 | +// the GNU General Public License. This exception does not however | ||
| 2240 | +// invalidate any other reasons why the executable file might be covered by | ||
| 2241 | +// the GNU General Public License. | ||
| 2242 | + | ||
| 2243 | +// | ||
| 2244 | +// ISO C++ 14882: 22.2.5.1.2 - time_get virtual functions | ||
| 2245 | +// ISO C++ 14882: 22.2.5.3.2 - time_put virtual functions | ||
| 2246 | +// | ||
| 2247 | + | ||
| 2248 | +// Written by Benjamin Kosnik <bkoz@redhat.com> | ||
| 2249 | + | ||
| 2250 | +#include <locale> | ||
| 2251 | +#include <bits/c++locale_internal.h> | ||
| 2252 | + | ||
| 2253 | +#ifdef __UCLIBC_MJN3_ONLY__ | ||
| 2254 | +#warning tailor for stub locale support | ||
| 2255 | +#endif | ||
| 2256 | +#ifndef __UCLIBC_HAS_XLOCALE__ | ||
| 2257 | +#define __nl_langinfo_l(N, L) nl_langinfo((N)) | ||
| 2258 | +#endif | ||
| 2259 | + | ||
| 2260 | +namespace std | ||
| 2261 | +{ | ||
| 2262 | + template<> | ||
| 2263 | + void | ||
| 2264 | + __timepunct<char>:: | ||
| 2265 | + _M_put(char* __s, size_t __maxlen, const char* __format, | ||
| 2266 | + const tm* __tm) const | ||
| 2267 | + { | ||
| 2268 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 2269 | + const size_t __len = __strftime_l(__s, __maxlen, __format, __tm, | ||
| 2270 | + _M_c_locale_timepunct); | ||
| 2271 | +#else | ||
| 2272 | + char* __old = strdup(setlocale(LC_ALL, NULL)); | ||
| 2273 | + setlocale(LC_ALL, _M_name_timepunct); | ||
| 2274 | + const size_t __len = strftime(__s, __maxlen, __format, __tm); | ||
| 2275 | + setlocale(LC_ALL, __old); | ||
| 2276 | + free(__old); | ||
| 2277 | +#endif | ||
| 2278 | + // Make sure __s is null terminated. | ||
| 2279 | + if (__len == 0) | ||
| 2280 | + __s[0] = '\0'; | ||
| 2281 | + } | ||
| 2282 | + | ||
| 2283 | + template<> | ||
| 2284 | + void | ||
| 2285 | + __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc) | ||
| 2286 | + { | ||
| 2287 | + if (!_M_data) | ||
| 2288 | + _M_data = new __timepunct_cache<char>; | ||
| 2289 | + | ||
| 2290 | + if (!__cloc) | ||
| 2291 | + { | ||
| 2292 | + // "C" locale | ||
| 2293 | + _M_c_locale_timepunct = _S_get_c_locale(); | ||
| 2294 | + | ||
| 2295 | + _M_data->_M_date_format = "%m/%d/%y"; | ||
| 2296 | + _M_data->_M_date_era_format = "%m/%d/%y"; | ||
| 2297 | + _M_data->_M_time_format = "%H:%M:%S"; | ||
| 2298 | + _M_data->_M_time_era_format = "%H:%M:%S"; | ||
| 2299 | + _M_data->_M_date_time_format = ""; | ||
| 2300 | + _M_data->_M_date_time_era_format = ""; | ||
| 2301 | + _M_data->_M_am = "AM"; | ||
| 2302 | + _M_data->_M_pm = "PM"; | ||
| 2303 | + _M_data->_M_am_pm_format = ""; | ||
| 2304 | + | ||
| 2305 | + // Day names, starting with "C"'s Sunday. | ||
| 2306 | + _M_data->_M_day1 = "Sunday"; | ||
| 2307 | + _M_data->_M_day2 = "Monday"; | ||
| 2308 | + _M_data->_M_day3 = "Tuesday"; | ||
| 2309 | + _M_data->_M_day4 = "Wednesday"; | ||
| 2310 | + _M_data->_M_day5 = "Thursday"; | ||
| 2311 | + _M_data->_M_day6 = "Friday"; | ||
| 2312 | + _M_data->_M_day7 = "Saturday"; | ||
| 2313 | + | ||
| 2314 | + // Abbreviated day names, starting with "C"'s Sun. | ||
| 2315 | + _M_data->_M_aday1 = "Sun"; | ||
| 2316 | + _M_data->_M_aday2 = "Mon"; | ||
| 2317 | + _M_data->_M_aday3 = "Tue"; | ||
| 2318 | + _M_data->_M_aday4 = "Wed"; | ||
| 2319 | + _M_data->_M_aday5 = "Thu"; | ||
| 2320 | + _M_data->_M_aday6 = "Fri"; | ||
| 2321 | + _M_data->_M_aday7 = "Sat"; | ||
| 2322 | + | ||
| 2323 | + // Month names, starting with "C"'s January. | ||
| 2324 | + _M_data->_M_month01 = "January"; | ||
| 2325 | + _M_data->_M_month02 = "February"; | ||
| 2326 | + _M_data->_M_month03 = "March"; | ||
| 2327 | + _M_data->_M_month04 = "April"; | ||
| 2328 | + _M_data->_M_month05 = "May"; | ||
| 2329 | + _M_data->_M_month06 = "June"; | ||
| 2330 | + _M_data->_M_month07 = "July"; | ||
| 2331 | + _M_data->_M_month08 = "August"; | ||
| 2332 | + _M_data->_M_month09 = "September"; | ||
| 2333 | + _M_data->_M_month10 = "October"; | ||
| 2334 | + _M_data->_M_month11 = "November"; | ||
| 2335 | + _M_data->_M_month12 = "December"; | ||
| 2336 | + | ||
| 2337 | + // Abbreviated month names, starting with "C"'s Jan. | ||
| 2338 | + _M_data->_M_amonth01 = "Jan"; | ||
| 2339 | + _M_data->_M_amonth02 = "Feb"; | ||
| 2340 | + _M_data->_M_amonth03 = "Mar"; | ||
| 2341 | + _M_data->_M_amonth04 = "Apr"; | ||
| 2342 | + _M_data->_M_amonth05 = "May"; | ||
| 2343 | + _M_data->_M_amonth06 = "Jun"; | ||
| 2344 | + _M_data->_M_amonth07 = "Jul"; | ||
| 2345 | + _M_data->_M_amonth08 = "Aug"; | ||
| 2346 | + _M_data->_M_amonth09 = "Sep"; | ||
| 2347 | + _M_data->_M_amonth10 = "Oct"; | ||
| 2348 | + _M_data->_M_amonth11 = "Nov"; | ||
| 2349 | + _M_data->_M_amonth12 = "Dec"; | ||
| 2350 | + } | ||
| 2351 | + else | ||
| 2352 | + { | ||
| 2353 | + _M_c_locale_timepunct = _S_clone_c_locale(__cloc); | ||
| 2354 | + | ||
| 2355 | + _M_data->_M_date_format = __nl_langinfo_l(D_FMT, __cloc); | ||
| 2356 | + _M_data->_M_date_era_format = __nl_langinfo_l(ERA_D_FMT, __cloc); | ||
| 2357 | + _M_data->_M_time_format = __nl_langinfo_l(T_FMT, __cloc); | ||
| 2358 | + _M_data->_M_time_era_format = __nl_langinfo_l(ERA_T_FMT, __cloc); | ||
| 2359 | + _M_data->_M_date_time_format = __nl_langinfo_l(D_T_FMT, __cloc); | ||
| 2360 | + _M_data->_M_date_time_era_format = __nl_langinfo_l(ERA_D_T_FMT, | ||
| 2361 | + __cloc); | ||
| 2362 | + _M_data->_M_am = __nl_langinfo_l(AM_STR, __cloc); | ||
| 2363 | + _M_data->_M_pm = __nl_langinfo_l(PM_STR, __cloc); | ||
| 2364 | + _M_data->_M_am_pm_format = __nl_langinfo_l(T_FMT_AMPM, __cloc); | ||
| 2365 | + | ||
| 2366 | + // Day names, starting with "C"'s Sunday. | ||
| 2367 | + _M_data->_M_day1 = __nl_langinfo_l(DAY_1, __cloc); | ||
| 2368 | + _M_data->_M_day2 = __nl_langinfo_l(DAY_2, __cloc); | ||
| 2369 | + _M_data->_M_day3 = __nl_langinfo_l(DAY_3, __cloc); | ||
| 2370 | + _M_data->_M_day4 = __nl_langinfo_l(DAY_4, __cloc); | ||
| 2371 | + _M_data->_M_day5 = __nl_langinfo_l(DAY_5, __cloc); | ||
| 2372 | + _M_data->_M_day6 = __nl_langinfo_l(DAY_6, __cloc); | ||
| 2373 | + _M_data->_M_day7 = __nl_langinfo_l(DAY_7, __cloc); | ||
| 2374 | + | ||
| 2375 | + // Abbreviated day names, starting with "C"'s Sun. | ||
| 2376 | + _M_data->_M_aday1 = __nl_langinfo_l(ABDAY_1, __cloc); | ||
| 2377 | + _M_data->_M_aday2 = __nl_langinfo_l(ABDAY_2, __cloc); | ||
| 2378 | + _M_data->_M_aday3 = __nl_langinfo_l(ABDAY_3, __cloc); | ||
| 2379 | + _M_data->_M_aday4 = __nl_langinfo_l(ABDAY_4, __cloc); | ||
| 2380 | + _M_data->_M_aday5 = __nl_langinfo_l(ABDAY_5, __cloc); | ||
| 2381 | + _M_data->_M_aday6 = __nl_langinfo_l(ABDAY_6, __cloc); | ||
| 2382 | + _M_data->_M_aday7 = __nl_langinfo_l(ABDAY_7, __cloc); | ||
| 2383 | + | ||
| 2384 | + // Month names, starting with "C"'s January. | ||
| 2385 | + _M_data->_M_month01 = __nl_langinfo_l(MON_1, __cloc); | ||
| 2386 | + _M_data->_M_month02 = __nl_langinfo_l(MON_2, __cloc); | ||
| 2387 | + _M_data->_M_month03 = __nl_langinfo_l(MON_3, __cloc); | ||
| 2388 | + _M_data->_M_month04 = __nl_langinfo_l(MON_4, __cloc); | ||
| 2389 | + _M_data->_M_month05 = __nl_langinfo_l(MON_5, __cloc); | ||
| 2390 | + _M_data->_M_month06 = __nl_langinfo_l(MON_6, __cloc); | ||
| 2391 | + _M_data->_M_month07 = __nl_langinfo_l(MON_7, __cloc); | ||
| 2392 | + _M_data->_M_month08 = __nl_langinfo_l(MON_8, __cloc); | ||
| 2393 | + _M_data->_M_month09 = __nl_langinfo_l(MON_9, __cloc); | ||
| 2394 | + _M_data->_M_month10 = __nl_langinfo_l(MON_10, __cloc); | ||
| 2395 | + _M_data->_M_month11 = __nl_langinfo_l(MON_11, __cloc); | ||
| 2396 | + _M_data->_M_month12 = __nl_langinfo_l(MON_12, __cloc); | ||
| 2397 | + | ||
| 2398 | + // Abbreviated month names, starting with "C"'s Jan. | ||
| 2399 | + _M_data->_M_amonth01 = __nl_langinfo_l(ABMON_1, __cloc); | ||
| 2400 | + _M_data->_M_amonth02 = __nl_langinfo_l(ABMON_2, __cloc); | ||
| 2401 | + _M_data->_M_amonth03 = __nl_langinfo_l(ABMON_3, __cloc); | ||
| 2402 | + _M_data->_M_amonth04 = __nl_langinfo_l(ABMON_4, __cloc); | ||
| 2403 | + _M_data->_M_amonth05 = __nl_langinfo_l(ABMON_5, __cloc); | ||
| 2404 | + _M_data->_M_amonth06 = __nl_langinfo_l(ABMON_6, __cloc); | ||
| 2405 | + _M_data->_M_amonth07 = __nl_langinfo_l(ABMON_7, __cloc); | ||
| 2406 | + _M_data->_M_amonth08 = __nl_langinfo_l(ABMON_8, __cloc); | ||
| 2407 | + _M_data->_M_amonth09 = __nl_langinfo_l(ABMON_9, __cloc); | ||
| 2408 | + _M_data->_M_amonth10 = __nl_langinfo_l(ABMON_10, __cloc); | ||
| 2409 | + _M_data->_M_amonth11 = __nl_langinfo_l(ABMON_11, __cloc); | ||
| 2410 | + _M_data->_M_amonth12 = __nl_langinfo_l(ABMON_12, __cloc); | ||
| 2411 | + } | ||
| 2412 | + } | ||
| 2413 | + | ||
| 2414 | +#ifdef _GLIBCXX_USE_WCHAR_T | ||
| 2415 | + template<> | ||
| 2416 | + void | ||
| 2417 | + __timepunct<wchar_t>:: | ||
| 2418 | + _M_put(wchar_t* __s, size_t __maxlen, const wchar_t* __format, | ||
| 2419 | + const tm* __tm) const | ||
| 2420 | + { | ||
| 2421 | +#ifdef __UCLIBC_HAS_XLOCALE__ | ||
| 2422 | + __wcsftime_l(__s, __maxlen, __format, __tm, _M_c_locale_timepunct); | ||
| 2423 | + const size_t __len = __wcsftime_l(__s, __maxlen, __format, __tm, | ||
| 2424 | + _M_c_locale_timepunct); | ||
| 2425 | +#else | ||
| 2426 | + char* __old = strdup(setlocale(LC_ALL, NULL)); | ||
| 2427 | + setlocale(LC_ALL, _M_name_timepunct); | ||
| 2428 | + const size_t __len = wcsftime(__s, __maxlen, __format, __tm); | ||
| 2429 | + setlocale(LC_ALL, __old); | ||
| 2430 | + free(__old); | ||
| 2431 | +#endif | ||
| 2432 | + // Make sure __s is null terminated. | ||
| 2433 | + if (__len == 0) | ||
| 2434 | + __s[0] = L'\0'; | ||
| 2435 | + } | ||
| 2436 | + | ||
| 2437 | + template<> | ||
| 2438 | + void | ||
| 2439 | + __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc) | ||
| 2440 | + { | ||
| 2441 | + if (!_M_data) | ||
| 2442 | + _M_data = new __timepunct_cache<wchar_t>; | ||
| 2443 | + | ||
| 2444 | +#warning wide time stuff | ||
| 2445 | +// if (!__cloc) | ||
| 2446 | + { | ||
| 2447 | + // "C" locale | ||
| 2448 | + _M_c_locale_timepunct = _S_get_c_locale(); | ||
| 2449 | + | ||
| 2450 | + _M_data->_M_date_format = L"%m/%d/%y"; | ||
| 2451 | + _M_data->_M_date_era_format = L"%m/%d/%y"; | ||
| 2452 | + _M_data->_M_time_format = L"%H:%M:%S"; | ||
| 2453 | + _M_data->_M_time_era_format = L"%H:%M:%S"; | ||
| 2454 | + _M_data->_M_date_time_format = L""; | ||
| 2455 | + _M_data->_M_date_time_era_format = L""; | ||
| 2456 | + _M_data->_M_am = L"AM"; | ||
| 2457 | + _M_data->_M_pm = L"PM"; | ||
| 2458 | + _M_data->_M_am_pm_format = L""; | ||
| 2459 | + | ||
| 2460 | + // Day names, starting with "C"'s Sunday. | ||
| 2461 | + _M_data->_M_day1 = L"Sunday"; | ||
| 2462 | + _M_data->_M_day2 = L"Monday"; | ||
| 2463 | + _M_data->_M_day3 = L"Tuesday"; | ||
| 2464 | + _M_data->_M_day4 = L"Wednesday"; | ||
| 2465 | + _M_data->_M_day5 = L"Thursday"; | ||
| 2466 | + _M_data->_M_day6 = L"Friday"; | ||
| 2467 | + _M_data->_M_day7 = L"Saturday"; | ||
| 2468 | + | ||
| 2469 | + // Abbreviated day names, starting with "C"'s Sun. | ||
| 2470 | + _M_data->_M_aday1 = L"Sun"; | ||
| 2471 | + _M_data->_M_aday2 = L"Mon"; | ||
| 2472 | + _M_data->_M_aday3 = L"Tue"; | ||
| 2473 | + _M_data->_M_aday4 = L"Wed"; | ||
| 2474 | + _M_data->_M_aday5 = L"Thu"; | ||
| 2475 | + _M_data->_M_aday6 = L"Fri"; | ||
| 2476 | + _M_data->_M_aday7 = L"Sat"; | ||
| 2477 | + | ||
| 2478 | + // Month names, starting with "C"'s January. | ||
| 2479 | + _M_data->_M_month01 = L"January"; | ||
| 2480 | + _M_data->_M_month02 = L"February"; | ||
| 2481 | + _M_data->_M_month03 = L"March"; | ||
| 2482 | + _M_data->_M_month04 = L"April"; | ||
| 2483 | + _M_data->_M_month05 = L"May"; | ||
| 2484 | + _M_data->_M_month06 = L"June"; | ||
| 2485 | + _M_data->_M_month07 = L"July"; | ||
| 2486 | + _M_data->_M_month08 = L"August"; | ||
| 2487 | + _M_data->_M_month09 = L"September"; | ||
| 2488 | + _M_data->_M_month10 = L"October"; | ||
| 2489 | + _M_data->_M_month11 = L"November"; | ||
| 2490 | + _M_data->_M_month12 = L"December"; | ||
| 2491 | + | ||
| 2492 | + // Abbreviated month names, starting with "C"'s Jan. | ||
| 2493 | + _M_data->_M_amonth01 = L"Jan"; | ||
| 2494 | + _M_data->_M_amonth02 = L"Feb"; | ||
| 2495 | + _M_data->_M_amonth03 = L"Mar"; | ||
| 2496 | + _M_data->_M_amonth04 = L"Apr"; | ||
| 2497 | + _M_data->_M_amonth05 = L"May"; | ||
| 2498 | + _M_data->_M_amonth06 = L"Jun"; | ||
| 2499 | + _M_data->_M_amonth07 = L"Jul"; | ||
| 2500 | + _M_data->_M_amonth08 = L"Aug"; | ||
| 2501 | + _M_data->_M_amonth09 = L"Sep"; | ||
| 2502 | + _M_data->_M_amonth10 = L"Oct"; | ||
| 2503 | + _M_data->_M_amonth11 = L"Nov"; | ||
| 2504 | + _M_data->_M_amonth12 = L"Dec"; | ||
| 2505 | + } | ||
| 2506 | +#if 0 | ||
| 2507 | + else | ||
| 2508 | + { | ||
| 2509 | + _M_c_locale_timepunct = _S_clone_c_locale(__cloc); | ||
| 2510 | + | ||
| 2511 | + union { char *__s; wchar_t *__w; } __u; | ||
| 2512 | + | ||
| 2513 | + __u.__s = __nl_langinfo_l(_NL_WD_FMT, __cloc); | ||
| 2514 | + _M_data->_M_date_format = __u.__w; | ||
| 2515 | + __u.__s = __nl_langinfo_l(_NL_WERA_D_FMT, __cloc); | ||
| 2516 | + _M_data->_M_date_era_format = __u.__w; | ||
| 2517 | + __u.__s = __nl_langinfo_l(_NL_WT_FMT, __cloc); | ||
| 2518 | + _M_data->_M_time_format = __u.__w; | ||
| 2519 | + __u.__s = __nl_langinfo_l(_NL_WERA_T_FMT, __cloc); | ||
| 2520 | + _M_data->_M_time_era_format = __u.__w; | ||
| 2521 | + __u.__s = __nl_langinfo_l(_NL_WD_T_FMT, __cloc); | ||
| 2522 | + _M_data->_M_date_time_format = __u.__w; | ||
| 2523 | + __u.__s = __nl_langinfo_l(_NL_WERA_D_T_FMT, __cloc); | ||
| 2524 | + _M_data->_M_date_time_era_format = __u.__w; | ||
| 2525 | + __u.__s = __nl_langinfo_l(_NL_WAM_STR, __cloc); | ||
| 2526 | + _M_data->_M_am = __u.__w; | ||
| 2527 | + __u.__s = __nl_langinfo_l(_NL_WPM_STR, __cloc); | ||
| 2528 | + _M_data->_M_pm = __u.__w; | ||
| 2529 | + __u.__s = __nl_langinfo_l(_NL_WT_FMT_AMPM, __cloc); | ||
| 2530 | + _M_data->_M_am_pm_format = __u.__w; | ||
| 2531 | + | ||
| 2532 | + // Day names, starting with "C"'s Sunday. | ||
| 2533 | + __u.__s = __nl_langinfo_l(_NL_WDAY_1, __cloc); | ||
| 2534 | + _M_data->_M_day1 = __u.__w; | ||
| 2535 | + __u.__s = __nl_langinfo_l(_NL_WDAY_2, __cloc); | ||
| 2536 | + _M_data->_M_day2 = __u.__w; | ||
| 2537 | + __u.__s = __nl_langinfo_l(_NL_WDAY_3, __cloc); | ||
| 2538 | + _M_data->_M_day3 = __u.__w; | ||
| 2539 | + __u.__s = __nl_langinfo_l(_NL_WDAY_4, __cloc); | ||
| 2540 | + _M_data->_M_day4 = __u.__w; | ||
| 2541 | + __u.__s = __nl_langinfo_l(_NL_WDAY_5, __cloc); | ||
| 2542 | + _M_data->_M_day5 = __u.__w; | ||
| 2543 | + __u.__s = __nl_langinfo_l(_NL_WDAY_6, __cloc); | ||
| 2544 | + _M_data->_M_day6 = __u.__w; | ||
| 2545 | + __u.__s = __nl_langinfo_l(_NL_WDAY_7, __cloc); | ||
| 2546 | + _M_data->_M_day7 = __u.__w; | ||
| 2547 | + | ||
| 2548 | + // Abbreviated day names, starting with "C"'s Sun. | ||
| 2549 | + __u.__s = __nl_langinfo_l(_NL_WABDAY_1, __cloc); | ||
| 2550 | + _M_data->_M_aday1 = __u.__w; | ||
| 2551 | + __u.__s = __nl_langinfo_l(_NL_WABDAY_2, __cloc); | ||
| 2552 | + _M_data->_M_aday2 = __u.__w; | ||
| 2553 | + __u.__s = __nl_langinfo_l(_NL_WABDAY_3, __cloc); | ||
| 2554 | + _M_data->_M_aday3 = __u.__w; | ||
| 2555 | + __u.__s = __nl_langinfo_l(_NL_WABDAY_4, __cloc); | ||
| 2556 | + _M_data->_M_aday4 = __u.__w; | ||
| 2557 | + __u.__s = __nl_langinfo_l(_NL_WABDAY_5, __cloc); | ||
| 2558 | + _M_data->_M_aday5 = __u.__w; | ||
| 2559 | + __u.__s = __nl_langinfo_l(_NL_WABDAY_6, __cloc); | ||
| 2560 | + _M_data->_M_aday6 = __u.__w; | ||
| 2561 | + __u.__s = __nl_langinfo_l(_NL_WABDAY_7, __cloc); | ||
| 2562 | + _M_data->_M_aday7 = __u.__w; | ||
| 2563 | + | ||
| 2564 | + // Month names, starting with "C"'s January. | ||
| 2565 | + __u.__s = __nl_langinfo_l(_NL_WMON_1, __cloc); | ||
| 2566 | + _M_data->_M_month01 = __u.__w; | ||
| 2567 | + __u.__s = __nl_langinfo_l(_NL_WMON_2, __cloc); | ||
| 2568 | + _M_data->_M_month02 = __u.__w; | ||
| 2569 | + __u.__s = __nl_langinfo_l(_NL_WMON_3, __cloc); | ||
| 2570 | + _M_data->_M_month03 = __u.__w; | ||
| 2571 | + __u.__s = __nl_langinfo_l(_NL_WMON_4, __cloc); | ||
| 2572 | + _M_data->_M_month04 = __u.__w; | ||
| 2573 | + __u.__s = __nl_langinfo_l(_NL_WMON_5, __cloc); | ||
| 2574 | + _M_data->_M_month05 = __u.__w; | ||
| 2575 | + __u.__s = __nl_langinfo_l(_NL_WMON_6, __cloc); | ||
| 2576 | + _M_data->_M_month06 = __u.__w; | ||
| 2577 | + __u.__s = __nl_langinfo_l(_NL_WMON_7, __cloc); | ||
| 2578 | + _M_data->_M_month07 = __u.__w; | ||
| 2579 | + __u.__s = __nl_langinfo_l(_NL_WMON_8, __cloc); | ||
| 2580 | + _M_data->_M_month08 = __u.__w; | ||
| 2581 | + __u.__s = __nl_langinfo_l(_NL_WMON_9, __cloc); | ||
| 2582 | + _M_data->_M_month09 = __u.__w; | ||
| 2583 | + __u.__s = __nl_langinfo_l(_NL_WMON_10, __cloc); | ||
| 2584 | + _M_data->_M_month10 = __u.__w; | ||
| 2585 | + __u.__s = __nl_langinfo_l(_NL_WMON_11, __cloc); | ||
| 2586 | + _M_data->_M_month11 = __u.__w; | ||
| 2587 | + __u.__s = __nl_langinfo_l(_NL_WMON_12, __cloc); | ||
| 2588 | + _M_data->_M_month12 = __u.__w; | ||
| 2589 | + | ||
| 2590 | + // Abbreviated month names, starting with "C"'s Jan. | ||
| 2591 | + __u.__s = __nl_langinfo_l(_NL_WABMON_1, __cloc); | ||
| 2592 | + _M_data->_M_amonth01 = __u.__w; | ||
| 2593 | + __u.__s = __nl_langinfo_l(_NL_WABMON_2, __cloc); | ||
| 2594 | + _M_data->_M_amonth02 = __u.__w; | ||
| 2595 | + __u.__s = __nl_langinfo_l(_NL_WABMON_3, __cloc); | ||
| 2596 | + _M_data->_M_amonth03 = __u.__w; | ||
| 2597 | + __u.__s = __nl_langinfo_l(_NL_WABMON_4, __cloc); | ||
| 2598 | + _M_data->_M_amonth04 = __u.__w; | ||
| 2599 | + __u.__s = __nl_langinfo_l(_NL_WABMON_5, __cloc); | ||
| 2600 | + _M_data->_M_amonth05 = __u.__w; | ||
| 2601 | + __u.__s = __nl_langinfo_l(_NL_WABMON_6, __cloc); | ||
| 2602 | + _M_data->_M_amonth06 = __u.__w; | ||
| 2603 | + __u.__s = __nl_langinfo_l(_NL_WABMON_7, __cloc); | ||
| 2604 | + _M_data->_M_amonth07 = __u.__w; | ||
| 2605 | + __u.__s = __nl_langinfo_l(_NL_WABMON_8, __cloc); | ||
| 2606 | + _M_data->_M_amonth08 = __u.__w; | ||
| 2607 | + __u.__s = __nl_langinfo_l(_NL_WABMON_9, __cloc); | ||
| 2608 | + _M_data->_M_amonth09 = __u.__w; | ||
| 2609 | + __u.__s = __nl_langinfo_l(_NL_WABMON_10, __cloc); | ||
| 2610 | + _M_data->_M_amonth10 = __u.__w; | ||
| 2611 | + __u.__s = __nl_langinfo_l(_NL_WABMON_11, __cloc); | ||
| 2612 | + _M_data->_M_amonth11 = __u.__w; | ||
| 2613 | + __u.__s = __nl_langinfo_l(_NL_WABMON_12, __cloc); | ||
| 2614 | + _M_data->_M_amonth12 = __u.__w; | ||
| 2615 | + } | ||
| 2616 | +#endif // 0 | ||
| 2617 | + } | ||
| 2618 | +#endif | ||
| 2619 | +} | ||
| 2620 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/time_members.h gcc-4.0.0/libstdc++-v3/config/locale/uclibc/time_members.h | ||
| 2621 | --- gcc-4.0.0-100/libstdc++-v3/config/locale/uclibc/time_members.h 1969-12-31 18:00:00.000000000 -0600 | ||
| 2622 | +++ gcc-4.0.0/libstdc++-v3/config/locale/uclibc/time_members.h 2004-05-22 18:46:31.000000000 -0500 | ||
| 2623 | @@ -0,0 +1,68 @@ | ||
| 2624 | +// std::time_get, std::time_put implementation, GNU version -*- C++ -*- | ||
| 2625 | + | ||
| 2626 | +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. | ||
| 2627 | +// | ||
| 2628 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 2629 | +// software; you can redistribute it and/or modify it under the | ||
| 2630 | +// terms of the GNU General Public License as published by the | ||
| 2631 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 2632 | +// any later version. | ||
| 2633 | + | ||
| 2634 | +// This library is distributed in the hope that it will be useful, | ||
| 2635 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 2636 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 2637 | +// GNU General Public License for more details. | ||
| 2638 | + | ||
| 2639 | +// You should have received a copy of the GNU General Public License along | ||
| 2640 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 2641 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 2642 | +// USA. | ||
| 2643 | + | ||
| 2644 | +// As a special exception, you may use this file as part of a free software | ||
| 2645 | +// library without restriction. Specifically, if other files instantiate | ||
| 2646 | +// templates or use macros or inline functions from this file, or you compile | ||
| 2647 | +// this file and link it with other files to produce an executable, this | ||
| 2648 | +// file does not by itself cause the resulting executable to be covered by | ||
| 2649 | +// the GNU General Public License. This exception does not however | ||
| 2650 | +// invalidate any other reasons why the executable file might be covered by | ||
| 2651 | +// the GNU General Public License. | ||
| 2652 | + | ||
| 2653 | +// | ||
| 2654 | +// ISO C++ 14882: 22.2.5.1.2 - time_get functions | ||
| 2655 | +// ISO C++ 14882: 22.2.5.3.2 - time_put functions | ||
| 2656 | +// | ||
| 2657 | + | ||
| 2658 | +// Written by Benjamin Kosnik <bkoz@redhat.com> | ||
| 2659 | + | ||
| 2660 | + template<typename _CharT> | ||
| 2661 | + __timepunct<_CharT>::__timepunct(size_t __refs) | ||
| 2662 | + : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL), | ||
| 2663 | + _M_name_timepunct(_S_get_c_name()) | ||
| 2664 | + { _M_initialize_timepunct(); } | ||
| 2665 | + | ||
| 2666 | + template<typename _CharT> | ||
| 2667 | + __timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs) | ||
| 2668 | + : facet(__refs), _M_data(__cache), _M_c_locale_timepunct(NULL), | ||
| 2669 | + _M_name_timepunct(_S_get_c_name()) | ||
| 2670 | + { _M_initialize_timepunct(); } | ||
| 2671 | + | ||
| 2672 | + template<typename _CharT> | ||
| 2673 | + __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s, | ||
| 2674 | + size_t __refs) | ||
| 2675 | + : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL), | ||
| 2676 | + _M_name_timepunct(__s) | ||
| 2677 | + { | ||
| 2678 | + char* __tmp = new char[std::strlen(__s) + 1]; | ||
| 2679 | + std::strcpy(__tmp, __s); | ||
| 2680 | + _M_name_timepunct = __tmp; | ||
| 2681 | + _M_initialize_timepunct(__cloc); | ||
| 2682 | + } | ||
| 2683 | + | ||
| 2684 | + template<typename _CharT> | ||
| 2685 | + __timepunct<_CharT>::~__timepunct() | ||
| 2686 | + { | ||
| 2687 | + if (_M_name_timepunct != _S_get_c_name()) | ||
| 2688 | + delete [] _M_name_timepunct; | ||
| 2689 | + delete _M_data; | ||
| 2690 | + _S_destroy_c_locale(_M_c_locale_timepunct); | ||
| 2691 | + } | ||
| 2692 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/os/uclibc/ctype_base.h gcc-4.0.0/libstdc++-v3/config/os/uclibc/ctype_base.h | ||
| 2693 | --- gcc-4.0.0-100/libstdc++-v3/config/os/uclibc/ctype_base.h 1969-12-31 18:00:00.000000000 -0600 | ||
| 2694 | +++ gcc-4.0.0/libstdc++-v3/config/os/uclibc/ctype_base.h 2005-04-28 01:10:27.000000000 -0500 | ||
| 2695 | @@ -0,0 +1,64 @@ | ||
| 2696 | +// Locale support -*- C++ -*- | ||
| 2697 | + | ||
| 2698 | +// Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004 | ||
| 2699 | +// Free Software Foundation, Inc. | ||
| 2700 | +// | ||
| 2701 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 2702 | +// software; you can redistribute it and/or modify it under the | ||
| 2703 | +// terms of the GNU General Public License as published by the | ||
| 2704 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 2705 | +// any later version. | ||
| 2706 | + | ||
| 2707 | +// This library is distributed in the hope that it will be useful, | ||
| 2708 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 2709 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 2710 | +// GNU General Public License for more details. | ||
| 2711 | + | ||
| 2712 | +// You should have received a copy of the GNU General Public License along | ||
| 2713 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 2714 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 2715 | +// USA. | ||
| 2716 | + | ||
| 2717 | +// As a special exception, you may use this file as part of a free software | ||
| 2718 | +// library without restriction. Specifically, if other files instantiate | ||
| 2719 | +// templates or use macros or inline functions from this file, or you compile | ||
| 2720 | +// this file and link it with other files to produce an executable, this | ||
| 2721 | +// file does not by itself cause the resulting executable to be covered by | ||
| 2722 | +// the GNU General Public License. This exception does not however | ||
| 2723 | +// invalidate any other reasons why the executable file might be covered by | ||
| 2724 | +// the GNU General Public License. | ||
| 2725 | + | ||
| 2726 | +// | ||
| 2727 | +// ISO C++ 14882: 22.1 Locales | ||
| 2728 | +// | ||
| 2729 | + | ||
| 2730 | +/** @file ctype_base.h | ||
| 2731 | + * This is an internal header file, included by other library headers. | ||
| 2732 | + * You should not attempt to use it directly. | ||
| 2733 | + */ | ||
| 2734 | + | ||
| 2735 | +// Information as gleaned from /usr/include/ctype.h | ||
| 2736 | + | ||
| 2737 | + /// @brief Base class for ctype. | ||
| 2738 | + struct ctype_base | ||
| 2739 | + { | ||
| 2740 | + // Note: In uClibc, the following two types depend on configuration. | ||
| 2741 | + | ||
| 2742 | + // Non-standard typedefs. | ||
| 2743 | + typedef const __ctype_touplow_t* __to_type; | ||
| 2744 | + | ||
| 2745 | + // NB: Offsets into ctype<char>::_M_table force a particular size | ||
| 2746 | + // on the mask type. Because of this, we don't use an enum. | ||
| 2747 | + typedef __ctype_mask_t mask; | ||
| 2748 | + static const mask upper = _ISupper; | ||
| 2749 | + static const mask lower = _ISlower; | ||
| 2750 | + static const mask alpha = _ISalpha; | ||
| 2751 | + static const mask digit = _ISdigit; | ||
| 2752 | + static const mask xdigit = _ISxdigit; | ||
| 2753 | + static const mask space = _ISspace; | ||
| 2754 | + static const mask print = _ISprint; | ||
| 2755 | + static const mask graph = _ISalpha | _ISdigit | _ISpunct; | ||
| 2756 | + static const mask cntrl = _IScntrl; | ||
| 2757 | + static const mask punct = _ISpunct; | ||
| 2758 | + static const mask alnum = _ISalpha | _ISdigit; | ||
| 2759 | + }; | ||
| 2760 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/os/uclibc/ctype_inline.h gcc-4.0.0/libstdc++-v3/config/os/uclibc/ctype_inline.h | ||
| 2761 | --- gcc-4.0.0-100/libstdc++-v3/config/os/uclibc/ctype_inline.h 1969-12-31 18:00:00.000000000 -0600 | ||
| 2762 | +++ gcc-4.0.0/libstdc++-v3/config/os/uclibc/ctype_inline.h 2002-06-24 00:49:19.000000000 -0500 | ||
| 2763 | @@ -0,0 +1,69 @@ | ||
| 2764 | +// Locale support -*- C++ -*- | ||
| 2765 | + | ||
| 2766 | +// Copyright (C) 2000, 2002 Free Software Foundation, Inc. | ||
| 2767 | +// | ||
| 2768 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 2769 | +// software; you can redistribute it and/or modify it under the | ||
| 2770 | +// terms of the GNU General Public License as published by the | ||
| 2771 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 2772 | +// any later version. | ||
| 2773 | + | ||
| 2774 | +// This library is distributed in the hope that it will be useful, | ||
| 2775 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 2776 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 2777 | +// GNU General Public License for more details. | ||
| 2778 | + | ||
| 2779 | +// You should have received a copy of the GNU General Public License along | ||
| 2780 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 2781 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 2782 | +// USA. | ||
| 2783 | + | ||
| 2784 | +// As a special exception, you may use this file as part of a free software | ||
| 2785 | +// library without restriction. Specifically, if other files instantiate | ||
| 2786 | +// templates or use macros or inline functions from this file, or you compile | ||
| 2787 | +// this file and link it with other files to produce an executable, this | ||
| 2788 | +// file does not by itself cause the resulting executable to be covered by | ||
| 2789 | +// the GNU General Public License. This exception does not however | ||
| 2790 | +// invalidate any other reasons why the executable file might be covered by | ||
| 2791 | +// the GNU General Public License. | ||
| 2792 | + | ||
| 2793 | +// | ||
| 2794 | +// ISO C++ 14882: 22.1 Locales | ||
| 2795 | +// | ||
| 2796 | + | ||
| 2797 | +// ctype bits to be inlined go here. Non-inlinable (ie virtual do_*) | ||
| 2798 | +// functions go in ctype.cc | ||
| 2799 | + | ||
| 2800 | + bool | ||
| 2801 | + ctype<char>:: | ||
| 2802 | + is(mask __m, char __c) const | ||
| 2803 | + { return _M_table[static_cast<unsigned char>(__c)] & __m; } | ||
| 2804 | + | ||
| 2805 | + const char* | ||
| 2806 | + ctype<char>:: | ||
| 2807 | + is(const char* __low, const char* __high, mask* __vec) const | ||
| 2808 | + { | ||
| 2809 | + while (__low < __high) | ||
| 2810 | + *__vec++ = _M_table[static_cast<unsigned char>(*__low++)]; | ||
| 2811 | + return __high; | ||
| 2812 | + } | ||
| 2813 | + | ||
| 2814 | + const char* | ||
| 2815 | + ctype<char>:: | ||
| 2816 | + scan_is(mask __m, const char* __low, const char* __high) const | ||
| 2817 | + { | ||
| 2818 | + while (__low < __high | ||
| 2819 | + && !(_M_table[static_cast<unsigned char>(*__low)] & __m)) | ||
| 2820 | + ++__low; | ||
| 2821 | + return __low; | ||
| 2822 | + } | ||
| 2823 | + | ||
| 2824 | + const char* | ||
| 2825 | + ctype<char>:: | ||
| 2826 | + scan_not(mask __m, const char* __low, const char* __high) const | ||
| 2827 | + { | ||
| 2828 | + while (__low < __high | ||
| 2829 | + && (_M_table[static_cast<unsigned char>(*__low)] & __m) != 0) | ||
| 2830 | + ++__low; | ||
| 2831 | + return __low; | ||
| 2832 | + } | ||
| 2833 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/os/uclibc/ctype_noninline.h gcc-4.0.0/libstdc++-v3/config/os/uclibc/ctype_noninline.h | ||
| 2834 | --- gcc-4.0.0-100/libstdc++-v3/config/os/uclibc/ctype_noninline.h 1969-12-31 18:00:00.000000000 -0600 | ||
| 2835 | +++ gcc-4.0.0/libstdc++-v3/config/os/uclibc/ctype_noninline.h 2005-04-28 01:10:27.000000000 -0500 | ||
| 2836 | @@ -0,0 +1,92 @@ | ||
| 2837 | +// Locale support -*- C++ -*- | ||
| 2838 | + | ||
| 2839 | +// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004 | ||
| 2840 | +// Free Software Foundation, Inc. | ||
| 2841 | +// | ||
| 2842 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 2843 | +// software; you can redistribute it and/or modify it under the | ||
| 2844 | +// terms of the GNU General Public License as published by the | ||
| 2845 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 2846 | +// any later version. | ||
| 2847 | + | ||
| 2848 | +// This library is distributed in the hope that it will be useful, | ||
| 2849 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 2850 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 2851 | +// GNU General Public License for more details. | ||
| 2852 | + | ||
| 2853 | +// You should have received a copy of the GNU General Public License along | ||
| 2854 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 2855 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 2856 | +// USA. | ||
| 2857 | + | ||
| 2858 | +// As a special exception, you may use this file as part of a free software | ||
| 2859 | +// library without restriction. Specifically, if other files instantiate | ||
| 2860 | +// templates or use macros or inline functions from this file, or you compile | ||
| 2861 | +// this file and link it with other files to produce an executable, this | ||
| 2862 | +// file does not by itself cause the resulting executable to be covered by | ||
| 2863 | +// the GNU General Public License. This exception does not however | ||
| 2864 | +// invalidate any other reasons why the executable file might be covered by | ||
| 2865 | +// the GNU General Public License. | ||
| 2866 | + | ||
| 2867 | +// | ||
| 2868 | +// ISO C++ 14882: 22.1 Locales | ||
| 2869 | +// | ||
| 2870 | + | ||
| 2871 | +// Information as gleaned from /usr/include/ctype.h | ||
| 2872 | + | ||
| 2873 | + const ctype_base::mask* | ||
| 2874 | + ctype<char>::classic_table() throw() | ||
| 2875 | + { return __C_ctype_b; } | ||
| 2876 | + | ||
| 2877 | + ctype<char>::ctype(__c_locale, const mask* __table, bool __del, | ||
| 2878 | + size_t __refs) | ||
| 2879 | + : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()), | ||
| 2880 | + _M_del(__table != 0 && __del), _M_widen_ok(0), _M_narrow_ok(0) | ||
| 2881 | + { | ||
| 2882 | + _M_toupper = __C_ctype_toupper; | ||
| 2883 | + _M_tolower = __C_ctype_tolower; | ||
| 2884 | + _M_table = __table ? __table : __C_ctype_b; | ||
| 2885 | + memset(_M_widen, 0, sizeof(_M_widen)); | ||
| 2886 | + memset(_M_narrow, 0, sizeof(_M_narrow)); | ||
| 2887 | + } | ||
| 2888 | + | ||
| 2889 | + ctype<char>::ctype(const mask* __table, bool __del, size_t __refs) | ||
| 2890 | + : facet(__refs), _M_c_locale_ctype(_S_get_c_locale()), | ||
| 2891 | + _M_del(__table != 0 && __del), _M_widen_ok(0), _M_narrow_ok(0) | ||
| 2892 | + { | ||
| 2893 | + _M_toupper = __C_ctype_toupper; | ||
| 2894 | + _M_tolower = __C_ctype_tolower; | ||
| 2895 | + _M_table = __table ? __table : __C_ctype_b; | ||
| 2896 | + memset(_M_widen, 0, sizeof(_M_widen)); | ||
| 2897 | + memset(_M_narrow, 0, sizeof(_M_narrow)); | ||
| 2898 | + } | ||
| 2899 | + | ||
| 2900 | + char | ||
| 2901 | + ctype<char>::do_toupper(char __c) const | ||
| 2902 | + { return _M_toupper[static_cast<unsigned char>(__c)]; } | ||
| 2903 | + | ||
| 2904 | + const char* | ||
| 2905 | + ctype<char>::do_toupper(char* __low, const char* __high) const | ||
| 2906 | + { | ||
| 2907 | + while (__low < __high) | ||
| 2908 | + { | ||
| 2909 | + *__low = _M_toupper[static_cast<unsigned char>(*__low)]; | ||
| 2910 | + ++__low; | ||
| 2911 | + } | ||
| 2912 | + return __high; | ||
| 2913 | + } | ||
| 2914 | + | ||
| 2915 | + char | ||
| 2916 | + ctype<char>::do_tolower(char __c) const | ||
| 2917 | + { return _M_tolower[static_cast<unsigned char>(__c)]; } | ||
| 2918 | + | ||
| 2919 | + const char* | ||
| 2920 | + ctype<char>::do_tolower(char* __low, const char* __high) const | ||
| 2921 | + { | ||
| 2922 | + while (__low < __high) | ||
| 2923 | + { | ||
| 2924 | + *__low = _M_tolower[static_cast<unsigned char>(*__low)]; | ||
| 2925 | + ++__low; | ||
| 2926 | + } | ||
| 2927 | + return __high; | ||
| 2928 | + } | ||
| 2929 | diff -urN gcc-4.0.0-100/libstdc++-v3/config/os/uclibc/os_defines.h gcc-4.0.0/libstdc++-v3/config/os/uclibc/os_defines.h | ||
| 2930 | --- gcc-4.0.0-100/libstdc++-v3/config/os/uclibc/os_defines.h 1969-12-31 18:00:00.000000000 -0600 | ||
| 2931 | +++ gcc-4.0.0/libstdc++-v3/config/os/uclibc/os_defines.h 2005-04-28 01:10:27.000000000 -0500 | ||
| 2932 | @@ -0,0 +1,44 @@ | ||
| 2933 | +// Specific definitions for GNU/Linux -*- C++ -*- | ||
| 2934 | + | ||
| 2935 | +// Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. | ||
| 2936 | +// | ||
| 2937 | +// This file is part of the GNU ISO C++ Library. This library is free | ||
| 2938 | +// software; you can redistribute it and/or modify it under the | ||
| 2939 | +// terms of the GNU General Public License as published by the | ||
| 2940 | +// Free Software Foundation; either version 2, or (at your option) | ||
| 2941 | +// any later version. | ||
| 2942 | + | ||
| 2943 | +// This library is distributed in the hope that it will be useful, | ||
| 2944 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 2945 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 2946 | +// GNU General Public License for more details. | ||
| 2947 | + | ||
| 2948 | +// You should have received a copy of the GNU General Public License along | ||
| 2949 | +// with this library; see the file COPYING. If not, write to the Free | ||
| 2950 | +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | ||
| 2951 | +// USA. | ||
| 2952 | + | ||
| 2953 | +// As a special exception, you may use this file as part of a free software | ||
| 2954 | +// library without restriction. Specifically, if other files instantiate | ||
| 2955 | +// templates or use macros or inline functions from this file, or you compile | ||
| 2956 | +// this file and link it with other files to produce an executable, this | ||
| 2957 | +// file does not by itself cause the resulting executable to be covered by | ||
| 2958 | +// the GNU General Public License. This exception does not however | ||
| 2959 | +// invalidate any other reasons why the executable file might be covered by | ||
| 2960 | +// the GNU General Public License. | ||
| 2961 | + | ||
| 2962 | +#ifndef _GLIBCXX_OS_DEFINES | ||
| 2963 | +#define _GLIBCXX_OS_DEFINES 1 | ||
| 2964 | + | ||
| 2965 | +// System-specific #define, typedefs, corrections, etc, go here. This | ||
| 2966 | +// file will come before all others. | ||
| 2967 | + | ||
| 2968 | +// This keeps isanum, et al from being propagated as macros. | ||
| 2969 | +#define __NO_CTYPE 1 | ||
| 2970 | + | ||
| 2971 | +#include <features.h> | ||
| 2972 | + | ||
| 2973 | +// We must not see the optimized string functions GNU libc defines. | ||
| 2974 | +#define __NO_STRING_INLINES | ||
| 2975 | + | ||
| 2976 | +#endif | ||
| 2977 | diff -urN gcc-4.0.0-100/libstdc++-v3/configure gcc-4.0.0/libstdc++-v3/configure | ||
| 2978 | --- gcc-4.0.0-100/libstdc++-v3/configure 2005-04-30 13:06:53.683055232 -0500 | ||
| 2979 | +++ gcc-4.0.0/libstdc++-v3/configure 2005-04-30 12:24:24.000000000 -0500 | ||
| 2980 | @@ -3998,6 +3998,11 @@ | ||
| 2981 | lt_cv_deplibs_check_method=pass_all | ||
| 2982 | ;; | ||
| 2983 | |||
| 2984 | +linux-uclibc*) | ||
| 2985 | + lt_cv_deplibs_check_method=pass_all | ||
| 2986 | + lt_cv_file_magic_test_file=`echo /lib/libuClibc-*.so` | ||
| 2987 | + ;; | ||
| 2988 | + | ||
| 2989 | netbsd* | knetbsd*-gnu) | ||
| 2990 | if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then | ||
| 2991 | lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' | ||
| 2992 | @@ -5672,7 +5677,7 @@ | ||
| 2993 | enableval="$enable_clocale" | ||
| 2994 | |||
| 2995 | case "$enableval" in | ||
| 2996 | - generic|gnu|ieee_1003.1-2001|yes|no|auto) ;; | ||
| 2997 | + generic|gnu|ieee_1003.1-2001|uclibc|yes|no|auto) ;; | ||
| 2998 | *) { { echo "$as_me:$LINENO: error: Unknown argument to enable/disable clocale" >&5 | ||
| 2999 | echo "$as_me: error: Unknown argument to enable/disable clocale" >&2;} | ||
| 3000 | { (exit 1); exit 1; }; } ;; | ||
| 3001 | @@ -5697,6 +5702,9 @@ | ||
| 3002 | # Default to "generic". | ||
| 3003 | if test $enable_clocale_flag = auto; then | ||
| 3004 | case ${target_os} in | ||
| 3005 | + linux-uclibc*) | ||
| 3006 | + enable_clocale_flag=uclibc | ||
| 3007 | + ;; | ||
| 3008 | linux* | gnu* | kfreebsd*-gnu | knetbsd*-gnu) | ||
| 3009 | cat >conftest.$ac_ext <<_ACEOF | ||
| 3010 | /* confdefs.h. */ | ||
| 3011 | @@ -5927,6 +5935,76 @@ | ||
| 3012 | CTIME_CC=config/locale/generic/time_members.cc | ||
| 3013 | CLOCALE_INTERNAL_H=config/locale/generic/c++locale_internal.h | ||
| 3014 | ;; | ||
| 3015 | + uclibc) | ||
| 3016 | + echo "$as_me:$LINENO: result: uclibc" >&5 | ||
| 3017 | +echo "${ECHO_T}uclibc" >&6 | ||
| 3018 | + | ||
| 3019 | + # Declare intention to use gettext, and add support for specific | ||
| 3020 | + # languages. | ||
| 3021 | + # For some reason, ALL_LINGUAS has to be before AM-GNU-GETTEXT | ||
| 3022 | + ALL_LINGUAS="de fr" | ||
| 3023 | + | ||
| 3024 | + # Don't call AM-GNU-GETTEXT here. Instead, assume glibc. | ||
| 3025 | + # Extract the first word of "msgfmt", so it can be a program name with args. | ||
| 3026 | +set dummy msgfmt; ac_word=$2 | ||
| 3027 | +echo "$as_me:$LINENO: checking for $ac_word" >&5 | ||
| 3028 | +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 | ||
| 3029 | +if test "${ac_cv_prog_check_msgfmt+set}" = set; then | ||
| 3030 | + echo $ECHO_N "(cached) $ECHO_C" >&6 | ||
| 3031 | +else | ||
| 3032 | + if test -n "$check_msgfmt"; then | ||
| 3033 | + ac_cv_prog_check_msgfmt="$check_msgfmt" # Let the user override the test. | ||
| 3034 | +else | ||
| 3035 | +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR | ||
| 3036 | +for as_dir in $PATH | ||
| 3037 | +do | ||
| 3038 | + IFS=$as_save_IFS | ||
| 3039 | + test -z "$as_dir" && as_dir=. | ||
| 3040 | + for ac_exec_ext in '' $ac_executable_extensions; do | ||
| 3041 | + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then | ||
| 3042 | + ac_cv_prog_check_msgfmt="yes" | ||
| 3043 | + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 | ||
| 3044 | + break 2 | ||
| 3045 | + fi | ||
| 3046 | +done | ||
| 3047 | +done | ||
| 3048 | + | ||
| 3049 | + test -z "$ac_cv_prog_check_msgfmt" && ac_cv_prog_check_msgfmt="no" | ||
| 3050 | +fi | ||
| 3051 | +fi | ||
| 3052 | +check_msgfmt=$ac_cv_prog_check_msgfmt | ||
| 3053 | +if test -n "$check_msgfmt"; then | ||
| 3054 | + echo "$as_me:$LINENO: result: $check_msgfmt" >&5 | ||
| 3055 | +echo "${ECHO_T}$check_msgfmt" >&6 | ||
| 3056 | +else | ||
| 3057 | + echo "$as_me:$LINENO: result: no" >&5 | ||
| 3058 | +echo "${ECHO_T}no" >&6 | ||
| 3059 | +fi | ||
| 3060 | + | ||
| 3061 | + if test x"$check_msgfmt" = x"yes" && test x"$enable_nls" = x"yes"; then | ||
| 3062 | + USE_NLS=yes | ||
| 3063 | + fi | ||
| 3064 | + # Export the build objects. | ||
| 3065 | + for ling in $ALL_LINGUAS; do \ | ||
| 3066 | + glibcxx_MOFILES="$glibcxx_MOFILES $ling.mo"; \ | ||
| 3067 | + glibcxx_POFILES="$glibcxx_POFILES $ling.po"; \ | ||
| 3068 | + done | ||
| 3069 | + | ||
| 3070 | + | ||
| 3071 | + | ||
| 3072 | + CLOCALE_H=config/locale/uclibc/c_locale.h | ||
| 3073 | + CLOCALE_CC=config/locale/uclibc/c_locale.cc | ||
| 3074 | + CCODECVT_CC=config/locale/uclibc/codecvt_members.cc | ||
| 3075 | + CCOLLATE_CC=config/locale/uclibc/collate_members.cc | ||
| 3076 | + CCTYPE_CC=config/locale/uclibc/ctype_members.cc | ||
| 3077 | + CMESSAGES_H=config/locale/uclibc/messages_members.h | ||
| 3078 | + CMESSAGES_CC=config/locale/uclibc/messages_members.cc | ||
| 3079 | + CMONEY_CC=config/locale/uclibc/monetary_members.cc | ||
| 3080 | + CNUMERIC_CC=config/locale/uclibc/numeric_members.cc | ||
| 3081 | + CTIME_H=config/locale/uclibc/time_members.h | ||
| 3082 | + CTIME_CC=config/locale/uclibc/time_members.cc | ||
| 3083 | + CLOCALE_INTERNAL_H=config/locale/uclibc/c++locale_internal.h | ||
| 3084 | + ;; | ||
| 3085 | esac | ||
| 3086 | |||
| 3087 | # This is where the testsuite looks for locale catalogs, using the | ||
| 3088 | diff -urN gcc-4.0.0-100/libstdc++-v3/configure.host gcc-4.0.0/libstdc++-v3/configure.host | ||
| 3089 | --- gcc-4.0.0-100/libstdc++-v3/configure.host 2005-04-30 13:06:53.688054472 -0500 | ||
| 3090 | +++ gcc-4.0.0/libstdc++-v3/configure.host 2005-04-28 20:20:32.000000000 -0500 | ||
| 3091 | @@ -249,6 +249,12 @@ | ||
| 3092 | ;; | ||
| 3093 | esac | ||
| 3094 | |||
| 3095 | +# Override for uClibc since linux-uclibc gets mishandled above. | ||
| 3096 | +case "${host_os}" in | ||
| 3097 | + *-uclibc*) | ||
| 3098 | + os_include_dir="os/uclibc" | ||
| 3099 | + ;; | ||
| 3100 | +esac | ||
| 3101 | |||
| 3102 | # Set any OS-dependent and CPU-dependent bits. | ||
| 3103 | # THIS TABLE IS SORTED. KEEP IT THAT WAY. | ||
| 3104 | diff -urN gcc-4.0.0-100/libstdc++-v3/crossconfig.m4 gcc-4.0.0/libstdc++-v3/crossconfig.m4 | ||
| 3105 | --- gcc-4.0.0-100/libstdc++-v3/crossconfig.m4 2005-04-30 13:06:53.689054320 -0500 | ||
| 3106 | +++ gcc-4.0.0/libstdc++-v3/crossconfig.m4 2005-04-28 20:27:15.000000000 -0500 | ||
| 3107 | @@ -142,6 +142,98 @@ | ||
| 3108 | ;; | ||
| 3109 | esac | ||
| 3110 | ;; | ||
| 3111 | + *-uclibc*) | ||
| 3112 | +# Temporary hack until we implement the float versions of the libm funcs | ||
| 3113 | + AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h \ | ||
| 3114 | + machine/endian.h machine/param.h sys/machine.h sys/types.h \ | ||
| 3115 | + fp.h float.h endian.h inttypes.h locale.h float.h stdint.h]) | ||
| 3116 | + SECTION_FLAGS='-ffunction-sections -fdata-sections' | ||
| 3117 | + AC_SUBST(SECTION_FLAGS) | ||
| 3118 | + GLIBCXX_CHECK_LINKER_FEATURES | ||
| 3119 | + GLIBCXX_CHECK_COMPLEX_MATH_SUPPORT | ||
| 3120 | + GLIBCXX_CHECK_WCHAR_T_SUPPORT | ||
| 3121 | + | ||
| 3122 | + # For LFS. | ||
| 3123 | + AC_DEFINE(HAVE_INT64_T) | ||
| 3124 | + case "$target" in | ||
| 3125 | + *-uclinux*) | ||
| 3126 | + # Don't enable LFS with uClinux | ||
| 3127 | + ;; | ||
| 3128 | + *) | ||
| 3129 | + AC_DEFINE(_GLIBCXX_USE_LFS) | ||
| 3130 | + esac | ||
| 3131 | + | ||
| 3132 | + # For showmanyc_helper(). | ||
| 3133 | + AC_CHECK_HEADERS(sys/ioctl.h sys/filio.h) | ||
| 3134 | + GLIBCXX_CHECK_POLL | ||
| 3135 | + GLIBCXX_CHECK_S_ISREG_OR_S_IFREG | ||
| 3136 | + | ||
| 3137 | + # For xsputn_2(). | ||
| 3138 | + AC_CHECK_HEADERS(sys/uio.h) | ||
| 3139 | + GLIBCXX_CHECK_WRITEV | ||
| 3140 | + | ||
| 3141 | +# AC_DEFINE(HAVE_ACOSF) | ||
| 3142 | +# AC_DEFINE(HAVE_ASINF) | ||
| 3143 | +# AC_DEFINE(HAVE_ATANF) | ||
| 3144 | +# AC_DEFINE(HAVE_ATAN2F) | ||
| 3145 | + AC_DEFINE(HAVE_CEILF) | ||
| 3146 | + AC_DEFINE(HAVE_COPYSIGN) | ||
| 3147 | +# AC_DEFINE(HAVE_COPYSIGNF) | ||
| 3148 | +# AC_DEFINE(HAVE_COSF) | ||
| 3149 | +# AC_DEFINE(HAVE_COSHF) | ||
| 3150 | +# AC_DEFINE(HAVE_EXPF) | ||
| 3151 | +# AC_DEFINE(HAVE_FABSF) | ||
| 3152 | + AC_DEFINE(HAVE_FINITE) | ||
| 3153 | + AC_DEFINE(HAVE_FINITEF) | ||
| 3154 | + AC_DEFINE(HAVE_FLOORF) | ||
| 3155 | +# AC_DEFINE(HAVE_FMODF) | ||
| 3156 | +# AC_DEFINE(HAVE_FREXPF) | ||
| 3157 | + AC_DEFINE(HAVE_HYPOT) | ||
| 3158 | +# AC_DEFINE(HAVE_HYPOTF) | ||
| 3159 | + AC_DEFINE(HAVE_ISINF) | ||
| 3160 | + AC_DEFINE(HAVE_ISINFF) | ||
| 3161 | + AC_DEFINE(HAVE_ISNAN) | ||
| 3162 | + AC_DEFINE(HAVE_ISNANF) | ||
| 3163 | +# AC_DEFINE(HAVE_LOGF) | ||
| 3164 | +# AC_DEFINE(HAVE_LOG10F) | ||
| 3165 | +# AC_DEFINE(HAVE_MODFF) | ||
| 3166 | +# AC_DEFINE(HAVE_SINF) | ||
| 3167 | +# AC_DEFINE(HAVE_SINHF) | ||
| 3168 | +# AC_DEFINE(HAVE_SINCOS) | ||
| 3169 | +# AC_DEFINE(HAVE_SINCOSF) | ||
| 3170 | + AC_DEFINE(HAVE_SQRTF) | ||
| 3171 | +# AC_DEFINE(HAVE_TANF) | ||
| 3172 | +# AC_DEFINE(HAVE_TANHF) | ||
| 3173 | + if test x"long_double_math_on_this_cpu" = x"yes"; then | ||
| 3174 | +# AC_DEFINE(HAVE_ACOSL) | ||
| 3175 | +# AC_DEFINE(HAVE_ASINL) | ||
| 3176 | +# AC_DEFINE(HAVE_ATANL) | ||
| 3177 | +# AC_DEFINE(HAVE_ATAN2L) | ||
| 3178 | +# AC_DEFINE(HAVE_CEILL) | ||
| 3179 | +# AC_DEFINE(HAVE_COPYSIGNL) | ||
| 3180 | +# AC_DEFINE(HAVE_COSL) | ||
| 3181 | +# AC_DEFINE(HAVE_COSHL) | ||
| 3182 | +# AC_DEFINE(HAVE_EXPL) | ||
| 3183 | +# AC_DEFINE(HAVE_FABSL) | ||
| 3184 | +# AC_DEFINE(HAVE_FINITEL) | ||
| 3185 | +# AC_DEFINE(HAVE_FLOORL) | ||
| 3186 | +# AC_DEFINE(HAVE_FMODL) | ||
| 3187 | +# AC_DEFINE(HAVE_FREXPL) | ||
| 3188 | +# AC_DEFINE(HAVE_HYPOTL) | ||
| 3189 | +# AC_DEFINE(HAVE_ISINFL) | ||
| 3190 | +# AC_DEFINE(HAVE_ISNANL) | ||
| 3191 | +# AC_DEFINE(HAVE_LOGL) | ||
| 3192 | +# AC_DEFINE(HAVE_LOG10L) | ||
| 3193 | +# AC_DEFINE(HAVE_MODFL) | ||
| 3194 | +# AC_DEFINE(HAVE_POWL) | ||
| 3195 | +# AC_DEFINE(HAVE_SINL) | ||
| 3196 | +# AC_DEFINE(HAVE_SINHL) | ||
| 3197 | +# AC_DEFINE(HAVE_SINCOSL) | ||
| 3198 | +# AC_DEFINE(HAVE_SQRTL) | ||
| 3199 | +# AC_DEFINE(HAVE_TANL) | ||
| 3200 | +# AC_DEFINE(HAVE_TANHL) | ||
| 3201 | + fi | ||
| 3202 | + ;; | ||
| 3203 | *-linux* | *-uclinux* | *-gnu* | *-kfreebsd*-gnu | *-knetbsd*-gnu) | ||
| 3204 | AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h \ | ||
| 3205 | machine/endian.h machine/param.h sys/machine.h sys/types.h \ | ||
| 3206 | @@ -156,7 +248,7 @@ | ||
| 3207 | AC_DEFINE(HAVE_INT64_T) | ||
| 3208 | case "$target" in | ||
| 3209 | *-uclinux*) | ||
| 3210 | - # Don't enable LFS with uClibc | ||
| 3211 | + # Don't enable LFS with uClinux | ||
| 3212 | ;; | ||
| 3213 | *) | ||
| 3214 | AC_DEFINE(_GLIBCXX_USE_LFS) | ||
| 3215 | diff -urN gcc-4.0.0-100/libstdc++-v3/include/c_compatibility/wchar.h gcc-4.0.0/libstdc++-v3/include/c_compatibility/wchar.h | ||
| 3216 | --- gcc-4.0.0-100/libstdc++-v3/include/c_compatibility/wchar.h 2005-04-30 13:06:53.690054168 -0500 | ||
| 3217 | +++ gcc-4.0.0/libstdc++-v3/include/c_compatibility/wchar.h 2005-04-28 20:15:56.000000000 -0500 | ||
| 3218 | @@ -101,7 +101,9 @@ | ||
| 3219 | using std::wmemcpy; | ||
| 3220 | using std::wmemmove; | ||
| 3221 | using std::wmemset; | ||
| 3222 | +#if _GLIBCXX_HAVE_WCSFTIME | ||
| 3223 | using std::wcsftime; | ||
| 3224 | +#endif | ||
| 3225 | |||
| 3226 | #if _GLIBCXX_USE_C99 | ||
| 3227 | using std::wcstold; | ||
| 3228 | diff -urN gcc-4.0.0-100/libstdc++-v3/include/c_std/std_cwchar.h gcc-4.0.0/libstdc++-v3/include/c_std/std_cwchar.h | ||
| 3229 | --- gcc-4.0.0-100/libstdc++-v3/include/c_std/std_cwchar.h 2005-04-30 13:06:53.691054016 -0500 | ||
| 3230 | +++ gcc-4.0.0/libstdc++-v3/include/c_std/std_cwchar.h 2005-04-28 20:15:56.000000000 -0500 | ||
| 3231 | @@ -179,7 +179,9 @@ | ||
| 3232 | using ::wcscoll; | ||
| 3233 | using ::wcscpy; | ||
| 3234 | using ::wcscspn; | ||
| 3235 | +#if _GLIBCXX_HAVE_WCSFTIME | ||
| 3236 | using ::wcsftime; | ||
| 3237 | +#endif | ||
| 3238 | using ::wcslen; | ||
| 3239 | using ::wcsncat; | ||
| 3240 | using ::wcsncmp; | ||
diff --git a/meta/packages/gcc/gcc-4.0.2/301-missing-execinfo_h.patch b/meta/packages/gcc/gcc-4.0.2/301-missing-execinfo_h.patch deleted file mode 100644 index 8867593819..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/301-missing-execinfo_h.patch +++ /dev/null | |||
| @@ -1,14 +0,0 @@ | |||
| 1 | From: | ||
| 2 | http://buildroot.uclibc.org/cgi-bin/viewcvs.cgi/*checkout*/trunk/buildroot/toolchain/gcc/4.0.2/301-missing-execinfo_h.patch?rev=11715 | ||
| 3 | |||
| 4 | --- gcc-4.0.0/boehm-gc/include/gc.h-orig 2005-04-28 22:28:57.000000000 -0500 | ||
| 5 | +++ gcc-4.0.0/boehm-gc/include/gc.h 2005-04-28 22:30:38.000000000 -0500 | ||
| 6 | @@ -500,7 +500,7 @@ | ||
| 7 | #ifdef __linux__ | ||
| 8 | # include <features.h> | ||
| 9 | # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \ | ||
| 10 | - && !defined(__ia64__) | ||
| 11 | + && !defined(__ia64__) && !defined(__UCLIBC__) | ||
| 12 | # ifndef GC_HAVE_BUILTIN_BACKTRACE | ||
| 13 | # define GC_HAVE_BUILTIN_BACKTRACE | ||
| 14 | # endif | ||
diff --git a/meta/packages/gcc/gcc-4.0.2/302-c99-snprintf.patch b/meta/packages/gcc/gcc-4.0.2/302-c99-snprintf.patch deleted file mode 100644 index 5159a52cd7..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/302-c99-snprintf.patch +++ /dev/null | |||
| @@ -1,14 +0,0 @@ | |||
| 1 | From: | ||
| 2 | http://buildroot.uclibc.org/cgi-bin/viewcvs.cgi/*checkout*/trunk/buildroot/toolchain/gcc/4.0.2/302-c99-snprintf.patch?rev=11715 | ||
| 3 | |||
| 4 | --- gcc-4.0.0/libstdc++-v3/include/c_std/std_cstdio.h-orig 2005-04-29 00:08:41.000000000 -0500 | ||
| 5 | +++ gcc-4.0.0/libstdc++-v3/include/c_std/std_cstdio.h 2005-04-29 00:08:45.000000000 -0500 | ||
| 6 | @@ -142,7 +142,7 @@ | ||
| 7 | using ::vsprintf; | ||
| 8 | } | ||
| 9 | |||
| 10 | -#if _GLIBCXX_USE_C99 | ||
| 11 | +#if _GLIBCXX_USE_C99 || defined(__UCLIBC__) | ||
| 12 | |||
| 13 | #undef snprintf | ||
| 14 | #undef vfscanf | ||
diff --git a/meta/packages/gcc/gcc-4.0.2/303-c99-complex-ugly-hack.patch b/meta/packages/gcc/gcc-4.0.2/303-c99-complex-ugly-hack.patch deleted file mode 100644 index 0ba0a89b4f..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/303-c99-complex-ugly-hack.patch +++ /dev/null | |||
| @@ -1,15 +0,0 @@ | |||
| 1 | From: | ||
| 2 | http://buildroot.uclibc.org/cgi-bin/viewcvs.cgi/*checkout*/trunk/buildroot/toolchain/gcc/4.0.2/303-c99-complex-ugly-hack.patch?rev=11715 | ||
| 3 | |||
| 4 | --- gcc-4.0.0/libstdc++-v3/configure-old 2005-04-30 22:04:48.061603912 -0500 | ||
| 5 | +++ gcc-4.0.0/libstdc++-v3/configure 2005-04-30 22:06:13.678588152 -0500 | ||
| 6 | @@ -7194,6 +7194,9 @@ | ||
| 7 | cat >>conftest.$ac_ext <<_ACEOF | ||
| 8 | /* end confdefs.h. */ | ||
| 9 | #include <complex.h> | ||
| 10 | +#ifdef __UCLIBC__ | ||
| 11 | +#error ugly hack to make sure configure test fails here for cross until uClibc supports the complex funcs | ||
| 12 | +#endif | ||
| 13 | int | ||
| 14 | main () | ||
| 15 | { | ||
diff --git a/meta/packages/gcc/gcc-4.0.2/800-arm-bigendian.patch b/meta/packages/gcc/gcc-4.0.2/800-arm-bigendian.patch deleted file mode 100644 index e5fc413485..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/800-arm-bigendian.patch +++ /dev/null | |||
| @@ -1,70 +0,0 @@ | |||
| 1 | From: | ||
| 2 | http://buildroot.uclibc.org/cgi-bin/viewcvs.cgi/trunk/buildroot/toolchain/gcc/4.0.2/800-arm-bigendian.patch?rev=14828&view=markup | ||
| 3 | |||
| 4 | By Lennert Buytenhek <buytenh@wantstofly.org> | ||
| 5 | Adds support for arm*b-linux* big-endian ARM targets | ||
| 6 | |||
| 7 | See http://gcc.gnu.org/PR16350 | ||
| 8 | |||
| 9 | --- gcc-4.0.3/gcc/config/arm/linux-elf.h | ||
| 10 | +++ gcc-4.0.3/gcc/config/arm/linux-elf.h | ||
| 11 | @@ -31,19 +31,33 @@ | ||
| 12 | /* Do not assume anything about header files. */ | ||
| 13 | #define NO_IMPLICIT_EXTERN_C | ||
| 14 | |||
| 15 | +/* | ||
| 16 | + * 'config.gcc' defines TARGET_BIG_ENDIAN_DEFAULT as 1 for arm*b-* | ||
| 17 | + * (big endian) configurations. | ||
| 18 | + */ | ||
| 19 | +#if TARGET_BIG_ENDIAN_DEFAULT | ||
| 20 | +#define TARGET_ENDIAN_DEFAULT ARM_FLAG_BIG_END | ||
| 21 | +#define TARGET_ENDIAN_OPTION "mbig-endian" | ||
| 22 | +#define TARGET_LINKER_EMULATION "armelfb_linux" | ||
| 23 | +#else | ||
| 24 | +#define TARGET_ENDIAN_DEFAULT 0 | ||
| 25 | +#define TARGET_ENDIAN_OPTION "mlittle-endian" | ||
| 26 | +#define TARGET_LINKER_EMULATION "armelf_linux" | ||
| 27 | +#endif | ||
| 28 | + | ||
| 29 | #undef TARGET_DEFAULT_FLOAT_ABI | ||
| 30 | #define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_HARD | ||
| 31 | |||
| 32 | #undef TARGET_DEFAULT | ||
| 33 | -#define TARGET_DEFAULT (0) | ||
| 34 | +#define TARGET_DEFAULT (TARGET_ENDIAN_DEFAULT) | ||
| 35 | |||
| 36 | #define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm6 | ||
| 37 | |||
| 38 | -#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux -p" | ||
| 39 | +#define SUBTARGET_EXTRA_LINK_SPEC " -m " TARGET_LINKER_EMULATION " -p" | ||
| 40 | |||
| 41 | #undef MULTILIB_DEFAULTS | ||
| 42 | #define MULTILIB_DEFAULTS \ | ||
| 43 | - { "marm", "mlittle-endian", "mhard-float", "mno-thumb-interwork" } | ||
| 44 | + { "marm", TARGET_ENDIAN_OPTION, "mhard-float", "mno-thumb-interwork" } | ||
| 45 | |||
| 46 | /* The GNU C++ standard library requires that these macros be defined. */ | ||
| 47 | #undef CPLUSPLUS_CPP_SPEC | ||
| 48 | @@ -90,7 +104,7 @@ | ||
| 49 | %{rdynamic:-export-dynamic} \ | ||
| 50 | %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2} \ | ||
| 51 | -X \ | ||
| 52 | - %{mbig-endian:-EB}" \ | ||
| 53 | + %{mbig-endian:-EB} %{mlittle-endian:-EL}" \ | ||
| 54 | SUBTARGET_EXTRA_LINK_SPEC | ||
| 55 | |||
| 56 | #define TARGET_OS_CPP_BUILTINS() \ | ||
| 57 | --- gcc-4.0.3/gcc/config.gcc | ||
| 58 | +++ gcc-4.0.3/gcc/config.gcc | ||
| 59 | @@ -672,6 +672,11 @@ | ||
| 60 | ;; | ||
| 61 | arm*-*-linux*) # ARM GNU/Linux with ELF | ||
| 62 | tm_file="dbxelf.h elfos.h linux.h arm/elf.h arm/linux-gas.h arm/linux-elf.h arm/aout.h arm/arm.h" | ||
| 63 | + case $target in | ||
| 64 | + arm*b-*) | ||
| 65 | + tm_defines="TARGET_BIG_ENDIAN_DEFAULT=1 $tm_defines" | ||
| 66 | + ;; | ||
| 67 | + esac | ||
| 68 | tmake_file="${tmake_file} arm/t-arm arm/t-linux" | ||
| 69 | extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" | ||
| 70 | gnu_ld=yes | ||
diff --git a/meta/packages/gcc/gcc-4.0.2/GCOV_PREFIX_STRIP-cross-profile_4.1.patch b/meta/packages/gcc/gcc-4.0.2/GCOV_PREFIX_STRIP-cross-profile_4.1.patch deleted file mode 100644 index 92ce00a1e3..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/GCOV_PREFIX_STRIP-cross-profile_4.1.patch +++ /dev/null | |||
| @@ -1,371 +0,0 @@ | |||
| 1 | 2005-05-04 Grigory Zagorodnev <grigory.zagorodnev@intel.com> | ||
| 2 | H.J. Lu <hongjiu.lu@intel.com> | ||
| 3 | |||
| 4 | * gcov-io.c (gcov_open): When in libgcov library | ||
| 5 | use given data file relocation prefix to build file name. | ||
| 6 | * gcov-io.h (gcov_open): Updated proto to accept | ||
| 7 | data file relocation prefix. | ||
| 8 | * libgcov.c (create_file_directory): New function. | ||
| 9 | (gcov_prefix): New static variable to hold data file | ||
| 10 | relocation prefix. | ||
| 11 | (gcov_version): Use relocation prefix. | ||
| 12 | (gcov_exit): Always try to create directory for output | ||
| 13 | file. Relocate filename at each use. | ||
| 14 | (__gcov_init): Initialize directory relocation prefix | ||
| 15 | if required. Strip off leading directories from | ||
| 16 | the initial filename. | ||
| 17 | * tsystem.h: include filenames.h | ||
| 18 | (DIR_SEPARATOR): Macro copied from system.h. | ||
| 19 | (DIR_SEPARATOR_2): Likewise. | ||
| 20 | * doc/gcov.texi (Cross-profiling): New node documenting | ||
| 21 | cross-profiling management. | ||
| 22 | * doc/invoke.texi (-fprofile-arcs): xref to cross-profiling. | ||
| 23 | |||
| 24 | --- gcc-4/gcc/doc/gcov.texi.prefix 2005-03-28 11:56:34.000000000 -0800 | ||
| 25 | +++ gcc-4/gcc/doc/gcov.texi 2005-05-04 15:07:44.000000000 -0700 | ||
| 26 | @@ -42,6 +42,7 @@ test code coverage in your programs. | ||
| 27 | * Invoking Gcov:: How to use gcov. | ||
| 28 | * Gcov and Optimization:: Using gcov with GCC optimization. | ||
| 29 | * Gcov Data Files:: The files used by gcov. | ||
| 30 | +* Cross-profiling:: Data files relocation. | ||
| 31 | @end menu | ||
| 32 | |||
| 33 | @node Gcov Intro | ||
| 34 | @@ -531,3 +532,36 @@ information. | ||
| 35 | The full details of the file format is specified in @file{gcov-io.h}, | ||
| 36 | and functions provided in that header file should be used to access the | ||
| 37 | coverage files. | ||
| 38 | + | ||
| 39 | +@node Cross-profiling | ||
| 40 | +@section Data files relocation to support cross-profiling | ||
| 41 | + | ||
| 42 | +Running the program will cause profile output to be generated. For each | ||
| 43 | +source file compiled with @option{-fprofile-arcs}, an accompanying @file{.gcda} | ||
| 44 | +file will be placed in the object file directory. That implicitly requires | ||
| 45 | +running the program at the same system as it was build or having same | ||
| 46 | +absolute directory structure on the target system (program will try | ||
| 47 | +to create needed directory structure). | ||
| 48 | + | ||
| 49 | +To support cross-profiling, program compiled with @option{-fprofile-arcs} | ||
| 50 | +performs data file relocation basing on two environment variables: | ||
| 51 | + | ||
| 52 | +@itemize @bullet | ||
| 53 | +@item | ||
| 54 | +GCOV_PREFIX contains the prefix to add to the absolute paths | ||
| 55 | +in the object file. | ||
| 56 | + | ||
| 57 | +@item | ||
| 58 | +GCOV_PREFIX_STRIP indicates the how many initial directory names to strip off | ||
| 59 | +the hardwired absolute paths. Default value is 0. | ||
| 60 | +@end itemize | ||
| 61 | + | ||
| 62 | +For example, if object file @file{/user/build/foo.o} was build with | ||
| 63 | +@option{-fprofile-arcs}, the final executable will try to create data file | ||
| 64 | +@file{/user/build/foo.gcda} when running at the target system and will | ||
| 65 | +fail if corresponding directory does not exists and is not allowed to create. | ||
| 66 | + | ||
| 67 | +In this case, manipulating environment variables you can relocate data file | ||
| 68 | +to the suitable local directory. For our example, setting @samp{GCOV_PREFIX=/target/run} | ||
| 69 | +and @samp{GCOV_PREFIX_STRIP=1} values will force use of @file{/target/run/build/foo.gcda} | ||
| 70 | +file name. | ||
| 71 | --- gcc-4/gcc/doc/invoke.texi.prefix 2005-05-04 11:21:00.000000000 -0700 | ||
| 72 | +++ gcc-4/gcc/doc/invoke.texi 2005-05-04 15:07:44.000000000 -0700 | ||
| 73 | @@ -3420,6 +3420,7 @@ explicitly specified and it is not the f | ||
| 74 | the basename of the source file. In both cases any suffix is removed | ||
| 75 | (e.g.@: @file{foo.gcda} for input file @file{dir/foo.c}, or | ||
| 76 | @file{dir/foo.gcda} for output file specified as @option{-o dir/foo.o}). | ||
| 77 | +@xref{Cross-profiling}. | ||
| 78 | |||
| 79 | @cindex @command{gcov} | ||
| 80 | @item --coverage | ||
| 81 | --- gcc-4/gcc/gcov-io.c.prefix 2005-04-28 16:11:30.000000000 -0700 | ||
| 82 | +++ gcc-4/gcc/gcov-io.c 2005-05-04 20:02:35.000000000 -0700 | ||
| 83 | @@ -55,13 +55,14 @@ static inline gcov_unsigned_t from_file | ||
| 84 | |||
| 85 | GCOV_LINKAGE int | ||
| 86 | #if IN_LIBGCOV | ||
| 87 | -gcov_open (const char *name) | ||
| 88 | +gcov_open (const char *prefix, const char *name) | ||
| 89 | #else | ||
| 90 | gcov_open (const char *name, int mode) | ||
| 91 | #endif | ||
| 92 | { | ||
| 93 | #if IN_LIBGCOV | ||
| 94 | const int mode = 0; | ||
| 95 | + char *tmp; | ||
| 96 | #endif | ||
| 97 | #if GCOV_LOCKED | ||
| 98 | struct flock s_flock; | ||
| 99 | @@ -82,6 +83,13 @@ gcov_open (const char *name, int mode) | ||
| 100 | #if !IN_LIBGCOV | ||
| 101 | gcov_var.endian = 0; | ||
| 102 | #endif | ||
| 103 | + | ||
| 104 | +#if IN_LIBGCOV | ||
| 105 | + /* Build complete filename with prefix */ | ||
| 106 | + tmp = alloca (strlen (prefix) + strlen (name) + 1); | ||
| 107 | + name = strcat (strcpy (tmp, prefix), name); | ||
| 108 | +#endif | ||
| 109 | + | ||
| 110 | #if GCOV_LOCKED | ||
| 111 | if (mode > 0) | ||
| 112 | fd = open (name, O_RDWR); | ||
| 113 | --- gcc-4/gcc/gcov-io.h.prefix 2005-05-02 17:43:08.000000000 -0700 | ||
| 114 | +++ gcc-4/gcc/gcov-io.h 2005-05-04 15:07:44.000000000 -0700 | ||
| 115 | @@ -515,7 +515,7 @@ GCOV_LINKAGE struct gcov_var | ||
| 116 | functions for writing. Your file may become corrupted if you break | ||
| 117 | these invariants. */ | ||
| 118 | #if IN_LIBGCOV | ||
| 119 | -GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN; | ||
| 120 | +GCOV_LINKAGE int gcov_open (const char */*prefix*/, const char */*name*/) ATTRIBUTE_HIDDEN; | ||
| 121 | #else | ||
| 122 | GCOV_LINKAGE int gcov_open (const char */*name*/, int /*direction*/); | ||
| 123 | GCOV_LINKAGE int gcov_magic (gcov_unsigned_t, gcov_unsigned_t); | ||
| 124 | --- gcc-4/gcc/libgcov.c.prefix 2005-04-28 16:11:30.000000000 -0700 | ||
| 125 | +++ gcc-4/gcc/libgcov.c 2005-05-04 15:07:44.000000000 -0700 | ||
| 126 | @@ -92,6 +92,70 @@ static struct gcov_info *gcov_list; | ||
| 127 | object file included in multiple programs. */ | ||
| 128 | static gcov_unsigned_t gcov_crc32; | ||
| 129 | |||
| 130 | +/* Directory prefix to relocate coverage data file names */ | ||
| 131 | +static char *gcov_prefix = 0; | ||
| 132 | + | ||
| 133 | +/* Level of dirs to strip off the initial filename to relocate */ | ||
| 134 | +static int gcov_prefix_strip = 0; | ||
| 135 | + | ||
| 136 | +static int | ||
| 137 | +create_file_directory (const char *prefix, const char *filename) | ||
| 138 | +{ | ||
| 139 | + char *dname; | ||
| 140 | + char sep, *r, *s; | ||
| 141 | + size_t plen, flen; | ||
| 142 | + | ||
| 143 | + /* Detect directory separator */ | ||
| 144 | + s = strrchr (prefix, DIR_SEPARATOR); | ||
| 145 | +#ifdef DIR_SEPARATOR_2 | ||
| 146 | + if (! s) | ||
| 147 | + s = strrchr (prefix, DIR_SEPARATOR_2); | ||
| 148 | +#endif | ||
| 149 | + if (s) | ||
| 150 | + sep = *s; | ||
| 151 | + else | ||
| 152 | + sep = DIR_SEPARATOR; | ||
| 153 | + | ||
| 154 | + /* join prefix and filename, split path */ | ||
| 155 | + plen = strlen(prefix); | ||
| 156 | + flen = strlen(filename); | ||
| 157 | + r = alloca(plen + flen + 1); | ||
| 158 | + strncpy(r, prefix, plen); | ||
| 159 | + strncpy(r + plen, filename, flen); | ||
| 160 | + r[plen + flen] = '\0'; | ||
| 161 | + s = strrchr(r, sep); | ||
| 162 | + if (s) | ||
| 163 | + *(s + 1) = '\0'; | ||
| 164 | + | ||
| 165 | + if (access (r, F_OK) == 0) | ||
| 166 | + return 0; | ||
| 167 | + | ||
| 168 | + /* Skip consecutive separators. */ | ||
| 169 | + for (dname = r; *dname && *dname == sep; ++dname); | ||
| 170 | + while (1) | ||
| 171 | + { | ||
| 172 | + char *s = strchr (dname, sep); | ||
| 173 | + if (s == 0) | ||
| 174 | + break; | ||
| 175 | + *s = '\0'; | ||
| 176 | + /* Try to make directory if it doesn't already exist. */ | ||
| 177 | + if (access (r, F_OK) == -1 | ||
| 178 | + && mkdir (r, 0755) == -1 | ||
| 179 | + /* The directory might have been made by another process. */ | ||
| 180 | + && errno != EEXIST) | ||
| 181 | + { | ||
| 182 | + *s = sep; | ||
| 183 | + fprintf (stderr, "profiling:%s:Cannot create directory\n", r); | ||
| 184 | + return -1; | ||
| 185 | + }; | ||
| 186 | + *s = sep; | ||
| 187 | + /* Skip consecutive separators. */ | ||
| 188 | + for (dname = s + 1; *dname && *dname == sep; ++dname) | ||
| 189 | + ; | ||
| 190 | + } | ||
| 191 | + return 0; | ||
| 192 | +} | ||
| 193 | + | ||
| 194 | static int | ||
| 195 | gcov_version (struct gcov_info *ptr, gcov_unsigned_t version) | ||
| 196 | { | ||
| 197 | @@ -103,8 +167,8 @@ gcov_version (struct gcov_info *ptr, gco | ||
| 198 | GCOV_UNSIGNED2STRING (e, GCOV_VERSION); | ||
| 199 | |||
| 200 | fprintf (stderr, | ||
| 201 | - "profiling:%s:Version mismatch - expected %.4s got %.4s\n", | ||
| 202 | - ptr->filename, e, v); | ||
| 203 | + "profiling:%s%s:Version mismatch - expected %.4s got %.4s\n", | ||
| 204 | + gcov_prefix, ptr->filename, e, v); | ||
| 205 | return 0; | ||
| 206 | } | ||
| 207 | return 1; | ||
| 208 | @@ -205,9 +269,16 @@ gcov_exit (void) | ||
| 209 | fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1); | ||
| 210 | } | ||
| 211 | |||
| 212 | - if (!gcov_open (gi_ptr->filename)) | ||
| 213 | + if (create_file_directory (gcov_prefix, gi_ptr->filename)) | ||
| 214 | + { | ||
| 215 | + fprintf (stderr, "profiling:%s%s:Skip\n", gcov_prefix, | ||
| 216 | + gi_ptr->filename); | ||
| 217 | + continue; | ||
| 218 | + } | ||
| 219 | + else if (!gcov_open (gcov_prefix, gi_ptr->filename)) | ||
| 220 | { | ||
| 221 | - fprintf (stderr, "profiling:%s:Cannot open\n", gi_ptr->filename); | ||
| 222 | + fprintf (stderr, "profiling:%s%s:Cannot open\n", gcov_prefix, | ||
| 223 | + gi_ptr->filename); | ||
| 224 | continue; | ||
| 225 | } | ||
| 226 | |||
| 227 | @@ -217,8 +288,8 @@ gcov_exit (void) | ||
| 228 | /* Merge data from file. */ | ||
| 229 | if (tag != GCOV_DATA_MAGIC) | ||
| 230 | { | ||
| 231 | - fprintf (stderr, "profiling:%s:Not a gcov data file\n", | ||
| 232 | - gi_ptr->filename); | ||
| 233 | + fprintf (stderr, "profiling:%s%s:Not a gcov data file\n", | ||
| 234 | + gcov_prefix, gi_ptr->filename); | ||
| 235 | goto read_fatal; | ||
| 236 | } | ||
| 237 | length = gcov_read_unsigned (); | ||
| 238 | @@ -245,8 +316,8 @@ gcov_exit (void) | ||
| 239 | || gcov_read_unsigned () != fi_ptr->checksum) | ||
| 240 | { | ||
| 241 | read_mismatch:; | ||
| 242 | - fprintf (stderr, "profiling:%s:Merge mismatch for %s\n", | ||
| 243 | - gi_ptr->filename, | ||
| 244 | + fprintf (stderr, "profiling:%s%s:Merge mismatch for %s\n", | ||
| 245 | + gcov_prefix, gi_ptr->filename, | ||
| 246 | f_ix + 1 ? "function" : "summaries"); | ||
| 247 | goto read_fatal; | ||
| 248 | } | ||
| 249 | @@ -305,7 +376,8 @@ gcov_exit (void) | ||
| 250 | |||
| 251 | read_error:; | ||
| 252 | fprintf (stderr, error < 0 ? "profiling:%s:Overflow merging\n" | ||
| 253 | - : "profiling:%s:Error merging\n", gi_ptr->filename); | ||
| 254 | + : "profiling:%s%s:Error merging\n", gcov_prefix, | ||
| 255 | + gi_ptr->filename); | ||
| 256 | |||
| 257 | read_fatal:; | ||
| 258 | gcov_close (); | ||
| 259 | @@ -355,8 +427,8 @@ gcov_exit (void) | ||
| 260 | && (!GCOV_LOCKED || cs_all->runs == cs_prg->runs) | ||
| 261 | && memcmp (cs_all, cs_prg, sizeof (*cs_all))) | ||
| 262 | { | ||
| 263 | - fprintf (stderr, "profiling:%s:Invocation mismatch - some data files may have been removed%s", | ||
| 264 | - gi_ptr->filename, GCOV_LOCKED | ||
| 265 | + fprintf (stderr, "profiling:%s%s:Invocation mismatch - some data files may have been removed%s", | ||
| 266 | + gcov_prefix, gi_ptr->filename, GCOV_LOCKED | ||
| 267 | ? "" : " or concurrent update without locking support"); | ||
| 268 | all.checksum = ~0u; | ||
| 269 | } | ||
| 270 | @@ -419,9 +491,9 @@ gcov_exit (void) | ||
| 271 | gcov_write_unsigned (0); | ||
| 272 | if ((error = gcov_close ())) | ||
| 273 | fprintf (stderr, error < 0 ? | ||
| 274 | - "profiling:%s:Overflow writing\n" : | ||
| 275 | - "profiling:%s:Error writing\n", | ||
| 276 | - gi_ptr->filename); | ||
| 277 | + "profiling:%s%s:Overflow writing\n" : | ||
| 278 | + "profiling:%s%s:Error writing\n", | ||
| 279 | + gcov_prefix, gi_ptr->filename); | ||
| 280 | } | ||
| 281 | } | ||
| 282 | |||
| 283 | @@ -431,11 +503,69 @@ gcov_exit (void) | ||
| 284 | void | ||
| 285 | __gcov_init (struct gcov_info *info) | ||
| 286 | { | ||
| 287 | + /* Save initial filename pointer to calculate CRC. */ | ||
| 288 | + const char *ptr = info->filename; | ||
| 289 | + | ||
| 290 | if (!info->version) | ||
| 291 | return; | ||
| 292 | + | ||
| 293 | + /* Initialize directory prefix if requred */ | ||
| 294 | + if (gcov_prefix == 0) | ||
| 295 | + { | ||
| 296 | + if ((gcov_prefix = getenv("GCOV_PREFIX"))) | ||
| 297 | + { | ||
| 298 | + char *tmp; | ||
| 299 | + | ||
| 300 | + /* Normalize prefix: take off trailing separator. */ | ||
| 301 | + tmp = gcov_prefix + strlen(gcov_prefix) - 1; | ||
| 302 | + if (IS_DIR_SEPARATOR(*tmp)) | ||
| 303 | + *tmp = '\0'; | ||
| 304 | + | ||
| 305 | + /* Check if the level of dirs to strip off specified */ | ||
| 306 | + if ((tmp = getenv("GCOV_PREFIX_STRIP"))) | ||
| 307 | + { | ||
| 308 | + gcov_prefix_strip = atoi (tmp); | ||
| 309 | + /* Do not consider negative values. */ | ||
| 310 | + if (gcov_prefix_strip < 0) | ||
| 311 | + gcov_prefix_strip = 0; | ||
| 312 | + }; | ||
| 313 | + } | ||
| 314 | + else | ||
| 315 | + gcov_prefix = (char *) ""; | ||
| 316 | + }; | ||
| 317 | + | ||
| 318 | + /* Strip off leading directories from the initial filename */ | ||
| 319 | + if (gcov_prefix_strip > 0) | ||
| 320 | + { | ||
| 321 | + char sep, *s; | ||
| 322 | + int level; | ||
| 323 | + const char *fname = info->filename; | ||
| 324 | + | ||
| 325 | + /* Detect directory separator */ | ||
| 326 | + s = strrchr (fname, DIR_SEPARATOR); | ||
| 327 | +#ifdef DIR_SEPARATOR_2 | ||
| 328 | + if (! s) | ||
| 329 | + s = strrchr (fname, DIR_SEPARATOR_2); | ||
| 330 | +#endif | ||
| 331 | + if (s) | ||
| 332 | + sep = *s; | ||
| 333 | + else | ||
| 334 | + sep = DIR_SEPARATOR; | ||
| 335 | + | ||
| 336 | + /* Skip selected directory levels */ | ||
| 337 | + for ( level = gcov_prefix_strip; level > 0; level--) | ||
| 338 | + if ((s = strchr(fname + 1, sep))) | ||
| 339 | + fname = s; | ||
| 340 | + else | ||
| 341 | + break; | ||
| 342 | + | ||
| 343 | + /* From this point info block refers stripped file name and | ||
| 344 | + further operations must add prefix to get complete name.*/ | ||
| 345 | + info->filename = fname; | ||
| 346 | + }; | ||
| 347 | + | ||
| 348 | if (gcov_version (info, info->version)) | ||
| 349 | { | ||
| 350 | - const char *ptr = info->filename; | ||
| 351 | gcov_unsigned_t crc32 = gcov_crc32; | ||
| 352 | |||
| 353 | do | ||
| 354 | --- gcc-4/gcc/tsystem.h.prefix 2005-03-29 16:06:26.000000000 -0800 | ||
| 355 | +++ gcc-4/gcc/tsystem.h 2005-05-04 15:07:44.000000000 -0700 | ||
| 356 | @@ -131,4 +131,15 @@ extern int errno; | ||
| 357 | unreachable default case of a switch. Do not use gcc_assert(0). */ | ||
| 358 | #define gcc_unreachable() (abort ()) | ||
| 359 | |||
| 360 | +/* Filename handling macros. */ | ||
| 361 | +#include "filenames.h" | ||
| 362 | + | ||
| 363 | +/* These should be phased out in favor of IS_DIR_SEPARATOR, where possible. */ | ||
| 364 | +#ifndef DIR_SEPARATOR | ||
| 365 | +# define DIR_SEPARATOR '/' | ||
| 366 | +# ifdef HAVE_DOS_BASED_FILE_SYSTEM | ||
| 367 | +# define DIR_SEPARATOR_2 '\\' | ||
| 368 | +# endif | ||
| 369 | +#endif | ||
| 370 | + | ||
| 371 | #endif /* ! GCC_TSYSTEM_H */ | ||
diff --git a/meta/packages/gcc/gcc-4.0.2/arm-nolibfloat.patch b/meta/packages/gcc/gcc-4.0.2/arm-nolibfloat.patch deleted file mode 100644 index c4897c0330..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/arm-nolibfloat.patch +++ /dev/null | |||
| @@ -1,24 +0,0 @@ | |||
| 1 | # Dimitry Andric <dimitry@andric.com>, 2004-05-01 | ||
| 2 | # | ||
| 3 | # * Removed the extra -lfloat option from LIBGCC_SPEC, since it isn't needed | ||
| 4 | # anymore. (The required functions are now in libgcc.) | ||
| 5 | # | ||
| 6 | # Fixes errors like | ||
| 7 | # arm-softfloat-linux-gnu/3.4.0/../../../../arm-softfloat-linux-gnu/bin/ld: cannot find -lfloat | ||
| 8 | # collect2: ld returned 1 exit status | ||
| 9 | # make[2]: *** [arm-softfloat-linux-gnu/gcc-3.4.0-glibc-2.3.2/build-glibc/iconvdata/ISO8859-1.so] Error 1 | ||
| 10 | # when building glibc-2.3.3 with gcc-3.4.0 for arm-softfloat | ||
| 11 | |||
| 12 | Index: gcc-4.0.2/gcc/config/arm/linux-elf.h | ||
| 13 | =================================================================== | ||
| 14 | --- gcc-4.0.2.orig/gcc/config/arm/linux-elf.h 2005-03-04 16:14:01.000000000 +0000 | ||
| 15 | +++ gcc-4.0.2/gcc/config/arm/linux-elf.h 2005-11-11 18:02:54.000000000 +0000 | ||
| 16 | @@ -56,7 +56,7 @@ | ||
| 17 | %{shared:-lc} \ | ||
| 18 | %{!shared:%{profile:-lc_p}%{!profile:-lc}}" | ||
| 19 | |||
| 20 | -#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc" | ||
| 21 | +#define LIBGCC_SPEC "-lgcc" | ||
| 22 | |||
| 23 | /* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add | ||
| 24 | the GNU/Linux magical crtbegin.o file (see crtstuff.c) which | ||
diff --git a/meta/packages/gcc/gcc-4.0.2/arm-softfloat.patch b/meta/packages/gcc/gcc-4.0.2/arm-softfloat.patch deleted file mode 100644 index c86c83ed15..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/arm-softfloat.patch +++ /dev/null | |||
| @@ -1,16 +0,0 @@ | |||
| 1 | Index: gcc-4.0.2/gcc/config/arm/t-linux | ||
| 2 | =================================================================== | ||
| 3 | --- gcc-4.0.2.orig/gcc/config/arm/t-linux 2004-05-15 12:41:35.000000000 +0000 | ||
| 4 | +++ gcc-4.0.2/gcc/config/arm/t-linux 2005-11-11 16:07:53.000000000 +0000 | ||
| 5 | @@ -4,7 +4,10 @@ | ||
| 6 | LIBGCC2_DEBUG_CFLAGS = -g0 | ||
| 7 | |||
| 8 | LIB1ASMSRC = arm/lib1funcs.asm | ||
| 9 | -LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx | ||
| 10 | +LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx \ | ||
| 11 | + _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \ | ||
| 12 | + _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \ | ||
| 13 | + _fixsfsi _fixunssfsi _floatdidf _floatdisf | ||
| 14 | |||
| 15 | # MULTILIB_OPTIONS = mhard-float/msoft-float | ||
| 16 | # MULTILIB_DIRNAMES = hard-float soft-float | ||
diff --git a/meta/packages/gcc/gcc-4.0.2/gcc-4.0.2-atmel.0.99.2.patch b/meta/packages/gcc/gcc-4.0.2/gcc-4.0.2-atmel.0.99.2.patch deleted file mode 100644 index 273846f565..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/gcc-4.0.2-atmel.0.99.2.patch +++ /dev/null | |||
| @@ -1,21330 +0,0 @@ | |||
| 1 | diff -Nrup --ignore-space-change gcc-4.0.2/config.sub gcc-4.0.2-atmel.0.99.2/config.sub | ||
| 2 | --- gcc-4.0.2/config.sub 2005-04-25 12:36:56.000000000 +0200 | ||
| 3 | +++ gcc-4.0.2-atmel.0.99.2/config.sub 2005-06-07 14:59:22.000000000 +0200 | ||
| 4 | @@ -1,9 +1,9 @@ | ||
| 5 | #! /bin/sh | ||
| 6 | # Configuration validation subroutine script. | ||
| 7 | # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | ||
| 8 | -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. | ||
| 9 | +# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. | ||
| 10 | |||
| 11 | -timestamp='2005-04-22' | ||
| 12 | +timestamp='2005-06-07' | ||
| 13 | |||
| 14 | # This file is (in principle) common to ALL GNU software. | ||
| 15 | # The presence of a machine in this file suggests that SOME GNU software | ||
| 16 | @@ -70,7 +70,7 @@ Report bugs and patches to <config-patch | ||
| 17 | version="\ | ||
| 18 | GNU config.sub ($timestamp) | ||
| 19 | |||
| 20 | -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 | ||
| 21 | +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 | ||
| 22 | Free Software Foundation, Inc. | ||
| 23 | |||
| 24 | This is free software; see the source for copying conditions. There is NO | ||
| 25 | @@ -230,8 +230,7 @@ case $basic_machine in | ||
| 26 | | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | ||
| 27 | | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | ||
| 28 | | am33_2.0 \ | ||
| 29 | - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | ||
| 30 | - | bfin \ | ||
| 31 | + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | ||
| 32 | | c4x | clipper \ | ||
| 33 | | d10v | d30v | dlx | dsp16xx \ | ||
| 34 | | fr30 | frv \ | ||
| 35 | @@ -263,8 +262,7 @@ case $basic_machine in | ||
| 36 | | pyramid \ | ||
| 37 | | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | ||
| 38 | | sh64 | sh64le \ | ||
| 39 | - | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ | ||
| 40 | - | sparcv8 | sparcv9 | sparcv9b \ | ||
| 41 | + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \ | ||
| 42 | | strongarm \ | ||
| 43 | | tahoe | thumb | tic4x | tic80 | tron \ | ||
| 44 | | v850 | v850e \ | ||
| 45 | @@ -299,8 +297,8 @@ case $basic_machine in | ||
| 46 | | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | ||
| 47 | | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | ||
| 48 | | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | ||
| 49 | - | avr-* \ | ||
| 50 | - | bfin-* | bs2000-* \ | ||
| 51 | + | avr-* | avr32-* \ | ||
| 52 | + | bs2000-* \ | ||
| 53 | | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | ||
| 54 | | clipper-* | craynv-* | cydra-* \ | ||
| 55 | | d10v-* | d30v-* | dlx-* \ | ||
| 56 | @@ -338,8 +336,7 @@ case $basic_machine in | ||
| 57 | | romp-* | rs6000-* \ | ||
| 58 | | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | ||
| 59 | | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | ||
| 60 | - | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ | ||
| 61 | - | sparclite-* \ | ||
| 62 | + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ | ||
| 63 | | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | ||
| 64 | | tahoe-* | thumb-* \ | ||
| 65 | | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | ||
| 66 | diff -Nrup --ignore-space-change gcc-4.0.2/configure gcc-4.0.2-atmel.0.99.2/configure | ||
| 67 | --- gcc-4.0.2/configure 2005-09-13 09:01:28.000000000 +0200 | ||
| 68 | +++ gcc-4.0.2-atmel.0.99.2/configure 2006-01-20 14:31:15.000000000 +0100 | ||
| 69 | @@ -1284,6 +1284,9 @@ case "${target}" in | ||
| 70 | arm-*-riscix*) | ||
| 71 | noconfigdirs="$noconfigdirs ld target-libgloss ${libgcj}" | ||
| 72 | ;; | ||
| 73 | + avr32-*-*) | ||
| 74 | + noconfigdirs="$noconfigdirs target-libiberty target-libmudflap target-libffi ${libgcj}" | ||
| 75 | + ;; | ||
| 76 | avr-*-*) | ||
| 77 | noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}" | ||
| 78 | ;; | ||
| 79 | @@ -1804,7 +1807,7 @@ else | ||
| 80 | # Extract the first word of "gcc", so it can be a program name with args. | ||
| 81 | set dummy gcc; ac_word=$2 | ||
| 82 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 83 | -echo "configure:1808: checking for $ac_word" >&5 | ||
| 84 | +echo "configure:1811: checking for $ac_word" >&5 | ||
| 85 | if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then | ||
| 86 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 87 | else | ||
| 88 | @@ -1834,7 +1837,7 @@ if test -z "$CC"; then | ||
| 89 | # Extract the first word of "cc", so it can be a program name with args. | ||
| 90 | set dummy cc; ac_word=$2 | ||
| 91 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 92 | -echo "configure:1838: checking for $ac_word" >&5 | ||
| 93 | +echo "configure:1841: checking for $ac_word" >&5 | ||
| 94 | if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then | ||
| 95 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 96 | else | ||
| 97 | @@ -1885,7 +1888,7 @@ fi | ||
| 98 | # Extract the first word of "cl", so it can be a program name with args. | ||
| 99 | set dummy cl; ac_word=$2 | ||
| 100 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 101 | -echo "configure:1889: checking for $ac_word" >&5 | ||
| 102 | +echo "configure:1892: checking for $ac_word" >&5 | ||
| 103 | if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then | ||
| 104 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 105 | else | ||
| 106 | @@ -1917,7 +1920,7 @@ fi | ||
| 107 | fi | ||
| 108 | |||
| 109 | echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 | ||
| 110 | -echo "configure:1921: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 | ||
| 111 | +echo "configure:1924: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 | ||
| 112 | |||
| 113 | ac_ext=c | ||
| 114 | # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. | ||
| 115 | @@ -1928,12 +1931,12 @@ cross_compiling=$ac_cv_prog_cc_cross | ||
| 116 | |||
| 117 | cat > conftest.$ac_ext << EOF | ||
| 118 | |||
| 119 | -#line 1932 "configure" | ||
| 120 | +#line 1935 "configure" | ||
| 121 | #include "confdefs.h" | ||
| 122 | |||
| 123 | main(){return(0);} | ||
| 124 | EOF | ||
| 125 | -if { (eval echo configure:1937: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then | ||
| 126 | +if { (eval echo configure:1940: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then | ||
| 127 | ac_cv_prog_cc_works=yes | ||
| 128 | # If we can't run a trivial program, we are probably using a cross compiler. | ||
| 129 | if (./conftest; exit) 2>/dev/null; then | ||
| 130 | @@ -1959,12 +1962,12 @@ if test $ac_cv_prog_cc_works = no; then | ||
| 131 | { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } | ||
| 132 | fi | ||
| 133 | echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 | ||
| 134 | -echo "configure:1963: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 | ||
| 135 | +echo "configure:1966: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 | ||
| 136 | echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 | ||
| 137 | cross_compiling=$ac_cv_prog_cc_cross | ||
| 138 | |||
| 139 | echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 | ||
| 140 | -echo "configure:1968: checking whether we are using GNU C" >&5 | ||
| 141 | +echo "configure:1971: checking whether we are using GNU C" >&5 | ||
| 142 | if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then | ||
| 143 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 144 | else | ||
| 145 | @@ -1973,7 +1976,7 @@ else | ||
| 146 | yes; | ||
| 147 | #endif | ||
| 148 | EOF | ||
| 149 | -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1977: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then | ||
| 150 | +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1980: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then | ||
| 151 | ac_cv_prog_gcc=yes | ||
| 152 | else | ||
| 153 | ac_cv_prog_gcc=no | ||
| 154 | @@ -1992,7 +1995,7 @@ ac_test_CFLAGS="${CFLAGS+set}" | ||
| 155 | ac_save_CFLAGS="$CFLAGS" | ||
| 156 | CFLAGS= | ||
| 157 | echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 | ||
| 158 | -echo "configure:1996: checking whether ${CC-cc} accepts -g" >&5 | ||
| 159 | +echo "configure:1999: checking whether ${CC-cc} accepts -g" >&5 | ||
| 160 | if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then | ||
| 161 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 162 | else | ||
| 163 | @@ -2059,7 +2062,7 @@ fi | ||
| 164 | # Extract the first word of "${ac_tool_prefix}gnatbind", so it can be a program name with args. | ||
| 165 | set dummy ${ac_tool_prefix}gnatbind; ac_word=$2 | ||
| 166 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 167 | -echo "configure:2063: checking for $ac_word" >&5 | ||
| 168 | +echo "configure:2066: checking for $ac_word" >&5 | ||
| 169 | if eval "test \"`echo '$''{'ac_cv_prog_GNATBIND'+set}'`\" = set"; then | ||
| 170 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 171 | else | ||
| 172 | @@ -2091,7 +2094,7 @@ if test -n "$ac_tool_prefix"; then | ||
| 173 | # Extract the first word of "gnatbind", so it can be a program name with args. | ||
| 174 | set dummy gnatbind; ac_word=$2 | ||
| 175 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 176 | -echo "configure:2095: checking for $ac_word" >&5 | ||
| 177 | +echo "configure:2098: checking for $ac_word" >&5 | ||
| 178 | if eval "test \"`echo '$''{'ac_cv_prog_GNATBIND'+set}'`\" = set"; then | ||
| 179 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 180 | else | ||
| 181 | @@ -2124,7 +2127,7 @@ fi | ||
| 182 | fi | ||
| 183 | |||
| 184 | echo $ac_n "checking whether compiler driver understands Ada""... $ac_c" 1>&6 | ||
| 185 | -echo "configure:2128: checking whether compiler driver understands Ada" >&5 | ||
| 186 | +echo "configure:2131: checking whether compiler driver understands Ada" >&5 | ||
| 187 | if eval "test \"`echo '$''{'acx_cv_cc_gcc_supports_ada'+set}'`\" = set"; then | ||
| 188 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 189 | else | ||
| 190 | @@ -2156,7 +2159,7 @@ else | ||
| 191 | fi | ||
| 192 | |||
| 193 | echo $ac_n "checking how to compare bootstrapped objects""... $ac_c" 1>&6 | ||
| 194 | -echo "configure:2160: checking how to compare bootstrapped objects" >&5 | ||
| 195 | +echo "configure:2163: checking how to compare bootstrapped objects" >&5 | ||
| 196 | if eval "test \"`echo '$''{'gcc_cv_prog_cmp_skip'+set}'`\" = set"; then | ||
| 197 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 198 | else | ||
| 199 | @@ -2254,9 +2257,9 @@ saved_CFLAGS="$CFLAGS" | ||
| 200 | CFLAGS="$CFLAGS $gmpinc" | ||
| 201 | # Check GMP actually works | ||
| 202 | echo $ac_n "checking for correct version of gmp.h""... $ac_c" 1>&6 | ||
| 203 | -echo "configure:2258: checking for correct version of gmp.h" >&5 | ||
| 204 | +echo "configure:2261: checking for correct version of gmp.h" >&5 | ||
| 205 | cat > conftest.$ac_ext <<EOF | ||
| 206 | -#line 2260 "configure" | ||
| 207 | +#line 2263 "configure" | ||
| 208 | #include "confdefs.h" | ||
| 209 | #include "gmp.h" | ||
| 210 | int main() { | ||
| 211 | @@ -2267,7 +2270,7 @@ choke me | ||
| 212 | |||
| 213 | ; return 0; } | ||
| 214 | EOF | ||
| 215 | -if { (eval echo configure:2271: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then | ||
| 216 | +if { (eval echo configure:2274: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then | ||
| 217 | rm -rf conftest* | ||
| 218 | echo "$ac_t""yes" 1>&6 | ||
| 219 | else | ||
| 220 | @@ -2280,12 +2283,12 @@ rm -f conftest* | ||
| 221 | |||
| 222 | if test x"$have_gmp" = xyes; then | ||
| 223 | echo $ac_n "checking for MPFR""... $ac_c" 1>&6 | ||
| 224 | -echo "configure:2284: checking for MPFR" >&5 | ||
| 225 | +echo "configure:2287: checking for MPFR" >&5 | ||
| 226 | |||
| 227 | saved_LIBS="$LIBS" | ||
| 228 | LIBS="$LIBS $gmplibs" | ||
| 229 | cat > conftest.$ac_ext <<EOF | ||
| 230 | -#line 2289 "configure" | ||
| 231 | +#line 2292 "configure" | ||
| 232 | #include "confdefs.h" | ||
| 233 | #include <gmp.h> | ||
| 234 | #include <mpfr.h> | ||
| 235 | @@ -2293,7 +2296,7 @@ int main() { | ||
| 236 | mpfr_t n; mpfr_init(n); | ||
| 237 | ; return 0; } | ||
| 238 | EOF | ||
| 239 | -if { (eval echo configure:2297: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then | ||
| 240 | +if { (eval echo configure:2300: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then | ||
| 241 | rm -rf conftest* | ||
| 242 | echo "$ac_t""yes" 1>&6 | ||
| 243 | else | ||
| 244 | @@ -2789,7 +2792,7 @@ do | ||
| 245 | # Extract the first word of "$ac_prog", so it can be a program name with args. | ||
| 246 | set dummy $ac_prog; ac_word=$2 | ||
| 247 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 248 | -echo "configure:2793: checking for $ac_word" >&5 | ||
| 249 | +echo "configure:2796: checking for $ac_word" >&5 | ||
| 250 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_BISON'+set}'`\" = set"; then | ||
| 251 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 252 | else | ||
| 253 | @@ -2824,7 +2827,7 @@ do | ||
| 254 | # Extract the first word of "$ac_prog", so it can be a program name with args. | ||
| 255 | set dummy $ac_prog; ac_word=$2 | ||
| 256 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 257 | -echo "configure:2828: checking for $ac_word" >&5 | ||
| 258 | +echo "configure:2831: checking for $ac_word" >&5 | ||
| 259 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_YACC'+set}'`\" = set"; then | ||
| 260 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 261 | else | ||
| 262 | @@ -2859,7 +2862,7 @@ do | ||
| 263 | # Extract the first word of "$ac_prog", so it can be a program name with args. | ||
| 264 | set dummy $ac_prog; ac_word=$2 | ||
| 265 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 266 | -echo "configure:2863: checking for $ac_word" >&5 | ||
| 267 | +echo "configure:2866: checking for $ac_word" >&5 | ||
| 268 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_M4'+set}'`\" = set"; then | ||
| 269 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 270 | else | ||
| 271 | @@ -2894,7 +2897,7 @@ do | ||
| 272 | # Extract the first word of "$ac_prog", so it can be a program name with args. | ||
| 273 | set dummy $ac_prog; ac_word=$2 | ||
| 274 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 275 | -echo "configure:2898: checking for $ac_word" >&5 | ||
| 276 | +echo "configure:2901: checking for $ac_word" >&5 | ||
| 277 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_FLEX'+set}'`\" = set"; then | ||
| 278 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 279 | else | ||
| 280 | @@ -2929,7 +2932,7 @@ do | ||
| 281 | # Extract the first word of "$ac_prog", so it can be a program name with args. | ||
| 282 | set dummy $ac_prog; ac_word=$2 | ||
| 283 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 284 | -echo "configure:2933: checking for $ac_word" >&5 | ||
| 285 | +echo "configure:2936: checking for $ac_word" >&5 | ||
| 286 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_LEX'+set}'`\" = set"; then | ||
| 287 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 288 | else | ||
| 289 | @@ -2964,7 +2967,7 @@ do | ||
| 290 | # Extract the first word of "$ac_prog", so it can be a program name with args. | ||
| 291 | set dummy $ac_prog; ac_word=$2 | ||
| 292 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 293 | -echo "configure:2968: checking for $ac_word" >&5 | ||
| 294 | +echo "configure:2971: checking for $ac_word" >&5 | ||
| 295 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_MAKEINFO'+set}'`\" = set"; then | ||
| 296 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 297 | else | ||
| 298 | @@ -3611,7 +3614,7 @@ test -n "$target_alias" && ncn_target_to | ||
| 299 | # Extract the first word of "${ncn_tool_prefix}ar", so it can be a program name with args. | ||
| 300 | set dummy ${ncn_tool_prefix}ar; ac_word=$2 | ||
| 301 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 302 | -echo "configure:3615: checking for $ac_word" >&5 | ||
| 303 | +echo "configure:3618: checking for $ac_word" >&5 | ||
| 304 | if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then | ||
| 305 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 306 | else | ||
| 307 | @@ -3644,7 +3647,7 @@ if test -z "$ac_cv_prog_AR" ; then | ||
| 308 | # Extract the first word of "ar", so it can be a program name with args. | ||
| 309 | set dummy ar; ac_word=$2 | ||
| 310 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 311 | -echo "configure:3648: checking for $ac_word" >&5 | ||
| 312 | +echo "configure:3651: checking for $ac_word" >&5 | ||
| 313 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_AR'+set}'`\" = set"; then | ||
| 314 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 315 | else | ||
| 316 | @@ -3683,7 +3686,7 @@ fi | ||
| 317 | # Extract the first word of "${ncn_tool_prefix}as", so it can be a program name with args. | ||
| 318 | set dummy ${ncn_tool_prefix}as; ac_word=$2 | ||
| 319 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 320 | -echo "configure:3687: checking for $ac_word" >&5 | ||
| 321 | +echo "configure:3690: checking for $ac_word" >&5 | ||
| 322 | if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then | ||
| 323 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 324 | else | ||
| 325 | @@ -3716,7 +3719,7 @@ if test -z "$ac_cv_prog_AS" ; then | ||
| 326 | # Extract the first word of "as", so it can be a program name with args. | ||
| 327 | set dummy as; ac_word=$2 | ||
| 328 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 329 | -echo "configure:3720: checking for $ac_word" >&5 | ||
| 330 | +echo "configure:3723: checking for $ac_word" >&5 | ||
| 331 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_AS'+set}'`\" = set"; then | ||
| 332 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 333 | else | ||
| 334 | @@ -3755,7 +3758,7 @@ fi | ||
| 335 | # Extract the first word of "${ncn_tool_prefix}dlltool", so it can be a program name with args. | ||
| 336 | set dummy ${ncn_tool_prefix}dlltool; ac_word=$2 | ||
| 337 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 338 | -echo "configure:3759: checking for $ac_word" >&5 | ||
| 339 | +echo "configure:3762: checking for $ac_word" >&5 | ||
| 340 | if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then | ||
| 341 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 342 | else | ||
| 343 | @@ -3788,7 +3791,7 @@ if test -z "$ac_cv_prog_DLLTOOL" ; then | ||
| 344 | # Extract the first word of "dlltool", so it can be a program name with args. | ||
| 345 | set dummy dlltool; ac_word=$2 | ||
| 346 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 347 | -echo "configure:3792: checking for $ac_word" >&5 | ||
| 348 | +echo "configure:3795: checking for $ac_word" >&5 | ||
| 349 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_DLLTOOL'+set}'`\" = set"; then | ||
| 350 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 351 | else | ||
| 352 | @@ -3827,7 +3830,7 @@ fi | ||
| 353 | # Extract the first word of "${ncn_tool_prefix}ld", so it can be a program name with args. | ||
| 354 | set dummy ${ncn_tool_prefix}ld; ac_word=$2 | ||
| 355 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 356 | -echo "configure:3831: checking for $ac_word" >&5 | ||
| 357 | +echo "configure:3834: checking for $ac_word" >&5 | ||
| 358 | if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then | ||
| 359 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 360 | else | ||
| 361 | @@ -3860,7 +3863,7 @@ if test -z "$ac_cv_prog_LD" ; then | ||
| 362 | # Extract the first word of "ld", so it can be a program name with args. | ||
| 363 | set dummy ld; ac_word=$2 | ||
| 364 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 365 | -echo "configure:3864: checking for $ac_word" >&5 | ||
| 366 | +echo "configure:3867: checking for $ac_word" >&5 | ||
| 367 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_LD'+set}'`\" = set"; then | ||
| 368 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 369 | else | ||
| 370 | @@ -3899,7 +3902,7 @@ fi | ||
| 371 | # Extract the first word of "${ncn_tool_prefix}nm", so it can be a program name with args. | ||
| 372 | set dummy ${ncn_tool_prefix}nm; ac_word=$2 | ||
| 373 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 374 | -echo "configure:3903: checking for $ac_word" >&5 | ||
| 375 | +echo "configure:3906: checking for $ac_word" >&5 | ||
| 376 | if eval "test \"`echo '$''{'ac_cv_prog_NM'+set}'`\" = set"; then | ||
| 377 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 378 | else | ||
| 379 | @@ -3932,7 +3935,7 @@ if test -z "$ac_cv_prog_NM" ; then | ||
| 380 | # Extract the first word of "nm", so it can be a program name with args. | ||
| 381 | set dummy nm; ac_word=$2 | ||
| 382 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 383 | -echo "configure:3936: checking for $ac_word" >&5 | ||
| 384 | +echo "configure:3939: checking for $ac_word" >&5 | ||
| 385 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_NM'+set}'`\" = set"; then | ||
| 386 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 387 | else | ||
| 388 | @@ -3971,7 +3974,7 @@ fi | ||
| 389 | # Extract the first word of "${ncn_tool_prefix}ranlib", so it can be a program name with args. | ||
| 390 | set dummy ${ncn_tool_prefix}ranlib; ac_word=$2 | ||
| 391 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 392 | -echo "configure:3975: checking for $ac_word" >&5 | ||
| 393 | +echo "configure:3978: checking for $ac_word" >&5 | ||
| 394 | if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then | ||
| 395 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 396 | else | ||
| 397 | @@ -4004,7 +4007,7 @@ if test -z "$ac_cv_prog_RANLIB" ; then | ||
| 398 | # Extract the first word of "ranlib", so it can be a program name with args. | ||
| 399 | set dummy ranlib; ac_word=$2 | ||
| 400 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 401 | -echo "configure:4008: checking for $ac_word" >&5 | ||
| 402 | +echo "configure:4011: checking for $ac_word" >&5 | ||
| 403 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_RANLIB'+set}'`\" = set"; then | ||
| 404 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 405 | else | ||
| 406 | @@ -4043,7 +4046,7 @@ fi | ||
| 407 | # Extract the first word of "${ncn_tool_prefix}windres", so it can be a program name with args. | ||
| 408 | set dummy ${ncn_tool_prefix}windres; ac_word=$2 | ||
| 409 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 410 | -echo "configure:4047: checking for $ac_word" >&5 | ||
| 411 | +echo "configure:4050: checking for $ac_word" >&5 | ||
| 412 | if eval "test \"`echo '$''{'ac_cv_prog_WINDRES'+set}'`\" = set"; then | ||
| 413 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 414 | else | ||
| 415 | @@ -4076,7 +4079,7 @@ if test -z "$ac_cv_prog_WINDRES" ; then | ||
| 416 | # Extract the first word of "windres", so it can be a program name with args. | ||
| 417 | set dummy windres; ac_word=$2 | ||
| 418 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 419 | -echo "configure:4080: checking for $ac_word" >&5 | ||
| 420 | +echo "configure:4083: checking for $ac_word" >&5 | ||
| 421 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_WINDRES'+set}'`\" = set"; then | ||
| 422 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 423 | else | ||
| 424 | @@ -4115,7 +4118,7 @@ fi | ||
| 425 | # Extract the first word of "${ncn_tool_prefix}objcopy", so it can be a program name with args. | ||
| 426 | set dummy ${ncn_tool_prefix}objcopy; ac_word=$2 | ||
| 427 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 428 | -echo "configure:4119: checking for $ac_word" >&5 | ||
| 429 | +echo "configure:4122: checking for $ac_word" >&5 | ||
| 430 | if eval "test \"`echo '$''{'ac_cv_prog_OBJCOPY'+set}'`\" = set"; then | ||
| 431 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 432 | else | ||
| 433 | @@ -4148,7 +4151,7 @@ if test -z "$ac_cv_prog_OBJCOPY" ; then | ||
| 434 | # Extract the first word of "objcopy", so it can be a program name with args. | ||
| 435 | set dummy objcopy; ac_word=$2 | ||
| 436 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 437 | -echo "configure:4152: checking for $ac_word" >&5 | ||
| 438 | +echo "configure:4155: checking for $ac_word" >&5 | ||
| 439 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_OBJCOPY'+set}'`\" = set"; then | ||
| 440 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 441 | else | ||
| 442 | @@ -4187,7 +4190,7 @@ fi | ||
| 443 | # Extract the first word of "${ncn_tool_prefix}objdump", so it can be a program name with args. | ||
| 444 | set dummy ${ncn_tool_prefix}objdump; ac_word=$2 | ||
| 445 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 446 | -echo "configure:4191: checking for $ac_word" >&5 | ||
| 447 | +echo "configure:4194: checking for $ac_word" >&5 | ||
| 448 | if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then | ||
| 449 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 450 | else | ||
| 451 | @@ -4220,7 +4223,7 @@ if test -z "$ac_cv_prog_OBJDUMP" ; then | ||
| 452 | # Extract the first word of "objdump", so it can be a program name with args. | ||
| 453 | set dummy objdump; ac_word=$2 | ||
| 454 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 455 | -echo "configure:4224: checking for $ac_word" >&5 | ||
| 456 | +echo "configure:4227: checking for $ac_word" >&5 | ||
| 457 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_OBJDUMP'+set}'`\" = set"; then | ||
| 458 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 459 | else | ||
| 460 | @@ -4266,7 +4269,7 @@ fi | ||
| 461 | # Extract the first word of "${ncn_target_tool_prefix}ar", so it can be a program name with args. | ||
| 462 | set dummy ${ncn_target_tool_prefix}ar; ac_word=$2 | ||
| 463 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 464 | -echo "configure:4270: checking for $ac_word" >&5 | ||
| 465 | +echo "configure:4273: checking for $ac_word" >&5 | ||
| 466 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_AR_FOR_TARGET'+set}'`\" = set"; then | ||
| 467 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 468 | else | ||
| 469 | @@ -4299,7 +4302,7 @@ if test -z "$ac_cv_prog_CONFIGURED_AR_FO | ||
| 470 | # Extract the first word of "ar", so it can be a program name with args. | ||
| 471 | set dummy ar; ac_word=$2 | ||
| 472 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 473 | -echo "configure:4303: checking for $ac_word" >&5 | ||
| 474 | +echo "configure:4306: checking for $ac_word" >&5 | ||
| 475 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_AR_FOR_TARGET'+set}'`\" = set"; then | ||
| 476 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 477 | else | ||
| 478 | @@ -4338,7 +4341,7 @@ fi | ||
| 479 | # Extract the first word of "${ncn_target_tool_prefix}as", so it can be a program name with args. | ||
| 480 | set dummy ${ncn_target_tool_prefix}as; ac_word=$2 | ||
| 481 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 482 | -echo "configure:4342: checking for $ac_word" >&5 | ||
| 483 | +echo "configure:4345: checking for $ac_word" >&5 | ||
| 484 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_AS_FOR_TARGET'+set}'`\" = set"; then | ||
| 485 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 486 | else | ||
| 487 | @@ -4371,7 +4374,7 @@ if test -z "$ac_cv_prog_CONFIGURED_AS_FO | ||
| 488 | # Extract the first word of "as", so it can be a program name with args. | ||
| 489 | set dummy as; ac_word=$2 | ||
| 490 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 491 | -echo "configure:4375: checking for $ac_word" >&5 | ||
| 492 | +echo "configure:4378: checking for $ac_word" >&5 | ||
| 493 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_AS_FOR_TARGET'+set}'`\" = set"; then | ||
| 494 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 495 | else | ||
| 496 | @@ -4410,7 +4413,7 @@ fi | ||
| 497 | # Extract the first word of "${ncn_target_tool_prefix}dlltool", so it can be a program name with args. | ||
| 498 | set dummy ${ncn_target_tool_prefix}dlltool; ac_word=$2 | ||
| 499 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 500 | -echo "configure:4414: checking for $ac_word" >&5 | ||
| 501 | +echo "configure:4417: checking for $ac_word" >&5 | ||
| 502 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_DLLTOOL_FOR_TARGET'+set}'`\" = set"; then | ||
| 503 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 504 | else | ||
| 505 | @@ -4443,7 +4446,7 @@ if test -z "$ac_cv_prog_CONFIGURED_DLLTO | ||
| 506 | # Extract the first word of "dlltool", so it can be a program name with args. | ||
| 507 | set dummy dlltool; ac_word=$2 | ||
| 508 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 509 | -echo "configure:4447: checking for $ac_word" >&5 | ||
| 510 | +echo "configure:4450: checking for $ac_word" >&5 | ||
| 511 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_DLLTOOL_FOR_TARGET'+set}'`\" = set"; then | ||
| 512 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 513 | else | ||
| 514 | @@ -4482,7 +4485,7 @@ fi | ||
| 515 | # Extract the first word of "${ncn_target_tool_prefix}ld", so it can be a program name with args. | ||
| 516 | set dummy ${ncn_target_tool_prefix}ld; ac_word=$2 | ||
| 517 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 518 | -echo "configure:4486: checking for $ac_word" >&5 | ||
| 519 | +echo "configure:4489: checking for $ac_word" >&5 | ||
| 520 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_LD_FOR_TARGET'+set}'`\" = set"; then | ||
| 521 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 522 | else | ||
| 523 | @@ -4515,7 +4518,7 @@ if test -z "$ac_cv_prog_CONFIGURED_LD_FO | ||
| 524 | # Extract the first word of "ld", so it can be a program name with args. | ||
| 525 | set dummy ld; ac_word=$2 | ||
| 526 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 527 | -echo "configure:4519: checking for $ac_word" >&5 | ||
| 528 | +echo "configure:4522: checking for $ac_word" >&5 | ||
| 529 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_LD_FOR_TARGET'+set}'`\" = set"; then | ||
| 530 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 531 | else | ||
| 532 | @@ -4554,7 +4557,7 @@ fi | ||
| 533 | # Extract the first word of "${ncn_target_tool_prefix}nm", so it can be a program name with args. | ||
| 534 | set dummy ${ncn_target_tool_prefix}nm; ac_word=$2 | ||
| 535 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 536 | -echo "configure:4558: checking for $ac_word" >&5 | ||
| 537 | +echo "configure:4561: checking for $ac_word" >&5 | ||
| 538 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_NM_FOR_TARGET'+set}'`\" = set"; then | ||
| 539 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 540 | else | ||
| 541 | @@ -4587,7 +4590,7 @@ if test -z "$ac_cv_prog_CONFIGURED_NM_FO | ||
| 542 | # Extract the first word of "nm", so it can be a program name with args. | ||
| 543 | set dummy nm; ac_word=$2 | ||
| 544 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 545 | -echo "configure:4591: checking for $ac_word" >&5 | ||
| 546 | +echo "configure:4594: checking for $ac_word" >&5 | ||
| 547 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_NM_FOR_TARGET'+set}'`\" = set"; then | ||
| 548 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 549 | else | ||
| 550 | @@ -4626,7 +4629,7 @@ fi | ||
| 551 | # Extract the first word of "${ncn_target_tool_prefix}ranlib", so it can be a program name with args. | ||
| 552 | set dummy ${ncn_target_tool_prefix}ranlib; ac_word=$2 | ||
| 553 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 554 | -echo "configure:4630: checking for $ac_word" >&5 | ||
| 555 | +echo "configure:4633: checking for $ac_word" >&5 | ||
| 556 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_RANLIB_FOR_TARGET'+set}'`\" = set"; then | ||
| 557 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 558 | else | ||
| 559 | @@ -4659,7 +4662,7 @@ if test -z "$ac_cv_prog_CONFIGURED_RANLI | ||
| 560 | # Extract the first word of "ranlib", so it can be a program name with args. | ||
| 561 | set dummy ranlib; ac_word=$2 | ||
| 562 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 563 | -echo "configure:4663: checking for $ac_word" >&5 | ||
| 564 | +echo "configure:4666: checking for $ac_word" >&5 | ||
| 565 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_RANLIB_FOR_TARGET'+set}'`\" = set"; then | ||
| 566 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 567 | else | ||
| 568 | @@ -4698,7 +4701,7 @@ fi | ||
| 569 | # Extract the first word of "${ncn_target_tool_prefix}windres", so it can be a program name with args. | ||
| 570 | set dummy ${ncn_target_tool_prefix}windres; ac_word=$2 | ||
| 571 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 572 | -echo "configure:4702: checking for $ac_word" >&5 | ||
| 573 | +echo "configure:4705: checking for $ac_word" >&5 | ||
| 574 | if eval "test \"`echo '$''{'ac_cv_prog_CONFIGURED_WINDRES_FOR_TARGET'+set}'`\" = set"; then | ||
| 575 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 576 | else | ||
| 577 | @@ -4731,7 +4734,7 @@ if test -z "$ac_cv_prog_CONFIGURED_WINDR | ||
| 578 | # Extract the first word of "windres", so it can be a program name with args. | ||
| 579 | set dummy windres; ac_word=$2 | ||
| 580 | echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | ||
| 581 | -echo "configure:4735: checking for $ac_word" >&5 | ||
| 582 | +echo "configure:4738: checking for $ac_word" >&5 | ||
| 583 | if eval "test \"`echo '$''{'ac_cv_prog_ncn_cv_CONFIGURED_WINDRES_FOR_TARGET'+set}'`\" = set"; then | ||
| 584 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 585 | else | ||
| 586 | @@ -4816,7 +4819,7 @@ RANLIB_FOR_TARGET=${RANLIB_FOR_TARGET}${ | ||
| 587 | NM_FOR_TARGET=${NM_FOR_TARGET}${extra_nmflags_for_target} | ||
| 588 | |||
| 589 | echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 | ||
| 590 | -echo "configure:4820: checking whether to enable maintainer-specific portions of Makefiles" >&5 | ||
| 591 | +echo "configure:4823: checking whether to enable maintainer-specific portions of Makefiles" >&5 | ||
| 592 | # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. | ||
| 593 | if test "${enable_maintainer_mode+set}" = set; then | ||
| 594 | enableval="$enable_maintainer_mode" | ||
| 595 | @@ -4863,7 +4866,7 @@ esac | ||
| 596 | # gcc for stageN-gcc and stagePREV-gcc for stage(N-1). In case this is not | ||
| 597 | # possible, however, we can resort to mv. | ||
| 598 | echo $ac_n "checking if symbolic links between directories work""... $ac_c" 1>&6 | ||
| 599 | -echo "configure:4867: checking if symbolic links between directories work" >&5 | ||
| 600 | +echo "configure:4870: checking if symbolic links between directories work" >&5 | ||
| 601 | if eval "test \"`echo '$''{'gcc_cv_prog_ln_s_dir'+set}'`\" = set"; then | ||
| 602 | echo $ac_n "(cached) $ac_c" 1>&6 | ||
| 603 | else | ||
| 604 | @@ -4997,15 +5000,34 @@ trap 'rm -f $CONFIG_STATUS conftest*; ex | ||
| 605 | # Transform confdefs.h into DEFS. | ||
| 606 | # Protect against shell expansion while executing Makefile rules. | ||
| 607 | # Protect against Makefile macro expansion. | ||
| 608 | -cat > conftest.defs <<\EOF | ||
| 609 | -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g | ||
| 610 | -s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g | ||
| 611 | -s%\[%\\&%g | ||
| 612 | -s%\]%\\&%g | ||
| 613 | -s%\$%$$%g | ||
| 614 | -EOF | ||
| 615 | -DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` | ||
| 616 | -rm -f conftest.defs | ||
| 617 | +# | ||
| 618 | +# If the first sed substitution is executed (which looks for macros that | ||
| 619 | +# take arguments), then we branch to the quote section. Otherwise, | ||
| 620 | +# look for a macro that doesn't take arguments. | ||
| 621 | +cat >confdef2opt.sed <<\_ACEOF | ||
| 622 | +t clear | ||
| 623 | +: clear | ||
| 624 | +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g | ||
| 625 | +t quote | ||
| 626 | +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g | ||
| 627 | +t quote | ||
| 628 | +d | ||
| 629 | +: quote | ||
| 630 | +s,[ `~#$^&*(){}\\|;'"<>?],\\&,g | ||
| 631 | +s,\[,\\&,g | ||
| 632 | +s,\],\\&,g | ||
| 633 | +s,\$,$$,g | ||
| 634 | +p | ||
| 635 | +_ACEOF | ||
| 636 | +# We use echo to avoid assuming a particular line-breaking character. | ||
| 637 | +# The extra dot is to prevent the shell from consuming trailing | ||
| 638 | +# line-breaks from the sub-command output. A line-break within | ||
| 639 | +# single-quotes doesn't work because, if this script is created in a | ||
| 640 | +# platform that uses two characters for line-breaks (e.g., DOS), tr | ||
| 641 | +# would break. | ||
| 642 | +ac_LF_and_DOT=`echo; echo .` | ||
| 643 | +DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` | ||
| 644 | +rm -f confdef2opt.sed | ||
| 645 | |||
| 646 | |||
| 647 | # Without the "./", some shells look in PATH for config.status. | ||
| 648 | diff -Nrup --ignore-space-change gcc-4.0.2/configure.in gcc-4.0.2-atmel.0.99.2/configure.in | ||
| 649 | --- gcc-4.0.2/configure.in 2005-09-13 09:01:28.000000000 +0200 | ||
| 650 | +++ gcc-4.0.2-atmel.0.99.2/configure.in 2006-01-20 14:31:15.000000000 +0100 | ||
| 651 | @@ -493,6 +493,9 @@ case "${target}" in | ||
| 652 | arm-*-riscix*) | ||
| 653 | noconfigdirs="$noconfigdirs ld target-libgloss ${libgcj}" | ||
| 654 | ;; | ||
| 655 | + avr32-*-*) | ||
| 656 | + noconfigdirs="$noconfigdirs target-libiberty target-libmudflap target-libffi ${libgcj}" | ||
| 657 | + ;; | ||
| 658 | avr-*-*) | ||
| 659 | noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}" | ||
| 660 | ;; | ||
| 661 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/ada/s-tpopsp-rtems.adb gcc-4.0.2-atmel.0.99.2/gcc/ada/s-tpopsp-rtems.adb | ||
| 662 | --- gcc-4.0.2/gcc/ada/s-tpopsp-rtems.adb 2005-01-27 12:56:57.000000000 +0100 | ||
| 663 | +++ gcc-4.0.2-atmel.0.99.2/gcc/ada/s-tpopsp-rtems.adb 2005-07-15 16:26:03.000000000 +0200 | ||
| 664 | @@ -7,7 +7,7 @@ | ||
| 665 | -- -- | ||
| 666 | -- B o d y -- | ||
| 667 | -- -- | ||
| 668 | --- $Revision: 1.2 $ | ||
| 669 | +-- $Revision: 3484 $ | ||
| 670 | -- -- | ||
| 671 | -- Copyright (C) 1991-2003, Florida State University -- | ||
| 672 | -- -- | ||
| 673 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/builtins.c gcc-4.0.2-atmel.0.99.2/gcc/builtins.c | ||
| 674 | --- gcc-4.0.2/gcc/builtins.c 2005-08-28 13:08:55.000000000 +0200 | ||
| 675 | +++ gcc-4.0.2-atmel.0.99.2/gcc/builtins.c 2006-03-23 13:29:00.000000000 +0100 | ||
| 676 | @@ -8387,7 +8387,7 @@ validate_arglist (tree arglist, ...) | ||
| 677 | |||
| 678 | do | ||
| 679 | { | ||
| 680 | - code = va_arg (ap, enum tree_code); | ||
| 681 | + code = va_arg (ap, int); | ||
| 682 | switch (code) | ||
| 683 | { | ||
| 684 | case 0: | ||
| 685 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/calls.c gcc-4.0.2-atmel.0.99.2/gcc/calls.c | ||
| 686 | --- gcc-4.0.2/gcc/calls.c 2005-07-25 18:36:33.000000000 +0200 | ||
| 687 | +++ gcc-4.0.2-atmel.0.99.2/gcc/calls.c 2006-03-23 13:29:00.000000000 +0100 | ||
| 688 | @@ -3353,7 +3353,7 @@ emit_library_call_value_1 (int retval, r | ||
| 689 | for (; count < nargs; count++) | ||
| 690 | { | ||
| 691 | rtx val = va_arg (p, rtx); | ||
| 692 | - enum machine_mode mode = va_arg (p, enum machine_mode); | ||
| 693 | + enum machine_mode mode = va_arg (p, int); | ||
| 694 | |||
| 695 | /* We cannot convert the arg value to the mode the library wants here; | ||
| 696 | must do it earlier where we know the signedness of the arg. */ | ||
| 697 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/avr32.c gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/avr32.c | ||
| 698 | --- gcc-4.0.2/gcc/config/avr32/avr32.c 1970-01-01 01:00:00.000000000 +0100 | ||
| 699 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/avr32.c 2006-11-24 17:13:09.000000000 +0100 | ||
| 700 | @@ -0,0 +1,7276 @@ | ||
| 701 | +/* | ||
| 702 | + Target hooks and helper functions for AVR32. | ||
| 703 | + Copyright 2003-2006 Atmel Corporation. | ||
| 704 | + | ||
| 705 | + Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com> | ||
| 706 | + Initial porting by Anders Ådland. | ||
| 707 | + | ||
| 708 | + This file is part of GCC. | ||
| 709 | + | ||
| 710 | + This program is free software; you can redistribute it and/or modify | ||
| 711 | + it under the terms of the GNU General Public License as published by | ||
| 712 | + the Free Software Foundation; either version 2 of the License, or | ||
| 713 | + (at your option) any later version. | ||
| 714 | + | ||
| 715 | + This program is distributed in the hope that it will be useful, | ||
| 716 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 717 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 718 | + GNU General Public License for more details. | ||
| 719 | + | ||
| 720 | + You should have received a copy of the GNU General Public License | ||
| 721 | + along with this program; if not, write to the Free Software | ||
| 722 | + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 723 | + | ||
| 724 | +#include "config.h" | ||
| 725 | +#include "system.h" | ||
| 726 | +#include "coretypes.h" | ||
| 727 | +#include "tm.h" | ||
| 728 | +#include "rtl.h" | ||
| 729 | +#include "tree.h" | ||
| 730 | +#include "obstack.h" | ||
| 731 | +#include "regs.h" | ||
| 732 | +#include "hard-reg-set.h" | ||
| 733 | +#include "real.h" | ||
| 734 | +#include "insn-config.h" | ||
| 735 | +#include "conditions.h" | ||
| 736 | +#include "output.h" | ||
| 737 | +#include "insn-attr.h" | ||
| 738 | +#include "flags.h" | ||
| 739 | +#include "reload.h" | ||
| 740 | +#include "function.h" | ||
| 741 | +#include "expr.h" | ||
| 742 | +#include "optabs.h" | ||
| 743 | +#include "toplev.h" | ||
| 744 | +#include "recog.h" | ||
| 745 | +#include "ggc.h" | ||
| 746 | +#include "except.h" | ||
| 747 | +#include "c-pragma.h" | ||
| 748 | +#include "integrate.h" | ||
| 749 | +#include "tm_p.h" | ||
| 750 | +#include "langhooks.h" | ||
| 751 | + | ||
| 752 | +#include "target.h" | ||
| 753 | +#include "target-def.h" | ||
| 754 | + | ||
| 755 | +#include <ctype.h> | ||
| 756 | + | ||
| 757 | +/* Forward definitions of types. */ | ||
| 758 | +typedef struct minipool_node Mnode; | ||
| 759 | +typedef struct minipool_fixup Mfix; | ||
| 760 | + | ||
| 761 | +/* Obstack for minipool constant handling. */ | ||
| 762 | +static struct obstack minipool_obstack; | ||
| 763 | +static char *minipool_startobj; | ||
| 764 | +static rtx minipool_vector_label; | ||
| 765 | + | ||
| 766 | +/* True if we are currently building a constant table. */ | ||
| 767 | +int making_const_table; | ||
| 768 | + | ||
| 769 | +/* Some forward function declarations */ | ||
| 770 | +static unsigned long avr32_isr_value (tree); | ||
| 771 | +static unsigned long avr32_compute_func_type (void); | ||
| 772 | +static tree avr32_handle_isr_attribute (tree *, tree, tree, int, bool *); | ||
| 773 | +static tree avr32_handle_acall_attribute (tree *, tree, tree, int, bool *); | ||
| 774 | +static tree avr32_handle_fndecl_attribute (tree * node, tree name, tree args, | ||
| 775 | + int flags, bool * no_add_attrs); | ||
| 776 | +static void avr32_reorg (void); | ||
| 777 | +bool avr32_return_in_msb (tree type); | ||
| 778 | +bool avr32_vector_mode_supported (enum machine_mode mode); | ||
| 779 | +static void avr32_init_libfuncs (void); | ||
| 780 | +void avr32_load_pic_register (void); | ||
| 781 | + | ||
| 782 | + | ||
| 783 | +static void | ||
| 784 | +avr32_add_gc_roots (void) | ||
| 785 | +{ | ||
| 786 | + gcc_obstack_init (&minipool_obstack); | ||
| 787 | + minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0); | ||
| 788 | +} | ||
| 789 | + | ||
| 790 | + | ||
| 791 | +/* List of all known AVR32 parts */ | ||
| 792 | +static const struct part_type_s avr32_part_types[] = { | ||
| 793 | + /* name, part_type, architecture type, macro */ | ||
| 794 | + {"none", PART_TYPE_AVR32_NONE, ARCH_TYPE_AVR32_AP, "__AVR32__"}, | ||
| 795 | + {"ap7000", PART_TYPE_AVR32_AP7000, ARCH_TYPE_AVR32_AP, "__AVR32_AP7000__"}, | ||
| 796 | + {"ap7010", PART_TYPE_AVR32_AP7010, ARCH_TYPE_AVR32_AP, "__AVR32_AP7010__"}, | ||
| 797 | + {"ap7020", PART_TYPE_AVR32_AP7020, ARCH_TYPE_AVR32_AP, "__AVR32_AP7020__"}, | ||
| 798 | + {"uc3a0256", PART_TYPE_AVR32_UC3A0256, ARCH_TYPE_AVR32_UC, "__AVR32_UC3A0256__"}, | ||
| 799 | + {"uc3a0512", PART_TYPE_AVR32_UC3A0512, ARCH_TYPE_AVR32_UC, "__AVR32_UC3A0512__"}, | ||
| 800 | + {"uc3a1128", PART_TYPE_AVR32_UC3A1128, ARCH_TYPE_AVR32_UC, "__AVR32_UC3A1128__"}, | ||
| 801 | + {"uc3a1256", PART_TYPE_AVR32_UC3A1256, ARCH_TYPE_AVR32_UC, "__AVR32_UC3A1256__"}, | ||
| 802 | + {"uc3a1512", PART_TYPE_AVR32_UC3A1512, ARCH_TYPE_AVR32_UC, "__AVR32_UC3A1512__"}, | ||
| 803 | + {NULL, 0, 0, NULL} | ||
| 804 | +}; | ||
| 805 | + | ||
| 806 | +/* List of all known AVR32 architectures */ | ||
| 807 | +static const struct arch_type_s avr32_arch_types[] = { | ||
| 808 | + /* name, architecture type, microarchitecture type, feature flags, macro */ | ||
| 809 | + {"ap", ARCH_TYPE_AVR32_AP, UARCH_TYPE_AVR32B, FLAG_AVR32_HAS_DSP | | ||
| 810 | + FLAG_AVR32_HAS_SIMD | FLAG_AVR32_HAS_UNALIGNED_WORD | | ||
| 811 | + FLAG_AVR32_HAS_BRANCH_PRED, "__AVR32_AP__"}, | ||
| 812 | + {"uc", ARCH_TYPE_AVR32_UC, UARCH_TYPE_AVR32A, | ||
| 813 | + FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW, "__AVR32_UC__"}, | ||
| 814 | + {NULL, 0, 0, 0, NULL} | ||
| 815 | +}; | ||
| 816 | + | ||
| 817 | +/* Default arch name */ | ||
| 818 | +const char *avr32_arch_name = "ap"; | ||
| 819 | +const char *avr32_part_name = "none"; | ||
| 820 | + | ||
| 821 | +const struct part_type_s *avr32_part; | ||
| 822 | +const struct arch_type_s *avr32_arch; | ||
| 823 | + | ||
| 824 | + | ||
| 825 | +/* Override command line options */ | ||
| 826 | +void | ||
| 827 | +avr32_override_options (void) | ||
| 828 | +{ | ||
| 829 | + const struct part_type_s *part; | ||
| 830 | + const struct arch_type_s *arch; | ||
| 831 | + | ||
| 832 | + /* Check if part type is set. */ | ||
| 833 | + for (part = avr32_part_types; part->name; part++) | ||
| 834 | + if (strcmp (part->name, avr32_part_name) == 0) | ||
| 835 | + break; | ||
| 836 | + | ||
| 837 | + avr32_part = part; | ||
| 838 | + | ||
| 839 | + if (!part->name) | ||
| 840 | + { | ||
| 841 | + fprintf (stderr, "Unknown part `%s' specified\nKnown part names:\n", | ||
| 842 | + avr32_part_name); | ||
| 843 | + for (part = avr32_part_types; part->name; part++) | ||
| 844 | + fprintf (stderr, "\t%s\n", part->name); | ||
| 845 | + avr32_part = &avr32_part_types[PART_TYPE_AVR32_NONE]; | ||
| 846 | + } | ||
| 847 | + | ||
| 848 | + avr32_arch = &avr32_arch_types[avr32_part->arch_type]; | ||
| 849 | + | ||
| 850 | + /* If part was set to "none" then check if arch was set. */ | ||
| 851 | + if (strcmp (avr32_part->name, "none") == 0) | ||
| 852 | + { | ||
| 853 | + /* Check if arch type is set. */ | ||
| 854 | + for (arch = avr32_arch_types; arch->name; arch++) | ||
| 855 | + if (strcmp (arch->name, avr32_arch_name) == 0) | ||
| 856 | + break; | ||
| 857 | + | ||
| 858 | + avr32_arch = arch; | ||
| 859 | + | ||
| 860 | + if (!arch->name) | ||
| 861 | + { | ||
| 862 | + fprintf (stderr, "Unknown arch `%s' specified\nKnown arch names:\n", | ||
| 863 | + avr32_arch_name); | ||
| 864 | + for (arch = avr32_arch_types; arch->name; arch++) | ||
| 865 | + fprintf (stderr, "\t%s\n", arch->name); | ||
| 866 | + avr32_arch = &avr32_arch_types[ARCH_TYPE_AVR32_AP]; | ||
| 867 | + } | ||
| 868 | + } | ||
| 869 | + | ||
| 870 | + /* If optimization level is two or greater, then align start of loops to a | ||
| 871 | + word boundary since this will allow folding the first insn of the loop. | ||
| 872 | + Do this only for targets supporting branch prediction. */ | ||
| 873 | + if (optimize >= 2 && TARGET_BRANCH_PRED) | ||
| 874 | + align_loops = 2; | ||
| 875 | + | ||
| 876 | + if (AVR32_ALWAYS_PIC) | ||
| 877 | + flag_pic = 1; | ||
| 878 | + | ||
| 879 | + if (target_flags & AVR32_FLAG_NO_PIC) | ||
| 880 | + flag_pic = 0; | ||
| 881 | + | ||
| 882 | + avr32_add_gc_roots (); | ||
| 883 | +} | ||
| 884 | + | ||
| 885 | + | ||
| 886 | +/* | ||
| 887 | +If defined, a function that outputs the assembler code for entry to a | ||
| 888 | +function. The prologue is responsible for setting up the stack frame, | ||
| 889 | +initializing the frame pointer register, saving registers that must be | ||
| 890 | +saved, and allocating size additional bytes of storage for the | ||
| 891 | +local variables. size is an integer. file is a stdio | ||
| 892 | +stream to which the assembler code should be output. | ||
| 893 | + | ||
| 894 | +The label for the beginning of the function need not be output by this | ||
| 895 | +macro. That has already been done when the macro is run. | ||
| 896 | + | ||
| 897 | +To determine which registers to save, the macro can refer to the array | ||
| 898 | +regs_ever_live: element r is nonzero if hard register | ||
| 899 | +r is used anywhere within the function. This implies the function | ||
| 900 | +prologue should save register r, provided it is not one of the | ||
| 901 | +call-used registers. (TARGET_ASM_FUNCTION_EPILOGUE must likewise use | ||
| 902 | +regs_ever_live.) | ||
| 903 | + | ||
| 904 | +On machines that have ``register windows'', the function entry code does | ||
| 905 | +not save on the stack the registers that are in the windows, even if | ||
| 906 | +they are supposed to be preserved by function calls; instead it takes | ||
| 907 | +appropriate steps to ``push'' the register stack, if any non-call-used | ||
| 908 | +registers are used in the function. | ||
| 909 | + | ||
| 910 | +On machines where functions may or may not have frame-pointers, the | ||
| 911 | +function entry code must vary accordingly; it must set up the frame | ||
| 912 | +pointer if one is wanted, and not otherwise. To determine whether a | ||
| 913 | +frame pointer is in wanted, the macro can refer to the variable | ||
| 914 | +frame_pointer_needed. The variable's value will be 1 at run | ||
| 915 | +time in a function that needs a frame pointer. (see Elimination). | ||
| 916 | + | ||
| 917 | +The function entry code is responsible for allocating any stack space | ||
| 918 | +required for the function. This stack space consists of the regions | ||
| 919 | +listed below. In most cases, these regions are allocated in the | ||
| 920 | +order listed, with the last listed region closest to the top of the | ||
| 921 | +stack (the lowest address if STACK_GROWS_DOWNWARD is defined, and | ||
| 922 | +the highest address if it is not defined). You can use a different order | ||
| 923 | +for a machine if doing so is more convenient or required for | ||
| 924 | +compatibility reasons. Except in cases where required by standard | ||
| 925 | +or by a debugger, there is no reason why the stack layout used by GCC | ||
| 926 | +need agree with that used by other compilers for a machine. | ||
| 927 | +*/ | ||
| 928 | + | ||
| 929 | +#undef TARGET_ASM_FUNCTION_PROLOGUE | ||
| 930 | +#define TARGET_ASM_FUNCTION_PROLOGUE avr32_target_asm_function_prologue | ||
| 931 | + | ||
| 932 | + | ||
| 933 | +#undef TARGET_DEFAULT_SHORT_ENUMS | ||
| 934 | +#define TARGET_DEFAULT_SHORT_ENUMS hook_bool_void_false | ||
| 935 | + | ||
| 936 | +#undef TARGET_PROMOTE_FUNCTION_ARGS | ||
| 937 | +#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true | ||
| 938 | + | ||
| 939 | +#undef TARGET_PROMOTE_FUNCTION_RETURN | ||
| 940 | +#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true | ||
| 941 | + | ||
| 942 | +#undef TARGET_PROMOTE_PROTOTYPES | ||
| 943 | +#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true | ||
| 944 | + | ||
| 945 | +#undef TARGET_MUST_PASS_IN_STACK | ||
| 946 | +#define TARGET_MUST_PASS_IN_STACK avr32_must_pass_in_stack | ||
| 947 | + | ||
| 948 | +#undef TARGET_PASS_BY_REFERENCE | ||
| 949 | +#define TARGET_PASS_BY_REFERENCE avr32_pass_by_reference | ||
| 950 | + | ||
| 951 | +#undef TARGET_STRICT_ARGUMENT_NAMING | ||
| 952 | +#define TARGET_STRICT_ARGUMENT_NAMING avr32_strict_argument_naming | ||
| 953 | + | ||
| 954 | +#undef TARGET_VECTOR_MODE_SUPPORTED_P | ||
| 955 | +#define TARGET_VECTOR_MODE_SUPPORTED_P avr32_vector_mode_supported | ||
| 956 | + | ||
| 957 | +#undef TARGET_RETURN_IN_MEMORY | ||
| 958 | +#define TARGET_RETURN_IN_MEMORY avr32_return_in_memory | ||
| 959 | + | ||
| 960 | +#undef TARGET_RETURN_IN_MSB | ||
| 961 | +#define TARGET_RETURN_IN_MSB avr32_return_in_msb | ||
| 962 | + | ||
| 963 | +#undef TARGET_ARG_PARTIAL_BYTES | ||
| 964 | +#define TARGET_ARG_PARTIAL_BYTES avr32_arg_partial_bytes | ||
| 965 | + | ||
| 966 | +#undef TARGET_STRIP_NAME_ENCODING | ||
| 967 | +#define TARGET_STRIP_NAME_ENCODING avr32_strip_name_encoding | ||
| 968 | + | ||
| 969 | +#define streq(string1, string2) (strcmp (string1, string2) == 0) | ||
| 970 | + | ||
| 971 | +#undef TARGET_ATTRIBUTE_TABLE | ||
| 972 | +#define TARGET_ATTRIBUTE_TABLE avr32_attribute_table | ||
| 973 | + | ||
| 974 | +#undef TARGET_COMP_TYPE_ATTRIBUTES | ||
| 975 | +#define TARGET_COMP_TYPE_ATTRIBUTES avr32_comp_type_attributes | ||
| 976 | + | ||
| 977 | + | ||
| 978 | +#undef TARGET_RTX_COSTS | ||
| 979 | +#define TARGET_RTX_COSTS avr32_rtx_costs | ||
| 980 | + | ||
| 981 | +#undef TARGET_CANNOT_FORCE_CONST_MEM | ||
| 982 | +#define TARGET_CANNOT_FORCE_CONST_MEM avr32_cannot_force_const_mem | ||
| 983 | + | ||
| 984 | +#undef TARGET_ASM_INTEGER | ||
| 985 | +#define TARGET_ASM_INTEGER avr32_assemble_integer | ||
| 986 | + | ||
| 987 | +/* | ||
| 988 | + * Switches to the appropriate section for output of constant pool | ||
| 989 | + * entry x in mode. You can assume that x is some kind of constant in | ||
| 990 | + * RTL. The argument mode is redundant except in the case of a | ||
| 991 | + * const_int rtx. Select the section by calling readonly_data_ section | ||
| 992 | + * or one of the alternatives for other sections. align is the | ||
| 993 | + * constant alignment in bits. | ||
| 994 | + * | ||
| 995 | + * The default version of this function takes care of putting symbolic | ||
| 996 | + * constants in flag_ pic mode in data_section and everything else in | ||
| 997 | + * readonly_data_section. | ||
| 998 | + */ | ||
| 999 | +#undef TARGET_ASM_SELECT_RTX_SECTION | ||
| 1000 | +#define TARGET_ASM_SELECT_RTX_SECTION avr32_select_rtx_section | ||
| 1001 | + | ||
| 1002 | + | ||
| 1003 | +/* | ||
| 1004 | + * If non-null, this hook performs a target-specific pass over the | ||
| 1005 | + * instruction stream. The compiler will run it at all optimization | ||
| 1006 | + * levels, just before the point at which it normally does | ||
| 1007 | + * delayed-branch scheduling. | ||
| 1008 | + * | ||
| 1009 | + * The exact purpose of the hook varies from target to target. Some | ||
| 1010 | + * use it to do transformations that are necessary for correctness, | ||
| 1011 | + * such as laying out in-function constant pools or avoiding hardware | ||
| 1012 | + * hazards. Others use it as an opportunity to do some | ||
| 1013 | + * machine-dependent optimizations. | ||
| 1014 | + * | ||
| 1015 | + * You need not implement the hook if it has nothing to do. The | ||
| 1016 | + * default definition is null. | ||
| 1017 | + */ | ||
| 1018 | +#undef TARGET_MACHINE_DEPENDENT_REORG | ||
| 1019 | +#define TARGET_MACHINE_DEPENDENT_REORG avr32_reorg | ||
| 1020 | + | ||
| 1021 | +/* Target hook for assembling integer objects. | ||
| 1022 | + Need to handle integer vectors */ | ||
| 1023 | +static bool | ||
| 1024 | +avr32_assemble_integer (rtx x, unsigned int size, int aligned_p) | ||
| 1025 | +{ | ||
| 1026 | + if (avr32_vector_mode_supported (GET_MODE (x))) | ||
| 1027 | + { | ||
| 1028 | + int i, units; | ||
| 1029 | + | ||
| 1030 | + if (GET_CODE (x) != CONST_VECTOR) | ||
| 1031 | + abort (); | ||
| 1032 | + | ||
| 1033 | + units = CONST_VECTOR_NUNITS (x); | ||
| 1034 | + | ||
| 1035 | + switch (GET_MODE (x)) | ||
| 1036 | + { | ||
| 1037 | + case V2HImode: | ||
| 1038 | + size = 2; | ||
| 1039 | + break; | ||
| 1040 | + case V4QImode: | ||
| 1041 | + size = 1; | ||
| 1042 | + break; | ||
| 1043 | + default: | ||
| 1044 | + abort (); | ||
| 1045 | + } | ||
| 1046 | + | ||
| 1047 | + for (i = 0; i < units; i++) | ||
| 1048 | + { | ||
| 1049 | + rtx elt; | ||
| 1050 | + | ||
| 1051 | + elt = CONST_VECTOR_ELT (x, i); | ||
| 1052 | + assemble_integer (elt, size, i == 0 ? 32 : size * BITS_PER_UNIT, 1); | ||
| 1053 | + } | ||
| 1054 | + | ||
| 1055 | + return true; | ||
| 1056 | + } | ||
| 1057 | + | ||
| 1058 | + return default_assemble_integer (x, size, aligned_p); | ||
| 1059 | +} | ||
| 1060 | + | ||
| 1061 | +/* | ||
| 1062 | + * This target hook describes the relative costs of RTL expressions. | ||
| 1063 | + * | ||
| 1064 | + * The cost may depend on the precise form of the expression, which is | ||
| 1065 | + * available for examination in x, and the rtx code of the expression | ||
| 1066 | + * in which it is contained, found in outer_code. code is the | ||
| 1067 | + * expression code--redundant, since it can be obtained with GET_CODE | ||
| 1068 | + * (x). | ||
| 1069 | + * | ||
| 1070 | + * In implementing this hook, you can use the construct COSTS_N_INSNS | ||
| 1071 | + * (n) to specify a cost equal to n fast instructions. | ||
| 1072 | + * | ||
| 1073 | + * On entry to the hook, *total contains a default estimate for the | ||
| 1074 | + * cost of the expression. The hook should modify this value as | ||
| 1075 | + * necessary. Traditionally, the default costs are COSTS_N_INSNS (5) | ||
| 1076 | + * for multiplications, COSTS_N_INSNS (7) for division and modulus | ||
| 1077 | + * operations, and COSTS_N_INSNS (1) for all other operations. | ||
| 1078 | + * | ||
| 1079 | + * When optimizing for code size, i.e. when optimize_size is non-zero, | ||
| 1080 | + * this target hook should be used to estimate the relative size cost | ||
| 1081 | + * of an expression, again relative to COSTS_N_INSNS. | ||
| 1082 | + * | ||
| 1083 | + * The hook returns true when all subexpressions of x have been | ||
| 1084 | + * processed, and false when rtx_cost should recurse. | ||
| 1085 | + */ | ||
| 1086 | + | ||
| 1087 | +/* Worker routine for avr32_rtx_costs. */ | ||
| 1088 | +static inline int | ||
| 1089 | +avr32_rtx_costs_1 (rtx x, enum rtx_code code ATTRIBUTE_UNUSED, | ||
| 1090 | + enum rtx_code outer ATTRIBUTE_UNUSED) | ||
| 1091 | +{ | ||
| 1092 | + enum machine_mode mode = GET_MODE (x); | ||
| 1093 | + | ||
| 1094 | + switch (GET_CODE (x)) | ||
| 1095 | + { | ||
| 1096 | + case MEM: | ||
| 1097 | + /* Using pre decrement / post increment memory operations on the | ||
| 1098 | + avr32_uc architecture means that two writebacks must be performed | ||
| 1099 | + and hence two cycles are needed. */ | ||
| 1100 | + if (!optimize_size | ||
| 1101 | + && GET_MODE_SIZE (mode) <= 2 * UNITS_PER_WORD | ||
| 1102 | + && avr32_arch->arch_type == ARCH_TYPE_AVR32_UC | ||
| 1103 | + && (GET_CODE (XEXP (x, 0)) == PRE_DEC | ||
| 1104 | + || GET_CODE (XEXP (x, 0)) == POST_INC)) | ||
| 1105 | + return COSTS_N_INSNS (4); | ||
| 1106 | + | ||
| 1107 | + /* Memory costs quite a lot for the first word, but subsequent words | ||
| 1108 | + load at the equivalent of a single insn each. */ | ||
| 1109 | + if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) | ||
| 1110 | + return COSTS_N_INSNS (2 + (GET_MODE_SIZE (mode) / UNITS_PER_WORD)); | ||
| 1111 | + | ||
| 1112 | + return COSTS_N_INSNS (3); | ||
| 1113 | + case SYMBOL_REF: | ||
| 1114 | + case CONST: | ||
| 1115 | + /* These are valid for the pseudo insns: lda.w and call which operates | ||
| 1116 | + on direct addresses. We assume that the cost of a lda.w is the same | ||
| 1117 | + as the cost of a ld.w insn. */ | ||
| 1118 | + return (outer == SET) ? COSTS_N_INSNS (3) : COSTS_N_INSNS (1); | ||
| 1119 | + case DIV: | ||
| 1120 | + case MOD: | ||
| 1121 | + case UDIV: | ||
| 1122 | + case UMOD: | ||
| 1123 | + return optimize_size ? COSTS_N_INSNS (1) : COSTS_N_INSNS (16); | ||
| 1124 | + | ||
| 1125 | + case ROTATE: | ||
| 1126 | + case ROTATERT: | ||
| 1127 | + if (mode == TImode) | ||
| 1128 | + return COSTS_N_INSNS (100); | ||
| 1129 | + | ||
| 1130 | + if (mode == DImode) | ||
| 1131 | + return COSTS_N_INSNS (10); | ||
| 1132 | + return COSTS_N_INSNS (4); | ||
| 1133 | + case ASHIFT: | ||
| 1134 | + case LSHIFTRT: | ||
| 1135 | + case ASHIFTRT: | ||
| 1136 | + case NOT: | ||
| 1137 | + if (mode == TImode) | ||
| 1138 | + return COSTS_N_INSNS (10); | ||
| 1139 | + | ||
| 1140 | + if (mode == DImode) | ||
| 1141 | + return COSTS_N_INSNS (4); | ||
| 1142 | + return COSTS_N_INSNS (1); | ||
| 1143 | + case PLUS: | ||
| 1144 | + case MINUS: | ||
| 1145 | + case NEG: | ||
| 1146 | + case COMPARE: | ||
| 1147 | + case ABS: | ||
| 1148 | + if (GET_MODE_CLASS (mode) == MODE_FLOAT) | ||
| 1149 | + return COSTS_N_INSNS (100); | ||
| 1150 | + | ||
| 1151 | + if (mode == TImode) | ||
| 1152 | + return COSTS_N_INSNS (50); | ||
| 1153 | + | ||
| 1154 | + if (mode == DImode) | ||
| 1155 | + return COSTS_N_INSNS (2); | ||
| 1156 | + return COSTS_N_INSNS (1); | ||
| 1157 | + | ||
| 1158 | + case MULT: | ||
| 1159 | + { | ||
| 1160 | + if (GET_MODE_CLASS (mode) == MODE_FLOAT) | ||
| 1161 | + return COSTS_N_INSNS (300); | ||
| 1162 | + | ||
| 1163 | + if (mode == TImode) | ||
| 1164 | + return COSTS_N_INSNS (16); | ||
| 1165 | + | ||
| 1166 | + if (mode == DImode) | ||
| 1167 | + return COSTS_N_INSNS (4); | ||
| 1168 | + | ||
| 1169 | + if (mode == HImode) | ||
| 1170 | + return COSTS_N_INSNS (2); | ||
| 1171 | + | ||
| 1172 | + return COSTS_N_INSNS (3); | ||
| 1173 | + } | ||
| 1174 | + case IF_THEN_ELSE: | ||
| 1175 | + if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC) | ||
| 1176 | + return COSTS_N_INSNS (4); | ||
| 1177 | + return COSTS_N_INSNS (1); | ||
| 1178 | + case SIGN_EXTEND: | ||
| 1179 | + case ZERO_EXTEND: | ||
| 1180 | + /* Sign/Zero extensions of registers cost quite much since these | ||
| 1181 | + instrcutions only take one register operand which means that gcc | ||
| 1182 | + often must insert some move instrcutions */ | ||
| 1183 | + if (mode == QImode || mode == HImode) | ||
| 1184 | + return (COSTS_N_INSNS (GET_CODE (XEXP (x, 0)) == MEM ? 0 : 1)); | ||
| 1185 | + return COSTS_N_INSNS (4); | ||
| 1186 | + case UNSPEC: | ||
| 1187 | + /* divmod operations */ | ||
| 1188 | + if (XINT (x, 1) == UNSPEC_UDIVMODSI4_INTERNAL | ||
| 1189 | + || XINT (x, 1) == UNSPEC_DIVMODSI4_INTERNAL) | ||
| 1190 | + { | ||
| 1191 | + return optimize_size ? COSTS_N_INSNS (1) : COSTS_N_INSNS (16); | ||
| 1192 | + } | ||
| 1193 | + /* Fallthrough */ | ||
| 1194 | + default: | ||
| 1195 | + return COSTS_N_INSNS (1); | ||
| 1196 | + } | ||
| 1197 | +} | ||
| 1198 | + | ||
| 1199 | +static bool | ||
| 1200 | +avr32_rtx_costs (rtx x, int code, int outer_code, int *total) | ||
| 1201 | +{ | ||
| 1202 | + *total = avr32_rtx_costs_1 (x, code, outer_code); | ||
| 1203 | + return true; | ||
| 1204 | +} | ||
| 1205 | + | ||
| 1206 | + | ||
| 1207 | +bool | ||
| 1208 | +avr32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED) | ||
| 1209 | +{ | ||
| 1210 | + /* Do not want symbols in the constant pool when compiling pic or if using | ||
| 1211 | + address pseudo instructions. */ | ||
| 1212 | + return ((flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS) | ||
| 1213 | + && avr32_find_symbol (x) != NULL_RTX); | ||
| 1214 | +} | ||
| 1215 | + | ||
| 1216 | + | ||
| 1217 | +/* Table of machine attributes. */ | ||
| 1218 | +const struct attribute_spec avr32_attribute_table[] = { | ||
| 1219 | + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ | ||
| 1220 | + /* Interrupt Service Routines have special prologue and epilogue | ||
| 1221 | + requirements. */ | ||
| 1222 | + {"isr", 0, 1, false, false, false, avr32_handle_isr_attribute}, | ||
| 1223 | + {"interrupt", 0, 1, false, false, false, avr32_handle_isr_attribute}, | ||
| 1224 | + {"acall", 0, 1, false, true, true, avr32_handle_acall_attribute}, | ||
| 1225 | + {"naked", 0, 0, true, false, false, avr32_handle_fndecl_attribute}, | ||
| 1226 | + {NULL, 0, 0, false, false, false, NULL} | ||
| 1227 | +}; | ||
| 1228 | + | ||
| 1229 | + | ||
| 1230 | +typedef struct | ||
| 1231 | +{ | ||
| 1232 | + const char *const arg; | ||
| 1233 | + const unsigned long return_value; | ||
| 1234 | +} | ||
| 1235 | +isr_attribute_arg; | ||
| 1236 | + | ||
| 1237 | +static const isr_attribute_arg isr_attribute_args[] = { | ||
| 1238 | + {"FULL", AVR32_FT_ISR_FULL}, | ||
| 1239 | + {"full", AVR32_FT_ISR_FULL}, | ||
| 1240 | + {"HALF", AVR32_FT_ISR_HALF}, | ||
| 1241 | + {"half", AVR32_FT_ISR_HALF}, | ||
| 1242 | + {"NONE", AVR32_FT_ISR_NONE}, | ||
| 1243 | + {"none", AVR32_FT_ISR_NONE}, | ||
| 1244 | + {"UNDEF", AVR32_FT_ISR_NONE}, | ||
| 1245 | + {"undef", AVR32_FT_ISR_NONE}, | ||
| 1246 | + {"SWI", AVR32_FT_ISR_NONE}, | ||
| 1247 | + {"swi", AVR32_FT_ISR_NONE}, | ||
| 1248 | + {NULL, AVR32_FT_ISR_NONE} | ||
| 1249 | +}; | ||
| 1250 | + | ||
| 1251 | +/* Returns the (interrupt) function type of the current | ||
| 1252 | + function, or AVR32_FT_UNKNOWN if the type cannot be determined. */ | ||
| 1253 | + | ||
| 1254 | +static unsigned long | ||
| 1255 | +avr32_isr_value (tree argument) | ||
| 1256 | +{ | ||
| 1257 | + const isr_attribute_arg *ptr; | ||
| 1258 | + const char *arg; | ||
| 1259 | + | ||
| 1260 | + /* No argument - default to ISR_NONE. */ | ||
| 1261 | + if (argument == NULL_TREE) | ||
| 1262 | + return AVR32_FT_ISR_NONE; | ||
| 1263 | + | ||
| 1264 | + /* Get the value of the argument. */ | ||
| 1265 | + if (TREE_VALUE (argument) == NULL_TREE | ||
| 1266 | + || TREE_CODE (TREE_VALUE (argument)) != STRING_CST) | ||
| 1267 | + return AVR32_FT_UNKNOWN; | ||
| 1268 | + | ||
| 1269 | + arg = TREE_STRING_POINTER (TREE_VALUE (argument)); | ||
| 1270 | + | ||
| 1271 | + /* Check it against the list of known arguments. */ | ||
| 1272 | + for (ptr = isr_attribute_args; ptr->arg != NULL; ptr++) | ||
| 1273 | + if (streq (arg, ptr->arg)) | ||
| 1274 | + return ptr->return_value; | ||
| 1275 | + | ||
| 1276 | + /* An unrecognized interrupt type. */ | ||
| 1277 | + return AVR32_FT_UNKNOWN; | ||
| 1278 | +} | ||
| 1279 | + | ||
| 1280 | + | ||
| 1281 | + | ||
| 1282 | +/* | ||
| 1283 | +These hooks specify assembly directives for creating certain kinds | ||
| 1284 | +of integer object. The TARGET_ASM_BYTE_OP directive creates a | ||
| 1285 | +byte-sized object, the TARGET_ASM_ALIGNED_HI_OP one creates an | ||
| 1286 | +aligned two-byte object, and so on. Any of the hooks may be | ||
| 1287 | +NULL, indicating that no suitable directive is available. | ||
| 1288 | + | ||
| 1289 | +The compiler will print these strings at the start of a new line, | ||
| 1290 | +followed immediately by the object's initial value. In most cases, | ||
| 1291 | +the string should contain a tab, a pseudo-op, and then another tab. | ||
| 1292 | +*/ | ||
| 1293 | +#undef TARGET_ASM_BYTE_OP | ||
| 1294 | +#define TARGET_ASM_BYTE_OP "\t.byte\t" | ||
| 1295 | +#undef TARGET_ASM_ALIGNED_HI_OP | ||
| 1296 | +#define TARGET_ASM_ALIGNED_HI_OP "\t.align 1\n\t.short\t" | ||
| 1297 | +#undef TARGET_ASM_ALIGNED_SI_OP | ||
| 1298 | +#define TARGET_ASM_ALIGNED_SI_OP "\t.align 2\n\t.int\t" | ||
| 1299 | +#undef TARGET_ASM_ALIGNED_DI_OP | ||
| 1300 | +#define TARGET_ASM_ALIGNED_DI_OP NULL | ||
| 1301 | +#undef TARGET_ASM_ALIGNED_TI_OP | ||
| 1302 | +#define TARGET_ASM_ALIGNED_TI_OP NULL | ||
| 1303 | +#undef TARGET_ASM_UNALIGNED_HI_OP | ||
| 1304 | +#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t" | ||
| 1305 | +#undef TARGET_ASM_UNALIGNED_SI_OP | ||
| 1306 | +#define TARGET_ASM_UNALIGNED_SI_OP "\t.int\t" | ||
| 1307 | +#undef TARGET_ASM_UNALIGNED_DI_OP | ||
| 1308 | +#define TARGET_ASM_UNALIGNED_DI_OP NULL | ||
| 1309 | +#undef TARGET_ASM_UNALIGNED_TI_OP | ||
| 1310 | +#define TARGET_ASM_UNALIGNED_TI_OP NULL | ||
| 1311 | + | ||
| 1312 | +#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE | ||
| 1313 | +#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE avr32_sched_use_dfa_pipeline_interface | ||
| 1314 | + | ||
| 1315 | +#undef TARGET_ASM_OUTPUT_MI_THUNK | ||
| 1316 | +#define TARGET_ASM_OUTPUT_MI_THUNK avr32_output_mi_thunk | ||
| 1317 | + | ||
| 1318 | + | ||
| 1319 | +static void | ||
| 1320 | +avr32_output_mi_thunk (FILE * file, | ||
| 1321 | + tree thunk ATTRIBUTE_UNUSED, | ||
| 1322 | + HOST_WIDE_INT delta, | ||
| 1323 | + HOST_WIDE_INT vcall_offset, tree function) | ||
| 1324 | +{ | ||
| 1325 | + int mi_delta = delta; | ||
| 1326 | + int this_regno = | ||
| 1327 | + (avr32_return_in_memory (DECL_RESULT (function), TREE_TYPE (function)) ? | ||
| 1328 | + INTERNAL_REGNUM (11) : INTERNAL_REGNUM (12)); | ||
| 1329 | + | ||
| 1330 | + | ||
| 1331 | + if (!avr32_const_ok_for_constraint_p (mi_delta, 'I', "Is21") | ||
| 1332 | + || vcall_offset) | ||
| 1333 | + { | ||
| 1334 | + fprintf (file, "\tpushm\tr10\n"); | ||
| 1335 | + } | ||
| 1336 | + | ||
| 1337 | + | ||
| 1338 | + if (mi_delta != 0) | ||
| 1339 | + { | ||
| 1340 | + if (avr32_const_ok_for_constraint_p (mi_delta, 'I', "Is21")) | ||
| 1341 | + { | ||
| 1342 | + fprintf (file, "\tsub\t%s, -0x%x\n", reg_names[this_regno], | ||
| 1343 | + mi_delta); | ||
| 1344 | + } | ||
| 1345 | + else | ||
| 1346 | + { | ||
| 1347 | + /* Immediate is larger than k21 we must make us a temp register by | ||
| 1348 | + pushing a register to the stack. */ | ||
| 1349 | + fprintf (file, "\tmov\tr10, lo(%x)\n", mi_delta); | ||
| 1350 | + fprintf (file, "\torh\tr10, hi(%x)\n", mi_delta); | ||
| 1351 | + fprintf (file, "\tadd\t%s, r10\n", reg_names[this_regno]); | ||
| 1352 | + } | ||
| 1353 | + } | ||
| 1354 | + | ||
| 1355 | + | ||
| 1356 | + if (vcall_offset != 0) | ||
| 1357 | + { | ||
| 1358 | + fprintf (file, "\tld.w\tr10, %s[0]\n", reg_names[this_regno]); | ||
| 1359 | + fprintf (file, "\tld.w\tr10, r10[%i]\n", (int) vcall_offset); | ||
| 1360 | + fprintf (file, "\tadd\t%s, r10\n", reg_names[this_regno]); | ||
| 1361 | + } | ||
| 1362 | + | ||
| 1363 | + | ||
| 1364 | + if (!avr32_const_ok_for_constraint_p (mi_delta, 'I', "Is21") | ||
| 1365 | + || vcall_offset) | ||
| 1366 | + { | ||
| 1367 | + fprintf (file, "\tpopm\tr10\n"); | ||
| 1368 | + } | ||
| 1369 | + | ||
| 1370 | + if (flag_pic) | ||
| 1371 | + { | ||
| 1372 | + /* Don't know how we should do this!!! For now we'll just use an | ||
| 1373 | + extended branch instruction and hope that the function will be | ||
| 1374 | + reached. */ | ||
| 1375 | + fprintf (file, "\tbral\t"); | ||
| 1376 | + assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0)); | ||
| 1377 | + fputc ('\n', file); | ||
| 1378 | + } | ||
| 1379 | + else | ||
| 1380 | + { | ||
| 1381 | + fprintf (file, "\tlddpc\tpc, 0f\n"); | ||
| 1382 | + fprintf (file, "\t.align 2\n"); | ||
| 1383 | + fputs ("0:\t.long\t", file); | ||
| 1384 | + assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0)); | ||
| 1385 | + fputc ('\n', file); | ||
| 1386 | + } | ||
| 1387 | +} | ||
| 1388 | + | ||
| 1389 | +/* Implements target hook vector_mode_supported. */ | ||
| 1390 | +bool | ||
| 1391 | +avr32_vector_mode_supported (enum machine_mode mode) | ||
| 1392 | +{ | ||
| 1393 | + if ((mode == V2HImode) || (mode == V4QImode)) | ||
| 1394 | + return true; | ||
| 1395 | + | ||
| 1396 | + return false; | ||
| 1397 | +} | ||
| 1398 | + | ||
| 1399 | + | ||
| 1400 | +#undef TARGET_INIT_LIBFUNCS | ||
| 1401 | +#define TARGET_INIT_LIBFUNCS avr32_init_libfuncs | ||
| 1402 | + | ||
| 1403 | +#undef TARGET_INIT_BUILTINS | ||
| 1404 | +#define TARGET_INIT_BUILTINS avr32_init_builtins | ||
| 1405 | + | ||
| 1406 | +#undef TARGET_EXPAND_BUILTIN | ||
| 1407 | +#define TARGET_EXPAND_BUILTIN avr32_expand_builtin | ||
| 1408 | + | ||
| 1409 | +tree int_ftype_int, int_ftype_void, short_ftype_short, void_ftype_int_int, | ||
| 1410 | + void_ftype_ptr_int; | ||
| 1411 | +tree void_ftype_int, void_ftype_void, int_ftype_ptr_int; | ||
| 1412 | +tree short_ftype_short, int_ftype_int_short, int_ftype_short_short, | ||
| 1413 | + short_ftype_short_short; | ||
| 1414 | +tree int_ftype_int_int, longlong_ftype_int_short, longlong_ftype_short_short; | ||
| 1415 | +tree void_ftype_int_int_int_int_int, void_ftype_int_int_int; | ||
| 1416 | +tree longlong_ftype_int_int, void_ftype_int_int_longlong; | ||
| 1417 | +tree int_ftype_int_int_int, longlong_ftype_longlong_int_short; | ||
| 1418 | +tree longlong_ftype_longlong_short_short, int_ftype_int_short_short; | ||
| 1419 | + | ||
| 1420 | +#define def_builtin(NAME, TYPE, CODE) \ | ||
| 1421 | + lang_hooks.builtin_function ((NAME), (TYPE), (CODE), \ | ||
| 1422 | + BUILT_IN_MD, NULL, NULL_TREE) | ||
| 1423 | + | ||
| 1424 | +#define def_mbuiltin(MASK, NAME, TYPE, CODE) \ | ||
| 1425 | + do \ | ||
| 1426 | + { \ | ||
| 1427 | + if ((MASK)) \ | ||
| 1428 | + lang_hooks.builtin_function ((NAME), (TYPE), (CODE), \ | ||
| 1429 | + BUILT_IN_MD, NULL, NULL_TREE); \ | ||
| 1430 | + } \ | ||
| 1431 | + while (0) | ||
| 1432 | + | ||
| 1433 | +struct builtin_description | ||
| 1434 | +{ | ||
| 1435 | + const unsigned int mask; | ||
| 1436 | + const enum insn_code icode; | ||
| 1437 | + const char *const name; | ||
| 1438 | + const int code; | ||
| 1439 | + const enum rtx_code comparison; | ||
| 1440 | + const unsigned int flag; | ||
| 1441 | + const tree *ftype; | ||
| 1442 | +}; | ||
| 1443 | + | ||
| 1444 | +static const struct builtin_description bdesc_2arg[] = { | ||
| 1445 | +#define DSP_BUILTIN(code, builtin, ftype) \ | ||
| 1446 | + { 1, CODE_FOR_##code, "__builtin_" #code , \ | ||
| 1447 | + AVR32_BUILTIN_##builtin, 0, 0, ftype } | ||
| 1448 | + | ||
| 1449 | + DSP_BUILTIN (mulsathh_h, MULSATHH_H, &short_ftype_short_short), | ||
| 1450 | + DSP_BUILTIN (mulsathh_w, MULSATHH_W, &int_ftype_short_short), | ||
| 1451 | + DSP_BUILTIN (mulsatrndhh_h, MULSATRNDHH_H, &short_ftype_short_short), | ||
| 1452 | + DSP_BUILTIN (mulsatrndwh_w, MULSATRNDWH_W, &int_ftype_int_short), | ||
| 1453 | + DSP_BUILTIN (mulsatwh_w, MULSATWH_W, &int_ftype_int_short), | ||
| 1454 | + DSP_BUILTIN (satadd_h, SATADD_H, &short_ftype_short_short), | ||
| 1455 | + DSP_BUILTIN (satsub_h, SATSUB_H, &short_ftype_short_short), | ||
| 1456 | + DSP_BUILTIN (satadd_w, SATADD_W, &int_ftype_int_int), | ||
| 1457 | + DSP_BUILTIN (satsub_w, SATSUB_W, &int_ftype_int_int), | ||
| 1458 | + DSP_BUILTIN (mulwh_d, MULWH_D, &longlong_ftype_int_short), | ||
| 1459 | + DSP_BUILTIN (mulnwh_d, MULNWH_D, &longlong_ftype_int_short) | ||
| 1460 | +}; | ||
| 1461 | + | ||
| 1462 | + | ||
| 1463 | +void | ||
| 1464 | +avr32_init_builtins (void) | ||
| 1465 | +{ | ||
| 1466 | + unsigned int i; | ||
| 1467 | + const struct builtin_description *d; | ||
| 1468 | + tree endlink = void_list_node; | ||
| 1469 | + tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink); | ||
| 1470 | + tree longlong_endlink = | ||
| 1471 | + tree_cons (NULL_TREE, long_long_integer_type_node, endlink); | ||
| 1472 | + tree short_endlink = | ||
| 1473 | + tree_cons (NULL_TREE, short_integer_type_node, endlink); | ||
| 1474 | + tree void_endlink = tree_cons (NULL_TREE, void_type_node, endlink); | ||
| 1475 | + | ||
| 1476 | + /* int func (int) */ | ||
| 1477 | + int_ftype_int = build_function_type (integer_type_node, int_endlink); | ||
| 1478 | + | ||
| 1479 | + /* short func (short) */ | ||
| 1480 | + short_ftype_short | ||
| 1481 | + = build_function_type (short_integer_type_node, short_endlink); | ||
| 1482 | + | ||
| 1483 | + /* short func (short, short) */ | ||
| 1484 | + short_ftype_short_short | ||
| 1485 | + = build_function_type (short_integer_type_node, | ||
| 1486 | + tree_cons (NULL_TREE, short_integer_type_node, | ||
| 1487 | + short_endlink)); | ||
| 1488 | + | ||
| 1489 | + /* long long func (long long, short, short) */ | ||
| 1490 | + longlong_ftype_longlong_short_short | ||
| 1491 | + = build_function_type (long_long_integer_type_node, | ||
| 1492 | + tree_cons (NULL_TREE, long_long_integer_type_node, | ||
| 1493 | + tree_cons (NULL_TREE, | ||
| 1494 | + short_integer_type_node, | ||
| 1495 | + short_endlink))); | ||
| 1496 | + | ||
| 1497 | + /* long long func (short, short) */ | ||
| 1498 | + longlong_ftype_short_short | ||
| 1499 | + = build_function_type (long_long_integer_type_node, | ||
| 1500 | + tree_cons (NULL_TREE, short_integer_type_node, | ||
| 1501 | + short_endlink)); | ||
| 1502 | + | ||
| 1503 | + /* int func (int, int) */ | ||
| 1504 | + int_ftype_int_int | ||
| 1505 | + = build_function_type (integer_type_node, | ||
| 1506 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1507 | + int_endlink)); | ||
| 1508 | + | ||
| 1509 | + /* long long func (int, int) */ | ||
| 1510 | + longlong_ftype_int_int | ||
| 1511 | + = build_function_type (long_long_integer_type_node, | ||
| 1512 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1513 | + int_endlink)); | ||
| 1514 | + | ||
| 1515 | + /* long long int func (long long, int, short) */ | ||
| 1516 | + longlong_ftype_longlong_int_short | ||
| 1517 | + = build_function_type (long_long_integer_type_node, | ||
| 1518 | + tree_cons (NULL_TREE, long_long_integer_type_node, | ||
| 1519 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1520 | + short_endlink))); | ||
| 1521 | + | ||
| 1522 | + /* long long int func (int, short) */ | ||
| 1523 | + longlong_ftype_int_short | ||
| 1524 | + = build_function_type (long_long_integer_type_node, | ||
| 1525 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1526 | + short_endlink)); | ||
| 1527 | + | ||
| 1528 | + /* int func (int, short, short) */ | ||
| 1529 | + int_ftype_int_short_short | ||
| 1530 | + = build_function_type (integer_type_node, | ||
| 1531 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1532 | + tree_cons (NULL_TREE, | ||
| 1533 | + short_integer_type_node, | ||
| 1534 | + short_endlink))); | ||
| 1535 | + | ||
| 1536 | + /* int func (short, short) */ | ||
| 1537 | + int_ftype_short_short | ||
| 1538 | + = build_function_type (integer_type_node, | ||
| 1539 | + tree_cons (NULL_TREE, short_integer_type_node, | ||
| 1540 | + short_endlink)); | ||
| 1541 | + | ||
| 1542 | + /* int func (int, short) */ | ||
| 1543 | + int_ftype_int_short | ||
| 1544 | + = build_function_type (integer_type_node, | ||
| 1545 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1546 | + short_endlink)); | ||
| 1547 | + | ||
| 1548 | + /* void func (int, int) */ | ||
| 1549 | + void_ftype_int_int | ||
| 1550 | + = build_function_type (void_type_node, | ||
| 1551 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1552 | + int_endlink)); | ||
| 1553 | + | ||
| 1554 | + /* void func (int, int, int) */ | ||
| 1555 | + void_ftype_int_int_int | ||
| 1556 | + = build_function_type (void_type_node, | ||
| 1557 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1558 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1559 | + int_endlink))); | ||
| 1560 | + | ||
| 1561 | + /* void func (int, int, long long) */ | ||
| 1562 | + void_ftype_int_int_longlong | ||
| 1563 | + = build_function_type (void_type_node, | ||
| 1564 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1565 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1566 | + longlong_endlink))); | ||
| 1567 | + | ||
| 1568 | + /* void func (int, int, int, int, int) */ | ||
| 1569 | + void_ftype_int_int_int_int_int | ||
| 1570 | + = build_function_type (void_type_node, | ||
| 1571 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1572 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1573 | + tree_cons (NULL_TREE, | ||
| 1574 | + integer_type_node, | ||
| 1575 | + tree_cons | ||
| 1576 | + (NULL_TREE, | ||
| 1577 | + integer_type_node, | ||
| 1578 | + int_endlink))))); | ||
| 1579 | + | ||
| 1580 | + /* void func (void *, int) */ | ||
| 1581 | + void_ftype_ptr_int | ||
| 1582 | + = build_function_type (void_type_node, | ||
| 1583 | + tree_cons (NULL_TREE, ptr_type_node, int_endlink)); | ||
| 1584 | + | ||
| 1585 | + /* void func (int) */ | ||
| 1586 | + void_ftype_int = build_function_type (void_type_node, int_endlink); | ||
| 1587 | + | ||
| 1588 | + /* void func (void) */ | ||
| 1589 | + void_ftype_void = build_function_type (void_type_node, void_endlink); | ||
| 1590 | + | ||
| 1591 | + /* int func (void) */ | ||
| 1592 | + int_ftype_void = build_function_type (integer_type_node, void_endlink); | ||
| 1593 | + | ||
| 1594 | + /* int func (void *, int) */ | ||
| 1595 | + int_ftype_ptr_int | ||
| 1596 | + = build_function_type (integer_type_node, | ||
| 1597 | + tree_cons (NULL_TREE, ptr_type_node, int_endlink)); | ||
| 1598 | + | ||
| 1599 | + /* int func (int, int, int) */ | ||
| 1600 | + int_ftype_int_int_int | ||
| 1601 | + = build_function_type (integer_type_node, | ||
| 1602 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1603 | + tree_cons (NULL_TREE, integer_type_node, | ||
| 1604 | + int_endlink))); | ||
| 1605 | + | ||
| 1606 | + /* Initialize avr32 builtins. */ | ||
| 1607 | + def_builtin ("__builtin_mfsr", int_ftype_int, AVR32_BUILTIN_MFSR); | ||
| 1608 | + def_builtin ("__builtin_mtsr", void_ftype_int_int, AVR32_BUILTIN_MTSR); | ||
| 1609 | + def_builtin ("__builtin_mfdr", int_ftype_int, AVR32_BUILTIN_MFDR); | ||
| 1610 | + def_builtin ("__builtin_mtdr", void_ftype_int_int, AVR32_BUILTIN_MTDR); | ||
| 1611 | + def_builtin ("__builtin_cache", void_ftype_ptr_int, AVR32_BUILTIN_CACHE); | ||
| 1612 | + def_builtin ("__builtin_sync", void_ftype_int, AVR32_BUILTIN_SYNC); | ||
| 1613 | + def_builtin ("__builtin_tlbr", void_ftype_void, AVR32_BUILTIN_TLBR); | ||
| 1614 | + def_builtin ("__builtin_tlbs", void_ftype_void, AVR32_BUILTIN_TLBS); | ||
| 1615 | + def_builtin ("__builtin_tlbw", void_ftype_void, AVR32_BUILTIN_TLBW); | ||
| 1616 | + def_builtin ("__builtin_breakpoint", void_ftype_void, | ||
| 1617 | + AVR32_BUILTIN_BREAKPOINT); | ||
| 1618 | + def_builtin ("__builtin_xchg", int_ftype_ptr_int, AVR32_BUILTIN_XCHG); | ||
| 1619 | + def_builtin ("__builtin_ldxi", int_ftype_ptr_int, AVR32_BUILTIN_LDXI); | ||
| 1620 | + def_builtin ("__builtin_bswap_16", short_ftype_short, | ||
| 1621 | + AVR32_BUILTIN_BSWAP16); | ||
| 1622 | + def_builtin ("__builtin_bswap_32", int_ftype_int, AVR32_BUILTIN_BSWAP32); | ||
| 1623 | + def_builtin ("__builtin_cop", void_ftype_int_int_int_int_int, | ||
| 1624 | + AVR32_BUILTIN_COP); | ||
| 1625 | + def_builtin ("__builtin_mvcr_w", int_ftype_int_int, AVR32_BUILTIN_MVCR_W); | ||
| 1626 | + def_builtin ("__builtin_mvrc_w", void_ftype_int_int_int, | ||
| 1627 | + AVR32_BUILTIN_MVRC_W); | ||
| 1628 | + def_builtin ("__builtin_mvcr_d", longlong_ftype_int_int, | ||
| 1629 | + AVR32_BUILTIN_MVCR_D); | ||
| 1630 | + def_builtin ("__builtin_mvrc_d", void_ftype_int_int_longlong, | ||
| 1631 | + AVR32_BUILTIN_MVRC_D); | ||
| 1632 | + def_builtin ("__builtin_sats", int_ftype_int_int_int, AVR32_BUILTIN_SATS); | ||
| 1633 | + def_builtin ("__builtin_satu", int_ftype_int_int_int, AVR32_BUILTIN_SATU); | ||
| 1634 | + def_builtin ("__builtin_satrnds", int_ftype_int_int_int, | ||
| 1635 | + AVR32_BUILTIN_SATRNDS); | ||
| 1636 | + def_builtin ("__builtin_satrndu", int_ftype_int_int_int, | ||
| 1637 | + AVR32_BUILTIN_SATRNDU); | ||
| 1638 | + def_builtin ("__builtin_musfr", void_ftype_int, AVR32_BUILTIN_MUSFR); | ||
| 1639 | + def_builtin ("__builtin_mustr", int_ftype_void, AVR32_BUILTIN_MUSTR); | ||
| 1640 | + def_builtin ("__builtin_macsathh_w", int_ftype_int_short_short, | ||
| 1641 | + AVR32_BUILTIN_MACSATHH_W); | ||
| 1642 | + def_builtin ("__builtin_macwh_d", longlong_ftype_longlong_int_short, | ||
| 1643 | + AVR32_BUILTIN_MACWH_D); | ||
| 1644 | + def_builtin ("__builtin_machh_d", longlong_ftype_longlong_short_short, | ||
| 1645 | + AVR32_BUILTIN_MACHH_D); | ||
| 1646 | + | ||
| 1647 | + /* Add all builtins that are more or less simple operations on two | ||
| 1648 | + operands. */ | ||
| 1649 | + for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++) | ||
| 1650 | + { | ||
| 1651 | + /* Use one of the operands; the target can have a different mode for | ||
| 1652 | + mask-generating compares. */ | ||
| 1653 | + | ||
| 1654 | + if (d->name == 0) | ||
| 1655 | + continue; | ||
| 1656 | + | ||
| 1657 | + def_mbuiltin (d->mask, d->name, *(d->ftype), d->code); | ||
| 1658 | + } | ||
| 1659 | +} | ||
| 1660 | + | ||
| 1661 | + | ||
| 1662 | +/* Subroutine of avr32_expand_builtin to take care of binop insns. */ | ||
| 1663 | + | ||
| 1664 | +static rtx | ||
| 1665 | +avr32_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target) | ||
| 1666 | +{ | ||
| 1667 | + rtx pat; | ||
| 1668 | + tree arg0 = TREE_VALUE (arglist); | ||
| 1669 | + tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); | ||
| 1670 | + rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 1671 | + rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | ||
| 1672 | + enum machine_mode tmode = insn_data[icode].operand[0].mode; | ||
| 1673 | + enum machine_mode mode0 = insn_data[icode].operand[1].mode; | ||
| 1674 | + enum machine_mode mode1 = insn_data[icode].operand[2].mode; | ||
| 1675 | + | ||
| 1676 | + if (!target | ||
| 1677 | + || GET_MODE (target) != tmode | ||
| 1678 | + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) | ||
| 1679 | + target = gen_reg_rtx (tmode); | ||
| 1680 | + | ||
| 1681 | + /* In case the insn wants input operands in modes different from the | ||
| 1682 | + result, abort. */ | ||
| 1683 | + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) | ||
| 1684 | + { | ||
| 1685 | + /* If op0 is already a reg we must cast it to the correct mode. */ | ||
| 1686 | + if (REG_P (op0)) | ||
| 1687 | + op0 = convert_to_mode (mode0, op0, 1); | ||
| 1688 | + else | ||
| 1689 | + op0 = copy_to_mode_reg (mode0, op0); | ||
| 1690 | + } | ||
| 1691 | + if (!(*insn_data[icode].operand[2].predicate) (op1, mode1)) | ||
| 1692 | + { | ||
| 1693 | + /* If op1 is already a reg we must cast it to the correct mode. */ | ||
| 1694 | + if (REG_P (op1)) | ||
| 1695 | + op1 = convert_to_mode (mode1, op1, 1); | ||
| 1696 | + else | ||
| 1697 | + op1 = copy_to_mode_reg (mode1, op1); | ||
| 1698 | + } | ||
| 1699 | + pat = GEN_FCN (icode) (target, op0, op1); | ||
| 1700 | + if (!pat) | ||
| 1701 | + return 0; | ||
| 1702 | + emit_insn (pat); | ||
| 1703 | + return target; | ||
| 1704 | +} | ||
| 1705 | + | ||
| 1706 | +/* Expand an expression EXP that calls a built-in function, | ||
| 1707 | + with result going to TARGET if that's convenient | ||
| 1708 | + (and in mode MODE if that's convenient). | ||
| 1709 | + SUBTARGET may be used as the target for computing one of EXP's operands. | ||
| 1710 | + IGNORE is nonzero if the value is to be ignored. */ | ||
| 1711 | + | ||
| 1712 | +rtx | ||
| 1713 | +avr32_expand_builtin (tree exp, | ||
| 1714 | + rtx target, | ||
| 1715 | + rtx subtarget ATTRIBUTE_UNUSED, | ||
| 1716 | + enum machine_mode mode ATTRIBUTE_UNUSED, | ||
| 1717 | + int ignore ATTRIBUTE_UNUSED) | ||
| 1718 | +{ | ||
| 1719 | + const struct builtin_description *d; | ||
| 1720 | + unsigned int i; | ||
| 1721 | + enum insn_code icode; | ||
| 1722 | + tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); | ||
| 1723 | + tree arglist = TREE_OPERAND (exp, 1); | ||
| 1724 | + tree arg0, arg1, arg2; | ||
| 1725 | + rtx op0, op1, op2, pat; | ||
| 1726 | + enum machine_mode tmode, mode0, mode1; | ||
| 1727 | + enum machine_mode arg0_mode; | ||
| 1728 | + int fcode = DECL_FUNCTION_CODE (fndecl); | ||
| 1729 | + | ||
| 1730 | + switch (fcode) | ||
| 1731 | + { | ||
| 1732 | + default: | ||
| 1733 | + break; | ||
| 1734 | + | ||
| 1735 | + case AVR32_BUILTIN_SATS: | ||
| 1736 | + case AVR32_BUILTIN_SATU: | ||
| 1737 | + case AVR32_BUILTIN_SATRNDS: | ||
| 1738 | + case AVR32_BUILTIN_SATRNDU: | ||
| 1739 | + { | ||
| 1740 | + const char *fname; | ||
| 1741 | + switch (fcode) | ||
| 1742 | + { | ||
| 1743 | + default: | ||
| 1744 | + case AVR32_BUILTIN_SATS: | ||
| 1745 | + icode = CODE_FOR_sats; | ||
| 1746 | + fname = "sats"; | ||
| 1747 | + break; | ||
| 1748 | + case AVR32_BUILTIN_SATU: | ||
| 1749 | + icode = CODE_FOR_satu; | ||
| 1750 | + fname = "satu"; | ||
| 1751 | + break; | ||
| 1752 | + case AVR32_BUILTIN_SATRNDS: | ||
| 1753 | + icode = CODE_FOR_satrnds; | ||
| 1754 | + fname = "satrnds"; | ||
| 1755 | + break; | ||
| 1756 | + case AVR32_BUILTIN_SATRNDU: | ||
| 1757 | + icode = CODE_FOR_satrndu; | ||
| 1758 | + fname = "satrndu"; | ||
| 1759 | + break; | ||
| 1760 | + } | ||
| 1761 | + | ||
| 1762 | + arg0 = TREE_VALUE (arglist); | ||
| 1763 | + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); | ||
| 1764 | + arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); | ||
| 1765 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 1766 | + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | ||
| 1767 | + op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0); | ||
| 1768 | + | ||
| 1769 | + tmode = insn_data[icode].operand[0].mode; | ||
| 1770 | + | ||
| 1771 | + | ||
| 1772 | + if (target == 0 | ||
| 1773 | + || GET_MODE (target) != tmode | ||
| 1774 | + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) | ||
| 1775 | + target = gen_reg_rtx (tmode); | ||
| 1776 | + | ||
| 1777 | + | ||
| 1778 | + if (!(*insn_data[icode].operand[0].predicate) (op0, GET_MODE (op0))) | ||
| 1779 | + { | ||
| 1780 | + op0 = copy_to_mode_reg (insn_data[icode].operand[0].mode, op0); | ||
| 1781 | + } | ||
| 1782 | + | ||
| 1783 | + if (!(*insn_data[icode].operand[1].predicate) (op1, SImode)) | ||
| 1784 | + { | ||
| 1785 | + error ("Parameter 2 to __builtin_%s should be a constant number.", | ||
| 1786 | + fname); | ||
| 1787 | + return NULL_RTX; | ||
| 1788 | + } | ||
| 1789 | + | ||
| 1790 | + if (!(*insn_data[icode].operand[1].predicate) (op2, SImode)) | ||
| 1791 | + { | ||
| 1792 | + error ("Parameter 3 to __builtin_%s should be a constant number.", | ||
| 1793 | + fname); | ||
| 1794 | + return NULL_RTX; | ||
| 1795 | + } | ||
| 1796 | + | ||
| 1797 | + emit_move_insn (target, op0); | ||
| 1798 | + pat = GEN_FCN (icode) (target, op1, op2); | ||
| 1799 | + if (!pat) | ||
| 1800 | + return 0; | ||
| 1801 | + emit_insn (pat); | ||
| 1802 | + | ||
| 1803 | + return target; | ||
| 1804 | + } | ||
| 1805 | + case AVR32_BUILTIN_MUSTR: | ||
| 1806 | + icode = CODE_FOR_mustr; | ||
| 1807 | + tmode = insn_data[icode].operand[0].mode; | ||
| 1808 | + | ||
| 1809 | + if (target == 0 | ||
| 1810 | + || GET_MODE (target) != tmode | ||
| 1811 | + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) | ||
| 1812 | + target = gen_reg_rtx (tmode); | ||
| 1813 | + pat = GEN_FCN (icode) (target); | ||
| 1814 | + if (!pat) | ||
| 1815 | + return 0; | ||
| 1816 | + emit_insn (pat); | ||
| 1817 | + return target; | ||
| 1818 | + | ||
| 1819 | + case AVR32_BUILTIN_MFSR: | ||
| 1820 | + icode = CODE_FOR_mfsr; | ||
| 1821 | + arg0 = TREE_VALUE (arglist); | ||
| 1822 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 1823 | + tmode = insn_data[icode].operand[0].mode; | ||
| 1824 | + mode0 = insn_data[icode].operand[1].mode; | ||
| 1825 | + | ||
| 1826 | + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) | ||
| 1827 | + { | ||
| 1828 | + error ("Parameter 1 to __builtin_mfsr must be a constant number"); | ||
| 1829 | + } | ||
| 1830 | + | ||
| 1831 | + if (target == 0 | ||
| 1832 | + || GET_MODE (target) != tmode | ||
| 1833 | + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) | ||
| 1834 | + target = gen_reg_rtx (tmode); | ||
| 1835 | + pat = GEN_FCN (icode) (target, op0); | ||
| 1836 | + if (!pat) | ||
| 1837 | + return 0; | ||
| 1838 | + emit_insn (pat); | ||
| 1839 | + return target; | ||
| 1840 | + case AVR32_BUILTIN_MTSR: | ||
| 1841 | + icode = CODE_FOR_mtsr; | ||
| 1842 | + arg0 = TREE_VALUE (arglist); | ||
| 1843 | + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); | ||
| 1844 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 1845 | + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | ||
| 1846 | + mode0 = insn_data[icode].operand[0].mode; | ||
| 1847 | + mode1 = insn_data[icode].operand[1].mode; | ||
| 1848 | + | ||
| 1849 | + if (!(*insn_data[icode].operand[0].predicate) (op0, mode0)) | ||
| 1850 | + { | ||
| 1851 | + error ("Parameter 1 to __builtin_mtsr must be a constant number"); | ||
| 1852 | + return gen_reg_rtx (mode0); | ||
| 1853 | + } | ||
| 1854 | + if (!(*insn_data[icode].operand[1].predicate) (op1, mode1)) | ||
| 1855 | + op1 = copy_to_mode_reg (mode1, op1); | ||
| 1856 | + pat = GEN_FCN (icode) (op0, op1); | ||
| 1857 | + if (!pat) | ||
| 1858 | + return 0; | ||
| 1859 | + emit_insn (pat); | ||
| 1860 | + return NULL_RTX; | ||
| 1861 | + case AVR32_BUILTIN_MFDR: | ||
| 1862 | + icode = CODE_FOR_mfdr; | ||
| 1863 | + arg0 = TREE_VALUE (arglist); | ||
| 1864 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 1865 | + tmode = insn_data[icode].operand[0].mode; | ||
| 1866 | + mode0 = insn_data[icode].operand[1].mode; | ||
| 1867 | + | ||
| 1868 | + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) | ||
| 1869 | + { | ||
| 1870 | + error ("Parameter 1 to __builtin_mfdr must be a constant number"); | ||
| 1871 | + } | ||
| 1872 | + | ||
| 1873 | + if (target == 0 | ||
| 1874 | + || GET_MODE (target) != tmode | ||
| 1875 | + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) | ||
| 1876 | + target = gen_reg_rtx (tmode); | ||
| 1877 | + pat = GEN_FCN (icode) (target, op0); | ||
| 1878 | + if (!pat) | ||
| 1879 | + return 0; | ||
| 1880 | + emit_insn (pat); | ||
| 1881 | + return target; | ||
| 1882 | + case AVR32_BUILTIN_MTDR: | ||
| 1883 | + icode = CODE_FOR_mtdr; | ||
| 1884 | + arg0 = TREE_VALUE (arglist); | ||
| 1885 | + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); | ||
| 1886 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 1887 | + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | ||
| 1888 | + mode0 = insn_data[icode].operand[0].mode; | ||
| 1889 | + mode1 = insn_data[icode].operand[1].mode; | ||
| 1890 | + | ||
| 1891 | + if (!(*insn_data[icode].operand[0].predicate) (op0, mode0)) | ||
| 1892 | + { | ||
| 1893 | + error ("Parameter 1 to __builtin_mtdr must be a constant number"); | ||
| 1894 | + return gen_reg_rtx (mode0); | ||
| 1895 | + } | ||
| 1896 | + if (!(*insn_data[icode].operand[1].predicate) (op1, mode1)) | ||
| 1897 | + op1 = copy_to_mode_reg (mode1, op1); | ||
| 1898 | + pat = GEN_FCN (icode) (op0, op1); | ||
| 1899 | + if (!pat) | ||
| 1900 | + return 0; | ||
| 1901 | + emit_insn (pat); | ||
| 1902 | + return NULL_RTX; | ||
| 1903 | + case AVR32_BUILTIN_CACHE: | ||
| 1904 | + icode = CODE_FOR_cache; | ||
| 1905 | + arg0 = TREE_VALUE (arglist); | ||
| 1906 | + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); | ||
| 1907 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 1908 | + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | ||
| 1909 | + mode0 = insn_data[icode].operand[0].mode; | ||
| 1910 | + mode1 = insn_data[icode].operand[1].mode; | ||
| 1911 | + | ||
| 1912 | + if (!(*insn_data[icode].operand[1].predicate) (op1, mode1)) | ||
| 1913 | + { | ||
| 1914 | + error ("Parameter 2 to __builtin_cache must be a constant number"); | ||
| 1915 | + return gen_reg_rtx (mode1); | ||
| 1916 | + } | ||
| 1917 | + | ||
| 1918 | + if (!(*insn_data[icode].operand[0].predicate) (op0, mode0)) | ||
| 1919 | + op0 = copy_to_mode_reg (mode0, op0); | ||
| 1920 | + | ||
| 1921 | + pat = GEN_FCN (icode) (op0, op1); | ||
| 1922 | + if (!pat) | ||
| 1923 | + return 0; | ||
| 1924 | + emit_insn (pat); | ||
| 1925 | + return NULL_RTX; | ||
| 1926 | + case AVR32_BUILTIN_SYNC: | ||
| 1927 | + case AVR32_BUILTIN_MUSFR: | ||
| 1928 | + { | ||
| 1929 | + const char *fname; | ||
| 1930 | + switch (fcode) | ||
| 1931 | + { | ||
| 1932 | + default: | ||
| 1933 | + case AVR32_BUILTIN_SYNC: | ||
| 1934 | + icode = CODE_FOR_sync; | ||
| 1935 | + fname = "sync"; | ||
| 1936 | + break; | ||
| 1937 | + case AVR32_BUILTIN_MUSFR: | ||
| 1938 | + icode = CODE_FOR_musfr; | ||
| 1939 | + fname = "musfr"; | ||
| 1940 | + break; | ||
| 1941 | + } | ||
| 1942 | + | ||
| 1943 | + arg0 = TREE_VALUE (arglist); | ||
| 1944 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 1945 | + mode0 = insn_data[icode].operand[0].mode; | ||
| 1946 | + | ||
| 1947 | + if (!(*insn_data[icode].operand[0].predicate) (op0, mode0)) | ||
| 1948 | + { | ||
| 1949 | + if (icode == CODE_FOR_musfr) | ||
| 1950 | + op0 = copy_to_mode_reg (mode0, op0); | ||
| 1951 | + else | ||
| 1952 | + { | ||
| 1953 | + error ("Parameter to __builtin_%s is illegal.", fname); | ||
| 1954 | + return gen_reg_rtx (mode0); | ||
| 1955 | + } | ||
| 1956 | + } | ||
| 1957 | + pat = GEN_FCN (icode) (op0); | ||
| 1958 | + if (!pat) | ||
| 1959 | + return 0; | ||
| 1960 | + emit_insn (pat); | ||
| 1961 | + return NULL_RTX; | ||
| 1962 | + } | ||
| 1963 | + case AVR32_BUILTIN_TLBR: | ||
| 1964 | + icode = CODE_FOR_tlbr; | ||
| 1965 | + pat = GEN_FCN (icode) (NULL_RTX); | ||
| 1966 | + if (!pat) | ||
| 1967 | + return 0; | ||
| 1968 | + emit_insn (pat); | ||
| 1969 | + return NULL_RTX; | ||
| 1970 | + case AVR32_BUILTIN_TLBS: | ||
| 1971 | + icode = CODE_FOR_tlbs; | ||
| 1972 | + pat = GEN_FCN (icode) (NULL_RTX); | ||
| 1973 | + if (!pat) | ||
| 1974 | + return 0; | ||
| 1975 | + emit_insn (pat); | ||
| 1976 | + return NULL_RTX; | ||
| 1977 | + case AVR32_BUILTIN_TLBW: | ||
| 1978 | + icode = CODE_FOR_tlbw; | ||
| 1979 | + pat = GEN_FCN (icode) (NULL_RTX); | ||
| 1980 | + if (!pat) | ||
| 1981 | + return 0; | ||
| 1982 | + emit_insn (pat); | ||
| 1983 | + return NULL_RTX; | ||
| 1984 | + case AVR32_BUILTIN_BREAKPOINT: | ||
| 1985 | + icode = CODE_FOR_breakpoint; | ||
| 1986 | + pat = GEN_FCN (icode) (NULL_RTX); | ||
| 1987 | + if (!pat) | ||
| 1988 | + return 0; | ||
| 1989 | + emit_insn (pat); | ||
| 1990 | + return NULL_RTX; | ||
| 1991 | + case AVR32_BUILTIN_XCHG: | ||
| 1992 | + icode = CODE_FOR_xchg; | ||
| 1993 | + arg0 = TREE_VALUE (arglist); | ||
| 1994 | + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); | ||
| 1995 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 1996 | + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | ||
| 1997 | + tmode = insn_data[icode].operand[0].mode; | ||
| 1998 | + mode0 = insn_data[icode].operand[1].mode; | ||
| 1999 | + mode1 = insn_data[icode].operand[3].mode; | ||
| 2000 | + | ||
| 2001 | + if (!(*insn_data[icode].operand[3].predicate) (op1, mode1)) | ||
| 2002 | + { | ||
| 2003 | + op1 = copy_to_mode_reg (mode1, op1); | ||
| 2004 | + } | ||
| 2005 | + | ||
| 2006 | + if (!(*insn_data[icode].operand[2].predicate) (op0, mode0)) | ||
| 2007 | + { | ||
| 2008 | + op0 = copy_to_mode_reg (mode0, op0); | ||
| 2009 | + } | ||
| 2010 | + | ||
| 2011 | + if (target == 0 | ||
| 2012 | + || GET_MODE (target) != tmode | ||
| 2013 | + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) | ||
| 2014 | + target = gen_reg_rtx (tmode); | ||
| 2015 | + pat = GEN_FCN (icode) (target, op0, op0, op1); | ||
| 2016 | + if (!pat) | ||
| 2017 | + return 0; | ||
| 2018 | + emit_insn (pat); | ||
| 2019 | + return target; | ||
| 2020 | + case AVR32_BUILTIN_LDXI: | ||
| 2021 | + icode = CODE_FOR_ldxi; | ||
| 2022 | + arg0 = TREE_VALUE (arglist); | ||
| 2023 | + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); | ||
| 2024 | + arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); | ||
| 2025 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 2026 | + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | ||
| 2027 | + op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0); | ||
| 2028 | + tmode = insn_data[icode].operand[0].mode; | ||
| 2029 | + mode0 = insn_data[icode].operand[1].mode; | ||
| 2030 | + mode1 = insn_data[icode].operand[2].mode; | ||
| 2031 | + | ||
| 2032 | + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) | ||
| 2033 | + { | ||
| 2034 | + op0 = copy_to_mode_reg (mode0, op0); | ||
| 2035 | + } | ||
| 2036 | + | ||
| 2037 | + if (!(*insn_data[icode].operand[2].predicate) (op1, mode1)) | ||
| 2038 | + { | ||
| 2039 | + op1 = copy_to_mode_reg (mode1, op1); | ||
| 2040 | + } | ||
| 2041 | + | ||
| 2042 | + if (!(*insn_data[icode].operand[3].predicate) (op2, SImode)) | ||
| 2043 | + { | ||
| 2044 | + error | ||
| 2045 | + ("Parameter 3 to __builtin_ldxi must be a valid extract shift operand: (0|8|16|24)"); | ||
| 2046 | + return gen_reg_rtx (mode0); | ||
| 2047 | + } | ||
| 2048 | + | ||
| 2049 | + if (target == 0 | ||
| 2050 | + || GET_MODE (target) != tmode | ||
| 2051 | + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) | ||
| 2052 | + target = gen_reg_rtx (tmode); | ||
| 2053 | + pat = GEN_FCN (icode) (target, op0, op1, op2); | ||
| 2054 | + if (!pat) | ||
| 2055 | + return 0; | ||
| 2056 | + emit_insn (pat); | ||
| 2057 | + return target; | ||
| 2058 | + case AVR32_BUILTIN_BSWAP16: | ||
| 2059 | + { | ||
| 2060 | + icode = CODE_FOR_bswap_16; | ||
| 2061 | + arg0 = TREE_VALUE (arglist); | ||
| 2062 | + arg0_mode = TYPE_MODE (TREE_TYPE (arg0)); | ||
| 2063 | + mode0 = insn_data[icode].operand[1].mode; | ||
| 2064 | + if (arg0_mode != mode0) | ||
| 2065 | + arg0 = build1 (NOP_EXPR, | ||
| 2066 | + (*lang_hooks.types.type_for_mode) (mode0, 0), arg0); | ||
| 2067 | + | ||
| 2068 | + op0 = expand_expr (arg0, NULL_RTX, HImode, 0); | ||
| 2069 | + tmode = insn_data[icode].operand[0].mode; | ||
| 2070 | + | ||
| 2071 | + | ||
| 2072 | + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) | ||
| 2073 | + { | ||
| 2074 | + op0 = copy_to_mode_reg (mode0, op0); | ||
| 2075 | + } | ||
| 2076 | + | ||
| 2077 | + if (target == 0 | ||
| 2078 | + || GET_MODE (target) != tmode | ||
| 2079 | + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) | ||
| 2080 | + { | ||
| 2081 | + target = gen_reg_rtx (tmode); | ||
| 2082 | + } | ||
| 2083 | + | ||
| 2084 | + | ||
| 2085 | + pat = GEN_FCN (icode) (target, op0); | ||
| 2086 | + if (!pat) | ||
| 2087 | + return 0; | ||
| 2088 | + emit_insn (pat); | ||
| 2089 | + | ||
| 2090 | + return target; | ||
| 2091 | + } | ||
| 2092 | + case AVR32_BUILTIN_BSWAP32: | ||
| 2093 | + { | ||
| 2094 | + icode = CODE_FOR_bswap_32; | ||
| 2095 | + arg0 = TREE_VALUE (arglist); | ||
| 2096 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 2097 | + tmode = insn_data[icode].operand[0].mode; | ||
| 2098 | + mode0 = insn_data[icode].operand[1].mode; | ||
| 2099 | + | ||
| 2100 | + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) | ||
| 2101 | + { | ||
| 2102 | + op0 = copy_to_mode_reg (mode0, op0); | ||
| 2103 | + } | ||
| 2104 | + | ||
| 2105 | + if (target == 0 | ||
| 2106 | + || GET_MODE (target) != tmode | ||
| 2107 | + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) | ||
| 2108 | + target = gen_reg_rtx (tmode); | ||
| 2109 | + | ||
| 2110 | + | ||
| 2111 | + pat = GEN_FCN (icode) (target, op0); | ||
| 2112 | + if (!pat) | ||
| 2113 | + return 0; | ||
| 2114 | + emit_insn (pat); | ||
| 2115 | + | ||
| 2116 | + return target; | ||
| 2117 | + } | ||
| 2118 | + case AVR32_BUILTIN_MVCR_W: | ||
| 2119 | + case AVR32_BUILTIN_MVCR_D: | ||
| 2120 | + { | ||
| 2121 | + arg0 = TREE_VALUE (arglist); | ||
| 2122 | + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); | ||
| 2123 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 2124 | + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | ||
| 2125 | + | ||
| 2126 | + if (fcode == AVR32_BUILTIN_MVCR_W) | ||
| 2127 | + icode = CODE_FOR_mvcrsi; | ||
| 2128 | + else | ||
| 2129 | + icode = CODE_FOR_mvcrdi; | ||
| 2130 | + | ||
| 2131 | + tmode = insn_data[icode].operand[0].mode; | ||
| 2132 | + | ||
| 2133 | + if (target == 0 | ||
| 2134 | + || GET_MODE (target) != tmode | ||
| 2135 | + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) | ||
| 2136 | + target = gen_reg_rtx (tmode); | ||
| 2137 | + | ||
| 2138 | + if (!(*insn_data[icode].operand[1].predicate) (op0, SImode)) | ||
| 2139 | + { | ||
| 2140 | + error | ||
| 2141 | + ("Parameter 1 to __builtin_cop is not a valid coprocessor number."); | ||
| 2142 | + error ("Number should be between 0 and 7."); | ||
| 2143 | + return NULL_RTX; | ||
| 2144 | + } | ||
| 2145 | + | ||
| 2146 | + if (!(*insn_data[icode].operand[2].predicate) (op1, SImode)) | ||
| 2147 | + { | ||
| 2148 | + error | ||
| 2149 | + ("Parameter 2 to __builtin_cop is not a valid coprocessor register number."); | ||
| 2150 | + error ("Number should be between 0 and 15."); | ||
| 2151 | + return NULL_RTX; | ||
| 2152 | + } | ||
| 2153 | + | ||
| 2154 | + pat = GEN_FCN (icode) (target, op0, op1); | ||
| 2155 | + if (!pat) | ||
| 2156 | + return 0; | ||
| 2157 | + emit_insn (pat); | ||
| 2158 | + | ||
| 2159 | + return target; | ||
| 2160 | + } | ||
| 2161 | + case AVR32_BUILTIN_MACSATHH_W: | ||
| 2162 | + case AVR32_BUILTIN_MACWH_D: | ||
| 2163 | + case AVR32_BUILTIN_MACHH_D: | ||
| 2164 | + { | ||
| 2165 | + arg0 = TREE_VALUE (arglist); | ||
| 2166 | + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); | ||
| 2167 | + arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); | ||
| 2168 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 2169 | + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | ||
| 2170 | + op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0); | ||
| 2171 | + | ||
| 2172 | + icode = ((fcode == AVR32_BUILTIN_MACSATHH_W) ? CODE_FOR_macsathh_w : | ||
| 2173 | + (fcode == AVR32_BUILTIN_MACWH_D) ? CODE_FOR_macwh_d : | ||
| 2174 | + CODE_FOR_machh_d); | ||
| 2175 | + | ||
| 2176 | + tmode = insn_data[icode].operand[0].mode; | ||
| 2177 | + mode0 = insn_data[icode].operand[1].mode; | ||
| 2178 | + mode1 = insn_data[icode].operand[2].mode; | ||
| 2179 | + | ||
| 2180 | + | ||
| 2181 | + if (!target | ||
| 2182 | + || GET_MODE (target) != tmode | ||
| 2183 | + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) | ||
| 2184 | + target = gen_reg_rtx (tmode); | ||
| 2185 | + | ||
| 2186 | + if (!(*insn_data[icode].operand[0].predicate) (op0, tmode)) | ||
| 2187 | + { | ||
| 2188 | + /* If op0 is already a reg we must cast it to the correct mode. */ | ||
| 2189 | + if (REG_P (op0)) | ||
| 2190 | + op0 = convert_to_mode (tmode, op0, 1); | ||
| 2191 | + else | ||
| 2192 | + op0 = copy_to_mode_reg (tmode, op0); | ||
| 2193 | + } | ||
| 2194 | + | ||
| 2195 | + if (!(*insn_data[icode].operand[1].predicate) (op1, mode0)) | ||
| 2196 | + { | ||
| 2197 | + /* If op1 is already a reg we must cast it to the correct mode. */ | ||
| 2198 | + if (REG_P (op1)) | ||
| 2199 | + op1 = convert_to_mode (mode0, op1, 1); | ||
| 2200 | + else | ||
| 2201 | + op1 = copy_to_mode_reg (mode0, op1); | ||
| 2202 | + } | ||
| 2203 | + | ||
| 2204 | + if (!(*insn_data[icode].operand[2].predicate) (op2, mode1)) | ||
| 2205 | + { | ||
| 2206 | + /* If op1 is already a reg we must cast it to the correct mode. */ | ||
| 2207 | + if (REG_P (op2)) | ||
| 2208 | + op2 = convert_to_mode (mode1, op2, 1); | ||
| 2209 | + else | ||
| 2210 | + op2 = copy_to_mode_reg (mode1, op2); | ||
| 2211 | + } | ||
| 2212 | + | ||
| 2213 | + emit_move_insn (target, op0); | ||
| 2214 | + | ||
| 2215 | + pat = GEN_FCN (icode) (target, op1, op2); | ||
| 2216 | + if (!pat) | ||
| 2217 | + return 0; | ||
| 2218 | + emit_insn (pat); | ||
| 2219 | + return target; | ||
| 2220 | + } | ||
| 2221 | + case AVR32_BUILTIN_MVRC_W: | ||
| 2222 | + case AVR32_BUILTIN_MVRC_D: | ||
| 2223 | + { | ||
| 2224 | + arg0 = TREE_VALUE (arglist); | ||
| 2225 | + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); | ||
| 2226 | + arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); | ||
| 2227 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 2228 | + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | ||
| 2229 | + op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0); | ||
| 2230 | + | ||
| 2231 | + if (fcode == AVR32_BUILTIN_MVRC_W) | ||
| 2232 | + icode = CODE_FOR_mvrcsi; | ||
| 2233 | + else | ||
| 2234 | + icode = CODE_FOR_mvrcdi; | ||
| 2235 | + | ||
| 2236 | + if (!(*insn_data[icode].operand[0].predicate) (op0, SImode)) | ||
| 2237 | + { | ||
| 2238 | + error ("Parameter 1 is not a valid coprocessor number."); | ||
| 2239 | + error ("Number should be between 0 and 7."); | ||
| 2240 | + return NULL_RTX; | ||
| 2241 | + } | ||
| 2242 | + | ||
| 2243 | + if (!(*insn_data[icode].operand[1].predicate) (op1, SImode)) | ||
| 2244 | + { | ||
| 2245 | + error ("Parameter 2 is not a valid coprocessor register number."); | ||
| 2246 | + error ("Number should be between 0 and 15."); | ||
| 2247 | + return NULL_RTX; | ||
| 2248 | + } | ||
| 2249 | + | ||
| 2250 | + if (GET_CODE (op2) == CONST_INT | ||
| 2251 | + || GET_CODE (op2) == CONST | ||
| 2252 | + || GET_CODE (op2) == SYMBOL_REF || GET_CODE (op2) == LABEL_REF) | ||
| 2253 | + { | ||
| 2254 | + op2 = force_const_mem (insn_data[icode].operand[2].mode, op2); | ||
| 2255 | + } | ||
| 2256 | + | ||
| 2257 | + if (!(*insn_data[icode].operand[2].predicate) (op2, GET_MODE (op2))) | ||
| 2258 | + op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2); | ||
| 2259 | + | ||
| 2260 | + | ||
| 2261 | + pat = GEN_FCN (icode) (op0, op1, op2); | ||
| 2262 | + if (!pat) | ||
| 2263 | + return 0; | ||
| 2264 | + emit_insn (pat); | ||
| 2265 | + | ||
| 2266 | + return NULL_RTX; | ||
| 2267 | + } | ||
| 2268 | + case AVR32_BUILTIN_COP: | ||
| 2269 | + { | ||
| 2270 | + rtx op3, op4; | ||
| 2271 | + tree arg3, arg4; | ||
| 2272 | + icode = CODE_FOR_cop; | ||
| 2273 | + arg0 = TREE_VALUE (arglist); | ||
| 2274 | + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); | ||
| 2275 | + arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); | ||
| 2276 | + arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))); | ||
| 2277 | + arg4 = | ||
| 2278 | + TREE_VALUE (TREE_CHAIN | ||
| 2279 | + (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))))); | ||
| 2280 | + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0); | ||
| 2281 | + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); | ||
| 2282 | + op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0); | ||
| 2283 | + op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0); | ||
| 2284 | + op4 = expand_expr (arg4, NULL_RTX, VOIDmode, 0); | ||
| 2285 | + | ||
| 2286 | + if (!(*insn_data[icode].operand[0].predicate) (op0, SImode)) | ||
| 2287 | + { | ||
| 2288 | + error | ||
| 2289 | + ("Parameter 1 to __builtin_cop is not a valid coprocessor number."); | ||
| 2290 | + error ("Number should be between 0 and 7."); | ||
| 2291 | + return NULL_RTX; | ||
| 2292 | + } | ||
| 2293 | + | ||
| 2294 | + if (!(*insn_data[icode].operand[1].predicate) (op1, SImode)) | ||
| 2295 | + { | ||
| 2296 | + error | ||
| 2297 | + ("Parameter 2 to __builtin_cop is not a valid coprocessor register number."); | ||
| 2298 | + error ("Number should be between 0 and 15."); | ||
| 2299 | + return NULL_RTX; | ||
| 2300 | + } | ||
| 2301 | + | ||
| 2302 | + if (!(*insn_data[icode].operand[2].predicate) (op2, SImode)) | ||
| 2303 | + { | ||
| 2304 | + error | ||
| 2305 | + ("Parameter 3 to __builtin_cop is not a valid coprocessor register number."); | ||
| 2306 | + error ("Number should be between 0 and 15."); | ||
| 2307 | + return NULL_RTX; | ||
| 2308 | + } | ||
| 2309 | + | ||
| 2310 | + if (!(*insn_data[icode].operand[3].predicate) (op3, SImode)) | ||
| 2311 | + { | ||
| 2312 | + error | ||
| 2313 | + ("Parameter 4 to __builtin_cop is not a valid coprocessor register number."); | ||
| 2314 | + error ("Number should be between 0 and 15."); | ||
| 2315 | + return NULL_RTX; | ||
| 2316 | + } | ||
| 2317 | + | ||
| 2318 | + if (!(*insn_data[icode].operand[4].predicate) (op4, SImode)) | ||
| 2319 | + { | ||
| 2320 | + error | ||
| 2321 | + ("Parameter 5 to __builtin_cop is not a valid coprocessor operation."); | ||
| 2322 | + error ("Number should be between 0 and 127."); | ||
| 2323 | + return NULL_RTX; | ||
| 2324 | + } | ||
| 2325 | + | ||
| 2326 | + pat = GEN_FCN (icode) (op0, op1, op2, op3, op4); | ||
| 2327 | + if (!pat) | ||
| 2328 | + return 0; | ||
| 2329 | + emit_insn (pat); | ||
| 2330 | + | ||
| 2331 | + return target; | ||
| 2332 | + } | ||
| 2333 | + } | ||
| 2334 | + | ||
| 2335 | + for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++) | ||
| 2336 | + if (d->code == fcode) | ||
| 2337 | + return avr32_expand_binop_builtin (d->icode, arglist, target); | ||
| 2338 | + | ||
| 2339 | + | ||
| 2340 | + /* @@@ Should really do something sensible here. */ | ||
| 2341 | + return NULL_RTX; | ||
| 2342 | +} | ||
| 2343 | + | ||
| 2344 | + | ||
| 2345 | +/* Handle an "interrupt" or "isr" attribute; | ||
| 2346 | + arguments as in struct attribute_spec.handler. */ | ||
| 2347 | + | ||
| 2348 | +static tree | ||
| 2349 | +avr32_handle_isr_attribute (tree * node, tree name, tree args, | ||
| 2350 | + int flags, bool * no_add_attrs) | ||
| 2351 | +{ | ||
| 2352 | + if (DECL_P (*node)) | ||
| 2353 | + { | ||
| 2354 | + if (TREE_CODE (*node) != FUNCTION_DECL) | ||
| 2355 | + { | ||
| 2356 | + warning ("`%s' attribute only applies to functions", | ||
| 2357 | + IDENTIFIER_POINTER (name)); | ||
| 2358 | + *no_add_attrs = true; | ||
| 2359 | + } | ||
| 2360 | + /* FIXME: the argument if any is checked for type attributes; should it | ||
| 2361 | + be checked for decl ones? */ | ||
| 2362 | + } | ||
| 2363 | + else | ||
| 2364 | + { | ||
| 2365 | + if (TREE_CODE (*node) == FUNCTION_TYPE | ||
| 2366 | + || TREE_CODE (*node) == METHOD_TYPE) | ||
| 2367 | + { | ||
| 2368 | + if (avr32_isr_value (args) == AVR32_FT_UNKNOWN) | ||
| 2369 | + { | ||
| 2370 | + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); | ||
| 2371 | + *no_add_attrs = true; | ||
| 2372 | + } | ||
| 2373 | + } | ||
| 2374 | + else if (TREE_CODE (*node) == POINTER_TYPE | ||
| 2375 | + && (TREE_CODE (TREE_TYPE (*node)) == FUNCTION_TYPE | ||
| 2376 | + || TREE_CODE (TREE_TYPE (*node)) == METHOD_TYPE) | ||
| 2377 | + && avr32_isr_value (args) != AVR32_FT_UNKNOWN) | ||
| 2378 | + { | ||
| 2379 | + *node = build_variant_type_copy (*node); | ||
| 2380 | + TREE_TYPE (*node) = build_type_attribute_variant | ||
| 2381 | + (TREE_TYPE (*node), | ||
| 2382 | + tree_cons (name, args, TYPE_ATTRIBUTES (TREE_TYPE (*node)))); | ||
| 2383 | + *no_add_attrs = true; | ||
| 2384 | + } | ||
| 2385 | + else | ||
| 2386 | + { | ||
| 2387 | + /* Possibly pass this attribute on from the type to a decl. */ | ||
| 2388 | + if (flags & ((int) ATTR_FLAG_DECL_NEXT | ||
| 2389 | + | (int) ATTR_FLAG_FUNCTION_NEXT | ||
| 2390 | + | (int) ATTR_FLAG_ARRAY_NEXT)) | ||
| 2391 | + { | ||
| 2392 | + *no_add_attrs = true; | ||
| 2393 | + return tree_cons (name, args, NULL_TREE); | ||
| 2394 | + } | ||
| 2395 | + else | ||
| 2396 | + { | ||
| 2397 | + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); | ||
| 2398 | + } | ||
| 2399 | + } | ||
| 2400 | + } | ||
| 2401 | + | ||
| 2402 | + return NULL_TREE; | ||
| 2403 | +} | ||
| 2404 | + | ||
| 2405 | +/* Handle an attribute requiring a FUNCTION_DECL; | ||
| 2406 | + arguments as in struct attribute_spec.handler. */ | ||
| 2407 | +static tree | ||
| 2408 | +avr32_handle_fndecl_attribute (tree * node, tree name, | ||
| 2409 | + tree args ATTRIBUTE_UNUSED, | ||
| 2410 | + int flags ATTRIBUTE_UNUSED, | ||
| 2411 | + bool * no_add_attrs) | ||
| 2412 | +{ | ||
| 2413 | + if (TREE_CODE (*node) != FUNCTION_DECL) | ||
| 2414 | + { | ||
| 2415 | + warning ("%qs attribute only applies to functions", | ||
| 2416 | + IDENTIFIER_POINTER (name)); | ||
| 2417 | + *no_add_attrs = true; | ||
| 2418 | + } | ||
| 2419 | + | ||
| 2420 | + return NULL_TREE; | ||
| 2421 | +} | ||
| 2422 | + | ||
| 2423 | + | ||
| 2424 | +/* Handle an acall attribute; | ||
| 2425 | + arguments as in struct attribute_spec.handler. */ | ||
| 2426 | + | ||
| 2427 | +static tree | ||
| 2428 | +avr32_handle_acall_attribute (tree * node, tree name, | ||
| 2429 | + tree args ATTRIBUTE_UNUSED, | ||
| 2430 | + int flags ATTRIBUTE_UNUSED, bool * no_add_attrs) | ||
| 2431 | +{ | ||
| 2432 | + if (TREE_CODE (*node) == FUNCTION_TYPE || TREE_CODE (*node) == METHOD_TYPE) | ||
| 2433 | + { | ||
| 2434 | + warning ("`%s' attribute not yet supported...", | ||
| 2435 | + IDENTIFIER_POINTER (name)); | ||
| 2436 | + *no_add_attrs = true; | ||
| 2437 | + return NULL_TREE; | ||
| 2438 | + } | ||
| 2439 | + | ||
| 2440 | + warning ("`%s' attribute only applies to functions", | ||
| 2441 | + IDENTIFIER_POINTER (name)); | ||
| 2442 | + *no_add_attrs = true; | ||
| 2443 | + return NULL_TREE; | ||
| 2444 | +} | ||
| 2445 | + | ||
| 2446 | + | ||
| 2447 | +/* Return 0 if the attributes for two types are incompatible, 1 if they | ||
| 2448 | + are compatible, and 2 if they are nearly compatible (which causes a | ||
| 2449 | + warning to be generated). */ | ||
| 2450 | + | ||
| 2451 | +static int | ||
| 2452 | +avr32_comp_type_attributes (tree type1, tree type2) | ||
| 2453 | +{ | ||
| 2454 | + int acall1, acall2, isr1, isr2, naked1, naked2; | ||
| 2455 | + | ||
| 2456 | + /* Check for mismatch of non-default calling convention. */ | ||
| 2457 | + if (TREE_CODE (type1) != FUNCTION_TYPE) | ||
| 2458 | + return 1; | ||
| 2459 | + | ||
| 2460 | + /* Check for mismatched call attributes. */ | ||
| 2461 | + acall1 = lookup_attribute ("acall", TYPE_ATTRIBUTES (type1)) != NULL; | ||
| 2462 | + acall2 = lookup_attribute ("acall", TYPE_ATTRIBUTES (type2)) != NULL; | ||
| 2463 | + naked1 = lookup_attribute ("naked", TYPE_ATTRIBUTES (type1)) != NULL; | ||
| 2464 | + naked2 = lookup_attribute ("naked", TYPE_ATTRIBUTES (type2)) != NULL; | ||
| 2465 | + isr1 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type1)) != NULL; | ||
| 2466 | + if (!isr1) | ||
| 2467 | + isr1 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type1)) != NULL; | ||
| 2468 | + | ||
| 2469 | + isr2 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type2)) != NULL; | ||
| 2470 | + if (!isr2) | ||
| 2471 | + isr2 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type2)) != NULL; | ||
| 2472 | + | ||
| 2473 | + if ((acall1 && isr2) | ||
| 2474 | + || (acall2 && isr1) || (naked1 && isr2) || (naked2 && isr1)) | ||
| 2475 | + return 0; | ||
| 2476 | + | ||
| 2477 | + return 1; | ||
| 2478 | +} | ||
| 2479 | + | ||
| 2480 | + | ||
| 2481 | +/* Computes the type of the current function. */ | ||
| 2482 | + | ||
| 2483 | +static unsigned long | ||
| 2484 | +avr32_compute_func_type (void) | ||
| 2485 | +{ | ||
| 2486 | + unsigned long type = AVR32_FT_UNKNOWN; | ||
| 2487 | + tree a; | ||
| 2488 | + tree attr; | ||
| 2489 | + | ||
| 2490 | + if (TREE_CODE (current_function_decl) != FUNCTION_DECL) | ||
| 2491 | + abort (); | ||
| 2492 | + | ||
| 2493 | + /* Decide if the current function is volatile. Such functions never | ||
| 2494 | + return, and many memory cycles can be saved by not storing register | ||
| 2495 | + values that will never be needed again. This optimization was added to | ||
| 2496 | + speed up context switching in a kernel application. */ | ||
| 2497 | + if (optimize > 0 | ||
| 2498 | + && TREE_NOTHROW (current_function_decl) | ||
| 2499 | + && TREE_THIS_VOLATILE (current_function_decl)) | ||
| 2500 | + type |= AVR32_FT_VOLATILE; | ||
| 2501 | + | ||
| 2502 | + if (cfun->static_chain_decl != NULL) | ||
| 2503 | + type |= AVR32_FT_NESTED; | ||
| 2504 | + | ||
| 2505 | + attr = DECL_ATTRIBUTES (current_function_decl); | ||
| 2506 | + | ||
| 2507 | + a = lookup_attribute ("isr", attr); | ||
| 2508 | + if (a == NULL_TREE) | ||
| 2509 | + a = lookup_attribute ("interrupt", attr); | ||
| 2510 | + | ||
| 2511 | + if (a == NULL_TREE) | ||
| 2512 | + type |= AVR32_FT_NORMAL; | ||
| 2513 | + else | ||
| 2514 | + type |= avr32_isr_value (TREE_VALUE (a)); | ||
| 2515 | + | ||
| 2516 | + | ||
| 2517 | + a = lookup_attribute ("acall", attr); | ||
| 2518 | + if (a != NULL_TREE) | ||
| 2519 | + type |= AVR32_FT_ACALL; | ||
| 2520 | + | ||
| 2521 | + a = lookup_attribute ("naked", attr); | ||
| 2522 | + if (a != NULL_TREE) | ||
| 2523 | + type |= AVR32_FT_NAKED; | ||
| 2524 | + | ||
| 2525 | + return type; | ||
| 2526 | +} | ||
| 2527 | + | ||
| 2528 | +/* Returns the type of the current function. */ | ||
| 2529 | + | ||
| 2530 | +static unsigned long | ||
| 2531 | +avr32_current_func_type (void) | ||
| 2532 | +{ | ||
| 2533 | + if (AVR32_FUNC_TYPE (cfun->machine->func_type) == AVR32_FT_UNKNOWN) | ||
| 2534 | + cfun->machine->func_type = avr32_compute_func_type (); | ||
| 2535 | + | ||
| 2536 | + return cfun->machine->func_type; | ||
| 2537 | +} | ||
| 2538 | + | ||
| 2539 | +/* | ||
| 2540 | + This target hook should return true if we should not pass type solely | ||
| 2541 | + in registers. The file expr.h defines a definition that is usually appropriate, | ||
| 2542 | + refer to expr.h for additional documentation. | ||
| 2543 | +*/ | ||
| 2544 | +bool | ||
| 2545 | +avr32_must_pass_in_stack (enum machine_mode mode ATTRIBUTE_UNUSED, tree type) | ||
| 2546 | +{ | ||
| 2547 | + if (type && AGGREGATE_TYPE_P (type) | ||
| 2548 | + /* If the alignment is less than the size then pass in the struct on | ||
| 2549 | + the stack. */ | ||
| 2550 | + && ((unsigned int) TYPE_ALIGN_UNIT (type) < | ||
| 2551 | + (unsigned int) int_size_in_bytes (type)) | ||
| 2552 | + /* If we support unaligned word accesses then structs of size 4 and 8 | ||
| 2553 | + can have any alignment and still be passed in registers. */ | ||
| 2554 | + && !(TARGET_UNALIGNED_WORD | ||
| 2555 | + && (int_size_in_bytes (type) == 4 | ||
| 2556 | + || int_size_in_bytes (type) == 8)) | ||
| 2557 | + /* Double word structs need only a word alignment. */ | ||
| 2558 | + && !(int_size_in_bytes (type) == 8 && TYPE_ALIGN_UNIT (type) >= 4)) | ||
| 2559 | + return true; | ||
| 2560 | + | ||
| 2561 | + if (type && AGGREGATE_TYPE_P (type) | ||
| 2562 | + /* Structs of size 3,5,6,7 are always passed in registers. */ | ||
| 2563 | + && (int_size_in_bytes (type) == 3 | ||
| 2564 | + || int_size_in_bytes (type) == 5 | ||
| 2565 | + || int_size_in_bytes (type) == 6 || int_size_in_bytes (type) == 7)) | ||
| 2566 | + return true; | ||
| 2567 | + | ||
| 2568 | + | ||
| 2569 | + return (type && TREE_ADDRESSABLE (type)); | ||
| 2570 | +} | ||
| 2571 | + | ||
| 2572 | + | ||
| 2573 | +bool | ||
| 2574 | +avr32_strict_argument_naming (CUMULATIVE_ARGS * ca ATTRIBUTE_UNUSED) | ||
| 2575 | +{ | ||
| 2576 | + return true; | ||
| 2577 | +} | ||
| 2578 | + | ||
| 2579 | +/* | ||
| 2580 | + This target hook should return true if an argument at the position indicated | ||
| 2581 | + by cum should be passed by reference. This predicate is queried after target | ||
| 2582 | + independent reasons for being passed by reference, such as TREE_ADDRESSABLE (type). | ||
| 2583 | + | ||
| 2584 | + If the hook returns true, a copy of that argument is made in memory and a | ||
| 2585 | + pointer to the argument is passed instead of the argument itself. The pointer | ||
| 2586 | + is passed in whatever way is appropriate for passing a pointer to that type. | ||
| 2587 | +*/ | ||
| 2588 | +bool | ||
| 2589 | +avr32_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED, | ||
| 2590 | + enum machine_mode mode ATTRIBUTE_UNUSED, | ||
| 2591 | + tree type, bool named ATTRIBUTE_UNUSED) | ||
| 2592 | +{ | ||
| 2593 | + return (type && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)); | ||
| 2594 | +} | ||
| 2595 | + | ||
| 2596 | +static int | ||
| 2597 | +avr32_arg_partial_bytes (CUMULATIVE_ARGS * pcum ATTRIBUTE_UNUSED, | ||
| 2598 | + enum machine_mode mode ATTRIBUTE_UNUSED, | ||
| 2599 | + tree type ATTRIBUTE_UNUSED, | ||
| 2600 | + bool named ATTRIBUTE_UNUSED) | ||
| 2601 | +{ | ||
| 2602 | + return 0; | ||
| 2603 | +} | ||
| 2604 | + | ||
| 2605 | + | ||
| 2606 | +struct gcc_target targetm = TARGET_INITIALIZER; | ||
| 2607 | + | ||
| 2608 | +/* | ||
| 2609 | + Table used to convert from register number in the assembler instructions and | ||
| 2610 | + the register numbers used in gcc. | ||
| 2611 | +*/ | ||
| 2612 | +const int avr32_function_arg_reglist[] = | ||
| 2613 | +{ | ||
| 2614 | + INTERNAL_REGNUM (12), | ||
| 2615 | + INTERNAL_REGNUM (11), | ||
| 2616 | + INTERNAL_REGNUM (10), | ||
| 2617 | + INTERNAL_REGNUM (9), | ||
| 2618 | + INTERNAL_REGNUM (8) | ||
| 2619 | +}; | ||
| 2620 | + | ||
| 2621 | +rtx avr32_compare_op0 = NULL_RTX; | ||
| 2622 | +rtx avr32_compare_op1 = NULL_RTX; | ||
| 2623 | +rtx avr32_compare_operator = NULL_RTX; | ||
| 2624 | +rtx avr32_acc_cache = NULL_RTX; | ||
| 2625 | + | ||
| 2626 | +/* | ||
| 2627 | + Returns nonzero if it is allowed to store a value of mode mode in hard | ||
| 2628 | + register number regno. | ||
| 2629 | +*/ | ||
| 2630 | +int | ||
| 2631 | +avr32_hard_regno_mode_ok (int regnr, enum machine_mode mode) | ||
| 2632 | +{ | ||
| 2633 | + /* We allow only float modes in the fp-registers */ | ||
| 2634 | + if (regnr >= FIRST_FP_REGNUM | ||
| 2635 | + && regnr <= LAST_FP_REGNUM && GET_MODE_CLASS (mode) != MODE_FLOAT) | ||
| 2636 | + { | ||
| 2637 | + return 0; | ||
| 2638 | + } | ||
| 2639 | + | ||
| 2640 | + switch (mode) | ||
| 2641 | + { | ||
| 2642 | + case DImode: /* long long */ | ||
| 2643 | + case DFmode: /* double */ | ||
| 2644 | + case SCmode: /* __complex__ float */ | ||
| 2645 | + case CSImode: /* __complex__ int */ | ||
| 2646 | + if (regnr < 4) | ||
| 2647 | + { /* long long int not supported in r12, sp, lr | ||
| 2648 | + or pc. */ | ||
| 2649 | + return 0; | ||
| 2650 | + } | ||
| 2651 | + else | ||
| 2652 | + { | ||
| 2653 | + if (regnr % 2) /* long long int has to be refered in even | ||
| 2654 | + registers. */ | ||
| 2655 | + return 0; | ||
| 2656 | + else | ||
| 2657 | + return 1; | ||
| 2658 | + } | ||
| 2659 | + case CDImode: /* __complex__ long long */ | ||
| 2660 | + case DCmode: /* __complex__ double */ | ||
| 2661 | + case TImode: /* 16 bytes */ | ||
| 2662 | + if (regnr < 7) | ||
| 2663 | + return 0; | ||
| 2664 | + else if (regnr % 2) | ||
| 2665 | + return 0; | ||
| 2666 | + else | ||
| 2667 | + return 1; | ||
| 2668 | + default: | ||
| 2669 | + return 1; | ||
| 2670 | + } | ||
| 2671 | +} | ||
| 2672 | + | ||
| 2673 | + | ||
| 2674 | +int | ||
| 2675 | +avr32_rnd_operands (rtx add, rtx shift) | ||
| 2676 | +{ | ||
| 2677 | + if (GET_CODE (shift) == CONST_INT && | ||
| 2678 | + GET_CODE (add) == CONST_INT && INTVAL (shift) > 0) | ||
| 2679 | + { | ||
| 2680 | + if ((1 << (INTVAL (shift) - 1)) == INTVAL (add)) | ||
| 2681 | + return TRUE; | ||
| 2682 | + } | ||
| 2683 | + | ||
| 2684 | + return FALSE; | ||
| 2685 | +} | ||
| 2686 | + | ||
| 2687 | + | ||
| 2688 | + | ||
| 2689 | +int | ||
| 2690 | +avr32_const_ok_for_constraint_p (HOST_WIDE_INT value, char c, const char *str) | ||
| 2691 | +{ | ||
| 2692 | + switch (c) | ||
| 2693 | + { | ||
| 2694 | + case 'K': | ||
| 2695 | + case 'I': | ||
| 2696 | + { | ||
| 2697 | + HOST_WIDE_INT min_value = 0, max_value = 0; | ||
| 2698 | + char size_str[3]; | ||
| 2699 | + int const_size; | ||
| 2700 | + | ||
| 2701 | + size_str[0] = str[2]; | ||
| 2702 | + size_str[1] = str[3]; | ||
| 2703 | + size_str[2] = '\0'; | ||
| 2704 | + const_size = atoi (size_str); | ||
| 2705 | + | ||
| 2706 | + if (toupper (str[1]) == 'U') | ||
| 2707 | + { | ||
| 2708 | + min_value = 0; | ||
| 2709 | + max_value = (1 << const_size) - 1; | ||
| 2710 | + } | ||
| 2711 | + else if (toupper (str[1]) == 'S') | ||
| 2712 | + { | ||
| 2713 | + min_value = -(1 << (const_size - 1)); | ||
| 2714 | + max_value = (1 << (const_size - 1)) - 1; | ||
| 2715 | + } | ||
| 2716 | + | ||
| 2717 | + if (c == 'I') | ||
| 2718 | + { | ||
| 2719 | + value = -value; | ||
| 2720 | + } | ||
| 2721 | + | ||
| 2722 | + if (value >= min_value && value <= max_value) | ||
| 2723 | + { | ||
| 2724 | + return 1; | ||
| 2725 | + } | ||
| 2726 | + break; | ||
| 2727 | + } | ||
| 2728 | + case 'M': | ||
| 2729 | + return avr32_mask_upper_bits_operand (GEN_INT (value), VOIDmode); | ||
| 2730 | + } | ||
| 2731 | + | ||
| 2732 | + return 0; | ||
| 2733 | +} | ||
| 2734 | + | ||
| 2735 | + | ||
| 2736 | +/*Compute mask of which floating-point registers needs saving upon | ||
| 2737 | + entry to this function*/ | ||
| 2738 | +static unsigned long | ||
| 2739 | +avr32_compute_save_fp_reg_mask (void) | ||
| 2740 | +{ | ||
| 2741 | + unsigned long func_type = avr32_current_func_type (); | ||
| 2742 | + unsigned int save_reg_mask = 0; | ||
| 2743 | + unsigned int reg; | ||
| 2744 | + unsigned int max_reg = 7; | ||
| 2745 | + int save_all_call_used_regs = FALSE; | ||
| 2746 | + | ||
| 2747 | + /* This only applies for hardware floating-point implementation. */ | ||
| 2748 | + if (!TARGET_HARD_FLOAT) | ||
| 2749 | + return 0; | ||
| 2750 | + | ||
| 2751 | + if (IS_INTERRUPT (func_type)) | ||
| 2752 | + { | ||
| 2753 | + | ||
| 2754 | + /* Interrupt functions must not corrupt any registers, even call | ||
| 2755 | + clobbered ones. If this is a leaf function we can just examine the | ||
| 2756 | + registers used by the RTL, but otherwise we have to assume that | ||
| 2757 | + whatever function is called might clobber anything, and so we have | ||
| 2758 | + to save all the call-clobbered registers as well. */ | ||
| 2759 | + max_reg = 13; | ||
| 2760 | + save_all_call_used_regs = !current_function_is_leaf; | ||
| 2761 | + } | ||
| 2762 | + | ||
| 2763 | + /* All used registers used must be saved */ | ||
| 2764 | + for (reg = 0; reg <= max_reg; reg++) | ||
| 2765 | + if (regs_ever_live[INTERNAL_FP_REGNUM (reg)] | ||
| 2766 | + || (save_all_call_used_regs | ||
| 2767 | + && call_used_regs[INTERNAL_FP_REGNUM (reg)])) | ||
| 2768 | + save_reg_mask |= (1 << reg); | ||
| 2769 | + | ||
| 2770 | + return save_reg_mask; | ||
| 2771 | +} | ||
| 2772 | + | ||
| 2773 | +/*Compute mask of registers which needs saving upon function entry */ | ||
| 2774 | +static unsigned long | ||
| 2775 | +avr32_compute_save_reg_mask (int push) | ||
| 2776 | +{ | ||
| 2777 | + unsigned long func_type; | ||
| 2778 | + unsigned int save_reg_mask = 0; | ||
| 2779 | + unsigned int reg; | ||
| 2780 | + | ||
| 2781 | + func_type = avr32_current_func_type (); | ||
| 2782 | + | ||
| 2783 | + if (IS_INTERRUPT (func_type)) | ||
| 2784 | + { | ||
| 2785 | + unsigned int max_reg = 12; | ||
| 2786 | + | ||
| 2787 | + | ||
| 2788 | + /* Get the banking scheme for the interrupt */ | ||
| 2789 | + switch (func_type) | ||
| 2790 | + { | ||
| 2791 | + case AVR32_FT_ISR_FULL: | ||
| 2792 | + max_reg = 0; | ||
| 2793 | + break; | ||
| 2794 | + case AVR32_FT_ISR_HALF: | ||
| 2795 | + max_reg = 7; | ||
| 2796 | + break; | ||
| 2797 | + case AVR32_FT_ISR_NONE: | ||
| 2798 | + max_reg = 12; | ||
| 2799 | + break; | ||
| 2800 | + } | ||
| 2801 | + | ||
| 2802 | + /* Interrupt functions must not corrupt any registers, even call | ||
| 2803 | + clobbered ones. If this is a leaf function we can just examine the | ||
| 2804 | + registers used by the RTL, but otherwise we have to assume that | ||
| 2805 | + whatever function is called might clobber anything, and so we have | ||
| 2806 | + to save all the call-clobbered registers as well. */ | ||
| 2807 | + | ||
| 2808 | + /* Need not push the registers r8-r12 for AVR32A architectures, as this | ||
| 2809 | + is automatially done in hardware. We also do not have any shadow | ||
| 2810 | + registers. */ | ||
| 2811 | + if (avr32_arch->uarch_type == UARCH_TYPE_AVR32A) | ||
| 2812 | + { | ||
| 2813 | + max_reg = 7; | ||
| 2814 | + func_type = AVR32_FT_ISR_NONE; | ||
| 2815 | + } | ||
| 2816 | + | ||
| 2817 | + /* All registers which are used and is not shadowed must be saved */ | ||
| 2818 | + for (reg = 0; reg <= max_reg; reg++) | ||
| 2819 | + if (regs_ever_live[INTERNAL_REGNUM (reg)] | ||
| 2820 | + || (!current_function_is_leaf | ||
| 2821 | + && call_used_regs[INTERNAL_REGNUM (reg)])) | ||
| 2822 | + save_reg_mask |= (1 << reg); | ||
| 2823 | + | ||
| 2824 | + /* Check LR */ | ||
| 2825 | + if ((regs_ever_live[LR_REGNUM] || !current_function_is_leaf || frame_pointer_needed) && (func_type == AVR32_FT_ISR_NONE) /* Only | ||
| 2826 | + non-shadowed | ||
| 2827 | + register | ||
| 2828 | + models | ||
| 2829 | + */ ) | ||
| 2830 | + save_reg_mask |= (1 << ASM_REGNUM (LR_REGNUM)); | ||
| 2831 | + | ||
| 2832 | + /* Make sure that the GOT register is pushed. */ | ||
| 2833 | + if (max_reg >= ASM_REGNUM (PIC_OFFSET_TABLE_REGNUM) | ||
| 2834 | + && current_function_uses_pic_offset_table) | ||
| 2835 | + save_reg_mask |= (1 << ASM_REGNUM (PIC_OFFSET_TABLE_REGNUM)); | ||
| 2836 | + | ||
| 2837 | + } | ||
| 2838 | + else | ||
| 2839 | + { | ||
| 2840 | + int use_pushm = optimize_size; | ||
| 2841 | + | ||
| 2842 | + /* In the normal case we only need to save those registers which are | ||
| 2843 | + call saved and which are used by this function. */ | ||
| 2844 | + for (reg = 0; reg <= 7; reg++) | ||
| 2845 | + if (regs_ever_live[INTERNAL_REGNUM (reg)] | ||
| 2846 | + && !call_used_regs[INTERNAL_REGNUM (reg)]) | ||
| 2847 | + save_reg_mask |= (1 << reg); | ||
| 2848 | + | ||
| 2849 | + /* Make sure that the GOT register is pushed. */ | ||
| 2850 | + if (current_function_uses_pic_offset_table) | ||
| 2851 | + save_reg_mask |= (1 << ASM_REGNUM (PIC_OFFSET_TABLE_REGNUM)); | ||
| 2852 | + | ||
| 2853 | + | ||
| 2854 | + /* If we optimize for size and do not have anonymous arguments: use | ||
| 2855 | + popm/pushm always */ | ||
| 2856 | + if (use_pushm) | ||
| 2857 | + { | ||
| 2858 | + if ((save_reg_mask & (1 << 0)) | ||
| 2859 | + || (save_reg_mask & (1 << 1)) | ||
| 2860 | + || (save_reg_mask & (1 << 2)) || (save_reg_mask & (1 << 3))) | ||
| 2861 | + save_reg_mask |= 0xf; | ||
| 2862 | + | ||
| 2863 | + if ((save_reg_mask & (1 << 4)) | ||
| 2864 | + || (save_reg_mask & (1 << 5)) | ||
| 2865 | + || (save_reg_mask & (1 << 6)) || (save_reg_mask & (1 << 7))) | ||
| 2866 | + save_reg_mask |= 0xf0; | ||
| 2867 | + | ||
| 2868 | + if ((save_reg_mask & (1 << 8)) || (save_reg_mask & (1 << 9))) | ||
| 2869 | + save_reg_mask |= 0x300; | ||
| 2870 | + } | ||
| 2871 | + | ||
| 2872 | + | ||
| 2873 | + /* Check LR */ | ||
| 2874 | + if ((regs_ever_live[LR_REGNUM] || !current_function_is_leaf || | ||
| 2875 | + (optimize_size && save_reg_mask) || frame_pointer_needed)) | ||
| 2876 | + { | ||
| 2877 | + if (push) | ||
| 2878 | + { | ||
| 2879 | + /* Push/Pop LR */ | ||
| 2880 | + save_reg_mask |= (1 << ASM_REGNUM (LR_REGNUM)); | ||
| 2881 | + } | ||
| 2882 | + else | ||
| 2883 | + { | ||
| 2884 | + /* Pop PC */ | ||
| 2885 | + save_reg_mask |= (1 << ASM_REGNUM (PC_REGNUM)); | ||
| 2886 | + } | ||
| 2887 | + } | ||
| 2888 | + } | ||
| 2889 | + | ||
| 2890 | + return save_reg_mask; | ||
| 2891 | +} | ||
| 2892 | + | ||
| 2893 | +/*Compute total size in bytes of all saved registers */ | ||
| 2894 | +static int | ||
| 2895 | +avr32_get_reg_mask_size (int reg_mask) | ||
| 2896 | +{ | ||
| 2897 | + int reg, size; | ||
| 2898 | + size = 0; | ||
| 2899 | + | ||
| 2900 | + for (reg = 0; reg <= 15; reg++) | ||
| 2901 | + if (reg_mask & (1 << reg)) | ||
| 2902 | + size += 4; | ||
| 2903 | + | ||
| 2904 | + return size; | ||
| 2905 | +} | ||
| 2906 | + | ||
| 2907 | +/*Get a register from one of the registers which are saved onto the stack | ||
| 2908 | + upon function entry */ | ||
| 2909 | + | ||
| 2910 | +static int | ||
| 2911 | +avr32_get_saved_reg (int save_reg_mask) | ||
| 2912 | +{ | ||
| 2913 | + unsigned int reg; | ||
| 2914 | + | ||
| 2915 | + /* Find the first register which is saved in the saved_reg_mask */ | ||
| 2916 | + for (reg = 0; reg <= 15; reg++) | ||
| 2917 | + if (save_reg_mask & (1 << reg)) | ||
| 2918 | + return reg; | ||
| 2919 | + | ||
| 2920 | + return -1; | ||
| 2921 | +} | ||
| 2922 | + | ||
| 2923 | +/* Return 1 if it is possible to return using a single instruction. */ | ||
| 2924 | +int | ||
| 2925 | +avr32_use_return_insn (int iscond) | ||
| 2926 | +{ | ||
| 2927 | + unsigned int func_type = avr32_current_func_type (); | ||
| 2928 | + unsigned long saved_int_regs; | ||
| 2929 | + unsigned long saved_fp_regs; | ||
| 2930 | + | ||
| 2931 | + /* Never use a return instruction before reload has run. */ | ||
| 2932 | + if (!reload_completed) | ||
| 2933 | + return 0; | ||
| 2934 | + | ||
| 2935 | + /* Must adjust the stack for vararg functions. */ | ||
| 2936 | + if (current_function_args_info.uses_anonymous_args) | ||
| 2937 | + return 0; | ||
| 2938 | + | ||
| 2939 | + /* If there a stack adjstment. */ | ||
| 2940 | + if (get_frame_size ()) | ||
| 2941 | + return 0; | ||
| 2942 | + | ||
| 2943 | + saved_int_regs = avr32_compute_save_reg_mask (TRUE); | ||
| 2944 | + saved_fp_regs = avr32_compute_save_fp_reg_mask (); | ||
| 2945 | + | ||
| 2946 | + /* Functions which have saved fp-regs on the stack can not be performed in | ||
| 2947 | + one instruction */ | ||
| 2948 | + if (saved_fp_regs) | ||
| 2949 | + return 0; | ||
| 2950 | + | ||
| 2951 | + /* Conditional returns can not be performed in one instruction if we need | ||
| 2952 | + to restore registers from the stack */ | ||
| 2953 | + if (iscond && saved_int_regs) | ||
| 2954 | + return 0; | ||
| 2955 | + | ||
| 2956 | + /* Conditional return can not be used for interrupt handlers. */ | ||
| 2957 | + if (iscond && IS_INTERRUPT (func_type)) | ||
| 2958 | + return 0; | ||
| 2959 | + | ||
| 2960 | + /* For interrupt handlers which needs to pop registers */ | ||
| 2961 | + if (saved_int_regs && IS_INTERRUPT (func_type)) | ||
| 2962 | + return 0; | ||
| 2963 | + | ||
| 2964 | + | ||
| 2965 | + /* If there are saved registers but the LR isn't saved, then we need two | ||
| 2966 | + instructions for the return. */ | ||
| 2967 | + if (saved_int_regs && !(saved_int_regs & (1 << ASM_REGNUM (LR_REGNUM)))) | ||
| 2968 | + return 0; | ||
| 2969 | + | ||
| 2970 | + | ||
| 2971 | + return 1; | ||
| 2972 | +} | ||
| 2973 | + | ||
| 2974 | + | ||
| 2975 | +/*Generate some function prologue info in the assembly file*/ | ||
| 2976 | + | ||
| 2977 | +void | ||
| 2978 | +avr32_target_asm_function_prologue (FILE * f, HOST_WIDE_INT frame_size) | ||
| 2979 | +{ | ||
| 2980 | + if (IS_NAKED (avr32_current_func_type ())) | ||
| 2981 | + fprintf (f, | ||
| 2982 | + "\t# Function is naked: Prologue and epilogue provided by programmer\n"); | ||
| 2983 | + | ||
| 2984 | + if (IS_INTERRUPT (avr32_current_func_type ())) | ||
| 2985 | + { | ||
| 2986 | + switch (avr32_current_func_type ()) | ||
| 2987 | + { | ||
| 2988 | + case AVR32_FT_ISR_FULL: | ||
| 2989 | + fprintf (f, | ||
| 2990 | + "\t# Interrupt Function: Fully shadowed register file\n"); | ||
| 2991 | + break; | ||
| 2992 | + case AVR32_FT_ISR_HALF: | ||
| 2993 | + fprintf (f, | ||
| 2994 | + "\t# Interrupt Function: Half shadowed register file\n"); | ||
| 2995 | + break; | ||
| 2996 | + default: | ||
| 2997 | + case AVR32_FT_ISR_NONE: | ||
| 2998 | + fprintf (f, "\t# Interrupt Function: No shadowed register file\n"); | ||
| 2999 | + break; | ||
| 3000 | + } | ||
| 3001 | + } | ||
| 3002 | + | ||
| 3003 | + | ||
| 3004 | + fprintf (f, "\t# args = %i, frame = %li, pretend = %i\n", | ||
| 3005 | + current_function_args_size, frame_size, | ||
| 3006 | + current_function_pretend_args_size); | ||
| 3007 | + | ||
| 3008 | + fprintf (f, "\t# frame_needed = %i, leaf_function = %i\n", | ||
| 3009 | + frame_pointer_needed, current_function_is_leaf); | ||
| 3010 | + | ||
| 3011 | + fprintf (f, "\t# uses_anonymous_args = %i\n", | ||
| 3012 | + current_function_args_info.uses_anonymous_args); | ||
| 3013 | +} | ||
| 3014 | + | ||
| 3015 | + | ||
| 3016 | +/* Generate and emit an insn that we will recognize as a pushm or stm. | ||
| 3017 | + Unfortunately, since this insn does not reflect very well the actual | ||
| 3018 | + semantics of the operation, we need to annotate the insn for the benefit | ||
| 3019 | + of DWARF2 frame unwind information. */ | ||
| 3020 | + | ||
| 3021 | +int avr32_convert_to_reglist16 (int reglist8_vect); | ||
| 3022 | + | ||
| 3023 | +static rtx | ||
| 3024 | +emit_multi_reg_push (int reglist, int usePUSHM) | ||
| 3025 | +{ | ||
| 3026 | + rtx insn; | ||
| 3027 | + rtx dwarf; | ||
| 3028 | + rtx tmp; | ||
| 3029 | + rtx reg; | ||
| 3030 | + int i; | ||
| 3031 | + int nr_regs; | ||
| 3032 | + int index = 0; | ||
| 3033 | + | ||
| 3034 | + if (usePUSHM) | ||
| 3035 | + { | ||
| 3036 | + insn = emit_insn (gen_pushm (gen_rtx_CONST_INT (SImode, reglist))); | ||
| 3037 | + reglist = avr32_convert_to_reglist16 (reglist); | ||
| 3038 | + } | ||
| 3039 | + else | ||
| 3040 | + { | ||
| 3041 | + insn = emit_insn (gen_stm (stack_pointer_rtx, | ||
| 3042 | + gen_rtx_CONST_INT (SImode, reglist), | ||
| 3043 | + gen_rtx_CONST_INT (SImode, 1))); | ||
| 3044 | + } | ||
| 3045 | + | ||
| 3046 | + nr_regs = avr32_get_reg_mask_size (reglist) / 4; | ||
| 3047 | + dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (nr_regs + 1)); | ||
| 3048 | + | ||
| 3049 | + for (i = 15; i >= 0; i--) | ||
| 3050 | + { | ||
| 3051 | + if (reglist & (1 << i)) | ||
| 3052 | + { | ||
| 3053 | + reg = gen_rtx_REG (SImode, INTERNAL_REGNUM (i)); | ||
| 3054 | + tmp = gen_rtx_SET (VOIDmode, | ||
| 3055 | + gen_rtx_MEM (SImode, | ||
| 3056 | + plus_constant (stack_pointer_rtx, | ||
| 3057 | + 4 * index)), reg); | ||
| 3058 | + RTX_FRAME_RELATED_P (tmp) = 1; | ||
| 3059 | + XVECEXP (dwarf, 0, 1 + index++) = tmp; | ||
| 3060 | + } | ||
| 3061 | + } | ||
| 3062 | + | ||
| 3063 | + tmp = gen_rtx_SET (SImode, | ||
| 3064 | + stack_pointer_rtx, | ||
| 3065 | + gen_rtx_PLUS (SImode, | ||
| 3066 | + stack_pointer_rtx, | ||
| 3067 | + GEN_INT (-4 * nr_regs))); | ||
| 3068 | + RTX_FRAME_RELATED_P (tmp) = 1; | ||
| 3069 | + XVECEXP (dwarf, 0, 0) = tmp; | ||
| 3070 | + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf, | ||
| 3071 | + REG_NOTES (insn)); | ||
| 3072 | + return insn; | ||
| 3073 | +} | ||
| 3074 | + | ||
| 3075 | + | ||
| 3076 | +static rtx | ||
| 3077 | +emit_multi_fp_reg_push (int reglist) | ||
| 3078 | +{ | ||
| 3079 | + rtx insn; | ||
| 3080 | + rtx dwarf; | ||
| 3081 | + rtx tmp; | ||
| 3082 | + rtx reg; | ||
| 3083 | + int i; | ||
| 3084 | + int nr_regs; | ||
| 3085 | + int index = 0; | ||
| 3086 | + | ||
| 3087 | + insn = emit_insn (gen_stm_fp (stack_pointer_rtx, | ||
| 3088 | + gen_rtx_CONST_INT (SImode, reglist), | ||
| 3089 | + gen_rtx_CONST_INT (SImode, 1))); | ||
| 3090 | + | ||
| 3091 | + nr_regs = avr32_get_reg_mask_size (reglist) / 4; | ||
| 3092 | + dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (nr_regs + 1)); | ||
| 3093 | + | ||
| 3094 | + for (i = 15; i >= 0; i--) | ||
| 3095 | + { | ||
| 3096 | + if (reglist & (1 << i)) | ||
| 3097 | + { | ||
| 3098 | + reg = gen_rtx_REG (SImode, INTERNAL_FP_REGNUM (i)); | ||
| 3099 | + tmp = gen_rtx_SET (VOIDmode, | ||
| 3100 | + gen_rtx_MEM (SImode, | ||
| 3101 | + plus_constant (stack_pointer_rtx, | ||
| 3102 | + 4 * index)), reg); | ||
| 3103 | + RTX_FRAME_RELATED_P (tmp) = 1; | ||
| 3104 | + XVECEXP (dwarf, 0, 1 + index++) = tmp; | ||
| 3105 | + } | ||
| 3106 | + } | ||
| 3107 | + | ||
| 3108 | + tmp = gen_rtx_SET (SImode, | ||
| 3109 | + stack_pointer_rtx, | ||
| 3110 | + gen_rtx_PLUS (SImode, | ||
| 3111 | + stack_pointer_rtx, | ||
| 3112 | + GEN_INT (-4 * nr_regs))); | ||
| 3113 | + RTX_FRAME_RELATED_P (tmp) = 1; | ||
| 3114 | + XVECEXP (dwarf, 0, 0) = tmp; | ||
| 3115 | + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf, | ||
| 3116 | + REG_NOTES (insn)); | ||
| 3117 | + return insn; | ||
| 3118 | +} | ||
| 3119 | + | ||
| 3120 | +rtx | ||
| 3121 | +avr32_gen_load_multiple (rtx * regs, int count, rtx from, | ||
| 3122 | + int write_back, int in_struct_p, int scalar_p) | ||
| 3123 | +{ | ||
| 3124 | + | ||
| 3125 | + rtx result; | ||
| 3126 | + int i = 0, j; | ||
| 3127 | + | ||
| 3128 | + result = | ||
| 3129 | + gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + (write_back ? 1 : 0))); | ||
| 3130 | + | ||
| 3131 | + if (write_back) | ||
| 3132 | + { | ||
| 3133 | + XVECEXP (result, 0, 0) | ||
| 3134 | + = gen_rtx_SET (GET_MODE (from), from, | ||
| 3135 | + plus_constant (from, count * 4)); | ||
| 3136 | + i = 1; | ||
| 3137 | + count++; | ||
| 3138 | + } | ||
| 3139 | + | ||
| 3140 | + | ||
| 3141 | + for (j = 0; i < count; i++, j++) | ||
| 3142 | + { | ||
| 3143 | + rtx unspec; | ||
| 3144 | + rtx mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4)); | ||
| 3145 | + MEM_IN_STRUCT_P (mem) = in_struct_p; | ||
| 3146 | + MEM_SCALAR_P (mem) = scalar_p; | ||
| 3147 | + unspec = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, mem), UNSPEC_LDM); | ||
| 3148 | + XVECEXP (result, 0, i) = gen_rtx_SET (VOIDmode, regs[j], unspec); | ||
| 3149 | + } | ||
| 3150 | + | ||
| 3151 | + return result; | ||
| 3152 | +} | ||
| 3153 | + | ||
| 3154 | + | ||
| 3155 | +rtx | ||
| 3156 | +avr32_gen_store_multiple (rtx * regs, int count, rtx to, | ||
| 3157 | + int in_struct_p, int scalar_p) | ||
| 3158 | +{ | ||
| 3159 | + rtx result; | ||
| 3160 | + int i = 0, j; | ||
| 3161 | + | ||
| 3162 | + result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); | ||
| 3163 | + | ||
| 3164 | + for (j = 0; i < count; i++, j++) | ||
| 3165 | + { | ||
| 3166 | + rtx mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4)); | ||
| 3167 | + MEM_IN_STRUCT_P (mem) = in_struct_p; | ||
| 3168 | + MEM_SCALAR_P (mem) = scalar_p; | ||
| 3169 | + XVECEXP (result, 0, i) | ||
| 3170 | + = gen_rtx_SET (VOIDmode, mem, | ||
| 3171 | + gen_rtx_UNSPEC (VOIDmode, | ||
| 3172 | + gen_rtvec (1, regs[j]), | ||
| 3173 | + UNSPEC_STORE_MULTIPLE)); | ||
| 3174 | + } | ||
| 3175 | + | ||
| 3176 | + return result; | ||
| 3177 | +} | ||
| 3178 | + | ||
| 3179 | + | ||
| 3180 | +/* Move a block of memory if it is word aligned or we support unaligned | ||
| 3181 | + word memory accesses. The size must be maximum 64 bytes. */ | ||
| 3182 | + | ||
| 3183 | +int | ||
| 3184 | +avr32_gen_movmemsi (rtx * operands) | ||
| 3185 | +{ | ||
| 3186 | + HOST_WIDE_INT bytes_to_go; | ||
| 3187 | + rtx src, dst; | ||
| 3188 | + rtx st_src, st_dst; | ||
| 3189 | + int ptr_offset = 0; | ||
| 3190 | + int block_size; | ||
| 3191 | + int dst_in_struct_p, src_in_struct_p; | ||
| 3192 | + int dst_scalar_p, src_scalar_p; | ||
| 3193 | + int unaligned; | ||
| 3194 | + | ||
| 3195 | + if (GET_CODE (operands[2]) != CONST_INT | ||
| 3196 | + || GET_CODE (operands[3]) != CONST_INT | ||
| 3197 | + || INTVAL (operands[2]) > 64 | ||
| 3198 | + || ((INTVAL (operands[3]) & 3) && !TARGET_UNALIGNED_WORD)) | ||
| 3199 | + return 0; | ||
| 3200 | + | ||
| 3201 | + unaligned = (INTVAL (operands[3]) & 3) != 0; | ||
| 3202 | + | ||
| 3203 | + block_size = 4; | ||
| 3204 | + | ||
| 3205 | + st_dst = XEXP (operands[0], 0); | ||
| 3206 | + st_src = XEXP (operands[1], 0); | ||
| 3207 | + | ||
| 3208 | + dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]); | ||
| 3209 | + dst_scalar_p = MEM_SCALAR_P (operands[0]); | ||
| 3210 | + src_in_struct_p = MEM_IN_STRUCT_P (operands[1]); | ||
| 3211 | + src_scalar_p = MEM_SCALAR_P (operands[1]); | ||
| 3212 | + | ||
| 3213 | + dst = copy_to_mode_reg (SImode, st_dst); | ||
| 3214 | + src = copy_to_mode_reg (SImode, st_src); | ||
| 3215 | + | ||
| 3216 | + bytes_to_go = INTVAL (operands[2]); | ||
| 3217 | + | ||
| 3218 | + while (bytes_to_go) | ||
| 3219 | + { | ||
| 3220 | + enum machine_mode move_mode; | ||
| 3221 | + /* Seems to be a problem with reloads for the movti pattern so this is | ||
| 3222 | + disabled until that problem is resolved */ | ||
| 3223 | + | ||
| 3224 | + /* if ( bytes_to_go >= GET_MODE_SIZE(TImode) ) move_mode = TImode; else | ||
| 3225 | + */ | ||
| 3226 | + if ((bytes_to_go >= GET_MODE_SIZE (DImode)) && !unaligned) | ||
| 3227 | + move_mode = DImode; | ||
| 3228 | + else if (bytes_to_go >= GET_MODE_SIZE (SImode)) | ||
| 3229 | + move_mode = SImode; | ||
| 3230 | + else | ||
| 3231 | + move_mode = QImode; | ||
| 3232 | + | ||
| 3233 | + { | ||
| 3234 | + rtx dst_mem = gen_rtx_MEM (move_mode, | ||
| 3235 | + gen_rtx_PLUS (SImode, dst, | ||
| 3236 | + GEN_INT (ptr_offset))); | ||
| 3237 | + rtx src_mem = gen_rtx_MEM (move_mode, | ||
| 3238 | + gen_rtx_PLUS (SImode, src, | ||
| 3239 | + GEN_INT (ptr_offset))); | ||
| 3240 | + ptr_offset += GET_MODE_SIZE (move_mode); | ||
| 3241 | + bytes_to_go -= GET_MODE_SIZE (move_mode); | ||
| 3242 | + | ||
| 3243 | + MEM_IN_STRUCT_P (dst_mem) = dst_in_struct_p; | ||
| 3244 | + MEM_SCALAR_P (dst_mem) = dst_scalar_p; | ||
| 3245 | + | ||
| 3246 | + MEM_IN_STRUCT_P (src_mem) = src_in_struct_p; | ||
| 3247 | + MEM_SCALAR_P (src_mem) = src_scalar_p; | ||
| 3248 | + emit_move_insn (dst_mem, src_mem); | ||
| 3249 | + | ||
| 3250 | + } | ||
| 3251 | + } | ||
| 3252 | + | ||
| 3253 | + return 1; | ||
| 3254 | +} | ||
| 3255 | + | ||
| 3256 | + | ||
| 3257 | + | ||
| 3258 | +/*Expand the prologue instruction*/ | ||
| 3259 | +void | ||
| 3260 | +avr32_expand_prologue (void) | ||
| 3261 | +{ | ||
| 3262 | + rtx insn, dwarf; | ||
| 3263 | + unsigned long saved_reg_mask, saved_fp_reg_mask; | ||
| 3264 | + int reglist8 = 0; | ||
| 3265 | + | ||
| 3266 | + /* Naked functions does not have a prologue */ | ||
| 3267 | + if (IS_NAKED (avr32_current_func_type ())) | ||
| 3268 | + return; | ||
| 3269 | + | ||
| 3270 | + saved_reg_mask = avr32_compute_save_reg_mask (TRUE); | ||
| 3271 | + | ||
| 3272 | + if (saved_reg_mask) | ||
| 3273 | + { | ||
| 3274 | + /* Must push used registers */ | ||
| 3275 | + | ||
| 3276 | + /* Should we use POPM or LDM? */ | ||
| 3277 | + int usePUSHM = TRUE; | ||
| 3278 | + reglist8 = 0; | ||
| 3279 | + if (((saved_reg_mask & (1 << 0)) || | ||
| 3280 | + (saved_reg_mask & (1 << 1)) || | ||
| 3281 | + (saved_reg_mask & (1 << 2)) || (saved_reg_mask & (1 << 3)))) | ||
| 3282 | + { | ||
| 3283 | + /* One of R0-R3 should at least be pushed */ | ||
| 3284 | + if (((saved_reg_mask & (1 << 0)) && | ||
| 3285 | + (saved_reg_mask & (1 << 1)) && | ||
| 3286 | + (saved_reg_mask & (1 << 2)) && (saved_reg_mask & (1 << 3)))) | ||
| 3287 | + { | ||
| 3288 | + /* All should be pushed */ | ||
| 3289 | + reglist8 |= 0x01; | ||
| 3290 | + } | ||
| 3291 | + else | ||
| 3292 | + { | ||
| 3293 | + usePUSHM = FALSE; | ||
| 3294 | + } | ||
| 3295 | + } | ||
| 3296 | + | ||
| 3297 | + if (((saved_reg_mask & (1 << 4)) || | ||
| 3298 | + (saved_reg_mask & (1 << 5)) || | ||
| 3299 | + (saved_reg_mask & (1 << 6)) || (saved_reg_mask & (1 << 7)))) | ||
| 3300 | + { | ||
| 3301 | + /* One of R4-R7 should at least be pushed */ | ||
| 3302 | + if (((saved_reg_mask & (1 << 4)) && | ||
| 3303 | + (saved_reg_mask & (1 << 5)) && | ||
| 3304 | + (saved_reg_mask & (1 << 6)) && (saved_reg_mask & (1 << 7)))) | ||
| 3305 | + { | ||
| 3306 | + if (usePUSHM) | ||
| 3307 | + /* All should be pushed */ | ||
| 3308 | + reglist8 |= 0x02; | ||
| 3309 | + } | ||
| 3310 | + else | ||
| 3311 | + { | ||
| 3312 | + usePUSHM = FALSE; | ||
| 3313 | + } | ||
| 3314 | + } | ||
| 3315 | + | ||
| 3316 | + if (((saved_reg_mask & (1 << 8)) || (saved_reg_mask & (1 << 9)))) | ||
| 3317 | + { | ||
| 3318 | + /* One of R8-R9 should at least be pushed */ | ||
| 3319 | + if (((saved_reg_mask & (1 << 8)) && (saved_reg_mask & (1 << 9)))) | ||
| 3320 | + { | ||
| 3321 | + if (usePUSHM) | ||
| 3322 | + /* All should be pushed */ | ||
| 3323 | + reglist8 |= 0x04; | ||
| 3324 | + } | ||
| 3325 | + else | ||
| 3326 | + { | ||
| 3327 | + usePUSHM = FALSE; | ||
| 3328 | + } | ||
| 3329 | + } | ||
| 3330 | + | ||
| 3331 | + if (saved_reg_mask & (1 << 10)) | ||
| 3332 | + reglist8 |= 0x08; | ||
| 3333 | + | ||
| 3334 | + if (saved_reg_mask & (1 << 11)) | ||
| 3335 | + reglist8 |= 0x10; | ||
| 3336 | + | ||
| 3337 | + if (saved_reg_mask & (1 << 12)) | ||
| 3338 | + reglist8 |= 0x20; | ||
| 3339 | + | ||
| 3340 | + if (saved_reg_mask & (1 << ASM_REGNUM (LR_REGNUM))) | ||
| 3341 | + { | ||
| 3342 | + /* Push LR */ | ||
| 3343 | + reglist8 |= 0x40; | ||
| 3344 | + } | ||
| 3345 | + | ||
| 3346 | + if (usePUSHM) | ||
| 3347 | + { | ||
| 3348 | + insn = emit_multi_reg_push (reglist8, TRUE); | ||
| 3349 | + } | ||
| 3350 | + else | ||
| 3351 | + { | ||
| 3352 | + insn = emit_multi_reg_push (saved_reg_mask, FALSE); | ||
| 3353 | + } | ||
| 3354 | + RTX_FRAME_RELATED_P (insn) = 1; | ||
| 3355 | + | ||
| 3356 | + /* Prevent this instruction from being scheduled after any other | ||
| 3357 | + instructions. */ | ||
| 3358 | + emit_insn (gen_blockage ()); | ||
| 3359 | + } | ||
| 3360 | + | ||
| 3361 | + saved_fp_reg_mask = avr32_compute_save_fp_reg_mask (); | ||
| 3362 | + if (saved_fp_reg_mask) | ||
| 3363 | + { | ||
| 3364 | + insn = emit_multi_fp_reg_push (saved_fp_reg_mask); | ||
| 3365 | + RTX_FRAME_RELATED_P (insn) = 1; | ||
| 3366 | + | ||
| 3367 | + /* Prevent this instruction from being scheduled after any other | ||
| 3368 | + instructions. */ | ||
| 3369 | + emit_insn (gen_blockage ()); | ||
| 3370 | + } | ||
| 3371 | + | ||
| 3372 | + /* Set frame pointer */ | ||
| 3373 | + if (frame_pointer_needed) | ||
| 3374 | + { | ||
| 3375 | + insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx); | ||
| 3376 | + RTX_FRAME_RELATED_P (insn) = 1; | ||
| 3377 | + } | ||
| 3378 | + | ||
| 3379 | + if (get_frame_size () > 0) | ||
| 3380 | + { | ||
| 3381 | + if (avr32_const_ok_for_constraint_p (get_frame_size (), 'K', "Ks21")) | ||
| 3382 | + { | ||
| 3383 | + insn = emit_insn (gen_rtx_SET (SImode, | ||
| 3384 | + stack_pointer_rtx, | ||
| 3385 | + gen_rtx_PLUS (SImode, | ||
| 3386 | + stack_pointer_rtx, | ||
| 3387 | + gen_rtx_CONST_INT | ||
| 3388 | + (SImode, | ||
| 3389 | + -get_frame_size | ||
| 3390 | + ())))); | ||
| 3391 | + RTX_FRAME_RELATED_P (insn) = 1; | ||
| 3392 | + } | ||
| 3393 | + else | ||
| 3394 | + { | ||
| 3395 | + /* Immediate is larger than k21 We must either check if we can use | ||
| 3396 | + one of the pushed reegisters as temporary storage or we must | ||
| 3397 | + make us a temp register by pushing a register to the stack. */ | ||
| 3398 | + rtx temp_reg, const_pool_entry, insn; | ||
| 3399 | + if (saved_reg_mask) | ||
| 3400 | + { | ||
| 3401 | + temp_reg = | ||
| 3402 | + gen_rtx_REG (SImode, | ||
| 3403 | + INTERNAL_REGNUM (avr32_get_saved_reg | ||
| 3404 | + (saved_reg_mask))); | ||
| 3405 | + } | ||
| 3406 | + else | ||
| 3407 | + { | ||
| 3408 | + temp_reg = gen_rtx_REG (SImode, INTERNAL_REGNUM (7)); | ||
| 3409 | + emit_move_insn (gen_rtx_MEM | ||
| 3410 | + (SImode, | ||
| 3411 | + gen_rtx_PRE_DEC (SImode, stack_pointer_rtx)), | ||
| 3412 | + temp_reg); | ||
| 3413 | + } | ||
| 3414 | + | ||
| 3415 | + const_pool_entry = | ||
| 3416 | + force_const_mem (SImode, | ||
| 3417 | + gen_rtx_CONST_INT (SImode, get_frame_size ())); | ||
| 3418 | + emit_move_insn (temp_reg, const_pool_entry); | ||
| 3419 | + | ||
| 3420 | + insn = emit_insn (gen_rtx_SET (SImode, | ||
| 3421 | + stack_pointer_rtx, | ||
| 3422 | + gen_rtx_MINUS (SImode, | ||
| 3423 | + stack_pointer_rtx, | ||
| 3424 | + temp_reg))); | ||
| 3425 | + | ||
| 3426 | + dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx, | ||
| 3427 | + gen_rtx_PLUS (SImode, stack_pointer_rtx, | ||
| 3428 | + GEN_INT (-get_frame_size ()))); | ||
| 3429 | + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, | ||
| 3430 | + dwarf, REG_NOTES (insn)); | ||
| 3431 | + RTX_FRAME_RELATED_P (insn) = 1; | ||
| 3432 | + | ||
| 3433 | + if (!saved_reg_mask) | ||
| 3434 | + { | ||
| 3435 | + insn = | ||
| 3436 | + emit_move_insn (temp_reg, | ||
| 3437 | + gen_rtx_MEM (SImode, | ||
| 3438 | + gen_rtx_POST_INC (SImode, | ||
| 3439 | + gen_rtx_REG | ||
| 3440 | + (SImode, | ||
| 3441 | + 13)))); | ||
| 3442 | + } | ||
| 3443 | + | ||
| 3444 | + /* Mark the temp register as dead */ | ||
| 3445 | + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, temp_reg, | ||
| 3446 | + REG_NOTES (insn)); | ||
| 3447 | + | ||
| 3448 | + | ||
| 3449 | + } | ||
| 3450 | + | ||
| 3451 | + /* Prevent the the stack adjustment to be scheduled after any | ||
| 3452 | + instructions using the frame pointer. */ | ||
| 3453 | + emit_insn (gen_blockage ()); | ||
| 3454 | + } | ||
| 3455 | + | ||
| 3456 | + /* Load GOT */ | ||
| 3457 | + if (flag_pic) | ||
| 3458 | + { | ||
| 3459 | + avr32_load_pic_register (); | ||
| 3460 | + | ||
| 3461 | + /* gcc does not know that load or call instructions might use the pic | ||
| 3462 | + register so it might schedule these instructions before the loading | ||
| 3463 | + of the pic register. To avoid this emit a barrier for now. TODO! | ||
| 3464 | + Find out a better way to let gcc know which instructions might use | ||
| 3465 | + the pic register. */ | ||
| 3466 | + emit_insn (gen_blockage ()); | ||
| 3467 | + } | ||
| 3468 | + return; | ||
| 3469 | +} | ||
| 3470 | + | ||
| 3471 | +void | ||
| 3472 | +avr32_set_return_address (rtx source) | ||
| 3473 | +{ | ||
| 3474 | + rtx addr; | ||
| 3475 | + unsigned long saved_regs; | ||
| 3476 | + | ||
| 3477 | + saved_regs = avr32_compute_save_reg_mask (TRUE); | ||
| 3478 | + | ||
| 3479 | + if (!(saved_regs & (1 << ASM_REGNUM (LR_REGNUM)))) | ||
| 3480 | + emit_move_insn (gen_rtx_REG (Pmode, LR_REGNUM), source); | ||
| 3481 | + else | ||
| 3482 | + { | ||
| 3483 | + if (frame_pointer_needed) | ||
| 3484 | + addr = gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM); | ||
| 3485 | + else | ||
| 3486 | + /* FIXME: Need to use scratch register if frame is large */ | ||
| 3487 | + addr = plus_constant (stack_pointer_rtx, get_frame_size ()); | ||
| 3488 | + | ||
| 3489 | + emit_move_insn (gen_rtx_MEM (Pmode, addr), source); | ||
| 3490 | + } | ||
| 3491 | +} | ||
| 3492 | + | ||
| 3493 | + | ||
| 3494 | + | ||
| 3495 | +/* Return the length of INSN. LENGTH is the initial length computed by | ||
| 3496 | + attributes in the machine-description file. */ | ||
| 3497 | + | ||
| 3498 | +int | ||
| 3499 | +avr32_adjust_insn_length (rtx insn ATTRIBUTE_UNUSED, | ||
| 3500 | + int length ATTRIBUTE_UNUSED) | ||
| 3501 | +{ | ||
| 3502 | + return length; | ||
| 3503 | +} | ||
| 3504 | + | ||
| 3505 | +void | ||
| 3506 | +avr32_output_return_instruction (int single_ret_inst ATTRIBUTE_UNUSED, | ||
| 3507 | + int iscond ATTRIBUTE_UNUSED, | ||
| 3508 | + rtx cond ATTRIBUTE_UNUSED, rtx r12_imm) | ||
| 3509 | +{ | ||
| 3510 | + | ||
| 3511 | + unsigned long saved_reg_mask, saved_fp_reg_mask; | ||
| 3512 | + int insert_ret = TRUE; | ||
| 3513 | + int reglist8 = 0; | ||
| 3514 | + int stack_adjustment = get_frame_size (); | ||
| 3515 | + unsigned int func_type = avr32_current_func_type (); | ||
| 3516 | + FILE *f = asm_out_file; | ||
| 3517 | + | ||
| 3518 | + /* Naked functions does not have an epilogue */ | ||
| 3519 | + if (IS_NAKED (func_type)) | ||
| 3520 | + return; | ||
| 3521 | + | ||
| 3522 | + saved_fp_reg_mask = avr32_compute_save_fp_reg_mask (); | ||
| 3523 | + | ||
| 3524 | + saved_reg_mask = avr32_compute_save_reg_mask (FALSE); | ||
| 3525 | + | ||
| 3526 | + /* Reset frame pointer */ | ||
| 3527 | + if (stack_adjustment > 0) | ||
| 3528 | + { | ||
| 3529 | + if (avr32_const_ok_for_constraint_p (stack_adjustment, 'I', "Is21")) | ||
| 3530 | + { | ||
| 3531 | + fprintf (f, "\tsub sp, %i # Reset Frame Pointer\n", | ||
| 3532 | + -stack_adjustment); | ||
| 3533 | + } | ||
| 3534 | + else | ||
| 3535 | + { | ||
| 3536 | + /* TODO! Is it safe to use r8 as scratch?? */ | ||
| 3537 | + fprintf (f, "\tmov r8, lo(%i) # Reset Frame Pointer\n", | ||
| 3538 | + -stack_adjustment); | ||
| 3539 | + fprintf (f, "\torh r8, hi(%i) # Reset Frame Pointer\n", | ||
| 3540 | + -stack_adjustment); | ||
| 3541 | + fprintf (f, "\tadd sp,r8 # Reset Frame Pointer\n"); | ||
| 3542 | + } | ||
| 3543 | + } | ||
| 3544 | + | ||
| 3545 | + if (saved_fp_reg_mask) | ||
| 3546 | + { | ||
| 3547 | + char reglist[64]; /* 64 bytes should be enough... */ | ||
| 3548 | + avr32_make_fp_reglist_w (saved_fp_reg_mask, (char *) reglist); | ||
| 3549 | + fprintf (f, "\tldcm.w\tcp0, sp++, %s\n", reglist); | ||
| 3550 | + if (saved_fp_reg_mask & ~0xff) | ||
| 3551 | + { | ||
| 3552 | + saved_fp_reg_mask &= ~0xff; | ||
| 3553 | + avr32_make_fp_reglist_d (saved_fp_reg_mask, (char *) reglist); | ||
| 3554 | + fprintf (f, "\tldcm.d\tcp0, sp++, %s\n", reglist); | ||
| 3555 | + } | ||
| 3556 | + } | ||
| 3557 | + | ||
| 3558 | + if (saved_reg_mask) | ||
| 3559 | + { | ||
| 3560 | + /* Must pop used registers */ | ||
| 3561 | + | ||
| 3562 | + /* Should we use POPM or LDM? */ | ||
| 3563 | + int usePOPM = TRUE; | ||
| 3564 | + if (((saved_reg_mask & (1 << 0)) || | ||
| 3565 | + (saved_reg_mask & (1 << 1)) || | ||
| 3566 | + (saved_reg_mask & (1 << 2)) || (saved_reg_mask & (1 << 3)))) | ||
| 3567 | + { | ||
| 3568 | + /* One of R0-R3 should at least be popped */ | ||
| 3569 | + if (((saved_reg_mask & (1 << 0)) && | ||
| 3570 | + (saved_reg_mask & (1 << 1)) && | ||
| 3571 | + (saved_reg_mask & (1 << 2)) && (saved_reg_mask & (1 << 3)))) | ||
| 3572 | + { | ||
| 3573 | + /* All should be popped */ | ||
| 3574 | + reglist8 |= 0x01; | ||
| 3575 | + } | ||
| 3576 | + else | ||
| 3577 | + { | ||
| 3578 | + usePOPM = FALSE; | ||
| 3579 | + } | ||
| 3580 | + } | ||
| 3581 | + | ||
| 3582 | + if (((saved_reg_mask & (1 << 4)) || | ||
| 3583 | + (saved_reg_mask & (1 << 5)) || | ||
| 3584 | + (saved_reg_mask & (1 << 6)) || (saved_reg_mask & (1 << 7)))) | ||
| 3585 | + { | ||
| 3586 | + /* One of R0-R3 should at least be popped */ | ||
| 3587 | + if (((saved_reg_mask & (1 << 4)) && | ||
| 3588 | + (saved_reg_mask & (1 << 5)) && | ||
| 3589 | + (saved_reg_mask & (1 << 6)) && (saved_reg_mask & (1 << 7)))) | ||
| 3590 | + { | ||
| 3591 | + if (usePOPM) | ||
| 3592 | + /* All should be popped */ | ||
| 3593 | + reglist8 |= 0x02; | ||
| 3594 | + } | ||
| 3595 | + else | ||
| 3596 | + { | ||
| 3597 | + usePOPM = FALSE; | ||
| 3598 | + } | ||
| 3599 | + } | ||
| 3600 | + | ||
| 3601 | + if (((saved_reg_mask & (1 << 8)) || (saved_reg_mask & (1 << 9)))) | ||
| 3602 | + { | ||
| 3603 | + /* One of R8-R9 should at least be pushed */ | ||
| 3604 | + if (((saved_reg_mask & (1 << 8)) && (saved_reg_mask & (1 << 9)))) | ||
| 3605 | + { | ||
| 3606 | + if (usePOPM) | ||
| 3607 | + /* All should be pushed */ | ||
| 3608 | + reglist8 |= 0x04; | ||
| 3609 | + } | ||
| 3610 | + else | ||
| 3611 | + { | ||
| 3612 | + usePOPM = FALSE; | ||
| 3613 | + } | ||
| 3614 | + } | ||
| 3615 | + | ||
| 3616 | + if (saved_reg_mask & (1 << 10)) | ||
| 3617 | + reglist8 |= 0x08; | ||
| 3618 | + | ||
| 3619 | + if (saved_reg_mask & (1 << 11)) | ||
| 3620 | + reglist8 |= 0x10; | ||
| 3621 | + | ||
| 3622 | + if (saved_reg_mask & (1 << 12)) | ||
| 3623 | + reglist8 |= 0x20; | ||
| 3624 | + | ||
| 3625 | + if (saved_reg_mask & (1 << ASM_REGNUM (LR_REGNUM))) | ||
| 3626 | + /* Pop LR */ | ||
| 3627 | + reglist8 |= 0x40; | ||
| 3628 | + | ||
| 3629 | + if (saved_reg_mask & (1 << ASM_REGNUM (PC_REGNUM))) | ||
| 3630 | + /* Pop LR into PC. */ | ||
| 3631 | + reglist8 |= 0x80; | ||
| 3632 | + | ||
| 3633 | + if (usePOPM) | ||
| 3634 | + { | ||
| 3635 | + char reglist[64]; /* 64 bytes should be enough... */ | ||
| 3636 | + avr32_make_reglist8 (reglist8, (char *) reglist); | ||
| 3637 | + | ||
| 3638 | + if (reglist8 & 0x80) | ||
| 3639 | + /* This instruction is also a return */ | ||
| 3640 | + insert_ret = FALSE; | ||
| 3641 | + | ||
| 3642 | + if (r12_imm && !insert_ret) | ||
| 3643 | + fprintf (f, "\tpopm %s, r12=%li\n", reglist, INTVAL (r12_imm)); | ||
| 3644 | + else | ||
| 3645 | + fprintf (f, "\tpopm %s\n", reglist); | ||
| 3646 | + | ||
| 3647 | + } | ||
| 3648 | + else | ||
| 3649 | + { | ||
| 3650 | + char reglist[64]; /* 64 bytes should be enough... */ | ||
| 3651 | + avr32_make_reglist16 (saved_reg_mask, (char *) reglist); | ||
| 3652 | + if (saved_reg_mask & (1 << ASM_REGNUM (PC_REGNUM))) | ||
| 3653 | + /* This instruction is also a return */ | ||
| 3654 | + insert_ret = FALSE; | ||
| 3655 | + | ||
| 3656 | + if (r12_imm && !insert_ret) | ||
| 3657 | + fprintf (f, "\tldm sp++, %s, r12=%li\n", reglist, | ||
| 3658 | + INTVAL (r12_imm)); | ||
| 3659 | + else | ||
| 3660 | + fprintf (f, "\tldm sp++, %s\n", reglist); | ||
| 3661 | + | ||
| 3662 | + } | ||
| 3663 | + | ||
| 3664 | + } | ||
| 3665 | + | ||
| 3666 | + if (IS_INTERRUPT (func_type)) | ||
| 3667 | + { | ||
| 3668 | + fprintf (f, "\trete\n"); | ||
| 3669 | + } | ||
| 3670 | + else if (insert_ret) | ||
| 3671 | + { | ||
| 3672 | + if (r12_imm) | ||
| 3673 | + fprintf (f, "\tretal %li\n", INTVAL (r12_imm)); | ||
| 3674 | + else | ||
| 3675 | + fprintf (f, "\tretal r12\n"); | ||
| 3676 | + } | ||
| 3677 | +} | ||
| 3678 | + | ||
| 3679 | +/* Function for converting a fp-register mask to a | ||
| 3680 | + reglistCPD8 register list string. */ | ||
| 3681 | +void | ||
| 3682 | +avr32_make_fp_reglist_d (int reglist_mask, char *reglist_string) | ||
| 3683 | +{ | ||
| 3684 | + int i; | ||
| 3685 | + | ||
| 3686 | + /* Make sure reglist_string is empty */ | ||
| 3687 | + reglist_string[0] = '\0'; | ||
| 3688 | + | ||
| 3689 | + for (i = 0; i < NUM_FP_REGS; i += 2) | ||
| 3690 | + { | ||
| 3691 | + if (reglist_mask & (1 << i)) | ||
| 3692 | + { | ||
| 3693 | + strlen (reglist_string) ? | ||
| 3694 | + sprintf (reglist_string, "%s, %s-%s", reglist_string, | ||
| 3695 | + reg_names[INTERNAL_FP_REGNUM (i)], | ||
| 3696 | + reg_names[INTERNAL_FP_REGNUM (i + 1)]) : | ||
| 3697 | + sprintf (reglist_string, "%s-%s", | ||
| 3698 | + reg_names[INTERNAL_FP_REGNUM (i)], | ||
| 3699 | + reg_names[INTERNAL_FP_REGNUM (i + 1)]); | ||
| 3700 | + } | ||
| 3701 | + } | ||
| 3702 | +} | ||
| 3703 | + | ||
| 3704 | +/* Function for converting a fp-register mask to a | ||
| 3705 | + reglistCP8 register list string. */ | ||
| 3706 | +void | ||
| 3707 | +avr32_make_fp_reglist_w (int reglist_mask, char *reglist_string) | ||
| 3708 | +{ | ||
| 3709 | + int i; | ||
| 3710 | + | ||
| 3711 | + /* Make sure reglist_string is empty */ | ||
| 3712 | + reglist_string[0] = '\0'; | ||
| 3713 | + | ||
| 3714 | + for (i = 0; i < NUM_FP_REGS; ++i) | ||
| 3715 | + { | ||
| 3716 | + if (reglist_mask & (1 << i)) | ||
| 3717 | + { | ||
| 3718 | + strlen (reglist_string) ? | ||
| 3719 | + sprintf (reglist_string, "%s, %s", reglist_string, | ||
| 3720 | + reg_names[INTERNAL_FP_REGNUM (i)]) : | ||
| 3721 | + sprintf (reglist_string, "%s", reg_names[INTERNAL_FP_REGNUM (i)]); | ||
| 3722 | + } | ||
| 3723 | + } | ||
| 3724 | +} | ||
| 3725 | + | ||
| 3726 | +void | ||
| 3727 | +avr32_make_reglist16 (int reglist16_vect, char *reglist16_string) | ||
| 3728 | +{ | ||
| 3729 | + int i; | ||
| 3730 | + | ||
| 3731 | + /* Make sure reglist16_string is empty */ | ||
| 3732 | + reglist16_string[0] = '\0'; | ||
| 3733 | + | ||
| 3734 | + for (i = 0; i < 16; ++i) | ||
| 3735 | + { | ||
| 3736 | + if (reglist16_vect & (1 << i)) | ||
| 3737 | + { | ||
| 3738 | + strlen (reglist16_string) ? | ||
| 3739 | + sprintf (reglist16_string, "%s, %s", reglist16_string, | ||
| 3740 | + reg_names[INTERNAL_REGNUM (i)]) : | ||
| 3741 | + sprintf (reglist16_string, "%s", reg_names[INTERNAL_REGNUM (i)]); | ||
| 3742 | + } | ||
| 3743 | + } | ||
| 3744 | +} | ||
| 3745 | + | ||
| 3746 | +int | ||
| 3747 | +avr32_convert_to_reglist16 (int reglist8_vect) | ||
| 3748 | +{ | ||
| 3749 | + int reglist16_vect = 0; | ||
| 3750 | + if (reglist8_vect & 0x1) | ||
| 3751 | + reglist16_vect |= 0xF; | ||
| 3752 | + if (reglist8_vect & 0x2) | ||
| 3753 | + reglist16_vect |= 0xF0; | ||
| 3754 | + if (reglist8_vect & 0x4) | ||
| 3755 | + reglist16_vect |= 0x300; | ||
| 3756 | + if (reglist8_vect & 0x8) | ||
| 3757 | + reglist16_vect |= 0x400; | ||
| 3758 | + if (reglist8_vect & 0x10) | ||
| 3759 | + reglist16_vect |= 0x800; | ||
| 3760 | + if (reglist8_vect & 0x20) | ||
| 3761 | + reglist16_vect |= 0x1000; | ||
| 3762 | + if (reglist8_vect & 0x40) | ||
| 3763 | + reglist16_vect |= 0x4000; | ||
| 3764 | + if (reglist8_vect & 0x80) | ||
| 3765 | + reglist16_vect |= 0x8000; | ||
| 3766 | + | ||
| 3767 | + return reglist16_vect; | ||
| 3768 | +} | ||
| 3769 | + | ||
| 3770 | +void | ||
| 3771 | +avr32_make_reglist8 (int reglist8_vect, char *reglist8_string) | ||
| 3772 | +{ | ||
| 3773 | + /* Make sure reglist8_string is empty */ | ||
| 3774 | + reglist8_string[0] = '\0'; | ||
| 3775 | + | ||
| 3776 | + if (reglist8_vect & 0x1) | ||
| 3777 | + sprintf (reglist8_string, "r0-r3"); | ||
| 3778 | + if (reglist8_vect & 0x2) | ||
| 3779 | + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r4-r7", | ||
| 3780 | + reglist8_string) : | ||
| 3781 | + sprintf (reglist8_string, "r4-r7"); | ||
| 3782 | + if (reglist8_vect & 0x4) | ||
| 3783 | + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r8-r9", | ||
| 3784 | + reglist8_string) : | ||
| 3785 | + sprintf (reglist8_string, "r8-r9"); | ||
| 3786 | + if (reglist8_vect & 0x8) | ||
| 3787 | + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r10", | ||
| 3788 | + reglist8_string) : | ||
| 3789 | + sprintf (reglist8_string, "r10"); | ||
| 3790 | + if (reglist8_vect & 0x10) | ||
| 3791 | + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r11", | ||
| 3792 | + reglist8_string) : | ||
| 3793 | + sprintf (reglist8_string, "r11"); | ||
| 3794 | + if (reglist8_vect & 0x20) | ||
| 3795 | + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r12", | ||
| 3796 | + reglist8_string) : | ||
| 3797 | + sprintf (reglist8_string, "r12"); | ||
| 3798 | + if (reglist8_vect & 0x40) | ||
| 3799 | + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, lr", | ||
| 3800 | + reglist8_string) : | ||
| 3801 | + sprintf (reglist8_string, "lr"); | ||
| 3802 | + if (reglist8_vect & 0x80) | ||
| 3803 | + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, pc", | ||
| 3804 | + reglist8_string) : | ||
| 3805 | + sprintf (reglist8_string, "pc"); | ||
| 3806 | +} | ||
| 3807 | + | ||
| 3808 | +int | ||
| 3809 | +avr32_eh_return_data_regno (int n) | ||
| 3810 | +{ | ||
| 3811 | + if (n >= 0 && n <= 3) | ||
| 3812 | + return 8 + n; | ||
| 3813 | + else | ||
| 3814 | + return INVALID_REGNUM; | ||
| 3815 | +} | ||
| 3816 | + | ||
| 3817 | +/* Compute the distance from register FROM to register TO. | ||
| 3818 | + These can be the arg pointer, the frame pointer or | ||
| 3819 | + the stack pointer. | ||
| 3820 | + Typical stack layout looks like this: | ||
| 3821 | + | ||
| 3822 | + old stack pointer -> | | | ||
| 3823 | + ---- | ||
| 3824 | + | | \ | ||
| 3825 | + | | saved arguments for | ||
| 3826 | + | | vararg functions | ||
| 3827 | + arg_pointer -> | | / | ||
| 3828 | + -- | ||
| 3829 | + | | \ | ||
| 3830 | + | | call saved | ||
| 3831 | + | | registers | ||
| 3832 | + | | / | ||
| 3833 | + frame ptr -> -- | ||
| 3834 | + | | \ | ||
| 3835 | + | | local | ||
| 3836 | + | | variables | ||
| 3837 | + stack ptr --> | | / | ||
| 3838 | + -- | ||
| 3839 | + | | \ | ||
| 3840 | + | | outgoing | ||
| 3841 | + | | arguments | ||
| 3842 | + | | / | ||
| 3843 | + -- | ||
| 3844 | + | ||
| 3845 | + For a given funciton some or all of these stack compomnents | ||
| 3846 | + may not be needed, giving rise to the possibility of | ||
| 3847 | + eliminating some of the registers. | ||
| 3848 | + | ||
| 3849 | + The values returned by this function must reflect the behaviour | ||
| 3850 | + of avr32_expand_prologue() and avr32_compute_save_reg_mask(). | ||
| 3851 | + | ||
| 3852 | + The sign of the number returned reflects the direction of stack | ||
| 3853 | + growth, so the values are positive for all eliminations except | ||
| 3854 | + from the soft frame pointer to the hard frame pointer. */ | ||
| 3855 | + | ||
| 3856 | + | ||
| 3857 | +int | ||
| 3858 | +avr32_initial_elimination_offset (int from, int to) | ||
| 3859 | +{ | ||
| 3860 | + int i; | ||
| 3861 | + int call_saved_regs = 0; | ||
| 3862 | + unsigned long saved_reg_mask, saved_fp_reg_mask; | ||
| 3863 | + unsigned int local_vars = get_frame_size (); | ||
| 3864 | + | ||
| 3865 | + saved_reg_mask = avr32_compute_save_reg_mask (TRUE); | ||
| 3866 | + saved_fp_reg_mask = avr32_compute_save_fp_reg_mask (); | ||
| 3867 | + | ||
| 3868 | + for (i = 0; i < 16; ++i) | ||
| 3869 | + { | ||
| 3870 | + if (saved_reg_mask & (1 << i)) | ||
| 3871 | + call_saved_regs += 4; | ||
| 3872 | + } | ||
| 3873 | + | ||
| 3874 | + for (i = 0; i < NUM_FP_REGS; ++i) | ||
| 3875 | + { | ||
| 3876 | + if (saved_fp_reg_mask & (1 << i)) | ||
| 3877 | + call_saved_regs += 4; | ||
| 3878 | + } | ||
| 3879 | + | ||
| 3880 | + switch (from) | ||
| 3881 | + { | ||
| 3882 | + case ARG_POINTER_REGNUM: | ||
| 3883 | + switch (to) | ||
| 3884 | + { | ||
| 3885 | + case STACK_POINTER_REGNUM: | ||
| 3886 | + return call_saved_regs + local_vars; | ||
| 3887 | + case FRAME_POINTER_REGNUM: | ||
| 3888 | + return call_saved_regs; | ||
| 3889 | + default: | ||
| 3890 | + abort (); | ||
| 3891 | + } | ||
| 3892 | + case FRAME_POINTER_REGNUM: | ||
| 3893 | + switch (to) | ||
| 3894 | + { | ||
| 3895 | + case STACK_POINTER_REGNUM: | ||
| 3896 | + return local_vars; | ||
| 3897 | + default: | ||
| 3898 | + abort (); | ||
| 3899 | + } | ||
| 3900 | + default: | ||
| 3901 | + abort (); | ||
| 3902 | + } | ||
| 3903 | +} | ||
| 3904 | + | ||
| 3905 | + | ||
| 3906 | +/* | ||
| 3907 | + Returns a rtx used when passing the next argument to a function. | ||
| 3908 | + avr32_init_cumulative_args() and avr32_function_arg_advance() sets witch | ||
| 3909 | + register to use. | ||
| 3910 | +*/ | ||
| 3911 | +rtx | ||
| 3912 | +avr32_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, | ||
| 3913 | + tree type, int named) | ||
| 3914 | +{ | ||
| 3915 | + int index = -1; | ||
| 3916 | + | ||
| 3917 | + HOST_WIDE_INT arg_size, arg_rsize; | ||
| 3918 | + if (type) | ||
| 3919 | + { | ||
| 3920 | + arg_size = int_size_in_bytes (type); | ||
| 3921 | + } | ||
| 3922 | + else | ||
| 3923 | + { | ||
| 3924 | + arg_size = GET_MODE_SIZE (mode); | ||
| 3925 | + } | ||
| 3926 | + arg_rsize = PUSH_ROUNDING (arg_size); | ||
| 3927 | + | ||
| 3928 | + /* | ||
| 3929 | + The last time this macro is called, it is called with mode == VOIDmode, | ||
| 3930 | + and its result is passed to the call or call_value pattern as operands 2 | ||
| 3931 | + and 3 respectively. */ | ||
| 3932 | + if (mode == VOIDmode) | ||
| 3933 | + { | ||
| 3934 | + return gen_rtx_CONST_INT (SImode, 22); /* ToDo: fixme. */ | ||
| 3935 | + } | ||
| 3936 | + | ||
| 3937 | + if ((*targetm.calls.must_pass_in_stack) (mode, type) || !named) | ||
| 3938 | + { | ||
| 3939 | + return NULL_RTX; | ||
| 3940 | + } | ||
| 3941 | + | ||
| 3942 | + if (arg_rsize == 8) | ||
| 3943 | + { | ||
| 3944 | + /* use r11:r10 or r9:r8. */ | ||
| 3945 | + if (!(GET_USED_INDEX (cum, 1) || GET_USED_INDEX (cum, 2))) | ||
| 3946 | + index = 1; | ||
| 3947 | + else if (!(GET_USED_INDEX (cum, 3) || GET_USED_INDEX (cum, 4))) | ||
| 3948 | + index = 3; | ||
| 3949 | + else | ||
| 3950 | + index = -1; | ||
| 3951 | + } | ||
| 3952 | + else if (arg_rsize == 4) | ||
| 3953 | + { /* Use first available register */ | ||
| 3954 | + index = 0; | ||
| 3955 | + while (index <= LAST_CUM_REG_INDEX && GET_USED_INDEX (cum, index)) | ||
| 3956 | + index++; | ||
| 3957 | + if (index > LAST_CUM_REG_INDEX) | ||
| 3958 | + index = -1; | ||
| 3959 | + } | ||
| 3960 | + | ||
| 3961 | + SET_REG_INDEX (cum, index); | ||
| 3962 | + | ||
| 3963 | + if (GET_REG_INDEX (cum) >= 0) | ||
| 3964 | + return gen_rtx_REG (mode, | ||
| 3965 | + avr32_function_arg_reglist[GET_REG_INDEX (cum)]); | ||
| 3966 | + | ||
| 3967 | + return NULL_RTX; | ||
| 3968 | +} | ||
| 3969 | + | ||
| 3970 | +/* | ||
| 3971 | + Set the register used for passing the first argument to a function. | ||
| 3972 | +*/ | ||
| 3973 | +void | ||
| 3974 | +avr32_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype, | ||
| 3975 | + rtx libname ATTRIBUTE_UNUSED, | ||
| 3976 | + tree fndecl ATTRIBUTE_UNUSED) | ||
| 3977 | +{ | ||
| 3978 | + /* Set all registers as unused. */ | ||
| 3979 | + SET_INDEXES_UNUSED (cum); | ||
| 3980 | + | ||
| 3981 | + /* Reset uses_anonymous_args */ | ||
| 3982 | + cum->uses_anonymous_args = 0; | ||
| 3983 | + | ||
| 3984 | + /* Reset size of stack pushed arguments */ | ||
| 3985 | + cum->stack_pushed_args_size = 0; | ||
| 3986 | + | ||
| 3987 | + /* If the function is returning a value passed in memory r12 is used as a | ||
| 3988 | + Return Value Pointer. */ | ||
| 3989 | + | ||
| 3990 | + if (fntype != 0 && avr32_return_in_memory (TREE_TYPE (fntype), fntype)) | ||
| 3991 | + { | ||
| 3992 | + SET_REG_INDEX (cum, 0); | ||
| 3993 | + SET_USED_INDEX (cum, GET_REG_INDEX (cum)); | ||
| 3994 | + } | ||
| 3995 | +} | ||
| 3996 | + | ||
| 3997 | +/* | ||
| 3998 | + Set register used for passing the next argument to a function. Only the | ||
| 3999 | + Scratch Registers are used. | ||
| 4000 | + | ||
| 4001 | + number name | ||
| 4002 | + 15 r15 PC | ||
| 4003 | + 14 r14 LR | ||
| 4004 | + 13 r13 _SP_________ | ||
| 4005 | + FIRST_CUM_REG 12 r12 _||_ | ||
| 4006 | + 10 r11 || | ||
| 4007 | + 11 r10 _||_ Scratch Registers | ||
| 4008 | + 8 r9 || | ||
| 4009 | + LAST_SCRATCH_REG 9 r8 _\/_________ | ||
| 4010 | + 6 r7 /\ | ||
| 4011 | + 7 r6 || | ||
| 4012 | + 4 r5 || | ||
| 4013 | + 5 r4 || | ||
| 4014 | + 2 r3 || | ||
| 4015 | + 3 r2 || | ||
| 4016 | + 0 r1 || | ||
| 4017 | + 1 r0 _||_________ | ||
| 4018 | + | ||
| 4019 | +*/ | ||
| 4020 | +void | ||
| 4021 | +avr32_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode, | ||
| 4022 | + tree type, int named ATTRIBUTE_UNUSED) | ||
| 4023 | +{ | ||
| 4024 | + HOST_WIDE_INT arg_size, arg_rsize; | ||
| 4025 | + | ||
| 4026 | + if (type) | ||
| 4027 | + { | ||
| 4028 | + arg_size = int_size_in_bytes (type); | ||
| 4029 | + } | ||
| 4030 | + else | ||
| 4031 | + { | ||
| 4032 | + arg_size = GET_MODE_SIZE (mode); | ||
| 4033 | + } | ||
| 4034 | + arg_rsize = PUSH_ROUNDING (arg_size); | ||
| 4035 | + | ||
| 4036 | + /* It the argument had to be passed in stack, no register is used. */ | ||
| 4037 | + if ((*targetm.calls.must_pass_in_stack) (mode, type)) | ||
| 4038 | + { | ||
| 4039 | + cum->stack_pushed_args_size += PUSH_ROUNDING (int_size_in_bytes (type)); | ||
| 4040 | + return; | ||
| 4041 | + } | ||
| 4042 | + | ||
| 4043 | + /* Mark the used registers as "used". */ | ||
| 4044 | + if (GET_REG_INDEX (cum) >= 0) | ||
| 4045 | + { | ||
| 4046 | + SET_USED_INDEX (cum, GET_REG_INDEX (cum)); | ||
| 4047 | + if (arg_rsize == 8) | ||
| 4048 | + { | ||
| 4049 | + SET_USED_INDEX (cum, (GET_REG_INDEX (cum) + 1)); | ||
| 4050 | + } | ||
| 4051 | + } | ||
| 4052 | + else | ||
| 4053 | + { | ||
| 4054 | + /* Had to use stack */ | ||
| 4055 | + cum->stack_pushed_args_size += arg_rsize; | ||
| 4056 | + } | ||
| 4057 | +} | ||
| 4058 | + | ||
| 4059 | +/* | ||
| 4060 | + Defines witch direction to go to find the next register to use if the | ||
| 4061 | + argument is larger then one register or for arguments shorter than an | ||
| 4062 | + int which is not promoted, such as the last part of structures with | ||
| 4063 | + size not a multiple of 4. */ | ||
| 4064 | +enum direction | ||
| 4065 | +avr32_function_arg_padding (enum machine_mode mode ATTRIBUTE_UNUSED, | ||
| 4066 | + tree type) | ||
| 4067 | +{ | ||
| 4068 | + /* Pad upward for all aggregates except byte and halfword sized aggregates | ||
| 4069 | + which can be passed in registers. */ | ||
| 4070 | + if (type | ||
| 4071 | + && AGGREGATE_TYPE_P (type) | ||
| 4072 | + && (int_size_in_bytes (type) != 1) | ||
| 4073 | + && !((int_size_in_bytes (type) == 2) | ||
| 4074 | + && TYPE_ALIGN_UNIT (type) >= 2) | ||
| 4075 | + && (int_size_in_bytes (type) & 0x3)) | ||
| 4076 | + { | ||
| 4077 | + return upward; | ||
| 4078 | + } | ||
| 4079 | + | ||
| 4080 | + return downward; | ||
| 4081 | +} | ||
| 4082 | + | ||
| 4083 | +/* | ||
| 4084 | + Return a rtx used for the return value from a function call. | ||
| 4085 | +*/ | ||
| 4086 | +rtx | ||
| 4087 | +avr32_function_value (tree type, tree func) | ||
| 4088 | +{ | ||
| 4089 | + if (avr32_return_in_memory (type, func)) | ||
| 4090 | + return NULL_RTX; | ||
| 4091 | + | ||
| 4092 | + if (int_size_in_bytes (type) <= 4) | ||
| 4093 | + if (avr32_return_in_msb (type)) | ||
| 4094 | + /* Aggregates of size less than a word which does align the data in the | ||
| 4095 | + MSB must use SImode for r12. */ | ||
| 4096 | + return gen_rtx_REG (SImode, RET_REGISTER); | ||
| 4097 | + else | ||
| 4098 | + return gen_rtx_REG (TYPE_MODE (type), RET_REGISTER); | ||
| 4099 | + else if (int_size_in_bytes (type) <= 8) | ||
| 4100 | + return gen_rtx_REG (TYPE_MODE (type), INTERNAL_REGNUM (11)); | ||
| 4101 | + | ||
| 4102 | + return NULL_RTX; | ||
| 4103 | +} | ||
| 4104 | + | ||
| 4105 | +/* | ||
| 4106 | + Return a rtx used for the return value from a library function call. | ||
| 4107 | +*/ | ||
| 4108 | +rtx | ||
| 4109 | +avr32_libcall_value (enum machine_mode mode) | ||
| 4110 | +{ | ||
| 4111 | + | ||
| 4112 | + if (GET_MODE_SIZE (mode) <= 4) | ||
| 4113 | + return gen_rtx_REG (mode, RET_REGISTER); | ||
| 4114 | + else if (GET_MODE_SIZE (mode) <= 8) | ||
| 4115 | + return gen_rtx_REG (mode, INTERNAL_REGNUM (11)); | ||
| 4116 | + else | ||
| 4117 | + return NULL_RTX; | ||
| 4118 | +} | ||
| 4119 | + | ||
| 4120 | +/* Return TRUE if X references a SYMBOL_REF. */ | ||
| 4121 | +int | ||
| 4122 | +symbol_mentioned_p (rtx x) | ||
| 4123 | +{ | ||
| 4124 | + const char *fmt; | ||
| 4125 | + int i; | ||
| 4126 | + | ||
| 4127 | + if (GET_CODE (x) == SYMBOL_REF) | ||
| 4128 | + return 1; | ||
| 4129 | + | ||
| 4130 | + fmt = GET_RTX_FORMAT (GET_CODE (x)); | ||
| 4131 | + | ||
| 4132 | + for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) | ||
| 4133 | + { | ||
| 4134 | + if (fmt[i] == 'E') | ||
| 4135 | + { | ||
| 4136 | + int j; | ||
| 4137 | + | ||
| 4138 | + for (j = XVECLEN (x, i) - 1; j >= 0; j--) | ||
| 4139 | + if (symbol_mentioned_p (XVECEXP (x, i, j))) | ||
| 4140 | + return 1; | ||
| 4141 | + } | ||
| 4142 | + else if (fmt[i] == 'e' && symbol_mentioned_p (XEXP (x, i))) | ||
| 4143 | + return 1; | ||
| 4144 | + } | ||
| 4145 | + | ||
| 4146 | + return 0; | ||
| 4147 | +} | ||
| 4148 | + | ||
| 4149 | +/* Return TRUE if X references a LABEL_REF. */ | ||
| 4150 | +int | ||
| 4151 | +label_mentioned_p (rtx x) | ||
| 4152 | +{ | ||
| 4153 | + const char *fmt; | ||
| 4154 | + int i; | ||
| 4155 | + | ||
| 4156 | + if (GET_CODE (x) == LABEL_REF) | ||
| 4157 | + return 1; | ||
| 4158 | + | ||
| 4159 | + fmt = GET_RTX_FORMAT (GET_CODE (x)); | ||
| 4160 | + for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) | ||
| 4161 | + { | ||
| 4162 | + if (fmt[i] == 'E') | ||
| 4163 | + { | ||
| 4164 | + int j; | ||
| 4165 | + | ||
| 4166 | + for (j = XVECLEN (x, i) - 1; j >= 0; j--) | ||
| 4167 | + if (label_mentioned_p (XVECEXP (x, i, j))) | ||
| 4168 | + return 1; | ||
| 4169 | + } | ||
| 4170 | + else if (fmt[i] == 'e' && label_mentioned_p (XEXP (x, i))) | ||
| 4171 | + return 1; | ||
| 4172 | + } | ||
| 4173 | + | ||
| 4174 | + return 0; | ||
| 4175 | +} | ||
| 4176 | + | ||
| 4177 | + | ||
| 4178 | +int | ||
| 4179 | +avr32_legitimate_pic_operand_p (rtx x) | ||
| 4180 | +{ | ||
| 4181 | + | ||
| 4182 | + /* We can't have const, this must be broken down to a symbol. */ | ||
| 4183 | + if (GET_CODE (x) == CONST) | ||
| 4184 | + return FALSE; | ||
| 4185 | + | ||
| 4186 | + /* Can't access symbols or labels via the constant pool either */ | ||
| 4187 | + if ((GET_CODE (x) == SYMBOL_REF | ||
| 4188 | + && CONSTANT_POOL_ADDRESS_P (x) | ||
| 4189 | + && (symbol_mentioned_p (get_pool_constant (x)) | ||
| 4190 | + || label_mentioned_p (get_pool_constant (x))))) | ||
| 4191 | + return FALSE; | ||
| 4192 | + | ||
| 4193 | + return TRUE; | ||
| 4194 | +} | ||
| 4195 | + | ||
| 4196 | + | ||
| 4197 | +rtx | ||
| 4198 | +legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED, | ||
| 4199 | + rtx reg) | ||
| 4200 | +{ | ||
| 4201 | + | ||
| 4202 | + if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF) | ||
| 4203 | + { | ||
| 4204 | + int subregs = 0; | ||
| 4205 | + | ||
| 4206 | + if (reg == 0) | ||
| 4207 | + { | ||
| 4208 | + if (no_new_pseudos) | ||
| 4209 | + abort (); | ||
| 4210 | + else | ||
| 4211 | + reg = gen_reg_rtx (Pmode); | ||
| 4212 | + | ||
| 4213 | + subregs = 1; | ||
| 4214 | + } | ||
| 4215 | + | ||
| 4216 | + emit_move_insn (reg, orig); | ||
| 4217 | + | ||
| 4218 | + /* Only set current function as using pic offset table if flag_pic is | ||
| 4219 | + set. This is because this function is also used if | ||
| 4220 | + TARGET_HAS_ASM_ADDR_PSEUDOS is set. */ | ||
| 4221 | + if (flag_pic) | ||
| 4222 | + current_function_uses_pic_offset_table = 1; | ||
| 4223 | + | ||
| 4224 | + /* Put a REG_EQUAL note on this insn, so that it can be optimized by | ||
| 4225 | + loop. */ | ||
| 4226 | + return reg; | ||
| 4227 | + } | ||
| 4228 | + else if (GET_CODE (orig) == CONST) | ||
| 4229 | + { | ||
| 4230 | + rtx base, offset; | ||
| 4231 | + | ||
| 4232 | + if (flag_pic | ||
| 4233 | + && GET_CODE (XEXP (orig, 0)) == PLUS | ||
| 4234 | + && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) | ||
| 4235 | + return orig; | ||
| 4236 | + | ||
| 4237 | + if (reg == 0) | ||
| 4238 | + { | ||
| 4239 | + if (no_new_pseudos) | ||
| 4240 | + abort (); | ||
| 4241 | + else | ||
| 4242 | + reg = gen_reg_rtx (Pmode); | ||
| 4243 | + } | ||
| 4244 | + | ||
| 4245 | + if (GET_CODE (XEXP (orig, 0)) == PLUS) | ||
| 4246 | + { | ||
| 4247 | + base = | ||
| 4248 | + legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg); | ||
| 4249 | + offset = | ||
| 4250 | + legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, | ||
| 4251 | + base == reg ? 0 : reg); | ||
| 4252 | + } | ||
| 4253 | + else | ||
| 4254 | + abort (); | ||
| 4255 | + | ||
| 4256 | + if (GET_CODE (offset) == CONST_INT) | ||
| 4257 | + { | ||
| 4258 | + /* The base register doesn't really matter, we only want to test | ||
| 4259 | + the index for the appropriate mode. */ | ||
| 4260 | + if (!avr32_const_ok_for_constraint_p (INTVAL (offset), 'I', "Is21")) | ||
| 4261 | + { | ||
| 4262 | + if (!no_new_pseudos) | ||
| 4263 | + offset = force_reg (Pmode, offset); | ||
| 4264 | + else | ||
| 4265 | + abort (); | ||
| 4266 | + } | ||
| 4267 | + | ||
| 4268 | + if (GET_CODE (offset) == CONST_INT) | ||
| 4269 | + return plus_constant (base, INTVAL (offset)); | ||
| 4270 | + } | ||
| 4271 | + | ||
| 4272 | + return gen_rtx_PLUS (Pmode, base, offset); | ||
| 4273 | + } | ||
| 4274 | + | ||
| 4275 | + return orig; | ||
| 4276 | +} | ||
| 4277 | + | ||
| 4278 | +/* Generate code to load the PIC register. */ | ||
| 4279 | +void | ||
| 4280 | +avr32_load_pic_register (void) | ||
| 4281 | +{ | ||
| 4282 | + rtx l1, pic_tmp; | ||
| 4283 | + rtx global_offset_table; | ||
| 4284 | + | ||
| 4285 | + if ((current_function_uses_pic_offset_table == 0) || TARGET_NO_INIT_GOT) | ||
| 4286 | + return; | ||
| 4287 | + | ||
| 4288 | + if (!flag_pic) | ||
| 4289 | + abort (); | ||
| 4290 | + | ||
| 4291 | + l1 = gen_label_rtx (); | ||
| 4292 | + | ||
| 4293 | + global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); | ||
| 4294 | + pic_tmp = | ||
| 4295 | + gen_rtx_CONST (Pmode, | ||
| 4296 | + gen_rtx_MINUS (SImode, gen_rtx_LABEL_REF (Pmode, l1), | ||
| 4297 | + global_offset_table)); | ||
| 4298 | + emit_insn (gen_pic_load_addr | ||
| 4299 | + (pic_offset_table_rtx, force_const_mem (SImode, pic_tmp))); | ||
| 4300 | + emit_insn (gen_pic_compute_got_from_pc (pic_offset_table_rtx, l1)); | ||
| 4301 | + | ||
| 4302 | + /* Need to emit this whether or not we obey regdecls, since setjmp/longjmp | ||
| 4303 | + can cause life info to screw up. */ | ||
| 4304 | + emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx)); | ||
| 4305 | +} | ||
| 4306 | + | ||
| 4307 | + | ||
| 4308 | + | ||
| 4309 | +/* This hook should return true if values of type type are returned at the most | ||
| 4310 | + significant end of a register (in other words, if they are padded at the | ||
| 4311 | + least significant end). You can assume that type is returned in a register; | ||
| 4312 | + the caller is required to check this. Note that the register provided by | ||
| 4313 | + FUNCTION_VALUE must be able to hold the complete return value. For example, | ||
| 4314 | + if a 1-, 2- or 3-byte structure is returned at the most significant end of a | ||
| 4315 | + 4-byte register, FUNCTION_VALUE should provide an SImode rtx. */ | ||
| 4316 | +bool | ||
| 4317 | +avr32_return_in_msb (tree type ATTRIBUTE_UNUSED) | ||
| 4318 | +{ | ||
| 4319 | + /* if ( AGGREGATE_TYPE_P (type) ) if ((int_size_in_bytes(type) == 1) || | ||
| 4320 | + ((int_size_in_bytes(type) == 2) && TYPE_ALIGN_UNIT(type) >= 2)) return | ||
| 4321 | + false; else return true; */ | ||
| 4322 | + | ||
| 4323 | + return false; | ||
| 4324 | +} | ||
| 4325 | + | ||
| 4326 | + | ||
| 4327 | +/* | ||
| 4328 | + Returns one if a certain function value is going to be returned in memory | ||
| 4329 | + and zero if it is going to be returned in a register. | ||
| 4330 | + | ||
| 4331 | + BLKmode and all other modes that is larger than 64 bits are returned in | ||
| 4332 | + memory. | ||
| 4333 | +*/ | ||
| 4334 | +bool | ||
| 4335 | +avr32_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED) | ||
| 4336 | +{ | ||
| 4337 | + if (TYPE_MODE (type) == VOIDmode) | ||
| 4338 | + return false; | ||
| 4339 | + | ||
| 4340 | + if (int_size_in_bytes (type) > (2 * UNITS_PER_WORD) | ||
| 4341 | + || int_size_in_bytes (type) == -1) | ||
| 4342 | + { | ||
| 4343 | + return true; | ||
| 4344 | + } | ||
| 4345 | + | ||
| 4346 | + /* If we have an aggregate then use the same mechanism as when checking if | ||
| 4347 | + it should be passed on the stack. */ | ||
| 4348 | + if (type | ||
| 4349 | + && AGGREGATE_TYPE_P (type) | ||
| 4350 | + && (*targetm.calls.must_pass_in_stack) (TYPE_MODE (type), type)) | ||
| 4351 | + return true; | ||
| 4352 | + | ||
| 4353 | + return false; | ||
| 4354 | +} | ||
| 4355 | + | ||
| 4356 | + | ||
| 4357 | +/* Output the constant part of the trampoline. | ||
| 4358 | + lddpc r0, pc[0x8:e] ; load static chain register | ||
| 4359 | + lddpc pc, pc[0x8:e] ; jump to subrutine | ||
| 4360 | + .long 0 ; Address to static chain, | ||
| 4361 | + ; filled in by avr32_initialize_trampoline() | ||
| 4362 | + .long 0 ; Address to subrutine, | ||
| 4363 | + ; filled in by avr32_initialize_trampoline() | ||
| 4364 | +*/ | ||
| 4365 | +void | ||
| 4366 | +avr32_trampoline_template (FILE * file) | ||
| 4367 | +{ | ||
| 4368 | + fprintf (file, "\tlddpc r0, pc[8]\n"); | ||
| 4369 | + fprintf (file, "\tlddpc pc, pc[8]\n"); | ||
| 4370 | + /* make room for the address of the static chain. */ | ||
| 4371 | + fprintf (file, "\t.long\t0\n"); | ||
| 4372 | + /* make room for the address to the subrutine. */ | ||
| 4373 | + fprintf (file, "\t.long\t0\n"); | ||
| 4374 | +} | ||
| 4375 | + | ||
| 4376 | + | ||
| 4377 | +/* | ||
| 4378 | + Initialize the variable parts of a trampoline. | ||
| 4379 | +*/ | ||
| 4380 | +void | ||
| 4381 | +avr32_initialize_trampoline (rtx addr, rtx fnaddr, rtx static_chain) | ||
| 4382 | +{ | ||
| 4383 | + /* Store the address to the static chain. */ | ||
| 4384 | + emit_move_insn (gen_rtx_MEM | ||
| 4385 | + (SImode, plus_constant (addr, TRAMPOLINE_SIZE - 4)), | ||
| 4386 | + static_chain); | ||
| 4387 | + | ||
| 4388 | + /* Store the address to the function. */ | ||
| 4389 | + emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, TRAMPOLINE_SIZE)), | ||
| 4390 | + fnaddr); | ||
| 4391 | + | ||
| 4392 | + emit_insn (gen_cache (gen_rtx_REG (SImode, 13), | ||
| 4393 | + gen_rtx_CONST_INT (SImode, | ||
| 4394 | + AVR32_CACHE_INVALIDATE_ICACHE))); | ||
| 4395 | +} | ||
| 4396 | + | ||
| 4397 | +/* Return nonzero if X is valid as an addressing register. */ | ||
| 4398 | +int | ||
| 4399 | +avr32_address_register_rtx_p (rtx x, int strict_p) | ||
| 4400 | +{ | ||
| 4401 | + int regno; | ||
| 4402 | + | ||
| 4403 | + if (GET_CODE (x) != REG) | ||
| 4404 | + return 0; | ||
| 4405 | + | ||
| 4406 | + regno = REGNO (x); | ||
| 4407 | + | ||
| 4408 | + if (strict_p) | ||
| 4409 | + return REGNO_OK_FOR_BASE_P (regno); | ||
| 4410 | + | ||
| 4411 | + return (regno <= LAST_REGNUM || regno >= FIRST_PSEUDO_REGISTER); | ||
| 4412 | +} | ||
| 4413 | + | ||
| 4414 | +/* Return nonzero if INDEX is valid for an address index operand. */ | ||
| 4415 | +int | ||
| 4416 | +avr32_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p) | ||
| 4417 | +{ | ||
| 4418 | + enum rtx_code code = GET_CODE (index); | ||
| 4419 | + | ||
| 4420 | + if (mode == TImode) | ||
| 4421 | + return 0; | ||
| 4422 | + | ||
| 4423 | + /* Standard coprocessor addressing modes. */ | ||
| 4424 | + if (code == CONST_INT) | ||
| 4425 | + { | ||
| 4426 | + if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT) | ||
| 4427 | + /* Coprocessor mem insns has a smaller reach than ordinary mem insns */ | ||
| 4428 | + return CONST_OK_FOR_CONSTRAINT_P (INTVAL (index), 'K', "Ku14"); | ||
| 4429 | + else | ||
| 4430 | + return CONST_OK_FOR_CONSTRAINT_P (INTVAL (index), 'K', "Ks16"); | ||
| 4431 | + } | ||
| 4432 | + | ||
| 4433 | + if (avr32_address_register_rtx_p (index, strict_p)) | ||
| 4434 | + return 1; | ||
| 4435 | + | ||
| 4436 | + if (code == MULT) | ||
| 4437 | + { | ||
| 4438 | + rtx xiop0 = XEXP (index, 0); | ||
| 4439 | + rtx xiop1 = XEXP (index, 1); | ||
| 4440 | + return ((avr32_address_register_rtx_p (xiop0, strict_p) | ||
| 4441 | + && power_of_two_operand (xiop1, SImode) | ||
| 4442 | + && (INTVAL (xiop1) <= 8)) | ||
| 4443 | + || (avr32_address_register_rtx_p (xiop1, strict_p) | ||
| 4444 | + && power_of_two_operand (xiop0, SImode) | ||
| 4445 | + && (INTVAL (xiop0) <= 8))); | ||
| 4446 | + } | ||
| 4447 | + else if (code == ASHIFT) | ||
| 4448 | + { | ||
| 4449 | + rtx op = XEXP (index, 1); | ||
| 4450 | + | ||
| 4451 | + return (avr32_address_register_rtx_p (XEXP (index, 0), strict_p) | ||
| 4452 | + && GET_CODE (op) == CONST_INT | ||
| 4453 | + && INTVAL (op) > 0 && INTVAL (op) <= 3); | ||
| 4454 | + } | ||
| 4455 | + | ||
| 4456 | + return 0; | ||
| 4457 | +} | ||
| 4458 | + | ||
| 4459 | +/* | ||
| 4460 | + Used in the GO_IF_LEGITIMATE_ADDRESS macro. Returns a nonzero value if | ||
| 4461 | + the RTX x is a legitimate memory address. | ||
| 4462 | + | ||
| 4463 | + Returns NO_REGS if the address is not legatime, GENERAL_REGS or ALL_REGS | ||
| 4464 | + if it is. | ||
| 4465 | +*/ | ||
| 4466 | + | ||
| 4467 | +/* Forward declaration*/ | ||
| 4468 | +int is_minipool_label (rtx label); | ||
| 4469 | + | ||
| 4470 | +int | ||
| 4471 | +avr32_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED, | ||
| 4472 | + rtx x, int strict) | ||
| 4473 | +{ | ||
| 4474 | + | ||
| 4475 | + switch (GET_CODE (x)) | ||
| 4476 | + { | ||
| 4477 | + case REG: | ||
| 4478 | + return avr32_address_register_rtx_p (x, strict); | ||
| 4479 | + case CONST: | ||
| 4480 | + { | ||
| 4481 | + rtx label = avr32_find_symbol (x); | ||
| 4482 | + if (label | ||
| 4483 | + && | ||
| 4484 | + ( (CONSTANT_POOL_ADDRESS_P (label) | ||
| 4485 | + && !(flag_pic | ||
| 4486 | + && (symbol_mentioned_p (get_pool_constant (label)) | ||
| 4487 | + || label_mentioned_p (get_pool_constant(label))))) | ||
| 4488 | + /* TODO! Can this ever happen??? */ | ||
| 4489 | + || ((GET_CODE (label) == LABEL_REF) | ||
| 4490 | + && GET_CODE (XEXP (label, 0)) == CODE_LABEL | ||
| 4491 | + && is_minipool_label (XEXP (label, 0))))) | ||
| 4492 | + { | ||
| 4493 | + return TRUE; | ||
| 4494 | + } | ||
| 4495 | + } | ||
| 4496 | + break; | ||
| 4497 | + case LABEL_REF: | ||
| 4498 | + if (GET_CODE (XEXP (x, 0)) == CODE_LABEL | ||
| 4499 | + && is_minipool_label (XEXP (x, 0))) | ||
| 4500 | + { | ||
| 4501 | + return TRUE; | ||
| 4502 | + } | ||
| 4503 | + break; | ||
| 4504 | + case SYMBOL_REF: | ||
| 4505 | + { | ||
| 4506 | + if (CONSTANT_POOL_ADDRESS_P (x) | ||
| 4507 | + && !(flag_pic | ||
| 4508 | + && (symbol_mentioned_p (get_pool_constant (x)) | ||
| 4509 | + || label_mentioned_p (get_pool_constant (x))))) | ||
| 4510 | + return TRUE; | ||
| 4511 | + /* | ||
| 4512 | + A symbol_ref is only legal if it is a function. If all of them are | ||
| 4513 | + legal, a pseudo reg that is a constant will be replaced by a | ||
| 4514 | + symbol_ref and make illegale code. SYMBOL_REF_FLAG is set by | ||
| 4515 | + ENCODE_SECTION_INFO. */ | ||
| 4516 | + else if (SYMBOL_REF_RCALL_FUNCTION_P (x)) | ||
| 4517 | + return TRUE; | ||
| 4518 | + break; | ||
| 4519 | + } | ||
| 4520 | + case PRE_DEC: /* (pre_dec (...)) */ | ||
| 4521 | + case POST_INC: /* (post_inc (...)) */ | ||
| 4522 | + return avr32_address_register_rtx_p (XEXP (x, 0), strict); | ||
| 4523 | + case PLUS: /* (plus (...) (...)) */ | ||
| 4524 | + { | ||
| 4525 | + rtx xop0 = XEXP (x, 0); | ||
| 4526 | + rtx xop1 = XEXP (x, 1); | ||
| 4527 | + | ||
| 4528 | + return ((avr32_address_register_rtx_p (xop0, strict) | ||
| 4529 | + && avr32_legitimate_index_p (mode, xop1, strict)) | ||
| 4530 | + || (avr32_address_register_rtx_p (xop1, strict) | ||
| 4531 | + && avr32_legitimate_index_p (mode, xop0, strict))); | ||
| 4532 | + } | ||
| 4533 | + default: | ||
| 4534 | + break; | ||
| 4535 | + } | ||
| 4536 | + | ||
| 4537 | + return FALSE; | ||
| 4538 | +} | ||
| 4539 | + | ||
| 4540 | + | ||
| 4541 | +int | ||
| 4542 | +avr32_const_double_immediate (rtx value) | ||
| 4543 | +{ | ||
| 4544 | + HOST_WIDE_INT hi, lo; | ||
| 4545 | + | ||
| 4546 | + if (GET_CODE (value) != CONST_DOUBLE) | ||
| 4547 | + return FALSE; | ||
| 4548 | + | ||
| 4549 | + if (GET_MODE (value) == DImode) | ||
| 4550 | + { | ||
| 4551 | + hi = CONST_DOUBLE_HIGH (value); | ||
| 4552 | + lo = CONST_DOUBLE_LOW (value); | ||
| 4553 | + } | ||
| 4554 | + else | ||
| 4555 | + { | ||
| 4556 | + HOST_WIDE_INT target_float[2]; | ||
| 4557 | + hi = lo = 0; | ||
| 4558 | + real_to_target (target_float, CONST_DOUBLE_REAL_VALUE (value), | ||
| 4559 | + GET_MODE (value)); | ||
| 4560 | + lo = target_float[0]; | ||
| 4561 | + hi = target_float[1]; | ||
| 4562 | + } | ||
| 4563 | + if (avr32_const_ok_for_constraint_p (lo, 'K', "Ks21") | ||
| 4564 | + && ((GET_MODE (value) == SFmode) | ||
| 4565 | + || avr32_const_ok_for_constraint_p (hi, 'K', "Ks21"))) | ||
| 4566 | + { | ||
| 4567 | + return TRUE; | ||
| 4568 | + } | ||
| 4569 | + | ||
| 4570 | + return FALSE; | ||
| 4571 | +} | ||
| 4572 | + | ||
| 4573 | + | ||
| 4574 | +int | ||
| 4575 | +avr32_legitimate_constant_p (rtx x) | ||
| 4576 | +{ | ||
| 4577 | + switch (GET_CODE (x)) | ||
| 4578 | + { | ||
| 4579 | + case CONST_INT: | ||
| 4580 | + return avr32_const_ok_for_constraint_p (INTVAL (x), 'K', "Ks21"); | ||
| 4581 | + case CONST_DOUBLE: | ||
| 4582 | + if (GET_MODE (x) == SFmode | ||
| 4583 | + || GET_MODE (x) == DFmode || GET_MODE (x) == DImode) | ||
| 4584 | + return avr32_const_double_immediate (x); | ||
| 4585 | + else | ||
| 4586 | + return 0; | ||
| 4587 | + case LABEL_REF: | ||
| 4588 | + return flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS; | ||
| 4589 | + case SYMBOL_REF: | ||
| 4590 | + return flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS; | ||
| 4591 | + case CONST: | ||
| 4592 | + /* We must handle this one in the movsi expansion in order for gcc not | ||
| 4593 | + to put it in the constant pool. */ | ||
| 4594 | + return 0 /* flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS */ ; | ||
| 4595 | + case HIGH: | ||
| 4596 | + case CONST_VECTOR: | ||
| 4597 | + return 0; | ||
| 4598 | + default: | ||
| 4599 | + printf ("%s():\n", __FUNCTION__); | ||
| 4600 | + debug_rtx (x); | ||
| 4601 | + return 1; | ||
| 4602 | + } | ||
| 4603 | +} | ||
| 4604 | + | ||
| 4605 | + | ||
| 4606 | +/* Strip any special encoding from labels */ | ||
| 4607 | +const char * | ||
| 4608 | +avr32_strip_name_encoding (const char *name) | ||
| 4609 | +{ | ||
| 4610 | + const char *stripped = name; | ||
| 4611 | + | ||
| 4612 | + while (1) | ||
| 4613 | + { | ||
| 4614 | + switch (stripped[0]) | ||
| 4615 | + { | ||
| 4616 | + case '#': | ||
| 4617 | + stripped = strchr (name + 1, '#') + 1; | ||
| 4618 | + break; | ||
| 4619 | + case '*': | ||
| 4620 | + stripped = &stripped[1]; | ||
| 4621 | + break; | ||
| 4622 | + default: | ||
| 4623 | + return stripped; | ||
| 4624 | + } | ||
| 4625 | + } | ||
| 4626 | +} | ||
| 4627 | + | ||
| 4628 | + | ||
| 4629 | + | ||
| 4630 | +/* Do anything needed before RTL is emitted for each function. */ | ||
| 4631 | +static struct machine_function * | ||
| 4632 | +avr32_init_machine_status (void) | ||
| 4633 | +{ | ||
| 4634 | + struct machine_function *machine; | ||
| 4635 | + machine = | ||
| 4636 | + (machine_function *) ggc_alloc_cleared (sizeof (machine_function)); | ||
| 4637 | + | ||
| 4638 | +#if AVR32_FT_UNKNOWN != 0 | ||
| 4639 | + machine->func_type = AVR32_FT_UNKNOWN; | ||
| 4640 | +#endif | ||
| 4641 | + | ||
| 4642 | + machine->minipool_label_head = 0; | ||
| 4643 | + machine->minipool_label_tail = 0; | ||
| 4644 | + return machine; | ||
| 4645 | +} | ||
| 4646 | + | ||
| 4647 | +void | ||
| 4648 | +avr32_init_expanders (void) | ||
| 4649 | +{ | ||
| 4650 | + /* Arrange to initialize and mark the machine per-function status. */ | ||
| 4651 | + init_machine_status = avr32_init_machine_status; | ||
| 4652 | +} | ||
| 4653 | + | ||
| 4654 | + | ||
| 4655 | +/* Return an RTX indicating where the return address to the | ||
| 4656 | + calling function can be found. */ | ||
| 4657 | + | ||
| 4658 | +rtx | ||
| 4659 | +avr32_return_addr (int count, rtx frame ATTRIBUTE_UNUSED) | ||
| 4660 | +{ | ||
| 4661 | + if (count != 0) | ||
| 4662 | + return NULL_RTX; | ||
| 4663 | + | ||
| 4664 | + return get_hard_reg_initial_val (Pmode, LR_REGNUM); | ||
| 4665 | +} | ||
| 4666 | + | ||
| 4667 | + | ||
| 4668 | +void | ||
| 4669 | +avr32_encode_section_info (tree decl, rtx rtl, int first) | ||
| 4670 | +{ | ||
| 4671 | + | ||
| 4672 | + if (first && DECL_P (decl)) | ||
| 4673 | + { | ||
| 4674 | + /* Set SYMBOL_REG_FLAG for local functions */ | ||
| 4675 | + if (!TREE_PUBLIC (decl) && TREE_CODE (decl) == FUNCTION_DECL) | ||
| 4676 | + { | ||
| 4677 | + if ((*targetm.binds_local_p) (decl)) | ||
| 4678 | + { | ||
| 4679 | + SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1; | ||
| 4680 | + } | ||
| 4681 | + } | ||
| 4682 | + } | ||
| 4683 | +} | ||
| 4684 | + | ||
| 4685 | + | ||
| 4686 | +void | ||
| 4687 | +avr32_asm_output_ascii (FILE * stream, char *ptr, int len) | ||
| 4688 | +{ | ||
| 4689 | + int i, i_new = 0; | ||
| 4690 | + char *new_ptr = xmalloc (4 * len); | ||
| 4691 | + if (new_ptr == NULL) | ||
| 4692 | + internal_error ("Out of memory."); | ||
| 4693 | + | ||
| 4694 | + for (i = 0; i < len; i++) | ||
| 4695 | + { | ||
| 4696 | + if (ptr[i] == '\n') | ||
| 4697 | + { | ||
| 4698 | + new_ptr[i_new++] = '\\'; | ||
| 4699 | + new_ptr[i_new++] = '0'; | ||
| 4700 | + new_ptr[i_new++] = '1'; | ||
| 4701 | + new_ptr[i_new++] = '2'; | ||
| 4702 | + } | ||
| 4703 | + else if (ptr[i] == '\"') | ||
| 4704 | + { | ||
| 4705 | + new_ptr[i_new++] = '\\'; | ||
| 4706 | + new_ptr[i_new++] = '\"'; | ||
| 4707 | + } | ||
| 4708 | + else if (ptr[i] == '\\') | ||
| 4709 | + { | ||
| 4710 | + new_ptr[i_new++] = '\\'; | ||
| 4711 | + new_ptr[i_new++] = '\\'; | ||
| 4712 | + } | ||
| 4713 | + else if (ptr[i] == '\0' && i + 1 < len) | ||
| 4714 | + { | ||
| 4715 | + new_ptr[i_new++] = '\\'; | ||
| 4716 | + new_ptr[i_new++] = '0'; | ||
| 4717 | + } | ||
| 4718 | + else | ||
| 4719 | + { | ||
| 4720 | + new_ptr[i_new++] = ptr[i]; | ||
| 4721 | + } | ||
| 4722 | + } | ||
| 4723 | + | ||
| 4724 | + /* Terminate new_ptr. */ | ||
| 4725 | + new_ptr[i_new] = '\0'; | ||
| 4726 | + fprintf (stream, "\t.ascii\t\"%s\"\n", new_ptr); | ||
| 4727 | + free (new_ptr); | ||
| 4728 | +} | ||
| 4729 | + | ||
| 4730 | + | ||
| 4731 | +void | ||
| 4732 | +avr32_asm_output_label (FILE * stream, const char *name) | ||
| 4733 | +{ | ||
| 4734 | + name = avr32_strip_name_encoding (name); | ||
| 4735 | + | ||
| 4736 | + /* Print the label. */ | ||
| 4737 | + assemble_name (stream, name); | ||
| 4738 | + fprintf (stream, ":\n"); | ||
| 4739 | +} | ||
| 4740 | + | ||
| 4741 | + | ||
| 4742 | + | ||
| 4743 | +void | ||
| 4744 | +avr32_asm_weaken_label (FILE * stream, const char *name) | ||
| 4745 | +{ | ||
| 4746 | + fprintf (stream, "\t.weak "); | ||
| 4747 | + assemble_name (stream, name); | ||
| 4748 | + fprintf (stream, "\n"); | ||
| 4749 | +} | ||
| 4750 | + | ||
| 4751 | +/* | ||
| 4752 | + Checks if a labelref is equal to a reserved word in the assembler. If it is, | ||
| 4753 | + insert a '_' before the label name. | ||
| 4754 | +*/ | ||
| 4755 | +void | ||
| 4756 | +avr32_asm_output_labelref (FILE * stream, const char *name) | ||
| 4757 | +{ | ||
| 4758 | + int verbatim = FALSE; | ||
| 4759 | + const char *stripped = name; | ||
| 4760 | + int strip_finished = FALSE; | ||
| 4761 | + | ||
| 4762 | + while (!strip_finished) | ||
| 4763 | + { | ||
| 4764 | + switch (stripped[0]) | ||
| 4765 | + { | ||
| 4766 | + case '#': | ||
| 4767 | + stripped = strchr (name + 1, '#') + 1; | ||
| 4768 | + break; | ||
| 4769 | + case '*': | ||
| 4770 | + stripped = &stripped[1]; | ||
| 4771 | + verbatim = TRUE; | ||
| 4772 | + break; | ||
| 4773 | + default: | ||
| 4774 | + strip_finished = TRUE; | ||
| 4775 | + break; | ||
| 4776 | + } | ||
| 4777 | + } | ||
| 4778 | + | ||
| 4779 | + if (verbatim) | ||
| 4780 | + fputs (stripped, stream); | ||
| 4781 | + else | ||
| 4782 | + asm_fprintf (stream, "%U%s", stripped); | ||
| 4783 | +} | ||
| 4784 | + | ||
| 4785 | + | ||
| 4786 | + | ||
| 4787 | +/* | ||
| 4788 | + Check if the comparison in compare_exp is redundant | ||
| 4789 | + for the condition given in next_cond given that the | ||
| 4790 | + needed flags are already set by an earlier instruction. | ||
| 4791 | + Uses cc_prev_status to check this. | ||
| 4792 | + | ||
| 4793 | + Returns NULL_RTX if the compare is not redundant | ||
| 4794 | + or the new condition to use in the conditional | ||
| 4795 | + instruction if the compare is redundant. | ||
| 4796 | +*/ | ||
| 4797 | +static rtx | ||
| 4798 | +is_compare_redundant (rtx compare_exp, rtx next_cond) | ||
| 4799 | +{ | ||
| 4800 | + int z_flag_valid = FALSE; | ||
| 4801 | + int n_flag_valid = FALSE; | ||
| 4802 | + rtx new_cond; | ||
| 4803 | + | ||
| 4804 | + if (GET_CODE (compare_exp) != COMPARE) | ||
| 4805 | + return NULL_RTX; | ||
| 4806 | + | ||
| 4807 | + | ||
| 4808 | + if (GET_MODE (compare_exp) != SImode) | ||
| 4809 | + return NULL_RTX; | ||
| 4810 | + | ||
| 4811 | + if (rtx_equal_p (cc_prev_status.mdep.value, compare_exp)) | ||
| 4812 | + { | ||
| 4813 | + /* cc0 already contains the correct comparison -> delete cmp insn */ | ||
| 4814 | + return next_cond; | ||
| 4815 | + } | ||
| 4816 | + | ||
| 4817 | + switch (cc_prev_status.mdep.flags) | ||
| 4818 | + { | ||
| 4819 | + case CC_SET_VNCZ: | ||
| 4820 | + case CC_SET_NCZ: | ||
| 4821 | + n_flag_valid = TRUE; | ||
| 4822 | + case CC_SET_CZ: | ||
| 4823 | + case CC_SET_Z: | ||
| 4824 | + z_flag_valid = TRUE; | ||
| 4825 | + } | ||
| 4826 | + | ||
| 4827 | + if (cc_prev_status.mdep.value | ||
| 4828 | + && REG_P (XEXP (compare_exp, 0)) | ||
| 4829 | + && REGNO (XEXP (compare_exp, 0)) == REGNO (cc_prev_status.mdep.value) | ||
| 4830 | + && GET_CODE (XEXP (compare_exp, 1)) == CONST_INT | ||
| 4831 | + && next_cond != NULL_RTX) | ||
| 4832 | + { | ||
| 4833 | + if (INTVAL (XEXP (compare_exp, 1)) == 0 | ||
| 4834 | + && z_flag_valid | ||
| 4835 | + && (GET_CODE (next_cond) == EQ || GET_CODE (next_cond) == NE)) | ||
| 4836 | + /* We can skip comparison Z flag is already reflecting ops[0] */ | ||
| 4837 | + return next_cond; | ||
| 4838 | + else if (n_flag_valid | ||
| 4839 | + && ((INTVAL (XEXP (compare_exp, 1)) == 0 | ||
| 4840 | + && (GET_CODE (next_cond) == GE | ||
| 4841 | + || GET_CODE (next_cond) == LT)) | ||
| 4842 | + || (INTVAL (XEXP (compare_exp, 1)) == -1 | ||
| 4843 | + && (GET_CODE (next_cond) == GT | ||
| 4844 | + || GET_CODE (next_cond) == LE)))) | ||
| 4845 | + { | ||
| 4846 | + /* We can skip comparison N flag is already reflecting ops[0], | ||
| 4847 | + which means that we can use the mi/pl conditions to check if | ||
| 4848 | + ops[0] is GE or LT 0. */ | ||
| 4849 | + if ((GET_CODE (next_cond) == GE) || (GET_CODE (next_cond) == GT)) | ||
| 4850 | + new_cond = | ||
| 4851 | + gen_rtx_UNSPEC (CCmode, gen_rtvec (2, cc0_rtx, const0_rtx), | ||
| 4852 | + UNSPEC_COND_PL); | ||
| 4853 | + else | ||
| 4854 | + new_cond = | ||
| 4855 | + gen_rtx_UNSPEC (CCmode, gen_rtvec (2, cc0_rtx, const0_rtx), | ||
| 4856 | + UNSPEC_COND_MI); | ||
| 4857 | + return new_cond; | ||
| 4858 | + } | ||
| 4859 | + } | ||
| 4860 | + return NULL_RTX; | ||
| 4861 | +} | ||
| 4862 | + | ||
| 4863 | +/* Updates cc_status. */ | ||
| 4864 | +void | ||
| 4865 | +avr32_notice_update_cc (rtx exp, rtx insn) | ||
| 4866 | +{ | ||
| 4867 | + switch (get_attr_cc (insn)) | ||
| 4868 | + { | ||
| 4869 | + case CC_CALL_SET: | ||
| 4870 | + CC_STATUS_INIT; | ||
| 4871 | + FPCC_STATUS_INIT; | ||
| 4872 | + /* Check if the function call returns a value in r12 */ | ||
| 4873 | + if (REG_P (recog_data.operand[0]) | ||
| 4874 | + && REGNO (recog_data.operand[0]) == RETVAL_REGNUM) | ||
| 4875 | + { | ||
| 4876 | + cc_status.flags = 0; | ||
| 4877 | + cc_status.mdep.value = | ||
| 4878 | + gen_rtx_COMPARE (SImode, recog_data.operand[0], const0_rtx); | ||
| 4879 | + cc_status.mdep.flags = CC_SET_VNCZ; | ||
| 4880 | + | ||
| 4881 | + } | ||
| 4882 | + break; | ||
| 4883 | + case CC_COMPARE: | ||
| 4884 | + /* Check that compare will not be optimized away if so nothing should | ||
| 4885 | + be done */ | ||
| 4886 | + if (is_compare_redundant (SET_SRC (exp), get_next_insn_cond (insn)) | ||
| 4887 | + == NULL_RTX) | ||
| 4888 | + { | ||
| 4889 | + | ||
| 4890 | + /* Reset the nonstandard flag */ | ||
| 4891 | + CC_STATUS_INIT; | ||
| 4892 | + cc_status.flags = 0; | ||
| 4893 | + cc_status.mdep.value = SET_SRC (exp); | ||
| 4894 | + cc_status.mdep.flags = CC_SET_VNCZ; | ||
| 4895 | + } | ||
| 4896 | + break; | ||
| 4897 | + case CC_FPCOMPARE: | ||
| 4898 | + /* Check that floating-point compare will not be optimized away if so | ||
| 4899 | + nothing should be done */ | ||
| 4900 | + if (!rtx_equal_p (cc_prev_status.mdep.fpvalue, SET_SRC (exp))) | ||
| 4901 | + { | ||
| 4902 | + /* cc0 already contains the correct comparison -> delete cmp insn */ | ||
| 4903 | + /* Reset the nonstandard flag */ | ||
| 4904 | + cc_status.mdep.fpvalue = SET_SRC (exp); | ||
| 4905 | + cc_status.mdep.fpflags = CC_SET_CZ; | ||
| 4906 | + } | ||
| 4907 | + break; | ||
| 4908 | + case CC_FROM_FPCC: | ||
| 4909 | + /* Flags are updated with flags from Floating-point coprocessor, set | ||
| 4910 | + CC_NOT_SIGNED flag since the flags are set so that unsigned | ||
| 4911 | + condidion codes can be used directly. */ | ||
| 4912 | + CC_STATUS_INIT; | ||
| 4913 | + cc_status.flags = CC_NOT_SIGNED; | ||
| 4914 | + cc_status.mdep.value = cc_status.mdep.fpvalue; | ||
| 4915 | + cc_status.mdep.flags = cc_status.mdep.fpflags; | ||
| 4916 | + break; | ||
| 4917 | + case CC_BLD: | ||
| 4918 | + /* Bit load is kind of like an inverted testsi, because the Z flag is | ||
| 4919 | + inverted */ | ||
| 4920 | + CC_STATUS_INIT; | ||
| 4921 | + cc_status.flags = CC_INVERTED; | ||
| 4922 | + cc_status.mdep.value = SET_SRC (exp); | ||
| 4923 | + cc_status.mdep.flags = CC_SET_Z; | ||
| 4924 | + break; | ||
| 4925 | + case CC_NONE: | ||
| 4926 | + /* Insn does not affect CC at all. Check if the instruction updates | ||
| 4927 | + some of the register currently reflected in cc0 */ | ||
| 4928 | + | ||
| 4929 | + if ((GET_CODE (exp) == SET) | ||
| 4930 | + && (cc_status.value1 || cc_status.value2 || cc_status.mdep.value) | ||
| 4931 | + && (reg_mentioned_p (SET_DEST (exp), cc_status.value1) | ||
| 4932 | + || reg_mentioned_p (SET_DEST (exp), cc_status.value2) | ||
| 4933 | + || reg_mentioned_p (SET_DEST (exp), cc_status.mdep.value))) | ||
| 4934 | + { | ||
| 4935 | + CC_STATUS_INIT; | ||
| 4936 | + } | ||
| 4937 | + | ||
| 4938 | + /* If this is a parallel we must step through each of the parallel | ||
| 4939 | + expressions */ | ||
| 4940 | + if (GET_CODE (exp) == PARALLEL) | ||
| 4941 | + { | ||
| 4942 | + int i; | ||
| 4943 | + for (i = 0; i < XVECLEN (exp, 0); ++i) | ||
| 4944 | + { | ||
| 4945 | + rtx vec_exp = XVECEXP (exp, 0, i); | ||
| 4946 | + if ((GET_CODE (vec_exp) == SET) | ||
| 4947 | + && (cc_status.value1 || cc_status.value2 | ||
| 4948 | + || cc_status.mdep.value) | ||
| 4949 | + && (reg_mentioned_p (SET_DEST (vec_exp), cc_status.value1) | ||
| 4950 | + || reg_mentioned_p (SET_DEST (vec_exp), | ||
| 4951 | + cc_status.value2) | ||
| 4952 | + || reg_mentioned_p (SET_DEST (vec_exp), | ||
| 4953 | + cc_status.mdep.value))) | ||
| 4954 | + { | ||
| 4955 | + CC_STATUS_INIT; | ||
| 4956 | + } | ||
| 4957 | + } | ||
| 4958 | + } | ||
| 4959 | + | ||
| 4960 | + /* Check if we have memory opartions with post_inc or pre_dec on the | ||
| 4961 | + register currently reflected in cc0 */ | ||
| 4962 | + if (GET_CODE (exp) == SET | ||
| 4963 | + && GET_CODE (SET_SRC (exp)) == MEM | ||
| 4964 | + && (GET_CODE (XEXP (SET_SRC (exp), 0)) == POST_INC | ||
| 4965 | + || GET_CODE (XEXP (SET_SRC (exp), 0)) == PRE_DEC) | ||
| 4966 | + && | ||
| 4967 | + (reg_mentioned_p | ||
| 4968 | + (XEXP (XEXP (SET_SRC (exp), 0), 0), cc_status.value1) | ||
| 4969 | + || reg_mentioned_p (XEXP (XEXP (SET_SRC (exp), 0), 0), | ||
| 4970 | + cc_status.value2) | ||
| 4971 | + || reg_mentioned_p (XEXP (XEXP (SET_SRC (exp), 0), 0), | ||
| 4972 | + cc_status.mdep.value))) | ||
| 4973 | + CC_STATUS_INIT; | ||
| 4974 | + | ||
| 4975 | + if (GET_CODE (exp) == SET | ||
| 4976 | + && GET_CODE (SET_DEST (exp)) == MEM | ||
| 4977 | + && (GET_CODE (XEXP (SET_DEST (exp), 0)) == POST_INC | ||
| 4978 | + || GET_CODE (XEXP (SET_DEST (exp), 0)) == PRE_DEC) | ||
| 4979 | + && | ||
| 4980 | + (reg_mentioned_p | ||
| 4981 | + (XEXP (XEXP (SET_DEST (exp), 0), 0), cc_status.value1) | ||
| 4982 | + || reg_mentioned_p (XEXP (XEXP (SET_DEST (exp), 0), 0), | ||
| 4983 | + cc_status.value2) | ||
| 4984 | + || reg_mentioned_p (XEXP (XEXP (SET_DEST (exp), 0), 0), | ||
| 4985 | + cc_status.mdep.value))) | ||
| 4986 | + CC_STATUS_INIT; | ||
| 4987 | + break; | ||
| 4988 | + | ||
| 4989 | + case CC_SET_VNCZ: | ||
| 4990 | + CC_STATUS_INIT; | ||
| 4991 | + cc_status.mdep.value = recog_data.operand[0]; | ||
| 4992 | + cc_status.mdep.flags = CC_SET_VNCZ; | ||
| 4993 | + break; | ||
| 4994 | + | ||
| 4995 | + case CC_SET_NCZ: | ||
| 4996 | + CC_STATUS_INIT; | ||
| 4997 | + cc_status.mdep.value = recog_data.operand[0]; | ||
| 4998 | + cc_status.mdep.flags = CC_SET_NCZ; | ||
| 4999 | + break; | ||
| 5000 | + | ||
| 5001 | + case CC_SET_CZ: | ||
| 5002 | + CC_STATUS_INIT; | ||
| 5003 | + cc_status.mdep.value = recog_data.operand[0]; | ||
| 5004 | + cc_status.mdep.flags = CC_SET_CZ; | ||
| 5005 | + break; | ||
| 5006 | + | ||
| 5007 | + case CC_SET_Z: | ||
| 5008 | + CC_STATUS_INIT; | ||
| 5009 | + cc_status.mdep.value = recog_data.operand[0]; | ||
| 5010 | + cc_status.mdep.flags = CC_SET_Z; | ||
| 5011 | + break; | ||
| 5012 | + | ||
| 5013 | + case CC_CLOBBER: | ||
| 5014 | + CC_STATUS_INIT; | ||
| 5015 | + break; | ||
| 5016 | + | ||
| 5017 | + default: | ||
| 5018 | + CC_STATUS_INIT; | ||
| 5019 | + } | ||
| 5020 | +} | ||
| 5021 | + | ||
| 5022 | + | ||
| 5023 | +/* | ||
| 5024 | + Outputs to stdio stream stream the assembler syntax for an instruction | ||
| 5025 | + operand x. x is an RTL expression. | ||
| 5026 | +*/ | ||
| 5027 | +void | ||
| 5028 | +avr32_print_operand (FILE * stream, rtx x, int code) | ||
| 5029 | +{ | ||
| 5030 | + int error = 0; | ||
| 5031 | + | ||
| 5032 | + switch (GET_CODE (x)) | ||
| 5033 | + { | ||
| 5034 | + case UNSPEC: | ||
| 5035 | + switch (XINT (x, 1)) | ||
| 5036 | + { | ||
| 5037 | + case UNSPEC_COND_PL: | ||
| 5038 | + if (code == 'i') | ||
| 5039 | + fputs ("mi", stream); | ||
| 5040 | + else | ||
| 5041 | + fputs ("pl", stream); | ||
| 5042 | + break; | ||
| 5043 | + case UNSPEC_COND_MI: | ||
| 5044 | + if (code == 'i') | ||
| 5045 | + fputs ("pl", stream); | ||
| 5046 | + else | ||
| 5047 | + fputs ("mi", stream); | ||
| 5048 | + break; | ||
| 5049 | + default: | ||
| 5050 | + error = 1; | ||
| 5051 | + } | ||
| 5052 | + break; | ||
| 5053 | + case EQ: | ||
| 5054 | + if (code == 'i') | ||
| 5055 | + fputs ("ne", stream); | ||
| 5056 | + else | ||
| 5057 | + fputs ("eq", stream); | ||
| 5058 | + break; | ||
| 5059 | + case NE: | ||
| 5060 | + if (code == 'i') | ||
| 5061 | + fputs ("eq", stream); | ||
| 5062 | + else | ||
| 5063 | + fputs ("ne", stream); | ||
| 5064 | + break; | ||
| 5065 | + case GT: | ||
| 5066 | + if (code == 'i') | ||
| 5067 | + fputs ("le", stream); | ||
| 5068 | + else | ||
| 5069 | + fputs ("gt", stream); | ||
| 5070 | + break; | ||
| 5071 | + case GTU: | ||
| 5072 | + if (code == 'i') | ||
| 5073 | + fputs ("ls", stream); | ||
| 5074 | + else | ||
| 5075 | + fputs ("hi", stream); | ||
| 5076 | + break; | ||
| 5077 | + case LT: | ||
| 5078 | + if (code == 'i') | ||
| 5079 | + fputs ("ge", stream); | ||
| 5080 | + else | ||
| 5081 | + fputs ("lt", stream); | ||
| 5082 | + break; | ||
| 5083 | + case LTU: | ||
| 5084 | + if (code == 'i') | ||
| 5085 | + fputs ("hs", stream); | ||
| 5086 | + else | ||
| 5087 | + fputs ("lo", stream); | ||
| 5088 | + break; | ||
| 5089 | + case GE: | ||
| 5090 | + if (code == 'i') | ||
| 5091 | + fputs ("lt", stream); | ||
| 5092 | + else | ||
| 5093 | + fputs ("ge", stream); | ||
| 5094 | + break; | ||
| 5095 | + case GEU: | ||
| 5096 | + if (code == 'i') | ||
| 5097 | + fputs ("lo", stream); | ||
| 5098 | + else | ||
| 5099 | + fputs ("hs", stream); | ||
| 5100 | + break; | ||
| 5101 | + case LE: | ||
| 5102 | + if (code == 'i') | ||
| 5103 | + fputs ("gt", stream); | ||
| 5104 | + else | ||
| 5105 | + fputs ("le", stream); | ||
| 5106 | + break; | ||
| 5107 | + case LEU: | ||
| 5108 | + if (code == 'i') | ||
| 5109 | + fputs ("hi", stream); | ||
| 5110 | + else | ||
| 5111 | + fputs ("ls", stream); | ||
| 5112 | + break; | ||
| 5113 | + case CONST_INT: | ||
| 5114 | + { | ||
| 5115 | + int value = INTVAL (x); | ||
| 5116 | + | ||
| 5117 | + if (code == 'i') | ||
| 5118 | + { | ||
| 5119 | + value++; | ||
| 5120 | + } | ||
| 5121 | + | ||
| 5122 | + if (code == 'p') | ||
| 5123 | + { | ||
| 5124 | + /* Set to bit position of first bit set in immediate */ | ||
| 5125 | + int i, bitpos = 32; | ||
| 5126 | + for (i = 0; i < 32; i++) | ||
| 5127 | + if (value & (1 << i)) | ||
| 5128 | + { | ||
| 5129 | + bitpos = i; | ||
| 5130 | + break; | ||
| 5131 | + } | ||
| 5132 | + value = bitpos; | ||
| 5133 | + } | ||
| 5134 | + | ||
| 5135 | + if (code == 'r') | ||
| 5136 | + { | ||
| 5137 | + /* Reglist 8 */ | ||
| 5138 | + char op[50]; | ||
| 5139 | + op[0] = '\0'; | ||
| 5140 | + | ||
| 5141 | + if (value & 0x01) | ||
| 5142 | + sprintf (op, "r0-r3"); | ||
| 5143 | + if (value & 0x02) | ||
| 5144 | + strlen (op) ? sprintf (op, "%s, r4-r7", op) : sprintf (op, | ||
| 5145 | + "r4-r7"); | ||
| 5146 | + if (value & 0x04) | ||
| 5147 | + strlen (op) ? sprintf (op, "%s, r8-r9", op) : sprintf (op, | ||
| 5148 | + "r8-r9"); | ||
| 5149 | + if (value & 0x08) | ||
| 5150 | + strlen (op) ? sprintf (op, "%s, r10", op) : sprintf (op, "r10"); | ||
| 5151 | + if (value & 0x10) | ||
| 5152 | + strlen (op) ? sprintf (op, "%s, r11", op) : sprintf (op, "r11"); | ||
| 5153 | + if (value & 0x20) | ||
| 5154 | + strlen (op) ? sprintf (op, "%s, r12", op) : sprintf (op, "r12"); | ||
| 5155 | + if (value & 0x40) | ||
| 5156 | + strlen (op) ? sprintf (op, "%s, lr", op) : sprintf (op, "lr"); | ||
| 5157 | + if (value & 0x80) | ||
| 5158 | + strlen (op) ? sprintf (op, "%s, pc", op) : sprintf (op, "pc"); | ||
| 5159 | + | ||
| 5160 | + fputs (op, stream); | ||
| 5161 | + } | ||
| 5162 | + else if (code == 's') | ||
| 5163 | + { | ||
| 5164 | + /* Reglist 16 */ | ||
| 5165 | + char reglist16_string[100]; | ||
| 5166 | + int i; | ||
| 5167 | + reglist16_string[0] = '\0'; | ||
| 5168 | + | ||
| 5169 | + for (i = 0; i < 16; ++i) | ||
| 5170 | + { | ||
| 5171 | + if (value & (1 << i)) | ||
| 5172 | + { | ||
| 5173 | + strlen (reglist16_string) ? sprintf (reglist16_string, | ||
| 5174 | + "%s, %s", | ||
| 5175 | + reglist16_string, | ||
| 5176 | + reg_names | ||
| 5177 | + [INTERNAL_REGNUM | ||
| 5178 | + (i)]) : | ||
| 5179 | + sprintf (reglist16_string, "%s", | ||
| 5180 | + reg_names[INTERNAL_REGNUM (i)]); | ||
| 5181 | + } | ||
| 5182 | + } | ||
| 5183 | + fputs (reglist16_string, stream); | ||
| 5184 | + } | ||
| 5185 | + else if (code == 'C') | ||
| 5186 | + { | ||
| 5187 | + /* RegListCP8 */ | ||
| 5188 | + char reglist_string[100]; | ||
| 5189 | + avr32_make_fp_reglist_w (value, (char *) reglist_string); | ||
| 5190 | + fputs (reglist_string, stream); | ||
| 5191 | + } | ||
| 5192 | + else if (code == 'D') | ||
| 5193 | + { | ||
| 5194 | + /* RegListCPD8 */ | ||
| 5195 | + char reglist_string[100]; | ||
| 5196 | + avr32_make_fp_reglist_d (value, (char *) reglist_string); | ||
| 5197 | + fputs (reglist_string, stream); | ||
| 5198 | + } | ||
| 5199 | + else if (code == 'd') | ||
| 5200 | + { | ||
| 5201 | + /* Print in decimal format */ | ||
| 5202 | + fprintf (stream, "%d", value); | ||
| 5203 | + } | ||
| 5204 | + else if (code == 'h') | ||
| 5205 | + { | ||
| 5206 | + /* Print halfword part of word */ | ||
| 5207 | + fputs (value ? "b" : "t", stream); | ||
| 5208 | + } | ||
| 5209 | + else | ||
| 5210 | + { | ||
| 5211 | + /* Normal constant */ | ||
| 5212 | + fprintf (stream, "%d", value); | ||
| 5213 | + } | ||
| 5214 | + break; | ||
| 5215 | + } | ||
| 5216 | + case CONST_DOUBLE: | ||
| 5217 | + { | ||
| 5218 | + HOST_WIDE_INT hi, lo; | ||
| 5219 | + if (GET_MODE (x) == DImode) | ||
| 5220 | + { | ||
| 5221 | + hi = CONST_DOUBLE_HIGH (x); | ||
| 5222 | + lo = CONST_DOUBLE_LOW (x); | ||
| 5223 | + } | ||
| 5224 | + else | ||
| 5225 | + { | ||
| 5226 | + HOST_WIDE_INT target_float[2]; | ||
| 5227 | + hi = lo = 0; | ||
| 5228 | + real_to_target (target_float, CONST_DOUBLE_REAL_VALUE (x), | ||
| 5229 | + GET_MODE (x)); | ||
| 5230 | + /* For doubles the most significant part starts at index 0. */ | ||
| 5231 | + if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) | ||
| 5232 | + { | ||
| 5233 | + hi = target_float[0]; | ||
| 5234 | + lo = target_float[1]; | ||
| 5235 | + } | ||
| 5236 | + else | ||
| 5237 | + { | ||
| 5238 | + lo = target_float[0]; | ||
| 5239 | + } | ||
| 5240 | + } | ||
| 5241 | + | ||
| 5242 | + if (avr32_const_ok_for_constraint_p (lo, 'K', "Ks21") | ||
| 5243 | + && ((GET_MODE (x) == SFmode) | ||
| 5244 | + || avr32_const_ok_for_constraint_p (hi, 'K', "Ks21"))) | ||
| 5245 | + { | ||
| 5246 | + if (code == 'm') | ||
| 5247 | + fprintf (stream, "%ld", hi); | ||
| 5248 | + else | ||
| 5249 | + fprintf (stream, "%ld", lo); | ||
| 5250 | + } | ||
| 5251 | + else | ||
| 5252 | + { | ||
| 5253 | + fprintf (stream, "value too large"); | ||
| 5254 | + } | ||
| 5255 | + break; | ||
| 5256 | + } | ||
| 5257 | + case CONST: | ||
| 5258 | + output_addr_const (stream, XEXP (XEXP (x, 0), 0)); | ||
| 5259 | + fprintf (stream, "+%ld", INTVAL (XEXP (XEXP (x, 0), 1))); | ||
| 5260 | + break; | ||
| 5261 | + case REG: | ||
| 5262 | + /* Swap register name if the register is DImode or DFmode. */ | ||
| 5263 | + if (GET_MODE (x) == DImode || GET_MODE (x) == DFmode) | ||
| 5264 | + { | ||
| 5265 | + /* Double register must have an even numbered address */ | ||
| 5266 | + gcc_assert (!(REGNO (x) % 2)); | ||
| 5267 | + if (code == 'm') | ||
| 5268 | + fputs (reg_names[true_regnum (x)], stream); | ||
| 5269 | + else | ||
| 5270 | + fputs (reg_names[true_regnum (x) + 1], stream); | ||
| 5271 | + } | ||
| 5272 | + else if (GET_MODE (x) == TImode) | ||
| 5273 | + { | ||
| 5274 | + switch (code) | ||
| 5275 | + { | ||
| 5276 | + case 'T': | ||
| 5277 | + fputs (reg_names[true_regnum (x)], stream); | ||
| 5278 | + break; | ||
| 5279 | + case 'U': | ||
| 5280 | + fputs (reg_names[true_regnum (x) + 1], stream); | ||
| 5281 | + break; | ||
| 5282 | + case 'L': | ||
| 5283 | + fputs (reg_names[true_regnum (x) + 2], stream); | ||
| 5284 | + break; | ||
| 5285 | + case 'B': | ||
| 5286 | + fputs (reg_names[true_regnum (x) + 3], stream); | ||
| 5287 | + break; | ||
| 5288 | + default: | ||
| 5289 | + fprintf (stream, "%s, %s, %s, %s", | ||
| 5290 | + reg_names[true_regnum (x) + 3], | ||
| 5291 | + reg_names[true_regnum (x) + 2], | ||
| 5292 | + reg_names[true_regnum (x) + 1], | ||
| 5293 | + reg_names[true_regnum (x)]); | ||
| 5294 | + break; | ||
| 5295 | + } | ||
| 5296 | + } | ||
| 5297 | + else | ||
| 5298 | + { | ||
| 5299 | + fputs (reg_names[true_regnum (x)], stream); | ||
| 5300 | + } | ||
| 5301 | + break; | ||
| 5302 | + case CODE_LABEL: | ||
| 5303 | + case LABEL_REF: | ||
| 5304 | + case SYMBOL_REF: | ||
| 5305 | + output_addr_const (stream, x); | ||
| 5306 | + break; | ||
| 5307 | + case MEM: | ||
| 5308 | + switch (GET_CODE (XEXP (x, 0))) | ||
| 5309 | + { | ||
| 5310 | + case LABEL_REF: | ||
| 5311 | + case SYMBOL_REF: | ||
| 5312 | + output_addr_const (stream, XEXP (x, 0)); | ||
| 5313 | + break; | ||
| 5314 | + case MEM: | ||
| 5315 | + switch (GET_CODE (XEXP (XEXP (x, 0), 0))) | ||
| 5316 | + { | ||
| 5317 | + case SYMBOL_REF: | ||
| 5318 | + output_addr_const (stream, XEXP (XEXP (x, 0), 0)); | ||
| 5319 | + break; | ||
| 5320 | + default: | ||
| 5321 | + error = 1; | ||
| 5322 | + break; | ||
| 5323 | + } | ||
| 5324 | + break; | ||
| 5325 | + case REG: | ||
| 5326 | + avr32_print_operand (stream, XEXP (x, 0), 0); | ||
| 5327 | + if (code != 'p') | ||
| 5328 | + fputs ("[0]", stream); | ||
| 5329 | + break; | ||
| 5330 | + case PRE_DEC: | ||
| 5331 | + fputs ("--", stream); | ||
| 5332 | + avr32_print_operand (stream, XEXP (XEXP (x, 0), 0), 0); | ||
| 5333 | + break; | ||
| 5334 | + case POST_INC: | ||
| 5335 | + avr32_print_operand (stream, XEXP (XEXP (x, 0), 0), 0); | ||
| 5336 | + fputs ("++", stream); | ||
| 5337 | + break; | ||
| 5338 | + case PLUS: | ||
| 5339 | + { | ||
| 5340 | + rtx op0 = XEXP (XEXP (x, 0), 0); | ||
| 5341 | + rtx op1 = XEXP (XEXP (x, 0), 1); | ||
| 5342 | + rtx base = NULL_RTX, offset = NULL_RTX; | ||
| 5343 | + | ||
| 5344 | + if (avr32_address_register_rtx_p (op0, 1)) | ||
| 5345 | + { | ||
| 5346 | + base = op0; | ||
| 5347 | + offset = op1; | ||
| 5348 | + } | ||
| 5349 | + else if (avr32_address_register_rtx_p (op1, 1)) | ||
| 5350 | + { | ||
| 5351 | + /* Operands are switched. */ | ||
| 5352 | + base = op1; | ||
| 5353 | + offset = op0; | ||
| 5354 | + } | ||
| 5355 | + | ||
| 5356 | + gcc_assert (base && offset | ||
| 5357 | + && avr32_address_register_rtx_p (base, 1) | ||
| 5358 | + && avr32_legitimate_index_p (GET_MODE (x), offset, | ||
| 5359 | + 1)); | ||
| 5360 | + | ||
| 5361 | + avr32_print_operand (stream, base, 0); | ||
| 5362 | + fputs ("[", stream); | ||
| 5363 | + avr32_print_operand (stream, offset, 0); | ||
| 5364 | + fputs ("]", stream); | ||
| 5365 | + break; | ||
| 5366 | + } | ||
| 5367 | + case CONST: | ||
| 5368 | + output_addr_const (stream, XEXP (XEXP (XEXP (x, 0), 0), 0)); | ||
| 5369 | + fprintf (stream, " + %ld", | ||
| 5370 | + INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))); | ||
| 5371 | + break; | ||
| 5372 | + default: | ||
| 5373 | + error = 1; | ||
| 5374 | + } | ||
| 5375 | + break; | ||
| 5376 | + case MULT: | ||
| 5377 | + { | ||
| 5378 | + int value = INTVAL (XEXP (x, 1)); | ||
| 5379 | + | ||
| 5380 | + /* Convert immediate in multiplication into a shift immediate */ | ||
| 5381 | + switch (value) | ||
| 5382 | + { | ||
| 5383 | + case 2: | ||
| 5384 | + value = 1; | ||
| 5385 | + break; | ||
| 5386 | + case 4: | ||
| 5387 | + value = 2; | ||
| 5388 | + break; | ||
| 5389 | + case 8: | ||
| 5390 | + value = 3; | ||
| 5391 | + break; | ||
| 5392 | + default: | ||
| 5393 | + value = 0; | ||
| 5394 | + } | ||
| 5395 | + fprintf (stream, "%s << %i", reg_names[true_regnum (XEXP (x, 0))], | ||
| 5396 | + value); | ||
| 5397 | + break; | ||
| 5398 | + } | ||
| 5399 | + case ASHIFT: | ||
| 5400 | + if (GET_CODE (XEXP (x, 1)) == CONST_INT) | ||
| 5401 | + fprintf (stream, "%s << %i", reg_names[true_regnum (XEXP (x, 0))], | ||
| 5402 | + (int) INTVAL (XEXP (x, 1))); | ||
| 5403 | + else if (REG_P (XEXP (x, 1))) | ||
| 5404 | + fprintf (stream, "%s << %s", reg_names[true_regnum (XEXP (x, 0))], | ||
| 5405 | + reg_names[true_regnum (XEXP (x, 1))]); | ||
| 5406 | + else | ||
| 5407 | + { | ||
| 5408 | + error = 1; | ||
| 5409 | + } | ||
| 5410 | + break; | ||
| 5411 | + case LSHIFTRT: | ||
| 5412 | + if (GET_CODE (XEXP (x, 1)) == CONST_INT) | ||
| 5413 | + fprintf (stream, "%s >> %i", reg_names[true_regnum (XEXP (x, 0))], | ||
| 5414 | + (int) INTVAL (XEXP (x, 1))); | ||
| 5415 | + else if (REG_P (XEXP (x, 1))) | ||
| 5416 | + fprintf (stream, "%s >> %s", reg_names[true_regnum (XEXP (x, 0))], | ||
| 5417 | + reg_names[true_regnum (XEXP (x, 1))]); | ||
| 5418 | + else | ||
| 5419 | + { | ||
| 5420 | + error = 1; | ||
| 5421 | + } | ||
| 5422 | + fprintf (stream, ">>"); | ||
| 5423 | + break; | ||
| 5424 | + case PARALLEL: | ||
| 5425 | + { | ||
| 5426 | + /* Load store multiple */ | ||
| 5427 | + int i; | ||
| 5428 | + int count = XVECLEN (x, 0); | ||
| 5429 | + int reglist16 = 0; | ||
| 5430 | + char reglist16_string[100]; | ||
| 5431 | + | ||
| 5432 | + for (i = 0; i < count; ++i) | ||
| 5433 | + { | ||
| 5434 | + rtx vec_elm = XVECEXP (x, 0, i); | ||
| 5435 | + if (GET_MODE (vec_elm) != SET) | ||
| 5436 | + { | ||
| 5437 | + debug_rtx (vec_elm); | ||
| 5438 | + internal_error ("Unknown element in parallel expression!"); | ||
| 5439 | + } | ||
| 5440 | + if (GET_MODE (XEXP (vec_elm, 0)) == REG) | ||
| 5441 | + { | ||
| 5442 | + /* Load multiple */ | ||
| 5443 | + reglist16 |= 1 << ASM_REGNUM (REGNO (XEXP (vec_elm, 0))); | ||
| 5444 | + } | ||
| 5445 | + else | ||
| 5446 | + { | ||
| 5447 | + /* Store multiple */ | ||
| 5448 | + reglist16 |= 1 << ASM_REGNUM (REGNO (XEXP (vec_elm, 1))); | ||
| 5449 | + } | ||
| 5450 | + } | ||
| 5451 | + | ||
| 5452 | + avr32_make_reglist16 (reglist16, reglist16_string); | ||
| 5453 | + fputs (reglist16_string, stream); | ||
| 5454 | + | ||
| 5455 | + break; | ||
| 5456 | + } | ||
| 5457 | + | ||
| 5458 | + default: | ||
| 5459 | + error = 1; | ||
| 5460 | + } | ||
| 5461 | + | ||
| 5462 | + if (error) | ||
| 5463 | + { | ||
| 5464 | + debug_rtx (x); | ||
| 5465 | + internal_error ("Illegal expression for avr32_print_operand"); | ||
| 5466 | + } | ||
| 5467 | +} | ||
| 5468 | + | ||
| 5469 | +rtx | ||
| 5470 | +avr32_get_note_reg_equiv (rtx insn) | ||
| 5471 | +{ | ||
| 5472 | + rtx note; | ||
| 5473 | + | ||
| 5474 | + note = find_reg_note (insn, REG_EQUIV, NULL_RTX); | ||
| 5475 | + | ||
| 5476 | + if (note != NULL_RTX) | ||
| 5477 | + return XEXP (note, 0); | ||
| 5478 | + else | ||
| 5479 | + return NULL_RTX; | ||
| 5480 | +} | ||
| 5481 | + | ||
| 5482 | +/* | ||
| 5483 | + Outputs to stdio stream stream the assembler syntax for an instruction | ||
| 5484 | + operand that is a memory reference whose address is x. x is an RTL | ||
| 5485 | + expression. | ||
| 5486 | + | ||
| 5487 | + ToDo: fixme. | ||
| 5488 | +*/ | ||
| 5489 | +void | ||
| 5490 | +avr32_print_operand_address (FILE * stream, rtx x) | ||
| 5491 | +{ | ||
| 5492 | + fprintf (stream, "(%d) /* address */", REGNO (x)); | ||
| 5493 | +} | ||
| 5494 | + | ||
| 5495 | +/* Return true if _GLOBAL_OFFSET_TABLE_ symbol is mentioned. */ | ||
| 5496 | +bool | ||
| 5497 | +avr32_got_mentioned_p (rtx addr) | ||
| 5498 | +{ | ||
| 5499 | + if (GET_CODE (addr) == MEM) | ||
| 5500 | + addr = XEXP (addr, 0); | ||
| 5501 | + while (GET_CODE (addr) == CONST) | ||
| 5502 | + addr = XEXP (addr, 0); | ||
| 5503 | + if (GET_CODE (addr) == SYMBOL_REF) | ||
| 5504 | + { | ||
| 5505 | + return streq (XSTR (addr, 0), "_GLOBAL_OFFSET_TABLE_"); | ||
| 5506 | + } | ||
| 5507 | + if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS) | ||
| 5508 | + { | ||
| 5509 | + bool l1, l2; | ||
| 5510 | + | ||
| 5511 | + l1 = avr32_got_mentioned_p (XEXP (addr, 0)); | ||
| 5512 | + l2 = avr32_got_mentioned_p (XEXP (addr, 1)); | ||
| 5513 | + return l1 || l2; | ||
| 5514 | + } | ||
| 5515 | + return false; | ||
| 5516 | +} | ||
| 5517 | + | ||
| 5518 | + | ||
| 5519 | +/* Find the symbol in an address expression. */ | ||
| 5520 | + | ||
| 5521 | +rtx | ||
| 5522 | +avr32_find_symbol (rtx addr) | ||
| 5523 | +{ | ||
| 5524 | + if (GET_CODE (addr) == MEM) | ||
| 5525 | + addr = XEXP (addr, 0); | ||
| 5526 | + | ||
| 5527 | + while (GET_CODE (addr) == CONST) | ||
| 5528 | + addr = XEXP (addr, 0); | ||
| 5529 | + | ||
| 5530 | + if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF) | ||
| 5531 | + return addr; | ||
| 5532 | + if (GET_CODE (addr) == PLUS) | ||
| 5533 | + { | ||
| 5534 | + rtx l1, l2; | ||
| 5535 | + | ||
| 5536 | + l1 = avr32_find_symbol (XEXP (addr, 0)); | ||
| 5537 | + l2 = avr32_find_symbol (XEXP (addr, 1)); | ||
| 5538 | + if (l1 != NULL_RTX && l2 == NULL_RTX) | ||
| 5539 | + return l1; | ||
| 5540 | + else if (l1 == NULL_RTX && l2 != NULL_RTX) | ||
| 5541 | + return l2; | ||
| 5542 | + } | ||
| 5543 | + | ||
| 5544 | + return NULL_RTX; | ||
| 5545 | +} | ||
| 5546 | + | ||
| 5547 | + | ||
| 5548 | +/* Routines for manipulation of the constant pool. */ | ||
| 5549 | + | ||
| 5550 | +/* AVR32 instructions cannot load a large constant directly into a | ||
| 5551 | + register; they have to come from a pc relative load. The constant | ||
| 5552 | + must therefore be placed in the addressable range of the pc | ||
| 5553 | + relative load. Depending on the precise pc relative load | ||
| 5554 | + instruction the range is somewhere between 256 bytes and 4k. This | ||
| 5555 | + means that we often have to dump a constant inside a function, and | ||
| 5556 | + generate code to branch around it. | ||
| 5557 | + | ||
| 5558 | + It is important to minimize this, since the branches will slow | ||
| 5559 | + things down and make the code larger. | ||
| 5560 | + | ||
| 5561 | + Normally we can hide the table after an existing unconditional | ||
| 5562 | + branch so that there is no interruption of the flow, but in the | ||
| 5563 | + worst case the code looks like this: | ||
| 5564 | + | ||
| 5565 | + lddpc rn, L1 | ||
| 5566 | + ... | ||
| 5567 | + rjmp L2 | ||
| 5568 | + align | ||
| 5569 | + L1: .long value | ||
| 5570 | + L2: | ||
| 5571 | + ... | ||
| 5572 | + | ||
| 5573 | + lddpc rn, L3 | ||
| 5574 | + ... | ||
| 5575 | + rjmp L4 | ||
| 5576 | + align | ||
| 5577 | + L3: .long value | ||
| 5578 | + L4: | ||
| 5579 | + ... | ||
| 5580 | + | ||
| 5581 | + We fix this by performing a scan after scheduling, which notices | ||
| 5582 | + which instructions need to have their operands fetched from the | ||
| 5583 | + constant table and builds the table. | ||
| 5584 | + | ||
| 5585 | + The algorithm starts by building a table of all the constants that | ||
| 5586 | + need fixing up and all the natural barriers in the function (places | ||
| 5587 | + where a constant table can be dropped without breaking the flow). | ||
| 5588 | + For each fixup we note how far the pc-relative replacement will be | ||
| 5589 | + able to reach and the offset of the instruction into the function. | ||
| 5590 | + | ||
| 5591 | + Having built the table we then group the fixes together to form | ||
| 5592 | + tables that are as large as possible (subject to addressing | ||
| 5593 | + constraints) and emit each table of constants after the last | ||
| 5594 | + barrier that is within range of all the instructions in the group. | ||
| 5595 | + If a group does not contain a barrier, then we forcibly create one | ||
| 5596 | + by inserting a jump instruction into the flow. Once the table has | ||
| 5597 | + been inserted, the insns are then modified to reference the | ||
| 5598 | + relevant entry in the pool. | ||
| 5599 | + | ||
| 5600 | + Possible enhancements to the algorithm (not implemented) are: | ||
| 5601 | + | ||
| 5602 | + 1) For some processors and object formats, there may be benefit in | ||
| 5603 | + aligning the pools to the start of cache lines; this alignment | ||
| 5604 | + would need to be taken into account when calculating addressability | ||
| 5605 | + of a pool. */ | ||
| 5606 | + | ||
| 5607 | +/* These typedefs are located at the start of this file, so that | ||
| 5608 | + they can be used in the prototypes there. This comment is to | ||
| 5609 | + remind readers of that fact so that the following structures | ||
| 5610 | + can be understood more easily. | ||
| 5611 | + | ||
| 5612 | + typedef struct minipool_node Mnode; | ||
| 5613 | + typedef struct minipool_fixup Mfix; */ | ||
| 5614 | + | ||
| 5615 | +struct minipool_node | ||
| 5616 | +{ | ||
| 5617 | + /* Doubly linked chain of entries. */ | ||
| 5618 | + Mnode *next; | ||
| 5619 | + Mnode *prev; | ||
| 5620 | + /* The maximum offset into the code that this entry can be placed. While | ||
| 5621 | + pushing fixes for forward references, all entries are sorted in order of | ||
| 5622 | + increasing max_address. */ | ||
| 5623 | + HOST_WIDE_INT max_address; | ||
| 5624 | + /* Similarly for an entry inserted for a backwards ref. */ | ||
| 5625 | + HOST_WIDE_INT min_address; | ||
| 5626 | + /* The number of fixes referencing this entry. This can become zero if we | ||
| 5627 | + "unpush" an entry. In this case we ignore the entry when we come to | ||
| 5628 | + emit the code. */ | ||
| 5629 | + int refcount; | ||
| 5630 | + /* The offset from the start of the minipool. */ | ||
| 5631 | + HOST_WIDE_INT offset; | ||
| 5632 | + /* The value in table. */ | ||
| 5633 | + rtx value; | ||
| 5634 | + /* The mode of value. */ | ||
| 5635 | + enum machine_mode mode; | ||
| 5636 | + /* The size of the value. */ | ||
| 5637 | + int fix_size; | ||
| 5638 | +}; | ||
| 5639 | + | ||
| 5640 | +struct minipool_fixup | ||
| 5641 | +{ | ||
| 5642 | + Mfix *next; | ||
| 5643 | + rtx insn; | ||
| 5644 | + HOST_WIDE_INT address; | ||
| 5645 | + rtx *loc; | ||
| 5646 | + enum machine_mode mode; | ||
| 5647 | + int fix_size; | ||
| 5648 | + rtx value; | ||
| 5649 | + Mnode *minipool; | ||
| 5650 | + HOST_WIDE_INT forwards; | ||
| 5651 | + HOST_WIDE_INT backwards; | ||
| 5652 | +}; | ||
| 5653 | + | ||
| 5654 | + | ||
| 5655 | +/* Fixes less than a word need padding out to a word boundary. */ | ||
| 5656 | +#define MINIPOOL_FIX_SIZE(mode, value) \ | ||
| 5657 | + (IS_FORCE_MINIPOOL(value) ? 0 : \ | ||
| 5658 | + (GET_MODE_SIZE ((mode)) >= 4 ? GET_MODE_SIZE ((mode)) : 4)) | ||
| 5659 | + | ||
| 5660 | +#define IS_FORCE_MINIPOOL(x) \ | ||
| 5661 | + (GET_CODE(x) == UNSPEC && \ | ||
| 5662 | + XINT(x, 1) == UNSPEC_FORCE_MINIPOOL) | ||
| 5663 | + | ||
| 5664 | +static Mnode *minipool_vector_head; | ||
| 5665 | +static Mnode *minipool_vector_tail; | ||
| 5666 | + | ||
| 5667 | +/* The linked list of all minipool fixes required for this function. */ | ||
| 5668 | +Mfix *minipool_fix_head; | ||
| 5669 | +Mfix *minipool_fix_tail; | ||
| 5670 | +/* The fix entry for the current minipool, once it has been placed. */ | ||
| 5671 | +Mfix *minipool_barrier; | ||
| 5672 | + | ||
| 5673 | +/* Determines if INSN is the start of a jump table. Returns the end | ||
| 5674 | + of the TABLE or NULL_RTX. */ | ||
| 5675 | +static rtx | ||
| 5676 | +is_jump_table (rtx insn) | ||
| 5677 | +{ | ||
| 5678 | + rtx table; | ||
| 5679 | + | ||
| 5680 | + if (GET_CODE (insn) == JUMP_INSN | ||
| 5681 | + && JUMP_LABEL (insn) != NULL | ||
| 5682 | + && ((table = next_real_insn (JUMP_LABEL (insn))) | ||
| 5683 | + == next_real_insn (insn)) | ||
| 5684 | + && table != NULL | ||
| 5685 | + && GET_CODE (table) == JUMP_INSN | ||
| 5686 | + && (GET_CODE (PATTERN (table)) == ADDR_VEC | ||
| 5687 | + || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC)) | ||
| 5688 | + return table; | ||
| 5689 | + | ||
| 5690 | + return NULL_RTX; | ||
| 5691 | +} | ||
| 5692 | + | ||
| 5693 | +static HOST_WIDE_INT | ||
| 5694 | +get_jump_table_size (rtx insn) | ||
| 5695 | +{ | ||
| 5696 | + /* ADDR_VECs only take room if read-only data does into the text section. */ | ||
| 5697 | + if (JUMP_TABLES_IN_TEXT_SECTION | ||
| 5698 | +#if !defined(READONLY_DATA_SECTION) && !defined(READONLY_DATA_SECTION_ASM_OP) | ||
| 5699 | + || 1 | ||
| 5700 | +#endif | ||
| 5701 | + ) | ||
| 5702 | + { | ||
| 5703 | + rtx body = PATTERN (insn); | ||
| 5704 | + int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0; | ||
| 5705 | + | ||
| 5706 | + return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt); | ||
| 5707 | + } | ||
| 5708 | + | ||
| 5709 | + return 0; | ||
| 5710 | +} | ||
| 5711 | + | ||
| 5712 | +/* Move a minipool fix MP from its current location to before MAX_MP. | ||
| 5713 | + If MAX_MP is NULL, then MP doesn't need moving, but the addressing | ||
| 5714 | + constraints may need updating. */ | ||
| 5715 | +static Mnode * | ||
| 5716 | +move_minipool_fix_forward_ref (Mnode * mp, Mnode * max_mp, | ||
| 5717 | + HOST_WIDE_INT max_address) | ||
| 5718 | +{ | ||
| 5719 | + /* This should never be true and the code below assumes these are | ||
| 5720 | + different. */ | ||
| 5721 | + if (mp == max_mp) | ||
| 5722 | + abort (); | ||
| 5723 | + | ||
| 5724 | + if (max_mp == NULL) | ||
| 5725 | + { | ||
| 5726 | + if (max_address < mp->max_address) | ||
| 5727 | + mp->max_address = max_address; | ||
| 5728 | + } | ||
| 5729 | + else | ||
| 5730 | + { | ||
| 5731 | + if (max_address > max_mp->max_address - mp->fix_size) | ||
| 5732 | + mp->max_address = max_mp->max_address - mp->fix_size; | ||
| 5733 | + else | ||
| 5734 | + mp->max_address = max_address; | ||
| 5735 | + | ||
| 5736 | + /* Unlink MP from its current position. Since max_mp is non-null, | ||
| 5737 | + mp->prev must be non-null. */ | ||
| 5738 | + mp->prev->next = mp->next; | ||
| 5739 | + if (mp->next != NULL) | ||
| 5740 | + mp->next->prev = mp->prev; | ||
| 5741 | + else | ||
| 5742 | + minipool_vector_tail = mp->prev; | ||
| 5743 | + | ||
| 5744 | + /* Re-insert it before MAX_MP. */ | ||
| 5745 | + mp->next = max_mp; | ||
| 5746 | + mp->prev = max_mp->prev; | ||
| 5747 | + max_mp->prev = mp; | ||
| 5748 | + | ||
| 5749 | + if (mp->prev != NULL) | ||
| 5750 | + mp->prev->next = mp; | ||
| 5751 | + else | ||
| 5752 | + minipool_vector_head = mp; | ||
| 5753 | + } | ||
| 5754 | + | ||
| 5755 | + /* Save the new entry. */ | ||
| 5756 | + max_mp = mp; | ||
| 5757 | + | ||
| 5758 | + /* Scan over the preceding entries and adjust their addresses as required. | ||
| 5759 | + */ | ||
| 5760 | + while (mp->prev != NULL | ||
| 5761 | + && mp->prev->max_address > mp->max_address - mp->prev->fix_size) | ||
| 5762 | + { | ||
| 5763 | + mp->prev->max_address = mp->max_address - mp->prev->fix_size; | ||
| 5764 | + mp = mp->prev; | ||
| 5765 | + } | ||
| 5766 | + | ||
| 5767 | + return max_mp; | ||
| 5768 | +} | ||
| 5769 | + | ||
| 5770 | +/* Add a constant to the minipool for a forward reference. Returns the | ||
| 5771 | + node added or NULL if the constant will not fit in this pool. */ | ||
| 5772 | +static Mnode * | ||
| 5773 | +add_minipool_forward_ref (Mfix * fix) | ||
| 5774 | +{ | ||
| 5775 | + /* If set, max_mp is the first pool_entry that has a lower constraint than | ||
| 5776 | + the one we are trying to add. */ | ||
| 5777 | + Mnode *max_mp = NULL; | ||
| 5778 | + HOST_WIDE_INT max_address = fix->address + fix->forwards; | ||
| 5779 | + Mnode *mp; | ||
| 5780 | + | ||
| 5781 | + /* If this fix's address is greater than the address of the first entry, | ||
| 5782 | + then we can't put the fix in this pool. We subtract the size of the | ||
| 5783 | + current fix to ensure that if the table is fully packed we still have | ||
| 5784 | + enough room to insert this value by suffling the other fixes forwards. */ | ||
| 5785 | + if (minipool_vector_head && | ||
| 5786 | + fix->address >= minipool_vector_head->max_address - fix->fix_size) | ||
| 5787 | + return NULL; | ||
| 5788 | + | ||
| 5789 | + /* Scan the pool to see if a constant with the same value has already been | ||
| 5790 | + added. While we are doing this, also note the location where we must | ||
| 5791 | + insert the constant if it doesn't already exist. */ | ||
| 5792 | + for (mp = minipool_vector_head; mp != NULL; mp = mp->next) | ||
| 5793 | + { | ||
| 5794 | + if (GET_CODE (fix->value) == GET_CODE (mp->value) | ||
| 5795 | + && fix->mode == mp->mode | ||
| 5796 | + && (GET_CODE (fix->value) != CODE_LABEL | ||
| 5797 | + || (CODE_LABEL_NUMBER (fix->value) | ||
| 5798 | + == CODE_LABEL_NUMBER (mp->value))) | ||
| 5799 | + && rtx_equal_p (fix->value, mp->value)) | ||
| 5800 | + { | ||
| 5801 | + /* More than one fix references this entry. */ | ||
| 5802 | + mp->refcount++; | ||
| 5803 | + return move_minipool_fix_forward_ref (mp, max_mp, max_address); | ||
| 5804 | + } | ||
| 5805 | + | ||
| 5806 | + /* Note the insertion point if necessary. */ | ||
| 5807 | + if (max_mp == NULL && mp->max_address > max_address) | ||
| 5808 | + max_mp = mp; | ||
| 5809 | + | ||
| 5810 | + } | ||
| 5811 | + | ||
| 5812 | + /* The value is not currently in the minipool, so we need to create a new | ||
| 5813 | + entry for it. If MAX_MP is NULL, the entry will be put on the end of | ||
| 5814 | + the list since the placement is less constrained than any existing | ||
| 5815 | + entry. Otherwise, we insert the new fix before MAX_MP and, if | ||
| 5816 | + necessary, adjust the constraints on the other entries. */ | ||
| 5817 | + mp = xmalloc (sizeof (*mp)); | ||
| 5818 | + mp->fix_size = fix->fix_size; | ||
| 5819 | + mp->mode = fix->mode; | ||
| 5820 | + mp->value = fix->value; | ||
| 5821 | + mp->refcount = 1; | ||
| 5822 | + /* Not yet required for a backwards ref. */ | ||
| 5823 | + mp->min_address = -65536; | ||
| 5824 | + | ||
| 5825 | + if (max_mp == NULL) | ||
| 5826 | + { | ||
| 5827 | + mp->max_address = max_address; | ||
| 5828 | + mp->next = NULL; | ||
| 5829 | + mp->prev = minipool_vector_tail; | ||
| 5830 | + | ||
| 5831 | + if (mp->prev == NULL) | ||
| 5832 | + { | ||
| 5833 | + minipool_vector_head = mp; | ||
| 5834 | + minipool_vector_label = gen_label_rtx (); | ||
| 5835 | + } | ||
| 5836 | + else | ||
| 5837 | + mp->prev->next = mp; | ||
| 5838 | + | ||
| 5839 | + minipool_vector_tail = mp; | ||
| 5840 | + } | ||
| 5841 | + else | ||
| 5842 | + { | ||
| 5843 | + if (max_address > max_mp->max_address - mp->fix_size) | ||
| 5844 | + mp->max_address = max_mp->max_address - mp->fix_size; | ||
| 5845 | + else | ||
| 5846 | + mp->max_address = max_address; | ||
| 5847 | + | ||
| 5848 | + mp->next = max_mp; | ||
| 5849 | + mp->prev = max_mp->prev; | ||
| 5850 | + max_mp->prev = mp; | ||
| 5851 | + if (mp->prev != NULL) | ||
| 5852 | + mp->prev->next = mp; | ||
| 5853 | + else | ||
| 5854 | + minipool_vector_head = mp; | ||
| 5855 | + } | ||
| 5856 | + | ||
| 5857 | + /* Save the new entry. */ | ||
| 5858 | + max_mp = mp; | ||
| 5859 | + | ||
| 5860 | + /* Scan over the preceding entries and adjust their addresses as required. | ||
| 5861 | + */ | ||
| 5862 | + while (mp->prev != NULL | ||
| 5863 | + && mp->prev->max_address > mp->max_address - mp->prev->fix_size) | ||
| 5864 | + { | ||
| 5865 | + mp->prev->max_address = mp->max_address - mp->prev->fix_size; | ||
| 5866 | + mp = mp->prev; | ||
| 5867 | + } | ||
| 5868 | + | ||
| 5869 | + return max_mp; | ||
| 5870 | +} | ||
| 5871 | + | ||
| 5872 | +static Mnode * | ||
| 5873 | +move_minipool_fix_backward_ref (Mnode * mp, Mnode * min_mp, | ||
| 5874 | + HOST_WIDE_INT min_address) | ||
| 5875 | +{ | ||
| 5876 | + HOST_WIDE_INT offset; | ||
| 5877 | + | ||
| 5878 | + /* This should never be true, and the code below assumes these are | ||
| 5879 | + different. */ | ||
| 5880 | + if (mp == min_mp) | ||
| 5881 | + abort (); | ||
| 5882 | + | ||
| 5883 | + if (min_mp == NULL) | ||
| 5884 | + { | ||
| 5885 | + if (min_address > mp->min_address) | ||
| 5886 | + mp->min_address = min_address; | ||
| 5887 | + } | ||
| 5888 | + else | ||
| 5889 | + { | ||
| 5890 | + /* We will adjust this below if it is too loose. */ | ||
| 5891 | + mp->min_address = min_address; | ||
| 5892 | + | ||
| 5893 | + /* Unlink MP from its current position. Since min_mp is non-null, | ||
| 5894 | + mp->next must be non-null. */ | ||
| 5895 | + mp->next->prev = mp->prev; | ||
| 5896 | + if (mp->prev != NULL) | ||
| 5897 | + mp->prev->next = mp->next; | ||
| 5898 | + else | ||
| 5899 | + minipool_vector_head = mp->next; | ||
| 5900 | + | ||
| 5901 | + /* Reinsert it after MIN_MP. */ | ||
| 5902 | + mp->prev = min_mp; | ||
| 5903 | + mp->next = min_mp->next; | ||
| 5904 | + min_mp->next = mp; | ||
| 5905 | + if (mp->next != NULL) | ||
| 5906 | + mp->next->prev = mp; | ||
| 5907 | + else | ||
| 5908 | + minipool_vector_tail = mp; | ||
| 5909 | + } | ||
| 5910 | + | ||
| 5911 | + min_mp = mp; | ||
| 5912 | + | ||
| 5913 | + offset = 0; | ||
| 5914 | + for (mp = minipool_vector_head; mp != NULL; mp = mp->next) | ||
| 5915 | + { | ||
| 5916 | + mp->offset = offset; | ||
| 5917 | + if (mp->refcount > 0) | ||
| 5918 | + offset += mp->fix_size; | ||
| 5919 | + | ||
| 5920 | + if (mp->next && mp->next->min_address < mp->min_address + mp->fix_size) | ||
| 5921 | + mp->next->min_address = mp->min_address + mp->fix_size; | ||
| 5922 | + } | ||
| 5923 | + | ||
| 5924 | + return min_mp; | ||
| 5925 | +} | ||
| 5926 | + | ||
| 5927 | +/* Add a constant to the minipool for a backward reference. Returns the | ||
| 5928 | + node added or NULL if the constant will not fit in this pool. | ||
| 5929 | + | ||
| 5930 | + Note that the code for insertion for a backwards reference can be | ||
| 5931 | + somewhat confusing because the calculated offsets for each fix do | ||
| 5932 | + not take into account the size of the pool (which is still under | ||
| 5933 | + construction. */ | ||
| 5934 | +static Mnode * | ||
| 5935 | +add_minipool_backward_ref (Mfix * fix) | ||
| 5936 | +{ | ||
| 5937 | + /* If set, min_mp is the last pool_entry that has a lower constraint than | ||
| 5938 | + the one we are trying to add. */ | ||
| 5939 | + Mnode *min_mp = NULL; | ||
| 5940 | + /* This can be negative, since it is only a constraint. */ | ||
| 5941 | + HOST_WIDE_INT min_address = fix->address - fix->backwards; | ||
| 5942 | + Mnode *mp; | ||
| 5943 | + | ||
| 5944 | + /* If we can't reach the current pool from this insn, or if we can't insert | ||
| 5945 | + this entry at the end of the pool without pushing other fixes out of | ||
| 5946 | + range, then we don't try. This ensures that we can't fail later on. */ | ||
| 5947 | + if (min_address >= minipool_barrier->address | ||
| 5948 | + || (minipool_vector_tail->min_address + fix->fix_size | ||
| 5949 | + >= minipool_barrier->address)) | ||
| 5950 | + return NULL; | ||
| 5951 | + | ||
| 5952 | + /* Scan the pool to see if a constant with the same value has already been | ||
| 5953 | + added. While we are doing this, also note the location where we must | ||
| 5954 | + insert the constant if it doesn't already exist. */ | ||
| 5955 | + for (mp = minipool_vector_tail; mp != NULL; mp = mp->prev) | ||
| 5956 | + { | ||
| 5957 | + if (GET_CODE (fix->value) == GET_CODE (mp->value) | ||
| 5958 | + && fix->mode == mp->mode | ||
| 5959 | + && (GET_CODE (fix->value) != CODE_LABEL | ||
| 5960 | + || (CODE_LABEL_NUMBER (fix->value) | ||
| 5961 | + == CODE_LABEL_NUMBER (mp->value))) | ||
| 5962 | + && rtx_equal_p (fix->value, mp->value) | ||
| 5963 | + /* Check that there is enough slack to move this entry to the end | ||
| 5964 | + of the table (this is conservative). */ | ||
| 5965 | + && (mp->max_address | ||
| 5966 | + > (minipool_barrier->address | ||
| 5967 | + + minipool_vector_tail->offset | ||
| 5968 | + + minipool_vector_tail->fix_size))) | ||
| 5969 | + { | ||
| 5970 | + mp->refcount++; | ||
| 5971 | + return move_minipool_fix_backward_ref (mp, min_mp, min_address); | ||
| 5972 | + } | ||
| 5973 | + | ||
| 5974 | + if (min_mp != NULL) | ||
| 5975 | + mp->min_address += fix->fix_size; | ||
| 5976 | + else | ||
| 5977 | + { | ||
| 5978 | + /* Note the insertion point if necessary. */ | ||
| 5979 | + if (mp->min_address < min_address) | ||
| 5980 | + { | ||
| 5981 | + min_mp = mp; | ||
| 5982 | + } | ||
| 5983 | + else if (mp->max_address | ||
| 5984 | + < minipool_barrier->address + mp->offset + fix->fix_size) | ||
| 5985 | + { | ||
| 5986 | + /* Inserting before this entry would push the fix beyond its | ||
| 5987 | + maximum address (which can happen if we have re-located a | ||
| 5988 | + forwards fix); force the new fix to come after it. */ | ||
| 5989 | + min_mp = mp; | ||
| 5990 | + min_address = mp->min_address + fix->fix_size; | ||
| 5991 | + } | ||
| 5992 | + } | ||
| 5993 | + } | ||
| 5994 | + | ||
| 5995 | + /* We need to create a new entry. */ | ||
| 5996 | + mp = xmalloc (sizeof (*mp)); | ||
| 5997 | + mp->fix_size = fix->fix_size; | ||
| 5998 | + mp->mode = fix->mode; | ||
| 5999 | + mp->value = fix->value; | ||
| 6000 | + mp->refcount = 1; | ||
| 6001 | + mp->max_address = minipool_barrier->address + 65536; | ||
| 6002 | + | ||
| 6003 | + mp->min_address = min_address; | ||
| 6004 | + | ||
| 6005 | + if (min_mp == NULL) | ||
| 6006 | + { | ||
| 6007 | + mp->prev = NULL; | ||
| 6008 | + mp->next = minipool_vector_head; | ||
| 6009 | + | ||
| 6010 | + if (mp->next == NULL) | ||
| 6011 | + { | ||
| 6012 | + minipool_vector_tail = mp; | ||
| 6013 | + minipool_vector_label = gen_label_rtx (); | ||
| 6014 | + } | ||
| 6015 | + else | ||
| 6016 | + mp->next->prev = mp; | ||
| 6017 | + | ||
| 6018 | + minipool_vector_head = mp; | ||
| 6019 | + } | ||
| 6020 | + else | ||
| 6021 | + { | ||
| 6022 | + mp->next = min_mp->next; | ||
| 6023 | + mp->prev = min_mp; | ||
| 6024 | + min_mp->next = mp; | ||
| 6025 | + | ||
| 6026 | + if (mp->next != NULL) | ||
| 6027 | + mp->next->prev = mp; | ||
| 6028 | + else | ||
| 6029 | + minipool_vector_tail = mp; | ||
| 6030 | + } | ||
| 6031 | + | ||
| 6032 | + /* Save the new entry. */ | ||
| 6033 | + min_mp = mp; | ||
| 6034 | + | ||
| 6035 | + if (mp->prev) | ||
| 6036 | + mp = mp->prev; | ||
| 6037 | + else | ||
| 6038 | + mp->offset = 0; | ||
| 6039 | + | ||
| 6040 | + /* Scan over the following entries and adjust their offsets. */ | ||
| 6041 | + while (mp->next != NULL) | ||
| 6042 | + { | ||
| 6043 | + if (mp->next->min_address < mp->min_address + mp->fix_size) | ||
| 6044 | + mp->next->min_address = mp->min_address + mp->fix_size; | ||
| 6045 | + | ||
| 6046 | + if (mp->refcount) | ||
| 6047 | + mp->next->offset = mp->offset + mp->fix_size; | ||
| 6048 | + else | ||
| 6049 | + mp->next->offset = mp->offset; | ||
| 6050 | + | ||
| 6051 | + mp = mp->next; | ||
| 6052 | + } | ||
| 6053 | + | ||
| 6054 | + return min_mp; | ||
| 6055 | +} | ||
| 6056 | + | ||
| 6057 | +static void | ||
| 6058 | +assign_minipool_offsets (Mfix * barrier) | ||
| 6059 | +{ | ||
| 6060 | + HOST_WIDE_INT offset = 0; | ||
| 6061 | + Mnode *mp; | ||
| 6062 | + | ||
| 6063 | + minipool_barrier = barrier; | ||
| 6064 | + | ||
| 6065 | + for (mp = minipool_vector_head; mp != NULL; mp = mp->next) | ||
| 6066 | + { | ||
| 6067 | + mp->offset = offset; | ||
| 6068 | + | ||
| 6069 | + if (mp->refcount > 0 | ||
| 6070 | + /* If the value is (const_int 0) then this is a fake entry so don't | ||
| 6071 | + add an offset for it since it will not be output. */ | ||
| 6072 | + && !(GET_CODE (mp->value) == CONST_INT && INTVAL (mp->value) == 0)) | ||
| 6073 | + offset += mp->fix_size; | ||
| 6074 | + } | ||
| 6075 | +} | ||
| 6076 | + | ||
| 6077 | +/* Print a symbolic form of X to the debug file, F. */ | ||
| 6078 | +static void | ||
| 6079 | +avr32_print_value (FILE * f, rtx x) | ||
| 6080 | +{ | ||
| 6081 | + switch (GET_CODE (x)) | ||
| 6082 | + { | ||
| 6083 | + case CONST_INT: | ||
| 6084 | + fprintf (f, "0x%x", (int) INTVAL (x)); | ||
| 6085 | + return; | ||
| 6086 | + | ||
| 6087 | + case CONST_DOUBLE: | ||
| 6088 | + fprintf (f, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3)); | ||
| 6089 | + return; | ||
| 6090 | + | ||
| 6091 | + case CONST_VECTOR: | ||
| 6092 | + { | ||
| 6093 | + int i; | ||
| 6094 | + | ||
| 6095 | + fprintf (f, "<"); | ||
| 6096 | + for (i = 0; i < CONST_VECTOR_NUNITS (x); i++) | ||
| 6097 | + { | ||
| 6098 | + fprintf (f, "0x%x", (int) INTVAL (CONST_VECTOR_ELT (x, i))); | ||
| 6099 | + if (i < (CONST_VECTOR_NUNITS (x) - 1)) | ||
| 6100 | + fputc (',', f); | ||
| 6101 | + } | ||
| 6102 | + fprintf (f, ">"); | ||
| 6103 | + } | ||
| 6104 | + return; | ||
| 6105 | + | ||
| 6106 | + case CONST_STRING: | ||
| 6107 | + fprintf (f, "\"%s\"", XSTR (x, 0)); | ||
| 6108 | + return; | ||
| 6109 | + | ||
| 6110 | + case SYMBOL_REF: | ||
| 6111 | + fprintf (f, "`%s'", XSTR (x, 0)); | ||
| 6112 | + return; | ||
| 6113 | + | ||
| 6114 | + case LABEL_REF: | ||
| 6115 | + fprintf (f, "L%d", INSN_UID (XEXP (x, 0))); | ||
| 6116 | + return; | ||
| 6117 | + | ||
| 6118 | + case CONST: | ||
| 6119 | + avr32_print_value (f, XEXP (x, 0)); | ||
| 6120 | + return; | ||
| 6121 | + | ||
| 6122 | + case PLUS: | ||
| 6123 | + avr32_print_value (f, XEXP (x, 0)); | ||
| 6124 | + fprintf (f, "+"); | ||
| 6125 | + avr32_print_value (f, XEXP (x, 1)); | ||
| 6126 | + return; | ||
| 6127 | + | ||
| 6128 | + case PC: | ||
| 6129 | + fprintf (f, "pc"); | ||
| 6130 | + return; | ||
| 6131 | + | ||
| 6132 | + default: | ||
| 6133 | + fprintf (f, "????"); | ||
| 6134 | + return; | ||
| 6135 | + } | ||
| 6136 | +} | ||
| 6137 | + | ||
| 6138 | +int | ||
| 6139 | +is_minipool_label (rtx label) | ||
| 6140 | +{ | ||
| 6141 | + minipool_labels *cur_mp_label = cfun->machine->minipool_label_head; | ||
| 6142 | + | ||
| 6143 | + if (GET_CODE (label) != CODE_LABEL) | ||
| 6144 | + return FALSE; | ||
| 6145 | + | ||
| 6146 | + while (cur_mp_label) | ||
| 6147 | + { | ||
| 6148 | + if (CODE_LABEL_NUMBER (label) | ||
| 6149 | + == CODE_LABEL_NUMBER (cur_mp_label->label)) | ||
| 6150 | + return TRUE; | ||
| 6151 | + cur_mp_label = cur_mp_label->next; | ||
| 6152 | + } | ||
| 6153 | + return FALSE; | ||
| 6154 | +} | ||
| 6155 | + | ||
| 6156 | +static void | ||
| 6157 | +new_minipool_label (rtx label) | ||
| 6158 | +{ | ||
| 6159 | + if (!cfun->machine->minipool_label_head) | ||
| 6160 | + { | ||
| 6161 | + cfun->machine->minipool_label_head = | ||
| 6162 | + ggc_alloc (sizeof (minipool_labels)); | ||
| 6163 | + cfun->machine->minipool_label_tail = cfun->machine->minipool_label_head; | ||
| 6164 | + cfun->machine->minipool_label_head->label = label; | ||
| 6165 | + cfun->machine->minipool_label_head->next = 0; | ||
| 6166 | + cfun->machine->minipool_label_head->prev = 0; | ||
| 6167 | + } | ||
| 6168 | + else | ||
| 6169 | + { | ||
| 6170 | + cfun->machine->minipool_label_tail->next = | ||
| 6171 | + ggc_alloc (sizeof (minipool_labels)); | ||
| 6172 | + cfun->machine->minipool_label_tail->next->label = label; | ||
| 6173 | + cfun->machine->minipool_label_tail->next->next = 0; | ||
| 6174 | + cfun->machine->minipool_label_tail->next->prev = | ||
| 6175 | + cfun->machine->minipool_label_tail; | ||
| 6176 | + cfun->machine->minipool_label_tail = | ||
| 6177 | + cfun->machine->minipool_label_tail->next; | ||
| 6178 | + } | ||
| 6179 | +} | ||
| 6180 | + | ||
| 6181 | +/* Output the literal table */ | ||
| 6182 | +static void | ||
| 6183 | +dump_minipool (rtx scan) | ||
| 6184 | +{ | ||
| 6185 | + Mnode *mp; | ||
| 6186 | + Mnode *nmp; | ||
| 6187 | + | ||
| 6188 | + if (dump_file) | ||
| 6189 | + fprintf (dump_file, | ||
| 6190 | + ";; Emitting minipool after insn %u; address %ld; align %d (bytes)\n", | ||
| 6191 | + INSN_UID (scan), (unsigned long) minipool_barrier->address, 4); | ||
| 6192 | + | ||
| 6193 | + scan = emit_insn_after (gen_consttable_start (), scan); | ||
| 6194 | + scan = emit_insn_after (gen_align_4 (), scan); | ||
| 6195 | + scan = emit_label_after (minipool_vector_label, scan); | ||
| 6196 | + new_minipool_label (minipool_vector_label); | ||
| 6197 | + | ||
| 6198 | + for (mp = minipool_vector_head; mp != NULL; mp = nmp) | ||
| 6199 | + { | ||
| 6200 | + if (mp->refcount > 0) | ||
| 6201 | + { | ||
| 6202 | + if (dump_file) | ||
| 6203 | + { | ||
| 6204 | + fprintf (dump_file, | ||
| 6205 | + ";; Offset %u, min %ld, max %ld ", | ||
| 6206 | + (unsigned) mp->offset, (unsigned long) mp->min_address, | ||
| 6207 | + (unsigned long) mp->max_address); | ||
| 6208 | + avr32_print_value (dump_file, mp->value); | ||
| 6209 | + fputc ('\n', dump_file); | ||
| 6210 | + } | ||
| 6211 | + | ||
| 6212 | + switch (mp->fix_size) | ||
| 6213 | + { | ||
| 6214 | +#ifdef HAVE_consttable_4 | ||
| 6215 | + case 4: | ||
| 6216 | + scan = emit_insn_after (gen_consttable_4 (mp->value), scan); | ||
| 6217 | + break; | ||
| 6218 | + | ||
| 6219 | +#endif | ||
| 6220 | +#ifdef HAVE_consttable_8 | ||
| 6221 | + case 8: | ||
| 6222 | + scan = emit_insn_after (gen_consttable_8 (mp->value), scan); | ||
| 6223 | + break; | ||
| 6224 | + | ||
| 6225 | +#endif | ||
| 6226 | + case 0: | ||
| 6227 | + /* This can happen for force-minipool entries which just are | ||
| 6228 | + there to force the minipool to be generate. */ | ||
| 6229 | + break; | ||
| 6230 | + default: | ||
| 6231 | + abort (); | ||
| 6232 | + break; | ||
| 6233 | + } | ||
| 6234 | + } | ||
| 6235 | + | ||
| 6236 | + nmp = mp->next; | ||
| 6237 | + free (mp); | ||
| 6238 | + } | ||
| 6239 | + | ||
| 6240 | + minipool_vector_head = minipool_vector_tail = NULL; | ||
| 6241 | + scan = emit_insn_after (gen_consttable_end (), scan); | ||
| 6242 | + scan = emit_barrier_after (scan); | ||
| 6243 | +} | ||
| 6244 | + | ||
| 6245 | +/* Return the cost of forcibly inserting a barrier after INSN. */ | ||
| 6246 | +static int | ||
| 6247 | +avr32_barrier_cost (rtx insn) | ||
| 6248 | +{ | ||
| 6249 | + /* Basing the location of the pool on the loop depth is preferable, but at | ||
| 6250 | + the moment, the basic block information seems to be corrupt by this | ||
| 6251 | + stage of the compilation. */ | ||
| 6252 | + int base_cost = 50; | ||
| 6253 | + rtx next = next_nonnote_insn (insn); | ||
| 6254 | + | ||
| 6255 | + if (next != NULL && GET_CODE (next) == CODE_LABEL) | ||
| 6256 | + base_cost -= 20; | ||
| 6257 | + | ||
| 6258 | + switch (GET_CODE (insn)) | ||
| 6259 | + { | ||
| 6260 | + case CODE_LABEL: | ||
| 6261 | + /* It will always be better to place the table before the label, rather | ||
| 6262 | + than after it. */ | ||
| 6263 | + return 50; | ||
| 6264 | + | ||
| 6265 | + case INSN: | ||
| 6266 | + case CALL_INSN: | ||
| 6267 | + return base_cost; | ||
| 6268 | + | ||
| 6269 | + case JUMP_INSN: | ||
| 6270 | + return base_cost - 10; | ||
| 6271 | + | ||
| 6272 | + default: | ||
| 6273 | + return base_cost + 10; | ||
| 6274 | + } | ||
| 6275 | +} | ||
| 6276 | + | ||
| 6277 | +/* Find the best place in the insn stream in the range | ||
| 6278 | + (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier. | ||
| 6279 | + Create the barrier by inserting a jump and add a new fix entry for | ||
| 6280 | + it. */ | ||
| 6281 | +static Mfix * | ||
| 6282 | +create_fix_barrier (Mfix * fix, HOST_WIDE_INT max_address) | ||
| 6283 | +{ | ||
| 6284 | + HOST_WIDE_INT count = 0; | ||
| 6285 | + rtx barrier; | ||
| 6286 | + rtx from = fix->insn; | ||
| 6287 | + rtx selected = from; | ||
| 6288 | + int selected_cost; | ||
| 6289 | + HOST_WIDE_INT selected_address; | ||
| 6290 | + Mfix *new_fix; | ||
| 6291 | + HOST_WIDE_INT max_count = max_address - fix->address; | ||
| 6292 | + rtx label = gen_label_rtx (); | ||
| 6293 | + | ||
| 6294 | + selected_cost = avr32_barrier_cost (from); | ||
| 6295 | + selected_address = fix->address; | ||
| 6296 | + | ||
| 6297 | + while (from && count < max_count) | ||
| 6298 | + { | ||
| 6299 | + rtx tmp; | ||
| 6300 | + int new_cost; | ||
| 6301 | + | ||
| 6302 | + /* This code shouldn't have been called if there was a natural barrier | ||
| 6303 | + within range. */ | ||
| 6304 | + if (GET_CODE (from) == BARRIER) | ||
| 6305 | + abort (); | ||
| 6306 | + | ||
| 6307 | + /* Count the length of this insn. */ | ||
| 6308 | + count += get_attr_length (from); | ||
| 6309 | + | ||
| 6310 | + /* If there is a jump table, add its length. */ | ||
| 6311 | + tmp = is_jump_table (from); | ||
| 6312 | + if (tmp != NULL) | ||
| 6313 | + { | ||
| 6314 | + count += get_jump_table_size (tmp); | ||
| 6315 | + | ||
| 6316 | + /* Jump tables aren't in a basic block, so base the cost on the | ||
| 6317 | + dispatch insn. If we select this location, we will still put | ||
| 6318 | + the pool after the table. */ | ||
| 6319 | + new_cost = avr32_barrier_cost (from); | ||
| 6320 | + | ||
| 6321 | + if (count < max_count && new_cost <= selected_cost) | ||
| 6322 | + { | ||
| 6323 | + selected = tmp; | ||
| 6324 | + selected_cost = new_cost; | ||
| 6325 | + selected_address = fix->address + count; | ||
| 6326 | + } | ||
| 6327 | + | ||
| 6328 | + /* Continue after the dispatch table. */ | ||
| 6329 | + from = NEXT_INSN (tmp); | ||
| 6330 | + continue; | ||
| 6331 | + } | ||
| 6332 | + | ||
| 6333 | + new_cost = avr32_barrier_cost (from); | ||
| 6334 | + | ||
| 6335 | + if (count < max_count && new_cost <= selected_cost) | ||
| 6336 | + { | ||
| 6337 | + selected = from; | ||
| 6338 | + selected_cost = new_cost; | ||
| 6339 | + selected_address = fix->address + count; | ||
| 6340 | + } | ||
| 6341 | + | ||
| 6342 | + from = NEXT_INSN (from); | ||
| 6343 | + } | ||
| 6344 | + | ||
| 6345 | + /* Create a new JUMP_INSN that branches around a barrier. */ | ||
| 6346 | + from = emit_jump_insn_after (gen_jump (label), selected); | ||
| 6347 | + JUMP_LABEL (from) = label; | ||
| 6348 | + barrier = emit_barrier_after (from); | ||
| 6349 | + emit_label_after (label, barrier); | ||
| 6350 | + | ||
| 6351 | + /* Create a minipool barrier entry for the new barrier. */ | ||
| 6352 | + new_fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*new_fix)); | ||
| 6353 | + new_fix->insn = barrier; | ||
| 6354 | + new_fix->address = selected_address; | ||
| 6355 | + new_fix->next = fix->next; | ||
| 6356 | + fix->next = new_fix; | ||
| 6357 | + | ||
| 6358 | + return new_fix; | ||
| 6359 | +} | ||
| 6360 | + | ||
| 6361 | +/* Record that there is a natural barrier in the insn stream at | ||
| 6362 | + ADDRESS. */ | ||
| 6363 | +static void | ||
| 6364 | +push_minipool_barrier (rtx insn, HOST_WIDE_INT address) | ||
| 6365 | +{ | ||
| 6366 | + Mfix *fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*fix)); | ||
| 6367 | + | ||
| 6368 | + fix->insn = insn; | ||
| 6369 | + fix->address = address; | ||
| 6370 | + | ||
| 6371 | + fix->next = NULL; | ||
| 6372 | + if (minipool_fix_head != NULL) | ||
| 6373 | + minipool_fix_tail->next = fix; | ||
| 6374 | + else | ||
| 6375 | + minipool_fix_head = fix; | ||
| 6376 | + | ||
| 6377 | + minipool_fix_tail = fix; | ||
| 6378 | +} | ||
| 6379 | + | ||
| 6380 | +/* Record INSN, which will need fixing up to load a value from the | ||
| 6381 | + minipool. ADDRESS is the offset of the insn since the start of the | ||
| 6382 | + function; LOC is a pointer to the part of the insn which requires | ||
| 6383 | + fixing; VALUE is the constant that must be loaded, which is of type | ||
| 6384 | + MODE. */ | ||
| 6385 | +static void | ||
| 6386 | +push_minipool_fix (rtx insn, HOST_WIDE_INT address, rtx * loc, | ||
| 6387 | + enum machine_mode mode, rtx value) | ||
| 6388 | +{ | ||
| 6389 | + Mfix *fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*fix)); | ||
| 6390 | + rtx body = PATTERN (insn); | ||
| 6391 | + | ||
| 6392 | + fix->insn = insn; | ||
| 6393 | + fix->address = address; | ||
| 6394 | + fix->loc = loc; | ||
| 6395 | + fix->mode = mode; | ||
| 6396 | + fix->fix_size = MINIPOOL_FIX_SIZE (mode, value); | ||
| 6397 | + fix->value = value; | ||
| 6398 | + | ||
| 6399 | + if (GET_CODE (body) == PARALLEL) | ||
| 6400 | + { | ||
| 6401 | + /* Mcall : Ks16 << 2 */ | ||
| 6402 | + fix->forwards = ((1 << 15) - 1) << 2; | ||
| 6403 | + fix->backwards = (1 << 15) << 2; | ||
| 6404 | + } | ||
| 6405 | + else if (GET_CODE (body) == SET | ||
| 6406 | + && GET_MODE_SIZE (GET_MODE (SET_DEST (body))) == 4) | ||
| 6407 | + { | ||
| 6408 | + /* Word Load */ | ||
| 6409 | + if (TARGET_HARD_FLOAT | ||
| 6410 | + && GET_MODE_CLASS (GET_MODE (SET_DEST (body))) == MODE_FLOAT) | ||
| 6411 | + { | ||
| 6412 | + /* Ldc0.w : Ku12 << 2 */ | ||
| 6413 | + fix->forwards = ((1 << 12) - 1) << 2; | ||
| 6414 | + fix->backwards = 0; | ||
| 6415 | + } | ||
| 6416 | + else | ||
| 6417 | + { | ||
| 6418 | + if (optimize_size) | ||
| 6419 | + { | ||
| 6420 | + /* Lddpc : Ku7 << 2 */ | ||
| 6421 | + fix->forwards = ((1 << 7) - 1) << 2; | ||
| 6422 | + fix->backwards = 0; | ||
| 6423 | + } | ||
| 6424 | + else | ||
| 6425 | + { | ||
| 6426 | + /* Ld.w : Ks16 */ | ||
| 6427 | + fix->forwards = ((1 << 15) - 4); | ||
| 6428 | + fix->backwards = (1 << 15); | ||
| 6429 | + } | ||
| 6430 | + } | ||
| 6431 | + } | ||
| 6432 | + else if (GET_CODE (body) == SET | ||
| 6433 | + && GET_MODE_SIZE (GET_MODE (SET_DEST (body))) == 8) | ||
| 6434 | + { | ||
| 6435 | + /* Double word load */ | ||
| 6436 | + if (TARGET_HARD_FLOAT | ||
| 6437 | + && GET_MODE_CLASS (GET_MODE (SET_DEST (body))) == MODE_FLOAT) | ||
| 6438 | + { | ||
| 6439 | + /* Ldc0.d : Ku12 << 2 */ | ||
| 6440 | + fix->forwards = ((1 << 12) - 1) << 2; | ||
| 6441 | + fix->backwards = 0; | ||
| 6442 | + } | ||
| 6443 | + else | ||
| 6444 | + { | ||
| 6445 | + /* Ld.d : Ks16 */ | ||
| 6446 | + fix->forwards = ((1 << 15) - 4); | ||
| 6447 | + fix->backwards = (1 << 15); | ||
| 6448 | + } | ||
| 6449 | + } | ||
| 6450 | + else if (GET_CODE (body) == UNSPEC_VOLATILE | ||
| 6451 | + && XINT (body, 1) == VUNSPEC_MVRC) | ||
| 6452 | + { | ||
| 6453 | + /* Coprocessor load */ | ||
| 6454 | + /* Ldc : Ku8 << 2 */ | ||
| 6455 | + fix->forwards = ((1 << 8) - 1) << 2; | ||
| 6456 | + fix->backwards = 0; | ||
| 6457 | + } | ||
| 6458 | + else | ||
| 6459 | + { | ||
| 6460 | + /* Assume worst case which is lddpc insn. */ | ||
| 6461 | + fix->forwards = ((1 << 7) - 1) << 2; | ||
| 6462 | + fix->backwards = 0; | ||
| 6463 | + } | ||
| 6464 | + | ||
| 6465 | + fix->minipool = NULL; | ||
| 6466 | + | ||
| 6467 | + /* If an insn doesn't have a range defined for it, then it isn't expecting | ||
| 6468 | + to be reworked by this code. Better to abort now than to generate duff | ||
| 6469 | + assembly code. */ | ||
| 6470 | + if (fix->forwards == 0 && fix->backwards == 0) | ||
| 6471 | + abort (); | ||
| 6472 | + | ||
| 6473 | + if (dump_file) | ||
| 6474 | + { | ||
| 6475 | + fprintf (dump_file, | ||
| 6476 | + ";; %smode fixup for i%d; addr %lu, range (%ld,%ld): ", | ||
| 6477 | + GET_MODE_NAME (mode), | ||
| 6478 | + INSN_UID (insn), (unsigned long) address, | ||
| 6479 | + -1 * (long) fix->backwards, (long) fix->forwards); | ||
| 6480 | + avr32_print_value (dump_file, fix->value); | ||
| 6481 | + fprintf (dump_file, "\n"); | ||
| 6482 | + } | ||
| 6483 | + | ||
| 6484 | + /* Add it to the chain of fixes. */ | ||
| 6485 | + fix->next = NULL; | ||
| 6486 | + | ||
| 6487 | + if (minipool_fix_head != NULL) | ||
| 6488 | + minipool_fix_tail->next = fix; | ||
| 6489 | + else | ||
| 6490 | + minipool_fix_head = fix; | ||
| 6491 | + | ||
| 6492 | + minipool_fix_tail = fix; | ||
| 6493 | +} | ||
| 6494 | + | ||
| 6495 | +/* Scan INSN and note any of its operands that need fixing. | ||
| 6496 | + If DO_PUSHES is false we do not actually push any of the fixups | ||
| 6497 | + needed. The function returns TRUE is any fixups were needed/pushed. | ||
| 6498 | + This is used by avr32_memory_load_p() which needs to know about loads | ||
| 6499 | + of constants that will be converted into minipool loads. */ | ||
| 6500 | +static bool | ||
| 6501 | +note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes) | ||
| 6502 | +{ | ||
| 6503 | + bool result = false; | ||
| 6504 | + int opno; | ||
| 6505 | + | ||
| 6506 | + extract_insn (insn); | ||
| 6507 | + | ||
| 6508 | + if (!constrain_operands (1)) | ||
| 6509 | + fatal_insn_not_found (insn); | ||
| 6510 | + | ||
| 6511 | + if (recog_data.n_alternatives == 0) | ||
| 6512 | + return false; | ||
| 6513 | + | ||
| 6514 | + /* Fill in recog_op_alt with information about the constraints of this | ||
| 6515 | + insn. */ | ||
| 6516 | + preprocess_constraints (); | ||
| 6517 | + | ||
| 6518 | + for (opno = 0; opno < recog_data.n_operands; opno++) | ||
| 6519 | + { | ||
| 6520 | + rtx op; | ||
| 6521 | + | ||
| 6522 | + /* Things we need to fix can only occur in inputs. */ | ||
| 6523 | + if (recog_data.operand_type[opno] != OP_IN) | ||
| 6524 | + continue; | ||
| 6525 | + | ||
| 6526 | + op = recog_data.operand[opno]; | ||
| 6527 | + | ||
| 6528 | + if (avr32_const_pool_ref_operand (op, GET_MODE (op))) | ||
| 6529 | + { | ||
| 6530 | + if (do_pushes) | ||
| 6531 | + { | ||
| 6532 | + rtx cop = avoid_constant_pool_reference (op); | ||
| 6533 | + | ||
| 6534 | + /* Casting the address of something to a mode narrower than a | ||
| 6535 | + word can cause avoid_constant_pool_reference() to return the | ||
| 6536 | + pool reference itself. That's no good to us here. Lets | ||
| 6537 | + just hope that we can use the constant pool value directly. | ||
| 6538 | + */ | ||
| 6539 | + if (op == cop) | ||
| 6540 | + cop = get_pool_constant (XEXP (op, 0)); | ||
| 6541 | + | ||
| 6542 | + push_minipool_fix (insn, address, | ||
| 6543 | + recog_data.operand_loc[opno], | ||
| 6544 | + recog_data.operand_mode[opno], cop); | ||
| 6545 | + } | ||
| 6546 | + | ||
| 6547 | + result = true; | ||
| 6548 | + } | ||
| 6549 | + else if (TARGET_HAS_ASM_ADDR_PSEUDOS | ||
| 6550 | + && avr32_address_operand (op, GET_MODE (op))) | ||
| 6551 | + { | ||
| 6552 | + /* Handle pseudo instructions using a direct address. These pseudo | ||
| 6553 | + instructions might need entries in the constant pool and we must | ||
| 6554 | + therefor create a constant pool for them, in case the | ||
| 6555 | + assembler/linker needs to insert entries. */ | ||
| 6556 | + if (do_pushes) | ||
| 6557 | + { | ||
| 6558 | + /* Push a dummy constant pool entry so that the .cpool | ||
| 6559 | + directive should be inserted on the appropriate place in the | ||
| 6560 | + code even if there are no real constant pool entries. This | ||
| 6561 | + is used by the assembler and linker to know where to put | ||
| 6562 | + generated constant pool entries. */ | ||
| 6563 | + push_minipool_fix (insn, address, | ||
| 6564 | + recog_data.operand_loc[opno], | ||
| 6565 | + recog_data.operand_mode[opno], | ||
| 6566 | + gen_rtx_UNSPEC (VOIDmode, | ||
| 6567 | + gen_rtvec (1, const0_rtx), | ||
| 6568 | + UNSPEC_FORCE_MINIPOOL)); | ||
| 6569 | + result = true; | ||
| 6570 | + } | ||
| 6571 | + } | ||
| 6572 | + } | ||
| 6573 | + return result; | ||
| 6574 | +} | ||
| 6575 | + | ||
| 6576 | + | ||
| 6577 | +static int | ||
| 6578 | +avr32_insn_is_cast (rtx insn) | ||
| 6579 | +{ | ||
| 6580 | + | ||
| 6581 | + if (NONJUMP_INSN_P (insn) | ||
| 6582 | + && GET_CODE (PATTERN (insn)) == SET | ||
| 6583 | + && (GET_CODE (SET_SRC (PATTERN (insn))) == ZERO_EXTEND | ||
| 6584 | + || GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTEND) | ||
| 6585 | + && REG_P (XEXP (SET_SRC (PATTERN (insn)), 0)) | ||
| 6586 | + && REG_P (SET_DEST (PATTERN (insn)))) | ||
| 6587 | + return true; | ||
| 6588 | + return false; | ||
| 6589 | +} | ||
| 6590 | + | ||
| 6591 | +/* FIXME: The level of nesting in this function is way too deep. It needs to be | ||
| 6592 | + torn apart. */ | ||
| 6593 | +static void | ||
| 6594 | +avr32_reorg_optimization (void) | ||
| 6595 | +{ | ||
| 6596 | + rtx first = get_insns (); | ||
| 6597 | + rtx insn; | ||
| 6598 | + | ||
| 6599 | + if (TARGET_MD_REORG_OPTIMIZATION && (optimize_size || (optimize > 0))) | ||
| 6600 | + { | ||
| 6601 | + | ||
| 6602 | + /* Scan through all insns looking for cast operations. */ | ||
| 6603 | + if (dump_file) | ||
| 6604 | + { | ||
| 6605 | + fprintf (dump_file, ";; Deleting redundant cast operations:\n"); | ||
| 6606 | + } | ||
| 6607 | + for (insn = first; insn; insn = NEXT_INSN (insn)) | ||
| 6608 | + { | ||
| 6609 | + rtx reg, src_reg, scan; | ||
| 6610 | + enum machine_mode mode; | ||
| 6611 | + int unused_cast; | ||
| 6612 | + rtx label_ref; | ||
| 6613 | + | ||
| 6614 | + if (avr32_insn_is_cast (insn) | ||
| 6615 | + && (GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == QImode | ||
| 6616 | + || GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == HImode)) | ||
| 6617 | + { | ||
| 6618 | + mode = GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0)); | ||
| 6619 | + reg = SET_DEST (PATTERN (insn)); | ||
| 6620 | + src_reg = XEXP (SET_SRC (PATTERN (insn)), 0); | ||
| 6621 | + } | ||
| 6622 | + else | ||
| 6623 | + { | ||
| 6624 | + continue; | ||
| 6625 | + } | ||
| 6626 | + | ||
| 6627 | + unused_cast = false; | ||
| 6628 | + label_ref = NULL_RTX; | ||
| 6629 | + for (scan = NEXT_INSN (insn); scan; scan = NEXT_INSN (scan)) | ||
| 6630 | + { | ||
| 6631 | + /* Check if we have reached the destination of a simple | ||
| 6632 | + conditional jump which we have already scanned past. If so, | ||
| 6633 | + we can safely continue scanning. */ | ||
| 6634 | + if (LABEL_P (scan) && label_ref != NULL_RTX) | ||
| 6635 | + { | ||
| 6636 | + if (CODE_LABEL_NUMBER (scan) == | ||
| 6637 | + CODE_LABEL_NUMBER (XEXP (label_ref, 0))) | ||
| 6638 | + label_ref = NULL_RTX; | ||
| 6639 | + else | ||
| 6640 | + break; | ||
| 6641 | + } | ||
| 6642 | + | ||
| 6643 | + if (!INSN_P (scan)) | ||
| 6644 | + continue; | ||
| 6645 | + | ||
| 6646 | + /* For conditional jumps we can manage to keep on scanning if | ||
| 6647 | + we meet the destination label later on before any new jump | ||
| 6648 | + insns occure. */ | ||
| 6649 | + if (GET_CODE (scan) == JUMP_INSN) | ||
| 6650 | + { | ||
| 6651 | + if (any_condjump_p (scan) && label_ref == NULL_RTX) | ||
| 6652 | + label_ref = condjump_label (scan); | ||
| 6653 | + else | ||
| 6654 | + break; | ||
| 6655 | + } | ||
| 6656 | + | ||
| 6657 | + if (!reg_mentioned_p (reg, PATTERN (scan))) | ||
| 6658 | + continue; | ||
| 6659 | + | ||
| 6660 | + /* Check if casted register is used in this insn */ | ||
| 6661 | + if ((regno_use_in (REGNO (reg), PATTERN (scan)) != NULL_RTX) | ||
| 6662 | + && (GET_MODE (regno_use_in (REGNO (reg), PATTERN (scan))) == | ||
| 6663 | + GET_MODE (reg))) | ||
| 6664 | + { | ||
| 6665 | + /* If not used in the source to the set or in a memory | ||
| 6666 | + expression in the destiantion then the register is used | ||
| 6667 | + as a destination and is really dead. */ | ||
| 6668 | + if (single_set (scan) | ||
| 6669 | + && GET_CODE (PATTERN (scan)) == SET | ||
| 6670 | + && REG_P (SET_DEST (PATTERN (scan))) | ||
| 6671 | + && !regno_use_in (REGNO (reg), SET_SRC (PATTERN (scan))) | ||
| 6672 | + && label_ref == NULL_RTX) | ||
| 6673 | + { | ||
| 6674 | + unused_cast = true; | ||
| 6675 | + } | ||
| 6676 | + break; | ||
| 6677 | + } | ||
| 6678 | + | ||
| 6679 | + /* Check if register is dead or set in this insn */ | ||
| 6680 | + if (dead_or_set_p (scan, reg)) | ||
| 6681 | + { | ||
| 6682 | + unused_cast = true; | ||
| 6683 | + break; | ||
| 6684 | + } | ||
| 6685 | + } | ||
| 6686 | + | ||
| 6687 | + /* Check if we have unresolved conditional jumps */ | ||
| 6688 | + if (label_ref != NULL_RTX) | ||
| 6689 | + continue; | ||
| 6690 | + | ||
| 6691 | + if (unused_cast) | ||
| 6692 | + { | ||
| 6693 | + if (REGNO (reg) == REGNO (XEXP (SET_SRC (PATTERN (insn)), 0))) | ||
| 6694 | + { | ||
| 6695 | + /* One operand cast, safe to delete */ | ||
| 6696 | + if (dump_file) | ||
| 6697 | + { | ||
| 6698 | + fprintf (dump_file, | ||
| 6699 | + ";; INSN %i removed, casted register %i value not used.\n", | ||
| 6700 | + INSN_UID (insn), REGNO (reg)); | ||
| 6701 | + } | ||
| 6702 | + SET_INSN_DELETED (insn); | ||
| 6703 | + /* Force the instruction to be recognized again */ | ||
| 6704 | + INSN_CODE (insn) = -1; | ||
| 6705 | + } | ||
| 6706 | + else | ||
| 6707 | + { | ||
| 6708 | + /* Two operand cast, which really could be substituted with | ||
| 6709 | + a move, if the source register is dead after the cast | ||
| 6710 | + insn and then the insn which sets the source register | ||
| 6711 | + could instead directly set the destination register for | ||
| 6712 | + the cast. As long as there are no insns in between which | ||
| 6713 | + uses the register. */ | ||
| 6714 | + rtx link = NULL_RTX; | ||
| 6715 | + rtx set; | ||
| 6716 | + rtx src_reg = XEXP (SET_SRC (PATTERN (insn)), 0); | ||
| 6717 | + unused_cast = false; | ||
| 6718 | + | ||
| 6719 | + if (!find_reg_note (insn, REG_DEAD, src_reg)) | ||
| 6720 | + continue; | ||
| 6721 | + | ||
| 6722 | + /* Search for the insn which sets the source register */ | ||
| 6723 | + for (link = LOG_LINKS (insn); link; link = XEXP (link, 1)) | ||
| 6724 | + { | ||
| 6725 | + if (REG_NOTE_KIND (link) != 0) | ||
| 6726 | + continue; | ||
| 6727 | + set = single_set (XEXP (link, 0)); | ||
| 6728 | + if (set && rtx_equal_p (src_reg, SET_DEST (set))) | ||
| 6729 | + { | ||
| 6730 | + link = XEXP (link, 0); | ||
| 6731 | + break; | ||
| 6732 | + } | ||
| 6733 | + } | ||
| 6734 | + | ||
| 6735 | + /* Found no link or link is a call insn where we can not | ||
| 6736 | + change the destination register */ | ||
| 6737 | + if (link == NULL_RTX || CALL_P (link)) | ||
| 6738 | + continue; | ||
| 6739 | + | ||
| 6740 | + /* Scan through all insn between link and insn */ | ||
| 6741 | + for (scan = NEXT_INSN (link); scan; scan = NEXT_INSN (scan)) | ||
| 6742 | + { | ||
| 6743 | + /* Don't try to trace forward past a CODE_LABEL if we | ||
| 6744 | + haven't seen INSN yet. Ordinarily, we will only | ||
| 6745 | + find the setting insn in LOG_LINKS if it is in the | ||
| 6746 | + same basic block. However, cross-jumping can insert | ||
| 6747 | + code labels in between the load and the call, and | ||
| 6748 | + can result in situations where a single call insn | ||
| 6749 | + may have two targets depending on where we came | ||
| 6750 | + from. */ | ||
| 6751 | + | ||
| 6752 | + if (GET_CODE (scan) == CODE_LABEL) | ||
| 6753 | + break; | ||
| 6754 | + | ||
| 6755 | + if (!INSN_P (scan)) | ||
| 6756 | + continue; | ||
| 6757 | + | ||
| 6758 | + /* Don't try to trace forward past a JUMP. To optimize | ||
| 6759 | + safely, we would have to check that all the | ||
| 6760 | + instructions at the jump destination did not use REG. | ||
| 6761 | + */ | ||
| 6762 | + | ||
| 6763 | + if (GET_CODE (scan) == JUMP_INSN) | ||
| 6764 | + { | ||
| 6765 | + break; | ||
| 6766 | + } | ||
| 6767 | + | ||
| 6768 | + if (!reg_mentioned_p (src_reg, PATTERN (scan))) | ||
| 6769 | + continue; | ||
| 6770 | + | ||
| 6771 | + /* We have reached the cast insn */ | ||
| 6772 | + if (scan == insn) | ||
| 6773 | + { | ||
| 6774 | + /* We can remove cast and replace the destination | ||
| 6775 | + register of the link insn with the destination | ||
| 6776 | + of the cast */ | ||
| 6777 | + if (dump_file) | ||
| 6778 | + { | ||
| 6779 | + fprintf (dump_file, | ||
| 6780 | + ";; INSN %i removed, casted value unused. " | ||
| 6781 | + "Destination of removed cast operation: register %i, folded into INSN %i.\n", | ||
| 6782 | + INSN_UID (insn), REGNO (reg), | ||
| 6783 | + INSN_UID (link)); | ||
| 6784 | + } | ||
| 6785 | + /* Update link insn */ | ||
| 6786 | + SET_DEST (PATTERN (link)) = | ||
| 6787 | + gen_rtx_REG (mode, REGNO (reg)); | ||
| 6788 | + /* Force the instruction to be recognized again */ | ||
| 6789 | + INSN_CODE (link) = -1; | ||
| 6790 | + | ||
| 6791 | + /* Delete insn */ | ||
| 6792 | + SET_INSN_DELETED (insn); | ||
| 6793 | + /* Force the instruction to be recognized again */ | ||
| 6794 | + INSN_CODE (insn) = -1; | ||
| 6795 | + break; | ||
| 6796 | + } | ||
| 6797 | + } | ||
| 6798 | + } | ||
| 6799 | + } | ||
| 6800 | + } | ||
| 6801 | + } | ||
| 6802 | + | ||
| 6803 | + if (TARGET_MD_REORG_OPTIMIZATION && (optimize_size || (optimize > 0))) | ||
| 6804 | + { | ||
| 6805 | + | ||
| 6806 | + /* Scan through all insns looking for shifted add operations */ | ||
| 6807 | + if (dump_file) | ||
| 6808 | + { | ||
| 6809 | + fprintf (dump_file, | ||
| 6810 | + ";; Deleting redundant shifted add operations:\n"); | ||
| 6811 | + } | ||
| 6812 | + for (insn = first; insn; insn = NEXT_INSN (insn)) | ||
| 6813 | + { | ||
| 6814 | + rtx reg, mem_expr, scan, op0, op1; | ||
| 6815 | + int add_only_used_as_pointer; | ||
| 6816 | + | ||
| 6817 | + if (INSN_P (insn) | ||
| 6818 | + && GET_CODE (PATTERN (insn)) == SET | ||
| 6819 | + && GET_CODE (SET_SRC (PATTERN (insn))) == PLUS | ||
| 6820 | + && (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == MULT | ||
| 6821 | + || GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == ASHIFT) | ||
| 6822 | + && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1)) == | ||
| 6823 | + CONST_INT && REG_P (SET_DEST (PATTERN (insn))) | ||
| 6824 | + && REG_P (XEXP (SET_SRC (PATTERN (insn)), 1)) | ||
| 6825 | + && REG_P (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0))) | ||
| 6826 | + { | ||
| 6827 | + reg = SET_DEST (PATTERN (insn)); | ||
| 6828 | + mem_expr = SET_SRC (PATTERN (insn)); | ||
| 6829 | + op0 = XEXP (XEXP (mem_expr, 0), 0); | ||
| 6830 | + op1 = XEXP (mem_expr, 1); | ||
| 6831 | + } | ||
| 6832 | + else | ||
| 6833 | + { | ||
| 6834 | + continue; | ||
| 6835 | + } | ||
| 6836 | + | ||
| 6837 | + /* Scan forward the check if the result of the shifted add | ||
| 6838 | + operation is only used as an address in memory operations and | ||
| 6839 | + that the operands to the shifted add are not clobbered. */ | ||
| 6840 | + add_only_used_as_pointer = false; | ||
| 6841 | + for (scan = NEXT_INSN (insn); scan; scan = NEXT_INSN (scan)) | ||
| 6842 | + { | ||
| 6843 | + if (!INSN_P (scan)) | ||
| 6844 | + continue; | ||
| 6845 | + | ||
| 6846 | + /* Don't try to trace forward past a JUMP or CALL. To optimize | ||
| 6847 | + safely, we would have to check that all the instructions at | ||
| 6848 | + the jump destination did not use REG. */ | ||
| 6849 | + | ||
| 6850 | + if (GET_CODE (scan) == JUMP_INSN) | ||
| 6851 | + { | ||
| 6852 | + break; | ||
| 6853 | + } | ||
| 6854 | + | ||
| 6855 | + /* If used in a call insn then we cannot optimize it away */ | ||
| 6856 | + if (CALL_P (scan) && find_regno_fusage (scan, USE, REGNO (reg))) | ||
| 6857 | + break; | ||
| 6858 | + | ||
| 6859 | + /* If any of the operands of the shifted add are clobbered we | ||
| 6860 | + cannot optimize the shifted adda away */ | ||
| 6861 | + if ((reg_set_p (op0, scan) && (REGNO (op0) != REGNO (reg))) | ||
| 6862 | + || (reg_set_p (op1, scan) && (REGNO (op1) != REGNO (reg)))) | ||
| 6863 | + break; | ||
| 6864 | + | ||
| 6865 | + if (!reg_mentioned_p (reg, PATTERN (scan))) | ||
| 6866 | + continue; | ||
| 6867 | + | ||
| 6868 | + /* If used any other place than as a pointer or as the | ||
| 6869 | + destination register we failed */ | ||
| 6870 | + if (!(single_set (scan) | ||
| 6871 | + && GET_CODE (PATTERN (scan)) == SET | ||
| 6872 | + && ((MEM_P (SET_DEST (PATTERN (scan))) | ||
| 6873 | + && REG_P (XEXP (SET_DEST (PATTERN (scan)), 0)) | ||
| 6874 | + && REGNO (XEXP (SET_DEST (PATTERN (scan)), 0)) == | ||
| 6875 | + REGNO (reg)) || (MEM_P (SET_SRC (PATTERN (scan))) | ||
| 6876 | + && | ||
| 6877 | + REG_P (XEXP | ||
| 6878 | + (SET_SRC (PATTERN (scan)), | ||
| 6879 | + 0)) | ||
| 6880 | + && | ||
| 6881 | + REGNO (XEXP | ||
| 6882 | + (SET_SRC (PATTERN (scan)), | ||
| 6883 | + 0)) == REGNO (reg)))) | ||
| 6884 | + && !(GET_CODE (PATTERN (scan)) == SET | ||
| 6885 | + && REG_P (SET_DEST (PATTERN (scan))) | ||
| 6886 | + && !regno_use_in (REGNO (reg), | ||
| 6887 | + SET_SRC (PATTERN (scan))))) | ||
| 6888 | + break; | ||
| 6889 | + | ||
| 6890 | + /* Check if register is dead or set in this insn */ | ||
| 6891 | + if (dead_or_set_p (scan, reg)) | ||
| 6892 | + { | ||
| 6893 | + add_only_used_as_pointer = true; | ||
| 6894 | + break; | ||
| 6895 | + } | ||
| 6896 | + } | ||
| 6897 | + | ||
| 6898 | + if (add_only_used_as_pointer) | ||
| 6899 | + { | ||
| 6900 | + /* Lets delete the add insn and replace all memory references | ||
| 6901 | + which uses the pointer with the full expression. */ | ||
| 6902 | + if (dump_file) | ||
| 6903 | + { | ||
| 6904 | + fprintf (dump_file, | ||
| 6905 | + ";; Deleting INSN %i since address expression can be folded into all " | ||
| 6906 | + "memory references using this expression\n", | ||
| 6907 | + INSN_UID (insn)); | ||
| 6908 | + } | ||
| 6909 | + SET_INSN_DELETED (insn); | ||
| 6910 | + /* Force the instruction to be recognized again */ | ||
| 6911 | + INSN_CODE (insn) = -1; | ||
| 6912 | + | ||
| 6913 | + for (scan = NEXT_INSN (insn); scan; scan = NEXT_INSN (scan)) | ||
| 6914 | + { | ||
| 6915 | + if (!INSN_P (scan)) | ||
| 6916 | + continue; | ||
| 6917 | + | ||
| 6918 | + if (!reg_mentioned_p (reg, PATTERN (scan))) | ||
| 6919 | + continue; | ||
| 6920 | + | ||
| 6921 | + /* If used any other place than as a pointer or as the | ||
| 6922 | + destination register we failed */ | ||
| 6923 | + if ((single_set (scan) | ||
| 6924 | + && GET_CODE (PATTERN (scan)) == SET | ||
| 6925 | + && ((MEM_P (SET_DEST (PATTERN (scan))) | ||
| 6926 | + && REG_P (XEXP (SET_DEST (PATTERN (scan)), 0)) | ||
| 6927 | + && REGNO (XEXP (SET_DEST (PATTERN (scan)), 0)) == | ||
| 6928 | + REGNO (reg)) || (MEM_P (SET_SRC (PATTERN (scan))) | ||
| 6929 | + && | ||
| 6930 | + REG_P (XEXP | ||
| 6931 | + (SET_SRC (PATTERN (scan)), | ||
| 6932 | + 0)) | ||
| 6933 | + && | ||
| 6934 | + REGNO (XEXP | ||
| 6935 | + (SET_SRC (PATTERN (scan)), | ||
| 6936 | + 0)) == REGNO (reg))))) | ||
| 6937 | + { | ||
| 6938 | + if (dump_file) | ||
| 6939 | + { | ||
| 6940 | + fprintf (dump_file, | ||
| 6941 | + ";; Register %i replaced by indexed address in INSN %i\n", | ||
| 6942 | + REGNO (reg), INSN_UID (scan)); | ||
| 6943 | + } | ||
| 6944 | + if (MEM_P (SET_DEST (PATTERN (scan)))) | ||
| 6945 | + XEXP (SET_DEST (PATTERN (scan)), 0) = mem_expr; | ||
| 6946 | + else | ||
| 6947 | + XEXP (SET_SRC (PATTERN (scan)), 0) = mem_expr; | ||
| 6948 | + } | ||
| 6949 | + | ||
| 6950 | + /* Check if register is dead or set in this insn */ | ||
| 6951 | + if (dead_or_set_p (scan, reg)) | ||
| 6952 | + { | ||
| 6953 | + break; | ||
| 6954 | + } | ||
| 6955 | + | ||
| 6956 | + } | ||
| 6957 | + } | ||
| 6958 | + } | ||
| 6959 | + } | ||
| 6960 | +} | ||
| 6961 | + | ||
| 6962 | +/* Exported to toplev.c. | ||
| 6963 | + | ||
| 6964 | + Do a final pass over the function, just before delayed branch | ||
| 6965 | + scheduling. */ | ||
| 6966 | + | ||
| 6967 | +static void | ||
| 6968 | +avr32_reorg (void) | ||
| 6969 | +{ | ||
| 6970 | + rtx insn; | ||
| 6971 | + HOST_WIDE_INT address = 0; | ||
| 6972 | + Mfix *fix; | ||
| 6973 | + | ||
| 6974 | + minipool_fix_head = minipool_fix_tail = NULL; | ||
| 6975 | + | ||
| 6976 | + /* The first insn must always be a note, or the code below won't scan it | ||
| 6977 | + properly. */ | ||
| 6978 | + insn = get_insns (); | ||
| 6979 | + if (GET_CODE (insn) != NOTE) | ||
| 6980 | + abort (); | ||
| 6981 | + | ||
| 6982 | + /* Scan all the insns and record the operands that will need fixing. */ | ||
| 6983 | + for (insn = next_nonnote_insn (insn); insn; insn = next_nonnote_insn (insn)) | ||
| 6984 | + { | ||
| 6985 | + if (GET_CODE (insn) == BARRIER) | ||
| 6986 | + push_minipool_barrier (insn, address); | ||
| 6987 | + else if (INSN_P (insn)) | ||
| 6988 | + { | ||
| 6989 | + rtx table; | ||
| 6990 | + | ||
| 6991 | + note_invalid_constants (insn, address, true); | ||
| 6992 | + address += get_attr_length (insn); | ||
| 6993 | + | ||
| 6994 | + /* If the insn is a vector jump, add the size of the table and skip | ||
| 6995 | + the table. */ | ||
| 6996 | + if ((table = is_jump_table (insn)) != NULL) | ||
| 6997 | + { | ||
| 6998 | + address += get_jump_table_size (table); | ||
| 6999 | + insn = table; | ||
| 7000 | + } | ||
| 7001 | + } | ||
| 7002 | + } | ||
| 7003 | + | ||
| 7004 | + fix = minipool_fix_head; | ||
| 7005 | + | ||
| 7006 | + /* Now scan the fixups and perform the required changes. */ | ||
| 7007 | + while (fix) | ||
| 7008 | + { | ||
| 7009 | + Mfix *ftmp; | ||
| 7010 | + Mfix *fdel; | ||
| 7011 | + Mfix *last_added_fix; | ||
| 7012 | + Mfix *last_barrier = NULL; | ||
| 7013 | + Mfix *this_fix; | ||
| 7014 | + | ||
| 7015 | + /* Skip any further barriers before the next fix. */ | ||
| 7016 | + while (fix && GET_CODE (fix->insn) == BARRIER) | ||
| 7017 | + fix = fix->next; | ||
| 7018 | + | ||
| 7019 | + /* No more fixes. */ | ||
| 7020 | + if (fix == NULL) | ||
| 7021 | + break; | ||
| 7022 | + | ||
| 7023 | + last_added_fix = NULL; | ||
| 7024 | + | ||
| 7025 | + for (ftmp = fix; ftmp; ftmp = ftmp->next) | ||
| 7026 | + { | ||
| 7027 | + if (GET_CODE (ftmp->insn) == BARRIER) | ||
| 7028 | + { | ||
| 7029 | + if (ftmp->address >= minipool_vector_head->max_address) | ||
| 7030 | + break; | ||
| 7031 | + | ||
| 7032 | + last_barrier = ftmp; | ||
| 7033 | + } | ||
| 7034 | + else if ((ftmp->minipool = add_minipool_forward_ref (ftmp)) == NULL) | ||
| 7035 | + break; | ||
| 7036 | + | ||
| 7037 | + last_added_fix = ftmp; /* Keep track of the last fix added. | ||
| 7038 | + */ | ||
| 7039 | + } | ||
| 7040 | + | ||
| 7041 | + /* If we found a barrier, drop back to that; any fixes that we could | ||
| 7042 | + have reached but come after the barrier will now go in the next | ||
| 7043 | + mini-pool. */ | ||
| 7044 | + if (last_barrier != NULL) | ||
| 7045 | + { | ||
| 7046 | + /* Reduce the refcount for those fixes that won't go into this pool | ||
| 7047 | + after all. */ | ||
| 7048 | + for (fdel = last_barrier->next; | ||
| 7049 | + fdel && fdel != ftmp; fdel = fdel->next) | ||
| 7050 | + { | ||
| 7051 | + fdel->minipool->refcount--; | ||
| 7052 | + fdel->minipool = NULL; | ||
| 7053 | + } | ||
| 7054 | + | ||
| 7055 | + ftmp = last_barrier; | ||
| 7056 | + } | ||
| 7057 | + else | ||
| 7058 | + { | ||
| 7059 | + /* ftmp is first fix that we can't fit into this pool and there no | ||
| 7060 | + natural barriers that we could use. Insert a new barrier in the | ||
| 7061 | + code somewhere between the previous fix and this one, and | ||
| 7062 | + arrange to jump around it. */ | ||
| 7063 | + HOST_WIDE_INT max_address; | ||
| 7064 | + | ||
| 7065 | + /* The last item on the list of fixes must be a barrier, so we can | ||
| 7066 | + never run off the end of the list of fixes without last_barrier | ||
| 7067 | + being set. */ | ||
| 7068 | + if (ftmp == NULL) | ||
| 7069 | + abort (); | ||
| 7070 | + | ||
| 7071 | + max_address = minipool_vector_head->max_address; | ||
| 7072 | + /* Check that there isn't another fix that is in range that we | ||
| 7073 | + couldn't fit into this pool because the pool was already too | ||
| 7074 | + large: we need to put the pool before such an instruction. */ | ||
| 7075 | + if (ftmp->address < max_address) | ||
| 7076 | + max_address = ftmp->address; | ||
| 7077 | + | ||
| 7078 | + last_barrier = create_fix_barrier (last_added_fix, max_address); | ||
| 7079 | + } | ||
| 7080 | + | ||
| 7081 | + assign_minipool_offsets (last_barrier); | ||
| 7082 | + | ||
| 7083 | + while (ftmp) | ||
| 7084 | + { | ||
| 7085 | + if (GET_CODE (ftmp->insn) != BARRIER | ||
| 7086 | + && ((ftmp->minipool = add_minipool_backward_ref (ftmp)) | ||
| 7087 | + == NULL)) | ||
| 7088 | + break; | ||
| 7089 | + | ||
| 7090 | + ftmp = ftmp->next; | ||
| 7091 | + } | ||
| 7092 | + | ||
| 7093 | + /* Scan over the fixes we have identified for this pool, fixing them up | ||
| 7094 | + and adding the constants to the pool itself. */ | ||
| 7095 | + for (this_fix = fix; this_fix && ftmp != this_fix; | ||
| 7096 | + this_fix = this_fix->next) | ||
| 7097 | + if (GET_CODE (this_fix->insn) != BARRIER | ||
| 7098 | + /* Do nothing for entries present just to force the insertion of | ||
| 7099 | + a minipool. */ | ||
| 7100 | + && !IS_FORCE_MINIPOOL (this_fix->value)) | ||
| 7101 | + { | ||
| 7102 | + rtx addr = plus_constant (gen_rtx_LABEL_REF (VOIDmode, | ||
| 7103 | + minipool_vector_label), | ||
| 7104 | + this_fix->minipool->offset); | ||
| 7105 | + *this_fix->loc = gen_rtx_MEM (this_fix->mode, addr); | ||
| 7106 | + } | ||
| 7107 | + | ||
| 7108 | + dump_minipool (last_barrier->insn); | ||
| 7109 | + fix = ftmp; | ||
| 7110 | + } | ||
| 7111 | + | ||
| 7112 | + /* Free the minipool memory. */ | ||
| 7113 | + obstack_free (&minipool_obstack, minipool_startobj); | ||
| 7114 | + | ||
| 7115 | + avr32_reorg_optimization (); | ||
| 7116 | +} | ||
| 7117 | + | ||
| 7118 | + | ||
| 7119 | +/* | ||
| 7120 | + Hook for doing some final scanning of instructions. Does nothing yet...*/ | ||
| 7121 | +void | ||
| 7122 | +avr32_final_prescan_insn (rtx insn ATTRIBUTE_UNUSED, | ||
| 7123 | + rtx * opvec ATTRIBUTE_UNUSED, | ||
| 7124 | + int noperands ATTRIBUTE_UNUSED) | ||
| 7125 | +{ | ||
| 7126 | + return; | ||
| 7127 | +} | ||
| 7128 | + | ||
| 7129 | + | ||
| 7130 | + | ||
| 7131 | +int | ||
| 7132 | +avr32_expand_movcc (enum machine_mode mode, rtx operands[]) | ||
| 7133 | +{ | ||
| 7134 | + rtx operator; | ||
| 7135 | + rtx compare_op0 = avr32_compare_op0; | ||
| 7136 | + rtx compare_op1 = avr32_compare_op1; | ||
| 7137 | + | ||
| 7138 | + /* Only allow certain compare operations */ | ||
| 7139 | + if (GET_MODE (compare_op0) != DImode | ||
| 7140 | + && GET_MODE (compare_op0) != SImode | ||
| 7141 | + && GET_MODE (compare_op0) != HImode && GET_MODE (compare_op0) != QImode) | ||
| 7142 | + return FALSE; | ||
| 7143 | + | ||
| 7144 | + if (GET_CODE (compare_op0) == MEM) | ||
| 7145 | + { | ||
| 7146 | + if (no_new_pseudos) | ||
| 7147 | + return FALSE; | ||
| 7148 | + else | ||
| 7149 | + compare_op0 = force_reg (GET_MODE (compare_op0), compare_op0); | ||
| 7150 | + } | ||
| 7151 | + | ||
| 7152 | + if (GET_CODE (compare_op1) == MEM) | ||
| 7153 | + { | ||
| 7154 | + if (no_new_pseudos) | ||
| 7155 | + return FALSE; | ||
| 7156 | + else | ||
| 7157 | + compare_op1 = force_reg (GET_MODE (compare_op1), compare_op1); | ||
| 7158 | + } | ||
| 7159 | + | ||
| 7160 | + /* For DI, HI and QI mode force comparison operands to registers */ | ||
| 7161 | + if (GET_MODE (compare_op0) == DImode | ||
| 7162 | + || GET_MODE (compare_op0) == HImode || GET_MODE (compare_op0) == QImode) | ||
| 7163 | + { | ||
| 7164 | + if (GET_CODE (compare_op0) != REG) | ||
| 7165 | + { | ||
| 7166 | + if (no_new_pseudos) | ||
| 7167 | + return FALSE; | ||
| 7168 | + else | ||
| 7169 | + compare_op0 = force_reg (GET_MODE (compare_op0), compare_op0); | ||
| 7170 | + } | ||
| 7171 | + | ||
| 7172 | + if (GET_CODE (compare_op1) != REG) | ||
| 7173 | + { | ||
| 7174 | + if (no_new_pseudos) | ||
| 7175 | + return FALSE; | ||
| 7176 | + else | ||
| 7177 | + compare_op1 = force_reg (GET_MODE (compare_op0), compare_op1); | ||
| 7178 | + } | ||
| 7179 | + } | ||
| 7180 | + | ||
| 7181 | + /* Force any immediate compare operands for SI, larger than the L | ||
| 7182 | + constraint, to a register */ | ||
| 7183 | + if (GET_MODE (compare_op0) == SImode) | ||
| 7184 | + { | ||
| 7185 | + if ((GET_CODE (compare_op0) == CONST_INT | ||
| 7186 | + && !avr32_const_ok_for_constraint_p (INTVAL (compare_op0), 'K', | ||
| 7187 | + "Ks21"))) | ||
| 7188 | + { | ||
| 7189 | + if (no_new_pseudos) | ||
| 7190 | + return FALSE; | ||
| 7191 | + else | ||
| 7192 | + compare_op0 = force_reg (SImode, compare_op0); | ||
| 7193 | + } | ||
| 7194 | + | ||
| 7195 | + if ((GET_CODE (compare_op1) == CONST_INT | ||
| 7196 | + && !avr32_const_ok_for_constraint_p (INTVAL (compare_op1), 'K', | ||
| 7197 | + "Ks21"))) | ||
| 7198 | + { | ||
| 7199 | + if (no_new_pseudos) | ||
| 7200 | + return FALSE; | ||
| 7201 | + else | ||
| 7202 | + compare_op1 = force_reg (SImode, compare_op1); | ||
| 7203 | + } | ||
| 7204 | + } | ||
| 7205 | + | ||
| 7206 | + /* If we have immediates larger than can be allowed in conditional mov | ||
| 7207 | + instructions, force them to registers */ | ||
| 7208 | + if (GET_CODE (operands[2]) == CONST_INT | ||
| 7209 | + && !avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks08")) | ||
| 7210 | + { | ||
| 7211 | + if (no_new_pseudos) | ||
| 7212 | + return FALSE; | ||
| 7213 | + else | ||
| 7214 | + operands[2] = force_reg (mode, operands[2]); | ||
| 7215 | + } | ||
| 7216 | + | ||
| 7217 | + if (GET_CODE (operands[3]) == CONST_INT | ||
| 7218 | + && !avr32_const_ok_for_constraint_p (INTVAL (operands[3]), 'K', "Ks08")) | ||
| 7219 | + { | ||
| 7220 | + if (no_new_pseudos) | ||
| 7221 | + return FALSE; | ||
| 7222 | + else | ||
| 7223 | + operands[3] = force_reg (mode, operands[3]); | ||
| 7224 | + } | ||
| 7225 | + | ||
| 7226 | + /* Emit the actual instruction */ | ||
| 7227 | + operator = gen_rtx_EQ (VOIDmode, const0_rtx, const0_rtx); | ||
| 7228 | + PUT_CODE (operator, GET_CODE (operands[1])); | ||
| 7229 | + switch (mode) | ||
| 7230 | + { | ||
| 7231 | + case SImode: | ||
| 7232 | + switch (GET_MODE (compare_op0)) | ||
| 7233 | + { | ||
| 7234 | + case SImode: | ||
| 7235 | + emit_insn (gen_movsicc_cmpsi | ||
| 7236 | + (operands[0], operator, operands[2], operands[3], | ||
| 7237 | + compare_op0, compare_op1)); | ||
| 7238 | + break; | ||
| 7239 | + case DImode: | ||
| 7240 | + emit_insn (gen_movsicc_cmpdi | ||
| 7241 | + (operands[0], operator, operands[2], operands[3], | ||
| 7242 | + compare_op0, compare_op1)); | ||
| 7243 | + break; | ||
| 7244 | + case HImode: | ||
| 7245 | + emit_insn (gen_movsicc_cmphi | ||
| 7246 | + (operands[0], operator, operands[2], operands[3], | ||
| 7247 | + compare_op0, compare_op1)); | ||
| 7248 | + break; | ||
| 7249 | + case QImode: | ||
| 7250 | + emit_insn (gen_movsicc_cmpqi | ||
| 7251 | + (operands[0], operator, operands[2], operands[3], | ||
| 7252 | + compare_op0, compare_op1)); | ||
| 7253 | + break; | ||
| 7254 | + default: | ||
| 7255 | + return FALSE; | ||
| 7256 | + } | ||
| 7257 | + break; | ||
| 7258 | + case HImode: | ||
| 7259 | + switch (GET_MODE (compare_op0)) | ||
| 7260 | + { | ||
| 7261 | + case SImode: | ||
| 7262 | + emit_insn (gen_movhicc_cmpsi | ||
| 7263 | + (operands[0], operator, operands[2], operands[3], | ||
| 7264 | + compare_op0, compare_op1)); | ||
| 7265 | + break; | ||
| 7266 | + case DImode: | ||
| 7267 | + emit_insn (gen_movhicc_cmpdi | ||
| 7268 | + (operands[0], operator, operands[2], operands[3], | ||
| 7269 | + compare_op0, compare_op1)); | ||
| 7270 | + break; | ||
| 7271 | + case HImode: | ||
| 7272 | + emit_insn (gen_movhicc_cmphi | ||
| 7273 | + (operands[0], operator, operands[2], operands[3], | ||
| 7274 | + compare_op0, compare_op1)); | ||
| 7275 | + break; | ||
| 7276 | + case QImode: | ||
| 7277 | + emit_insn (gen_movhicc_cmpqi | ||
| 7278 | + (operands[0], operator, operands[2], operands[3], | ||
| 7279 | + compare_op0, compare_op1)); | ||
| 7280 | + break; | ||
| 7281 | + default: | ||
| 7282 | + return FALSE; | ||
| 7283 | + } | ||
| 7284 | + break; | ||
| 7285 | + case QImode: | ||
| 7286 | + switch (GET_MODE (compare_op0)) | ||
| 7287 | + { | ||
| 7288 | + case SImode: | ||
| 7289 | + emit_insn (gen_movqicc_cmpsi | ||
| 7290 | + (operands[0], operator, operands[2], operands[3], | ||
| 7291 | + compare_op0, compare_op1)); | ||
| 7292 | + break; | ||
| 7293 | + case DImode: | ||
| 7294 | + emit_insn (gen_movqicc_cmpdi | ||
| 7295 | + (operands[0], operator, operands[2], operands[3], | ||
| 7296 | + compare_op0, compare_op1)); | ||
| 7297 | + break; | ||
| 7298 | + case HImode: | ||
| 7299 | + emit_insn (gen_movqicc_cmphi | ||
| 7300 | + (operands[0], operator, operands[2], operands[3], | ||
| 7301 | + compare_op0, compare_op1)); | ||
| 7302 | + break; | ||
| 7303 | + case QImode: | ||
| 7304 | + emit_insn (gen_movqicc_cmpqi | ||
| 7305 | + (operands[0], operator, operands[2], operands[3], | ||
| 7306 | + compare_op0, compare_op1)); | ||
| 7307 | + break; | ||
| 7308 | + default: | ||
| 7309 | + return FALSE; | ||
| 7310 | + } | ||
| 7311 | + break; | ||
| 7312 | + default: | ||
| 7313 | + return FALSE; | ||
| 7314 | + } | ||
| 7315 | + | ||
| 7316 | + return TRUE; | ||
| 7317 | +} | ||
| 7318 | + | ||
| 7319 | + | ||
| 7320 | +int | ||
| 7321 | +avr32_expand_addcc (enum machine_mode mode, rtx operands[]) | ||
| 7322 | +{ | ||
| 7323 | + rtx operator; | ||
| 7324 | + rtx compare_op0 = avr32_compare_op0; | ||
| 7325 | + rtx compare_op1 = avr32_compare_op1; | ||
| 7326 | + | ||
| 7327 | + /* Check if we have an add/sub with an k8 immediate */ | ||
| 7328 | + if (!(GET_CODE (operands[3]) == CONST_INT | ||
| 7329 | + && avr32_const_ok_for_constraint_p (-INTVAL (operands[3]), 'K', | ||
| 7330 | + "Ks08"))) | ||
| 7331 | + return FALSE; | ||
| 7332 | + else | ||
| 7333 | + /* Flip sign */ | ||
| 7334 | + operands[3] = GEN_INT (-INTVAL (operands[3])); | ||
| 7335 | + | ||
| 7336 | + /* Only allow certain compare operations */ | ||
| 7337 | + if (GET_MODE (compare_op0) != DImode | ||
| 7338 | + && GET_MODE (compare_op0) != SImode | ||
| 7339 | + && GET_MODE (compare_op0) != HImode && GET_MODE (compare_op0) != QImode) | ||
| 7340 | + return FALSE; | ||
| 7341 | + | ||
| 7342 | + if (GET_CODE (compare_op0) == MEM) | ||
| 7343 | + { | ||
| 7344 | + if (no_new_pseudos) | ||
| 7345 | + return FALSE; | ||
| 7346 | + else | ||
| 7347 | + compare_op0 = force_reg (GET_MODE (compare_op0), compare_op0); | ||
| 7348 | + } | ||
| 7349 | + | ||
| 7350 | + if (GET_CODE (compare_op1) == MEM) | ||
| 7351 | + { | ||
| 7352 | + if (no_new_pseudos) | ||
| 7353 | + return FALSE; | ||
| 7354 | + else | ||
| 7355 | + compare_op1 = force_reg (GET_MODE (compare_op1), compare_op1); | ||
| 7356 | + } | ||
| 7357 | + | ||
| 7358 | + /* For DI, HI and QI mode force comparison operands to registers */ | ||
| 7359 | + if (GET_MODE (compare_op0) == DImode | ||
| 7360 | + || GET_MODE (compare_op0) == HImode || GET_MODE (compare_op0) == QImode) | ||
| 7361 | + { | ||
| 7362 | + if (GET_CODE (compare_op0) != REG) | ||
| 7363 | + { | ||
| 7364 | + if (no_new_pseudos) | ||
| 7365 | + return FALSE; | ||
| 7366 | + else | ||
| 7367 | + compare_op0 = force_reg (GET_MODE (compare_op0), compare_op0); | ||
| 7368 | + } | ||
| 7369 | + | ||
| 7370 | + if (GET_CODE (compare_op1) != REG) | ||
| 7371 | + { | ||
| 7372 | + if (no_new_pseudos) | ||
| 7373 | + return FALSE; | ||
| 7374 | + else | ||
| 7375 | + compare_op1 = force_reg (GET_MODE (compare_op0), compare_op1); | ||
| 7376 | + } | ||
| 7377 | + } | ||
| 7378 | + | ||
| 7379 | + /* Force any immediate compare operands for SI, larger than the L | ||
| 7380 | + constraint, to a register */ | ||
| 7381 | + if (GET_MODE (compare_op0) == SImode) | ||
| 7382 | + { | ||
| 7383 | + if ((GET_CODE (compare_op0) == CONST_INT | ||
| 7384 | + && !avr32_const_ok_for_constraint_p (INTVAL (compare_op0), 'K', | ||
| 7385 | + "Ks21"))) | ||
| 7386 | + { | ||
| 7387 | + if (no_new_pseudos) | ||
| 7388 | + return FALSE; | ||
| 7389 | + else | ||
| 7390 | + compare_op0 = force_reg (SImode, compare_op0); | ||
| 7391 | + } | ||
| 7392 | + | ||
| 7393 | + if ((GET_CODE (compare_op1) == CONST_INT | ||
| 7394 | + && !avr32_const_ok_for_constraint_p (INTVAL (compare_op1), 'K', | ||
| 7395 | + "Ks21"))) | ||
| 7396 | + { | ||
| 7397 | + if (no_new_pseudos) | ||
| 7398 | + return FALSE; | ||
| 7399 | + else | ||
| 7400 | + compare_op1 = force_reg (SImode, compare_op1); | ||
| 7401 | + } | ||
| 7402 | + } | ||
| 7403 | + | ||
| 7404 | + /* If we have immediates larger than can be allowed in conditional mov | ||
| 7405 | + instructions, force them to registers */ | ||
| 7406 | + if (GET_CODE (operands[2]) == CONST_INT | ||
| 7407 | + && !avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks08")) | ||
| 7408 | + { | ||
| 7409 | + if (no_new_pseudos) | ||
| 7410 | + return FALSE; | ||
| 7411 | + else | ||
| 7412 | + operands[2] = force_reg (mode, operands[2]); | ||
| 7413 | + } | ||
| 7414 | + | ||
| 7415 | + if (GET_CODE (operands[3]) == CONST_INT | ||
| 7416 | + && !avr32_const_ok_for_constraint_p (INTVAL (operands[3]), 'K', "Ks08")) | ||
| 7417 | + { | ||
| 7418 | + if (no_new_pseudos) | ||
| 7419 | + return FALSE; | ||
| 7420 | + else | ||
| 7421 | + operands[3] = force_reg (mode, operands[3]); | ||
| 7422 | + } | ||
| 7423 | + | ||
| 7424 | + if (GET_CODE (operands[0]) != REG) | ||
| 7425 | + { | ||
| 7426 | + if (no_new_pseudos) | ||
| 7427 | + return FALSE; | ||
| 7428 | + else | ||
| 7429 | + operands[0] = force_reg (GET_MODE (operands[0]), operands[0]); | ||
| 7430 | + } | ||
| 7431 | + | ||
| 7432 | + if (GET_CODE (operands[2]) != REG) | ||
| 7433 | + { | ||
| 7434 | + if (no_new_pseudos) | ||
| 7435 | + return FALSE; | ||
| 7436 | + else | ||
| 7437 | + operands[2] = force_reg (GET_MODE (operands[2]), operands[2]); | ||
| 7438 | + } | ||
| 7439 | + | ||
| 7440 | + /* Check if operands[0] and operands[2] are different */ | ||
| 7441 | + if (REGNO (operands[0]) != REGNO (operands[2])) | ||
| 7442 | + { | ||
| 7443 | + emit_move_insn (operands[0], operands[2]); | ||
| 7444 | + operands[2] = operands[0]; | ||
| 7445 | + } | ||
| 7446 | + | ||
| 7447 | + /* Emit the actual instruction */ | ||
| 7448 | + operator = gen_rtx_EQ (VOIDmode, const0_rtx, const0_rtx); | ||
| 7449 | + PUT_CODE (operator, GET_CODE (operands[1])); | ||
| 7450 | + switch (mode) | ||
| 7451 | + { | ||
| 7452 | + case SImode: | ||
| 7453 | + switch (GET_MODE (compare_op0)) | ||
| 7454 | + { | ||
| 7455 | + case SImode: | ||
| 7456 | + emit_insn (gen_addsicc_cmpsi | ||
| 7457 | + (operands[0], operator, operands[2], operands[3], | ||
| 7458 | + compare_op0, compare_op1)); | ||
| 7459 | + break; | ||
| 7460 | + case DImode: | ||
| 7461 | + emit_insn (gen_addsicc_cmpdi | ||
| 7462 | + (operands[0], operator, operands[2], operands[3], | ||
| 7463 | + compare_op0, compare_op1)); | ||
| 7464 | + break; | ||
| 7465 | + case HImode: | ||
| 7466 | + emit_insn (gen_addsicc_cmphi | ||
| 7467 | + (operands[0], operator, operands[2], operands[3], | ||
| 7468 | + compare_op0, compare_op1)); | ||
| 7469 | + break; | ||
| 7470 | + case QImode: | ||
| 7471 | + emit_insn (gen_addsicc_cmpqi | ||
| 7472 | + (operands[0], operator, operands[2], operands[3], | ||
| 7473 | + compare_op0, compare_op1)); | ||
| 7474 | + break; | ||
| 7475 | + default: | ||
| 7476 | + return FALSE; | ||
| 7477 | + } | ||
| 7478 | + break; | ||
| 7479 | + case HImode: | ||
| 7480 | + switch (GET_MODE (compare_op0)) | ||
| 7481 | + { | ||
| 7482 | + case SImode: | ||
| 7483 | + emit_insn (gen_addhicc_cmpsi | ||
| 7484 | + (operands[0], operator, operands[2], operands[3], | ||
| 7485 | + compare_op0, compare_op1)); | ||
| 7486 | + break; | ||
| 7487 | + case DImode: | ||
| 7488 | + emit_insn (gen_addhicc_cmpdi | ||
| 7489 | + (operands[0], operator, operands[2], operands[3], | ||
| 7490 | + compare_op0, compare_op1)); | ||
| 7491 | + break; | ||
| 7492 | + case HImode: | ||
| 7493 | + emit_insn (gen_addhicc_cmphi | ||
| 7494 | + (operands[0], operator, operands[2], operands[3], | ||
| 7495 | + compare_op0, compare_op1)); | ||
| 7496 | + break; | ||
| 7497 | + case QImode: | ||
| 7498 | + emit_insn (gen_addhicc_cmpqi | ||
| 7499 | + (operands[0], operator, operands[2], operands[3], | ||
| 7500 | + compare_op0, compare_op1)); | ||
| 7501 | + break; | ||
| 7502 | + default: | ||
| 7503 | + return FALSE; | ||
| 7504 | + } | ||
| 7505 | + break; | ||
| 7506 | + case QImode: | ||
| 7507 | + switch (GET_MODE (compare_op0)) | ||
| 7508 | + { | ||
| 7509 | + case SImode: | ||
| 7510 | + emit_insn (gen_addqicc_cmpsi | ||
| 7511 | + (operands[0], operator, operands[2], operands[3], | ||
| 7512 | + compare_op0, compare_op1)); | ||
| 7513 | + break; | ||
| 7514 | + case DImode: | ||
| 7515 | + emit_insn (gen_addqicc_cmpdi | ||
| 7516 | + (operands[0], operator, operands[2], operands[3], | ||
| 7517 | + compare_op0, compare_op1)); | ||
| 7518 | + break; | ||
| 7519 | + case HImode: | ||
| 7520 | + emit_insn (gen_addqicc_cmphi | ||
| 7521 | + (operands[0], operator, operands[2], operands[3], | ||
| 7522 | + compare_op0, compare_op1)); | ||
| 7523 | + break; | ||
| 7524 | + case QImode: | ||
| 7525 | + emit_insn (gen_addqicc_cmpqi | ||
| 7526 | + (operands[0], operator, operands[2], operands[3], | ||
| 7527 | + compare_op0, compare_op1)); | ||
| 7528 | + break; | ||
| 7529 | + default: | ||
| 7530 | + return FALSE; | ||
| 7531 | + } | ||
| 7532 | + break; | ||
| 7533 | + default: | ||
| 7534 | + return FALSE; | ||
| 7535 | + } | ||
| 7536 | + | ||
| 7537 | + return TRUE; | ||
| 7538 | +} | ||
| 7539 | + | ||
| 7540 | +/* Function for changing the condition on the next instruction, | ||
| 7541 | + should be used when emmiting compare instructions and | ||
| 7542 | + the condition of the next instruction needs to change. | ||
| 7543 | +*/ | ||
| 7544 | +int | ||
| 7545 | +set_next_insn_cond (rtx cur_insn, rtx new_cond) | ||
| 7546 | +{ | ||
| 7547 | + rtx next_insn = next_nonnote_insn (cur_insn); | ||
| 7548 | + if ((next_insn != NULL_RTX) | ||
| 7549 | + && (INSN_P (next_insn)) | ||
| 7550 | + && (GET_CODE (PATTERN (next_insn)) == SET) | ||
| 7551 | + && (GET_CODE (SET_SRC (PATTERN (next_insn))) == IF_THEN_ELSE)) | ||
| 7552 | + { | ||
| 7553 | + /* Branch instructions */ | ||
| 7554 | + XEXP (SET_SRC (PATTERN (next_insn)), 0) = new_cond; | ||
| 7555 | + /* Force the instruction to be recognized again */ | ||
| 7556 | + INSN_CODE (next_insn) = -1; | ||
| 7557 | + return TRUE; | ||
| 7558 | + } | ||
| 7559 | + else if ((next_insn != NULL_RTX) | ||
| 7560 | + && (INSN_P (next_insn)) | ||
| 7561 | + && (GET_CODE (PATTERN (next_insn)) == SET) | ||
| 7562 | + && comparison_operator (SET_SRC (PATTERN (next_insn)), | ||
| 7563 | + GET_MODE (SET_SRC (PATTERN (next_insn))))) | ||
| 7564 | + { | ||
| 7565 | + /* scc with no compare */ | ||
| 7566 | + SET_SRC (PATTERN (next_insn)) = new_cond; | ||
| 7567 | + /* Force the instruction to be recognized again */ | ||
| 7568 | + INSN_CODE (next_insn) = -1; | ||
| 7569 | + return TRUE; | ||
| 7570 | + } | ||
| 7571 | + | ||
| 7572 | + return FALSE; | ||
| 7573 | +} | ||
| 7574 | + | ||
| 7575 | +/* Function for obtaining the condition for the next instruction | ||
| 7576 | + after cur_insn. | ||
| 7577 | +*/ | ||
| 7578 | +rtx | ||
| 7579 | +get_next_insn_cond (rtx cur_insn) | ||
| 7580 | +{ | ||
| 7581 | + rtx next_insn = next_nonnote_insn (cur_insn); | ||
| 7582 | + rtx cond = NULL_RTX; | ||
| 7583 | + if ((next_insn != NULL_RTX) | ||
| 7584 | + && (INSN_P (next_insn)) | ||
| 7585 | + && (GET_CODE (PATTERN (next_insn)) == SET) | ||
| 7586 | + && (GET_CODE (SET_SRC (PATTERN (next_insn))) == IF_THEN_ELSE)) | ||
| 7587 | + { | ||
| 7588 | + /* Branch instructions */ | ||
| 7589 | + cond = XEXP (SET_SRC (PATTERN (next_insn)), 0); | ||
| 7590 | + } | ||
| 7591 | + else if ((next_insn != NULL_RTX) | ||
| 7592 | + && (INSN_P (next_insn)) | ||
| 7593 | + && (GET_CODE (PATTERN (next_insn)) == SET) | ||
| 7594 | + && comparison_operator (SET_SRC (PATTERN (next_insn)), | ||
| 7595 | + GET_MODE (SET_SRC (PATTERN (next_insn))))) | ||
| 7596 | + { | ||
| 7597 | + /* scc with no compare */ | ||
| 7598 | + cond = SET_SRC (PATTERN (next_insn)); | ||
| 7599 | + } | ||
| 7600 | + | ||
| 7601 | + return cond; | ||
| 7602 | +} | ||
| 7603 | + | ||
| 7604 | +int | ||
| 7605 | +avr32_expand_scc (enum rtx_code cond, rtx * operands) | ||
| 7606 | +{ | ||
| 7607 | + | ||
| 7608 | + rtx comparation; | ||
| 7609 | + /* Only allow certain compare operations */ | ||
| 7610 | + if (GET_MODE (avr32_compare_op0) != DImode | ||
| 7611 | + && GET_MODE (avr32_compare_op0) != SImode | ||
| 7612 | + && GET_MODE (avr32_compare_op0) != HImode | ||
| 7613 | + && GET_MODE (avr32_compare_op0) != QImode) | ||
| 7614 | + return FALSE; | ||
| 7615 | + | ||
| 7616 | + /* Delete compare instruction as it is merged into this instruction */ | ||
| 7617 | + remove_insn (get_last_insn_anywhere ()); | ||
| 7618 | + | ||
| 7619 | + if (!REG_P (avr32_compare_op0)) | ||
| 7620 | + avr32_compare_op0 = | ||
| 7621 | + force_reg (GET_MODE (avr32_compare_op0), avr32_compare_op0); | ||
| 7622 | + | ||
| 7623 | + if (GET_MODE (avr32_compare_op0) != SImode && !REG_P (avr32_compare_op1)) | ||
| 7624 | + { | ||
| 7625 | + avr32_compare_op1 = | ||
| 7626 | + force_reg (GET_MODE (avr32_compare_op0), avr32_compare_op1); | ||
| 7627 | + } | ||
| 7628 | + else if (GET_MODE (avr32_compare_op0) == SImode | ||
| 7629 | + && !REG_P (avr32_compare_op1) | ||
| 7630 | + && (GET_CODE (avr32_compare_op1) != CONST_INT | ||
| 7631 | + || (GET_CODE (avr32_compare_op1) == CONST_INT | ||
| 7632 | + && | ||
| 7633 | + !avr32_const_ok_for_constraint_p (INTVAL | ||
| 7634 | + (avr32_compare_op1), 'K', | ||
| 7635 | + "Ks21")))) | ||
| 7636 | + avr32_compare_op1 = | ||
| 7637 | + force_reg (GET_MODE (avr32_compare_op0), avr32_compare_op1); | ||
| 7638 | + | ||
| 7639 | + | ||
| 7640 | + comparation = | ||
| 7641 | + gen_rtx_EQ (SImode, | ||
| 7642 | + gen_rtx_COMPARE (GET_MODE (avr32_compare_op0), | ||
| 7643 | + avr32_compare_op0, avr32_compare_op1), | ||
| 7644 | + const0_rtx); | ||
| 7645 | + /* Set correct condition */ | ||
| 7646 | + PUT_CODE (comparation, cond); | ||
| 7647 | + emit_insn (gen_rtx_SET (VOIDmode, operands[0], comparation)); | ||
| 7648 | + return TRUE; | ||
| 7649 | +} | ||
| 7650 | + | ||
| 7651 | +rtx | ||
| 7652 | +avr32_output_cmp (rtx cond, enum machine_mode mode, rtx op0, rtx op1) | ||
| 7653 | +{ | ||
| 7654 | + | ||
| 7655 | + rtx new_cond = NULL_RTX; | ||
| 7656 | + rtx ops[2]; | ||
| 7657 | + rtx compare_pattern; | ||
| 7658 | + ops[0] = op0; | ||
| 7659 | + ops[1] = op1; | ||
| 7660 | + | ||
| 7661 | + compare_pattern = gen_rtx_COMPARE (mode, op0, op1); | ||
| 7662 | + | ||
| 7663 | + new_cond = is_compare_redundant (compare_pattern, cond); | ||
| 7664 | + | ||
| 7665 | + if (new_cond != NULL_RTX) | ||
| 7666 | + return new_cond; | ||
| 7667 | + | ||
| 7668 | + /* Insert compare */ | ||
| 7669 | + switch (mode) | ||
| 7670 | + { | ||
| 7671 | + case QImode: | ||
| 7672 | + output_asm_insn ("cp.b\t%0, %1", ops); | ||
| 7673 | + break; | ||
| 7674 | + case HImode: | ||
| 7675 | + output_asm_insn ("cp.h\t%0, %1", ops); | ||
| 7676 | + break; | ||
| 7677 | + case SImode: | ||
| 7678 | + output_asm_insn ("cp.w\t%0, %1", ops); | ||
| 7679 | + break; | ||
| 7680 | + case DImode: | ||
| 7681 | + if (rtx_equal_p (op1, const0_rtx)) | ||
| 7682 | + output_asm_insn ("cp.w\t%0, %1\ncpc\t%m0", ops); | ||
| 7683 | + else | ||
| 7684 | + output_asm_insn ("cp.w\t%0, %1\ncpc\t%m0, %m1", ops); | ||
| 7685 | + break; | ||
| 7686 | + default: | ||
| 7687 | + internal_error ("Unknown comparison mode"); | ||
| 7688 | + break; | ||
| 7689 | + } | ||
| 7690 | + | ||
| 7691 | + return cond; | ||
| 7692 | +} | ||
| 7693 | + | ||
| 7694 | +int | ||
| 7695 | +avr32_load_multiple_operation (rtx op, | ||
| 7696 | + enum machine_mode mode ATTRIBUTE_UNUSED) | ||
| 7697 | +{ | ||
| 7698 | + int count = XVECLEN (op, 0); | ||
| 7699 | + unsigned int dest_regno; | ||
| 7700 | + rtx src_addr; | ||
| 7701 | + rtx elt; | ||
| 7702 | + int i = 1, base = 0; | ||
| 7703 | + | ||
| 7704 | + if (count <= 1 || GET_CODE (XVECEXP (op, 0, 0)) != SET) | ||
| 7705 | + return 0; | ||
| 7706 | + | ||
| 7707 | + /* Check to see if this might be a write-back. */ | ||
| 7708 | + if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS) | ||
| 7709 | + { | ||
| 7710 | + i++; | ||
| 7711 | + base = 1; | ||
| 7712 | + | ||
| 7713 | + /* Now check it more carefully. */ | ||
| 7714 | + if (GET_CODE (SET_DEST (elt)) != REG | ||
| 7715 | + || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG | ||
| 7716 | + || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT | ||
| 7717 | + || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4) | ||
| 7718 | + return 0; | ||
| 7719 | + } | ||
| 7720 | + | ||
| 7721 | + /* Perform a quick check so we don't blow up below. */ | ||
| 7722 | + if (count <= 1 | ||
| 7723 | + || GET_CODE (XVECEXP (op, 0, i - 1)) != SET | ||
| 7724 | + || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG | ||
| 7725 | + || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != UNSPEC) | ||
| 7726 | + return 0; | ||
| 7727 | + | ||
| 7728 | + dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1))); | ||
| 7729 | + src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0); | ||
| 7730 | + | ||
| 7731 | + for (; i < count; i++) | ||
| 7732 | + { | ||
| 7733 | + elt = XVECEXP (op, 0, i); | ||
| 7734 | + | ||
| 7735 | + if (GET_CODE (elt) != SET | ||
| 7736 | + || GET_CODE (SET_DEST (elt)) != REG | ||
| 7737 | + || GET_MODE (SET_DEST (elt)) != SImode | ||
| 7738 | + || GET_CODE (SET_SRC (elt)) != UNSPEC) | ||
| 7739 | + return 0; | ||
| 7740 | + } | ||
| 7741 | + | ||
| 7742 | + return 1; | ||
| 7743 | +} | ||
| 7744 | + | ||
| 7745 | +int | ||
| 7746 | +avr32_store_multiple_operation (rtx op, | ||
| 7747 | + enum machine_mode mode ATTRIBUTE_UNUSED) | ||
| 7748 | +{ | ||
| 7749 | + int count = XVECLEN (op, 0); | ||
| 7750 | + int src_regno; | ||
| 7751 | + rtx dest_addr; | ||
| 7752 | + rtx elt; | ||
| 7753 | + int i = 1; | ||
| 7754 | + | ||
| 7755 | + if (count <= 1 || GET_CODE (XVECEXP (op, 0, 0)) != SET) | ||
| 7756 | + return 0; | ||
| 7757 | + | ||
| 7758 | + /* Perform a quick check so we don't blow up below. */ | ||
| 7759 | + if (count <= i | ||
| 7760 | + || GET_CODE (XVECEXP (op, 0, i - 1)) != SET | ||
| 7761 | + || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM | ||
| 7762 | + || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != UNSPEC) | ||
| 7763 | + return 0; | ||
| 7764 | + | ||
| 7765 | + src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1))); | ||
| 7766 | + dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0); | ||
| 7767 | + | ||
| 7768 | + for (; i < count; i++) | ||
| 7769 | + { | ||
| 7770 | + elt = XVECEXP (op, 0, i); | ||
| 7771 | + | ||
| 7772 | + if (GET_CODE (elt) != SET | ||
| 7773 | + || GET_CODE (SET_DEST (elt)) != MEM | ||
| 7774 | + || GET_MODE (SET_DEST (elt)) != SImode | ||
| 7775 | + || GET_CODE (SET_SRC (elt)) != UNSPEC) | ||
| 7776 | + return 0; | ||
| 7777 | + } | ||
| 7778 | + | ||
| 7779 | + return 1; | ||
| 7780 | +} | ||
| 7781 | + | ||
| 7782 | +int | ||
| 7783 | +avr32_valid_macmac_bypass (rtx insn_out, rtx insn_in) | ||
| 7784 | +{ | ||
| 7785 | + /* Check if they use the same accumulator */ | ||
| 7786 | + if (rtx_equal_p | ||
| 7787 | + (SET_DEST (PATTERN (insn_out)), SET_DEST (PATTERN (insn_in)))) | ||
| 7788 | + { | ||
| 7789 | + return TRUE; | ||
| 7790 | + } | ||
| 7791 | + | ||
| 7792 | + return FALSE; | ||
| 7793 | +} | ||
| 7794 | + | ||
| 7795 | +int | ||
| 7796 | +avr32_valid_mulmac_bypass (rtx insn_out, rtx insn_in) | ||
| 7797 | +{ | ||
| 7798 | + /* | ||
| 7799 | + Check if the mul instruction produces the accumulator for the mac | ||
| 7800 | + instruction. */ | ||
| 7801 | + if (rtx_equal_p | ||
| 7802 | + (SET_DEST (PATTERN (insn_out)), SET_DEST (PATTERN (insn_in)))) | ||
| 7803 | + { | ||
| 7804 | + return TRUE; | ||
| 7805 | + } | ||
| 7806 | + return FALSE; | ||
| 7807 | +} | ||
| 7808 | + | ||
| 7809 | +int | ||
| 7810 | +avr32_store_bypass (rtx insn_out, rtx insn_in) | ||
| 7811 | +{ | ||
| 7812 | + /* Only valid bypass if the output result is used as an src in the store | ||
| 7813 | + instruction, NOT if used as a pointer or base. */ | ||
| 7814 | + if (rtx_equal_p | ||
| 7815 | + (SET_DEST (PATTERN (insn_out)), SET_SRC (PATTERN (insn_in)))) | ||
| 7816 | + { | ||
| 7817 | + return TRUE; | ||
| 7818 | + } | ||
| 7819 | + | ||
| 7820 | + return FALSE; | ||
| 7821 | +} | ||
| 7822 | + | ||
| 7823 | +int | ||
| 7824 | +avr32_mul_waw_bypass (rtx insn_out, rtx insn_in) | ||
| 7825 | +{ | ||
| 7826 | + /* Check if the register holding the result from the mul instruction is | ||
| 7827 | + used as a result register in the input instruction. */ | ||
| 7828 | + if (rtx_equal_p | ||
| 7829 | + (SET_DEST (PATTERN (insn_out)), SET_DEST (PATTERN (insn_in)))) | ||
| 7830 | + { | ||
| 7831 | + return TRUE; | ||
| 7832 | + } | ||
| 7833 | + | ||
| 7834 | + return FALSE; | ||
| 7835 | +} | ||
| 7836 | + | ||
| 7837 | +int | ||
| 7838 | +avr32_valid_load_double_bypass (rtx insn_out, rtx insn_in) | ||
| 7839 | +{ | ||
| 7840 | + /* Check if the first loaded word in insn_out is used in insn_in. */ | ||
| 7841 | + rtx dst_reg; | ||
| 7842 | + rtx second_loaded_reg; | ||
| 7843 | + | ||
| 7844 | + /* If this is a double alu operation then the bypass is not valid */ | ||
| 7845 | + if ((get_attr_type (insn_in) == TYPE_ALU | ||
| 7846 | + || get_attr_type (insn_in) == TYPE_ALU2) | ||
| 7847 | + && (GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (insn_out)))) > 4)) | ||
| 7848 | + return FALSE; | ||
| 7849 | + | ||
| 7850 | + /* Get the destination register in the load */ | ||
| 7851 | + if (!REG_P (SET_DEST (PATTERN (insn_out)))) | ||
| 7852 | + return FALSE; | ||
| 7853 | + | ||
| 7854 | + dst_reg = SET_DEST (PATTERN (insn_out)); | ||
| 7855 | + second_loaded_reg = gen_rtx_REG (SImode, REGNO (dst_reg) + 1); | ||
| 7856 | + | ||
| 7857 | + if (!reg_mentioned_p (second_loaded_reg, PATTERN (insn_in))) | ||
| 7858 | + return TRUE; | ||
| 7859 | + | ||
| 7860 | + return FALSE; | ||
| 7861 | +} | ||
| 7862 | + | ||
| 7863 | + | ||
| 7864 | +int | ||
| 7865 | +avr32_valid_load_quad_bypass (rtx insn_out, rtx insn_in) | ||
| 7866 | +{ | ||
| 7867 | + /* | ||
| 7868 | + Check if the two first loaded word in insn_out are used in insn_in. */ | ||
| 7869 | + rtx dst_reg; | ||
| 7870 | + rtx third_loaded_reg, fourth_loaded_reg; | ||
| 7871 | + | ||
| 7872 | + /* Get the destination register in the load */ | ||
| 7873 | + if (!REG_P (SET_DEST (PATTERN (insn_out)))) | ||
| 7874 | + return FALSE; | ||
| 7875 | + | ||
| 7876 | + dst_reg = SET_DEST (PATTERN (insn_out)); | ||
| 7877 | + third_loaded_reg = gen_rtx_REG (SImode, REGNO (dst_reg) + 2); | ||
| 7878 | + fourth_loaded_reg = gen_rtx_REG (SImode, REGNO (dst_reg) + 3); | ||
| 7879 | + | ||
| 7880 | + if (!reg_mentioned_p (third_loaded_reg, PATTERN (insn_in)) | ||
| 7881 | + && !reg_mentioned_p (fourth_loaded_reg, PATTERN (insn_in))) | ||
| 7882 | + { | ||
| 7883 | + return TRUE; | ||
| 7884 | + } | ||
| 7885 | + | ||
| 7886 | + return FALSE; | ||
| 7887 | +} | ||
| 7888 | + | ||
| 7889 | +int | ||
| 7890 | +avr32_sched_use_dfa_pipeline_interface (void) | ||
| 7891 | +{ | ||
| 7892 | + /* No need to scedule on avr32_uc architecture. */ | ||
| 7893 | + return (avr32_arch->arch_type != ARCH_TYPE_AVR32_UC); | ||
| 7894 | +} | ||
| 7895 | + | ||
| 7896 | +void | ||
| 7897 | +avr32_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED, | ||
| 7898 | + rtx x ATTRIBUTE_UNUSED, | ||
| 7899 | + unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) | ||
| 7900 | +{ | ||
| 7901 | + /* Let ASM_OUTPUT_POOL_PROLOGUE take care of this */ | ||
| 7902 | +} | ||
| 7903 | + | ||
| 7904 | +/* Set up library functions to comply to AVR32 ABI */ | ||
| 7905 | + | ||
| 7906 | +static void | ||
| 7907 | +avr32_init_libfuncs (void) | ||
| 7908 | +{ | ||
| 7909 | + /* Convert gcc run-time function names to AVR32 ABI names */ | ||
| 7910 | + | ||
| 7911 | + /* Double-precision floating-point arithmetic. */ | ||
| 7912 | + set_optab_libfunc (add_optab, DFmode, "__avr32_f64_add"); | ||
| 7913 | + set_optab_libfunc (sdiv_optab, DFmode, "__avr32_f64_div"); | ||
| 7914 | + set_optab_libfunc (smul_optab, DFmode, "__avr32_f64_mul"); | ||
| 7915 | + set_optab_libfunc (neg_optab, DFmode, NULL); | ||
| 7916 | + set_optab_libfunc (sub_optab, DFmode, "__avr32_f64_sub"); | ||
| 7917 | + | ||
| 7918 | + /* Double-precision comparisons. */ | ||
| 7919 | + set_optab_libfunc (eq_optab, DFmode, "__avr32_f64_cmp_eq"); | ||
| 7920 | + set_optab_libfunc (ne_optab, DFmode, NULL); | ||
| 7921 | + set_optab_libfunc (lt_optab, DFmode, "__avr32_f64_cmp_lt"); | ||
| 7922 | + set_optab_libfunc (le_optab, DFmode, NULL); | ||
| 7923 | + set_optab_libfunc (ge_optab, DFmode, "__avr32_f64_cmp_ge"); | ||
| 7924 | + set_optab_libfunc (gt_optab, DFmode, NULL); | ||
| 7925 | + | ||
| 7926 | + /* Single-precision floating-point arithmetic. */ | ||
| 7927 | + set_optab_libfunc (add_optab, SFmode, "__avr32_f32_add"); | ||
| 7928 | + set_optab_libfunc (sdiv_optab, SFmode, "__avr32_f32_div"); | ||
| 7929 | + set_optab_libfunc (smul_optab, SFmode, "__avr32_f32_mul"); | ||
| 7930 | + set_optab_libfunc (neg_optab, SFmode, NULL); | ||
| 7931 | + set_optab_libfunc (sub_optab, SFmode, "__avr32_f32_sub"); | ||
| 7932 | + | ||
| 7933 | + /* Single-precision comparisons. */ | ||
| 7934 | + set_optab_libfunc (eq_optab, SFmode, "__avr32_f32_cmp_eq"); | ||
| 7935 | + set_optab_libfunc (ne_optab, SFmode, NULL); | ||
| 7936 | + set_optab_libfunc (lt_optab, SFmode, "__avr32_f32_cmp_lt"); | ||
| 7937 | + set_optab_libfunc (le_optab, SFmode, NULL); | ||
| 7938 | + set_optab_libfunc (ge_optab, SFmode, "__avr32_f32_cmp_ge"); | ||
| 7939 | + set_optab_libfunc (gt_optab, SFmode, NULL); | ||
| 7940 | + | ||
| 7941 | + /* Floating-point to integer conversions. */ | ||
| 7942 | + set_conv_libfunc (sfix_optab, SImode, DFmode, "__avr32_f64_to_s32"); | ||
| 7943 | + set_conv_libfunc (ufix_optab, SImode, DFmode, "__avr32_f64_to_u32"); | ||
| 7944 | + set_conv_libfunc (sfix_optab, DImode, DFmode, "__avr32_f64_to_s64"); | ||
| 7945 | + set_conv_libfunc (ufix_optab, DImode, DFmode, "__avr32_f64_to_u64"); | ||
| 7946 | + set_conv_libfunc (sfix_optab, SImode, SFmode, "__avr32_f32_to_s32"); | ||
| 7947 | + set_conv_libfunc (ufix_optab, SImode, SFmode, "__avr32_f32_to_u32"); | ||
| 7948 | + set_conv_libfunc (sfix_optab, DImode, SFmode, "__avr32_f32_to_s64"); | ||
| 7949 | + set_conv_libfunc (ufix_optab, DImode, SFmode, "__avr32_f32_to_u64"); | ||
| 7950 | + | ||
| 7951 | + /* Conversions between floating types. */ | ||
| 7952 | + set_conv_libfunc (trunc_optab, SFmode, DFmode, "__avr32_f64_to_f32"); | ||
| 7953 | + set_conv_libfunc (sext_optab, DFmode, SFmode, "__avr32_f32_to_f64"); | ||
| 7954 | + | ||
| 7955 | + /* Integer to floating-point conversions. Table 8. */ | ||
| 7956 | + set_conv_libfunc (sfloat_optab, DFmode, SImode, "__avr32_s32_to_f64"); | ||
| 7957 | + set_conv_libfunc (sfloat_optab, DFmode, DImode, "__avr32_s64_to_f64"); | ||
| 7958 | + set_conv_libfunc (sfloat_optab, SFmode, SImode, "__avr32_s32_to_f32"); | ||
| 7959 | + set_conv_libfunc (sfloat_optab, SFmode, DImode, "__avr32_s64_to_f32"); | ||
| 7960 | + set_conv_libfunc (ufloat_optab, DFmode, SImode, "__avr32_u32_to_f64"); | ||
| 7961 | + set_conv_libfunc (ufloat_optab, SFmode, SImode, "__avr32_u32_to_f32"); | ||
| 7962 | + /* TODO: Add these to gcc library functions */ | ||
| 7963 | + | ||
| 7964 | + set_conv_libfunc (ufloat_optab, DFmode, DImode, NULL); | ||
| 7965 | + set_conv_libfunc (ufloat_optab, SFmode, DImode, NULL); | ||
| 7966 | + | ||
| 7967 | + /* Long long. Table 9. */ | ||
| 7968 | + set_optab_libfunc (smul_optab, DImode, "__avr32_mul64"); | ||
| 7969 | + set_optab_libfunc (sdiv_optab, DImode, "__avr32_sdiv64"); | ||
| 7970 | + set_optab_libfunc (udiv_optab, DImode, "__avr32_udiv64"); | ||
| 7971 | + set_optab_libfunc (smod_optab, DImode, "__avr32_smod64"); | ||
| 7972 | + set_optab_libfunc (umod_optab, DImode, "__avr32_umod64"); | ||
| 7973 | + set_optab_libfunc (ashl_optab, DImode, "__avr32_lsl64"); | ||
| 7974 | + set_optab_libfunc (lshr_optab, DImode, "__avr32_lsr64"); | ||
| 7975 | + set_optab_libfunc (ashr_optab, DImode, "__avr32_asr64"); | ||
| 7976 | +} | ||
| 7977 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/avr32-elf.h gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/avr32-elf.h | ||
| 7978 | --- gcc-4.0.2/gcc/config/avr32/avr32-elf.h 1970-01-01 01:00:00.000000000 +0100 | ||
| 7979 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/avr32-elf.h 2006-11-17 10:38:10.000000000 +0100 | ||
| 7980 | @@ -0,0 +1,82 @@ | ||
| 7981 | +/* | ||
| 7982 | + Elf specific definitions. | ||
| 7983 | + Copyright 2003-2006 Atmel Corporation. | ||
| 7984 | + | ||
| 7985 | + Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com> | ||
| 7986 | + | ||
| 7987 | + This file is part of GCC. | ||
| 7988 | + | ||
| 7989 | + This program is free software; you can redistribute it and/or modify | ||
| 7990 | + it under the terms of the GNU General Public License as published by | ||
| 7991 | + the Free Software Foundation; either version 2 of the License, or | ||
| 7992 | + (at your option) any later version. | ||
| 7993 | + | ||
| 7994 | + This program is distributed in the hope that it will be useful, | ||
| 7995 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 7996 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 7997 | + GNU General Public License for more details. | ||
| 7998 | + | ||
| 7999 | + You should have received a copy of the GNU General Public License | ||
| 8000 | + along with this program; if not, write to the Free Software | ||
| 8001 | + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 8002 | + | ||
| 8003 | + | ||
| 8004 | +/***************************************************************************** | ||
| 8005 | + * Controlling the Compilator Driver, 'gcc' | ||
| 8006 | + *****************************************************************************/ | ||
| 8007 | + | ||
| 8008 | +/* Run-time Target Specification. */ | ||
| 8009 | +#undef TARGET_VERSION | ||
| 8010 | +#define TARGET_VERSION fputs (" (AVR32 GNU with ELF)", stderr); | ||
| 8011 | + | ||
| 8012 | +/* | ||
| 8013 | +Another C string constant used much like LINK_SPEC. The | ||
| 8014 | +difference between the two is that STARTFILE_SPEC is used at | ||
| 8015 | +the very beginning of the command given to the linker. | ||
| 8016 | + | ||
| 8017 | +If this macro is not defined, a default is provided that loads the | ||
| 8018 | +standard C startup file from the usual place. See gcc.c. | ||
| 8019 | +*/ | ||
| 8020 | +#undef STARTFILE_SPEC | ||
| 8021 | +#define STARTFILE_SPEC "crt0%O%s crti%O%s crtbegin%O%s" | ||
| 8022 | + | ||
| 8023 | +#undef LINK_SPEC | ||
| 8024 | +#define LINK_SPEC "%{muse-oscall:--defsym __do_not_use_oscall_coproc__=0} %{mrelax|O*:%{mno-relax|O0|O1: ;:--relax}} %{mpart=*:-mavr32elf_%*} %{mcpu=*:-mavr32elf_%*}" | ||
| 8025 | + | ||
| 8026 | + | ||
| 8027 | +/* | ||
| 8028 | +Another C string constant used much like LINK_SPEC. The | ||
| 8029 | +difference between the two is that ENDFILE_SPEC is used at | ||
| 8030 | +the very end of the command given to the linker. | ||
| 8031 | + | ||
| 8032 | +Do not define this macro if it does not need to do anything. | ||
| 8033 | +*/ | ||
| 8034 | +#undef ENDFILE_SPEC | ||
| 8035 | +#define ENDFILE_SPEC "crtend%O%s crtn%O%s" | ||
| 8036 | + | ||
| 8037 | + | ||
| 8038 | +/* Target CPU builtins. */ | ||
| 8039 | +#define TARGET_CPU_CPP_BUILTINS() \ | ||
| 8040 | + do \ | ||
| 8041 | + { \ | ||
| 8042 | + builtin_define ("__avr32__"); \ | ||
| 8043 | + builtin_define ("__AVR32__"); \ | ||
| 8044 | + builtin_define ("__AVR32_ELF__"); \ | ||
| 8045 | + builtin_define (avr32_part->macro); \ | ||
| 8046 | + builtin_define (avr32_arch->macro); \ | ||
| 8047 | + if (avr32_arch->uarch_type == UARCH_TYPE_AVR32A) \ | ||
| 8048 | + builtin_define ("__AVR32_AVR32A__"); \ | ||
| 8049 | + else \ | ||
| 8050 | + builtin_define ("__AVR32_AVR32B__"); \ | ||
| 8051 | + if (TARGET_UNALIGNED_WORD) \ | ||
| 8052 | + builtin_define ("__AVR32_HAS_UNALIGNED_WORD__"); \ | ||
| 8053 | + if (TARGET_SIMD) \ | ||
| 8054 | + builtin_define ("__AVR32_HAS_SIMD__"); \ | ||
| 8055 | + if (TARGET_DSP) \ | ||
| 8056 | + builtin_define ("__AVR32_HAS_DSP__"); \ | ||
| 8057 | + if (TARGET_RMW) \ | ||
| 8058 | + builtin_define ("__AVR32_HAS_RMW__"); \ | ||
| 8059 | + if (TARGET_BRANCH_PRED) \ | ||
| 8060 | + builtin_define ("__AVR32_HAS_BRANCH_PRED__"); \ | ||
| 8061 | + } \ | ||
| 8062 | + while (0) | ||
| 8063 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/avr32.h gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/avr32.h | ||
| 8064 | --- gcc-4.0.2/gcc/config/avr32/avr32.h 1970-01-01 01:00:00.000000000 +0100 | ||
| 8065 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/avr32.h 2006-11-10 15:14:06.000000000 +0100 | ||
| 8066 | @@ -0,0 +1,3374 @@ | ||
| 8067 | +/* | ||
| 8068 | + Definitions of target machine for AVR32. | ||
| 8069 | + Copyright 2003-2006 Atmel Corporation. | ||
| 8070 | + | ||
| 8071 | + Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com> | ||
| 8072 | + Initial porting by Anders Ådland. | ||
| 8073 | + | ||
| 8074 | + This file is part of GCC. | ||
| 8075 | + | ||
| 8076 | + This program is free software; you can redistribute it and/or modify | ||
| 8077 | + it under the terms of the GNU General Public License as published by | ||
| 8078 | + the Free Software Foundation; either version 2 of the License, or | ||
| 8079 | + (at your option) any later version. | ||
| 8080 | + | ||
| 8081 | + This program is distributed in the hope that it will be useful, | ||
| 8082 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 8083 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 8084 | + GNU General Public License for more details. | ||
| 8085 | + | ||
| 8086 | + You should have received a copy of the GNU General Public License | ||
| 8087 | + along with this program; if not, write to the Free Software | ||
| 8088 | + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 8089 | + | ||
| 8090 | +#ifndef GCC_AVR32_H | ||
| 8091 | +#define GCC_AVR32_H | ||
| 8092 | + | ||
| 8093 | + | ||
| 8094 | +#ifndef OBJECT_FORMAT_ELF | ||
| 8095 | +#error avr32.h included before elfos.h | ||
| 8096 | +#endif | ||
| 8097 | + | ||
| 8098 | +#ifndef LOCAL_LABEL_PREFIX | ||
| 8099 | +#define LOCAL_LABEL_PREFIX "." | ||
| 8100 | +#endif | ||
| 8101 | + | ||
| 8102 | +#ifndef SUBTARGET_CPP_SPEC | ||
| 8103 | +#define SUBTARGET_CPP_SPEC "-D__ELF__" | ||
| 8104 | +#endif | ||
| 8105 | + | ||
| 8106 | + | ||
| 8107 | +extern struct rtx_def *avr32_compare_op0; | ||
| 8108 | +extern struct rtx_def *avr32_compare_op1; | ||
| 8109 | + | ||
| 8110 | + | ||
| 8111 | +extern struct rtx_def *avr32_acc_cache; | ||
| 8112 | + | ||
| 8113 | +/* cache instruction op5 codes */ | ||
| 8114 | +#define AVR32_CACHE_INVALIDATE_ICACHE 1 | ||
| 8115 | + | ||
| 8116 | +/* These bits describe the different types of function supported | ||
| 8117 | + by the AVR32 backend. They are exclusive. ie a function cannot be both a | ||
| 8118 | + normal function and an interworked function, for example. Knowing the | ||
| 8119 | + type of a function is important for determining its prologue and | ||
| 8120 | + epilogue sequences. | ||
| 8121 | + Note value 7 is currently unassigned. Also note that the interrupt | ||
| 8122 | + function types all have bit 2 set, so that they can be tested for easily. | ||
| 8123 | + Note that 0 is deliberately chosen for AVR32_FT_UNKNOWN so that when the | ||
| 8124 | + machine_function structure is initialized (to zero) func_type will | ||
| 8125 | + default to unknown. This will force the first use of avr32_current_func_type | ||
| 8126 | + to call avr32_compute_func_type. */ | ||
| 8127 | +#define AVR32_FT_UNKNOWN 0 /* Type has not yet been determined. | ||
| 8128 | + */ | ||
| 8129 | +#define AVR32_FT_NORMAL 1 /* Your normal, straightforward | ||
| 8130 | + function. */ | ||
| 8131 | +#define AVR32_FT_ACALL 2 /* An acall function. */ | ||
| 8132 | +#define AVR32_FT_EXCEPTION_HANDLER 3 /* A C++ exception handler. */ | ||
| 8133 | +#define AVR32_FT_ISR_FULL 4 /* A fully shadowed interrupt mode. */ | ||
| 8134 | +#define AVR32_FT_ISR_HALF 5 /* A half shadowed interrupt mode. */ | ||
| 8135 | +#define AVR32_FT_ISR_NONE 6 /* No shadow registers. */ | ||
| 8136 | + | ||
| 8137 | +#define AVR32_FT_TYPE_MASK ((1 << 3) - 1) | ||
| 8138 | + | ||
| 8139 | +/* In addition functions can have several type modifiers, | ||
| 8140 | + outlined by these bit masks: */ | ||
| 8141 | +#define AVR32_FT_INTERRUPT (1 << 2) /* Note overlap with FT_ISR | ||
| 8142 | + and above. */ | ||
| 8143 | +#define AVR32_FT_NAKED (1 << 3) /* No prologue or epilogue. */ | ||
| 8144 | +#define AVR32_FT_VOLATILE (1 << 4) /* Does not return. */ | ||
| 8145 | +#define AVR32_FT_NESTED (1 << 5) /* Embedded inside another | ||
| 8146 | + func. */ | ||
| 8147 | + | ||
| 8148 | +/* Some macros to test these flags. */ | ||
| 8149 | +#define AVR32_FUNC_TYPE(t) (t & AVR32_FT_TYPE_MASK) | ||
| 8150 | +#define IS_INTERRUPT(t) (t & AVR32_FT_INTERRUPT) | ||
| 8151 | +#define IS_VOLATILE(t) (t & AVR32_FT_VOLATILE) | ||
| 8152 | +#define IS_NAKED(t) (t & AVR32_FT_NAKED) | ||
| 8153 | +#define IS_NESTED(t) (t & AVR32_FT_NESTED) | ||
| 8154 | + | ||
| 8155 | + | ||
| 8156 | +typedef struct minipool_labels | ||
| 8157 | +GTY ((chain_next ("%h.next"), chain_prev ("%h.prev"))) | ||
| 8158 | +{ | ||
| 8159 | + rtx label; | ||
| 8160 | + struct minipool_labels *prev; | ||
| 8161 | + struct minipool_labels *next; | ||
| 8162 | +} minipool_labels; | ||
| 8163 | + | ||
| 8164 | +/* A C structure for machine-specific, per-function data. | ||
| 8165 | + This is added to the cfun structure. */ | ||
| 8166 | + | ||
| 8167 | +typedef struct machine_function | ||
| 8168 | +GTY (()) | ||
| 8169 | +{ | ||
| 8170 | + /* Records the type of the current function. */ | ||
| 8171 | + unsigned long func_type; | ||
| 8172 | + /* List of minipool labels, use for checking if code label is valid in a | ||
| 8173 | + memory expression */ | ||
| 8174 | + minipool_labels *minipool_label_head; | ||
| 8175 | + minipool_labels *minipool_label_tail; | ||
| 8176 | +} machine_function; | ||
| 8177 | + | ||
| 8178 | +/* Initialize data used by insn expanders. This is called from insn_emit, | ||
| 8179 | + once for every function before code is generated. */ | ||
| 8180 | +#define INIT_EXPANDERS avr32_init_expanders () | ||
| 8181 | + | ||
| 8182 | +/****************************************************************************** | ||
| 8183 | + * SPECS | ||
| 8184 | + *****************************************************************************/ | ||
| 8185 | + | ||
| 8186 | +#ifndef ASM_SPEC | ||
| 8187 | +#define ASM_SPEC "%{fpic:--pic} %{mrelax|O*:%{mno-relax|O0|O1: ;:--linkrelax}} %{march=*:-march=%*} %{mpart=*:-mpart=%*}" | ||
| 8188 | +#endif | ||
| 8189 | + | ||
| 8190 | +#ifndef MULTILIB_DEFAULTS | ||
| 8191 | +#define MULTILIB_DEFAULTS { "march=ap" } | ||
| 8192 | +#endif | ||
| 8193 | + | ||
| 8194 | + | ||
| 8195 | +/****************************************************************************** | ||
| 8196 | + * Run-time Target Specification | ||
| 8197 | + *****************************************************************************/ | ||
| 8198 | +extern int target_flags; | ||
| 8199 | + | ||
| 8200 | +/* Part types. Keep this in sync with the order of avr32_part_types in avr32.c*/ | ||
| 8201 | +enum part_type | ||
| 8202 | +{ | ||
| 8203 | + PART_TYPE_AVR32_NONE, | ||
| 8204 | + PART_TYPE_AVR32_AP7000, | ||
| 8205 | + PART_TYPE_AVR32_AP7010, | ||
| 8206 | + PART_TYPE_AVR32_AP7020, | ||
| 8207 | + PART_TYPE_AVR32_UC3A0256, | ||
| 8208 | + PART_TYPE_AVR32_UC3A0512, | ||
| 8209 | + PART_TYPE_AVR32_UC3A1128, | ||
| 8210 | + PART_TYPE_AVR32_UC3A1256, | ||
| 8211 | + PART_TYPE_AVR32_UC3A1512 | ||
| 8212 | +}; | ||
| 8213 | + | ||
| 8214 | +/* Microarchitectures. */ | ||
| 8215 | +enum microarchitecture_type | ||
| 8216 | +{ | ||
| 8217 | + UARCH_TYPE_AVR32A, | ||
| 8218 | + UARCH_TYPE_AVR32B | ||
| 8219 | +}; | ||
| 8220 | + | ||
| 8221 | +/* Architectures types which specifies the pipeline. | ||
| 8222 | + Keep this in sync with avr32_arch_types in avr32.c*/ | ||
| 8223 | +enum architecture_type | ||
| 8224 | +{ | ||
| 8225 | + ARCH_TYPE_AVR32_AP, | ||
| 8226 | + ARCH_TYPE_AVR32_UC | ||
| 8227 | +}; | ||
| 8228 | + | ||
| 8229 | +/* Flag specifying if the cpu has support for DSP instructions.*/ | ||
| 8230 | +#define FLAG_AVR32_HAS_DSP (1 << 0) | ||
| 8231 | +/* Flag specifying if the cpu has support for Read-Modify-Write | ||
| 8232 | + instructions.*/ | ||
| 8233 | +#define FLAG_AVR32_HAS_RMW (1 << 1) | ||
| 8234 | +/* Flag specifying if the cpu has support for SIMD instructions. */ | ||
| 8235 | +#define FLAG_AVR32_HAS_SIMD (1 << 2) | ||
| 8236 | +/* Flag specifying if the cpu has support for unaligned memory word access. */ | ||
| 8237 | +#define FLAG_AVR32_HAS_UNALIGNED_WORD (1 << 3) | ||
| 8238 | +/* Flag specifying if the cpu has support for branch prediction. */ | ||
| 8239 | +#define FLAG_AVR32_HAS_BRANCH_PRED (1 << 4) | ||
| 8240 | + | ||
| 8241 | +/* Structure for holding information about different avr32 CPUs/parts */ | ||
| 8242 | +struct part_type_s | ||
| 8243 | +{ | ||
| 8244 | + const char *const name; | ||
| 8245 | + enum part_type part_type; | ||
| 8246 | + enum architecture_type arch_type; | ||
| 8247 | + /* Must lie outside user's namespace. NULL == no macro. */ | ||
| 8248 | + const char *const macro; | ||
| 8249 | +}; | ||
| 8250 | + | ||
| 8251 | +/* Structure for holding information about different avr32 pipeline | ||
| 8252 | + architectures. */ | ||
| 8253 | +struct arch_type_s | ||
| 8254 | +{ | ||
| 8255 | + const char *const name; | ||
| 8256 | + enum architecture_type arch_type; | ||
| 8257 | + enum microarchitecture_type uarch_type; | ||
| 8258 | + const unsigned long feature_flags; | ||
| 8259 | + /* Must lie outside user's namespace. NULL == no macro. */ | ||
| 8260 | + const char *const macro; | ||
| 8261 | +}; | ||
| 8262 | + | ||
| 8263 | +extern const struct part_type_s *avr32_part; | ||
| 8264 | +extern const struct arch_type_s *avr32_arch; | ||
| 8265 | + | ||
| 8266 | +#define USE_RODATA_SECTION (1 << 0) | ||
| 8267 | +#define AVR32_FLAG_HARD_FLOAT (1 << 1) | ||
| 8268 | +#define AVR32_FLAG_FORCE_DOUBLE_ALIGN (1 << 2) | ||
| 8269 | +#define AVR32_FLAG_RELAX (1 << 4) | ||
| 8270 | +#define AVR32_FLAG_NO_INIT_GOT (1 << 5) | ||
| 8271 | +#define AVR32_FLAG_NO_REORG_OPT (1 << 6) | ||
| 8272 | +#define AVR32_FLAG_NO_ASM_ADDR_PSEUDOS (1 << 7) | ||
| 8273 | +#define AVR32_FLAG_NO_PIC (1 << 8) | ||
| 8274 | + | ||
| 8275 | +#define TARGET_HARD_FLOAT (target_flags & AVR32_FLAG_HARD_FLOAT) | ||
| 8276 | +#define TARGET_SOFT_FLOAT (!TARGET_HARD_FLOAT) | ||
| 8277 | +#define TARGET_FORCE_DOUBLE_ALIGN (target_flags & AVR32_FLAG_FORCE_DOUBLE_ALIGN) | ||
| 8278 | +#define TARGET_RELAX (target_flags & AVR32_FLAG_RELAX) | ||
| 8279 | +#define TARGET_NO_INIT_GOT (target_flags & AVR32_FLAG_NO_INIT_GOT) | ||
| 8280 | +#define TARGET_MD_REORG_OPTIMIZATION (!(target_flags & AVR32_FLAG_NO_REORG_OPT)) | ||
| 8281 | +#define TARGET_HAS_ASM_ADDR_PSEUDOS (!(target_flags & AVR32_FLAG_NO_ASM_ADDR_PSEUDOS)) | ||
| 8282 | + | ||
| 8283 | +#define TARGET_SIMD (avr32_arch->feature_flags & FLAG_AVR32_HAS_SIMD) | ||
| 8284 | +#define TARGET_DSP (avr32_arch->feature_flags & FLAG_AVR32_HAS_DSP) | ||
| 8285 | +#define TARGET_RMW (avr32_arch->feature_flags & FLAG_AVR32_HAS_RMW) | ||
| 8286 | +#define TARGET_UNALIGNED_WORD (avr32_arch->feature_flags & FLAG_AVR32_HAS_UNALIGNED_WORD) | ||
| 8287 | +#define TARGET_BRANCH_PRED (avr32_arch->feature_flags & FLAG_AVR32_HAS_BRANCH_PRED) | ||
| 8288 | + | ||
| 8289 | + | ||
| 8290 | +#define TARGET_SWITCHES { \ | ||
| 8291 | + { "use-rodata-section", USE_RODATA_SECTION, \ | ||
| 8292 | + N_("Do not put readonly-data in .text section, but in .rodata.") }, \ | ||
| 8293 | + { "hard-float", AVR32_FLAG_HARD_FLOAT, \ | ||
| 8294 | + N_("Use floating point coprocessor instructions.") }, \ | ||
| 8295 | + { "soft-float", -AVR32_FLAG_HARD_FLOAT, \ | ||
| 8296 | + N_("Use software floating-point library for floating-point operations.") }, \ | ||
| 8297 | + { "force-double-align", AVR32_FLAG_FORCE_DOUBLE_ALIGN, \ | ||
| 8298 | + N_("Force double-word alignment for double-word memory accesses.") }, \ | ||
| 8299 | + { "no-init-got", AVR32_FLAG_NO_INIT_GOT, \ | ||
| 8300 | + N_("Do not initialize GOT register before using it when compiling PIC code.") }, \ | ||
| 8301 | + { "relax", AVR32_FLAG_RELAX, \ | ||
| 8302 | + N_("Let invoked assembler and linker do relaxing (Enabled by default when optimization level is >1).") }, \ | ||
| 8303 | + { "no-relax", -AVR32_FLAG_RELAX, \ | ||
| 8304 | + N_("Don't let invoked assembler and linker do relaxing.") }, \ | ||
| 8305 | + { "no-reorg-opt", AVR32_FLAG_NO_REORG_OPT, \ | ||
| 8306 | + N_("Do not perform machine dependent optimizations in reorg stage.") }, \ | ||
| 8307 | + { "asm-addr-pseudos", -AVR32_FLAG_NO_ASM_ADDR_PSEUDOS, \ | ||
| 8308 | + N_("Use assembler pseudo-instructions lda.w and call for handling direct addresses. (Enabled by default)") }, \ | ||
| 8309 | + { "no-asm-addr-pseudos", AVR32_FLAG_NO_ASM_ADDR_PSEUDOS, \ | ||
| 8310 | + N_("Do not use assembler pseudo-instructions lda.w and call for handling direct addresses.") }, \ | ||
| 8311 | + { "no-pic", AVR32_FLAG_NO_PIC, \ | ||
| 8312 | + N_("Do not emit position-independent code (will break dynamic linking.)") }, \ | ||
| 8313 | + { "", 0, NULL } \ | ||
| 8314 | +} | ||
| 8315 | + | ||
| 8316 | + | ||
| 8317 | +extern const char *avr32_part_name; | ||
| 8318 | +extern const char *avr32_arch_name; | ||
| 8319 | + | ||
| 8320 | +#define TARGET_OPTIONS { \ | ||
| 8321 | + { "part=", &avr32_part_name, N_("Specify the AVR32 part name"), 0}, \ | ||
| 8322 | + { "cpu=", &avr32_part_name, N_("Specify the AVR32 part name (deprecated)"), 0}, \ | ||
| 8323 | + { "arch=", &avr32_arch_name, N_("Specify the AVR32 architecture name"), 0} } | ||
| 8324 | + | ||
| 8325 | +#define CAN_DEBUG_WITHOUT_FP | ||
| 8326 | + | ||
| 8327 | +/****************************************************************************** | ||
| 8328 | + * Storage Layout | ||
| 8329 | + *****************************************************************************/ | ||
| 8330 | + | ||
| 8331 | +/* | ||
| 8332 | +Define this macro to have the value 1 if the most significant bit in a | ||
| 8333 | +byte has the lowest number; otherwise define it to have the value zero. | ||
| 8334 | +This means that bit-field instructions count from the most significant | ||
| 8335 | +bit. If the machine has no bit-field instructions, then this must still | ||
| 8336 | +be defined, but it doesn't matter which value it is defined to. This | ||
| 8337 | +macro need not be a constant. | ||
| 8338 | + | ||
| 8339 | +This macro does not affect the way structure fields are packed into | ||
| 8340 | +bytes or words; that is controlled by BYTES_BIG_ENDIAN. | ||
| 8341 | +*/ | ||
| 8342 | +#define BITS_BIG_ENDIAN 0 | ||
| 8343 | + | ||
| 8344 | +/* | ||
| 8345 | +Define this macro to have the value 1 if the most significant byte in a | ||
| 8346 | +word has the lowest number. This macro need not be a constant. | ||
| 8347 | +*/ | ||
| 8348 | +/* | ||
| 8349 | + Data is stored in an big-endian way. | ||
| 8350 | +*/ | ||
| 8351 | +#define BYTES_BIG_ENDIAN 1 | ||
| 8352 | + | ||
| 8353 | +/* | ||
| 8354 | +Define this macro to have the value 1 if, in a multiword object, the | ||
| 8355 | +most significant word has the lowest number. This applies to both | ||
| 8356 | +memory locations and registers; GCC fundamentally assumes that the | ||
| 8357 | +order of words in memory is the same as the order in registers. This | ||
| 8358 | +macro need not be a constant. | ||
| 8359 | +*/ | ||
| 8360 | +/* | ||
| 8361 | + Data is stored in an bin-endian way. | ||
| 8362 | +*/ | ||
| 8363 | +#define WORDS_BIG_ENDIAN 1 | ||
| 8364 | + | ||
| 8365 | +/* | ||
| 8366 | +Define this macro if WORDS_BIG_ENDIAN is not constant. This must be a | ||
| 8367 | +constant value with the same meaning as WORDS_BIG_ENDIAN, which will be | ||
| 8368 | +used only when compiling libgcc2.c. Typically the value will be set | ||
| 8369 | +based on preprocessor defines. | ||
| 8370 | +*/ | ||
| 8371 | +#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN | ||
| 8372 | + | ||
| 8373 | +/* | ||
| 8374 | +Define this macro to have the value 1 if DFmode, XFmode or | ||
| 8375 | +TFmode floating point numbers are stored in memory with the word | ||
| 8376 | +containing the sign bit at the lowest address; otherwise define it to | ||
| 8377 | +have the value 0. This macro need not be a constant. | ||
| 8378 | + | ||
| 8379 | +You need not define this macro if the ordering is the same as for | ||
| 8380 | +multi-word integers. | ||
| 8381 | +*/ | ||
| 8382 | +/* #define FLOAT_WORDS_BIG_ENDIAN 1 */ | ||
| 8383 | + | ||
| 8384 | +/* | ||
| 8385 | +Define this macro to be the number of bits in an addressable storage | ||
| 8386 | +unit (byte); normally 8. | ||
| 8387 | +*/ | ||
| 8388 | +#define BITS_PER_UNIT 8 | ||
| 8389 | + | ||
| 8390 | +/* | ||
| 8391 | +Number of bits in a word; normally 32. | ||
| 8392 | +*/ | ||
| 8393 | +#define BITS_PER_WORD 32 | ||
| 8394 | + | ||
| 8395 | +/* | ||
| 8396 | +Maximum number of bits in a word. If this is undefined, the default is | ||
| 8397 | +BITS_PER_WORD. Otherwise, it is the constant value that is the | ||
| 8398 | +largest value that BITS_PER_WORD can have at run-time. | ||
| 8399 | +*/ | ||
| 8400 | +/* MAX_BITS_PER_WORD not defined*/ | ||
| 8401 | + | ||
| 8402 | +/* | ||
| 8403 | +Number of storage units in a word; normally 4. | ||
| 8404 | +*/ | ||
| 8405 | +#define UNITS_PER_WORD 4 | ||
| 8406 | + | ||
| 8407 | +/* | ||
| 8408 | +Minimum number of units in a word. If this is undefined, the default is | ||
| 8409 | +UNITS_PER_WORD. Otherwise, it is the constant value that is the | ||
| 8410 | +smallest value that UNITS_PER_WORD can have at run-time. | ||
| 8411 | +*/ | ||
| 8412 | +/* MIN_UNITS_PER_WORD not defined */ | ||
| 8413 | + | ||
| 8414 | +/* | ||
| 8415 | +Width of a pointer, in bits. You must specify a value no wider than the | ||
| 8416 | +width of Pmode. If it is not equal to the width of Pmode, | ||
| 8417 | +you must define POINTERS_EXTEND_UNSIGNED. | ||
| 8418 | +*/ | ||
| 8419 | +#define POINTER_SIZE 32 | ||
| 8420 | + | ||
| 8421 | +/* | ||
| 8422 | +A C expression whose value is greater than zero if pointers that need to be | ||
| 8423 | +extended from being POINTER_SIZE bits wide to Pmode are to | ||
| 8424 | +be zero-extended and zero if they are to be sign-extended. If the value | ||
| 8425 | +is less then zero then there must be an "ptr_extend" instruction that | ||
| 8426 | +extends a pointer from POINTER_SIZE to Pmode. | ||
| 8427 | + | ||
| 8428 | +You need not define this macro if the POINTER_SIZE is equal | ||
| 8429 | +to the width of Pmode. | ||
| 8430 | +*/ | ||
| 8431 | +/* #define POINTERS_EXTEND_UNSIGNED */ | ||
| 8432 | + | ||
| 8433 | +/* | ||
| 8434 | +A Macro to update M and UNSIGNEDP when an object whose type | ||
| 8435 | +is TYPE and which has the specified mode and signedness is to be | ||
| 8436 | +stored in a register. This macro is only called when TYPE is a | ||
| 8437 | +scalar type. | ||
| 8438 | + | ||
| 8439 | +On most RISC machines, which only have operations that operate on a full | ||
| 8440 | +register, define this macro to set M to word_mode if | ||
| 8441 | +M is an integer mode narrower than BITS_PER_WORD. In most | ||
| 8442 | +cases, only integer modes should be widened because wider-precision | ||
| 8443 | +floating-point operations are usually more expensive than their narrower | ||
| 8444 | +counterparts. | ||
| 8445 | + | ||
| 8446 | +For most machines, the macro definition does not change UNSIGNEDP. | ||
| 8447 | +However, some machines, have instructions that preferentially handle | ||
| 8448 | +either signed or unsigned quantities of certain modes. For example, on | ||
| 8449 | +the DEC Alpha, 32-bit loads from memory and 32-bit add instructions | ||
| 8450 | +sign-extend the result to 64 bits. On such machines, set | ||
| 8451 | +UNSIGNEDP according to which kind of extension is more efficient. | ||
| 8452 | + | ||
| 8453 | +Do not define this macro if it would never modify M. | ||
| 8454 | +*/ | ||
| 8455 | +#define PROMOTE_MODE(M, UNSIGNEDP, TYPE) \ | ||
| 8456 | + do \ | ||
| 8457 | + { \ | ||
| 8458 | + if (GET_MODE_CLASS (M) == MODE_INT \ | ||
| 8459 | + && GET_MODE_SIZE (M) < 4) \ | ||
| 8460 | + { \ | ||
| 8461 | + (M) = SImode; \ | ||
| 8462 | + } \ | ||
| 8463 | + } \ | ||
| 8464 | + while (0) | ||
| 8465 | + | ||
| 8466 | +/* Define if operations between registers always perform the operation | ||
| 8467 | + on the full register even if a narrower mode is specified. */ | ||
| 8468 | +#define WORD_REGISTER_OPERATIONS | ||
| 8469 | + | ||
| 8470 | +/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD | ||
| 8471 | + will either zero-extend or sign-extend. The value of this macro should | ||
| 8472 | + be the code that says which one of the two operations is implicitly | ||
| 8473 | + done, UNKNOWN if not known. */ | ||
| 8474 | +#define LOAD_EXTEND_OP(MODE) \ | ||
| 8475 | + (((MODE) == QImode) ? ZERO_EXTEND \ | ||
| 8476 | + : ((MODE) == HImode) ? SIGN_EXTEND : UNKNOWN) | ||
| 8477 | + | ||
| 8478 | + | ||
| 8479 | +/* | ||
| 8480 | +Define this macro if the promotion described by PROMOTE_MODE | ||
| 8481 | +should only be performed for outgoing function arguments or | ||
| 8482 | +function return values, as specified by PROMOTE_FUNCTION_ARGS | ||
| 8483 | +and PROMOTE_FUNCTION_RETURN, respectively. | ||
| 8484 | +*/ | ||
| 8485 | +/* #define PROMOTE_FOR_CALL_ONLY */ | ||
| 8486 | + | ||
| 8487 | +/* | ||
| 8488 | +Normal alignment required for function parameters on the stack, in | ||
| 8489 | +bits. All stack parameters receive at least this much alignment | ||
| 8490 | +regardless of data type. On most machines, this is the same as the | ||
| 8491 | +size of an integer. | ||
| 8492 | +*/ | ||
| 8493 | +#define PARM_BOUNDARY 32 | ||
| 8494 | + | ||
| 8495 | +/* | ||
| 8496 | +Define this macro to the minimum alignment enforced by hardware for the | ||
| 8497 | +stack pointer on this machine. The definition is a C expression for the | ||
| 8498 | +desired alignment (measured in bits). This value is used as a default | ||
| 8499 | +if PREFERRED_STACK_BOUNDARY is not defined. On most machines, | ||
| 8500 | +this should be the same as PARM_BOUNDARY. | ||
| 8501 | +*/ | ||
| 8502 | +#define STACK_BOUNDARY 32 | ||
| 8503 | + | ||
| 8504 | +/* | ||
| 8505 | +Define this macro if you wish to preserve a certain alignment for the | ||
| 8506 | +stack pointer, greater than what the hardware enforces. The definition | ||
| 8507 | +is a C expression for the desired alignment (measured in bits). This | ||
| 8508 | +macro must evaluate to a value equal to or larger than | ||
| 8509 | +STACK_BOUNDARY. | ||
| 8510 | +*/ | ||
| 8511 | +#define PREFERRED_STACK_BOUNDARY (TARGET_FORCE_DOUBLE_ALIGN ? 64 : 32 ) | ||
| 8512 | + | ||
| 8513 | +/* | ||
| 8514 | +Alignment required for a function entry point, in bits. | ||
| 8515 | +*/ | ||
| 8516 | +#define FUNCTION_BOUNDARY 16 | ||
| 8517 | + | ||
| 8518 | +/* | ||
| 8519 | +Biggest alignment that any data type can require on this machine, in bits. | ||
| 8520 | +*/ | ||
| 8521 | +#define BIGGEST_ALIGNMENT (TARGET_FORCE_DOUBLE_ALIGN ? 64 : 32 ) | ||
| 8522 | + | ||
| 8523 | +/* | ||
| 8524 | +If defined, the smallest alignment, in bits, that can be given to an | ||
| 8525 | +object that can be referenced in one operation, without disturbing any | ||
| 8526 | +nearby object. Normally, this is BITS_PER_UNIT, but may be larger | ||
| 8527 | +on machines that don't have byte or half-word store operations. | ||
| 8528 | +*/ | ||
| 8529 | +#define MINIMUM_ATOMIC_ALIGNMENT BITS_PER_UNIT | ||
| 8530 | + | ||
| 8531 | + | ||
| 8532 | +/* | ||
| 8533 | +An integer expression for the size in bits of the largest integer machine mode that | ||
| 8534 | +should actually be used. All integer machine modes of this size or smaller can be | ||
| 8535 | +used for structures and unions with the appropriate sizes. If this macro is undefined, | ||
| 8536 | +GET_MODE_BITSIZE (DImode) is assumed.*/ | ||
| 8537 | +#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode) | ||
| 8538 | + | ||
| 8539 | + | ||
| 8540 | +/* | ||
| 8541 | +If defined, a C expression to compute the alignment given to a constant | ||
| 8542 | +that is being placed in memory. CONSTANT is the constant and | ||
| 8543 | +BASIC_ALIGN is the alignment that the object would ordinarily | ||
| 8544 | +have. The value of this macro is used instead of that alignment to | ||
| 8545 | +align the object. | ||
| 8546 | + | ||
| 8547 | +If this macro is not defined, then BASIC_ALIGN is used. | ||
| 8548 | + | ||
| 8549 | +The typical use of this macro is to increase alignment for string | ||
| 8550 | +constants to be word aligned so that strcpy calls that copy | ||
| 8551 | +constants can be done inline. | ||
| 8552 | +*/ | ||
| 8553 | +#define CONSTANT_ALIGNMENT(CONSTANT, BASIC_ALIGN) \ | ||
| 8554 | + ((TREE_CODE(CONSTANT) == STRING_CST) ? BITS_PER_WORD : BASIC_ALIGN) | ||
| 8555 | + | ||
| 8556 | +/* Try to align string to a word. */ | ||
| 8557 | +#define DATA_ALIGNMENT(TYPE, ALIGN) \ | ||
| 8558 | + ({(TREE_CODE (TYPE) == ARRAY_TYPE \ | ||
| 8559 | + && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ | ||
| 8560 | + && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN));}) | ||
| 8561 | + | ||
| 8562 | +/* Try to align local store strings to a word. */ | ||
| 8563 | +#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ | ||
| 8564 | + ({(TREE_CODE (TYPE) == ARRAY_TYPE \ | ||
| 8565 | + && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ | ||
| 8566 | + && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN));}) | ||
| 8567 | + | ||
| 8568 | +/* | ||
| 8569 | +Define this macro to be the value 1 if instructions will fail to work | ||
| 8570 | +if given data not on the nominal alignment. If instructions will merely | ||
| 8571 | +go slower in that case, define this macro as 0. | ||
| 8572 | +*/ | ||
| 8573 | +#define STRICT_ALIGNMENT 1 | ||
| 8574 | + | ||
| 8575 | +/* | ||
| 8576 | +Define this if you wish to imitate the way many other C compilers handle | ||
| 8577 | +alignment of bit-fields and the structures that contain them. | ||
| 8578 | + | ||
| 8579 | +The behavior is that the type written for a bit-field (int, | ||
| 8580 | +short, or other integer type) imposes an alignment for the | ||
| 8581 | +entire structure, as if the structure really did contain an ordinary | ||
| 8582 | +field of that type. In addition, the bit-field is placed within the | ||
| 8583 | +structure so that it would fit within such a field, not crossing a | ||
| 8584 | +boundary for it. | ||
| 8585 | + | ||
| 8586 | +Thus, on most machines, a bit-field whose type is written as int | ||
| 8587 | +would not cross a four-byte boundary, and would force four-byte | ||
| 8588 | +alignment for the whole structure. (The alignment used may not be four | ||
| 8589 | +bytes; it is controlled by the other alignment parameters.) | ||
| 8590 | + | ||
| 8591 | +If the macro is defined, its definition should be a C expression; | ||
| 8592 | +a nonzero value for the expression enables this behavior. | ||
| 8593 | + | ||
| 8594 | +Note that if this macro is not defined, or its value is zero, some | ||
| 8595 | +bit-fields may cross more than one alignment boundary. The compiler can | ||
| 8596 | +support such references if there are insv, extv, and | ||
| 8597 | +extzv insns that can directly reference memory. | ||
| 8598 | + | ||
| 8599 | +The other known way of making bit-fields work is to define | ||
| 8600 | +STRUCTURE_SIZE_BOUNDARY as large as BIGGEST_ALIGNMENT. | ||
| 8601 | +Then every structure can be accessed with fullwords. | ||
| 8602 | + | ||
| 8603 | +Unless the machine has bit-field instructions or you define | ||
| 8604 | +STRUCTURE_SIZE_BOUNDARY that way, you must define | ||
| 8605 | +PCC_BITFIELD_TYPE_MATTERS to have a nonzero value. | ||
| 8606 | + | ||
| 8607 | +If your aim is to make GCC use the same conventions for laying out | ||
| 8608 | +bit-fields as are used by another compiler, here is how to investigate | ||
| 8609 | +what the other compiler does. Compile and run this program: | ||
| 8610 | + | ||
| 8611 | +struct foo1 | ||
| 8612 | +{ | ||
| 8613 | + char x; | ||
| 8614 | + char :0; | ||
| 8615 | + char y; | ||
| 8616 | +}; | ||
| 8617 | + | ||
| 8618 | +struct foo2 | ||
| 8619 | +{ | ||
| 8620 | + char x; | ||
| 8621 | + int :0; | ||
| 8622 | + char y; | ||
| 8623 | +}; | ||
| 8624 | + | ||
| 8625 | +main () | ||
| 8626 | +{ | ||
| 8627 | + printf ("Size of foo1 is %d\n", | ||
| 8628 | + sizeof (struct foo1)); | ||
| 8629 | + printf ("Size of foo2 is %d\n", | ||
| 8630 | + sizeof (struct foo2)); | ||
| 8631 | + exit (0); | ||
| 8632 | +} | ||
| 8633 | + | ||
| 8634 | +If this prints 2 and 5, then the compiler's behavior is what you would | ||
| 8635 | +get from PCC_BITFIELD_TYPE_MATTERS. | ||
| 8636 | +*/ | ||
| 8637 | +#define PCC_BITFIELD_TYPE_MATTERS 1 | ||
| 8638 | + | ||
| 8639 | + | ||
| 8640 | +/****************************************************************************** | ||
| 8641 | + * Layout of Source Language Data Types | ||
| 8642 | + *****************************************************************************/ | ||
| 8643 | + | ||
| 8644 | +/* | ||
| 8645 | +A C expression for the size in bits of the type int on the | ||
| 8646 | +target machine. If you don't define this, the default is one word. | ||
| 8647 | +*/ | ||
| 8648 | +#define INT_TYPE_SIZE 32 | ||
| 8649 | + | ||
| 8650 | +/* | ||
| 8651 | +A C expression for the size in bits of the type short on the | ||
| 8652 | +target machine. If you don't define this, the default is half a word. (If | ||
| 8653 | +this would be less than one storage unit, it is rounded up to one unit.) | ||
| 8654 | +*/ | ||
| 8655 | +#define SHORT_TYPE_SIZE 16 | ||
| 8656 | + | ||
| 8657 | +/* | ||
| 8658 | +A C expression for the size in bits of the type long on the | ||
| 8659 | +target machine. If you don't define this, the default is one word. | ||
| 8660 | +*/ | ||
| 8661 | +#define LONG_TYPE_SIZE 32 | ||
| 8662 | + | ||
| 8663 | + | ||
| 8664 | +/* | ||
| 8665 | +A C expression for the size in bits of the type long long on the | ||
| 8666 | +target machine. If you don't define this, the default is two | ||
| 8667 | +words. If you want to support GNU Ada on your machine, the value of this | ||
| 8668 | +macro must be at least 64. | ||
| 8669 | +*/ | ||
| 8670 | +#define LONG_LONG_TYPE_SIZE 64 | ||
| 8671 | + | ||
| 8672 | +/* | ||
| 8673 | +A C expression for the size in bits of the type char on the | ||
| 8674 | +target machine. If you don't define this, the default is | ||
| 8675 | +BITS_PER_UNIT. | ||
| 8676 | +*/ | ||
| 8677 | +#define CHAR_TYPE_SIZE 8 | ||
| 8678 | + | ||
| 8679 | + | ||
| 8680 | +/* | ||
| 8681 | +A C expression for the size in bits of the C++ type bool and | ||
| 8682 | +C99 type _Bool on the target machine. If you don't define | ||
| 8683 | +this, and you probably shouldn't, the default is CHAR_TYPE_SIZE. | ||
| 8684 | +*/ | ||
| 8685 | +#define BOOL_TYPE_SIZE 8 | ||
| 8686 | + | ||
| 8687 | + | ||
| 8688 | +/* | ||
| 8689 | +An expression whose value is 1 or 0, according to whether the type | ||
| 8690 | +char should be signed or unsigned by default. The user can | ||
| 8691 | +always override this default with the options -fsigned-char | ||
| 8692 | +and -funsigned-char. | ||
| 8693 | +*/ | ||
| 8694 | +/* We are using unsigned char */ | ||
| 8695 | +#define DEFAULT_SIGNED_CHAR 0 | ||
| 8696 | + | ||
| 8697 | + | ||
| 8698 | +/* | ||
| 8699 | +A C expression for a string describing the name of the data type to use | ||
| 8700 | +for size values. The typedef name size_t is defined using the | ||
| 8701 | +contents of the string. | ||
| 8702 | + | ||
| 8703 | +The string can contain more than one keyword. If so, separate them with | ||
| 8704 | +spaces, and write first any length keyword, then unsigned if | ||
| 8705 | +appropriate, and finally int. The string must exactly match one | ||
| 8706 | +of the data type names defined in the function | ||
| 8707 | +init_decl_processing in the file c-decl.c. You may not | ||
| 8708 | +omit int or change the order - that would cause the compiler to | ||
| 8709 | +crash on startup. | ||
| 8710 | + | ||
| 8711 | +If you don't define this macro, the default is "long unsigned int". | ||
| 8712 | +*/ | ||
| 8713 | +#define SIZE_TYPE "long unsigned int" | ||
| 8714 | + | ||
| 8715 | +/* | ||
| 8716 | +A C expression for a string describing the name of the data type to use | ||
| 8717 | +for the result of subtracting two pointers. The typedef name | ||
| 8718 | +ptrdiff_t is defined using the contents of the string. See | ||
| 8719 | +SIZE_TYPE above for more information. | ||
| 8720 | + | ||
| 8721 | +If you don't define this macro, the default is "long int". | ||
| 8722 | +*/ | ||
| 8723 | +#define PTRDIFF_TYPE "long int" | ||
| 8724 | + | ||
| 8725 | + | ||
| 8726 | +/* | ||
| 8727 | +A C expression for the size in bits of the data type for wide | ||
| 8728 | +characters. This is used in cpp, which cannot make use of | ||
| 8729 | +WCHAR_TYPE. | ||
| 8730 | +*/ | ||
| 8731 | +#define WCHAR_TYPE_SIZE 32 | ||
| 8732 | + | ||
| 8733 | + | ||
| 8734 | +/* | ||
| 8735 | +A C expression for a string describing the name of the data type to | ||
| 8736 | +use for wide characters passed to printf and returned from | ||
| 8737 | +getwc. The typedef name wint_t is defined using the | ||
| 8738 | +contents of the string. See SIZE_TYPE above for more | ||
| 8739 | +information. | ||
| 8740 | + | ||
| 8741 | +If you don't define this macro, the default is "unsigned int". | ||
| 8742 | +*/ | ||
| 8743 | +#define WINT_TYPE "unsigned int" | ||
| 8744 | + | ||
| 8745 | +/* | ||
| 8746 | +A C expression for a string describing the name of the data type that | ||
| 8747 | +can represent any value of any standard or extended signed integer type. | ||
| 8748 | +The typedef name intmax_t is defined using the contents of the | ||
| 8749 | +string. See SIZE_TYPE above for more information. | ||
| 8750 | + | ||
| 8751 | +If you don't define this macro, the default is the first of | ||
| 8752 | +"int", "long int", or "long long int" that has as | ||
| 8753 | +much precision as long long int. | ||
| 8754 | +*/ | ||
| 8755 | +#define INTMAX_TYPE "long long int" | ||
| 8756 | + | ||
| 8757 | +/* | ||
| 8758 | +A C expression for a string describing the name of the data type that | ||
| 8759 | +can represent any value of any standard or extended unsigned integer | ||
| 8760 | +type. The typedef name uintmax_t is defined using the contents | ||
| 8761 | +of the string. See SIZE_TYPE above for more information. | ||
| 8762 | + | ||
| 8763 | +If you don't define this macro, the default is the first of | ||
| 8764 | +"unsigned int", "long unsigned int", or "long long unsigned int" | ||
| 8765 | +that has as much precision as long long unsigned int. | ||
| 8766 | +*/ | ||
| 8767 | +#define UINTMAX_TYPE "long long unsigned int" | ||
| 8768 | + | ||
| 8769 | + | ||
| 8770 | +/****************************************************************************** | ||
| 8771 | + * Register Usage | ||
| 8772 | + *****************************************************************************/ | ||
| 8773 | + | ||
| 8774 | +/* Convert from gcc internal register number to register number | ||
| 8775 | + used in assembly code */ | ||
| 8776 | +#define ASM_REGNUM(reg) (LAST_REGNUM - (reg)) | ||
| 8777 | +#define ASM_FP_REGNUM(reg) (LAST_FP_REGNUM - (reg)) | ||
| 8778 | + | ||
| 8779 | +/* Convert between register number used in assembly to gcc | ||
| 8780 | + internal register number */ | ||
| 8781 | +#define INTERNAL_REGNUM(reg) (LAST_REGNUM - (reg)) | ||
| 8782 | +#define INTERNAL_FP_REGNUM(reg) (LAST_FP_REGNUM - (reg)) | ||
| 8783 | + | ||
| 8784 | +/** Basic Characteristics of Registers **/ | ||
| 8785 | + | ||
| 8786 | +/* | ||
| 8787 | +Number of hardware registers known to the compiler. They receive | ||
| 8788 | +numbers 0 through FIRST_PSEUDO_REGISTER-1; thus, the first | ||
| 8789 | +pseudo register's number really is assigned the number | ||
| 8790 | +FIRST_PSEUDO_REGISTER. | ||
| 8791 | +*/ | ||
| 8792 | +#define FIRST_PSEUDO_REGISTER (LAST_FP_REGNUM + 1) | ||
| 8793 | + | ||
| 8794 | +#define FIRST_REGNUM 0 | ||
| 8795 | +#define LAST_REGNUM 15 | ||
| 8796 | +#define NUM_FP_REGS 16 | ||
| 8797 | +#define FIRST_FP_REGNUM 16 | ||
| 8798 | +#define LAST_FP_REGNUM (16+NUM_FP_REGS-1) | ||
| 8799 | + | ||
| 8800 | +/* | ||
| 8801 | +An initializer that says which registers are used for fixed purposes | ||
| 8802 | +all throughout the compiled code and are therefore not available for | ||
| 8803 | +general allocation. These would include the stack pointer, the frame | ||
| 8804 | +pointer (except on machines where that can be used as a general | ||
| 8805 | +register when no frame pointer is needed), the program counter on | ||
| 8806 | +machines where that is considered one of the addressable registers, | ||
| 8807 | +and any other numbered register with a standard use. | ||
| 8808 | + | ||
| 8809 | +This information is expressed as a sequence of numbers, separated by | ||
| 8810 | +commas and surrounded by braces. The nth number is 1 if | ||
| 8811 | +register n is fixed, 0 otherwise. | ||
| 8812 | + | ||
| 8813 | +The table initialized from this macro, and the table initialized by | ||
| 8814 | +the following one, may be overridden at run time either automatically, | ||
| 8815 | +by the actions of the macro CONDITIONAL_REGISTER_USAGE, or by | ||
| 8816 | +the user with the command options -ffixed-[reg], | ||
| 8817 | +-fcall-used-[reg] and -fcall-saved-[reg]. | ||
| 8818 | +*/ | ||
| 8819 | + | ||
| 8820 | +/* The internal gcc register numbers are reversed | ||
| 8821 | + compared to the real register numbers since | ||
| 8822 | + gcc expects data types stored over multiple | ||
| 8823 | + registers in the register file to be big endian | ||
| 8824 | + if the memory layout is big endian. But this | ||
| 8825 | + is not the case for avr32 so we fake a big | ||
| 8826 | + endian register file. */ | ||
| 8827 | + | ||
| 8828 | +#define FIXED_REGISTERS { \ | ||
| 8829 | + 1, /* Program Counter */ \ | ||
| 8830 | + 0, /* Link Register */ \ | ||
| 8831 | + 1, /* Stack Pointer */ \ | ||
| 8832 | + 0, /* r12 */ \ | ||
| 8833 | + 0, /* r11 */ \ | ||
| 8834 | + 0, /* r10 */ \ | ||
| 8835 | + 0, /* r9 */ \ | ||
| 8836 | + 0, /* r8 */ \ | ||
| 8837 | + 0, /* r7 */ \ | ||
| 8838 | + 0, /* r6 */ \ | ||
| 8839 | + 0, /* r5 */ \ | ||
| 8840 | + 0, /* r4 */ \ | ||
| 8841 | + 0, /* r3 */ \ | ||
| 8842 | + 0, /* r2 */ \ | ||
| 8843 | + 0, /* r1 */ \ | ||
| 8844 | + 0, /* r0 */ \ | ||
| 8845 | + 0, /* f15 */ \ | ||
| 8846 | + 0, /* f14 */ \ | ||
| 8847 | + 0, /* f13 */ \ | ||
| 8848 | + 0, /* f12 */ \ | ||
| 8849 | + 0, /* f11 */ \ | ||
| 8850 | + 0, /* f10 */ \ | ||
| 8851 | + 0, /* f9 */ \ | ||
| 8852 | + 0, /* f8 */ \ | ||
| 8853 | + 0, /* f7 */ \ | ||
| 8854 | + 0, /* f6 */ \ | ||
| 8855 | + 0, /* f5 */ \ | ||
| 8856 | + 0, /* f4 */ \ | ||
| 8857 | + 0, /* f3 */ \ | ||
| 8858 | + 0, /* f2*/ \ | ||
| 8859 | + 0, /* f1 */ \ | ||
| 8860 | + 0 /* f0 */ \ | ||
| 8861 | +} | ||
| 8862 | + | ||
| 8863 | +/* | ||
| 8864 | +Like FIXED_REGISTERS but has 1 for each register that is | ||
| 8865 | +clobbered (in general) by function calls as well as for fixed | ||
| 8866 | +registers. This macro therefore identifies the registers that are not | ||
| 8867 | +available for general allocation of values that must live across | ||
| 8868 | +function calls. | ||
| 8869 | + | ||
| 8870 | +If a register has 0 in CALL_USED_REGISTERS, the compiler | ||
| 8871 | +automatically saves it on function entry and restores it on function | ||
| 8872 | +exit, if the register is used within the function. | ||
| 8873 | +*/ | ||
| 8874 | +#define CALL_USED_REGISTERS { \ | ||
| 8875 | + 1, /* Program Counter */ \ | ||
| 8876 | + 0, /* Link Register */ \ | ||
| 8877 | + 1, /* Stack Pointer */ \ | ||
| 8878 | + 1, /* r12 */ \ | ||
| 8879 | + 1, /* r11 */ \ | ||
| 8880 | + 1, /* r10 */ \ | ||
| 8881 | + 1, /* r9 */ \ | ||
| 8882 | + 1, /* r8 */ \ | ||
| 8883 | + 0, /* r7 */ \ | ||
| 8884 | + 0, /* r6 */ \ | ||
| 8885 | + 0, /* r5 */ \ | ||
| 8886 | + 0, /* r4 */ \ | ||
| 8887 | + 0, /* r3 */ \ | ||
| 8888 | + 0, /* r2 */ \ | ||
| 8889 | + 0, /* r1 */ \ | ||
| 8890 | + 0, /* r0 */ \ | ||
| 8891 | + 1, /* f15 */ \ | ||
| 8892 | + 1, /* f14 */ \ | ||
| 8893 | + 1, /* f13 */ \ | ||
| 8894 | + 1, /* f12 */ \ | ||
| 8895 | + 1, /* f11 */ \ | ||
| 8896 | + 1, /* f10 */ \ | ||
| 8897 | + 1, /* f9 */ \ | ||
| 8898 | + 1, /* f8 */ \ | ||
| 8899 | + 0, /* f7 */ \ | ||
| 8900 | + 0, /* f6 */ \ | ||
| 8901 | + 0, /* f5 */ \ | ||
| 8902 | + 0, /* f4 */ \ | ||
| 8903 | + 0, /* f3 */ \ | ||
| 8904 | + 0, /* f2*/ \ | ||
| 8905 | + 0, /* f1*/ \ | ||
| 8906 | + 0, /* f0 */ \ | ||
| 8907 | +} | ||
| 8908 | + | ||
| 8909 | +/* Interrupt functions can only use registers that have already been | ||
| 8910 | + saved by the prologue, even if they would normally be | ||
| 8911 | + call-clobbered. */ | ||
| 8912 | +#define HARD_REGNO_RENAME_OK(SRC, DST) \ | ||
| 8913 | + (! IS_INTERRUPT (cfun->machine->func_type) || \ | ||
| 8914 | + regs_ever_live[DST]) | ||
| 8915 | + | ||
| 8916 | + | ||
| 8917 | +/* | ||
| 8918 | +Zero or more C statements that may conditionally modify five variables | ||
| 8919 | +fixed_regs, call_used_regs, global_regs, | ||
| 8920 | +reg_names, and reg_class_contents, to take into account | ||
| 8921 | +any dependence of these register sets on target flags. The first three | ||
| 8922 | +of these are of type char [] (interpreted as Boolean vectors). | ||
| 8923 | +global_regs is a const char *[], and | ||
| 8924 | +reg_class_contents is a HARD_REG_SET. Before the macro is | ||
| 8925 | +called, fixed_regs, call_used_regs, | ||
| 8926 | +reg_class_contents, and reg_names have been initialized | ||
| 8927 | +from FIXED_REGISTERS, CALL_USED_REGISTERS, | ||
| 8928 | +REG_CLASS_CONTENTS, and REGISTER_NAMES, respectively. | ||
| 8929 | +global_regs has been cleared, and any -ffixed-[reg], | ||
| 8930 | +-fcall-used-[reg] and -fcall-saved-[reg] | ||
| 8931 | +command options have been applied. | ||
| 8932 | + | ||
| 8933 | +You need not define this macro if it has no work to do. | ||
| 8934 | + | ||
| 8935 | +If the usage of an entire class of registers depends on the target | ||
| 8936 | +flags, you may indicate this to GCC by using this macro to modify | ||
| 8937 | +fixed_regs and call_used_regs to 1 for each of the | ||
| 8938 | +registers in the classes which should not be used by GCC. Also define | ||
| 8939 | +the macro REG_CLASS_FROM_LETTER to return NO_REGS if it | ||
| 8940 | +is called with a letter for a class that shouldn't be used. | ||
| 8941 | + | ||
| 8942 | + (However, if this class is not included in GENERAL_REGS and all | ||
| 8943 | +of the insn patterns whose constraints permit this class are | ||
| 8944 | +controlled by target switches, then GCC will automatically avoid using | ||
| 8945 | +these registers when the target switches are opposed to them.) | ||
| 8946 | +*/ | ||
| 8947 | +#define CONDITIONAL_REGISTER_USAGE \ | ||
| 8948 | + do \ | ||
| 8949 | + { \ | ||
| 8950 | + int regno; \ | ||
| 8951 | + \ | ||
| 8952 | + if (TARGET_SOFT_FLOAT) \ | ||
| 8953 | + { \ | ||
| 8954 | + for (regno = FIRST_FP_REGNUM; \ | ||
| 8955 | + regno <= LAST_FP_REGNUM; ++regno) \ | ||
| 8956 | + fixed_regs[regno] = call_used_regs[regno] = 1; \ | ||
| 8957 | + } \ | ||
| 8958 | + if (flag_pic) \ | ||
| 8959 | + { \ | ||
| 8960 | + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ | ||
| 8961 | + call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ | ||
| 8962 | + } \ | ||
| 8963 | + } \ | ||
| 8964 | + while (0) | ||
| 8965 | + | ||
| 8966 | + | ||
| 8967 | +/* | ||
| 8968 | +If the program counter has a register number, define this as that | ||
| 8969 | +register number. Otherwise, do not define it. | ||
| 8970 | +*/ | ||
| 8971 | + | ||
| 8972 | +#define LAST_AVR32_REGNUM 16 | ||
| 8973 | + | ||
| 8974 | + | ||
| 8975 | +/** Order of Allocation of Registers **/ | ||
| 8976 | + | ||
| 8977 | +/* | ||
| 8978 | +If defined, an initializer for a vector of integers, containing the | ||
| 8979 | +numbers of hard registers in the order in which GCC should prefer | ||
| 8980 | +to use them (from most preferred to least). | ||
| 8981 | + | ||
| 8982 | +If this macro is not defined, registers are used lowest numbered first | ||
| 8983 | +(all else being equal). | ||
| 8984 | + | ||
| 8985 | +One use of this macro is on machines where the highest numbered | ||
| 8986 | +registers must always be saved and the save-multiple-registers | ||
| 8987 | +instruction supports only sequences of consecutive registers. On such | ||
| 8988 | +machines, define REG_ALLOC_ORDER to be an initializer that lists | ||
| 8989 | +the highest numbered allocable register first. | ||
| 8990 | +*/ | ||
| 8991 | +#define REG_ALLOC_ORDER \ | ||
| 8992 | +{ \ | ||
| 8993 | + INTERNAL_REGNUM(8), \ | ||
| 8994 | + INTERNAL_REGNUM(9), \ | ||
| 8995 | + INTERNAL_REGNUM(10), \ | ||
| 8996 | + INTERNAL_REGNUM(11), \ | ||
| 8997 | + INTERNAL_REGNUM(12), \ | ||
| 8998 | + LR_REGNUM, \ | ||
| 8999 | + INTERNAL_REGNUM(7), \ | ||
| 9000 | + INTERNAL_REGNUM(6), \ | ||
| 9001 | + INTERNAL_REGNUM(5), \ | ||
| 9002 | + INTERNAL_REGNUM(4), \ | ||
| 9003 | + INTERNAL_REGNUM(3), \ | ||
| 9004 | + INTERNAL_REGNUM(2), \ | ||
| 9005 | + INTERNAL_REGNUM(1), \ | ||
| 9006 | + INTERNAL_REGNUM(0), \ | ||
| 9007 | + INTERNAL_FP_REGNUM(15), \ | ||
| 9008 | + INTERNAL_FP_REGNUM(14), \ | ||
| 9009 | + INTERNAL_FP_REGNUM(13), \ | ||
| 9010 | + INTERNAL_FP_REGNUM(12), \ | ||
| 9011 | + INTERNAL_FP_REGNUM(11), \ | ||
| 9012 | + INTERNAL_FP_REGNUM(10), \ | ||
| 9013 | + INTERNAL_FP_REGNUM(9), \ | ||
| 9014 | + INTERNAL_FP_REGNUM(8), \ | ||
| 9015 | + INTERNAL_FP_REGNUM(7), \ | ||
| 9016 | + INTERNAL_FP_REGNUM(6), \ | ||
| 9017 | + INTERNAL_FP_REGNUM(5), \ | ||
| 9018 | + INTERNAL_FP_REGNUM(4), \ | ||
| 9019 | + INTERNAL_FP_REGNUM(3), \ | ||
| 9020 | + INTERNAL_FP_REGNUM(2), \ | ||
| 9021 | + INTERNAL_FP_REGNUM(1), \ | ||
| 9022 | + INTERNAL_FP_REGNUM(0), \ | ||
| 9023 | + SP_REGNUM, \ | ||
| 9024 | + PC_REGNUM \ | ||
| 9025 | +} | ||
| 9026 | + | ||
| 9027 | + | ||
| 9028 | +/** How Values Fit in Registers **/ | ||
| 9029 | + | ||
| 9030 | +/* | ||
| 9031 | +A C expression for the number of consecutive hard registers, starting | ||
| 9032 | +at register number REGNO, required to hold a value of mode | ||
| 9033 | +MODE. | ||
| 9034 | + | ||
| 9035 | +On a machine where all registers are exactly one word, a suitable | ||
| 9036 | +definition of this macro is | ||
| 9037 | + | ||
| 9038 | +#define HARD_REGNO_NREGS(REGNO, MODE) \ | ||
| 9039 | + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \ | ||
| 9040 | + / UNITS_PER_WORD) | ||
| 9041 | +*/ | ||
| 9042 | +#define HARD_REGNO_NREGS(REGNO, MODE) \ | ||
| 9043 | + ((unsigned int)((GET_MODE_SIZE(MODE) + UNITS_PER_WORD -1 ) / UNITS_PER_WORD)) | ||
| 9044 | + | ||
| 9045 | +/* | ||
| 9046 | +A C expression that is nonzero if it is permissible to store a value | ||
| 9047 | +of mode MODE in hard register number REGNO (or in several | ||
| 9048 | +registers starting with that one). For a machine where all registers | ||
| 9049 | +are equivalent, a suitable definition is | ||
| 9050 | + | ||
| 9051 | + #define HARD_REGNO_MODE_OK(REGNO, MODE) 1 | ||
| 9052 | + | ||
| 9053 | +You need not include code to check for the numbers of fixed registers, | ||
| 9054 | +because the allocation mechanism considers them to be always occupied. | ||
| 9055 | + | ||
| 9056 | +On some machines, double-precision values must be kept in even/odd | ||
| 9057 | +register pairs. You can implement that by defining this macro to reject | ||
| 9058 | +odd register numbers for such modes. | ||
| 9059 | + | ||
| 9060 | +The minimum requirement for a mode to be OK in a register is that the | ||
| 9061 | +mov[mode] instruction pattern support moves between the | ||
| 9062 | +register and other hard register in the same class and that moving a | ||
| 9063 | +value into the register and back out not alter it. | ||
| 9064 | + | ||
| 9065 | +Since the same instruction used to move word_mode will work for | ||
| 9066 | +all narrower integer modes, it is not necessary on any machine for | ||
| 9067 | +HARD_REGNO_MODE_OK to distinguish between these modes, provided | ||
| 9068 | +you define patterns movhi, etc., to take advantage of this. This | ||
| 9069 | +is useful because of the interaction between HARD_REGNO_MODE_OK | ||
| 9070 | +and MODES_TIEABLE_P; it is very desirable for all integer modes | ||
| 9071 | +to be tieable. | ||
| 9072 | + | ||
| 9073 | +Many machines have special registers for floating point arithmetic. | ||
| 9074 | +Often people assume that floating point machine modes are allowed only | ||
| 9075 | +in floating point registers. This is not true. Any registers that | ||
| 9076 | +can hold integers can safely hold a floating point machine | ||
| 9077 | +mode, whether or not floating arithmetic can be done on it in those | ||
| 9078 | +registers. Integer move instructions can be used to move the values. | ||
| 9079 | + | ||
| 9080 | +On some machines, though, the converse is true: fixed-point machine | ||
| 9081 | +modes may not go in floating registers. This is true if the floating | ||
| 9082 | +registers normalize any value stored in them, because storing a | ||
| 9083 | +non-floating value there would garble it. In this case, | ||
| 9084 | +HARD_REGNO_MODE_OK should reject fixed-point machine modes in | ||
| 9085 | +floating registers. But if the floating registers do not automatically | ||
| 9086 | +normalize, if you can store any bit pattern in one and retrieve it | ||
| 9087 | +unchanged without a trap, then any machine mode may go in a floating | ||
| 9088 | +register, so you can define this macro to say so. | ||
| 9089 | + | ||
| 9090 | +The primary significance of special floating registers is rather that | ||
| 9091 | +they are the registers acceptable in floating point arithmetic | ||
| 9092 | +instructions. However, this is of no concern to | ||
| 9093 | +HARD_REGNO_MODE_OK. You handle it by writing the proper | ||
| 9094 | +constraints for those instructions. | ||
| 9095 | + | ||
| 9096 | +On some machines, the floating registers are especially slow to access, | ||
| 9097 | +so that it is better to store a value in a stack frame than in such a | ||
| 9098 | +register if floating point arithmetic is not being done. As long as the | ||
| 9099 | +floating registers are not in class GENERAL_REGS, they will not | ||
| 9100 | +be used unless some pattern's constraint asks for one. | ||
| 9101 | +*/ | ||
| 9102 | +#define HARD_REGNO_MODE_OK(REGNO, MODE) avr32_hard_regno_mode_ok(REGNO, MODE) | ||
| 9103 | + | ||
| 9104 | +/* | ||
| 9105 | +A C expression that is nonzero if a value of mode | ||
| 9106 | +MODE1 is accessible in mode MODE2 without copying. | ||
| 9107 | + | ||
| 9108 | +If HARD_REGNO_MODE_OK(R, MODE1) and | ||
| 9109 | +HARD_REGNO_MODE_OK(R, MODE2) are always the same for | ||
| 9110 | +any R, then MODES_TIEABLE_P(MODE1, MODE2) | ||
| 9111 | +should be nonzero. If they differ for any R, you should define | ||
| 9112 | +this macro to return zero unless some other mechanism ensures the | ||
| 9113 | +accessibility of the value in a narrower mode. | ||
| 9114 | + | ||
| 9115 | +You should define this macro to return nonzero in as many cases as | ||
| 9116 | +possible since doing so will allow GCC to perform better register | ||
| 9117 | +allocation. | ||
| 9118 | +*/ | ||
| 9119 | +#define MODES_TIEABLE_P(MODE1, MODE2) \ | ||
| 9120 | + (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)) | ||
| 9121 | + | ||
| 9122 | + | ||
| 9123 | + | ||
| 9124 | +/****************************************************************************** | ||
| 9125 | + * Register Classes | ||
| 9126 | + *****************************************************************************/ | ||
| 9127 | + | ||
| 9128 | +/* | ||
| 9129 | +An enumeral type that must be defined with all the register class names | ||
| 9130 | +as enumeral values. NO_REGS must be first. ALL_REGS | ||
| 9131 | +must be the last register class, followed by one more enumeral value, | ||
| 9132 | +LIM_REG_CLASSES, which is not a register class but rather | ||
| 9133 | +tells how many classes there are. | ||
| 9134 | + | ||
| 9135 | +Each register class has a number, which is the value of casting | ||
| 9136 | +the class name to type int. The number serves as an index | ||
| 9137 | +in many of the tables described below. | ||
| 9138 | +*/ | ||
| 9139 | +enum reg_class | ||
| 9140 | +{ | ||
| 9141 | + NO_REGS, | ||
| 9142 | + GENERAL_REGS, | ||
| 9143 | + FP_REGS, | ||
| 9144 | + ALL_REGS, | ||
| 9145 | + LIM_REG_CLASSES | ||
| 9146 | +}; | ||
| 9147 | + | ||
| 9148 | +/* | ||
| 9149 | +The number of distinct register classes, defined as follows: | ||
| 9150 | + #define N_REG_CLASSES (int) LIM_REG_CLASSES | ||
| 9151 | +*/ | ||
| 9152 | +#define N_REG_CLASSES (int)LIM_REG_CLASSES | ||
| 9153 | + | ||
| 9154 | +/* | ||
| 9155 | +An initializer containing the names of the register classes as C string | ||
| 9156 | +constants. These names are used in writing some of the debugging dumps. | ||
| 9157 | +*/ | ||
| 9158 | +#define REG_CLASS_NAMES \ | ||
| 9159 | +{ \ | ||
| 9160 | + "NO_REGS", \ | ||
| 9161 | + "GENERAL_REGS", \ | ||
| 9162 | + "FLOATING_POINT_REGS", \ | ||
| 9163 | + "ALL_REGS" \ | ||
| 9164 | +} | ||
| 9165 | + | ||
| 9166 | +/* | ||
| 9167 | +An initializer containing the contents of the register classes, as integers | ||
| 9168 | +which are bit masks. The nth integer specifies the contents of class | ||
| 9169 | +n. The way the integer mask is interpreted is that | ||
| 9170 | +register r is in the class if mask & (1 << r) is 1. | ||
| 9171 | + | ||
| 9172 | +When the machine has more than 32 registers, an integer does not suffice. | ||
| 9173 | +Then the integers are replaced by sub-initializers, braced groupings containing | ||
| 9174 | +several integers. Each sub-initializer must be suitable as an initializer | ||
| 9175 | +for the type HARD_REG_SET which is defined in hard-reg-set.h. | ||
| 9176 | +In this situation, the first integer in each sub-initializer corresponds to | ||
| 9177 | +registers 0 through 31, the second integer to registers 32 through 63, and | ||
| 9178 | +so on. | ||
| 9179 | +*/ | ||
| 9180 | +#define REG_CLASS_CONTENTS { \ | ||
| 9181 | + {0x00000000}, /* NO_REGS */ \ | ||
| 9182 | + {0x0000FFFF}, /* GENERAL_REGS */ \ | ||
| 9183 | + {0xFFFF0000}, /* FP_REGS */ \ | ||
| 9184 | + {0x7FFFFFFF}, /* ALL_REGS */ \ | ||
| 9185 | +} | ||
| 9186 | + | ||
| 9187 | + | ||
| 9188 | +/* | ||
| 9189 | +A C expression whose value is a register class containing hard register | ||
| 9190 | +REGNO. In general there is more than one such class; choose a class | ||
| 9191 | +which is minimal, meaning that no smaller class also contains the | ||
| 9192 | +register. | ||
| 9193 | +*/ | ||
| 9194 | +#define REGNO_REG_CLASS(REGNO) ((REGNO < 16) ? GENERAL_REGS : FP_REGS) | ||
| 9195 | + | ||
| 9196 | +/* | ||
| 9197 | +A macro whose definition is the name of the class to which a valid | ||
| 9198 | +base register must belong. A base register is one used in an address | ||
| 9199 | +which is the register value plus a displacement. | ||
| 9200 | +*/ | ||
| 9201 | +#define BASE_REG_CLASS GENERAL_REGS | ||
| 9202 | + | ||
| 9203 | +/* | ||
| 9204 | +This is a variation of the BASE_REG_CLASS macro which allows | ||
| 9205 | +the selection of a base register in a mode depenedent manner. If | ||
| 9206 | +mode is VOIDmode then it should return the same value as | ||
| 9207 | +BASE_REG_CLASS. | ||
| 9208 | +*/ | ||
| 9209 | +#define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS | ||
| 9210 | + | ||
| 9211 | +/* | ||
| 9212 | +A macro whose definition is the name of the class to which a valid | ||
| 9213 | +index register must belong. An index register is one used in an | ||
| 9214 | +address where its value is either multiplied by a scale factor or | ||
| 9215 | +added to another register (as well as added to a displacement). | ||
| 9216 | +*/ | ||
| 9217 | +#define INDEX_REG_CLASS BASE_REG_CLASS | ||
| 9218 | + | ||
| 9219 | +/* | ||
| 9220 | +A C expression which defines the machine-dependent operand constraint | ||
| 9221 | +letters for register classes. If CHAR is such a letter, the | ||
| 9222 | +value should be the register class corresponding to it. Otherwise, | ||
| 9223 | +the value should be NO_REGS. The register letter r, | ||
| 9224 | +corresponding to class GENERAL_REGS, will not be passed | ||
| 9225 | +to this macro; you do not need to handle it. | ||
| 9226 | +*/ | ||
| 9227 | +#define REG_CLASS_FROM_LETTER(CHAR) ((CHAR) == 'f' ? FP_REGS : NO_REGS) | ||
| 9228 | + | ||
| 9229 | + | ||
| 9230 | +/* These assume that REGNO is a hard or pseudo reg number. | ||
| 9231 | + They give nonzero only if REGNO is a hard reg of the suitable class | ||
| 9232 | + or a pseudo reg currently allocated to a suitable hard reg. | ||
| 9233 | + Since they use reg_renumber, they are safe only once reg_renumber | ||
| 9234 | + has been allocated, which happens in local-alloc.c. */ | ||
| 9235 | +#define TEST_REGNO(R, TEST, VALUE) \ | ||
| 9236 | + ((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE)) | ||
| 9237 | + | ||
| 9238 | +/* | ||
| 9239 | +A C expression which is nonzero if register number num is suitable for use as a base | ||
| 9240 | +register in operand addresses. It may be either a suitable hard register or a pseudo | ||
| 9241 | +register that has been allocated such a hard register. | ||
| 9242 | +*/ | ||
| 9243 | +#define REGNO_OK_FOR_BASE_P(NUM) TEST_REGNO(NUM, <=, LAST_REGNUM) | ||
| 9244 | + | ||
| 9245 | +/* | ||
| 9246 | +A C expression which is nonzero if register number NUM is | ||
| 9247 | +suitable for use as an index register in operand addresses. It may be | ||
| 9248 | +either a suitable hard register or a pseudo register that has been | ||
| 9249 | +allocated such a hard register. | ||
| 9250 | + | ||
| 9251 | +The difference between an index register and a base register is that | ||
| 9252 | +the index register may be scaled. If an address involves the sum of | ||
| 9253 | +two registers, neither one of them scaled, then either one may be | ||
| 9254 | +labeled the ``base'' and the other the ``index''; but whichever | ||
| 9255 | +labeling is used must fit the machine's constraints of which registers | ||
| 9256 | +may serve in each capacity. The compiler will try both labelings, | ||
| 9257 | +looking for one that is valid, and will reload one or both registers | ||
| 9258 | +only if neither labeling works. | ||
| 9259 | +*/ | ||
| 9260 | +#define REGNO_OK_FOR_INDEX_P(NUM) TEST_REGNO(NUM, <=, LAST_REGNUM) | ||
| 9261 | + | ||
| 9262 | +/* | ||
| 9263 | +A C expression that places additional restrictions on the register class | ||
| 9264 | +to use when it is necessary to copy value X into a register in class | ||
| 9265 | +CLASS. The value is a register class; perhaps CLASS, or perhaps | ||
| 9266 | +another, smaller class. On many machines, the following definition is | ||
| 9267 | +safe: #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS | ||
| 9268 | + | ||
| 9269 | +Sometimes returning a more restrictive class makes better code. For | ||
| 9270 | +example, on the 68000, when X is an integer constant that is in range | ||
| 9271 | +for a 'moveq' instruction, the value of this macro is always | ||
| 9272 | +DATA_REGS as long as CLASS includes the data registers. | ||
| 9273 | +Requiring a data register guarantees that a 'moveq' will be used. | ||
| 9274 | + | ||
| 9275 | +If X is a const_double, by returning NO_REGS | ||
| 9276 | +you can force X into a memory constant. This is useful on | ||
| 9277 | +certain machines where immediate floating values cannot be loaded into | ||
| 9278 | +certain kinds of registers. | ||
| 9279 | +*/ | ||
| 9280 | +#define PREFERRED_RELOAD_CLASS(X, CLASS) CLASS | ||
| 9281 | + | ||
| 9282 | + | ||
| 9283 | + | ||
| 9284 | +/* | ||
| 9285 | +A C expression for the maximum number of consecutive registers | ||
| 9286 | +of class CLASS needed to hold a value of mode MODE. | ||
| 9287 | + | ||
| 9288 | +This is closely related to the macro HARD_REGNO_NREGS. In fact, | ||
| 9289 | +the value of the macro CLASS_MAX_NREGS(CLASS, MODE) | ||
| 9290 | +should be the maximum value of HARD_REGNO_NREGS(REGNO, MODE) | ||
| 9291 | +for all REGNO values in the class CLASS. | ||
| 9292 | + | ||
| 9293 | +This macro helps control the handling of multiple-word values | ||
| 9294 | +in the reload pass. | ||
| 9295 | +*/ | ||
| 9296 | +#define CLASS_MAX_NREGS(CLASS, MODE) /* ToDo:fixme */ \ | ||
| 9297 | + (unsigned int)((GET_MODE_SIZE(MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) | ||
| 9298 | + | ||
| 9299 | + | ||
| 9300 | +/* | ||
| 9301 | + Using CONST_OK_FOR_CONSTRAINT_P instead of CONS_OK_FOR_LETTER_P | ||
| 9302 | + in order to support constraints with more than one letter. | ||
| 9303 | + Only two letters are then used for constant constraints, | ||
| 9304 | + the letter 'K' and the letter 'I'. The constraint starting with | ||
| 9305 | + these letters must consist of four characters. The character following | ||
| 9306 | + 'K' or 'I' must be either 'u' (unsigned) or 's' (signed) to specify | ||
| 9307 | + if the constant is zero or sign extended. The last two characters specify | ||
| 9308 | + the length in bits of the constant. The base constraint letter 'I' means | ||
| 9309 | + that this is an negated constant, meaning that actually -VAL should be | ||
| 9310 | + checked to lie withing the valid range instead of VAL which is used when | ||
| 9311 | + 'K' is the base constraint letter. | ||
| 9312 | + | ||
| 9313 | +*/ | ||
| 9314 | + | ||
| 9315 | +#define CONSTRAINT_LEN(C, STR) \ | ||
| 9316 | + ( ((C) == 'K' || (C) == 'I') ? 4 : \ | ||
| 9317 | + ((C) == 'R') ? 5 : \ | ||
| 9318 | + ((C) == 'N' || (C) == 'O' || \ | ||
| 9319 | + (C) == 'P' || (C) == 'L' || (C) == 'J') ? -1 : \ | ||
| 9320 | + DEFAULT_CONSTRAINT_LEN((C), (STR)) ) | ||
| 9321 | + | ||
| 9322 | +#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \ | ||
| 9323 | + avr32_const_ok_for_constraint_p(VALUE, C, STR) | ||
| 9324 | + | ||
| 9325 | +/* | ||
| 9326 | +A C expression that defines the machine-dependent operand constraint | ||
| 9327 | +letters that specify particular ranges of const_double values ('G' or 'H'). | ||
| 9328 | + | ||
| 9329 | +If C is one of those letters, the expression should check that | ||
| 9330 | +VALUE, an RTX of code const_double, is in the appropriate | ||
| 9331 | +range and return 1 if so, 0 otherwise. If C is not one of those | ||
| 9332 | +letters, the value should be 0 regardless of VALUE. | ||
| 9333 | + | ||
| 9334 | +const_double is used for all floating-point constants and for | ||
| 9335 | +DImode fixed-point constants. A given letter can accept either | ||
| 9336 | +or both kinds of values. It can use GET_MODE to distinguish | ||
| 9337 | +between these kinds. | ||
| 9338 | +*/ | ||
| 9339 | +#define CONST_DOUBLE_OK_FOR_LETTER_P(OP, C) \ | ||
| 9340 | + ((C) == 'G' ? avr32_const_double_immediate(OP) : 0) | ||
| 9341 | + | ||
| 9342 | +/* | ||
| 9343 | +A C expression that defines the optional machine-dependent constraint | ||
| 9344 | +letters that can be used to segregate specific types of operands, usually | ||
| 9345 | +memory references, for the target machine. Any letter that is not | ||
| 9346 | +elsewhere defined and not matched by REG_CLASS_FROM_LETTER | ||
| 9347 | +may be used. Normally this macro will not be defined. | ||
| 9348 | + | ||
| 9349 | +If it is required for a particular target machine, it should return 1 | ||
| 9350 | +if VALUE corresponds to the operand type represented by the | ||
| 9351 | +constraint letter C. If C is not defined as an extra | ||
| 9352 | +constraint, the value returned should be 0 regardless of VALUE. | ||
| 9353 | + | ||
| 9354 | +For example, on the ROMP, load instructions cannot have their output | ||
| 9355 | +in r0 if the memory reference contains a symbolic address. Constraint | ||
| 9356 | +letter 'Q' is defined as representing a memory address that does | ||
| 9357 | +not contain a symbolic address. An alternative is specified with | ||
| 9358 | +a 'Q' constraint on the input and 'r' on the output. The next | ||
| 9359 | +alternative specifies 'm' on the input and a register class that | ||
| 9360 | +does not include r0 on the output. | ||
| 9361 | +*/ | ||
| 9362 | +#define EXTRA_CONSTRAINT_STR(OP, C, STR) \ | ||
| 9363 | + ((C) == 'W' ? avr32_address_operand(OP, GET_MODE(OP)) : \ | ||
| 9364 | + (C) == 'R' ? (avr32_indirect_register_operand(OP, GET_MODE(OP)) || \ | ||
| 9365 | + (avr32_imm_disp_memory_operand(OP, GET_MODE(OP)) \ | ||
| 9366 | + && avr32_const_ok_for_constraint_p( \ | ||
| 9367 | + INTVAL(XEXP(XEXP(OP, 0), 1)), \ | ||
| 9368 | + (STR)[1], &(STR)[1]))) : \ | ||
| 9369 | + (C) == 'S' ? avr32_indexed_memory_operand(OP, GET_MODE(OP)) : \ | ||
| 9370 | + (C) == 'T' ? avr32_const_pool_ref_operand(OP, GET_MODE(OP)) : \ | ||
| 9371 | + (C) == 'U' ? SYMBOL_REF_RCALL_FUNCTION_P(OP) : \ | ||
| 9372 | + (C) == 'Z' ? avr32_cop_memory_operand(OP, GET_MODE(OP)) : \ | ||
| 9373 | + 0) | ||
| 9374 | + | ||
| 9375 | + | ||
| 9376 | +#define EXTRA_MEMORY_CONSTRAINT(C, STR) ( ((C) == 'R') || \ | ||
| 9377 | + ((C) == 'S') || \ | ||
| 9378 | + ((C) == 'Z') ) | ||
| 9379 | + | ||
| 9380 | + | ||
| 9381 | +/* Returns nonzero if op is a function SYMBOL_REF which | ||
| 9382 | + can be called using an rcall instruction */ | ||
| 9383 | +#define SYMBOL_REF_RCALL_FUNCTION_P(op) \ | ||
| 9384 | + ( GET_CODE(op) == SYMBOL_REF \ | ||
| 9385 | + && SYMBOL_REF_FUNCTION_P(op) \ | ||
| 9386 | + && SYMBOL_REF_LOCAL_P(op) \ | ||
| 9387 | + && !SYMBOL_REF_EXTERNAL_P(op) \ | ||
| 9388 | + && !TARGET_HAS_ASM_ADDR_PSEUDOS ) | ||
| 9389 | + | ||
| 9390 | +/****************************************************************************** | ||
| 9391 | + * Stack Layout and Calling Conventions | ||
| 9392 | + *****************************************************************************/ | ||
| 9393 | + | ||
| 9394 | +/** Basic Stack Layout **/ | ||
| 9395 | + | ||
| 9396 | +/* | ||
| 9397 | +Define this macro if pushing a word onto the stack moves the stack | ||
| 9398 | +pointer to a smaller address. | ||
| 9399 | + | ||
| 9400 | +When we say, ``define this macro if ...,'' it means that the | ||
| 9401 | +compiler checks this macro only with #ifdef so the precise | ||
| 9402 | +definition used does not matter. | ||
| 9403 | +*/ | ||
| 9404 | +/* pushm decrece SP: *(--SP) <-- Rx */ | ||
| 9405 | +#define STACK_GROWS_DOWNWARD | ||
| 9406 | + | ||
| 9407 | +/* | ||
| 9408 | +This macro defines the operation used when something is pushed | ||
| 9409 | +on the stack. In RTL, a push operation will be | ||
| 9410 | +(set (mem (STACK_PUSH_CODE (reg sp))) ...) | ||
| 9411 | + | ||
| 9412 | +The choices are PRE_DEC, POST_DEC, PRE_INC, | ||
| 9413 | +and POST_INC. Which of these is correct depends on | ||
| 9414 | +the stack direction and on whether the stack pointer points | ||
| 9415 | +to the last item on the stack or whether it points to the | ||
| 9416 | +space for the next item on the stack. | ||
| 9417 | + | ||
| 9418 | +The default is PRE_DEC when STACK_GROWS_DOWNWARD is | ||
| 9419 | +defined, which is almost always right, and PRE_INC otherwise, | ||
| 9420 | +which is often wrong. | ||
| 9421 | +*/ | ||
| 9422 | +/* pushm: *(--SP) <-- Rx */ | ||
| 9423 | +#define STACK_PUSH_CODE PRE_DEC | ||
| 9424 | + | ||
| 9425 | +/* | ||
| 9426 | +Define this macro if the addresses of local variable slots are at negative | ||
| 9427 | +offsets from the frame pointer. | ||
| 9428 | +*/ | ||
| 9429 | +#define FRAME_GROWS_DOWNWARD | ||
| 9430 | + | ||
| 9431 | + | ||
| 9432 | +/* | ||
| 9433 | +Offset from the frame pointer to the first local variable slot to be allocated. | ||
| 9434 | + | ||
| 9435 | +If FRAME_GROWS_DOWNWARD, find the next slot's offset by | ||
| 9436 | +subtracting the first slot's length from STARTING_FRAME_OFFSET. | ||
| 9437 | +Otherwise, it is found by adding the length of the first slot to the | ||
| 9438 | +value STARTING_FRAME_OFFSET. | ||
| 9439 | + (i'm not sure if the above is still correct.. had to change it to get | ||
| 9440 | + rid of an overfull. --mew 2feb93 ) | ||
| 9441 | +*/ | ||
| 9442 | +#define STARTING_FRAME_OFFSET 0 | ||
| 9443 | + | ||
| 9444 | +/* | ||
| 9445 | +Offset from the stack pointer register to the first location at which | ||
| 9446 | +outgoing arguments are placed. If not specified, the default value of | ||
| 9447 | +zero is used. This is the proper value for most machines. | ||
| 9448 | + | ||
| 9449 | +If ARGS_GROW_DOWNWARD, this is the offset to the location above | ||
| 9450 | +the first location at which outgoing arguments are placed. | ||
| 9451 | +*/ | ||
| 9452 | +#define STACK_POINTER_OFFSET 0 | ||
| 9453 | + | ||
| 9454 | +/* | ||
| 9455 | +Offset from the argument pointer register to the first argument's | ||
| 9456 | +address. On some machines it may depend on the data type of the | ||
| 9457 | +function. | ||
| 9458 | + | ||
| 9459 | +If ARGS_GROW_DOWNWARD, this is the offset to the location above | ||
| 9460 | +the first argument's address. | ||
| 9461 | +*/ | ||
| 9462 | +#define FIRST_PARM_OFFSET(FUNDECL) 0 | ||
| 9463 | + | ||
| 9464 | + | ||
| 9465 | +/* | ||
| 9466 | +A C expression whose value is RTL representing the address in a stack | ||
| 9467 | +frame where the pointer to the caller's frame is stored. Assume that | ||
| 9468 | +FRAMEADDR is an RTL expression for the address of the stack frame | ||
| 9469 | +itself. | ||
| 9470 | + | ||
| 9471 | +If you don't define this macro, the default is to return the value | ||
| 9472 | +of FRAMEADDR - that is, the stack frame address is also the | ||
| 9473 | +address of the stack word that points to the previous frame. | ||
| 9474 | +*/ | ||
| 9475 | +#define DYNAMIC_CHAIN_ADDRESS(FRAMEADDR) plus_constant ((FRAMEADDR), 4) | ||
| 9476 | + | ||
| 9477 | + | ||
| 9478 | +/* | ||
| 9479 | +A C expression whose value is RTL representing the value of the return | ||
| 9480 | +address for the frame COUNT steps up from the current frame, after | ||
| 9481 | +the prologue. FRAMEADDR is the frame pointer of the COUNT | ||
| 9482 | +frame, or the frame pointer of the COUNT - 1 frame if | ||
| 9483 | +RETURN_ADDR_IN_PREVIOUS_FRAME is defined. | ||
| 9484 | + | ||
| 9485 | +The value of the expression must always be the correct address when | ||
| 9486 | +COUNT is zero, but may be NULL_RTX if there is not way to | ||
| 9487 | +determine the return address of other frames. | ||
| 9488 | +*/ | ||
| 9489 | +#define RETURN_ADDR_RTX(COUNT, FRAMEADDR) avr32_return_addr(COUNT, FRAMEADDR) | ||
| 9490 | + | ||
| 9491 | + | ||
| 9492 | +/* | ||
| 9493 | +A C expression whose value is RTL representing the location of the | ||
| 9494 | +incoming return address at the beginning of any function, before the | ||
| 9495 | +prologue. This RTL is either a REG, indicating that the return | ||
| 9496 | +value is saved in 'REG', or a MEM representing a location in | ||
| 9497 | +the stack. | ||
| 9498 | + | ||
| 9499 | +You only need to define this macro if you want to support call frame | ||
| 9500 | +debugging information like that provided by DWARF 2. | ||
| 9501 | + | ||
| 9502 | +If this RTL is a REG, you should also define | ||
| 9503 | +DWARF_FRAME_RETURN_COLUMN to DWARF_FRAME_REGNUM (REGNO). | ||
| 9504 | +*/ | ||
| 9505 | +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LR_REGNUM) | ||
| 9506 | + | ||
| 9507 | + | ||
| 9508 | + | ||
| 9509 | +/* | ||
| 9510 | +A C expression whose value is an integer giving the offset, in bytes, | ||
| 9511 | +from the value of the stack pointer register to the top of the stack | ||
| 9512 | +frame at the beginning of any function, before the prologue. The top of | ||
| 9513 | +the frame is defined to be the value of the stack pointer in the | ||
| 9514 | +previous frame, just before the call instruction. | ||
| 9515 | + | ||
| 9516 | +You only need to define this macro if you want to support call frame | ||
| 9517 | +debugging information like that provided by DWARF 2. | ||
| 9518 | +*/ | ||
| 9519 | +#define INCOMING_FRAME_SP_OFFSET 0 | ||
| 9520 | + | ||
| 9521 | + | ||
| 9522 | +/** Exception Handling Support **/ | ||
| 9523 | + | ||
| 9524 | +#define DWARF2_UNWIND_INFO 1 | ||
| 9525 | + | ||
| 9526 | +/* | ||
| 9527 | +A C expression whose value is the Nth register number used for | ||
| 9528 | +data by exception handlers, or INVALID_REGNUM if fewer than | ||
| 9529 | +N registers are usable. | ||
| 9530 | + | ||
| 9531 | +The exception handling library routines communicate with the exception | ||
| 9532 | +handlers via a set of agreed upon registers. Ideally these registers | ||
| 9533 | +should be call-clobbered; it is possible to use call-saved registers, | ||
| 9534 | +but may negatively impact code size. The target must support at least | ||
| 9535 | +2 data registers, but should define 4 if there are enough free registers. | ||
| 9536 | + | ||
| 9537 | +You must define this macro if you want to support call frame exception | ||
| 9538 | +handling like that provided by DWARF 2. | ||
| 9539 | +*/ | ||
| 9540 | +/* | ||
| 9541 | + Use r8-r11 | ||
| 9542 | +*/ | ||
| 9543 | +#define EH_RETURN_DATA_REGNO(N) \ | ||
| 9544 | + ((N) < 4 ? INTERNAL_REGNUM((N) + 8U) : INVALID_REGNUM) | ||
| 9545 | + | ||
| 9546 | +/* | ||
| 9547 | +A C expression whose value is RTL representing a location in which | ||
| 9548 | +to store a stack adjustment to be applied before function return. | ||
| 9549 | +This is used to unwind the stack to an exception handler's call frame. | ||
| 9550 | +It will be assigned zero on code paths that return normally. | ||
| 9551 | + | ||
| 9552 | +Typically this is a call-clobbered hard register that is otherwise | ||
| 9553 | +untouched by the epilogue, but could also be a stack slot. | ||
| 9554 | + | ||
| 9555 | +You must define this macro if you want to support call frame exception | ||
| 9556 | +handling like that provided by DWARF 2. | ||
| 9557 | +*/ | ||
| 9558 | +/* | ||
| 9559 | + I don't think functions that may throw exceptions can ever be leaf | ||
| 9560 | + functions, so we may safely use LR for this. | ||
| 9561 | +*/ | ||
| 9562 | +#define EH_RETURN_STACKADJ_REGNO LR_REGNUM | ||
| 9563 | +#define EH_RETURN_STACKADJ_RTX gen_rtx_REG(SImode, EH_RETURN_STACKADJ_REGNO) | ||
| 9564 | + | ||
| 9565 | +/* | ||
| 9566 | +A C expression whose value is RTL representing a location in which | ||
| 9567 | +to store the address of an exception handler to which we should | ||
| 9568 | +return. It will not be assigned on code paths that return normally. | ||
| 9569 | + | ||
| 9570 | +Typically this is the location in the call frame at which the normal | ||
| 9571 | +return address is stored. For targets that return by popping an | ||
| 9572 | +address off the stack, this might be a memory address just below | ||
| 9573 | +the target call frame rather than inside the current call | ||
| 9574 | +frame. EH_RETURN_STACKADJ_RTX will have already been assigned, | ||
| 9575 | +so it may be used to calculate the location of the target call frame. | ||
| 9576 | + | ||
| 9577 | +Some targets have more complex requirements than storing to an | ||
| 9578 | +address calculable during initial code generation. In that case | ||
| 9579 | +the eh_return instruction pattern should be used instead. | ||
| 9580 | + | ||
| 9581 | +If you want to support call frame exception handling, you must | ||
| 9582 | +define either this macro or the eh_return instruction pattern. | ||
| 9583 | +*/ | ||
| 9584 | +/* | ||
| 9585 | + We define the eh_return instruction pattern, so this isn't needed. | ||
| 9586 | +*/ | ||
| 9587 | +/* #define EH_RETURN_HANDLER_RTX gen_rtx_REG(Pmode, RET_REGISTER) */ | ||
| 9588 | + | ||
| 9589 | +/* | ||
| 9590 | + This macro chooses the encoding of pointers embedded in the | ||
| 9591 | + exception handling sections. If at all possible, this should be | ||
| 9592 | + defined such that the exception handling section will not require | ||
| 9593 | + dynamic relocations, and so may be read-only. | ||
| 9594 | + | ||
| 9595 | + code is 0 for data, 1 for code labels, 2 for function | ||
| 9596 | + pointers. global is true if the symbol may be affected by dynamic | ||
| 9597 | + relocations. The macro should return a combination of the DW_EH_PE_* | ||
| 9598 | + defines as found in dwarf2.h. | ||
| 9599 | + | ||
| 9600 | + If this macro is not defined, pointers will not be encoded but | ||
| 9601 | + represented directly. | ||
| 9602 | +*/ | ||
| 9603 | +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \ | ||
| 9604 | + ((flag_pic && (GLOBAL) ? DW_EH_PE_indirect : 0) \ | ||
| 9605 | + | (flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr) \ | ||
| 9606 | + | DW_EH_PE_sdata4) | ||
| 9607 | + | ||
| 9608 | +/* ToDo: The rest of this subsection */ | ||
| 9609 | + | ||
| 9610 | +/** Specifying How Stack Checking is Done **/ | ||
| 9611 | +/* ToDo: All in this subsection */ | ||
| 9612 | + | ||
| 9613 | +/** Registers That Address the Stack Frame **/ | ||
| 9614 | + | ||
| 9615 | +/* | ||
| 9616 | +The register number of the stack pointer register, which must also be a | ||
| 9617 | +fixed register according to FIXED_REGISTERS. On most machines, | ||
| 9618 | +the hardware determines which register this is. | ||
| 9619 | +*/ | ||
| 9620 | +/* Using r13 as stack pointer. */ | ||
| 9621 | +#define STACK_POINTER_REGNUM INTERNAL_REGNUM(13) | ||
| 9622 | + | ||
| 9623 | +/* | ||
| 9624 | +The register number of the frame pointer register, which is used to | ||
| 9625 | +access automatic variables in the stack frame. On some machines, the | ||
| 9626 | +hardware determines which register this is. On other machines, you can | ||
| 9627 | +choose any register you wish for this purpose. | ||
| 9628 | +*/ | ||
| 9629 | +/* Use r7 */ | ||
| 9630 | +#define FRAME_POINTER_REGNUM INTERNAL_REGNUM(7) | ||
| 9631 | + | ||
| 9632 | + | ||
| 9633 | + | ||
| 9634 | +/* | ||
| 9635 | +The register number of the arg pointer register, which is used to access | ||
| 9636 | +the function's argument list. On some machines, this is the same as the | ||
| 9637 | +frame pointer register. On some machines, the hardware determines which | ||
| 9638 | +register this is. On other machines, you can choose any register you | ||
| 9639 | +wish for this purpose. If this is not the same register as the frame | ||
| 9640 | +pointer register, then you must mark it as a fixed register according to | ||
| 9641 | +FIXED_REGISTERS, or arrange to be able to eliminate it (see Section | ||
| 9642 | +10.10.5 [Elimination], page 224). | ||
| 9643 | +*/ | ||
| 9644 | +/* Using r5 */ | ||
| 9645 | +#define ARG_POINTER_REGNUM INTERNAL_REGNUM(4) | ||
| 9646 | + | ||
| 9647 | + | ||
| 9648 | +/* | ||
| 9649 | +Register numbers used for passing a function's static chain pointer. If | ||
| 9650 | +register windows are used, the register number as seen by the called | ||
| 9651 | +function is STATIC_CHAIN_INCOMING_REGNUM, while the register | ||
| 9652 | +number as seen by the calling function is STATIC_CHAIN_REGNUM. If | ||
| 9653 | +these registers are the same, STATIC_CHAIN_INCOMING_REGNUM need | ||
| 9654 | +not be defined. | ||
| 9655 | + | ||
| 9656 | +The static chain register need not be a fixed register. | ||
| 9657 | + | ||
| 9658 | +If the static chain is passed in memory, these macros should not be | ||
| 9659 | +defined; instead, the next two macros should be defined. | ||
| 9660 | +*/ | ||
| 9661 | +/* Using r0 */ | ||
| 9662 | +#define STATIC_CHAIN_REGNUM INTERNAL_REGNUM(0) | ||
| 9663 | + | ||
| 9664 | + | ||
| 9665 | +/** Eliminating Frame Pointer and Arg Pointer **/ | ||
| 9666 | + | ||
| 9667 | +/* | ||
| 9668 | +A C expression which is nonzero if a function must have and use a frame | ||
| 9669 | +pointer. This expression is evaluated in the reload pass. If its value is | ||
| 9670 | +nonzero the function will have a frame pointer. | ||
| 9671 | + | ||
| 9672 | +The expression can in principle examine the current function and decide | ||
| 9673 | +according to the facts, but on most machines the constant 0 or the | ||
| 9674 | +constant 1 suffices. Use 0 when the machine allows code to be generated | ||
| 9675 | +with no frame pointer, and doing so saves some time or space. Use 1 | ||
| 9676 | +when there is no possible advantage to avoiding a frame pointer. | ||
| 9677 | + | ||
| 9678 | +In certain cases, the compiler does not know how to produce valid code | ||
| 9679 | +without a frame pointer. The compiler recognizes those cases and | ||
| 9680 | +automatically gives the function a frame pointer regardless of what | ||
| 9681 | +FRAME_POINTER_REQUIRED says. You don't need to worry about | ||
| 9682 | +them. | ||
| 9683 | + | ||
| 9684 | +In a function that does not require a frame pointer, the frame pointer | ||
| 9685 | +register can be allocated for ordinary usage, unless you mark it as a | ||
| 9686 | +fixed register. See FIXED_REGISTERS for more information. | ||
| 9687 | +*/ | ||
| 9688 | +/* We need the frame pointer when compiling for profiling */ | ||
| 9689 | +#define FRAME_POINTER_REQUIRED (current_function_profile) | ||
| 9690 | + | ||
| 9691 | +/* | ||
| 9692 | +A C statement to store in the variable DEPTH_VAR the difference | ||
| 9693 | +between the frame pointer and the stack pointer values immediately after | ||
| 9694 | +the function prologue. The value would be computed from information | ||
| 9695 | +such as the result of get_frame_size () and the tables of | ||
| 9696 | +registers regs_ever_live and call_used_regs. | ||
| 9697 | + | ||
| 9698 | +If ELIMINABLE_REGS is defined, this macro will be not be used and | ||
| 9699 | +need not be defined. Otherwise, it must be defined even if | ||
| 9700 | +FRAME_POINTER_REQUIRED is defined to always be true; in that | ||
| 9701 | +case, you may set DEPTH_VAR to anything. | ||
| 9702 | +*/ | ||
| 9703 | +#define INITIAL_FRAME_POINTER_OFFSET(DEPTH_VAR) ((DEPTH_VAR) = get_frame_size()) | ||
| 9704 | + | ||
| 9705 | +/* | ||
| 9706 | +If defined, this macro specifies a table of register pairs used to | ||
| 9707 | +eliminate unneeded registers that point into the stack frame. If it is not | ||
| 9708 | +defined, the only elimination attempted by the compiler is to replace | ||
| 9709 | +references to the frame pointer with references to the stack pointer. | ||
| 9710 | + | ||
| 9711 | +The definition of this macro is a list of structure initializations, each | ||
| 9712 | +of which specifies an original and replacement register. | ||
| 9713 | + | ||
| 9714 | +On some machines, the position of the argument pointer is not known until | ||
| 9715 | +the compilation is completed. In such a case, a separate hard register | ||
| 9716 | +must be used for the argument pointer. This register can be eliminated by | ||
| 9717 | +replacing it with either the frame pointer or the argument pointer, | ||
| 9718 | +depending on whether or not the frame pointer has been eliminated. | ||
| 9719 | + | ||
| 9720 | +In this case, you might specify: | ||
| 9721 | + #define ELIMINABLE_REGS \ | ||
| 9722 | + {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ | ||
| 9723 | + {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ | ||
| 9724 | + {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}} | ||
| 9725 | + | ||
| 9726 | +Note that the elimination of the argument pointer with the stack pointer is | ||
| 9727 | +specified first since that is the preferred elimination. | ||
| 9728 | +*/ | ||
| 9729 | +#define ELIMINABLE_REGS \ | ||
| 9730 | +{ \ | ||
| 9731 | + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ | ||
| 9732 | + { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ | ||
| 9733 | + { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM } \ | ||
| 9734 | +} | ||
| 9735 | + | ||
| 9736 | +/* | ||
| 9737 | +A C expression that returns nonzero if the compiler is allowed to try | ||
| 9738 | +to replace register number FROM with register number | ||
| 9739 | +TO. This macro need only be defined if ELIMINABLE_REGS | ||
| 9740 | +is defined, and will usually be the constant 1, since most of the cases | ||
| 9741 | +preventing register elimination are things that the compiler already | ||
| 9742 | +knows about. | ||
| 9743 | +*/ | ||
| 9744 | +#define CAN_ELIMINATE(FROM, TO) 1 | ||
| 9745 | + | ||
| 9746 | +/* | ||
| 9747 | +This macro is similar to INITIAL_FRAME_POINTER_OFFSET. It | ||
| 9748 | +specifies the initial difference between the specified pair of | ||
| 9749 | +registers. This macro must be defined if ELIMINABLE_REGS is | ||
| 9750 | +defined. | ||
| 9751 | +*/ | ||
| 9752 | +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ | ||
| 9753 | + ((OFFSET) = avr32_initial_elimination_offset(FROM, TO)) | ||
| 9754 | + | ||
| 9755 | +/** Passing Function Arguments on the Stack **/ | ||
| 9756 | + | ||
| 9757 | + | ||
| 9758 | +/* | ||
| 9759 | +A C expression. If nonzero, push insns will be used to pass | ||
| 9760 | +outgoing arguments. | ||
| 9761 | +If the target machine does not have a push instruction, set it to zero. | ||
| 9762 | +That directs GCC to use an alternate strategy: to | ||
| 9763 | +allocate the entire argument block and then store the arguments into | ||
| 9764 | +it. When PUSH_ARGS is nonzero, PUSH_ROUNDING must be defined too. | ||
| 9765 | +*/ | ||
| 9766 | +#define PUSH_ARGS 1 | ||
| 9767 | + | ||
| 9768 | + | ||
| 9769 | +/* | ||
| 9770 | +A C expression that is the number of bytes actually pushed onto the | ||
| 9771 | +stack when an instruction attempts to push NPUSHED bytes. | ||
| 9772 | + | ||
| 9773 | +On some machines, the definition | ||
| 9774 | + | ||
| 9775 | + #define PUSH_ROUNDING(BYTES) (BYTES) | ||
| 9776 | + | ||
| 9777 | +will suffice. But on other machines, instructions that appear | ||
| 9778 | +to push one byte actually push two bytes in an attempt to maintain | ||
| 9779 | +alignment. Then the definition should be | ||
| 9780 | + | ||
| 9781 | + #define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1) | ||
| 9782 | +*/ | ||
| 9783 | +/* Push 4 bytes at the time. */ | ||
| 9784 | +#define PUSH_ROUNDING(NPUSHED) (((NPUSHED) + 3) & ~3) | ||
| 9785 | + | ||
| 9786 | +/* | ||
| 9787 | +A C expression. If nonzero, the maximum amount of space required for | ||
| 9788 | +outgoing arguments will be computed and placed into the variable | ||
| 9789 | +current_function_outgoing_args_size. No space will be pushed | ||
| 9790 | +onto the stack for each call; instead, the function prologue should | ||
| 9791 | +increase the stack frame size by this amount. | ||
| 9792 | + | ||
| 9793 | +Setting both PUSH_ARGS and ACCUMULATE_OUTGOING_ARGS is not proper. | ||
| 9794 | +*/ | ||
| 9795 | +#define ACCUMULATE_OUTGOING_ARGS 0 | ||
| 9796 | + | ||
| 9797 | + | ||
| 9798 | + | ||
| 9799 | + | ||
| 9800 | +/* | ||
| 9801 | +A C expression that should indicate the number of bytes of its own | ||
| 9802 | +arguments that a function pops on returning, or 0 if the | ||
| 9803 | +function pops no arguments and the caller must therefore pop them all | ||
| 9804 | +after the function returns. | ||
| 9805 | + | ||
| 9806 | +FUNDECL is a C variable whose value is a tree node that describes | ||
| 9807 | +the function in question. Normally it is a node of type | ||
| 9808 | +FUNCTION_DECL that describes the declaration of the function. | ||
| 9809 | +From this you can obtain the DECL_ATTRIBUTES of the function. | ||
| 9810 | + | ||
| 9811 | +FUNTYPE is a C variable whose value is a tree node that | ||
| 9812 | +describes the function in question. Normally it is a node of type | ||
| 9813 | +FUNCTION_TYPE that describes the data type of the function. | ||
| 9814 | +From this it is possible to obtain the data types of the value and | ||
| 9815 | +arguments (if known). | ||
| 9816 | + | ||
| 9817 | +When a call to a library function is being considered, FUNDECL | ||
| 9818 | +will contain an identifier node for the library function. Thus, if | ||
| 9819 | +you need to distinguish among various library functions, you can do so | ||
| 9820 | +by their names. Note that ``library function'' in this context means | ||
| 9821 | +a function used to perform arithmetic, whose name is known specially | ||
| 9822 | +in the compiler and was not mentioned in the C code being compiled. | ||
| 9823 | + | ||
| 9824 | +STACK_SIZE is the number of bytes of arguments passed on the | ||
| 9825 | +stack. If a variable number of bytes is passed, it is zero, and | ||
| 9826 | +argument popping will always be the responsibility of the calling function. | ||
| 9827 | + | ||
| 9828 | +On the VAX, all functions always pop their arguments, so the definition | ||
| 9829 | +of this macro is STACK_SIZE. On the 68000, using the standard | ||
| 9830 | +calling convention, no functions pop their arguments, so the value of | ||
| 9831 | +the macro is always 0 in this case. But an alternative calling | ||
| 9832 | +convention is available in which functions that take a fixed number of | ||
| 9833 | +arguments pop them but other functions (such as printf) pop | ||
| 9834 | +nothing (the caller pops all). When this convention is in use, | ||
| 9835 | +FUNTYPE is examined to determine whether a function takes a fixed | ||
| 9836 | +number of arguments. | ||
| 9837 | +*/ | ||
| 9838 | +#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 | ||
| 9839 | + | ||
| 9840 | + | ||
| 9841 | +/*Return true if this function can we use a single return instruction*/ | ||
| 9842 | +#define USE_RETURN_INSN(ISCOND) avr32_use_return_insn(ISCOND) | ||
| 9843 | + | ||
| 9844 | +/* | ||
| 9845 | +A C expression that should indicate the number of bytes a call sequence | ||
| 9846 | +pops off the stack. It is added to the value of RETURN_POPS_ARGS | ||
| 9847 | +when compiling a function call. | ||
| 9848 | + | ||
| 9849 | +CUM is the variable in which all arguments to the called function | ||
| 9850 | +have been accumulated. | ||
| 9851 | + | ||
| 9852 | +On certain architectures, such as the SH5, a call trampoline is used | ||
| 9853 | +that pops certain registers off the stack, depending on the arguments | ||
| 9854 | +that have been passed to the function. Since this is a property of the | ||
| 9855 | +call site, not of the called function, RETURN_POPS_ARGS is not | ||
| 9856 | +appropriate. | ||
| 9857 | +*/ | ||
| 9858 | +#define CALL_POPS_ARGS(CUM) 0 | ||
| 9859 | + | ||
| 9860 | +/* Passing Arguments in Registers */ | ||
| 9861 | + | ||
| 9862 | +/* | ||
| 9863 | +A C expression that controls whether a function argument is passed | ||
| 9864 | +in a register, and which register. | ||
| 9865 | + | ||
| 9866 | +The arguments are CUM, which summarizes all the previous | ||
| 9867 | +arguments; MODE, the machine mode of the argument; TYPE, | ||
| 9868 | +the data type of the argument as a tree node or 0 if that is not known | ||
| 9869 | +(which happens for C support library functions); and NAMED, | ||
| 9870 | +which is 1 for an ordinary argument and 0 for nameless arguments that | ||
| 9871 | +correspond to '...' in the called function's prototype. | ||
| 9872 | +TYPE can be an incomplete type if a syntax error has previously | ||
| 9873 | +occurred. | ||
| 9874 | + | ||
| 9875 | +The value of the expression is usually either a reg RTX for the | ||
| 9876 | +hard register in which to pass the argument, or zero to pass the | ||
| 9877 | +argument on the stack. | ||
| 9878 | + | ||
| 9879 | +For machines like the VAX and 68000, where normally all arguments are | ||
| 9880 | +pushed, zero suffices as a definition. | ||
| 9881 | + | ||
| 9882 | +The value of the expression can also be a parallel RTX. This is | ||
| 9883 | +used when an argument is passed in multiple locations. The mode of the | ||
| 9884 | +of the parallel should be the mode of the entire argument. The | ||
| 9885 | +parallel holds any number of expr_list pairs; each one | ||
| 9886 | +describes where part of the argument is passed. In each | ||
| 9887 | +expr_list the first operand must be a reg RTX for the hard | ||
| 9888 | +register in which to pass this part of the argument, and the mode of the | ||
| 9889 | +register RTX indicates how large this part of the argument is. The | ||
| 9890 | +second operand of the expr_list is a const_int which gives | ||
| 9891 | +the offset in bytes into the entire argument of where this part starts. | ||
| 9892 | +As a special exception the first expr_list in the parallel | ||
| 9893 | +RTX may have a first operand of zero. This indicates that the entire | ||
| 9894 | +argument is also stored on the stack. | ||
| 9895 | + | ||
| 9896 | +The last time this macro is called, it is called with MODE == VOIDmode, | ||
| 9897 | +and its result is passed to the call or call_value | ||
| 9898 | +pattern as operands 2 and 3 respectively. | ||
| 9899 | + | ||
| 9900 | +The usual way to make the ISO library 'stdarg.h' work on a machine | ||
| 9901 | +where some arguments are usually passed in registers, is to cause | ||
| 9902 | +nameless arguments to be passed on the stack instead. This is done | ||
| 9903 | +by making FUNCTION_ARG return 0 whenever NAMED is 0. | ||
| 9904 | + | ||
| 9905 | +You may use the macro MUST_PASS_IN_STACK (MODE, TYPE) | ||
| 9906 | +in the definition of this macro to determine if this argument is of a | ||
| 9907 | +type that must be passed in the stack. If REG_PARM_STACK_SPACE | ||
| 9908 | +is not defined and FUNCTION_ARG returns nonzero for such an | ||
| 9909 | +argument, the compiler will abort. If REG_PARM_STACK_SPACE is | ||
| 9910 | +defined, the argument will be computed in the stack and then loaded into | ||
| 9911 | +a register. */ | ||
| 9912 | + | ||
| 9913 | +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ | ||
| 9914 | + avr32_function_arg(&(CUM), MODE, TYPE, NAMED) | ||
| 9915 | + | ||
| 9916 | + | ||
| 9917 | + | ||
| 9918 | + | ||
| 9919 | +/* | ||
| 9920 | +A C type for declaring a variable that is used as the first argument of | ||
| 9921 | +FUNCTION_ARG and other related values. For some target machines, | ||
| 9922 | +the type int suffices and can hold the number of bytes of | ||
| 9923 | +argument so far. | ||
| 9924 | + | ||
| 9925 | +There is no need to record in CUMULATIVE_ARGS anything about the | ||
| 9926 | +arguments that have been passed on the stack. The compiler has other | ||
| 9927 | +variables to keep track of that. For target machines on which all | ||
| 9928 | +arguments are passed on the stack, there is no need to store anything in | ||
| 9929 | +CUMULATIVE_ARGS; however, the data structure must exist and | ||
| 9930 | +should not be empty, so use int. | ||
| 9931 | +*/ | ||
| 9932 | +typedef struct avr32_args | ||
| 9933 | +{ | ||
| 9934 | + /* Index representing the argument register the current function argument | ||
| 9935 | + will occupy */ | ||
| 9936 | + int index; | ||
| 9937 | + /* A mask with bits representing the argument registers: if a bit is set | ||
| 9938 | + then this register is used for an arguemnt */ | ||
| 9939 | + int used_index; | ||
| 9940 | + /* TRUE if this function has anonymous arguments */ | ||
| 9941 | + int uses_anonymous_args; | ||
| 9942 | + /* The size in bytes of the named arguments pushed on the stack */ | ||
| 9943 | + int stack_pushed_args_size; | ||
| 9944 | + /* Set to true if this function needs a Return Value Pointer */ | ||
| 9945 | + int use_rvp; | ||
| 9946 | + | ||
| 9947 | +} CUMULATIVE_ARGS; | ||
| 9948 | + | ||
| 9949 | + | ||
| 9950 | +#define FIRST_CUM_REG_INDEX 0 | ||
| 9951 | +#define LAST_CUM_REG_INDEX 4 | ||
| 9952 | +#define GET_REG_INDEX(CUM) ((CUM)->index) | ||
| 9953 | +#define SET_REG_INDEX(CUM, INDEX) ((CUM)->index = (INDEX)); | ||
| 9954 | +#define GET_USED_INDEX(CUM, INDEX) ((CUM)->used_index & (1 << (INDEX))) | ||
| 9955 | +#define SET_USED_INDEX(CUM, INDEX) \ | ||
| 9956 | + do \ | ||
| 9957 | + { \ | ||
| 9958 | + if (INDEX >= 0) \ | ||
| 9959 | + (CUM)->used_index |= (1 << (INDEX)); \ | ||
| 9960 | + } \ | ||
| 9961 | + while (0) | ||
| 9962 | +#define SET_INDEXES_UNUSED(CUM) ((CUM)->used_index = 0) | ||
| 9963 | + | ||
| 9964 | + | ||
| 9965 | +/* | ||
| 9966 | + A C statement (sans semicolon) for initializing the variable cum for the | ||
| 9967 | + state at the beginning of the argument list. The variable has type | ||
| 9968 | + CUMULATIVE_ARGS. The value of FNTYPE is the tree node for the data type of | ||
| 9969 | + the function which will receive the args, or 0 if the args are to a compiler | ||
| 9970 | + support library function. For direct calls that are not libcalls, FNDECL | ||
| 9971 | + contain the declaration node of the function. FNDECL is also set when | ||
| 9972 | + INIT_CUMULATIVE_ARGS is used to find arguments for the function being | ||
| 9973 | + compiled. N_NAMED_ARGS is set to the number of named arguments, including a | ||
| 9974 | + structure return address if it is passed as a parameter, when making a call. | ||
| 9975 | + When processing incoming arguments, N_NAMED_ARGS is set to -1. | ||
| 9976 | + | ||
| 9977 | + When processing a call to a compiler support library function, LIBNAME | ||
| 9978 | + identifies which one. It is a symbol_ref rtx which contains the name of the | ||
| 9979 | + function, as a string. LIBNAME is 0 when an ordinary C function call is | ||
| 9980 | + being processed. Thus, each time this macro is called, either LIBNAME or | ||
| 9981 | + FNTYPE is nonzero, but never both of them at once. | ||
| 9982 | +*/ | ||
| 9983 | +#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \ | ||
| 9984 | + avr32_init_cumulative_args(&(CUM), FNTYPE, LIBNAME, FNDECL) | ||
| 9985 | + | ||
| 9986 | + | ||
| 9987 | +/* | ||
| 9988 | +A C statement (sans semicolon) to update the summarizer variable | ||
| 9989 | +CUM to advance past an argument in the argument list. The | ||
| 9990 | +values MODE, TYPE and NAMED describe that argument. | ||
| 9991 | +Once this is done, the variable CUM is suitable for analyzing | ||
| 9992 | +the following argument with FUNCTION_ARG, etc. | ||
| 9993 | + | ||
| 9994 | +This macro need not do anything if the argument in question was passed | ||
| 9995 | +on the stack. The compiler knows how to track the amount of stack space | ||
| 9996 | +used for arguments without any special help. | ||
| 9997 | +*/ | ||
| 9998 | +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ | ||
| 9999 | + avr32_function_arg_advance(&(CUM), MODE, TYPE, NAMED) | ||
| 10000 | + | ||
| 10001 | +/* | ||
| 10002 | +If defined, a C expression which determines whether, and in which direction, | ||
| 10003 | +to pad out an argument with extra space. The value should be of type | ||
| 10004 | +enum direction: either 'upward' to pad above the argument, | ||
| 10005 | +'downward' to pad below, or 'none' to inhibit padding. | ||
| 10006 | + | ||
| 10007 | +The amount of padding is always just enough to reach the next | ||
| 10008 | +multiple of FUNCTION_ARG_BOUNDARY; this macro does not control | ||
| 10009 | +it. | ||
| 10010 | + | ||
| 10011 | +This macro has a default definition which is right for most systems. | ||
| 10012 | +For little-endian machines, the default is to pad upward. For | ||
| 10013 | +big-endian machines, the default is to pad downward for an argument of | ||
| 10014 | +constant size shorter than an int, and upward otherwise. | ||
| 10015 | +*/ | ||
| 10016 | +#define FUNCTION_ARG_PADDING(MODE, TYPE) \ | ||
| 10017 | + avr32_function_arg_padding(MODE, TYPE) | ||
| 10018 | + | ||
| 10019 | +/* | ||
| 10020 | + Specify padding for the last element of a block move between registers | ||
| 10021 | + and memory. First is nonzero if this is the only element. Defining | ||
| 10022 | + this macro allows better control of register function parameters on | ||
| 10023 | + big-endian machines, without using PARALLEL rtl. In particular, | ||
| 10024 | + MUST_PASS_IN_STACK need not test padding and mode of types in registers, | ||
| 10025 | + as there is no longer a "wrong" part of a register; For example, a three | ||
| 10026 | + byte aggregate may be passed in the high part of a register if so required. | ||
| 10027 | +*/ | ||
| 10028 | +#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \ | ||
| 10029 | + avr32_function_arg_padding(MODE, TYPE) | ||
| 10030 | + | ||
| 10031 | +/* | ||
| 10032 | +If defined, a C expression which determines whether the default | ||
| 10033 | +implementation of va_arg will attempt to pad down before reading the | ||
| 10034 | +next argument, if that argument is smaller than its aligned space as | ||
| 10035 | +controlled by PARM_BOUNDARY. If this macro is not defined, all such | ||
| 10036 | +arguments are padded down if BYTES_BIG_ENDIAN is true. | ||
| 10037 | +*/ | ||
| 10038 | +#define PAD_VARARGS_DOWN \ | ||
| 10039 | + (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward) | ||
| 10040 | + | ||
| 10041 | + | ||
| 10042 | +/* | ||
| 10043 | +A C expression that is nonzero if REGNO is the number of a hard | ||
| 10044 | +register in which function arguments are sometimes passed. This does | ||
| 10045 | +not include implicit arguments such as the static chain and | ||
| 10046 | +the structure-value address. On many machines, no registers can be | ||
| 10047 | +used for this purpose since all function arguments are pushed on the | ||
| 10048 | +stack. | ||
| 10049 | +*/ | ||
| 10050 | +/* | ||
| 10051 | + Use r8 - r12 for function arguments. | ||
| 10052 | +*/ | ||
| 10053 | +#define FUNCTION_ARG_REGNO_P(REGNO) \ | ||
| 10054 | + (REGNO >= 3 && REGNO <= 7) | ||
| 10055 | + | ||
| 10056 | +/* Number of registers used for passing function arguments */ | ||
| 10057 | +#define NUM_ARG_REGS 5 | ||
| 10058 | + | ||
| 10059 | +/* | ||
| 10060 | +If defined, the order in which arguments are loaded into their | ||
| 10061 | +respective argument registers is reversed so that the last | ||
| 10062 | +argument is loaded first. This macro only affects arguments | ||
| 10063 | +passed in registers. | ||
| 10064 | +*/ | ||
| 10065 | +/* #define LOAD_ARGS_REVERSED */ | ||
| 10066 | + | ||
| 10067 | +/** How Scalar Function Values Are Returned **/ | ||
| 10068 | + | ||
| 10069 | +/* AVR32 is using r12 as return register. */ | ||
| 10070 | +#define RET_REGISTER (15 - 12) | ||
| 10071 | + | ||
| 10072 | +/* | ||
| 10073 | +Define this macro if -traditional should not cause functions | ||
| 10074 | +declared to return float to convert the value to double. | ||
| 10075 | +*/ | ||
| 10076 | +/* #define TRADITIONAL_RETURN_FLOAT */ | ||
| 10077 | + | ||
| 10078 | +/* | ||
| 10079 | +A C expression to create an RTX representing the place where a | ||
| 10080 | +function returns a value of data type VALTYPE. VALTYPE is | ||
| 10081 | +a tree node representing a data type. Write TYPE_MODE(VALTYPE) | ||
| 10082 | +to get the machine mode used to represent that type. | ||
| 10083 | +On many machines, only the mode is relevant. (Actually, on most | ||
| 10084 | +machines, scalar values are returned in the same place regardless of | ||
| 10085 | +mode). | ||
| 10086 | + | ||
| 10087 | +The value of the expression is usually a reg RTX for the hard | ||
| 10088 | +register where the return value is stored. The value can also be a | ||
| 10089 | +parallel RTX, if the return value is in multiple places. See | ||
| 10090 | +FUNCTION_ARG for an explanation of the parallel form. | ||
| 10091 | + | ||
| 10092 | +If PROMOTE_FUNCTION_RETURN is defined, you must apply the same | ||
| 10093 | +promotion rules specified in PROMOTE_MODE if VALTYPE is a | ||
| 10094 | +scalar type. | ||
| 10095 | + | ||
| 10096 | +If the precise function being called is known, FUNC is a tree | ||
| 10097 | +node (FUNCTION_DECL) for it; otherwise, FUNC is a null | ||
| 10098 | +pointer. This makes it possible to use a different value-returning | ||
| 10099 | +convention for specific functions when all their calls are | ||
| 10100 | +known. | ||
| 10101 | + | ||
| 10102 | +FUNCTION_VALUE is not used for return vales with aggregate data | ||
| 10103 | +types, because these are returned in another way. See | ||
| 10104 | +STRUCT_VALUE_REGNUM and related macros, below. | ||
| 10105 | +*/ | ||
| 10106 | +#define FUNCTION_VALUE(VALTYPE, FUNC) avr32_function_value(VALTYPE, FUNC) | ||
| 10107 | + | ||
| 10108 | + | ||
| 10109 | +/* | ||
| 10110 | +A C expression to create an RTX representing the place where a library | ||
| 10111 | +function returns a value of mode MODE. If the precise function | ||
| 10112 | +being called is known, FUNC is a tree node | ||
| 10113 | +(FUNCTION_DECL) for it; otherwise, func is a null | ||
| 10114 | +pointer. This makes it possible to use a different value-returning | ||
| 10115 | +convention for specific functions when all their calls are | ||
| 10116 | +known. | ||
| 10117 | + | ||
| 10118 | +Note that "library function" in this context means a compiler | ||
| 10119 | +support routine, used to perform arithmetic, whose name is known | ||
| 10120 | +specially by the compiler and was not mentioned in the C code being | ||
| 10121 | +compiled. | ||
| 10122 | + | ||
| 10123 | +The definition of LIBRARY_VALUE need not be concerned aggregate | ||
| 10124 | +data types, because none of the library functions returns such types. | ||
| 10125 | +*/ | ||
| 10126 | +#define LIBCALL_VALUE(MODE) avr32_libcall_value(MODE) | ||
| 10127 | + | ||
| 10128 | +/* | ||
| 10129 | +A C expression that is nonzero if REGNO is the number of a hard | ||
| 10130 | +register in which the values of called function may come back. | ||
| 10131 | + | ||
| 10132 | +A register whose use for returning values is limited to serving as the | ||
| 10133 | +second of a pair (for a value of type double, say) need not be | ||
| 10134 | +recognized by this macro. So for most machines, this definition | ||
| 10135 | +suffices: | ||
| 10136 | + #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0) | ||
| 10137 | + | ||
| 10138 | +If the machine has register windows, so that the caller and the called | ||
| 10139 | +function use different registers for the return value, this macro | ||
| 10140 | +should recognize only the caller's register numbers. | ||
| 10141 | +*/ | ||
| 10142 | +/* | ||
| 10143 | + When returning a value of mode DImode, r11:r10 is used, else r12 is used. | ||
| 10144 | +*/ | ||
| 10145 | +#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == RET_REGISTER \ | ||
| 10146 | + || (REGNO) == INTERNAL_REGNUM(11)) | ||
| 10147 | + | ||
| 10148 | + | ||
| 10149 | +/** How Large Values Are Returned **/ | ||
| 10150 | + | ||
| 10151 | + | ||
| 10152 | +/* | ||
| 10153 | +Define this macro to be 1 if all structure and union return values must be | ||
| 10154 | +in memory. Since this results in slower code, this should be defined | ||
| 10155 | +only if needed for compatibility with other compilers or with an ABI. | ||
| 10156 | +If you define this macro to be 0, then the conventions used for structure | ||
| 10157 | +and union return values are decided by the RETURN_IN_MEMORY macro. | ||
| 10158 | + | ||
| 10159 | +If not defined, this defaults to the value 1. | ||
| 10160 | +*/ | ||
| 10161 | +#define DEFAULT_PCC_STRUCT_RETURN 0 | ||
| 10162 | + | ||
| 10163 | + | ||
| 10164 | + | ||
| 10165 | + | ||
| 10166 | +/** Generating Code for Profiling **/ | ||
| 10167 | + | ||
| 10168 | +/* | ||
| 10169 | +A C statement or compound statement to output to FILE some | ||
| 10170 | +assembler code to call the profiling subroutine mcount. | ||
| 10171 | + | ||
| 10172 | +The details of how mcount expects to be called are determined by | ||
| 10173 | +your operating system environment, not by GCC. To figure them out, | ||
| 10174 | +compile a small program for profiling using the system's installed C | ||
| 10175 | +compiler and look at the assembler code that results. | ||
| 10176 | + | ||
| 10177 | +Older implementations of mcount expect the address of a counter | ||
| 10178 | +variable to be loaded into some register. The name of this variable is | ||
| 10179 | +'LP' followed by the number LABELNO, so you would generate | ||
| 10180 | +the name using 'LP%d' in a fprintf. | ||
| 10181 | +*/ | ||
| 10182 | +/* ToDo: fixme */ | ||
| 10183 | +#ifndef FUNCTION_PROFILER | ||
| 10184 | +#define FUNCTION_PROFILER(FILE, LABELNO) \ | ||
| 10185 | + fprintf((FILE), "/* profiler %d */", (LABELNO)) | ||
| 10186 | +#endif | ||
| 10187 | + | ||
| 10188 | + | ||
| 10189 | +/***************************************************************************** | ||
| 10190 | + * Trampolines for Nested Functions * | ||
| 10191 | + *****************************************************************************/ | ||
| 10192 | + | ||
| 10193 | +/* | ||
| 10194 | +A C statement to output, on the stream FILE, assembler code for a | ||
| 10195 | +block of data that contains the constant parts of a trampoline. This | ||
| 10196 | +code should not include a label - the label is taken care of | ||
| 10197 | +automatically. | ||
| 10198 | + | ||
| 10199 | +If you do not define this macro, it means no template is needed | ||
| 10200 | +for the target. Do not define this macro on systems where the block move | ||
| 10201 | +code to copy the trampoline into place would be larger than the code | ||
| 10202 | +to generate it on the spot. | ||
| 10203 | +*/ | ||
| 10204 | +/* ToDo: correct? */ | ||
| 10205 | +#define TRAMPOLINE_TEMPLATE(FILE) avr32_trampoline_template(FILE); | ||
| 10206 | + | ||
| 10207 | + | ||
| 10208 | +/* | ||
| 10209 | +A C expression for the size in bytes of the trampoline, as an integer. | ||
| 10210 | +*/ | ||
| 10211 | +/* ToDo: fixme */ | ||
| 10212 | +#define TRAMPOLINE_SIZE 0x0C | ||
| 10213 | + | ||
| 10214 | +/* | ||
| 10215 | +Alignment required for trampolines, in bits. | ||
| 10216 | + | ||
| 10217 | +If you don't define this macro, the value of BIGGEST_ALIGNMENT | ||
| 10218 | +is used for aligning trampolines. | ||
| 10219 | +*/ | ||
| 10220 | +#define TRAMPOLINE_ALIGNMENT 16 | ||
| 10221 | + | ||
| 10222 | +/* | ||
| 10223 | +A C statement to initialize the variable parts of a trampoline. | ||
| 10224 | +ADDR is an RTX for the address of the trampoline; FNADDR is | ||
| 10225 | +an RTX for the address of the nested function; STATIC_CHAIN is an | ||
| 10226 | +RTX for the static chain value that should be passed to the function | ||
| 10227 | +when it is called. | ||
| 10228 | +*/ | ||
| 10229 | +#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, STATIC_CHAIN) \ | ||
| 10230 | + avr32_initialize_trampoline(ADDR, FNADDR, STATIC_CHAIN) | ||
| 10231 | + | ||
| 10232 | + | ||
| 10233 | +/****************************************************************************** | ||
| 10234 | + * Implicit Calls to Library Routines | ||
| 10235 | + *****************************************************************************/ | ||
| 10236 | + | ||
| 10237 | +/* Tail calling. */ | ||
| 10238 | + | ||
| 10239 | +/* A C expression that evaluates to true if it is ok to perform a sibling | ||
| 10240 | + call to DECL. */ | ||
| 10241 | +#define FUNCTION_OK_FOR_SIBCALL(DECL) 0 | ||
| 10242 | + | ||
| 10243 | +#define OVERRIDE_OPTIONS avr32_override_options () | ||
| 10244 | + | ||
| 10245 | + | ||
| 10246 | + | ||
| 10247 | +/****************************************************************************** | ||
| 10248 | + * Addressing Modes | ||
| 10249 | + *****************************************************************************/ | ||
| 10250 | + | ||
| 10251 | +/* | ||
| 10252 | +A C expression that is nonzero if the machine supports pre-increment, | ||
| 10253 | +pre-decrement, post-increment, or post-decrement addressing respectively. | ||
| 10254 | +*/ | ||
| 10255 | +/* | ||
| 10256 | + AVR32 supports Rp++ and --Rp | ||
| 10257 | +*/ | ||
| 10258 | +#define HAVE_PRE_INCREMENT 0 | ||
| 10259 | +#define HAVE_PRE_DECREMENT 1 | ||
| 10260 | +#define HAVE_POST_INCREMENT 1 | ||
| 10261 | +#define HAVE_POST_DECREMENT 0 | ||
| 10262 | + | ||
| 10263 | +/* | ||
| 10264 | +A C expression that is nonzero if the machine supports pre- or | ||
| 10265 | +post-address side-effect generation involving constants other than | ||
| 10266 | +the size of the memory operand. | ||
| 10267 | +*/ | ||
| 10268 | +#define HAVE_PRE_MODIFY_DISP 0 | ||
| 10269 | +#define HAVE_POST_MODIFY_DISP 0 | ||
| 10270 | + | ||
| 10271 | +/* | ||
| 10272 | +A C expression that is nonzero if the machine supports pre- or | ||
| 10273 | +post-address side-effect generation involving a register displacement. | ||
| 10274 | +*/ | ||
| 10275 | +#define HAVE_PRE_MODIFY_REG 0 | ||
| 10276 | +#define HAVE_POST_MODIFY_REG 0 | ||
| 10277 | + | ||
| 10278 | +/* | ||
| 10279 | +A C expression that is 1 if the RTX X is a constant which | ||
| 10280 | +is a valid address. On most machines, this can be defined as | ||
| 10281 | +CONSTANT_P (X), but a few machines are more restrictive | ||
| 10282 | +in which constant addresses are supported. | ||
| 10283 | + | ||
| 10284 | +CONSTANT_P accepts integer-values expressions whose values are | ||
| 10285 | +not explicitly known, such as symbol_ref, label_ref, and | ||
| 10286 | +high expressions and const arithmetic expressions, in | ||
| 10287 | +addition to const_int and const_double expressions. | ||
| 10288 | +*/ | ||
| 10289 | +#define CONSTANT_ADDRESS_P(X) CONSTANT_P(X) | ||
| 10290 | + | ||
| 10291 | +/* | ||
| 10292 | +A number, the maximum number of registers that can appear in a valid | ||
| 10293 | +memory address. Note that it is up to you to specify a value equal to | ||
| 10294 | +the maximum number that GO_IF_LEGITIMATE_ADDRESS would ever | ||
| 10295 | +accept. | ||
| 10296 | +*/ | ||
| 10297 | +#define MAX_REGS_PER_ADDRESS 2 | ||
| 10298 | + | ||
| 10299 | +/* | ||
| 10300 | +A C compound statement with a conditional goto LABEL; | ||
| 10301 | +executed if X (an RTX) is a legitimate memory address on the | ||
| 10302 | +target machine for a memory operand of mode MODE. | ||
| 10303 | + | ||
| 10304 | +It usually pays to define several simpler macros to serve as | ||
| 10305 | +subroutines for this one. Otherwise it may be too complicated to | ||
| 10306 | +understand. | ||
| 10307 | + | ||
| 10308 | +This macro must exist in two variants: a strict variant and a | ||
| 10309 | +non-strict one. The strict variant is used in the reload pass. It | ||
| 10310 | +must be defined so that any pseudo-register that has not been | ||
| 10311 | +allocated a hard register is considered a memory reference. In | ||
| 10312 | +contexts where some kind of register is required, a pseudo-register | ||
| 10313 | +with no hard register must be rejected. | ||
| 10314 | + | ||
| 10315 | +The non-strict variant is used in other passes. It must be defined to | ||
| 10316 | +accept all pseudo-registers in every context where some kind of | ||
| 10317 | +register is required. | ||
| 10318 | + | ||
| 10319 | +Compiler source files that want to use the strict variant of this | ||
| 10320 | +macro define the macro REG_OK_STRICT. You should use an | ||
| 10321 | +#ifdef REG_OK_STRICT conditional to define the strict variant | ||
| 10322 | +in that case and the non-strict variant otherwise. | ||
| 10323 | + | ||
| 10324 | +Subroutines to check for acceptable registers for various purposes (one | ||
| 10325 | +for base registers, one for index registers, and so on) are typically | ||
| 10326 | +among the subroutines used to define GO_IF_LEGITIMATE_ADDRESS. | ||
| 10327 | +Then only these subroutine macros need have two variants; the higher | ||
| 10328 | +levels of macros may be the same whether strict or not. | ||
| 10329 | + | ||
| 10330 | +Normally, constant addresses which are the sum of a symbol_ref | ||
| 10331 | +and an integer are stored inside a const RTX to mark them as | ||
| 10332 | +constant. Therefore, there is no need to recognize such sums | ||
| 10333 | +specifically as legitimate addresses. Normally you would simply | ||
| 10334 | +recognize any const as legitimate. | ||
| 10335 | + | ||
| 10336 | +Usually PRINT_OPERAND_ADDRESS is not prepared to handle constant | ||
| 10337 | +sums that are not marked with const. It assumes that a naked | ||
| 10338 | +plus indicates indexing. If so, then you must reject such | ||
| 10339 | +naked constant sums as illegitimate addresses, so that none of them will | ||
| 10340 | +be given to PRINT_OPERAND_ADDRESS. | ||
| 10341 | + | ||
| 10342 | +On some machines, whether a symbolic address is legitimate depends on | ||
| 10343 | +the section that the address refers to. On these machines, define the | ||
| 10344 | +macro ENCODE_SECTION_INFO to store the information into the | ||
| 10345 | +symbol_ref, and then check for it here. When you see a | ||
| 10346 | +const, you will have to look inside it to find the | ||
| 10347 | +symbol_ref in order to determine the section. | ||
| 10348 | + | ||
| 10349 | +The best way to modify the name string is by adding text to the | ||
| 10350 | +beginning, with suitable punctuation to prevent any ambiguity. Allocate | ||
| 10351 | +the new name in saveable_obstack. You will have to modify | ||
| 10352 | +ASM_OUTPUT_LABELREF to remove and decode the added text and | ||
| 10353 | +output the name accordingly, and define STRIP_NAME_ENCODING to | ||
| 10354 | +access the original name string. | ||
| 10355 | + | ||
| 10356 | +You can check the information stored here into the symbol_ref in | ||
| 10357 | +the definitions of the macros GO_IF_LEGITIMATE_ADDRESS and | ||
| 10358 | +PRINT_OPERAND_ADDRESS. | ||
| 10359 | +*/ | ||
| 10360 | +#ifdef REG_OK_STRICT | ||
| 10361 | +# define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \ | ||
| 10362 | + do \ | ||
| 10363 | + { \ | ||
| 10364 | + if (avr32_legitimate_address(MODE, X, 1)) \ | ||
| 10365 | + goto LABEL; \ | ||
| 10366 | + } \ | ||
| 10367 | + while (0) | ||
| 10368 | +#else | ||
| 10369 | +# define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \ | ||
| 10370 | + do \ | ||
| 10371 | + { \ | ||
| 10372 | + if (avr32_legitimate_address(MODE, X, 0)) \ | ||
| 10373 | + goto LABEL; \ | ||
| 10374 | + } \ | ||
| 10375 | + while (0) | ||
| 10376 | +#endif | ||
| 10377 | + | ||
| 10378 | +/* | ||
| 10379 | +A C expression that is nonzero if X (assumed to be a reg | ||
| 10380 | +RTX) is valid for use as a base register. For hard registers, it | ||
| 10381 | +should always accept those which the hardware permits and reject the | ||
| 10382 | +others. Whether the macro accepts or rejects pseudo registers must be | ||
| 10383 | +controlled by REG_OK_STRICT as described above. This usually | ||
| 10384 | +requires two variant definitions, of which REG_OK_STRICT | ||
| 10385 | +controls the one actually used. | ||
| 10386 | +*/ | ||
| 10387 | +#ifdef REG_OK_STRICT | ||
| 10388 | +# define REG_OK_FOR_BASE_P(X) \ | ||
| 10389 | + REGNO_OK_FOR_BASE_P(REGNO(X)) | ||
| 10390 | +#else | ||
| 10391 | +# define REG_OK_FOR_BASE_P(X) \ | ||
| 10392 | + ((REGNO(X) <= LAST_REGNUM) || (REGNO(X) >= FIRST_PSEUDO_REGISTER)) | ||
| 10393 | +#endif | ||
| 10394 | + | ||
| 10395 | + | ||
| 10396 | +/* | ||
| 10397 | +A C expression that is nonzero if X (assumed to be a reg | ||
| 10398 | +RTX) is valid for use as an index register. | ||
| 10399 | + | ||
| 10400 | +The difference between an index register and a base register is that | ||
| 10401 | +the index register may be scaled. If an address involves the sum of | ||
| 10402 | +two registers, neither one of them scaled, then either one may be | ||
| 10403 | +labeled the "base" and the other the "index"; but whichever | ||
| 10404 | +labeling is used must fit the machine's constraints of which registers | ||
| 10405 | +may serve in each capacity. The compiler will try both labelings, | ||
| 10406 | +looking for one that is valid, and will reload one or both registers | ||
| 10407 | +only if neither labeling works. | ||
| 10408 | +*/ | ||
| 10409 | +#define REG_OK_FOR_INDEX_P(X) \ | ||
| 10410 | + REG_OK_FOR_BASE_P(X) | ||
| 10411 | + | ||
| 10412 | + | ||
| 10413 | +/* | ||
| 10414 | +A C compound statement that attempts to replace X with a valid | ||
| 10415 | +memory address for an operand of mode MODE. win will be a | ||
| 10416 | +C statement label elsewhere in the code; the macro definition may use | ||
| 10417 | + | ||
| 10418 | + GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); | ||
| 10419 | + | ||
| 10420 | +to avoid further processing if the address has become legitimate. | ||
| 10421 | + | ||
| 10422 | +X will always be the result of a call to break_out_memory_refs, | ||
| 10423 | +and OLDX will be the operand that was given to that function to produce | ||
| 10424 | +X. | ||
| 10425 | + | ||
| 10426 | +The code generated by this macro should not alter the substructure of | ||
| 10427 | +X. If it transforms X into a more legitimate form, it | ||
| 10428 | +should assign X (which will always be a C variable) a new value. | ||
| 10429 | + | ||
| 10430 | +It is not necessary for this macro to come up with a legitimate | ||
| 10431 | +address. The compiler has standard ways of doing so in all cases. In | ||
| 10432 | +fact, it is safe for this macro to do nothing. But often a | ||
| 10433 | +machine-dependent strategy can generate better code. | ||
| 10434 | +*/ | ||
| 10435 | +#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ | ||
| 10436 | + do \ | ||
| 10437 | + { \ | ||
| 10438 | + if (GET_CODE(X) == PLUS \ | ||
| 10439 | + && GET_CODE(XEXP(X, 0)) == REG \ | ||
| 10440 | + && GET_CODE(XEXP(X, 1)) == CONST_INT \ | ||
| 10441 | + && !CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(X, 1)), \ | ||
| 10442 | + 'K', "Ks16")) \ | ||
| 10443 | + { \ | ||
| 10444 | + rtx index = force_reg(SImode, XEXP(X, 1)); \ | ||
| 10445 | + X = gen_rtx_PLUS( SImode, XEXP(X, 0), index); \ | ||
| 10446 | + } \ | ||
| 10447 | + GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN); \ | ||
| 10448 | + } \ | ||
| 10449 | + while(0) | ||
| 10450 | + | ||
| 10451 | + | ||
| 10452 | +/* | ||
| 10453 | +A C statement or compound statement with a conditional | ||
| 10454 | +goto LABEL; executed if memory address X (an RTX) can have | ||
| 10455 | +different meanings depending on the machine mode of the memory | ||
| 10456 | +reference it is used for or if the address is valid for some modes | ||
| 10457 | +but not others. | ||
| 10458 | + | ||
| 10459 | +Autoincrement and autodecrement addresses typically have mode-dependent | ||
| 10460 | +effects because the amount of the increment or decrement is the size | ||
| 10461 | +of the operand being addressed. Some machines have other mode-dependent | ||
| 10462 | +addresses. Many RISC machines have no mode-dependent addresses. | ||
| 10463 | + | ||
| 10464 | +You may assume that ADDR is a valid address for the machine. | ||
| 10465 | +*/ | ||
| 10466 | +#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \ | ||
| 10467 | + do \ | ||
| 10468 | + { \ | ||
| 10469 | + if (GET_CODE (ADDR) == POST_INC \ | ||
| 10470 | + || GET_CODE (ADDR) == PRE_DEC) \ | ||
| 10471 | + goto LABEL; \ | ||
| 10472 | + } \ | ||
| 10473 | + while (0) | ||
| 10474 | + | ||
| 10475 | +/* | ||
| 10476 | +A C expression that is nonzero if X is a legitimate constant for | ||
| 10477 | +an immediate operand on the target machine. You can assume that | ||
| 10478 | +X satisfies CONSTANT_P, so you need not check this. In fact, | ||
| 10479 | +'1' is a suitable definition for this macro on machines where | ||
| 10480 | +anything CONSTANT_P is valid. | ||
| 10481 | +*/ | ||
| 10482 | +#define LEGITIMATE_CONSTANT_P(X) avr32_legitimate_constant_p(X) | ||
| 10483 | + | ||
| 10484 | + | ||
| 10485 | +/****************************************************************************** | ||
| 10486 | + * Condition Code Status | ||
| 10487 | + *****************************************************************************/ | ||
| 10488 | + | ||
| 10489 | +#define HAVE_conditional_move 1 | ||
| 10490 | + | ||
| 10491 | +/* | ||
| 10492 | +C code for a data type which is used for declaring the mdep | ||
| 10493 | +component of cc_status. It defaults to int. | ||
| 10494 | + | ||
| 10495 | +This macro is not used on machines that do not use cc0. | ||
| 10496 | +*/ | ||
| 10497 | + | ||
| 10498 | +typedef struct | ||
| 10499 | +{ | ||
| 10500 | + int flags; | ||
| 10501 | + rtx value; | ||
| 10502 | + int fpflags; | ||
| 10503 | + rtx fpvalue; | ||
| 10504 | +} avr32_status_reg; | ||
| 10505 | + | ||
| 10506 | + | ||
| 10507 | +#define CC_STATUS_MDEP avr32_status_reg | ||
| 10508 | + | ||
| 10509 | +/* | ||
| 10510 | +A C expression to initialize the mdep field to "empty". | ||
| 10511 | +The default definition does nothing, since most machines don't use | ||
| 10512 | +the field anyway. If you want to use the field, you should probably | ||
| 10513 | +define this macro to initialize it. | ||
| 10514 | + | ||
| 10515 | +This macro is not used on machines that do not use cc0. | ||
| 10516 | +*/ | ||
| 10517 | + | ||
| 10518 | +#define CC_STATUS_MDEP_INIT \ | ||
| 10519 | + (cc_status.mdep.flags = CC_NONE , cc_status.mdep.value = 0) | ||
| 10520 | + | ||
| 10521 | +#define FPCC_STATUS_INIT \ | ||
| 10522 | + (cc_status.mdep.fpflags = CC_NONE , cc_status.mdep.fpvalue = 0) | ||
| 10523 | + | ||
| 10524 | +/* | ||
| 10525 | +A C compound statement to set the components of cc_status | ||
| 10526 | +appropriately for an insn INSN whose body is EXP. It is | ||
| 10527 | +this macro's responsibility to recognize insns that set the condition | ||
| 10528 | +code as a byproduct of other activity as well as those that explicitly | ||
| 10529 | +set (cc0). | ||
| 10530 | + | ||
| 10531 | +This macro is not used on machines that do not use cc0. | ||
| 10532 | + | ||
| 10533 | +If there are insns that do not set the condition code but do alter | ||
| 10534 | +other machine registers, this macro must check to see whether they | ||
| 10535 | +invalidate the expressions that the condition code is recorded as | ||
| 10536 | +reflecting. For example, on the 68000, insns that store in address | ||
| 10537 | +registers do not set the condition code, which means that usually | ||
| 10538 | +NOTICE_UPDATE_CC can leave cc_status unaltered for such | ||
| 10539 | +insns. But suppose that the previous insn set the condition code | ||
| 10540 | +based on location 'a4@@(102)' and the current insn stores a new | ||
| 10541 | +value in 'a4'. Although the condition code is not changed by | ||
| 10542 | +this, it will no longer be true that it reflects the contents of | ||
| 10543 | +'a4@@(102)'. Therefore, NOTICE_UPDATE_CC must alter | ||
| 10544 | +cc_status in this case to say that nothing is known about the | ||
| 10545 | +condition code value. | ||
| 10546 | + | ||
| 10547 | +The definition of NOTICE_UPDATE_CC must be prepared to deal | ||
| 10548 | +with the results of peephole optimization: insns whose patterns are | ||
| 10549 | +parallel RTXs containing various reg, mem or | ||
| 10550 | +constants which are just the operands. The RTL structure of these | ||
| 10551 | +insns is not sufficient to indicate what the insns actually do. What | ||
| 10552 | +NOTICE_UPDATE_CC should do when it sees one is just to run | ||
| 10553 | +CC_STATUS_INIT. | ||
| 10554 | + | ||
| 10555 | +A possible definition of NOTICE_UPDATE_CC is to call a function | ||
| 10556 | +that looks at an attribute (see Insn Attributes) named, for example, | ||
| 10557 | +'cc'. This avoids having detailed information about patterns in | ||
| 10558 | +two places, the 'md' file and in NOTICE_UPDATE_CC. | ||
| 10559 | +*/ | ||
| 10560 | + | ||
| 10561 | +#define NOTICE_UPDATE_CC(EXP, INSN) avr32_notice_update_cc(EXP, INSN) | ||
| 10562 | + | ||
| 10563 | + | ||
| 10564 | + | ||
| 10565 | + | ||
| 10566 | +/****************************************************************************** | ||
| 10567 | + * Describing Relative Costs of Operations | ||
| 10568 | + *****************************************************************************/ | ||
| 10569 | + | ||
| 10570 | + | ||
| 10571 | + | ||
| 10572 | +/* | ||
| 10573 | +A C expression for the cost of moving data of mode MODE from a | ||
| 10574 | +register in class FROM to one in class TO. The classes are | ||
| 10575 | +expressed using the enumeration values such as GENERAL_REGS. A | ||
| 10576 | +value of 2 is the default; other values are interpreted relative to | ||
| 10577 | +that. | ||
| 10578 | + | ||
| 10579 | +It is not required that the cost always equal 2 when FROM is the | ||
| 10580 | +same as TO; on some machines it is expensive to move between | ||
| 10581 | +registers if they are not general registers. | ||
| 10582 | + | ||
| 10583 | +If reload sees an insn consisting of a single set between two | ||
| 10584 | +hard registers, and if REGISTER_MOVE_COST applied to their | ||
| 10585 | +classes returns a value of 2, reload does not check to ensure that the | ||
| 10586 | +constraints of the insn are met. Setting a cost of other than 2 will | ||
| 10587 | +allow reload to verify that the constraints are met. You should do this | ||
| 10588 | +if the movm pattern's constraints do not allow such copying. | ||
| 10589 | +*/ | ||
| 10590 | +#define REGISTER_MOVE_COST(MODE, FROM, TO) \ | ||
| 10591 | + ((GET_MODE_SIZE(MODE) <= 4) ? 2: \ | ||
| 10592 | + (GET_MODE_SIZE(MODE) <= 8) ? 3: \ | ||
| 10593 | + 4) | ||
| 10594 | + | ||
| 10595 | +/* | ||
| 10596 | +A C expression for the cost of moving data of mode MODE between a | ||
| 10597 | +register of class CLASS and memory; IN is zero if the value | ||
| 10598 | +is to be written to memory, nonzero if it is to be read in. This cost | ||
| 10599 | +is relative to those in REGISTER_MOVE_COST. If moving between | ||
| 10600 | +registers and memory is more expensive than between two registers, you | ||
| 10601 | +should define this macro to express the relative cost. | ||
| 10602 | + | ||
| 10603 | +If you do not define this macro, GCC uses a default cost of 4 plus | ||
| 10604 | +the cost of copying via a secondary reload register, if one is | ||
| 10605 | +needed. If your machine requires a secondary reload register to copy | ||
| 10606 | +between memory and a register of CLASS but the reload mechanism is | ||
| 10607 | +more complex than copying via an intermediate, define this macro to | ||
| 10608 | +reflect the actual cost of the move. | ||
| 10609 | + | ||
| 10610 | +GCC defines the function memory_move_secondary_cost if | ||
| 10611 | +secondary reloads are needed. It computes the costs due to copying via | ||
| 10612 | +a secondary register. If your machine copies from memory using a | ||
| 10613 | +secondary register in the conventional way but the default base value of | ||
| 10614 | +4 is not correct for your machine, define this macro to add some other | ||
| 10615 | +value to the result of that function. The arguments to that function | ||
| 10616 | +are the same as to this macro. | ||
| 10617 | +*/ | ||
| 10618 | +/* | ||
| 10619 | + Memory moves are costly | ||
| 10620 | +*/ | ||
| 10621 | +#define MEMORY_MOVE_COST(MODE, CLASS, IN) 10 | ||
| 10622 | +/* | ||
| 10623 | + (((IN) ? ((GET_MODE_SIZE(MODE) < 4) ? 4 : \ | ||
| 10624 | + (GET_MODE_SIZE(MODE) > 8) ? 6 : \ | ||
| 10625 | + 3) \ | ||
| 10626 | + : ((GET_MODE_SIZE(MODE) > 8) ? 4 : 2))) | ||
| 10627 | +*/ | ||
| 10628 | + | ||
| 10629 | +/* | ||
| 10630 | +A C expression for the cost of a branch instruction. A value of 1 is | ||
| 10631 | +the default; other values are interpreted relative to that. | ||
| 10632 | +*/ | ||
| 10633 | + /* Try to use conditionals as much as possible */ | ||
| 10634 | +#define BRANCH_COST (TARGET_BRANCH_PRED ? 3 : 5) | ||
| 10635 | + | ||
| 10636 | +/*A C expression for the maximum number of instructions to execute via conditional | ||
| 10637 | + execution instructions instead of a branch. A value of BRANCH_COST+1 is the default | ||
| 10638 | + if the machine does not use cc0, and 1 if it does use cc0.*/ | ||
| 10639 | +#define MAX_CONDITIONAL_EXECUTE 3 | ||
| 10640 | + | ||
| 10641 | +/* | ||
| 10642 | +Define this macro as a C expression which is nonzero if accessing less | ||
| 10643 | +than a word of memory (i.e.: a char or a short) is no | ||
| 10644 | +faster than accessing a word of memory, i.e., if such access | ||
| 10645 | +require more than one instruction or if there is no difference in cost | ||
| 10646 | +between byte and (aligned) word loads. | ||
| 10647 | + | ||
| 10648 | +When this macro is not defined, the compiler will access a field by | ||
| 10649 | +finding the smallest containing object; when it is defined, a fullword | ||
| 10650 | +load will be used if alignment permits. Unless bytes accesses are | ||
| 10651 | +faster than word accesses, using word accesses is preferable since it | ||
| 10652 | +may eliminate subsequent memory access if subsequent accesses occur to | ||
| 10653 | +other fields in the same word of the structure, but to different bytes. | ||
| 10654 | +*/ | ||
| 10655 | +#define SLOW_BYTE_ACCESS 1 | ||
| 10656 | + | ||
| 10657 | + | ||
| 10658 | +/* | ||
| 10659 | +Define this macro if it is as good or better to call a constant | ||
| 10660 | +function address than to call an address kept in a register. | ||
| 10661 | +*/ | ||
| 10662 | +#define NO_FUNCTION_CSE | ||
| 10663 | + | ||
| 10664 | + | ||
| 10665 | +/****************************************************************************** | ||
| 10666 | + * Adjusting the Instruction Scheduler | ||
| 10667 | + *****************************************************************************/ | ||
| 10668 | + | ||
| 10669 | +/***************************************************************************** | ||
| 10670 | + * Dividing the Output into Sections (Texts, Data, ...) * | ||
| 10671 | + *****************************************************************************/ | ||
| 10672 | + | ||
| 10673 | +/* | ||
| 10674 | +A C expression whose value is a string, including spacing, containing the | ||
| 10675 | +assembler operation that should precede instructions and read-only data. | ||
| 10676 | +Normally "\t.text" is right. | ||
| 10677 | +*/ | ||
| 10678 | +#define TEXT_SECTION_ASM_OP "\t.text" | ||
| 10679 | +/* | ||
| 10680 | +A C statement that switches to the default section containing instructions. | ||
| 10681 | +Normally this is not needed, as simply defining TEXT_SECTION_ASM_OP | ||
| 10682 | +is enough. The MIPS port uses this to sort all functions after all data | ||
| 10683 | +declarations. | ||
| 10684 | +*/ | ||
| 10685 | +/* #define TEXT_SECTION */ | ||
| 10686 | + | ||
| 10687 | +/* | ||
| 10688 | +A C expression whose value is a string, including spacing, containing the | ||
| 10689 | +assembler operation to identify the following data as writable initialized | ||
| 10690 | +data. Normally "\t.data" is right. | ||
| 10691 | +*/ | ||
| 10692 | +#define DATA_SECTION_ASM_OP "\t.data" | ||
| 10693 | + | ||
| 10694 | +/* | ||
| 10695 | +If defined, a C expression whose value is a string, including spacing, | ||
| 10696 | +containing the assembler operation to identify the following data as | ||
| 10697 | +shared data. If not defined, DATA_SECTION_ASM_OP will be used. | ||
| 10698 | +*/ | ||
| 10699 | + | ||
| 10700 | +/* | ||
| 10701 | +A C expression whose value is a string, including spacing, containing | ||
| 10702 | +the assembler operation to identify the following data as read-only | ||
| 10703 | +initialized data. | ||
| 10704 | +*/ | ||
| 10705 | +#undef READONLY_DATA_SECTION_ASM_OP | ||
| 10706 | +#define READONLY_DATA_SECTION_ASM_OP \ | ||
| 10707 | + ((target_flags & USE_RODATA_SECTION) ? \ | ||
| 10708 | + "\t.section\t.rodata" : \ | ||
| 10709 | + TEXT_SECTION_ASM_OP ) | ||
| 10710 | + | ||
| 10711 | + | ||
| 10712 | +/* | ||
| 10713 | +If defined, a C expression whose value is a string, including spacing, | ||
| 10714 | +containing the assembler operation to identify the following data as | ||
| 10715 | +uninitialized global data. If not defined, and neither | ||
| 10716 | +ASM_OUTPUT_BSS nor ASM_OUTPUT_ALIGNED_BSS are defined, | ||
| 10717 | +uninitialized global data will be output in the data section if | ||
| 10718 | +-fno-common is passed, otherwise ASM_OUTPUT_COMMON will be | ||
| 10719 | +used. | ||
| 10720 | +*/ | ||
| 10721 | +#define BSS_SECTION_ASM_OP "\t.section\t.bss" | ||
| 10722 | + | ||
| 10723 | +/* | ||
| 10724 | +If defined, a C expression whose value is a string, including spacing, | ||
| 10725 | +containing the assembler operation to identify the following data as | ||
| 10726 | +uninitialized global shared data. If not defined, and | ||
| 10727 | +BSS_SECTION_ASM_OP is, the latter will be used. | ||
| 10728 | +*/ | ||
| 10729 | +/*#define SHARED_BSS_SECTION_ASM_OP "\trseg\tshared_bbs_section:data:noroot(0)\n"*/ | ||
| 10730 | +/* | ||
| 10731 | +If defined, a C expression whose value is a string, including spacing, | ||
| 10732 | +containing the assembler operation to identify the following data as | ||
| 10733 | +initialization code. If not defined, GCC will assume such a section does | ||
| 10734 | +not exist. | ||
| 10735 | +*/ | ||
| 10736 | +#undef INIT_SECTION_ASM_OP | ||
| 10737 | +#define INIT_SECTION_ASM_OP "\t.section\t.init" | ||
| 10738 | + | ||
| 10739 | +/* | ||
| 10740 | +If defined, a C expression whose value is a string, including spacing, | ||
| 10741 | +containing the assembler operation to identify the following data as | ||
| 10742 | +finalization code. If not defined, GCC will assume such a section does | ||
| 10743 | +not exist. | ||
| 10744 | +*/ | ||
| 10745 | +#undef FINI_SECTION_ASM_OP | ||
| 10746 | +#define FINI_SECTION_ASM_OP "\t.section\t.fini" | ||
| 10747 | + | ||
| 10748 | +/* | ||
| 10749 | +If defined, an ASM statement that switches to a different section | ||
| 10750 | +via SECTION_OP, calls FUNCTION, and switches back to | ||
| 10751 | +the text section. This is used in crtstuff.c if | ||
| 10752 | +INIT_SECTION_ASM_OP or FINI_SECTION_ASM_OP to calls | ||
| 10753 | +to initialization and finalization functions from the init and fini | ||
| 10754 | +sections. By default, this macro uses a simple function call. Some | ||
| 10755 | +ports need hand-crafted assembly code to avoid dependencies on | ||
| 10756 | +registers initialized in the function prologue or to ensure that | ||
| 10757 | +constant pools don't end up too far way in the text section. | ||
| 10758 | +*/ | ||
| 10759 | +#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ | ||
| 10760 | + asm ( SECTION_OP "\n" \ | ||
| 10761 | + "mcall r6[" USER_LABEL_PREFIX #FUNC "@got]\n" \ | ||
| 10762 | + TEXT_SECTION_ASM_OP); | ||
| 10763 | + | ||
| 10764 | + | ||
| 10765 | +/* | ||
| 10766 | +Define this macro to be an expression with a nonzero value if jump | ||
| 10767 | +tables (for tablejump insns) should be output in the text | ||
| 10768 | +section, along with the assembler instructions. Otherwise, the | ||
| 10769 | +readonly data section is used. | ||
| 10770 | + | ||
| 10771 | +This macro is irrelevant if there is no separate readonly data section. | ||
| 10772 | +*/ | ||
| 10773 | +#define JUMP_TABLES_IN_TEXT_SECTION 1 | ||
| 10774 | + | ||
| 10775 | + | ||
| 10776 | +/****************************************************************************** | ||
| 10777 | + * Position Independent Code (PIC) | ||
| 10778 | + *****************************************************************************/ | ||
| 10779 | + | ||
| 10780 | +#ifndef AVR32_ALWAYS_PIC | ||
| 10781 | +#define AVR32_ALWAYS_PIC 0 | ||
| 10782 | +#endif | ||
| 10783 | + | ||
| 10784 | +/* GOT is set to r6 */ | ||
| 10785 | +#define PIC_OFFSET_TABLE_REGNUM INTERNAL_REGNUM(6) | ||
| 10786 | + | ||
| 10787 | +/* | ||
| 10788 | +A C expression that is nonzero if X is a legitimate immediate | ||
| 10789 | +operand on the target machine when generating position independent code. | ||
| 10790 | +You can assume that X satisfies CONSTANT_P, so you need not | ||
| 10791 | +check this. You can also assume flag_pic is true, so you need not | ||
| 10792 | +check it either. You need not define this macro if all constants | ||
| 10793 | +(including SYMBOL_REF) can be immediate operands when generating | ||
| 10794 | +position independent code. | ||
| 10795 | +*/ | ||
| 10796 | +/* We can't directly access anything that contains a symbol, | ||
| 10797 | + nor can we indirect via the constant pool. */ | ||
| 10798 | +#define LEGITIMATE_PIC_OPERAND_P(X) avr32_legitimate_pic_operand_p(X) | ||
| 10799 | + | ||
| 10800 | + | ||
| 10801 | +/* We need to know when we are making a constant pool; this determines | ||
| 10802 | + whether data needs to be in the GOT or can be referenced via a GOT | ||
| 10803 | + offset. */ | ||
| 10804 | +extern int making_const_table; | ||
| 10805 | + | ||
| 10806 | +/****************************************************************************** | ||
| 10807 | + * Defining the Output Assembler Language | ||
| 10808 | + *****************************************************************************/ | ||
| 10809 | + | ||
| 10810 | + | ||
| 10811 | +/* | ||
| 10812 | +A C string constant describing how to begin a comment in the target | ||
| 10813 | +assembler language. The compiler assumes that the comment will end at | ||
| 10814 | +the end of the line. | ||
| 10815 | +*/ | ||
| 10816 | +#define ASM_COMMENT_START "# " | ||
| 10817 | + | ||
| 10818 | +/* | ||
| 10819 | +A C string constant for text to be output before each asm | ||
| 10820 | +statement or group of consecutive ones. Normally this is | ||
| 10821 | +"#APP", which is a comment that has no effect on most | ||
| 10822 | +assemblers but tells the GNU assembler that it must check the lines | ||
| 10823 | +that follow for all valid assembler constructs. | ||
| 10824 | +*/ | ||
| 10825 | +#undef ASM_APP_ON | ||
| 10826 | +#define ASM_APP_ON "#APP\n" | ||
| 10827 | + | ||
| 10828 | +/* | ||
| 10829 | +A C string constant for text to be output after each asm | ||
| 10830 | +statement or group of consecutive ones. Normally this is | ||
| 10831 | +"#NO_APP", which tells the GNU assembler to resume making the | ||
| 10832 | +time-saving assumptions that are valid for ordinary compiler output. | ||
| 10833 | +*/ | ||
| 10834 | +#undef ASM_APP_OFF | ||
| 10835 | +#define ASM_APP_OFF "#NO_APP\n" | ||
| 10836 | + | ||
| 10837 | + | ||
| 10838 | + | ||
| 10839 | +#define FILE_ASM_OP "\t.file\n" | ||
| 10840 | +#define IDENT_ASM_OP "\t.ident\t" | ||
| 10841 | +#define SET_ASM_OP "\t.set\t" | ||
| 10842 | + | ||
| 10843 | + | ||
| 10844 | +/* | ||
| 10845 | + * Output assembly directives to switch to section name. The section | ||
| 10846 | + * should have attributes as specified by flags, which is a bit mask | ||
| 10847 | + * of the SECTION_* flags defined in 'output.h'. If align is nonzero, | ||
| 10848 | + * it contains an alignment in bytes to be used for the section, | ||
| 10849 | + * otherwise some target default should be used. Only targets that | ||
| 10850 | + * must specify an alignment within the section directive need pay | ||
| 10851 | + * attention to align -- we will still use ASM_OUTPUT_ALIGN. | ||
| 10852 | + * | ||
| 10853 | + * NOTE: This one must not be moved to avr32.c | ||
| 10854 | + */ | ||
| 10855 | +#undef TARGET_ASM_NAMED_SECTION | ||
| 10856 | +#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section | ||
| 10857 | + | ||
| 10858 | + | ||
| 10859 | +/* | ||
| 10860 | +You may define this macro as a C expression. You should define the | ||
| 10861 | +expression to have a nonzero value if GCC should output the constant | ||
| 10862 | +pool for a function before the code for the function, or a zero value if | ||
| 10863 | +GCC should output the constant pool after the function. If you do | ||
| 10864 | +not define this macro, the usual case, GCC will output the constant | ||
| 10865 | +pool before the function. | ||
| 10866 | +*/ | ||
| 10867 | +#define CONSTANT_POOL_BEFORE_FUNCTION 0 | ||
| 10868 | + | ||
| 10869 | + | ||
| 10870 | +/* | ||
| 10871 | +Define this macro as a C expression which is nonzero if the constant | ||
| 10872 | +EXP, of type tree, should be output after the code for a | ||
| 10873 | +function. The compiler will normally output all constants before the | ||
| 10874 | +function; you need not define this macro if this is OK. | ||
| 10875 | +*/ | ||
| 10876 | +#define CONSTANT_AFTER_FUNCTION_P(EXP) 1 | ||
| 10877 | + | ||
| 10878 | + | ||
| 10879 | +/* | ||
| 10880 | +Define this macro as a C expression which is nonzero if C is | ||
| 10881 | +used as a logical line separator by the assembler. | ||
| 10882 | + | ||
| 10883 | +If you do not define this macro, the default is that only | ||
| 10884 | +the character ';' is treated as a logical line separator. | ||
| 10885 | +*/ | ||
| 10886 | +#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == '\n') | ||
| 10887 | + | ||
| 10888 | + | ||
| 10889 | +/** Output of Uninitialized Variables **/ | ||
| 10890 | + | ||
| 10891 | +/* | ||
| 10892 | +A C statement (sans semicolon) to output to the stdio stream | ||
| 10893 | +STREAM the assembler definition of a common-label named | ||
| 10894 | +NAME whose size is SIZE bytes. The variable ROUNDED | ||
| 10895 | +is the size rounded up to whatever alignment the caller wants. | ||
| 10896 | + | ||
| 10897 | +Use the expression assemble_name(STREAM, NAME) to | ||
| 10898 | +output the name itself; before and after that, output the additional | ||
| 10899 | +assembler syntax for defining the name, and a newline. | ||
| 10900 | + | ||
| 10901 | +This macro controls how the assembler definitions of uninitialized | ||
| 10902 | +common global variables are output. | ||
| 10903 | +*/ | ||
| 10904 | +/* | ||
| 10905 | +#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \ | ||
| 10906 | + avr32_asm_output_common(STREAM, NAME, SIZE, ROUNDED) | ||
| 10907 | +*/ | ||
| 10908 | + | ||
| 10909 | +#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ | ||
| 10910 | + do \ | ||
| 10911 | + { \ | ||
| 10912 | + fputs ("\t.comm ", (FILE)); \ | ||
| 10913 | + assemble_name ((FILE), (NAME)); \ | ||
| 10914 | + fprintf ((FILE), ",%d\n", (SIZE)); \ | ||
| 10915 | + } \ | ||
| 10916 | + while (0) | ||
| 10917 | + | ||
| 10918 | +/* | ||
| 10919 | + * Like ASM_OUTPUT_BSS except takes the required alignment as a | ||
| 10920 | + * separate, explicit argument. If you define this macro, it is used | ||
| 10921 | + * in place of ASM_OUTPUT_BSS, and gives you more flexibility in | ||
| 10922 | + * handling the required alignment of the variable. The alignment is | ||
| 10923 | + * specified as the number of bits. | ||
| 10924 | + * | ||
| 10925 | + * Try to use function asm_output_aligned_bss defined in file varasm.c | ||
| 10926 | + * when defining this macro. | ||
| 10927 | + */ | ||
| 10928 | +#define ASM_OUTPUT_ALIGNED_BSS(STREAM, DECL, NAME, SIZE, ALIGNMENT) \ | ||
| 10929 | + asm_output_aligned_bss (STREAM, DECL, NAME, SIZE, ALIGNMENT) | ||
| 10930 | + | ||
| 10931 | +/* | ||
| 10932 | +A C statement (sans semicolon) to output to the stdio stream | ||
| 10933 | +STREAM the assembler definition of a local-common-label named | ||
| 10934 | +NAME whose size is SIZE bytes. The variable ROUNDED | ||
| 10935 | +is the size rounded up to whatever alignment the caller wants. | ||
| 10936 | + | ||
| 10937 | +Use the expression assemble_name(STREAM, NAME) to | ||
| 10938 | +output the name itself; before and after that, output the additional | ||
| 10939 | +assembler syntax for defining the name, and a newline. | ||
| 10940 | + | ||
| 10941 | +This macro controls how the assembler definitions of uninitialized | ||
| 10942 | +static variables are output. | ||
| 10943 | +*/ | ||
| 10944 | +#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ | ||
| 10945 | + do \ | ||
| 10946 | + { \ | ||
| 10947 | + fputs ("\t.lcomm ", (FILE)); \ | ||
| 10948 | + assemble_name ((FILE), (NAME)); \ | ||
| 10949 | + fprintf ((FILE), ",%d, %d\n", (SIZE), 2); \ | ||
| 10950 | + } \ | ||
| 10951 | + while (0) | ||
| 10952 | + | ||
| 10953 | + | ||
| 10954 | +/* | ||
| 10955 | +A C statement (sans semicolon) to output to the stdio stream | ||
| 10956 | +STREAM the assembler definition of a label named NAME. | ||
| 10957 | +Use the expression assemble_name(STREAM, NAME) to | ||
| 10958 | +output the name itself; before and after that, output the additional | ||
| 10959 | +assembler syntax for defining the name, and a newline. | ||
| 10960 | +*/ | ||
| 10961 | +#define ASM_OUTPUT_LABEL(STREAM, NAME) avr32_asm_output_label(STREAM, NAME) | ||
| 10962 | + | ||
| 10963 | +/* A C string containing the appropriate assembler directive to | ||
| 10964 | + * specify the size of a symbol, without any arguments. On systems | ||
| 10965 | + * that use ELF, the default (in 'config/elfos.h') is '"\t.size\t"'; | ||
| 10966 | + * on other systems, the default is not to define this macro. | ||
| 10967 | + * | ||
| 10968 | + * Define this macro only if it is correct to use the default | ||
| 10969 | + * definitions of ASM_ OUTPUT_SIZE_DIRECTIVE and | ||
| 10970 | + * ASM_OUTPUT_MEASURED_SIZE for your system. If you need your own | ||
| 10971 | + * custom definitions of those macros, or if you do not need explicit | ||
| 10972 | + * symbol sizes at all, do not define this macro. | ||
| 10973 | + */ | ||
| 10974 | +#define SIZE_ASM_OP "\t.size\t" | ||
| 10975 | + | ||
| 10976 | + | ||
| 10977 | +/* | ||
| 10978 | +A C statement (sans semicolon) to output to the stdio stream | ||
| 10979 | +STREAM some commands that will make the label NAME global; | ||
| 10980 | +that is, available for reference from other files. Use the expression | ||
| 10981 | +assemble_name(STREAM, NAME) to output the name | ||
| 10982 | +itself; before and after that, output the additional assembler syntax | ||
| 10983 | +for making that name global, and a newline. | ||
| 10984 | +*/ | ||
| 10985 | +#define GLOBAL_ASM_OP "\t.globl\t" | ||
| 10986 | + | ||
| 10987 | + | ||
| 10988 | + | ||
| 10989 | +/* | ||
| 10990 | +A C expression which evaluates to true if the target supports weak symbols. | ||
| 10991 | + | ||
| 10992 | +If you don't define this macro, defaults.h provides a default | ||
| 10993 | +definition. If either ASM_WEAKEN_LABEL or ASM_WEAKEN_DECL | ||
| 10994 | +is defined, the default definition is '1'; otherwise, it is | ||
| 10995 | +'0'. Define this macro if you want to control weak symbol support | ||
| 10996 | +with a compiler flag such as -melf. | ||
| 10997 | +*/ | ||
| 10998 | +#define SUPPORTS_WEAK 1 | ||
| 10999 | + | ||
| 11000 | +/* | ||
| 11001 | +A C statement (sans semicolon) to output to the stdio stream | ||
| 11002 | +STREAM a reference in assembler syntax to a label named | ||
| 11003 | +NAME. This should add '_' to the front of the name, if that | ||
| 11004 | +is customary on your operating system, as it is in most Berkeley Unix | ||
| 11005 | +systems. This macro is used in assemble_name. | ||
| 11006 | +*/ | ||
| 11007 | +#define ASM_OUTPUT_LABELREF(STREAM, NAME) \ | ||
| 11008 | + avr32_asm_output_labelref(STREAM, NAME) | ||
| 11009 | + | ||
| 11010 | + | ||
| 11011 | + | ||
| 11012 | +/* | ||
| 11013 | +A C expression to assign to OUTVAR (which is a variable of type | ||
| 11014 | +char *) a newly allocated string made from the string | ||
| 11015 | +NAME and the number NUMBER, with some suitable punctuation | ||
| 11016 | +added. Use alloca to get space for the string. | ||
| 11017 | + | ||
| 11018 | +The string will be used as an argument to ASM_OUTPUT_LABELREF to | ||
| 11019 | +produce an assembler label for an internal static variable whose name is | ||
| 11020 | +NAME. Therefore, the string must be such as to result in valid | ||
| 11021 | +assembler code. The argument NUMBER is different each time this | ||
| 11022 | +macro is executed; it prevents conflicts between similarly-named | ||
| 11023 | +internal static variables in different scopes. | ||
| 11024 | + | ||
| 11025 | +Ideally this string should not be a valid C identifier, to prevent any | ||
| 11026 | +conflict with the user's own symbols. Most assemblers allow periods | ||
| 11027 | +or percent signs in assembler symbols; putting at least one of these | ||
| 11028 | +between the name and the number will suffice. | ||
| 11029 | +*/ | ||
| 11030 | +#define ASM_FORMAT_PRIVATE_NAME(OUTVAR, NAME, NUMBER) \ | ||
| 11031 | + do \ | ||
| 11032 | + { \ | ||
| 11033 | + (OUTVAR) = (char *) alloca (strlen ((NAME)) + 10); \ | ||
| 11034 | + sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER)); \ | ||
| 11035 | + } \ | ||
| 11036 | + while (0) | ||
| 11037 | + | ||
| 11038 | + | ||
| 11039 | +/** Macros Controlling Initialization Routines **/ | ||
| 11040 | + | ||
| 11041 | + | ||
| 11042 | +/* | ||
| 11043 | +If defined, main will not call __main as described above. | ||
| 11044 | +This macro should be defined for systems that control start-up code | ||
| 11045 | +on a symbol-by-symbol basis, such as OSF/1, and should not | ||
| 11046 | +be defined explicitly for systems that support INIT_SECTION_ASM_OP. | ||
| 11047 | +*/ | ||
| 11048 | +/* | ||
| 11049 | + __main is not defined when debugging. | ||
| 11050 | +*/ | ||
| 11051 | +#define HAS_INIT_SECTION | ||
| 11052 | + | ||
| 11053 | + | ||
| 11054 | +/** Output of Assembler Instructions **/ | ||
| 11055 | + | ||
| 11056 | +/* | ||
| 11057 | +A C initializer containing the assembler's names for the machine | ||
| 11058 | +registers, each one as a C string constant. This is what translates | ||
| 11059 | +register numbers in the compiler into assembler language. | ||
| 11060 | +*/ | ||
| 11061 | + | ||
| 11062 | +#define REGISTER_NAMES \ | ||
| 11063 | +{ \ | ||
| 11064 | + "pc", "lr", \ | ||
| 11065 | + "sp", "r12", \ | ||
| 11066 | + "r11", "r10", \ | ||
| 11067 | + "r9", "r8", \ | ||
| 11068 | + "r7", "r6", \ | ||
| 11069 | + "r5", "r4", \ | ||
| 11070 | + "r3", "r2", \ | ||
| 11071 | + "r1", "r0", \ | ||
| 11072 | + "f15","f14", \ | ||
| 11073 | + "f13","f12", \ | ||
| 11074 | + "f11","f10", \ | ||
| 11075 | + "f9", "f8", \ | ||
| 11076 | + "f7", "f6", \ | ||
| 11077 | + "f5", "f4", \ | ||
| 11078 | + "f3", "f2", \ | ||
| 11079 | + "f1", "f0" \ | ||
| 11080 | +} | ||
| 11081 | + | ||
| 11082 | +/* | ||
| 11083 | +A C compound statement to output to stdio stream STREAM the | ||
| 11084 | +assembler syntax for an instruction operand X. X is an | ||
| 11085 | +RTL expression. | ||
| 11086 | + | ||
| 11087 | +CODE is a value that can be used to specify one of several ways | ||
| 11088 | +of printing the operand. It is used when identical operands must be | ||
| 11089 | +printed differently depending on the context. CODE comes from | ||
| 11090 | +the '%' specification that was used to request printing of the | ||
| 11091 | +operand. If the specification was just '%digit' then | ||
| 11092 | +CODE is 0; if the specification was '%ltr digit' | ||
| 11093 | +then CODE is the ASCII code for ltr. | ||
| 11094 | + | ||
| 11095 | +If X is a register, this macro should print the register's name. | ||
| 11096 | +The names can be found in an array reg_names whose type is | ||
| 11097 | +char *[]. reg_names is initialized from REGISTER_NAMES. | ||
| 11098 | + | ||
| 11099 | +When the machine description has a specification '%punct' | ||
| 11100 | +(a '%' followed by a punctuation character), this macro is called | ||
| 11101 | +with a null pointer for X and the punctuation character for | ||
| 11102 | +CODE. | ||
| 11103 | +*/ | ||
| 11104 | +#define PRINT_OPERAND(STREAM, X, CODE) avr32_print_operand(STREAM, X, CODE) | ||
| 11105 | + | ||
| 11106 | +/* A C statement to be executed just prior to the output of | ||
| 11107 | + assembler code for INSN, to modify the extracted operands so | ||
| 11108 | + they will be output differently. | ||
| 11109 | + | ||
| 11110 | + Here the argument OPVEC is the vector containing the operands | ||
| 11111 | + extracted from INSN, and NOPERANDS is the number of elements of | ||
| 11112 | + the vector which contain meaningful data for this insn. | ||
| 11113 | + The contents of this vector are what will be used to convert the insn | ||
| 11114 | + template into assembler code, so you can change the assembler output | ||
| 11115 | + by changing the contents of the vector. */ | ||
| 11116 | +#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \ | ||
| 11117 | + avr32_final_prescan_insn ((INSN), (OPVEC), (NOPERANDS)) | ||
| 11118 | + | ||
| 11119 | +/* | ||
| 11120 | +A C expression which evaluates to true if CODE is a valid | ||
| 11121 | +punctuation character for use in the PRINT_OPERAND macro. If | ||
| 11122 | +PRINT_OPERAND_PUNCT_VALID_P is not defined, it means that no | ||
| 11123 | +punctuation characters (except for the standard one, '%') are used | ||
| 11124 | +in this way. | ||
| 11125 | +*/ | ||
| 11126 | +/* | ||
| 11127 | + 'm' refers to the most significant word in a two-register mode. | ||
| 11128 | +*/ | ||
| 11129 | +#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == 'm' || (CODE) == 'e') | ||
| 11130 | + | ||
| 11131 | +/* | ||
| 11132 | +A C compound statement to output to stdio stream STREAM the | ||
| 11133 | +assembler syntax for an instruction operand that is a memory reference | ||
| 11134 | +whose address is X. X is an RTL expression. | ||
| 11135 | + | ||
| 11136 | +On some machines, the syntax for a symbolic address depends on the | ||
| 11137 | +section that the address refers to. On these machines, define the macro | ||
| 11138 | +ENCODE_SECTION_INFO to store the information into the | ||
| 11139 | +symbol_ref, and then check for it here. (see Assembler Format.) | ||
| 11140 | +*/ | ||
| 11141 | +#define PRINT_OPERAND_ADDRESS(STREAM, X) avr32_print_operand_address(STREAM, X) | ||
| 11142 | + | ||
| 11143 | + | ||
| 11144 | +/** Output of Dispatch Tables **/ | ||
| 11145 | + | ||
| 11146 | +/* | ||
| 11147 | + * A C statement to output to the stdio stream stream an assembler | ||
| 11148 | + * pseudo-instruction to generate a difference between two | ||
| 11149 | + * labels. value and rel are the numbers of two internal labels. The | ||
| 11150 | + * definitions of these labels are output using | ||
| 11151 | + * (*targetm.asm_out.internal_label), and they must be printed in the | ||
| 11152 | + * same way here. For example, | ||
| 11153 | + * | ||
| 11154 | + * fprintf (stream, "\t.word L%d-L%d\n", | ||
| 11155 | + * value, rel) | ||
| 11156 | + * | ||
| 11157 | + * You must provide this macro on machines where the addresses in a | ||
| 11158 | + * dispatch table are relative to the table's own address. If defined, | ||
| 11159 | + * GCC will also use this macro on all machines when producing | ||
| 11160 | + * PIC. body is the body of the ADDR_DIFF_VEC; it is provided so that | ||
| 11161 | + * the mode and flags can be read. | ||
| 11162 | + */ | ||
| 11163 | +#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \ | ||
| 11164 | + fprintf(STREAM, "\tbral\t%sL%d\n", LOCAL_LABEL_PREFIX, VALUE) | ||
| 11165 | + | ||
| 11166 | +/* | ||
| 11167 | +This macro should be provided on machines where the addresses | ||
| 11168 | +in a dispatch table are absolute. | ||
| 11169 | + | ||
| 11170 | +The definition should be a C statement to output to the stdio stream | ||
| 11171 | +STREAM an assembler pseudo-instruction to generate a reference to | ||
| 11172 | +a label. VALUE is the number of an internal label whose | ||
| 11173 | +definition is output using ASM_OUTPUT_INTERNAL_LABEL. | ||
| 11174 | +For example, | ||
| 11175 | + | ||
| 11176 | +fprintf(STREAM, "\t.word L%d\n", VALUE) | ||
| 11177 | +*/ | ||
| 11178 | + | ||
| 11179 | +#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \ | ||
| 11180 | + fprintf(STREAM, "\t.long %sL%d\n", LOCAL_LABEL_PREFIX, VALUE) | ||
| 11181 | + | ||
| 11182 | +/** Assembler Commands for Exception Regions */ | ||
| 11183 | + | ||
| 11184 | +/* ToDo: All of this subsection */ | ||
| 11185 | + | ||
| 11186 | +/** Assembler Commands for Alignment */ | ||
| 11187 | + | ||
| 11188 | + | ||
| 11189 | +/* | ||
| 11190 | +A C statement to output to the stdio stream STREAM an assembler | ||
| 11191 | +command to advance the location counter to a multiple of 2 to the | ||
| 11192 | +POWER bytes. POWER will be a C expression of type int. | ||
| 11193 | +*/ | ||
| 11194 | +#define ASM_OUTPUT_ALIGN(STREAM, POWER) \ | ||
| 11195 | + do \ | ||
| 11196 | + { \ | ||
| 11197 | + if ((POWER) != 0) \ | ||
| 11198 | + fprintf(STREAM, "\t.align\t%d\n", POWER); \ | ||
| 11199 | + } \ | ||
| 11200 | + while (0) | ||
| 11201 | + | ||
| 11202 | +/* | ||
| 11203 | +Like ASM_OUTPUT_ALIGN, except that the \nop" instruction is used for padding, if | ||
| 11204 | +necessary. | ||
| 11205 | +*/ | ||
| 11206 | +#define ASM_OUTPUT_ALIGN_WITH_NOP(STREAM, POWER) \ | ||
| 11207 | + fprintf(STREAM, "\t.balignw\t%d, 0xd703\n", (1 << POWER)) | ||
| 11208 | + | ||
| 11209 | + | ||
| 11210 | + | ||
| 11211 | +/****************************************************************************** | ||
| 11212 | + * Controlling Debugging Information Format | ||
| 11213 | + *****************************************************************************/ | ||
| 11214 | + | ||
| 11215 | +/* How to renumber registers for dbx and gdb. */ | ||
| 11216 | +#define DBX_REGISTER_NUMBER(REGNO) ASM_REGNUM (REGNO) | ||
| 11217 | + | ||
| 11218 | +/* The DWARF 2 CFA column which tracks the return address. */ | ||
| 11219 | +#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM(LR_REGNUM) | ||
| 11220 | + | ||
| 11221 | +/* | ||
| 11222 | +Define this macro if GCC should produce dwarf version 2 format | ||
| 11223 | +debugging output in response to the -g option. | ||
| 11224 | + | ||
| 11225 | +To support optional call frame debugging information, you must also | ||
| 11226 | +define INCOMING_RETURN_ADDR_RTX and either set | ||
| 11227 | +RTX_FRAME_RELATED_P on the prologue insns if you use RTL for the | ||
| 11228 | +prologue, or call dwarf2out_def_cfa and dwarf2out_reg_save | ||
| 11229 | +as appropriate from TARGET_ASM_FUNCTION_PROLOGUE if you don't. | ||
| 11230 | +*/ | ||
| 11231 | +#define DWARF2_DEBUGGING_INFO 1 | ||
| 11232 | + | ||
| 11233 | + | ||
| 11234 | +#define DWARF2_ASM_LINE_DEBUG_INFO 1 | ||
| 11235 | +#define DWARF2_FRAME_INFO 1 | ||
| 11236 | + | ||
| 11237 | + | ||
| 11238 | +/****************************************************************************** | ||
| 11239 | + * Miscellaneous Parameters | ||
| 11240 | + *****************************************************************************/ | ||
| 11241 | + | ||
| 11242 | +/* ToDo: a lot */ | ||
| 11243 | + | ||
| 11244 | +/* | ||
| 11245 | +An alias for a machine mode name. This is the machine mode that | ||
| 11246 | +elements of a jump-table should have. | ||
| 11247 | +*/ | ||
| 11248 | +#define CASE_VECTOR_MODE SImode | ||
| 11249 | + | ||
| 11250 | +/* | ||
| 11251 | +Define this macro to be a C expression to indicate when jump-tables | ||
| 11252 | +should contain relative addresses. If jump-tables never contain | ||
| 11253 | +relative addresses, then you need not define this macro. | ||
| 11254 | +*/ | ||
| 11255 | +#define CASE_VECTOR_PC_RELATIVE 0 | ||
| 11256 | + | ||
| 11257 | +/* | ||
| 11258 | +The maximum number of bytes that a single instruction can move quickly | ||
| 11259 | +between memory and registers or between two memory locations. | ||
| 11260 | +*/ | ||
| 11261 | +#define MOVE_MAX (2*UNITS_PER_WORD) | ||
| 11262 | + | ||
| 11263 | + | ||
| 11264 | +/* A C expression that is nonzero if on this machine the number of bits actually used | ||
| 11265 | + for the count of a shift operation is equal to the number of bits needed to represent | ||
| 11266 | + the size of the object being shifted. When this macro is nonzero, the compiler will | ||
| 11267 | + assume that it is safe to omit a sign-extend, zero-extend, and certain bitwise 'and' | ||
| 11268 | + instructions that truncates the count of a shift operation. On machines that have | ||
| 11269 | + instructions that act on bit-fields at variable positions, which may include 'bit test' | ||
| 11270 | + 378 GNU Compiler Collection (GCC) Internals | ||
| 11271 | + instructions, a nonzero SHIFT_COUNT_TRUNCATED also enables deletion of truncations | ||
| 11272 | + of the values that serve as arguments to bit-field instructions. | ||
| 11273 | + If both types of instructions truncate the count (for shifts) and position (for bit-field | ||
| 11274 | + operations), or if no variable-position bit-field instructions exist, you should define | ||
| 11275 | + this macro. | ||
| 11276 | + However, on some machines, such as the 80386 and the 680x0, truncation only applies | ||
| 11277 | + to shift operations and not the (real or pretended) bit-field operations. Define SHIFT_ | ||
| 11278 | + COUNT_TRUNCATED to be zero on such machines. Instead, add patterns to the 'md' file | ||
| 11279 | + that include the implied truncation of the shift instructions. | ||
| 11280 | + You need not dene this macro if it would always have the value of zero. */ | ||
| 11281 | +#define SHIFT_COUNT_TRUNCATED 1 | ||
| 11282 | + | ||
| 11283 | +/* | ||
| 11284 | +A C expression which is nonzero if on this machine it is safe to | ||
| 11285 | +convert an integer of INPREC bits to one of OUTPREC | ||
| 11286 | +bits (where OUTPREC is smaller than INPREC) by merely | ||
| 11287 | +operating on it as if it had only OUTPREC bits. | ||
| 11288 | + | ||
| 11289 | +On many machines, this expression can be 1. | ||
| 11290 | + | ||
| 11291 | +When TRULY_NOOP_TRUNCATION returns 1 for a pair of sizes for | ||
| 11292 | +modes for which MODES_TIEABLE_P is 0, suboptimal code can result. | ||
| 11293 | +If this is the case, making TRULY_NOOP_TRUNCATION return 0 in | ||
| 11294 | +such cases may improve things. | ||
| 11295 | +*/ | ||
| 11296 | +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 | ||
| 11297 | + | ||
| 11298 | +/* | ||
| 11299 | +An alias for the machine mode for pointers. On most machines, define | ||
| 11300 | +this to be the integer mode corresponding to the width of a hardware | ||
| 11301 | +pointer; SImode on 32-bit machine or DImode on 64-bit machines. | ||
| 11302 | +On some machines you must define this to be one of the partial integer | ||
| 11303 | +modes, such as PSImode. | ||
| 11304 | + | ||
| 11305 | +The width of Pmode must be at least as large as the value of | ||
| 11306 | +POINTER_SIZE. If it is not equal, you must define the macro | ||
| 11307 | +POINTERS_EXTEND_UNSIGNED to specify how pointers are extended | ||
| 11308 | +to Pmode. | ||
| 11309 | +*/ | ||
| 11310 | +#define Pmode SImode | ||
| 11311 | + | ||
| 11312 | +/* | ||
| 11313 | +An alias for the machine mode used for memory references to functions | ||
| 11314 | +being called, in call RTL expressions. On most machines this | ||
| 11315 | +should be QImode. | ||
| 11316 | +*/ | ||
| 11317 | +#define FUNCTION_MODE SImode | ||
| 11318 | + | ||
| 11319 | + | ||
| 11320 | +#define REG_S_P(x) \ | ||
| 11321 | + (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (XEXP (x, 0)))) | ||
| 11322 | + | ||
| 11323 | + | ||
| 11324 | +/* If defined, modifies the length assigned to instruction INSN as a | ||
| 11325 | + function of the context in which it is used. LENGTH is an lvalue | ||
| 11326 | + that contains the initially computed length of the insn and should | ||
| 11327 | + be updated with the correct length of the insn. */ | ||
| 11328 | +#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ | ||
| 11329 | + ((LENGTH) = avr32_adjust_insn_length ((INSN), (LENGTH))) | ||
| 11330 | + | ||
| 11331 | + | ||
| 11332 | +#define CLZ_DEFINED_VALUE_AT_ZERO(mode, value) \ | ||
| 11333 | + (value = 32, (mode == SImode)) | ||
| 11334 | + | ||
| 11335 | +#define CTZ_DEFINED_VALUE_AT_ZERO(mode, value) \ | ||
| 11336 | + (value = 32, (mode == SImode)) | ||
| 11337 | + | ||
| 11338 | +#define UNITS_PER_SIMD_WORD UNITS_PER_WORD | ||
| 11339 | + | ||
| 11340 | +#define STORE_FLAG_VALUE 1 | ||
| 11341 | + | ||
| 11342 | +enum avr32_builtins | ||
| 11343 | +{ | ||
| 11344 | + AVR32_BUILTIN_MTSR, | ||
| 11345 | + AVR32_BUILTIN_MFSR, | ||
| 11346 | + AVR32_BUILTIN_MTDR, | ||
| 11347 | + AVR32_BUILTIN_MFDR, | ||
| 11348 | + AVR32_BUILTIN_CACHE, | ||
| 11349 | + AVR32_BUILTIN_SYNC, | ||
| 11350 | + AVR32_BUILTIN_TLBR, | ||
| 11351 | + AVR32_BUILTIN_TLBS, | ||
| 11352 | + AVR32_BUILTIN_TLBW, | ||
| 11353 | + AVR32_BUILTIN_BREAKPOINT, | ||
| 11354 | + AVR32_BUILTIN_XCHG, | ||
| 11355 | + AVR32_BUILTIN_LDXI, | ||
| 11356 | + AVR32_BUILTIN_BSWAP16, | ||
| 11357 | + AVR32_BUILTIN_BSWAP32, | ||
| 11358 | + AVR32_BUILTIN_COP, | ||
| 11359 | + AVR32_BUILTIN_MVCR_W, | ||
| 11360 | + AVR32_BUILTIN_MVRC_W, | ||
| 11361 | + AVR32_BUILTIN_MVCR_D, | ||
| 11362 | + AVR32_BUILTIN_MVRC_D, | ||
| 11363 | + AVR32_BUILTIN_MULSATHH_H, | ||
| 11364 | + AVR32_BUILTIN_MULSATHH_W, | ||
| 11365 | + AVR32_BUILTIN_MULSATRNDHH_H, | ||
| 11366 | + AVR32_BUILTIN_MULSATRNDWH_W, | ||
| 11367 | + AVR32_BUILTIN_MULSATWH_W, | ||
| 11368 | + AVR32_BUILTIN_MACSATHH_W, | ||
| 11369 | + AVR32_BUILTIN_SATADD_H, | ||
| 11370 | + AVR32_BUILTIN_SATSUB_H, | ||
| 11371 | + AVR32_BUILTIN_SATADD_W, | ||
| 11372 | + AVR32_BUILTIN_SATSUB_W, | ||
| 11373 | + AVR32_BUILTIN_MULWH_D, | ||
| 11374 | + AVR32_BUILTIN_MULNWH_D, | ||
| 11375 | + AVR32_BUILTIN_MACWH_D, | ||
| 11376 | + AVR32_BUILTIN_MACHH_D, | ||
| 11377 | + AVR32_BUILTIN_MUSFR, | ||
| 11378 | + AVR32_BUILTIN_MUSTR, | ||
| 11379 | + AVR32_BUILTIN_SATS, | ||
| 11380 | + AVR32_BUILTIN_SATU, | ||
| 11381 | + AVR32_BUILTIN_SATRNDS, | ||
| 11382 | + AVR32_BUILTIN_SATRNDU | ||
| 11383 | +}; | ||
| 11384 | + | ||
| 11385 | + | ||
| 11386 | +#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) \ | ||
| 11387 | + ((MODE == SFmode) || (MODE == DFmode)) | ||
| 11388 | + | ||
| 11389 | +#define RENAME_LIBRARY_SET ".set" | ||
| 11390 | + | ||
| 11391 | +/* Make ABI_NAME an alias for __GCC_NAME. */ | ||
| 11392 | +#define RENAME_LIBRARY(GCC_NAME, ABI_NAME) \ | ||
| 11393 | + __asm__ (".globl\t__avr32_" #ABI_NAME "\n" \ | ||
| 11394 | + ".set\t__avr32_" #ABI_NAME \ | ||
| 11395 | + ", __" #GCC_NAME "\n"); | ||
| 11396 | + | ||
| 11397 | +/* Give libgcc functions avr32 ABI name. */ | ||
| 11398 | +#ifdef L_muldi3 | ||
| 11399 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (muldi3, mul64) | ||
| 11400 | +#endif | ||
| 11401 | +#ifdef L_divdi3 | ||
| 11402 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (divdi3, sdiv64) | ||
| 11403 | +#endif | ||
| 11404 | +#ifdef L_udivdi3 | ||
| 11405 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (udivdi3, udiv64) | ||
| 11406 | +#endif | ||
| 11407 | +#ifdef L_moddi3 | ||
| 11408 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (moddi3, smod64) | ||
| 11409 | +#endif | ||
| 11410 | +#ifdef L_umoddi3 | ||
| 11411 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (umoddi3, umod64) | ||
| 11412 | +#endif | ||
| 11413 | +#ifdef L_ashldi3 | ||
| 11414 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (ashldi3, lsl64) | ||
| 11415 | +#endif | ||
| 11416 | +#ifdef L_lshrdi3 | ||
| 11417 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (lshrdi3, lsr64) | ||
| 11418 | +#endif | ||
| 11419 | +#ifdef L_ashrdi3 | ||
| 11420 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (ashrdi3, asr64) | ||
| 11421 | +#endif | ||
| 11422 | + | ||
| 11423 | +#ifdef L_fixsfdi | ||
| 11424 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixsfdi, f32_to_s64) | ||
| 11425 | +#endif | ||
| 11426 | +#ifdef L_fixunssfdi | ||
| 11427 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfdi, f32_to_u64) | ||
| 11428 | +#endif | ||
| 11429 | +#ifdef L_floatdidf | ||
| 11430 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdidf, s64_to_f64) | ||
| 11431 | +#endif | ||
| 11432 | +#ifdef L_floatdisf | ||
| 11433 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdisf, s64_to_f32) | ||
| 11434 | +#endif | ||
| 11435 | + | ||
| 11436 | +#ifdef L_addsub_sf | ||
| 11437 | +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (addsf3, f32_add); RENAME_LIBRARY (subsf3, f32_sub) | ||
| 11438 | +#endif | ||
| 11439 | + | ||
| 11440 | +#endif | ||
| 11441 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/avr32.md gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/avr32.md | ||
| 11442 | --- gcc-4.0.2/gcc/config/avr32/avr32.md 1970-01-01 01:00:00.000000000 +0100 | ||
| 11443 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/avr32.md 2006-11-09 15:04:35.000000000 +0100 | ||
| 11444 | @@ -0,0 +1,4694 @@ | ||
| 11445 | +;; AVR32 machine description file. | ||
| 11446 | +;; Copyright 2003-2006 Atmel Corporation. | ||
| 11447 | +;; | ||
| 11448 | +;; Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com> | ||
| 11449 | +;; | ||
| 11450 | +;; This file is part of GCC. | ||
| 11451 | +;; | ||
| 11452 | +;; This program is free software; you can redistribute it and/or modify | ||
| 11453 | +;; it under the terms of the GNU General Public License as published by | ||
| 11454 | +;; the Free Software Foundation; either version 2 of the License, or | ||
| 11455 | +;; (at your option) any later version. | ||
| 11456 | +;; | ||
| 11457 | +;; This program is distributed in the hope that it will be useful, | ||
| 11458 | +;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11459 | +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11460 | +;; GNU General Public License for more details. | ||
| 11461 | +;; | ||
| 11462 | +;; You should have received a copy of the GNU General Public License | ||
| 11463 | +;; along with this program; if not, write to the Free Software | ||
| 11464 | +;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 11465 | + | ||
| 11466 | +;; -*- Mode: Scheme -*- | ||
| 11467 | + | ||
| 11468 | +(define_attr "type" "alu,alu2,alu_sat,mulhh,mulwh,mulww_w,mulww_d,div,machh_w,macww_w,macww_d,branch,call,load,load_rm,store,load2,load4,store2,store4,fmul,fcmps,fcmpd,fcast,fmv,fmvcpu,fldd,fstd,flds,fsts,fstm" | ||
| 11469 | + (const_string "alu")) | ||
| 11470 | + | ||
| 11471 | + | ||
| 11472 | +(define_attr "cc" "none,set_vncz,set_ncz,set_cz,set_z,bld,compare,clobber,call_set,fpcompare,from_fpcc" | ||
| 11473 | + (const_string "none")) | ||
| 11474 | + | ||
| 11475 | + | ||
| 11476 | +(define_attr "pipeline" "ap,uc" | ||
| 11477 | + (const_string "ap")) | ||
| 11478 | + | ||
| 11479 | +(define_attr "length" "" | ||
| 11480 | + (const_int 4)) | ||
| 11481 | + | ||
| 11482 | + | ||
| 11483 | +;; Uses of UNSPEC in this file: | ||
| 11484 | +(define_constants | ||
| 11485 | + [(UNSPEC_PUSHM 0) | ||
| 11486 | + (UNSPEC_POPM 1) | ||
| 11487 | + (UNSPEC_UDIVMODSI4_INTERNAL 2) | ||
| 11488 | + (UNSPEC_DIVMODSI4_INTERNAL 3) | ||
| 11489 | + (UNSPEC_STM 4) | ||
| 11490 | + (UNSPEC_LDM 5) | ||
| 11491 | + (UNSPEC_MOVSICC 6) | ||
| 11492 | + (UNSPEC_ADDSICC 7) | ||
| 11493 | + (UNSPEC_COND_MI 8) | ||
| 11494 | + (UNSPEC_COND_PL 9) | ||
| 11495 | + (UNSPEC_PIC_SYM 10) | ||
| 11496 | + (UNSPEC_PIC_BASE 11) | ||
| 11497 | + (UNSPEC_STORE_MULTIPLE 12) | ||
| 11498 | + (UNSPEC_STMFP 13) | ||
| 11499 | + (UNSPEC_FPCC_TO_REG 14) | ||
| 11500 | + (UNSPEC_REG_TO_CC 15) | ||
| 11501 | + (UNSPEC_FORCE_MINIPOOL 16) | ||
| 11502 | + (UNSPEC_SATS 17) | ||
| 11503 | + (UNSPEC_SATU 18) | ||
| 11504 | + (UNSPEC_SATRNDS 19) | ||
| 11505 | + (UNSPEC_SATRNDU 20) | ||
| 11506 | + ]) | ||
| 11507 | + | ||
| 11508 | +(define_constants | ||
| 11509 | + [(VUNSPEC_EPILOGUE 0) | ||
| 11510 | + (VUNSPEC_CACHE 1) | ||
| 11511 | + (VUNSPEC_MTSR 2) | ||
| 11512 | + (VUNSPEC_MFSR 3) | ||
| 11513 | + (VUNSPEC_BLOCKAGE 4) | ||
| 11514 | + (VUNSPEC_SYNC 5) | ||
| 11515 | + (VUNSPEC_TLBR 6) | ||
| 11516 | + (VUNSPEC_TLBW 7) | ||
| 11517 | + (VUNSPEC_TLBS 8) | ||
| 11518 | + (VUNSPEC_BREAKPOINT 9) | ||
| 11519 | + (VUNSPEC_MTDR 10) | ||
| 11520 | + (VUNSPEC_MFDR 11) | ||
| 11521 | + (VUNSPEC_MVCR 12) | ||
| 11522 | + (VUNSPEC_MVRC 13) | ||
| 11523 | + (VUNSPEC_COP 14) | ||
| 11524 | + (VUNSPEC_ALIGN 15) | ||
| 11525 | + (VUNSPEC_POOL_START 16) | ||
| 11526 | + (VUNSPEC_POOL_END 17) | ||
| 11527 | + (VUNSPEC_POOL_4 18) | ||
| 11528 | + (VUNSPEC_POOL_8 19) | ||
| 11529 | + (VUNSPEC_MUSFR 20) | ||
| 11530 | + (VUNSPEC_MUSTR 21) | ||
| 11531 | + ]) | ||
| 11532 | + | ||
| 11533 | +(define_constants | ||
| 11534 | + [ | ||
| 11535 | + ;; R7 = 15-7 = 8 | ||
| 11536 | + (FP_REGNUM 8) | ||
| 11537 | + ;; Return Register = R12 = 15 - 12 = 3 | ||
| 11538 | + (RETVAL_REGNUM 3) | ||
| 11539 | + ;; SP = R13 = 15 - 13 = 2 | ||
| 11540 | + (SP_REGNUM 2) | ||
| 11541 | + ;; LR = R14 = 15 - 14 = 1 | ||
| 11542 | + (LR_REGNUM 1) | ||
| 11543 | + ;; PC = R15 = 15 - 15 = 0 | ||
| 11544 | + (PC_REGNUM 0) | ||
| 11545 | + ;; FPSR = GENERAL_REGS + 1 = 17 | ||
| 11546 | + (FPCC_REGNUM 17) | ||
| 11547 | + ]) | ||
| 11548 | + | ||
| 11549 | + | ||
| 11550 | + | ||
| 11551 | + | ||
| 11552 | +;;****************************************************************************** | ||
| 11553 | +;; Macros | ||
| 11554 | +;;****************************************************************************** | ||
| 11555 | + | ||
| 11556 | +;; Integer Modes for basic alu insns | ||
| 11557 | +(define_mode_macro INTM [SI HI QI]) | ||
| 11558 | +(define_mode_attr alu_cc_attr [(SI "set_vncz") (HI "clobber") (QI "clobber")]) | ||
| 11559 | + | ||
| 11560 | +;; Move word modes | ||
| 11561 | +(define_mode_macro MOVM [SI V2HI V4QI]) | ||
| 11562 | + | ||
| 11563 | +;; For mov/addcc insns | ||
| 11564 | +(define_mode_macro ADDCC [SI HI QI]) | ||
| 11565 | +(define_mode_macro MOVCC [SI HI QI]) | ||
| 11566 | +(define_mode_macro CMP [DI SI HI QI]) | ||
| 11567 | +(define_mode_attr cmp_constraint [(DI "r") (SI "rKs21") (HI "r") (QI "r")]) | ||
| 11568 | +(define_mode_attr cmp_predicate [(DI "register_operand") | ||
| 11569 | + (SI "register_immediate_operand") | ||
| 11570 | + (HI "register_operand") | ||
| 11571 | + (QI "register_operand")]) | ||
| 11572 | + | ||
| 11573 | +;; For all conditional insns | ||
| 11574 | +(define_code_macro any_cond [eq ne gt ge lt le gtu geu ltu leu]) | ||
| 11575 | +(define_code_attr cond [(eq "eq") (ne "ne") (gt "gt") (ge "ge") (lt "lt") (le "le") | ||
| 11576 | + (gtu "hi") (geu "hs") (ltu "lo") (leu "ls")]) | ||
| 11577 | +(define_code_attr invcond [(eq "ne") (ne "eq") (gt "le") (ge "lt") (lt "ge") (le "gt") | ||
| 11578 | + (gtu "ls") (geu "lo") (ltu "hs") (leu "hi")]) | ||
| 11579 | + | ||
| 11580 | +;; For logical operations | ||
| 11581 | +(define_code_macro logical [and ior xor]) | ||
| 11582 | +(define_code_attr logical_insn [(and "and") (ior "or") (xor "eor")]) | ||
| 11583 | + | ||
| 11584 | +;; Load the predicates | ||
| 11585 | +(include "predicates.md") | ||
| 11586 | + | ||
| 11587 | + | ||
| 11588 | +;;****************************************************************************** | ||
| 11589 | +;; Automaton pipeline description for avr32 | ||
| 11590 | +;;****************************************************************************** | ||
| 11591 | + | ||
| 11592 | +(define_automaton "avr32_ap") | ||
| 11593 | + | ||
| 11594 | + | ||
| 11595 | +(define_cpu_unit "is" "avr32_ap") | ||
| 11596 | +(define_cpu_unit "a1,m1,da" "avr32_ap") | ||
| 11597 | +(define_cpu_unit "a2,m2,d" "avr32_ap") | ||
| 11598 | + | ||
| 11599 | +;;Alu instructions | ||
| 11600 | +(define_insn_reservation "alu_op" 1 | ||
| 11601 | + (and (eq_attr "pipeline" "ap") | ||
| 11602 | + (eq_attr "type" "alu")) | ||
| 11603 | + "is,a1,a2") | ||
| 11604 | + | ||
| 11605 | +(define_insn_reservation "alu2_op" 2 | ||
| 11606 | + (and (eq_attr "pipeline" "ap") | ||
| 11607 | + (eq_attr "type" "alu2")) | ||
| 11608 | + "is,is+a1,a1+a2,a2") | ||
| 11609 | + | ||
| 11610 | +(define_insn_reservation "alu_sat_op" 2 | ||
| 11611 | + (and (eq_attr "pipeline" "ap") | ||
| 11612 | + (eq_attr "type" "alu_sat")) | ||
| 11613 | + "is,a1,a2") | ||
| 11614 | + | ||
| 11615 | + | ||
| 11616 | +;;Mul instructions | ||
| 11617 | +(define_insn_reservation "mulhh_op" 2 | ||
| 11618 | + (and (eq_attr "pipeline" "ap") | ||
| 11619 | + (eq_attr "type" "mulhh,mulwh")) | ||
| 11620 | + "is,m1,m2") | ||
| 11621 | + | ||
| 11622 | +(define_insn_reservation "mulww_w_op" 3 | ||
| 11623 | + (and (eq_attr "pipeline" "ap") | ||
| 11624 | + (eq_attr "type" "mulww_w")) | ||
| 11625 | + "is,m1,m1+m2,m2") | ||
| 11626 | + | ||
| 11627 | +(define_insn_reservation "mulww_d_op" 5 | ||
| 11628 | + (and (eq_attr "pipeline" "ap") | ||
| 11629 | + (eq_attr "type" "mulww_d")) | ||
| 11630 | + "is,m1,m1+m2,m1+m2,m2,m2") | ||
| 11631 | + | ||
| 11632 | +(define_insn_reservation "div_op" 33 | ||
| 11633 | + (and (eq_attr "pipeline" "ap") | ||
| 11634 | + (eq_attr "type" "div")) | ||
| 11635 | + "is,m1,m1*31 + m2*31,m2") | ||
| 11636 | + | ||
| 11637 | +(define_insn_reservation "machh_w_op" 3 | ||
| 11638 | + (and (eq_attr "pipeline" "ap") | ||
| 11639 | + (eq_attr "type" "machh_w")) | ||
| 11640 | + "is*2,m1,m2") | ||
| 11641 | + | ||
| 11642 | + | ||
| 11643 | +(define_insn_reservation "macww_w_op" 4 | ||
| 11644 | + (and (eq_attr "pipeline" "ap") | ||
| 11645 | + (eq_attr "type" "macww_w")) | ||
| 11646 | + "is*2,m1,m1,m2") | ||
| 11647 | + | ||
| 11648 | + | ||
| 11649 | +(define_insn_reservation "macww_d_op" 6 | ||
| 11650 | + (and (eq_attr "pipeline" "ap") | ||
| 11651 | + (eq_attr "type" "macww_d")) | ||
| 11652 | + "is*2,m1,m1+m2,m1+m2,m2") | ||
| 11653 | + | ||
| 11654 | +;;Bypasses for Mac instructions, because of accumulator cache. | ||
| 11655 | +;;Set latency as low as possible in order to let the compiler let | ||
| 11656 | +;;mul -> mac and mac -> mac combinations which use the same | ||
| 11657 | +;;accumulator cache be placed close together to avoid any | ||
| 11658 | +;;instructions which can ruin the accumulator cache come inbetween. | ||
| 11659 | +(define_bypass 4 "machh_w_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass") | ||
| 11660 | +(define_bypass 5 "macww_w_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass") | ||
| 11661 | +(define_bypass 7 "macww_d_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass") | ||
| 11662 | + | ||
| 11663 | +(define_bypass 3 "mulhh_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass") | ||
| 11664 | +(define_bypass 4 "mulww_w_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass") | ||
| 11665 | +(define_bypass 6 "mulww_d_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass") | ||
| 11666 | + | ||
| 11667 | + | ||
| 11668 | +;;Bypasses for all mul/mac instructions followed by an instruction | ||
| 11669 | +;;which reads the output AND writes the result to the same register. | ||
| 11670 | +;;This will generate an Write After Write hazard which gives an | ||
| 11671 | +;;extra cycle before the result is ready. | ||
| 11672 | +(define_bypass 0 "machh_w_op" "machh_w_op" "avr32_valid_macmac_bypass") | ||
| 11673 | +(define_bypass 0 "macww_w_op" "macww_w_op" "avr32_valid_macmac_bypass") | ||
| 11674 | +(define_bypass 0 "macww_d_op" "macww_d_op" "avr32_valid_macmac_bypass") | ||
| 11675 | + | ||
| 11676 | +(define_bypass 0 "mulhh_op" "machh_w_op" "avr32_valid_mulmac_bypass") | ||
| 11677 | +(define_bypass 0 "mulww_w_op" "macww_w_op" "avr32_valid_mulmac_bypass") | ||
| 11678 | +(define_bypass 0 "mulww_d_op" "macww_d_op" "avr32_valid_mulmac_bypass") | ||
| 11679 | + | ||
| 11680 | +;;Branch and call instructions | ||
| 11681 | +;;We assume that all branches and rcalls are predicted correctly :-) | ||
| 11682 | +;;while calls use a lot of cycles. | ||
| 11683 | +(define_insn_reservation "branch_op" 0 | ||
| 11684 | + (and (eq_attr "pipeline" "ap") | ||
| 11685 | + (eq_attr "type" "branch")) | ||
| 11686 | + "nothing") | ||
| 11687 | + | ||
| 11688 | +(define_insn_reservation "call_op" 10 | ||
| 11689 | + (and (eq_attr "pipeline" "ap") | ||
| 11690 | + (eq_attr "type" "call")) | ||
| 11691 | + "nothing") | ||
| 11692 | + | ||
| 11693 | + | ||
| 11694 | +;;Load store instructions | ||
| 11695 | +(define_insn_reservation "load_op" 2 | ||
| 11696 | + (and (eq_attr "pipeline" "ap") | ||
| 11697 | + (eq_attr "type" "load")) | ||
| 11698 | + "is,da,d") | ||
| 11699 | + | ||
| 11700 | +(define_insn_reservation "load_rm_op" 3 | ||
| 11701 | + (and (eq_attr "pipeline" "ap") | ||
| 11702 | + (eq_attr "type" "load_rm")) | ||
| 11703 | + "is,da,d") | ||
| 11704 | + | ||
| 11705 | + | ||
| 11706 | +(define_insn_reservation "store_op" 0 | ||
| 11707 | + (and (eq_attr "pipeline" "ap") | ||
| 11708 | + (eq_attr "type" "store")) | ||
| 11709 | + "is,da,d") | ||
| 11710 | + | ||
| 11711 | + | ||
| 11712 | +(define_insn_reservation "load_double_op" 3 | ||
| 11713 | + (and (eq_attr "pipeline" "ap") | ||
| 11714 | + (eq_attr "type" "load2")) | ||
| 11715 | + "is,da,da+d,d") | ||
| 11716 | + | ||
| 11717 | +(define_insn_reservation "load_quad_op" 4 | ||
| 11718 | + (and (eq_attr "pipeline" "ap") | ||
| 11719 | + (eq_attr "type" "load4")) | ||
| 11720 | + "is,da,da+d,da+d,d") | ||
| 11721 | + | ||
| 11722 | +(define_insn_reservation "store_double_op" 0 | ||
| 11723 | + (and (eq_attr "pipeline" "ap") | ||
| 11724 | + (eq_attr "type" "store2")) | ||
| 11725 | + "is,da,da+d,d") | ||
| 11726 | + | ||
| 11727 | + | ||
| 11728 | +(define_insn_reservation "store_quad_op" 0 | ||
| 11729 | + (and (eq_attr "pipeline" "ap") | ||
| 11730 | + (eq_attr "type" "store4")) | ||
| 11731 | + "is,da,da+d,da+d,d") | ||
| 11732 | + | ||
| 11733 | +;;For store the operand to write to memory is read in d and | ||
| 11734 | +;;the real latency between any instruction and a store is therefore | ||
| 11735 | +;;one less than for the instructions which reads the operands in the first | ||
| 11736 | +;;excecution stage | ||
| 11737 | +(define_bypass 2 "load_double_op" "store_double_op" "avr32_store_bypass") | ||
| 11738 | +(define_bypass 3 "load_quad_op" "store_quad_op" "avr32_store_bypass") | ||
| 11739 | +(define_bypass 1 "load_op" "store_op" "avr32_store_bypass") | ||
| 11740 | +(define_bypass 2 "load_rm_op" "store_op" "avr32_store_bypass") | ||
| 11741 | +(define_bypass 1 "alu_sat_op" "store_op" "avr32_store_bypass") | ||
| 11742 | +(define_bypass 1 "alu2_op" "store_op" "avr32_store_bypass") | ||
| 11743 | +(define_bypass 1 "mulhh_op" "store_op" "avr32_store_bypass") | ||
| 11744 | +(define_bypass 2 "mulww_w_op" "store_op" "avr32_store_bypass") | ||
| 11745 | +(define_bypass 4 "mulww_d_op" "store_op" "avr32_store_bypass" ) | ||
| 11746 | +(define_bypass 2 "machh_w_op" "store_op" "avr32_store_bypass") | ||
| 11747 | +(define_bypass 3 "macww_w_op" "store_op" "avr32_store_bypass") | ||
| 11748 | +(define_bypass 5 "macww_d_op" "store_op" "avr32_store_bypass") | ||
| 11749 | + | ||
| 11750 | + | ||
| 11751 | +; Bypass for load double operation. If only the first loaded word is needed | ||
| 11752 | +; then the latency is 2 | ||
| 11753 | +(define_bypass 2 "load_double_op" | ||
| 11754 | + "load_op,load_rm_op,alu_sat_op, alu2_op, alu_op, mulhh_op, mulww_w_op, | ||
| 11755 | + mulww_d_op, machh_w_op, macww_w_op, macww_d_op" | ||
| 11756 | + "avr32_valid_load_double_bypass") | ||
| 11757 | + | ||
| 11758 | +; Bypass for load quad operation. If only the first or second loaded word is needed | ||
| 11759 | +; we set the latency to 2 | ||
| 11760 | +(define_bypass 2 "load_quad_op" | ||
| 11761 | + "load_op,load_rm_op,alu_sat_op, alu2_op, alu_op, mulhh_op, mulww_w_op, | ||
| 11762 | + mulww_d_op, machh_w_op, macww_w_op, macww_d_op" | ||
| 11763 | + "avr32_valid_load_quad_bypass") | ||
| 11764 | + | ||
| 11765 | + | ||
| 11766 | +;;****************************************************************************** | ||
| 11767 | +;; End of Automaton pipeline description for avr32 | ||
| 11768 | +;;****************************************************************************** | ||
| 11769 | + | ||
| 11770 | + | ||
| 11771 | + | ||
| 11772 | +;;============================================================================= | ||
| 11773 | +;; move | ||
| 11774 | +;;----------------------------------------------------------------------------- | ||
| 11775 | + | ||
| 11776 | +;;== char - 8 bits ============================================================ | ||
| 11777 | +(define_expand "movqi" | ||
| 11778 | + [(set (match_operand:QI 0 "nonimmediate_operand" "") | ||
| 11779 | + (match_operand:QI 1 "general_operand" ""))] | ||
| 11780 | + "" | ||
| 11781 | + { | ||
| 11782 | + if ( !no_new_pseudos ){ | ||
| 11783 | + if (GET_CODE (operands[1]) == MEM && optimize){ | ||
| 11784 | + rtx reg = gen_reg_rtx (SImode); | ||
| 11785 | + | ||
| 11786 | + emit_insn (gen_zero_extendqisi2 (reg, operands[1])); | ||
| 11787 | + operands[1] = gen_lowpart (QImode, reg); | ||
| 11788 | + } | ||
| 11789 | + | ||
| 11790 | + /* One of the ops has to be in a register. */ | ||
| 11791 | + if (GET_CODE (operands[0]) == MEM) | ||
| 11792 | + operands[1] = force_reg (QImode, operands[1]); | ||
| 11793 | + } | ||
| 11794 | + | ||
| 11795 | + }) | ||
| 11796 | + | ||
| 11797 | +(define_insn "*movqi_internal" | ||
| 11798 | + [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r") | ||
| 11799 | + (match_operand:QI 1 "general_operand" "rKs08,m,r,i"))] | ||
| 11800 | + "" | ||
| 11801 | + "@ | ||
| 11802 | + mov\t%0, %1 | ||
| 11803 | + ld.ub\t%0, %1 | ||
| 11804 | + st.b\t%0, %1 | ||
| 11805 | + mov\t%0, %1" | ||
| 11806 | + [(set_attr "length" "2,4,4,4") | ||
| 11807 | + (set_attr "type" "alu,load_rm,store,alu")]) | ||
| 11808 | + | ||
| 11809 | + | ||
| 11810 | + | ||
| 11811 | +;;== short - 16 bits ========================================================== | ||
| 11812 | +(define_expand "movhi" | ||
| 11813 | + [(set (match_operand:HI 0 "nonimmediate_operand" "") | ||
| 11814 | + (match_operand:HI 1 "general_operand" ""))] | ||
| 11815 | + "" | ||
| 11816 | + { | ||
| 11817 | + if ( !no_new_pseudos ){ | ||
| 11818 | + if (GET_CODE (operands[1]) == MEM && optimize){ | ||
| 11819 | + rtx reg = gen_reg_rtx (SImode); | ||
| 11820 | + | ||
| 11821 | + emit_insn (gen_extendhisi2 (reg, operands[1])); | ||
| 11822 | + operands[1] = gen_lowpart (HImode, reg); | ||
| 11823 | + } | ||
| 11824 | + | ||
| 11825 | + /* One of the ops has to be in a register. */ | ||
| 11826 | + if (GET_CODE (operands[0]) == MEM) | ||
| 11827 | + operands[1] = force_reg (HImode, operands[1]); | ||
| 11828 | + } | ||
| 11829 | + | ||
| 11830 | + }) | ||
| 11831 | + | ||
| 11832 | +(define_insn "*movhi_internal" | ||
| 11833 | + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r") | ||
| 11834 | + (match_operand:HI 1 "general_operand" "rKs08,m,r,i"))] | ||
| 11835 | + "" | ||
| 11836 | + "@ | ||
| 11837 | + mov\t%0, %1 | ||
| 11838 | + ld.sh\t%0, %1 | ||
| 11839 | + st.h\t%0, %1 | ||
| 11840 | + mov\t%0, %1" | ||
| 11841 | + [(set_attr "length" "2,4,4,4") | ||
| 11842 | + (set_attr "type" "alu,load_rm,store,alu")]) | ||
| 11843 | + | ||
| 11844 | + | ||
| 11845 | +;;== int - 32 bits ============================================================ | ||
| 11846 | + | ||
| 11847 | +(define_expand "movmisalignsi" | ||
| 11848 | + [(set (match_operand:SI 0 "nonimmediate_operand" "") | ||
| 11849 | + (match_operand:SI 1 "nonimmediate_operand" ""))] | ||
| 11850 | + "TARGET_UNALIGNED_WORD" | ||
| 11851 | + { | ||
| 11852 | + } | ||
| 11853 | +) | ||
| 11854 | + | ||
| 11855 | +(define_expand "mov<mode>" | ||
| 11856 | + [(set (match_operand:MOVM 0 "nonimmediate_operand" "") | ||
| 11857 | + (match_operand:MOVM 1 "general_operand" ""))] | ||
| 11858 | + "" | ||
| 11859 | + { | ||
| 11860 | + | ||
| 11861 | + /* One of the ops has to be in a register. */ | ||
| 11862 | + if (GET_CODE (operands[0]) == MEM) | ||
| 11863 | + operands[1] = force_reg (<MODE>mode, operands[1]); | ||
| 11864 | + | ||
| 11865 | + | ||
| 11866 | + /* Check for out of range immediate constants as these may | ||
| 11867 | + occur during reloading, since it seems like reload does | ||
| 11868 | + not check if the immediate is legitimate. Don't know if | ||
| 11869 | + this is a bug? */ | ||
| 11870 | + if ( reload_in_progress | ||
| 11871 | + && GET_CODE(operands[1]) == CONST_INT | ||
| 11872 | + && !avr32_const_ok_for_constraint_p(INTVAL(operands[1]), 'K', "Ks21") ){ | ||
| 11873 | + operands[1] = force_const_mem(SImode, operands[1]); | ||
| 11874 | + } | ||
| 11875 | + | ||
| 11876 | + if ( (flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS) | ||
| 11877 | + && !avr32_legitimate_pic_operand_p(operands[1]) ) | ||
| 11878 | + operands[1] = legitimize_pic_address (operands[1], <MODE>mode, | ||
| 11879 | + (no_new_pseudos ? operands[0] : 0)); | ||
| 11880 | + else if ( flag_pic && avr32_address_operand(operands[1], GET_MODE(operands[1])) ) | ||
| 11881 | + /* If we have an address operand then this function uses the pic register. */ | ||
| 11882 | + current_function_uses_pic_offset_table = 1; | ||
| 11883 | + }) | ||
| 11884 | + | ||
| 11885 | + | ||
| 11886 | +(define_insn "mov<mode>_internal" | ||
| 11887 | + [(set (match_operand:MOVM 0 "nonimmediate_operand" "=r,r,r,m,r") | ||
| 11888 | + (match_operand:MOVM 1 "general_operand" "rKs08,Ks21,m,r,W"))] | ||
| 11889 | + "" | ||
| 11890 | + { | ||
| 11891 | + switch (which_alternative) { | ||
| 11892 | + case 0: | ||
| 11893 | + case 1: return "mov\t%0, %1"; | ||
| 11894 | + case 2: | ||
| 11895 | + if ( (REG_P(XEXP(operands[1], 0)) | ||
| 11896 | + && REGNO(XEXP(operands[1], 0)) == SP_REGNUM) | ||
| 11897 | + || (GET_CODE(XEXP(operands[1], 0)) == PLUS | ||
| 11898 | + && REGNO(XEXP(XEXP(operands[1], 0), 0)) == SP_REGNUM | ||
| 11899 | + && GET_CODE(XEXP(XEXP(operands[1], 0), 1)) == CONST_INT | ||
| 11900 | + && INTVAL(XEXP(XEXP(operands[1], 0), 1)) % 4 == 0 | ||
| 11901 | + && INTVAL(XEXP(XEXP(operands[1], 0), 1)) <= 0x1FC) ) | ||
| 11902 | + return "lddsp\t%0, %1"; | ||
| 11903 | + else if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1])) ) | ||
| 11904 | + return "lddpc\t%0, %1"; | ||
| 11905 | + else | ||
| 11906 | + return "ld.w\t%0, %1"; | ||
| 11907 | + case 3: | ||
| 11908 | + if ( (REG_P(XEXP(operands[0], 0)) | ||
| 11909 | + && REGNO(XEXP(operands[0], 0)) == SP_REGNUM) | ||
| 11910 | + || (GET_CODE(XEXP(operands[0], 0)) == PLUS | ||
| 11911 | + && REGNO(XEXP(XEXP(operands[0], 0), 0)) == SP_REGNUM | ||
| 11912 | + && GET_CODE(XEXP(XEXP(operands[0], 0), 1)) == CONST_INT | ||
| 11913 | + && INTVAL(XEXP(XEXP(operands[0], 0), 1)) % 4 == 0 | ||
| 11914 | + && INTVAL(XEXP(XEXP(operands[0], 0), 1)) <= 0x1FC) ) | ||
| 11915 | + return "stdsp\t%0, %1"; | ||
| 11916 | + else | ||
| 11917 | + return "st.w\t%0, %1"; | ||
| 11918 | + case 4: | ||
| 11919 | + if ( TARGET_HAS_ASM_ADDR_PSEUDOS ) | ||
| 11920 | + return "lda.w\t%0, %1"; | ||
| 11921 | + else | ||
| 11922 | + return "ld.w\t%0, r6[%1@got]"; | ||
| 11923 | + default: | ||
| 11924 | + abort(); | ||
| 11925 | + } | ||
| 11926 | + } | ||
| 11927 | + | ||
| 11928 | + [(set_attr "length" "2,4,4,4,8") | ||
| 11929 | + (set_attr "type" "alu,alu,load,store,load") | ||
| 11930 | + (set_attr "cc" "none,none,none,none,clobber")]) | ||
| 11931 | + | ||
| 11932 | + | ||
| 11933 | +;; These instructions are for loading constants which cannot be loaded | ||
| 11934 | +;; directly from the constant pool because the offset is too large | ||
| 11935 | +;; high and lo_sum are used even tough for our case it should be | ||
| 11936 | +;; low and high sum :-) | ||
| 11937 | +(define_insn "mov_symbol_lo" | ||
| 11938 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 11939 | + (high:SI (match_operand:SI 1 "immediate_operand" "i" )))] | ||
| 11940 | + "" | ||
| 11941 | + "mov\t%0, lo(%1)" | ||
| 11942 | + [(set_attr "type" "alu") | ||
| 11943 | + (set_attr "length" "4")] | ||
| 11944 | +) | ||
| 11945 | + | ||
| 11946 | +(define_insn "add_symbol_hi" | ||
| 11947 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 11948 | + (lo_sum:SI (match_dup 0) | ||
| 11949 | + (match_operand:SI 1 "immediate_operand" "i" )))] | ||
| 11950 | + "" | ||
| 11951 | + "orh\t%0, hi(%1)" | ||
| 11952 | + [(set_attr "type" "alu") | ||
| 11953 | + (set_attr "length" "4")] | ||
| 11954 | +) | ||
| 11955 | + | ||
| 11956 | + | ||
| 11957 | + | ||
| 11958 | +;; When generating pic, we need to load the symbol offset into a register. | ||
| 11959 | +;; So that the optimizer does not confuse this with a normal symbol load | ||
| 11960 | +;; we use an unspec. The offset will be loaded from a constant pool entry, | ||
| 11961 | +;; since that is the only type of relocation we can use. | ||
| 11962 | +(define_insn "pic_load_addr" | ||
| 11963 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 11964 | + (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYM))] | ||
| 11965 | + "flag_pic && CONSTANT_POOL_ADDRESS_P(XEXP(operands[1], 0))" | ||
| 11966 | + "lddpc\t%0, %1" | ||
| 11967 | + [(set_attr "type" "load") | ||
| 11968 | + (set_attr "length" "4")] | ||
| 11969 | +) | ||
| 11970 | + | ||
| 11971 | +(define_insn "pic_compute_got_from_pc" | ||
| 11972 | + [(set (match_operand:SI 0 "register_operand" "+r") | ||
| 11973 | + (unspec:SI [(minus:SI (pc) | ||
| 11974 | + (match_dup 0))] UNSPEC_PIC_BASE)) | ||
| 11975 | + (use (label_ref (match_operand 1 "" "")))] | ||
| 11976 | + "flag_pic" | ||
| 11977 | + { | ||
| 11978 | + (*targetm.asm_out.internal_label) (asm_out_file, "L", | ||
| 11979 | + CODE_LABEL_NUMBER (operands[1])); | ||
| 11980 | + return \"rsub\t%0, pc\"; | ||
| 11981 | + } | ||
| 11982 | + [(set_attr "cc" "clobber") | ||
| 11983 | + (set_attr "length" "2")] | ||
| 11984 | +) | ||
| 11985 | + | ||
| 11986 | +;;== long long int - 64 bits ================================================== | ||
| 11987 | +(define_expand "movdi" | ||
| 11988 | + [(set (match_operand:DI 0 "nonimmediate_operand" "") | ||
| 11989 | + (match_operand:DI 1 "general_operand" ""))] | ||
| 11990 | + "" | ||
| 11991 | + { | ||
| 11992 | + | ||
| 11993 | + /* One of the ops has to be in a register. */ | ||
| 11994 | + if (GET_CODE (operands[0]) != REG) | ||
| 11995 | + operands[1] = force_reg (DImode, operands[1]); | ||
| 11996 | + | ||
| 11997 | + }) | ||
| 11998 | + | ||
| 11999 | + | ||
| 12000 | +(define_insn_and_split "*movdi_internal" | ||
| 12001 | + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m") | ||
| 12002 | + (match_operand:DI 1 "general_operand" "r,Ks08,Ks21,G,m,r"))] | ||
| 12003 | + "" | ||
| 12004 | + { | ||
| 12005 | + switch (which_alternative ){ | ||
| 12006 | + case 1: | ||
| 12007 | + case 2: | ||
| 12008 | + if ( INTVAL(operands[1]) < 0 ) | ||
| 12009 | + return "mov\t%0, %1\;mov\t%m0, -1"; | ||
| 12010 | + else | ||
| 12011 | + return "mov\t%0, %1\;mov\t%m0, 0"; | ||
| 12012 | + case 0: | ||
| 12013 | + case 3: | ||
| 12014 | + return "mov\t%0, %1\;mov\t%m0, %m1"; | ||
| 12015 | + case 4: | ||
| 12016 | + if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1]))) | ||
| 12017 | + return "ld.d\t%0, pc[%1 - .]"; | ||
| 12018 | + else | ||
| 12019 | + return "ld.d\t%0, %1"; | ||
| 12020 | + case 5: | ||
| 12021 | + return "st.d\t%0, %1"; | ||
| 12022 | + default: | ||
| 12023 | + abort(); | ||
| 12024 | + } | ||
| 12025 | + } | ||
| 12026 | + "reload_completed && | ||
| 12027 | + (REG_P(operands[0]) && | ||
| 12028 | + (REG_P(operands[1]) || avr32_const_double_immediate(operands[1]) || | ||
| 12029 | + ((GET_CODE(operands[1]) == CONST_INT) && avr32_const_ok_for_constraint_p(INTVAL(operands[1]), 'K', \"Ks21\")) ))" | ||
| 12030 | + [(set (match_dup 0) (match_dup 1)) | ||
| 12031 | + (set (match_dup 2) (match_dup 3))] | ||
| 12032 | + { | ||
| 12033 | + operands[2] = gen_highpart (SImode, operands[0]); | ||
| 12034 | + operands[0] = gen_lowpart (SImode, operands[0]); | ||
| 12035 | + if ( REG_P(operands[1]) ){ | ||
| 12036 | + operands[3] = gen_highpart(SImode, operands[1]); | ||
| 12037 | + operands[1] = gen_lowpart(SImode, operands[1]); | ||
| 12038 | + } else if ( GET_CODE(operands[1]) == CONST_DOUBLE ){ | ||
| 12039 | + operands[3] = GEN_INT(CONST_DOUBLE_LOW(operands[1])); | ||
| 12040 | + operands[1] = GEN_INT(CONST_DOUBLE_HIGH(operands[1])); | ||
| 12041 | + } else if ( GET_CODE(operands[1]) == CONST_INT ){ | ||
| 12042 | + operands[3] = GEN_INT((INTVAL(operands[1]) < 0) ? -1 : 0); | ||
| 12043 | + operands[1] = operands[1]; | ||
| 12044 | + } else { | ||
| 12045 | + internal_error("Illegal operand[1] for movdi split!"); | ||
| 12046 | + } | ||
| 12047 | + } | ||
| 12048 | + | ||
| 12049 | + [(set_attr "length" "4,6,8,8,4,4") | ||
| 12050 | + (set_attr "type" "alu2,alu2,alu2,alu2,load2,store2")]) | ||
| 12051 | + | ||
| 12052 | + | ||
| 12053 | +;;== 128 bits ================================================== | ||
| 12054 | +(define_expand "movti" | ||
| 12055 | + [(set (match_operand:TI 0 "nonimmediate_operand" "") | ||
| 12056 | + (match_operand:TI 1 "general_operand" ""))] | ||
| 12057 | + "" | ||
| 12058 | + { | ||
| 12059 | + | ||
| 12060 | + /* One of the ops has to be in a register. */ | ||
| 12061 | + if (GET_CODE (operands[0]) != REG) | ||
| 12062 | + operands[1] = force_reg (TImode, operands[1]); | ||
| 12063 | + | ||
| 12064 | + /* We must fix any pre_dec for loads and post_inc stores */ | ||
| 12065 | + if ( GET_CODE (operands[0]) == MEM | ||
| 12066 | + && GET_CODE (XEXP(operands[0],0)) == POST_INC ){ | ||
| 12067 | + emit_move_insn(gen_rtx_MEM(TImode, XEXP(XEXP(operands[0],0),0)), operands[1]); | ||
| 12068 | + emit_insn(gen_addsi3(XEXP(XEXP(operands[0],0),0), XEXP(XEXP(operands[0],0),0), GEN_INT(GET_MODE_SIZE(TImode)))); | ||
| 12069 | + DONE; | ||
| 12070 | + } | ||
| 12071 | + | ||
| 12072 | + if ( GET_CODE (operands[1]) == MEM | ||
| 12073 | + && GET_CODE (XEXP(operands[1],0)) == PRE_DEC ){ | ||
| 12074 | + emit_insn(gen_addsi3(XEXP(XEXP(operands[1],0),0), XEXP(XEXP(operands[1],0),0), GEN_INT(-GET_MODE_SIZE(TImode)))); | ||
| 12075 | + emit_move_insn(operands[0], gen_rtx_MEM(TImode, XEXP(XEXP(operands[1],0),0))); | ||
| 12076 | + DONE; | ||
| 12077 | + } | ||
| 12078 | + | ||
| 12079 | + if (GET_CODE (operands[1]) == CONST_INT){ | ||
| 12080 | + unsigned int sign_extend = (INTVAL(operands[1]) < 0) ? 0xFFFFFFFF : 0; | ||
| 12081 | + emit_move_insn(gen_rtx_SUBREG(SImode, operands[0], 12), operands[1]); | ||
| 12082 | + emit_move_insn(gen_rtx_SUBREG(SImode, operands[0], 8), GEN_INT(sign_extend)); | ||
| 12083 | + emit_move_insn(gen_rtx_SUBREG(SImode, operands[0], 4), GEN_INT(sign_extend)); | ||
| 12084 | + emit_move_insn(gen_rtx_SUBREG(SImode, operands[0], 0), GEN_INT(sign_extend)); | ||
| 12085 | + DONE; | ||
| 12086 | + } | ||
| 12087 | + | ||
| 12088 | + if (GET_CODE (operands[0]) == REG | ||
| 12089 | + && GET_CODE (operands[1]) == REG){ | ||
| 12090 | + emit_move_insn(gen_rtx_SUBREG(SImode, operands[0], 12), gen_rtx_SUBREG(SImode, operands[1], 12)); | ||
| 12091 | + emit_move_insn(gen_rtx_SUBREG(SImode, operands[0], 8), gen_rtx_SUBREG(SImode, operands[1], 8)); | ||
| 12092 | + emit_move_insn(gen_rtx_SUBREG(SImode, operands[0], 4), gen_rtx_SUBREG(SImode, operands[1], 4)); | ||
| 12093 | + emit_move_insn(gen_rtx_SUBREG(SImode, operands[0], 0), gen_rtx_SUBREG(SImode, operands[1], 0)); | ||
| 12094 | + DONE; | ||
| 12095 | + } | ||
| 12096 | + }) | ||
| 12097 | + | ||
| 12098 | + | ||
| 12099 | +(define_insn "*movti_internal" | ||
| 12100 | + [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r, <RKu00,r") | ||
| 12101 | + (match_operand:TI 1 "loadti_operand" " r,RKu00>,r,m"))] | ||
| 12102 | + "" | ||
| 12103 | + "@ | ||
| 12104 | + mov\t%T0, %T1\;mov\t%U0, %U1\;mov\t%L0, %L1\;mov\t%B0, %B1 | ||
| 12105 | + ldm\t%p1, %0 | ||
| 12106 | + stm\t%p0, %1 | ||
| 12107 | + ldm\t%p1, %0" | ||
| 12108 | + [(set_attr "length" "8,4,4,4") | ||
| 12109 | + (set_attr "type" "alu,load4,store4,load4")]) | ||
| 12110 | + | ||
| 12111 | + | ||
| 12112 | +;;== float - 32 bits ========================================================== | ||
| 12113 | +(define_expand "movsf" | ||
| 12114 | + [(set (match_operand:SF 0 "nonimmediate_operand" "") | ||
| 12115 | + (match_operand:SF 1 "general_operand" ""))] | ||
| 12116 | + "" | ||
| 12117 | + { | ||
| 12118 | + | ||
| 12119 | + | ||
| 12120 | + /* One of the ops has to be in a register. */ | ||
| 12121 | + if (GET_CODE (operands[0]) != REG) | ||
| 12122 | + operands[1] = force_reg (SFmode, operands[1]); | ||
| 12123 | + | ||
| 12124 | + }) | ||
| 12125 | + | ||
| 12126 | +(define_insn "*movsf_internal" | ||
| 12127 | + [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,m") | ||
| 12128 | + (match_operand:SF 1 "general_operand" "r,G,m,r"))] | ||
| 12129 | + "TARGET_SOFT_FLOAT" | ||
| 12130 | + { | ||
| 12131 | + switch (which_alternative) { | ||
| 12132 | + case 0: | ||
| 12133 | + case 1: return "mov\t%0, %1"; | ||
| 12134 | + case 2: | ||
| 12135 | + if ( (REG_P(XEXP(operands[1], 0)) | ||
| 12136 | + && REGNO(XEXP(operands[1], 0)) == SP_REGNUM) | ||
| 12137 | + || (GET_CODE(XEXP(operands[1], 0)) == PLUS | ||
| 12138 | + && REGNO(XEXP(XEXP(operands[1], 0), 0)) == SP_REGNUM | ||
| 12139 | + && GET_CODE(XEXP(XEXP(operands[1], 0), 1)) == CONST_INT | ||
| 12140 | + && INTVAL(XEXP(XEXP(operands[1], 0), 1)) % 4 == 0 | ||
| 12141 | + && INTVAL(XEXP(XEXP(operands[1], 0), 1)) <= 0x1FC) ) | ||
| 12142 | + return "lddsp\t%0, %1"; | ||
| 12143 | + else if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1])) ) | ||
| 12144 | + return "lddpc\t%0, %1"; | ||
| 12145 | + else | ||
| 12146 | + return "ld.w\t%0, %1"; | ||
| 12147 | + case 3: | ||
| 12148 | + if ( (REG_P(XEXP(operands[0], 0)) | ||
| 12149 | + && REGNO(XEXP(operands[0], 0)) == SP_REGNUM) | ||
| 12150 | + || (GET_CODE(XEXP(operands[0], 0)) == PLUS | ||
| 12151 | + && REGNO(XEXP(XEXP(operands[0], 0), 0)) == SP_REGNUM | ||
| 12152 | + && GET_CODE(XEXP(XEXP(operands[0], 0), 1)) == CONST_INT | ||
| 12153 | + && INTVAL(XEXP(XEXP(operands[0], 0), 1)) % 4 == 0 | ||
| 12154 | + && INTVAL(XEXP(XEXP(operands[0], 0), 1)) <= 0x1FC) ) | ||
| 12155 | + return "stdsp\t%0, %1"; | ||
| 12156 | + else | ||
| 12157 | + return "st.w\t%0, %1"; | ||
| 12158 | + default: | ||
| 12159 | + abort(); | ||
| 12160 | + } | ||
| 12161 | + } | ||
| 12162 | + | ||
| 12163 | + [(set_attr "length" "2,4,4,4") | ||
| 12164 | + (set_attr "type" "alu,alu,load,store")]) | ||
| 12165 | + | ||
| 12166 | + | ||
| 12167 | + | ||
| 12168 | +;;== double - 64 bits ========================================================= | ||
| 12169 | +(define_expand "movdf" | ||
| 12170 | + [(set (match_operand:DF 0 "nonimmediate_operand" "") | ||
| 12171 | + (match_operand:DF 1 "general_operand" ""))] | ||
| 12172 | + "" | ||
| 12173 | + { | ||
| 12174 | + /* One of the ops has to be in a register. */ | ||
| 12175 | + if (GET_CODE (operands[0]) != REG){ | ||
| 12176 | + operands[1] = force_reg (DFmode, operands[1]); | ||
| 12177 | + } | ||
| 12178 | + }) | ||
| 12179 | + | ||
| 12180 | + | ||
| 12181 | +(define_insn_and_split "*movdf_internal" | ||
| 12182 | + [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r,m") | ||
| 12183 | + (match_operand:DF 1 "general_operand" "r,G,m,r"))] | ||
| 12184 | + "TARGET_SOFT_FLOAT" | ||
| 12185 | + { | ||
| 12186 | + switch (which_alternative ){ | ||
| 12187 | + case 0: | ||
| 12188 | + case 1: | ||
| 12189 | + return "mov\t%0, %1\;mov\t%m0, %m1"; | ||
| 12190 | + case 2: | ||
| 12191 | + if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1]))) | ||
| 12192 | + return "ld.d\t%0, pc[%1 - .]"; | ||
| 12193 | + else | ||
| 12194 | + return "ld.d\t%0, %1"; | ||
| 12195 | + case 3: | ||
| 12196 | + return "st.d\t%0, %1"; | ||
| 12197 | + default: | ||
| 12198 | + abort(); | ||
| 12199 | + } | ||
| 12200 | + } | ||
| 12201 | + "TARGET_SOFT_FLOAT | ||
| 12202 | + && reload_completed | ||
| 12203 | + && (REG_P(operands[0]) && REG_P(operands[1]))" | ||
| 12204 | + [(set (match_dup 0) (match_dup 1)) | ||
| 12205 | + (set (match_dup 2) (match_dup 3))] | ||
| 12206 | + " | ||
| 12207 | + { | ||
| 12208 | + operands[2] = gen_highpart (SImode, operands[0]); | ||
| 12209 | + operands[0] = gen_lowpart (SImode, operands[0]); | ||
| 12210 | + operands[3] = gen_highpart(SImode, operands[1]); | ||
| 12211 | + operands[1] = gen_lowpart(SImode, operands[1]); | ||
| 12212 | + } | ||
| 12213 | + " | ||
| 12214 | + | ||
| 12215 | + [(set_attr "length" "4,8,4,4") | ||
| 12216 | + (set_attr "type" "alu2,alu2,load2,store2")]) | ||
| 12217 | + | ||
| 12218 | + | ||
| 12219 | + | ||
| 12220 | + | ||
| 12221 | +;;============================================================================= | ||
| 12222 | +;; Move chunks of memory | ||
| 12223 | +;;============================================================================= | ||
| 12224 | + | ||
| 12225 | +(define_expand "movmemsi" | ||
| 12226 | + [(match_operand:BLK 0 "general_operand" "") | ||
| 12227 | + (match_operand:BLK 1 "general_operand" "") | ||
| 12228 | + (match_operand:SI 2 "const_int_operand" "") | ||
| 12229 | + (match_operand:SI 3 "const_int_operand" "")] | ||
| 12230 | + "" | ||
| 12231 | + " | ||
| 12232 | + if (avr32_gen_movmemsi (operands)) | ||
| 12233 | + DONE; | ||
| 12234 | + FAIL; | ||
| 12235 | + " | ||
| 12236 | + ) | ||
| 12237 | + | ||
| 12238 | + | ||
| 12239 | + | ||
| 12240 | + | ||
| 12241 | +;;============================================================================= | ||
| 12242 | +;; Bit field instructions | ||
| 12243 | +;;----------------------------------------------------------------------------- | ||
| 12244 | +;; Instructions to insert or extract bit-fields | ||
| 12245 | +;;============================================================================= | ||
| 12246 | + | ||
| 12247 | +(define_insn "insv" | ||
| 12248 | + [ (set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") | ||
| 12249 | + (match_operand:SI 1 "immediate_operand" "Ku05") | ||
| 12250 | + (match_operand:SI 2 "immediate_operand" "Ku05")) | ||
| 12251 | + (match_operand 3 "register_operand" "r"))] | ||
| 12252 | + "" | ||
| 12253 | + "bfins\t%0, %3, %2, %1" | ||
| 12254 | + [(set_attr "type" "alu") | ||
| 12255 | + (set_attr "length" "4") | ||
| 12256 | + (set_attr "cc" "set_ncz")]) | ||
| 12257 | + | ||
| 12258 | + | ||
| 12259 | + | ||
| 12260 | + | ||
| 12261 | +(define_insn "extv" | ||
| 12262 | + [ (set (match_operand:SI 0 "register_operand" "=r") | ||
| 12263 | + (sign_extract:SI (match_operand:SI 1 "register_operand" "r") | ||
| 12264 | + (match_operand:SI 2 "immediate_operand" "Ku05") | ||
| 12265 | + (match_operand:SI 3 "immediate_operand" "Ku05")))] | ||
| 12266 | + "" | ||
| 12267 | + "bfexts\t%0, %1, %3, %2" | ||
| 12268 | + [(set_attr "type" "alu") | ||
| 12269 | + (set_attr "length" "4") | ||
| 12270 | + (set_attr "cc" "set_ncz")]) | ||
| 12271 | + | ||
| 12272 | + | ||
| 12273 | +(define_insn "extzv" | ||
| 12274 | + [ (set (match_operand:SI 0 "register_operand" "=r") | ||
| 12275 | + (zero_extract:SI (match_operand:SI 1 "register_operand" "r") | ||
| 12276 | + (match_operand:SI 2 "immediate_operand" "Ku05") | ||
| 12277 | + (match_operand:SI 3 "immediate_operand" "Ku05")))] | ||
| 12278 | + "" | ||
| 12279 | + "bfextu\t%0, %1, %3, %2" | ||
| 12280 | + [(set_attr "type" "alu") | ||
| 12281 | + (set_attr "length" "4") | ||
| 12282 | + (set_attr "cc" "set_ncz")]) | ||
| 12283 | + | ||
| 12284 | + | ||
| 12285 | + | ||
| 12286 | +;;============================================================================= | ||
| 12287 | +;; Some peepholes for avoiding unnecessary cast instructions | ||
| 12288 | +;; followed by bfins. | ||
| 12289 | +;;----------------------------------------------------------------------------- | ||
| 12290 | + | ||
| 12291 | +(define_peephole2 | ||
| 12292 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 12293 | + (zero_extend:SI (match_operand:QI 1 "register_operand" ""))) | ||
| 12294 | + (set (zero_extract:SI (match_operand 2 "register_operand" "") | ||
| 12295 | + (match_operand:SI 3 "immediate_operand" "") | ||
| 12296 | + (match_operand:SI 4 "immediate_operand" "")) | ||
| 12297 | + (match_dup 0))] | ||
| 12298 | + "((peep2_reg_dead_p(2, operands[0]) && | ||
| 12299 | + (INTVAL(operands[3]) <= 8)))" | ||
| 12300 | + [(set (zero_extract:SI (match_dup 2) | ||
| 12301 | + (match_dup 3) | ||
| 12302 | + (match_dup 4)) | ||
| 12303 | + (match_dup 1))] | ||
| 12304 | + ) | ||
| 12305 | + | ||
| 12306 | +(define_peephole2 | ||
| 12307 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 12308 | + (zero_extend:SI (match_operand:HI 1 "register_operand" ""))) | ||
| 12309 | + (set (zero_extract:SI (match_operand 2 "register_operand" "") | ||
| 12310 | + (match_operand:SI 3 "immediate_operand" "") | ||
| 12311 | + (match_operand:SI 4 "immediate_operand" "")) | ||
| 12312 | + (match_dup 0))] | ||
| 12313 | + "((peep2_reg_dead_p(2, operands[0]) && | ||
| 12314 | + (INTVAL(operands[3]) <= 16)))" | ||
| 12315 | + [(set (zero_extract:SI (match_dup 2) | ||
| 12316 | + (match_dup 3) | ||
| 12317 | + (match_dup 4)) | ||
| 12318 | + (match_dup 1))] | ||
| 12319 | + ) | ||
| 12320 | + | ||
| 12321 | +;;============================================================================= | ||
| 12322 | +;; push bytes | ||
| 12323 | +;;----------------------------------------------------------------------------- | ||
| 12324 | +;; Implements the push instruction | ||
| 12325 | +;;============================================================================= | ||
| 12326 | +(define_insn "pushm" | ||
| 12327 | + [(set (mem:BLK (pre_dec:BLK (reg:SI SP_REGNUM))) | ||
| 12328 | + (unspec:BLK [(match_operand 0 "const_int_operand" "")] | ||
| 12329 | + UNSPEC_PUSHM))] | ||
| 12330 | + "" | ||
| 12331 | + { | ||
| 12332 | + if (INTVAL(operands[0])) { | ||
| 12333 | + return "pushm\t%r0"; | ||
| 12334 | + } else { | ||
| 12335 | + return ""; | ||
| 12336 | + } | ||
| 12337 | + } | ||
| 12338 | + [(set_attr "type" "store") | ||
| 12339 | + (set_attr "length" "2") | ||
| 12340 | + (set_attr "cc" "none")]) | ||
| 12341 | + | ||
| 12342 | +(define_insn "stm" | ||
| 12343 | + [(unspec [(match_operand 0 "register_operand" "r") | ||
| 12344 | + (match_operand 1 "const_int_operand" "") | ||
| 12345 | + (match_operand 2 "const_int_operand" "")] | ||
| 12346 | + UNSPEC_STM)] | ||
| 12347 | + "" | ||
| 12348 | + { | ||
| 12349 | + if (INTVAL(operands[1])) { | ||
| 12350 | + if (INTVAL(operands[2]) != 0) | ||
| 12351 | + return "stm\t--%0, %s1"; | ||
| 12352 | + else | ||
| 12353 | + return "stm\t%0, %s1"; | ||
| 12354 | + } else { | ||
| 12355 | + return ""; | ||
| 12356 | + } | ||
| 12357 | + } | ||
| 12358 | + [(set_attr "type" "store") | ||
| 12359 | + (set_attr "length" "4") | ||
| 12360 | + (set_attr "cc" "none")]) | ||
| 12361 | + | ||
| 12362 | + | ||
| 12363 | + | ||
| 12364 | +(define_insn "popm" | ||
| 12365 | + [(unspec [(match_operand 0 "const_int_operand" "")] | ||
| 12366 | + UNSPEC_POPM)] | ||
| 12367 | + "" | ||
| 12368 | + { | ||
| 12369 | + if (INTVAL(operands[0])) { | ||
| 12370 | + return "popm %r0"; | ||
| 12371 | + } else { | ||
| 12372 | + return ""; | ||
| 12373 | + } | ||
| 12374 | + } | ||
| 12375 | + [(set_attr "type" "load") | ||
| 12376 | + (set_attr "length" "2")]) | ||
| 12377 | + | ||
| 12378 | + | ||
| 12379 | + | ||
| 12380 | +;;============================================================================= | ||
| 12381 | +;; add | ||
| 12382 | +;;----------------------------------------------------------------------------- | ||
| 12383 | +;; Adds reg1 with reg2 and puts the result in reg0. | ||
| 12384 | +;;============================================================================= | ||
| 12385 | +(define_insn "add<mode>3" | ||
| 12386 | + [(set (match_operand:INTM 0 "register_operand" "=r,r,r,r,r") | ||
| 12387 | + (plus:INTM (match_operand:INTM 1 "register_operand" "%0,r,0,r,0") | ||
| 12388 | + (match_operand:INTM 2 "avr32_add_operand" "r,r,Is08,Is16,Is21")))] | ||
| 12389 | + "" | ||
| 12390 | + "@ | ||
| 12391 | + add %0, %2 | ||
| 12392 | + add %0, %1, %2 | ||
| 12393 | + sub %0, %n2 | ||
| 12394 | + sub %0, %1, %n2 | ||
| 12395 | + sub %0, %n2" | ||
| 12396 | + | ||
| 12397 | + [(set_attr "length" "2,4,2,4,4") | ||
| 12398 | + (set_attr "cc" "<INTM:alu_cc_attr>")]) | ||
| 12399 | + | ||
| 12400 | +(define_insn "*addsi3_lsl" | ||
| 12401 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 12402 | + (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") | ||
| 12403 | + (match_operand:SI 3 "avr32_add_shift_immediate_operand" "Ku02")) | ||
| 12404 | + (match_operand:SI 2 "register_operand" "r")))] | ||
| 12405 | + "" | ||
| 12406 | + "add %0, %2, %1 << %3" | ||
| 12407 | + [(set_attr "length" "4") | ||
| 12408 | + (set_attr "cc" "set_vncz")]) | ||
| 12409 | + | ||
| 12410 | + | ||
| 12411 | +(define_insn "*addsi3_mul" | ||
| 12412 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 12413 | + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") | ||
| 12414 | + (match_operand:SI 3 "immediate_operand" "Ku04" )) | ||
| 12415 | + (match_operand:SI 2 "register_operand" "r")))] | ||
| 12416 | + "(INTVAL(operands[3]) == 0) || (INTVAL(operands[3]) == 2) || | ||
| 12417 | + (INTVAL(operands[3]) == 4) || (INTVAL(operands[3]) == 8)" | ||
| 12418 | + "add %0, %2, %1 << %p3" | ||
| 12419 | + [(set_attr "length" "4") | ||
| 12420 | + (set_attr "cc" "set_vncz")]) | ||
| 12421 | + | ||
| 12422 | + | ||
| 12423 | +(define_peephole2 | ||
| 12424 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 12425 | + (ashift:SI (match_operand:SI 1 "register_operand" "") | ||
| 12426 | + (match_operand:SI 2 "immediate_operand" ""))) | ||
| 12427 | + (set (match_operand:SI 3 "register_operand" "") | ||
| 12428 | + (plus:SI (match_dup 0) | ||
| 12429 | + (match_operand:SI 4 "register_operand" "")))] | ||
| 12430 | + "(peep2_reg_dead_p(2, operands[0]) && | ||
| 12431 | + (INTVAL(operands[2]) < 4 && INTVAL(operands[2]) > 0))" | ||
| 12432 | + [(set (match_dup 3) | ||
| 12433 | + (plus:SI (ashift:SI (match_dup 1) | ||
| 12434 | + (match_dup 2)) | ||
| 12435 | + (match_dup 4)))] | ||
| 12436 | + ) | ||
| 12437 | + | ||
| 12438 | +(define_peephole2 | ||
| 12439 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 12440 | + (ashift:SI (match_operand:SI 1 "register_operand" "") | ||
| 12441 | + (match_operand:SI 2 "immediate_operand" ""))) | ||
| 12442 | + (set (match_operand:SI 3 "register_operand" "") | ||
| 12443 | + (plus:SI (match_operand:SI 4 "register_operand" "") | ||
| 12444 | + (match_dup 0)))] | ||
| 12445 | + "(peep2_reg_dead_p(2, operands[0]) && | ||
| 12446 | + (INTVAL(operands[2]) < 4 && INTVAL(operands[2]) > 0))" | ||
| 12447 | + [(set (match_dup 3) | ||
| 12448 | + (plus:SI (ashift:SI (match_dup 1) | ||
| 12449 | + (match_dup 2)) | ||
| 12450 | + (match_dup 4)))] | ||
| 12451 | + ) | ||
| 12452 | + | ||
| 12453 | +(define_insn "adddi3" | ||
| 12454 | + [(set (match_operand:DI 0 "register_operand" "=r,r") | ||
| 12455 | + (plus:DI (match_operand:DI 1 "register_operand" "%r,0") | ||
| 12456 | + (match_operand:DI 2 "register_operand" "r,r")))] | ||
| 12457 | + "" | ||
| 12458 | + "@ | ||
| 12459 | + add %0, %1, %2\;adc %m0, %m1, %m2 | ||
| 12460 | + add %0, %2\;adc %m0, %m0, %m2" | ||
| 12461 | + [(set_attr "length" "8,6") | ||
| 12462 | + (set_attr "type" "alu2") | ||
| 12463 | + (set_attr "cc" "set_vncz")]) | ||
| 12464 | + | ||
| 12465 | + | ||
| 12466 | + | ||
| 12467 | +;;============================================================================= | ||
| 12468 | +;; subtract | ||
| 12469 | +;;----------------------------------------------------------------------------- | ||
| 12470 | +;; Subtract reg2 or immediate value from reg0 and puts the result in reg0. | ||
| 12471 | +;;============================================================================= | ||
| 12472 | + | ||
| 12473 | +(define_peephole2 | ||
| 12474 | + [(set (match_operand:QI 0 "register_operand" "") | ||
| 12475 | + (minus:QI (match_operand:QI 1 "general_operand" "") | ||
| 12476 | + (match_operand:QI 2 "general_operand" ""))) | ||
| 12477 | + (set (match_operand:QI 3 "register_operand" "") | ||
| 12478 | + (match_dup 0))] | ||
| 12479 | + "peep2_reg_dead_p(2, operands[0])" | ||
| 12480 | + [(set (match_dup 3) | ||
| 12481 | + (minus:QI (match_dup 1) (match_dup 2)))] | ||
| 12482 | + ) | ||
| 12483 | + | ||
| 12484 | +(define_peephole | ||
| 12485 | + [(set (match_operand:QI 0 "register_operand" "") | ||
| 12486 | + (minus:QI (match_operand:QI 1 "immediate_operand" "Ks08") | ||
| 12487 | + (match_operand:QI 2 "register_operand" "r"))) | ||
| 12488 | + (set (match_operand:QI 3 "register_operand" "r") | ||
| 12489 | + (match_dup 0))] | ||
| 12490 | + "dead_or_set_p(insn, operands[0])" | ||
| 12491 | + "rsub %3, %2, %1" | ||
| 12492 | + [(set_attr "length" "4") | ||
| 12493 | + (set_attr "cc" "clobber")] | ||
| 12494 | + ) | ||
| 12495 | + | ||
| 12496 | + | ||
| 12497 | + | ||
| 12498 | +(define_insn "sub<mode>3" | ||
| 12499 | + [(set (match_operand:INTM 0 "general_operand" "=r,r,r,r,r,r,r") | ||
| 12500 | + (minus:INTM (match_operand:INTM 1 "nonmemory_operand" "0,r,0,r,0,r,Ks08") | ||
| 12501 | + (match_operand:INTM 2 "nonmemory_operand" "r,r,Ks08,Ks16,Ks21,0,r")))] | ||
| 12502 | + "" | ||
| 12503 | + "@ | ||
| 12504 | + sub %0, %2 | ||
| 12505 | + sub %0, %1, %2 | ||
| 12506 | + sub %0, %2 | ||
| 12507 | + sub %0, %1, %2 | ||
| 12508 | + sub %0, %2 | ||
| 12509 | + rsub %0, %1 | ||
| 12510 | + rsub %0, %2, %1" | ||
| 12511 | + [(set_attr "length" "2,4,2,4,4,2,4") | ||
| 12512 | + (set_attr "cc" "<INTM:alu_cc_attr>")]) | ||
| 12513 | + | ||
| 12514 | +(define_insn "*sub<mode>3_mul" | ||
| 12515 | + [(set (match_operand:INTM 0 "register_operand" "=r,r,r") | ||
| 12516 | + (minus:INTM (match_operand:INTM 1 "register_operand" "r,0,r") | ||
| 12517 | + (mult:INTM (match_operand:INTM 2 "register_operand" "r,r,0") | ||
| 12518 | + (match_operand:SI 3 "immediate_operand" "Ku04,Ku04,Ku04" ))))] | ||
| 12519 | + "(INTVAL(operands[3]) == 0) || (INTVAL(operands[3]) == 2) || | ||
| 12520 | + (INTVAL(operands[3]) == 4) || (INTVAL(operands[3]) == 8)" | ||
| 12521 | + "@ | ||
| 12522 | + sub %0, %1, %2 << %p3 | ||
| 12523 | + sub %0, %0, %2 << %p3 | ||
| 12524 | + sub %0, %1, %0 << %p3" | ||
| 12525 | + [(set_attr "length" "4,4,4") | ||
| 12526 | + (set_attr "cc" "<INTM:alu_cc_attr>")]) | ||
| 12527 | + | ||
| 12528 | +(define_insn "*sub<mode>3_lsl" | ||
| 12529 | + [(set (match_operand:INTM 0 "register_operand" "=r") | ||
| 12530 | + (minus:INTM (ashift:INTM (match_operand:INTM 1 "register_operand" "r") | ||
| 12531 | + (match_operand:SI 3 "avr32_add_shift_immediate_operand" "Ku02")) | ||
| 12532 | + (match_operand:INTM 2 "register_operand" "r")))] | ||
| 12533 | + "" | ||
| 12534 | + "sub %0, %2, %1 << %3" | ||
| 12535 | + [(set_attr "length" "4") | ||
| 12536 | + (set_attr "cc" "<INTM:alu_cc_attr>")]) | ||
| 12537 | + | ||
| 12538 | + | ||
| 12539 | +(define_insn "subdi3" | ||
| 12540 | + [(set (match_operand:DI 0 "register_operand" "=r,r") | ||
| 12541 | + (minus:DI (match_operand:DI 1 "register_operand" "%r,0") | ||
| 12542 | + (match_operand:DI 2 "register_operand" "r,r")))] | ||
| 12543 | + "" | ||
| 12544 | + "@ | ||
| 12545 | + sub %0, %1, %2\;sbc %m0, %m1, %m2 | ||
| 12546 | + sub %0, %2\;sbc %m0, %m0, %m2" | ||
| 12547 | + [(set_attr "length" "8,6") | ||
| 12548 | + (set_attr "type" "alu2") | ||
| 12549 | + (set_attr "cc" "set_vncz")]) | ||
| 12550 | + | ||
| 12551 | + | ||
| 12552 | + | ||
| 12553 | +;;============================================================================= | ||
| 12554 | +;; multiply | ||
| 12555 | +;;----------------------------------------------------------------------------- | ||
| 12556 | +;; Multiply op1 and op2 and put the value in op0. | ||
| 12557 | +;;============================================================================= | ||
| 12558 | + | ||
| 12559 | + | ||
| 12560 | +(define_insn "mulqi3" | ||
| 12561 | + [(set (match_operand:QI 0 "register_operand" "=r,r,r") | ||
| 12562 | + (mult:QI (match_operand:QI 1 "register_operand" "%0,r,r") | ||
| 12563 | + (match_operand:QI 2 "avr32_mul_operand" "r,r,Ks08")))] | ||
| 12564 | + "" | ||
| 12565 | + { | ||
| 12566 | + switch (which_alternative){ | ||
| 12567 | + case 0: | ||
| 12568 | + return "mul %0, %2"; | ||
| 12569 | + case 1: | ||
| 12570 | + return "mul %0, %1, %2"; | ||
| 12571 | + case 2: | ||
| 12572 | + return "mul %0, %1, %2"; | ||
| 12573 | + default: | ||
| 12574 | + abort(); | ||
| 12575 | + } | ||
| 12576 | + } | ||
| 12577 | + [(set_attr "type" "mulww_w,mulww_w,mulwh") | ||
| 12578 | + (set_attr "length" "2,4,4") | ||
| 12579 | + (set_attr "cc" "none")]) | ||
| 12580 | + | ||
| 12581 | +(define_insn "mulsi3" | ||
| 12582 | + [(set (match_operand:SI 0 "register_operand" "=r,r,r") | ||
| 12583 | + (mult:SI (match_operand:SI 1 "register_operand" "%0,r,r") | ||
| 12584 | + (match_operand:SI 2 "avr32_mul_operand" "r,r,Ks08")))] | ||
| 12585 | + "" | ||
| 12586 | + { | ||
| 12587 | + switch (which_alternative){ | ||
| 12588 | + case 0: | ||
| 12589 | + return "mul %0, %2"; | ||
| 12590 | + case 1: | ||
| 12591 | + return "mul %0, %1, %2"; | ||
| 12592 | + case 2: | ||
| 12593 | + return "mul %0, %1, %2"; | ||
| 12594 | + default: | ||
| 12595 | + abort(); | ||
| 12596 | + } | ||
| 12597 | + } | ||
| 12598 | + [(set_attr "type" "mulww_w,mulww_w,mulwh") | ||
| 12599 | + (set_attr "length" "2,4,4") | ||
| 12600 | + (set_attr "cc" "none")]) | ||
| 12601 | + | ||
| 12602 | + | ||
| 12603 | +(define_insn "mulhisi3" | ||
| 12604 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 12605 | + (mult:SI | ||
| 12606 | + (sign_extend:SI (match_operand:HI 1 "register_operand" "%r")) | ||
| 12607 | + (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] | ||
| 12608 | + "TARGET_DSP" | ||
| 12609 | + "mulhh.w %0, %1:b, %2:b" | ||
| 12610 | + [(set_attr "type" "mulhh") | ||
| 12611 | + (set_attr "length" "4") | ||
| 12612 | + (set_attr "cc" "none")]) | ||
| 12613 | + | ||
| 12614 | +(define_peephole2 | ||
| 12615 | + [(match_scratch:DI 6 "r") | ||
| 12616 | + (set (match_operand:SI 0 "register_operand" "") | ||
| 12617 | + (mult:SI | ||
| 12618 | + (sign_extend:SI (match_operand:HI 1 "register_operand" "")) | ||
| 12619 | + (sign_extend:SI (match_operand:HI 2 "register_operand" "")))) | ||
| 12620 | + (set (match_operand:SI 3 "register_operand" "") | ||
| 12621 | + (ashiftrt:SI (match_dup 0) | ||
| 12622 | + (const_int 16)))] | ||
| 12623 | + "TARGET_DSP | ||
| 12624 | + && (peep2_reg_dead_p(1, operands[0]) || (REGNO(operands[0]) == REGNO(operands[3])))" | ||
| 12625 | + [(set (match_dup 4) (sign_extend:SI (match_dup 1))) | ||
| 12626 | + (set (match_dup 6) | ||
| 12627 | + (ashift:DI (mult:DI (sign_extend:DI (match_dup 4)) | ||
| 12628 | + (sign_extend:DI (match_dup 2))) | ||
| 12629 | + (const_int 16))) | ||
| 12630 | + (set (match_dup 3) (match_dup 5))] | ||
| 12631 | + | ||
| 12632 | + "{ | ||
| 12633 | + operands[4] = gen_rtx_REG(SImode, REGNO(operands[1])); | ||
| 12634 | + operands[5] = gen_highpart (SImode, operands[4]); | ||
| 12635 | + }" | ||
| 12636 | + ) | ||
| 12637 | + | ||
| 12638 | +(define_insn "mulnhisi3" | ||
| 12639 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 12640 | + (mult:SI | ||
| 12641 | + (sign_extend:SI (neg:HI (match_operand:HI 1 "register_operand" "r"))) | ||
| 12642 | + (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] | ||
| 12643 | + "TARGET_DSP" | ||
| 12644 | + "mulnhh.w %0, %1:b, %2:b" | ||
| 12645 | + [(set_attr "type" "mulhh") | ||
| 12646 | + (set_attr "length" "4") | ||
| 12647 | + (set_attr "cc" "none")]) | ||
| 12648 | + | ||
| 12649 | +(define_insn "machisi3" | ||
| 12650 | + [(set (match_operand:SI 0 "register_operand" "+r") | ||
| 12651 | + (plus:SI (mult:SI | ||
| 12652 | + (sign_extend:SI (match_operand:HI 1 "register_operand" "%r")) | ||
| 12653 | + (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) | ||
| 12654 | + (match_dup 0)))] | ||
| 12655 | + "TARGET_DSP" | ||
| 12656 | + "machh.w %0, %1:b, %2:b" | ||
| 12657 | + [(set_attr "type" "machh_w") | ||
| 12658 | + (set_attr "length" "4") | ||
| 12659 | + (set_attr "cc" "none")]) | ||
| 12660 | + | ||
| 12661 | + | ||
| 12662 | + | ||
| 12663 | +(define_insn "mulsidi3" | ||
| 12664 | + [(set (match_operand:DI 0 "register_operand" "=r") | ||
| 12665 | + (mult:DI | ||
| 12666 | + (sign_extend:DI (match_operand:SI 1 "register_operand" "%r")) | ||
| 12667 | + (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | ||
| 12668 | + "" | ||
| 12669 | + "muls.d %0, %1, %2" | ||
| 12670 | + [(set_attr "type" "mulww_d") | ||
| 12671 | + (set_attr "length" "4") | ||
| 12672 | + (set_attr "cc" "none")]) | ||
| 12673 | + | ||
| 12674 | +(define_insn "umulsidi3" | ||
| 12675 | + [(set (match_operand:DI 0 "register_operand" "=r") | ||
| 12676 | + (mult:DI | ||
| 12677 | + (zero_extend:DI (match_operand:SI 1 "register_operand" "%r")) | ||
| 12678 | + (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | ||
| 12679 | + "" | ||
| 12680 | + "mulu.d %0, %1, %2" | ||
| 12681 | + [(set_attr "type" "mulww_d") | ||
| 12682 | + (set_attr "length" "4") | ||
| 12683 | + (set_attr "cc" "none")]) | ||
| 12684 | + | ||
| 12685 | +(define_insn "*mulaccsi3" | ||
| 12686 | + [(set (match_operand:SI 0 "register_operand" "+r") | ||
| 12687 | + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r") | ||
| 12688 | + (match_operand:SI 2 "register_operand" "r")) | ||
| 12689 | + (match_dup 0)))] | ||
| 12690 | + "" | ||
| 12691 | + "mac %0, %1, %2" | ||
| 12692 | + [(set_attr "type" "macww_w") | ||
| 12693 | + (set_attr "length" "4") | ||
| 12694 | + (set_attr "cc" "none")]) | ||
| 12695 | + | ||
| 12696 | +(define_insn "mulaccsidi3" | ||
| 12697 | + [(set (match_operand:DI 0 "register_operand" "+r") | ||
| 12698 | + (plus:DI (mult:DI | ||
| 12699 | + (sign_extend:DI (match_operand:SI 1 "register_operand" "%r")) | ||
| 12700 | + (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) | ||
| 12701 | + (match_dup 0)))] | ||
| 12702 | + "" | ||
| 12703 | + "macs.d %0, %1, %2" | ||
| 12704 | + [(set_attr "type" "macww_d") | ||
| 12705 | + (set_attr "length" "4") | ||
| 12706 | + (set_attr "cc" "none")]) | ||
| 12707 | + | ||
| 12708 | +(define_insn "umulaccsidi3" | ||
| 12709 | + [(set (match_operand:DI 0 "register_operand" "+r") | ||
| 12710 | + (plus:DI (mult:DI | ||
| 12711 | + (zero_extend:DI (match_operand:SI 1 "register_operand" "%r")) | ||
| 12712 | + (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) | ||
| 12713 | + (match_dup 0)))] | ||
| 12714 | + "" | ||
| 12715 | + "macu.d %0, %1, %2" | ||
| 12716 | + [(set_attr "type" "macww_d") | ||
| 12717 | + (set_attr "length" "4") | ||
| 12718 | + (set_attr "cc" "none")]) | ||
| 12719 | + | ||
| 12720 | + | ||
| 12721 | + | ||
| 12722 | +;; Try to avoid Write-After-Write hazards for mul operations | ||
| 12723 | +;; if it can be done | ||
| 12724 | +(define_peephole2 | ||
| 12725 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 12726 | + (mult:SI | ||
| 12727 | + (sign_extend:SI (match_operand 1 "general_operand" "")) | ||
| 12728 | + (sign_extend:SI (match_operand 2 "general_operand" "")))) | ||
| 12729 | + (set (match_dup 0) | ||
| 12730 | + (match_operator:SI 3 "alu_operator" [(match_dup 0) | ||
| 12731 | + (match_operand 4 "general_operand" "")]))] | ||
| 12732 | + "peep2_reg_dead_p(1, operands[2])" | ||
| 12733 | + [(set (match_dup 5) | ||
| 12734 | + (mult:SI | ||
| 12735 | + (sign_extend:SI (match_dup 1)) | ||
| 12736 | + (sign_extend:SI (match_dup 2)))) | ||
| 12737 | + (set (match_dup 0) | ||
| 12738 | + (match_op_dup 3 [(match_dup 5) | ||
| 12739 | + (match_dup 4)]))] | ||
| 12740 | + "{operands[5] = gen_rtx_REG(SImode, REGNO(operands[2]));}" | ||
| 12741 | + ) | ||
| 12742 | + | ||
| 12743 | + | ||
| 12744 | + | ||
| 12745 | +;;============================================================================= | ||
| 12746 | +;; DSP instructions | ||
| 12747 | +;;============================================================================= | ||
| 12748 | +(define_insn "mulsathh_h" | ||
| 12749 | + [(set (match_operand:HI 0 "register_operand" "=r") | ||
| 12750 | + (ss_truncate:HI (ashiftrt:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r")) | ||
| 12751 | + (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) | ||
| 12752 | + (const_int 15))))] | ||
| 12753 | + "TARGET_DSP" | ||
| 12754 | + "mulsathh.h\t%0, %1:b, %2:b" | ||
| 12755 | + [(set_attr "length" "4") | ||
| 12756 | + (set_attr "cc" "none") | ||
| 12757 | + (set_attr "type" "mulhh")]) | ||
| 12758 | + | ||
| 12759 | +(define_insn "mulsatrndhh_h" | ||
| 12760 | + [(set (match_operand:HI 0 "register_operand" "=r") | ||
| 12761 | + (ss_truncate:HI (ashiftrt:SI | ||
| 12762 | + (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r")) | ||
| 12763 | + (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) | ||
| 12764 | + (const_int 1073741824)) | ||
| 12765 | + (const_int 15))))] | ||
| 12766 | + "TARGET_DSP" | ||
| 12767 | + "mulsatrndhh.h\t%0, %1:b, %2:b" | ||
| 12768 | + [(set_attr "length" "4") | ||
| 12769 | + (set_attr "cc" "none") | ||
| 12770 | + (set_attr "type" "mulhh")]) | ||
| 12771 | + | ||
| 12772 | +(define_insn "mulsathh_w" | ||
| 12773 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 12774 | + (ss_truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_operand:HI 1 "register_operand" "%r")) | ||
| 12775 | + (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) | ||
| 12776 | + (const_int 1))))] | ||
| 12777 | + "TARGET_DSP" | ||
| 12778 | + "mulsathh.w\t%0, %1:b, %2:b" | ||
| 12779 | + [(set_attr "length" "4") | ||
| 12780 | + (set_attr "cc" "none") | ||
| 12781 | + (set_attr "type" "mulhh")]) | ||
| 12782 | + | ||
| 12783 | +(define_insn "mulsatwh_w" | ||
| 12784 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 12785 | + (ss_truncate:SI (ashiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | ||
| 12786 | + (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) | ||
| 12787 | + (const_int 15))))] | ||
| 12788 | + "TARGET_DSP" | ||
| 12789 | + "mulsatwh.w\t%0, %1, %2:b" | ||
| 12790 | + [(set_attr "length" "4") | ||
| 12791 | + (set_attr "cc" "none") | ||
| 12792 | + (set_attr "type" "mulwh")]) | ||
| 12793 | + | ||
| 12794 | +(define_insn "mulsatrndwh_w" | ||
| 12795 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 12796 | + (ss_truncate:SI (ashiftrt:DI (plus:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | ||
| 12797 | + (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) | ||
| 12798 | + (const_int 1073741824)) | ||
| 12799 | + (const_int 15))))] | ||
| 12800 | + "TARGET_DSP" | ||
| 12801 | + "mulsatrndwh.w\t%0, %1, %2:b" | ||
| 12802 | + [(set_attr "length" "4") | ||
| 12803 | + (set_attr "cc" "none") | ||
| 12804 | + (set_attr "type" "mulwh")]) | ||
| 12805 | + | ||
| 12806 | +(define_insn "macsathh_w" | ||
| 12807 | + [(set (match_operand:SI 0 "register_operand" "+r") | ||
| 12808 | + (plus:SI (match_dup 0) | ||
| 12809 | + (ss_truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_operand:HI 1 "register_operand" "%r")) | ||
| 12810 | + (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) | ||
| 12811 | + (const_int 1)))))] | ||
| 12812 | + "TARGET_DSP" | ||
| 12813 | + "macsathh.w\t%0, %1:b, %2:b" | ||
| 12814 | + [(set_attr "length" "4") | ||
| 12815 | + (set_attr "cc" "none") | ||
| 12816 | + (set_attr "type" "mulhh")]) | ||
| 12817 | + | ||
| 12818 | + | ||
| 12819 | +(define_insn "mulwh_d" | ||
| 12820 | + [(set (match_operand:DI 0 "register_operand" "=r") | ||
| 12821 | + (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | ||
| 12822 | + (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) | ||
| 12823 | + (const_int 16)))] | ||
| 12824 | + "TARGET_DSP" | ||
| 12825 | + "mulwh.d\t%0, %1, %2:b" | ||
| 12826 | + [(set_attr "length" "4") | ||
| 12827 | + (set_attr "cc" "none") | ||
| 12828 | + (set_attr "type" "mulwh")]) | ||
| 12829 | + | ||
| 12830 | + | ||
| 12831 | +(define_insn "mulnwh_d" | ||
| 12832 | + [(set (match_operand:DI 0 "register_operand" "=r") | ||
| 12833 | + (ashift:DI (mult:DI (not:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))) | ||
| 12834 | + (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) | ||
| 12835 | + (const_int 16)))] | ||
| 12836 | + "TARGET_DSP" | ||
| 12837 | + "mulnwh.d\t%0, %1, %2:b" | ||
| 12838 | + [(set_attr "length" "4") | ||
| 12839 | + (set_attr "cc" "none") | ||
| 12840 | + (set_attr "type" "mulwh")]) | ||
| 12841 | + | ||
| 12842 | +(define_insn "macwh_d" | ||
| 12843 | + [(set (match_operand:DI 0 "register_operand" "+r") | ||
| 12844 | + (plus:DI (match_dup 0) | ||
| 12845 | + (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r")) | ||
| 12846 | + (sign_extend:DI (match_operand:HI 2 "register_operand" "r"))) | ||
| 12847 | + (const_int 16))))] | ||
| 12848 | + "TARGET_DSP" | ||
| 12849 | + "macwh.d\t%0, %1, %2:b" | ||
| 12850 | + [(set_attr "length" "4") | ||
| 12851 | + (set_attr "cc" "none") | ||
| 12852 | + (set_attr "type" "mulwh")]) | ||
| 12853 | + | ||
| 12854 | +(define_insn "machh_d" | ||
| 12855 | + [(set (match_operand:DI 0 "register_operand" "+r") | ||
| 12856 | + (plus:DI (match_dup 0) | ||
| 12857 | + (mult:DI (sign_extend:DI (match_operand:HI 1 "register_operand" "%r")) | ||
| 12858 | + (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))))] | ||
| 12859 | + "TARGET_DSP" | ||
| 12860 | + "machh.d\t%0, %1:b, %2:b" | ||
| 12861 | + [(set_attr "length" "4") | ||
| 12862 | + (set_attr "cc" "none") | ||
| 12863 | + (set_attr "type" "mulwh")]) | ||
| 12864 | + | ||
| 12865 | +(define_insn "satadd_w" | ||
| 12866 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 12867 | + (ss_plus:SI (match_operand:SI 1 "register_operand" "r") | ||
| 12868 | + (match_operand:SI 2 "register_operand" "r")))] | ||
| 12869 | + "TARGET_DSP" | ||
| 12870 | + "satadd.w\t%0, %1, %2" | ||
| 12871 | + [(set_attr "length" "4") | ||
| 12872 | + (set_attr "cc" "none") | ||
| 12873 | + (set_attr "type" "alu_sat")]) | ||
| 12874 | + | ||
| 12875 | +(define_insn "satsub_w" | ||
| 12876 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 12877 | + (ss_minus:SI (match_operand:SI 1 "register_operand" "r") | ||
| 12878 | + (match_operand:SI 2 "register_operand" "r")))] | ||
| 12879 | + "TARGET_DSP" | ||
| 12880 | + "satsub.w\t%0, %1, %2" | ||
| 12881 | + [(set_attr "length" "4") | ||
| 12882 | + (set_attr "cc" "none") | ||
| 12883 | + (set_attr "type" "alu_sat")]) | ||
| 12884 | + | ||
| 12885 | +(define_insn "satadd_h" | ||
| 12886 | + [(set (match_operand:HI 0 "register_operand" "=r") | ||
| 12887 | + (ss_plus:HI (match_operand:HI 1 "register_operand" "r") | ||
| 12888 | + (match_operand:HI 2 "register_operand" "r")))] | ||
| 12889 | + "TARGET_DSP" | ||
| 12890 | + "satadd.h\t%0, %1, %2" | ||
| 12891 | + [(set_attr "length" "4") | ||
| 12892 | + (set_attr "cc" "none") | ||
| 12893 | + (set_attr "type" "alu_sat")]) | ||
| 12894 | + | ||
| 12895 | +(define_insn "satsub_h" | ||
| 12896 | + [(set (match_operand:HI 0 "register_operand" "=r") | ||
| 12897 | + (ss_minus:HI (match_operand:HI 1 "register_operand" "r") | ||
| 12898 | + (match_operand:HI 2 "register_operand" "r")))] | ||
| 12899 | + "TARGET_DSP" | ||
| 12900 | + "satsub.h\t%0, %1, %2" | ||
| 12901 | + [(set_attr "length" "4") | ||
| 12902 | + (set_attr "cc" "none") | ||
| 12903 | + (set_attr "type" "alu_sat")]) | ||
| 12904 | + | ||
| 12905 | + | ||
| 12906 | +;;============================================================================= | ||
| 12907 | +;; smin | ||
| 12908 | +;;----------------------------------------------------------------------------- | ||
| 12909 | +;; Set reg0 to the smallest value of reg1 and reg2. It is used for signed | ||
| 12910 | +;; values in the registers. | ||
| 12911 | +;;============================================================================= | ||
| 12912 | +(define_insn "sminsi3" | ||
| 12913 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 12914 | + (smin:SI (match_operand:SI 1 "register_operand" "r") | ||
| 12915 | + (match_operand:SI 2 "register_operand" "r")))] | ||
| 12916 | + "" | ||
| 12917 | + "min %0, %1, %2" | ||
| 12918 | + [(set_attr "length" "4") | ||
| 12919 | + (set_attr "cc" "none")]) | ||
| 12920 | + | ||
| 12921 | +;;============================================================================= | ||
| 12922 | +;; smax | ||
| 12923 | +;;----------------------------------------------------------------------------- | ||
| 12924 | +;; Set reg0 to the largest value of reg1 and reg2. It is used for signed | ||
| 12925 | +;; values in the registers. | ||
| 12926 | +;;============================================================================= | ||
| 12927 | +(define_insn "smaxsi3" | ||
| 12928 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 12929 | + (smax:SI (match_operand:SI 1 "register_operand" "r") | ||
| 12930 | + (match_operand:SI 2 "register_operand" "r")))] | ||
| 12931 | + "" | ||
| 12932 | + "max %0, %1, %2" | ||
| 12933 | + [(set_attr "length" "4") | ||
| 12934 | + (set_attr "cc" "none")]) | ||
| 12935 | + | ||
| 12936 | + | ||
| 12937 | +;;============================================================================= | ||
| 12938 | +;; Logical operations | ||
| 12939 | +;;----------------------------------------------------------------------------- | ||
| 12940 | + | ||
| 12941 | +;; Split up simple DImode logical operations. Simply perform the logical | ||
| 12942 | +;; operation on the upper and lower halves of the registers. | ||
| 12943 | +(define_split | ||
| 12944 | + [(set (match_operand:DI 0 "register_operand" "") | ||
| 12945 | + (match_operator:DI 6 "logical_binary_operator" | ||
| 12946 | + [(match_operand:DI 1 "register_operand" "") | ||
| 12947 | + (match_operand:DI 2 "register_operand" "")]))] | ||
| 12948 | + "reload_completed" | ||
| 12949 | + [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)])) | ||
| 12950 | + (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))] | ||
| 12951 | + " | ||
| 12952 | + { | ||
| 12953 | + operands[3] = gen_highpart (SImode, operands[0]); | ||
| 12954 | + operands[0] = gen_lowpart (SImode, operands[0]); | ||
| 12955 | + operands[4] = gen_highpart (SImode, operands[1]); | ||
| 12956 | + operands[1] = gen_lowpart (SImode, operands[1]); | ||
| 12957 | + operands[5] = gen_highpart (SImode, operands[2]); | ||
| 12958 | + operands[2] = gen_lowpart (SImode, operands[2]); | ||
| 12959 | + }" | ||
| 12960 | +) | ||
| 12961 | + | ||
| 12962 | +;;============================================================================= | ||
| 12963 | +;; Logical operations with shifted operand | ||
| 12964 | +;;============================================================================= | ||
| 12965 | +(define_insn "<code>si_lshift" | ||
| 12966 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 12967 | + (logical:SI (match_operator:SI 4 "logical_shift_operator" | ||
| 12968 | + [(match_operand:SI 2 "register_operand" "r") | ||
| 12969 | + (match_operand:SI 3 "immediate_operand" "Ku05")]) | ||
| 12970 | + (match_operand:SI 1 "register_operand" "r")))] | ||
| 12971 | + "" | ||
| 12972 | + { | ||
| 12973 | + if ( GET_CODE(operands[4]) == ASHIFT ) | ||
| 12974 | + return "<logical_insn>\t%0, %1, %2 << %3"; | ||
| 12975 | + else | ||
| 12976 | + return "<logical_insn>\t%0, %1, %2 >> %3"; | ||
| 12977 | + } | ||
| 12978 | + | ||
| 12979 | + [(set_attr "cc" "set_z")] | ||
| 12980 | +) | ||
| 12981 | + | ||
| 12982 | + | ||
| 12983 | +;;************************************************ | ||
| 12984 | +;; Peepholes for detecting logical operantions | ||
| 12985 | +;; with shifted operands | ||
| 12986 | +;;************************************************ | ||
| 12987 | + | ||
| 12988 | +(define_peephole | ||
| 12989 | + [(set (match_operand:SI 3 "register_operand" "") | ||
| 12990 | + (match_operator:SI 5 "logical_shift_operator" | ||
| 12991 | + [(match_operand:SI 1 "register_operand" "") | ||
| 12992 | + (match_operand:SI 2 "immediate_operand" "")])) | ||
| 12993 | + (set (match_operand:SI 0 "register_operand" "") | ||
| 12994 | + (logical:SI (match_operand:SI 4 "register_operand" "") | ||
| 12995 | + (match_dup 3)))] | ||
| 12996 | + "(dead_or_set_p(insn, operands[3])) || (REGNO(operands[3]) == REGNO(operands[0]))" | ||
| 12997 | + { | ||
| 12998 | + if ( GET_CODE(operands[5]) == ASHIFT ) | ||
| 12999 | + return "<logical_insn>\t%0, %4, %1 << %2"; | ||
| 13000 | + else | ||
| 13001 | + return "<logical_insn>\t%0, %4, %1 >> %2"; | ||
| 13002 | + } | ||
| 13003 | + [(set_attr "cc" "set_z")] | ||
| 13004 | + ) | ||
| 13005 | + | ||
| 13006 | +(define_peephole | ||
| 13007 | + [(set (match_operand:SI 3 "register_operand" "") | ||
| 13008 | + (match_operator:SI 5 "logical_shift_operator" | ||
| 13009 | + [(match_operand:SI 1 "register_operand" "") | ||
| 13010 | + (match_operand:SI 2 "immediate_operand" "")])) | ||
| 13011 | + (set (match_operand:SI 0 "register_operand" "") | ||
| 13012 | + (logical:SI (match_dup 3) | ||
| 13013 | + (match_operand:SI 4 "register_operand" "")))] | ||
| 13014 | + "(dead_or_set_p(insn, operands[3])) || (REGNO(operands[3]) == REGNO(operands[0]))" | ||
| 13015 | + { | ||
| 13016 | + if ( GET_CODE(operands[5]) == ASHIFT ) | ||
| 13017 | + return "<logical_insn>\t%0, %4, %1 << %2"; | ||
| 13018 | + else | ||
| 13019 | + return "<logical_insn>\t%0, %4, %1 >> %2"; | ||
| 13020 | + } | ||
| 13021 | + [(set_attr "cc" "set_z")] | ||
| 13022 | + ) | ||
| 13023 | + | ||
| 13024 | + | ||
| 13025 | +(define_peephole2 | ||
| 13026 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 13027 | + (match_operator:SI 5 "logical_shift_operator" | ||
| 13028 | + [(match_operand:SI 1 "register_operand" "") | ||
| 13029 | + (match_operand:SI 2 "immediate_operand" "")])) | ||
| 13030 | + (set (match_operand:SI 3 "register_operand" "") | ||
| 13031 | + (logical:SI (match_operand:SI 4 "register_operand" "") | ||
| 13032 | + (match_dup 0)))] | ||
| 13033 | + "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[3]) == REGNO(operands[0]))" | ||
| 13034 | + | ||
| 13035 | + [(set (match_dup 3) | ||
| 13036 | + (logical:SI (match_op_dup:SI 5 [(match_dup 1) (match_dup 2)]) | ||
| 13037 | + (match_dup 4)))] | ||
| 13038 | + | ||
| 13039 | + "" | ||
| 13040 | +) | ||
| 13041 | + | ||
| 13042 | +(define_peephole2 | ||
| 13043 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 13044 | + (match_operator:SI 5 "logical_shift_operator" | ||
| 13045 | + [(match_operand:SI 1 "register_operand" "") | ||
| 13046 | + (match_operand:SI 2 "immediate_operand" "")])) | ||
| 13047 | + (set (match_operand:SI 3 "register_operand" "") | ||
| 13048 | + (logical:SI (match_dup 0) | ||
| 13049 | + (match_operand:SI 4 "register_operand" "")))] | ||
| 13050 | + "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[3]) == REGNO(operands[0]))" | ||
| 13051 | + | ||
| 13052 | + [(set (match_dup 3) | ||
| 13053 | + (logical:SI (match_op_dup:SI 5 [(match_dup 1) (match_dup 2)]) | ||
| 13054 | + (match_dup 4)))] | ||
| 13055 | + | ||
| 13056 | + "" | ||
| 13057 | +) | ||
| 13058 | + | ||
| 13059 | + | ||
| 13060 | +;;============================================================================= | ||
| 13061 | +;; and | ||
| 13062 | +;;----------------------------------------------------------------------------- | ||
| 13063 | +;; Store the result after a bitwise logical-and between reg0 and reg2 in reg0. | ||
| 13064 | +;;============================================================================= | ||
| 13065 | + | ||
| 13066 | +(define_insn "andnsi" | ||
| 13067 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 13068 | + (and:SI (match_operand:SI 1 "register_operand" "0") | ||
| 13069 | + (not:SI (match_operand:SI 2 "register_operand" "r"))))] | ||
| 13070 | + "" | ||
| 13071 | + "andn %0, %2" | ||
| 13072 | + [(set_attr "cc" "set_z") | ||
| 13073 | + (set_attr "length" "2")] | ||
| 13074 | +) | ||
| 13075 | + | ||
| 13076 | + | ||
| 13077 | + | ||
| 13078 | + | ||
| 13079 | +(define_insn "andsi3" | ||
| 13080 | + [(set (match_operand:SI 0 "register_operand" "=r, r, r, r") | ||
| 13081 | + (and:SI (match_operand:SI 1 "register_operand" "%0, r, 0, r") | ||
| 13082 | + (match_operand:SI 2 "nonmemory_operand" "r, M, i, r")))] | ||
| 13083 | + "" | ||
| 13084 | + { | ||
| 13085 | + switch (which_alternative){ | ||
| 13086 | + case 0: | ||
| 13087 | + return "and\t%0, %2"; | ||
| 13088 | + case 1: | ||
| 13089 | + { | ||
| 13090 | + int i, first_set = -1; | ||
| 13091 | + /* Search for first bit set in mask */ | ||
| 13092 | + for ( i = 31; i >= 0; --i ) | ||
| 13093 | + if ( INTVAL(operands[2]) & (1 << i) ){ | ||
| 13094 | + first_set = i; | ||
| 13095 | + break; | ||
| 13096 | + } | ||
| 13097 | + operands[2] = gen_rtx_CONST_INT(SImode, first_set + 1); | ||
| 13098 | + return "bfextu\t%0, %1, 0, %2"; | ||
| 13099 | + } | ||
| 13100 | + case 2: | ||
| 13101 | + if ( one_bit_cleared_operand(operands[2], VOIDmode) ){ | ||
| 13102 | + int bitpos; | ||
| 13103 | + for ( bitpos = 0; bitpos < 32; bitpos++ ) | ||
| 13104 | + if ( !(INTVAL(operands[2]) & (1 << bitpos)) ) | ||
| 13105 | + break; | ||
| 13106 | + operands[2] = gen_rtx_CONST_INT(SImode, bitpos); | ||
| 13107 | + return "cbr\t%0, %2"; | ||
| 13108 | + } else if ( (INTVAL(operands[2]) >= 0) && | ||
| 13109 | + (INTVAL(operands[2]) <= 65535) ) | ||
| 13110 | + return "andl\t%0, %2, COH"; | ||
| 13111 | + else if ( (INTVAL(operands[2]) < 0) && | ||
| 13112 | + (INTVAL(operands[2]) >= -65536 ) ) | ||
| 13113 | + return "andl\t%0, lo(%2)"; | ||
| 13114 | + else if ( ((INTVAL(operands[2]) & 0xffff) == 0xffff) ) | ||
| 13115 | + return "andh\t%0, hi(%2)"; | ||
| 13116 | + else if ( ((INTVAL(operands[2]) & 0xffff) == 0x0) ) | ||
| 13117 | + return "andh\t%0, hi(%2), COH"; | ||
| 13118 | + else | ||
| 13119 | + return "andh\t%0, hi(%2)\;andl\t%0, lo(%2)"; | ||
| 13120 | + case 3: | ||
| 13121 | + return "and\t%0, %1, %2"; | ||
| 13122 | + default: | ||
| 13123 | + abort(); | ||
| 13124 | + } | ||
| 13125 | + } | ||
| 13126 | + | ||
| 13127 | + [(set_attr "length" "2,4,8,4") | ||
| 13128 | + (set_attr "cc" "set_z")]) | ||
| 13129 | + | ||
| 13130 | + | ||
| 13131 | +(define_insn "anddi3" | ||
| 13132 | + [(set (match_operand:DI 0 "register_operand" "=&r,&r") | ||
| 13133 | + (and:DI (match_operand:DI 1 "register_operand" "%0,r") | ||
| 13134 | + (match_operand:DI 2 "register_operand" "r,r")))] | ||
| 13135 | + "" | ||
| 13136 | + "#" | ||
| 13137 | + [(set_attr "length" "8") | ||
| 13138 | + (set_attr "cc" "clobber")] | ||
| 13139 | +) | ||
| 13140 | + | ||
| 13141 | +;;============================================================================= | ||
| 13142 | +;; or | ||
| 13143 | +;;----------------------------------------------------------------------------- | ||
| 13144 | +;; Store the result after a bitwise inclusive-or between reg0 and reg2 in reg0. | ||
| 13145 | +;;============================================================================= | ||
| 13146 | + | ||
| 13147 | +(define_insn "iorsi3" | ||
| 13148 | + [(set (match_operand:SI 0 "register_operand" "=r,r,r") | ||
| 13149 | + (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r" ) | ||
| 13150 | + (match_operand:SI 2 "nonmemory_operand" "r ,i,r")))] | ||
| 13151 | + "" | ||
| 13152 | + { | ||
| 13153 | + switch (which_alternative){ | ||
| 13154 | + case 0: | ||
| 13155 | + return "or\t%0, %2"; | ||
| 13156 | + case 1: | ||
| 13157 | + if ( one_bit_set_operand(operands[2], VOIDmode) ){ | ||
| 13158 | + int bitpos; | ||
| 13159 | + for (bitpos = 0; bitpos < 32; bitpos++) | ||
| 13160 | + if (INTVAL(operands[2]) & (1 << bitpos)) | ||
| 13161 | + break; | ||
| 13162 | + operands[2] = gen_rtx_CONST_INT( SImode, bitpos); | ||
| 13163 | + return "sbr\t%0, %2"; | ||
| 13164 | + } else if ( (INTVAL(operands[2]) >= 0) && | ||
| 13165 | + (INTVAL(operands[2]) <= 65535) ) | ||
| 13166 | + return "orl\t%0, %2"; | ||
| 13167 | + else if ( ((INTVAL(operands[2]) & 0xffff) == 0x0) ) | ||
| 13168 | + return "orh\t%0, hi(%2)"; | ||
| 13169 | + else | ||
| 13170 | + return "orh\t%0, hi(%2)\;orl\t%0, lo(%2)"; | ||
| 13171 | + case 2: | ||
| 13172 | + return "or\t%0, %1, %2"; | ||
| 13173 | + default: | ||
| 13174 | + abort(); | ||
| 13175 | + } | ||
| 13176 | + } | ||
| 13177 | + [(set_attr "length" "2,8,4") | ||
| 13178 | + (set_attr "cc" "set_z")]) | ||
| 13179 | + | ||
| 13180 | + | ||
| 13181 | +;(define_insn "iorsi3" | ||
| 13182 | +; [(set (match_operand:SI 0 "register_operand" "=r, r, r") | ||
| 13183 | +; (ior:SI (match_operand:SI 1 "avr32_logical_insn_operand" "r, r, rA" ) | ||
| 13184 | +; (match_operand:SI 2 "register_operand" "0, i, r")))] | ||
| 13185 | +; "" | ||
| 13186 | +; { | ||
| 13187 | +; switch (which_alternative){ | ||
| 13188 | +; case 0: | ||
| 13189 | +; return "or %0, %2"; | ||
| 13190 | +; case 1: | ||
| 13191 | +; if ( one_bit_set_operand(operands[2], VOIDmode) ){ | ||
| 13192 | +; int i, bitpos; | ||
| 13193 | +; for ( i = 0; i < 32; i++ ) | ||
| 13194 | +; if ( INTVAL(operands[2]) & (1 << i) ){ | ||
| 13195 | +; bitpos = i; | ||
| 13196 | +; break; | ||
| 13197 | +; } | ||
| 13198 | +; operands[2] = gen_rtx_CONST_INT( SImode, bitpos); | ||
| 13199 | +; return "sbr %0, %2"; | ||
| 13200 | +; } else if ( (INTVAL(operands[2]) >= 0) && | ||
| 13201 | +; (INTVAL(operands[2]) <= 65535) ) | ||
| 13202 | +; return "orl %0, %2"; | ||
| 13203 | +; else if ( ((INTVAL(operands[2]) & 0xffff) == 0x0) ) | ||
| 13204 | +; return "orh %0, hi(%2)"; | ||
| 13205 | +; else | ||
| 13206 | +; return "orh %0, hi(%2)\;orl %0, lo(%2)"; | ||
| 13207 | +; case 2: | ||
| 13208 | +; return "or %0, %2, %1"; | ||
| 13209 | +; } | ||
| 13210 | +; } | ||
| 13211 | +; [(set_attr "length" "2,8,4") | ||
| 13212 | +; (set_attr "cc" "set_z")]) | ||
| 13213 | + | ||
| 13214 | +(define_insn "iordi3" | ||
| 13215 | + [(set (match_operand:DI 0 "register_operand" "=&r,&r") | ||
| 13216 | + (ior:DI (match_operand:DI 1 "register_operand" "%0,r") | ||
| 13217 | + (match_operand:DI 2 "register_operand" "r,r")))] | ||
| 13218 | + "" | ||
| 13219 | + "#" | ||
| 13220 | + [(set_attr "length" "8") | ||
| 13221 | + (set_attr "cc" "clobber")] | ||
| 13222 | +) | ||
| 13223 | + | ||
| 13224 | +;;============================================================================= | ||
| 13225 | +;; xor bytes | ||
| 13226 | +;;----------------------------------------------------------------------------- | ||
| 13227 | +;; Store the result after a bitwise exclusive-or between reg0 and reg2 in reg0. | ||
| 13228 | +;;============================================================================= | ||
| 13229 | + | ||
| 13230 | +(define_insn "xorsi3" | ||
| 13231 | + [(set (match_operand:SI 0 "register_operand" "=r,r,r") | ||
| 13232 | + (xor:SI (match_operand:SI 1 "register_operand" "0,0,r") | ||
| 13233 | + (match_operand:SI 2 "nonmemory_operand" "r,i,r")))] | ||
| 13234 | + "" | ||
| 13235 | + { | ||
| 13236 | + switch (which_alternative){ | ||
| 13237 | + case 0: | ||
| 13238 | + return "eor %0, %2"; | ||
| 13239 | + case 1: | ||
| 13240 | + if ( (INTVAL(operands[2]) >= 0) && | ||
| 13241 | + (INTVAL(operands[2]) <= 65535) ) | ||
| 13242 | + return "eorl %0, %2"; | ||
| 13243 | + else if ( ((INTVAL(operands[2]) & 0xffff) == 0x0) ) | ||
| 13244 | + return "eorh %0, hi(%2)"; | ||
| 13245 | + else | ||
| 13246 | + return "eorh %0, hi(%2)\;eorl %0, lo(%2)"; | ||
| 13247 | + case 2: | ||
| 13248 | + return "eor %0, %1, %2"; | ||
| 13249 | + default: | ||
| 13250 | + abort(); | ||
| 13251 | + } | ||
| 13252 | + } | ||
| 13253 | + | ||
| 13254 | + [(set_attr "length" "2,8,4") | ||
| 13255 | + (set_attr "cc" "set_z")]) | ||
| 13256 | + | ||
| 13257 | +(define_insn "xordi3" | ||
| 13258 | + [(set (match_operand:DI 0 "register_operand" "=&r,&r") | ||
| 13259 | + (xor:DI (match_operand:DI 1 "register_operand" "%0,r") | ||
| 13260 | + (match_operand:DI 2 "register_operand" "r,r")))] | ||
| 13261 | + "" | ||
| 13262 | + "#" | ||
| 13263 | + [(set_attr "length" "8") | ||
| 13264 | + (set_attr "cc" "clobber")] | ||
| 13265 | +) | ||
| 13266 | + | ||
| 13267 | +;;============================================================================= | ||
| 13268 | +;; divmod | ||
| 13269 | +;;----------------------------------------------------------------------------- | ||
| 13270 | +;; Signed division that produces both a quotient and a remainder. | ||
| 13271 | +;;============================================================================= | ||
| 13272 | +(define_expand "divmodsi4" | ||
| 13273 | + [(parallel [ | ||
| 13274 | + (parallel [ | ||
| 13275 | + (set (match_operand:SI 0 "register_operand" "=r") | ||
| 13276 | + (div:SI (match_operand:SI 1 "register_operand" "r") | ||
| 13277 | + (match_operand:SI 2 "register_operand" "r"))) | ||
| 13278 | + (set (match_operand:SI 3 "register_operand" "=r") | ||
| 13279 | + (mod:SI (match_dup 1) | ||
| 13280 | + (match_dup 2)))]) | ||
| 13281 | + (use (match_dup 4))])] | ||
| 13282 | + "" | ||
| 13283 | + { | ||
| 13284 | + if (! no_new_pseudos) { | ||
| 13285 | + operands[4] = gen_reg_rtx (DImode); | ||
| 13286 | + | ||
| 13287 | + emit_insn(gen_divmodsi4_internal(operands[4],operands[1],operands[2])); | ||
| 13288 | + emit_move_insn(operands[0], gen_rtx_SUBREG( SImode, operands[4], 4)); | ||
| 13289 | + emit_move_insn(operands[3], gen_rtx_SUBREG( SImode, operands[4], 0)); | ||
| 13290 | + | ||
| 13291 | + DONE; | ||
| 13292 | + } else { | ||
| 13293 | + FAIL; | ||
| 13294 | + } | ||
| 13295 | + | ||
| 13296 | + }) | ||
| 13297 | + | ||
| 13298 | + | ||
| 13299 | +(define_insn "divmodsi4_internal" | ||
| 13300 | + [(set (match_operand:DI 0 "register_operand" "=r") | ||
| 13301 | + (unspec:DI [(match_operand:SI 1 "register_operand" "r") | ||
| 13302 | + (match_operand:SI 2 "register_operand" "r")] | ||
| 13303 | + UNSPEC_DIVMODSI4_INTERNAL))] | ||
| 13304 | + "" | ||
| 13305 | + "divs %0, %1, %2" | ||
| 13306 | + [(set_attr "type" "div") | ||
| 13307 | + (set_attr "cc" "none")]) | ||
| 13308 | + | ||
| 13309 | + | ||
| 13310 | +;;============================================================================= | ||
| 13311 | +;; udivmod | ||
| 13312 | +;;----------------------------------------------------------------------------- | ||
| 13313 | +;; Unsigned division that produces both a quotient and a remainder. | ||
| 13314 | +;;============================================================================= | ||
| 13315 | +(define_expand "udivmodsi4" | ||
| 13316 | + [(parallel [ | ||
| 13317 | + (parallel [ | ||
| 13318 | + (set (match_operand:SI 0 "register_operand" "=r") | ||
| 13319 | + (udiv:SI (match_operand:SI 1 "register_operand" "r") | ||
| 13320 | + (match_operand:SI 2 "register_operand" "r"))) | ||
| 13321 | + (set (match_operand:SI 3 "register_operand" "=r") | ||
| 13322 | + (umod:SI (match_dup 1) | ||
| 13323 | + (match_dup 2)))]) | ||
| 13324 | + (use (match_dup 4))])] | ||
| 13325 | + "" | ||
| 13326 | + { | ||
| 13327 | + if (! no_new_pseudos) { | ||
| 13328 | + operands[4] = gen_reg_rtx (DImode); | ||
| 13329 | + | ||
| 13330 | + emit_insn(gen_udivmodsi4_internal(operands[4],operands[1],operands[2])); | ||
| 13331 | + emit_move_insn(operands[0], gen_rtx_SUBREG( SImode, operands[4], 4)); | ||
| 13332 | + emit_move_insn(operands[3], gen_rtx_SUBREG( SImode, operands[4], 0)); | ||
| 13333 | + | ||
| 13334 | + DONE; | ||
| 13335 | + } else { | ||
| 13336 | + FAIL; | ||
| 13337 | + } | ||
| 13338 | + }) | ||
| 13339 | + | ||
| 13340 | +(define_insn "udivmodsi4_internal" | ||
| 13341 | + [(set (match_operand:DI 0 "register_operand" "=r") | ||
| 13342 | + (unspec:DI [(match_operand:SI 1 "register_operand" "r") | ||
| 13343 | + (match_operand:SI 2 "register_operand" "r")] | ||
| 13344 | + UNSPEC_UDIVMODSI4_INTERNAL))] | ||
| 13345 | + "" | ||
| 13346 | + "divu %0, %1, %2" | ||
| 13347 | + [(set_attr "type" "div") | ||
| 13348 | + (set_attr "cc" "none")]) | ||
| 13349 | + | ||
| 13350 | + | ||
| 13351 | +;;============================================================================= | ||
| 13352 | +;; Arithmetic-shift left | ||
| 13353 | +;;----------------------------------------------------------------------------- | ||
| 13354 | +;; Arithmetic-shift reg0 left by reg2 or immediate value. | ||
| 13355 | +;;============================================================================= | ||
| 13356 | + | ||
| 13357 | +(define_insn "ashlsi3" | ||
| 13358 | + [(set (match_operand:SI 0 "register_operand" "=r,r,r") | ||
| 13359 | + (ashift:SI (match_operand:SI 1 "register_operand" "r,0,r") | ||
| 13360 | + (match_operand:SI 2 "nonmemory_operand" "r,Ku05,Ku05")))] | ||
| 13361 | + "" | ||
| 13362 | + "@ | ||
| 13363 | + lsl %0, %1, %2 | ||
| 13364 | + lsl %0, %2 | ||
| 13365 | + lsl %0, %1, %2" | ||
| 13366 | + [(set_attr "length" "4,2,4") | ||
| 13367 | + (set_attr "cc" "set_ncz")]) | ||
| 13368 | + | ||
| 13369 | +;;============================================================================= | ||
| 13370 | +;; Arithmetic-shift right | ||
| 13371 | +;;----------------------------------------------------------------------------- | ||
| 13372 | +;; Arithmetic-shift reg0 right by an immediate value. | ||
| 13373 | +;;============================================================================= | ||
| 13374 | + | ||
| 13375 | +(define_insn "ashrsi3" | ||
| 13376 | + [(set (match_operand:SI 0 "register_operand" "=r,r,r") | ||
| 13377 | + (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,0,r") | ||
| 13378 | + (match_operand:SI 2 "nonmemory_operand" "r,Ku05,Ku05")))] | ||
| 13379 | + "" | ||
| 13380 | + "@ | ||
| 13381 | + asr %0, %1, %2 | ||
| 13382 | + asr %0, %2 | ||
| 13383 | + asr %0, %1, %2" | ||
| 13384 | + [(set_attr "length" "4,2,4") | ||
| 13385 | + (set_attr "cc" "set_ncz")]) | ||
| 13386 | + | ||
| 13387 | +;;============================================================================= | ||
| 13388 | +;; Logical shift right | ||
| 13389 | +;;----------------------------------------------------------------------------- | ||
| 13390 | +;; Logical shift reg0 right by an immediate value. | ||
| 13391 | +;;============================================================================= | ||
| 13392 | + | ||
| 13393 | +(define_insn "lshrsi3" | ||
| 13394 | + [(set (match_operand:SI 0 "register_operand" "=r,r,r") | ||
| 13395 | + (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0,r") | ||
| 13396 | + (match_operand:SI 2 "nonmemory_operand" "r,Ku05,Ku05")))] | ||
| 13397 | + "" | ||
| 13398 | + "@ | ||
| 13399 | + lsr %0, %1, %2 | ||
| 13400 | + lsr %0, %2 | ||
| 13401 | + lsr %0, %1, %2" | ||
| 13402 | + [(set_attr "length" "4,2,4") | ||
| 13403 | + (set_attr "cc" "set_ncz")]) | ||
| 13404 | + | ||
| 13405 | + | ||
| 13406 | +;;============================================================================= | ||
| 13407 | +;; neg | ||
| 13408 | +;;----------------------------------------------------------------------------- | ||
| 13409 | +;; Negate operand 1 and store the result in operand 0. | ||
| 13410 | +;;============================================================================= | ||
| 13411 | +(define_insn "negsi2" | ||
| 13412 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 13413 | + (neg:SI (match_operand:SI 1 "register_operand" "0")))] | ||
| 13414 | + "" | ||
| 13415 | + "neg %0" | ||
| 13416 | + [(set_attr "length" "2") | ||
| 13417 | + (set_attr "cc" "set_vncz")]) | ||
| 13418 | + | ||
| 13419 | +;;============================================================================= | ||
| 13420 | +;; abs | ||
| 13421 | +;;----------------------------------------------------------------------------- | ||
| 13422 | +;; Store the absolute value of operand 1 into operand 0. | ||
| 13423 | +;;============================================================================= | ||
| 13424 | +(define_insn "abssi2" | ||
| 13425 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 13426 | + (abs:SI (match_operand:SI 1 "register_operand" "0")))] | ||
| 13427 | + "" | ||
| 13428 | + "abs %0" | ||
| 13429 | + [(set_attr "length" "2") | ||
| 13430 | + (set_attr "cc" "set_z")]) | ||
| 13431 | + | ||
| 13432 | + | ||
| 13433 | +;;============================================================================= | ||
| 13434 | +;; one_cmpl | ||
| 13435 | +;;----------------------------------------------------------------------------- | ||
| 13436 | +;; Store the bitwise-complement of operand 1 into operand 0. | ||
| 13437 | +;;============================================================================= | ||
| 13438 | + | ||
| 13439 | +(define_insn "one_cmplsi2" | ||
| 13440 | + [(set (match_operand:SI 0 "register_operand" "=r,r") | ||
| 13441 | + (not:SI (match_operand:SI 1 "register_operand" "r,0")))] | ||
| 13442 | + "" | ||
| 13443 | + "@ | ||
| 13444 | + rsub %0, %1, -1 | ||
| 13445 | + com %0" | ||
| 13446 | + [(set_attr "length" "4,2") | ||
| 13447 | + (set_attr "cc" "set_z")]) | ||
| 13448 | + | ||
| 13449 | + | ||
| 13450 | +;;============================================================================= | ||
| 13451 | +;; Bit load | ||
| 13452 | +;;----------------------------------------------------------------------------- | ||
| 13453 | +;; Load a bit into Z and C flags | ||
| 13454 | +;;============================================================================= | ||
| 13455 | +(define_insn "bldsi" | ||
| 13456 | + [(set (cc0) | ||
| 13457 | + (and:SI (match_operand:SI 0 "register_operand" "r") | ||
| 13458 | + (match_operand:SI 1 "one_bit_set_operand" "i")))] | ||
| 13459 | + "" | ||
| 13460 | + "bld\t%0, %p1" | ||
| 13461 | + [(set_attr "length" "4") | ||
| 13462 | + (set_attr "cc" "bld")] | ||
| 13463 | + ) | ||
| 13464 | + | ||
| 13465 | + | ||
| 13466 | +;;============================================================================= | ||
| 13467 | +;; Compare | ||
| 13468 | +;;----------------------------------------------------------------------------- | ||
| 13469 | +;; Compare reg0 with reg1 or an immediate value. | ||
| 13470 | +;;============================================================================= | ||
| 13471 | + | ||
| 13472 | +(define_expand "cmpqi" | ||
| 13473 | + [(set (cc0) | ||
| 13474 | + (compare:QI | ||
| 13475 | + (match_operand:QI 0 "general_operand" "") | ||
| 13476 | + (match_operand:QI 1 "general_operand" "")))] | ||
| 13477 | + "" | ||
| 13478 | + "{ | ||
| 13479 | + | ||
| 13480 | + if ( GET_CODE(operands[0]) != REG | ||
| 13481 | + && GET_CODE(operands[0]) != SUBREG) | ||
| 13482 | + operands[0] = force_reg(QImode, operands[0]); | ||
| 13483 | + | ||
| 13484 | + | ||
| 13485 | + if ( GET_CODE(operands[1]) != REG | ||
| 13486 | + && GET_CODE(operands[1]) != SUBREG ) | ||
| 13487 | + operands[1] = force_reg(QImode, operands[1]); | ||
| 13488 | + | ||
| 13489 | + avr32_compare_op0 = operands[0]; | ||
| 13490 | + avr32_compare_op1 = operands[1]; | ||
| 13491 | + emit_insn(gen_cmpqi_internal(operands[0], operands[1])); | ||
| 13492 | + DONE; | ||
| 13493 | + }" | ||
| 13494 | +) | ||
| 13495 | + | ||
| 13496 | +(define_insn "cmpqi_internal" | ||
| 13497 | + [(set (cc0) | ||
| 13498 | + (compare:QI | ||
| 13499 | + (match_operand:QI 0 "register_operand" "r") | ||
| 13500 | + (match_operand:QI 1 "register_operand" "r")))] | ||
| 13501 | + "" | ||
| 13502 | + { | ||
| 13503 | + set_next_insn_cond(insn, | ||
| 13504 | + avr32_output_cmp(get_next_insn_cond(insn), QImode, operands[0], operands[1])); | ||
| 13505 | + return ""; | ||
| 13506 | + } | ||
| 13507 | + [(set_attr "length" "4") | ||
| 13508 | + (set_attr "cc" "compare")]) | ||
| 13509 | + | ||
| 13510 | +(define_expand "cmphi" | ||
| 13511 | + [(set (cc0) | ||
| 13512 | + (compare:HI | ||
| 13513 | + (match_operand:HI 0 "general_operand" "") | ||
| 13514 | + (match_operand:HI 1 "general_operand" "")))] | ||
| 13515 | + "" | ||
| 13516 | + "{ | ||
| 13517 | + if ( GET_CODE(operands[0]) != REG | ||
| 13518 | + && GET_CODE(operands[0]) != SUBREG ) | ||
| 13519 | + operands[0] = force_reg(HImode, operands[0]); | ||
| 13520 | + | ||
| 13521 | + | ||
| 13522 | + if ( GET_CODE(operands[1]) != REG | ||
| 13523 | + && GET_CODE(operands[1]) != SUBREG) | ||
| 13524 | + operands[1] = force_reg(HImode, operands[1]); | ||
| 13525 | + | ||
| 13526 | + avr32_compare_op0 = operands[0]; | ||
| 13527 | + avr32_compare_op1 = operands[1]; | ||
| 13528 | + emit_insn(gen_cmphi_internal(operands[0], operands[1])); | ||
| 13529 | + DONE; | ||
| 13530 | + }" | ||
| 13531 | +) | ||
| 13532 | + | ||
| 13533 | + | ||
| 13534 | +(define_insn "cmphi_internal" | ||
| 13535 | + [(set (cc0) | ||
| 13536 | + (compare:HI | ||
| 13537 | + (match_operand:HI 0 "register_operand" "r") | ||
| 13538 | + (match_operand:HI 1 "register_operand" "r")))] | ||
| 13539 | + "" | ||
| 13540 | + { | ||
| 13541 | + set_next_insn_cond(insn, | ||
| 13542 | + avr32_output_cmp(get_next_insn_cond(insn), HImode, operands[0], operands[1])); | ||
| 13543 | + return ""; | ||
| 13544 | + } | ||
| 13545 | + [(set_attr "length" "4") | ||
| 13546 | + (set_attr "cc" "compare")]) | ||
| 13547 | + | ||
| 13548 | + | ||
| 13549 | +(define_expand "cmpsi" | ||
| 13550 | + [(set (cc0) | ||
| 13551 | + (compare:SI | ||
| 13552 | + (match_operand:SI 0 "general_operand" "") | ||
| 13553 | + (match_operand:SI 1 "general_operand" "")))] | ||
| 13554 | + "" | ||
| 13555 | + "{ | ||
| 13556 | + if ( GET_CODE(operands[0]) != REG | ||
| 13557 | + && GET_CODE(operands[0]) != SUBREG ) | ||
| 13558 | + operands[0] = force_reg(SImode, operands[0]); | ||
| 13559 | + | ||
| 13560 | + if ( GET_CODE(operands[1]) != REG | ||
| 13561 | + && GET_CODE(operands[1]) != SUBREG | ||
| 13562 | + && GET_CODE(operands[1]) != CONST_INT ) | ||
| 13563 | + operands[1] = force_reg(SImode, operands[1]); | ||
| 13564 | + | ||
| 13565 | + avr32_compare_op0 = operands[0]; | ||
| 13566 | + avr32_compare_op1 = operands[1]; | ||
| 13567 | + | ||
| 13568 | + | ||
| 13569 | + emit_insn(gen_cmpsi_internal(operands[0], operands[1])); | ||
| 13570 | + DONE; | ||
| 13571 | + }" | ||
| 13572 | +) | ||
| 13573 | + | ||
| 13574 | + | ||
| 13575 | + | ||
| 13576 | + | ||
| 13577 | +(define_insn "cmpsi_internal" | ||
| 13578 | + [(set (cc0) | ||
| 13579 | + (compare:SI | ||
| 13580 | + (match_operand:SI 0 "register_operand" "r, r, r") | ||
| 13581 | + (match_operand:SI 1 "nonmemory_operand" "r, Ks06, Ks21")))] | ||
| 13582 | + "" | ||
| 13583 | + { | ||
| 13584 | + set_next_insn_cond(insn, | ||
| 13585 | + avr32_output_cmp(get_next_insn_cond(insn), SImode, operands[0], operands[1])); | ||
| 13586 | + return ""; | ||
| 13587 | + } | ||
| 13588 | + | ||
| 13589 | + [(set_attr "length" "2,2,4") | ||
| 13590 | + (set_attr "cc" "compare")]) | ||
| 13591 | + | ||
| 13592 | + | ||
| 13593 | +(define_expand "cmpdi" | ||
| 13594 | + [(set (cc0) | ||
| 13595 | + (compare:DI | ||
| 13596 | + (match_operand:DI 0 "register_operand" "") | ||
| 13597 | + (match_operand:DI 1 "register_operand" "")))] | ||
| 13598 | + "" | ||
| 13599 | + { | ||
| 13600 | + avr32_compare_op0 = operands[0]; | ||
| 13601 | + avr32_compare_op1 = operands[1]; | ||
| 13602 | + emit_insn(gen_cmpdi_internal(operands[0], operands[1])); | ||
| 13603 | + DONE; | ||
| 13604 | + } | ||
| 13605 | +) | ||
| 13606 | + | ||
| 13607 | +(define_insn "cmpdi_internal" | ||
| 13608 | + [(set (cc0) | ||
| 13609 | + (compare:DI | ||
| 13610 | + (match_operand:DI 0 "register_operand" "r") | ||
| 13611 | + (match_operand:DI 1 "register_operand" "r")))] | ||
| 13612 | + "" | ||
| 13613 | + { | ||
| 13614 | + set_next_insn_cond(insn, | ||
| 13615 | + avr32_output_cmp(get_next_insn_cond(insn), DImode, operands[0], operands[1])); | ||
| 13616 | + return ""; | ||
| 13617 | + } | ||
| 13618 | + | ||
| 13619 | + [(set_attr "length" "6") | ||
| 13620 | + (set_attr "type" "alu2") | ||
| 13621 | + (set_attr "cc" "compare")]) | ||
| 13622 | + | ||
| 13623 | + | ||
| 13624 | + | ||
| 13625 | +;;============================================================================= | ||
| 13626 | +;; Test if zero | ||
| 13627 | +;;----------------------------------------------------------------------------- | ||
| 13628 | +;; Compare reg against zero and set the condition codes. | ||
| 13629 | +;;============================================================================= | ||
| 13630 | + | ||
| 13631 | + | ||
| 13632 | +(define_expand "tstsi" | ||
| 13633 | + [(set (cc0) | ||
| 13634 | + (match_operand:SI 0 "register_operand" ""))] | ||
| 13635 | + "" | ||
| 13636 | + { | ||
| 13637 | + avr32_compare_op0 = operands[0]; | ||
| 13638 | + avr32_compare_op1 = gen_rtx_CONST_INT(SImode, 0); | ||
| 13639 | + emit_insn(gen_tstsi_internal(operands[0])); | ||
| 13640 | + DONE; | ||
| 13641 | + } | ||
| 13642 | +) | ||
| 13643 | + | ||
| 13644 | +(define_insn "tstsi_internal" | ||
| 13645 | + [(set (cc0) | ||
| 13646 | + (match_operand:SI 0 "register_operand" "r"))] | ||
| 13647 | + "" | ||
| 13648 | + { | ||
| 13649 | + set_next_insn_cond(insn, | ||
| 13650 | + avr32_output_cmp(get_next_insn_cond(insn), SImode, operands[0], const0_rtx)); | ||
| 13651 | + | ||
| 13652 | + return ""; | ||
| 13653 | + } | ||
| 13654 | + [(set_attr "length" "2") | ||
| 13655 | + (set_attr "cc" "compare")]) | ||
| 13656 | + | ||
| 13657 | + | ||
| 13658 | +(define_expand "tstdi" | ||
| 13659 | + [(set (cc0) | ||
| 13660 | + (match_operand:DI 0 "register_operand" ""))] | ||
| 13661 | + "" | ||
| 13662 | + { | ||
| 13663 | + avr32_compare_op0 = operands[0]; | ||
| 13664 | + avr32_compare_op1 = gen_rtx_CONST_INT(DImode, 0); | ||
| 13665 | + emit_insn(gen_tstdi_internal(operands[0])); | ||
| 13666 | + DONE; | ||
| 13667 | + } | ||
| 13668 | +) | ||
| 13669 | + | ||
| 13670 | +(define_insn "tstdi_internal" | ||
| 13671 | + [(set (cc0) | ||
| 13672 | + (match_operand:DI 0 "register_operand" "r"))] | ||
| 13673 | + "" | ||
| 13674 | + { | ||
| 13675 | + set_next_insn_cond(insn, | ||
| 13676 | + avr32_output_cmp(get_next_insn_cond(insn), DImode, operands[0], const0_rtx)); | ||
| 13677 | + return ""; | ||
| 13678 | + } | ||
| 13679 | + [(set_attr "length" "4") | ||
| 13680 | + (set_attr "type" "alu2") | ||
| 13681 | + (set_attr "cc" "compare")]) | ||
| 13682 | + | ||
| 13683 | + | ||
| 13684 | + | ||
| 13685 | +;;============================================================================= | ||
| 13686 | +;; Convert operands | ||
| 13687 | +;;----------------------------------------------------------------------------- | ||
| 13688 | +;; | ||
| 13689 | +;;============================================================================= | ||
| 13690 | +(define_insn "truncdisi2" | ||
| 13691 | + [(set (match_operand:SI 0 "general_operand" "") | ||
| 13692 | + (truncate:SI (match_operand:DI 1 "general_operand" "")))] | ||
| 13693 | + "" | ||
| 13694 | + "truncdisi2") | ||
| 13695 | + | ||
| 13696 | +;;============================================================================= | ||
| 13697 | +;; Extend | ||
| 13698 | +;;----------------------------------------------------------------------------- | ||
| 13699 | +;; | ||
| 13700 | +;;============================================================================= | ||
| 13701 | + | ||
| 13702 | + | ||
| 13703 | +(define_insn "extendhisi2" | ||
| 13704 | + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") | ||
| 13705 | + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r,<RKu00>,m")))] | ||
| 13706 | + "" | ||
| 13707 | + { | ||
| 13708 | + switch ( which_alternative ){ | ||
| 13709 | + case 0: | ||
| 13710 | + return "casts.h\t%0"; | ||
| 13711 | + case 1: | ||
| 13712 | + return "bfexts\t%0, %1, 0, 16"; | ||
| 13713 | + case 2: | ||
| 13714 | + case 3: | ||
| 13715 | + return "ld.sh\t%0, %1"; | ||
| 13716 | + default: | ||
| 13717 | + abort(); | ||
| 13718 | + } | ||
| 13719 | + } | ||
| 13720 | + [(set_attr "length" "2,4,2,4") | ||
| 13721 | + (set_attr "cc" "set_ncz,set_ncz,none,none") | ||
| 13722 | + (set_attr "type" "alu,alu,load_rm,load_rm")]) | ||
| 13723 | + | ||
| 13724 | +(define_insn "extendqisi2" | ||
| 13725 | + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") | ||
| 13726 | + (sign_extend:SI (match_operand:QI 1 "extendqi_operand" "0,r,RKu00,m")))] | ||
| 13727 | + "" | ||
| 13728 | + { | ||
| 13729 | + switch ( which_alternative ){ | ||
| 13730 | + case 0: | ||
| 13731 | + return "casts.b\t%0"; | ||
| 13732 | + case 1: | ||
| 13733 | + return "bfexts\t%0, %1, 0, 8"; | ||
| 13734 | + case 2: | ||
| 13735 | + case 3: | ||
| 13736 | + return "ld.sb\t%0, %1"; | ||
| 13737 | + default: | ||
| 13738 | + abort(); | ||
| 13739 | + } | ||
| 13740 | + } | ||
| 13741 | + [(set_attr "length" "2,4,2,4") | ||
| 13742 | + (set_attr "cc" "set_ncz,set_ncz,none,none") | ||
| 13743 | + (set_attr "type" "alu,alu,load_rm,load_rm")]) | ||
| 13744 | + | ||
| 13745 | +(define_insn "extendqihi2" | ||
| 13746 | + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") | ||
| 13747 | + (sign_extend:HI (match_operand:QI 1 "extendqi_operand" "0,r,RKu00,m")))] | ||
| 13748 | + "" | ||
| 13749 | + { | ||
| 13750 | + switch ( which_alternative ){ | ||
| 13751 | + case 0: | ||
| 13752 | + return "casts.b\t%0"; | ||
| 13753 | + case 1: | ||
| 13754 | + return "bfexts\t%0, %1, 0, 8"; | ||
| 13755 | + case 2: | ||
| 13756 | + case 3: | ||
| 13757 | + return "ld.sb\t%0, %1"; | ||
| 13758 | + default: | ||
| 13759 | + abort(); | ||
| 13760 | + } | ||
| 13761 | + } | ||
| 13762 | + [(set_attr "length" "2,4,2,4") | ||
| 13763 | + (set_attr "cc" "set_ncz,set_ncz,none,none") | ||
| 13764 | + (set_attr "type" "alu,alu,load_rm,load_rm")]) | ||
| 13765 | + | ||
| 13766 | + | ||
| 13767 | +;;============================================================================= | ||
| 13768 | +;; Zero-extend | ||
| 13769 | +;;----------------------------------------------------------------------------- | ||
| 13770 | +;; | ||
| 13771 | +;;============================================================================= | ||
| 13772 | + | ||
| 13773 | +(define_insn "zero_extendhisi2" | ||
| 13774 | + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") | ||
| 13775 | + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r,<RKu00>,m")))] | ||
| 13776 | + "" | ||
| 13777 | + { | ||
| 13778 | + switch ( which_alternative ){ | ||
| 13779 | + case 0: | ||
| 13780 | + return "castu.h\t%0"; | ||
| 13781 | + case 1: | ||
| 13782 | + return "bfextu\t%0, %1, 0, 16"; | ||
| 13783 | + case 2: | ||
| 13784 | + case 3: | ||
| 13785 | + return "ld.uh\t%0, %1"; | ||
| 13786 | + default: | ||
| 13787 | + abort(); | ||
| 13788 | + } | ||
| 13789 | + } | ||
| 13790 | + | ||
| 13791 | + [(set_attr "length" "2,4,2,4") | ||
| 13792 | + (set_attr "cc" "set_ncz,set_ncz,none,none") | ||
| 13793 | + (set_attr "type" "alu,alu,load_rm,load_rm")]) | ||
| 13794 | + | ||
| 13795 | +(define_insn "zero_extendqisi2" | ||
| 13796 | + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") | ||
| 13797 | + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,r,<RKu00>,m")))] | ||
| 13798 | + "" | ||
| 13799 | + { | ||
| 13800 | + switch ( which_alternative ){ | ||
| 13801 | + case 0: | ||
| 13802 | + return "castu.b\t%0"; | ||
| 13803 | + case 1: | ||
| 13804 | + return "bfextu\t%0, %1, 0, 8"; | ||
| 13805 | + case 2: | ||
| 13806 | + case 3: | ||
| 13807 | + return "ld.ub\t%0, %1"; | ||
| 13808 | + default: | ||
| 13809 | + abort(); | ||
| 13810 | + } | ||
| 13811 | + } | ||
| 13812 | + [(set_attr "length" "2,4,2,4") | ||
| 13813 | + (set_attr "cc" "set_ncz, set_ncz, none, none") | ||
| 13814 | + (set_attr "type" "alu, alu, load_rm, load_rm")]) | ||
| 13815 | + | ||
| 13816 | +(define_insn "zero_extendqihi2" | ||
| 13817 | + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") | ||
| 13818 | + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,r,<RKu00>,m")))] | ||
| 13819 | + "" | ||
| 13820 | + { | ||
| 13821 | + switch ( which_alternative ){ | ||
| 13822 | + case 0: | ||
| 13823 | + return "castu.b\t%0"; | ||
| 13824 | + case 1: | ||
| 13825 | + return "bfextu\t%0, %1, 0, 8"; | ||
| 13826 | + case 2: | ||
| 13827 | + case 3: | ||
| 13828 | + return "ld.ub\t%0, %1"; | ||
| 13829 | + default: | ||
| 13830 | + abort(); | ||
| 13831 | + } | ||
| 13832 | + } | ||
| 13833 | + [(set_attr "length" "2,4,2,4") | ||
| 13834 | + (set_attr "cc" "set_ncz, set_ncz, none, none") | ||
| 13835 | + (set_attr "type" "alu, alu, load_rm, load_rm")]) | ||
| 13836 | + | ||
| 13837 | + | ||
| 13838 | + | ||
| 13839 | +;;============================================================================= | ||
| 13840 | +;; Conditional set register | ||
| 13841 | +;; sr{cond4} rd | ||
| 13842 | +;;----------------------------------------------------------------------------- | ||
| 13843 | + | ||
| 13844 | +;;Because of the same issue as with conditional moves and adds we must | ||
| 13845 | +;;not separate the compare instrcution from the scc instruction as | ||
| 13846 | +;;they might be sheduled "badly". | ||
| 13847 | + | ||
| 13848 | +(define_expand "s<code>" | ||
| 13849 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 13850 | + (any_cond (cc0) | ||
| 13851 | + (const_int 0)))] | ||
| 13852 | + "" | ||
| 13853 | + { | ||
| 13854 | + if ( !avr32_expand_scc(<CODE>, operands) ){ | ||
| 13855 | + FAIL; | ||
| 13856 | + } | ||
| 13857 | + DONE; | ||
| 13858 | + } | ||
| 13859 | + ) | ||
| 13860 | + | ||
| 13861 | + | ||
| 13862 | +(define_insn "comparesi_and_set" | ||
| 13863 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 13864 | + (match_operator 1 "avr32_comparison_operator" | ||
| 13865 | + [ (compare (match_operand:SI 2 "register_operand" "r") | ||
| 13866 | + (match_operand:SI 3 "general_operand" "rKs06Ks21")) | ||
| 13867 | + (const_int 0)]))] | ||
| 13868 | + "" | ||
| 13869 | + { | ||
| 13870 | + operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[2]), operands[2], operands[3]); | ||
| 13871 | + return "sr%1\t%0"; | ||
| 13872 | + } | ||
| 13873 | + [(set_attr "length" "6") | ||
| 13874 | + (set_attr "cc" "clobber")]) | ||
| 13875 | + | ||
| 13876 | +(define_insn "comparehi_and_set" | ||
| 13877 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 13878 | + (match_operator 1 "avr32_comparison_operator" | ||
| 13879 | + [ (compare (match_operand:HI 2 "register_operand" "r") | ||
| 13880 | + (match_operand:HI 3 "register_operand" "r")) | ||
| 13881 | + (const_int 0)]))] | ||
| 13882 | + "" | ||
| 13883 | + { | ||
| 13884 | + operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[2]), operands[2], operands[3]); | ||
| 13885 | + return "sr%1\t%0"; | ||
| 13886 | + } | ||
| 13887 | + [(set_attr "length" "6") | ||
| 13888 | + (set_attr "cc" "clobber")]) | ||
| 13889 | + | ||
| 13890 | +(define_insn "compareqi_and_set" | ||
| 13891 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 13892 | + (match_operator 1 "avr32_comparison_operator" | ||
| 13893 | + [ (compare (match_operand:QI 2 "register_operand" "r") | ||
| 13894 | + (match_operand:QI 3 "register_operand" "r")) | ||
| 13895 | + (const_int 0)]))] | ||
| 13896 | + "" | ||
| 13897 | + { | ||
| 13898 | + operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[2]), operands[2], operands[3]); | ||
| 13899 | + return "sr%1\t%0"; | ||
| 13900 | + } | ||
| 13901 | + [(set_attr "length" "6") | ||
| 13902 | + (set_attr "cc" "clobber")]) | ||
| 13903 | + | ||
| 13904 | +(define_insn "*comparedi_and_set" | ||
| 13905 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 13906 | + (match_operator 1 "avr32_comparison_operator" | ||
| 13907 | + [ (compare (match_operand:DI 2 "register_operand" "r") | ||
| 13908 | + (match_operand:DI 3 "register_operand" "r")) | ||
| 13909 | + (const_int 0)]))] | ||
| 13910 | + "" | ||
| 13911 | + { | ||
| 13912 | + operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[2]), operands[2], operands[3]); | ||
| 13913 | + return "sr%1\t%0"; | ||
| 13914 | + } | ||
| 13915 | + [(set_attr "length" "6") | ||
| 13916 | + (set_attr "cc" "clobber")]) | ||
| 13917 | + | ||
| 13918 | +(define_insn "*tstdi_and_set" | ||
| 13919 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 13920 | + (match_operator 1 "avr32_comparison_operator" | ||
| 13921 | + [ (compare (match_operand:DI 2 "register_operand" "r") | ||
| 13922 | + (const_int 0)) | ||
| 13923 | + (const_int 0)]))] | ||
| 13924 | + "" | ||
| 13925 | + { | ||
| 13926 | + operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[2]), operands[2], const0_rtx); | ||
| 13927 | + return "sr%1\t%0"; | ||
| 13928 | + } | ||
| 13929 | + [(set_attr "length" "6") | ||
| 13930 | + (set_attr "cc" "clobber")]) | ||
| 13931 | + | ||
| 13932 | + | ||
| 13933 | + | ||
| 13934 | +;;============================================================================= | ||
| 13935 | +;; Conditional branch | ||
| 13936 | +;;----------------------------------------------------------------------------- | ||
| 13937 | +;; Branch to label if the specified condition codes are set. | ||
| 13938 | +;;============================================================================= | ||
| 13939 | +; branch if negative | ||
| 13940 | +(define_insn "bmi" | ||
| 13941 | + [(set (pc) | ||
| 13942 | + (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_MI) | ||
| 13943 | + (label_ref (match_operand 0 "" "")) | ||
| 13944 | + (pc)))] | ||
| 13945 | + "" | ||
| 13946 | + "brmi %0" | ||
| 13947 | + [(set_attr "type" "branch") | ||
| 13948 | + (set (attr "length") | ||
| 13949 | + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254)) | ||
| 13950 | + (le (minus (pc) (match_dup 0)) (const_int 256))) | ||
| 13951 | + (const_int 2)] ; use compact branch | ||
| 13952 | + (const_int 4))) ; use extended branch | ||
| 13953 | + (set_attr "cc" "none")]) | ||
| 13954 | + | ||
| 13955 | +(define_insn "*bmi-reverse" | ||
| 13956 | + [(set (pc) | ||
| 13957 | + (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_MI) | ||
| 13958 | + (pc) | ||
| 13959 | + (label_ref (match_operand 0 "" ""))))] | ||
| 13960 | + "" | ||
| 13961 | + "brpl %0" | ||
| 13962 | + [(set_attr "type" "branch") | ||
| 13963 | + (set (attr "length") | ||
| 13964 | + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254)) | ||
| 13965 | + (le (minus (pc) (match_dup 0)) (const_int 256))) | ||
| 13966 | + (const_int 2)] ; use compact branch | ||
| 13967 | + (const_int 4))) ; use extended branch | ||
| 13968 | + (set_attr "cc" "none")]) | ||
| 13969 | + | ||
| 13970 | +; branch if positive | ||
| 13971 | +(define_insn "bpl" | ||
| 13972 | + [(set (pc) | ||
| 13973 | + (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_PL) | ||
| 13974 | + (label_ref (match_operand 0 "" "")) | ||
| 13975 | + (pc)))] | ||
| 13976 | + "" | ||
| 13977 | + "brpl %0" | ||
| 13978 | + [(set_attr "type" "branch") | ||
| 13979 | + (set (attr "length") | ||
| 13980 | + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254)) | ||
| 13981 | + (le (minus (pc) (match_dup 0)) (const_int 256))) | ||
| 13982 | + (const_int 2)] ; use compact branch | ||
| 13983 | + (const_int 4))) ; use extended branch | ||
| 13984 | + (set_attr "cc" "none")]) | ||
| 13985 | + | ||
| 13986 | +(define_insn "*bpl-reverse" | ||
| 13987 | + [(set (pc) | ||
| 13988 | + (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_PL) | ||
| 13989 | + (pc) | ||
| 13990 | + (label_ref (match_operand 0 "" ""))))] | ||
| 13991 | + "" | ||
| 13992 | + "brmi %0" | ||
| 13993 | + [(set_attr "type" "branch") | ||
| 13994 | + (set (attr "length") | ||
| 13995 | + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254)) | ||
| 13996 | + (le (minus (pc) (match_dup 0)) (const_int 256))) | ||
| 13997 | + (const_int 2)] ; use compact branch | ||
| 13998 | + (const_int 4))) ; use extended branch | ||
| 13999 | + (set_attr "cc" "none")]) | ||
| 14000 | + | ||
| 14001 | +; branch if equal | ||
| 14002 | +(define_insn "b<code>" | ||
| 14003 | + [(set (pc) | ||
| 14004 | + (if_then_else (any_cond:CC (cc0) | ||
| 14005 | + (const_int 0)) | ||
| 14006 | + (label_ref (match_operand 0 "" "")) | ||
| 14007 | + (pc)))] | ||
| 14008 | + "" | ||
| 14009 | + "br<cond> %0 " | ||
| 14010 | + [(set_attr "type" "branch") | ||
| 14011 | + (set (attr "length") | ||
| 14012 | + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254)) | ||
| 14013 | + (le (minus (pc) (match_dup 0)) (const_int 256))) | ||
| 14014 | + (const_int 2)] ; use compact branch | ||
| 14015 | + (const_int 4))) ; use extended branch | ||
| 14016 | + (set_attr "cc" "none")]) | ||
| 14017 | + | ||
| 14018 | + | ||
| 14019 | +(define_insn "*b<code>-reverse" | ||
| 14020 | + [(set (pc) | ||
| 14021 | + (if_then_else (any_cond:CC (cc0) | ||
| 14022 | + (const_int 0)) | ||
| 14023 | + (pc) | ||
| 14024 | + (label_ref (match_operand 0 "" ""))))] | ||
| 14025 | + "" | ||
| 14026 | + "br<invcond> %0 " | ||
| 14027 | + [(set_attr "type" "branch") | ||
| 14028 | + (set (attr "length") | ||
| 14029 | + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254)) | ||
| 14030 | + (le (minus (pc) (match_dup 0)) (const_int 256))) | ||
| 14031 | + (const_int 2)] ; use compact branch | ||
| 14032 | + (const_int 4))) ; use extended branch | ||
| 14033 | + (set_attr "cc" "none")]) | ||
| 14034 | + | ||
| 14035 | + | ||
| 14036 | + | ||
| 14037 | +;============================================================================= | ||
| 14038 | +; Conditional Add/Subtract | ||
| 14039 | +;----------------------------------------------------------------------------- | ||
| 14040 | +; sub{cond4} Rd, imm | ||
| 14041 | +;============================================================================= | ||
| 14042 | + | ||
| 14043 | + | ||
| 14044 | +(define_expand "add<mode>cc" | ||
| 14045 | + [(set (match_operand:ADDCC 0 "register_operand" "") | ||
| 14046 | + (if_then_else:ADDCC (match_operand 1 "avr32_comparison_operator" "") | ||
| 14047 | + (match_operand:ADDCC 2 "register_immediate_operand" "") | ||
| 14048 | + (match_operand:ADDCC 3 "register_immediate_operand" "")))] | ||
| 14049 | + "" | ||
| 14050 | + { | ||
| 14051 | + if ( avr32_expand_addcc(<MODE>mode, operands ) ) | ||
| 14052 | + DONE; | ||
| 14053 | + else | ||
| 14054 | + FAIL; | ||
| 14055 | + } | ||
| 14056 | + ) | ||
| 14057 | + | ||
| 14058 | + | ||
| 14059 | +(define_insn "add<ADDCC:mode>cc_cmp<CMP:mode>" | ||
| 14060 | + [(set (match_operand:ADDCC 0 "register_operand" "=&r") | ||
| 14061 | + (unspec:ADDCC [(match_operand 1 "avr32_comparison_operator" "") | ||
| 14062 | + (match_operand:ADDCC 2 "register_operand" "0") | ||
| 14063 | + (match_operand:ADDCC 3 "immediate_operand" "Ks08") | ||
| 14064 | + (match_operand:CMP 4 "register_operand" "r") | ||
| 14065 | + (match_operand:CMP 5 "<CMP:cmp_predicate>" "<CMP:cmp_constraint>") | ||
| 14066 | + ] | ||
| 14067 | + UNSPEC_ADDSICC ))] | ||
| 14068 | + "" | ||
| 14069 | + { | ||
| 14070 | + operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]); | ||
| 14071 | + | ||
| 14072 | + return "sub%1\t%0, %3"; | ||
| 14073 | + } | ||
| 14074 | + [(set_attr "length" "8") | ||
| 14075 | + (set_attr "cc" "clobber")]) | ||
| 14076 | + | ||
| 14077 | + | ||
| 14078 | +;============================================================================= | ||
| 14079 | +; Conditional Move | ||
| 14080 | +;----------------------------------------------------------------------------- | ||
| 14081 | +; mov{cond4} Rd, (Rs/imm) | ||
| 14082 | +;============================================================================= | ||
| 14083 | +(define_expand "mov<mode>cc" | ||
| 14084 | + [(set (match_operand:ADDCC 0 "register_operand" "") | ||
| 14085 | + (if_then_else:ADDCC (match_operand 1 "avr32_comparison_operator" "") | ||
| 14086 | + (match_operand:ADDCC 2 "register_immediate_operand" "") | ||
| 14087 | + (match_operand:ADDCC 3 "register_immediate_operand" "")))] | ||
| 14088 | + "" | ||
| 14089 | + { | ||
| 14090 | + if ( avr32_expand_movcc(<MODE>mode, operands ) ) | ||
| 14091 | + DONE; | ||
| 14092 | + else | ||
| 14093 | + FAIL; | ||
| 14094 | + } | ||
| 14095 | + ) | ||
| 14096 | + | ||
| 14097 | +(define_insn "mov<MOVCC:mode>cc_cmp<CMP:mode>" | ||
| 14098 | + [(set (match_operand:MOVCC 0 "register_operand" "=r,r,r") | ||
| 14099 | + (unspec:MOVCC [(match_operand 1 "avr32_comparison_operator" "") | ||
| 14100 | + (match_operand:MOVCC 2 "register_immediate_operand" "0,rKs08,rKs08") | ||
| 14101 | + (match_operand:MOVCC 3 "register_immediate_operand" "rKs08,0,rKs08") | ||
| 14102 | + (match_operand:CMP 4 "register_operand" "r, r, r") | ||
| 14103 | + (match_operand:CMP 5 "<CMP:cmp_predicate>" "<CMP:cmp_constraint>, <CMP:cmp_constraint>, <CMP:cmp_constraint>") | ||
| 14104 | + ] | ||
| 14105 | + UNSPEC_MOVSICC ))] | ||
| 14106 | + "" | ||
| 14107 | + { | ||
| 14108 | + operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]); | ||
| 14109 | + | ||
| 14110 | + switch( which_alternative ){ | ||
| 14111 | + case 0: | ||
| 14112 | + return "mov%i1 %0, %3"; | ||
| 14113 | + case 1: | ||
| 14114 | + return "mov%1 %0, %2"; | ||
| 14115 | + case 2: | ||
| 14116 | + return "mov%1 %0, %2\;mov%i1 %0, %3"; | ||
| 14117 | + default: | ||
| 14118 | + abort(); | ||
| 14119 | + } | ||
| 14120 | + | ||
| 14121 | + | ||
| 14122 | + } | ||
| 14123 | + [(set_attr "length" "8,8,12") | ||
| 14124 | + (set_attr "cc" "clobber")]) | ||
| 14125 | + | ||
| 14126 | + | ||
| 14127 | +;;============================================================================= | ||
| 14128 | +;; jump | ||
| 14129 | +;;----------------------------------------------------------------------------- | ||
| 14130 | +;; Jump inside a function; an unconditional branch to a label. | ||
| 14131 | +;;============================================================================= | ||
| 14132 | +(define_insn "jump" | ||
| 14133 | + [(set (pc) | ||
| 14134 | + (label_ref (match_operand 0 "" "")))] | ||
| 14135 | + "" | ||
| 14136 | + { | ||
| 14137 | + if (get_attr_length(insn) > 4) | ||
| 14138 | + return "Can't jump this far"; | ||
| 14139 | + return (get_attr_length(insn) == 2 ? | ||
| 14140 | + "rjmp %0" : "bral %0"); | ||
| 14141 | + } | ||
| 14142 | + [(set_attr "type" "branch") | ||
| 14143 | + (set (attr "length") | ||
| 14144 | + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 1022)) | ||
| 14145 | + (le (minus (pc) (match_dup 0)) (const_int 1024))) | ||
| 14146 | + (const_int 2) ; use rjmp | ||
| 14147 | + (le (match_dup 0) (const_int 1048575)) | ||
| 14148 | + (const_int 4)] ; use bral | ||
| 14149 | + (const_int 8))) ; do something else | ||
| 14150 | + (set_attr "cc" "none")]) | ||
| 14151 | + | ||
| 14152 | +;;============================================================================= | ||
| 14153 | +;; call | ||
| 14154 | +;;----------------------------------------------------------------------------- | ||
| 14155 | +;; Subroutine call instruction returning no value. | ||
| 14156 | +;;============================================================================= | ||
| 14157 | +(define_insn "call_internal" | ||
| 14158 | + [(parallel [(call (mem:SI (match_operand:SI 0 "avr32_call_operand" "r,U,T,W")) | ||
| 14159 | + (match_operand 1 "" "")) | ||
| 14160 | + (clobber (reg:SI LR_REGNUM))])] | ||
| 14161 | + "" | ||
| 14162 | + { | ||
| 14163 | + switch (which_alternative){ | ||
| 14164 | + case 0: | ||
| 14165 | + return "icall\t%0"; | ||
| 14166 | + case 1: | ||
| 14167 | + return "rcall\t%0"; | ||
| 14168 | + case 2: | ||
| 14169 | + return "mcall\t%0"; | ||
| 14170 | + case 3: | ||
| 14171 | + if ( TARGET_HAS_ASM_ADDR_PSEUDOS ) | ||
| 14172 | + return "call\t%0"; | ||
| 14173 | + else | ||
| 14174 | + return "mcall\tr6[%0@got]"; | ||
| 14175 | + default: | ||
| 14176 | + abort(); | ||
| 14177 | + } | ||
| 14178 | + } | ||
| 14179 | + [(set_attr "type" "call") | ||
| 14180 | + (set_attr "length" "2,4,4,10") | ||
| 14181 | + (set_attr "cc" "clobber")]) | ||
| 14182 | + | ||
| 14183 | + | ||
| 14184 | +(define_expand "call" | ||
| 14185 | + [(parallel [(call (match_operand:SI 0 "" "") | ||
| 14186 | + (match_operand 1 "" "")) | ||
| 14187 | + (clobber (reg:SI LR_REGNUM))])] | ||
| 14188 | + "" | ||
| 14189 | + { | ||
| 14190 | + rtx call_address; | ||
| 14191 | + if ( GET_CODE(operands[0]) != MEM ) | ||
| 14192 | + FAIL; | ||
| 14193 | + | ||
| 14194 | + call_address = XEXP(operands[0], 0); | ||
| 14195 | + | ||
| 14196 | + /* If assembler supports call pseudo insn and the call | ||
| 14197 | + address is a symbol then nothing special needs to be done. */ | ||
| 14198 | + if ( TARGET_HAS_ASM_ADDR_PSEUDOS | ||
| 14199 | + && (GET_CODE(call_address) == SYMBOL_REF) ){ | ||
| 14200 | + /* We must however mark the function as using the GOT if | ||
| 14201 | + flag_pic is set, since the call insn might turn into | ||
| 14202 | + a mcall using the GOT ptr register. */ | ||
| 14203 | + if ( flag_pic ){ | ||
| 14204 | + current_function_uses_pic_offset_table = 1; | ||
| 14205 | + emit_call_insn(gen_call_internal(call_address, operands[1])); | ||
| 14206 | + DONE; | ||
| 14207 | + } | ||
| 14208 | + } else { | ||
| 14209 | + if ( flag_pic && | ||
| 14210 | + GET_CODE(call_address) == SYMBOL_REF ){ | ||
| 14211 | + current_function_uses_pic_offset_table = 1; | ||
| 14212 | + emit_call_insn(gen_call_internal(call_address, operands[1])); | ||
| 14213 | + DONE; | ||
| 14214 | + } | ||
| 14215 | + | ||
| 14216 | + if ( !SYMBOL_REF_RCALL_FUNCTION_P(operands[0]) ){ | ||
| 14217 | + if ( optimize_size && | ||
| 14218 | + GET_CODE(call_address) == SYMBOL_REF ){ | ||
| 14219 | + call_address = force_const_mem(SImode, call_address); | ||
| 14220 | + } else { | ||
| 14221 | + call_address = force_reg(SImode, call_address); | ||
| 14222 | + } | ||
| 14223 | + } | ||
| 14224 | + } | ||
| 14225 | + emit_call_insn(gen_call_internal(call_address, operands[1])); | ||
| 14226 | + DONE; | ||
| 14227 | + } | ||
| 14228 | +) | ||
| 14229 | + | ||
| 14230 | +;;============================================================================= | ||
| 14231 | +;; call_value | ||
| 14232 | +;;----------------------------------------------------------------------------- | ||
| 14233 | +;; Subrutine call instruction returning a value. | ||
| 14234 | +;;============================================================================= | ||
| 14235 | +(define_expand "call_value" | ||
| 14236 | + [(parallel [(set (match_operand:SI 0 "" "") | ||
| 14237 | + (call (match_operand:SI 1 "" "") | ||
| 14238 | + (match_operand 2 "" ""))) | ||
| 14239 | + (clobber (reg:SI LR_REGNUM))])] | ||
| 14240 | + "" | ||
| 14241 | + { | ||
| 14242 | + rtx call_address; | ||
| 14243 | + if ( GET_CODE(operands[1]) != MEM ) | ||
| 14244 | + FAIL; | ||
| 14245 | + | ||
| 14246 | + call_address = XEXP(operands[1], 0); | ||
| 14247 | + | ||
| 14248 | + /* If assembler supports call pseudo insn and the call | ||
| 14249 | + address is a symbol then nothing special needs to be done. */ | ||
| 14250 | + if ( TARGET_HAS_ASM_ADDR_PSEUDOS | ||
| 14251 | + && (GET_CODE(call_address) == SYMBOL_REF) ){ | ||
| 14252 | + /* We must however mark the function as using the GOT if | ||
| 14253 | + flag_pic is set, since the call insn might turn into | ||
| 14254 | + a mcall using the GOT ptr register. */ | ||
| 14255 | + if ( flag_pic ) { | ||
| 14256 | + current_function_uses_pic_offset_table = 1; | ||
| 14257 | + emit_call_insn(gen_call_value_internal(operands[0], call_address, operands[2])); | ||
| 14258 | + DONE; | ||
| 14259 | + } | ||
| 14260 | + } else { | ||
| 14261 | + if ( flag_pic && | ||
| 14262 | + GET_CODE(call_address) == SYMBOL_REF ){ | ||
| 14263 | + current_function_uses_pic_offset_table = 1; | ||
| 14264 | + emit_call_insn(gen_call_value_internal(operands[0], call_address, operands[2])); | ||
| 14265 | + DONE; | ||
| 14266 | + } | ||
| 14267 | + | ||
| 14268 | + if ( !SYMBOL_REF_RCALL_FUNCTION_P(operands[1]) ){ | ||
| 14269 | + if ( optimize_size && | ||
| 14270 | + GET_CODE(call_address) == SYMBOL_REF){ | ||
| 14271 | + call_address = force_const_mem(SImode, call_address); | ||
| 14272 | + } else { | ||
| 14273 | + call_address = force_reg(SImode, call_address); | ||
| 14274 | + } | ||
| 14275 | + } | ||
| 14276 | + } | ||
| 14277 | + emit_call_insn(gen_call_value_internal(operands[0], call_address, | ||
| 14278 | + operands[2])); | ||
| 14279 | + DONE; | ||
| 14280 | + | ||
| 14281 | + }) | ||
| 14282 | + | ||
| 14283 | +(define_insn "call_value_internal" | ||
| 14284 | + [(parallel [(set (match_operand 0 "register_operand" "=r,r,r,r") | ||
| 14285 | + (call (mem:SI (match_operand:SI 1 "avr32_call_operand" "r,U,T,W")) | ||
| 14286 | + (match_operand 2 "" ""))) | ||
| 14287 | + (clobber (reg:SI LR_REGNUM))])] | ||
| 14288 | + ;; Operand 2 not used on the AVR32. | ||
| 14289 | + "" | ||
| 14290 | + { | ||
| 14291 | + switch (which_alternative){ | ||
| 14292 | + case 0: | ||
| 14293 | + return "icall\t%1"; | ||
| 14294 | + case 1: | ||
| 14295 | + return "rcall\t%1"; | ||
| 14296 | + case 2: | ||
| 14297 | + return "mcall\t%1"; | ||
| 14298 | + case 3: | ||
| 14299 | + if ( TARGET_HAS_ASM_ADDR_PSEUDOS ) | ||
| 14300 | + return "call\t%1"; | ||
| 14301 | + else | ||
| 14302 | + return "mcall\tr6[%1@got]"; | ||
| 14303 | + default: | ||
| 14304 | + abort(); | ||
| 14305 | + } | ||
| 14306 | + } | ||
| 14307 | + [(set_attr "type" "call") | ||
| 14308 | + (set_attr "length" "2,4,4,10") | ||
| 14309 | + (set_attr "cc" "call_set")]) | ||
| 14310 | + | ||
| 14311 | + | ||
| 14312 | +;;============================================================================= | ||
| 14313 | +;; untyped_call | ||
| 14314 | +;;----------------------------------------------------------------------------- | ||
| 14315 | +;; Subrutine call instruction returning a value of any type. | ||
| 14316 | +;; The code is copied from m68k.md (except gen_blockage is removed) | ||
| 14317 | +;; Fixme! | ||
| 14318 | +;;============================================================================= | ||
| 14319 | +(define_expand "untyped_call" | ||
| 14320 | + [(parallel [(call (match_operand 0 "avr32_call_operand" "") | ||
| 14321 | + (const_int 0)) | ||
| 14322 | + (match_operand 1 "" "") | ||
| 14323 | + (match_operand 2 "" "")])] | ||
| 14324 | + "" | ||
| 14325 | + { | ||
| 14326 | + int i; | ||
| 14327 | + | ||
| 14328 | + emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx)); | ||
| 14329 | + | ||
| 14330 | + for (i = 0; i < XVECLEN (operands[2], 0); i++) { | ||
| 14331 | + rtx set = XVECEXP (operands[2], 0, i); | ||
| 14332 | + emit_move_insn (SET_DEST (set), SET_SRC (set)); | ||
| 14333 | + } | ||
| 14334 | + | ||
| 14335 | + /* The optimizer does not know that the call sets the function value | ||
| 14336 | + registers we stored in the result block. We avoid problems by | ||
| 14337 | + claiming that all hard registers are used and clobbered at this | ||
| 14338 | + point. */ | ||
| 14339 | + emit_insn (gen_blockage ()); | ||
| 14340 | + | ||
| 14341 | + DONE; | ||
| 14342 | + }) | ||
| 14343 | + | ||
| 14344 | + | ||
| 14345 | +;;============================================================================= | ||
| 14346 | +;; return | ||
| 14347 | +;;============================================================================= | ||
| 14348 | + | ||
| 14349 | +(define_insn "return" | ||
| 14350 | + [(return)] | ||
| 14351 | + "USE_RETURN_INSN (FALSE)" | ||
| 14352 | + { | ||
| 14353 | + avr32_output_return_instruction(TRUE, FALSE, NULL, NULL); | ||
| 14354 | + return ""; | ||
| 14355 | + } | ||
| 14356 | + [(set_attr "length" "4") | ||
| 14357 | + (set_attr "type" "call")] | ||
| 14358 | + ) | ||
| 14359 | + | ||
| 14360 | +(define_insn "*return_value_imm" | ||
| 14361 | + [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i")) | ||
| 14362 | + (use (reg RETVAL_REGNUM)) | ||
| 14363 | + (return)])] | ||
| 14364 | + "USE_RETURN_INSN (FALSE) && | ||
| 14365 | + ((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))" | ||
| 14366 | + { | ||
| 14367 | + avr32_output_return_instruction(TRUE, FALSE, NULL, operands[0]); | ||
| 14368 | + return ""; | ||
| 14369 | + } | ||
| 14370 | + [(set_attr "length" "4") | ||
| 14371 | + (set_attr "type" "call")] | ||
| 14372 | + ) | ||
| 14373 | + | ||
| 14374 | +(define_insn "*return_value_si" | ||
| 14375 | + [(set (reg RETVAL_REGNUM) (match_operand:SI 0 "register_operand" "r")) | ||
| 14376 | + (use (reg RETVAL_REGNUM)) | ||
| 14377 | + (return)] | ||
| 14378 | + "USE_RETURN_INSN (TRUE)" | ||
| 14379 | + "retal %0"; | ||
| 14380 | + [(set_attr "type" "call")] | ||
| 14381 | + ) | ||
| 14382 | + | ||
| 14383 | +(define_insn "*return_value_hi" | ||
| 14384 | + [(parallel [(set (reg RETVAL_REGNUM) (match_operand:HI 0 "register_operand" "r")) | ||
| 14385 | + (use (reg RETVAL_REGNUM)) | ||
| 14386 | + (return)])] | ||
| 14387 | + "USE_RETURN_INSN (TRUE)" | ||
| 14388 | + "retal %0" | ||
| 14389 | + [(set_attr "type" "call")] | ||
| 14390 | + ) | ||
| 14391 | + | ||
| 14392 | +(define_insn "*return_value_qi" | ||
| 14393 | + [(parallel [(set (reg RETVAL_REGNUM) (match_operand:QI 0 "register_operand" "r")) | ||
| 14394 | + (use (reg RETVAL_REGNUM)) | ||
| 14395 | + (return)])] | ||
| 14396 | + "USE_RETURN_INSN (TRUE)" | ||
| 14397 | + "retal %0" | ||
| 14398 | + [(set_attr "type" "call")] | ||
| 14399 | + ) | ||
| 14400 | + | ||
| 14401 | +;;============================================================================= | ||
| 14402 | +;; nop | ||
| 14403 | +;;----------------------------------------------------------------------------- | ||
| 14404 | +;; No-op instruction. | ||
| 14405 | +;;============================================================================= | ||
| 14406 | +(define_insn "nop" | ||
| 14407 | + [(const_int 0)] | ||
| 14408 | + "" | ||
| 14409 | + "nop" | ||
| 14410 | + [(set_attr "length" "2") | ||
| 14411 | + (set_attr "type" "alu") | ||
| 14412 | + (set_attr "cc" "none")]) | ||
| 14413 | + | ||
| 14414 | +;;============================================================================= | ||
| 14415 | +;; nonlocal_goto | ||
| 14416 | +;;----------------------------------------------------------------------------- | ||
| 14417 | +;; Jump from one function to a label in an outer function. | ||
| 14418 | +;; Must invalidate return stack, since the function will be exited without | ||
| 14419 | +;; a return | ||
| 14420 | +;;============================================================================= | ||
| 14421 | +(define_expand "nonlocal_goto" | ||
| 14422 | + [(use (match_operand 0 "" "")) | ||
| 14423 | + (use (match_operand 1 "" "")) | ||
| 14424 | + (use (match_operand 2 "" "")) | ||
| 14425 | + (use (match_operand 3 "" ""))] | ||
| 14426 | + "" | ||
| 14427 | + { | ||
| 14428 | + emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__nonlocal_goto"), | ||
| 14429 | + 0, VOIDmode, 3, | ||
| 14430 | + operands[0], SImode, | ||
| 14431 | + operands[1], Pmode, | ||
| 14432 | + operands[2], SImode); | ||
| 14433 | + | ||
| 14434 | + DONE; | ||
| 14435 | + } | ||
| 14436 | +) | ||
| 14437 | + | ||
| 14438 | + | ||
| 14439 | +(define_expand "builtin_longjmp" | ||
| 14440 | + [(use (match_operand 0 "" ""))] | ||
| 14441 | + "" | ||
| 14442 | + { | ||
| 14443 | + rtx ops[3]; | ||
| 14444 | + | ||
| 14445 | + ops[0] = gen_rtx_MEM (Pmode, gen_rtx_PLUS(SImode, operands[0], gen_rtx_CONST_INT(SImode,0))); | ||
| 14446 | + ops[1] = gen_rtx_MEM (Pmode, gen_rtx_PLUS(SImode, operands[0], gen_rtx_CONST_INT(SImode,4))); | ||
| 14447 | + ops[2] = gen_rtx_MEM (Pmode, gen_rtx_PLUS(SImode, operands[0], gen_rtx_CONST_INT(SImode,8))); | ||
| 14448 | + | ||
| 14449 | + | ||
| 14450 | + emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__nonlocal_goto"), | ||
| 14451 | + 0, VOIDmode, 3, | ||
| 14452 | + ops[0], SImode, | ||
| 14453 | + ops[1], Pmode, | ||
| 14454 | + ops[2], SImode); | ||
| 14455 | + | ||
| 14456 | + DONE; | ||
| 14457 | + } | ||
| 14458 | + ) | ||
| 14459 | + | ||
| 14460 | + | ||
| 14461 | +;;============================================================================= | ||
| 14462 | +;; indirect_jump | ||
| 14463 | +;;----------------------------------------------------------------------------- | ||
| 14464 | +;; Jump to an address in reg or memory. | ||
| 14465 | +;;============================================================================= | ||
| 14466 | +(define_expand "indirect_jump" | ||
| 14467 | + [(set (pc) | ||
| 14468 | + (match_operand:SI 0 "general_operand" "r,m"))] | ||
| 14469 | + "" | ||
| 14470 | + { | ||
| 14471 | + /* One of the ops has to be in a register. */ | ||
| 14472 | + if ( (flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS ) | ||
| 14473 | + && !avr32_legitimate_pic_operand_p(operands[0]) ) | ||
| 14474 | + operands[0] = legitimize_pic_address (operands[0], SImode, 0); | ||
| 14475 | + else if ( flag_pic && avr32_address_operand(operands[0], GET_MODE(operands[0])) ) | ||
| 14476 | + /* If we have an address operand then this function uses the pic register. */ | ||
| 14477 | + current_function_uses_pic_offset_table = 1; | ||
| 14478 | + }) | ||
| 14479 | + | ||
| 14480 | + | ||
| 14481 | +(define_insn "indirect_jump_internal" | ||
| 14482 | + [(set (pc) | ||
| 14483 | + (match_operand:SI 0 "general_operand" "r,m,W"))] | ||
| 14484 | + "" | ||
| 14485 | + { | ||
| 14486 | + switch( which_alternative ){ | ||
| 14487 | + case 0: | ||
| 14488 | + return "mov\tpc, %0"; | ||
| 14489 | + case 1: | ||
| 14490 | + if ( avr32_const_pool_ref_operand(operands[0], GET_MODE(operands[0])) ) | ||
| 14491 | + return "lddpc\tpc, %0"; | ||
| 14492 | + else | ||
| 14493 | + return "ld.w\tpc, %0"; | ||
| 14494 | + case 2: | ||
| 14495 | + if ( flag_pic ) | ||
| 14496 | + return "ld.w\tpc, r6[%0@got]"; | ||
| 14497 | + else | ||
| 14498 | + return "lda.w\tpc, %0"; | ||
| 14499 | + default: | ||
| 14500 | + abort(); | ||
| 14501 | + } | ||
| 14502 | + } | ||
| 14503 | + [(set_attr "length" "2,4,8") | ||
| 14504 | + (set_attr "type" "call,call,call") | ||
| 14505 | + (set_attr "cc" "none,none,clobber")]) | ||
| 14506 | + | ||
| 14507 | + | ||
| 14508 | +;;============================================================================= | ||
| 14509 | +;; casesi | ||
| 14510 | +;;============================================================================= | ||
| 14511 | + | ||
| 14512 | + | ||
| 14513 | +(define_expand "casesi" | ||
| 14514 | + [(match_operand:SI 0 "register_operand" "") ; index to jump on | ||
| 14515 | + (match_operand:SI 1 "const_int_operand" "") ; lower bound | ||
| 14516 | + (match_operand:SI 2 "const_int_operand" "") ; total range | ||
| 14517 | + (match_operand:SI 3 "" "") ; table label | ||
| 14518 | + (match_operand:SI 4 "" "")] ; Out of range label | ||
| 14519 | + "" | ||
| 14520 | + " | ||
| 14521 | + { | ||
| 14522 | + rtx reg; | ||
| 14523 | + if (operands[1] != const0_rtx) | ||
| 14524 | + { | ||
| 14525 | + if (!avr32_const_ok_for_constraint_p(INTVAL (operands[1]), 'I', \"Is21\")){ | ||
| 14526 | + reg = force_reg(SImode, GEN_INT (INTVAL (operands[1]))); | ||
| 14527 | + emit_insn (gen_subsi3 (reg, operands[0], | ||
| 14528 | + reg)); | ||
| 14529 | + } else { | ||
| 14530 | + reg = gen_reg_rtx (SImode); | ||
| 14531 | + emit_insn (gen_addsi3 (reg, operands[0], | ||
| 14532 | + GEN_INT (-INTVAL (operands[1])))); | ||
| 14533 | + } | ||
| 14534 | + operands[0] = reg; | ||
| 14535 | + } | ||
| 14536 | + | ||
| 14537 | + if (!avr32_const_ok_for_constraint_p(INTVAL (operands[2]), 'K', \"Ks21\")) | ||
| 14538 | + operands[2] = force_reg (SImode, operands[2]); | ||
| 14539 | + | ||
| 14540 | + emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3], | ||
| 14541 | + operands[4], gen_reg_rtx(SImode))); | ||
| 14542 | + DONE; | ||
| 14543 | + }" | ||
| 14544 | +) | ||
| 14545 | + | ||
| 14546 | +;; The USE in this pattern is needed to tell flow analysis that this is | ||
| 14547 | +;; a CASESI insn. It has no other purpose. | ||
| 14548 | +(define_insn "casesi_internal" | ||
| 14549 | + [(parallel [(set (pc) | ||
| 14550 | + (if_then_else | ||
| 14551 | + (leu (match_operand:SI 0 "register_operand" "r") | ||
| 14552 | + (match_operand:SI 1 "register_immediate_operand" "rKu03")) | ||
| 14553 | + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) | ||
| 14554 | + (label_ref (match_operand 2 "" "")))) | ||
| 14555 | + (label_ref (match_operand 3 "" "")))) | ||
| 14556 | + (clobber (match_operand:SI 4 "register_operand" "=r")) | ||
| 14557 | + (use (label_ref (match_dup 2)))])] | ||
| 14558 | + "" | ||
| 14559 | + { | ||
| 14560 | + if (flag_pic) | ||
| 14561 | + return "cp.w\t%0, %1\;brhi\t%3\;sub\t%4, pc, -(%2 - .)\;add\tpc, %4, %0 << 2"; | ||
| 14562 | + return "cp.w\t%0, %1\;brhi\t%3\;sub\t%4, pc, -(%2 - .)\;ld.w\tpc, %4[%0 << 2]"; | ||
| 14563 | + } | ||
| 14564 | + [(set_attr "cc" "clobber") | ||
| 14565 | + (set_attr "length" "16")] | ||
| 14566 | +) | ||
| 14567 | + | ||
| 14568 | + | ||
| 14569 | +(define_insn "prefetch" | ||
| 14570 | + [(prefetch (match_operand:SI 0 "register_operand" "r") | ||
| 14571 | + (match_operand 1 "const_int_operand" "") | ||
| 14572 | + (match_operand 2 "const_int_operand" ""))] | ||
| 14573 | + "" | ||
| 14574 | + { | ||
| 14575 | + return "pref\t%0[0]"; | ||
| 14576 | + } | ||
| 14577 | + | ||
| 14578 | + [(set_attr "length" "4") | ||
| 14579 | + (set_attr "type" "load") | ||
| 14580 | + (set_attr "cc" "none")]) | ||
| 14581 | + | ||
| 14582 | + | ||
| 14583 | + | ||
| 14584 | +;;============================================================================= | ||
| 14585 | +;; prologue | ||
| 14586 | +;;----------------------------------------------------------------------------- | ||
| 14587 | +;; This pattern, if defined, emits RTL for entry to a function. The function | ||
| 14588 | +;; entry i responsible for setting up the stack frame, initializing the frame | ||
| 14589 | +;; pointer register, saving callee saved registers, etc. | ||
| 14590 | +;;============================================================================= | ||
| 14591 | +(define_expand "prologue" | ||
| 14592 | + [(clobber (const_int 0))] | ||
| 14593 | + "" | ||
| 14594 | + " | ||
| 14595 | + avr32_expand_prologue(); | ||
| 14596 | + DONE; | ||
| 14597 | + " | ||
| 14598 | + ) | ||
| 14599 | + | ||
| 14600 | +;;============================================================================= | ||
| 14601 | +;; eh_return | ||
| 14602 | +;;----------------------------------------------------------------------------- | ||
| 14603 | +;; This pattern, if defined, affects the way __builtin_eh_return, and | ||
| 14604 | +;; thence the call frame exception handling library routines, are | ||
| 14605 | +;; built. It is intended to handle non-trivial actions needed along | ||
| 14606 | +;; the abnormal return path. | ||
| 14607 | +;; | ||
| 14608 | +;; The address of the exception handler to which the function should | ||
| 14609 | +;; return is passed as operand to this pattern. It will normally need | ||
| 14610 | +;; to copied by the pattern to some special register or memory | ||
| 14611 | +;; location. If the pattern needs to determine the location of the | ||
| 14612 | +;; target call frame in order to do so, it may use | ||
| 14613 | +;; EH_RETURN_STACKADJ_RTX, if defined; it will have already been | ||
| 14614 | +;; assigned. | ||
| 14615 | +;; | ||
| 14616 | +;; If this pattern is not defined, the default action will be to | ||
| 14617 | +;; simply copy the return address to EH_RETURN_HANDLER_RTX. Either | ||
| 14618 | +;; that macro or this pattern needs to be defined if call frame | ||
| 14619 | +;; exception handling is to be used. | ||
| 14620 | +(define_expand "eh_return" | ||
| 14621 | + [(use (match_operand 0 "general_operand" ""))] | ||
| 14622 | + "" | ||
| 14623 | + " | ||
| 14624 | + avr32_set_return_address (operands[0]); | ||
| 14625 | + DONE; | ||
| 14626 | + " | ||
| 14627 | + ) | ||
| 14628 | + | ||
| 14629 | +;;============================================================================= | ||
| 14630 | +;; ffssi2 | ||
| 14631 | +;;----------------------------------------------------------------------------- | ||
| 14632 | +(define_insn "ffssi2" | ||
| 14633 | + [ (set (match_operand:SI 0 "register_operand" "=r") | ||
| 14634 | + (ffs:SI (match_operand:SI 1 "register_operand" "r"))) ] | ||
| 14635 | + "" | ||
| 14636 | + "mov %0, %1 | ||
| 14637 | + brev %0 | ||
| 14638 | + clz %0, %0 | ||
| 14639 | + sub %0, -1 | ||
| 14640 | + cp %0, 33 | ||
| 14641 | + moveq %0, 0" | ||
| 14642 | + [(set_attr "length" "18") | ||
| 14643 | + (set_attr "cc" "clobber")] | ||
| 14644 | + ) | ||
| 14645 | + | ||
| 14646 | + | ||
| 14647 | + | ||
| 14648 | +;;============================================================================= | ||
| 14649 | +;; swap_h | ||
| 14650 | +;;----------------------------------------------------------------------------- | ||
| 14651 | +(define_insn "*swap_h" | ||
| 14652 | + [ (set (match_operand:SI 0 "register_operand" "=r") | ||
| 14653 | + (ior:SI (ashift:SI (match_dup 0) (const_int 16)) | ||
| 14654 | + (lshiftrt:SI (match_dup 0) (const_int 16))))] | ||
| 14655 | + "" | ||
| 14656 | + "swap.h %0" | ||
| 14657 | + [(set_attr "length" "2")] | ||
| 14658 | + ) | ||
| 14659 | + | ||
| 14660 | +(define_insn_and_split "bswap_16" | ||
| 14661 | + [ (set (match_operand:HI 0 "avr32_bswap_operand" "=r,RKs13,r") | ||
| 14662 | + (ior:HI (and:HI (lshiftrt:HI (match_operand:HI 1 "avr32_bswap_operand" "r,r,RKs13") | ||
| 14663 | + (const_int 8)) | ||
| 14664 | + (const_int 255)) | ||
| 14665 | + (ashift:HI (and:HI (match_dup 1) | ||
| 14666 | + (const_int 255)) | ||
| 14667 | + (const_int 8))))] | ||
| 14668 | + "" | ||
| 14669 | + { | ||
| 14670 | + switch ( which_alternative ){ | ||
| 14671 | + case 0: | ||
| 14672 | + if ( REGNO(operands[0]) == REGNO(operands[1])) | ||
| 14673 | + return "swap.bh\t%0"; | ||
| 14674 | + else | ||
| 14675 | + return "mov\t%0, %1\;swap.bh\t%0"; | ||
| 14676 | + case 1: | ||
| 14677 | + return "stswp.h\t%0, %1"; | ||
| 14678 | + case 2: | ||
| 14679 | + return "ldswp.sh\t%0, %1"; | ||
| 14680 | + default: | ||
| 14681 | + abort(); | ||
| 14682 | + } | ||
| 14683 | + } | ||
| 14684 | + | ||
| 14685 | + "(reload_completed && | ||
| 14686 | + REG_P(operands[0]) && REG_P(operands[1]) | ||
| 14687 | + && (REGNO(operands[0]) != REGNO(operands[1])))" | ||
| 14688 | + [(set (match_dup 0) (match_dup 1)) | ||
| 14689 | + (set (match_dup 0) | ||
| 14690 | + (ior:HI (and:HI (lshiftrt:HI (match_dup 0) | ||
| 14691 | + (const_int 8)) | ||
| 14692 | + (const_int 255)) | ||
| 14693 | + (ashift:HI (and:HI (match_dup 0) | ||
| 14694 | + (const_int 255)) | ||
| 14695 | + (const_int 8))))] | ||
| 14696 | + "" | ||
| 14697 | + | ||
| 14698 | + [(set_attr "length" "4,4,4") | ||
| 14699 | + (set_attr "type" "alu,store,load_rm")] | ||
| 14700 | + ) | ||
| 14701 | + | ||
| 14702 | +(define_insn_and_split "bswap_32" | ||
| 14703 | + [ (set (match_operand:SI 0 "avr32_bswap_operand" "=r,RKs14,r") | ||
| 14704 | + (ior:SI (ior:SI (lshiftrt:SI (and:SI (match_operand:SI 1 "avr32_bswap_operand" "=r,r,RKs14") | ||
| 14705 | + (const_int 4278190080)) | ||
| 14706 | + (const_int 24)) | ||
| 14707 | + (lshiftrt:SI (and:SI (match_dup 1) | ||
| 14708 | + (const_int 16711680)) | ||
| 14709 | + (const_int 8))) | ||
| 14710 | + (ior:SI (ashift:SI (and:SI (match_dup 1) | ||
| 14711 | + (const_int 65280)) | ||
| 14712 | + (const_int 8)) | ||
| 14713 | + (ashift:SI (and:SI (match_dup 1) | ||
| 14714 | + (const_int 255)) | ||
| 14715 | + (const_int 24)))))] | ||
| 14716 | + "" | ||
| 14717 | + { | ||
| 14718 | + switch ( which_alternative ){ | ||
| 14719 | + case 0: | ||
| 14720 | + if ( REGNO(operands[0]) == REGNO(operands[1])) | ||
| 14721 | + return "swap.b\t%0"; | ||
| 14722 | + else | ||
| 14723 | + return "mov\t%0, %1\;swap.b\t%0"; | ||
| 14724 | + case 1: | ||
| 14725 | + return "stswp.w\t%0, %1"; | ||
| 14726 | + case 2: | ||
| 14727 | + return "ldswp.w\t%0, %1"; | ||
| 14728 | + default: | ||
| 14729 | + abort(); | ||
| 14730 | + } | ||
| 14731 | + } | ||
| 14732 | + "(reload_completed && | ||
| 14733 | + REG_P(operands[0]) && REG_P(operands[1]) | ||
| 14734 | + && (REGNO(operands[0]) != REGNO(operands[1])))" | ||
| 14735 | + [(set (match_dup 0) (match_dup 1)) | ||
| 14736 | + (set (match_dup 0) | ||
| 14737 | + (ior:SI (ior:SI (lshiftrt:SI (and:SI (match_dup 0) | ||
| 14738 | + (const_int 4278190080)) | ||
| 14739 | + (const_int 24)) | ||
| 14740 | + (lshiftrt:SI (and:SI (match_dup 0) | ||
| 14741 | + (const_int 16711680)) | ||
| 14742 | + (const_int 8))) | ||
| 14743 | + (ior:SI (ashift:SI (and:SI (match_dup 0) | ||
| 14744 | + (const_int 65280)) | ||
| 14745 | + (const_int 8)) | ||
| 14746 | + (ashift:SI (and:SI (match_dup 0) | ||
| 14747 | + (const_int 255)) | ||
| 14748 | + (const_int 24)))))] | ||
| 14749 | + "" | ||
| 14750 | + | ||
| 14751 | + [(set_attr "length" "4,4,4") | ||
| 14752 | + (set_attr "type" "alu,store,load_rm")] | ||
| 14753 | + ) | ||
| 14754 | + | ||
| 14755 | + | ||
| 14756 | +;;============================================================================= | ||
| 14757 | +;; blockage | ||
| 14758 | +;;----------------------------------------------------------------------------- | ||
| 14759 | +;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and | ||
| 14760 | +;; all of memory. This blocks insns from being moved across this point. | ||
| 14761 | + | ||
| 14762 | +(define_insn "blockage" | ||
| 14763 | + [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)] | ||
| 14764 | + "" | ||
| 14765 | + "" | ||
| 14766 | + [(set_attr "length" "0")] | ||
| 14767 | +) | ||
| 14768 | + | ||
| 14769 | +;;============================================================================= | ||
| 14770 | +;; clzsi2 | ||
| 14771 | +;;----------------------------------------------------------------------------- | ||
| 14772 | +(define_insn "clzsi2" | ||
| 14773 | + [ (set (match_operand:SI 0 "register_operand" "=r") | ||
| 14774 | + (clz:SI (match_operand:SI 1 "register_operand" "r"))) ] | ||
| 14775 | + "" | ||
| 14776 | + "clz %0, %1" | ||
| 14777 | + [(set_attr "length" "4") | ||
| 14778 | + (set_attr "cc" "set_z")] | ||
| 14779 | + ) | ||
| 14780 | + | ||
| 14781 | +;;============================================================================= | ||
| 14782 | +;; ctzsi2 | ||
| 14783 | +;;----------------------------------------------------------------------------- | ||
| 14784 | +(define_insn "ctzsi2" | ||
| 14785 | + [ (set (match_operand:SI 0 "register_operand" "=r,r") | ||
| 14786 | + (ctz:SI (match_operand:SI 1 "register_operand" "0,r"))) ] | ||
| 14787 | + "" | ||
| 14788 | + "@ | ||
| 14789 | + brev\t%0\;clz\t%0, %0 | ||
| 14790 | + mov\t%0, %1\;brev\t%0\;clz\t%0, %0" | ||
| 14791 | + [(set_attr "length" "8") | ||
| 14792 | + (set_attr "cc" "set_z")] | ||
| 14793 | + ) | ||
| 14794 | + | ||
| 14795 | +;;============================================================================= | ||
| 14796 | +;; cache instructions | ||
| 14797 | +;;----------------------------------------------------------------------------- | ||
| 14798 | +(define_insn "cache" | ||
| 14799 | + [ (unspec_volatile [(match_operand:SI 0 "register_operand" "r") | ||
| 14800 | + (match_operand:SI 1 "immediate_operand" "Ku05")] VUNSPEC_CACHE)] | ||
| 14801 | + "" | ||
| 14802 | + "cache %0[0], %1" | ||
| 14803 | + [(set_attr "length" "4")] | ||
| 14804 | + ) | ||
| 14805 | + | ||
| 14806 | +(define_insn "sync" | ||
| 14807 | + [ (unspec_volatile [(match_operand:SI 0 "immediate_operand" "Ku08")] VUNSPEC_SYNC)] | ||
| 14808 | + "" | ||
| 14809 | + "sync %0" | ||
| 14810 | + [(set_attr "length" "4")] | ||
| 14811 | + ) | ||
| 14812 | + | ||
| 14813 | +;;============================================================================= | ||
| 14814 | +;; TLB instructions | ||
| 14815 | +;;----------------------------------------------------------------------------- | ||
| 14816 | +(define_insn "tlbr" | ||
| 14817 | + [ (unspec_volatile [(const_int 0)] VUNSPEC_TLBR)] | ||
| 14818 | + "" | ||
| 14819 | + "tlbr" | ||
| 14820 | + [(set_attr "length" "2")] | ||
| 14821 | + ) | ||
| 14822 | + | ||
| 14823 | +(define_insn "tlbw" | ||
| 14824 | + [ (unspec_volatile [(const_int 0)] VUNSPEC_TLBW)] | ||
| 14825 | + "" | ||
| 14826 | + "tlbw" | ||
| 14827 | + [(set_attr "length" "2")] | ||
| 14828 | + ) | ||
| 14829 | + | ||
| 14830 | +(define_insn "tlbs" | ||
| 14831 | + [ (unspec_volatile [(const_int 0)] VUNSPEC_TLBS)] | ||
| 14832 | + "" | ||
| 14833 | + "tlbs" | ||
| 14834 | + [(set_attr "length" "2")] | ||
| 14835 | + ) | ||
| 14836 | + | ||
| 14837 | +;;============================================================================= | ||
| 14838 | +;; Breakpoint instruction | ||
| 14839 | +;;----------------------------------------------------------------------------- | ||
| 14840 | +(define_insn "breakpoint" | ||
| 14841 | + [ (unspec_volatile [(const_int 0)] VUNSPEC_BREAKPOINT)] | ||
| 14842 | + "" | ||
| 14843 | + "breakpoint" | ||
| 14844 | + [(set_attr "length" "2")] | ||
| 14845 | + ) | ||
| 14846 | + | ||
| 14847 | +;;============================================================================= | ||
| 14848 | +;; Xchg instruction | ||
| 14849 | +;;----------------------------------------------------------------------------- | ||
| 14850 | +(define_insn "xchg" | ||
| 14851 | + [ (parallel [(set (match_operand:SI 0 "register_operand" "=&r") | ||
| 14852 | + (mem:SI (match_operand:SI 1 "register_operand" "r"))) | ||
| 14853 | + (set (mem:SI (match_operand:SI 2 "register_operand" "=1")) | ||
| 14854 | + (match_operand:SI 3 "register_operand" "r"))])] | ||
| 14855 | + "" | ||
| 14856 | + "xchg\t%0, %1, %3" | ||
| 14857 | + [(set_attr "length" "4")] | ||
| 14858 | + ) | ||
| 14859 | + | ||
| 14860 | +;;============================================================================= | ||
| 14861 | +;; mtsr/mfsr instruction | ||
| 14862 | +;;----------------------------------------------------------------------------- | ||
| 14863 | +(define_insn "mtsr" | ||
| 14864 | + [ (unspec_volatile [(match_operand 0 "immediate_operand" "i") | ||
| 14865 | + (match_operand:SI 1 "register_operand" "r")] VUNSPEC_MTSR)] | ||
| 14866 | + "" | ||
| 14867 | + "mtsr\t%0, %1" | ||
| 14868 | + [(set_attr "length" "4")] | ||
| 14869 | + ) | ||
| 14870 | + | ||
| 14871 | +(define_insn "mfsr" | ||
| 14872 | + [ (set (match_operand:SI 0 "register_operand" "=r") | ||
| 14873 | + (unspec_volatile:SI [(match_operand 1 "immediate_operand" "i")] VUNSPEC_MFSR)) ] | ||
| 14874 | + "" | ||
| 14875 | + "mfsr\t%0, %1" | ||
| 14876 | + [(set_attr "length" "4")] | ||
| 14877 | + ) | ||
| 14878 | + | ||
| 14879 | +;;============================================================================= | ||
| 14880 | +;; mtdr/mfdr instruction | ||
| 14881 | +;;----------------------------------------------------------------------------- | ||
| 14882 | +(define_insn "mtdr" | ||
| 14883 | + [ (unspec_volatile [(match_operand 0 "immediate_operand" "i") | ||
| 14884 | + (match_operand:SI 1 "register_operand" "r")] VUNSPEC_MTDR)] | ||
| 14885 | + "" | ||
| 14886 | + "mtdr\t%0, %1" | ||
| 14887 | + [(set_attr "length" "4")] | ||
| 14888 | + ) | ||
| 14889 | + | ||
| 14890 | +(define_insn "mfdr" | ||
| 14891 | + [ (set (match_operand:SI 0 "register_operand" "=r") | ||
| 14892 | + (unspec_volatile:SI [(match_operand 1 "immediate_operand" "i")] VUNSPEC_MFDR)) ] | ||
| 14893 | + "" | ||
| 14894 | + "mfdr\t%0, %1" | ||
| 14895 | + [(set_attr "length" "4")] | ||
| 14896 | + ) | ||
| 14897 | + | ||
| 14898 | +;;============================================================================= | ||
| 14899 | +;; musfr | ||
| 14900 | +;;----------------------------------------------------------------------------- | ||
| 14901 | +(define_insn "musfr" | ||
| 14902 | + [ (unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_MUSFR)] | ||
| 14903 | + "" | ||
| 14904 | + "musfr\t%0" | ||
| 14905 | + [(set_attr "length" "2") | ||
| 14906 | + (set_attr "cc" "clobber")] | ||
| 14907 | + ) | ||
| 14908 | + | ||
| 14909 | +(define_insn "mustr" | ||
| 14910 | + [ (set (match_operand:SI 0 "register_operand" "=r") | ||
| 14911 | + (unspec_volatile:SI [(const_int 0)] VUNSPEC_MUSTR)) ] | ||
| 14912 | + "" | ||
| 14913 | + "mustr\t%0" | ||
| 14914 | + [(set_attr "length" "2")] | ||
| 14915 | + ) | ||
| 14916 | + | ||
| 14917 | +;;============================================================================= | ||
| 14918 | +;; Saturation Round Scale instruction | ||
| 14919 | +;;----------------------------------------------------------------------------- | ||
| 14920 | +(define_insn "sats" | ||
| 14921 | + [ (set (match_operand:SI 0 "register_operand" "+r") | ||
| 14922 | + (unspec:SI [(match_dup 0) | ||
| 14923 | + (match_operand 1 "immediate_operand" "Ku05") | ||
| 14924 | + (match_operand 2 "immediate_operand" "Ku05")] | ||
| 14925 | + UNSPEC_SATS)) ] | ||
| 14926 | + "TARGET_DSP" | ||
| 14927 | + "sats\t%0 >> %1, %2" | ||
| 14928 | + [(set_attr "type" "alu_sat") | ||
| 14929 | + (set_attr "length" "4")] | ||
| 14930 | + ) | ||
| 14931 | + | ||
| 14932 | +(define_insn "satu" | ||
| 14933 | + [ (set (match_operand:SI 0 "register_operand" "+r") | ||
| 14934 | + (unspec:SI [(match_dup 0) | ||
| 14935 | + (match_operand 1 "immediate_operand" "Ku05") | ||
| 14936 | + (match_operand 2 "immediate_operand" "Ku05")] | ||
| 14937 | + UNSPEC_SATU)) ] | ||
| 14938 | + "TARGET_DSP" | ||
| 14939 | + "satu\t%0 >> %1, %2" | ||
| 14940 | + [(set_attr "type" "alu_sat") | ||
| 14941 | + (set_attr "length" "4")] | ||
| 14942 | + ) | ||
| 14943 | + | ||
| 14944 | +(define_insn "satrnds" | ||
| 14945 | + [ (set (match_operand:SI 0 "register_operand" "+r") | ||
| 14946 | + (unspec:SI [(match_dup 0) | ||
| 14947 | + (match_operand 1 "immediate_operand" "Ku05") | ||
| 14948 | + (match_operand 2 "immediate_operand" "Ku05")] | ||
| 14949 | + UNSPEC_SATRNDS)) ] | ||
| 14950 | + "TARGET_DSP" | ||
| 14951 | + "satrnds\t%0 >> %1, %2" | ||
| 14952 | + [(set_attr "type" "alu_sat") | ||
| 14953 | + (set_attr "length" "4")] | ||
| 14954 | + ) | ||
| 14955 | + | ||
| 14956 | +(define_insn "satrndu" | ||
| 14957 | + [ (set (match_operand:SI 0 "register_operand" "+r") | ||
| 14958 | + (unspec:SI [(match_dup 0) | ||
| 14959 | + (match_operand 1 "immediate_operand" "Ku05") | ||
| 14960 | + (match_operand 2 "immediate_operand" "Ku05")] | ||
| 14961 | + UNSPEC_SATRNDU)) ] | ||
| 14962 | + "TARGET_DSP" | ||
| 14963 | + "sats\t%0 >> %1, %2" | ||
| 14964 | + [(set_attr "type" "alu_sat") | ||
| 14965 | + (set_attr "length" "4")] | ||
| 14966 | + ) | ||
| 14967 | + | ||
| 14968 | +;; Special patterns for dealing with the constant pool | ||
| 14969 | + | ||
| 14970 | +(define_insn "align_4" | ||
| 14971 | + [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)] | ||
| 14972 | + "" | ||
| 14973 | + { | ||
| 14974 | + assemble_align (32); | ||
| 14975 | + return ""; | ||
| 14976 | + } | ||
| 14977 | + [(set_attr "length" "2")] | ||
| 14978 | +) | ||
| 14979 | + | ||
| 14980 | +(define_insn "consttable_start" | ||
| 14981 | + [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_START)] | ||
| 14982 | + "" | ||
| 14983 | + { | ||
| 14984 | + return ".cpool"; | ||
| 14985 | + } | ||
| 14986 | + [(set_attr "length" "0")] | ||
| 14987 | + ) | ||
| 14988 | + | ||
| 14989 | +(define_insn "consttable_end" | ||
| 14990 | + [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)] | ||
| 14991 | + "" | ||
| 14992 | + { | ||
| 14993 | + making_const_table = FALSE; | ||
| 14994 | + return ""; | ||
| 14995 | + } | ||
| 14996 | + [(set_attr "length" "0")] | ||
| 14997 | +) | ||
| 14998 | + | ||
| 14999 | + | ||
| 15000 | +(define_insn "consttable_4" | ||
| 15001 | + [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)] | ||
| 15002 | + "" | ||
| 15003 | + { | ||
| 15004 | + making_const_table = TRUE; | ||
| 15005 | + switch (GET_MODE_CLASS (GET_MODE (operands[0]))) | ||
| 15006 | + { | ||
| 15007 | + case MODE_FLOAT: | ||
| 15008 | + { | ||
| 15009 | + REAL_VALUE_TYPE r; | ||
| 15010 | + char real_string[1024]; | ||
| 15011 | + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]); | ||
| 15012 | + real_to_decimal(real_string, &r, 1024, 0, 1); | ||
| 15013 | + asm_fprintf (asm_out_file, "\t.float\t%s\n", real_string); | ||
| 15014 | + break; | ||
| 15015 | + } | ||
| 15016 | + default: | ||
| 15017 | + assemble_integer (operands[0], 4, 0, 1); | ||
| 15018 | + break; | ||
| 15019 | + } | ||
| 15020 | + return ""; | ||
| 15021 | + } | ||
| 15022 | + [(set_attr "length" "4")] | ||
| 15023 | +) | ||
| 15024 | + | ||
| 15025 | +(define_insn "consttable_8" | ||
| 15026 | + [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)] | ||
| 15027 | + "" | ||
| 15028 | + { | ||
| 15029 | + making_const_table = TRUE; | ||
| 15030 | + switch (GET_MODE_CLASS (GET_MODE (operands[0]))) | ||
| 15031 | + { | ||
| 15032 | + case MODE_FLOAT: | ||
| 15033 | + { | ||
| 15034 | + REAL_VALUE_TYPE r; | ||
| 15035 | + char real_string[1024]; | ||
| 15036 | + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]); | ||
| 15037 | + real_to_decimal(real_string, &r, 1024, 0, 1); | ||
| 15038 | + asm_fprintf (asm_out_file, "\t.double\t%s\n", real_string); | ||
| 15039 | + break; | ||
| 15040 | + } | ||
| 15041 | + default: | ||
| 15042 | + assemble_integer(operands[0], 8, 0, 1); | ||
| 15043 | + break; | ||
| 15044 | + } | ||
| 15045 | + return ""; | ||
| 15046 | + } | ||
| 15047 | + [(set_attr "length" "8")] | ||
| 15048 | +) | ||
| 15049 | + | ||
| 15050 | +;;============================================================================= | ||
| 15051 | +;; coprocessor instructions | ||
| 15052 | +;;----------------------------------------------------------------------------- | ||
| 15053 | +(define_insn "cop" | ||
| 15054 | + [ (unspec_volatile [(match_operand 0 "immediate_operand" "Ku03") | ||
| 15055 | + (match_operand 1 "immediate_operand" "Ku04") | ||
| 15056 | + (match_operand 2 "immediate_operand" "Ku04") | ||
| 15057 | + (match_operand 3 "immediate_operand" "Ku04") | ||
| 15058 | + (match_operand 4 "immediate_operand" "Ku07")] VUNSPEC_COP)] | ||
| 15059 | + "" | ||
| 15060 | + "cop\tcp%0, cr%1, cr%2, cr%3, %4" | ||
| 15061 | + [(set_attr "length" "4")] | ||
| 15062 | + ) | ||
| 15063 | + | ||
| 15064 | +(define_insn "mvcrsi" | ||
| 15065 | + [ (set (match_operand:SI 0 "avr32_cop_move_operand" "=r,<,Z") | ||
| 15066 | + (unspec_volatile:SI [(match_operand 1 "immediate_operand" "Ku03,Ku03,Ku03") | ||
| 15067 | + (match_operand 2 "immediate_operand" "Ku04,Ku04,Ku04")] | ||
| 15068 | + VUNSPEC_MVCR)) ] | ||
| 15069 | + "" | ||
| 15070 | + "@ | ||
| 15071 | + mvcr.w\tcp%1, %0, cr%2 | ||
| 15072 | + stcm.w\tcp%1, %0, cr%2 | ||
| 15073 | + stc.w\tcp%1, %0, cr%2" | ||
| 15074 | + [(set_attr "length" "4")] | ||
| 15075 | + ) | ||
| 15076 | + | ||
| 15077 | +(define_insn "mvcrdi" | ||
| 15078 | + [ (set (match_operand:DI 0 "avr32_cop_move_operand" "=r,<,Z") | ||
| 15079 | + (unspec_volatile:DI [(match_operand 1 "immediate_operand" "Ku03,Ku03,Ku03") | ||
| 15080 | + (match_operand 2 "immediate_operand" "Ku04,Ku04,Ku04")] | ||
| 15081 | + VUNSPEC_MVCR)) ] | ||
| 15082 | + "" | ||
| 15083 | + "@ | ||
| 15084 | + mvcr.d\tcp%1, %0, cr%2 | ||
| 15085 | + stcm.d\tcp%1, %0, cr%2-cr%i2 | ||
| 15086 | + stc.d\tcp%1, %0, cr%2" | ||
| 15087 | + [(set_attr "length" "4")] | ||
| 15088 | + ) | ||
| 15089 | + | ||
| 15090 | +(define_insn "mvrcsi" | ||
| 15091 | + [ (unspec_volatile:SI [(match_operand 0 "immediate_operand" "Ku03,Ku03,Ku03") | ||
| 15092 | + (match_operand 1 "immediate_operand" "Ku04,Ku04,Ku04") | ||
| 15093 | + (match_operand:SI 2 "avr32_cop_move_operand" "r,>,Z")] | ||
| 15094 | + VUNSPEC_MVRC)] | ||
| 15095 | + "" | ||
| 15096 | + { | ||
| 15097 | + switch (which_alternative){ | ||
| 15098 | + case 0: | ||
| 15099 | + return "mvrc.w\tcp%0, cr%1, %2"; | ||
| 15100 | + case 1: | ||
| 15101 | + return "ldcm.w\tcp%0, %2, cr%1"; | ||
| 15102 | + case 2: | ||
| 15103 | + return "ldc.w\tcp%0, cr%1, %2"; | ||
| 15104 | + default: | ||
| 15105 | + abort(); | ||
| 15106 | + } | ||
| 15107 | + } | ||
| 15108 | + [(set_attr "length" "4")] | ||
| 15109 | + ) | ||
| 15110 | + | ||
| 15111 | +(define_insn "mvrcdi" | ||
| 15112 | + [ (unspec_volatile:DI [(match_operand 0 "immediate_operand" "Ku03,Ku03,Ku03") | ||
| 15113 | + (match_operand 1 "immediate_operand" "Ku04,Ku04,Ku04") | ||
| 15114 | + (match_operand:DI 2 "avr32_cop_move_operand" "r,>,Z")] | ||
| 15115 | + VUNSPEC_MVRC)] | ||
| 15116 | + "" | ||
| 15117 | + { | ||
| 15118 | + switch (which_alternative){ | ||
| 15119 | + case 0: | ||
| 15120 | + return "mvrc.d\tcp%0, cr%1, %2"; | ||
| 15121 | + case 1: | ||
| 15122 | + return "ldcm.d\tcp%0, %2, cr%1-cr%i1"; | ||
| 15123 | + case 2: | ||
| 15124 | + return "ldc.d\tcp%0, cr%1, %2"; | ||
| 15125 | + default: | ||
| 15126 | + abort(); | ||
| 15127 | + } | ||
| 15128 | + } | ||
| 15129 | + [(set_attr "length" "4")] | ||
| 15130 | + ) | ||
| 15131 | + | ||
| 15132 | +;;============================================================================= | ||
| 15133 | +;; epilogue | ||
| 15134 | +;;----------------------------------------------------------------------------- | ||
| 15135 | +;; This pattern emits RTL for exit from a function. The function exit is | ||
| 15136 | +;; responsible for deallocating the stack frame, restoring callee saved | ||
| 15137 | +;; registers and emitting the return instruction. | ||
| 15138 | +;; ToDo: using TARGET_ASM_FUNCTION_PROLOGUE instead. | ||
| 15139 | +;;============================================================================= | ||
| 15140 | +(define_expand "epilogue" | ||
| 15141 | + [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)] | ||
| 15142 | + "" | ||
| 15143 | + " | ||
| 15144 | + if (USE_RETURN_INSN (FALSE)){ | ||
| 15145 | + emit_jump_insn (gen_return ()); | ||
| 15146 | + DONE; | ||
| 15147 | + } | ||
| 15148 | + emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, | ||
| 15149 | + gen_rtvec (1, | ||
| 15150 | + gen_rtx_RETURN (VOIDmode)), | ||
| 15151 | + VUNSPEC_EPILOGUE)); | ||
| 15152 | + DONE; | ||
| 15153 | + " | ||
| 15154 | + ) | ||
| 15155 | + | ||
| 15156 | +(define_insn "*epilogue_insns" | ||
| 15157 | + [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)] | ||
| 15158 | + "" | ||
| 15159 | + { | ||
| 15160 | + avr32_output_return_instruction (FALSE, FALSE, NULL, NULL); | ||
| 15161 | + return ""; | ||
| 15162 | + } | ||
| 15163 | + ; Length is absolute worst case | ||
| 15164 | + [(set_attr "type" "branch") | ||
| 15165 | + (set_attr "length" "12")] | ||
| 15166 | + ) | ||
| 15167 | + | ||
| 15168 | +(define_insn "*epilogue_insns_ret_imm" | ||
| 15169 | + [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i")) | ||
| 15170 | + (use (reg RETVAL_REGNUM)) | ||
| 15171 | + (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])] | ||
| 15172 | + "((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))" | ||
| 15173 | + { | ||
| 15174 | + avr32_output_return_instruction (FALSE, FALSE, NULL, operands[0]); | ||
| 15175 | + return ""; | ||
| 15176 | + } | ||
| 15177 | + ; Length is absolute worst case | ||
| 15178 | + [(set_attr "type" "branch") | ||
| 15179 | + (set_attr "length" "12")] | ||
| 15180 | + ) | ||
| 15181 | + | ||
| 15182 | +(define_insn "sibcall_epilogue" | ||
| 15183 | + [(unspec_volatile [(const_int 0)] VUNSPEC_EPILOGUE)] | ||
| 15184 | + "" | ||
| 15185 | + { | ||
| 15186 | + avr32_output_return_instruction (FALSE, FALSE, NULL, NULL); | ||
| 15187 | + return ""; | ||
| 15188 | + } | ||
| 15189 | +;; Length is absolute worst case | ||
| 15190 | + [(set_attr "type" "branch") | ||
| 15191 | + (set_attr "length" "12")] | ||
| 15192 | + ) | ||
| 15193 | + | ||
| 15194 | +(define_insn "*sibcall_epilogue_insns_ret_imm" | ||
| 15195 | + [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i")) | ||
| 15196 | + (use (reg RETVAL_REGNUM)) | ||
| 15197 | + (unspec_volatile [(const_int 0)] VUNSPEC_EPILOGUE)])] | ||
| 15198 | + "((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))" | ||
| 15199 | + { | ||
| 15200 | + avr32_output_return_instruction (FALSE, FALSE, NULL, operands[0]); | ||
| 15201 | + return ""; | ||
| 15202 | + } | ||
| 15203 | + ; Length is absolute worst case | ||
| 15204 | + [(set_attr "type" "branch") | ||
| 15205 | + (set_attr "length" "12")] | ||
| 15206 | + ) | ||
| 15207 | + | ||
| 15208 | +(define_insn "ldxi" | ||
| 15209 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 15210 | + (mem:SI (plus:SI | ||
| 15211 | + (match_operand:SI 1 "register_operand" "r") | ||
| 15212 | + (mult:SI (zero_extract:SI (match_operand:SI 2 "register_operand" "r") | ||
| 15213 | + (const_int 8) | ||
| 15214 | + (match_operand:SI 3 "immediate_operand" "Ku05")) | ||
| 15215 | + (const_int 4)))))] | ||
| 15216 | + "(INTVAL(operands[3]) == 24 || INTVAL(operands[3]) == 16 || INTVAL(operands[3]) == 8 | ||
| 15217 | + || INTVAL(operands[3]) == 0)" | ||
| 15218 | + { | ||
| 15219 | + switch ( INTVAL(operands[3]) ){ | ||
| 15220 | + case 0: | ||
| 15221 | + return "ld.w %0, %1[%2:b << 2]"; | ||
| 15222 | + case 8: | ||
| 15223 | + return "ld.w %0, %1[%2:l << 2]"; | ||
| 15224 | + case 16: | ||
| 15225 | + return "ld.w %0, %1[%2:u << 2]"; | ||
| 15226 | + case 24: | ||
| 15227 | + return "ld.w %0, %1[%2:t << 2]"; | ||
| 15228 | + default: | ||
| 15229 | + internal_error("illegal operand for ldxi"); | ||
| 15230 | + } | ||
| 15231 | + } | ||
| 15232 | + [(set_attr "type" "load") | ||
| 15233 | + (set_attr "length" "4") | ||
| 15234 | + (set_attr "cc" "none")]) | ||
| 15235 | + | ||
| 15236 | + | ||
| 15237 | + | ||
| 15238 | + | ||
| 15239 | + | ||
| 15240 | + | ||
| 15241 | +;;============================================================================= | ||
| 15242 | +;; Peephole optimizing | ||
| 15243 | +;;----------------------------------------------------------------------------- | ||
| 15244 | +;; Changing | ||
| 15245 | +;; sub r8, r7, 8 | ||
| 15246 | +;; st.w r8[0x0], r12 | ||
| 15247 | +;; to | ||
| 15248 | +;; sub r8, r7, 8 | ||
| 15249 | +;; st.w r7[-0x8], r12 | ||
| 15250 | +;;============================================================================= | ||
| 15251 | +; (set (reg:SI 9 r8) | ||
| 15252 | +; (plus:SI (reg/f:SI 6 r7) | ||
| 15253 | +; (const_int ...))) | ||
| 15254 | +; (set (mem:SI (reg:SI 9 r8)) | ||
| 15255 | +; (reg:SI 12 r12)) | ||
| 15256 | +(define_peephole2 | ||
| 15257 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15258 | + (plus:SI (match_operand:SI 1 "register_operand" "") | ||
| 15259 | + (match_operand:SI 2 "immediate_operand" ""))) | ||
| 15260 | + (set (mem:SI (match_dup 0)) | ||
| 15261 | + (match_operand:SI 3 "register_operand" ""))] | ||
| 15262 | + "REGNO(operands[0]) != REGNO(operands[1])" | ||
| 15263 | + [(set (match_dup 0) | ||
| 15264 | + (plus:SI (match_dup 1) | ||
| 15265 | + (match_dup 2))) | ||
| 15266 | + (set (mem:SI (plus:SI (match_dup 1) | ||
| 15267 | + (match_dup 2))) | ||
| 15268 | + (match_dup 3))] | ||
| 15269 | + "") | ||
| 15270 | + | ||
| 15271 | +;;============================================================================= | ||
| 15272 | +;; Peephole optimizing | ||
| 15273 | +;;----------------------------------------------------------------------------- | ||
| 15274 | +;; Changing | ||
| 15275 | +;; sub r6, r7, 4 | ||
| 15276 | +;; ld.w r6, r6[0x0] | ||
| 15277 | +;; to | ||
| 15278 | +;; sub r6, r7, 4 | ||
| 15279 | +;; ld.w r6, r7[-0x4] | ||
| 15280 | +;;============================================================================= | ||
| 15281 | +; (set (reg:SI 7 r6) | ||
| 15282 | +; (plus:SI (reg/f:SI 6 r7) | ||
| 15283 | +; (const_int -4 [0xfffffffc]))) | ||
| 15284 | +; (set (reg:SI 7 r6) | ||
| 15285 | +; (mem:SI (reg:SI 7 r6))) | ||
| 15286 | +(define_peephole2 | ||
| 15287 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15288 | + (plus:SI (match_operand:SI 1 "register_operand" "") | ||
| 15289 | + (match_operand:SI 2 "immediate_operand" ""))) | ||
| 15290 | + (set (match_operand:SI 3 "register_operand" "") | ||
| 15291 | + (mem:SI (match_dup 0)))] | ||
| 15292 | + "REGNO(operands[0]) != REGNO(operands[1])" | ||
| 15293 | + [(set (match_dup 0) | ||
| 15294 | + (plus:SI (match_dup 1) | ||
| 15295 | + (match_dup 2))) | ||
| 15296 | + (set (match_dup 3) | ||
| 15297 | + (mem:SI (plus:SI (match_dup 1) | ||
| 15298 | + (match_dup 2))))] | ||
| 15299 | + "") | ||
| 15300 | + | ||
| 15301 | +;;============================================================================= | ||
| 15302 | +;; Peephole optimizing | ||
| 15303 | +;;----------------------------------------------------------------------------- | ||
| 15304 | +;; Changing | ||
| 15305 | +;; ld.sb r0, r7[-0x6] | ||
| 15306 | +;; cashs.b r0 | ||
| 15307 | +;; to | ||
| 15308 | +;; ld.sb r0, r7[-0x6] | ||
| 15309 | +;;============================================================================= | ||
| 15310 | +(define_peephole2 | ||
| 15311 | + [(set (match_operand:QI 0 "register_operand" "") | ||
| 15312 | + (match_operand:QI 1 "load_sb_memory_operand" "")) | ||
| 15313 | + (set (match_operand:SI 2 "register_operand" "") | ||
| 15314 | + (sign_extend:SI (match_dup 0)))] | ||
| 15315 | + "(REGNO(operands[0]) == REGNO(operands[2]) || peep2_reg_dead_p(2, operands[0]))" | ||
| 15316 | + [(set (match_dup 2) | ||
| 15317 | + (sign_extend:SI (match_dup 1)))] | ||
| 15318 | + "") | ||
| 15319 | + | ||
| 15320 | +;;============================================================================= | ||
| 15321 | +;; Peephole optimizing | ||
| 15322 | +;;----------------------------------------------------------------------------- | ||
| 15323 | +;; Changing | ||
| 15324 | +;; ld.ub r0, r7[-0x6] | ||
| 15325 | +;; cashu.b r0 | ||
| 15326 | +;; to | ||
| 15327 | +;; ld.ub r0, r7[-0x6] | ||
| 15328 | +;;============================================================================= | ||
| 15329 | +(define_peephole2 | ||
| 15330 | + [(set (match_operand:QI 0 "register_operand" "") | ||
| 15331 | + (match_operand:QI 1 "memory_operand" "")) | ||
| 15332 | + (set (match_operand:SI 2 "register_operand" "") | ||
| 15333 | + (zero_extend:SI (match_dup 0)))] | ||
| 15334 | + "(REGNO(operands[0]) == REGNO(operands[2])) || peep2_reg_dead_p(2, operands[0])" | ||
| 15335 | + [(set (match_dup 2) | ||
| 15336 | + (zero_extend:SI (match_dup 1)))] | ||
| 15337 | + "") | ||
| 15338 | + | ||
| 15339 | +;;============================================================================= | ||
| 15340 | +;; Peephole optimizing | ||
| 15341 | +;;----------------------------------------------------------------------------- | ||
| 15342 | +;; Changing | ||
| 15343 | +;; ld.sh r0, r7[-0x6] | ||
| 15344 | +;; casts.h r0 | ||
| 15345 | +;; to | ||
| 15346 | +;; ld.sh r0, r7[-0x6] | ||
| 15347 | +;;============================================================================= | ||
| 15348 | +(define_peephole2 | ||
| 15349 | + [(set (match_operand:HI 0 "register_operand" "") | ||
| 15350 | + (match_operand:HI 1 "memory_operand" "")) | ||
| 15351 | + (set (match_operand:SI 2 "register_operand" "") | ||
| 15352 | + (sign_extend:SI (match_dup 0)))] | ||
| 15353 | + "(REGNO(operands[0]) == REGNO(operands[2])) || peep2_reg_dead_p(2, operands[0])" | ||
| 15354 | + [(set (match_dup 2) | ||
| 15355 | + (sign_extend:SI (match_dup 1)))] | ||
| 15356 | + "") | ||
| 15357 | + | ||
| 15358 | +;;============================================================================= | ||
| 15359 | +;; Peephole optimizing | ||
| 15360 | +;;----------------------------------------------------------------------------- | ||
| 15361 | +;; Changing | ||
| 15362 | +;; ld.uh r0, r7[-0x6] | ||
| 15363 | +;; castu.h r0 | ||
| 15364 | +;; to | ||
| 15365 | +;; ld.uh r0, r7[-0x6] | ||
| 15366 | +;;============================================================================= | ||
| 15367 | +(define_peephole2 | ||
| 15368 | + [(set (match_operand:HI 0 "register_operand" "") | ||
| 15369 | + (match_operand:HI 1 "memory_operand" "")) | ||
| 15370 | + (set (match_operand:SI 2 "register_operand" "") | ||
| 15371 | + (zero_extend:SI (match_dup 0)))] | ||
| 15372 | + "(REGNO(operands[0]) == REGNO(operands[2])) || peep2_reg_dead_p(2, operands[0])" | ||
| 15373 | + [(set (match_dup 2) | ||
| 15374 | + (zero_extend:SI (match_dup 1)))] | ||
| 15375 | + "") | ||
| 15376 | + | ||
| 15377 | +;;============================================================================= | ||
| 15378 | +;; Peephole optimizing | ||
| 15379 | +;;----------------------------------------------------------------------------- | ||
| 15380 | +;; Changing | ||
| 15381 | +;; mul rd, rx, ry | ||
| 15382 | +;; add rd2, rd | ||
| 15383 | +;; to | ||
| 15384 | +;; mac rd2, rx, ry | ||
| 15385 | +;;============================================================================= | ||
| 15386 | +(define_peephole2 | ||
| 15387 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15388 | + (mult:SI (match_operand:SI 1 "register_operand" "") | ||
| 15389 | + (match_operand:SI 2 "register_operand" ""))) | ||
| 15390 | + (set (match_operand:SI 3 "register_operand" "") | ||
| 15391 | + (plus:SI (match_dup 3) | ||
| 15392 | + (match_dup 0)))] | ||
| 15393 | + "peep2_reg_dead_p(2, operands[0])" | ||
| 15394 | + [(set (match_dup 3) | ||
| 15395 | + (plus:SI (mult:SI (match_dup 1) | ||
| 15396 | + (match_dup 2)) | ||
| 15397 | + (match_dup 3)))] | ||
| 15398 | + "") | ||
| 15399 | + | ||
| 15400 | + | ||
| 15401 | + | ||
| 15402 | +;;============================================================================= | ||
| 15403 | +;; Peephole optimizing | ||
| 15404 | +;;----------------------------------------------------------------------------- | ||
| 15405 | +;; Changing | ||
| 15406 | +;; bfextu rd, rs, k5, 1 or and(h/l) rd, one_bit_set_mask | ||
| 15407 | +;; to | ||
| 15408 | +;; bld rs, k5 | ||
| 15409 | +;; | ||
| 15410 | +;; If rd is dead after the operation. | ||
| 15411 | +;;============================================================================= | ||
| 15412 | +(define_peephole2 | ||
| 15413 | + [ (set (match_operand:SI 0 "register_operand" "") | ||
| 15414 | + (zero_extract:SI (match_operand:SI 1 "register_operand" "") | ||
| 15415 | + (const_int 1) | ||
| 15416 | + (match_operand:SI 2 "immediate_operand" ""))) | ||
| 15417 | + (set (cc0) | ||
| 15418 | + (match_dup 0))] | ||
| 15419 | + "peep2_reg_dead_p(2, operands[0])" | ||
| 15420 | + [(set (cc0) | ||
| 15421 | + (and:SI (match_dup 1) | ||
| 15422 | + (match_dup 2)))] | ||
| 15423 | + "operands[2] = GEN_INT(1 << INTVAL(operands[2]));") | ||
| 15424 | + | ||
| 15425 | +(define_peephole2 | ||
| 15426 | + [ (set (match_operand:SI 0 "register_operand" "") | ||
| 15427 | + (and:SI (match_operand:SI 1 "register_operand" "") | ||
| 15428 | + (match_operand:SI 2 "one_bit_set_operand" ""))) | ||
| 15429 | + (set (cc0) | ||
| 15430 | + (match_dup 0))] | ||
| 15431 | + "peep2_reg_dead_p(2, operands[0])" | ||
| 15432 | + [(set (cc0) | ||
| 15433 | + (and:SI (match_dup 1) | ||
| 15434 | + (match_dup 2)))] | ||
| 15435 | + "") | ||
| 15436 | + | ||
| 15437 | +;;============================================================================= | ||
| 15438 | +;; Peephole optimizing | ||
| 15439 | +;;----------------------------------------------------------------------------- | ||
| 15440 | +;; Load with extracted index: ld.w Rd, Rb[Ri:{t/u/b/l} << 2] | ||
| 15441 | +;; | ||
| 15442 | +;;============================================================================= | ||
| 15443 | + | ||
| 15444 | + | ||
| 15445 | +(define_peephole | ||
| 15446 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15447 | + (zero_extract:SI (match_operand:SI 1 "register_operand" "") | ||
| 15448 | + (const_int 8) | ||
| 15449 | + (match_operand:SI 2 "avr32_extract_shift_operand" ""))) | ||
| 15450 | + (set (match_operand:SI 3 "register_operand" "") | ||
| 15451 | + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) | ||
| 15452 | + (match_operand:SI 4 "register_operand" ""))))] | ||
| 15453 | + | ||
| 15454 | + "(dead_or_set_p(insn, operands[0]))" | ||
| 15455 | + { | ||
| 15456 | + switch ( INTVAL(operands[2]) ){ | ||
| 15457 | + case 0: | ||
| 15458 | + return "ld.w %3, %4[%1:b << 2]"; | ||
| 15459 | + case 8: | ||
| 15460 | + return "ld.w %3, %4[%1:l << 2]"; | ||
| 15461 | + case 16: | ||
| 15462 | + return "ld.w %3, %4[%1:u << 2]"; | ||
| 15463 | + case 24: | ||
| 15464 | + return "ld.w %3, %4[%1:t << 2]"; | ||
| 15465 | + default: | ||
| 15466 | + internal_error("illegal operand for ldxi"); | ||
| 15467 | + } | ||
| 15468 | + } | ||
| 15469 | + [(set_attr "type" "load") | ||
| 15470 | + (set_attr "length" "4") | ||
| 15471 | + (set_attr "cc" "clobber")] | ||
| 15472 | + ) | ||
| 15473 | + | ||
| 15474 | + | ||
| 15475 | + | ||
| 15476 | +(define_peephole | ||
| 15477 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15478 | + (and:SI (match_operand:SI 1 "register_operand" "") (const_int 255))) | ||
| 15479 | + (set (match_operand:SI 2 "register_operand" "") | ||
| 15480 | + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) | ||
| 15481 | + (match_operand:SI 3 "register_operand" ""))))] | ||
| 15482 | + | ||
| 15483 | + "(dead_or_set_p(insn, operands[0]))" | ||
| 15484 | + | ||
| 15485 | + "ld.w %2, %3[%1:b << 2]" | ||
| 15486 | + [(set_attr "type" "load") | ||
| 15487 | + (set_attr "length" "4") | ||
| 15488 | + (set_attr "cc" "clobber")] | ||
| 15489 | + ) | ||
| 15490 | + | ||
| 15491 | + | ||
| 15492 | +(define_peephole2 | ||
| 15493 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15494 | + (zero_extract:SI (match_operand:SI 1 "register_operand" "") | ||
| 15495 | + (const_int 8) | ||
| 15496 | + (match_operand:SI 2 "avr32_extract_shift_operand" ""))) | ||
| 15497 | + (set (match_operand:SI 3 "register_operand" "") | ||
| 15498 | + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) | ||
| 15499 | + (match_operand:SI 4 "register_operand" ""))))] | ||
| 15500 | + | ||
| 15501 | + "(peep2_reg_dead_p(2, operands[0])) | ||
| 15502 | + || (REGNO(operands[0]) == REGNO(operands[3]))" | ||
| 15503 | + [(set (match_dup 3) | ||
| 15504 | + (mem:SI (plus:SI | ||
| 15505 | + (match_dup 4) | ||
| 15506 | + (mult:SI (zero_extract:SI (match_dup 1) | ||
| 15507 | + (const_int 8) | ||
| 15508 | + (match_dup 2)) | ||
| 15509 | + (const_int 4)))))] | ||
| 15510 | + ) | ||
| 15511 | + | ||
| 15512 | +(define_peephole2 | ||
| 15513 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15514 | + (zero_extend:SI (match_operand:QI 1 "register_operand" ""))) | ||
| 15515 | + (set (match_operand:SI 2 "register_operand" "") | ||
| 15516 | + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) | ||
| 15517 | + (match_operand:SI 3 "register_operand" ""))))] | ||
| 15518 | + | ||
| 15519 | + "(peep2_reg_dead_p(2, operands[0])) | ||
| 15520 | + || (REGNO(operands[0]) == REGNO(operands[2]))" | ||
| 15521 | + [(set (match_dup 2) | ||
| 15522 | + (mem:SI (plus:SI | ||
| 15523 | + (match_dup 3) | ||
| 15524 | + (mult:SI (zero_extract:SI (match_dup 1) | ||
| 15525 | + (const_int 8) | ||
| 15526 | + (const_int 0)) | ||
| 15527 | + (const_int 4)))))] | ||
| 15528 | + "operands[1] = gen_rtx_REG(SImode, REGNO(operands[1]));" | ||
| 15529 | + ) | ||
| 15530 | + | ||
| 15531 | + | ||
| 15532 | +(define_peephole2 | ||
| 15533 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15534 | + (and:SI (match_operand:SI 1 "register_operand" "") | ||
| 15535 | + (const_int 255))) | ||
| 15536 | + (set (match_operand:SI 2 "register_operand" "") | ||
| 15537 | + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) | ||
| 15538 | + (match_operand:SI 3 "register_operand" ""))))] | ||
| 15539 | + | ||
| 15540 | + "(peep2_reg_dead_p(2, operands[0])) | ||
| 15541 | + || (REGNO(operands[0]) == REGNO(operands[2]))" | ||
| 15542 | + [(set (match_dup 2) | ||
| 15543 | + (mem:SI (plus:SI | ||
| 15544 | + (match_dup 3) | ||
| 15545 | + (mult:SI (zero_extract:SI (match_dup 1) | ||
| 15546 | + (const_int 8) | ||
| 15547 | + (const_int 0)) | ||
| 15548 | + (const_int 4)))))] | ||
| 15549 | + "" | ||
| 15550 | + ) | ||
| 15551 | + | ||
| 15552 | + | ||
| 15553 | + | ||
| 15554 | +(define_peephole2 | ||
| 15555 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15556 | + (lshiftrt:SI (match_operand:SI 1 "register_operand" "") | ||
| 15557 | + (const_int 24))) | ||
| 15558 | + (set (match_operand:SI 2 "register_operand" "") | ||
| 15559 | + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) | ||
| 15560 | + (match_operand:SI 3 "register_operand" ""))))] | ||
| 15561 | + | ||
| 15562 | + "(peep2_reg_dead_p(2, operands[0])) | ||
| 15563 | + || (REGNO(operands[0]) == REGNO(operands[2]))" | ||
| 15564 | + [(set (match_dup 2) | ||
| 15565 | + (mem:SI (plus:SI | ||
| 15566 | + (match_dup 3) | ||
| 15567 | + (mult:SI (zero_extract:SI (match_dup 1) | ||
| 15568 | + (const_int 8) | ||
| 15569 | + (const_int 24)) | ||
| 15570 | + (const_int 4)))))] | ||
| 15571 | + "" | ||
| 15572 | + ) | ||
| 15573 | + | ||
| 15574 | + | ||
| 15575 | +;;************************************************ | ||
| 15576 | +;; ANDN | ||
| 15577 | +;; | ||
| 15578 | +;;************************************************ | ||
| 15579 | + | ||
| 15580 | + | ||
| 15581 | +(define_peephole2 | ||
| 15582 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15583 | + (not:SI (match_operand:SI 1 "register_operand" ""))) | ||
| 15584 | + (set (match_operand:SI 2 "register_operand" "") | ||
| 15585 | + (and:SI (match_dup 2) | ||
| 15586 | + (match_dup 0)))] | ||
| 15587 | + "peep2_reg_dead_p(2, operands[0])" | ||
| 15588 | + | ||
| 15589 | + [(set (match_dup 2) | ||
| 15590 | + (and:SI (match_dup 2) | ||
| 15591 | + (not:SI (match_dup 1)) | ||
| 15592 | + ))] | ||
| 15593 | + "" | ||
| 15594 | +) | ||
| 15595 | + | ||
| 15596 | +(define_peephole2 | ||
| 15597 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15598 | + (not:SI (match_operand:SI 1 "register_operand" ""))) | ||
| 15599 | + (set (match_operand:SI 2 "register_operand" "") | ||
| 15600 | + (and:SI (match_dup 0) | ||
| 15601 | + (match_dup 2) | ||
| 15602 | + ))] | ||
| 15603 | + "peep2_reg_dead_p(2, operands[0])" | ||
| 15604 | + | ||
| 15605 | + [(set (match_dup 2) | ||
| 15606 | + (and:SI (match_dup 2) | ||
| 15607 | + (not:SI (match_dup 1)) | ||
| 15608 | + ))] | ||
| 15609 | + | ||
| 15610 | + "" | ||
| 15611 | +) | ||
| 15612 | + | ||
| 15613 | + | ||
| 15614 | +;;================================================================= | ||
| 15615 | +;; Addabs peephole | ||
| 15616 | +;;================================================================= | ||
| 15617 | + | ||
| 15618 | +(define_peephole | ||
| 15619 | + [(set (match_operand:SI 2 "register_operand" "=r") | ||
| 15620 | + (abs:SI (match_operand:SI 1 "register_operand" "r"))) | ||
| 15621 | + (set (match_operand:SI 0 "register_operand" "=r") | ||
| 15622 | + (plus:SI (match_operand:SI 3 "register_operand" "r") | ||
| 15623 | + (match_dup 2)))] | ||
| 15624 | + "dead_or_set_p(insn, operands[2])" | ||
| 15625 | + "addabs %0, %3, %1" | ||
| 15626 | + [(set_attr "length" "4") | ||
| 15627 | + (set_attr "cc" "set_z")]) | ||
| 15628 | + | ||
| 15629 | +(define_peephole | ||
| 15630 | + [(set (match_operand:SI 2 "register_operand" "=r") | ||
| 15631 | + (abs:SI (match_operand:SI 1 "register_operand" "r"))) | ||
| 15632 | + (set (match_operand:SI 0 "register_operand" "=r") | ||
| 15633 | + (plus:SI (match_dup 2) | ||
| 15634 | + (match_operand:SI 3 "register_operand" "r")))] | ||
| 15635 | + "dead_or_set_p(insn, operands[2])" | ||
| 15636 | + "addabs %0, %3, %1" | ||
| 15637 | + [(set_attr "length" "4") | ||
| 15638 | + (set_attr "cc" "set_z")]) | ||
| 15639 | + | ||
| 15640 | + | ||
| 15641 | +;;================================================================= | ||
| 15642 | +;; Detect roundings | ||
| 15643 | +;;================================================================= | ||
| 15644 | + | ||
| 15645 | +(define_insn "*round" | ||
| 15646 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 15647 | + (ashiftrt:SI (plus:SI (match_operand:SI 1 "register_operand" "0") | ||
| 15648 | + (match_operand:SI 2 "immediate_operand" "i")) | ||
| 15649 | + (match_operand:SI 3 "immediate_operand" "i")))] | ||
| 15650 | + "avr32_rnd_operands(operands[2], operands[3])" | ||
| 15651 | + | ||
| 15652 | + "satrnds %0 >> %3, 31" | ||
| 15653 | + | ||
| 15654 | + [(set_attr "type" "alu_sat") | ||
| 15655 | + (set_attr "length" "4")] | ||
| 15656 | + | ||
| 15657 | + ) | ||
| 15658 | + | ||
| 15659 | + | ||
| 15660 | +(define_peephole2 | ||
| 15661 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15662 | + (plus:SI (match_dup 0) | ||
| 15663 | + (match_operand:SI 1 "immediate_operand" ""))) | ||
| 15664 | + (set (match_dup 0) | ||
| 15665 | + (ashiftrt:SI (match_dup 0) | ||
| 15666 | + (match_operand:SI 2 "immediate_operand" "")))] | ||
| 15667 | + "avr32_rnd_operands(operands[1], operands[2])" | ||
| 15668 | + | ||
| 15669 | + [(set (match_dup 0) | ||
| 15670 | + (ashiftrt:SI (plus:SI (match_dup 0) | ||
| 15671 | + (match_dup 1)) | ||
| 15672 | + (match_dup 2)))] | ||
| 15673 | + ) | ||
| 15674 | + | ||
| 15675 | +(define_peephole | ||
| 15676 | + [(set (match_operand:SI 0 "register_operand" "r") | ||
| 15677 | + (plus:SI (match_dup 0) | ||
| 15678 | + (match_operand:SI 1 "immediate_operand" "i"))) | ||
| 15679 | + (set (match_dup 0) | ||
| 15680 | + (ashiftrt:SI (match_dup 0) | ||
| 15681 | + (match_operand:SI 2 "immediate_operand" "i")))] | ||
| 15682 | + "avr32_rnd_operands(operands[1], operands[2])" | ||
| 15683 | + | ||
| 15684 | + "satrnds %0 >> %2, 31" | ||
| 15685 | + | ||
| 15686 | + [(set_attr "type" "alu_sat") | ||
| 15687 | + (set_attr "length" "4") | ||
| 15688 | + (set_attr "cc" "clobber")] | ||
| 15689 | + | ||
| 15690 | + ) | ||
| 15691 | + | ||
| 15692 | + | ||
| 15693 | + | ||
| 15694 | + | ||
| 15695 | +;;================================================================= | ||
| 15696 | +;; Conditional Subtract | ||
| 15697 | +;;================================================================= | ||
| 15698 | + | ||
| 15699 | + | ||
| 15700 | +(define_peephole | ||
| 15701 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15702 | + (minus:SI (match_operand:SI 1 "register_operand" "") | ||
| 15703 | + (match_operand:SI 2 "immediate_operand" ""))) | ||
| 15704 | + (set (match_dup 1) | ||
| 15705 | + (unspec:SI [(match_operand 5 "avr32_comparison_operator" "") | ||
| 15706 | + (match_dup 0) | ||
| 15707 | + (match_dup 1) | ||
| 15708 | + (match_operand 3 "general_operand" "") | ||
| 15709 | + (match_operand 4 "general_operand" "")] | ||
| 15710 | + UNSPEC_MOVSICC))] | ||
| 15711 | + | ||
| 15712 | + "(dead_or_set_p(insn, operands[0])) && avr32_const_ok_for_constraint_p(INTVAL(operands[2]), 'K', \"Ks08\")" | ||
| 15713 | + | ||
| 15714 | + { | ||
| 15715 | + | ||
| 15716 | + operands[5] = avr32_output_cmp(operands[5], GET_MODE(operands[3]), operands[3], operands[4]); | ||
| 15717 | + | ||
| 15718 | + return "sub%5 %1, %2"; | ||
| 15719 | + } | ||
| 15720 | + | ||
| 15721 | + [(set_attr "length" "10") | ||
| 15722 | + (set_attr "cc" "clobber")] | ||
| 15723 | + ) | ||
| 15724 | + | ||
| 15725 | +(define_peephole | ||
| 15726 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15727 | + (plus:SI (match_operand:SI 1 "register_operand" "") | ||
| 15728 | + (match_operand:SI 2 "immediate_operand" ""))) | ||
| 15729 | + (set (match_dup 1) | ||
| 15730 | + (unspec:SI [(match_operand 5 "avr32_comparison_operator" "") | ||
| 15731 | + (match_dup 0) | ||
| 15732 | + (match_dup 1) | ||
| 15733 | + (match_operand 3 "general_operand" "") | ||
| 15734 | + (match_operand 4 "general_operand" "")] | ||
| 15735 | + UNSPEC_MOVSICC))] | ||
| 15736 | + | ||
| 15737 | + "(dead_or_set_p(insn, operands[0]) && avr32_const_ok_for_constraint_p(INTVAL(operands[2]), 'I', \"Is08\"))" | ||
| 15738 | + | ||
| 15739 | + { | ||
| 15740 | + operands[5] = avr32_output_cmp(operands[5], GET_MODE(operands[3]), operands[3], operands[4]); | ||
| 15741 | + | ||
| 15742 | + return "sub%5 %1, %n2"; | ||
| 15743 | + } | ||
| 15744 | + [(set_attr "length" "10") | ||
| 15745 | + (set_attr "cc" "clobber")] | ||
| 15746 | + ) | ||
| 15747 | + | ||
| 15748 | +;;================================================================= | ||
| 15749 | +;; mcall | ||
| 15750 | +;;================================================================= | ||
| 15751 | +(define_peephole | ||
| 15752 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15753 | + (match_operand 1 "avr32_const_pool_ref_operand" "")) | ||
| 15754 | + (parallel [(call (mem:SI (match_dup 0)) | ||
| 15755 | + (match_operand 2 "" "")) | ||
| 15756 | + (clobber (reg:SI LR_REGNUM))])] | ||
| 15757 | + "dead_or_set_p(insn, operands[0])" | ||
| 15758 | + "mcall %1" | ||
| 15759 | + [(set_attr "type" "call") | ||
| 15760 | + (set_attr "length" "4") | ||
| 15761 | + (set_attr "cc" "clobber")] | ||
| 15762 | +) | ||
| 15763 | + | ||
| 15764 | +(define_peephole | ||
| 15765 | + [(set (match_operand:SI 2 "register_operand" "") | ||
| 15766 | + (match_operand 1 "avr32_const_pool_ref_operand" "")) | ||
| 15767 | + (parallel [(set (match_operand 0 "register_operand" "") | ||
| 15768 | + (call (mem:SI (match_dup 2)) | ||
| 15769 | + (match_operand 3 "" ""))) | ||
| 15770 | + (clobber (reg:SI LR_REGNUM))])] | ||
| 15771 | + "dead_or_set_p(insn, operands[2])" | ||
| 15772 | + "mcall %1" | ||
| 15773 | + [(set_attr "type" "call") | ||
| 15774 | + (set_attr "length" "4") | ||
| 15775 | + (set_attr "cc" "call_set")] | ||
| 15776 | +) | ||
| 15777 | + | ||
| 15778 | + | ||
| 15779 | +(define_peephole2 | ||
| 15780 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15781 | + (match_operand 1 "avr32_const_pool_ref_operand" "")) | ||
| 15782 | + (parallel [(call (mem:SI (match_dup 0)) | ||
| 15783 | + (match_operand 2 "" "")) | ||
| 15784 | + (clobber (reg:SI LR_REGNUM))])] | ||
| 15785 | + "peep2_reg_dead_p(2, operands[0])" | ||
| 15786 | + [(parallel [(call (mem:SI (match_dup 1)) | ||
| 15787 | + (match_dup 2)) | ||
| 15788 | + (clobber (reg:SI LR_REGNUM))])] | ||
| 15789 | + "" | ||
| 15790 | +) | ||
| 15791 | + | ||
| 15792 | +(define_peephole2 | ||
| 15793 | + [(set (match_operand:SI 0 "register_operand" "") | ||
| 15794 | + (match_operand 1 "avr32_const_pool_ref_operand" "")) | ||
| 15795 | + (parallel [(set (match_operand 2 "register_operand" "") | ||
| 15796 | + (call (mem:SI (match_dup 0)) | ||
| 15797 | + (match_operand 3 "" ""))) | ||
| 15798 | + (clobber (reg:SI LR_REGNUM))])] | ||
| 15799 | + "(peep2_reg_dead_p(2, operands[0]) || (REGNO(operands[2]) == REGNO(operands[0])))" | ||
| 15800 | + [(parallel [(set (match_dup 2) | ||
| 15801 | + (call (mem:SI (match_dup 1)) | ||
| 15802 | + (match_dup 3))) | ||
| 15803 | + (clobber (reg:SI LR_REGNUM))])] | ||
| 15804 | + "" | ||
| 15805 | +) | ||
| 15806 | + | ||
| 15807 | +;;================================================================= | ||
| 15808 | +;; Returning a value | ||
| 15809 | +;;================================================================= | ||
| 15810 | + | ||
| 15811 | + | ||
| 15812 | +(define_peephole | ||
| 15813 | + [(set (match_operand 0 "register_operand" "") | ||
| 15814 | + (match_operand 1 "register_operand" "")) | ||
| 15815 | + (return)] | ||
| 15816 | + "USE_RETURN_INSN (TRUE) && (REGNO(operands[0]) == RETVAL_REGNUM) | ||
| 15817 | + && (REGNO(operands[1]) != LR_REGNUM) | ||
| 15818 | + && (REGNO_REG_CLASS(REGNO(operands[1])) == GENERAL_REGS)" | ||
| 15819 | + "retal %1" | ||
| 15820 | + [(set_attr "type" "call") | ||
| 15821 | + (set_attr "length" "2")] | ||
| 15822 | + ) | ||
| 15823 | + | ||
| 15824 | + | ||
| 15825 | +(define_peephole | ||
| 15826 | + [(set (match_operand 0 "register_operand" "r") | ||
| 15827 | + (match_operand 1 "immediate_operand" "i")) | ||
| 15828 | + (return)] | ||
| 15829 | + "(USE_RETURN_INSN (FALSE) && (REGNO(operands[0]) == RETVAL_REGNUM) && | ||
| 15830 | + ((INTVAL(operands[1]) == -1) || (INTVAL(operands[1]) == 0) || (INTVAL(operands[1]) == 1)))" | ||
| 15831 | + { | ||
| 15832 | + avr32_output_return_instruction (TRUE, FALSE, NULL, operands[1]); | ||
| 15833 | + return ""; | ||
| 15834 | + } | ||
| 15835 | + [(set_attr "type" "call") | ||
| 15836 | + (set_attr "length" "4")] | ||
| 15837 | + ) | ||
| 15838 | + | ||
| 15839 | +(define_peephole | ||
| 15840 | + [(set (match_operand 0 "register_operand" "r") | ||
| 15841 | + (match_operand 1 "immediate_operand" "i")) | ||
| 15842 | + (unspec_volatile [(return)] VUNSPEC_EPILOGUE)] | ||
| 15843 | + "(REGNO(operands[0]) == RETVAL_REGNUM) && | ||
| 15844 | + ((INTVAL(operands[1]) == -1) || (INTVAL(operands[1]) == 0) || (INTVAL(operands[1]) == 1))" | ||
| 15845 | + { | ||
| 15846 | + avr32_output_return_instruction (FALSE, FALSE, NULL, operands[1]); | ||
| 15847 | + return ""; | ||
| 15848 | + } | ||
| 15849 | + ; Length is absolute worst case | ||
| 15850 | + [(set_attr "type" "branch") | ||
| 15851 | + (set_attr "length" "12")] | ||
| 15852 | + ) | ||
| 15853 | + | ||
| 15854 | +(define_peephole | ||
| 15855 | + [(set (match_operand 0 "register_operand" "r") | ||
| 15856 | + (unspec [(match_operand 1 "avr32_comparison_operator" "") | ||
| 15857 | + (match_operand 2 "register_immediate_operand" "rKs08") | ||
| 15858 | + (match_operand 3 "register_immediate_operand" "rKs08") | ||
| 15859 | + (match_operand 4 "register_immediate_operand" "r") | ||
| 15860 | + (match_operand 5 "register_immediate_operand" "rKs21") | ||
| 15861 | + ] | ||
| 15862 | + UNSPEC_MOVSICC )) | ||
| 15863 | + (return)] | ||
| 15864 | + "USE_RETURN_INSN (TRUE) && (REGNO(operands[0]) == RETVAL_REGNUM) && | ||
| 15865 | + ((GET_MODE(operands[4]) == SImode) || | ||
| 15866 | + ((GET_MODE(operands[4]) != SImode) && (GET_CODE(operands[5]) == REG)))" | ||
| 15867 | + { | ||
| 15868 | + operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]); | ||
| 15869 | + | ||
| 15870 | + if ( GET_CODE(operands[2]) == REG | ||
| 15871 | + && GET_CODE(operands[3]) == REG | ||
| 15872 | + && REGNO(operands[2]) != LR_REGNUM | ||
| 15873 | + && REGNO(operands[3]) != LR_REGNUM ){ | ||
| 15874 | + return "ret%1 %2\;ret%i1 %3"; | ||
| 15875 | + } else if ( GET_CODE(operands[2]) == REG | ||
| 15876 | + && GET_CODE(operands[3]) == CONST_INT ){ | ||
| 15877 | + if ( INTVAL(operands[3]) == -1 | ||
| 15878 | + || INTVAL(operands[3]) == 0 | ||
| 15879 | + || INTVAL(operands[3]) == 1 ){ | ||
| 15880 | + return "ret%1 %2\;ret%i1 %d3"; | ||
| 15881 | + } else { | ||
| 15882 | + return "mov%1 r12, %2\;mov%i1 r12, %3\;retal r12"; | ||
| 15883 | + } | ||
| 15884 | + } else if ( GET_CODE(operands[2]) == CONST_INT | ||
| 15885 | + && GET_CODE(operands[3]) == REG ){ | ||
| 15886 | + if ( INTVAL(operands[2]) == -1 | ||
| 15887 | + || INTVAL(operands[2]) == 0 | ||
| 15888 | + || INTVAL(operands[2]) == 1 ){ | ||
| 15889 | + return "ret%1 %d2\;ret%i1 %3"; | ||
| 15890 | + } else { | ||
| 15891 | + return "mov%1 r12, %2\;mov%i1 r12, %3\;retal r12"; | ||
| 15892 | + } | ||
| 15893 | + } else { | ||
| 15894 | + if ( (INTVAL(operands[2]) == -1 | ||
| 15895 | + || INTVAL(operands[2]) == 0 | ||
| 15896 | + || INTVAL(operands[2]) == 1 ) | ||
| 15897 | + && (INTVAL(operands[3]) == -1 | ||
| 15898 | + || INTVAL(operands[3]) == 0 | ||
| 15899 | + || INTVAL(operands[3]) == 1 )){ | ||
| 15900 | + return "ret%1 %d2\;ret%i1 %d3"; | ||
| 15901 | + } else { | ||
| 15902 | + return "mov%1 r12, %2\;mov%i1 r12, %3\;retal r12"; | ||
| 15903 | + } | ||
| 15904 | + } | ||
| 15905 | + } | ||
| 15906 | + | ||
| 15907 | + [(set_attr "length" "14") | ||
| 15908 | + (set_attr "cc" "clobber") | ||
| 15909 | + (set_attr "type" "call")]) | ||
| 15910 | + | ||
| 15911 | + | ||
| 15912 | +;;================================================================= | ||
| 15913 | +;; mulnhh.w | ||
| 15914 | +;;================================================================= | ||
| 15915 | + | ||
| 15916 | +(define_peephole2 | ||
| 15917 | + [(set (match_operand:HI 0 "register_operand" "") | ||
| 15918 | + (neg:HI (match_operand:HI 1 "register_operand" ""))) | ||
| 15919 | + (set (match_operand:SI 2 "register_operand" "") | ||
| 15920 | + (mult:SI | ||
| 15921 | + (sign_extend:SI (match_dup 0)) | ||
| 15922 | + (sign_extend:SI (match_operand:HI 3 "register_operand" ""))))] | ||
| 15923 | + "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[2]) == REGNO(operands[0]))" | ||
| 15924 | + [ (set (match_dup 2) | ||
| 15925 | + (mult:SI | ||
| 15926 | + (sign_extend:SI (neg:HI (match_dup 1))) | ||
| 15927 | + (sign_extend:SI (match_dup 3))))] | ||
| 15928 | + "" | ||
| 15929 | + ) | ||
| 15930 | + | ||
| 15931 | +(define_peephole2 | ||
| 15932 | + [(set (match_operand:HI 0 "register_operand" "") | ||
| 15933 | + (neg:HI (match_operand:HI 1 "register_operand" ""))) | ||
| 15934 | + (set (match_operand:SI 2 "register_operand" "") | ||
| 15935 | + (mult:SI | ||
| 15936 | + (sign_extend:SI (match_operand:HI 3 "register_operand" "")) | ||
| 15937 | + (sign_extend:SI (match_dup 0))))] | ||
| 15938 | + "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[2]) == REGNO(operands[0]))" | ||
| 15939 | + [ (set (match_dup 2) | ||
| 15940 | + (mult:SI | ||
| 15941 | + (sign_extend:SI (neg:HI (match_dup 1))) | ||
| 15942 | + (sign_extend:SI (match_dup 3))))] | ||
| 15943 | + "" | ||
| 15944 | + ) | ||
| 15945 | + | ||
| 15946 | + | ||
| 15947 | + | ||
| 15948 | +;;================================================================= | ||
| 15949 | +;; sthh.w | ||
| 15950 | +;;================================================================= | ||
| 15951 | +(define_insn "vec_setv2hi" | ||
| 15952 | + [(set (match_operand:V2HI 0 "register_operand" "=r") | ||
| 15953 | + (vec_merge:V2HI | ||
| 15954 | + (match_dup 0) | ||
| 15955 | + (vec_duplicate:V2HI | ||
| 15956 | + (match_operand:HI 1 "register_operand" "r")) | ||
| 15957 | + (const_int 1)))] | ||
| 15958 | + "" | ||
| 15959 | + "bfins\t%0, %1, 16, 16" | ||
| 15960 | + [(set_attr "type" "alu") | ||
| 15961 | + (set_attr "length" "4") | ||
| 15962 | + (set_attr "cc" "clobber")]) | ||
| 15963 | + | ||
| 15964 | +(define_insn "vec_setv2lo" | ||
| 15965 | + [(set (match_operand:V2HI 0 "register_operand" "+r") | ||
| 15966 | + (vec_merge:V2HI | ||
| 15967 | + (match_dup 0) | ||
| 15968 | + (vec_duplicate:V2HI | ||
| 15969 | + (match_operand:HI 1 "register_operand" "r")) | ||
| 15970 | + (const_int 2)))] | ||
| 15971 | + "" | ||
| 15972 | + "bfins\t%0, %1, 0, 16" | ||
| 15973 | + [(set_attr "type" "alu") | ||
| 15974 | + (set_attr "length" "4") | ||
| 15975 | + (set_attr "cc" "clobber")]) | ||
| 15976 | + | ||
| 15977 | +(define_expand "vec_setv2" | ||
| 15978 | + [(set (match_operand:V2HI 0 "register_operand" "") | ||
| 15979 | + (vec_merge:V2HI | ||
| 15980 | + (match_dup 0) | ||
| 15981 | + (vec_duplicate:V2HI | ||
| 15982 | + (match_operand:HI 1 "register_operand" "")) | ||
| 15983 | + (match_operand 2 "immediate_operand" "")))] | ||
| 15984 | + "" | ||
| 15985 | + { operands[2] = GEN_INT(INTVAL(operands[2]) + 1); } | ||
| 15986 | + ) | ||
| 15987 | + | ||
| 15988 | +(define_insn "vec_extractv2hi" | ||
| 15989 | + [(set (match_operand:HI 0 "register_operand" "=r") | ||
| 15990 | + (vec_select:HI | ||
| 15991 | + (match_operand:V2HI 1 "register_operand" "r") | ||
| 15992 | + (parallel [(match_operand:SI 2 "immediate_operand" "i")])))] | ||
| 15993 | + "" | ||
| 15994 | + { | ||
| 15995 | + if ( INTVAL(operands[2]) == 0 ) | ||
| 15996 | + return "bfextu\t%0, %1, 16, 16"; | ||
| 15997 | + else | ||
| 15998 | + return "bfextu\t%0, %1, 0, 16"; | ||
| 15999 | + } | ||
| 16000 | + [(set_attr "type" "alu") | ||
| 16001 | + (set_attr "length" "4") | ||
| 16002 | + (set_attr "cc" "clobber")]) | ||
| 16003 | + | ||
| 16004 | +(define_insn "vec_extractv4qi" | ||
| 16005 | + [(set (match_operand:QI 0 "register_operand" "=r") | ||
| 16006 | + (vec_select:QI | ||
| 16007 | + (match_operand:V4QI 1 "register_operand" "r") | ||
| 16008 | + (parallel [(match_operand:SI 2 "immediate_operand" "i")])))] | ||
| 16009 | + "" | ||
| 16010 | + { | ||
| 16011 | + switch ( INTVAL(operands[2]) ){ | ||
| 16012 | + case 0: | ||
| 16013 | + return "bfextu\t%0, %1, 24, 8"; | ||
| 16014 | + case 1: | ||
| 16015 | + return "bfextu\t%0, %1, 16, 8"; | ||
| 16016 | + case 2: | ||
| 16017 | + return "bfextu\t%0, %1, 8, 8"; | ||
| 16018 | + case 3: | ||
| 16019 | + return "bfextu\t%0, %1, 0, 8"; | ||
| 16020 | + default: | ||
| 16021 | + abort(); | ||
| 16022 | + } | ||
| 16023 | + } | ||
| 16024 | + [(set_attr "type" "alu") | ||
| 16025 | + (set_attr "length" "4") | ||
| 16026 | + (set_attr "cc" "clobber")]) | ||
| 16027 | + | ||
| 16028 | + | ||
| 16029 | +(define_insn "concatv2hi" | ||
| 16030 | + [(set (match_operand:V2HI 0 "register_operand" "=r, r, r") | ||
| 16031 | + (vec_concat:V2HI | ||
| 16032 | + (match_operand:HI 1 "register_operand" "r, r, 0") | ||
| 16033 | + (match_operand:HI 2 "register_operand" "r, 0, r")))] | ||
| 16034 | + "" | ||
| 16035 | + "@ | ||
| 16036 | + mov\t%0, %1\;bfins\t%0, %2, 0, 16 | ||
| 16037 | + bfins\t%0, %2, 0, 16 | ||
| 16038 | + bfins\t%0, %1, 16, 16" | ||
| 16039 | + [(set_attr "length" "6, 4, 4") | ||
| 16040 | + (set_attr "type" "alu")]) | ||
| 16041 | + | ||
| 16042 | +;(define_peephole2 | ||
| 16043 | +; [(set (match_operand:HI 0 "register_operand" "r") | ||
| 16044 | +; (plus:HI (match_operand:HI 3 "register_operand" "r") | ||
| 16045 | +; (match_operand:HI 4 "register_operand" "r"))) | ||
| 16046 | +; (set (match_operand:HI 1 "register_operand" "r") | ||
| 16047 | +; (minus:HI (match_dup 3) | ||
| 16048 | +; (match_dup 4)))] | ||
| 16049 | +; "REGNO(operands[0]) != REGNO(operands[3])" | ||
| 16050 | +; [(set (match_dup 2) | ||
| 16051 | +; (vec_concat:V2HI | ||
| 16052 | +; (minus:HI (match_dup 3) | ||
| 16053 | +; (match_dup 4)) | ||
| 16054 | +; (plus:HI (match_dup 3) (match_dup 4)))) | ||
| 16055 | +; (set (match_dup 1) (vec_select:HI (match_dup 2) | ||
| 16056 | +; (parallel [(const_int 0)])))] | ||
| 16057 | +; | ||
| 16058 | +; "operands[2] = gen_rtx_REG(V2HImode, REGNO(operands[0]));" | ||
| 16059 | +; ) | ||
| 16060 | +; | ||
| 16061 | +;(define_peephole2 | ||
| 16062 | +; [(set (match_operand:HI 0 "register_operand" "r") | ||
| 16063 | +; (minus:HI (match_operand:HI 3 "register_operand" "r") | ||
| 16064 | +; (match_operand:HI 4 "register_operand" "r"))) | ||
| 16065 | +; (set (match_operand:HI 1 "register_operand" "r") | ||
| 16066 | +; (plus:HI (match_dup 3) | ||
| 16067 | +; (match_dup 4)))] | ||
| 16068 | +; "REGNO(operands[0]) != REGNO(operands[3])" | ||
| 16069 | +; [(set (match_dup 2) | ||
| 16070 | +; (vec_concat:V2HI | ||
| 16071 | +; (plus:HI (match_dup 3) | ||
| 16072 | +; (match_dup 4)) | ||
| 16073 | +; (minus:HI (match_dup 3) (match_dup 4)))) | ||
| 16074 | +; (set (match_dup 1) (vec_select:HI (match_dup 2) | ||
| 16075 | +; (parallel [(const_int 0)])))] | ||
| 16076 | +; | ||
| 16077 | +; "operands[2] = gen_rtx_REG(V2HImode, REGNO(operands[0]));" | ||
| 16078 | +; ) | ||
| 16079 | + | ||
| 16080 | + | ||
| 16081 | +;(define_peephole2 | ||
| 16082 | +; [(match_scratch:V2HI 5 "r") | ||
| 16083 | +; (set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "") | ||
| 16084 | +; (match_operand:HI 1 "immediate_operand" ""))) | ||
| 16085 | +; (match_operand:HI 2 "register_operand" "r")) | ||
| 16086 | +; (set (mem:HI (plus:SI (match_dup 0) | ||
| 16087 | +; (match_operand:HI 3 "immediate_operand" ""))) | ||
| 16088 | +; (match_operand:HI 4 "register_operand" "r"))] | ||
| 16089 | +; "(GET_CODE(operands[1]) == CONST_INT) && (GET_CODE(operands[3]) == CONST_INT) | ||
| 16090 | +; && (INTVAL(operands[3]) == (INTVAL(operands[1]) + 2))" | ||
| 16091 | +; | ||
| 16092 | +; [(set (match_dup 5) | ||
| 16093 | +; (vec_concat:V2HI | ||
| 16094 | +; (match_dup 2) | ||
| 16095 | +; (match_dup 4))) | ||
| 16096 | +; (set (mem:V2HI (plus:SI (match_dup 0) (match_dup 1))) | ||
| 16097 | +; (match_dup 5))] | ||
| 16098 | +; "" | ||
| 16099 | +; ) | ||
| 16100 | +; | ||
| 16101 | + | ||
| 16102 | +;(define_insn "sthh_w" | ||
| 16103 | +; [(set (match_operand:V2HI 0 "avr32_sthh_w_memory_operand" "m") | ||
| 16104 | +; (vec_concat:V2HI | ||
| 16105 | +; (vec_select:HI (match_operand:V2HI 1 "register_operand" "r") | ||
| 16106 | +; (parallel [(match_operand 3 "immediate_operand" "i")])) | ||
| 16107 | +; (vec_select:HI (match_operand:V2HI 2 "register_operand" "r") | ||
| 16108 | +; (parallel [(match_operand 4 "immediate_operand" "i")]))))] | ||
| 16109 | +; "MEM_ALIGN(operands[0]) >= 32" | ||
| 16110 | +; "sthh.w\t%0, %1:%h3, %2:%h4" | ||
| 16111 | +; [(set_attr "length" "4") | ||
| 16112 | +; (set_attr "type" "store")]) | ||
| 16113 | +; | ||
| 16114 | +;(define_peephole2 | ||
| 16115 | +; [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "") | ||
| 16116 | +; (match_operand:HI 1 "immediate_operand" ""))) | ||
| 16117 | +; (match_operand:HI 2 "register_operand" "r")) | ||
| 16118 | +; (set (mem:HI (plus:SI (match_dup 0) | ||
| 16119 | +; (match_operand:HI 3 "avr32_sthh_operand" ""))) | ||
| 16120 | +; (match_operand:HI 4 "register_operand" "r"))] | ||
| 16121 | +; "(GET_CODE(operands[1]) == CONST_INT) && (GET_CODE(operands[3]) == CONST_INT) | ||
| 16122 | +; && (INTVAL(operands[3]) == (INTVAL(operands[1]) - 2))" | ||
| 16123 | +; | ||
| 16124 | +; [(paralell [(set (mem:HI (plus:SI (match_dup 0) | ||
| 16125 | +; (match_dup 3))) | ||
| 16126 | +; (match_dup 4)) | ||
| 16127 | +; (set (mem:HI (plus:SI (match_dup 0) | ||
| 16128 | +; (plus:SI (match_dup 3) (const_int 2)))) | ||
| 16129 | +; (match_dup 2))])] | ||
| 16130 | +; "" | ||
| 16131 | +; ) | ||
| 16132 | + | ||
| 16133 | + | ||
| 16134 | +;; Load the SIMD description | ||
| 16135 | +(include "simd.md") | ||
| 16136 | + | ||
| 16137 | +;; Load the FP coprocessor patterns | ||
| 16138 | +(include "fpcp.md") | ||
| 16139 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/avr32-modes.def gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/avr32-modes.def | ||
| 16140 | --- gcc-4.0.2/gcc/config/avr32/avr32-modes.def 1970-01-01 01:00:00.000000000 +0100 | ||
| 16141 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/avr32-modes.def 2005-08-19 14:17:15.000000000 +0200 | ||
| 16142 | @@ -0,0 +1 @@ | ||
| 16143 | +VECTOR_MODES (INT, 4); /* V4QI V2HI */ | ||
| 16144 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/avr32-protos.h gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/avr32-protos.h | ||
| 16145 | --- gcc-4.0.2/gcc/config/avr32/avr32-protos.h 1970-01-01 01:00:00.000000000 +0100 | ||
| 16146 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/avr32-protos.h 2006-10-10 13:03:42.000000000 +0200 | ||
| 16147 | @@ -0,0 +1,175 @@ | ||
| 16148 | +/* | ||
| 16149 | + Prototypes for exported functions defined in avr32.c | ||
| 16150 | + Copyright 2003-2006 Atmel Corporation. | ||
| 16151 | + | ||
| 16152 | + Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com> | ||
| 16153 | + Initial porting by Anders Ådland. | ||
| 16154 | + | ||
| 16155 | + This file is part of GCC. | ||
| 16156 | + | ||
| 16157 | + This program is free software; you can redistribute it and/or modify | ||
| 16158 | + it under the terms of the GNU General Public License as published by | ||
| 16159 | + the Free Software Foundation; either version 2 of the License, or | ||
| 16160 | + (at your option) any later version. | ||
| 16161 | + | ||
| 16162 | + This program is distributed in the hope that it will be useful, | ||
| 16163 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16164 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16165 | + GNU General Public License for more details. | ||
| 16166 | + | ||
| 16167 | + You should have received a copy of the GNU General Public License | ||
| 16168 | + along with this program; if not, write to the Free Software | ||
| 16169 | + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 16170 | + | ||
| 16171 | + | ||
| 16172 | +#ifndef AVR32_PROTOS_H | ||
| 16173 | +#define AVR32_PROTOS_H | ||
| 16174 | + | ||
| 16175 | +extern const int swap_reg[]; | ||
| 16176 | + | ||
| 16177 | +extern int avr32_valid_macmac_bypass (rtx, rtx); | ||
| 16178 | +extern int avr32_valid_mulmac_bypass (rtx, rtx); | ||
| 16179 | + | ||
| 16180 | +extern int avr32_decode_lcomm_symbol_offset (rtx, int *); | ||
| 16181 | +extern void avr32_encode_lcomm_symbol_offset (tree, char *, int); | ||
| 16182 | + | ||
| 16183 | +extern const char *avr32_strip_name_encoding (const char *); | ||
| 16184 | + | ||
| 16185 | +extern rtx avr32_get_note_reg_equiv (rtx insn); | ||
| 16186 | + | ||
| 16187 | +extern int avr32_use_return_insn (int iscond); | ||
| 16188 | + | ||
| 16189 | +extern void avr32_make_reglist16 (int reglist16_vect, char *reglist16_string); | ||
| 16190 | + | ||
| 16191 | +extern void avr32_make_reglist8 (int reglist8_vect, char *reglist8_string); | ||
| 16192 | +extern void avr32_make_fp_reglist_w (int reglist_mask, char *reglist_string); | ||
| 16193 | +extern void avr32_make_fp_reglist_d (int reglist_mask, char *reglist_string); | ||
| 16194 | + | ||
| 16195 | +extern void avr32_output_return_instruction (int single_ret_inst, | ||
| 16196 | + int iscond, rtx cond, | ||
| 16197 | + rtx r12_imm); | ||
| 16198 | +extern void avr32_expand_prologue (void); | ||
| 16199 | +extern void avr32_set_return_address (rtx source); | ||
| 16200 | + | ||
| 16201 | +extern int avr32_hard_regno_mode_ok (int regno, enum machine_mode mode); | ||
| 16202 | +extern int avr32_extra_constraint_s (rtx value, const int strict); | ||
| 16203 | +extern int avr32_eh_return_data_regno (const int n); | ||
| 16204 | +extern int avr32_initial_elimination_offset (const int from, const int to); | ||
| 16205 | +extern rtx avr32_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, | ||
| 16206 | + tree type, int named); | ||
| 16207 | +extern void avr32_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype, | ||
| 16208 | + rtx libname, tree fndecl); | ||
| 16209 | +extern void avr32_function_arg_advance (CUMULATIVE_ARGS * cum, | ||
| 16210 | + enum machine_mode mode, | ||
| 16211 | + tree type, int named); | ||
| 16212 | +#ifdef ARGS_SIZE_RTX | ||
| 16213 | +/* expr.h defines ARGS_SIZE_RTX and `enum direction'. */ | ||
| 16214 | +extern enum direction avr32_function_arg_padding (enum machine_mode mode, | ||
| 16215 | + tree type); | ||
| 16216 | +#endif /* ARGS_SIZE_RTX */ | ||
| 16217 | +extern rtx avr32_function_value (tree valtype, tree func); | ||
| 16218 | +extern rtx avr32_libcall_value (enum machine_mode mode); | ||
| 16219 | +extern int avr32_sched_use_dfa_pipeline_interface (void); | ||
| 16220 | +extern bool avr32_return_in_memory (tree type, tree fntype); | ||
| 16221 | +extern void avr32_regs_to_save (char *operand); | ||
| 16222 | +extern void avr32_target_asm_function_prologue (FILE * file, | ||
| 16223 | + HOST_WIDE_INT size); | ||
| 16224 | +extern void avr32_target_asm_function_epilogue (FILE * file, | ||
| 16225 | + HOST_WIDE_INT size); | ||
| 16226 | +extern void avr32_trampoline_template (FILE * file); | ||
| 16227 | +extern void avr32_initialize_trampoline (rtx addr, rtx fnaddr, | ||
| 16228 | + rtx static_chain); | ||
| 16229 | +extern int avr32_legitimate_address (enum machine_mode mode, rtx x, | ||
| 16230 | + int strict); | ||
| 16231 | +extern int avr32_legitimate_constant_p (rtx x); | ||
| 16232 | + | ||
| 16233 | +extern int avr32_legitimate_pic_operand_p (rtx x); | ||
| 16234 | + | ||
| 16235 | +extern rtx avr32_find_symbol (rtx x); | ||
| 16236 | +extern void avr32_select_section (rtx exp, int reloc, int align); | ||
| 16237 | +extern void avr32_encode_section_info (tree decl, rtx rtl, int first); | ||
| 16238 | +extern void avr32_asm_file_end (FILE * stream); | ||
| 16239 | +extern void avr32_asm_output_ascii (FILE * stream, char *ptr, int len); | ||
| 16240 | +extern void avr32_asm_output_common (FILE * stream, const char *name, | ||
| 16241 | + int size, int rounded); | ||
| 16242 | +extern void avr32_asm_output_label (FILE * stream, const char *name); | ||
| 16243 | +extern void avr32_asm_declare_object_name (FILE * stream, char *name, | ||
| 16244 | + tree decl); | ||
| 16245 | +extern void avr32_asm_globalize_label (FILE * stream, const char *name); | ||
| 16246 | +extern void avr32_asm_weaken_label (FILE * stream, const char *name); | ||
| 16247 | +extern void avr32_asm_output_external (FILE * stream, tree decl, | ||
| 16248 | + const char *name); | ||
| 16249 | +extern void avr32_asm_output_external_libcall (FILE * stream, rtx symref); | ||
| 16250 | +extern void avr32_asm_output_labelref (FILE * stream, const char *name); | ||
| 16251 | +extern void avr32_notice_update_cc (rtx exp, rtx insn); | ||
| 16252 | +extern void avr32_print_operand (FILE * stream, rtx x, int code); | ||
| 16253 | +extern void avr32_print_operand_address (FILE * stream, rtx x); | ||
| 16254 | + | ||
| 16255 | +extern int avr32_symbol (rtx x); | ||
| 16256 | + | ||
| 16257 | +extern void avr32_select_rtx_section (enum machine_mode mode, rtx x, | ||
| 16258 | + unsigned HOST_WIDE_INT align); | ||
| 16259 | + | ||
| 16260 | +extern int avr32_load_multiple_operation (rtx op, enum machine_mode mode); | ||
| 16261 | +extern int avr32_store_multiple_operation (rtx op, enum machine_mode mode); | ||
| 16262 | + | ||
| 16263 | +extern int avr32_const_ok_for_constraint_p (HOST_WIDE_INT value, char c, | ||
| 16264 | + const char *str); | ||
| 16265 | + | ||
| 16266 | +extern bool avr32_cannot_force_const_mem (rtx x); | ||
| 16267 | + | ||
| 16268 | +extern void avr32_init_builtins (void); | ||
| 16269 | + | ||
| 16270 | +extern rtx avr32_expand_builtin (tree exp, rtx target, rtx subtarget, | ||
| 16271 | + enum machine_mode mode, int ignore); | ||
| 16272 | + | ||
| 16273 | +extern bool avr32_must_pass_in_stack (enum machine_mode mode, tree type); | ||
| 16274 | + | ||
| 16275 | +extern bool avr32_strict_argument_naming (CUMULATIVE_ARGS * ca); | ||
| 16276 | + | ||
| 16277 | +extern bool avr32_pass_by_reference (CUMULATIVE_ARGS * cum, | ||
| 16278 | + enum machine_mode mode, | ||
| 16279 | + tree type, bool named); | ||
| 16280 | + | ||
| 16281 | +extern rtx avr32_gen_load_multiple (rtx * regs, int count, rtx from, | ||
| 16282 | + int write_back, int in_struct_p, | ||
| 16283 | + int scalar_p); | ||
| 16284 | +extern rtx avr32_gen_store_multiple (rtx * regs, int count, rtx to, | ||
| 16285 | + int in_struct_p, int scalar_p); | ||
| 16286 | +extern int avr32_gen_movmemsi (rtx * operands); | ||
| 16287 | + | ||
| 16288 | +extern int avr32_rnd_operands (rtx add, rtx shift); | ||
| 16289 | +extern int avr32_adjust_insn_length (rtx insn, int length); | ||
| 16290 | + | ||
| 16291 | +extern int symbol_mentioned_p (rtx x); | ||
| 16292 | +extern int label_mentioned_p (rtx x); | ||
| 16293 | +extern rtx legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg); | ||
| 16294 | +extern int avr32_address_register_rtx_p (rtx x, int strict_p); | ||
| 16295 | +extern int avr32_legitimate_index_p (enum machine_mode mode, rtx index, | ||
| 16296 | + int strict_p); | ||
| 16297 | + | ||
| 16298 | +extern int avr32_const_double_immediate (rtx value); | ||
| 16299 | +extern void avr32_init_expanders (void); | ||
| 16300 | +extern rtx avr32_return_addr (int count, rtx frame); | ||
| 16301 | +extern bool avr32_got_mentioned_p (rtx addr); | ||
| 16302 | + | ||
| 16303 | +extern void avr32_final_prescan_insn (rtx insn, rtx * opvec, int noperands); | ||
| 16304 | + | ||
| 16305 | +extern int avr32_expand_movcc (enum machine_mode mode, rtx operands[]); | ||
| 16306 | +extern int avr32_expand_addcc (enum machine_mode mode, rtx operands[]); | ||
| 16307 | +#ifdef RTX_CODE | ||
| 16308 | +extern int avr32_expand_scc (RTX_CODE cond, rtx * operands); | ||
| 16309 | +#endif | ||
| 16310 | + | ||
| 16311 | +extern int avr32_store_bypass (rtx insn_out, rtx insn_in); | ||
| 16312 | +extern int avr32_mul_waw_bypass (rtx insn_out, rtx insn_in); | ||
| 16313 | +extern int avr32_valid_load_double_bypass (rtx insn_out, rtx insn_in); | ||
| 16314 | +extern int avr32_valid_load_quad_bypass (rtx insn_out, rtx insn_in); | ||
| 16315 | +extern rtx avr32_output_cmp (rtx cond, enum machine_mode mode, | ||
| 16316 | + rtx op0, rtx op1); | ||
| 16317 | + | ||
| 16318 | +rtx get_next_insn_cond (rtx cur_insn); | ||
| 16319 | +int set_next_insn_cond (rtx cur_insn, rtx cond); | ||
| 16320 | +void avr32_override_options (void); | ||
| 16321 | + | ||
| 16322 | +#endif /* AVR32_PROTOS_H */ | ||
| 16323 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/crti.asm gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/crti.asm | ||
| 16324 | --- gcc-4.0.2/gcc/config/avr32/crti.asm 1970-01-01 01:00:00.000000000 +0100 | ||
| 16325 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/crti.asm 2006-10-10 12:36:34.000000000 +0200 | ||
| 16326 | @@ -0,0 +1,64 @@ | ||
| 16327 | +/* | ||
| 16328 | + Init/fini stuff for AVR32. | ||
| 16329 | + Copyright 2003-2006 Atmel Corporation. | ||
| 16330 | + | ||
| 16331 | + Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com> | ||
| 16332 | + | ||
| 16333 | + This file is part of GCC. | ||
| 16334 | + | ||
| 16335 | + This program is free software; you can redistribute it and/or modify | ||
| 16336 | + it under the terms of the GNU General Public License as published by | ||
| 16337 | + the Free Software Foundation; either version 2 of the License, or | ||
| 16338 | + (at your option) any later version. | ||
| 16339 | + | ||
| 16340 | + This program is distributed in the hope that it will be useful, | ||
| 16341 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16342 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16343 | + GNU General Public License for more details. | ||
| 16344 | + | ||
| 16345 | + You should have received a copy of the GNU General Public License | ||
| 16346 | + along with this program; if not, write to the Free Software | ||
| 16347 | + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 16348 | + | ||
| 16349 | + | ||
| 16350 | +/* The code in sections .init and .fini is supposed to be a single | ||
| 16351 | + regular function. The function in .init is called directly from | ||
| 16352 | + start in crt1.asm. The function in .fini is atexit()ed in crt1.asm | ||
| 16353 | + too. | ||
| 16354 | + | ||
| 16355 | + crti.asm contributes the prologue of a function to these sections, | ||
| 16356 | + and crtn.asm comes up the epilogue. STARTFILE_SPEC should list | ||
| 16357 | + crti.o before any other object files that might add code to .init | ||
| 16358 | + or .fini sections, and ENDFILE_SPEC should list crtn.o after any | ||
| 16359 | + such object files. */ | ||
| 16360 | + | ||
| 16361 | + .file "crti.asm" | ||
| 16362 | + | ||
| 16363 | + .section ".init" | ||
| 16364 | +/* Just load the GOT */ | ||
| 16365 | + .align 2 | ||
| 16366 | + .global _init | ||
| 16367 | +_init: | ||
| 16368 | + stm --sp, r6, lr | ||
| 16369 | + lddpc r6, 1f | ||
| 16370 | +0: | ||
| 16371 | + rsub r6, pc | ||
| 16372 | + rjmp 2f | ||
| 16373 | + .align 2 | ||
| 16374 | +1: .long 0b - _GLOBAL_OFFSET_TABLE_ | ||
| 16375 | +2: | ||
| 16376 | + | ||
| 16377 | + .section ".fini" | ||
| 16378 | +/* Just load the GOT */ | ||
| 16379 | + .align 2 | ||
| 16380 | + .global _fini | ||
| 16381 | +_fini: | ||
| 16382 | + stm --sp, r6, lr | ||
| 16383 | + lddpc r6, 1f | ||
| 16384 | +0: | ||
| 16385 | + rsub r6, pc | ||
| 16386 | + rjmp 2f | ||
| 16387 | + .align 2 | ||
| 16388 | +1: .long 0b - _GLOBAL_OFFSET_TABLE_ | ||
| 16389 | +2: | ||
| 16390 | + | ||
| 16391 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/crtn.asm gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/crtn.asm | ||
| 16392 | --- gcc-4.0.2/gcc/config/avr32/crtn.asm 1970-01-01 01:00:00.000000000 +0100 | ||
| 16393 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/crtn.asm 2006-10-10 12:36:34.000000000 +0200 | ||
| 16394 | @@ -0,0 +1,44 @@ | ||
| 16395 | +/* Copyright (C) 2001 Free Software Foundation, Inc. | ||
| 16396 | + Written By Nick Clifton | ||
| 16397 | + | ||
| 16398 | + This file is free software; you can redistribute it and/or modify it | ||
| 16399 | + under the terms of the GNU General Public License as published by the | ||
| 16400 | + Free Software Foundation; either version 2, or (at your option) any | ||
| 16401 | + later version. | ||
| 16402 | + | ||
| 16403 | + In addition to the permissions in the GNU General Public License, the | ||
| 16404 | + Free Software Foundation gives you unlimited permission to link the | ||
| 16405 | + compiled version of this file with other programs, and to distribute | ||
| 16406 | + those programs without any restriction coming from the use of this | ||
| 16407 | + file. (The General Public License restrictions do apply in other | ||
| 16408 | + respects; for example, they cover modification of the file, and | ||
| 16409 | + distribution when not linked into another program.) | ||
| 16410 | + | ||
| 16411 | + This file is distributed in the hope that it will be useful, but | ||
| 16412 | + WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16413 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16414 | + General Public License for more details. | ||
| 16415 | + | ||
| 16416 | + You should have received a copy of the GNU General Public License | ||
| 16417 | + along with this program; see the file COPYING. If not, write to | ||
| 16418 | + the Free Software Foundation, 59 Temple Place - Suite 330, | ||
| 16419 | + Boston, MA 02111-1307, USA. | ||
| 16420 | + | ||
| 16421 | + As a special exception, if you link this library with files | ||
| 16422 | + compiled with GCC to produce an executable, this does not cause | ||
| 16423 | + the resulting executable to be covered by the GNU General Public License. | ||
| 16424 | + This exception does not however invalidate any other reasons why | ||
| 16425 | + the executable file might be covered by the GNU General Public License. | ||
| 16426 | +*/ | ||
| 16427 | + | ||
| 16428 | + | ||
| 16429 | + | ||
| 16430 | + | ||
| 16431 | + .file "crtn.asm" | ||
| 16432 | + | ||
| 16433 | + .section ".init" | ||
| 16434 | + ldm sp++, r6, pc | ||
| 16435 | + | ||
| 16436 | + .section ".fini" | ||
| 16437 | + ldm sp++, r6, pc | ||
| 16438 | + | ||
| 16439 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/fpcp.md gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/fpcp.md | ||
| 16440 | --- gcc-4.0.2/gcc/config/avr32/fpcp.md 1970-01-01 01:00:00.000000000 +0100 | ||
| 16441 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/fpcp.md 2006-10-10 12:36:34.000000000 +0200 | ||
| 16442 | @@ -0,0 +1,551 @@ | ||
| 16443 | +;; AVR32 machine description file for Floating-Point instructions. | ||
| 16444 | +;; Copyright 2003-2006 Atmel Corporation. | ||
| 16445 | +;; | ||
| 16446 | +;; Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com> | ||
| 16447 | +;; | ||
| 16448 | +;; This file is part of GCC. | ||
| 16449 | +;; | ||
| 16450 | +;; This program is free software; you can redistribute it and/or modify | ||
| 16451 | +;; it under the terms of the GNU General Public License as published by | ||
| 16452 | +;; the Free Software Foundation; either version 2 of the License, or | ||
| 16453 | +;; (at your option) any later version. | ||
| 16454 | +;; | ||
| 16455 | +;; This program is distributed in the hope that it will be useful, | ||
| 16456 | +;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16457 | +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16458 | +;; GNU General Public License for more details. | ||
| 16459 | +;; | ||
| 16460 | +;; You should have received a copy of the GNU General Public License | ||
| 16461 | +;; along with this program; if not, write to the Free Software | ||
| 16462 | +;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 16463 | + | ||
| 16464 | +;; -*- Mode: Scheme -*- | ||
| 16465 | + | ||
| 16466 | +;;****************************************************************************** | ||
| 16467 | +;; Automaton pipeline description for floating-point coprocessor insns | ||
| 16468 | +;;****************************************************************************** | ||
| 16469 | +(define_cpu_unit "fid,fm1,fm2,fm3,fm4,fwb,fcmp,fcast" "avr32_ap") | ||
| 16470 | + | ||
| 16471 | +(define_insn_reservation "fmv_op" 1 | ||
| 16472 | + (and (eq_attr "pipeline" "ap") | ||
| 16473 | + (eq_attr "type" "fmv")) | ||
| 16474 | + "is,da,d,fid,fwb") | ||
| 16475 | + | ||
| 16476 | +(define_insn_reservation "fmul_op" 5 | ||
| 16477 | + (and (eq_attr "pipeline" "ap") | ||
| 16478 | + (eq_attr "type" "fmul")) | ||
| 16479 | + "is,da,d,fid,fm1,fm2,fm3,fm4,fwb") | ||
| 16480 | + | ||
| 16481 | +(define_insn_reservation "fcmps_op" 1 | ||
| 16482 | + (and (eq_attr "pipeline" "ap") | ||
| 16483 | + (eq_attr "type" "fcmps")) | ||
| 16484 | + "is,da,d,fid,fcmp") | ||
| 16485 | + | ||
| 16486 | +(define_insn_reservation "fcmpd_op" 2 | ||
| 16487 | + (and (eq_attr "pipeline" "ap") | ||
| 16488 | + (eq_attr "type" "fcmpd")) | ||
| 16489 | + "is,da,d,fid*2,fcmp") | ||
| 16490 | + | ||
| 16491 | +(define_insn_reservation "fcast_op" 3 | ||
| 16492 | + (and (eq_attr "pipeline" "ap") | ||
| 16493 | + (eq_attr "type" "fcast")) | ||
| 16494 | + "is,da,d,fid,fcmp,fcast,fwb") | ||
| 16495 | + | ||
| 16496 | +(define_insn_reservation "fmvcpu_op" 2 | ||
| 16497 | + (and (eq_attr "pipeline" "ap") | ||
| 16498 | + (eq_attr "type" "fmvcpu")) | ||
| 16499 | + "is,da,d") | ||
| 16500 | + | ||
| 16501 | +(define_insn_reservation "fldd_op" 1 | ||
| 16502 | + (and (eq_attr "pipeline" "ap") | ||
| 16503 | + (eq_attr "type" "fldd")) | ||
| 16504 | + "is,da,d,fwb") | ||
| 16505 | + | ||
| 16506 | +(define_insn_reservation "flds_op" 1 | ||
| 16507 | + (and (eq_attr "pipeline" "ap") | ||
| 16508 | + (eq_attr "type" "flds")) | ||
| 16509 | + "is,da,d,fwb") | ||
| 16510 | + | ||
| 16511 | +(define_insn_reservation "fsts_op" 0 | ||
| 16512 | + (and (eq_attr "pipeline" "ap") | ||
| 16513 | + (eq_attr "type" "fsts")) | ||
| 16514 | + "is,da*2,d") | ||
| 16515 | + | ||
| 16516 | +(define_insn_reservation "fstd_op" 0 | ||
| 16517 | + (and (eq_attr "pipeline" "ap") | ||
| 16518 | + (eq_attr "type" "fstd")) | ||
| 16519 | + "is,da*2,d") | ||
| 16520 | + | ||
| 16521 | + | ||
| 16522 | +(define_insn "*movsf_fpcp" | ||
| 16523 | + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,f,m,r,r,r,m") | ||
| 16524 | + (match_operand:SF 1 "general_operand" " f,r,f,m,f,r,G,m,r"))] | ||
| 16525 | + "TARGET_HARD_FLOAT" | ||
| 16526 | + "@ | ||
| 16527 | + fmov.s\t%0, %1 | ||
| 16528 | + fmov.s\t%0, %1 | ||
| 16529 | + fmov.s\t%0, %1 | ||
| 16530 | + fld.s\t%0, %1 | ||
| 16531 | + fst.s\t%0, %1 | ||
| 16532 | + mov\t%0, %1 | ||
| 16533 | + mov\t%0, %1 | ||
| 16534 | + ld.w\t%0, %1 | ||
| 16535 | + st.w\t%0, %1" | ||
| 16536 | + [(set_attr "length" "4,4,4,4,4,2,4,4,4") | ||
| 16537 | + (set_attr "type" "fmv,flds,fmvcpu,flds,fsts,alu,alu,load,store")]) | ||
| 16538 | + | ||
| 16539 | +(define_insn_and_split "*movdf_fpcp" | ||
| 16540 | + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,f,m,r,r,m") | ||
| 16541 | + (match_operand:DF 1 "general_operand" " f,r,f,m,f,r,m,r"))] | ||
| 16542 | + "TARGET_HARD_FLOAT" | ||
| 16543 | + "@ | ||
| 16544 | + fmov.d\t%0, %1 | ||
| 16545 | + fmov.d\t%0, %1 | ||
| 16546 | + fmov.d\t%0, %1 | ||
| 16547 | + fld.d\t%0, %1 | ||
| 16548 | + fst.d\t%0, %1 | ||
| 16549 | + mov\t%0, %1\;mov\t%m0, %m1 | ||
| 16550 | + ld.d\t%0, %1 | ||
| 16551 | + st.d\t%0, %1" | ||
| 16552 | + | ||
| 16553 | + "TARGET_HARD_FLOAT | ||
| 16554 | + && reload_completed | ||
| 16555 | + && (REG_P(operands[0]) && (REGNO_REG_CLASS(REGNO(operands[0])) == GENERAL_REGS)) | ||
| 16556 | + && (REG_P(operands[1]) && (REGNO_REG_CLASS(REGNO(operands[1])) == GENERAL_REGS))" | ||
| 16557 | + [(set (match_dup 0) (match_dup 1)) | ||
| 16558 | + (set (match_dup 2) (match_dup 3))] | ||
| 16559 | + " | ||
| 16560 | + { | ||
| 16561 | + operands[2] = gen_highpart (SImode, operands[0]); | ||
| 16562 | + operands[0] = gen_lowpart (SImode, operands[0]); | ||
| 16563 | + operands[3] = gen_highpart(SImode, operands[1]); | ||
| 16564 | + operands[1] = gen_lowpart(SImode, operands[1]); | ||
| 16565 | + } | ||
| 16566 | + " | ||
| 16567 | + | ||
| 16568 | + [(set_attr "length" "4,4,4,4,4,4,4,4") | ||
| 16569 | + (set_attr "type" "fmv,fldd,fmvcpu,fldd,fstd,alu2,load2,store2")]) | ||
| 16570 | + | ||
| 16571 | + | ||
| 16572 | +(define_insn "mulsf3" | ||
| 16573 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") | ||
| 16574 | + (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") | ||
| 16575 | + (match_operand:SF 2 "avr32_fp_register_operand" "f")))] | ||
| 16576 | + "TARGET_HARD_FLOAT" | ||
| 16577 | + "fmul.s\t%0, %1, %2" | ||
| 16578 | + [(set_attr "length" "4") | ||
| 16579 | + (set_attr "type" "fmul")]) | ||
| 16580 | + | ||
| 16581 | +(define_insn "nmulsf3" | ||
| 16582 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") | ||
| 16583 | + (neg:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") | ||
| 16584 | + (match_operand:SF 2 "avr32_fp_register_operand" "f"))))] | ||
| 16585 | + "TARGET_HARD_FLOAT" | ||
| 16586 | + "fnmul.s\t%0, %1, %2" | ||
| 16587 | + [(set_attr "length" "4") | ||
| 16588 | + (set_attr "type" "fmul")]) | ||
| 16589 | + | ||
| 16590 | +(define_peephole2 | ||
| 16591 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "") | ||
| 16592 | + (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "") | ||
| 16593 | + (match_operand:SF 2 "avr32_fp_register_operand" ""))) | ||
| 16594 | + (set (match_operand:SF 3 "avr32_fp_register_operand" "") | ||
| 16595 | + (neg:SF (match_dup 0)))] | ||
| 16596 | + "TARGET_HARD_FLOAT && | ||
| 16597 | + (peep2_reg_dead_p(2, operands[0]) || (REGNO(operands[3]) == REGNO(operands[0])))" | ||
| 16598 | + [(set (match_dup 3) | ||
| 16599 | + (neg:SF (mult:SF (match_dup 1) | ||
| 16600 | + (match_dup 2))))] | ||
| 16601 | +) | ||
| 16602 | + | ||
| 16603 | + | ||
| 16604 | +(define_insn "macsf3" | ||
| 16605 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") | ||
| 16606 | + (plus:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") | ||
| 16607 | + (match_operand:SF 2 "avr32_fp_register_operand" "f")) | ||
| 16608 | + (match_operand:SF 3 "avr32_fp_register_operand" "0")))] | ||
| 16609 | + "TARGET_HARD_FLOAT" | ||
| 16610 | + "fmac.s\t%0, %1, %2" | ||
| 16611 | + [(set_attr "length" "4") | ||
| 16612 | + (set_attr "type" "fmul")]) | ||
| 16613 | + | ||
| 16614 | +(define_insn "nmacsf3" | ||
| 16615 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") | ||
| 16616 | + (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") | ||
| 16617 | + (match_operand:SF 2 "avr32_fp_register_operand" "f"))) | ||
| 16618 | + (match_operand:SF 3 "avr32_fp_register_operand" "0")))] | ||
| 16619 | + "TARGET_HARD_FLOAT" | ||
| 16620 | + "fnmac.s\t%0, %1, %2" | ||
| 16621 | + [(set_attr "length" "4") | ||
| 16622 | + (set_attr "type" "fmul")]) | ||
| 16623 | + | ||
| 16624 | +(define_peephole2 | ||
| 16625 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "") | ||
| 16626 | + (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "") | ||
| 16627 | + (match_operand:SF 2 "avr32_fp_register_operand" ""))) | ||
| 16628 | + (set (match_operand:SF 3 "avr32_fp_register_operand" "") | ||
| 16629 | + (minus:SF | ||
| 16630 | + (match_dup 3) | ||
| 16631 | + (match_dup 0)))] | ||
| 16632 | + "TARGET_HARD_FLOAT && peep2_reg_dead_p(2, operands[0])" | ||
| 16633 | + [(set (match_dup 3) | ||
| 16634 | + (plus:SF (neg:SF (mult:SF (match_dup 1) | ||
| 16635 | + (match_dup 2))) | ||
| 16636 | + (match_dup 3)))] | ||
| 16637 | +) | ||
| 16638 | + | ||
| 16639 | + | ||
| 16640 | +(define_insn "msubacsf3" | ||
| 16641 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") | ||
| 16642 | + (minus:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") | ||
| 16643 | + (match_operand:SF 2 "avr32_fp_register_operand" "f")) | ||
| 16644 | + (match_operand:SF 3 "avr32_fp_register_operand" "0")))] | ||
| 16645 | + "TARGET_HARD_FLOAT" | ||
| 16646 | + "fmsc.s\t%0, %1, %2" | ||
| 16647 | + [(set_attr "length" "4") | ||
| 16648 | + (set_attr "type" "fmul")]) | ||
| 16649 | + | ||
| 16650 | +(define_peephole2 | ||
| 16651 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "") | ||
| 16652 | + (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "") | ||
| 16653 | + (match_operand:SF 2 "avr32_fp_register_operand" ""))) | ||
| 16654 | + (set (match_operand:SF 3 "avr32_fp_register_operand" "") | ||
| 16655 | + (minus:SF | ||
| 16656 | + (match_dup 0) | ||
| 16657 | + (match_dup 3)))] | ||
| 16658 | + "TARGET_HARD_FLOAT && peep2_reg_dead_p(2, operands[0])" | ||
| 16659 | + [(set (match_dup 3) | ||
| 16660 | + (minus:SF (mult:SF (match_dup 1) | ||
| 16661 | + (match_dup 2)) | ||
| 16662 | + (match_dup 3)))] | ||
| 16663 | +) | ||
| 16664 | + | ||
| 16665 | +(define_insn "nmsubacsf3" | ||
| 16666 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") | ||
| 16667 | + (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") | ||
| 16668 | + (match_operand:SF 2 "avr32_fp_register_operand" "f"))) | ||
| 16669 | + (match_operand:SF 3 "avr32_fp_register_operand" "0")))] | ||
| 16670 | + "TARGET_HARD_FLOAT" | ||
| 16671 | + "fnmsc.s\t%0, %1, %2" | ||
| 16672 | + [(set_attr "length" "4") | ||
| 16673 | + (set_attr "type" "fmul")]) | ||
| 16674 | + | ||
| 16675 | + | ||
| 16676 | + | ||
| 16677 | +(define_insn "addsf3" | ||
| 16678 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") | ||
| 16679 | + (plus:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") | ||
| 16680 | + (match_operand:SF 2 "avr32_fp_register_operand" "f")))] | ||
| 16681 | + "TARGET_HARD_FLOAT" | ||
| 16682 | + "fadd.s\t%0, %1, %2" | ||
| 16683 | + [(set_attr "length" "4") | ||
| 16684 | + (set_attr "type" "fmul")]) | ||
| 16685 | + | ||
| 16686 | +(define_insn "subsf3" | ||
| 16687 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") | ||
| 16688 | + (minus:SF (match_operand:SF 1 "avr32_fp_register_operand" "f") | ||
| 16689 | + (match_operand:SF 2 "avr32_fp_register_operand" "f")))] | ||
| 16690 | + "TARGET_HARD_FLOAT" | ||
| 16691 | + "fsub.s\t%0, %1, %2" | ||
| 16692 | + [(set_attr "length" "4") | ||
| 16693 | + (set_attr "type" "fmul")]) | ||
| 16694 | + | ||
| 16695 | + | ||
| 16696 | +(define_insn "negsf2" | ||
| 16697 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") | ||
| 16698 | + (neg:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")))] | ||
| 16699 | + "TARGET_HARD_FLOAT" | ||
| 16700 | + "fneg.s\t%0, %1" | ||
| 16701 | + [(set_attr "length" "4") | ||
| 16702 | + (set_attr "type" "fmv")]) | ||
| 16703 | + | ||
| 16704 | +(define_insn "abssf2" | ||
| 16705 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") | ||
| 16706 | + (abs:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")))] | ||
| 16707 | + "TARGET_HARD_FLOAT" | ||
| 16708 | + "fabs.s\t%0, %1" | ||
| 16709 | + [(set_attr "length" "4") | ||
| 16710 | + (set_attr "type" "fmv")]) | ||
| 16711 | + | ||
| 16712 | +(define_insn "truncdfsf2" | ||
| 16713 | + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f") | ||
| 16714 | + (float_truncate:SF | ||
| 16715 | + (match_operand:DF 1 "avr32_fp_register_operand" "f")))] | ||
| 16716 | + "TARGET_HARD_FLOAT" | ||
| 16717 | + "fcastd.s\t%0, %1" | ||
| 16718 | + [(set_attr "length" "4") | ||
| 16719 | + (set_attr "type" "fcast")]) | ||
| 16720 | + | ||
| 16721 | +(define_insn "extendsfdf2" | ||
| 16722 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") | ||
| 16723 | + (float_extend:DF | ||
| 16724 | + (match_operand:SF 1 "avr32_fp_register_operand" "f")))] | ||
| 16725 | + "TARGET_HARD_FLOAT" | ||
| 16726 | + "fcasts.d\t%0, %1" | ||
| 16727 | + [(set_attr "length" "4") | ||
| 16728 | + (set_attr "type" "fcast")]) | ||
| 16729 | + | ||
| 16730 | +(define_insn "muldf3" | ||
| 16731 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") | ||
| 16732 | + (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") | ||
| 16733 | + (match_operand:DF 2 "avr32_fp_register_operand" "f")))] | ||
| 16734 | + "TARGET_HARD_FLOAT" | ||
| 16735 | + "fmul.d\t%0, %1, %2" | ||
| 16736 | + [(set_attr "length" "4") | ||
| 16737 | + (set_attr "type" "fmul")]) | ||
| 16738 | + | ||
| 16739 | +(define_insn "nmuldf3" | ||
| 16740 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") | ||
| 16741 | + (neg:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") | ||
| 16742 | + (match_operand:DF 2 "avr32_fp_register_operand" "f"))))] | ||
| 16743 | + "TARGET_HARD_FLOAT" | ||
| 16744 | + "fnmul.d\t%0, %1, %2" | ||
| 16745 | + [(set_attr "length" "4") | ||
| 16746 | + (set_attr "type" "fmul")]) | ||
| 16747 | + | ||
| 16748 | +(define_peephole2 | ||
| 16749 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "") | ||
| 16750 | + (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "") | ||
| 16751 | + (match_operand:DF 2 "avr32_fp_register_operand" ""))) | ||
| 16752 | + (set (match_operand:DF 3 "avr32_fp_register_operand" "") | ||
| 16753 | + (neg:DF (match_dup 0)))] | ||
| 16754 | + "TARGET_HARD_FLOAT && | ||
| 16755 | + (peep2_reg_dead_p(2, operands[0]) || (REGNO(operands[3]) == REGNO(operands[0])))" | ||
| 16756 | + [(set (match_dup 3) | ||
| 16757 | + (neg:DF (mult:DF (match_dup 1) | ||
| 16758 | + (match_dup 2))))] | ||
| 16759 | +) | ||
| 16760 | + | ||
| 16761 | +(define_insn "macdf3" | ||
| 16762 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") | ||
| 16763 | + (plus:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") | ||
| 16764 | + (match_operand:DF 2 "avr32_fp_register_operand" "f")) | ||
| 16765 | + (match_operand:DF 3 "avr32_fp_register_operand" "0")))] | ||
| 16766 | + "TARGET_HARD_FLOAT" | ||
| 16767 | + "fmac.d\t%0, %1, %2" | ||
| 16768 | + [(set_attr "length" "4") | ||
| 16769 | + (set_attr "type" "fmul")]) | ||
| 16770 | + | ||
| 16771 | +(define_insn "msubacdf3" | ||
| 16772 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") | ||
| 16773 | + (minus:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") | ||
| 16774 | + (match_operand:DF 2 "avr32_fp_register_operand" "f")) | ||
| 16775 | + (match_operand:DF 3 "avr32_fp_register_operand" "0")))] | ||
| 16776 | + "TARGET_HARD_FLOAT" | ||
| 16777 | + "fmsc.d\t%0, %1, %2" | ||
| 16778 | + [(set_attr "length" "4") | ||
| 16779 | + (set_attr "type" "fmul")]) | ||
| 16780 | + | ||
| 16781 | +(define_peephole2 | ||
| 16782 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "") | ||
| 16783 | + (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "") | ||
| 16784 | + (match_operand:DF 2 "avr32_fp_register_operand" ""))) | ||
| 16785 | + (set (match_operand:DF 3 "avr32_fp_register_operand" "") | ||
| 16786 | + (minus:DF | ||
| 16787 | + (match_dup 0) | ||
| 16788 | + (match_dup 3)))] | ||
| 16789 | + "TARGET_HARD_FLOAT && peep2_reg_dead_p(2, operands[0])" | ||
| 16790 | + [(set (match_dup 3) | ||
| 16791 | + (minus:DF (mult:DF (match_dup 1) | ||
| 16792 | + (match_dup 2)) | ||
| 16793 | + (match_dup 3)))] | ||
| 16794 | + ) | ||
| 16795 | + | ||
| 16796 | +(define_insn "nmsubacdf3" | ||
| 16797 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") | ||
| 16798 | + (minus:DF (neg:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") | ||
| 16799 | + (match_operand:DF 2 "avr32_fp_register_operand" "f"))) | ||
| 16800 | + (match_operand:DF 3 "avr32_fp_register_operand" "0")))] | ||
| 16801 | + "TARGET_HARD_FLOAT" | ||
| 16802 | + "fnmsc.d\t%0, %1, %2" | ||
| 16803 | + [(set_attr "length" "4") | ||
| 16804 | + (set_attr "type" "fmul")]) | ||
| 16805 | + | ||
| 16806 | +(define_insn "nmacdf3" | ||
| 16807 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") | ||
| 16808 | + (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") | ||
| 16809 | + (match_operand:DF 2 "avr32_fp_register_operand" "f"))) | ||
| 16810 | + (match_operand:DF 3 "avr32_fp_register_operand" "0")))] | ||
| 16811 | + "TARGET_HARD_FLOAT" | ||
| 16812 | + "fnmac.d\t%0, %1, %2" | ||
| 16813 | + [(set_attr "length" "4") | ||
| 16814 | + (set_attr "type" "fmul")]) | ||
| 16815 | + | ||
| 16816 | +(define_peephole2 | ||
| 16817 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "") | ||
| 16818 | + (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "") | ||
| 16819 | + (match_operand:DF 2 "avr32_fp_register_operand" ""))) | ||
| 16820 | + (set (match_operand:DF 3 "avr32_fp_register_operand" "") | ||
| 16821 | + (minus:DF | ||
| 16822 | + (match_dup 3) | ||
| 16823 | + (match_dup 0)))] | ||
| 16824 | + "TARGET_HARD_FLOAT && peep2_reg_dead_p(2, operands[0])" | ||
| 16825 | + [(set (match_dup 3) | ||
| 16826 | + (plus:DF (neg:DF (mult:DF (match_dup 1) | ||
| 16827 | + (match_dup 2))) | ||
| 16828 | + (match_dup 3)))] | ||
| 16829 | +) | ||
| 16830 | + | ||
| 16831 | +(define_insn "adddf3" | ||
| 16832 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") | ||
| 16833 | + (plus:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") | ||
| 16834 | + (match_operand:DF 2 "avr32_fp_register_operand" "f")))] | ||
| 16835 | + "TARGET_HARD_FLOAT" | ||
| 16836 | + "fadd.d\t%0, %1, %2" | ||
| 16837 | + [(set_attr "length" "4") | ||
| 16838 | + (set_attr "type" "fmul")]) | ||
| 16839 | + | ||
| 16840 | +(define_insn "subdf3" | ||
| 16841 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") | ||
| 16842 | + (minus:DF (match_operand:DF 1 "avr32_fp_register_operand" "f") | ||
| 16843 | + (match_operand:DF 2 "avr32_fp_register_operand" "f")))] | ||
| 16844 | + "TARGET_HARD_FLOAT" | ||
| 16845 | + "fsub.d\t%0, %1, %2" | ||
| 16846 | + [(set_attr "length" "4") | ||
| 16847 | + (set_attr "type" "fmul")]) | ||
| 16848 | + | ||
| 16849 | +(define_insn "negdf2" | ||
| 16850 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") | ||
| 16851 | + (neg:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")))] | ||
| 16852 | + "TARGET_HARD_FLOAT" | ||
| 16853 | + "fneg.d\t%0, %1" | ||
| 16854 | + [(set_attr "length" "4") | ||
| 16855 | + (set_attr "type" "fmv")]) | ||
| 16856 | + | ||
| 16857 | +(define_insn "absdf2" | ||
| 16858 | + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f") | ||
| 16859 | + (abs:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")))] | ||
| 16860 | + "TARGET_HARD_FLOAT" | ||
| 16861 | + "fabs.d\t%0, %1" | ||
| 16862 | + [(set_attr "length" "4") | ||
| 16863 | + (set_attr "type" "fmv")]) | ||
| 16864 | + | ||
| 16865 | + | ||
| 16866 | +(define_expand "cmpdf" | ||
| 16867 | + [(set (cc0) | ||
| 16868 | + (compare:DF | ||
| 16869 | + (match_operand:DF 0 "general_operand" "") | ||
| 16870 | + (match_operand:DF 1 "general_operand" "")))] | ||
| 16871 | + "TARGET_HARD_FLOAT" | ||
| 16872 | + "{ | ||
| 16873 | + rtx tmpreg; | ||
| 16874 | + if ( !REG_P(operands[0]) ) | ||
| 16875 | + operands[0] = force_reg(DFmode, operands[0]); | ||
| 16876 | + | ||
| 16877 | + if ( !REG_P(operands[1]) ) | ||
| 16878 | + operands[1] = force_reg(DFmode, operands[1]); | ||
| 16879 | + | ||
| 16880 | + avr32_compare_op0 = operands[0]; | ||
| 16881 | + avr32_compare_op1 = operands[1]; | ||
| 16882 | + | ||
| 16883 | + emit_insn(gen_cmpdf_internal(operands[0], operands[1])); | ||
| 16884 | + | ||
| 16885 | + tmpreg = gen_reg_rtx(SImode); | ||
| 16886 | + emit_insn(gen_fpcc_to_reg(tmpreg)); | ||
| 16887 | + emit_insn(gen_reg_to_cc(tmpreg)); | ||
| 16888 | + | ||
| 16889 | + DONE; | ||
| 16890 | + }" | ||
| 16891 | +) | ||
| 16892 | + | ||
| 16893 | +(define_insn "cmpdf_internal" | ||
| 16894 | + [(set (reg:CC FPCC_REGNUM) | ||
| 16895 | + (compare:CC | ||
| 16896 | + (match_operand:DF 0 "avr32_fp_register_operand" "f") | ||
| 16897 | + (match_operand:DF 1 "avr32_fp_register_operand" "f")))] | ||
| 16898 | + "TARGET_HARD_FLOAT" | ||
| 16899 | + { | ||
| 16900 | + if (!rtx_equal_p(cc_prev_status.mdep.fpvalue, SET_SRC(PATTERN (insn))) ) | ||
| 16901 | + return "fcmp.d\t%0, %1"; | ||
| 16902 | + return ""; | ||
| 16903 | + } | ||
| 16904 | + [(set_attr "length" "4") | ||
| 16905 | + (set_attr "type" "fcmpd") | ||
| 16906 | + (set_attr "cc" "fpcompare")]) | ||
| 16907 | + | ||
| 16908 | +(define_expand "cmpsf" | ||
| 16909 | + [(set (cc0) | ||
| 16910 | + (compare:SF | ||
| 16911 | + (match_operand:SF 0 "general_operand" "") | ||
| 16912 | + (match_operand:SF 1 "general_operand" "")))] | ||
| 16913 | + "TARGET_HARD_FLOAT" | ||
| 16914 | + "{ | ||
| 16915 | + rtx tmpreg; | ||
| 16916 | + if ( !REG_P(operands[0]) ) | ||
| 16917 | + operands[0] = force_reg(SFmode, operands[0]); | ||
| 16918 | + | ||
| 16919 | + if ( !REG_P(operands[1]) ) | ||
| 16920 | + operands[1] = force_reg(SFmode, operands[1]); | ||
| 16921 | + | ||
| 16922 | + avr32_compare_op0 = operands[0]; | ||
| 16923 | + avr32_compare_op1 = operands[1]; | ||
| 16924 | + | ||
| 16925 | + emit_insn(gen_cmpsf_internal(operands[0], operands[1])); | ||
| 16926 | + | ||
| 16927 | + tmpreg = gen_reg_rtx(SImode); | ||
| 16928 | + emit_insn(gen_fpcc_to_reg(tmpreg)); | ||
| 16929 | + emit_insn(gen_reg_to_cc(tmpreg)); | ||
| 16930 | + | ||
| 16931 | + DONE; | ||
| 16932 | + }" | ||
| 16933 | +) | ||
| 16934 | + | ||
| 16935 | +(define_insn "cmpsf_internal" | ||
| 16936 | + [(set (reg:CC FPCC_REGNUM) | ||
| 16937 | + (compare:CC | ||
| 16938 | + (match_operand:SF 0 "avr32_fp_register_operand" "f") | ||
| 16939 | + (match_operand:SF 1 "avr32_fp_register_operand" "f")))] | ||
| 16940 | + "TARGET_HARD_FLOAT" | ||
| 16941 | + { | ||
| 16942 | + if (!rtx_equal_p(cc_prev_status.mdep.fpvalue, SET_SRC(PATTERN (insn))) ) | ||
| 16943 | + return "fcmp.s\t%0, %1"; | ||
| 16944 | + return ""; | ||
| 16945 | + } | ||
| 16946 | + [(set_attr "length" "4") | ||
| 16947 | + (set_attr "type" "fcmps") | ||
| 16948 | + (set_attr "cc" "fpcompare")]) | ||
| 16949 | + | ||
| 16950 | +(define_insn "fpcc_to_reg" | ||
| 16951 | + [(set (match_operand:SI 0 "register_operand" "=r") | ||
| 16952 | + (unspec:SI [(reg:CC FPCC_REGNUM)] | ||
| 16953 | + UNSPEC_FPCC_TO_REG))] | ||
| 16954 | + "TARGET_HARD_FLOAT" | ||
| 16955 | + "fmov.s\t%0, fsr" | ||
| 16956 | + [(set_attr "length" "4") | ||
| 16957 | + (set_attr "type" "fmvcpu")]) | ||
| 16958 | + | ||
| 16959 | +(define_insn "reg_to_cc" | ||
| 16960 | + [(set (cc0) | ||
| 16961 | + (unspec:SI [(match_operand:SI 0 "register_operand" "r")] | ||
| 16962 | + UNSPEC_REG_TO_CC))] | ||
| 16963 | + "TARGET_HARD_FLOAT" | ||
| 16964 | + "musfr\t%0" | ||
| 16965 | + [(set_attr "length" "2") | ||
| 16966 | + (set_attr "type" "alu") | ||
| 16967 | + (set_attr "cc" "from_fpcc")]) | ||
| 16968 | + | ||
| 16969 | +(define_insn "stm_fp" | ||
| 16970 | + [(unspec [(match_operand 0 "register_operand" "r") | ||
| 16971 | + (match_operand 1 "const_int_operand" "") | ||
| 16972 | + (match_operand 2 "const_int_operand" "")] | ||
| 16973 | + UNSPEC_STMFP)] | ||
| 16974 | + "TARGET_HARD_FLOAT" | ||
| 16975 | + { | ||
| 16976 | + int cop_reglist = INTVAL(operands[1]); | ||
| 16977 | + | ||
| 16978 | + if (INTVAL(operands[2]) != 0) | ||
| 16979 | + return "stcm.w\tcp0, --%0, %C1"; | ||
| 16980 | + else | ||
| 16981 | + return "stcm.w\tcp0, %0, %C1"; | ||
| 16982 | + | ||
| 16983 | + if ( cop_reglist & ~0xff ){ | ||
| 16984 | + operands[1] = GEN_INT(cop_reglist & ~0xff); | ||
| 16985 | + if (INTVAL(operands[2]) != 0) | ||
| 16986 | + return "stcm.d\tcp0, --%0, %D1"; | ||
| 16987 | + else | ||
| 16988 | + return "stcm.d\tcp0, %0, %D1"; | ||
| 16989 | + } | ||
| 16990 | + } | ||
| 16991 | + [(set_attr "type" "fstm") | ||
| 16992 | + (set_attr "length" "4") | ||
| 16993 | + (set_attr "cc" "none")]) | ||
| 16994 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/lib1funcs.S gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/lib1funcs.S | ||
| 16995 | --- gcc-4.0.2/gcc/config/avr32/lib1funcs.S 1970-01-01 01:00:00.000000000 +0100 | ||
| 16996 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/lib1funcs.S 2006-10-10 12:36:34.000000000 +0200 | ||
| 16997 | @@ -0,0 +1,1678 @@ | ||
| 16998 | +/*#define __IEEE_LARGE_FLOATS__*/ | ||
| 16999 | + | ||
| 17000 | +/* Adjust the unpacked double number if it is a subnormal number. | ||
| 17001 | + The exponent and mantissa pair are stored | ||
| 17002 | + in [mant_hi,mant_lo] and [exp]. A register with the correct sign bit in | ||
| 17003 | + the MSB is passed in [sign]. Needs two scratch | ||
| 17004 | + registers [scratch1] and [scratch2]. An adjusted and packed double float | ||
| 17005 | + is present in [mant_hi,mant_lo] after macro has executed */ | ||
| 17006 | +.macro adjust_subnormal_df exp, mant_lo, mant_hi, sign, scratch1, scratch2 | ||
| 17007 | + /* We have an exponent which is <=0 indicating a subnormal number | ||
| 17008 | + As it should be stored as if the exponent was 1 (although the | ||
| 17009 | + exponent field is all zeros to indicate a subnormal number) | ||
| 17010 | + we have to shift down the mantissa to its correct position. */ | ||
| 17011 | + neg \exp | ||
| 17012 | + sub \exp,-1 /* amount to shift down */ | ||
| 17013 | + cp.w \exp,54 | ||
| 17014 | + brlo 50f /* if more than 53 shift steps, the | ||
| 17015 | + entire mantissa will disappear | ||
| 17016 | + without any rounding to occur */ | ||
| 17017 | + mov \mant_hi, 0 | ||
| 17018 | + mov \mant_lo, 0 | ||
| 17019 | + rjmp 52f | ||
| 17020 | +50: | ||
| 17021 | + sub \exp,-10 /* do the shift to position the | ||
| 17022 | + mantissa at the same time | ||
| 17023 | + note! this does not include the | ||
| 17024 | + final 1 step shift to add the sign */ | ||
| 17025 | + | ||
| 17026 | + /* when shifting, save all shifted out bits in [scratch2]. we may need to | ||
| 17027 | + look at them to make correct rounding. */ | ||
| 17028 | + | ||
| 17029 | + rsub \scratch1,\exp,32 /* get inverted shift count */ | ||
| 17030 | + cp.w \exp,32 /* handle shifts >= 32 separately */ | ||
| 17031 | + brhs 51f | ||
| 17032 | + | ||
| 17033 | + /* small (<32) shift amount, both words are part of the shift */ | ||
| 17034 | + lsl \scratch2,\mant_lo,\scratch1 /* save bits to shift out from lsw*/ | ||
| 17035 | + lsl \scratch1,\mant_hi,\scratch1 /* get bits from msw destined for lsw*/ | ||
| 17036 | + lsr \mant_lo,\mant_lo,\exp /* shift down lsw */ | ||
| 17037 | + lsr \mant_hi,\mant_hi,\exp /* shift down msw */ | ||
| 17038 | + or \mant_hi,\scratch1 /* add bits from msw with prepared lsw */ | ||
| 17039 | + rjmp 50f | ||
| 17040 | + | ||
| 17041 | + /* large (>=32) shift amount, only lsw will have bits left after shift. | ||
| 17042 | + note that shift operations will use ((shift count) mod 32) so | ||
| 17043 | + we do not need to subtract 32 from shift count. */ | ||
| 17044 | +51: | ||
| 17045 | + lsl \scratch2,\mant_hi,\scratch1 /* save bits to shift out from msw */ | ||
| 17046 | + or \scratch2,\mant_lo /* also save all bits from lsw */ | ||
| 17047 | + mov \mant_lo,\mant_hi /* msw -> lsw (i.e. "shift 32 first") */ | ||
| 17048 | + mov \mant_hi,0 /* clear msw */ | ||
| 17049 | + lsr \mant_lo,\mant_lo,\exp /* make rest of shift inside lsw */ | ||
| 17050 | + | ||
| 17051 | +50: | ||
| 17052 | + /* result is almost ready to return, except that least significant bit | ||
| 17053 | + and the part we already shifted out may cause the result to be | ||
| 17054 | + rounded */ | ||
| 17055 | + bld \mant_lo,0 /* get bit to be shifted out */ | ||
| 17056 | + brcc 51f /* if bit was 0, no rounding */ | ||
| 17057 | + | ||
| 17058 | + /* msb of part to remove is 1, so rounding depends on rest of bits */ | ||
| 17059 | + tst \scratch2,\scratch2 /* get shifted out tail */ | ||
| 17060 | + brne 50f /* if rest > 0, do round */ | ||
| 17061 | + bld \mant_lo,1 /* we have to look at lsb in result */ | ||
| 17062 | + brcc 51f /* if lsb is 0, don't round */ | ||
| 17063 | + | ||
| 17064 | +50: | ||
| 17065 | + /* subnormal result requires rounding | ||
| 17066 | + rounding may cause subnormal to become smallest normal number | ||
| 17067 | + luckily, smallest normal number has exactly the representation | ||
| 17068 | + we got by rippling a one bit up from mantissa into exponent field. */ | ||
| 17069 | + sub \mant_lo,-1 | ||
| 17070 | + subcc \mant_hi,-1 | ||
| 17071 | + | ||
| 17072 | +51: | ||
| 17073 | + /* shift and return packed double with correct sign */ | ||
| 17074 | + rol \sign | ||
| 17075 | + ror \mant_hi | ||
| 17076 | + ror \mant_lo | ||
| 17077 | +52: | ||
| 17078 | +.endm | ||
| 17079 | + | ||
| 17080 | + | ||
| 17081 | +/* Adjust subnormal single float number with exponent [exp] | ||
| 17082 | + and mantissa [mant] and round. */ | ||
| 17083 | +.macro adjust_subnormal_sf sf, exp, mant, sign, scratch | ||
| 17084 | + /* subnormal number */ | ||
| 17085 | + rsub \exp,\exp, 1 /* shift amount */ | ||
| 17086 | + cp.w \exp, 25 | ||
| 17087 | + movhs \mant, 0 | ||
| 17088 | + brhs 90f /* Return zero */ | ||
| 17089 | + rsub \scratch, \exp, 32 | ||
| 17090 | + lsl \scratch, \mant,\scratch/* Check if there are any bits set | ||
| 17091 | + in the bits discarded in the mantissa */ | ||
| 17092 | + srne \scratch /* If so set the lsb of the shifted mantissa */ | ||
| 17093 | + lsr \mant,\mant,\exp /* Shift the mantissa */ | ||
| 17094 | + or \mant, \scratch /* Round lsb if any bits were shifted out */ | ||
| 17095 | + /* Rounding : For explaination, see round_sf. */ | ||
| 17096 | + mov \scratch, 0x7f /* Set rounding constant */ | ||
| 17097 | + bld \mant, 8 | ||
| 17098 | + subeq \scratch, -1 /* For odd numbers use rounding constant 0x80 */ | ||
| 17099 | + add \mant, \scratch /* Add rounding constant to mantissa */ | ||
| 17100 | + /* We can't overflow because mantissa is at least shifted one position | ||
| 17101 | + to the right so the implicit bit is zero. We can however get the implicit | ||
| 17102 | + bit set after rounding which means that we have the lowest normal number | ||
| 17103 | + but this is ok since this bit has the same position as the LSB of the | ||
| 17104 | + exponent */ | ||
| 17105 | + lsr \sf, \mant, 7 | ||
| 17106 | + /* Rotate in sign */ | ||
| 17107 | + lsl \sign, 1 | ||
| 17108 | + ror \sf | ||
| 17109 | +90: | ||
| 17110 | +.endm | ||
| 17111 | + | ||
| 17112 | + | ||
| 17113 | +/* Round the unpacked df number with exponent [exp] and | ||
| 17114 | + mantissa [mant_hi, mant_lo]. Uses scratch register | ||
| 17115 | + [scratch] */ | ||
| 17116 | +.macro round_df exp, mant_lo, mant_hi, scratch | ||
| 17117 | + mov \scratch, 0x3ff /* Rounding constant */ | ||
| 17118 | + bld \mant_lo,11 /* Check if lsb in the final result is | ||
| 17119 | + set */ | ||
| 17120 | + subeq \scratch, -1 /* Adjust rounding constant to 0x400 | ||
| 17121 | + if rounding 0.5 upwards */ | ||
| 17122 | + add \mant_lo, \scratch /* Round */ | ||
| 17123 | + acr \mant_hi /* If overflowing we know that | ||
| 17124 | + we have all zeros in the bits not | ||
| 17125 | + scaled out so we can leave them | ||
| 17126 | + but we must increase the exponent with | ||
| 17127 | + two since we had an implicit bit | ||
| 17128 | + which is lost + the extra overflow bit */ | ||
| 17129 | + subcs \exp, -2 /* Update exponent */ | ||
| 17130 | +.endm | ||
| 17131 | + | ||
| 17132 | +/* Round single float number stored in [mant] and [exp] */ | ||
| 17133 | +.macro round_sf exp, mant, scratch | ||
| 17134 | + /* Round: | ||
| 17135 | + For 0.5 we round to nearest even integer | ||
| 17136 | + for all other cases we round to nearest integer. | ||
| 17137 | + This means that if the digit left of the "point" (.) | ||
| 17138 | + is 1 we can add 0x80 to the mantissa since the | ||
| 17139 | + corner case 0x180 will round up to 0x200. If the | ||
| 17140 | + digit left of the "point" is 0 we will have to | ||
| 17141 | + add 0x7f since this will give 0xff and hence a | ||
| 17142 | + truncation/rounding downwards for the corner | ||
| 17143 | + case when the 9 lowest bits are 0x080 */ | ||
| 17144 | + mov \scratch, 0x7f /* Set rounding constant */ | ||
| 17145 | + /* Check if the mantissa is even or odd */ | ||
| 17146 | + bld \mant, 8 | ||
| 17147 | + subeq \scratch, -1 /* Rounding constant should be 0x80 */ | ||
| 17148 | + add \mant, \scratch | ||
| 17149 | + subcs \exp, -2 /* Adjust exponent if we overflowed */ | ||
| 17150 | +.endm | ||
| 17151 | + | ||
| 17152 | +/* Scale mantissa [mant_hi, mant_lo] with amount [shift_count]. | ||
| 17153 | + Uses scratch registers [scratch1] and [scratch2] */ | ||
| 17154 | +.macro scale_df shift_count, mant_lo, mant_hi, scratch1, scratch2 | ||
| 17155 | + /* Scale [mant_hi, mant_lo] with shift_amount. | ||
| 17156 | + Must not forget the sticky bits we intend to shift out. */ | ||
| 17157 | + | ||
| 17158 | + rsub \scratch1,\shift_count,32/* get (32 - shift count) | ||
| 17159 | + (if shift count > 32 we get a | ||
| 17160 | + negative value, but that will | ||
| 17161 | + work as well in the code below.) */ | ||
| 17162 | + | ||
| 17163 | + cp.w \shift_count,32 /* handle shifts >= 32 separately */ | ||
| 17164 | + brhs 70f | ||
| 17165 | + | ||
| 17166 | + /* small (<32) shift amount, both words are part of the shift | ||
| 17167 | + first remember whether part that is lost contains any 1 bits ... */ | ||
| 17168 | + lsl \scratch2,\mant_lo,\scratch1 /*shift away bits that are part of | ||
| 17169 | + final mantissa. only part that goes | ||
| 17170 | + to scratch2 are bits that will be lost */ | ||
| 17171 | + | ||
| 17172 | + /* ... and now to the actual shift */ | ||
| 17173 | + lsl \scratch1,\mant_hi,\scratch1 /* get bits from msw destined for lsw*/ | ||
| 17174 | + lsr \mant_lo,\mant_lo,\shift_count /* shift down lsw of mantissa */ | ||
| 17175 | + lsr \mant_hi,\mant_hi,\shift_count /* shift down msw of mantissa */ | ||
| 17176 | + or \mant_lo,\scratch1 /* combine these bits with prepared lsw*/ | ||
| 17177 | + rjmp 71f | ||
| 17178 | + | ||
| 17179 | + /* large (>=32) shift amount, only lsw will have bits left after shift. | ||
| 17180 | + note that shift operations will use ((shift count) mod 32) so | ||
| 17181 | + we do not need to subtract 32 from shift count. */ | ||
| 17182 | +70: | ||
| 17183 | + /* first remember whether part that is lost contains any 1 bits ... */ | ||
| 17184 | + lsl \scratch2,\mant_hi,\scratch1 /* save all lost bits from msw */ | ||
| 17185 | + or \scratch2,\mant_lo /* also save lost bits (all) from lsw | ||
| 17186 | + now scratch2<>0 if we lose any bits */ | ||
| 17187 | + | ||
| 17188 | + /* ... and now to the actual shift */ | ||
| 17189 | + mov \mant_lo,\mant_hi /* msw -> lsw (i.e. "shift 32 first")*/ | ||
| 17190 | + mov \mant_hi,0 /* clear msw */ | ||
| 17191 | + lsr \mant_lo,\mant_lo,\shift_count /* make rest of shift inside lsw*/ | ||
| 17192 | + | ||
| 17193 | +71: | ||
| 17194 | + cp.w \scratch2,0 /* if any '1' bit in part we lost ...*/ | ||
| 17195 | + breq 70f | ||
| 17196 | + | ||
| 17197 | + sbr \mant_lo,0 /* ... we need to set sticky bit*/ | ||
| 17198 | +70: | ||
| 17199 | +.endm | ||
| 17200 | + | ||
| 17201 | +/* Unpack exponent and mantissa from the double number | ||
| 17202 | + stored in [df_hi,df_lo]. The exponent is stored in [exp] | ||
| 17203 | + while the mantissa is stored in [df_hi,df_lo]. */ | ||
| 17204 | + | ||
| 17205 | +.macro unpack_df exp, df_lo, df_hi | ||
| 17206 | + lsr \exp, \df_hi,21 /* Extract exponent */ | ||
| 17207 | + lsl \df_hi,10 /* Get mantissa */ | ||
| 17208 | + or \df_hi,\df_hi,\df_lo>>21 | ||
| 17209 | + lsl \df_lo,11 | ||
| 17210 | + | ||
| 17211 | + neg \exp /* Fix implicit bit */ | ||
| 17212 | + bst \df_hi,31 | ||
| 17213 | + subeq \exp,1 | ||
| 17214 | + neg \exp /* negate back exponent */ | ||
| 17215 | + .endm | ||
| 17216 | + | ||
| 17217 | +/* Unpack exponent and mantissa from the single float number | ||
| 17218 | + stored in [sf]. The exponent is stored in [exp] | ||
| 17219 | + while the mantissa is stored in [sf]. */ | ||
| 17220 | +.macro unpack_sf exp, sf | ||
| 17221 | + lsr \exp, \sf, 24 | ||
| 17222 | + brne 80f | ||
| 17223 | + /* Fix subnormal number */ | ||
| 17224 | + lsl \sf,7 | ||
| 17225 | + clz \exp,\sf | ||
| 17226 | + lsl \sf,\sf,\exp | ||
| 17227 | + rsub \exp,\exp,1 | ||
| 17228 | + rjmp 81f | ||
| 17229 | +80: | ||
| 17230 | + lsl \sf,7 | ||
| 17231 | + sbr \sf, 31 /*Implicit bit*/ | ||
| 17232 | +81: | ||
| 17233 | +.endm | ||
| 17234 | + | ||
| 17235 | + | ||
| 17236 | + | ||
| 17237 | +/* Pack a single float number stored in [mant] and [exp] | ||
| 17238 | + into a single float number in [sf] */ | ||
| 17239 | +.macro pack_sf sf, exp, mant | ||
| 17240 | + bld \mant,31 /* implicit bit to z */ | ||
| 17241 | + subne \exp,1 /* if subnormal (implicit bit 0) | ||
| 17242 | + adjust exponent to storage format */ | ||
| 17243 | + | ||
| 17244 | + lsr \sf, \mant, 7 | ||
| 17245 | + bfins \sf, \exp, 24, 8 | ||
| 17246 | +.endm | ||
| 17247 | + | ||
| 17248 | +/* Pack exponent [exp] and mantissa [mant_hi, mant_lo] | ||
| 17249 | + into [df_hi, df_lo]. [df_hi] is shifted | ||
| 17250 | + one bit up so the sign bit can be shifted into it */ | ||
| 17251 | + | ||
| 17252 | +.macro pack_df exp, mant_lo, mant_hi, df_lo, df_hi | ||
| 17253 | + bld \mant_hi,31 /* implicit bit to z */ | ||
| 17254 | + subne \exp,1 /* if subnormal (implicit bit 0) | ||
| 17255 | + adjust exponent to storage format */ | ||
| 17256 | + | ||
| 17257 | + lsr \mant_lo,11 /* shift back lsw */ | ||
| 17258 | + or \df_lo,\mant_lo,\mant_hi<<21 /* combine with low bits from msw */ | ||
| 17259 | + lsl \mant_hi,1 /* get rid of implicit bit */ | ||
| 17260 | + lsr \mant_hi,11 /* shift back msw except for one step*/ | ||
| 17261 | + or \df_hi,\mant_hi,\exp<<21 /* combine msw with exponent */ | ||
| 17262 | +.endm | ||
| 17263 | + | ||
| 17264 | +/* Normalize single float number stored in [mant] and [exp] | ||
| 17265 | + using scratch register [scratch] */ | ||
| 17266 | +.macro normalize_sf exp, mant, scratch | ||
| 17267 | + /* Adjust exponent and mantissa */ | ||
| 17268 | + clz \scratch, \mant | ||
| 17269 | + sub \exp, \scratch | ||
| 17270 | + lsl \mant, \mant, \scratch | ||
| 17271 | +.endm | ||
| 17272 | + | ||
| 17273 | +/* Normalize the exponent and mantissa pair stored | ||
| 17274 | + in [mant_hi,mant_lo] and [exp]. Needs two scratch | ||
| 17275 | + registers [scratch1] and [scratch2]. */ | ||
| 17276 | +.macro normalize_df exp, mant_lo, mant_hi, scratch1, scratch2 | ||
| 17277 | + clz \scratch1,\mant_hi /* Check if we have zeros in high bits */ | ||
| 17278 | + breq 80f /* No need for scaling if no zeros in high bits */ | ||
| 17279 | + cp.w \scratch1,32 /* Check for all zeros */ | ||
| 17280 | + breq 81f | ||
| 17281 | + | ||
| 17282 | + /* shift amount is smaller than 32, and involves both msw and lsw*/ | ||
| 17283 | + rsub \scratch2,\scratch1,32 /* shift mantissa */ | ||
| 17284 | + lsl \mant_hi,\mant_hi,\scratch1 | ||
| 17285 | + lsr \scratch2,\mant_lo,\scratch2 | ||
| 17286 | + or \mant_hi,\scratch2 | ||
| 17287 | + lsl \mant_lo,\mant_lo,\scratch1 | ||
| 17288 | + sub \exp,\scratch1 /* adjust exponent */ | ||
| 17289 | + rjmp 80f /* Finished */ | ||
| 17290 | +81: | ||
| 17291 | + /* shift amount is greater than 32 */ | ||
| 17292 | + clz \scratch1,\mant_lo /* shift mantissa */ | ||
| 17293 | + sub \scratch1,-32 | ||
| 17294 | + mov \mant_hi,\mant_lo | ||
| 17295 | + lsl \mant_hi,\mant_hi,\scratch1 | ||
| 17296 | + mov \mant_lo,0 | ||
| 17297 | + sub \exp,\scratch1 /* adjust exponent */ | ||
| 17298 | +80: | ||
| 17299 | +.endm | ||
| 17300 | + | ||
| 17301 | + | ||
| 17302 | +#ifdef L_avr32_f64_mul | ||
| 17303 | + .align 2 | ||
| 17304 | + .global __avr32_f64_mul | ||
| 17305 | + .type __avr32_f64_mul,@function | ||
| 17306 | + | ||
| 17307 | +__avr32_f64_mul: | ||
| 17308 | + pushm r0-r3,r4-r7,lr | ||
| 17309 | + | ||
| 17310 | + /* Unpack */ | ||
| 17311 | + eor r12, r11, r9 /* Sign op1 ^ Sign op2 is MSB of r12*/ | ||
| 17312 | + lsl r11,1 /* Unpack op1 */ | ||
| 17313 | + lsl r9,1 /* Unpack op2 */ | ||
| 17314 | + | ||
| 17315 | + /* Sort operands op1 >= op2 */ | ||
| 17316 | + lddpc r5, .Linf | ||
| 17317 | + cp.w r10,r8 | ||
| 17318 | + cpc r11,r9 | ||
| 17319 | + brhs 0f | ||
| 17320 | + | ||
| 17321 | + mov r7,r11 /* swap operands if op2 was larger */ | ||
| 17322 | + mov r6,r10 | ||
| 17323 | + mov r11,r9 | ||
| 17324 | + mov r10,r8 | ||
| 17325 | + mov r9,r7 | ||
| 17326 | + mov r8,r6 | ||
| 17327 | + | ||
| 17328 | +0: | ||
| 17329 | + /* Check against infinity */ | ||
| 17330 | + cp.w r11,r5 | ||
| 17331 | + brlo 1f | ||
| 17332 | + /* infinity or nan */ | ||
| 17333 | + /* we have to check low word as well as nan mantissa may be 0 in msw*/ | ||
| 17334 | + cpc r10 | ||
| 17335 | + /* we know that op1 is inf or nan. if z != 1 then we have nan. | ||
| 17336 | + in this case, also return nan. */ | ||
| 17337 | + breq 0f | ||
| 17338 | + /* Return NaN */ | ||
| 17339 | + mov r11, -1 | ||
| 17340 | + rjmp __dfmul_return_op1 | ||
| 17341 | +0: | ||
| 17342 | + | ||
| 17343 | + /* op1 is infinity. op2 is smaller or same so it cannot be nan. | ||
| 17344 | + it can be infinity or a (sub-)normal number. | ||
| 17345 | + we should return op1 (infinity) except when op2 is zero when | ||
| 17346 | + result should be nan. */ | ||
| 17347 | + or r5,r9,r8 | ||
| 17348 | + brne __dfmul_return_op1 /* op2 is not zero. return op1.*/ | ||
| 17349 | + /* Return NaN */ | ||
| 17350 | + mov r11, -1 | ||
| 17351 | + rjmp __dfmul_return_op1 | ||
| 17352 | + | ||
| 17353 | +1: | ||
| 17354 | + /* no operand is inf/nan, and operands have been arranged in order | ||
| 17355 | + with op1 >= op2, implying that if we have a zero, it is found in | ||
| 17356 | + op2. in this case, result should be zero (with sign from both ops). */ | ||
| 17357 | + | ||
| 17358 | + or r5,r9,r8 /* check the smaller value for zero */ | ||
| 17359 | + brne 0f | ||
| 17360 | + mov r10, 0 | ||
| 17361 | + mov r11, 0 | ||
| 17362 | + rjmp __dfmul_return_op1 /* Early exit */ | ||
| 17363 | +0: | ||
| 17364 | + | ||
| 17365 | + /* we have two "normal" (can be subnormal) nonzero numbers in r11:r10 | ||
| 17366 | + and r9:r8. sign of result is already calculated in r12. | ||
| 17367 | + perform a normal multiplication. */ | ||
| 17368 | + | ||
| 17369 | + /* Unpack and normalize*/ | ||
| 17370 | + unpack_df r7 /*exp*/, r10, r11 /* mantissa */ | ||
| 17371 | + normalize_df r7 /*exp*/, r10, r11 /* mantissa */, r4, r5 /* scratch */ | ||
| 17372 | + | ||
| 17373 | + | ||
| 17374 | + /* Unpack and normalize*/ | ||
| 17375 | + unpack_df r6 /*exp*/, r8, r9 /* mantissa */ | ||
| 17376 | + normalize_df r6 /*exp*/, r8, r9 /* mantissa */, r4, r5 /* scratch */ | ||
| 17377 | + | ||
| 17378 | + /* Multiply */ | ||
| 17379 | + | ||
| 17380 | + mulu.d r0,r10,r8 | ||
| 17381 | + add lr,r7,r6 /* calculate new exponent after mul */ | ||
| 17382 | + mulu.d r2,r11,r8 | ||
| 17383 | + sub lr,(1023-1) /* remove exponent bias as we have | ||
| 17384 | + included bias from both op1 and op2 | ||
| 17385 | + sub one less, or in other words | ||
| 17386 | + add one to exponent. see below why. */ | ||
| 17387 | + mulu.d r6,r11,r9 | ||
| 17388 | + add r2,r1 | ||
| 17389 | + mulu.d r4,r10,r9 | ||
| 17390 | + | ||
| 17391 | + | ||
| 17392 | + adc r6,r6,r3 | ||
| 17393 | + acr r7 | ||
| 17394 | + | ||
| 17395 | + add r4,r2 | ||
| 17396 | + adc r6,r6,r5 | ||
| 17397 | + acr r7 | ||
| 17398 | + | ||
| 17399 | + // r7:r6 is now in range [0x4000...0000 - 0xffff...fffe] | ||
| 17400 | + // remaining bits in r0 and r4 are of no interest, except that we have | ||
| 17401 | + // to add a sticky bit to r10 in case we had a 1 bit in r4 or r0. | ||
| 17402 | + | ||
| 17403 | + or r4,r0 | ||
| 17404 | + movne r0, 1 /* If we have bits in r4 or r0 */ | ||
| 17405 | + or r6,r0 /* set lsb of result to 1 */ | ||
| 17406 | + | ||
| 17407 | + | ||
| 17408 | + // if msb is set, it was because multiplication gave an "overflow" | ||
| 17409 | + // of one bit so exponent should be incremented. | ||
| 17410 | + // we already did that above so we are done. | ||
| 17411 | + // if msb is *not* set it will be normalized and exponent will be | ||
| 17412 | + // decremented (which will compensate the one we added above). | ||
| 17413 | + | ||
| 17414 | + normalize_df lr /*exp*/, r6, r7 /* mantissa */, r8, r9 /* scratch */ | ||
| 17415 | + | ||
| 17416 | + /* Check if a subnormal result was created */ | ||
| 17417 | + cp.w lr, 0 | ||
| 17418 | + brgt 0f | ||
| 17419 | + | ||
| 17420 | + adjust_subnormal_df lr, r6, r7, r12, r8, r9 | ||
| 17421 | + mov r10, r6 | ||
| 17422 | + mov r11, r7 | ||
| 17423 | + popm r0-r3,r4-r7, pc | ||
| 17424 | +0: | ||
| 17425 | + | ||
| 17426 | + /* Round result */ | ||
| 17427 | + round_df lr /*exp*/, r6, r7 /* Mantissa */, r4 /*scratch*/ | ||
| 17428 | + cp.w lr,0x7ff | ||
| 17429 | + brlt 0f | ||
| 17430 | + /*Return infinity */ | ||
| 17431 | + lddpc r11, .Linf | ||
| 17432 | + mov r10, 0 | ||
| 17433 | + rjmp __dfmul_return_op1 | ||
| 17434 | + | ||
| 17435 | +0: | ||
| 17436 | + | ||
| 17437 | + /* Pack */ | ||
| 17438 | + pack_df lr /*exp*/, r6, r7 /* mantissa */, r10, r11 /* Output df number*/ | ||
| 17439 | +__dfmul_return_op1: | ||
| 17440 | + lsl r12,1 /* shift in sign bit */ | ||
| 17441 | + ror r11 | ||
| 17442 | + | ||
| 17443 | + popm r0-r3,r4-r7, pc | ||
| 17444 | + | ||
| 17445 | +#endif | ||
| 17446 | + | ||
| 17447 | + | ||
| 17448 | +#ifdef L_avr32_f64_addsub | ||
| 17449 | + .align 2 | ||
| 17450 | + .global __avr32_f64_sub | ||
| 17451 | + .type __avr32_f64_sub,@function | ||
| 17452 | + | ||
| 17453 | +__avr32_f64_sub: | ||
| 17454 | + pushm r4-r7,lr | ||
| 17455 | + | ||
| 17456 | + eor r12,r11,r9 // compare signs of operands | ||
| 17457 | + bld r12,31 | ||
| 17458 | + brcc __dfsub // same sign => subtract | ||
| 17459 | + | ||
| 17460 | + eorh r9,0x8000 | ||
| 17461 | + rjmp __dfadd // different signs => op1 + (-op2) | ||
| 17462 | +__dfsub: | ||
| 17463 | + | ||
| 17464 | + lsl r11,1 // unpack op1 msw and get sign in c | ||
| 17465 | + or r4,r11,r10 // check if all bits zero | ||
| 17466 | + brne 1f | ||
| 17467 | + | ||
| 17468 | + // op1 is zero, negate op2 and handle as add | ||
| 17469 | + eorh r9,0x8000 | ||
| 17470 | + // op1 is +/-0, and is unpacked with sign in c. add to op2. | ||
| 17471 | + // also used by sub, but op2 has been negated in this case | ||
| 17472 | + ror r12 // save sign of op1 in msb of r12 | ||
| 17473 | + lsl r9,1 // unpack msw and get sign of op2 | ||
| 17474 | + or r4,r9,r8 // check all bits in op2 | ||
| 17475 | + breq 0f | ||
| 17476 | + | ||
| 17477 | + // if op2 != 0, then return op2 unchanged. | ||
| 17478 | + ror r9 // pack op2 msw again with sign from c | ||
| 17479 | + mov r11,r9 | ||
| 17480 | + mov r10,r8 | ||
| 17481 | + popm r4-r7,pc | ||
| 17482 | + | ||
| 17483 | +0: | ||
| 17484 | + // both op1 and op2 zero, but sign unknown. result should and signs. | ||
| 17485 | + ror r9 // pack op2 msw again with sign from c | ||
| 17486 | + lsl r12,1 // get back sign of op1 into c ... | ||
| 17487 | + ror r11 // and back in original op1 | ||
| 17488 | + and r11,r9 // and sign bits. as op1 is zero, the | ||
| 17489 | + // only bit which can be 1 is sign bit | ||
| 17490 | + popm r4-r7,pc | ||
| 17491 | + | ||
| 17492 | +1: | ||
| 17493 | + ror r12 // save op1 sign in msb of r12 | ||
| 17494 | + | ||
| 17495 | + lsl r9,1 // unpack op2 msw | ||
| 17496 | + or r4,r8,r9 | ||
| 17497 | + brne 0f | ||
| 17498 | + // op2 is zero, return op1 | ||
| 17499 | + // whatever it is. the only case | ||
| 17500 | + // requiring special handling is if | ||
| 17501 | + // op1 is zero, but that was handled | ||
| 17502 | + // above. | ||
| 17503 | + lsl r12, 1 | ||
| 17504 | + ror r11 | ||
| 17505 | + popm r4-r7,pc | ||
| 17506 | + | ||
| 17507 | +0: | ||
| 17508 | + // make sure that op1 >= op2, flip sign if we swap ops | ||
| 17509 | + cp.w r10,r8 | ||
| 17510 | + cpc r11,r9 | ||
| 17511 | + brhs 0f | ||
| 17512 | + | ||
| 17513 | + com r12 // sign of op1 and result in lsb(r12) | ||
| 17514 | + mov r7,r11 // swap operands if op2 was larger | ||
| 17515 | + mov r6,r10 | ||
| 17516 | + mov r11,r9 | ||
| 17517 | + mov r10,r8 | ||
| 17518 | + mov r9,r7 | ||
| 17519 | + mov r8,r6 | ||
| 17520 | + | ||
| 17521 | +0: | ||
| 17522 | + // check if op1 is nan or inf. | ||
| 17523 | + lddpc r5,.Linf | ||
| 17524 | + cp.w r11,r5 | ||
| 17525 | + brlo 1f | ||
| 17526 | + /* Op 1 is nan or inf */ | ||
| 17527 | + // we have to check low word as well as nan mantissa may be 0 in msw | ||
| 17528 | + cpc r10 | ||
| 17529 | + // we know that op1 is inf or nan. if z != 1 then we have nan. | ||
| 17530 | + // if we have nan, return nan. | ||
| 17531 | + breq 0f | ||
| 17532 | + mov r11, -1 | ||
| 17533 | + rjmp __dfsub_return_op1 | ||
| 17534 | +0: | ||
| 17535 | + | ||
| 17536 | + // op1 is infinity. check if op2 is nan, infinty or a normal number. | ||
| 17537 | + cp.w r9,r5 | ||
| 17538 | + movhs r11, -1 // op2 is a normal number. return op1. | ||
| 17539 | + | ||
| 17540 | + // op2 can be infinity (of the same sign as op1) or nan. | ||
| 17541 | + // in both cases we should return nan. | ||
| 17542 | + rjmp __dfsub_return_op1 | ||
| 17543 | +1: | ||
| 17544 | + // if op1 is not inf or nan, then op2 cannot be since op1 >= op2 | ||
| 17545 | + | ||
| 17546 | + // now prepare the operands by expanding them and shifting op2 | ||
| 17547 | + // to the correct position for the subtract. note! if op2 is | ||
| 17548 | + // insignificant compared to op1, the function will take care of | ||
| 17549 | + // this and return op1 directly to the application. | ||
| 17550 | + | ||
| 17551 | + /* Unpack operands */ | ||
| 17552 | + unpack_df r7 /* exp op1*/, r10, r11 /* Mantissa op1 */ | ||
| 17553 | + unpack_df r6 /* exp op2*/, r8, r9 /* Mantissa op2 */ | ||
| 17554 | + | ||
| 17555 | + /* Get shift amount required for aligning op1 and op2 */ | ||
| 17556 | + rsub r6, r7 | ||
| 17557 | + breq __perform_dfsub /* No shift needed */ | ||
| 17558 | + | ||
| 17559 | + cp.w r6, 63 | ||
| 17560 | + brhs __dfsub_pack_result /* Op 2 insignificant compared to op1 */ | ||
| 17561 | + | ||
| 17562 | + /* Shift mantissa of op2 so that op1 and op2 are aligned */ | ||
| 17563 | + scale_df r6 /* shift_count*/, r8, r9 /* Mantissa */, r4, r5 /*Scratch*/ | ||
| 17564 | + | ||
| 17565 | +__perform_dfsub: | ||
| 17566 | + sub r10,r8 /* subtract mantissa of op2 from op1 */ | ||
| 17567 | + sbc r11,r11,r9 | ||
| 17568 | + or r4,r11,r10 /* check if result is all zeroes */ | ||
| 17569 | + brne 0f | ||
| 17570 | + popm r4-r7,pc /* Early return */ | ||
| 17571 | +0: | ||
| 17572 | + | ||
| 17573 | + normalize_df r7 /*exp*/, r10, r11 /* mantissa */, r8, r9 /* scratch */ | ||
| 17574 | + | ||
| 17575 | + /* Check if a subnormal result was created */ | ||
| 17576 | + cp.w r7, 0 | ||
| 17577 | + brgt 0f | ||
| 17578 | + | ||
| 17579 | + adjust_subnormal_df r7 /*exp*/, r10, r11 /* Mantissa */, r12 /*sign*/, r8, r9 /*scratch*/ | ||
| 17580 | + popm r4-r7,pc | ||
| 17581 | +0: | ||
| 17582 | + | ||
| 17583 | + /* Round result */ | ||
| 17584 | + round_df r7 /*exp*/, r10, r11 /* Mantissa */, r9 /*scratch*/ | ||
| 17585 | + cp.w r7,0x7ff | ||
| 17586 | + brlt __dfsub_pack_result | ||
| 17587 | + /*Return infinity */ | ||
| 17588 | + lddpc r11, .Linf | ||
| 17589 | + mov r10, 0 | ||
| 17590 | + rjmp __dfsub_return_op1 | ||
| 17591 | + | ||
| 17592 | +__dfsub_pack_result: | ||
| 17593 | + /* Pack */ | ||
| 17594 | + pack_df r7 /*exp*/, r10, r11 /* mantissa */, r10, r11 /* Output df number*/ | ||
| 17595 | + | ||
| 17596 | +__dfsub_return_op1: | ||
| 17597 | + lsl r12,1 | ||
| 17598 | + ror r11 | ||
| 17599 | + popm r4-r7,pc | ||
| 17600 | + | ||
| 17601 | + .align 2 | ||
| 17602 | + .global __avr32_f64_add | ||
| 17603 | + .type __avr32_f64_add,@function | ||
| 17604 | +__avr32_f64_add: | ||
| 17605 | + pushm r4-r7,lr | ||
| 17606 | + eor r12,r11,r9 // compare signs of operands | ||
| 17607 | + lsl r12,1 | ||
| 17608 | + brcc __dfadd // same sign => add | ||
| 17609 | + | ||
| 17610 | + eorh r9,0x8000 | ||
| 17611 | + rjmp __dfsub // different signs => op1 - (-op2) | ||
| 17612 | +__dfadd: | ||
| 17613 | + | ||
| 17614 | + lsl r11,1 // unpack op1 msw and get sign in c | ||
| 17615 | + or r4,r11,r10 // check if all bits zero | ||
| 17616 | + brne 1f | ||
| 17617 | + | ||
| 17618 | + // op1 is +/-0, and is unpacked with sign in c. add to op2. | ||
| 17619 | + // also used by sub, but op2 has been negated in this case | ||
| 17620 | + ror r12 // save sign of op1 in msb of r12 | ||
| 17621 | + lsl r9,1 // unpack msw and get sign of op2 | ||
| 17622 | + or r4,r9,r8 // check all bits in op2 | ||
| 17623 | + breq 0f | ||
| 17624 | + | ||
| 17625 | + // if op2 != 0, then return op2 unchanged. | ||
| 17626 | + ror r9 // pack op2 msw again with sign from c | ||
| 17627 | + mov r11,r9 | ||
| 17628 | + mov r10,r8 | ||
| 17629 | + popm r4-r7,pc | ||
| 17630 | + | ||
| 17631 | +0: | ||
| 17632 | + // both op1 and op2 zero, but sign unknown. result should and signs. | ||
| 17633 | + ror r9 // pack op2 msw again with sign from c | ||
| 17634 | + lsl r12,1 // get back sign of op1 into c ... | ||
| 17635 | + ror r11 // and back in original op1 | ||
| 17636 | + and r11,r9 // and sign bits. as op1 is zero, the | ||
| 17637 | + // only bit which can be 1 is sign bit | ||
| 17638 | + popm r4-r7,pc | ||
| 17639 | +1: | ||
| 17640 | + ror r12 // save op1 sign in msb of r12 | ||
| 17641 | + | ||
| 17642 | + lsl r9,1 // unpack op2 msw | ||
| 17643 | + or r4,r8,r9 | ||
| 17644 | + brne 0f | ||
| 17645 | + // op2 is zero, return op1 | ||
| 17646 | + // whatever it is. the only case | ||
| 17647 | + // requiring special handling is if | ||
| 17648 | + // op1 is zero, but that was handled | ||
| 17649 | + // above. | ||
| 17650 | + lsl r12, 1 | ||
| 17651 | + ror r11 | ||
| 17652 | + popm r4-r7,pc | ||
| 17653 | +0: | ||
| 17654 | + // make sure that exp[op1] >= exp[op2] | ||
| 17655 | + cp.w r11,r9 | ||
| 17656 | + brhs 0f | ||
| 17657 | + | ||
| 17658 | + mov r7,r11 // swap operands if op2 was larger | ||
| 17659 | + mov r6,r10 | ||
| 17660 | + mov r11,r9 | ||
| 17661 | + mov r10,r8 | ||
| 17662 | + mov r9,r7 | ||
| 17663 | + mov r8,r6 | ||
| 17664 | + | ||
| 17665 | +0: | ||
| 17666 | + // check if op1 is nan or inf. | ||
| 17667 | + lddpc r5,.Linf | ||
| 17668 | + cp.w r11,r5 | ||
| 17669 | + brlo 1f | ||
| 17670 | + /* Op 1 is nan or inf */ | ||
| 17671 | + // we have to check low word as well as nan mantissa may be 0 in msw | ||
| 17672 | + cpc r10 | ||
| 17673 | + // we know that op1 is inf or nan. if z != 1 then we have nan. | ||
| 17674 | + // if we have nan, return nan. | ||
| 17675 | + breq 0f | ||
| 17676 | + mov r11, -1 | ||
| 17677 | + rjmp __dfadd_return_op1 | ||
| 17678 | +0: | ||
| 17679 | + | ||
| 17680 | + // op1 is infinity. check if op2 is nan, infinty or a normal number. | ||
| 17681 | + cp.w r9,r5 | ||
| 17682 | + // Op2 is NaN of Inf. Return op2 but with sign of result. | ||
| 17683 | + // If Op2 is NaN, sign doesn't matter but no need to separate NaN | ||
| 17684 | + movhs r11, r9 | ||
| 17685 | + movhs r10, r8 | ||
| 17686 | + | ||
| 17687 | + // op2 can be infinity (of the same sign as op1) or nan. | ||
| 17688 | + // in both cases we should return nan. | ||
| 17689 | + rjmp __dfadd_return_op1 | ||
| 17690 | +1: | ||
| 17691 | + // if op1 is not inf or nan, then op2 cannot be since exp[op1] >= | ||
| 17692 | + // exp[op2] | ||
| 17693 | + | ||
| 17694 | + // now prepare the operands by expanding them and shifting op2 | ||
| 17695 | + // to the correct position for the add. note! if op2 is | ||
| 17696 | + // insignificant compared to op1, the function will take care of | ||
| 17697 | + // this and return op1 directly to the application. | ||
| 17698 | + | ||
| 17699 | + /* Unpack operands */ | ||
| 17700 | + unpack_df r7 /* exp op1*/, r10, r11 /* Mantissa op1 */ | ||
| 17701 | + unpack_df r6 /* exp op2*/, r8, r9 /* Mantissa op2 */ | ||
| 17702 | + | ||
| 17703 | + /* Get shift amount required for aligning op1 and op2 */ | ||
| 17704 | + rsub r6, r7 | ||
| 17705 | + breq __perform_dfadd /* No shift needed */ | ||
| 17706 | + | ||
| 17707 | + cp.w r6, 63 | ||
| 17708 | + brhs __dfadd_pack_result /* Op 2 insignificant compared to op1 */ | ||
| 17709 | + | ||
| 17710 | + /* Shift mantissa of op2 so that op1 and op2 are aligned */ | ||
| 17711 | + scale_df r6 /* shift_count*/, r8, r9 /* Mantissa */, r4, r5 /*Scratch*/ | ||
| 17712 | + | ||
| 17713 | +__perform_dfadd: | ||
| 17714 | + add r10,r8 // add mantissas | ||
| 17715 | + adc r11,r11,r9 | ||
| 17716 | + brcc 0f | ||
| 17717 | + ror r11 // overflow => shift down mantissa | ||
| 17718 | + ror r10 | ||
| 17719 | + brcc 1f // sticky bit shifted out? | ||
| 17720 | + sbr r10,0 // if so, merge it into result again | ||
| 17721 | +1: | ||
| 17722 | + sub r7,-1 // increase exponent with 1 | ||
| 17723 | +0: | ||
| 17724 | + normalize_df r7 /*exp*/, r10, r11 /* mantissa */, r8, r9 /* scratch */ | ||
| 17725 | + | ||
| 17726 | + /* Check if a subnormal result was created */ | ||
| 17727 | + cp.w r7, 0 | ||
| 17728 | + brgt 0f | ||
| 17729 | + | ||
| 17730 | + adjust_subnormal_df r7 /*exp*/, r10, r11 /* Mantissa */, r12 /*sign*/, r8, r9 /*scratch*/ | ||
| 17731 | + popm r4-r7,pc | ||
| 17732 | +0: | ||
| 17733 | + | ||
| 17734 | + /* Round result */ | ||
| 17735 | + round_df r7 /*exp*/, r10, r11 /* Mantissa */, r9 /*scratch*/ | ||
| 17736 | + cp.w r7,0x7ff | ||
| 17737 | + brlt __dfadd_pack_result | ||
| 17738 | + /*Return infinity */ | ||
| 17739 | + lddpc r11, .Linf | ||
| 17740 | + mov r10, 0 | ||
| 17741 | + rjmp __dfadd_return_op1 | ||
| 17742 | + | ||
| 17743 | +__dfadd_pack_result: | ||
| 17744 | + /* Pack */ | ||
| 17745 | + pack_df r7 /*exp*/, r10, r11 /* mantissa */, r10, r11 /* Output df number*/ | ||
| 17746 | + | ||
| 17747 | +__dfadd_return_op1: | ||
| 17748 | + lsl r12,1 | ||
| 17749 | + ror r11 | ||
| 17750 | + popm r4-r7,pc | ||
| 17751 | +#endif | ||
| 17752 | + | ||
| 17753 | +#ifdef L_avr32_f64_to_u32 | ||
| 17754 | + /* This goes into L_fixdfsi */ | ||
| 17755 | +#endif | ||
| 17756 | + | ||
| 17757 | + | ||
| 17758 | +#ifdef L_avr32_f64_to_s32 | ||
| 17759 | + .global __avr32_f64_to_u32 | ||
| 17760 | + .type __avr32_f64_to_u32,@function | ||
| 17761 | +__avr32_f64_to_u32: | ||
| 17762 | + cp.w r11, 0 | ||
| 17763 | + retmi 0 /* Negative returns 0 */ | ||
| 17764 | +#ifdef __LARGE_FLOATS__ | ||
| 17765 | + lsl r12,r11,1 | ||
| 17766 | + lsr r12,21 /* extract exponent*/ | ||
| 17767 | + sub r12,1023 /* convert to unbiased exponent.*/ | ||
| 17768 | + retlo 0 /* too small exponent implies zero. */ | ||
| 17769 | + cp.w r12,32 | ||
| 17770 | + brcc 0f | ||
| 17771 | + rjmp 1f | ||
| 17772 | +#endif | ||
| 17773 | + | ||
| 17774 | + /* Fallthrough to df to signed si conversion */ | ||
| 17775 | + .global __avr32_f64_to_s32 | ||
| 17776 | + .type __avr32_f64_to_s32,@function | ||
| 17777 | +__avr32_f64_to_s32: | ||
| 17778 | + lsl r12,r11,1 | ||
| 17779 | + lsr r12,21 /* extract exponent*/ | ||
| 17780 | + sub r12,1023 /* convert to unbiased exponent.*/ | ||
| 17781 | + retlo 0 /* too small exponent implies zero. */ | ||
| 17782 | + | ||
| 17783 | +#ifdef __LARGE_FLOATS__ | ||
| 17784 | + cp.w r12,31 | ||
| 17785 | + brcc 0f | ||
| 17786 | +#endif | ||
| 17787 | +1: | ||
| 17788 | + rsub r12,r12,31 /* shift count = 31 - exponent */ | ||
| 17789 | + mov r9,r11 /* save sign for later...*/ | ||
| 17790 | + lsl r11,11 /* remove exponent and sign*/ | ||
| 17791 | + sbr r11,31 /* add implicit bit*/ | ||
| 17792 | + or r11,r11,r10>>21 /* get rest of bits from lsw of double */ | ||
| 17793 | + lsr r11,r11,r12 /* shift down mantissa to final place */ | ||
| 17794 | + lsl r9,1 /* sign -> carry */ | ||
| 17795 | + retcc r11 /* if positive, we are done */ | ||
| 17796 | + neg r11 /* if negative float, negate result */ | ||
| 17797 | + ret r11 | ||
| 17798 | + | ||
| 17799 | +#ifdef __LARGE_FLOATS__ | ||
| 17800 | +0: | ||
| 17801 | + mov r12,-1 /* r11 = 0xffffffff */ | ||
| 17802 | + lsr r12,1 /* r11 = 0x7fffffff */ | ||
| 17803 | + lsl r11,1 /* sign -> carry */ | ||
| 17804 | + acr r12 /* r11 = signed ? 0x80000000 | ||
| 17805 | + : 0x7fffffff */ | ||
| 17806 | + ret r12 | ||
| 17807 | +#endif | ||
| 17808 | +#endif /* L_fixdfsi*/ | ||
| 17809 | + | ||
| 17810 | +#ifdef L_avr32_f64_to_u64 | ||
| 17811 | + /* Actual function is in L_fixdfdi */ | ||
| 17812 | +#endif | ||
| 17813 | + | ||
| 17814 | +#ifdef L_avr32_f64_to_s64 | ||
| 17815 | + .global __avr32_f64_to_u64 | ||
| 17816 | + .type __avr32_f64_to_u64,@function | ||
| 17817 | +__avr32_f64_to_u64: | ||
| 17818 | + cp.w r11,0 | ||
| 17819 | + /* Negative numbers return zero */ | ||
| 17820 | + movmi r10, 0 | ||
| 17821 | + movmi r11, 0 | ||
| 17822 | + retmi r11 | ||
| 17823 | +#ifdef __LARGE_FLOATS__ | ||
| 17824 | + lsl r9,r11,1 | ||
| 17825 | + lsr r9,21 /* get exponent*/ | ||
| 17826 | + sub r9,1023 /* convert to correct range*/ | ||
| 17827 | + /* Return zero if exponent to small */ | ||
| 17828 | + movlo r10, 0 | ||
| 17829 | + movlo r11, 0 | ||
| 17830 | + retlo r11 | ||
| 17831 | + cp.w r9,64 | ||
| 17832 | + mov r8,r11 /* save sign for later...*/ | ||
| 17833 | + brcs 1f | ||
| 17834 | + rjmp 2f /* Number to large */ | ||
| 17835 | + | ||
| 17836 | +#endif | ||
| 17837 | + | ||
| 17838 | + | ||
| 17839 | + | ||
| 17840 | + /* Fallthrough */ | ||
| 17841 | + .global __avr32_f64_to_s64 | ||
| 17842 | + .type __avr32_f64_to_s64,@function | ||
| 17843 | +__avr32_f64_to_s64: | ||
| 17844 | + lsl r9,r11,1 | ||
| 17845 | + lsr r9,21 /* get exponent*/ | ||
| 17846 | + sub r9,1023 /* convert to correct range*/ | ||
| 17847 | + /* Return zero if exponent to small */ | ||
| 17848 | + movlo r10, 0 | ||
| 17849 | + movlo r11, 0 | ||
| 17850 | + retlo r11 | ||
| 17851 | + | ||
| 17852 | +#ifdef __LARGE_FLOATS__ | ||
| 17853 | + cp.w r9,63 | ||
| 17854 | + mov r8,r11 /* save sign for later...*/ | ||
| 17855 | + brcc 2f | ||
| 17856 | +#else | ||
| 17857 | + mov r8,r11 /* save sign for later...*/ | ||
| 17858 | +#endif | ||
| 17859 | +1: | ||
| 17860 | + lsl r11,11 /* remove exponent */ | ||
| 17861 | + sbr r11,31 /* add implicit bit*/ | ||
| 17862 | + or r11,r11,r10>>21 /* get rest of bits from lsw of double*/ | ||
| 17863 | + lsl r10,11 /* align lsw correctly as well */ | ||
| 17864 | + rsub r9,r9,63 /* shift count = 63 - exponent */ | ||
| 17865 | + breq 1f | ||
| 17866 | + | ||
| 17867 | + cp.w r9,32 /* is shift count more than one reg? */ | ||
| 17868 | + brhs 0f | ||
| 17869 | + | ||
| 17870 | + mov r12,r11 /* save msw */ | ||
| 17871 | + lsr r10,r10,r9 /* small shift count, shift down lsw */ | ||
| 17872 | + lsr r11,r11,r9 /* small shift count, shift down msw */ | ||
| 17873 | + rsub r9,r9,32 /* get 32-size of shifted out tail */ | ||
| 17874 | + lsl r12,r12,r9 /* align part to move from msw to lsw */ | ||
| 17875 | + or r10,r12 /* combine to get new lsw */ | ||
| 17876 | + rjmp 1f | ||
| 17877 | + | ||
| 17878 | +0: | ||
| 17879 | + lsr r10,r11,r9 /* large shift count,only lsw get bits | ||
| 17880 | + note that shift count is modulo 32*/ | ||
| 17881 | + mov r11,0 /* msw will be 0 */ | ||
| 17882 | + | ||
| 17883 | +1: | ||
| 17884 | + lsl r8,1 /* sign -> carry */ | ||
| 17885 | + retcc r11 /* if positive, we are done */ | ||
| 17886 | + | ||
| 17887 | + neg r11 /* if negative float, negate result */ | ||
| 17888 | + neg r10 | ||
| 17889 | + scr r11 | ||
| 17890 | + ret r11 | ||
| 17891 | + | ||
| 17892 | + | ||
| 17893 | +#ifdef __LARGE_FLOATS__ | ||
| 17894 | +2: | ||
| 17895 | + mov r11,-1 /* r11 = 0xffffffff */ | ||
| 17896 | + lsr r11,1 /* r11 = 0x7fffffff */ | ||
| 17897 | + lsl r8,1 /* sign -> carry */ | ||
| 17898 | + acr r11 /* r11 = signed ? 0x80000000 */ | ||
| 17899 | + /* : 0x7fffffff */ | ||
| 17900 | + lsl r10,r11,31 /* extend last bit of msw*/ | ||
| 17901 | + asr r10,31 | ||
| 17902 | + ret r11 | ||
| 17903 | +#endif | ||
| 17904 | +#endif | ||
| 17905 | + | ||
| 17906 | +#ifdef L_avr32_u32_to_f64 | ||
| 17907 | + /* Code located in L_floatsidf */ | ||
| 17908 | +#endif | ||
| 17909 | + | ||
| 17910 | +#ifdef L_avr32_s32_to_f64 | ||
| 17911 | + .global __avr32_u32_to_f64 | ||
| 17912 | + .type __avr32_u32_to_f64,@function | ||
| 17913 | +__avr32_u32_to_f64: | ||
| 17914 | + sub r11, r12, 0 /* Move to r11 and force Z flag to be updated */ | ||
| 17915 | + mov r12, 0 /* always positive */ | ||
| 17916 | + rjmp 0f /* Jump to common code for floatsidf */ | ||
| 17917 | + | ||
| 17918 | + .global __avr32_s32_to_f64 | ||
| 17919 | + .type __avr32_s32_to_f64,@function | ||
| 17920 | +__avr32_s32_to_f64: | ||
| 17921 | + mov r11, r12 /* Keep original value in r12 for sign */ | ||
| 17922 | + abs r11 /* Absolute value if r12 */ | ||
| 17923 | +0: | ||
| 17924 | + mov r10,0 /* let remaining bits be zero */ | ||
| 17925 | + reteq r11 /* zero long will return zero float */ | ||
| 17926 | + | ||
| 17927 | + pushm lr | ||
| 17928 | + mov r9,31+1023 /* set exponent */ | ||
| 17929 | + | ||
| 17930 | + normalize_df r9 /*exp*/, r10, r11 /* mantissa */, r8, lr /* scratch */ | ||
| 17931 | + | ||
| 17932 | + /* Check if a subnormal result was created */ | ||
| 17933 | + cp.w r9, 0 | ||
| 17934 | + brgt 0f | ||
| 17935 | + | ||
| 17936 | + adjust_subnormal_df r9 /* exp */, r10, r11 /* Mantissa */, r12 /*sign*/, r8, lr /* scratch */ | ||
| 17937 | + popm pc | ||
| 17938 | +0: | ||
| 17939 | + | ||
| 17940 | + /* Round result */ | ||
| 17941 | + round_df r9 /*exp*/, r10, r11 /* Mantissa */, r8 /*scratch*/ | ||
| 17942 | + cp.w r9,0x7ff | ||
| 17943 | + brlt 0f | ||
| 17944 | + /*Return infinity */ | ||
| 17945 | + lddpc r11, .Linf | ||
| 17946 | + mov r10, 0 | ||
| 17947 | + rjmp __floatsidf_return_op1 | ||
| 17948 | + | ||
| 17949 | +0: | ||
| 17950 | + | ||
| 17951 | + /* Pack */ | ||
| 17952 | + pack_df r9 /*exp*/, r10, r11 /* mantissa */, r10, r11 /* Output df number*/ | ||
| 17953 | +__floatsidf_return_op1: | ||
| 17954 | + lsl r12,1 /* shift in sign bit */ | ||
| 17955 | + ror r11 | ||
| 17956 | + | ||
| 17957 | + popm pc | ||
| 17958 | +#endif | ||
| 17959 | + | ||
| 17960 | + | ||
| 17961 | +#ifdef L_avr32_f32_cmp_eq | ||
| 17962 | + .global __avr32_f32_cmp_eq | ||
| 17963 | + .type __avr32_f32_cmp_eq,@function | ||
| 17964 | +__avr32_f32_cmp_eq: | ||
| 17965 | + cp.w r12, r11 | ||
| 17966 | + brne 0f /* If not equal check for +/-0 */ | ||
| 17967 | + | ||
| 17968 | + /* Check for NaN or Inf */ | ||
| 17969 | + lddpc r11,.Linf_sf | ||
| 17970 | + lsl r12, 1 | ||
| 17971 | + cp.w r12, r11 | ||
| 17972 | + srls r12 /* 0 if NaN, 1 otherwise */ | ||
| 17973 | + ret r12 | ||
| 17974 | +0: | ||
| 17975 | + /* Or together the two values and shift out the sign bit. | ||
| 17976 | + If the result is zero, then the two values are both zero. */ | ||
| 17977 | + or r12, r11 | ||
| 17978 | + lsl r12, 1 | ||
| 17979 | + sreq r12 | ||
| 17980 | + ret r12 | ||
| 17981 | +#endif | ||
| 17982 | + | ||
| 17983 | +#if defined(L_avr32_f32_cmp_ge) || defined(L_avr32_f32_cmp_lt) | ||
| 17984 | +#ifdef L_avr32_f32_cmp_ge | ||
| 17985 | + .global __avr32_f32_cmp_ge | ||
| 17986 | + .type __avr32_f32_cmp_ge,@function | ||
| 17987 | +__avr32_f32_cmp_ge: | ||
| 17988 | +#endif | ||
| 17989 | +#ifdef L_avr32_f32_cmp_lt | ||
| 17990 | + .global __avr32_f32_cmp_lt | ||
| 17991 | + .type __avr32_f32_cmp_lt,@function | ||
| 17992 | +__avr32_f32_cmp_lt: | ||
| 17993 | +#endif | ||
| 17994 | + lsl r10, r12, 1 /* Remove sign bits */ | ||
| 17995 | + lsl r9, r11, 1 | ||
| 17996 | + lddpc r8, .Linf_sf | ||
| 17997 | + cp.w r10, r8 | ||
| 17998 | + rethi 0 /* Op0 is NaN */ | ||
| 17999 | + cp.w r9, r8 | ||
| 18000 | + rethi 0 /* Op1 is Nan */ | ||
| 18001 | + | ||
| 18002 | + eor r8, r11, r12 | ||
| 18003 | + bld r12, 31 | ||
| 18004 | +#ifdef L_avr32_f32_cmp_ge | ||
| 18005 | + srcc r8 /* Set result to true if op0 is positive*/ | ||
| 18006 | +#endif | ||
| 18007 | +#ifdef L_avr32_f32_cmp_lt | ||
| 18008 | + srcs r8 /* Set result to true if op0 is negative*/ | ||
| 18009 | +#endif | ||
| 18010 | + retmi r8 /* Return if signs are different */ | ||
| 18011 | + brcs 0f /* Both signs negative? */ | ||
| 18012 | + | ||
| 18013 | + /* Both signs positive */ | ||
| 18014 | + cp.w r12, r11 | ||
| 18015 | +#ifdef L_avr32_f32_cmp_ge | ||
| 18016 | + srhs r12 | ||
| 18017 | +#endif | ||
| 18018 | +#ifdef L_avr32_f32_cmp_lt | ||
| 18019 | + srlo r12 | ||
| 18020 | +#endif | ||
| 18021 | + retal r12 | ||
| 18022 | +0: | ||
| 18023 | + /* Both signs negative */ | ||
| 18024 | + cp.w r11, r12 | ||
| 18025 | +#ifdef L_avr32_f32_cmp_ge | ||
| 18026 | + srhs r12 | ||
| 18027 | +#endif | ||
| 18028 | +#ifdef L_avr32_f32_cmp_lt | ||
| 18029 | + srlo r12 | ||
| 18030 | +#endif | ||
| 18031 | + retal r12 | ||
| 18032 | +#endif | ||
| 18033 | + | ||
| 18034 | + | ||
| 18035 | +#ifdef L_avr32_f64_cmp_eq | ||
| 18036 | + .global __avr32_f64_cmp_eq | ||
| 18037 | + .type __avr32_f64_cmp_eq,@function | ||
| 18038 | +__avr32_f64_cmp_eq: | ||
| 18039 | + cp.w r10,r8 | ||
| 18040 | + cpc r11,r9 | ||
| 18041 | + brne 0f /* Both args could be zero with different sign bits */ | ||
| 18042 | + | ||
| 18043 | + /* check for NaN */ | ||
| 18044 | + lsl r11,1 | ||
| 18045 | + lddpc r12,.Linf | ||
| 18046 | + cp.w r10,0 | ||
| 18047 | + cpc r11,r12 /* check if nan or inf */ | ||
| 18048 | + srls r12 /* If Arg is NaN return 0 else 1*/ | ||
| 18049 | + ret r12 /* Return */ | ||
| 18050 | + | ||
| 18051 | +0: | ||
| 18052 | + lsl r11,1 /* get rid of sign bits */ | ||
| 18053 | + lsl r9,1 | ||
| 18054 | + or r11,r10 /* Check if all bits are zero */ | ||
| 18055 | + or r11,r9 | ||
| 18056 | + or r11,r8 | ||
| 18057 | + sreq r12 /* If all zeros the arguments are equal | ||
| 18058 | + so return 1 else return 0 */ | ||
| 18059 | + ret r12 | ||
| 18060 | +#endif | ||
| 18061 | + | ||
| 18062 | + | ||
| 18063 | +#if defined(L_avr32_f64_cmp_ge) || defined(L_avr32_f64_cmp_lt) | ||
| 18064 | + | ||
| 18065 | +#ifdef L_avr32_f64_cmp_ge | ||
| 18066 | + .global __avr32_f64_cmp_ge | ||
| 18067 | + .type __avr32_f64_cmp_ge,@function | ||
| 18068 | +__avr32_f64_cmp_ge: | ||
| 18069 | +#endif | ||
| 18070 | +#ifdef L_avr32_f64_cmp_lt | ||
| 18071 | + .global __avr32_f64_cmp_lt | ||
| 18072 | + .type __avr32_f64_cmp_lt,@function | ||
| 18073 | +__avr32_f64_cmp_lt: | ||
| 18074 | +#endif | ||
| 18075 | + | ||
| 18076 | + /* compare magnitude of op1 and op2 */ | ||
| 18077 | + pushm lr | ||
| 18078 | + | ||
| 18079 | + lsl r11,1 /* Remove sign bit of op1 */ | ||
| 18080 | + srcs lr /* Sign op1 to lsb of lr*/ | ||
| 18081 | + lsl r9,1 /* Remove sign bit of op2 */ | ||
| 18082 | + rol lr /* Sign op2 to lsb of lr, sign bit op1 bit 1 of lr*/ | ||
| 18083 | + | ||
| 18084 | + /* Check for Nan */ | ||
| 18085 | + lddpc r12,.Linf | ||
| 18086 | + cp.w r10,0 | ||
| 18087 | + cpc r11,r12 | ||
| 18088 | + movhi r12, 0 /* Return false for NaN */ | ||
| 18089 | + brhi 0f /* We have NaN */ | ||
| 18090 | + cp.w r8,0 | ||
| 18091 | + cpc r9,r12 | ||
| 18092 | + movhi r12, 0 /* Return false for NaN */ | ||
| 18093 | + brhi 0f /* We have NaN */ | ||
| 18094 | + | ||
| 18095 | + cp.w lr,3 /* both operands negative ?*/ | ||
| 18096 | + breq 1f | ||
| 18097 | + | ||
| 18098 | + cp.w lr,1 /* both operands positive? */ | ||
| 18099 | + brlo 2f | ||
| 18100 | + | ||
| 18101 | + /* Different signs. If sign of op1 is negative the difference | ||
| 18102 | + between op1 and op2 will always be negative, and if op1 is | ||
| 18103 | + positive the difference will always be positive */ | ||
| 18104 | +#ifdef L_avr32_f64_cmp_ge | ||
| 18105 | + sreq r12 | ||
| 18106 | +#endif | ||
| 18107 | +#ifdef L_avr32_f64_cmp_lt | ||
| 18108 | + srne r12 | ||
| 18109 | +#endif | ||
| 18110 | + popm pc | ||
| 18111 | + | ||
| 18112 | + | ||
| 18113 | +2: | ||
| 18114 | + /* Both operands positive. Just compute the difference */ | ||
| 18115 | + cp.w r10,r8 | ||
| 18116 | + cpc r11,r9 | ||
| 18117 | +#ifdef L_avr32_f64_cmp_ge | ||
| 18118 | + srhs r12 | ||
| 18119 | +#endif | ||
| 18120 | +#ifdef L_avr32_f64_cmp_lt | ||
| 18121 | + srlo r12 | ||
| 18122 | +#endif | ||
| 18123 | + popm pc | ||
| 18124 | + | ||
| 18125 | +1: | ||
| 18126 | + /* Both operands negative. Compute the difference with operands switched */ | ||
| 18127 | + cp r8,r10 | ||
| 18128 | + cpc r9,r11 | ||
| 18129 | +#ifdef L_avr32_f64_cmp_ge | ||
| 18130 | + srhs r12 | ||
| 18131 | +#endif | ||
| 18132 | +#ifdef L_avr32_f64_cmp_lt | ||
| 18133 | + srlo r12 | ||
| 18134 | +#endif | ||
| 18135 | +0: | ||
| 18136 | + popm pc | ||
| 18137 | +#endif | ||
| 18138 | + | ||
| 18139 | + | ||
| 18140 | + | ||
| 18141 | +#ifdef L_avr32_f64_div | ||
| 18142 | + .global __avr32_f64_div | ||
| 18143 | + .type __avr32_f64_div,@function | ||
| 18144 | +__avr32_f64_div: | ||
| 18145 | + stm --sp, r2-r7,lr | ||
| 18146 | + eor r12, r11, r9 /* Sign(op1) ^ Sign(op2) to msb of r12*/ | ||
| 18147 | + lsl r11,1 /* unpack op1*/ | ||
| 18148 | + lddpc lr,.Linf | ||
| 18149 | + lsl r9,1 /* unpack op2*/ | ||
| 18150 | + | ||
| 18151 | + cp.w r11,lr | ||
| 18152 | + brhs 0f /* op1 is NaN or infinity */ | ||
| 18153 | + cp.w r9,lr | ||
| 18154 | + brhs 1f /* op2 is NaN or infinity */ | ||
| 18155 | + or r5,r9,r8 | ||
| 18156 | + breq 2f /* op2 is zero */ | ||
| 18157 | + or r5,r11,r10 | ||
| 18158 | + breq __dfdiv_return_op1 /* op1 is zero return zero*/ | ||
| 18159 | + | ||
| 18160 | + /* Unpack and normalize */ | ||
| 18161 | + /* op1 */ | ||
| 18162 | + unpack_df r7 /*exp*/, r10, r11 /*df number*/ | ||
| 18163 | + normalize_df r7 /*exp*/, r10, r11 /*Mantissa*/, r4, r5 /*scratch*/ | ||
| 18164 | + | ||
| 18165 | + /* op1 */ | ||
| 18166 | + unpack_df r6 /*exp*/, r8, r9 /*df number*/ | ||
| 18167 | + normalize_df r6 /*exp*/, r8, r9 /*Mantissa*/, r4, r5 /*scratch*/ | ||
| 18168 | + | ||
| 18169 | + /* Compute new exponent */ | ||
| 18170 | + sub r7,r6 | ||
| 18171 | + sub r7,-1023 | ||
| 18172 | + | ||
| 18173 | + /* Do fixed point division of mantissas*/ | ||
| 18174 | + mov r6,55 | ||
| 18175 | + lsr r11,1 | ||
| 18176 | + ror r10 | ||
| 18177 | + lsr r9,1 | ||
| 18178 | + ror r8 | ||
| 18179 | + | ||
| 18180 | +3: | ||
| 18181 | + /* Check if dividend is higher or same than divisor */ | ||
| 18182 | + sub r2,r10,r8 | ||
| 18183 | + sbc r3,r11,r9 | ||
| 18184 | + /* If so move the difference back into the dividend */ | ||
| 18185 | + movhs r10, r2 | ||
| 18186 | + movhs r11, r3 | ||
| 18187 | + /* Update the Quotient */ | ||
| 18188 | + rol r4 | ||
| 18189 | + rol r5 | ||
| 18190 | + eorl r4,1 | ||
| 18191 | + | ||
| 18192 | + /* Shift the dividend */ | ||
| 18193 | + lsl r10,1 | ||
| 18194 | + rol r11 | ||
| 18195 | + | ||
| 18196 | + sub r6,1 | ||
| 18197 | + brne 3b | ||
| 18198 | + | ||
| 18199 | + /* Check if we have a remainder which will the propagate into | ||
| 18200 | + the last bit */ | ||
| 18201 | + | ||
| 18202 | + or r11,r11,r10 | ||
| 18203 | + neg r11 | ||
| 18204 | + rol r4 | ||
| 18205 | + rol r5 | ||
| 18206 | + | ||
| 18207 | + /* Adjust mantissa into correct alignment */ | ||
| 18208 | + lsl r11, r5,(64-56) | ||
| 18209 | + or r11,r11,r4>>(32-64+56) | ||
| 18210 | + lsl r10,r4, (64-56) | ||
| 18211 | + | ||
| 18212 | + /* Normalize result */ | ||
| 18213 | + normalize_df r7 /*exp*/, r10, r11 /* mantissa */, r8, r9 /* scratch */ | ||
| 18214 | + | ||
| 18215 | + /* Check if a subnormal result was created */ | ||
| 18216 | + cp.w r7, 0 | ||
| 18217 | + brgt 3f | ||
| 18218 | + | ||
| 18219 | + adjust_subnormal_df r7 /*exp*/, r10, r11 /* Mantissa */, r12 /*sign*/, r8, r9 /*scratch*/ | ||
| 18220 | + ldm sp++, r2-r7,pc | ||
| 18221 | +3: | ||
| 18222 | + | ||
| 18223 | + /* Round result */ | ||
| 18224 | + round_df r7 /*exp*/, r10, r11 /* Mantissa */, r9 /*scratch*/ | ||
| 18225 | + cp.w r7,0x7ff | ||
| 18226 | + brlt __dfdiv_pack_result | ||
| 18227 | + /*Return infinity */ | ||
| 18228 | + lddpc r11, .Linf | ||
| 18229 | + mov r10, 0 | ||
| 18230 | + rjmp __dfdiv_return_op1 | ||
| 18231 | + | ||
| 18232 | +__dfdiv_pack_result: | ||
| 18233 | + /* Pack */ | ||
| 18234 | + pack_df r7 /*exp*/, r10, r11 /* mantissa */, r10, r11 /* Output df number*/ | ||
| 18235 | + | ||
| 18236 | +__dfdiv_return_op1: | ||
| 18237 | + lsl r12,1 | ||
| 18238 | + ror r11 | ||
| 18239 | + ldm sp++, r2-r7,pc | ||
| 18240 | + | ||
| 18241 | +0: | ||
| 18242 | + /* Op1 is NaN or Inf */ | ||
| 18243 | + cpc r10 | ||
| 18244 | + /* If op1 is a NaN the we should return a NaN */ | ||
| 18245 | + brne __dfdiv_return_op1 | ||
| 18246 | + | ||
| 18247 | + /* Op1 is infinity, check op2*/ | ||
| 18248 | + cp.w r9,lr | ||
| 18249 | + brlo __dfdiv_return_op1 /* Op2 is a normal number return inf */ | ||
| 18250 | + /* Other combinations: return NaN */ | ||
| 18251 | + mov r11, -1 | ||
| 18252 | + ldm sp++, r2-r7,pc | ||
| 18253 | + | ||
| 18254 | +1: | ||
| 18255 | + /* Op2 is NaN or Inf */ | ||
| 18256 | + cpc r8 | ||
| 18257 | + /* If inf return zero else return NaN*/ | ||
| 18258 | + mov r10, 0 | ||
| 18259 | + moveq r11, 0 | ||
| 18260 | + movne r11, -1 | ||
| 18261 | + ldm sp++, r2-r7,pc | ||
| 18262 | + | ||
| 18263 | +2: | ||
| 18264 | + /* Op2 is zero */ | ||
| 18265 | + or r6,r11,r10 /* 0.0/0.0 yields NaN */ | ||
| 18266 | + mov r10, 0 | ||
| 18267 | + moveq r11, -1 /* Return NaN */ | ||
| 18268 | + movne r11, lr /* Return inf */ | ||
| 18269 | + rjmp __dfdiv_return_op1 | ||
| 18270 | + | ||
| 18271 | +#endif | ||
| 18272 | + | ||
| 18273 | + | ||
| 18274 | +#ifdef L_avr32_f32_div | ||
| 18275 | + .global __avr32_f32_div | ||
| 18276 | + .type __avr32_f32_div,@function | ||
| 18277 | +__avr32_f32_div: | ||
| 18278 | + eor r8, r11, r12 /* MSB(r8) = Sign(op1) ^ Sign(op2) */ | ||
| 18279 | + /* Unpack */ | ||
| 18280 | + lsl r12,1 | ||
| 18281 | + reteq 0 /* Return zero if op1 is zero */ | ||
| 18282 | + lddpc r9, .Linf_sf | ||
| 18283 | + lsl r11,1 | ||
| 18284 | + | ||
| 18285 | + /* Check op1 for NaN or Inf */ | ||
| 18286 | + cp r12,r9 | ||
| 18287 | + brhs 2f | ||
| 18288 | + | ||
| 18289 | + /* Check op2 for NaN or Inf */ | ||
| 18290 | + cp r11,r9 | ||
| 18291 | + brhs 3f | ||
| 18292 | + /* Check op2 for zero */ | ||
| 18293 | + tst r11,r11 | ||
| 18294 | + breq 4f | ||
| 18295 | + | ||
| 18296 | + /* If op1 is zero return zero */ | ||
| 18297 | + tst r12, r12 | ||
| 18298 | + reteq 0 | ||
| 18299 | + | ||
| 18300 | + /* Unpack op1*/ | ||
| 18301 | + unpack_sf r9 /*exp*/, r12 /*sf*/ | ||
| 18302 | + | ||
| 18303 | + /* Unpack op2*/ | ||
| 18304 | + unpack_sf r10 /*exp*/, r11 /*sf*/ | ||
| 18305 | + | ||
| 18306 | + /* Calculate new exponent */ | ||
| 18307 | + stm --sp,r7,lr | ||
| 18308 | + sub r9, r10 | ||
| 18309 | + sub r9,-127 | ||
| 18310 | + | ||
| 18311 | + /* Divide */ | ||
| 18312 | + mov r7,26 | ||
| 18313 | + | ||
| 18314 | + lsr r12,1 /* Make room for one more bit in mantissas */ | ||
| 18315 | + lsr r11,1 | ||
| 18316 | + | ||
| 18317 | +0: | ||
| 18318 | + sub r10,r12,r11 | ||
| 18319 | + movcc r12, r10 /* update dividend if divisor smaller */ | ||
| 18320 | + rol lr /* shift result into lr */ | ||
| 18321 | + eorl lr,1 /* flip bit. */ | ||
| 18322 | + lsl r12,1 /* Shift dividend */ | ||
| 18323 | + sub r7,1 | ||
| 18324 | + brne 0b | ||
| 18325 | + | ||
| 18326 | + /* round and scale*/ | ||
| 18327 | + neg r12 /* c = 1 iff r12 != 0 */ | ||
| 18328 | + rol lr | ||
| 18329 | + lsl r10,lr,(32-27) /* Adjust mantissa */ | ||
| 18330 | + ldm sp++, r7, lr | ||
| 18331 | + | ||
| 18332 | + | ||
| 18333 | + normalize_sf r9 /*exp*/, r10 /*mant*/, r11 /*scratch*/ | ||
| 18334 | + | ||
| 18335 | + /* Check for subnormal result */ | ||
| 18336 | + cp.w r9, 0 | ||
| 18337 | + brgt 0f | ||
| 18338 | + | ||
| 18339 | + /* Adjust a subnormal result */ | ||
| 18340 | + adjust_subnormal_sf r12 /*sf*/, r9 /*exp*/, r10 /*mant*/, r8 /*sign*/,r11 /*scratch*/ | ||
| 18341 | + ret r12 | ||
| 18342 | +0: | ||
| 18343 | + round_sf r9 /*exp*/, r10 /*mant*/, r11 /*scratch*/ | ||
| 18344 | + pack_sf r12 /*sf*/, r9 /*exp*/, r10 /*mant*/ | ||
| 18345 | +__divsf_return_op1: | ||
| 18346 | + lsl r8, 1 | ||
| 18347 | + ror r12 | ||
| 18348 | + ret r12 | ||
| 18349 | + | ||
| 18350 | +2: | ||
| 18351 | + /* Op1 is NaN or inf */ | ||
| 18352 | + retne -1 /* Return NaN if op1 is NaN */ | ||
| 18353 | + /* Op1 is inf check op2 */ | ||
| 18354 | + cp r11, r9 | ||
| 18355 | + brlo __divsf_return_op1 /* inf/number gives inf */ | ||
| 18356 | + ret -1 /* The rest gives NaN*/ | ||
| 18357 | +3: | ||
| 18358 | + /* Op1 is NaN or inf */ | ||
| 18359 | + reteq 0 /* Return zero if number/inf*/ | ||
| 18360 | + ret -1 /* Return NaN*/ | ||
| 18361 | +4: | ||
| 18362 | + /* Op2 is zero ? */ | ||
| 18363 | + tst r12,r12 | ||
| 18364 | + reteq -1 /* 0.0/0.0 is NaN */ | ||
| 18365 | + lddpc r12, .Linf_sf | ||
| 18366 | + rjmp __divsf_return_op1 | ||
| 18367 | + | ||
| 18368 | +#endif | ||
| 18369 | + | ||
| 18370 | +#ifdef L_avr32_f32_mul | ||
| 18371 | + .global __avr32_f32_mul | ||
| 18372 | + .type __avr32_f32_mul,@function | ||
| 18373 | +__avr32_f32_mul: | ||
| 18374 | + eor r8, r11, r12 /* MSB(r8) = Sign(op1) ^ Sign(op2) */ | ||
| 18375 | + lsl r12,1 /* unpack op1 */ | ||
| 18376 | + lsl r11,1 /* unpack op2 */ | ||
| 18377 | + | ||
| 18378 | + /* arrange operands so that that op1 >= op2 */ | ||
| 18379 | + sub r9,r12,r11 | ||
| 18380 | + brcc 0f | ||
| 18381 | + | ||
| 18382 | + sub r12,r9 /* swap operands if op2 was larger */ | ||
| 18383 | + add r11,r9 | ||
| 18384 | + | ||
| 18385 | +0: | ||
| 18386 | + lddpc r9,.Linf_sf | ||
| 18387 | + cp r12,r9 | ||
| 18388 | + brhs 2f | ||
| 18389 | + | ||
| 18390 | + /* Check op2 for zero */ | ||
| 18391 | + tst r11,r11 | ||
| 18392 | + reteq 0 /* Return zero */ | ||
| 18393 | + | ||
| 18394 | + /* Unpack op1 */ | ||
| 18395 | + unpack_sf r9 /*exp*/, r12 /*sf*/ | ||
| 18396 | + /* Unpack op2 */ | ||
| 18397 | + unpack_sf r10 /*exp*/, r11 /*sf*/ | ||
| 18398 | + | ||
| 18399 | + /* Calculate new exponent */ | ||
| 18400 | + add r9,r10 | ||
| 18401 | + | ||
| 18402 | + /* Do the multiplication */ | ||
| 18403 | + mulu.d r10,r12,r11 | ||
| 18404 | + | ||
| 18405 | + sub r9,(127-1) /* remove extra exponent bias */ | ||
| 18406 | + | ||
| 18407 | + /* Check if we have any bits in r10 which | ||
| 18408 | + means a rounding bit should be inserted in LSB of result */ | ||
| 18409 | + tst r10,r10 | ||
| 18410 | + srne r10 | ||
| 18411 | + or r12,r11,r10 | ||
| 18412 | + | ||
| 18413 | + /* Normalize */ | ||
| 18414 | + normalize_sf r9 /*exp*/, r12 /*mant*/, r11 /*scratch*/ | ||
| 18415 | + | ||
| 18416 | + /* Check for subnormal result */ | ||
| 18417 | + cp.w r9, 0 | ||
| 18418 | + brgt 0f | ||
| 18419 | + | ||
| 18420 | + /* Adjust a subnormal result */ | ||
| 18421 | + adjust_subnormal_sf r12/*sf*/, r9 /*exp*/, r12 /*mant*/, r8 /*sign*/, r11 /*scratch */ | ||
| 18422 | + ret r12 | ||
| 18423 | +0: | ||
| 18424 | + round_sf r9 /*exp*/, r12 /*mant*/, r11 /*scratch*/ | ||
| 18425 | + cp.w r9, 0xff | ||
| 18426 | + brlo 1f | ||
| 18427 | + lddpc r12,.Linf_sf | ||
| 18428 | + rjmp __mulsf_return_op1 | ||
| 18429 | +1: | ||
| 18430 | + pack_sf r12 /*sf*/, r9 /*exp*/, r12 /*mant*/ | ||
| 18431 | +__mulsf_return_op1: | ||
| 18432 | + lsl r8, 1 | ||
| 18433 | + ror r12 | ||
| 18434 | + ret r12 | ||
| 18435 | + | ||
| 18436 | +2: | ||
| 18437 | + /* Op1 is inf or NaN */ | ||
| 18438 | + retne -1 /* Op1 is NaN return NaN */ | ||
| 18439 | + | ||
| 18440 | + /* Op1 is inf and op2 is smaller so it is either infinity | ||
| 18441 | + or a subnormal number */ | ||
| 18442 | + cp r11,0 | ||
| 18443 | + brne __mulsf_return_op1 /* op2 is not zero. return op1.*/ | ||
| 18444 | + ret -1 /* inf * 0 return NaN */ | ||
| 18445 | +#endif | ||
| 18446 | + | ||
| 18447 | + | ||
| 18448 | +#ifdef L_avr32_s32_to_f32 | ||
| 18449 | + .global __avr32_s32_to_f32 | ||
| 18450 | + .type __avr32_s32_to_f32,@function | ||
| 18451 | +__avr32_s32_to_f32: | ||
| 18452 | + cp r12, 0 | ||
| 18453 | + reteq r12 /* If zero then return zero float */ | ||
| 18454 | + mov r11, r12 /* Keep the sign */ | ||
| 18455 | + abs r12 /* Compute the absolute value */ | ||
| 18456 | + mov r10, 31 + 127 /* Set the correct exponent */ | ||
| 18457 | + | ||
| 18458 | + /* Normalize */ | ||
| 18459 | + normalize_sf r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/ | ||
| 18460 | + | ||
| 18461 | + /* Check for subnormal result */ | ||
| 18462 | + cp.w r10, 0 | ||
| 18463 | + brgt 0f | ||
| 18464 | + | ||
| 18465 | + /* Adjust a subnormal result */ | ||
| 18466 | + adjust_subnormal_sf r12/*sf*/, r10 /*exp*/, r12 /*mant*/, r11/*sign*/, r9 /*scratch*/ | ||
| 18467 | + ret r12 | ||
| 18468 | +0: | ||
| 18469 | + round_sf r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/ | ||
| 18470 | + pack_sf r12 /*sf*/, r10 /*exp*/, r12 /*mant*/ | ||
| 18471 | +__floatsisf_return_op1: | ||
| 18472 | + lsl r11, 1 | ||
| 18473 | + ror r12 | ||
| 18474 | + ret r12 | ||
| 18475 | +#endif | ||
| 18476 | + | ||
| 18477 | +#ifdef L_avr32_u32_to_f32 | ||
| 18478 | + .global __avr32_u32_to_f32 | ||
| 18479 | + .type __avr32_u32_to_f32,@function | ||
| 18480 | +__avr32_u32_to_f32: | ||
| 18481 | + cp r12, 0 | ||
| 18482 | + reteq r12 /* If zero then return zero float */ | ||
| 18483 | + mov r10, 31 + 127 /* Set the correct exponent */ | ||
| 18484 | + | ||
| 18485 | + /* Normalize */ | ||
| 18486 | + normalize_sf r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/ | ||
| 18487 | + | ||
| 18488 | + /* Check for subnormal result */ | ||
| 18489 | + cp.w r10, 0 | ||
| 18490 | + brgt 0f | ||
| 18491 | + | ||
| 18492 | + /* Adjust a subnormal result */ | ||
| 18493 | + mov r8, 0 | ||
| 18494 | + adjust_subnormal_sf r12/*sf*/,r10 /*exp*/, r12 /*mant*/,r8/*sign*/, r9 /*scratch*/ | ||
| 18495 | + ret r12 | ||
| 18496 | +0: | ||
| 18497 | + round_sf r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/ | ||
| 18498 | + pack_sf r12 /*sf*/, r10 /*exp*/, r12 /*mant*/ | ||
| 18499 | +__floatunsisf_return_op1: | ||
| 18500 | + lsr r12,1 /* Sign bit is 0 for unsigned int */ | ||
| 18501 | + ret r12 | ||
| 18502 | +#endif | ||
| 18503 | + | ||
| 18504 | + | ||
| 18505 | +#ifdef L_avr32_f32_to_s32 | ||
| 18506 | + .global __avr32_f32_to_s32 | ||
| 18507 | + .type __avr32_f32_to_s32,@function | ||
| 18508 | +__avr32_f32_to_s32: | ||
| 18509 | + lsr r11,r12,23 /* Extract exponent */ | ||
| 18510 | + castu.b r11 | ||
| 18511 | + sub r11,127 /* Fix bias */ | ||
| 18512 | + retlo 0 /* Negative exponent yields zero integer */ | ||
| 18513 | + | ||
| 18514 | +#ifdef __IEEE_LARGE_FLOATS__ | ||
| 18515 | + cp r11,31 | ||
| 18516 | + brcc 0f | ||
| 18517 | +#endif | ||
| 18518 | + /* Shift mantissa into correct position */ | ||
| 18519 | + rsub r11,r11,31 /* Shift amount */ | ||
| 18520 | + lsl r10,r12,8 /* Get mantissa */ | ||
| 18521 | + sbr r10,31 /* Add implicit bit */ | ||
| 18522 | + lsr r10,r10,r11 /* Perform shift */ | ||
| 18523 | + lsl r12,1 /* Check sign */ | ||
| 18524 | + retcc r10 /* if positive, we are done */ | ||
| 18525 | + neg r10 /* if negative float, negate result */ | ||
| 18526 | + ret r10 | ||
| 18527 | + | ||
| 18528 | +#ifdef __IEEE_LARGE_FLOATS__ | ||
| 18529 | +0: | ||
| 18530 | + mov r11,-1 | ||
| 18531 | + lsr r11,1 | ||
| 18532 | + lsl r12,1 | ||
| 18533 | + acr r11 | ||
| 18534 | + | ||
| 18535 | + ret r11 | ||
| 18536 | +#endif | ||
| 18537 | +#endif | ||
| 18538 | + | ||
| 18539 | +#ifdef L_avr32_f32_to_u32 | ||
| 18540 | + .global __avr32_f32_to_u32 | ||
| 18541 | + .type __avr32_f32_to_u32,@function | ||
| 18542 | +__avr32_f32_to_u32: | ||
| 18543 | + cp r12,0 | ||
| 18544 | + retmi 0 /* Negative numbers gives 0 */ | ||
| 18545 | + bfextu r11, r12, 23, 8 /* Extract exponent */ | ||
| 18546 | + sub r11,127 /* Fix bias */ | ||
| 18547 | + retlo 0 /* Negative exponent yields zero integer */ | ||
| 18548 | + | ||
| 18549 | +#ifdef __IEEE_LARGE_FLOATS__ | ||
| 18550 | + cp r11,32 | ||
| 18551 | + brcc 0f | ||
| 18552 | +#endif | ||
| 18553 | + /* Shift mantissa into correct position */ | ||
| 18554 | + rsub r11,r11,31 /* Shift amount */ | ||
| 18555 | + lsl r12,8 /* Get mantissa */ | ||
| 18556 | + sbr r12,31 /* Add implicit bit */ | ||
| 18557 | + lsr r12,r12,r11 /* Perform shift */ | ||
| 18558 | + ret r12 | ||
| 18559 | + | ||
| 18560 | +#ifdef __IEEE_LARGE_FLOATS__ | ||
| 18561 | +0: | ||
| 18562 | + mov r11,-1 | ||
| 18563 | + lsr r11,1 | ||
| 18564 | + lsl r12,1 | ||
| 18565 | + acr r11 | ||
| 18566 | + | ||
| 18567 | + ret r11 | ||
| 18568 | +#endif | ||
| 18569 | +#endif | ||
| 18570 | + | ||
| 18571 | +#ifdef L_avr32_f32_to_f64 | ||
| 18572 | + .global __avr32_f32_to_f64 | ||
| 18573 | + .type __avr32_f32_to_f64,@function | ||
| 18574 | + | ||
| 18575 | +__avr32_f32_to_f64: | ||
| 18576 | + lsl r11,r12,1 /* Remove sign bit, keep original value in r12*/ | ||
| 18577 | + moveq r10, 0 | ||
| 18578 | + reteq r11 /* Return zero if input is zero */ | ||
| 18579 | + | ||
| 18580 | + bfextu r9,r11,24,8 /* Get exponent */ | ||
| 18581 | + cp.w r9,0xff /* check for NaN or inf */ | ||
| 18582 | + breq 0f | ||
| 18583 | + | ||
| 18584 | + lsl r11,7 /* Convert sf mantissa to df format */ | ||
| 18585 | + mov r10,0 | ||
| 18586 | + | ||
| 18587 | + /* Check if implicit bit should be set */ | ||
| 18588 | + cp.w r9, 0 | ||
| 18589 | + subeq r9,-1 /* Adjust exponent if it was 0 */ | ||
| 18590 | + srne r8 | ||
| 18591 | + or r11, r11, r8 << 31 /* Set implicit bit if needed */ | ||
| 18592 | + sub r9,(127-0x3ff) /* Convert exponent to df format exponent */ | ||
| 18593 | + | ||
| 18594 | + pushm lr | ||
| 18595 | + normalize_df r9 /*exp*/, r10, r11 /*mantissa*/, r8, lr /*scratch*/ | ||
| 18596 | + popm lr | ||
| 18597 | + pack_df r9 /*exp*/, r10, r11 /*mantissa*/, r10, r11 /*df*/ | ||
| 18598 | + | ||
| 18599 | +__extendsfdf_return_op1: | ||
| 18600 | + /* Rotate in sign bit */ | ||
| 18601 | + lsl r12, 1 | ||
| 18602 | + ror r11 | ||
| 18603 | + ret r11 | ||
| 18604 | + | ||
| 18605 | +0: | ||
| 18606 | + /* Inf or NaN*/ | ||
| 18607 | + lddpc r10, .Linf | ||
| 18608 | + lsl r11,8 /* check mantissa */ | ||
| 18609 | + movne r11, -1 /* Return NaN */ | ||
| 18610 | + moveq r11, r10 /* Return inf */ | ||
| 18611 | + rjmp __extendsfdf_return_op1 | ||
| 18612 | +#endif | ||
| 18613 | + | ||
| 18614 | + | ||
| 18615 | +#ifdef L_avr32_f64_to_f32 | ||
| 18616 | + .global __avr32_f64_to_f32 | ||
| 18617 | + .type __avr32_f64_to_f32,@function | ||
| 18618 | + | ||
| 18619 | +__avr32_f64_to_f32: | ||
| 18620 | + /* Unpack */ | ||
| 18621 | + lsl r9,r11,1 /* Unpack exponent */ | ||
| 18622 | + lsr r9,21 | ||
| 18623 | + | ||
| 18624 | + reteq 0 /* If exponent is 0 the number is so small | ||
| 18625 | + that the conversion to single float gives | ||
| 18626 | + zero */ | ||
| 18627 | + | ||
| 18628 | + lsl r8,r11,10 /* Adjust mantissa */ | ||
| 18629 | + or r12,r8,r10>>22 | ||
| 18630 | + | ||
| 18631 | + lsl r10,10 /* Check if there are any remaining bits | ||
| 18632 | + in the low part of the mantissa.*/ | ||
| 18633 | + neg r10 | ||
| 18634 | + rol r12 /* If there were remaining bits then set lsb | ||
| 18635 | + of mantissa to 1 */ | ||
| 18636 | + | ||
| 18637 | + cp r9,0x7ff | ||
| 18638 | + breq 2f /* Check for NaN or inf */ | ||
| 18639 | + | ||
| 18640 | + sub r9,(0x3ff-127) /* Adjust bias of exponent */ | ||
| 18641 | + sbr r12,31 /* set the implicit bit.*/ | ||
| 18642 | + | ||
| 18643 | + cp.w r9, 0 /* Check for subnormal number */ | ||
| 18644 | + brgt 0f | ||
| 18645 | + | ||
| 18646 | + /* Adjust a subnormal result */ | ||
| 18647 | + adjust_subnormal_sf r12/*sf*/,r9 /*exp*/, r12 /*mant*/, r11/*sign*/, r10 /*scratch*/ | ||
| 18648 | + ret r12 | ||
| 18649 | +0: | ||
| 18650 | + round_sf r9 /*exp*/, r12 /*mant*/, r10 /*scratch*/ | ||
| 18651 | + pack_sf r12 /*sf*/, r9 /*exp*/, r12 /*mant*/ | ||
| 18652 | +__truncdfsf_return_op1: | ||
| 18653 | + /* Rotate in sign bit */ | ||
| 18654 | + lsl r11, 1 | ||
| 18655 | + ror r12 | ||
| 18656 | + ret r12 | ||
| 18657 | + | ||
| 18658 | + | ||
| 18659 | +2: | ||
| 18660 | + /* NaN or inf */ | ||
| 18661 | + cbr r12,31 /* clear implicit bit */ | ||
| 18662 | + retne -1 /* Return NaN if mantissa not zero */ | ||
| 18663 | + lddpc r12,.Linf_sf | ||
| 18664 | + ret r12 /* Return inf */ | ||
| 18665 | +#endif | ||
| 18666 | + | ||
| 18667 | + | ||
| 18668 | + .align 2 | ||
| 18669 | +.Linf: | ||
| 18670 | + .long 0xffe00000 | ||
| 18671 | + | ||
| 18672 | + .align 2 | ||
| 18673 | +.Linf_sf: | ||
| 18674 | + .long 0xff000000 | ||
| 18675 | + | ||
| 18676 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/lib2funcs.S gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/lib2funcs.S | ||
| 18677 | --- gcc-4.0.2/gcc/config/avr32/lib2funcs.S 1970-01-01 01:00:00.000000000 +0100 | ||
| 18678 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/lib2funcs.S 2006-10-10 12:36:34.000000000 +0200 | ||
| 18679 | @@ -0,0 +1,21 @@ | ||
| 18680 | + .align 4 | ||
| 18681 | + .global __nonlocal_goto | ||
| 18682 | + .type __nonlocal_goto,@function | ||
| 18683 | + | ||
| 18684 | +/* __nonlocal_goto: This function handles nonlocal_goto's in gcc. | ||
| 18685 | + | ||
| 18686 | + parameter 0 (r12) = New Frame Pointer | ||
| 18687 | + parameter 1 (r11) = Address to goto | ||
| 18688 | + parameter 2 (r10) = New Stack Pointer | ||
| 18689 | + | ||
| 18690 | + This function invalidates the return stack, since it returns from a | ||
| 18691 | + function without using a return instruction. | ||
| 18692 | +*/ | ||
| 18693 | +__nonlocal_goto: | ||
| 18694 | + mov r7, r12 | ||
| 18695 | + mov sp, r10 | ||
| 18696 | + frs # Flush return stack | ||
| 18697 | + mov pc, r11 | ||
| 18698 | + | ||
| 18699 | + | ||
| 18700 | + | ||
| 18701 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/linux-elf.h gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/linux-elf.h | ||
| 18702 | --- gcc-4.0.2/gcc/config/avr32/linux-elf.h 1970-01-01 01:00:00.000000000 +0100 | ||
| 18703 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/linux-elf.h 2006-11-10 15:14:06.000000000 +0100 | ||
| 18704 | @@ -0,0 +1,154 @@ | ||
| 18705 | +/* | ||
| 18706 | + Linux/Elf specific definitions. | ||
| 18707 | + Copyright 2003-2006 Atmel Corporation. | ||
| 18708 | + | ||
| 18709 | + Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com> | ||
| 18710 | + and Håvard Skinnemoen, Atmel Norway, <hskinnemoen@atmel.com> | ||
| 18711 | + | ||
| 18712 | + This file is part of GCC. | ||
| 18713 | + | ||
| 18714 | + This program is free software; you can redistribute it and/or modify | ||
| 18715 | + it under the terms of the GNU General Public License as published by | ||
| 18716 | + the Free Software Foundation; either version 2 of the License, or | ||
| 18717 | + (at your option) any later version. | ||
| 18718 | + | ||
| 18719 | + This program is distributed in the hope that it will be useful, | ||
| 18720 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18721 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18722 | + GNU General Public License for more details. | ||
| 18723 | + | ||
| 18724 | + You should have received a copy of the GNU General Public License | ||
| 18725 | + along with this program; if not, write to the Free Software | ||
| 18726 | + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 18727 | + | ||
| 18728 | + | ||
| 18729 | + | ||
| 18730 | +/* elfos.h should have already been included. Now just override | ||
| 18731 | + any conflicting definitions and add any extras. */ | ||
| 18732 | + | ||
| 18733 | +/* Run-time Target Specification. */ | ||
| 18734 | +#undef TARGET_VERSION | ||
| 18735 | +#define TARGET_VERSION fputs (" (AVR32 GNU/Linux with ELF)", stderr); | ||
| 18736 | + | ||
| 18737 | +/* Do not assume anything about header files. */ | ||
| 18738 | +#define NO_IMPLICIT_EXTERN_C | ||
| 18739 | + | ||
| 18740 | +/* The GNU C++ standard library requires that these macros be defined. */ | ||
| 18741 | +#undef CPLUSPLUS_CPP_SPEC | ||
| 18742 | +#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)" | ||
| 18743 | + | ||
| 18744 | +/* Now we define the strings used to build the spec file. */ | ||
| 18745 | +#undef LIB_SPEC | ||
| 18746 | +#define LIB_SPEC \ | ||
| 18747 | + "%{pthread:-lpthread} \ | ||
| 18748 | + %{shared:-lc} \ | ||
| 18749 | + %{!shared:%{profile:-lc_p}%{!profile:-lc}}" | ||
| 18750 | + | ||
| 18751 | +/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add | ||
| 18752 | + the GNU/Linux magical crtbegin.o file (see crtstuff.c) which | ||
| 18753 | + provides part of the support for getting C++ file-scope static | ||
| 18754 | + object constructed before entering `main'. */ | ||
| 18755 | + | ||
| 18756 | +#undef STARTFILE_SPEC | ||
| 18757 | +#define STARTFILE_SPEC \ | ||
| 18758 | + "%{!shared: \ | ||
| 18759 | + %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \ | ||
| 18760 | + %{!p:%{profile:gcrt1.o%s} \ | ||
| 18761 | + %{!profile:crt1.o%s}}}} \ | ||
| 18762 | + crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}" | ||
| 18763 | + | ||
| 18764 | +/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on | ||
| 18765 | + the GNU/Linux magical crtend.o file (see crtstuff.c) which | ||
| 18766 | + provides part of the support for getting C++ file-scope static | ||
| 18767 | + object constructed before entering `main', followed by a normal | ||
| 18768 | + GNU/Linux "finalizer" file, `crtn.o'. */ | ||
| 18769 | + | ||
| 18770 | +#undef ENDFILE_SPEC | ||
| 18771 | +#define ENDFILE_SPEC \ | ||
| 18772 | + "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s" | ||
| 18773 | + | ||
| 18774 | +#undef ASM_SPEC | ||
| 18775 | +#define ASM_SPEC "%{!mno-pic:--pic} %{mrelax|O*:%{mno-relax|O0|O1: ;:--linkrelax}} %{mcpu=*:-mcpu=%*}" | ||
| 18776 | + | ||
| 18777 | +#undef LINK_SPEC | ||
| 18778 | +#define LINK_SPEC "%{version:-v} \ | ||
| 18779 | + %{static:-Bstatic} \ | ||
| 18780 | + %{shared:-shared} \ | ||
| 18781 | + %{symbolic:-Bsymbolic} \ | ||
| 18782 | + %{rdynamic:-export-dynamic} \ | ||
| 18783 | + %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0} \ | ||
| 18784 | + %{mrelax|O*:%{mno-relax|O0|O1: ;:--relax}}" | ||
| 18785 | + | ||
| 18786 | +#define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS() | ||
| 18787 | + | ||
| 18788 | +/* This is how we tell the assembler that two symbols have the same value. */ | ||
| 18789 | +#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \ | ||
| 18790 | + do \ | ||
| 18791 | + { \ | ||
| 18792 | + assemble_name (FILE, NAME1); \ | ||
| 18793 | + fputs (" = ", FILE); \ | ||
| 18794 | + assemble_name (FILE, NAME2); \ | ||
| 18795 | + fputc ('\n', FILE); \ | ||
| 18796 | + } \ | ||
| 18797 | + while (0) | ||
| 18798 | + | ||
| 18799 | + | ||
| 18800 | + | ||
| 18801 | +#undef CC1_SPEC | ||
| 18802 | +#define CC1_SPEC "%{profile:-p}" | ||
| 18803 | + | ||
| 18804 | +/* Target CPU builtins. */ | ||
| 18805 | +#define TARGET_CPU_CPP_BUILTINS() \ | ||
| 18806 | + do \ | ||
| 18807 | + { \ | ||
| 18808 | + builtin_define ("__avr32__"); \ | ||
| 18809 | + builtin_define ("__AVR32__"); \ | ||
| 18810 | + builtin_define ("__AVR32_LINUX__"); \ | ||
| 18811 | + builtin_define (avr32_part->macro); \ | ||
| 18812 | + builtin_define (avr32_arch->macro); \ | ||
| 18813 | + if (avr32_arch->uarch_type == UARCH_TYPE_AVR32A) \ | ||
| 18814 | + builtin_define ("__AVR32_AVR32A__"); \ | ||
| 18815 | + else \ | ||
| 18816 | + builtin_define ("__AVR32_AVR32B__"); \ | ||
| 18817 | + if (TARGET_UNALIGNED_WORD) \ | ||
| 18818 | + builtin_define ("__AVR32_HAS_UNALIGNED_WORD__"); \ | ||
| 18819 | + if (TARGET_SIMD) \ | ||
| 18820 | + builtin_define ("__AVR32_HAS_SIMD__"); \ | ||
| 18821 | + if (TARGET_DSP) \ | ||
| 18822 | + builtin_define ("__AVR32_HAS_DSP__"); \ | ||
| 18823 | + if (TARGET_RMW) \ | ||
| 18824 | + builtin_define ("__AVR32_HAS_RMW__"); \ | ||
| 18825 | + if (TARGET_BRANCH_PRED) \ | ||
| 18826 | + builtin_define ("__AVR32_HAS_BRANCH_PRED__"); \ | ||
| 18827 | + if (flag_pic) \ | ||
| 18828 | + { \ | ||
| 18829 | + builtin_define ("__PIC__"); \ | ||
| 18830 | + builtin_define ("__pic__"); \ | ||
| 18831 | + } \ | ||
| 18832 | + } \ | ||
| 18833 | + while (0) | ||
| 18834 | + | ||
| 18835 | + | ||
| 18836 | + | ||
| 18837 | +/* Call the function profiler with a given profile label. */ | ||
| 18838 | +#undef FUNCTION_PROFILER | ||
| 18839 | +#define FUNCTION_PROFILER(STREAM, LABELNO) \ | ||
| 18840 | + do \ | ||
| 18841 | + { \ | ||
| 18842 | + fprintf (STREAM, "\tmov\tlr, lo(mcount)\n\torh\tlr, hi(mcount)\n"); \ | ||
| 18843 | + fprintf (STREAM, "\ticall lr\n"); \ | ||
| 18844 | + } \ | ||
| 18845 | + while (0) | ||
| 18846 | + | ||
| 18847 | +#define NO_PROFILE_COUNTERS 1 | ||
| 18848 | + | ||
| 18849 | +/* For dynamic libraries to work */ | ||
| 18850 | +/* #define PLT_REG_CALL_CLOBBERED 1 */ | ||
| 18851 | +#define AVR32_ALWAYS_PIC 1 | ||
| 18852 | + | ||
| 18853 | +/* uclibc does not implement sinf, cosf etc. */ | ||
| 18854 | +#undef TARGET_C99_FUNCTIONS | ||
| 18855 | +#define TARGET_C99_FUNCTIONS 0 | ||
| 18856 | + | ||
| 18857 | +#define LINK_GCC_C_SEQUENCE_SPEC \ | ||
| 18858 | + "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" | ||
| 18859 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/predicates.md gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/predicates.md | ||
| 18860 | --- gcc-4.0.2/gcc/config/avr32/predicates.md 1970-01-01 01:00:00.000000000 +0100 | ||
| 18861 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/predicates.md 2006-11-09 15:01:19.000000000 +0100 | ||
| 18862 | @@ -0,0 +1,303 @@ | ||
| 18863 | +;; AVR32 predicates file. | ||
| 18864 | +;; Copyright 2003-2006 Atmel Corporation. | ||
| 18865 | +;; | ||
| 18866 | +;; Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com> | ||
| 18867 | +;; | ||
| 18868 | +;; This file is part of GCC. | ||
| 18869 | +;; | ||
| 18870 | +;; This program is free software; you can redistribute it and/or modify | ||
| 18871 | +;; it under the terms of the GNU General Public License as published by | ||
| 18872 | +;; the Free Software Foundation; either version 2 of the License, or | ||
| 18873 | +;; (at your option) any later version. | ||
| 18874 | +;; | ||
| 18875 | +;; This program is distributed in the hope that it will be useful, | ||
| 18876 | +;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18877 | +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18878 | +;; GNU General Public License for more details. | ||
| 18879 | +;; | ||
| 18880 | +;; You should have received a copy of the GNU General Public License | ||
| 18881 | +;; along with this program; if not, write to the Free Software | ||
| 18882 | +;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 18883 | + | ||
| 18884 | + | ||
| 18885 | +;; True if the operand is a memory reference which contains an | ||
| 18886 | +;; Address consisting of a single pointer register | ||
| 18887 | +(define_predicate "avr32_indirect_register_operand" | ||
| 18888 | + (and (match_code "mem") | ||
| 18889 | + (match_test "register_operand(XEXP(op, 0), SImode)"))) | ||
| 18890 | + | ||
| 18891 | + | ||
| 18892 | + | ||
| 18893 | +;; Address expression with a base pointer offset with | ||
| 18894 | +;; a register displacement | ||
| 18895 | +(define_predicate "avr32_indexed_memory_operand" | ||
| 18896 | + (and (match_code "mem") | ||
| 18897 | + (match_test "GET_CODE(XEXP(op, 0)) == PLUS")) | ||
| 18898 | + { | ||
| 18899 | + | ||
| 18900 | + rtx op0 = XEXP(XEXP(op, 0), 0); | ||
| 18901 | + rtx op1 = XEXP(XEXP(op, 0), 1); | ||
| 18902 | + | ||
| 18903 | + return ((avr32_address_register_rtx_p (op0, 0) | ||
| 18904 | + && avr32_legitimate_index_p (GET_MODE(op), op1, 0)) | ||
| 18905 | + || (avr32_address_register_rtx_p (op1, 0) | ||
| 18906 | + && avr32_legitimate_index_p (GET_MODE(op), op0, 0))); | ||
| 18907 | + | ||
| 18908 | + }) | ||
| 18909 | + | ||
| 18910 | +;; Operand suitable for the ld.sb instruction | ||
| 18911 | +(define_predicate "load_sb_memory_operand" | ||
| 18912 | + (ior (match_operand 0 "avr32_indirect_register_operand") | ||
| 18913 | + (match_operand 0 "avr32_indexed_memory_operand"))) | ||
| 18914 | + | ||
| 18915 | + | ||
| 18916 | +;; Operand suitable as operand to insns sign extending QI values | ||
| 18917 | +(define_predicate "extendqi_operand" | ||
| 18918 | + (ior (match_operand 0 "load_sb_memory_operand") | ||
| 18919 | + (match_operand 0 "register_operand"))) | ||
| 18920 | + | ||
| 18921 | +(define_predicate "post_inc_memory_operand" | ||
| 18922 | + (and (match_code "mem") | ||
| 18923 | + (match_test "(GET_CODE(XEXP(op, 0)) == POST_INC) | ||
| 18924 | + && REG_P(XEXP(XEXP(op, 0), 0))"))) | ||
| 18925 | + | ||
| 18926 | +;; Operand suitable for loading TImode values | ||
| 18927 | +(define_predicate "loadti_operand" | ||
| 18928 | + (ior (ior (match_operand 0 "register_operand") | ||
| 18929 | + (match_operand 0 "avr32_indirect_register_operand")) | ||
| 18930 | + (match_operand 0 "post_inc_memory_operand"))) | ||
| 18931 | + | ||
| 18932 | +;; Operand suitable for add instructions | ||
| 18933 | +(define_predicate "avr32_add_operand" | ||
| 18934 | + (ior (match_operand 0 "register_operand") | ||
| 18935 | + (and (match_operand 0 "immediate_operand") | ||
| 18936 | + (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'I', \"Is21\")")))) | ||
| 18937 | + | ||
| 18938 | +;; Operand is a power of two immediate | ||
| 18939 | +(define_predicate "power_of_two_operand" | ||
| 18940 | + (match_code "const_int") | ||
| 18941 | +{ | ||
| 18942 | + HOST_WIDE_INT value = INTVAL (op); | ||
| 18943 | + | ||
| 18944 | + return value != 0 && (value & (value - 1)) == 0; | ||
| 18945 | +}) | ||
| 18946 | + | ||
| 18947 | +;; Operand is a multiple of 8 immediate | ||
| 18948 | +(define_predicate "multiple_of_8_operand" | ||
| 18949 | + (match_code "const_int") | ||
| 18950 | +{ | ||
| 18951 | + HOST_WIDE_INT value = INTVAL (op); | ||
| 18952 | + | ||
| 18953 | + return (value & 0x7) == 0 ; | ||
| 18954 | +}) | ||
| 18955 | + | ||
| 18956 | +;; Operand is a multiple of 16 immediate | ||
| 18957 | +(define_predicate "multiple_of_16_operand" | ||
| 18958 | + (match_code "const_int") | ||
| 18959 | +{ | ||
| 18960 | + HOST_WIDE_INT value = INTVAL (op); | ||
| 18961 | + | ||
| 18962 | + return (value & 0xf) == 0 ; | ||
| 18963 | +}) | ||
| 18964 | + | ||
| 18965 | +;; Operand is a mask used for masking away upper bits of a reg | ||
| 18966 | +(define_predicate "avr32_mask_upper_bits_operand" | ||
| 18967 | + (match_code "const_int") | ||
| 18968 | +{ | ||
| 18969 | + HOST_WIDE_INT value = INTVAL (op) + 1; | ||
| 18970 | + | ||
| 18971 | + return value != 1 && value != 0 && (value & (value - 1)) == 0; | ||
| 18972 | +}) | ||
| 18973 | + | ||
| 18974 | + | ||
| 18975 | +;; Operand suitable for mul instructions | ||
| 18976 | +(define_predicate "avr32_mul_operand" | ||
| 18977 | + (ior (match_operand 0 "register_operand") | ||
| 18978 | + (and (match_operand 0 "immediate_operand") | ||
| 18979 | + (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ks08\")")))) | ||
| 18980 | + | ||
| 18981 | +;; True for logical binary operators. | ||
| 18982 | +(define_predicate "logical_binary_operator" | ||
| 18983 | + (match_code "ior,xor,and")) | ||
| 18984 | + | ||
| 18985 | +;; True for logical shift operators | ||
| 18986 | +(define_predicate "logical_shift_operator" | ||
| 18987 | + (match_code "ashift,lshiftrt")) | ||
| 18988 | + | ||
| 18989 | +;; True for shift operand for logical and, or and eor insns | ||
| 18990 | +(define_predicate "avr32_logical_shift_operand" | ||
| 18991 | + (and (match_code "ashift,lshiftrt") | ||
| 18992 | + (ior (and (match_test "GET_CODE(XEXP(op, 1)) == CONST_INT") | ||
| 18993 | + (match_test "register_operand(XEXP(op, 0), GET_MODE(XEXP(op, 0)))")) | ||
| 18994 | + (and (match_test "GET_CODE(XEXP(op, 0)) == CONST_INT") | ||
| 18995 | + (match_test "register_operand(XEXP(op, 1), GET_MODE(XEXP(op, 1)))")))) | ||
| 18996 | + { | ||
| 18997 | + return 1; | ||
| 18998 | + } | ||
| 18999 | + ) | ||
| 19000 | + | ||
| 19001 | + | ||
| 19002 | +;; Predicate for second operand to and, ior and xor insn patterns | ||
| 19003 | +(define_predicate "avr32_logical_insn_operand" | ||
| 19004 | + (ior (match_operand 0 "register_operand") | ||
| 19005 | + (match_operand 0 "avr32_logical_shift_operand")) | ||
| 19006 | + { | ||
| 19007 | + return 1; | ||
| 19008 | + } | ||
| 19009 | +) | ||
| 19010 | + | ||
| 19011 | + | ||
| 19012 | +;; True for avr32 comparison operators | ||
| 19013 | +(define_predicate "avr32_comparison_operator" | ||
| 19014 | + (ior (match_code "eq, ne, gt, ge, lt, le, gtu, geu, ltu, leu") | ||
| 19015 | + (and (match_code "unspec") | ||
| 19016 | + (match_test "(XINT(op, 1) == UNSPEC_COND_MI) | ||
| 19017 | + || (XINT(op, 1) == UNSPEC_COND_PL)")))) | ||
| 19018 | + | ||
| 19019 | +;; True if this is a const_int with one bit set | ||
| 19020 | +(define_predicate "one_bit_set_operand" | ||
| 19021 | + (match_code "const_int") | ||
| 19022 | + { | ||
| 19023 | + int i; | ||
| 19024 | + int value; | ||
| 19025 | + int ones = 0; | ||
| 19026 | + | ||
| 19027 | + value = INTVAL(op); | ||
| 19028 | + for ( i = 0 ; i < 32; i++ ){ | ||
| 19029 | + if ( value & ( 1 << i ) ){ | ||
| 19030 | + ones++; | ||
| 19031 | + } | ||
| 19032 | + } | ||
| 19033 | + | ||
| 19034 | + return ( ones == 1 ); | ||
| 19035 | + }) | ||
| 19036 | + | ||
| 19037 | + | ||
| 19038 | +;; True if this is a const_int with one bit cleared | ||
| 19039 | +(define_predicate "one_bit_cleared_operand" | ||
| 19040 | + (match_code "const_int") | ||
| 19041 | + { | ||
| 19042 | + int i; | ||
| 19043 | + int value; | ||
| 19044 | + int zeroes = 0; | ||
| 19045 | + | ||
| 19046 | + value = INTVAL(op); | ||
| 19047 | + for ( i = 0 ; i < 32; i++ ){ | ||
| 19048 | + if ( !(value & ( 1 << i )) ){ | ||
| 19049 | + zeroes++; | ||
| 19050 | + } | ||
| 19051 | + } | ||
| 19052 | + | ||
| 19053 | + return ( zeroes == 1 ); | ||
| 19054 | + }) | ||
| 19055 | + | ||
| 19056 | + | ||
| 19057 | +;; True if this is a register or immediate operand | ||
| 19058 | +(define_predicate "register_immediate_operand" | ||
| 19059 | + (ior (match_operand 0 "register_operand") | ||
| 19060 | + (match_operand 0 "immediate_operand"))) | ||
| 19061 | + | ||
| 19062 | + | ||
| 19063 | +;; True is this is an operand containing a label_ref | ||
| 19064 | +(define_predicate "avr32_label_ref_operand" | ||
| 19065 | + (and (match_code "mem") | ||
| 19066 | + (match_test "avr32_find_symbol(op) | ||
| 19067 | + && (GET_CODE(avr32_find_symbol(op)) == LABEL_REF)"))) | ||
| 19068 | + | ||
| 19069 | +;; True is this is a valid symbol pointing to the constant pool | ||
| 19070 | +(define_predicate "avr32_const_pool_operand" | ||
| 19071 | + (and (match_code "symbol_ref") | ||
| 19072 | + (match_test "CONSTANT_POOL_ADDRESS_P(op)")) | ||
| 19073 | + { | ||
| 19074 | + return (flag_pic ? (!(symbol_mentioned_p (get_pool_constant (op)) | ||
| 19075 | + || label_mentioned_p (get_pool_constant (op))) | ||
| 19076 | + || avr32_got_mentioned_p(get_pool_constant (op))) | ||
| 19077 | + : true); | ||
| 19078 | + } | ||
| 19079 | +) | ||
| 19080 | + | ||
| 19081 | +;; True is this is a memory reference to the constant or mini pool | ||
| 19082 | +(define_predicate "avr32_const_pool_ref_operand" | ||
| 19083 | + (ior (match_operand 0 "avr32_label_ref_operand") | ||
| 19084 | + (and (match_code "mem") | ||
| 19085 | + (match_test "avr32_const_pool_operand(XEXP(op,0), GET_MODE(XEXP(op,0)))")))) | ||
| 19086 | + | ||
| 19087 | + | ||
| 19088 | + | ||
| 19089 | +;; True is this is a k12 offseted memory operand | ||
| 19090 | +(define_predicate "avr32_k12_memory_operand" | ||
| 19091 | + (and (match_code "mem") | ||
| 19092 | + (ior (match_test "REG_P(XEXP(op, 0))") | ||
| 19093 | + (match_test "GET_CODE(XEXP(op, 0)) == PLUS | ||
| 19094 | + && REG_P(XEXP(XEXP(op, 0), 0)) | ||
| 19095 | + && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT) | ||
| 19096 | + && (CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(XEXP(op, 0), 0)), | ||
| 19097 | + 'K', (mode == SImode) ? \"Ks14\" : ((mode == HImode) ? \"Ks13\" : \"Ks12\")))")))) | ||
| 19098 | + | ||
| 19099 | +;; True is this is a memory operand with an immediate displacement | ||
| 19100 | +(define_predicate "avr32_imm_disp_memory_operand" | ||
| 19101 | + (and (match_code "mem") | ||
| 19102 | + (match_test "GET_CODE(XEXP(op, 0)) == PLUS | ||
| 19103 | + && REG_P(XEXP(XEXP(op, 0), 0)) | ||
| 19104 | + && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT)"))) | ||
| 19105 | + | ||
| 19106 | +;; True is this is a bswap operand | ||
| 19107 | +(define_predicate "avr32_bswap_operand" | ||
| 19108 | + (ior (match_operand 0 "avr32_k12_memory_operand") | ||
| 19109 | + (match_operand 0 "register_operand"))) | ||
| 19110 | + | ||
| 19111 | +;; True is this is a valid coprocessor insn memory operand | ||
| 19112 | +(define_predicate "avr32_cop_memory_operand" | ||
| 19113 | + (and (match_operand 0 "memory_operand") | ||
| 19114 | + (not (match_test "GET_CODE(XEXP(op, 0)) == PLUS | ||
| 19115 | + && REG_P(XEXP(XEXP(op, 0), 0)) | ||
| 19116 | + && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT) | ||
| 19117 | + && !(CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(XEXP(op, 0), 0)), 'K', \"Ku10\"))")))) | ||
| 19118 | + | ||
| 19119 | +;; True is this is a valid source/destination operand | ||
| 19120 | +;; for moving values to/from a coprocessor | ||
| 19121 | +(define_predicate "avr32_cop_move_operand" | ||
| 19122 | + (ior (match_operand 0 "register_operand") | ||
| 19123 | + (match_operand 0 "avr32_cop_memory_operand"))) | ||
| 19124 | + | ||
| 19125 | + | ||
| 19126 | +;; True is this is a valid extract byte offset for use in | ||
| 19127 | +;; load extracted index insns | ||
| 19128 | +(define_predicate "avr32_extract_shift_operand" | ||
| 19129 | + (and (match_operand 0 "const_int_operand") | ||
| 19130 | + (match_test "(INTVAL(op) == 0) || (INTVAL(op) == 8) | ||
| 19131 | + || (INTVAL(op) == 16) || (INTVAL(op) == 24)"))) | ||
| 19132 | + | ||
| 19133 | +;; True is this is a floating-point register | ||
| 19134 | +(define_predicate "avr32_fp_register_operand" | ||
| 19135 | + (and (match_operand 0 "register_operand") | ||
| 19136 | + (match_test "REGNO_REG_CLASS(REGNO(op)) == FP_REGS"))) | ||
| 19137 | + | ||
| 19138 | +;; True is this is valid avr32 symbol operand | ||
| 19139 | +(define_predicate "avr32_symbol_operand" | ||
| 19140 | + (ior (match_code "label_ref, symbol_ref") | ||
| 19141 | + (and (match_code "const") | ||
| 19142 | + (match_test "avr32_find_symbol(op)")))) | ||
| 19143 | + | ||
| 19144 | +;; True is this is valid operand for the lda.w and call pseudo insns | ||
| 19145 | +(define_predicate "avr32_address_operand" | ||
| 19146 | + (and (match_code "label_ref, symbol_ref") | ||
| 19147 | + (ior (match_test "TARGET_HAS_ASM_ADDR_PSEUDOS") | ||
| 19148 | + (match_test "flag_pic")) )) | ||
| 19149 | + | ||
| 19150 | +;; True if this is a avr32 call operand | ||
| 19151 | +(define_predicate "avr32_call_operand" | ||
| 19152 | + (ior (ior (match_operand 0 "register_operand") | ||
| 19153 | + (ior (match_operand 0 "avr32_const_pool_ref_operand") | ||
| 19154 | + (match_operand 0 "avr32_address_operand"))) | ||
| 19155 | + (match_test "SYMBOL_REF_RCALL_FUNCTION_P(op)"))) | ||
| 19156 | + | ||
| 19157 | +;; Return true for operators performing ALU operations | ||
| 19158 | + | ||
| 19159 | +(define_predicate "alu_operator" | ||
| 19160 | + (match_code "ior, xor, and, plus, minus, ashift, lshiftrt, ashiftrt")) | ||
| 19161 | + | ||
| 19162 | +(define_predicate "avr32_add_shift_immediate_operand" | ||
| 19163 | + (and (match_operand 0 "immediate_operand") | ||
| 19164 | + (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ku02\")"))) | ||
| 19165 | + | ||
| 19166 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/simd.md gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/simd.md | ||
| 19167 | --- gcc-4.0.2/gcc/config/avr32/simd.md 1970-01-01 01:00:00.000000000 +0100 | ||
| 19168 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/simd.md 2006-10-10 12:36:34.000000000 +0200 | ||
| 19169 | @@ -0,0 +1,145 @@ | ||
| 19170 | +;; AVR32 machine description file for SIMD instructions. | ||
| 19171 | +;; Copyright 2003-2006 Atmel Corporation. | ||
| 19172 | +;; | ||
| 19173 | +;; Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com> | ||
| 19174 | +;; | ||
| 19175 | +;; This file is part of GCC. | ||
| 19176 | +;; | ||
| 19177 | +;; This program is free software; you can redistribute it and/or modify | ||
| 19178 | +;; it under the terms of the GNU General Public License as published by | ||
| 19179 | +;; the Free Software Foundation; either version 2 of the License, or | ||
| 19180 | +;; (at your option) any later version. | ||
| 19181 | +;; | ||
| 19182 | +;; This program is distributed in the hope that it will be useful, | ||
| 19183 | +;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19184 | +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19185 | +;; GNU General Public License for more details. | ||
| 19186 | +;; | ||
| 19187 | +;; You should have received a copy of the GNU General Public License | ||
| 19188 | +;; along with this program; if not, write to the Free Software | ||
| 19189 | +;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 19190 | + | ||
| 19191 | +;; -*- Mode: Scheme -*- | ||
| 19192 | + | ||
| 19193 | + | ||
| 19194 | +;; Vector modes | ||
| 19195 | +(define_mode_macro VECM [V2HI V4QI]) | ||
| 19196 | +(define_mode_attr size [(V2HI "h") (V4QI "b")]) | ||
| 19197 | + | ||
| 19198 | +(define_insn "add<mode>3" | ||
| 19199 | + [(set (match_operand:VECM 0 "register_operand" "=r") | ||
| 19200 | + (plus:VECM (match_operand:VECM 1 "register_operand" "r") | ||
| 19201 | + (match_operand:VECM 2 "register_operand" "r")))] | ||
| 19202 | + "TARGET_SIMD" | ||
| 19203 | + "padd.<size>\t%0, %1, %2" | ||
| 19204 | + [(set_attr "length" "4") | ||
| 19205 | + (set_attr "type" "alu")]) | ||
| 19206 | + | ||
| 19207 | + | ||
| 19208 | +(define_insn "sub<mode>3" | ||
| 19209 | + [(set (match_operand:VECM 0 "register_operand" "=r") | ||
| 19210 | + (minus:VECM (match_operand:VECM 1 "register_operand" "r") | ||
| 19211 | + (match_operand:VECM 2 "register_operand" "r")))] | ||
| 19212 | + "TARGET_SIMD" | ||
| 19213 | + "psub.<size>\t%0, %1, %2" | ||
| 19214 | + [(set_attr "length" "4") | ||
| 19215 | + (set_attr "type" "alu")]) | ||
| 19216 | + | ||
| 19217 | + | ||
| 19218 | +(define_insn "abs<mode>2" | ||
| 19219 | + [(set (match_operand:VECM 0 "register_operand" "=r") | ||
| 19220 | + (abs:VECM (match_operand:VECM 1 "register_operand" "r")))] | ||
| 19221 | + "TARGET_SIMD" | ||
| 19222 | + "pabs.s<size>\t%0, %1" | ||
| 19223 | + [(set_attr "length" "4") | ||
| 19224 | + (set_attr "type" "alu")]) | ||
| 19225 | + | ||
| 19226 | +(define_insn "ashl<mode>3" | ||
| 19227 | + [(set (match_operand:VECM 0 "register_operand" "=r") | ||
| 19228 | + (ashift:VECM (match_operand:VECM 1 "register_operand" "r") | ||
| 19229 | + (match_operand:SI 2 "immediate_operand" "Ku04")))] | ||
| 19230 | + "TARGET_SIMD" | ||
| 19231 | + "plsl.<size>\t%0, %1, %2" | ||
| 19232 | + [(set_attr "length" "4") | ||
| 19233 | + (set_attr "type" "alu")]) | ||
| 19234 | + | ||
| 19235 | +(define_insn "ashr<mode>3" | ||
| 19236 | + [(set (match_operand:VECM 0 "register_operand" "=r") | ||
| 19237 | + (ashiftrt:VECM (match_operand:VECM 1 "register_operand" "r") | ||
| 19238 | + (match_operand:SI 2 "immediate_operand" "Ku04")))] | ||
| 19239 | + "TARGET_SIMD" | ||
| 19240 | + "pasr.<size>\t%0, %1, %2" | ||
| 19241 | + [(set_attr "length" "4") | ||
| 19242 | + (set_attr "type" "alu")]) | ||
| 19243 | + | ||
| 19244 | +(define_insn "lshr<mode>3" | ||
| 19245 | + [(set (match_operand:VECM 0 "register_operand" "=r") | ||
| 19246 | + (lshiftrt:VECM (match_operand:VECM 1 "register_operand" "r") | ||
| 19247 | + (match_operand:SI 2 "immediate_operand" "Ku04")))] | ||
| 19248 | + "TARGET_SIMD" | ||
| 19249 | + "plsr.<size>\t%0, %1, %2" | ||
| 19250 | + [(set_attr "length" "4") | ||
| 19251 | + (set_attr "type" "alu")]) | ||
| 19252 | + | ||
| 19253 | +(define_insn "smaxv2hi3" | ||
| 19254 | + [(set (match_operand:V2HI 0 "register_operand" "=r") | ||
| 19255 | + (smax:V2HI (match_operand:V2HI 1 "register_operand" "r") | ||
| 19256 | + (match_operand:V2HI 2 "register_operand" "r")))] | ||
| 19257 | + | ||
| 19258 | + "TARGET_SIMD" | ||
| 19259 | + "pmax.sh\t%0, %1, %2" | ||
| 19260 | + [(set_attr "length" "4") | ||
| 19261 | + (set_attr "type" "alu")]) | ||
| 19262 | + | ||
| 19263 | +(define_insn "sminv2hi3" | ||
| 19264 | + [(set (match_operand:V2HI 0 "register_operand" "=r") | ||
| 19265 | + (smin:V2HI (match_operand:V2HI 1 "register_operand" "r") | ||
| 19266 | + (match_operand:V2HI 2 "register_operand" "r")))] | ||
| 19267 | + | ||
| 19268 | + "TARGET_SIMD" | ||
| 19269 | + "pmin.sh\t%0, %1, %2" | ||
| 19270 | + [(set_attr "length" "4") | ||
| 19271 | + (set_attr "type" "alu")]) | ||
| 19272 | + | ||
| 19273 | +(define_insn "umaxv4qi3" | ||
| 19274 | + [(set (match_operand:V4QI 0 "register_operand" "=r") | ||
| 19275 | + (umax:V4QI (match_operand:V4QI 1 "register_operand" "r") | ||
| 19276 | + (match_operand:V4QI 2 "register_operand" "r")))] | ||
| 19277 | + | ||
| 19278 | + "TARGET_SIMD" | ||
| 19279 | + "pmax.ub\t%0, %1, %2" | ||
| 19280 | + [(set_attr "length" "4") | ||
| 19281 | + (set_attr "type" "alu")]) | ||
| 19282 | + | ||
| 19283 | +(define_insn "uminv4qi3" | ||
| 19284 | + [(set (match_operand:V4QI 0 "register_operand" "=r") | ||
| 19285 | + (umin:V4QI (match_operand:V4QI 1 "register_operand" "r") | ||
| 19286 | + (match_operand:V4QI 2 "register_operand" "r")))] | ||
| 19287 | + | ||
| 19288 | + "TARGET_SIMD" | ||
| 19289 | + "pmin.ub\t%0, %1, %2" | ||
| 19290 | + [(set_attr "length" "4") | ||
| 19291 | + (set_attr "type" "alu")]) | ||
| 19292 | + | ||
| 19293 | + | ||
| 19294 | +(define_insn "addsubv2hi" | ||
| 19295 | + [(set (match_operand:V2HI 0 "register_operand" "=r") | ||
| 19296 | + (vec_concat:V2HI | ||
| 19297 | + (plus:HI (match_operand:HI 1 "register_operand" "r") | ||
| 19298 | + (match_operand:HI 2 "register_operand" "r")) | ||
| 19299 | + (minus:HI (match_dup 1) (match_dup 2))))] | ||
| 19300 | + "TARGET_SIMD" | ||
| 19301 | + "paddsub.h\t%0, %1:b, %2:b" | ||
| 19302 | + [(set_attr "length" "4") | ||
| 19303 | + (set_attr "type" "alu")]) | ||
| 19304 | + | ||
| 19305 | +(define_insn "subaddv2hi" | ||
| 19306 | + [(set (match_operand:V2HI 0 "register_operand" "=r") | ||
| 19307 | + (vec_concat:V2HI | ||
| 19308 | + (minus:HI (match_operand:HI 1 "register_operand" "r") | ||
| 19309 | + (match_operand:HI 2 "register_operand" "r")) | ||
| 19310 | + (plus:HI (match_dup 1) (match_dup 2))))] | ||
| 19311 | + "TARGET_SIMD" | ||
| 19312 | + "psubadd.h\t%0, %1:b, %2:b" | ||
| 19313 | + [(set_attr "length" "4") | ||
| 19314 | + (set_attr "type" "alu")]) | ||
| 19315 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/t-avr32 gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/t-avr32 | ||
| 19316 | --- gcc-4.0.2/gcc/config/avr32/t-avr32 1970-01-01 01:00:00.000000000 +0100 | ||
| 19317 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/t-avr32 2006-11-24 17:10:48.000000000 +0100 | ||
| 19318 | @@ -0,0 +1,63 @@ | ||
| 19319 | + | ||
| 19320 | +MD_INCLUDES= $(srcdir)/config/avr32/avr32.md \ | ||
| 19321 | + $(srcdir)/config/avr32/fpcp.md \ | ||
| 19322 | + $(srcdir)/config/avr32/simd.md \ | ||
| 19323 | + $(srcdir)/config/avr32/predicates.md | ||
| 19324 | + | ||
| 19325 | +s-config s-conditions s-flags s-codes s-constants s-emit s-recog s-preds \ | ||
| 19326 | + s-opinit s-extract s-peep s-attr s-attrtab s-output: $(MD_INCLUDES) | ||
| 19327 | + | ||
| 19328 | +# We want fine grained libraries, so use the new code | ||
| 19329 | +# to build the floating point emulation libraries. | ||
| 19330 | +FPBIT = fp-bit.c | ||
| 19331 | +DPBIT = dp-bit.c | ||
| 19332 | + | ||
| 19333 | +LIB1ASMSRC = avr32/lib1funcs.S | ||
| 19334 | +LIB1ASMFUNCS = _avr32_f64_mul _avr32_f64_addsub _avr32_f64_to_u32 _avr32_f64_to_s32 \ | ||
| 19335 | + _avr32_f64_to_u64 _avr32_f64_to_s64 _avr32_u32_to_f64 _avr32_s32_to_f64 \ | ||
| 19336 | + _avr32_f64_cmp_eq _avr32_f64_cmp_ge _avr32_f64_cmp_lt \ | ||
| 19337 | + _avr32_f32_cmp_eq _avr32_f32_cmp_ge _avr32_f32_cmp_lt \ | ||
| 19338 | + _avr32_f64_div _avr32_f32_div\ | ||
| 19339 | + _avr32_f32_mul _avr32_s32_to_f32 _avr32_u32_to_f32 _avr32_f32_to_s32 \ | ||
| 19340 | + _avr32_f32_to_u32 _avr32_f32_to_f64 _avr32_f64_to_f32 | ||
| 19341 | + | ||
| 19342 | +LIB2FUNCS_EXTRA += $(srcdir)/config/avr32/lib2funcs.S | ||
| 19343 | + | ||
| 19344 | +MULTILIB_OPTIONS = march=ap/march=uc | ||
| 19345 | +MULTILIB_DIRNAMES = ap uc | ||
| 19346 | +MULTILIB_EXCEPTIONS = | ||
| 19347 | +MULTILIB_MATCHES = march?ap=mcpu?ap7000 | ||
| 19348 | +MULTILIB_MATCHES += march?ap=mcpu?ap7010 | ||
| 19349 | +MULTILIB_MATCHES += march?ap=mcpu?ap7020 | ||
| 19350 | +MULTILIB_MATCHES += march?uc=mcpu?uc3a0256 | ||
| 19351 | +MULTILIB_MATCHES += march?uc=mcpu?uc3a0512 | ||
| 19352 | +MULTILIB_MATCHES += march?uc=mcpu?uc3a1128 | ||
| 19353 | +MULTILIB_MATCHES += march?uc=mcpu?uc3a1256 | ||
| 19354 | +MULTILIB_MATCHES += march?uc=mcpu?uc3a1512 | ||
| 19355 | +MULTILIB_MATCHES += march?ap=mpart?ap7000 | ||
| 19356 | +MULTILIB_MATCHES += march?ap=mpart?ap7010 | ||
| 19357 | +MULTILIB_MATCHES += march?ap=mpart?ap7020 | ||
| 19358 | +MULTILIB_MATCHES += march?uc=mpart?uc3a0256 | ||
| 19359 | +MULTILIB_MATCHES += march?uc=mpart?uc3a0512 | ||
| 19360 | +MULTILIB_MATCHES += march?uc=mpart?uc3a1128 | ||
| 19361 | +MULTILIB_MATCHES += march?uc=mpart?uc3a1256 | ||
| 19362 | +MULTILIB_MATCHES += march?uc=mpart?uc3a1512 | ||
| 19363 | + | ||
| 19364 | +EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o crti.o crtn.o | ||
| 19365 | + | ||
| 19366 | +CRTSTUFF_T_CFLAGS = -mrelax | ||
| 19367 | +CRTSTUFF_T_CFLAGS_S = -mrelax -fPIC | ||
| 19368 | +TARGET_LIBGCC2_CFLAGS += -mrelax | ||
| 19369 | + | ||
| 19370 | +LIBGCC = stmp-multilib | ||
| 19371 | +INSTALL_LIBGCC = install-multilib | ||
| 19372 | + | ||
| 19373 | +fp-bit.c: $(srcdir)/config/fp-bit.c | ||
| 19374 | + echo '#define FLOAT' > fp-bit.c | ||
| 19375 | + cat $(srcdir)/config/fp-bit.c >> fp-bit.c | ||
| 19376 | + | ||
| 19377 | +dp-bit.c: $(srcdir)/config/fp-bit.c | ||
| 19378 | + cat $(srcdir)/config/fp-bit.c > dp-bit.c | ||
| 19379 | + | ||
| 19380 | + | ||
| 19381 | + | ||
| 19382 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/t-elf gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/t-elf | ||
| 19383 | --- gcc-4.0.2/gcc/config/avr32/t-elf 1970-01-01 01:00:00.000000000 +0100 | ||
| 19384 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/t-elf 2006-03-20 13:59:57.000000000 +0100 | ||
| 19385 | @@ -0,0 +1,16 @@ | ||
| 19386 | + | ||
| 19387 | +# Assemble startup files. | ||
| 19388 | +$(T)crti.o: $(srcdir)/config/avr32/crti.asm $(GCC_PASSES) | ||
| 19389 | + $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) $(INCLUDES) \ | ||
| 19390 | + -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/avr32/crti.asm | ||
| 19391 | + | ||
| 19392 | +$(T)crtn.o: $(srcdir)/config/avr32/crtn.asm $(GCC_PASSES) | ||
| 19393 | + $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) $(INCLUDES) \ | ||
| 19394 | + -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/avr32/crtn.asm | ||
| 19395 | + | ||
| 19396 | + | ||
| 19397 | +# Build the libraries for both hard and soft floating point | ||
| 19398 | +EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o crti.o crtn.o | ||
| 19399 | + | ||
| 19400 | +LIBGCC = stmp-multilib | ||
| 19401 | +INSTALL_LIBGCC = install-multilib | ||
| 19402 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/avr32/uclinux-elf.h gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/uclinux-elf.h | ||
| 19403 | --- gcc-4.0.2/gcc/config/avr32/uclinux-elf.h 1970-01-01 01:00:00.000000000 +0100 | ||
| 19404 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/avr32/uclinux-elf.h 2006-01-04 10:57:09.000000000 +0100 | ||
| 19405 | @@ -0,0 +1,20 @@ | ||
| 19406 | + | ||
| 19407 | +/* Run-time Target Specification. */ | ||
| 19408 | +#undef TARGET_VERSION | ||
| 19409 | +#define TARGET_VERSION fputs (" (AVR32 uClinux with ELF)", stderr) | ||
| 19410 | + | ||
| 19411 | +/* We don't want a .jcr section on uClinux. As if this makes a difference... */ | ||
| 19412 | +#define TARGET_USE_JCR_SECTION 0 | ||
| 19413 | + | ||
| 19414 | +/* Here we go. Drop the crtbegin/crtend stuff completely. */ | ||
| 19415 | +#undef STARTFILE_SPEC | ||
| 19416 | +#define STARTFILE_SPEC \ | ||
| 19417 | + "%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s}" \ | ||
| 19418 | + " %{!p:%{profile:gcrt1.o%s}" \ | ||
| 19419 | + " %{!profile:crt1.o%s}}}} crti.o%s" | ||
| 19420 | + | ||
| 19421 | +#undef ENDFILE_SPEC | ||
| 19422 | +#define ENDFILE_SPEC "crtn.o%s" | ||
| 19423 | + | ||
| 19424 | +#undef TARGET_DEFAULT | ||
| 19425 | +#define TARGET_DEFAULT (AVR32_FLAG_NO_INIT_GOT) | ||
| 19426 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config/host-linux.c gcc-4.0.2-atmel.0.99.2/gcc/config/host-linux.c | ||
| 19427 | --- gcc-4.0.2/gcc/config/host-linux.c 2005-08-01 20:00:10.000000000 +0200 | ||
| 19428 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config/host-linux.c 2006-03-23 13:33:12.000000000 +0100 | ||
| 19429 | @@ -26,6 +26,9 @@ | ||
| 19430 | #include "hosthooks.h" | ||
| 19431 | #include "hosthooks-def.h" | ||
| 19432 | |||
| 19433 | +#ifndef SSIZE_MAX | ||
| 19434 | +#define SSIZE_MAX LONG_MAX | ||
| 19435 | +#endif | ||
| 19436 | |||
| 19437 | /* Linux has a feature called exec-shield-randomize that perturbs the | ||
| 19438 | address of non-fixed mapped segments by a (relatively) small amount. | ||
| 19439 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/config.gcc gcc-4.0.2-atmel.0.99.2/gcc/config.gcc | ||
| 19440 | --- gcc-4.0.2/gcc/config.gcc 2005-08-09 12:57:04.000000000 +0200 | ||
| 19441 | +++ gcc-4.0.2-atmel.0.99.2/gcc/config.gcc 2006-02-08 17:33:56.000000000 +0100 | ||
| 19442 | @@ -189,9 +189,6 @@ case ${target} in | ||
| 19443 | | ip2k-*-elf \ | ||
| 19444 | | ns32k-*-netbsdelf* \ | ||
| 19445 | | ns32k-*-netbsd* \ | ||
| 19446 | - | c4x-* \ | ||
| 19447 | - | tic4x-* \ | ||
| 19448 | - | hppa1.1-*-rtems* \ | ||
| 19449 | ) | ||
| 19450 | if test "x$enable_obsolete" != xyes; then | ||
| 19451 | echo "*** Configuration ${target} is obsolete." >&2 | ||
| 19452 | @@ -251,9 +248,6 @@ arm*-*-*) | ||
| 19453 | cpu_type=arm | ||
| 19454 | extra_headers="mmintrin.h" | ||
| 19455 | ;; | ||
| 19456 | -bfin*-*) | ||
| 19457 | - cpu_type=bfin | ||
| 19458 | - ;; | ||
| 19459 | ep9312*-*-*) | ||
| 19460 | cpu_type=arm | ||
| 19461 | ;; | ||
| 19462 | @@ -735,6 +729,24 @@ avr-*-*) | ||
| 19463 | tm_file="avr/avr.h dbxelf.h" | ||
| 19464 | use_fixproto=yes | ||
| 19465 | ;; | ||
| 19466 | +avr32*-*-linux*) | ||
| 19467 | + tm_file="dbxelf.h elfos.h linux.h avr32/linux-elf.h avr32/avr32.h " | ||
| 19468 | + tmake_file="t-linux avr32/t-avr32 avr32/t-elf" | ||
| 19469 | + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" | ||
| 19470 | + extra_modes=avr32/avr32-modes.def | ||
| 19471 | + gnu_ld=yes | ||
| 19472 | + ;; | ||
| 19473 | +avr32*-*-uclinux*) | ||
| 19474 | + tm_file="dbxelf.h elfos.h linux.h avr32/linux-elf.h avr32/uclinux-elf.h avr32/avr32.h" | ||
| 19475 | + tmake_file="t-linux avr32/t-avr32 avr32/t-elf" | ||
| 19476 | + extra_modes=avr32/avr32-modes.def | ||
| 19477 | + gnu_ld=yes | ||
| 19478 | + ;; | ||
| 19479 | +avr32-*-*) | ||
| 19480 | + tm_file="dbxelf.h elfos.h avr32/avr32.h avr32/avr32-elf.h" | ||
| 19481 | + tmake_file="avr32/t-avr32 avr32/t-elf" | ||
| 19482 | + extra_modes=avr32/avr32-modes.def | ||
| 19483 | + ;; | ||
| 19484 | bfin*-elf*) | ||
| 19485 | tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h" | ||
| 19486 | tmake_file=bfin/t-bfin-elf | ||
| 19487 | @@ -792,14 +804,10 @@ frv-*-*linux*) | ||
| 19488 | linux.h frv/linux.h frv/frv-abi.h" | ||
| 19489 | tmake_file="${tmake_file} frv/t-frv frv/t-linux" | ||
| 19490 | ;; | ||
| 19491 | -h8300-*-rtemscoff*) | ||
| 19492 | +h8300-*-rtems*) | ||
| 19493 | tmake_file="h8300/t-h8300 t-rtems h8300/t-rtems" | ||
| 19494 | tm_file="h8300/h8300.h dbxcoff.h h8300/coff.h h8300/rtems.h rtems.h" | ||
| 19495 | ;; | ||
| 19496 | -h8300-*-rtems*) | ||
| 19497 | - tmake_file="h8300/t-h8300 h8300/t-elf t-rtems h8300/t-rtems" | ||
| 19498 | - tm_file="h8300/h8300.h dbxelf.h elfos.h h8300/elf.h h8300/rtems.h rtems.h" | ||
| 19499 | - ;; | ||
| 19500 | h8300-*-elf*) | ||
| 19501 | tmake_file="h8300/t-h8300 h8300/t-elf" | ||
| 19502 | tm_file="h8300/h8300.h dbxelf.h elfos.h h8300/elf.h" | ||
| 19503 | @@ -1560,6 +1568,9 @@ pdp11-*-bsd) | ||
| 19504 | pdp11-*-*) | ||
| 19505 | use_fixproto=yes | ||
| 19506 | ;; | ||
| 19507 | +avr-*-*) | ||
| 19508 | + use_fixproto=yes | ||
| 19509 | + ;; | ||
| 19510 | # port not yet contributed | ||
| 19511 | #powerpc-*-openbsd*) | ||
| 19512 | # tmake_file="${tmake_file} rs6000/t-fprules " | ||
| 19513 | @@ -2471,6 +2482,21 @@ case "${target}" in | ||
| 19514 | fi | ||
| 19515 | ;; | ||
| 19516 | |||
| 19517 | + avr32*-*-*) | ||
| 19518 | + supported_defaults="cpu" | ||
| 19519 | + | ||
| 19520 | + case "$with_cpu" in | ||
| 19521 | + "" \ | ||
| 19522 | + | morgan | ap7000 ) | ||
| 19523 | + # OK | ||
| 19524 | + ;; | ||
| 19525 | + *) | ||
| 19526 | + echo "Unknown arch used in --with-arch=$with_arch" 1>&2 | ||
| 19527 | + exit 1 | ||
| 19528 | + ;; | ||
| 19529 | + esac | ||
| 19530 | + ;; | ||
| 19531 | + | ||
| 19532 | fr*-*-*linux*) | ||
| 19533 | supported_defaults=cpu | ||
| 19534 | case "$with_cpu" in | ||
| 19535 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/cp/decl.c gcc-4.0.2-atmel.0.99.2/gcc/cp/decl.c | ||
| 19536 | --- gcc-4.0.2/gcc/cp/decl.c 2005-09-09 02:51:56.000000000 +0200 | ||
| 19537 | +++ gcc-4.0.2-atmel.0.99.2/gcc/cp/decl.c 2006-10-03 15:32:50.000000000 +0200 | ||
| 19538 | @@ -6128,6 +6128,7 @@ compute_array_index_type (tree name, tre | ||
| 19539 | name); | ||
| 19540 | else | ||
| 19541 | error ("size of array is not an integral constant-expression"); | ||
| 19542 | + size = integer_one_node; | ||
| 19543 | } | ||
| 19544 | else if (pedantic) | ||
| 19545 | { | ||
| 19546 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/c-typeck.c gcc-4.0.2-atmel.0.99.2/gcc/c-typeck.c | ||
| 19547 | --- gcc-4.0.2/gcc/c-typeck.c 2005-09-06 22:10:50.000000000 +0200 | ||
| 19548 | +++ gcc-4.0.2-atmel.0.99.2/gcc/c-typeck.c 2006-10-03 15:32:50.000000000 +0200 | ||
| 19549 | @@ -2742,8 +2742,13 @@ build_unary_op (enum tree_code code, tre | ||
| 19550 | when we have proper support for integer constant expressions. */ | ||
| 19551 | val = get_base_address (arg); | ||
| 19552 | if (val && TREE_CODE (val) == INDIRECT_REF | ||
| 19553 | - && integer_zerop (TREE_OPERAND (val, 0))) | ||
| 19554 | - return fold_convert (argtype, fold_offsetof (arg)); | ||
| 19555 | + && TREE_CONSTANT (TREE_OPERAND (val, 0))) | ||
| 19556 | + { | ||
| 19557 | + tree op0 = fold_convert (argtype, fold_offsetof (arg)), op1; | ||
| 19558 | + | ||
| 19559 | + op1 = fold_convert (argtype, TREE_OPERAND (val, 0)); | ||
| 19560 | + return fold (build2 (PLUS_EXPR, argtype, op0, op1)); | ||
| 19561 | + } | ||
| 19562 | |||
| 19563 | val = build1 (ADDR_EXPR, argtype, arg); | ||
| 19564 | |||
| 19565 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/doc/extend.texi gcc-4.0.2-atmel.0.99.2/gcc/doc/extend.texi | ||
| 19566 | --- gcc-4.0.2/gcc/doc/extend.texi 2005-07-20 12:36:23.000000000 +0200 | ||
| 19567 | +++ gcc-4.0.2-atmel.0.99.2/gcc/doc/extend.texi 2006-06-19 13:14:00.000000000 +0200 | ||
| 19568 | @@ -1723,13 +1723,6 @@ on data in the eight bit data area. Not | ||
| 19569 | You must use GAS and GLD from GNU binutils version 2.7 or later for | ||
| 19570 | this attribute to work correctly. | ||
| 19571 | |||
| 19572 | -@item exception_handler | ||
| 19573 | -@cindex exception handler functions on the Blackfin processor | ||
| 19574 | -Use this attribute on the Blackfin to indicate that the specified function | ||
| 19575 | -is an exception handler. The compiler will generate function entry and | ||
| 19576 | -exit sequences suitable for use in an exception handler when this | ||
| 19577 | -attribute is present. | ||
| 19578 | - | ||
| 19579 | @item far | ||
| 19580 | @cindex functions which handle memory bank switching | ||
| 19581 | On 68HC11 and 68HC12 the @code{far} attribute causes the compiler to | ||
| 19582 | @@ -1873,13 +1866,13 @@ this attribute to work correctly. | ||
| 19583 | |||
| 19584 | @item interrupt | ||
| 19585 | @cindex interrupt handler functions | ||
| 19586 | -Use this attribute on the ARM, AVR, C4x, M32R/D and Xstormy16 ports to indicate | ||
| 19587 | +Use this attribute on the ARM, AVR, AVR32, C4x, M32R/D and Xstormy16 ports to indicate | ||
| 19588 | that the specified function is an interrupt handler. The compiler will | ||
| 19589 | generate function entry and exit sequences suitable for use in an | ||
| 19590 | interrupt handler when this attribute is present. | ||
| 19591 | |||
| 19592 | -Note, interrupt handlers for the Blackfin, m68k, H8/300, H8/300H, H8S, and | ||
| 19593 | -SH processors can be specified via the @code{interrupt_handler} attribute. | ||
| 19594 | +Note, interrupt handlers for the m68k, H8/300, H8/300H, H8S, and SH processors | ||
| 19595 | +can be specified via the @code{interrupt_handler} attribute. | ||
| 19596 | |||
| 19597 | Note, on the AVR, interrupts will be enabled inside the function. | ||
| 19598 | |||
| 19599 | @@ -1892,18 +1885,21 @@ void f () __attribute__ ((interrupt ("IR | ||
| 19600 | |||
| 19601 | Permissible values for this parameter are: IRQ, FIQ, SWI, ABORT and UNDEF@. | ||
| 19602 | |||
| 19603 | -@item interrupt_handler | ||
| 19604 | -@cindex interrupt handler functions on the Blackfin, m68k, H8/300 and SH processors | ||
| 19605 | -Use this attribute on the Blackfin, m68k, H8/300, H8/300H, H8S, and SH to | ||
| 19606 | -indicate that the specified function is an interrupt handler. The compiler | ||
| 19607 | -will generate function entry and exit sequences suitable for use in an | ||
| 19608 | -interrupt handler when this attribute is present. | ||
| 19609 | +Note, for the AVR32, you can specify which banking scheme is used for | ||
| 19610 | +the interrupt mode this interrupt handler is used in like this: | ||
| 19611 | + | ||
| 19612 | +@smallexample | ||
| 19613 | +void f () __attribute__ ((interrupt ("FULL"))); | ||
| 19614 | +@end smallexample | ||
| 19615 | |||
| 19616 | -@item kspisusp | ||
| 19617 | -@cindex User stack pointer in interrupts on the Blackfin | ||
| 19618 | -When used together with @code{interrupt_handler}, @code{exception_handler} | ||
| 19619 | -or @code{nmi_handler}, code will be generated to load the stack pointer | ||
| 19620 | -from the USP register in the function prologue. | ||
| 19621 | +Permissible values for this parameter are: FULL, HALF, NONE and UNDEF. | ||
| 19622 | + | ||
| 19623 | +@item interrupt_handler | ||
| 19624 | +@cindex interrupt handler functions on the m68k, H8/300 and SH processors | ||
| 19625 | +Use this attribute on the m68k, H8/300, H8/300H, H8S, and SH to indicate that | ||
| 19626 | +the specified function is an interrupt handler. The compiler will generate | ||
| 19627 | +function entry and exit sequences suitable for use in an interrupt | ||
| 19628 | +handler when this attribute is present. | ||
| 19629 | |||
| 19630 | @item long_call/short_call | ||
| 19631 | @cindex indirect calls on ARM | ||
| 19632 | @@ -1983,19 +1979,6 @@ use the normal calling convention based | ||
| 19633 | This attribute can be used to cancel the effect of the @option{-mlong-calls} | ||
| 19634 | option. | ||
| 19635 | |||
| 19636 | -@item nesting | ||
| 19637 | -@cindex Allow nesting in an interrupt handler on the Blackfin processor. | ||
| 19638 | -Use this attribute together with @code{interrupt_handler}, | ||
| 19639 | -@code{exception_handler} or @code{nmi_handler} to indicate that the function | ||
| 19640 | -entry code should enable nested interrupts or exceptions. | ||
| 19641 | - | ||
| 19642 | -@item nmi_handler | ||
| 19643 | -@cindex NMI handler functions on the Blackfin processor | ||
| 19644 | -Use this attribute on the Blackfin to indicate that the specified function | ||
| 19645 | -is an NMI handler. The compiler will generate function entry and | ||
| 19646 | -exit sequences suitable for use in an NMI handler when this | ||
| 19647 | -attribute is present. | ||
| 19648 | - | ||
| 19649 | @item no_instrument_function | ||
| 19650 | @cindex @code{no_instrument_function} function attribute | ||
| 19651 | @opindex finstrument-functions | ||
| 19652 | @@ -2140,8 +2123,8 @@ disabled with the linker or the loader i | ||
| 19653 | problem.) | ||
| 19654 | |||
| 19655 | @item saveall | ||
| 19656 | -@cindex save all registers on the Blackfin, H8/300, H8/300H, and H8S | ||
| 19657 | -Use this attribute on the Blackfin, H8/300, H8/300H, and H8S to indicate that | ||
| 19658 | +@cindex save all registers on the H8/300, H8/300H, and H8S | ||
| 19659 | +Use this attribute on the H8/300, H8/300H, and H8S to indicate that | ||
| 19660 | all registers except the stack pointer should be saved in the prologue | ||
| 19661 | regardless of whether they are used or not. | ||
| 19662 | |||
| 19663 | @@ -3221,7 +3204,7 @@ struct my_unpacked_struct | ||
| 19664 | int i; | ||
| 19665 | @}; | ||
| 19666 | |||
| 19667 | -struct __attribute__ ((__packed__)) my_packed_struct | ||
| 19668 | +struct my_packed_struct __attribute__ ((__packed__)) | ||
| 19669 | @{ | ||
| 19670 | char c; | ||
| 19671 | int i; | ||
| 19672 | @@ -5449,6 +5432,7 @@ instructions, but allow the compiler to | ||
| 19673 | @menu | ||
| 19674 | * Alpha Built-in Functions:: | ||
| 19675 | * ARM Built-in Functions:: | ||
| 19676 | +* AVR32 Built-in Functions:: | ||
| 19677 | * Blackfin Built-in Functions:: | ||
| 19678 | * FR-V Built-in Functions:: | ||
| 19679 | * X86 Built-in Functions:: | ||
| 19680 | @@ -5686,6 +5670,54 @@ long long __builtin_arm_wxor (long long, | ||
| 19681 | long long __builtin_arm_wzero () | ||
| 19682 | @end smallexample | ||
| 19683 | |||
| 19684 | +@node AVR32 Built-in Functions | ||
| 19685 | +@subsection AVR32 Built-in Functions | ||
| 19686 | + | ||
| 19687 | + | ||
| 19688 | +@smallexample | ||
| 19689 | + | ||
| 19690 | +int __builtin_sats (int /*Rd*/,int /*sa*/, int /*bn*/) | ||
| 19691 | +int __builtin_satu (int /*Rd*/,int /*sa*/, int /*bn*/) | ||
| 19692 | +int __builtin_satrnds (int /*Rd*/,int /*sa*/, int /*bn*/) | ||
| 19693 | +int __builtin_satrndu (int /*Rd*/,int /*sa*/, int /*bn*/) | ||
| 19694 | +short __builtin_mulsathh_h (short, short) | ||
| 19695 | +int __builtin_mulsathh_w (short, short) | ||
| 19696 | +short __builtin_mulsatrndhh_h (short, short) | ||
| 19697 | +int __builtin_mulsatrndwh_w (int, short) | ||
| 19698 | +int __builtin_mulsatwh_w (int, short) | ||
| 19699 | +int __builtin_macsathh_w (int, short, short) | ||
| 19700 | +short __builtin_satadd_h (short, short) | ||
| 19701 | +short __builtin_satsub_h (short, short) | ||
| 19702 | +int __builtin_satadd_w (int, int) | ||
| 19703 | +int __builtin_satsub_w (int, int) | ||
| 19704 | +long long __builtin_mulwh_d(int, short) | ||
| 19705 | +long long __builtin_mulnwh_d(int, short) | ||
| 19706 | +long long __builtin_macwh_d(long long, int, short) | ||
| 19707 | +long long __builtin_machh_d(long long, short, short) | ||
| 19708 | + | ||
| 19709 | +void __builtin_musfr(int); | ||
| 19710 | +int __builtin_mustr(void); | ||
| 19711 | +int __builtin_mfsr(int /*Status Register Address*/) | ||
| 19712 | +void __builtin_mtsr(int /*Status Register Address*/, int /*Value*/) | ||
| 19713 | +int __builtin_mfdr(int /*Debug Register Address*/) | ||
| 19714 | +void __builtin_mtdr(int /*Debug Register Address*/, int /*Value*/) | ||
| 19715 | +void __builtin_cache(void * /*Address*/, int /*Cache Operation*/) | ||
| 19716 | +void __builtin_sync(int /*Sync Operation*/) | ||
| 19717 | +void __builtin_tlbr(void) | ||
| 19718 | +void __builtin_tlbs(void) | ||
| 19719 | +void __builtin_tlbw(void) | ||
| 19720 | +void __builtin_breakpoint(void) | ||
| 19721 | +int __builtin_xchg(void * /*Address*/, int /*Value*/ ) | ||
| 19722 | +short __builtin_bswap_16(short) | ||
| 19723 | +int __builtin_bswap_32(int) | ||
| 19724 | +void __builtin_cop(int/*cpnr*/, int/*crd*/, int/*crx*/, int/*cry*/, int/*op*/) | ||
| 19725 | +int __builtin_mvcr_w(int/*cpnr*/, int/*crs*/) | ||
| 19726 | +void __builtin_mvrc_w(int/*cpnr*/, int/*crd*/, int/*value*/) | ||
| 19727 | +long long __builtin_mvcr_d(int/*cpnr*/, int/*crs*/) | ||
| 19728 | +void __builtin_mvrc_d(int/*cpnr*/, int/*crd*/, long long/*value*/) | ||
| 19729 | + | ||
| 19730 | +@end smallexample | ||
| 19731 | + | ||
| 19732 | @node Blackfin Built-in Functions | ||
| 19733 | @subsection Blackfin Built-in Functions | ||
| 19734 | |||
| 19735 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/doc/invoke.texi gcc-4.0.2-atmel.0.99.2/gcc/doc/invoke.texi | ||
| 19736 | --- gcc-4.0.2/gcc/doc/invoke.texi 2005-09-02 10:12:30.000000000 +0200 | ||
| 19737 | +++ gcc-4.0.2-atmel.0.99.2/gcc/doc/invoke.texi 2006-02-08 17:33:56.000000000 +0100 | ||
| 19738 | @@ -185,7 +185,7 @@ in the following sections. | ||
| 19739 | -fno-default-inline -fvisibility-inlines-hidden @gol | ||
| 19740 | -Wabi -Wctor-dtor-privacy @gol | ||
| 19741 | -Wnon-virtual-dtor -Wreorder @gol | ||
| 19742 | --Weffc++ -Wno-deprecated -Wstrict-null-sentinel @gol | ||
| 19743 | +-Weffc++ -Wno-deprecated @gol | ||
| 19744 | -Wno-non-template-friend -Wold-style-cast @gol | ||
| 19745 | -Woverloaded-virtual -Wno-pmf-conversions @gol | ||
| 19746 | -Wsign-promo} | ||
| 19747 | @@ -542,6 +542,10 @@ Objective-C and Objective-C++ Dialects}. | ||
| 19748 | -mauto-incdec -minmax -mlong-calls -mshort @gol | ||
| 19749 | -msoft-reg-count=@var{count}} | ||
| 19750 | |||
| 19751 | +@emph{AVR32 Options} | ||
| 19752 | +@gccoptlist{-muse-rodata-section -mhard-float -msoft-float -mrelax @gol | ||
| 19753 | +-muse-oscall -mforce-double-align -mno-init-got -mcpu=@var{cpu}} | ||
| 19754 | + | ||
| 19755 | @emph{MCore Options} | ||
| 19756 | @gccoptlist{-mhardlit -mno-hardlit -mdiv -mno-div -mrelax-immediates @gol | ||
| 19757 | -mno-relax-immediates -mwide-bitfields -mno-wide-bitfields @gol | ||
| 19758 | @@ -1738,14 +1742,6 @@ to filter out those warnings. | ||
| 19759 | @opindex Wno-deprecated | ||
| 19760 | Do not warn about usage of deprecated features. @xref{Deprecated Features}. | ||
| 19761 | |||
| 19762 | -@item -Wstrict-null-sentinel @r{(C++ only)} | ||
| 19763 | -@opindex Wstrict-null-sentinel | ||
| 19764 | -Warn also about the use of an uncasted @code{NULL} as sentinel. When | ||
| 19765 | -compiling only with GCC this is a valid sentinel, as @code{NULL} is defined | ||
| 19766 | -to @code{__null}. Although it is a null pointer constant not a null pointer, | ||
| 19767 | -it is guaranteed to of the same size as a pointer. But this use is | ||
| 19768 | -not portable across different compilers. | ||
| 19769 | - | ||
| 19770 | @item -Wno-non-template-friend @r{(C++ only)} | ||
| 19771 | @opindex Wno-non-template-friend | ||
| 19772 | Disable warnings when non-templatized friend functions are declared | ||
| 19773 | @@ -2549,13 +2545,11 @@ get these warnings. | ||
| 19774 | If you want to warn about code which uses the uninitialized value of the | ||
| 19775 | variable in its own initializer, use the @option{-Winit-self} option. | ||
| 19776 | |||
| 19777 | -These warnings occur for individual uninitialized or clobbered | ||
| 19778 | -elements of structure, union or array variables as well as for | ||
| 19779 | -variables which are uninitialized or clobbered as a whole. They do | ||
| 19780 | -not occur for variables or elements declared @code{volatile}. Because | ||
| 19781 | -these warnings depend on optimization, the exact variables or elements | ||
| 19782 | -for which there are warnings will depend on the precise optimization | ||
| 19783 | -options and version of GCC used. | ||
| 19784 | +These warnings occur only for variables that are candidates for | ||
| 19785 | +register allocation. Therefore, they do not occur for a variable that | ||
| 19786 | +is declared @code{volatile}, or whose address is taken, or whose size | ||
| 19787 | +is other than 1, 2, 4 or 8 bytes. Also, they do not occur for | ||
| 19788 | +structures, unions or arrays, even when they are in registers. | ||
| 19789 | |||
| 19790 | Note that there may be no warning about a variable that is used only | ||
| 19791 | to compute a value that itself is never used, because such | ||
| 19792 | @@ -5584,10 +5578,6 @@ If number of candidates in the set is sm | ||
| 19793 | we always try to remove unnecessary ivs from the set during its | ||
| 19794 | optimization when a new iv is added to the set. | ||
| 19795 | |||
| 19796 | -@item scev-max-expr-size | ||
| 19797 | -Bound on size of expressions used in the scalar evolutions analyzer. | ||
| 19798 | -Large expressions slow the analyzer. | ||
| 19799 | - | ||
| 19800 | @item max-iterations-to-track | ||
| 19801 | |||
| 19802 | The maximum number of iterations of a loop the brute force algorithm | ||
| 19803 | @@ -6695,7 +6685,7 @@ that macro, which enables you to change | ||
| 19804 | * ARC Options:: | ||
| 19805 | * ARM Options:: | ||
| 19806 | * AVR Options:: | ||
| 19807 | -* Blackfin Options:: | ||
| 19808 | +* AVR32 Options:: | ||
| 19809 | * CRIS Options:: | ||
| 19810 | * Darwin Options:: | ||
| 19811 | * DEC Alpha Options:: | ||
| 19812 | @@ -7147,81 +7137,55 @@ comply to the C standards, but it will p | ||
| 19813 | size. | ||
| 19814 | @end table | ||
| 19815 | |||
| 19816 | -@node Blackfin Options | ||
| 19817 | -@subsection Blackfin Options | ||
| 19818 | -@cindex Blackfin Options | ||
| 19819 | +@node AVR32 Options | ||
| 19820 | +@subsection AVR32 Options | ||
| 19821 | +@cindex AVR32 Options | ||
| 19822 | |||
| 19823 | -@table @gcctabopt | ||
| 19824 | -@item -momit-leaf-frame-pointer | ||
| 19825 | -@opindex momit-leaf-frame-pointer | ||
| 19826 | -Don't keep the frame pointer in a register for leaf functions. This | ||
| 19827 | -avoids the instructions to save, set up and restore frame pointers and | ||
| 19828 | -makes an extra register available in leaf functions. The option | ||
| 19829 | -@option{-fomit-frame-pointer} removes the frame pointer for all functions | ||
| 19830 | -which might make debugging harder. | ||
| 19831 | +These options are defined for AVR32 implementations: | ||
| 19832 | |||
| 19833 | -@item -mspecld-anomaly | ||
| 19834 | -@opindex mspecld-anomaly | ||
| 19835 | -When enabled, the compiler will ensure that the generated code does not | ||
| 19836 | -contain speculative loads after jump instructions. This option is enabled | ||
| 19837 | -by default. | ||
| 19838 | - | ||
| 19839 | -@item -mno-specld-anomaly | ||
| 19840 | -@opindex mno-specld-anomaly | ||
| 19841 | -Don't generate extra code to prevent speculative loads from occurring. | ||
| 19842 | - | ||
| 19843 | -@item -mcsync-anomaly | ||
| 19844 | -@opindex mcsync-anomaly | ||
| 19845 | -When enabled, the compiler will ensure that the generated code does not | ||
| 19846 | -contain CSYNC or SSYNC instructions too soon after conditional branches. | ||
| 19847 | -This option is enabled by default. | ||
| 19848 | - | ||
| 19849 | -@item -mno-csync-anomaly | ||
| 19850 | -@opindex mno-csync-anomaly | ||
| 19851 | -Don't generate extra code to prevent CSYNC or SSYNC instructions from | ||
| 19852 | -occurring too soon after a conditional branch. | ||
| 19853 | - | ||
| 19854 | -@item -mlow-64k | ||
| 19855 | -@opindex mlow-64k | ||
| 19856 | -When enabled, the compiler is free to take advantage of the knowledge that | ||
| 19857 | -the entire program fits into the low 64k of memory. | ||
| 19858 | - | ||
| 19859 | -@item -mno-low-64k | ||
| 19860 | -@opindex mno-low-64k | ||
| 19861 | -Assume that the program is arbitrarily large. This is the default. | ||
| 19862 | +@table @gcctabopt | ||
| 19863 | +@item -muse-rodata-section | ||
| 19864 | +@opindex muse-rodata-section | ||
| 19865 | +Use section @samp{.rodata} for read-only data instead of @samp{.text}. | ||
| 19866 | |||
| 19867 | -@item -mid-shared-library | ||
| 19868 | -@opindex mid-shared-library | ||
| 19869 | -Generate code that supports shared libraries via the library ID method. | ||
| 19870 | -This allows for execute in place and shared libraries in an environment | ||
| 19871 | -without virtual memory management. This option implies @option{-fPIC}. | ||
| 19872 | +@item -mhard-float | ||
| 19873 | +@opindex mhard-float | ||
| 19874 | +Use floating-point coprocessor instructions. | ||
| 19875 | |||
| 19876 | -@item -mno-id-shared-library | ||
| 19877 | -@opindex mno-id-shared-library | ||
| 19878 | -Generate code that doesn't assume ID based shared libraries are being used. | ||
| 19879 | -This is the default. | ||
| 19880 | +@item -msoft-float | ||
| 19881 | +@opindex msoft-float | ||
| 19882 | +Use software floating-point library. | ||
| 19883 | |||
| 19884 | -@item -mshared-library-id=n | ||
| 19885 | -@opindex mshared-library-id | ||
| 19886 | -Specified the identification number of the ID based shared library being | ||
| 19887 | -compiled. Specifying a value of 0 will generate more compact code, specifying | ||
| 19888 | -other values will force the allocation of that number to the current | ||
| 19889 | -library but is no more space or time efficient than omitting this option. | ||
| 19890 | +@item -mrelax | ||
| 19891 | +@opindex mrelax | ||
| 19892 | +Enable relaxing in linker. This means that when the address of symbols | ||
| 19893 | +are known at link time, the linker can optimize @samp{icall} and @samp{mcall} | ||
| 19894 | +instructions into a @samp{rcall} instruction if possible. Loading the address | ||
| 19895 | +of a symbol can also be optimized. | ||
| 19896 | + | ||
| 19897 | +@item -muse-oscall | ||
| 19898 | +@opindex muse-oscall | ||
| 19899 | +When using gcc as a frontend for linking this switch forces the use of | ||
| 19900 | +@samp{fake} system calls in the newlib c-library. These fake system | ||
| 19901 | +calls are handled by some AVR32 simulators which redirects these calls | ||
| 19902 | +to the OS in which the simulator is running. This is practical for | ||
| 19903 | +being able to perform file I/O when running programs in a simulator. | ||
| 19904 | + | ||
| 19905 | +@item -mforce-double-align | ||
| 19906 | +@opindex mforce-double-align | ||
| 19907 | +Force double-word alignment for double-word memory accesses. | ||
| 19908 | + | ||
| 19909 | +@item -mno-init-got | ||
| 19910 | +@opindex mno-init-got | ||
| 19911 | +Do not initialize the GOT register before using it when compiling PIC | ||
| 19912 | +code. | ||
| 19913 | |||
| 19914 | -@item -mlong-calls | ||
| 19915 | -@itemx -mno-long-calls | ||
| 19916 | -@opindex mlong-calls | ||
| 19917 | -@opindex mno-long-calls | ||
| 19918 | -Tells the compiler to perform function calls by first loading the | ||
| 19919 | -address of the function into a register and then performing a subroutine | ||
| 19920 | -call on this register. This switch is needed if the target function | ||
| 19921 | -will lie outside of the 24 bit addressing range of the offset based | ||
| 19922 | -version of subroutine call instruction. | ||
| 19923 | +@item -mcpu=@var{cpu-type} | ||
| 19924 | +@opindex mcpu | ||
| 19925 | +Generate code for the specified cpu. Permissible names are: @samp{morgan}, | ||
| 19926 | +@samp{ap7000} and @samp{default}. @samp{default} is a dummy cpu which | ||
| 19927 | +allows all avr32 instructions. | ||
| 19928 | |||
| 19929 | -This feature is not enabled by default. Specifying | ||
| 19930 | -@option{-mno-long-calls} will restore the default behavior. Note these | ||
| 19931 | -switches have no effect on how the compiler generates code to handle | ||
| 19932 | -function calls via function pointers. | ||
| 19933 | @end table | ||
| 19934 | |||
| 19935 | @node CRIS Options | ||
| 19936 | @@ -10853,6 +10817,7 @@ conventions that adheres to the March 19 | ||
| 19937 | Application Binary Interface, PowerPC processor supplement. This is the | ||
| 19938 | default unless you configured GCC using @samp{powerpc-*-eabiaix}. | ||
| 19939 | |||
| 19940 | + | ||
| 19941 | @item -mcall-sysv-eabi | ||
| 19942 | @opindex mcall-sysv-eabi | ||
| 19943 | Specify both @option{-mcall-sysv} and @option{-meabi} options. | ||
| 19944 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/doc/md.texi gcc-4.0.2-atmel.0.99.2/gcc/doc/md.texi | ||
| 19945 | --- gcc-4.0.2/gcc/doc/md.texi 2005-08-14 01:56:45.000000000 +0200 | ||
| 19946 | +++ gcc-4.0.2-atmel.0.99.2/gcc/doc/md.texi 2006-07-13 09:53:31.000000000 +0200 | ||
| 19947 | @@ -3,6 +3,7 @@ | ||
| 19948 | @c This is part of the GCC manual. | ||
| 19949 | @c For copying conditions, see the file gcc.texi. | ||
| 19950 | |||
| 19951 | + | ||
| 19952 | @ifset INTERNALS | ||
| 19953 | @node Machine Desc | ||
| 19954 | @chapter Machine Descriptions | ||
| 19955 | @@ -1683,6 +1684,59 @@ A memory reference suitable for iWMMXt l | ||
| 19956 | A memory reference suitable for the ARMv4 ldrsb instruction. | ||
| 19957 | @end table | ||
| 19958 | |||
| 19959 | +@item AVR32 family---@file{avr32.h} | ||
| 19960 | +@table @code | ||
| 19961 | +@item f | ||
| 19962 | +Floating-point registers (f0 to f15) | ||
| 19963 | + | ||
| 19964 | +@item Ku@var{bits} | ||
| 19965 | +Unsigned constant representable with @var{bits} number of bits (Must be | ||
| 19966 | +two digits). I.e: An unsigned 8-bit constant is written as @samp{Ku08} | ||
| 19967 | + | ||
| 19968 | +@item Ks@var{bits} | ||
| 19969 | +Signed constant representable with @var{bits} number of bits (Must be | ||
| 19970 | +two digits). I.e: A signed 12-bit constant is written as @samp{Ks12} | ||
| 19971 | + | ||
| 19972 | +@item Is@var{bits} | ||
| 19973 | +The negated range of a signed constant representable with @var{bits} | ||
| 19974 | +number of bits. The same as @samp{Ks@var{bits}} with a negated range. | ||
| 19975 | +This means that the constant must be in the range @math{-2^{bits-1}-1} to @math{2^{bits-1}} | ||
| 19976 | + | ||
| 19977 | +@item G | ||
| 19978 | +A single/double precision floating-point immediate or 64-bit integer | ||
| 19979 | +immediate where the least and most significant words both can be | ||
| 19980 | +loaded with a move instruction. That is the the integer form of the | ||
| 19981 | +values in the least and most significant words both are in the range | ||
| 19982 | +@math{-2^{20}} to @math{2^{20}-1}. | ||
| 19983 | + | ||
| 19984 | +@item RKs@var{bits} | ||
| 19985 | +A memory reference where the address consists of a base register | ||
| 19986 | +plus a signed immediate displacement with range given by @samp{Ks@var{bits}} | ||
| 19987 | +which has the same format as for the signed immediate integer constraint | ||
| 19988 | +given above. | ||
| 19989 | + | ||
| 19990 | +@item RKu@var{bits} | ||
| 19991 | +A memory reference where the address consists of a base register | ||
| 19992 | +plus an unsigned immediate displacement with range given by @samp{Ku@var{bits}} | ||
| 19993 | +which has the same format as for the unsigned immediate integer constraint | ||
| 19994 | +given above. | ||
| 19995 | + | ||
| 19996 | +@item S | ||
| 19997 | +A memory reference with an immediate or register offset | ||
| 19998 | + | ||
| 19999 | +@item T | ||
| 20000 | +A memory reference to a constant pool entry | ||
| 20001 | + | ||
| 20002 | +@item W | ||
| 20003 | +A valid operand for use in the @samp{lda.w} instruction macro when | ||
| 20004 | +relaxing is enabled | ||
| 20005 | + | ||
| 20006 | +@item Z | ||
| 20007 | +A memory reference valid for coprocessor memory instructions | ||
| 20008 | + | ||
| 20009 | +@end table | ||
| 20010 | + | ||
| 20011 | + | ||
| 20012 | @item AVR family---@file{avr.h} | ||
| 20013 | @table @code | ||
| 20014 | @item l | ||
| 20015 | @@ -2069,102 +2123,6 @@ range of 1 to 2047. | ||
| 20016 | |||
| 20017 | @end table | ||
| 20018 | |||
| 20019 | -@item Blackfin family---@file{bfin.h} | ||
| 20020 | -@table @code | ||
| 20021 | -@item a | ||
| 20022 | -P register | ||
| 20023 | - | ||
| 20024 | -@item d | ||
| 20025 | -D register | ||
| 20026 | - | ||
| 20027 | -@item z | ||
| 20028 | -A call clobbered P register. | ||
| 20029 | - | ||
| 20030 | -@item D | ||
| 20031 | -Even-numbered D register | ||
| 20032 | - | ||
| 20033 | -@item W | ||
| 20034 | -Odd-numbered D register | ||
| 20035 | - | ||
| 20036 | -@item e | ||
| 20037 | -Accumulator register. | ||
| 20038 | - | ||
| 20039 | -@item A | ||
| 20040 | -Even-numbered accumulator register. | ||
| 20041 | - | ||
| 20042 | -@item B | ||
| 20043 | -Odd-numbered accumulator register. | ||
| 20044 | - | ||
| 20045 | -@item b | ||
| 20046 | -I register | ||
| 20047 | - | ||
| 20048 | -@item B | ||
| 20049 | -B register | ||
| 20050 | - | ||
| 20051 | -@item f | ||
| 20052 | -M register | ||
| 20053 | - | ||
| 20054 | -@item c | ||
| 20055 | -Registers used for circular buffering, i.e. I, B, or L registers. | ||
| 20056 | - | ||
| 20057 | -@item C | ||
| 20058 | -The CC register. | ||
| 20059 | - | ||
| 20060 | -@item x | ||
| 20061 | -Any D, P, B, M, I or L register. | ||
| 20062 | - | ||
| 20063 | -@item y | ||
| 20064 | -Additional registers typically used only in prologues and epilogues: RETS, | ||
| 20065 | -RETN, RETI, RETX, RETE, ASTAT, SEQSTAT and USP. | ||
| 20066 | - | ||
| 20067 | -@item w | ||
| 20068 | -Any register except accumulators or CC. | ||
| 20069 | - | ||
| 20070 | -@item Ksh | ||
| 20071 | -Signed 16 bit integer (in the range -32768 to 32767) | ||
| 20072 | - | ||
| 20073 | -@item Kuh | ||
| 20074 | -Unsigned 16 bit integer (in the range 0 to 65535) | ||
| 20075 | - | ||
| 20076 | -@item Ks7 | ||
| 20077 | -Signed 7 bit integer (in the range -64 to 63) | ||
| 20078 | - | ||
| 20079 | -@item Ku7 | ||
| 20080 | -Unsigned 7 bit integer (in the range 0 to 127) | ||
| 20081 | - | ||
| 20082 | -@item Ku5 | ||
| 20083 | -Unsigned 5 bit integer (in the range 0 to 31) | ||
| 20084 | - | ||
| 20085 | -@item Ks4 | ||
| 20086 | -Signed 4 bit integer (in the range -8 to 7) | ||
| 20087 | - | ||
| 20088 | -@item Ks3 | ||
| 20089 | -Signed 3 bit integer (in the range -3 to 4) | ||
| 20090 | - | ||
| 20091 | -@item Ku3 | ||
| 20092 | -Unsigned 3 bit integer (in the range 0 to 7) | ||
| 20093 | - | ||
| 20094 | -@item P@var{n} | ||
| 20095 | -Constant @var{n}, where @var{n} is a single-digit constant in the range 0 to 4. | ||
| 20096 | - | ||
| 20097 | -@item M1 | ||
| 20098 | -Constant 255. | ||
| 20099 | - | ||
| 20100 | -@item M2 | ||
| 20101 | -Constant 65535. | ||
| 20102 | - | ||
| 20103 | -@item J | ||
| 20104 | -An integer constant with exactly a single bit set. | ||
| 20105 | - | ||
| 20106 | -@item L | ||
| 20107 | -An integer constant with all bits set except exactly one. | ||
| 20108 | - | ||
| 20109 | -@item H | ||
| 20110 | - | ||
| 20111 | -@item Q | ||
| 20112 | -Any SYMBOL_REF. | ||
| 20113 | -@end table | ||
| 20114 | - | ||
| 20115 | @item IP2K---@file{ip2k.h} | ||
| 20116 | @table @code | ||
| 20117 | @item a | ||
| 20118 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/expr.c gcc-4.0.2-atmel.0.99.2/gcc/expr.c | ||
| 20119 | --- gcc-4.0.2/gcc/expr.c 2005-09-10 03:03:28.000000000 +0200 | ||
| 20120 | +++ gcc-4.0.2-atmel.0.99.2/gcc/expr.c 2006-10-10 12:40:42.000000000 +0200 | ||
| 20121 | @@ -3314,16 +3314,17 @@ emit_single_push_insn (enum machine_mode | ||
| 20122 | } | ||
| 20123 | else | ||
| 20124 | { | ||
| 20125 | + emit_move_insn (stack_pointer_rtx, | ||
| 20126 | + expand_binop (Pmode, | ||
| 20127 | #ifdef STACK_GROWS_DOWNWARD | ||
| 20128 | - /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC. */ | ||
| 20129 | - dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, | ||
| 20130 | - GEN_INT (-(HOST_WIDE_INT) rounded_size)); | ||
| 20131 | + sub_optab, | ||
| 20132 | #else | ||
| 20133 | - /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC. */ | ||
| 20134 | - dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, | ||
| 20135 | - GEN_INT (rounded_size)); | ||
| 20136 | + add_optab, | ||
| 20137 | #endif | ||
| 20138 | - dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr); | ||
| 20139 | + stack_pointer_rtx, | ||
| 20140 | + GEN_INT (rounded_size), | ||
| 20141 | + NULL_RTX, 0, OPTAB_LIB_WIDEN)); | ||
| 20142 | + dest_addr = stack_pointer_rtx; | ||
| 20143 | } | ||
| 20144 | |||
| 20145 | dest = gen_rtx_MEM (mode, dest_addr); | ||
| 20146 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/genemit.c gcc-4.0.2-atmel.0.99.2/gcc/genemit.c | ||
| 20147 | --- gcc-4.0.2/gcc/genemit.c 2004-09-09 15:22:33.000000000 +0200 | ||
| 20148 | +++ gcc-4.0.2-atmel.0.99.2/gcc/genemit.c 2006-03-23 13:26:49.000000000 +0100 | ||
| 20149 | @@ -122,6 +122,24 @@ max_operand_vec (rtx insn, int arg) | ||
| 20150 | } | ||
| 20151 | |||
| 20152 | static void | ||
| 20153 | +gen_vararg_prologue(int operands) | ||
| 20154 | +{ | ||
| 20155 | + int i; | ||
| 20156 | + | ||
| 20157 | + if (operands > 1) | ||
| 20158 | + { | ||
| 20159 | + for (i = 1; i < operands; i++) | ||
| 20160 | + printf(" rtx operand%d ATTRIBUTE_UNUSED;\n", i); | ||
| 20161 | + | ||
| 20162 | + printf(" va_list args;\n\n"); | ||
| 20163 | + printf(" va_start(args, operand0);\n"); | ||
| 20164 | + for (i = 1; i < operands; i++) | ||
| 20165 | + printf(" operand%d = va_arg(args, rtx);\n", i); | ||
| 20166 | + printf(" va_end(args);\n\n"); | ||
| 20167 | + } | ||
| 20168 | +} | ||
| 20169 | + | ||
| 20170 | +static void | ||
| 20171 | print_code (RTX_CODE code) | ||
| 20172 | { | ||
| 20173 | const char *p1; | ||
| 20174 | @@ -406,18 +424,16 @@ gen_insn (rtx insn, int lineno) | ||
| 20175 | fatal ("match_dup operand number has no match_operand"); | ||
| 20176 | |||
| 20177 | /* Output the function name and argument declarations. */ | ||
| 20178 | - printf ("rtx\ngen_%s (", XSTR (insn, 0)); | ||
| 20179 | + printf ("rtx\ngen_%s ", XSTR (insn, 0)); | ||
| 20180 | + | ||
| 20181 | if (operands) | ||
| 20182 | - for (i = 0; i < operands; i++) | ||
| 20183 | - if (i) | ||
| 20184 | - printf (",\n\trtx operand%d ATTRIBUTE_UNUSED", i); | ||
| 20185 | + printf("(rtx operand0 ATTRIBUTE_UNUSED, ...)\n"); | ||
| 20186 | else | ||
| 20187 | - printf ("rtx operand%d ATTRIBUTE_UNUSED", i); | ||
| 20188 | - else | ||
| 20189 | - printf ("void"); | ||
| 20190 | - printf (")\n"); | ||
| 20191 | + printf("(void)\n"); | ||
| 20192 | printf ("{\n"); | ||
| 20193 | |||
| 20194 | + gen_vararg_prologue(operands); | ||
| 20195 | + | ||
| 20196 | /* Output code to construct and return the rtl for the instruction body. */ | ||
| 20197 | |||
| 20198 | if (XVECLEN (insn, 1) == 1) | ||
| 20199 | @@ -457,16 +473,12 @@ gen_expand (rtx expand) | ||
| 20200 | operands = max_operand_vec (expand, 1); | ||
| 20201 | |||
| 20202 | /* Output the function name and argument declarations. */ | ||
| 20203 | - printf ("rtx\ngen_%s (", XSTR (expand, 0)); | ||
| 20204 | + printf ("rtx\ngen_%s ", XSTR (expand, 0)); | ||
| 20205 | if (operands) | ||
| 20206 | - for (i = 0; i < operands; i++) | ||
| 20207 | - if (i) | ||
| 20208 | - printf (",\n\trtx operand%d", i); | ||
| 20209 | - else | ||
| 20210 | - printf ("rtx operand%d", i); | ||
| 20211 | + printf("(rtx operand0 ATTRIBUTE_UNUSED, ...)\n"); | ||
| 20212 | else | ||
| 20213 | - printf ("void"); | ||
| 20214 | - printf (")\n"); | ||
| 20215 | + printf("(void)\n"); | ||
| 20216 | + | ||
| 20217 | printf ("{\n"); | ||
| 20218 | |||
| 20219 | /* If we don't have any C code to write, only one insn is being written, | ||
| 20220 | @@ -476,6 +488,8 @@ gen_expand (rtx expand) | ||
| 20221 | && operands > max_dup_opno | ||
| 20222 | && XVECLEN (expand, 1) == 1) | ||
| 20223 | { | ||
| 20224 | + gen_vararg_prologue(operands); | ||
| 20225 | + | ||
| 20226 | printf (" return "); | ||
| 20227 | gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL); | ||
| 20228 | printf (";\n}\n\n"); | ||
| 20229 | @@ -489,6 +503,7 @@ gen_expand (rtx expand) | ||
| 20230 | for (; i <= max_scratch_opno; i++) | ||
| 20231 | printf (" rtx operand%d ATTRIBUTE_UNUSED;\n", i); | ||
| 20232 | printf (" rtx _val = 0;\n"); | ||
| 20233 | + gen_vararg_prologue(operands); | ||
| 20234 | printf (" start_sequence ();\n"); | ||
| 20235 | |||
| 20236 | /* The fourth operand of DEFINE_EXPAND is some code to be executed | ||
| 20237 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/genflags.c gcc-4.0.2-atmel.0.99.2/gcc/genflags.c | ||
| 20238 | --- gcc-4.0.2/gcc/genflags.c 2004-09-09 15:22:33.000000000 +0200 | ||
| 20239 | +++ gcc-4.0.2-atmel.0.99.2/gcc/genflags.c 2006-10-10 12:40:42.000000000 +0200 | ||
| 20240 | @@ -128,7 +128,6 @@ static void | ||
| 20241 | gen_proto (rtx insn) | ||
| 20242 | { | ||
| 20243 | int num = num_operands (insn); | ||
| 20244 | - int i; | ||
| 20245 | const char *name = XSTR (insn, 0); | ||
| 20246 | int truth = maybe_eval_c_test (XSTR (insn, 2)); | ||
| 20247 | |||
| 20248 | @@ -159,12 +158,7 @@ gen_proto (rtx insn) | ||
| 20249 | if (num == 0) | ||
| 20250 | fputs ("void", stdout); | ||
| 20251 | else | ||
| 20252 | - { | ||
| 20253 | - for (i = 1; i < num; i++) | ||
| 20254 | - fputs ("rtx, ", stdout); | ||
| 20255 | - | ||
| 20256 | - fputs ("rtx", stdout); | ||
| 20257 | - } | ||
| 20258 | + fputs("rtx, ...", stdout); | ||
| 20259 | |||
| 20260 | puts (");"); | ||
| 20261 | |||
| 20262 | @@ -174,12 +168,7 @@ gen_proto (rtx insn) | ||
| 20263 | { | ||
| 20264 | printf ("static inline rtx\ngen_%s", name); | ||
| 20265 | if (num > 0) | ||
| 20266 | - { | ||
| 20267 | - putchar ('('); | ||
| 20268 | - for (i = 0; i < num-1; i++) | ||
| 20269 | - printf ("rtx ARG_UNUSED (%c), ", 'a' + i); | ||
| 20270 | - printf ("rtx ARG_UNUSED (%c))\n", 'a' + i); | ||
| 20271 | - } | ||
| 20272 | + puts("(rtx ARG_UNUSED(a), ...)"); | ||
| 20273 | else | ||
| 20274 | puts ("(void)"); | ||
| 20275 | puts ("{\n return 0;\n}"); | ||
| 20276 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/genoutput.c gcc-4.0.2-atmel.0.99.2/gcc/genoutput.c | ||
| 20277 | --- gcc-4.0.2/gcc/genoutput.c 2004-09-09 15:22:34.000000000 +0200 | ||
| 20278 | +++ gcc-4.0.2-atmel.0.99.2/gcc/genoutput.c 2006-03-23 13:26:49.000000000 +0100 | ||
| 20279 | @@ -383,7 +383,7 @@ output_insn_data (void) | ||
| 20280 | } | ||
| 20281 | |||
| 20282 | if (d->name && d->name[0] != '*') | ||
| 20283 | - printf (" (insn_gen_fn) gen_%s,\n", d->name); | ||
| 20284 | + printf (" gen_%s,\n", d->name); | ||
| 20285 | else | ||
| 20286 | printf (" 0,\n"); | ||
| 20287 | |||
| 20288 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/longlong.h gcc-4.0.2-atmel.0.99.2/gcc/longlong.h | ||
| 20289 | --- gcc-4.0.2/gcc/longlong.h 2004-06-15 12:40:44.000000000 +0200 | ||
| 20290 | +++ gcc-4.0.2-atmel.0.99.2/gcc/longlong.h 2005-06-07 14:59:22.000000000 +0200 | ||
| 20291 | @@ -227,6 +227,39 @@ UDItype __umulsidi3 (USItype, USItype); | ||
| 20292 | #define UDIV_TIME 100 | ||
| 20293 | #endif /* __arm__ */ | ||
| 20294 | |||
| 20295 | +#if defined (__avr32__) && W_TYPE_SIZE == 32 | ||
| 20296 | +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ | ||
| 20297 | + __asm__ ("add\t%1, %4, %5\n\tadc\t%0, %2, %3" \ | ||
| 20298 | + : "=r" ((USItype) (sh)), \ | ||
| 20299 | + "=&r" ((USItype) (sl)) \ | ||
| 20300 | + : "r" ((USItype) (ah)), \ | ||
| 20301 | + "r" ((USItype) (bh)), \ | ||
| 20302 | + "r" ((USItype) (al)), \ | ||
| 20303 | + "r" ((USItype) (bl)) __CLOBBER_CC) | ||
| 20304 | +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ | ||
| 20305 | + __asm__ ("sub\t%1, %4, %5\n\tsbc\t%0, %2, %3" \ | ||
| 20306 | + : "=r" ((USItype) (sh)), \ | ||
| 20307 | + "=&r" ((USItype) (sl)) \ | ||
| 20308 | + : "r" ((USItype) (ah)), \ | ||
| 20309 | + "r" ((USItype) (bh)), \ | ||
| 20310 | + "r" ((USItype) (al)), \ | ||
| 20311 | + "r" ((USItype) (bl)) __CLOBBER_CC) | ||
| 20312 | + | ||
| 20313 | +#define __umulsidi3(a,b) ((UDItype)(a) * (UDItype)(b)) | ||
| 20314 | + | ||
| 20315 | +#define umul_ppmm(w1, w0, u, v) \ | ||
| 20316 | +{ \ | ||
| 20317 | + DWunion __w; \ | ||
| 20318 | + __w.ll = __umulsidi3 (u, v); \ | ||
| 20319 | + w1 = __w.s.high; \ | ||
| 20320 | + w0 = __w.s.low; \ | ||
| 20321 | +} | ||
| 20322 | + | ||
| 20323 | +#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X)) | ||
| 20324 | +#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctz (X)) | ||
| 20325 | +#define COUNT_LEADING_ZEROS_0 32 | ||
| 20326 | +#endif | ||
| 20327 | + | ||
| 20328 | #if defined (__hppa) && W_TYPE_SIZE == 32 | ||
| 20329 | #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ | ||
| 20330 | __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \ | ||
| 20331 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/optabs.h gcc-4.0.2-atmel.0.99.2/gcc/optabs.h | ||
| 20332 | --- gcc-4.0.2/gcc/optabs.h 2005-02-12 12:34:21.000000000 +0100 | ||
| 20333 | +++ gcc-4.0.2-atmel.0.99.2/gcc/optabs.h 2006-10-10 12:40:42.000000000 +0200 | ||
| 20334 | @@ -389,7 +389,7 @@ extern enum insn_code reload_out_optab[N | ||
| 20335 | extern GTY(()) optab code_to_optab[NUM_RTX_CODE + 1]; | ||
| 20336 | |||
| 20337 | |||
| 20338 | -typedef rtx (*rtxfun) (rtx); | ||
| 20339 | +typedef rtx (*rtxfun) (rtx, ...); | ||
| 20340 | |||
| 20341 | /* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...) | ||
| 20342 | gives the gen_function to make a branch to test that condition. */ | ||
| 20343 | Binary files gcc-4.0.2/gcc/po/be.gmo and gcc-4.0.2-atmel.0.99.2/gcc/po/be.gmo differ | ||
| 20344 | Binary files gcc-4.0.2/gcc/po/ca.gmo and gcc-4.0.2-atmel.0.99.2/gcc/po/ca.gmo differ | ||
| 20345 | Binary files gcc-4.0.2/gcc/po/da.gmo and gcc-4.0.2-atmel.0.99.2/gcc/po/da.gmo differ | ||
| 20346 | Binary files gcc-4.0.2/gcc/po/de.gmo and gcc-4.0.2-atmel.0.99.2/gcc/po/de.gmo differ | ||
| 20347 | Binary files gcc-4.0.2/gcc/po/el.gmo and gcc-4.0.2-atmel.0.99.2/gcc/po/el.gmo differ | ||
| 20348 | Binary files gcc-4.0.2/gcc/po/es.gmo and gcc-4.0.2-atmel.0.99.2/gcc/po/es.gmo differ | ||
| 20349 | Binary files gcc-4.0.2/gcc/po/fr.gmo and gcc-4.0.2-atmel.0.99.2/gcc/po/fr.gmo differ | ||
| 20350 | Binary files gcc-4.0.2/gcc/po/ja.gmo and gcc-4.0.2-atmel.0.99.2/gcc/po/ja.gmo differ | ||
| 20351 | Binary files gcc-4.0.2/gcc/po/nl.gmo and gcc-4.0.2-atmel.0.99.2/gcc/po/nl.gmo differ | ||
| 20352 | Binary files gcc-4.0.2/gcc/po/sv.gmo and gcc-4.0.2-atmel.0.99.2/gcc/po/sv.gmo differ | ||
| 20353 | Binary files gcc-4.0.2/gcc/po/tr.gmo and gcc-4.0.2-atmel.0.99.2/gcc/po/tr.gmo differ | ||
| 20354 | Binary files gcc-4.0.2/gcc/po/zh_CN.gmo and gcc-4.0.2-atmel.0.99.2/gcc/po/zh_CN.gmo differ | ||
| 20355 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/testsuite/gcc.dg/cpp/mac-eol-at-eof.c gcc-4.0.2-atmel.0.99.2/gcc/testsuite/gcc.dg/cpp/mac-eol-at-eof.c | ||
| 20356 | --- gcc-4.0.2/gcc/testsuite/gcc.dg/cpp/mac-eol-at-eof.c 2005-02-19 20:48:02.000000000 +0100 | ||
| 20357 | +++ gcc-4.0.2-atmel.0.99.2/gcc/testsuite/gcc.dg/cpp/mac-eol-at-eof.c 2005-06-07 14:06:28.000000000 +0200 | ||
| 20358 | @@ -1 +1,3 @@ | ||
| 20359 | -/* Test no newline at eof warning when Mac line ending is used*/ /* { dg-do compile } */ int main() { return 0; } | ||
| 20360 | \ No newline at end of file | ||
| 20361 | +/* Test no newline at eof warning when Mac line ending is used*/ | ||
| 20362 | +/* { dg-do compile } */ | ||
| 20363 | +int main() { return 0; } | ||
| 20364 | diff -Nrup --ignore-space-change gcc-4.0.2/gcc/tree-ssa-operands.c gcc-4.0.2-atmel.0.99.2/gcc/tree-ssa-operands.c | ||
| 20365 | --- gcc-4.0.2/gcc/tree-ssa-operands.c 2005-06-24 15:23:42.000000000 +0200 | ||
| 20366 | +++ gcc-4.0.2-atmel.0.99.2/gcc/tree-ssa-operands.c 2005-07-15 16:06:29.000000000 +0200 | ||
| 20367 | @@ -1135,7 +1135,7 @@ get_expr_operands (tree stmt, tree *expr | ||
| 20368 | |||
| 20369 | if (code == COMPONENT_REF) | ||
| 20370 | { | ||
| 20371 | - if (s_ann && TREE_THIS_VOLATILE (TREE_OPERAND (expr, 1))) | ||
| 20372 | + if (TREE_THIS_VOLATILE (TREE_OPERAND (expr, 1))) | ||
| 20373 | s_ann->has_volatile_ops = true; | ||
| 20374 | get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none); | ||
| 20375 | } | ||
| 20376 | diff -Nrup --ignore-space-change gcc-4.0.2/libcpp/po/sv.po gcc-4.0.2-atmel.0.99.2/libcpp/po/sv.po | ||
| 20377 | --- gcc-4.0.2/libcpp/po/sv.po 2005-09-04 14:30:22.000000000 +0200 | ||
| 20378 | +++ gcc-4.0.2-atmel.0.99.2/libcpp/po/sv.po 2006-01-20 10:54:31.000000000 +0100 | ||
| 20379 | @@ -2,7 +2,7 @@ | ||
| 20380 | # Copyright © 2000, 2005 Free Software Foundation, Inc. | ||
| 20381 | # Dennis Björklund <db@zigo.dhs.org>, 2000, 2001, 2002. | ||
| 20382 | # Göran Uddeborg <goeran@uddeborg.se>, 2005. | ||
| 20383 | -# $Revision: 1.2 $ | ||
| 20384 | +# $Revision: 3550 $ | ||
| 20385 | # | ||
| 20386 | msgid "" | ||
| 20387 | msgstr "" | ||
| 20388 | Binary files gcc-4.0.2/libcpp/po/tr.gmo and gcc-4.0.2-atmel.0.99.2/libcpp/po/tr.gmo differ | ||
| 20389 | Binary files gcc-4.0.2/libcpp/po/vi.gmo and gcc-4.0.2-atmel.0.99.2/libcpp/po/vi.gmo differ | ||
| 20390 | diff -Nrup --ignore-space-change gcc-4.0.2/libffi/src/frv/eabi.S gcc-4.0.2-atmel.0.99.2/libffi/src/frv/eabi.S | ||
| 20391 | --- gcc-4.0.2/libffi/src/frv/eabi.S 2004-08-30 17:43:03.000000000 +0200 | ||
| 20392 | +++ gcc-4.0.2-atmel.0.99.2/libffi/src/frv/eabi.S 2005-07-15 16:26:03.000000000 +0200 | ||
| 20393 | @@ -3,7 +3,7 @@ | ||
| 20394 | |||
| 20395 | FR-V Assembly glue. | ||
| 20396 | |||
| 20397 | - $Id: sysv.S,v 1.1.1.1 1998/11/29 16:48:16 green Exp $ | ||
| 20398 | + $Id: eabi.S 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20399 | |||
| 20400 | Permission is hereby granted, free of charge, to any person obtaining | ||
| 20401 | a copy of this software and associated documentation files (the | ||
| 20402 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/AttributeList.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/AttributeList.java | ||
| 20403 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/AttributeList.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20404 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/AttributeList.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20405 | @@ -1,7 +1,7 @@ | ||
| 20406 | // SAX Attribute List Interface. | ||
| 20407 | // http://www.saxproject.org | ||
| 20408 | // No warranty; no copyright -- use this as you will. | ||
| 20409 | -// $Id: AttributeList.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20410 | +// $Id: AttributeList.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20411 | |||
| 20412 | package org.xml.sax; | ||
| 20413 | |||
| 20414 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/Attributes.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/Attributes.java | ||
| 20415 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/Attributes.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20416 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/Attributes.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20417 | @@ -2,7 +2,7 @@ | ||
| 20418 | // http://www.saxproject.org | ||
| 20419 | // Written by David Megginson | ||
| 20420 | // NO WARRANTY! This class is in the public domain. | ||
| 20421 | -// $Id: Attributes.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20422 | +// $Id: Attributes.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20423 | |||
| 20424 | package org.xml.sax; | ||
| 20425 | |||
| 20426 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/ContentHandler.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ContentHandler.java | ||
| 20427 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/ContentHandler.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20428 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ContentHandler.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20429 | @@ -2,7 +2,7 @@ | ||
| 20430 | // http://www.saxproject.org | ||
| 20431 | // Written by David Megginson | ||
| 20432 | // NO WARRANTY! This class is in the public domain. | ||
| 20433 | -// $Id: ContentHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20434 | +// $Id: ContentHandler.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20435 | |||
| 20436 | package org.xml.sax; | ||
| 20437 | |||
| 20438 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/DocumentHandler.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/DocumentHandler.java | ||
| 20439 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/DocumentHandler.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20440 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/DocumentHandler.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20441 | @@ -1,7 +1,7 @@ | ||
| 20442 | // SAX document handler. | ||
| 20443 | // http://www.saxproject.org | ||
| 20444 | // No warranty; no copyright -- use this as you will. | ||
| 20445 | -// $Id: DocumentHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20446 | +// $Id: DocumentHandler.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20447 | |||
| 20448 | package org.xml.sax; | ||
| 20449 | |||
| 20450 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/DTDHandler.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/DTDHandler.java | ||
| 20451 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/DTDHandler.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20452 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/DTDHandler.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20453 | @@ -1,7 +1,7 @@ | ||
| 20454 | // SAX DTD handler. | ||
| 20455 | // http://www.saxproject.org | ||
| 20456 | // No warranty; no copyright -- use this as you will. | ||
| 20457 | -// $Id: DTDHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20458 | +// $Id: DTDHandler.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20459 | |||
| 20460 | package org.xml.sax; | ||
| 20461 | |||
| 20462 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/EntityResolver.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/EntityResolver.java | ||
| 20463 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/EntityResolver.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20464 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/EntityResolver.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20465 | @@ -1,7 +1,7 @@ | ||
| 20466 | // SAX entity resolver. | ||
| 20467 | // http://www.saxproject.org | ||
| 20468 | // No warranty; no copyright -- use this as you will. | ||
| 20469 | -// $Id: EntityResolver.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20470 | +// $Id: EntityResolver.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20471 | |||
| 20472 | package org.xml.sax; | ||
| 20473 | |||
| 20474 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/ErrorHandler.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ErrorHandler.java | ||
| 20475 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/ErrorHandler.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20476 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ErrorHandler.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20477 | @@ -1,7 +1,7 @@ | ||
| 20478 | // SAX error handler. | ||
| 20479 | // http://www.saxproject.org | ||
| 20480 | // No warranty; no copyright -- use this as you will. | ||
| 20481 | -// $Id: ErrorHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20482 | +// $Id: ErrorHandler.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20483 | |||
| 20484 | package org.xml.sax; | ||
| 20485 | |||
| 20486 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/Attributes2Impl.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/Attributes2Impl.java | ||
| 20487 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/Attributes2Impl.java 2005-02-02 01:41:52.000000000 +0100 | ||
| 20488 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/Attributes2Impl.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20489 | @@ -1,7 +1,7 @@ | ||
| 20490 | // Attributes2Impl.java - extended AttributesImpl | ||
| 20491 | // http://www.saxproject.org | ||
| 20492 | // Public Domain: no warranty. | ||
| 20493 | -// $Id: Attributes2Impl.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20494 | +// $Id: Attributes2Impl.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20495 | |||
| 20496 | package org.xml.sax.ext; | ||
| 20497 | |||
| 20498 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/Attributes2.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/Attributes2.java | ||
| 20499 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/Attributes2.java 2005-02-02 01:41:52.000000000 +0100 | ||
| 20500 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/Attributes2.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20501 | @@ -1,7 +1,7 @@ | ||
| 20502 | // Attributes2.java - extended Attributes | ||
| 20503 | // http://www.saxproject.org | ||
| 20504 | // Public Domain: no warranty. | ||
| 20505 | -// $Id: Attributes2.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20506 | +// $Id: Attributes2.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20507 | |||
| 20508 | package org.xml.sax.ext; | ||
| 20509 | |||
| 20510 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/DeclHandler.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/DeclHandler.java | ||
| 20511 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/DeclHandler.java 2005-02-02 01:41:52.000000000 +0100 | ||
| 20512 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/DeclHandler.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20513 | @@ -1,7 +1,7 @@ | ||
| 20514 | // DeclHandler.java - Optional handler for DTD declaration events. | ||
| 20515 | // http://www.saxproject.org | ||
| 20516 | // Public Domain: no warranty. | ||
| 20517 | -// $Id: DeclHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20518 | +// $Id: DeclHandler.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20519 | |||
| 20520 | package org.xml.sax.ext; | ||
| 20521 | |||
| 20522 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/DefaultHandler2.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/DefaultHandler2.java | ||
| 20523 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/DefaultHandler2.java 2005-02-02 01:41:52.000000000 +0100 | ||
| 20524 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/DefaultHandler2.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20525 | @@ -1,7 +1,7 @@ | ||
| 20526 | // DefaultHandler2.java - extended DefaultHandler | ||
| 20527 | // http://www.saxproject.org | ||
| 20528 | // Public Domain: no warranty. | ||
| 20529 | -// $Id: DefaultHandler2.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20530 | +// $Id: DefaultHandler2.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20531 | |||
| 20532 | package org.xml.sax.ext; | ||
| 20533 | |||
| 20534 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/EntityResolver2.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/EntityResolver2.java | ||
| 20535 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/EntityResolver2.java 2005-02-02 01:41:52.000000000 +0100 | ||
| 20536 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/EntityResolver2.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20537 | @@ -1,7 +1,7 @@ | ||
| 20538 | // EntityResolver2.java - Extended SAX entity resolver. | ||
| 20539 | // http://www.saxproject.org | ||
| 20540 | // No warranty; no copyright -- use this as you will. | ||
| 20541 | -// $Id: EntityResolver2.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20542 | +// $Id: EntityResolver2.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20543 | |||
| 20544 | package org.xml.sax.ext; | ||
| 20545 | |||
| 20546 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/LexicalHandler.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/LexicalHandler.java | ||
| 20547 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/LexicalHandler.java 2005-02-02 01:41:52.000000000 +0100 | ||
| 20548 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/LexicalHandler.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20549 | @@ -1,7 +1,7 @@ | ||
| 20550 | // LexicalHandler.java - optional handler for lexical parse events. | ||
| 20551 | // http://www.saxproject.org | ||
| 20552 | // Public Domain: no warranty. | ||
| 20553 | -// $Id: LexicalHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20554 | +// $Id: LexicalHandler.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20555 | |||
| 20556 | package org.xml.sax.ext; | ||
| 20557 | |||
| 20558 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/Locator2Impl.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/Locator2Impl.java | ||
| 20559 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/Locator2Impl.java 2005-02-02 01:41:52.000000000 +0100 | ||
| 20560 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/Locator2Impl.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20561 | @@ -1,7 +1,7 @@ | ||
| 20562 | // Locator2Impl.java - extended LocatorImpl | ||
| 20563 | // http://www.saxproject.org | ||
| 20564 | // Public Domain: no warranty. | ||
| 20565 | -// $Id: Locator2Impl.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20566 | +// $Id: Locator2Impl.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20567 | |||
| 20568 | package org.xml.sax.ext; | ||
| 20569 | |||
| 20570 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/Locator2.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/Locator2.java | ||
| 20571 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/Locator2.java 2005-02-02 01:41:52.000000000 +0100 | ||
| 20572 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/Locator2.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20573 | @@ -1,7 +1,7 @@ | ||
| 20574 | // Locator2.java - extended Locator | ||
| 20575 | // http://www.saxproject.org | ||
| 20576 | // Public Domain: no warranty. | ||
| 20577 | -// $Id: Locator2.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20578 | +// $Id: Locator2.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20579 | |||
| 20580 | package org.xml.sax.ext; | ||
| 20581 | |||
| 20582 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/package.html gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/package.html | ||
| 20583 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/ext/package.html 2005-02-02 01:41:52.000000000 +0100 | ||
| 20584 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/ext/package.html 2005-07-15 16:26:03.000000000 +0200 | ||
| 20585 | @@ -1,5 +1,5 @@ | ||
| 20586 | <HTML><HEAD> | ||
| 20587 | -<!-- $Id: package.html,v 1.1 2004/12/23 22:38:42 mark Exp $ --> | ||
| 20588 | +<!-- $Id: package.html 3484 2005-07-15 14:26:03Z rpedersen $ --> | ||
| 20589 | </HEAD><BODY> | ||
| 20590 | |||
| 20591 | <p> | ||
| 20592 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/HandlerBase.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/HandlerBase.java | ||
| 20593 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/HandlerBase.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20594 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/HandlerBase.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20595 | @@ -1,7 +1,7 @@ | ||
| 20596 | // SAX default handler base class. | ||
| 20597 | // http://www.saxproject.org | ||
| 20598 | // No warranty; no copyright -- use this as you will. | ||
| 20599 | -// $Id: HandlerBase.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20600 | +// $Id: HandlerBase.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20601 | |||
| 20602 | package org.xml.sax; | ||
| 20603 | |||
| 20604 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/AttributeListImpl.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/AttributeListImpl.java | ||
| 20605 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/AttributeListImpl.java 2005-02-02 01:41:53.000000000 +0100 | ||
| 20606 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/AttributeListImpl.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20607 | @@ -1,7 +1,7 @@ | ||
| 20608 | // SAX default implementation for AttributeList. | ||
| 20609 | // http://www.saxproject.org | ||
| 20610 | // No warranty; no copyright -- use this as you will. | ||
| 20611 | -// $Id: AttributeListImpl.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20612 | +// $Id: AttributeListImpl.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20613 | |||
| 20614 | package org.xml.sax.helpers; | ||
| 20615 | |||
| 20616 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/AttributesImpl.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/AttributesImpl.java | ||
| 20617 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/AttributesImpl.java 2005-02-02 01:41:54.000000000 +0100 | ||
| 20618 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/AttributesImpl.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20619 | @@ -2,7 +2,7 @@ | ||
| 20620 | // http://www.saxproject.org | ||
| 20621 | // Written by David Megginson | ||
| 20622 | // NO WARRANTY! This class is in the public domain. | ||
| 20623 | -// $Id: AttributesImpl.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20624 | +// $Id: AttributesImpl.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20625 | |||
| 20626 | package org.xml.sax.helpers; | ||
| 20627 | |||
| 20628 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/DefaultHandler.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/DefaultHandler.java | ||
| 20629 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/DefaultHandler.java 2005-02-02 01:41:54.000000000 +0100 | ||
| 20630 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/DefaultHandler.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20631 | @@ -2,7 +2,7 @@ | ||
| 20632 | // http://www.saxproject.org | ||
| 20633 | // Written by David Megginson | ||
| 20634 | // NO WARRANTY! This class is in the public domain. | ||
| 20635 | -// $Id: DefaultHandler.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20636 | +// $Id: DefaultHandler.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20637 | |||
| 20638 | package org.xml.sax.helpers; | ||
| 20639 | |||
| 20640 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/LocatorImpl.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/LocatorImpl.java | ||
| 20641 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/LocatorImpl.java 2005-02-02 01:41:54.000000000 +0100 | ||
| 20642 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/LocatorImpl.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20643 | @@ -1,7 +1,7 @@ | ||
| 20644 | // SAX default implementation for Locator. | ||
| 20645 | // http://www.saxproject.org | ||
| 20646 | // No warranty; no copyright -- use this as you will. | ||
| 20647 | -// $Id: LocatorImpl.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20648 | +// $Id: LocatorImpl.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20649 | |||
| 20650 | package org.xml.sax.helpers; | ||
| 20651 | |||
| 20652 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/NamespaceSupport.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/NamespaceSupport.java | ||
| 20653 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/NamespaceSupport.java 2005-04-06 23:38:28.000000000 +0200 | ||
| 20654 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/NamespaceSupport.java 2005-06-07 14:06:28.000000000 +0200 | ||
| 20655 | @@ -2,7 +2,7 @@ | ||
| 20656 | // http://www.saxproject.org | ||
| 20657 | // Written by David Megginson | ||
| 20658 | // This class is in the Public Domain. NO WARRANTY! | ||
| 20659 | -// $Id: NamespaceSupport.java,v 1.2 2005/03/24 00:04:07 tromey Exp $ | ||
| 20660 | +// $Id: NamespaceSupport.java 3462 2005-06-07 12:06:28Z rpedersen $ | ||
| 20661 | |||
| 20662 | package org.xml.sax.helpers; | ||
| 20663 | |||
| 20664 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/NewInstance.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/NewInstance.java | ||
| 20665 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/NewInstance.java 2005-02-02 01:41:54.000000000 +0100 | ||
| 20666 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/NewInstance.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20667 | @@ -3,7 +3,7 @@ | ||
| 20668 | // Written by Edwin Goei, edwingo@apache.org | ||
| 20669 | // and by David Brownell, dbrownell@users.sourceforge.net | ||
| 20670 | // NO WARRANTY! This class is in the Public Domain. | ||
| 20671 | -// $Id: NewInstance.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20672 | +// $Id: NewInstance.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20673 | |||
| 20674 | package org.xml.sax.helpers; | ||
| 20675 | |||
| 20676 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/package.html gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/package.html | ||
| 20677 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/package.html 2005-02-02 01:41:54.000000000 +0100 | ||
| 20678 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/package.html 2005-07-15 16:26:03.000000000 +0200 | ||
| 20679 | @@ -1,5 +1,5 @@ | ||
| 20680 | <HTML><HEAD> | ||
| 20681 | -<!-- $Id: package.html,v 1.1 2004/12/23 22:38:42 mark Exp $ --> | ||
| 20682 | +<!-- $Id: package.html 3484 2005-07-15 14:26:03Z rpedersen $ --> | ||
| 20683 | </HEAD><BODY> | ||
| 20684 | |||
| 20685 | <p>This package contains "helper" classes, including | ||
| 20686 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/ParserAdapter.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/ParserAdapter.java | ||
| 20687 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/ParserAdapter.java 2005-02-02 01:41:54.000000000 +0100 | ||
| 20688 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/ParserAdapter.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20689 | @@ -2,7 +2,7 @@ | ||
| 20690 | // http://www.saxproject.org | ||
| 20691 | // Written by David Megginson | ||
| 20692 | // NO WARRANTY! This class is in the public domain. | ||
| 20693 | -// $Id: ParserAdapter.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20694 | +// $Id: ParserAdapter.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20695 | |||
| 20696 | package org.xml.sax.helpers; | ||
| 20697 | |||
| 20698 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/ParserFactory.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/ParserFactory.java | ||
| 20699 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/ParserFactory.java 2005-02-02 01:41:54.000000000 +0100 | ||
| 20700 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/ParserFactory.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20701 | @@ -1,7 +1,7 @@ | ||
| 20702 | // SAX parser factory. | ||
| 20703 | // http://www.saxproject.org | ||
| 20704 | // No warranty; no copyright -- use this as you will. | ||
| 20705 | -// $Id: ParserFactory.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20706 | +// $Id: ParserFactory.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20707 | |||
| 20708 | package org.xml.sax.helpers; | ||
| 20709 | |||
| 20710 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/XMLFilterImpl.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/XMLFilterImpl.java | ||
| 20711 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/XMLFilterImpl.java 2005-02-02 01:41:54.000000000 +0100 | ||
| 20712 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/XMLFilterImpl.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20713 | @@ -2,7 +2,7 @@ | ||
| 20714 | // http://www.saxproject.org | ||
| 20715 | // Written by David Megginson | ||
| 20716 | // NO WARRANTY! This class is in the Public Domain. | ||
| 20717 | -// $Id: XMLFilterImpl.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20718 | +// $Id: XMLFilterImpl.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20719 | |||
| 20720 | package org.xml.sax.helpers; | ||
| 20721 | |||
| 20722 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/XMLReaderAdapter.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/XMLReaderAdapter.java | ||
| 20723 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/XMLReaderAdapter.java 2005-02-02 01:41:54.000000000 +0100 | ||
| 20724 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/XMLReaderAdapter.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20725 | @@ -2,7 +2,7 @@ | ||
| 20726 | // http://www.saxproject.org | ||
| 20727 | // Written by David Megginson | ||
| 20728 | // NO WARRANTY! This class is in the public domain. | ||
| 20729 | -// $Id: XMLReaderAdapter.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20730 | +// $Id: XMLReaderAdapter.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20731 | |||
| 20732 | package org.xml.sax.helpers; | ||
| 20733 | |||
| 20734 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/XMLReaderFactory.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/XMLReaderFactory.java | ||
| 20735 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/helpers/XMLReaderFactory.java 2005-02-02 01:41:54.000000000 +0100 | ||
| 20736 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/helpers/XMLReaderFactory.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20737 | @@ -3,7 +3,7 @@ | ||
| 20738 | // Written by David Megginson | ||
| 20739 | // and by David Brownell | ||
| 20740 | // NO WARRANTY! This class is in the Public Domain. | ||
| 20741 | -// $Id: XMLReaderFactory.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20742 | +// $Id: XMLReaderFactory.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20743 | |||
| 20744 | package org.xml.sax.helpers; | ||
| 20745 | import java.io.BufferedReader; | ||
| 20746 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/InputSource.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/InputSource.java | ||
| 20747 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/InputSource.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20748 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/InputSource.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20749 | @@ -1,7 +1,7 @@ | ||
| 20750 | // SAX input source. | ||
| 20751 | // http://www.saxproject.org | ||
| 20752 | // No warranty; no copyright -- use this as you will. | ||
| 20753 | -// $Id: InputSource.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20754 | +// $Id: InputSource.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20755 | |||
| 20756 | package org.xml.sax; | ||
| 20757 | |||
| 20758 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/Locator.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/Locator.java | ||
| 20759 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/Locator.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20760 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/Locator.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20761 | @@ -1,7 +1,7 @@ | ||
| 20762 | // SAX locator interface for document events. | ||
| 20763 | // http://www.saxproject.org | ||
| 20764 | // No warranty; no copyright -- use this as you will. | ||
| 20765 | -// $Id: Locator.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20766 | +// $Id: Locator.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20767 | |||
| 20768 | package org.xml.sax; | ||
| 20769 | |||
| 20770 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/package.html gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/package.html | ||
| 20771 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/package.html 2005-02-02 01:41:51.000000000 +0100 | ||
| 20772 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/package.html 2005-07-15 16:26:03.000000000 +0200 | ||
| 20773 | @@ -1,5 +1,5 @@ | ||
| 20774 | <html><head> | ||
| 20775 | -<!-- $Id: package.html,v 1.1 2004/12/23 22:38:42 mark Exp $ --> | ||
| 20776 | +<!-- $Id: package.html 3484 2005-07-15 14:26:03Z rpedersen $ --> | ||
| 20777 | </head><body> | ||
| 20778 | |||
| 20779 | <p> This package provides the core SAX APIs. | ||
| 20780 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/Parser.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/Parser.java | ||
| 20781 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/Parser.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20782 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/Parser.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20783 | @@ -1,7 +1,7 @@ | ||
| 20784 | // SAX parser interface. | ||
| 20785 | // http://www.saxproject.org | ||
| 20786 | // No warranty; no copyright -- use this as you will. | ||
| 20787 | -// $Id: Parser.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20788 | +// $Id: Parser.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20789 | |||
| 20790 | package org.xml.sax; | ||
| 20791 | |||
| 20792 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/SAXException.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/SAXException.java | ||
| 20793 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/SAXException.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20794 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/SAXException.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20795 | @@ -1,7 +1,7 @@ | ||
| 20796 | // SAX exception class. | ||
| 20797 | // http://www.saxproject.org | ||
| 20798 | // No warranty; no copyright -- use this as you will. | ||
| 20799 | -// $Id: SAXException.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20800 | +// $Id: SAXException.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20801 | |||
| 20802 | package org.xml.sax; | ||
| 20803 | |||
| 20804 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/SAXNotRecognizedException.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/SAXNotRecognizedException.java | ||
| 20805 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/SAXNotRecognizedException.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20806 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/SAXNotRecognizedException.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20807 | @@ -2,7 +2,7 @@ | ||
| 20808 | // http://www.saxproject.org | ||
| 20809 | // Written by David Megginson | ||
| 20810 | // NO WARRANTY! This class is in the Public Domain. | ||
| 20811 | -// $Id: SAXNotRecognizedException.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20812 | +// $Id: SAXNotRecognizedException.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20813 | |||
| 20814 | package org.xml.sax; | ||
| 20815 | |||
| 20816 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/SAXNotSupportedException.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/SAXNotSupportedException.java | ||
| 20817 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/SAXNotSupportedException.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20818 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/SAXNotSupportedException.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20819 | @@ -2,7 +2,7 @@ | ||
| 20820 | // http://www.saxproject.org | ||
| 20821 | // Written by David Megginson | ||
| 20822 | // NO WARRANTY! This class is in the Public Domain. | ||
| 20823 | -// $Id: SAXNotSupportedException.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20824 | +// $Id: SAXNotSupportedException.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20825 | |||
| 20826 | package org.xml.sax; | ||
| 20827 | |||
| 20828 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/SAXParseException.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/SAXParseException.java | ||
| 20829 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/SAXParseException.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20830 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/SAXParseException.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20831 | @@ -1,7 +1,7 @@ | ||
| 20832 | // SAX exception class. | ||
| 20833 | // http://www.saxproject.org | ||
| 20834 | // No warranty; no copyright -- use this as you will. | ||
| 20835 | -// $Id: SAXParseException.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20836 | +// $Id: SAXParseException.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20837 | |||
| 20838 | package org.xml.sax; | ||
| 20839 | |||
| 20840 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/XMLFilter.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/XMLFilter.java | ||
| 20841 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/XMLFilter.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20842 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/XMLFilter.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20843 | @@ -2,7 +2,7 @@ | ||
| 20844 | // http://www.saxproject.org | ||
| 20845 | // Written by David Megginson | ||
| 20846 | // NO WARRANTY! This class is in the Public Domain. | ||
| 20847 | -// $Id: XMLFilter.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20848 | +// $Id: XMLFilter.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20849 | |||
| 20850 | package org.xml.sax; | ||
| 20851 | |||
| 20852 | diff -Nrup --ignore-space-change gcc-4.0.2/libjava/external/sax/org/xml/sax/XMLReader.java gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/XMLReader.java | ||
| 20853 | --- gcc-4.0.2/libjava/external/sax/org/xml/sax/XMLReader.java 2005-02-02 01:41:51.000000000 +0100 | ||
| 20854 | +++ gcc-4.0.2-atmel.0.99.2/libjava/external/sax/org/xml/sax/XMLReader.java 2005-07-15 16:26:03.000000000 +0200 | ||
| 20855 | @@ -2,7 +2,7 @@ | ||
| 20856 | // http://www.saxproject.org | ||
| 20857 | // Written by David Megginson | ||
| 20858 | // NO WARRANTY! This class is in the Public Domain. | ||
| 20859 | -// $Id: XMLReader.java,v 1.1 2004/12/23 22:38:42 mark Exp $ | ||
| 20860 | +// $Id: XMLReader.java 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 20861 | |||
| 20862 | package org.xml.sax; | ||
| 20863 | |||
| 20864 | Binary files gcc-4.0.2/libjava/gnu/java/awt/doc-files/BitwiseXORComposite-1.png and gcc-4.0.2-atmel.0.99.2/libjava/gnu/java/awt/doc-files/BitwiseXORComposite-1.png differ | ||
| 20865 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/Area-1.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/Area-1.png differ | ||
| 20866 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/CubicCurve2D-1.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/CubicCurve2D-1.png differ | ||
| 20867 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/CubicCurve2D-2.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/CubicCurve2D-2.png differ | ||
| 20868 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/CubicCurve2D-3.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/CubicCurve2D-3.png differ | ||
| 20869 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/CubicCurve2D-4.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/CubicCurve2D-4.png differ | ||
| 20870 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/CubicCurve2D-5.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/CubicCurve2D-5.png differ | ||
| 20871 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/Ellipse-1.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/Ellipse-1.png differ | ||
| 20872 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/GeneralPath-1.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/GeneralPath-1.png differ | ||
| 20873 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/QuadCurve2D-1.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/QuadCurve2D-1.png differ | ||
| 20874 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/QuadCurve2D-2.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/QuadCurve2D-2.png differ | ||
| 20875 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/QuadCurve2D-3.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/QuadCurve2D-3.png differ | ||
| 20876 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/QuadCurve2D-4.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/QuadCurve2D-4.png differ | ||
| 20877 | Binary files gcc-4.0.2/libjava/java/awt/geom/doc-files/QuadCurve2D-5.png and gcc-4.0.2-atmel.0.99.2/libjava/java/awt/geom/doc-files/QuadCurve2D-5.png differ | ||
| 20878 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/BevelBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/BevelBorder-1.png differ | ||
| 20879 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/BevelBorder-2.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/BevelBorder-2.png differ | ||
| 20880 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/BevelBorder-3.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/BevelBorder-3.png differ | ||
| 20881 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/EmptyBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/EmptyBorder-1.png differ | ||
| 20882 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/EtchedBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/EtchedBorder-1.png differ | ||
| 20883 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/EtchedBorder-2.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/EtchedBorder-2.png differ | ||
| 20884 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/LineBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/LineBorder-1.png differ | ||
| 20885 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/MatteBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/MatteBorder-1.png differ | ||
| 20886 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/MatteBorder-2.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/MatteBorder-2.png differ | ||
| 20887 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/MatteBorder-3.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/MatteBorder-3.png differ | ||
| 20888 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/MatteBorder-4.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/MatteBorder-4.png differ | ||
| 20889 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/MatteBorder-5.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/MatteBorder-5.png differ | ||
| 20890 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/MatteBorder-6.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/MatteBorder-6.png differ | ||
| 20891 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/SoftBevelBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/SoftBevelBorder-1.png differ | ||
| 20892 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/SoftBevelBorder-2.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/SoftBevelBorder-2.png differ | ||
| 20893 | Binary files gcc-4.0.2/libjava/javax/swing/border/doc-files/SoftBevelBorder-3.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/border/doc-files/SoftBevelBorder-3.png differ | ||
| 20894 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders-1.png differ | ||
| 20895 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders-2.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders-2.png differ | ||
| 20896 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.ButtonBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.ButtonBorder-1.png differ | ||
| 20897 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.FieldBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.FieldBorder-1.png differ | ||
| 20898 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.MarginBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.MarginBorder-1.png differ | ||
| 20899 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.MenuBarBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.MenuBarBorder-1.png differ | ||
| 20900 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.RadioButtonBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.RadioButtonBorder-1.png differ | ||
| 20901 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.SplitPaneBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.SplitPaneBorder-1.png differ | ||
| 20902 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.SplitPaneBorder-2.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.SplitPaneBorder-2.png differ | ||
| 20903 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.SplitPaneDividerBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.SplitPaneDividerBorder-1.png differ | ||
| 20904 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.ToggleButtonBorder-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicBorders.ToggleButtonBorder-1.png differ | ||
| 20905 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-1.png differ | ||
| 20906 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-2.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-2.png differ | ||
| 20907 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-3.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-3.png differ | ||
| 20908 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-4.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-4.png differ | ||
| 20909 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-5.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-5.png differ | ||
| 20910 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-6.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-6.png differ | ||
| 20911 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-7.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/basic/doc-files/BasicGraphicsUtils-7.png differ | ||
| 20912 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/doc-files/ComponentUI-1.dia and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/doc-files/ComponentUI-1.dia differ | ||
| 20913 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/doc-files/ComponentUI-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/doc-files/ComponentUI-1.png differ | ||
| 20914 | Binary files gcc-4.0.2/libjava/javax/swing/plaf/doc-files/TreeUI-1.png and gcc-4.0.2-atmel.0.99.2/libjava/javax/swing/plaf/doc-files/TreeUI-1.png differ | ||
| 20915 | Binary files gcc-4.0.2/libjava/testsuite/libjava.jar/simple.jar and gcc-4.0.2-atmel.0.99.2/libjava/testsuite/libjava.jar/simple.jar differ | ||
| 20916 | diff -Nrup --ignore-space-change gcc-4.0.2/libstdc++-v3/acinclude.m4 gcc-4.0.2-atmel.0.99.2/libstdc++-v3/acinclude.m4 | ||
| 20917 | --- gcc-4.0.2/libstdc++-v3/acinclude.m4 2005-06-23 11:23:59.000000000 +0200 | ||
| 20918 | +++ gcc-4.0.2-atmel.0.99.2/libstdc++-v3/acinclude.m4 2006-03-28 10:54:09.000000000 +0200 | ||
| 20919 | @@ -139,6 +139,15 @@ AC_DEFUN([GLIBCXX_CONFIGURE], [ | ||
| 20920 | #enable_symvers=no | ||
| 20921 | #enable_hosted_libstdcxx=yes | ||
| 20922 | |||
| 20923 | + # Check for uClibc since Linux platforms use different configuration | ||
| 20924 | + # directories depending on the C library in use. | ||
| 20925 | + AC_EGREP_CPP([_using_uclibc], [ | ||
| 20926 | + #include <stdio.h> | ||
| 20927 | + #if __UCLIBC__ | ||
| 20928 | + _using_uclibc | ||
| 20929 | + #endif | ||
| 20930 | + ], uclibc=yes, uclibc=no) | ||
| 20931 | + | ||
| 20932 | # Find platform-specific directories containing configuration info. | ||
| 20933 | # Also possibly modify flags used elsewhere, as needed by the platform. | ||
| 20934 | GLIBCXX_CHECK_HOST | ||
| 20935 | diff -Nrup --ignore-space-change gcc-4.0.2/libstdc++-v3/configure.host gcc-4.0.2-atmel.0.99.2/libstdc++-v3/configure.host | ||
| 20936 | --- gcc-4.0.2/libstdc++-v3/configure.host 2005-06-17 02:22:20.000000000 +0200 | ||
| 20937 | +++ gcc-4.0.2-atmel.0.99.2/libstdc++-v3/configure.host 2006-03-28 10:54:09.000000000 +0200 | ||
| 20938 | @@ -193,8 +193,15 @@ case "${host_os}" in | ||
| 20939 | freebsd*) | ||
| 20940 | os_include_dir="os/bsd/freebsd" | ||
| 20941 | ;; | ||
| 20942 | + linux-uclibc*) | ||
| 20943 | + os_include_dir="os/uclibc-linux" | ||
| 20944 | + ;; | ||
| 20945 | gnu* | linux* | kfreebsd*-gnu | knetbsd*-gnu) | ||
| 20946 | + if [ "$uclibc" = "yes" ]; then | ||
| 20947 | + os_include_dir="os/uclibc" | ||
| 20948 | + else | ||
| 20949 | os_include_dir="os/gnu-linux" | ||
| 20950 | + fi | ||
| 20951 | ;; | ||
| 20952 | hpux*) | ||
| 20953 | os_include_dir="os/hpux" | ||
| 20954 | diff -Nrup --ignore-space-change gcc-4.0.2/libstdc++-v3/crossconfig.m4 gcc-4.0.2-atmel.0.99.2/libstdc++-v3/crossconfig.m4 | ||
| 20955 | --- gcc-4.0.2/libstdc++-v3/crossconfig.m4 2005-02-01 07:56:19.000000000 +0100 | ||
| 20956 | +++ gcc-4.0.2-atmel.0.99.2/libstdc++-v3/crossconfig.m4 2006-03-28 10:54:09.000000000 +0200 | ||
| 20957 | @@ -148,9 +148,13 @@ case "${host}" in | ||
| 20958 | fp.h float.h endian.h inttypes.h locale.h float.h stdint.h]) | ||
| 20959 | SECTION_FLAGS='-ffunction-sections -fdata-sections' | ||
| 20960 | AC_SUBST(SECTION_FLAGS) | ||
| 20961 | + GLIBCXX_CHECK_COMPILER_FEATURES | ||
| 20962 | GLIBCXX_CHECK_LINKER_FEATURES | ||
| 20963 | + GLIBCXX_CHECK_MATH_SUPPORT | ||
| 20964 | + GLIBCXX_CHECK_BUILTIN_MATH_SUPPORT | ||
| 20965 | GLIBCXX_CHECK_COMPLEX_MATH_SUPPORT | ||
| 20966 | - GLIBCXX_CHECK_WCHAR_T_SUPPORT | ||
| 20967 | + GLIBCXX_CHECK_ICONV_SUPPORT | ||
| 20968 | + GLIBCXX_CHECK_STDLIB_SUPPORT | ||
| 20969 | |||
| 20970 | # For LFS. | ||
| 20971 | AC_DEFINE(HAVE_INT64_T) | ||
| 20972 | Binary files gcc-4.0.2/libstdc++-v3/docs/html/17_intro/confdeps.png and gcc-4.0.2-atmel.0.99.2/libstdc++-v3/docs/html/17_intro/confdeps.png differ | ||
| 20973 | diff -Nrup --ignore-space-change gcc-4.0.2/libstdc++-v3/include/Makefile.in gcc-4.0.2-atmel.0.99.2/libstdc++-v3/include/Makefile.in | ||
| 20974 | --- gcc-4.0.2/libstdc++-v3/include/Makefile.in 2005-06-22 22:39:09.000000000 +0200 | ||
| 20975 | +++ gcc-4.0.2-atmel.0.99.2/libstdc++-v3/include/Makefile.in 2006-03-28 10:54:09.000000000 +0200 | ||
| 20976 | @@ -1,8 +1,8 @@ | ||
| 20977 | -# Makefile.in generated by automake 1.9.3 from Makefile.am. | ||
| 20978 | +# Makefile.in generated by automake 1.9.6 from Makefile.am. | ||
| 20979 | # @configure_input@ | ||
| 20980 | |||
| 20981 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, | ||
| 20982 | -# 2003, 2004 Free Software Foundation, Inc. | ||
| 20983 | +# 2003, 2004, 2005 Free Software Foundation, Inc. | ||
| 20984 | # This Makefile.in is free software; the Free Software Foundation | ||
| 20985 | # gives unlimited permission to copy and/or distribute it, | ||
| 20986 | # with or without modifications, as long as this notice is preserved. | ||
| 20987 | @@ -36,6 +36,7 @@ POST_UNINSTALL = : | ||
| 20988 | build_triplet = @build@ | ||
| 20989 | host_triplet = @host@ | ||
| 20990 | target_triplet = @target@ | ||
| 20991 | +LIBOBJDIR = | ||
| 20992 | DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ | ||
| 20993 | $(top_srcdir)/fragment.am | ||
| 20994 | subdir = include | ||
| 20995 | diff -Nrup --ignore-space-change gcc-4.0.2/libstdc++-v3/libmath/Makefile.in gcc-4.0.2-atmel.0.99.2/libstdc++-v3/libmath/Makefile.in | ||
| 20996 | --- gcc-4.0.2/libstdc++-v3/libmath/Makefile.in 2005-06-22 22:39:18.000000000 +0200 | ||
| 20997 | +++ gcc-4.0.2-atmel.0.99.2/libstdc++-v3/libmath/Makefile.in 2006-03-28 10:54:09.000000000 +0200 | ||
| 20998 | @@ -1,8 +1,8 @@ | ||
| 20999 | -# Makefile.in generated by automake 1.9.3 from Makefile.am. | ||
| 21000 | +# Makefile.in generated by automake 1.9.6 from Makefile.am. | ||
| 21001 | # @configure_input@ | ||
| 21002 | |||
| 21003 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, | ||
| 21004 | -# 2003, 2004 Free Software Foundation, Inc. | ||
| 21005 | +# 2003, 2004, 2005 Free Software Foundation, Inc. | ||
| 21006 | # This Makefile.in is free software; the Free Software Foundation | ||
| 21007 | # gives unlimited permission to copy and/or distribute it, | ||
| 21008 | # with or without modifications, as long as this notice is preserved. | ||
| 21009 | @@ -14,8 +14,6 @@ | ||
| 21010 | |||
| 21011 | @SET_MAKE@ | ||
| 21012 | |||
| 21013 | -SOURCES = $(libmath_la_SOURCES) | ||
| 21014 | - | ||
| 21015 | srcdir = @srcdir@ | ||
| 21016 | top_srcdir = @top_srcdir@ | ||
| 21017 | VPATH = @srcdir@ | ||
| 21018 | @@ -39,6 +37,7 @@ POST_UNINSTALL = : | ||
| 21019 | build_triplet = @build@ | ||
| 21020 | host_triplet = @host@ | ||
| 21021 | target_triplet = @target@ | ||
| 21022 | +LIBOBJDIR = | ||
| 21023 | subdir = libmath | ||
| 21024 | DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in | ||
| 21025 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | ||
| 21026 | diff -Nrup --ignore-space-change gcc-4.0.2/libstdc++-v3/libsupc++/Makefile.in gcc-4.0.2-atmel.0.99.2/libstdc++-v3/libsupc++/Makefile.in | ||
| 21027 | --- gcc-4.0.2/libstdc++-v3/libsupc++/Makefile.in 2005-06-22 22:39:21.000000000 +0200 | ||
| 21028 | +++ gcc-4.0.2-atmel.0.99.2/libstdc++-v3/libsupc++/Makefile.in 2006-03-28 10:54:09.000000000 +0200 | ||
| 21029 | @@ -1,8 +1,8 @@ | ||
| 21030 | -# Makefile.in generated by automake 1.9.3 from Makefile.am. | ||
| 21031 | +# Makefile.in generated by automake 1.9.6 from Makefile.am. | ||
| 21032 | # @configure_input@ | ||
| 21033 | |||
| 21034 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, | ||
| 21035 | -# 2003, 2004 Free Software Foundation, Inc. | ||
| 21036 | +# 2003, 2004, 2005 Free Software Foundation, Inc. | ||
| 21037 | # This Makefile.in is free software; the Free Software Foundation | ||
| 21038 | # gives unlimited permission to copy and/or distribute it, | ||
| 21039 | # with or without modifications, as long as this notice is preserved. | ||
| 21040 | @@ -15,8 +15,6 @@ | ||
| 21041 | @SET_MAKE@ | ||
| 21042 | |||
| 21043 | |||
| 21044 | -SOURCES = $(libsupc___la_SOURCES) $(libsupc__convenience_la_SOURCES) | ||
| 21045 | - | ||
| 21046 | srcdir = @srcdir@ | ||
| 21047 | top_srcdir = @top_srcdir@ | ||
| 21048 | VPATH = @srcdir@ | ||
| 21049 | @@ -40,6 +38,7 @@ POST_UNINSTALL = : | ||
| 21050 | build_triplet = @build@ | ||
| 21051 | host_triplet = @host@ | ||
| 21052 | target_triplet = @target@ | ||
| 21053 | +LIBOBJDIR = | ||
| 21054 | DIST_COMMON = $(glibcxxinstall_HEADERS) $(srcdir)/Makefile.am \ | ||
| 21055 | $(srcdir)/Makefile.in $(top_srcdir)/fragment.am | ||
| 21056 | subdir = libsupc++ | ||
| 21057 | diff -Nrup --ignore-space-change gcc-4.0.2/libstdc++-v3/Makefile.in gcc-4.0.2-atmel.0.99.2/libstdc++-v3/Makefile.in | ||
| 21058 | --- gcc-4.0.2/libstdc++-v3/Makefile.in 2005-06-22 22:37:12.000000000 +0200 | ||
| 21059 | +++ gcc-4.0.2-atmel.0.99.2/libstdc++-v3/Makefile.in 2006-03-28 10:54:09.000000000 +0200 | ||
| 21060 | @@ -1,8 +1,8 @@ | ||
| 21061 | -# Makefile.in generated by automake 1.9.3 from Makefile.am. | ||
| 21062 | +# Makefile.in generated by automake 1.9.6 from Makefile.am. | ||
| 21063 | # @configure_input@ | ||
| 21064 | |||
| 21065 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, | ||
| 21066 | -# 2003, 2004 Free Software Foundation, Inc. | ||
| 21067 | +# 2003, 2004, 2005 Free Software Foundation, Inc. | ||
| 21068 | # This Makefile.in is free software; the Free Software Foundation | ||
| 21069 | # gives unlimited permission to copy and/or distribute it, | ||
| 21070 | # with or without modifications, as long as this notice is preserved. | ||
| 21071 | @@ -36,6 +36,7 @@ POST_UNINSTALL = : | ||
| 21072 | build_triplet = @build@ | ||
| 21073 | host_triplet = @host@ | ||
| 21074 | target_triplet = @target@ | ||
| 21075 | +LIBOBJDIR = | ||
| 21076 | DIST_COMMON = README $(am__configure_deps) $(srcdir)/../config.guess \ | ||
| 21077 | $(srcdir)/../config.sub $(srcdir)/../install-sh \ | ||
| 21078 | $(srcdir)/../ltmain.sh $(srcdir)/../missing \ | ||
| 21079 | @@ -408,7 +409,13 @@ uninstall-info-am: | ||
| 21080 | # (which will cause the Makefiles to be regenerated when you run `make'); | ||
| 21081 | # (2) otherwise, pass the desired values on the `make' command line. | ||
| 21082 | $(RECURSIVE_TARGETS): | ||
| 21083 | - @set fnord $$MAKEFLAGS; amf=$$2; \ | ||
| 21084 | + @failcom='exit 1'; \ | ||
| 21085 | + for f in x $$MAKEFLAGS; do \ | ||
| 21086 | + case $$f in \ | ||
| 21087 | + *=* | --[!k]*);; \ | ||
| 21088 | + *k*) failcom='fail=yes';; \ | ||
| 21089 | + esac; \ | ||
| 21090 | + done; \ | ||
| 21091 | dot_seen=no; \ | ||
| 21092 | target=`echo $@ | sed s/-recursive//`; \ | ||
| 21093 | list='$(SUBDIRS)'; for subdir in $$list; do \ | ||
| 21094 | @@ -420,7 +427,7 @@ $(RECURSIVE_TARGETS): | ||
| 21095 | local_target="$$target"; \ | ||
| 21096 | fi; \ | ||
| 21097 | (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ | ||
| 21098 | - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ | ||
| 21099 | + || eval $$failcom; \ | ||
| 21100 | done; \ | ||
| 21101 | if test "$$dot_seen" = "no"; then \ | ||
| 21102 | $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ | ||
| 21103 | @@ -428,7 +435,13 @@ $(RECURSIVE_TARGETS): | ||
| 21104 | |||
| 21105 | mostlyclean-recursive clean-recursive distclean-recursive \ | ||
| 21106 | maintainer-clean-recursive: | ||
| 21107 | - @set fnord $$MAKEFLAGS; amf=$$2; \ | ||
| 21108 | + @failcom='exit 1'; \ | ||
| 21109 | + for f in x $$MAKEFLAGS; do \ | ||
| 21110 | + case $$f in \ | ||
| 21111 | + *=* | --[!k]*);; \ | ||
| 21112 | + *k*) failcom='fail=yes';; \ | ||
| 21113 | + esac; \ | ||
| 21114 | + done; \ | ||
| 21115 | dot_seen=no; \ | ||
| 21116 | case "$@" in \ | ||
| 21117 | distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ | ||
| 21118 | @@ -449,7 +462,7 @@ maintainer-clean-recursive: | ||
| 21119 | local_target="$$target"; \ | ||
| 21120 | fi; \ | ||
| 21121 | (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ | ||
| 21122 | - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ | ||
| 21123 | + || eval $$failcom; \ | ||
| 21124 | done && test -z "$$fail" | ||
| 21125 | tags-recursive: | ||
| 21126 | list='$(SUBDIRS)'; for subdir in $$list; do \ | ||
| 21127 | diff -Nrup --ignore-space-change gcc-4.0.2/libstdc++-v3/po/Makefile.in gcc-4.0.2-atmel.0.99.2/libstdc++-v3/po/Makefile.in | ||
| 21128 | --- gcc-4.0.2/libstdc++-v3/po/Makefile.in 2005-06-22 22:39:24.000000000 +0200 | ||
| 21129 | +++ gcc-4.0.2-atmel.0.99.2/libstdc++-v3/po/Makefile.in 2006-03-28 10:54:09.000000000 +0200 | ||
| 21130 | @@ -1,8 +1,8 @@ | ||
| 21131 | -# Makefile.in generated by automake 1.9.3 from Makefile.am. | ||
| 21132 | +# Makefile.in generated by automake 1.9.6 from Makefile.am. | ||
| 21133 | # @configure_input@ | ||
| 21134 | |||
| 21135 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, | ||
| 21136 | -# 2003, 2004 Free Software Foundation, Inc. | ||
| 21137 | +# 2003, 2004, 2005 Free Software Foundation, Inc. | ||
| 21138 | # This Makefile.in is free software; the Free Software Foundation | ||
| 21139 | # gives unlimited permission to copy and/or distribute it, | ||
| 21140 | # with or without modifications, as long as this notice is preserved. | ||
| 21141 | @@ -36,6 +36,7 @@ POST_UNINSTALL = : | ||
| 21142 | build_triplet = @build@ | ||
| 21143 | host_triplet = @host@ | ||
| 21144 | target_triplet = @target@ | ||
| 21145 | +LIBOBJDIR = | ||
| 21146 | DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ | ||
| 21147 | $(top_srcdir)/fragment.am | ||
| 21148 | subdir = po | ||
| 21149 | diff -Nrup --ignore-space-change gcc-4.0.2/libstdc++-v3/src/Makefile.in gcc-4.0.2-atmel.0.99.2/libstdc++-v3/src/Makefile.in | ||
| 21150 | --- gcc-4.0.2/libstdc++-v3/src/Makefile.in 2005-06-22 22:39:26.000000000 +0200 | ||
| 21151 | +++ gcc-4.0.2-atmel.0.99.2/libstdc++-v3/src/Makefile.in 2006-03-28 10:54:09.000000000 +0200 | ||
| 21152 | @@ -1,8 +1,8 @@ | ||
| 21153 | -# Makefile.in generated by automake 1.9.3 from Makefile.am. | ||
| 21154 | +# Makefile.in generated by automake 1.9.6 from Makefile.am. | ||
| 21155 | # @configure_input@ | ||
| 21156 | |||
| 21157 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, | ||
| 21158 | -# 2003, 2004 Free Software Foundation, Inc. | ||
| 21159 | +# 2003, 2004, 2005 Free Software Foundation, Inc. | ||
| 21160 | # This Makefile.in is free software; the Free Software Foundation | ||
| 21161 | # gives unlimited permission to copy and/or distribute it, | ||
| 21162 | # with or without modifications, as long as this notice is preserved. | ||
| 21163 | @@ -14,8 +14,6 @@ | ||
| 21164 | |||
| 21165 | @SET_MAKE@ | ||
| 21166 | |||
| 21167 | -SOURCES = $(libstdc___la_SOURCES) | ||
| 21168 | - | ||
| 21169 | srcdir = @srcdir@ | ||
| 21170 | top_srcdir = @top_srcdir@ | ||
| 21171 | pkgdatadir = $(datadir)/@PACKAGE@ | ||
| 21172 | @@ -38,6 +36,7 @@ POST_UNINSTALL = : | ||
| 21173 | build_triplet = @build@ | ||
| 21174 | host_triplet = @host@ | ||
| 21175 | target_triplet = @target@ | ||
| 21176 | +LIBOBJDIR = | ||
| 21177 | DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ | ||
| 21178 | $(top_srcdir)/fragment.am | ||
| 21179 | subdir = src | ||
| 21180 | diff -Nrup --ignore-space-change gcc-4.0.2/libstdc++-v3/testsuite/Makefile.in gcc-4.0.2-atmel.0.99.2/libstdc++-v3/testsuite/Makefile.in | ||
| 21181 | --- gcc-4.0.2/libstdc++-v3/testsuite/Makefile.in 2005-06-22 22:39:30.000000000 +0200 | ||
| 21182 | +++ gcc-4.0.2-atmel.0.99.2/libstdc++-v3/testsuite/Makefile.in 2006-03-28 10:54:09.000000000 +0200 | ||
| 21183 | @@ -1,8 +1,8 @@ | ||
| 21184 | -# Makefile.in generated by automake 1.9.3 from Makefile.am. | ||
| 21185 | +# Makefile.in generated by automake 1.9.6 from Makefile.am. | ||
| 21186 | # @configure_input@ | ||
| 21187 | |||
| 21188 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, | ||
| 21189 | -# 2003, 2004 Free Software Foundation, Inc. | ||
| 21190 | +# 2003, 2004, 2005 Free Software Foundation, Inc. | ||
| 21191 | # This Makefile.in is free software; the Free Software Foundation | ||
| 21192 | # gives unlimited permission to copy and/or distribute it, | ||
| 21193 | # with or without modifications, as long as this notice is preserved. | ||
| 21194 | @@ -14,8 +14,6 @@ | ||
| 21195 | |||
| 21196 | @SET_MAKE@ | ||
| 21197 | |||
| 21198 | -SOURCES = $(libv3test_a_SOURCES) | ||
| 21199 | - | ||
| 21200 | srcdir = @srcdir@ | ||
| 21201 | top_srcdir = @top_srcdir@ | ||
| 21202 | VPATH = @srcdir@ | ||
| 21203 | @@ -39,6 +37,7 @@ POST_UNINSTALL = : | ||
| 21204 | build_triplet = @build@ | ||
| 21205 | host_triplet = @host@ | ||
| 21206 | target_triplet = @target@ | ||
| 21207 | +LIBOBJDIR = | ||
| 21208 | DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ | ||
| 21209 | $(top_srcdir)/fragment.am | ||
| 21210 | subdir = testsuite | ||
| 21211 | diff -Nrup --ignore-space-change gcc-4.0.2/zlib/contrib/ada/mtest.adb gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/mtest.adb | ||
| 21212 | --- gcc-4.0.2/zlib/contrib/ada/mtest.adb 2004-10-11 19:44:23.000000000 +0200 | ||
| 21213 | +++ gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/mtest.adb 2005-07-15 16:26:03.000000000 +0200 | ||
| 21214 | @@ -8,7 +8,7 @@ | ||
| 21215 | -- Continuous test for ZLib multithreading. If the test is fail | ||
| 21216 | -- Wou should provide thread safe allocation routines for the Z_Stream. | ||
| 21217 | -- | ||
| 21218 | --- $Id: mtest.adb,v 1.2 2003/08/12 12:11:05 vagul Exp $ | ||
| 21219 | +-- $Id: mtest.adb 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 21220 | |||
| 21221 | with ZLib; | ||
| 21222 | with Ada.Streams; | ||
| 21223 | diff -Nrup --ignore-space-change gcc-4.0.2/zlib/contrib/ada/read.adb gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/read.adb | ||
| 21224 | --- gcc-4.0.2/zlib/contrib/ada/read.adb 2004-10-11 19:44:23.000000000 +0200 | ||
| 21225 | +++ gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/read.adb 2005-07-15 16:26:03.000000000 +0200 | ||
| 21226 | @@ -6,7 +6,7 @@ | ||
| 21227 | -- Open source license information is in the zlib.ads file. -- | ||
| 21228 | ---------------------------------------------------------------- | ||
| 21229 | |||
| 21230 | --- $Id: read.adb,v 1.7 2003/08/12 12:12:35 vagul Exp $ | ||
| 21231 | +-- $Id: read.adb 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 21232 | |||
| 21233 | -- Test/demo program for the generic read interface. | ||
| 21234 | |||
| 21235 | diff -Nrup --ignore-space-change gcc-4.0.2/zlib/contrib/ada/test.adb gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/test.adb | ||
| 21236 | --- gcc-4.0.2/zlib/contrib/ada/test.adb 2004-10-11 19:44:23.000000000 +0200 | ||
| 21237 | +++ gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/test.adb 2005-07-15 16:26:03.000000000 +0200 | ||
| 21238 | @@ -6,7 +6,7 @@ | ||
| 21239 | -- Open source license information is in the zlib.ads file. -- | ||
| 21240 | ---------------------------------------------------------------- | ||
| 21241 | |||
| 21242 | --- $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $ | ||
| 21243 | +-- $Id: test.adb 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 21244 | |||
| 21245 | -- The program has a few aims. | ||
| 21246 | -- 1. Test ZLib.Ada95 thick binding functionality. | ||
| 21247 | diff -Nrup --ignore-space-change gcc-4.0.2/zlib/contrib/ada/zlib.adb gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/zlib.adb | ||
| 21248 | --- gcc-4.0.2/zlib/contrib/ada/zlib.adb 2004-10-11 19:44:23.000000000 +0200 | ||
| 21249 | +++ gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/zlib.adb 2005-07-15 16:26:03.000000000 +0200 | ||
| 21250 | @@ -6,7 +6,7 @@ | ||
| 21251 | -- Open source license information is in the zlib.ads file. -- | ||
| 21252 | ---------------------------------------------------------------- | ||
| 21253 | |||
| 21254 | --- $Id: zlib.adb,v 1.19 2003/07/13 16:02:19 vagul Exp $ | ||
| 21255 | +-- $Id: zlib.adb 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 21256 | |||
| 21257 | with Ada.Exceptions; | ||
| 21258 | with Ada.Unchecked_Conversion; | ||
| 21259 | diff -Nrup --ignore-space-change gcc-4.0.2/zlib/contrib/ada/zlib.ads gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/zlib.ads | ||
| 21260 | --- gcc-4.0.2/zlib/contrib/ada/zlib.ads 2004-10-11 19:44:23.000000000 +0200 | ||
| 21261 | +++ gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/zlib.ads 2005-07-15 16:26:03.000000000 +0200 | ||
| 21262 | @@ -25,7 +25,7 @@ | ||
| 21263 | -- covered by the GNU Public License. -- | ||
| 21264 | ------------------------------------------------------------------------------ | ||
| 21265 | |||
| 21266 | --- $Id: zlib.ads,v 1.17 2003/08/12 13:19:07 vagul Exp $ | ||
| 21267 | +-- $Id: zlib.ads 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 21268 | |||
| 21269 | with Ada.Streams; | ||
| 21270 | |||
| 21271 | diff -Nrup --ignore-space-change gcc-4.0.2/zlib/contrib/ada/zlib-streams.adb gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/zlib-streams.adb | ||
| 21272 | --- gcc-4.0.2/zlib/contrib/ada/zlib-streams.adb 2004-10-11 19:44:23.000000000 +0200 | ||
| 21273 | +++ gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/zlib-streams.adb 2005-07-15 16:26:03.000000000 +0200 | ||
| 21274 | @@ -6,7 +6,7 @@ | ||
| 21275 | -- Open source license information is in the zlib.ads file. -- | ||
| 21276 | ---------------------------------------------------------------- | ||
| 21277 | |||
| 21278 | --- $Id: zlib-streams.adb,v 1.9 2003/08/12 13:15:31 vagul Exp $ | ||
| 21279 | +-- $Id: zlib-streams.adb 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 21280 | |||
| 21281 | with Ada.Unchecked_Deallocation; | ||
| 21282 | |||
| 21283 | diff -Nrup --ignore-space-change gcc-4.0.2/zlib/contrib/ada/zlib-streams.ads gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/zlib-streams.ads | ||
| 21284 | --- gcc-4.0.2/zlib/contrib/ada/zlib-streams.ads 2004-10-11 19:44:23.000000000 +0200 | ||
| 21285 | +++ gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/zlib-streams.ads 2005-07-15 16:26:03.000000000 +0200 | ||
| 21286 | @@ -6,7 +6,7 @@ | ||
| 21287 | -- Open source license information is in the zlib.ads file. -- | ||
| 21288 | ---------------------------------------------------------------- | ||
| 21289 | |||
| 21290 | --- $Id: zlib-streams.ads,v 1.11 2003/08/12 13:15:31 vagul Exp $ | ||
| 21291 | +-- $Id: zlib-streams.ads 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 21292 | |||
| 21293 | package ZLib.Streams is | ||
| 21294 | |||
| 21295 | diff -Nrup --ignore-space-change gcc-4.0.2/zlib/contrib/ada/zlib-thin.adb gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/zlib-thin.adb | ||
| 21296 | --- gcc-4.0.2/zlib/contrib/ada/zlib-thin.adb 2004-10-11 19:44:23.000000000 +0200 | ||
| 21297 | +++ gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/zlib-thin.adb 2005-07-15 16:26:03.000000000 +0200 | ||
| 21298 | @@ -6,7 +6,7 @@ | ||
| 21299 | -- Open source license information is in the zlib.ads file. -- | ||
| 21300 | ---------------------------------------------------------------- | ||
| 21301 | |||
| 21302 | --- $Id: zlib-thin.adb,v 1.6 2003/01/21 15:26:37 vagul Exp $ | ||
| 21303 | +-- $Id: zlib-thin.adb 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 21304 | |||
| 21305 | package body ZLib.Thin is | ||
| 21306 | |||
| 21307 | diff -Nrup --ignore-space-change gcc-4.0.2/zlib/contrib/ada/zlib-thin.ads gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/zlib-thin.ads | ||
| 21308 | --- gcc-4.0.2/zlib/contrib/ada/zlib-thin.ads 2004-10-11 19:44:23.000000000 +0200 | ||
| 21309 | +++ gcc-4.0.2-atmel.0.99.2/zlib/contrib/ada/zlib-thin.ads 2005-07-15 16:26:03.000000000 +0200 | ||
| 21310 | @@ -6,7 +6,7 @@ | ||
| 21311 | -- Open source license information is in the zlib.ads file. -- | ||
| 21312 | ---------------------------------------------------------------- | ||
| 21313 | |||
| 21314 | --- $Id: zlib-thin.ads,v 1.8 2003/08/12 13:16:51 vagul Exp $ | ||
| 21315 | +-- $Id: zlib-thin.ads 3484 2005-07-15 14:26:03Z rpedersen $ | ||
| 21316 | |||
| 21317 | with Interfaces.C.Strings; | ||
| 21318 | with System.Address_To_Access_Conversions; | ||
| 21319 | diff -Nrup --ignore-space-change gcc-4.0.2/zlib/zconf.in.h gcc-4.0.2-atmel.0.99.2/zlib/zconf.in.h | ||
| 21320 | --- gcc-4.0.2/zlib/zconf.in.h 2004-10-11 19:44:14.000000000 +0200 | ||
| 21321 | +++ gcc-4.0.2-atmel.0.99.2/zlib/zconf.in.h 2005-07-15 16:26:03.000000000 +0200 | ||
| 21322 | @@ -3,7 +3,7 @@ | ||
| 21323 | * For conditions of distribution and use, see copyright notice in zlib.h | ||
| 21324 | */ | ||
| 21325 | |||
| 21326 | -/* @(#) $Id$ */ | ||
| 21327 | +/* @(#) $Id: zconf.in.h 3484 2005-07-15 14:26:03Z rpedersen $ */ | ||
| 21328 | |||
| 21329 | #ifndef ZCONF_H | ||
| 21330 | #define ZCONF_H | ||
diff --git a/meta/packages/gcc/gcc-4.0.2/ldflags.patch b/meta/packages/gcc/gcc-4.0.2/ldflags.patch deleted file mode 100644 index 1196bf0c8e..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/ldflags.patch +++ /dev/null | |||
| @@ -1,22 +0,0 @@ | |||
| 1 | --- gcc-4.0.0/Makefile.tpl.old 2005-06-10 13:05:09.000000000 +0100 | ||
| 2 | +++ gcc-4.0.0/Makefile.tpl 2005-06-10 13:05:10.000000000 +0100 | ||
| 3 | @@ -339,7 +339,7 @@ | ||
| 4 | NM = @NM@ | ||
| 5 | |||
| 6 | LD = @LD@ | ||
| 7 | -LDFLAGS = | ||
| 8 | +LDFLAGS = @LDFLAGS@ | ||
| 9 | |||
| 10 | RANLIB = @RANLIB@ | ||
| 11 | |||
| 12 | --- gcc-4.0.0/Makefile.in.old 2005-06-10 17:13:12.000000000 +0100 | ||
| 13 | +++ gcc-4.0.0/Makefile.in 2005-06-10 17:13:22.000000000 +0100 | ||
| 14 | @@ -336,7 +336,7 @@ | ||
| 15 | NM = @NM@ | ||
| 16 | |||
| 17 | LD = @LD@ | ||
| 18 | -LDFLAGS = | ||
| 19 | +LDFLAGS = @LDFLAGS@ | ||
| 20 | |||
| 21 | RANLIB = @RANLIB@ | ||
| 22 | |||
diff --git a/meta/packages/gcc/gcc-4.0.2/libstdc++-configure.patch b/meta/packages/gcc/gcc-4.0.2/libstdc++-configure.patch deleted file mode 100644 index 8dc613104d..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/libstdc++-configure.patch +++ /dev/null | |||
| @@ -1,10 +0,0 @@ | |||
| 1 | --- /tmp/configure 2007-06-02 09:26:29.000000000 +0200 | ||
| 2 | +++ gcc-4.0.2/libstdc++-v3/configure 2007-06-02 09:26:40.135215000 +0200 | ||
| 3 | @@ -101472,7 +101472,6 @@ | ||
| 4 | _ACEOF | ||
| 5 | |||
| 6 | fi | ||
| 7 | -done | ||
| 8 | |||
| 9 | fi | ||
| 10 | |||
diff --git a/meta/packages/gcc/gcc-4.0.2/zecke-host-cpp-ac-hack.patch b/meta/packages/gcc/gcc-4.0.2/zecke-host-cpp-ac-hack.patch deleted file mode 100644 index 3f26dce71f..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/zecke-host-cpp-ac-hack.patch +++ /dev/null | |||
| @@ -1,140 +0,0 @@ | |||
| 1 | gcc (AC_CHECK_HEADERS) is using $CPP to check if the header pass | ||
| 2 | the precompiler, if compiling with $CC failed. | ||
| 3 | Sadly $CC is xgcc of gcc, and $CPP is 'gcc -E'. And as you build | ||
| 4 | on a glibc machine, precompiling of the headers (execinfo.h and | ||
| 5 | iconv.h will succeed). As a dirty hack we will handle this case | ||
| 6 | as failure. | ||
| 7 | This fixes the libmudflap build for uclibc which lacks execinfo.h | ||
| 8 | but has HAVE_EXECINFO_H defined | ||
| 9 | |||
| 10 | Index: gcc-4.0.2/libmudflap/configure | ||
| 11 | =================================================================== | ||
| 12 | --- gcc-4.0.2.orig/libmudflap/configure 2006-04-30 16:57:47.000000000 +0200 | ||
| 13 | +++ gcc-4.0.2/libmudflap/configure 2006-04-30 17:00:59.000000000 +0200 | ||
| 14 | @@ -3719,6 +3719,8 @@ | ||
| 15 | ac_header_preproc=yes | ||
| 16 | ;; | ||
| 17 | no:yes:* ) | ||
| 18 | + # hack, hack, hack | ||
| 19 | + ac_header_preproc=no | ||
| 20 | { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 | ||
| 21 | echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} | ||
| 22 | { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 | ||
| 23 | @@ -3731,6 +3733,8 @@ | ||
| 24 | echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} | ||
| 25 | { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 | ||
| 26 | echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} | ||
| 27 | + { echo "$as_me:$LINENO: WARNING: $ac_header: Zecke says do not trust the wrong cpp! Ignoring." >&5 | ||
| 28 | +echo "$as_me: WARNING: $ac_header: Zecke says do not trust the wrong cpp! Ignoring." >&2;} | ||
| 29 | ( | ||
| 30 | cat <<\_ASBOX | ||
| 31 | ## ------------------------------------- ## | ||
| 32 | Index: gcc-4.0.2/libstdc++-v3/configure | ||
| 33 | =================================================================== | ||
| 34 | --- gcc-4.0.2.orig/libstdc++-v3/configure 2006-04-30 16:57:53.000000000 +0200 | ||
| 35 | +++ gcc-4.0.2/libstdc++-v3/configure 2006-04-30 22:59:00.000000000 +0200 | ||
| 36 | @@ -30513,6 +30513,7 @@ | ||
| 37 | ac_header_preproc=yes | ||
| 38 | ;; | ||
| 39 | no:yes:* ) | ||
| 40 | + ac_header_preproc=no | ||
| 41 | { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5 | ||
| 42 | echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;} | ||
| 43 | { echo "$as_me:$LINENO: WARNING: iconv.h: check for missing prerequisite headers?" >&5 | ||
| 44 | @@ -30525,6 +30526,8 @@ | ||
| 45 | echo "$as_me: WARNING: iconv.h: proceeding with the preprocessor's result" >&2;} | ||
| 46 | { echo "$as_me:$LINENO: WARNING: iconv.h: in the future, the compiler will take precedence" >&5 | ||
| 47 | echo "$as_me: WARNING: iconv.h: in the future, the compiler will take precedence" >&2;} | ||
| 48 | + { echo "$as_me:$LINENO: WARNING: $ac_header: Zecke says do not trust the wrong cpp! Ignoring." >&5 | ||
| 49 | +echo "$as_me: WARNING: $ac_header: Zecke says do not trust the wrong cpp! Ignoring." >&2;} | ||
| 50 | ( | ||
| 51 | cat <<\_ASBOX | ||
| 52 | ## ----------------------------------------- ## | ||
| 53 | @@ -53622,6 +53625,7 @@ | ||
| 54 | ac_header_preproc=yes | ||
| 55 | ;; | ||
| 56 | no:yes:* ) | ||
| 57 | + ac_header_preproc=no | ||
| 58 | { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5 | ||
| 59 | echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;} | ||
| 60 | { echo "$as_me:$LINENO: WARNING: iconv.h: check for missing prerequisite headers?" >&5 | ||
| 61 | @@ -75885,6 +75889,7 @@ | ||
| 62 | ac_header_preproc=yes | ||
| 63 | ;; | ||
| 64 | no:yes:* ) | ||
| 65 | + ac_header_preproc=no | ||
| 66 | { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5 | ||
| 67 | echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;} | ||
| 68 | { echo "$as_me:$LINENO: WARNING: iconv.h: check for missing prerequisite headers?" >&5 | ||
| 69 | @@ -78600,6 +78605,7 @@ | ||
| 70 | ac_header_preproc=yes | ||
| 71 | ;; | ||
| 72 | no:yes:* ) | ||
| 73 | + ac_header_preproc=no | ||
| 74 | { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5 | ||
| 75 | echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;} | ||
| 76 | { echo "$as_me:$LINENO: WARNING: iconv.h: check for missing prerequisite headers?" >&5 | ||
| 77 | @@ -80969,6 +80975,7 @@ | ||
| 78 | ac_header_preproc=yes | ||
| 79 | ;; | ||
| 80 | no:yes:* ) | ||
| 81 | + ac_header_preproc=no | ||
| 82 | { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5 | ||
| 83 | echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;} | ||
| 84 | { echo "$as_me:$LINENO: WARNING: iconv.h: check for missing prerequisite headers?" >&5 | ||
| 85 | @@ -83214,6 +83221,7 @@ | ||
| 86 | ac_header_preproc=yes | ||
| 87 | ;; | ||
| 88 | no:yes:* ) | ||
| 89 | + ac_header_preproc=no | ||
| 90 | { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5 | ||
| 91 | echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;} | ||
| 92 | { echo "$as_me:$LINENO: WARNING: iconv.h: check for missing prerequisite headers?" >&5 | ||
| 93 | @@ -86227,6 +86235,7 @@ | ||
| 94 | ac_header_preproc=yes | ||
| 95 | ;; | ||
| 96 | no:yes:* ) | ||
| 97 | + ac_header_preproc=no | ||
| 98 | { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5 | ||
| 99 | echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;} | ||
| 100 | { echo "$as_me:$LINENO: WARNING: iconv.h: check for missing prerequisite headers?" >&5 | ||
| 101 | @@ -88425,6 +88434,7 @@ | ||
| 102 | ac_header_preproc=yes | ||
| 103 | ;; | ||
| 104 | no:yes:* ) | ||
| 105 | + ac_header_preproc=no | ||
| 106 | { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5 | ||
| 107 | echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;} | ||
| 108 | { echo "$as_me:$LINENO: WARNING: iconv.h: check for missing prerequisite headers?" >&5 | ||
| 109 | @@ -90672,6 +90682,7 @@ | ||
| 110 | ac_header_preproc=yes | ||
| 111 | ;; | ||
| 112 | no:yes:* ) | ||
| 113 | + ac_header_preproc=no | ||
| 114 | { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5 | ||
| 115 | echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;} | ||
| 116 | { echo "$as_me:$LINENO: WARNING: iconv.h: check for missing prerequisite headers?" >&5 | ||
| 117 | @@ -93280,6 +93291,7 @@ | ||
| 118 | ac_header_preproc=yes | ||
| 119 | ;; | ||
| 120 | no:yes:* ) | ||
| 121 | + ac_header_preproc=no | ||
| 122 | { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5 | ||
| 123 | echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;} | ||
| 124 | { echo "$as_me:$LINENO: WARNING: iconv.h: check for missing prerequisite headers?" >&5 | ||
| 125 | @@ -94996,6 +95008,7 @@ | ||
| 126 | ac_header_preproc=yes | ||
| 127 | ;; | ||
| 128 | no:yes:* ) | ||
| 129 | + ac_header_preproc=no | ||
| 130 | { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5 | ||
| 131 | echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;} | ||
| 132 | { echo "$as_me:$LINENO: WARNING: iconv.h: check for missing prerequisite headers?" >&5 | ||
| 133 | @@ -97337,6 +97350,7 @@ | ||
| 134 | ac_header_preproc=yes | ||
| 135 | ;; | ||
| 136 | no:yes:* ) | ||
| 137 | + ac_header_preproc=no | ||
| 138 | { echo "$as_me:$LINENO: WARNING: iconv.h: present but cannot be compiled" >&5 | ||
| 139 | echo "$as_me: WARNING: iconv.h: present but cannot be compiled" >&2;} | ||
| 140 | { echo "$as_me:$LINENO: WARNING: iconv.h: check for missing prerequisite headers?" >&5 | ||
diff --git a/meta/packages/gcc/gcc-4.0.2/zecke-no-host-includes.patch b/meta/packages/gcc/gcc-4.0.2/zecke-no-host-includes.patch deleted file mode 100644 index 6afb10d6ef..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/zecke-no-host-includes.patch +++ /dev/null | |||
| @@ -1,31 +0,0 @@ | |||
| 1 | Index: gcc-4.0.2/gcc/c-incpath.c | ||
| 2 | =================================================================== | ||
| 3 | --- gcc-4.0.2.orig/gcc/c-incpath.c 2005-01-23 16:05:27.000000000 +0100 | ||
| 4 | +++ gcc-4.0.2/gcc/c-incpath.c 2006-05-15 21:23:02.000000000 +0200 | ||
| 5 | @@ -350,6 +350,26 @@ | ||
| 6 | p->construct = 0; | ||
| 7 | p->user_supplied_p = user_supplied_p; | ||
| 8 | |||
| 9 | +#ifdef CROSS_COMPILE | ||
| 10 | + /* A common error when cross compiling is including | ||
| 11 | + host headers. This code below will try to fail fast | ||
| 12 | + for cross compiling. Currently we consider /usr/include, | ||
| 13 | + /opt/include and /sw/include as harmful. */ | ||
| 14 | + { | ||
| 15 | + /* printf("Adding Path: %s\n", p->name ); */ | ||
| 16 | + if( strstr(p->name, "/usr/include" ) == p->name ) { | ||
| 17 | + fprintf(stderr, _("CROSS COMPILE Badness: /usr/include in INCLUDEPATH: %s\n"), p->name); | ||
| 18 | + abort(); | ||
| 19 | + } else if( strstr(p->name, "/sw/include") == p->name ) { | ||
| 20 | + fprintf(stderr, _("CROSS COMPILE Badness: /sw/include in INCLUDEPATH: %s\n"), p->name); | ||
| 21 | + abort(); | ||
| 22 | + } else if( strstr(p->name, "/opt/include") == p->name ) { | ||
| 23 | + fprintf(stderr, _("CROSS COMPILE Badness: /opt/include in INCLUDEPATH: %s\n"), p->name); | ||
| 24 | + abort(); | ||
| 25 | + } | ||
| 26 | + } | ||
| 27 | +#endif | ||
| 28 | + | ||
| 29 | add_cpp_dir_path (p, chain); | ||
| 30 | } | ||
| 31 | |||
diff --git a/meta/packages/gcc/gcc-4.0.2/zecke-xgcc-cpp.patch b/meta/packages/gcc/gcc-4.0.2/zecke-xgcc-cpp.patch deleted file mode 100644 index ba7d7257d9..0000000000 --- a/meta/packages/gcc/gcc-4.0.2/zecke-xgcc-cpp.patch +++ /dev/null | |||
| @@ -1,12 +0,0 @@ | |||
| 1 | Index: gcc-4.0.2/Makefile.in | ||
| 2 | =================================================================== | ||
| 3 | --- gcc-4.0.2.orig/Makefile.in 2006-08-06 13:17:09.000000000 +0200 | ||
| 4 | +++ gcc-4.0.2/Makefile.in 2006-08-06 13:18:35.000000000 +0200 | ||
| 5 | @@ -197,6 +197,7 @@ | ||
| 6 | AS="$(AS_FOR_TARGET)"; export AS; \ | ||
| 7 | CC="$(CC_FOR_TARGET)"; export CC; \ | ||
| 8 | CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \ | ||
| 9 | + CPP="$(CC_FOR_TARGET) -E"; export CCP; \ | ||
| 10 | CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \ | ||
| 11 | CPPFLAGS="$(CPPFLAGS_FOR_TARGET)"; export CPPFLAGS; \ | ||
| 12 | CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \ | ||
diff --git a/meta/packages/gcc/gcc-cross-initial_4.0.2.bb b/meta/packages/gcc/gcc-cross-initial_4.0.2.bb deleted file mode 100644 index 70877fe626..0000000000 --- a/meta/packages/gcc/gcc-cross-initial_4.0.2.bb +++ /dev/null | |||
| @@ -1,4 +0,0 @@ | |||
| 1 | require gcc-cross_${PV}.bb | ||
| 2 | require gcc-cross-initial.inc | ||
| 3 | |||
| 4 | EXTRA_OECONF += "--disable-multilib" | ||
diff --git a/meta/packages/gcc/gcc-cross_4.0.2.bb b/meta/packages/gcc/gcc-cross_4.0.2.bb deleted file mode 100644 index c296a03237..0000000000 --- a/meta/packages/gcc/gcc-cross_4.0.2.bb +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | PR = "r10" | ||
| 2 | |||
| 3 | require gcc-${PV}.inc | ||
| 4 | require gcc-cross4.inc | ||
| 5 | require gcc-configure-cross.inc | ||
| 6 | require gcc-package-cross.inc | ||
diff --git a/meta/packages/gcc/gcc_4.0.2.bb b/meta/packages/gcc/gcc_4.0.2.bb deleted file mode 100644 index 5e2598079b..0000000000 --- a/meta/packages/gcc/gcc_4.0.2.bb +++ /dev/null | |||
| @@ -1,5 +0,0 @@ | |||
| 1 | PR = "r7" | ||
| 2 | |||
| 3 | require gcc-${PV}.inc | ||
| 4 | require gcc-configure-target.inc | ||
| 5 | require gcc-package-target.inc | ||
