Guest User

gcc-3.2.3-PS2.patch

a guest
Aug 13th, 2015
450
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 187.42 KB | None | 0 0
  1. diff -burN orig.gcc-3.2.3/config.sub gcc-3.2.3/config.sub
  2. --- orig.gcc-3.2.3/config.sub 2003-01-30 18:32:36.000000000 -0400
  3. +++ gcc-3.2.3/config.sub 2007-07-26 13:04:40.000000000 -0300
  4. @@ -236,6 +236,7 @@
  5. | i370 | i860 | i960 | ia64 \
  6. | ip2k \
  7. | m32r | m68000 | m68k | m88k | mcore \
  8. + | mips64r5900 | mips64r5900el \
  9. | mips | mipsbe | mipseb | mipsel | mipsle \
  10. | mips16 \
  11. | mips64 | mips64el \
  12. @@ -308,6 +309,7 @@
  13. | m32r-* \
  14. | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
  15. | m88110-* | m88k-* | mcore-* \
  16. + | mips64r5900-* | mips64r5900el-* \
  17. | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
  18. | mips16-* \
  19. | mips64-* | mips64el-* \
  20. @@ -594,6 +596,10 @@
  21. basic_machine=i386-unknown
  22. os=-vsta
  23. ;;
  24. + iop)
  25. + basic_machine=mipsel-scei
  26. + os=-irx
  27. + ;;
  28. iris | iris4d)
  29. basic_machine=mips-sgi
  30. case $os in
  31. @@ -630,6 +636,16 @@
  32. basic_machine=m68k-atari
  33. os=-mint
  34. ;;
  35. + mipsEE* | ee | ps2)
  36. + basic_machine=mips64r5900el-scei
  37. + case $os in
  38. + -linux*)
  39. + ;;
  40. + *)
  41. + os=-elf
  42. + ;;
  43. + esac
  44. + ;;
  45. mips3*-*)
  46. basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
  47. ;;
  48. @@ -1118,7 +1134,8 @@
  49. | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
  50. | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
  51. | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
  52. - | -powermax* | -dnix* | -microbsd*)
  53. + | -powermax* | -dnix* | -microbsd* \
  54. + | -irx* )
  55. # Remember, each alternative MUST END IN *, to match a version number.
  56. ;;
  57. -qnx*)
  58. diff -burN orig.gcc-3.2.3/configure gcc-3.2.3/configure
  59. --- orig.gcc-3.2.3/configure 2002-06-24 13:14:28.000000000 -0300
  60. +++ gcc-3.2.3/configure 2007-07-26 13:04:40.000000000 -0300
  61. @@ -89,7 +89,7 @@
  62. target_alias=NOTARGET
  63. target_makefile_frag=
  64. undefs=NOUNDEFS
  65. -version="$Revision: 1.40.6.3 $"
  66. +version="$Revision: 1.8 $"
  67. x11=default
  68. bindir='${exec_prefix}/bin'
  69. sbindir='${exec_prefix}/sbin'
  70. @@ -697,7 +697,7 @@
  71. if test -f skip-this-dir; then
  72. # Perform the same cleanup as the trap handler, minus the "exit 1" of course,
  73. # and reset the trap handler.
  74. - trap 0
  75. + trap - 0
  76. rm -rf Makefile* ${tmpdir}
  77. # Execute the final clean-up actions
  78. ${config_shell} skip-this-dir
  79. @@ -1615,7 +1615,7 @@
  80. # Perform the same cleanup as the trap handler, minus the "exit 1" of course,
  81. # and reset the trap handler.
  82. rm -rf ${tmpdir}
  83. -trap 0
  84. +trap - 0
  85.  
  86. exit 0
  87.  
  88. diff -burN orig.gcc-3.2.3/configure.in gcc-3.2.3/configure.in
  89. --- orig.gcc-3.2.3/configure.in 2002-07-08 07:00:57.000000000 -0300
  90. +++ gcc-3.2.3/configure.in 2007-07-26 13:04:40.000000000 -0300
  91. @@ -980,6 +980,9 @@
  92. mips*-*-linux*)
  93. noconfigdirs="$noconfigdirs target-libffi"
  94. ;;
  95. + mipsel-*-irx*)
  96. + noconfigdirs="$noconfigdirs target-libiberty target-newlib target-libgloss target-libstdc++-v3 ${libgcj}"
  97. + ;;
  98. mips*-*-*)
  99. noconfigdirs="$noconfigdirs gprof ${libgcj}"
  100. ;;
  101. diff -burN orig.gcc-3.2.3/gcc/caller-save.c gcc-3.2.3/gcc/caller-save.c
  102. --- orig.gcc-3.2.3/gcc/caller-save.c 2002-01-01 18:22:25.000000000 -0400
  103. +++ gcc-3.2.3/gcc/caller-save.c 2007-07-26 13:04:40.000000000 -0300
  104. @@ -50,13 +50,21 @@
  105. If that is not possible the save is done one register at a time. */
  106.  
  107. static enum machine_mode
  108. +#if TARGET_MIPS5900
  109. + regno_save_mode[FIRST_PSEUDO_REGISTER][16 / MIN_UNITS_PER_WORD + 1];
  110. +#else
  111. regno_save_mode[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
  112. +#endif
  113.  
  114. /* For each hard register, a place on the stack where it can be saved,
  115. if needed. */
  116.  
  117. static rtx
  118. +#if TARGET_MIPS5900
  119. + regno_save_mem[FIRST_PSEUDO_REGISTER][16 / MIN_UNITS_PER_WORD + 1];
  120. +#else
  121. regno_save_mem[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
  122. +#endif
  123.  
  124. /* We will only make a register eligible for caller-save if it can be
  125. saved in its widest mode with a simple SET insn as long as the memory
  126. diff -burN orig.gcc-3.2.3/gcc/c-common.c gcc-3.2.3/gcc/c-common.c
  127. --- orig.gcc-3.2.3/gcc/c-common.c 2002-12-01 14:19:08.000000000 -0400
  128. +++ gcc-3.2.3/gcc/c-common.c 2007-07-26 13:04:40.000000000 -0300
  129. @@ -1336,6 +1336,9 @@
  130. if (bits <= TYPE_PRECISION (intDI_type_node))
  131. return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
  132.  
  133. + if (bits <= TYPE_PRECISION (intTI_type_node))
  134. + return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
  135. +
  136. return 0;
  137. }
  138.  
  139. @@ -1379,10 +1382,8 @@
  140. if (mode == DImode)
  141. return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
  142.  
  143. -#if HOST_BITS_PER_WIDE_INT >= 64
  144. if (mode == TYPE_MODE (intTI_type_node))
  145. return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
  146. -#endif
  147.  
  148. if (mode == TYPE_MODE (float_type_node))
  149. return float_type_node;
  150. @@ -1449,10 +1450,8 @@
  151. return long_long_unsigned_type_node;
  152. if (type1 == widest_integer_literal_type_node)
  153. return widest_unsigned_literal_type_node;
  154. -#if HOST_BITS_PER_WIDE_INT >= 64
  155. if (type1 == intTI_type_node)
  156. return unsigned_intTI_type_node;
  157. -#endif
  158. if (type1 == intDI_type_node)
  159. return unsigned_intDI_type_node;
  160. if (type1 == intSI_type_node)
  161. @@ -1484,10 +1483,8 @@
  162. return long_long_integer_type_node;
  163. if (type1 == widest_unsigned_literal_type_node)
  164. return widest_integer_literal_type_node;
  165. -#if HOST_BITS_PER_WIDE_INT >= 64
  166. if (type1 == unsigned_intTI_type_node)
  167. return intTI_type_node;
  168. -#endif
  169. if (type1 == unsigned_intDI_type_node)
  170. return intDI_type_node;
  171. if (type1 == unsigned_intSI_type_node)
  172. @@ -1527,10 +1524,8 @@
  173. return (unsignedp ? widest_unsigned_literal_type_node
  174. : widest_integer_literal_type_node);
  175.  
  176. -#if HOST_BITS_PER_WIDE_INT >= 64
  177. if (TYPE_PRECISION (type) == TYPE_PRECISION (intTI_type_node))
  178. return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
  179. -#endif
  180. if (TYPE_PRECISION (type) == TYPE_PRECISION (intDI_type_node))
  181. return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
  182. if (TYPE_PRECISION (type) == TYPE_PRECISION (intSI_type_node))
  183. @@ -2576,16 +2571,12 @@
  184. pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node));
  185. pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node));
  186. pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
  187. -#if HOST_BITS_PER_WIDE_INT >= 64
  188. pushdecl (build_decl (TYPE_DECL, get_identifier ("__int128_t"), intTI_type_node));
  189. -#endif
  190. pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
  191. pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node));
  192. pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node));
  193. pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
  194. -#if HOST_BITS_PER_WIDE_INT >= 64
  195. pushdecl (build_decl (TYPE_DECL, get_identifier ("__uint128_t"), unsigned_intTI_type_node));
  196. -#endif
  197.  
  198. /* Create the widest literal types. */
  199. widest_integer_literal_type_node
  200. diff -burN orig.gcc-3.2.3/gcc/config/i386/xm-mingw32.h gcc-3.2.3/gcc/config/i386/xm-mingw32.h
  201. --- orig.gcc-3.2.3/gcc/config/i386/xm-mingw32.h 2002-01-10 18:21:39.000000000 -0400
  202. +++ gcc-3.2.3/gcc/config/i386/xm-mingw32.h 2007-07-26 13:04:51.000000000 -0300
  203. @@ -31,3 +31,143 @@
  204.  
  205. #undef PATH_SEPARATOR
  206. #define PATH_SEPARATOR ';'
  207. +
  208. +/* This describes the machine the compiler is hosted on. */
  209. +#define HOST_BITS_PER_CHAR CHAR_BIT
  210. +#define HOST_BITS_PER_SHORT (CHAR_BIT * SIZEOF_SHORT)
  211. +#define HOST_BITS_PER_INT (CHAR_BIT * SIZEOF_INT)
  212. +#define HOST_BITS_PER_LONG (CHAR_BIT * SIZEOF_LONG)
  213. +
  214. +#ifdef HAVE_LONG_LONG
  215. +# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF_LONG_LONG)
  216. +#else
  217. +#ifdef HAVE___INT64
  218. +# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF___INT64)
  219. +#else
  220. +/* If we're here and we're GCC, assume this is stage 2+ of a bootstrap
  221. + and 'long long' has the width of the *target*'s long long. */
  222. +# if GCC_VERSION > 3000
  223. +# define HOST_BITS_PER_LONGLONG LONG_LONG_TYPE_SIZE
  224. +# endif /* gcc */
  225. +#endif
  226. +#endif /* no long long */
  227. +
  228. +/* Find the largest host integer type and set its size and type. */
  229. +
  230. +/* Use long long on the host if the target has a wider long type than
  231. + the host. */
  232. +
  233. +#if ! defined HOST_BITS_PER_WIDE_INT \
  234. + && defined HOST_BITS_PER_LONGLONG \
  235. + && (HOST_BITS_PER_LONGLONG > HOST_BITS_PER_LONG) \
  236. + && (defined (LONG_LONG_MAX) || defined (LONGLONG_MAX) \
  237. + || defined (LLONG_MAX) || defined (__GNUC__))
  238. +
  239. +# ifdef MAX_LONG_TYPE_SIZE
  240. +# if MAX_LONG_TYPE_SIZE > HOST_BITS_PER_LONG
  241. +# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONGLONG
  242. +# define HOST_WIDE_INT long long
  243. +# endif
  244. +# else
  245. +# if LONG_TYPE_SIZE > HOST_BITS_PER_LONG
  246. +# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONGLONG
  247. +# define HOST_WIDE_INT long long
  248. +# endif
  249. +# endif
  250. +
  251. +#endif
  252. +
  253. +#ifndef HOST_BITS_PER_WIDE_INT
  254. +
  255. +# if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
  256. +# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
  257. +# define HOST_WIDE_INT long
  258. +# else
  259. +# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
  260. +# define HOST_WIDE_INT int
  261. +# endif
  262. +
  263. +#endif /* ! HOST_BITS_PER_WIDE_INT */
  264. +
  265. +/* Provide defaults for the way to print a HOST_WIDE_INT
  266. + in various manners. */
  267. +
  268. +#ifndef HOST_WIDE_INT_PRINT_DEC
  269. +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
  270. +# define HOST_WIDE_INT_PRINT_DEC "%d"
  271. +# else
  272. +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
  273. +# define HOST_WIDE_INT_PRINT_DEC "%ld"
  274. +# else
  275. +# define HOST_WIDE_INT_PRINT_DEC "%I64d"
  276. +# endif
  277. +# endif
  278. +#endif /* ! HOST_WIDE_INT_PRINT_DEC */
  279. +
  280. +#ifndef HOST_WIDE_INT_PRINT_UNSIGNED
  281. +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
  282. +# define HOST_WIDE_INT_PRINT_UNSIGNED "%u"
  283. +# else
  284. +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
  285. +# define HOST_WIDE_INT_PRINT_UNSIGNED "%lu"
  286. +# else
  287. +# define HOST_WIDE_INT_PRINT_UNSIGNED "%I64u"
  288. +# endif
  289. +# endif
  290. +#endif /* ! HOST_WIDE_INT_PRINT_UNSIGNED */
  291. +
  292. +#ifndef HOST_WIDE_INT_PRINT_HEX
  293. +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
  294. +# define HOST_WIDE_INT_PRINT_HEX "0x%x"
  295. +# else
  296. +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
  297. +# define HOST_WIDE_INT_PRINT_HEX "0x%lx"
  298. +# else
  299. +# define HOST_WIDE_INT_PRINT_HEX "0x%I64x"
  300. +# endif
  301. +# endif
  302. +#endif /* ! HOST_WIDE_INT_PRINT_HEX */
  303. +
  304. +#ifndef HOST_WIDE_INT_PRINT_DOUBLE_HEX
  305. +# if HOST_BITS_PER_WIDE_INT == 64
  306. +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
  307. +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%x%016x"
  308. +# else
  309. +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
  310. +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%016lx"
  311. +# else
  312. +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%llx%016llx"
  313. +# endif
  314. +# endif
  315. +# else
  316. +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
  317. +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%x%08x"
  318. +# else
  319. +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
  320. +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%08lx"
  321. +# else
  322. +# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%llx%08llx"
  323. +# endif
  324. +# endif
  325. +# endif
  326. +#endif /* ! HOST_WIDE_INT_PRINT_DOUBLE_HEX */
  327. +
  328. +/* Find HOST_WIDEST_INT and set its bit size, type and print macros.
  329. + It will be the largest integer mode supported by the host which may
  330. + (or may not) be larger than HOST_WIDE_INT. */
  331. +
  332. +#ifndef HOST_WIDEST_INT
  333. +#if defined HOST_BITS_PER_LONGLONG && HOST_BITS_PER_LONGLONG > HOST_BITS_PER_LONG
  334. +# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG
  335. +# define HOST_WIDEST_INT __int64
  336. +# define HOST_WIDEST_INT_PRINT_DEC "%I64d"
  337. +# define HOST_WIDEST_INT_PRINT_UNSIGNED "%I64u"
  338. +# define HOST_WIDEST_INT_PRINT_HEX "0x%I64x"
  339. +# else
  340. +# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONG
  341. +# define HOST_WIDEST_INT long
  342. +# define HOST_WIDEST_INT_PRINT_DEC "%ld"
  343. +# define HOST_WIDEST_INT_PRINT_UNSIGNED "%lu"
  344. +# define HOST_WIDEST_INT_PRINT_HEX "0x%lx"
  345. +# endif /* long long wider than long */
  346. +#endif /* ! HOST_WIDEST_INT */
  347. diff -burN orig.gcc-3.2.3/gcc/config/mips/core-mmi.h gcc-3.2.3/gcc/config/mips/core-mmi.h
  348. --- orig.gcc-3.2.3/gcc/config/mips/core-mmi.h 1969-12-31 20:00:00.000000000 -0400
  349. +++ gcc-3.2.3/gcc/config/mips/core-mmi.h 2007-07-26 13:04:40.000000000 -0300
  350. @@ -0,0 +1,104 @@
  351. +/*
  352. + * mmi-intrinsics.h - R5900 MMI compiler intrinsics.
  353. + *
  354. + * Copyright (c) 2003 M. R. Brown <mrbrown@0xd6.org>
  355. + *
  356. + * This file is licensed under the GNU GPL version 2.
  357. + *
  358. + * As a special exception, if you include this header file into source
  359. + * files compiled by GCC, this header file does not by itself cause
  360. + * the resulting executable to be covered by the GNU General Public
  361. + * License. This exception does not however invalidate any other
  362. + * reasons why the executable file might be covered by the GNU General
  363. + * Public License.
  364. + *
  365. + */
  366. +
  367. +/* Based off of the mmintrin.h file in GCC 3.2.1 */
  368. +
  369. +#ifndef __mmi_intrinsics_h
  370. +#define __mmi_intrinsics_h
  371. +
  372. +/* This for user programs. */
  373. +typedef int __m128 __attribute__ ((mode(TI)));
  374. +
  375. +#define __vector __attribute__((vector_size(16)))
  376. +
  377. +/* These are internal. */
  378. +typedef int __v16qi __attribute__ ((mode(V16QI)));
  379. +typedef int __v8hi __attribute__ ((mode(V8HI)));
  380. +typedef int __v4si __attribute__ ((mode(V4SI)));
  381. +
  382. +#if !defined(__u128)
  383. +typedef unsigned int __u128 __attribute__((mode(TI)));
  384. +#endif
  385. +#if !defined(__s128)
  386. +typedef __signed__ int __s128 __attribute__((mode(TI)));
  387. +#endif
  388. +
  389. +/* Convert i to a __m128 object. The integer is zero-extended to 128-bits. */
  390. +/* XXX: No, not really. Figure out why. */
  391. +static __inline __m128 _mmi_cvtsi32_si128(int i)
  392. +{
  393. + __u128 tmp = (unsigned int)i;
  394. + return (__m128)tmp;
  395. +}
  396. +
  397. +/* Add the 8-bit values in m1 to the 8-bit values in m2. */
  398. +
  399. +static inline __m128
  400. +_mmi_paddb(__m128 m1, __m128 m2)
  401. +{
  402. + return (__m128) __builtin_mmi_paddb((__v16qi)m1, (__v16qi)m2);
  403. +}
  404. +
  405. +/* Creates a vector of two 64-bit values; d0 is least significant. */
  406. +static inline __m128
  407. +_mmi_create_vec64(long d1, long d0)
  408. +{
  409. + union {
  410. + __m128 q;
  411. + struct {
  412. + unsigned long d0;
  413. + unsigned long d1;
  414. + } s;
  415. + } u;
  416. +
  417. + u.s.d0 = d0;
  418. + u.s.d1 = d1;
  419. + return u.q;
  420. +}
  421. +
  422. +/* Convienence routines for creating vectors. */
  423. +
  424. +/* Creates a vector of 4 32-bit values; w0 is least significant. */
  425. +static inline __m128
  426. +_mmi_create_vec32(int w3, int w2, int w1, int w0)
  427. +{
  428. + unsigned long d1 = (unsigned int)w3 << 32 | (unsigned int)w2;
  429. + unsigned long d0 = (unsigned int)w1 << 32 | (unsigned int)w0;
  430. + return _mmi_create_vec64(d1, d0);
  431. +}
  432. +
  433. +/* Creates a vector of 8 16-bit values; h0 is least significant. */
  434. +static inline __m128
  435. +_mmi_create_vec16(short h7, short h6, short h5, short h4,
  436. + short h3, short h2, short h1, short h0)
  437. +{
  438. + unsigned long d1, d0;
  439. +
  440. + d1 = (unsigned short)h7;
  441. + d1 = d1 << 16 | (unsigned short)h6;
  442. + d1 = d1 << 16 | (unsigned short)h5;
  443. + d1 = d1 << 16 | (unsigned short)h4;
  444. +
  445. + d0 = (unsigned short)h3;
  446. + d0 = d0 << 16 | (unsigned short)h2;
  447. + d0 = d0 << 16 | (unsigned short)h1;
  448. + d0 = d0 << 16 | (unsigned short)h0;
  449. +
  450. + return _mmi_create_vec64(d1, d0);
  451. +}
  452. +
  453. +#endif /* __mmi_intrinsics_h */
  454. +
  455. diff -burN orig.gcc-3.2.3/gcc/config/mips/core-vumm.h gcc-3.2.3/gcc/config/mips/core-vumm.h
  456. --- orig.gcc-3.2.3/gcc/config/mips/core-vumm.h 1969-12-31 20:00:00.000000000 -0400
  457. +++ gcc-3.2.3/gcc/config/mips/core-vumm.h 2007-07-26 13:04:40.000000000 -0300
  458. @@ -0,0 +1 @@
  459. +#define __THIS__IS__A__BLANK__FILE__
  460. diff -burN orig.gcc-3.2.3/gcc/config/mips/crti5900.asm gcc-3.2.3/gcc/config/mips/crti5900.asm
  461. --- orig.gcc-3.2.3/gcc/config/mips/crti5900.asm 1969-12-31 20:00:00.000000000 -0400
  462. +++ gcc-3.2.3/gcc/config/mips/crti5900.asm 2007-07-26 13:04:40.000000000 -0300
  463. @@ -0,0 +1,16 @@
  464. +/* 4 slots for argument spill area. 1 for cpreturn, 1 for stack.
  465. + Return spill offset of 80. */
  466. +
  467. + .section .init,"ax",@progbits
  468. + .globl _init
  469. + .type _init,@function
  470. +_init:
  471. + addu $sp,$sp,-96
  472. + sq $31,80($sp)
  473. +
  474. + .section .fini,"ax",@progbits
  475. + .globl _fini
  476. + .type _fini,@function
  477. +_fini:
  478. + addu $sp,$sp,-96
  479. + sq $31,80($sp)
  480. diff -burN orig.gcc-3.2.3/gcc/config/mips/crtn5900.asm gcc-3.2.3/gcc/config/mips/crtn5900.asm
  481. --- orig.gcc-3.2.3/gcc/config/mips/crtn5900.asm 1969-12-31 20:00:00.000000000 -0400
  482. +++ gcc-3.2.3/gcc/config/mips/crtn5900.asm 2007-07-26 13:04:40.000000000 -0300
  483. @@ -0,0 +1,12 @@
  484. +/* 4 slots for argument spill area. 1 for cpreturn, 1 for stack.
  485. + Return spill offset of 80. */
  486. +
  487. + .section .init,"ax",@progbits
  488. + lq $31,80($sp)
  489. + addu $sp,$sp,96
  490. + j $31
  491. +
  492. + .section .fini,"ax",@progbits
  493. + lq $31,80($sp)
  494. + addu $sp,$sp,96
  495. + j $31
  496. diff -burN orig.gcc-3.2.3/gcc/config/mips/mips.c gcc-3.2.3/gcc/config/mips/mips.c
  497. --- orig.gcc-3.2.3/gcc/config/mips/mips.c 2002-07-26 20:23:02.000000000 -0300
  498. +++ gcc-3.2.3/gcc/config/mips/mips.c 2015-08-10 16:10:25 +0300
  499. @@ -51,6 +51,7 @@
  500. #include "gstab.h"
  501. #include "hashtab.h"
  502. #include "debug.h"
  503. +#include "optabs.h"
  504. #include "target.h"
  505. #include "target-def.h"
  506.  
  507. @@ -102,6 +103,7 @@
  508. int, int));
  509. static void mips_emit_frame_related_store PARAMS ((rtx, rtx,
  510. HOST_WIDE_INT));
  511. +static void mips_check_reg_mode PARAMS ((rtx, rtx, void *));
  512. static void save_restore_insns PARAMS ((int, rtx,
  513. long, FILE *));
  514. static void mips16_output_gp_offset PARAMS ((FILE *, rtx));
  515. @@ -135,6 +137,23 @@
  516. #endif
  517. static int mips_adjust_cost PARAMS ((rtx, rtx, rtx, int));
  518.  
  519. +/* R5900 (Emotion Engine) support. */
  520. +static enum sequence_type r5900_detect_sequence_type PARAMS ((rtx, int *, rtx *,
  521. + int *, int));
  522. +static void r5900_lengthen_loops PARAMS ((rtx, int));
  523. +static void r5900_sched_init PARAMS ((void));
  524. +static void mips_sched_init PARAMS ((FILE *, int, int));
  525. +static void r5900_sched_reorder PARAMS ((FILE *, int, rtx *, int));
  526. +static int mips_sched_reorder PARAMS ((FILE *, int, rtx *,
  527. + int *, int));
  528. +static void r5900_init_builtins PARAMS ((void));
  529. +static rtx r5900_expand_binop_builtin PARAMS ((enum insn_code, tree,
  530. + rtx));
  531. +static rtx r5900_expand_builtin PARAMS ((tree, rtx));
  532. +static rtx mips_expand_builtin PARAMS ((tree, rtx, rtx,
  533. + enum machine_mode, int));
  534. +static void mips_init_builtins PARAMS ((void));
  535. +
  536. /* Global variables for machine-dependent things. */
  537.  
  538. /* Threshold for data being put into the small data/bss area, instead
  539. @@ -232,6 +251,8 @@
  540. /* which abi to use. */
  541. int mips_abi;
  542.  
  543. +int mips_alignment;
  544. +
  545. /* Strings to hold which cpu and instruction set architecture to use. */
  546. const char *mips_cpu_string; /* for -mcpu=<xxx> */
  547. const char *mips_arch_string; /* for -march=<xxx> */
  548. @@ -253,6 +274,18 @@
  549. set this option if such an option is used. */
  550. const char *mips_explicit_type_size_string;
  551.  
  552. +#ifdef DEFAULT_MIPS_ALIGNMENT
  553. +int mips_alignment=DEFAULT_MIPS_ALIGNMENT; /* biggest alignment bits */
  554. +#else
  555. +int mips_alignment=BIGGEST_ALIGNMENT; /* biggest alignment bits */
  556. +#endif
  557. +const char * mips_no_align128_string;
  558. +const char * mips_align128_string;
  559. +const char * mips_use_128_string;
  560. +const char * mips_align_all_string;
  561. +int mips_align_all = 1;
  562. +int mips_use_128 = 0;
  563. +
  564. /* Whether we are generating mips16 hard float code. In mips16 mode
  565. we always set TARGET_SOFT_FLOAT; this variable is nonzero if
  566. -msoft-float was not specified by the user, which means that we
  567. @@ -280,8 +313,11 @@
  568. initialized in override_options. */
  569. REAL_VALUE_TYPE dfhigh, dflow, sfhigh, sflow;
  570.  
  571. -/* Mode used for saving/restoring general purpose registers. */
  572. -static enum machine_mode gpr_mode;
  573. +/* The mode that will be used to save a given gpr on the stack. Note
  574. + the entry for $0 is special; it indicates the generic size of a gpr
  575. + save/restore by the prologue/epilogue and must be the maximum mode
  576. + ever used to save a GPR. This is typically WORD_MODE. */
  577. +enum machine_mode mips_reg_mode[GP_REG_NUM];
  578.  
  579. /* Array giving truth value on whether or not a given hard register
  580. can support a given mode. */
  581. @@ -343,7 +379,8 @@
  582. "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
  583. "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
  584. "hi", "lo", "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
  585. - "$fcc5","$fcc6","$fcc7","$rap"
  586. + "$fcc5","$fcc6","$fcc7","$rap",
  587. + "hi1", "lo1", "accum1"
  588. };
  589.  
  590. /* Mips software names for the registers, used to overwrite the
  591. @@ -360,7 +397,8 @@
  592. "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
  593. "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
  594. "hi", "lo", "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
  595. - "$fcc5","$fcc6","$fcc7","$rap"
  596. + "$fcc5","$fcc6","$fcc7","$rap",
  597. + "hi1", "lo1", "accum1"
  598. };
  599.  
  600. /* Map hard register number to register class */
  601. @@ -384,7 +422,8 @@
  602. FP_REGS, FP_REGS, FP_REGS, FP_REGS,
  603. HI_REG, LO_REG, HILO_REG, ST_REGS,
  604. ST_REGS, ST_REGS, ST_REGS, ST_REGS,
  605. - ST_REGS, ST_REGS, ST_REGS, GR_REGS
  606. + ST_REGS, ST_REGS, ST_REGS, GR_REGS,
  607. + HI1_REG, LO1_REG, HILO1_REG
  608. };
  609.  
  610. /* Map register constraint character to register class. */
  611. @@ -479,6 +518,18 @@
  612. #undef TARGET_SCHED_ADJUST_COST
  613. #define TARGET_SCHED_ADJUST_COST mips_adjust_cost
  614.  
  615. +#undef TARGET_SCHED_INIT
  616. +#define TARGET_SCHED_INIT mips_sched_init
  617. +
  618. +#undef TARGET_SCHED_REORDER
  619. +#define TARGET_SCHED_REORDER mips_sched_reorder
  620. +
  621. +#undef TARGET_INIT_BUILTINS
  622. +#define TARGET_INIT_BUILTINS mips_init_builtins
  623. +
  624. +#undef TARGET_EXPAND_BUILTIN
  625. +#define TARGET_EXPAND_BUILTIN mips_expand_builtin
  626. +
  627. struct gcc_target targetm = TARGET_INITIALIZER;
  628. /* Return truth value of whether OP can be used as an operands
  629. @@ -1111,6 +1162,38 @@
  630. && ! mips16_constant (op, mode, 1, 0)));
  631. }
  632.  
  633. +/* Return truth value of whether OP is a register, a memory operand,
  634. + or a constant. This is used by the r5900 lq/sq support. */
  635. +
  636. +int
  637. +movti_operand (op, mode)
  638. + rtx op;
  639. + enum machine_mode mode;
  640. +{
  641. + switch (GET_CODE (op))
  642. + {
  643. + case CONST_INT:
  644. + if (TARGET_MIPS16)
  645. + return FALSE;
  646. + return TRUE;
  647. +
  648. + case CONST_DOUBLE:
  649. + if (TARGET_MIPS16 || GET_MODE (op) != VOIDmode)
  650. + return FALSE;
  651. + return TRUE;
  652. +
  653. + case REG:
  654. + case SUBREG:
  655. + return register_operand (op, mode);
  656. +
  657. + case MEM:
  658. + return memory_operand (op, mode);
  659. +
  660. + default:
  661. + return FALSE;
  662. + }
  663. +}
  664. +
  665. /* Like register_operand, but when in 64 bit mode also accept a sign
  666. extend of a 32 bit register, since the value is known to be already
  667. sign extended. */
  668. @@ -1315,6 +1398,7 @@
  669. accept (subreg (const_int)) which will fail to reload. */
  670. if (CONSTANT_ADDRESS_P (xinsn)
  671. && ! (mips_split_addresses && mips_check_split (xinsn, mode))
  672. + && ! (TARGET_MIPS5900 && mode == TImode)
  673. && (! TARGET_MIPS16 || mips16_constant (xinsn, mode, 1, 0)))
  674. return 1;
  675.  
  676. @@ -1651,7 +1735,7 @@
  677. if (type == DELAY_LOAD || type == DELAY_FCMP)
  678. num_nops = 1;
  679.  
  680. - else if (type == DELAY_HILO)
  681. + else if (type == DELAY_HILO || type == DELAY_HILO1)
  682. num_nops = 2;
  683.  
  684. else
  685. @@ -1663,6 +1747,7 @@
  686. next_insn = NEXT_INSN (next_insn);
  687.  
  688. dslots_load_total += num_nops;
  689. +
  690. if (TARGET_DEBUG_F_MODE
  691. || !optimize
  692. || type == DELAY_NONE
  693. @@ -1701,6 +1786,11 @@
  694. mips_load_reg3 = gen_rtx_REG (SImode, MD_REG_FIRST);
  695. mips_load_reg4 = gen_rtx_REG (SImode, MD_REG_FIRST+1);
  696. }
  697. + else if (type == DELAY_HILO1)
  698. + {
  699. + mips_load_reg3 = gen_rtx_REG (SImode, MD1_REG_FIRST);
  700. + mips_load_reg4 = gen_rtx_REG (SImode, MD1_REG_FIRST+1);
  701. + }
  702. else
  703. {
  704. mips_load_reg3 = 0;
  705. @@ -1935,6 +2025,15 @@
  706. ret = "mflo\t%0";
  707. }
  708.  
  709. + else if (MD1_REG_P (regno1))
  710. + {
  711. + delay = DELAY_HILO1;
  712. + if (regno1 != HILO1_REGNUM)
  713. + ret = "mf%1\t%0";
  714. + else
  715. + ret = "mflo1\t%0";
  716. + }
  717. +
  718. else if (ST_REG_P (regno1) && ISA_HAS_8CC)
  719. ret = "li\t%0,1\n\tmovf\t%0,%.,%1";
  720.  
  721. @@ -1971,6 +2070,16 @@
  722. }
  723. }
  724.  
  725. + else if (MD1_REG_P (regno0))
  726. + {
  727. + if (GP_REG_P (regno1))
  728. + {
  729. + delay = DELAY_HILO1;
  730. + if (regno0 != HILO1_REGNUM && ! TARGET_MIPS16)
  731. + ret = "mt%0\t%1";
  732. + }
  733. + }
  734. +
  735. else if (regno0 == FPSW_REGNUM && ! ISA_HAS_8CC)
  736. {
  737. if (GP_REG_P (regno1))
  738. @@ -2056,6 +2165,12 @@
  739. delay = DELAY_HILO;
  740. ret = "mt%0\t%.";
  741. }
  742. +
  743. + else if (MD1_REG_P (regno0))
  744. + {
  745. + delay = DELAY_HILO1;
  746. + ret = "mt%0\t%.";
  747. + }
  748. }
  749.  
  750. else if (GP_REG_P (regno0))
  751. @@ -2390,6 +2505,20 @@
  752. ret = "mthi\t%M1\n\tmtlo\t%L1";
  753. }
  754.  
  755. + else if (MD1_REG_P (regno0) && GP_REG_P (regno1) && !TARGET_MIPS16)
  756. + {
  757. + delay = DELAY_HILO1;
  758. + if (TARGET_64BIT)
  759. + {
  760. + if (regno0 != HILO1_REGNUM)
  761. + ret = "mt%0\t%1";
  762. + else if (regno1 == 0)
  763. + ret = "mtlo%H0\t%.\n\tmthi%H0\t%.";
  764. + }
  765. + else
  766. + ret = "mthi%H0\t%M1\n\tmtlo%H0\t%L1";
  767. + }
  768. +
  769. else if (GP_REG_P (regno0) && MD_REG_P (regno1))
  770. {
  771. delay = DELAY_HILO;
  772. @@ -2402,6 +2531,18 @@
  773. ret = "mfhi\t%M0\n\tmflo\t%L0";
  774. }
  775.  
  776. + else if (GP_REG_P (regno0) && MD1_REG_P (regno1))
  777. + {
  778. + delay = DELAY_HILO1;
  779. + if (TARGET_64BIT)
  780. + {
  781. + if (regno1 != HILO1_REGNUM)
  782. + ret = "mf%1\t%0";
  783. + }
  784. + else
  785. + ret = "mfhi%H1\t%M0\n\tmflo%H1\t%L0";
  786. + }
  787. +
  788. else if (TARGET_64BIT)
  789. ret = "move\t%0,%1";
  790.  
  791. @@ -2507,6 +2648,14 @@
  792. ? "mtlo\t%.\n\tmthi\t%."
  793. : "mt%0\t%.\n");
  794. }
  795. +
  796. + else if (MD1_REG_P (regno0))
  797. + {
  798. + delay = DELAY_HILO1;
  799. + ret = (regno0 == HILO1_REGNUM
  800. + ? "mtlo%H0\t%.\n\tmthi%H0\t%."
  801. + : "mt%0\t%.\n");
  802. + }
  803. }
  804.  
  805. else if (code1 == CONST_INT && GET_MODE (op0) == DImode
  806. @@ -4015,6 +4164,14 @@
  807. cum->gp_reg_found = 1;
  808. cum->arg_words++;
  809. break;
  810. +
  811. + case V16QImode:
  812. + case V8HImode:
  813. + case V4SImode:
  814. + if (! TARGET_MMI)
  815. + abort ();
  816. + cum->gp_reg_found = 1;
  817. + cum->arg_words++;
  818. }
  819. }
  820.  
  821. @@ -4135,6 +4292,15 @@
  822. if (! TARGET_64BIT)
  823. cum->arg_words += (cum->arg_words & 1);
  824. regbase = GP_ARG_FIRST;
  825. + break;
  826. +
  827. + case V4SImode:
  828. + case V8HImode:
  829. + case V16QImode:
  830. + if (! TARGET_MMI)
  831. + abort ();
  832. + regbase = GP_ARG_FIRST;
  833. +
  834. }
  835.  
  836. if (*arg_words >= (unsigned) MAX_ARGS_IN_REGISTERS)
  837. @@ -4311,6 +4477,7 @@
  838. int named ATTRIBUTE_UNUSED;/* != 0 for normal args, == 0 for ... args */
  839. {
  840. if ((mode == BLKmode
  841. + || (mode == TImode && TARGET_MIPS5900)
  842. || GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
  843. || GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
  844. && cum->arg_words < (unsigned) MAX_ARGS_IN_REGISTERS
  845. @@ -4851,6 +5018,14 @@
  846. target_flags &= ~((TARGET_DEFAULT) & (MASK_SOFT_FLOAT | MASK_SINGLE_FLOAT));
  847. #endif
  848.  
  849. + if (mips_align_all_string == 0)
  850. + mips_align_all = 1;
  851. +
  852. + else if (ISDIGIT (*mips_align_all_string))
  853. + {
  854. + mips_align_all = atoi (mips_align_all_string);
  855. + }
  856. +
  857. /* Get the architectural level. */
  858. if (mips_isa_string == 0)
  859. mips_isa = MIPS_ISA_DEFAULT;
  860. @@ -5081,6 +5256,10 @@
  861. }
  862. }
  863.  
  864. + /* Humf... */
  865. + if (mips_arch == PROCESSOR_R3000)
  866. + mips_isa = 1;
  867. +
  868. /* make sure sizes of ints/longs/etc. are ok */
  869. if (! ISA_HAS_64BIT_REGS)
  870. {
  871. @@ -5234,6 +5413,10 @@
  872. mips_char_to_class['l'] = LO_REG;
  873. mips_char_to_class['a'] = HILO_REG;
  874. mips_char_to_class['x'] = MD_REGS;
  875. + mips_char_to_class['u'] = HI1_REG;
  876. + mips_char_to_class['v'] = LO1_REG;
  877. + mips_char_to_class['q'] = HILO1_REG;
  878. + mips_char_to_class['w'] = MD1_REGS;
  879. mips_char_to_class['b'] = ALL_REGS;
  880. mips_char_to_class['y'] = GR_REGS;
  881. mips_char_to_class['z'] = ST_REGS;
  882. @@ -5279,6 +5462,10 @@
  883. || FP_REG_P (regno));
  884. }
  885.  
  886. + /* General registers can hold TImode values on the r5900. */
  887. + else if (GP_REG_P (regno) && mode == TImode && TARGET_MIPS5900)
  888. + temp = 1;
  889. +
  890. else if (GP_REG_P (regno))
  891. temp = ((regno & 1) == 0 || size <= UNITS_PER_WORD);
  892.  
  893. @@ -5302,6 +5489,12 @@
  894. || (regno == MD_REG_FIRST
  895. && size == 2 * UNITS_PER_WORD)));
  896.  
  897. + else if (MD1_REG_P (regno))
  898. + temp = (class == MODE_INT
  899. + && (size <= UNITS_PER_WORD
  900. + || (regno == MD1_REG_FIRST
  901. + && size == 2 * UNITS_PER_WORD)));
  902. +
  903. else
  904. temp = 0;
  905.  
  906. @@ -5311,9 +5504,18 @@
  907.  
  908. /* Save GPR registers in word_mode sized hunks. word_mode hasn't been
  909. initialized yet, so we can't use that here. */
  910. - gpr_mode = TARGET_64BIT ? DImode : SImode;
  911. + for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
  912. + {
  913. + mips_reg_mode[regno] = TARGET_64BIT ? DImode : SImode;
  914. + }
  915. +
  916. + /* Saves/restores of general purpose registers on the r5900 use
  917. + a mode wider than word_mode. */
  918. + if (TARGET_MIPS5900)
  919. + mips_reg_mode[0] = TImode;
  920.  
  921. /* Provide default values for align_* for 64-bit targets. */
  922. + /* XXX: fix this up for the r5900. */
  923. if (TARGET_64BIT && !TARGET_MIPS16)
  924. {
  925. if (align_loops == 0)
  926. @@ -5324,6 +5526,21 @@
  927. align_functions = 8;
  928. }
  929.  
  930. +#ifdef DEFAULT_MIPS_ALIGNMENT
  931. + if (mips_align128_string != NULL) {
  932. + /* -malign128 */
  933. + mips_alignment=128;
  934. + }
  935. + if (mips_no_align128_string != NULL) {
  936. + /* -mno-align128 */
  937. + mips_alignment=64;
  938. + }
  939. +#endif
  940. +
  941. + if (mips_use_128_string != NULL) {
  942. + mips_use_128=1;
  943. + }
  944. +
  945. /* Register global variables with the garbage collector. */
  946. mips_add_gc_roots ();
  947. }
  948. @@ -5425,6 +5642,7 @@
  949. 'M' print high-order register of double-word register operand.
  950. 'C' print part of opcode for a branch condition.
  951. 'F' print part of opcode for a floating-point branch condition.
  952. + 'H' print the appropiate Integer pipe # for r5900 mult/div instructions.
  953. 'N' print part of opcode for a branch condition, inverted.
  954. 'W' print part of opcode for a floating-point branch condition, inverted.
  955. 'S' X is CODE_LABEL, print with prefix of "LS" (for embedded switch).
  956. @@ -5649,7 +5867,17 @@
  957. default:
  958. abort_with_insn (op, "PRINT_OPERAND, invalid insn for %%W");
  959. }
  960. + else if (letter == 'H')
  961. + {
  962. + if (true_regnum (op) >= MD_REG_FIRST
  963. + && true_regnum (op) <= MD_REG_LAST)
  964. + ;
  965. +
  966. + else if (true_regnum (op) >= MD1_REG_FIRST
  967. + && true_regnum (op) <= MD1_REG_LAST)
  968. + fputs ("1", file);
  969.  
  970. + }
  971. else if (letter == 'S')
  972. {
  973. char buffer[100];
  974. @@ -5673,6 +5901,16 @@
  975. fprintf (file, "%s,", reg_names[regnum]);
  976. }
  977.  
  978. + else if ((letter == 'L' || letter == 'M')
  979. + && code == CONST_DOUBLE
  980. + && GET_MODE (op) == VOIDmode)
  981. + {
  982. + if (letter == 'L')
  983. + fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (op));
  984. + else
  985. + fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_HIGH (op));
  986. + }
  987. +
  988. else if (code == REG || code == SUBREG)
  989. {
  990. register int regnum;
  991. @@ -6144,8 +6382,7 @@
  992. || (mips_load_reg != 0 && reg_mentioned_p (mips_load_reg, pattern))
  993. || (mips_load_reg2 != 0 && reg_mentioned_p (mips_load_reg2, pattern))
  994. || (mips_load_reg3 != 0 && reg_mentioned_p (mips_load_reg3, pattern))
  995. - || (mips_load_reg4 != 0
  996. - && reg_mentioned_p (mips_load_reg4, pattern)))
  997. + || (mips_load_reg4 != 0 && reg_mentioned_p (mips_load_reg4, pattern)))
  998. fputs ("\t#nop\n", asm_out_file);
  999.  
  1000. else
  1001. @@ -6343,6 +6580,27 @@
  1002. }
  1003. }
  1004. +void
  1005. +mips_declare_object_align (stream, name, init_string, final_string, size, align)
  1006. + FILE *stream;
  1007. + const char *name;
  1008. + const char *init_string;
  1009. + const char *final_string;
  1010. + int size;
  1011. + int align;
  1012. +{
  1013. + fputs (init_string, stream); /* "", "\t.comm\t", or "\t.lcomm\t" */
  1014. + assemble_name (stream, name);
  1015. + fprintf (stream, final_string, size, align); /* ":\n", ",%u\n", ",%u\n" */
  1016. +
  1017. + if (TARGET_GP_OPT)
  1018. + {
  1019. + tree name_tree = get_identifier (name);
  1020. + TREE_ASM_WRITTEN (name_tree) = 1;
  1021. + }
  1022. +}
  1023. +
  1024. +
  1025. /* Return the bytes needed to compute the frame pointer from the current
  1026. stack pointer.
  1027.  
  1028. @@ -6455,7 +6713,7 @@
  1029. || (GET_MODE_SIZE (DECL_MODE (DECL_RESULT (current_function_decl)))
  1030. <= 4))))
  1031. {
  1032. - gp_reg_size += GET_MODE_SIZE (gpr_mode);
  1033. + gp_reg_size += GET_MODE_SIZE (mips_reg_mode[0]);
  1034. mask |= 1L << (regno - GP_REG_FIRST);
  1035.  
  1036. /* The entry and exit pseudo instructions can not save $17
  1037. @@ -6479,7 +6737,7 @@
  1038. regno = EH_RETURN_DATA_REGNO (i);
  1039. if (regno == INVALID_REGNUM)
  1040. break;
  1041. - gp_reg_size += GET_MODE_SIZE (gpr_mode);
  1042. + gp_reg_size += GET_MODE_SIZE (mips_reg_mode[0]);
  1043. mask |= 1L << (regno - GP_REG_FIRST);
  1044. }
  1045. }
  1046. @@ -6561,9 +6819,9 @@
  1047. top of the stack. */
  1048. if (! mips_entry)
  1049. offset = (args_size + extra_size + var_size
  1050. - + gp_reg_size - GET_MODE_SIZE (gpr_mode));
  1051. + + gp_reg_size - GET_MODE_SIZE (mips_reg_mode[0]));
  1052. else
  1053. - offset = total_size - GET_MODE_SIZE (gpr_mode);
  1054. + offset = total_size - GET_MODE_SIZE (mips_reg_mode[0]);
  1055.  
  1056. current_frame_info.gp_sp_offset = offset;
  1057. current_frame_info.gp_save_offset = offset - total_size;
  1058. @@ -6699,6 +6957,24 @@
  1059. mips_annotate_frame_insn (emit_move_insn (mem, reg), dwarf_expr);
  1060. }
  1061.  
  1062. +/* If modifying X uses a larger mode than in mips_reg_mode,
  1063. + indicate that fact by setting mips_reg_mode. */
  1064. +
  1065. +static void
  1066. +mips_check_reg_mode (x, set, data)
  1067. + rtx x;
  1068. + rtx set ATTRIBUTE_UNUSED;
  1069. + void *data ATTRIBUTE_UNUSED;
  1070. +{
  1071. + if (GET_CODE (x) == REG
  1072. + && REGNO (x) <= GP_REG_LAST
  1073. + && (GET_MODE_SIZE (GET_MODE (x))
  1074. + > GET_MODE_SIZE (mips_reg_mode[REGNO (x)])))
  1075. + {
  1076. + mips_reg_mode[REGNO (x)] = GET_MODE (x);
  1077. + }
  1078. +}
  1079. +
  1080. static void
  1081. save_restore_insns (store_p, large_reg, large_offset, file)
  1082. int store_p; /* true if this is prologue */
  1083. @@ -6735,6 +7011,47 @@
  1084. need a nop in the epilog if at least one register is reloaded in
  1085. addition to return address. */
  1086.  
  1087. + if (TARGET_MIPS5900 && store_p)
  1088. + {
  1089. + rtx insn;
  1090. + tree attr;
  1091. +
  1092. + for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
  1093. + {
  1094. + if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  1095. + note_stores (PATTERN (insn), mips_check_reg_mode, NULL);
  1096. + }
  1097. +
  1098. + if ((attr = lookup_attribute
  1099. + ("register_precision", DECL_ATTRIBUTES (current_function_decl)))
  1100. + != 0)
  1101. + for (; attr; attr = TREE_CHAIN (attr))
  1102. + {
  1103. + const char *reg_expr = IDENTIFIER_POINTER (TREE_VALUE (TREE_VALUE (attr)));
  1104. + tree reg_length = TREE_VALUE (TREE_CHAIN (TREE_VALUE (attr)));
  1105. + enum machine_mode mode = VOIDmode;
  1106. + int j;
  1107. + switch (TREE_INT_CST_LOW (reg_length))
  1108. + {
  1109. + case 32:
  1110. + mode= SImode;
  1111. + break;
  1112. + case 64:
  1113. + mode= DImode;
  1114. + break;
  1115. + case 128:
  1116. + mode= TImode;
  1117. + break;
  1118. + }
  1119. +
  1120. + if ((j = decode_reg_name (reg_expr)) >= 0)
  1121. + {
  1122. + if (j != 0)
  1123. + mips_reg_mode[j] = mode;
  1124. + }
  1125. + }
  1126. + }
  1127. +
  1128. /* Save GP registers if needed. */
  1129. if (mask)
  1130. {
  1131. @@ -6747,7 +7064,7 @@
  1132. gp_offset = current_frame_info.gp_sp_offset;
  1133. end_offset
  1134. = gp_offset - (current_frame_info.gp_reg_size
  1135. - - GET_MODE_SIZE (gpr_mode));
  1136. + - GET_MODE_SIZE (mips_reg_mode[0]));
  1137.  
  1138. if (gp_offset < 0 || end_offset < 0)
  1139. internal_error
  1140. @@ -6810,7 +7127,8 @@
  1141. {
  1142. rtx reg_rtx;
  1143. rtx mem_rtx
  1144. - = gen_rtx (MEM, gpr_mode,
  1145. + = gen_rtx (MEM,
  1146. + mips_reg_mode[regno],
  1147. gen_rtx (PLUS, Pmode, base_reg_rtx,
  1148. GEN_INT (gp_offset - base_offset)));
  1149.  
  1150. @@ -6821,23 +7139,24 @@
  1151. $31, so we load $7 instead, and work things out
  1152. in mips_expand_epilogue. */
  1153. if (TARGET_MIPS16 && ! store_p && regno == GP_REG_FIRST + 31)
  1154. - reg_rtx = gen_rtx (REG, gpr_mode, GP_REG_FIRST + 7);
  1155. + reg_rtx = gen_rtx (REG, mips_reg_mode[7], GP_REG_FIRST + 7);
  1156. /* The mips16 sometimes needs to save $18. */
  1157. else if (TARGET_MIPS16
  1158. && regno != GP_REG_FIRST + 31
  1159. && ! M16_REG_P (regno))
  1160. {
  1161. if (! store_p)
  1162. - reg_rtx = gen_rtx (REG, gpr_mode, 6);
  1163. + reg_rtx = gen_rtx (REG, mips_reg_mode[6], 6);
  1164. else
  1165. {
  1166. - reg_rtx = gen_rtx (REG, gpr_mode, 3);
  1167. + reg_rtx = gen_rtx (REG, mips_reg_mode[3], 3);
  1168. emit_move_insn (reg_rtx,
  1169. - gen_rtx (REG, gpr_mode, regno));
  1170. + gen_rtx (REG, mips_reg_mode[regno],
  1171. + regno));
  1172. }
  1173. }
  1174. else
  1175. - reg_rtx = gen_rtx (REG, gpr_mode, regno);
  1176. + reg_rtx = gen_rtx (REG, mips_reg_mode[regno], regno);
  1177.  
  1178. if (store_p)
  1179. mips_emit_frame_related_store (mem_rtx, reg_rtx, gp_offset);
  1180. @@ -6847,7 +7166,7 @@
  1181. if (TARGET_MIPS16
  1182. && regno != GP_REG_FIRST + 31
  1183. && ! M16_REG_P (regno))
  1184. - emit_move_insn (gen_rtx (REG, gpr_mode, regno),
  1185. + emit_move_insn (gen_rtx (REG, mips_reg_mode[regno], regno),
  1186. reg_rtx);
  1187. }
  1188. }
  1189. @@ -6889,13 +7208,13 @@
  1190. fprintf (file, "\tmove\t%s,%s\n",
  1191. reg_names[regno], reg_names[r]);
  1192. }
  1193. - gp_offset -= GET_MODE_SIZE (gpr_mode);
  1194. + gp_offset -= GET_MODE_SIZE (mips_reg_mode[0]);
  1195. }
  1196. /* If the restore is being supressed, still take into account
  1197. the offset at which it is stored. */
  1198. else if (BITSET_P (real_mask, regno - GP_REG_FIRST))
  1199. {
  1200. - gp_offset -= GET_MODE_SIZE (gpr_mode);
  1201. + gp_offset -= GET_MODE_SIZE (mips_reg_mode[0]);
  1202. }
  1203. }
  1204. else
  1205. @@ -6920,13 +7239,13 @@
  1206. base_reg_rtx = stack_pointer_rtx, base_offset = 0;
  1207.  
  1208. else if (base_reg_rtx != 0
  1209. - && (unsigned HOST_WIDE_INT) (base_offset - fp_offset) < 32768
  1210. - && (unsigned HOST_WIDE_INT) (base_offset - end_offset) < 32768)
  1211. + && (((unsigned HOST_WIDE_INT) (base_offset - fp_offset)) < 32768)
  1212. + && (((unsigned HOST_WIDE_INT) (base_offset - end_offset)) < 32768))
  1213. ; /* already set up for gp registers above */
  1214.  
  1215. else if (large_reg != 0
  1216. - && (unsigned HOST_WIDE_INT) (large_offset - fp_offset) < 32768
  1217. - && (unsigned HOST_WIDE_INT) (large_offset - end_offset) < 32768)
  1218. + && (((unsigned HOST_WIDE_INT) (large_offset - fp_offset)) < 32768)
  1219. + && (((unsigned HOST_WIDE_INT) (large_offset - end_offset)) < 32768))
  1220. {
  1221. base_reg_rtx = gen_rtx_REG (Pmode, MIPS_TEMP2_REGNUM);
  1222. base_offset = large_offset;
  1223. @@ -7358,10 +7677,10 @@
  1224. {
  1225. if (offset != 0)
  1226. ptr = gen_rtx (PLUS, Pmode, stack_pointer_rtx, GEN_INT (offset));
  1227. - emit_move_insn (gen_rtx (MEM, gpr_mode, ptr),
  1228. - gen_rtx (REG, gpr_mode, regno));
  1229. + emit_move_insn (gen_rtx (MEM, mips_reg_mode[regno], ptr),
  1230. + gen_rtx (REG, mips_reg_mode[regno], regno));
  1231.  
  1232. - offset += GET_MODE_SIZE (gpr_mode);
  1233. + offset += GET_MODE_SIZE (mips_reg_mode[0]);
  1234. }
  1235. }
  1236.  
  1237. @@ -7406,7 +7725,8 @@
  1238. moment. */
  1239. if (TARGET_MIPS16 && BITSET_P (current_frame_info.mask, 18))
  1240. {
  1241. - rtx reg_rtx = gen_rtx (REG, gpr_mode, GP_REG_FIRST + 3);
  1242. + rtx reg_rtx = gen_rtx (REG, mips_reg_mode[GP_REG_FIRST + 3],
  1243. + GP_REG_FIRST + 3);
  1244. long gp_offset, base_offset;
  1245.  
  1246. gp_offset = current_frame_info.gp_sp_offset;
  1247. @@ -7422,8 +7742,9 @@
  1248. base_offset = 0;
  1249. start_sequence ();
  1250. emit_move_insn (reg_rtx,
  1251. - gen_rtx (REG, gpr_mode, GP_REG_FIRST + 18));
  1252. - emit_move_insn (gen_rtx (MEM, gpr_mode,
  1253. + gen_rtx (REG, mips_reg_mode[GP_REG_FIRST + 18],
  1254. + GP_REG_FIRST + 18));
  1255. + emit_move_insn (gen_rtx (MEM, mips_reg_mode[GP_REG_FIRST + 18],
  1256. gen_rtx (PLUS, Pmode, stack_pointer_rtx,
  1257. GEN_INT (gp_offset
  1258. - base_offset))),
  1259. @@ -8153,6 +8474,11 @@
  1260. if (type == NULL_TREE || mode == DImode || mode == DFmode)
  1261. return 0;
  1262.  
  1263. + /* The r5900 can pass TImode values in a single register, so
  1264. + there is no need to pass it by reference. */
  1265. + if (mode == TImode && TARGET_MIPS5900)
  1266. + return 0;
  1267. +
  1268. size = int_size_in_bytes (type);
  1269. return size == -1 || size > UNITS_PER_WORD;
  1270. }
  1271. @@ -8213,15 +8539,30 @@
  1272. && gp_reg_p
  1273. && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode))
  1274. ? NO_REGS : gr_regs);
  1275. +
  1276. + else if (class == HILO1_REG && regno != GP_REG_FIRST + 0)
  1277. + return ((! in_p
  1278. + && gp_reg_p
  1279. + && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode))
  1280. + ? NO_REGS : gr_regs);
  1281. +
  1282. else if (regno == HILO_REGNUM)
  1283. return ((in_p
  1284. && class == gr_regs
  1285. && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode))
  1286. ? NO_REGS : gr_regs);
  1287.  
  1288. + else if (regno == HILO1_REGNUM)
  1289. + return ((in_p
  1290. + && class == gr_regs
  1291. + && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode))
  1292. + ? NO_REGS : gr_regs);
  1293. +
  1294. /* Copying from HI or LO to anywhere other than a general register
  1295. requires a general register. */
  1296. - if (class == HI_REG || class == LO_REG || class == MD_REGS)
  1297. +
  1298. + if (class == HI_REG || class == LO_REG || class == MD_REGS
  1299. + || class == HI1_REG || class == LO1_REG || class == MD1_REGS)
  1300. {
  1301. if (TARGET_MIPS16 && in_p)
  1302. {
  1303. @@ -8230,7 +8571,8 @@
  1304. }
  1305. return gp_reg_p ? NO_REGS : gr_regs;
  1306. }
  1307. - if (MD_REG_P (regno))
  1308. +
  1309. + if (MD_REG_P (regno) || MD1_REG_P (regno))
  1310. {
  1311. if (TARGET_MIPS16 && ! in_p)
  1312. {
  1313. @@ -9389,6 +9731,11 @@
  1314. if (! TARGET_MIPS16)
  1315. return;
  1316.  
  1317. +#ifdef FILL_BDSLOT_WITH_NOP
  1318. + if (TARGET_MIPS5900 && !TARGET_NO_LENGTHEN_LOOP)
  1319. + r5900_lengthen_loops (first,0);
  1320. +#endif
  1321. +
  1322. /* If $gp is used, try to remove stores, and replace loads with
  1323. copies from $gp. */
  1324. if (optimize)
  1325. @@ -9578,6 +9925,205 @@
  1326. constant table, but we have no way to prevent that. */
  1327. }
  1328.  
  1329. +
  1330. +/* On the R5900, we must ensure that the compiler never generates loops
  1331. + that satisfy all of the following conditions:
  1332. +
  1333. + * a loop consists of less than equal to six instructions (including the
  1334. + branch delay slot).
  1335. +
  1336. + * a loop contains only one conditional branch instruction at the
  1337. + end of the loop.
  1338. +
  1339. + * a loop does not contain any other branch or jump instructions.
  1340. +
  1341. + * a branch delay slot of the loop is not nop. ( EE#2.9 or later )
  1342. +
  1343. + We need to do this because of a bug in the chip.
  1344. +
  1345. + */
  1346. +
  1347. +#define NOP_INSN_P(INSN) (rtx_equal_p (INSN, gen_nop ()))
  1348. +
  1349. +enum sequence_type {Jump, Reset, Other};
  1350. +
  1351. +/* Detect if possible loop jump presents in the sequence */
  1352. +
  1353. +static enum sequence_type
  1354. +r5900_detect_sequence_type (insn, count_p, jump_insn_p, seen_before,
  1355. + after_delayed_branch_sched)
  1356. + rtx insn;
  1357. + int *count_p;
  1358. + rtx *jump_insn_p;
  1359. + int *seen_before;
  1360. + int after_delayed_branch_sched;
  1361. +{
  1362. + int i;
  1363. + int detect_later = 0;
  1364. +
  1365. + for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
  1366. + {
  1367. + rtx v_insn;
  1368. + v_insn = XVECEXP (PATTERN (insn), 0, i);
  1369. +
  1370. + switch (GET_CODE (v_insn))
  1371. + {
  1372. + case CODE_LABEL:
  1373. + seen_before [INSN_UID (v_insn)] = *count_p;
  1374. + break;
  1375. + case INSN:
  1376. + /* The attr_length may be bigger than acctual insn length.
  1377. + So don't use it in the after_delayed_branch_sched phase. */
  1378. + *count_p += ( get_attr_length (insn) > 0
  1379. + && !after_delayed_branch_sched )
  1380. + ? get_attr_length (insn) : 4 ;
  1381. + if (detect_later)
  1382. + {
  1383. + /* inspect BD slot */
  1384. + if (NOP_INSN_P (PATTERN (v_insn)))
  1385. + return Reset;
  1386. + return Jump;
  1387. + }
  1388. + break;
  1389. + case JUMP_INSN:
  1390. + *jump_insn_p = v_insn;
  1391. + detect_later = 1;
  1392. + break;
  1393. + case CALL_INSN:
  1394. + return Reset;
  1395. + break;
  1396. + default:
  1397. + break;
  1398. + }
  1399. + }
  1400. +
  1401. + if (detect_later)
  1402. + /* Since there's no instruction in the delay slot, the assembler will
  1403. + insert a "nop" later. */
  1404. + return Reset;
  1405. +
  1406. + return Other;
  1407. +}
  1408. +
  1409. +/* XXX: Fix this. */
  1410. +
  1411. +static void
  1412. +r5900_lengthen_loops (first, after_delayed_branch_sched)
  1413. + rtx first;
  1414. + int after_delayed_branch_sched;
  1415. +{
  1416. + rtx insn;
  1417. + rtx this_jump_insn;
  1418. + const int hazardous_distance = 6;
  1419. + int n = 4;
  1420. + int max_uid = get_max_uid ();
  1421. + int *seen_before = alloca (sizeof seen_before[0] * max_uid);
  1422. + int in_sequence = 0;
  1423. + enum sequence_type result;
  1424. +
  1425. + /*bzero ((char *) seen_before, sizeof seen_before[0] * max_uid);*/
  1426. + memset((char *) seen_before, 0, sizeof seen_before[0] * max_uid);
  1427. +
  1428. + for (insn = first; insn; insn = NEXT_INSN (insn))
  1429. + {
  1430. + in_sequence = 0;
  1431. + switch (GET_CODE (insn))
  1432. + {
  1433. + case CODE_LABEL:
  1434. + seen_before [INSN_UID (insn)] = n;
  1435. + break;
  1436. +
  1437. + case INSN:
  1438. + if (GET_CODE (PATTERN (insn)) != SEQUENCE )
  1439. + {
  1440. + /* The attr_length may be bigger than acctual insn length.
  1441. + So don't use it in the after_delayed_branch_sched phase. */
  1442. + n += ( get_attr_length (insn) > 0
  1443. + && !after_delayed_branch_sched )
  1444. + ? get_attr_length (insn) : 4 ;
  1445. + break;
  1446. + }
  1447. + result = r5900_detect_sequence_type(insn, &n, &this_jump_insn,
  1448. + seen_before, after_delayed_branch_sched);
  1449. + switch(result)
  1450. + {
  1451. + case Reset:
  1452. + goto reset;
  1453. + case Jump:
  1454. + in_sequence=1;
  1455. + goto jump_insn;
  1456. + case Other:
  1457. + default:
  1458. + break;
  1459. + }
  1460. + break;
  1461. +
  1462. + case JUMP_INSN:
  1463. + this_jump_insn = insn;
  1464. + in_sequence=0;
  1465. + jump_insn:
  1466. + if (condjump_p (this_jump_insn))
  1467. + {
  1468. + rtx target = condjump_label (this_jump_insn);
  1469. +
  1470. + if (seen_before [INSN_UID (XEXP (target, 0))])
  1471. + {
  1472. + int distance
  1473. + = (n - seen_before [INSN_UID (XEXP (target, 0))]) >> 2;
  1474. +
  1475. + if (!in_sequence)
  1476. + {
  1477. + /* try to insert one nop before jump
  1478. + * if distance is in hazardous_distance */
  1479. +
  1480. + if ( distance <= hazardous_distance )
  1481. + {
  1482. + rtx prev_insn = PREV_INSN (this_jump_insn);
  1483. + while ( prev_insn && ( GET_CODE (prev_insn) != INSN ))
  1484. + prev_insn = PREV_INSN (prev_insn);
  1485. + if (prev_insn && ! NOP_INSN_P (PATTERN (prev_insn)))
  1486. + emit_insn_before (gen_nop (), this_jump_insn);
  1487. +
  1488. + }
  1489. + }
  1490. + else
  1491. + {
  1492. + if ( distance <= hazardous_distance )
  1493. + {
  1494. + for (; distance <= hazardous_distance; distance++)
  1495. + emit_insn_before (gen_nop(), insn);
  1496. + }
  1497. + }
  1498. + }
  1499. + }
  1500. +
  1501. + /* Falls through */
  1502. +
  1503. + case CALL_INSN:
  1504. + reset:
  1505. + /*bzero ((char *) seen_before, sizeof seen_before[0] * max_uid);*/
  1506. + memset((char *) seen_before, 0, sizeof seen_before[0] * max_uid);
  1507. + break;
  1508. +
  1509. + default:
  1510. + break;
  1511. + }
  1512. + }
  1513. +}
  1514. +
  1515. +/* Exported to toplev.c.
  1516. +
  1517. + Do a final pass over the function, just before rtl to asm conversion
  1518. + (after "delayed branch scheduling" and "shorten jump"). */
  1519. +
  1520. +void
  1521. +machine_dependent_reorg_final (first)
  1522. + rtx first;
  1523. +{
  1524. + if (TARGET_MIPS5900 && ! TARGET_NO_LENGTHEN_LOOP)
  1525. + r5900_lengthen_loops (first, 1);
  1526. +}
  1527. +
  1528. /* Return nonzero if X is a SIGN or ZERO extend operator. */
  1529. int
  1530. extend_operator (x, mode)
  1531. @@ -9978,6 +10524,8 @@
  1532. case '5':
  1533. if (!strcmp (p, "5000") || !strcmp (p, "5k") || !strcmp (p, "5K"))
  1534. cpu = PROCESSOR_R5000;
  1535. + else if (!strcmp (p, "5900"))
  1536. + cpu = PROCESSOR_R5900;
  1537. else if (!strcmp (p, "5kc") || !strcmp (p, "5Kc") )
  1538. cpu = PROCESSOR_R5KC;
  1539. break;
  1540. @@ -10102,7 +10650,10 @@
  1541. int regno;
  1542. enum machine_mode mode;
  1543. {
  1544. - if (! FP_REG_P (regno))
  1545. + /* TODO: Add r5900 dual mode register support. */
  1546. + if (TARGET_MIPS5900 && GP_REG_P (regno) && mode == TImode)
  1547. + return 1;
  1548. + else if (! FP_REG_P (regno))
  1549. return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
  1550. else
  1551. return ((GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG);
  1552. @@ -10268,3 +10819,345 @@
  1553. mips_asm_file_end (stream);
  1554. }
  1555. #endif /* TARGET_IRIX6 */
  1556. +
  1557. +static void
  1558. +r5900_sched_init ()
  1559. +{
  1560. +}
  1561. +
  1562. +static void
  1563. +mips_sched_init (dump, sched_verbose, veclen)
  1564. + FILE *dump ATTRIBUTE_UNUSED;
  1565. + int sched_verbose ATTRIBUTE_UNUSED;
  1566. + int veclen ATTRIBUTE_UNUSED;
  1567. +{
  1568. + if (TARGET_MIPS5900)
  1569. + r5900_sched_init ();
  1570. +}
  1571. +
  1572. +static void
  1573. +r5900_sched_reorder (dump, sched_verbose, ready, n_ready)
  1574. + FILE *dump;
  1575. + int sched_verbose;
  1576. + rtx *ready;
  1577. + int n_ready;
  1578. +{
  1579. + static int imuldivunit = -1;
  1580. +
  1581. + return;
  1582. + /* There is also no point in trying these tweaks after reload has
  1583. + completed. */
  1584. + if (reload_completed)
  1585. + return;
  1586. +
  1587. + /* If there are less than three insns on the queue, then there's nothing
  1588. + to do. */
  1589. + if (n_ready < 3)
  1590. + return;
  1591. +
  1592. + /* We need to know what value will be returned by function_units_used for
  1593. + the r5900's multiply/divide units. If we have not computed it yet,
  1594. + do so now. */
  1595. + if (imuldivunit == -1)
  1596. + {
  1597. + int i;
  1598. +
  1599. + for (i = 0; i < FUNCTION_UNITS_SIZE; i++)
  1600. + {
  1601. + if (!strcmp ("r5900imuldiv", function_units[i].name))
  1602. + {
  1603. + imuldivunit = i;
  1604. + break;
  1605. + }
  1606. + }
  1607. + if (imuldivunit == -1)
  1608. + return;
  1609. + }
  1610. +
  1611. + {
  1612. + int i;
  1613. +
  1614. + /* Loop through the instructions and try to pair up two instructions
  1615. + which use the imuldiv pipelines.
  1616. +
  1617. + We want such instructions to appear back to back in the RTL chain
  1618. + so that the register allocator will allocate a different HILO
  1619. + register for the two imuldiv instructions.
  1620. +
  1621. + Note the ready list is ordered backwards.
  1622. +
  1623. + If we do not find an idivmul insn which could issue this cycle, quit
  1624. + to save time. */
  1625. + for (i = n_ready - 1; i >= n_ready - 2; i--)
  1626. + {
  1627. + rtx insn = ready[i];
  1628. + enum rtx_code code;
  1629. +
  1630. + /* Ignore anything we do not understand. */
  1631. + if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
  1632. + || (code = GET_CODE (PATTERN (insn))) == USE
  1633. + || code == CLOBBER || code == ADDR_VEC)
  1634. + continue;
  1635. + else
  1636. + {
  1637. + /* We are looking for instructions that issue to the imuldiv
  1638. + pipelines. */
  1639. + if (function_units_used (insn) == imuldivunit)
  1640. + {
  1641. + int j;
  1642. +
  1643. + /* We have found one insn that uses the imuldiv pipeline, so
  1644. + now look for another imuldiv instruction. */
  1645. + for (j = i - 1; j >= 0; j--)
  1646. + {
  1647. + rtx temp = ready[j];
  1648. +
  1649. + /* Ignore anything we do not understand. */
  1650. + if (GET_RTX_CLASS (GET_CODE (temp)) != 'i'
  1651. + || (code = GET_CODE (PATTERN (temp))) == USE
  1652. + || code == CLOBBER || code == ADDR_VEC)
  1653. + continue;
  1654. +
  1655. + /* Again, we are looking for an imuldiv insn. */
  1656. + if (function_units_used (temp) == imuldivunit)
  1657. + {
  1658. +
  1659. + /* Make the idivmul insns consecutive if they were
  1660. + not already consecutive. */
  1661. + if (i - j != 1)
  1662. + {
  1663. + rtx temp = ready[j];
  1664. + /*bcopy (&ready[j+1], &ready[j],
  1665. + (i - j - 1) * sizeof (rtx *));*/
  1666. + memcpy(&ready[j], &ready[j+1], (i - j - 1) * sizeof (rtx *));
  1667. + ready[i - 1] = temp;
  1668. + }
  1669. +
  1670. + /* Now the imuldiv insns are consecutive. We can
  1671. + still lose if they issue at different clocks, so
  1672. + move them as a pair to the head of ready list.
  1673. +
  1674. + Note I must either be the head of the queue or
  1675. + the second insn in the queue. */
  1676. + if (i != n_ready - 1)
  1677. + {
  1678. + rtx temp1, temp2;
  1679. +
  1680. + /* Rotate the first three elements in the
  1681. + ready queue. */
  1682. + temp1 = ready[n_ready - 1];
  1683. + temp2 = ready[n_ready - 2];
  1684. + ready[n_ready - 2] = ready[n_ready - 3];
  1685. + ready[n_ready - 3] = temp1;
  1686. + ready[n_ready - 1] = temp2;
  1687. + }
  1688. + return;
  1689. + }
  1690. + }
  1691. + }
  1692. + }
  1693. + }
  1694. + }
  1695. +}
  1696. +
  1697. +/* Reorder the ready list as needed to improve performance. */
  1698. +
  1699. +static int
  1700. +mips_sched_reorder (dump, sched_verbose, ready, n_readyp, clock_var)
  1701. + FILE *dump ATTRIBUTE_UNUSED;
  1702. + int sched_verbose ATTRIBUTE_UNUSED;
  1703. + rtx *ready;
  1704. + int *n_readyp;
  1705. + int clock_var ATTRIBUTE_UNUSED;
  1706. +{
  1707. + if (TARGET_MIPS5900)
  1708. + r5900_sched_reorder (dump, sched_verbose, ready, *n_readyp);
  1709. + return ISSUE_RATE;
  1710. +}
  1711. +
  1712. +/* R5900 built-ins support. This is largely based off of the ix86 SSE/MMX
  1713. + and rs6000 Altivec implementations. */
  1714. +
  1715. +#define def_builtin(MASK, NAME, TYPE, CODE) \
  1716. +do { \
  1717. + if ((MASK) & target_flags) \
  1718. + builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL); \
  1719. +} while (0)
  1720. +
  1721. +struct builtin_description
  1722. +{
  1723. + const unsigned int mask;
  1724. + const enum insn_code icode;
  1725. + const char *const name;
  1726. + const enum r5900_builtins code;
  1727. +};
  1728. +
  1729. +/* Builtins that take 2 arguments. */
  1730. +static struct builtin_description bdesc_2arg[] =
  1731. +{
  1732. + { MASK_MMI, CODE_FOR_addv16qi3, "__builtin_mmi_paddb", MMI_BUILTIN_PADDB },
  1733. + { MASK_MMI, CODE_FOR_addv8hi3, "__builtin_mmi_paddh", MMI_BUILTIN_PADDH },
  1734. + { MASK_MMI, CODE_FOR_addv4si3, "__builtin_mmi_paddw", MMI_BUILTIN_PADDW },
  1735. + { MASK_MMI, CODE_FOR_ssaddv16qi3, "__builtin_mmi_paddsb", MMI_BUILTIN_PADDSB },
  1736. + { MASK_MMI, CODE_FOR_ssaddv8hi3, "__builtin_mmi_paddsh", MMI_BUILTIN_PADDSW },
  1737. + { MASK_MMI, CODE_FOR_ssaddv4si3, "__builtin_mmi_paddsw", MMI_BUILTIN_PADDSH },
  1738. + { MASK_MMI, CODE_FOR_usaddv16qi3, "__builtin_mmi_paddub", MMI_BUILTIN_PADDUB },
  1739. + { MASK_MMI, CODE_FOR_usaddv8hi3, "__builtin_mmi_padduh", MMI_BUILTIN_PADDUW },
  1740. + { MASK_MMI, CODE_FOR_usaddv4si3, "__builtin_mmi_padduw", MMI_BUILTIN_PADDUH },
  1741. +
  1742. + { MASK_MMI, CODE_FOR_subv16qi3, "__builtin_mmi_psubb", MMI_BUILTIN_PSUBB },
  1743. + { MASK_MMI, CODE_FOR_subv8hi3, "__builtin_mmi_psubh", MMI_BUILTIN_PSUBH },
  1744. + { MASK_MMI, CODE_FOR_subv4si3, "__builtin_mmi_psubw", MMI_BUILTIN_PSUBW },
  1745. + { MASK_MMI, CODE_FOR_sssubv16qi3, "__builtin_mmi_psubsb", MMI_BUILTIN_PSUBSB },
  1746. + { MASK_MMI, CODE_FOR_sssubv8hi3, "__builtin_mmi_psubsh", MMI_BUILTIN_PSUBSW },
  1747. + { MASK_MMI, CODE_FOR_sssubv4si3, "__builtin_mmi_psubsw", MMI_BUILTIN_PSUBSH },
  1748. + { MASK_MMI, CODE_FOR_ussubv16qi3, "__builtin_mmi_psubub", MMI_BUILTIN_PSUBUB },
  1749. + { MASK_MMI, CODE_FOR_ussubv8hi3, "__builtin_mmi_psubuh", MMI_BUILTIN_PSUBUW },
  1750. + { MASK_MMI, CODE_FOR_ussubv4si3, "__builtin_mmi_psubuw", MMI_BUILTIN_PSUBUH },
  1751. +
  1752. +};
  1753. +
  1754. +/* Expand all r5900-specific builtins. This is only called if TARGET_MMI or
  1755. + TARGET_VUMM are true. */
  1756. +static void
  1757. +r5900_init_builtins()
  1758. +{
  1759. + struct builtin_description *d;
  1760. + size_t i;
  1761. + tree endlink = void_list_node;
  1762. +
  1763. + /* Normal vector binops. */
  1764. + tree v16qi_ftype_v16qi_v16qi
  1765. + = build_function_type (V16QI_type_node,
  1766. + tree_cons (NULL_TREE, V16QI_type_node,
  1767. + tree_cons (NULL_TREE, V16QI_type_node,
  1768. + endlink)));
  1769. +
  1770. + tree v8hi_ftype_v8hi_v8hi
  1771. + = build_function_type (V8HI_type_node,
  1772. + tree_cons (NULL_TREE, V8HI_type_node,
  1773. + tree_cons (NULL_TREE, V8HI_type_node,
  1774. + endlink)));
  1775. +
  1776. + tree v4si_ftype_v4si_v4si
  1777. + = build_function_type (V4SI_type_node,
  1778. + tree_cons (NULL_TREE, V4SI_type_node,
  1779. + tree_cons (NULL_TREE, V4SI_type_node,
  1780. + endlink)));
  1781. +
  1782. + tree ti_ftype_ti_ti
  1783. + = build_function_type (intTI_type_node,
  1784. + tree_cons (NULL_TREE, intTI_type_node,
  1785. + tree_cons (NULL_TREE, intTI_type_node,
  1786. + endlink)));
  1787. +
  1788. + /* Add all builtins that are simple binary operations. */
  1789. + for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
  1790. + {
  1791. + enum machine_mode mode;
  1792. + tree type;
  1793. +
  1794. + if (d->name == 0)
  1795. + continue;
  1796. + mode = insn_data[d->icode].operand[1].mode;
  1797. +
  1798. + switch (mode)
  1799. + {
  1800. + case V16QImode:
  1801. + type = v16qi_ftype_v16qi_v16qi;
  1802. + break;
  1803. + case V8HImode:
  1804. + type = v8hi_ftype_v8hi_v8hi;
  1805. + case V4SImode:
  1806. + type = v4si_ftype_v4si_v4si;
  1807. + case TImode:
  1808. + type = ti_ftype_ti_ti;
  1809. + break;
  1810. +
  1811. + default:
  1812. + abort ();
  1813. + }
  1814. +
  1815. + def_builtin (d->mask, d->name, type, d->code);
  1816. + }
  1817. +}
  1818. +
  1819. +static rtx
  1820. +r5900_expand_binop_builtin (icode, arglist, target)
  1821. + enum insn_code icode;
  1822. + tree arglist;
  1823. + rtx target;
  1824. +{
  1825. + rtx pat;
  1826. + tree arg0 = TREE_VALUE (arglist);
  1827. + tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
  1828. + rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
  1829. + rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
  1830. + enum machine_mode tmode = insn_data[icode].operand[0].mode;
  1831. + enum machine_mode mode0 = insn_data[icode].operand[1].mode;
  1832. + enum machine_mode mode1 = insn_data[icode].operand[2].mode;
  1833. +
  1834. + if (! target
  1835. + || GET_MODE (target) != tmode
  1836. + || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
  1837. + target = gen_reg_rtx (tmode);
  1838. +
  1839. + /* In case the insn wants input operands in modes different fro
  1840. + the result, abort. */
  1841. + if (GET_MODE (op0) != mode0 || GET_MODE (op1) != mode1)
  1842. + abort ();
  1843. +
  1844. + if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
  1845. + op0 = copy_to_mode_reg (mode0, op0);
  1846. + if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
  1847. + op1 = copy_to_mode_reg (mode1, op1);
  1848. +
  1849. + pat = GEN_FCN (icode) (target, op0, op1);
  1850. + if (! pat)
  1851. + return 0;
  1852. + emit_insn (pat);
  1853. + return target;
  1854. +}
  1855. +
  1856. +static rtx
  1857. +r5900_expand_builtin (exp, target)
  1858. + tree exp;
  1859. + rtx target;
  1860. +{
  1861. + struct builtin_description *d;
  1862. + size_t i;
  1863. + enum insn_code icode;
  1864. + tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
  1865. + tree arglist = TREE_OPERAND (exp, 1);
  1866. + tree arg0, arg1, arg2, arg3;
  1867. + rtx op0, op1, op2, pat;
  1868. + enum machine_mode tmode, mode0, mode1, mode2;
  1869. + unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
  1870. +
  1871. + for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
  1872. + if (d->code == fcode)
  1873. + return r5900_expand_binop_builtin (d->icode, arglist, target);
  1874. +
  1875. + return 0;
  1876. +}
  1877. +
  1878. +static rtx
  1879. +mips_expand_builtin (exp, target, subtarget, mode, ignore)
  1880. + tree exp;
  1881. + rtx target;
  1882. + rtx subtarget ATTRIBUTE_UNUSED;
  1883. + enum machine_mode mode ATTRIBUTE_UNUSED;
  1884. + int ignore ATTRIBUTE_UNUSED;
  1885. +{
  1886. + if (TARGET_MIPS5900)
  1887. + return r5900_expand_builtin (exp, target);
  1888. +
  1889. + abort ();
  1890. +}
  1891. +
  1892. +static void
  1893. +mips_init_builtins ()
  1894. +{
  1895. + if (TARGET_MIPS5900)
  1896. + r5900_init_builtins ();
  1897. +}
  1898. diff -burN orig.gcc-3.2.3/gcc/config/mips/mips.h gcc-3.2.3/gcc/config/mips/mips.h
  1899. --- orig.gcc-3.2.3/gcc/config/mips/mips.h 2002-04-26 18:32:14.000000000 -0300
  1900. +++ gcc-3.2.3/gcc/config/mips/mips.h 2015-08-10 16:11:20 +0300
  1901. @@ -48,6 +48,7 @@
  1902. DELAY_NONE, /* no delay slot */
  1903. DELAY_LOAD, /* load from memory delay */
  1904. DELAY_HILO, /* move from/to hi/lo registers */
  1905. + DELAY_HILO1, /* move from/to hi1/lo1 registers */
  1906. DELAY_FCMP /* delay after doing c.<xx>.{d,s} */
  1907. };
  1908.  
  1909. @@ -67,6 +68,7 @@
  1910. PROCESSOR_R4600,
  1911. PROCESSOR_R4650,
  1912. PROCESSOR_R5000,
  1913. + PROCESSOR_R5900,
  1914. PROCESSOR_R8000,
  1915. PROCESSOR_R4KC,
  1916. PROCESSOR_R5KC,
  1917. @@ -146,6 +148,7 @@
  1918. extern int mips16; /* whether generating mips16 code */
  1919. extern int mips16_hard_float; /* mips16 without -msoft-float */
  1920. extern int mips_entry; /* generate entry/exit for mips16 */
  1921. +extern int mips_alignment; /* max alignment bits */
  1922. extern const char *mips_cpu_string; /* for -mcpu=<xxx> */
  1923. extern const char *mips_arch_string; /* for -march=<xxx> */
  1924. extern const char *mips_tune_string; /* for -mtune=<xxx> */
  1925. @@ -155,6 +158,11 @@
  1926. extern const char *mips_no_mips16_string;/* for -mno-mips16 */
  1927. extern const char *mips_explicit_type_size_string;/* for -mexplicit-type-size */
  1928. extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */
  1929. +extern const char *mips_align_all_string;/* for -malign-all= */
  1930. +extern const char * mips_align128_string;/* for -malign128 */
  1931. +extern const char * mips_no_align128_string;/* for -mno-align128 */
  1932. +extern const char * mips_use_128_string; /* for -muse-128 */
  1933. +extern int mips_use_128; /* the boolean for -muse-128 */
  1934. extern int mips_split_addresses; /* perform high/lo_sum support */
  1935. extern int dslots_load_total; /* total # load related delay slots */
  1936. extern int dslots_load_filled; /* # filled load delay slots */
  1937. @@ -175,6 +183,8 @@
  1938. extern void sdata_section PARAMS ((void));
  1939. extern void sbss_section PARAMS ((void));
  1940.  
  1941. +extern int mips_align_all;
  1942. +
  1943. /* Stubs for half-pic support if not OSF/1 reference platform. */
  1944.  
  1945. #ifndef HALF_PIC_P
  1946. @@ -232,6 +242,10 @@
  1947. consts in rodata */
  1948. #define MASK_NO_FUSED_MADD 0x01000000 /* Don't generate floating point
  1949. multiply-add operations. */
  1950. +#define MASK_MMI 0x02000000 /* r5900 MultiMedia Instructions (MMI) */
  1951. +#define MASK_VUMM 0x04000000 /* r5900 VU0 macro mode (COP2) */
  1952. +#define MASK_NO_LENGTHEN_LOOP \
  1953. + 0x08000000 /* Disable r5900 loop bug workaround */
  1954.  
  1955. /* Debug switches, not documented */
  1956. #define MASK_DEBUG 0 /* unused */
  1957. @@ -327,6 +341,16 @@
  1958. #define TARGET_NO_CHECK_ZERO_DIV (target_flags & MASK_NO_CHECK_ZERO_DIV)
  1959. #define TARGET_CHECK_RANGE_DIV (target_flags & MASK_CHECK_RANGE_DIV)
  1960.  
  1961. + /* enable r5900 multimedia
  1962. + instructions. */
  1963. +#define TARGET_MMI (target_flags & MASK_MMI)
  1964. +
  1965. + /* enable r5900 macro mode for VU0 */
  1966. +#define TARGET_VUMM (target_flags & MASK_VUMM)
  1967. +
  1968. + /* disable r5900 loop bug workaround */
  1969. +#define TARGET_NO_LENGTHEN_LOOP (target_flags & MASK_NO_LENGTHEN_LOOP)
  1970. +
  1971. /* This is true if we must enable the assembly language file switching
  1972. code. */
  1973.  
  1974. @@ -346,6 +370,7 @@
  1975. #define TARGET_MIPS4000 (mips_arch == PROCESSOR_R4000)
  1976. #define TARGET_MIPS4100 (mips_arch == PROCESSOR_R4100)
  1977. #define TARGET_MIPS4300 (mips_arch == PROCESSOR_R4300)
  1978. +#define TARGET_MIPS5900 (mips_arch == PROCESSOR_R5900)
  1979. #define TARGET_MIPS4KC (mips_arch == PROCESSOR_R4KC)
  1980. #define TARGET_MIPS5KC (mips_arch == PROCESSOR_R5KC)
  1981.  
  1982. @@ -354,6 +379,7 @@
  1983. #define TUNE_MIPS3900 (mips_tune == PROCESSOR_R3900)
  1984. #define TUNE_MIPS4000 (mips_tune == PROCESSOR_R4000)
  1985. #define TUNE_MIPS5000 (mips_tune == PROCESSOR_R5000)
  1986. +#define TUNE_MIPS5900 (mips_tune == PROCESSOR_R5900)
  1987. #define TUNE_MIPS6000 (mips_tune == PROCESSOR_R6000)
  1988.  
  1989. /* Macro to define tables used to set the flags.
  1990. @@ -464,6 +490,18 @@
  1991. N_("Optimize for 3900")}, \
  1992. {"4650", 0, \
  1993. N_("Optimize for 4650")}, \
  1994. + {"5900", 0, \
  1995. + N_("Optimize for 5900")}, \
  1996. + {"mmi", MASK_MMI, \
  1997. + N_("Use r5900 multimedia instructions")}, \
  1998. + {"no-mmi", -MASK_MMI, \
  1999. + N_("Don't use r5900 multimedia instructions")}, \
  2000. + {"vumm", MASK_VUMM, \
  2001. + N_("Use r5900 VU0 macro mode instructions")}, \
  2002. + {"no-vumm", -MASK_VUMM, \
  2003. + N_("Don't use r5900 VU0 macro mode instructions")}, \
  2004. + {"no-lengthen-loop", MASK_NO_LENGTHEN_LOOP, \
  2005. + N_("Don't workaround r5900 short loop bug")}, \
  2006. {"check-zero-division",-MASK_NO_CHECK_ZERO_DIV, \
  2007. N_("Trap on integer divide by zero")}, \
  2008. {"no-check-zero-division", MASK_NO_CHECK_ZERO_DIV, \
  2009. @@ -472,6 +510,8 @@
  2010. N_("Trap on integer divide overflow")}, \
  2011. {"no-check-range-division",-MASK_CHECK_RANGE_DIV, \
  2012. N_("Don't trap on integer divide overflow")}, \
  2013. + {"iop", 0, \
  2014. + N_("Output IOP's IRX file")}, \
  2015. {"debug", MASK_DEBUG, \
  2016. NULL}, \
  2017. {"debuga", MASK_DEBUG_A, \
  2018. @@ -604,6 +644,8 @@
  2019. N_("Don't call any cache flush functions")}, \
  2020. { "flush-func=", &mips_cache_flush_func, \
  2021. N_("Specify cache flush function")}, \
  2022. + { "align-all=", &mips_align_all_string, \
  2023. + N_("Force lower alignment")}, \
  2024. }
  2025.  
  2026. /* This is meant to be redefined in the host dependent files. */
  2027. @@ -613,6 +655,7 @@
  2028.  
  2029. /* Generate three-operand multiply instructions for SImode. */
  2030. #define GENERATE_MULT3_SI ((TARGET_MIPS3900 \
  2031. + || TARGET_MIPS5900 \
  2032. || mips_isa == 32 \
  2033. || mips_isa == 64) \
  2034. && !TARGET_MIPS16)
  2035. @@ -644,7 +687,7 @@
  2036. || mips_isa == 64)
  2037.  
  2038. /* ISA has just the integer condition move instructions (movn,movz) */
  2039. -#define ISA_HAS_INT_CONDMOVE 0
  2040. +#define ISA_HAS_INT_CONDMOVE (TARGET_MIPS5900)
  2041.  
  2042.  
  2043.  
  2044. @@ -847,7 +890,7 @@
  2045. /* GAS_ASM_SPEC is passed when using gas, rather than the MIPS
  2046. assembler. */
  2047.  
  2048. -#define GAS_ASM_SPEC "%{march=*} %{mtune=*} %{mcpu=*} %{m4650} %{mmad:-m4650} %{m3900} %{v} %{mgp32} %{mgp64} %(abi_gas_asm_spec) %{mabi=32:%{!mips*:-mips1}}"
  2049. +#define GAS_ASM_SPEC "%{march=*} %{mtune=*} %{mcpu=*} %{m4650} %{mmad:-m4650} %{m3900} %{m5900} %{v} %{mgp32} %{mgp64} %(abi_gas_asm_spec) %{mabi=32:%{!mips*:-mips1}}"
  2050.  
  2051.  
  2052. extern int mips_abi;
  2053. @@ -964,7 +1007,7 @@
  2054. #ifndef LINK_SPEC
  2055. #define LINK_SPEC "\
  2056. %(endian_spec) \
  2057. -%{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips64} \
  2058. +%{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips64} %{miop:-mmipsirx} \
  2059. %{bestGnum} %{shared} %{non_shared}"
  2060. #endif /* LINK_SPEC defined */
  2061.  
  2062. @@ -984,7 +1027,9 @@
  2063. %{m3900:-march=r3900 -mips1 -mfp32 -mgp32 \
  2064. %n`-m3900' is deprecated. Use `-march=r3900' instead.\n} \
  2065. %{m4650:-march=r4650 -mmad -msingle-float \
  2066. -%n`-m4650' is deprecated. Use `-march=r4650' instead.\n}}"
  2067. +%n`-m4650' is deprecated. Use `-march=r4650' instead.\n} \
  2068. +%{m5900:-march=r5900 -mips3 -mgp64 -mfp32 -mlong64 -mmmi -msingle-float \
  2069. +%n`-m5900' is deprecated. Use `-march=r5900' instead.\n}}"
  2070. #endif
  2071.  
  2072. /* CC1_SPEC is the set of arguments to pass to the compiler proper. */
  2073. @@ -1003,6 +1048,7 @@
  2074. %{mfp64:%{msingle-float:%emay not use both -mfp64 and -msingle-float}} \
  2075. %{mfp64:%{m4650:%emay not use both -mfp64 and -m4650}} \
  2076. %{mint64|mlong64|mlong32:-mexplicit-type-size }\
  2077. +%{miop:-march=r3000 -mfp32 -mgp32 -fno-builtin} \
  2078. %{mgp32: %{mfp64:%emay not use both -mgp32 and -mfp64} %{!mfp32: -mfp32}} \
  2079. %{G*} %{EB:-meb} %{EL:-mel} %{EB:%{EL:%emay not use both -EB and -EL}} \
  2080. %{pic-none: -mno-half-pic} \
  2081. @@ -1661,7 +1707,7 @@
  2082. #define STRUCTURE_SIZE_BOUNDARY 8
  2083.  
  2084. /* There is no point aligning anything to a rounder boundary than this. */
  2085. -#define BIGGEST_ALIGNMENT 64
  2086. +#define BIGGEST_ALIGNMENT 128
  2087.  
  2088. /* Set this nonzero if move instructions will actually fail to work
  2089. when given unaligned data. */
  2090. @@ -1796,20 +1842,20 @@
  2091. address reg ($31) was stored. This is needed for C++ exception
  2092. handling. */
  2093.  
  2094. -#define FIRST_PSEUDO_REGISTER 76
  2095. +#define FIRST_PSEUDO_REGISTER 79
  2096.  
  2097. /* 1 for registers that have pervasive standard uses
  2098. and are not available for the register allocator.
  2099.  
  2100. On the MIPS, see conventions, page D-2 */
  2101. -
  2102. #define FIXED_REGISTERS \
  2103. { \
  2104. 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  2105. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
  2106. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  2107. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  2108. - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \
  2109. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, \
  2110. + 0, 0, 0 \
  2111. }
  2112.  
  2113.  
  2114. @@ -1826,7 +1872,8 @@
  2115. 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, \
  2116. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
  2117. 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  2118. - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
  2119. + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
  2120. + 1, 1, 1 \
  2121. }
  2122.  
  2123. /* Like `CALL_USED_REGISTERS' but used to overcome a historical
  2124. @@ -1846,7 +1893,8 @@
  2125. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
  2126. 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
  2127. /* Others. */ \
  2128. - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
  2129. + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
  2130. + 1, 1, 1 \
  2131. }
  2132.  
  2133. /* Internal macros to classify a register number as to whether it's a
  2134. @@ -1867,6 +1915,10 @@
  2135. #define MD_REG_LAST 66
  2136. #define MD_REG_NUM (MD_REG_LAST - MD_REG_FIRST + 1)
  2137.  
  2138. +#define MD1_REG_FIRST 76
  2139. +#define MD1_REG_LAST 78
  2140. +#define MD1_REG_NUM (MD1_REG_LAST - MD1_REG_FIRST + 1)
  2141. +
  2142. #define ST_REG_FIRST 67
  2143. #define ST_REG_LAST 74
  2144. #define ST_REG_NUM (ST_REG_LAST - ST_REG_FIRST + 1)
  2145. @@ -1877,6 +1929,9 @@
  2146. #define HI_REGNUM (MD_REG_FIRST + 0)
  2147. #define LO_REGNUM (MD_REG_FIRST + 1)
  2148. #define HILO_REGNUM (MD_REG_FIRST + 2)
  2149. +#define HI1_REGNUM (MD1_REG_FIRST + 0)
  2150. +#define LO1_REGNUM (MD1_REG_FIRST + 1)
  2151. +#define HILO1_REGNUM (MD1_REG_FIRST + 2)
  2152.  
  2153. /* FPSW_REGNUM is the single condition code used if mips_isa < 4. If
  2154. mips_isa >= 4, it should not be used, and an arbitrary ST_REG
  2155. @@ -1891,6 +1946,8 @@
  2156. ((unsigned int) ((int) (REGNO) - FP_REG_FIRST) < FP_REG_NUM)
  2157. #define MD_REG_P(REGNO) \
  2158. ((unsigned int) ((int) (REGNO) - MD_REG_FIRST) < MD_REG_NUM)
  2159. +#define MD1_REG_P(REGNO) \
  2160. + ((unsigned int) ((int) (REGNO) - MD1_REG_FIRST) < MD1_REG_NUM)
  2161. #define ST_REG_P(REGNO) \
  2162. ((unsigned int) ((int) (REGNO) - ST_REG_FIRST) < ST_REG_NUM)
  2163.  
  2164. @@ -2057,6 +2114,20 @@
  2165. LO_AND_GR_REGS,
  2166. HILO_AND_GR_REGS,
  2167. HI_AND_FP_REGS,
  2168. + HI1_REG, /* hi1 register */
  2169. + LO1_REG, /* lo1 register */
  2170. + HILO1_REG, /* hilo1 register pair for 64 bit mode mult */
  2171. + MD1_REGS, /* multiply/divide registers (hi/lo) */
  2172. + HI1_AND_GR_REGS, /* union classes */
  2173. + LO1_AND_GR_REGS,
  2174. + HILO1_AND_GR_REGS,
  2175. + HI01_REG, /* hi01 register */
  2176. + LO01_REG, /* lo01 register */
  2177. + HILO01_REG, /* hilo1 register pair for 64 bit mode mult */
  2178. + MD01_REGS, /* multiply/divide registers (hi1/lo1) */
  2179. + HI01_AND_GR_REGS, /* union classes */
  2180. + LO01_AND_GR_REGS,
  2181. + HILO01_AND_GR_REGS,
  2182. ST_REGS, /* status registers (fp status) */
  2183. ALL_REGS, /* all registers */
  2184. LIM_REG_CLASSES /* max value + 1 */
  2185. @@ -2087,6 +2158,20 @@
  2186. "LO_AND_GR_REGS", \
  2187. "HILO_AND_GR_REGS", \
  2188. "HI_AND_FP_REGS", \
  2189. + "HI1_REG", \
  2190. + "LO1_REG", \
  2191. + "HILO1_REG", \
  2192. + "MD1_REGS", \
  2193. + "HI1_AND_GR_REGS", \
  2194. + "LO1_AND_GR_REGS", \
  2195. + "HILO1_AND_GR_REGS", \
  2196. + "HI01_REG", \
  2197. + "LO01_REG", \
  2198. + "HILO01_REG", \
  2199. + "MD01_REGS", \
  2200. + "HI01_AND_GR_REGS", \
  2201. + "LO01_AND_GR_REGS", \
  2202. + "HILO01_AND_GR_REGS", \
  2203. "ST_REGS", \
  2204. "ALL_REGS" \
  2205. }
  2206. @@ -2105,7 +2190,7 @@
  2207. #define REG_CLASS_CONTENTS \
  2208. { \
  2209. { 0x00000000, 0x00000000, 0x00000000 }, /* no registers */ \
  2210. - { 0x0003000c, 0x00000000, 0x00000000 }, /* mips16 nonarg regs */\
  2211. + { 0x0003000c, 0x00000000, 0x00000000 }, /* mips16 nonarg regs */ \
  2212. { 0x000300fc, 0x00000000, 0x00000000 }, /* mips16 registers */ \
  2213. { 0x01000000, 0x00000000, 0x00000000 }, /* mips16 T register */ \
  2214. { 0x010300fc, 0x00000000, 0x00000000 }, /* mips16 and T regs */ \
  2215. @@ -2119,8 +2204,24 @@
  2216. { 0xffffffff, 0x00000000, 0x00000002 }, \
  2217. { 0xffffffff, 0x00000000, 0x00000004 }, \
  2218. { 0x00000000, 0xffffffff, 0x00000001 }, \
  2219. + /* Start of r5900 extra registers. */ \
  2220. + { 0x00000000, 0x00000000, 0x00001000 }, /* hi1 register */ \
  2221. + { 0x00000000, 0x00000000, 0x00002000 }, /* lo1 register */ \
  2222. + { 0x00000000, 0x00000000, 0x00004000 }, /* hilo1 register */ \
  2223. + { 0x00000000, 0x00000000, 0x00003000 }, /* mul1/div1 registers */ \
  2224. + { 0xffffffff, 0x00000000, 0x00001000 }, /* union classes */ \
  2225. + { 0xffffffff, 0x00000000, 0x00002000 }, \
  2226. + { 0xffffffff, 0x00000000, 0x00004000 }, \
  2227. + { 0x00000000, 0x00000000, 0x00001001 }, /* hi01 registers */ \
  2228. + { 0x00000000, 0x00000000, 0x00002002 }, /* lo01 registers */ \
  2229. + { 0x00000000, 0x00000000, 0x00004004 }, /* hilo01 registers */ \
  2230. + { 0x00000000, 0x00000000, 0x00003003 }, /* mul01/div01 registers */ \
  2231. + { 0xffffffff, 0x00000000, 0x00001001 }, /* union classes */ \
  2232. + { 0xffffffff, 0x00000000, 0x00002002 }, \
  2233. + { 0xffffffff, 0x00000000, 0x00004004 }, \
  2234. + /* End of r5900 extra registers. */ \
  2235. { 0x00000000, 0x00000000, 0x000007f8 }, /* status registers */ \
  2236. - { 0xffffffff, 0xffffffff, 0x000007ff } /* all registers */ \
  2237. + { 0xffffffff, 0xffffffff, 0x000078ff } /* all registers */ \
  2238. }
  2239.  
  2240.  
  2241. @@ -2169,7 +2270,8 @@
  2242. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, \
  2243. 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \
  2244. 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, \
  2245. - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75 \
  2246. + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, \
  2247. + 76, 77, 78 \
  2248. }
  2249.  
  2250. /* ORDER_REGS_FOR_LOCAL_ALLOC is a macro which permits reg_alloc_order
  2251. @@ -2197,7 +2299,11 @@
  2252. 'x' Multiply/divide registers
  2253. 'a' HILO_REG
  2254. 'z' FP Status register
  2255. - 'b' All registers */
  2256. + 'b' All registers
  2257. + 'u' Hi1 register
  2258. + 'v' Lo1 register
  2259. + 'w' Multiply/divide1 registers
  2260. + 'q' HILO1_REG */
  2261.  
  2262. extern enum reg_class mips_char_to_class[256];
  2263.  
  2264. @@ -2357,7 +2463,7 @@
  2265. #define CLASS_CANNOT_CHANGE_MODE \
  2266. (TARGET_BIG_ENDIAN \
  2267. ? (TARGET_FLOAT64 && ! TARGET_64BIT ? FP_REGS : NO_REGS) \
  2268. - : (TARGET_FLOAT64 && ! TARGET_64BIT ? HI_AND_FP_REGS : HI_REG))
  2269. + : (TARGET_FLOAT64 && ! TARGET_64BIT ? HI_AND_FP_REGS : HI01_REG))
  2270.  
  2271. /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
  2272.  
  2273. @@ -3470,8 +3576,9 @@
  2274.  
  2275. /* Max number of bytes we can move from memory to memory
  2276. in one reasonably fast instruction. */
  2277. -#define MOVE_MAX (TARGET_64BIT ? 8 : 4)
  2278. -#define MAX_MOVE_MAX 8
  2279. +/* We can do 16 bytes using the r5900's MMI */
  2280. +#define MOVE_MAX (TARGET_MIPS5900 ? (mips_use_128 ? 16 : 8) : (TARGET_64BIT ? 8 : 4))
  2281. +#define MAX_MOVE_MAX (mips_use_128 ? 16 : 8)
  2282.  
  2283. /* Define this macro as a C expression which is nonzero if
  2284. accessing less than a word of memory (i.e. a `char' or a
  2285. @@ -3764,6 +3871,8 @@
  2286. return COSTS_N_INSNS (17); \
  2287. else if (TUNE_MIPS5000) \
  2288. return COSTS_N_INSNS (5); \
  2289. + else if (TUNE_MIPS5900) \
  2290. + return (xmode == SImode ? COSTS_N_INSNS (3) : COSTS_N_INSNS (30));\
  2291. else \
  2292. return COSTS_N_INSNS (10); \
  2293. } \
  2294. @@ -3805,6 +3914,8 @@
  2295. return COSTS_N_INSNS (38); \
  2296. else if (TUNE_MIPS5000) \
  2297. return COSTS_N_INSNS (36); \
  2298. + else if (TUNE_MIPS5900) \
  2299. + return COSTS_N_INSNS (30); \
  2300. else \
  2301. return COSTS_N_INSNS (69); \
  2302. \
  2303. @@ -3910,10 +4021,14 @@
  2304. : GR_REG_CLASS_P (FROM) && (TO) == FP_REGS ? 4 \
  2305. : (FROM) == FP_REGS && GR_REG_CLASS_P (TO) ? 4 \
  2306. : (((FROM) == HI_REG || (FROM) == LO_REG \
  2307. - || (FROM) == MD_REGS || (FROM) == HILO_REG) \
  2308. + || (FROM) == MD_REGS || (FROM) == HILO_REG \
  2309. + || (FROM) == HI1_REG || (FROM) == LO1_REG \
  2310. + || (FROM) == MD1_REGS || (FROM) == HILO1_REG) \
  2311. && GR_REG_CLASS_P (TO)) ? (TARGET_MIPS16 ? 12 : 6) \
  2312. : (((TO) == HI_REG || (TO) == LO_REG \
  2313. - || (TO) == MD_REGS || (TO) == HILO_REG) \
  2314. + || (TO) == MD_REGS || (TO) == HILO_REG \
  2315. + || (TO) == HI1_REG || (TO) == LO1_REG \
  2316. + || (TO) == MD1_REGS || (TO) == HILO1_REG) \
  2317. && GR_REG_CLASS_P (FROM)) ? (TARGET_MIPS16 ? 12 : 6) \
  2318. : (FROM) == ST_REGS && GR_REG_CLASS_P (TO) ? 4 \
  2319. : (FROM) == FP_REGS && (TO) == ST_REGS ? 8 \
  2320. @@ -3947,6 +4062,10 @@
  2321. #define ADJUST_INSN_LENGTH(INSN, LENGTH) \
  2322. ((LENGTH) = mips_adjust_insn_length ((INSN), (LENGTH)))
  2323.  
  2324. +/* The r5900 is a dual issue processor. */
  2325. +#undef ISSUE_RATE
  2326. +#define ISSUE_RATE ((TARGET_MIPS5900) ? 2 : 1)
  2327. +
  2328. /* Optionally define this if you have added predicates to
  2329. `MACHINE.c'. This macro is called within an initializer of an
  2330. @@ -3992,6 +4111,8 @@
  2331. {"movdi_operand", { CONST_INT, CONST_DOUBLE, CONST, \
  2332. SYMBOL_REF, LABEL_REF, SUBREG, REG, \
  2333. MEM, SIGN_EXTEND }}, \
  2334. + {"movti_operand", { REG, MEM, CONST_INT, CONST_DOUBLE, \
  2335. + SUBREG }}, \
  2336. {"se_register_operand", { SUBREG, REG, SIGN_EXTEND }}, \
  2337. {"se_reg_or_0_operand", { REG, CONST_INT, CONST_DOUBLE, SUBREG, \
  2338. SIGN_EXTEND }}, \
  2339. @@ -4147,6 +4268,9 @@
  2340. &mips_reg_names[73][0], \
  2341. &mips_reg_names[74][0], \
  2342. &mips_reg_names[75][0], \
  2343. + &mips_reg_names[76][0], \
  2344. + &mips_reg_names[77][0], \
  2345. + &mips_reg_names[78][0], \
  2346. }
  2347.  
  2348. /* print-rtl.c can't use REGISTER_NAMES, since it depends on mips.c.
  2349. @@ -4162,7 +4286,8 @@
  2350. "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", \
  2351. "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", \
  2352. "hi", "lo", "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", \
  2353. - "$fcc5","$fcc6","$fcc7","$rap" \
  2354. + "$fcc5","$fcc6","$fcc7","$rap", \
  2355. + "hi1", "lo1", "accum1" \
  2356. }
  2357.  
  2358. /* If defined, a C initializer for an array of structures
  2359. @@ -4415,6 +4540,7 @@
  2360. } while (0)
  2361.  
  2362. /* This says how to define a global common symbol. */
  2363. +/* ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); */
  2364.  
  2365. #define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGN) \
  2366. do { \
  2367. @@ -4433,9 +4559,10 @@
  2368. mips_declare_object (STREAM, NAME, "", ":\n\t.space\t%u\n", \
  2369. (SIZE)); \
  2370. } \
  2371. - else \
  2372. - mips_declare_object (STREAM, NAME, "\n\t.comm\t", ",%u\n", \
  2373. - (SIZE)); \
  2374. + else { \
  2375. + mips_declare_object_align (STREAM, NAME, "\n\t.comm\t", ",%u,%u\n", \
  2376. + (SIZE),(ALIGN / BITS_PER_UNIT)); \
  2377. + } \
  2378. } while (0)
  2379.  
  2380.  
  2381. @@ -4547,7 +4674,7 @@
  2382. to a multiple of 2**LOG bytes. */
  2383.  
  2384. #define ASM_OUTPUT_ALIGN(STREAM,LOG) \
  2385. - fprintf (STREAM, "\t.align\t%d\n", (LOG))
  2386. + fprintf (STREAM, "\t.align\t%d\n", (LOG) > mips_align_all ? (LOG) : mips_align_all)
  2387.  
  2388. /* This is how to output an assembler line to advance the location
  2389. counter by SIZE bytes. */
  2390. @@ -4721,6 +4848,15 @@
  2391. PC relative loads that are out of range. */
  2392. #define MACHINE_DEPENDENT_REORG(X) machine_dependent_reorg (X)
  2393.  
  2394. +/* This is used to lengthen short loops on the r5900. */
  2395. +#define MACHINE_DEPENDENT_REORG_FINAL(X) \
  2396. +do \
  2397. + { \
  2398. + if (TARGET_MIPS5900 && ! TARGET_NO_LENGTHEN_LOOP) \
  2399. + machine_dependent_reorg_final (X); \
  2400. + } \
  2401. +while (0)
  2402. +
  2403. /* We need to use a special set of functions to handle hard floating
  2404. point code in mips16 mode. */
  2405.  
  2406. @@ -4793,3 +4929,44 @@
  2407. } \
  2408. } \
  2409. while (0)
  2410. +
  2411. +/* r5900 vector mode & built-in support. */
  2412. +
  2413. +#define VALID_MMI_REG_MODE(MODE) \
  2414. + ((MODE) == TImode || (MODE) == V16QImode || (MODE) == V8HImode \
  2415. + || (MODE) == V4SImode || (MODE) == V4SFmode || (MODE) == V2DImode)
  2416. +
  2417. +#define VALID_VUMM_REG_MODE(MODE) \
  2418. + ((MODE) == TImode || (MODE) == V4SFmode)
  2419. +
  2420. +#define VECTOR_MODE_SUPPORTED_P(MODE) \
  2421. + ((VALID_MMI_REG_MODE (MODE) && TARGET_MMI) \
  2422. + || (VALID_VUMM_REG_MODE (MODE) && TARGET_VUMM) ? 1 : 0)
  2423. +
  2424. +enum r5900_builtins
  2425. +{
  2426. + /* MMI built-ins */
  2427. + MMI_BUILTIN_PADDB,
  2428. + MMI_BUILTIN_PADDH,
  2429. + MMI_BUILTIN_PADDW,
  2430. + MMI_BUILTIN_PADDSB,
  2431. + MMI_BUILTIN_PADDSH,
  2432. + MMI_BUILTIN_PADDSW,
  2433. + MMI_BUILTIN_PADDUB,
  2434. + MMI_BUILTIN_PADDUH,
  2435. + MMI_BUILTIN_PADDUW,
  2436. +
  2437. + MMI_BUILTIN_PSUBB,
  2438. + MMI_BUILTIN_PSUBH,
  2439. + MMI_BUILTIN_PSUBW,
  2440. + MMI_BUILTIN_PSUBSB,
  2441. + MMI_BUILTIN_PSUBSH,
  2442. + MMI_BUILTIN_PSUBSW,
  2443. + MMI_BUILTIN_PSUBUB,
  2444. + MMI_BUILTIN_PSUBUH,
  2445. + MMI_BUILTIN_PSUBUW,
  2446. +
  2447. + /* VU macro mode built-ins */
  2448. +
  2449. + R5900_BUILTIN_MAX
  2450. +};
  2451. diff -burN orig.gcc-3.2.3/gcc/config/mips/mips.md gcc-3.2.3/gcc/config/mips/mips.md
  2452. --- orig.gcc-3.2.3/gcc/config/mips/mips.md 2002-11-11 01:57:14.000000000 -0400
  2453. +++ gcc-3.2.3/gcc/config/mips/mips.md 2015-08-10 16:15:12 +0300
  2454. @@ -84,11 +84,11 @@
  2455. ;; nop no operation
  2456.  
  2457. (define_attr "type"
  2458. - "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,multi,nop"
  2459. + "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop,mmi,mmi_mul,mmi_div,vmm_mul,vmm_div"
  2460. (const_string "unknown"))
  2461.  
  2462. ;; Main data type used by the insn
  2463. -(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
  2464. +(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,FPSW" (const_string "unknown"))
  2465.  
  2466. ;; Length (in # of bytes). A conditional branch is allowed only to a
  2467. ;; location within a signed 18-bit offset of the delay slot. If that
  2468. @@ -121,7 +121,7 @@
  2469.  
  2470. ;; ??? Fix everything that tests this attribute.
  2471. (define_attr "cpu"
  2472. - "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r8000,r4kc,r5kc,r20kc"
  2473. + "default,r3000,r3900,r6000,r4000,r4100,r4300,r4600,r4650,r5000,r5900,r8000,r4kc,r5kc,r20kc"
  2474. (const (symbol_ref "mips_cpu_attr")))
  2475.  
  2476. ;; Does the instruction have a mandatory delay slot?
  2477. @@ -206,7 +206,7 @@
  2478.  
  2479. (define_function_unit "memory" 1 0
  2480. (and (eq_attr "type" "load")
  2481. - (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
  2482. + (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4100,r4300,r5000,r5900"))
  2483. 3 0)
  2484.  
  2485. (define_function_unit "memory" 1 0
  2486. @@ -214,17 +214,20 @@
  2487. (eq_attr "cpu" "r3000,r3900,r4600,r4650,r4100,r4300,r5000"))
  2488. 2 0)
  2489.  
  2490. -(define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
  2491. +(define_function_unit "memory" 1 0
  2492. + (and (eq_attr "type" "store") (eq_attr "cpu" "!r5900")) 1 0)
  2493.  
  2494. -(define_function_unit "memory" 1 0 (eq_attr "type" "xfer") 2 0)
  2495. +(define_function_unit "memory" 1 0
  2496. + (and (eq_attr "type" "xfer") (eq_attr "cpu" "!r5900")) 2 0)
  2497.  
  2498. (define_function_unit "imuldiv" 1 0
  2499. - (eq_attr "type" "hilo")
  2500. + (and (eq_attr "type" "hilo")
  2501. + (eq_attr "cpu" "!r5900"))
  2502. 1 3)
  2503.  
  2504. (define_function_unit "imuldiv" 1 0
  2505. (and (eq_attr "type" "imul")
  2506. - (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
  2507. + (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000,r5900"))
  2508. 17 17)
  2509.  
  2510. ;; On them mips16, we want to stronly discourage a mult from appearing
  2511. @@ -276,7 +279,7 @@
  2512.  
  2513. (define_function_unit "imuldiv" 1 0
  2514. (and (eq_attr "type" "idiv")
  2515. - (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000"))
  2516. + (eq_attr "cpu" "!r3000,r3900,r4000,r4600,r4650,r4100,r4300,r5000,r5900"))
  2517. 38 38)
  2518.  
  2519. (define_function_unit "imuldiv" 1 0
  2520. @@ -333,7 +336,7 @@
  2521. ;; instructions to be processed in the "imuldiv" unit.
  2522.  
  2523. (define_function_unit "adder" 1 1
  2524. - (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000"))
  2525. + (and (eq_attr "type" "fcmp") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000,r5900"))
  2526. 3 0)
  2527.  
  2528. (define_function_unit "adder" 1 1
  2529. @@ -345,7 +348,7 @@
  2530. 1 0)
  2531.  
  2532. (define_function_unit "adder" 1 1
  2533. - (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300"))
  2534. + (and (eq_attr "type" "fadd") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5900"))
  2535. 4 0)
  2536.  
  2537. (define_function_unit "adder" 1 1
  2538. @@ -358,7 +361,7 @@
  2539.  
  2540. (define_function_unit "adder" 1 1
  2541. (and (eq_attr "type" "fabs,fneg")
  2542. - (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000"))
  2543. + (eq_attr "cpu" "!r3000,r3900,r4600,r4650,r4300,r5000,r5900"))
  2544. 2 0)
  2545.  
  2546. (define_function_unit "adder" 1 1
  2547. @@ -368,7 +371,7 @@
  2548. (define_function_unit "mult" 1 1
  2549. (and (eq_attr "type" "fmul")
  2550. (and (eq_attr "mode" "SF")
  2551. - (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
  2552. + (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000,r5900")))
  2553. 7 0)
  2554.  
  2555. (define_function_unit "mult" 1 1
  2556. @@ -388,7 +391,7 @@
  2557.  
  2558. (define_function_unit "mult" 1 1
  2559. (and (eq_attr "type" "fmul")
  2560. - (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000")))
  2561. + (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r3000,r3900,r6000,r4300,r5000,r5900")))
  2562. 8 0)
  2563.  
  2564. (define_function_unit "mult" 1 1
  2565. @@ -404,7 +407,7 @@
  2566. (define_function_unit "divide" 1 1
  2567. (and (eq_attr "type" "fdiv")
  2568. (and (eq_attr "mode" "SF")
  2569. - (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000")))
  2570. + (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5000,r5900")))
  2571. 23 0)
  2572.  
  2573. (define_function_unit "divide" 1 1
  2574. @@ -430,7 +433,7 @@
  2575. (define_function_unit "divide" 1 1
  2576. (and (eq_attr "type" "fdiv")
  2577. (and (eq_attr "mode" "DF")
  2578. - (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300")))
  2579. + (eq_attr "cpu" "!r3000,r3900,r6000,r4600,r4650,r4300,r5900")))
  2580. 36 0)
  2581.  
  2582. (define_function_unit "divide" 1 1
  2583. @@ -451,7 +454,7 @@
  2584. ;;; ??? Is this number right?
  2585. (define_function_unit "divide" 1 1
  2586. (and (eq_attr "type" "fsqrt")
  2587. - (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
  2588. + (and (eq_attr "mode" "SF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000,r5900")))
  2589. 54 0)
  2590.  
  2591. (define_function_unit "divide" 1 1
  2592. @@ -467,7 +470,7 @@
  2593. ;;; ??? Is this number right?
  2594. (define_function_unit "divide" 1 1
  2595. (and (eq_attr "type" "fsqrt")
  2596. - (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000")))
  2597. + (and (eq_attr "mode" "DF") (eq_attr "cpu" "!r4600,r4650,r4300,r5000,r5900")))
  2598. 112 0)
  2599.  
  2600. (define_function_unit "divide" 1 1
  2601. @@ -507,6 +510,63 @@
  2602. (and (eq_attr "mode" "DF") (eq_attr "cpu" "r4300")))
  2603. 58 58)
  2604. +;; Using a value immediately after a load causes a one cycle delay.
  2605. +(define_function_unit "memory" 1 0
  2606. + (and (eq_attr "type" "load") (eq_attr "cpu" "r5900")) 2 0)
  2607. +
  2608. +;; The r5900 has a store buffer which can cause an interlock for
  2609. +;; consecutive stores in some cases. So try to separate stores.
  2610. +(define_function_unit "memory" 1 0
  2611. + (and (eq_attr "type" "store") (eq_attr "cpu" "r5900")) 2 1)
  2612. +
  2613. +;; Transfer to/from coprocessor. This is just a guess. There may or
  2614. +;; may not be an interlock for such transfers.
  2615. +(define_function_unit "memory" 1 0
  2616. + (and (eq_attr "type" "xfer") (eq_attr "cpu" "r5900")) 2 0)
  2617. +
  2618. +;; The r5900 has two independent ALUs.
  2619. +;; XXX: MM instructions take up both ALUs, work that out properly here
  2620. +(define_function_unit "alu" 2 0
  2621. + (and (eq_attr "type" "move,arith,darith,icmp,nop,mmi,mmi_mul,mmi_div")
  2622. + (eq_attr "cpu" "r5900")) 1 0)
  2623. +
  2624. +;; It also has a seperate branch unit.
  2625. +(define_function_unit "branch" 1 0
  2626. + (and (eq_attr "type" "branch,jump,call")
  2627. + (eq_attr "cpu" "r5900")) 1 0)
  2628. +
  2629. +;; XXX There is differing data between the architecture manual
  2630. +;; about what these values should be.
  2631. +(define_function_unit "r5900imuldiv" 2 0
  2632. + (and (eq_attr "type" "hilo") (eq_attr "cpu" "r5900")) 1 3)
  2633. +
  2634. +(define_function_unit "r5900imuldiv" 2 0
  2635. + (and (eq_attr "type" "imul") (eq_attr "cpu" "r5900")) 4 2)
  2636. +
  2637. +(define_function_unit "r5900imuldiv" 2 0
  2638. + (and (eq_attr "type" "idiv") (eq_attr "cpu" "r5900")) 37 37)
  2639. +
  2640. +;; The r5900 FP unit has three independent units.
  2641. +;; fmac -- all computational instructions except fdiv, fsqrt, rsqrt
  2642. +;; fdiv -- fdiv, fsqrt, rsqrt
  2643. +;; load/store -- load store and transfer unit
  2644. +;;
  2645. +;; It appears that fmac/fdiv can dual issue with load/store.
  2646. +(define_function_unit "fmac" 1 0
  2647. + (and (eq_attr "type" "fadd,fmul,fmadd,fabs,fneg,fcmp,fcvt")
  2648. + (eq_attr "cpu" "r5900")) 3 0)
  2649. +
  2650. +(define_function_unit "fdiv" 1 1
  2651. + (and (eq_attr "type" "fdiv,fsqrt,frsqrt") (eq_attr "cpu" "r5900")) 6 0)
  2652. +
  2653. +;; And now a few fake units to encourage dual issue.
  2654. +;; We can only issue one operation to the FPU per cycle.
  2655. +(define_function_unit "flop" 1 0
  2656. + (and (eq_attr "type"
  2657. + "fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,xfer")
  2658. + (eq_attr "cpu" "r5900")) 1 0)
  2659. +
  2660. +
  2661. ;; The following functional units do not use the cpu type, and use
  2662. ;; much less memory in genattrtab.c.
  2663.  
  2664. @@ -1727,7 +1787,22 @@
  2665. ""
  2666. "
  2667. {
  2668. - if (GENERATE_MULT3_SI || TARGET_MAD)
  2669. + /* mulsi3_mult3_r5900 is just like the other mulsi3_mult3 pattern, except
  2670. + that it has additional alternatives, slightly different output
  2671. + templates and clobbers pseudos instead of scratches.
  2672. +
  2673. + We generate a different pattern merely to keep the sanitize issues from
  2674. + driving us crazy. Long term we may want the other multiply patterns to
  2675. + clobber pseudos instead of scratches. */
  2676. + if (TARGET_MIPS5900)
  2677. + {
  2678. + emit_insn (gen_mulsi3_mult3_r5900 (operands[0], operands[1], operands[2],
  2679. + gen_reg_rtx (SImode),
  2680. + gen_reg_rtx (SImode),
  2681. + gen_reg_rtx (SImode)));
  2682. + DONE;
  2683. + }
  2684. + else if (GENERATE_MULT3_SI || TARGET_MAD)
  2685. emit_insn (gen_mulsi3_mult3 (operands[0], operands[1], operands[2]));
  2686. else if (!TARGET_MIPS4000 || TARGET_MIPS16)
  2687. emit_insn (gen_mulsi3_internal (operands[0], operands[1], operands[2]));
  2688. @@ -1736,6 +1811,23 @@
  2689. DONE;
  2690. }")
  2691.  
  2692. +(define_insn "mulsi3_mult3_r5900"
  2693. + [(set (match_operand:SI 0 "register_operand" "=d,l,d,v")
  2694. + (mult:SI (match_operand:SI 1 "register_operand" "d,d,d,d")
  2695. + (match_operand:SI 2 "register_operand" "d,d,d,d")))
  2696. + (clobber (match_operand:SI 3 "register_operand" "=h,h,u,u"))
  2697. + (clobber (match_operand:SI 4 "register_operand" "=l,X,v,X"))
  2698. + (clobber (match_operand:SI 5 "register_operand" "=a,a,q,q"))]
  2699. + "TARGET_MIPS5900"
  2700. + "*
  2701. +{
  2702. + if (which_alternative == 1 || which_alternative == 3)
  2703. + return \"mult%H5\\t%1,%2\";
  2704. + return \"mult%H5\\t%0,%1,%2\";
  2705. +}"
  2706. + [(set_attr "type" "imul")
  2707. + (set_attr "mode" "SI")])
  2708. +
  2709. (define_insn "mulsi3_mult3"
  2710. [(set (match_operand:SI 0 "register_operand" "=d,l")
  2711. (mult:SI (match_operand:SI 1 "register_operand" "d,d")
  2712. @@ -1743,8 +1835,8 @@
  2713. (clobber (match_scratch:SI 3 "=h,h"))
  2714. (clobber (match_scratch:SI 4 "=l,X"))
  2715. (clobber (match_scratch:SI 5 "=a,a"))]
  2716. - "GENERATE_MULT3_SI
  2717. - || TARGET_MAD"
  2718. + "(GENERATE_MULT3_SI
  2719. + || TARGET_MAD) && !TARGET_MIPS5900"
  2720. "*
  2721. {
  2722. if (which_alternative == 1)
  2723. @@ -1804,6 +1896,31 @@
  2724. ;; "?" to the constraint is too strong, and causes values to be loaded into
  2725. ;; LO even when that's more costly. For now, using "*d" mostly does the
  2726. ;; trick.
  2727. +
  2728. +;; Like the standard multiply-accumulate, except with more alternatives and
  2729. +;; works with both pipelines.
  2730. +;; XXX: Broken for now.
  2731. +(define_insn "*mul_acc_si_r5900"
  2732. + [(set (match_operand:SI 0 "register_operand" "=l,*d,*d,v,*d,*d")
  2733. + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d,d,d,d")
  2734. + (match_operand:SI 2 "register_operand" "d,d,d,d,d,d"))
  2735. + (match_operand:SI 3 "register_operand" "0,l,*d,0,v,*d")))
  2736. + (clobber (match_scratch:SI 4 "=h,h,h,u,u,u"))
  2737. + (clobber (match_scratch:SI 5 "=X,3,l,X,3,v"))
  2738. + (clobber (match_scratch:SI 6 "=a,a,a,q,q,q"))
  2739. + (clobber (match_scratch:SI 7 "=X,X,d,X,X,d"))]
  2740. + "TARGET_MIPS5900 && !TARGET_MIPS16"
  2741. + "*
  2742. +{
  2743. + static char *const madd[] = { \"madd%H6\\t%1,%2\",
  2744. + \"madd%H6\\t%0,%1,%2\",
  2745. + \"#\" };
  2746. + return madd[which_alternative % 3];
  2747. +}"
  2748. + [(set_attr "type" "imul")
  2749. + (set_attr "mode" "SI")
  2750. + (set_attr "length" "4,4,8,4,4,8")])
  2751. +
  2752. (define_insn "*mul_acc_si"
  2753. [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
  2754. (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
  2755. @@ -1964,7 +2081,7 @@
  2756. (match_operand:DI 2 "register_operand" "d")))
  2757. (clobber (match_scratch:DI 3 "=h"))
  2758. (clobber (match_scratch:DI 4 "=a"))]
  2759. - "TARGET_64BIT"
  2760. + "TARGET_64BIT && !TARGET_MIPS5900"
  2761.  
  2762. "
  2763. {
  2764. @@ -1986,7 +2103,7 @@
  2765. (match_operand:DI 2 "register_operand" "d")))
  2766. (clobber (match_scratch:DI 3 "=h"))
  2767. (clobber (match_scratch:DI 4 "=a"))]
  2768. - "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16"
  2769. + "TARGET_64BIT && !TARGET_MIPS4000 && !TARGET_MIPS16 && !TARGET_MIPS5900"
  2770. "dmult\\t%1,%2"
  2771. [(set_attr "type" "imul")
  2772. (set_attr "mode" "DI")])
  2773. @@ -2032,6 +2149,15 @@
  2774. "
  2775. {
  2776. rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx);
  2777. + if (TARGET_64BIT && TARGET_MIPS5900)
  2778. + {
  2779. + emit_insn (gen_mulsidi3_64bit_r5900 (operands[0], operands[1],
  2780. + operands[2],
  2781. + dummy, dummy,
  2782. + gen_reg_rtx (DImode),
  2783. + gen_reg_rtx (DImode)));
  2784. + DONE;
  2785. + }
  2786. if (TARGET_64BIT)
  2787. emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
  2788. dummy, dummy));
  2789. @@ -2049,6 +2175,15 @@
  2790. "
  2791. {
  2792. rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx);
  2793. + if (TARGET_64BIT && TARGET_MIPS5900)
  2794. + {
  2795. + emit_insn (gen_mulsidi3_64bit_r5900 (operands[0], operands[1],
  2796. + operands[2],
  2797. + dummy, dummy,
  2798. + gen_reg_rtx (DImode),
  2799. + gen_reg_rtx (DImode)));
  2800. + DONE;
  2801. + }
  2802. if (TARGET_64BIT)
  2803. emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2],
  2804. dummy, dummy));
  2805. @@ -2075,6 +2210,25 @@
  2806. [(set_attr "type" "imul")
  2807. (set_attr "mode" "SI")])
  2808.  
  2809. +(define_insn "mulsidi3_64bit_r5900"
  2810. + [(set (match_operand:DI 0 "register_operand" "=a,q")
  2811. + (mult:DI (match_operator:DI 3 "extend_operator"
  2812. + [(match_operand:SI 1 "register_operand" "d,d")])
  2813. + (match_operator:DI 4 "extend_operator"
  2814. + [(match_operand:SI 2 "register_operand" "d,d")])))
  2815. + (clobber (match_operand:DI 5 "register_operand" "=l,v"))
  2816. + (clobber (match_operand:DI 6 "register_operand" "=h,u"))]
  2817. + "TARGET_64BIT && TARGET_MIPS5900
  2818. + && GET_CODE (operands[3]) == GET_CODE (operands[4])"
  2819. + "*
  2820. +{
  2821. + if (GET_CODE (operands[3]) == SIGN_EXTEND)
  2822. + return \"mult%H0\\t%1,%2\";
  2823. + return \"multu%H0\\t%1,%2\";
  2824. +}"
  2825. + [(set_attr "type" "imul")
  2826. + (set_attr "mode" "SI")])
  2827. +
  2828. (define_insn "mulsidi3_64bit"
  2829. [(set (match_operand:DI 0 "register_operand" "=a")
  2830. (mult:DI (match_operator:DI 3 "extend_operator"
  2831. @@ -2111,6 +2265,8 @@
  2832. rtx (*genfn) ();
  2833. #endif
  2834. genfn = gen_xmulsi3_highpart_internal;
  2835. + if (TARGET_MIPS5900)
  2836. + genfn = gen_xmulsi3_highpart_r5900;
  2837. emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
  2838. dummy, dummy2));
  2839. DONE;
  2840. @@ -2132,12 +2288,36 @@
  2841. #else
  2842. rtx (*genfn) ();
  2843. #endif
  2844. + if (TARGET_MIPS5900)
  2845. + genfn = gen_xmulsi3_highpart_r5900;
  2846. genfn = gen_xmulsi3_highpart_internal;
  2847. emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy,
  2848. dummy, dummy2));
  2849. DONE;
  2850. }")
  2851.  
  2852. +(define_insn "xmulsi3_highpart_r5900"
  2853. + [(set (match_operand:SI 0 "register_operand" "=h,u")
  2854. + (truncate:SI
  2855. + (match_operator:DI 5 "highpart_shift_operator"
  2856. + [(mult:DI (match_operator:DI 3 "extend_operator"
  2857. + [(match_operand:SI 1 "register_operand" "d,d")])
  2858. + (match_operator:DI 4 "extend_operator"
  2859. + [(match_operand:SI 2 "register_operand" "d,d")]))
  2860. + (const_int 32)])))
  2861. + (clobber (match_scratch:SI 6 "=l,v"))
  2862. + (clobber (match_scratch:SI 7 "=a,q"))]
  2863. + "TARGET_MIPS5900 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
  2864. + "*
  2865. +{
  2866. + if (GET_CODE (operands[3]) == SIGN_EXTEND)
  2867. + return \"mult%H0\\t%1,%2\";
  2868. + else
  2869. + return \"multu%H0\\t%1,%2\";
  2870. +}"
  2871. + [(set_attr "type" "imul")
  2872. + (set_attr "mode" "SI")])
  2873. +
  2874. (define_insn "xmulsi3_highpart_internal"
  2875. [(set (match_operand:SI 0 "register_operand" "=h")
  2876. (truncate:SI
  2877. @@ -2168,7 +2348,7 @@
  2878. (const_int 64))))
  2879. (clobber (match_scratch:DI 3 "=l"))
  2880. (clobber (match_scratch:DI 4 "=a"))]
  2881. - "TARGET_64BIT"
  2882. + "TARGET_64BIT && !TARGET_MIPS5900"
  2883. "dmult\\t%1,%2"
  2884. [(set_attr "type" "imul")
  2885. (set_attr "mode" "DI")])
  2886. @@ -2181,7 +2361,7 @@
  2887. (const_int 64))))
  2888. (clobber (match_scratch:DI 3 "=l"))
  2889. (clobber (match_scratch:DI 4 "=a"))]
  2890. - "TARGET_64BIT"
  2891. + "TARGET_64BIT && !TARGET_MIPS5900"
  2892. "dmultu\\t%1,%2"
  2893. [(set_attr "type" "imul")
  2894. (set_attr "mode" "DI")])
  2895. @@ -2397,8 +2577,15 @@
  2896. "optimize"
  2897. "
  2898. {
  2899. + if (TARGET_MIPS5900)
  2900. + {
  2901. + emit_insn (gen_divmodsi4_internal_r5900 (operands[0], operands[1],
  2902. + operands[2], operands[3]));
  2903. + goto zero_div_check;
  2904. + }
  2905. emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2],
  2906. operands[3]));
  2907. +zero_div_check:
  2908. if (!TARGET_NO_CHECK_ZERO_DIV)
  2909. {
  2910. emit_insn (gen_div_trap (operands[2],
  2911. @@ -2421,6 +2608,19 @@
  2912. DONE;
  2913. }")
  2914.  
  2915. +(define_insn "divmodsi4_internal_r5900"
  2916. + [(set (match_operand:SI 0 "register_operand" "=l,v")
  2917. + (div:SI (match_operand:SI 1 "register_operand" "d,d")
  2918. + (match_operand:SI 2 "register_operand" "d,d")))
  2919. + (set (match_operand:SI 3 "register_operand" "=h,u")
  2920. + (mod:SI (match_dup 1)
  2921. + (match_dup 2)))
  2922. + (clobber (match_scratch:SI 4 "=a,q"))]
  2923. + "optimize && TARGET_MIPS5900"
  2924. + "div%H0\\t$0,%1,%2"
  2925. + [(set_attr "type" "idiv")
  2926. + (set_attr "mode" "SI")])
  2927. +
  2928. (define_insn "divmodsi4_internal"
  2929. [(set (match_operand:SI 0 "register_operand" "=l")
  2930. (div:SI (match_operand:SI 1 "register_operand" "d")
  2931. @@ -2429,7 +2629,7 @@
  2932. (mod:SI (match_dup 1)
  2933. (match_dup 2)))
  2934. (clobber (match_scratch:SI 4 "=a"))]
  2935. - "optimize"
  2936. + "optimize && !TARGET_MIPS5900"
  2937. "div\\t$0,%1,%2"
  2938. [(set_attr "type" "idiv")
  2939. (set_attr "mode" "SI")])
  2940. @@ -2444,7 +2644,7 @@
  2941. (clobber (match_scratch:DI 4 "=l"))
  2942. (clobber (match_scratch:DI 5 "=h"))
  2943. (clobber (match_scratch:DI 6 "=a"))]
  2944. - "TARGET_64BIT && optimize"
  2945. + "TARGET_64BIT && optimize && !TARGET_MIPS5900"
  2946. "
  2947. {
  2948. emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2],
  2949. @@ -2477,7 +2677,7 @@
  2950. (mod:DI (match_dup 1)
  2951. (match_dup 2)))
  2952. (clobber (match_scratch:DI 4 "=a"))]
  2953. - "TARGET_64BIT && optimize"
  2954. + "TARGET_64BIT && optimize && !TARGET_MIPS5900"
  2955. "ddiv\\t$0,%1,%2"
  2956. [(set_attr "type" "idiv")
  2957. (set_attr "mode" "SI")])
  2958. @@ -2495,8 +2695,15 @@
  2959. "optimize"
  2960. "
  2961. {
  2962. + if (TARGET_MIPS5900)
  2963. + {
  2964. + emit_insn (gen_udivmodsi4_internal_r5900 (operands[0], operands[1],
  2965. + operands[2], operands[3]));
  2966. + goto zero_div_check;
  2967. + }
  2968. emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2],
  2969. operands[3]));
  2970. +zero_div_check:
  2971. if (!TARGET_NO_CHECK_ZERO_DIV)
  2972. {
  2973. emit_insn (gen_div_trap (operands[2],
  2974. @@ -2507,6 +2714,19 @@
  2975. DONE;
  2976. }")
  2977.  
  2978. +(define_insn "udivmodsi4_internal_r5900"
  2979. + [(set (match_operand:SI 0 "register_operand" "=l,v")
  2980. + (udiv:SI (match_operand:SI 1 "register_operand" "d,d")
  2981. + (match_operand:SI 2 "register_operand" "d,d")))
  2982. + (set (match_operand:SI 3 "register_operand" "=h,u")
  2983. + (umod:SI (match_dup 1)
  2984. + (match_dup 2)))
  2985. + (clobber (match_scratch:SI 4 "=a,q"))]
  2986. + "optimize && TARGET_MIPS5900"
  2987. + "divu%H0\\t$0,%1,%2"
  2988. + [(set_attr "type" "idiv")
  2989. + (set_attr "mode" "SI")])
  2990. +
  2991. (define_insn "udivmodsi4_internal"
  2992. [(set (match_operand:SI 0 "register_operand" "=l")
  2993. (udiv:SI (match_operand:SI 1 "register_operand" "d")
  2994. @@ -2515,7 +2735,7 @@
  2995. (umod:SI (match_dup 1)
  2996. (match_dup 2)))
  2997. (clobber (match_scratch:SI 4 "=a"))]
  2998. - "optimize"
  2999. + "optimize && !TARGET_MIPS5900"
  3000. "divu\\t$0,%1,%2"
  3001. [(set_attr "type" "idiv")
  3002. (set_attr "mode" "SI")])
  3003. @@ -2530,7 +2750,7 @@
  3004. (clobber (match_scratch:DI 4 "=l"))
  3005. (clobber (match_scratch:DI 5 "=h"))
  3006. (clobber (match_scratch:DI 6 "=a"))]
  3007. - "TARGET_64BIT && optimize"
  3008. + "TARGET_64BIT && optimize && !TARGET_MIPS5900"
  3009. "
  3010. {
  3011. emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2],
  3012. @@ -2553,7 +2773,7 @@
  3013. (umod:DI (match_dup 1)
  3014. (match_dup 2)))
  3015. (clobber (match_scratch:DI 4 "=a"))]
  3016. - "TARGET_64BIT && optimize"
  3017. + "TARGET_64BIT && optimize && !TARGET_MIPS5900"
  3018. "ddivu\\t$0,%1,%2"
  3019. [(set_attr "type" "idiv")
  3020. (set_attr "mode" "SI")])
  3021. @@ -2651,6 +2871,7 @@
  3022. [(set_attr "type" "unknown")
  3023. (set_attr "length" "12")])
  3024.  
  3025. +;; Add r5900-specific div here.
  3026. (define_expand "divsi3"
  3027. [(set (match_operand:SI 0 "register_operand" "=l")
  3028. (div:SI (match_operand:SI 1 "register_operand" "d")
  3029. @@ -2700,7 +2921,7 @@
  3030. (match_operand:DI 2 "se_register_operand" "d")))
  3031. (clobber (match_scratch:DI 3 "=h"))
  3032. (clobber (match_scratch:DI 4 "=a"))]
  3033. - "TARGET_64BIT && !optimize"
  3034. + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
  3035. "
  3036. {
  3037. emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2]));
  3038. @@ -2730,11 +2951,12 @@
  3039. (match_operand:DI 2 "se_nonmemory_operand" "di")))
  3040. (clobber (match_scratch:SI 3 "=h"))
  3041. (clobber (match_scratch:SI 4 "=a"))]
  3042. - "TARGET_64BIT && !optimize"
  3043. + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
  3044. "ddiv\\t$0,%1,%2"
  3045. [(set_attr "type" "idiv")
  3046. (set_attr "mode" "DI")])
  3047.  
  3048. +;; XXX: add r5900-specific support here
  3049. (define_expand "modsi3"
  3050. [(set (match_operand:SI 0 "register_operand" "=h")
  3051. (mod:SI (match_operand:SI 1 "register_operand" "d")
  3052. @@ -2784,7 +3006,7 @@
  3053. (match_operand:DI 2 "se_register_operand" "d")))
  3054. (clobber (match_scratch:DI 3 "=l"))
  3055. (clobber (match_scratch:DI 4 "=a"))]
  3056. - "TARGET_64BIT && !optimize"
  3057. + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
  3058. "
  3059. {
  3060. emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2]));
  3061. @@ -2814,11 +3036,12 @@
  3062. (match_operand:DI 2 "se_nonmemory_operand" "di")))
  3063. (clobber (match_scratch:SI 3 "=l"))
  3064. (clobber (match_scratch:SI 4 "=a"))]
  3065. - "TARGET_64BIT && !optimize"
  3066. + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
  3067. "ddiv\\t$0,%1,%2"
  3068. [(set_attr "type" "idiv")
  3069. (set_attr "mode" "DI")])
  3070.  
  3071. +;; XXX: Add r5900-specific support here
  3072. (define_expand "udivsi3"
  3073. [(set (match_operand:SI 0 "register_operand" "=l")
  3074. (udiv:SI (match_operand:SI 1 "register_operand" "d")
  3075. @@ -2856,7 +3079,7 @@
  3076. (match_operand:DI 2 "se_register_operand" "di")))
  3077. (clobber (match_scratch:DI 3 "=h"))
  3078. (clobber (match_scratch:DI 4 "=a"))]
  3079. - "TARGET_64BIT && !optimize"
  3080. + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
  3081. "
  3082. {
  3083. emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2]));
  3084. @@ -2876,11 +3099,12 @@
  3085. (match_operand:DI 2 "se_nonmemory_operand" "di")))
  3086. (clobber (match_scratch:SI 3 "=h"))
  3087. (clobber (match_scratch:SI 4 "=a"))]
  3088. - "TARGET_64BIT && !optimize"
  3089. + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
  3090. "ddivu\\t$0,%1,%2"
  3091. [(set_attr "type" "idiv")
  3092. (set_attr "mode" "DI")])
  3093.  
  3094. +;; XXX: add r5900-specific support here
  3095. (define_expand "umodsi3"
  3096. [(set (match_operand:SI 0 "register_operand" "=h")
  3097. (umod:SI (match_operand:SI 1 "register_operand" "d")
  3098. @@ -2918,7 +3142,7 @@
  3099. (match_operand:DI 2 "se_register_operand" "di")))
  3100. (clobber (match_scratch:DI 3 "=l"))
  3101. (clobber (match_scratch:DI 4 "=a"))]
  3102. - "TARGET_64BIT && !optimize"
  3103. + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
  3104. "
  3105. {
  3106. emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2]));
  3107. @@ -2938,7 +3162,7 @@
  3108. (match_operand:DI 2 "se_nonmemory_operand" "di")))
  3109. (clobber (match_scratch:SI 3 "=l"))
  3110. (clobber (match_scratch:SI 4 "=a"))]
  3111. - "TARGET_64BIT && !optimize"
  3112. + "TARGET_64BIT && !optimize && !TARGET_MIPS5900"
  3113. "ddivu\\t$0,%1,%2"
  3114. [(set_attr "type" "idiv")
  3115. (set_attr "mode" "DI")])
  3116. @@ -2979,7 +3203,7 @@
  3117. [(set (match_operand:SF 0 "register_operand" "=f")
  3118. (div:SF (match_operand:SF 1 "const_float_1_operand" "")
  3119. (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
  3120. - "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
  3121. + "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_MIPS5900 && flag_unsafe_math_optimizations"
  3122. "rsqrt.s\\t%0,%2"
  3123. [(set_attr "type" "fsqrt")
  3124. (set_attr "mode" "SF")])
  3125. @@ -3061,6 +3285,37 @@
  3126. (set_attr "mode" "SF")])
  3127.  
  3128. +;; ....................
  3129. +;;
  3130. +;; MIN, MAX
  3131. +;;
  3132. +;; ....................
  3133. +
  3134. +(define_insn "minsf3"
  3135. + [(set (match_operand:SF 0 "register_operand" "=f")
  3136. + (if_then_else (lt:SF
  3137. + (match_operand:SF 1 "register_operand" "f")
  3138. + (match_operand:SF 2 "register_operand" "f"))
  3139. + (match_dup 1)
  3140. + (match_dup 2)))]
  3141. + "TARGET_HARD_FLOAT && TARGET_MIPS5900"
  3142. + "min.s\\t%0,%1,%2"
  3143. + [(set_attr "type" "fadd")
  3144. + (set_attr "mode" "SF")])
  3145. +
  3146. +(define_insn "maxsf3"
  3147. + [(set (match_operand:SF 0 "register_operand" "=f")
  3148. + (if_then_else (gt:SF
  3149. + (match_operand:SF 1 "register_operand" "f")
  3150. + (match_operand:SF 2 "register_operand" "f"))
  3151. + (match_dup 1)
  3152. + (match_dup 2)))]
  3153. + "TARGET_HARD_FLOAT && TARGET_MIPS5900"
  3154. + "max.s\\t%0,%1,%2"
  3155. + [(set_attr "type" "fadd")
  3156. + (set_attr "mode" "SF")])
  3157. +
  3158. +
  3159. ;;
  3160. ;; ....................
  3161. ;;
  3162. @@ -3081,6 +3336,38 @@
  3163. dslots_jump_filled += 2;
  3164. operands[4] = const0_rtx;
  3165.  
  3166. + if (TARGET_MIPS5900 && !TARGET_NO_LENGTHEN_LOOP ) {
  3167. + if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
  3168. + return \"%(\\
  3169. +move\\t%0,%z4\\n\\
  3170. +\\tbeq\\t%1,%z4,2f\\n\\
  3171. +1:\\tand\\t%2,%1,0x0001\\n\\
  3172. +\\taddu\\t%0,%0,1\\n\\
  3173. +\\tbne\\t%2,%z4,2f\\n\\
  3174. +\\tsrl\\t%1,%1,1\\n\\
  3175. +\\n\\
  3176. +\\tand\\t%2,%1,0x0001\\n\\
  3177. +\\taddu\\t%0,%0,1\\n\\
  3178. +\\tbeq\\t%2,%z4,1b\\n\\
  3179. +\\tsrl\\t%1,%1,1\\n\\
  3180. +2:%)\";
  3181. +
  3182. + return \"%(\\
  3183. +move\\t%0,%z4\\n\\
  3184. +\\tmove\\t%3,%1\\n\\
  3185. +\\tbeq\\t%3,%z4,2f\\n\\
  3186. +1:\\tand\\t%2,%3,0x0001\\n\\
  3187. +\\taddu\\t%0,%0,1\\n\\
  3188. +\\tbne\\t%2,%z4,2f\\n\\
  3189. +\\tsrl\\t%3,%3,1\\n\\
  3190. +\\n\\
  3191. +\\tand\\t%2,%3,0x0001\\n\\
  3192. +\\taddu\\t%0,%0,1\\n\\
  3193. +\\tbeq\\t%2,%z4,1b\\n\\
  3194. +\\tsrl\\t%3,%3,1\\n\\
  3195. +2:%)\";
  3196. + }
  3197. +
  3198. if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
  3199. return \"%(\\
  3200. move\\t%0,%z4\\n\\
  3201. @@ -3103,7 +3390,11 @@
  3202. }"
  3203. [(set_attr "type" "multi")
  3204. (set_attr "mode" "SI")
  3205. - (set_attr "length" "12")])
  3206. + (set (attr "length")
  3207. + (if_then_else (and (ne (const_int 0) (symbol_ref "TARGET_MIPS5900") )
  3208. + (eq (const_int 0) (symbol_ref "TARGET_NO_LENGTHEN_LOOP")))
  3209. + (const_int 44)
  3210. + (const_int 24))) ])
  3211.  
  3212. (define_insn "ffsdi2"
  3213. [(set (match_operand:DI 0 "register_operand" "=&d")
  3214. @@ -3117,6 +3408,38 @@
  3215. dslots_jump_filled += 2;
  3216. operands[4] = const0_rtx;
  3217.  
  3218. + if (TARGET_MIPS5900 && !TARGET_NO_LENGTHEN_LOOP ) {
  3219. + if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
  3220. + return \"%(\\
  3221. +move\\t%0,%z4\\n\\
  3222. +\\tbeq\\t%1,%z4,2f\\n\\
  3223. +1:\\tand\\t%2,%1,0x0001\\n\\
  3224. +\\tdaddu\\t%0,%0,1\\n\\
  3225. +\\tbne\\t%2,%z4,2f\\n\\
  3226. +\\tdsrl\\t%1,%1,1\\n\\
  3227. +\\n\\
  3228. +\\tand\\t%2,%1,0x0001\\n\\
  3229. +\\tdaddu\\t%0,%0,1\\n\\
  3230. +\\tbeq\\t%2,%z4,1b\\n\\
  3231. +\\tdsrl\\t%1,%1,1\\n\\
  3232. +2:%)\";
  3233. +
  3234. + return \"%(\\
  3235. +move\\t%0,%z4\\n\\
  3236. +\\tmove\\t%3,%1\\n\\
  3237. +\\tbeq\\t%3,%z4,2f\\n\\
  3238. +1:\\tand\\t%2,%3,0x0001\\n\\
  3239. +\\tdaddu\\t%0,%0,1\\n\\
  3240. +\\tbne\\t%2,%z4,2f\\n\\
  3241. +\\tdsrl\\t%3,%3,1\\n\\
  3242. +\\n\\
  3243. +\\tand\\t%2,%3,0x0001\\n\\
  3244. +\\tdaddu\\t%0,%0,1\\n\\
  3245. +\\tbeq\\t%2,%z4,1b\\n\\
  3246. +\\tdsrl\\t%3,%3,1\\n\\
  3247. +2:%)\";
  3248. + }
  3249. +
  3250. if (optimize && find_reg_note (insn, REG_DEAD, operands[1]))
  3251. return \"%(\\
  3252. move\\t%0,%z4\\n\\
  3253. @@ -3139,7 +3462,11 @@
  3254. }"
  3255. [(set_attr "type" "multi")
  3256. (set_attr "mode" "DI")
  3257. - (set_attr "length" "24")])
  3258. + (set (attr "length")
  3259. + (if_then_else (and (ne (const_int 0) (symbol_ref "TARGET_MIPS5900") )
  3260. + (eq (const_int 0) (symbol_ref "TARGET_NO_LENGTHEN_LOOP")))
  3261. + (const_int 44)
  3262. + (const_int 24))) ])
  3263.  
  3264. ;;
  3265. @@ -3271,6 +3598,18 @@
  3266. (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))]
  3267. "")
  3268.  
  3269. +(define_insn "one_cmplti2"
  3270. + [(set (match_operand:TI 0 "register_operand" "=d")
  3271. + (not:TI (match_operand:TI 1 "register_operand" "d")))]
  3272. + "TARGET_MIPS5900"
  3273. + "*
  3274. +{
  3275. + operands[2] = const0_rtx;
  3276. + return \"pnor\\t%0,%z2,%1\";
  3277. +}"
  3278. + [(set_attr "type" "mmi")
  3279. + (set_attr "mode" "TI")])
  3280. +
  3281. ;;
  3282. ;; ....................
  3283. @@ -3386,6 +3725,17 @@
  3284. [(set_attr "type" "arith")
  3285. (set_attr "mode" "DI")])
  3286.  
  3287. +(define_insn "andti3"
  3288. + [(set (match_operand:TI 0 "register_operand" "=d,d")
  3289. + (and:TI (match_operand:TI 1 "register_operand" "%0,d")
  3290. + (match_operand:TI 2 "register_operand" "d,d")))]
  3291. + "TARGET_MIPS5900"
  3292. + "@
  3293. + pand\\t%0,%2
  3294. + pand\\t%0,%1,%2"
  3295. + [(set_attr "type" "mmi")
  3296. + (set_attr "mode" "TI")])
  3297. +
  3298. (define_expand "iorsi3"
  3299. [(set (match_operand:SI 0 "register_operand" "=d,d")
  3300. (ior:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
  3301. @@ -3477,6 +3827,17 @@
  3302. (set (subreg:SI (match_dup 0) 4) (ior:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))]
  3303. "")
  3304.  
  3305. +(define_insn "iorti3"
  3306. + [(set (match_operand:TI 0 "register_operand" "=d,d")
  3307. + (ior:TI (match_operand:TI 1 "register_operand" "%0,d")
  3308. + (match_operand:TI 2 "register_operand" "d,d")))]
  3309. + "TARGET_MIPS5900"
  3310. + "@
  3311. + por\\t%0,%2
  3312. + por\\t%0,%1,%2"
  3313. + [(set_attr "type" "mmi")
  3314. + (set_attr "mode" "TI")])
  3315. +
  3316. (define_expand "xorsi3"
  3317. [(set (match_operand:SI 0 "register_operand" "=d,d")
  3318. (xor:SI (match_operand:SI 1 "uns_arith_operand" "%d,d")
  3319. @@ -3591,6 +3952,17 @@
  3320. [(set_attr "type" "arith")
  3321. (set_attr "mode" "DI")])
  3322.  
  3323. +(define_insn "xorti3"
  3324. + [(set (match_operand:TI 0 "register_operand" "=d,d")
  3325. + (xor:TI (match_operand:TI 1 "register_operand" "%0,d")
  3326. + (match_operand:TI 2 "register_operand" "d,d")))]
  3327. + "TARGET_MIPS5900"
  3328. + "@
  3329. + pxor\\t%0,%2
  3330. + pxor\\t%0,%1,%2"
  3331. + [(set_attr "type" "mmi")
  3332. + (set_attr "mode" "TI")])
  3333. +
  3334. (define_insn "*norsi3"
  3335. [(set (match_operand:SI 0 "register_operand" "=d")
  3336. (and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
  3337. @@ -3632,6 +4004,18 @@
  3338. (set (subreg:SI (match_dup 0) 4) (and:SI (not:SI (subreg:SI (match_dup 1) 4)) (not:SI (subreg:SI (match_dup 2) 4))))]
  3339. "")
  3340. +(define_insn "*norti3"
  3341. + [(set (match_operand:TI 0 "register_operand" "=d,d")
  3342. + (and:TI (not:TI (match_operand:TI 1 "register_operand" "%0,d"))
  3343. + (not:TI (match_operand:TI 2 "register_operand" "d,d"))))]
  3344. + "TARGET_MIPS5900"
  3345. + "@
  3346. + pnor\\t%0,%2
  3347. + pnor\\t%0,%1,%2"
  3348. + [(set_attr "type" "mmi")
  3349. + (set_attr "mode" "TI")])
  3350. +
  3351. +
  3352. ;;
  3353. ;; ....................
  3354. ;;
  3355. @@ -4073,7 +4457,7 @@
  3356.  
  3357. (define_insn "extendsidi2"
  3358. [(set (match_operand:DI 0 "register_operand" "=d,y,d,*d,d,d")
  3359. - (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,d,y,*x,R,m")))]
  3360. + (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,d,y,*x*w,R,m")))]
  3361. "TARGET_64BIT"
  3362. "* return mips_move_1word (operands, insn, FALSE);"
  3363. [(set_attr "type" "move,move,move,hilo,load,load")
  3364. @@ -4299,6 +4683,21 @@
  3365. {
  3366. rtx xoperands[10];
  3367.  
  3368. + /* trunc.w.s isn't implemented on the r5900, but cvt.w.s */
  3369. + /* truncates, so use it here. */
  3370. + if (TARGET_MIPS5900)
  3371. + {
  3372. + if (which_alternative == 1)
  3373. + return \"cvt.w.s %0,%1\";
  3374. +
  3375. + output_asm_insn (\"cvt.w.s %3,%1\", operands);
  3376. +
  3377. + xoperands[0] = operands[0];
  3378. + xoperands[1] = operands[3];
  3379. + output_asm_insn (mips_move_1word (xoperands, insn, FALSE), xoperands);
  3380. + return \"\";
  3381. + }
  3382. +
  3383. if (which_alternative == 1)
  3384. return \"trunc.w.s %0,%1,%2\";
  3385.  
  3386. @@ -4912,6 +5311,86 @@
  3387. [(set_attr "type" "arith")
  3388. (set_attr "mode" "SI")])
  3389.  
  3390. +;; 128-bit integer moves
  3391. +
  3392. +;; Unlike most other insns, the move insns can't be split with
  3393. +;; different predicates, because register spilling and other parts of
  3394. +;; the compiler, have memoized the insn number already.
  3395. +
  3396. +(define_expand "movti"
  3397. + [(set (match_operand:TI 0 "nonimmediate_operand" "")
  3398. + (match_operand:TI 1 "general_operand" ""))]
  3399. + "TARGET_MIPS5900"
  3400. + "
  3401. +{
  3402. + /* I think this code is unnecessary since we'll never split when
  3403. + the mode is larger than UNITS_PER_WORD. */
  3404. + if (mips_split_addresses && mips_check_split (operands[1], TImode))
  3405. + {
  3406. + enum machine_mode mode = GET_MODE (operands[0]);
  3407. + rtx tem = ((reload_in_progress | reload_completed)
  3408. + ? operands[0] : gen_reg_rtx (mode));
  3409. +
  3410. + emit_insn (gen_rtx (SET, VOIDmode, tem,
  3411. + gen_rtx (HIGH, mode, operands[1])));
  3412. +
  3413. + operands[1] = gen_rtx (LO_SUM, mode, tem, operands[1]);
  3414. + }
  3415. +
  3416. + /* If we are generating embedded PIC code, and we are referring to a
  3417. + symbol in the .text section, we must use an offset from the start
  3418. + of the function.
  3419. +
  3420. + For now we abort this case on the R5900. */
  3421. + if (TARGET_EMBEDDED_PIC
  3422. + && (GET_CODE (operands[1]) == LABEL_REF
  3423. + || (GET_CODE (operands[1]) == SYMBOL_REF
  3424. + && ! SYMBOL_REF_FLAG (operands[1]))))
  3425. + abort ();
  3426. +
  3427. + /* If operands[1] is a constant address illegal for pic, then we need to
  3428. + handle it just like LEGITIMIZE_ADDRESS does.
  3429. + For now we abort this case on the R5900. */
  3430. + if (flag_pic && pic_address_needs_scratch (operands[1]))
  3431. + abort ();
  3432. +
  3433. + /* Make operand1 a register if it isn't already. */
  3434. + if ((reload_in_progress | reload_completed) == 0
  3435. + && !register_operand (operands[0], TImode)
  3436. + && !register_operand (operands[1], TImode)
  3437. + && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
  3438. + && operands[1] != CONST0_RTX (TImode))
  3439. + {
  3440. + rtx temp = force_reg (TImode, operands[1]);
  3441. + emit_move_insn (operands[0], temp);
  3442. + DONE;
  3443. + }
  3444. +}")
  3445. +
  3446. +(define_insn "movti_internal"
  3447. + [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,R,m,d,d,d,d,d")
  3448. + (match_operand:TI 1 "movti_operand" "d,R,m,d,d,J,K,L,M,i"))]
  3449. + "TARGET_MIPS5900
  3450. + && (register_operand (operands[0], TImode)
  3451. + || se_register_operand (operands[1], TImode)
  3452. + || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
  3453. + || operands[1] == CONST0_RTX (TImode))"
  3454. + "@
  3455. + por %0,$0,%1
  3456. + lq %0,%1
  3457. + lq %0,%1
  3458. + sq %1,%0
  3459. + sq %1,%0
  3460. + por %0,%.,%.
  3461. + por\\t%0,%.,%.\;li\\t%0,%1 \\t\\t\\t# ori
  3462. + por\\t%0,%.,%.\;li\\t%0,%1 \\t\\t\\t# lui
  3463. + por\\t%0,%.,%.\;dli\\t%0,%1 \\t\\t\\t# general li macro
  3464. + dli\\t%0,%M1\;pcpyld\\t%0,%0,%.\;dli\\t%0,%L1"
  3465. + [(set_attr "type" "mmi,load,load,store,store,mmi,mmi,mmi,mmi,mmi")
  3466. + (set_attr "mode" "TI")
  3467. +;; The general li macro on a 64 bit machine can be up to 7 instructions long.
  3468. + (set_attr "length" "4,4,4,4,4,4,16,16,32,60")])
  3469. +
  3470. ;; 64-bit integer moves
  3471.  
  3472. ;; Unlike most other insns, the move insns can't be split with
  3473. @@ -5039,7 +5518,7 @@
  3474. (set_attr "length" "4,8")])
  3475.  
  3476. (define_insn "movdi_internal"
  3477. - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x")
  3478. + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x*w,*d,*x*w")
  3479. (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d"))]
  3480. "!TARGET_64BIT && !TARGET_MIPS16
  3481. && (register_operand (operands[0], DImode)
  3482. @@ -5075,8 +5554,8 @@
  3483. "")
  3484.  
  3485. (define_insn "movdi_internal2"
  3486. - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x,*d,*x,*a")
  3487. - (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x,*d,*J"))]
  3488. + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*x*w,*d,*x*w,*a*q")
  3489. + (match_operand:DI 1 "movdi_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,J,*x*w,*d,*J"))]
  3490. "TARGET_64BIT && !TARGET_MIPS16
  3491. && (register_operand (operands[0], DImode)
  3492. || se_register_operand (operands[1], DImode)
  3493. @@ -5089,7 +5568,7 @@
  3494.  
  3495. (define_insn ""
  3496. [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
  3497. - (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
  3498. + (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x*w"))]
  3499. "TARGET_64BIT && TARGET_MIPS16
  3500. && (register_operand (operands[0], DImode)
  3501. || se_register_operand (operands[1], DImode))"
  3502. @@ -5180,7 +5659,7 @@
  3503. ? REGNO (operands[2]) + 1
  3504. : REGNO (operands[2])));
  3505.  
  3506. - if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
  3507. + if (GET_CODE (operands[0]) == REG && ( REGNO (operands[0]) == HILO_REGNUM || REGNO (operands[0]) == HILO1_REGNUM ) )
  3508. {
  3509. if (GET_CODE (operands[1]) == MEM)
  3510. {
  3511. @@ -5203,28 +5682,45 @@
  3512. lo_word = memword;
  3513. }
  3514. emit_move_insn (scratch, hi_word);
  3515. + if( REGNO (operands[0]) == HILO_REGNUM )
  3516. emit_move_insn (gen_rtx_REG (SImode, 64), scratch);
  3517. + else
  3518. + emit_move_insn (gen_rtx_REG (SImode, 76), scratch);
  3519. emit_move_insn (scratch, lo_word);
  3520. + if( REGNO (operands[0]) == HILO_REGNUM )
  3521. emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
  3522. + else
  3523. + emit_move_insn (gen_rtx (REG, SImode, 77), scratch);
  3524. emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
  3525. }
  3526. else
  3527. {
  3528. emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
  3529. + if( REGNO (operands[0]) == HILO_REGNUM )
  3530. emit_insn (gen_movdi (gen_rtx_REG (DImode, 64), scratch));
  3531. + else
  3532. + emit_insn (gen_movdi (gen_rtx_REG (DImode, 76), scratch));
  3533. emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
  3534. emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
  3535. + if( REGNO (operands[0]) == HILO_REGNUM )
  3536. emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
  3537. - emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
  3538. + else
  3539. + emit_insn (gen_movdi (gen_rtx (REG, DImode, 77), scratch));
  3540. }
  3541. DONE;
  3542. }
  3543. - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
  3544. + if (GET_CODE (operands[1]) == REG && ( REGNO (operands[1]) == HILO_REGNUM || REGNO (operands[1]) == HILO1_REGNUM ) )
  3545. {
  3546. + if( REGNO (operands[1]) == HILO_REGNUM )
  3547. emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 65)));
  3548. + else
  3549. + emit_insn (gen_movdi (scratch, gen_rtx_REG (DImode, 76)));
  3550. emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
  3551. emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
  3552. + if( REGNO (operands[1]) == HILO_REGNUM )
  3553. emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 64)));
  3554. + else
  3555. + emit_insn (gen_movdi (operands[0], gen_rtx_REG (DImode, 77)));
  3556. emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
  3557. emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
  3558. emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
  3559. @@ -5242,7 +5738,7 @@
  3560. ;; use a TImode scratch reg.
  3561.  
  3562. (define_expand "reload_outdi"
  3563. - [(set (match_operand:DI 0 "general_operand" "=b")
  3564. + [(set (match_operand:DI 0 "" "=b")
  3565. (match_operand:DI 1 "se_register_operand" "b"))
  3566. (clobber (match_operand:TI 2 "register_operand" "=&d"))]
  3567. "TARGET_64BIT"
  3568. @@ -5250,17 +5746,23 @@
  3569. {
  3570. rtx scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
  3571.  
  3572. - if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
  3573. + if (GET_CODE (operands[0]) == REG && ( REGNO (operands[0]) == HILO_REGNUM || REGNO (operands[0]) == HILO1_REGNUM ) )
  3574. {
  3575. emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
  3576. + if( REGNO (operands[0]) == HILO_REGNUM )
  3577. emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
  3578. + else
  3579. + emit_insn (gen_movdi (gen_rtx (REG, DImode, 76), scratch));
  3580. emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
  3581. emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
  3582. + if( REGNO (operands[0]) == HILO_REGNUM )
  3583. emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
  3584. + else
  3585. + emit_insn (gen_movdi (gen_rtx (REG, DImode, 77), scratch));
  3586. emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[0]), 2));
  3587. DONE;
  3588. }
  3589. - if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
  3590. + if (GET_CODE (operands[1]) == REG && ( REGNO (operands[1]) == HILO_REGNUM || REGNO (operands[1]) == HILO1_REGNUM ) )
  3591. {
  3592. if (GET_CODE (operands[0]) == MEM)
  3593. {
  3594. @@ -5282,9 +5784,15 @@
  3595. hi_word = offword;
  3596. lo_word = memword;
  3597. }
  3598. + if( REGNO (operands[1]) == HILO_REGNUM )
  3599. emit_move_insn (scratch, gen_rtx_REG (SImode, 64));
  3600. + else
  3601. + emit_move_insn (scratch, gen_rtx_REG (SImode, 76));
  3602. emit_move_insn (hi_word, scratch);
  3603. + if( REGNO (operands[1]) == HILO_REGNUM )
  3604. emit_move_insn (scratch, gen_rtx_REG (SImode, 65));
  3605. + else
  3606. + emit_move_insn (scratch, gen_rtx_REG (SImode, 77));
  3607. emit_move_insn (lo_word, scratch);
  3608. emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
  3609. }
  3610. @@ -5294,10 +5802,16 @@
  3611. and hence we can not directly move from the HILO register
  3612. into it. */
  3613. rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
  3614. + if( REGNO (operands[1]) == HILO_REGNUM )
  3615. emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
  3616. + else
  3617. + emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 77)));
  3618. emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
  3619. emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
  3620. + if( REGNO (operands[1]) == HILO_REGNUM )
  3621. emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 64)));
  3622. + else
  3623. + emit_insn (gen_movdi (scratch2, gen_rtx (REG, DImode, 76)));
  3624. emit_insn (gen_ashldi3 (scratch2, scratch2, GEN_INT (32)));
  3625. emit_insn (gen_iordi3 (scratch, scratch, scratch2));
  3626. emit_insn (gen_movdi (operands[0], scratch));
  3627. @@ -5305,10 +5819,16 @@
  3628. }
  3629. else
  3630. {
  3631. + if( REGNO (operands[1]) == HILO_REGNUM )
  3632. emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
  3633. + else
  3634. + emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 77)));
  3635. emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
  3636. emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
  3637. + if( REGNO (operands[1]) == HILO_REGNUM )
  3638. emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
  3639. + else
  3640. + emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 76)));
  3641. emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
  3642. emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
  3643. emit_insn (gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, operands[1]), 2));
  3644. @@ -5468,8 +5988,8 @@
  3645. ;; in FP registers (off by default, use -mdebugh to enable).
  3646.  
  3647. (define_insn "movsi_internal1"
  3648. - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x,*x,*d,*d")
  3649. - (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,J,*d,*x,*a"))]
  3650. + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x*w,*x*w,*d,*d")
  3651. + (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,J,*d,*x*w,*a*q"))]
  3652. "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
  3653. && (register_operand (operands[0], SImode)
  3654. || register_operand (operands[1], SImode)
  3655. @@ -5480,8 +6000,8 @@
  3656. (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,8,4,8,4,4,4,4")])
  3657.  
  3658. (define_insn "movsi_internal2"
  3659. - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
  3660. - (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))]
  3661. + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, d, d,d,d, R, m,*d,*z,*x*w,*d,*x*w,*d")
  3662. + (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x*w,*d,*a*q"))]
  3663. "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
  3664. && (register_operand (operands[0], SImode)
  3665. || register_operand (operands[1], SImode)
  3666. @@ -5764,7 +6284,7 @@
  3667.  
  3668. ;; This insn is for the unspec delay for HILO.
  3669.  
  3670. -(define_insn "*HILO_delay"
  3671. +(define_insn "HILO_delay"
  3672. [(unspec [(match_operand 0 "register_operand" "=b")] 2 )]
  3673. ""
  3674. ""
  3675. @@ -5937,8 +6457,8 @@
  3676. ;; in FP registers (off by default, use -mdebugh to enable).
  3677.  
  3678. (define_insn "movhi_internal1"
  3679. - [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x,*d")
  3680. - (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
  3681. + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f,*f*z,*x*w,*d")
  3682. + (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x*w"))]
  3683. "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
  3684. && (register_operand (operands[0], HImode)
  3685. || register_operand (operands[1], HImode)
  3686. @@ -5949,8 +6469,8 @@
  3687. (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
  3688.  
  3689. (define_insn "movhi_internal2"
  3690. - [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
  3691. - (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
  3692. + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x*w,*d")
  3693. + (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x*w"))]
  3694. "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
  3695. && (register_operand (operands[0], HImode)
  3696. || register_operand (operands[1], HImode)
  3697. @@ -5962,7 +6482,7 @@
  3698.  
  3699. (define_insn ""
  3700. [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
  3701. - (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
  3702. + (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x*w"))]
  3703. "TARGET_MIPS16
  3704. && (register_operand (operands[0], HImode)
  3705. || register_operand (operands[1], HImode))"
  3706. @@ -6059,8 +6579,8 @@
  3707. ;; in FP registers (off by default, use -mdebugh to enable).
  3708.  
  3709. (define_insn "movqi_internal1"
  3710. - [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
  3711. - (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
  3712. + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x*w,*d")
  3713. + (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x*w"))]
  3714. "TARGET_DEBUG_H_MODE && !TARGET_MIPS16
  3715. && (register_operand (operands[0], QImode)
  3716. || register_operand (operands[1], QImode)
  3717. @@ -6072,7 +6592,7 @@
  3718.  
  3719. (define_insn "movqi_internal2"
  3720. [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d")
  3721. - (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))]
  3722. + (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x*w"))]
  3723. "!TARGET_DEBUG_H_MODE && !TARGET_MIPS16
  3724. && (register_operand (operands[0], QImode)
  3725. || register_operand (operands[1], QImode)
  3726. @@ -6289,12 +6809,13 @@
  3727. ;; This is volatile to make sure that the scheduler won't move any symbol_ref
  3728. ;; uses in front of it. All symbol_refs implicitly use the gp reg.
  3729.  
  3730. +;; FIXME: what is this for? needed for r5900 PIC?
  3731. (define_insn "loadgp"
  3732. [(set (reg:DI 28)
  3733. (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
  3734. (match_operand:DI 1 "register_operand" "")] 2))
  3735. (clobber (reg:DI 1))]
  3736. - ""
  3737. + "!TARGET_MIPS5900"
  3738. "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]"
  3739. [(set_attr "type" "move")
  3740. (set_attr "mode" "DI")
  3741. @@ -9568,7 +10089,7 @@
  3742. }")
  3743.  
  3744. ;; Trivial return. Make it look like a normal return insn as that
  3745. -;; allows jump optimizations to work better .
  3746. +;; allows jump optimizations to work better.
  3747. (define_insn "return"
  3748. [(return)]
  3749. "mips_can_use_return_insn ()"
  3750. @@ -9773,6 +10294,37 @@
  3751. (set_attr "mode" "none")
  3752. (set_attr "length" "8")])
  3753.  
  3754. +;;
  3755. +;; use jalr instead of jal
  3756. +;;
  3757. +(define_insn "call_indirect_internal"
  3758. + [ (unspec_volatile [
  3759. + (match_operand 0 "call_insn_operand" "ri")
  3760. + (match_operand 1 "" "i")
  3761. + (match_operand:SI 2 "register_operand" "=d") ] 30 )]
  3762. + ""
  3763. + "*
  3764. +{
  3765. + register rtx target = operands[0];
  3766. +
  3767. + if (GET_CODE (target) == SYMBOL_REF)
  3768. + {
  3769. + if (GET_MODE (target) == SImode)
  3770. + return \"la\\t%^,%0\\n\\tjalr\\t%2,%^\";
  3771. + else
  3772. + return \"dla\\t%^,%0\\n\\tjalr\\t%2,%^\";
  3773. + }
  3774. + else if (GET_CODE (target) == CONST_INT)
  3775. + return \"li\\t%^,%0\\n\\tjalr\\t%2,%^\";
  3776. + else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
  3777. + return \"move\\t%^,%0\\n\\tjalr\\t%2,%^\";
  3778. + else
  3779. + return \"jalr\\t%2,%0\";
  3780. +}"
  3781. + [(set_attr "type" "call")
  3782. + (set_attr "mode" "none")
  3783. + (set_attr "length" "8")])
  3784. +
  3785. (define_insn "call_internal1"
  3786. [(call (mem (match_operand 0 "call_insn_operand" "ri"))
  3787. (match_operand 1 "" "i"))
  3788. @@ -9805,6 +10357,8 @@
  3789. return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
  3790. else if (CONSTANT_ADDRESS_P (target))
  3791. {
  3792. + if (REGNO (operands[2]) == (31 + GP_REG_FIRST))
  3793. + return \"jal\\t%0\";
  3794. if (GET_MODE (target) == SImode)
  3795. return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
  3796. else
  3797. @@ -10013,6 +10567,8 @@
  3798. return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
  3799. else if (CONSTANT_ADDRESS_P (target))
  3800. {
  3801. + if (REGNO (operands[3]) == (31 + GP_REG_FIRST))
  3802. + return \"jal\\t%1\";
  3803. if (GET_MODE (target) == SImode)
  3804. return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
  3805. else
  3806. @@ -10148,6 +10704,8 @@
  3807. return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
  3808. else if (CONSTANT_ADDRESS_P (target))
  3809. {
  3810. + if (REGNO (operands[4]) == (31 + GP_REG_FIRST))
  3811. + return \"jal\\t%1\";
  3812. if (GET_MODE (target) == SImode)
  3813. return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
  3814. else
  3815. @@ -10205,6 +10763,15 @@
  3816. [(set_attr "type" "nop")
  3817. (set_attr "mode" "none")])
  3818.  
  3819. +;; Used by the r5900 loop lengthening code.
  3820. +
  3821. +(define_insn "nop_internal"
  3822. + [ (unspec_volatile [(const_int 0)] 31)]
  3823. + "TARGET_MIPS5900"
  3824. + "%(nop%)"
  3825. + [(set_attr "type" "nop")
  3826. + (set_attr "mode" "none")])
  3827. +
  3828. ;; The MIPS chip does not seem to require stack probes.
  3829. ;;
  3830. ;; (define_expand "probe"
  3831. @@ -10419,6 +10986,11 @@
  3832. "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE"
  3833. "
  3834. {
  3835. + /* XXX: Verify this */
  3836. + if (TARGET_MIPS5900
  3837. + && GET_MODE_CLASS (GET_MODE (branch_cmp[0])) == MODE_FLOAT)
  3838. + FAIL;
  3839. +
  3840. gen_conditional_move (operands);
  3841. DONE;
  3842. }")
  3843. @@ -10720,3 +11292,175 @@
  3844. [(set_attr "type" "arith")
  3845. (set_attr "mode" "DI")
  3846. (set_attr "length" "40")])
  3847. +
  3848. +;; r5900 MultiMedia Instructions (MMI)
  3849. +;; A lot of this code is based on the MMX implementation in i386.md. The main
  3850. +;; differences between MMX and MMI is that MMI supports 128-bit wide vector
  3851. +;; operations and MMI operates directly on the r5900 128-bit GPRs vs. needing
  3852. +;; a special set of MM-dedicated registers. Most of the instructions have the
  3853. +;; same mnemonics and perform similiar operations.
  3854. +
  3855. +;; Supported vector types
  3856. +;; 16 x 8 bits = V16QI
  3857. +;; 8 x 16 bits = V8HI
  3858. +;; 4 x 32 bits = V4SI and V4SF
  3859. +;; 2 x 64 bits = V2DI and V2SF
  3860. +;;
  3861. +
  3862. +;; MMI arithmetic
  3863. +;; TODO: Add the alternative where operand 1 == operand 2
  3864. +
  3865. +(define_insn "addv16qi3"
  3866. + [(set (match_operand:V16QI 0 "register_operand" "=d")
  3867. + (plus:V16QI (match_operand:V16QI 1 "register_operand" "d")
  3868. + (match_operand:V16QI 2 "register_operand" "d")))]
  3869. + "TARGET_MMI"
  3870. + "paddb\\t%0,%1,%2"
  3871. + [(set_attr "type" "mmi")])
  3872. +
  3873. +(define_insn "addv8hi3"
  3874. + [(set (match_operand:V8HI 0 "register_operand" "=d")
  3875. + (plus:V8HI (match_operand:V8HI 1 "register_operand" "d")
  3876. + (match_operand:V8HI 2 "register_operand" "d")))]
  3877. + "TARGET_MMI"
  3878. + "paddh\\t%0,%1,%2"
  3879. + [(set_attr "type" "mmi")])
  3880. +
  3881. +(define_insn "addv4si3"
  3882. + [(set (match_operand:V4SI 0 "register_operand" "=d")
  3883. + (plus:V4SI (match_operand:V4SI 1 "register_operand" "d")
  3884. + (match_operand:V4SI 2 "register_operand" "d")))]
  3885. + "TARGET_MMI"
  3886. + "paddw\\t%0,%1,%2"
  3887. + [(set_attr "type" "mmi")])
  3888. +
  3889. +;; Signed saturation
  3890. +
  3891. +(define_insn "ssaddv16qi3"
  3892. + [(set (match_operand:V16QI 0 "register_operand" "=d")
  3893. + (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "d")
  3894. + (match_operand:V16QI 2 "register_operand" "d")))]
  3895. + "TARGET_MMI"
  3896. + "paddsb\\t%0,%1,%2"
  3897. + [(set_attr "type" "mmi")])
  3898. +
  3899. +(define_insn "ssaddv8hi3"
  3900. + [(set (match_operand:V8HI 0 "register_operand" "=d")
  3901. + (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "d")
  3902. + (match_operand:V8HI 2 "register_operand" "d")))]
  3903. + "TARGET_MMI"
  3904. + "paddsh\\t%0,%1,%2"
  3905. + [(set_attr "type" "mmi")])
  3906. +
  3907. +(define_insn "ssaddv4si3"
  3908. + [(set (match_operand:V4SI 0 "register_operand" "=d")
  3909. + (ss_plus:V4SI (match_operand:V4SI 1 "register_operand" "d")
  3910. + (match_operand:V4SI 2 "register_operand" "d")))]
  3911. + "TARGET_MMI"
  3912. + "paddsw\\t%0,%1,%2"
  3913. + [(set_attr "type" "mmi")])
  3914. +
  3915. +;; Unsigned saturation
  3916. +
  3917. +(define_insn "usaddv16qi3"
  3918. + [(set (match_operand:V16QI 0 "register_operand" "=d")
  3919. + (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "d")
  3920. + (match_operand:V16QI 2 "register_operand" "d")))]
  3921. + "TARGET_MMI"
  3922. + "paddub\\t%0,%1,%2"
  3923. + [(set_attr "type" "mmi")])
  3924. +
  3925. +(define_insn "usaddv8hi3"
  3926. + [(set (match_operand:V8HI 0 "register_operand" "=d")
  3927. + (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "d")
  3928. + (match_operand:V8HI 2 "register_operand" "d")))]
  3929. + "TARGET_MMI"
  3930. + "padduh\\t%0,%1,%2"
  3931. + [(set_attr "type" "mmi")])
  3932. +
  3933. +(define_insn "usaddv4si3"
  3934. + [(set (match_operand:V4SI 0 "register_operand" "=d")
  3935. + (us_plus:V4SI (match_operand:V4SI 1 "register_operand" "d")
  3936. + (match_operand:V4SI 2 "register_operand" "d")))]
  3937. + "TARGET_MMI"
  3938. + "padduw\\t%0,%1,%2"
  3939. + [(set_attr "type" "mmi")])
  3940. +
  3941. +;; Subtraction
  3942. +
  3943. +(define_insn "subv16qi3"
  3944. + [(set (match_operand:V16QI 0 "register_operand" "=d")
  3945. + (minus:V16QI (match_operand:V16QI 1 "register_operand" "d")
  3946. + (match_operand:V16QI 2 "register_operand" "d")))]
  3947. + "TARGET_MMI"
  3948. + "psubb\\t%0,%1,%2"
  3949. + [(set_attr "type" "mmi")])
  3950. +
  3951. +(define_insn "subv8hi3"
  3952. + [(set (match_operand:V8HI 0 "register_operand" "=d")
  3953. + (minus:V8HI (match_operand:V8HI 1 "register_operand" "d")
  3954. + (match_operand:V8HI 2 "register_operand" "d")))]
  3955. + "TARGET_MMI"
  3956. + "psubh\\t%0,%1,%2"
  3957. + [(set_attr "type" "mmi")])
  3958. +
  3959. +(define_insn "subv4si3"
  3960. + [(set (match_operand:V4SI 0 "register_operand" "=d")
  3961. + (minus:V4SI (match_operand:V4SI 1 "register_operand" "d")
  3962. + (match_operand:V4SI 2 "register_operand" "d")))]
  3963. + "TARGET_MMI"
  3964. + "psubw\\t%0,%1,%2"
  3965. + [(set_attr "type" "mmi")])
  3966. +
  3967. +;; Signed saturation
  3968. +
  3969. +(define_insn "sssubv16qi3"
  3970. + [(set (match_operand:V16QI 0 "register_operand" "=d")
  3971. + (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "d")
  3972. + (match_operand:V16QI 2 "register_operand" "d")))]
  3973. + "TARGET_MMI"
  3974. + "psubsb\\t%0,%1,%2"
  3975. + [(set_attr "type" "mmi")])
  3976. +
  3977. +(define_insn "sssubv8hi3"
  3978. + [(set (match_operand:V8HI 0 "register_operand" "=d")
  3979. + (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "d")
  3980. + (match_operand:V8HI 2 "register_operand" "d")))]
  3981. + "TARGET_MMI"
  3982. + "psubsh\\t%0,%1,%2"
  3983. + [(set_attr "type" "mmi")])
  3984. +
  3985. +(define_insn "sssubv4si3"
  3986. + [(set (match_operand:V4SI 0 "register_operand" "=d")
  3987. + (ss_minus:V4SI (match_operand:V4SI 1 "register_operand" "d")
  3988. + (match_operand:V4SI 2 "register_operand" "d")))]
  3989. + "TARGET_MMI"
  3990. + "psubsw\\t%0,%1,%2"
  3991. + [(set_attr "type" "mmi")])
  3992. +
  3993. +;; Unsigned saturation
  3994. +
  3995. +(define_insn "ussubv16qi3"
  3996. + [(set (match_operand:V16QI 0 "register_operand" "=d")
  3997. + (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "d")
  3998. + (match_operand:V16QI 2 "register_operand" "d")))]
  3999. + "TARGET_MMI"
  4000. + "psubub\\t%0,%1,%2"
  4001. + [(set_attr "type" "mmi")])
  4002. +
  4003. +(define_insn "ussubv8hi3"
  4004. + [(set (match_operand:V8HI 0 "register_operand" "=d")
  4005. + (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "d")
  4006. + (match_operand:V8HI 2 "register_operand" "d")))]
  4007. + "TARGET_MMI"
  4008. + "psubuh\\t%0,%1,%2"
  4009. + [(set_attr "type" "mmi")])
  4010. +
  4011. +(define_insn "ussubv4si3"
  4012. + [(set (match_operand:V4SI 0 "register_operand" "=d")
  4013. + (us_minus:V4SI (match_operand:V4SI 1 "register_operand" "d")
  4014. + (match_operand:V4SI 2 "register_operand" "d")))]
  4015. + "TARGET_MMI"
  4016. + "psubuw\\t%0,%1,%2"
  4017. + [(set_attr "type" "mmi")])
  4018. +
  4019. diff -burN orig.gcc-3.2.3/gcc/config/mips/mips-protos.h gcc-3.2.3/gcc/config/mips/mips-protos.h
  4020. --- orig.gcc-3.2.3/gcc/config/mips/mips-protos.h 2002-03-24 04:13:16.000000000 -0400
  4021. +++ gcc-3.2.3/gcc/config/mips/mips-protos.h 2015-08-10 16:09:43 +0300
  4022. @@ -82,6 +82,7 @@
  4023. extern void mips_gen_conditional_trap PARAMS ((rtx *));
  4024. extern void mips_emit_fcc_reload PARAMS ((rtx, rtx, rtx));
  4025. extern void machine_dependent_reorg PARAMS ((rtx));
  4026. +extern void machine_dependent_reorg_final PARAMS ((rtx));
  4027. extern int mips_address_cost PARAMS ((rtx));
  4028. extern void mips_count_memory_refs PARAMS ((rtx, int));
  4029. extern HOST_WIDE_INT mips_debugger_offset PARAMS ((rtx, HOST_WIDE_INT));
  4030. diff -burN orig.gcc-3.2.3/gcc/config/mips/r5900.h gcc-3.2.3/gcc/config/mips/r5900.h
  4031. --- orig.gcc-3.2.3/gcc/config/mips/r5900.h 1969-12-31 20:00:00.000000000 -0400
  4032. +++ gcc-3.2.3/gcc/config/mips/r5900.h 2007-07-26 13:04:40.000000000 -0300
  4033. @@ -0,0 +1,285 @@
  4034. +/*
  4035. + * Target machine definitions for the Toshiba r5900.
  4036. + *
  4037. + * Copyright (c) 2003 M. R. Brown <mrbrown@0xd6.org>
  4038. + *
  4039. + * Based on the file elf5900.h, which originally bore
  4040. + * the copyright banner:
  4041. + *
  4042. + * Definitions of target machine for GNU compiler.
  4043. + * Toshiba r5900 little-endian
  4044. + * Copyright (c) 1995 Cygnus Support Inc.
  4045. + *
  4046. + * Also based on the PS2/Linux GCC port provided by SCEI and SCEA.
  4047. + *
  4048. + * Licensed under the terms of the GNU GPL version 2.
  4049. + */
  4050. +
  4051. +/* TODO: Add Linux support. */
  4052. +
  4053. +#include "mips/elf64.h"
  4054. +#include "mips/abi64.h"
  4055. +
  4056. +#define MIPS_CPU_STRING_DEFAULT "R5900"
  4057. +
  4058. +#undef MIPS_ABI_DEFAULT
  4059. +#define MIPS_ABI_DEFAULT ABI_EABI
  4060. +
  4061. +#undef MIPS_ISA_DEFAULT
  4062. +#define MIPS_ISA_DEFAULT 3
  4063. +
  4064. +#undef MACHINE_TYPE
  4065. +#define MACHINE_TYPE "(MIPSel R5900 ELF)"
  4066. +
  4067. +/*
  4068. + I started doing some macro fixes, but as we plan to use 3.4 soon I'm not risking changing stuff I'm not
  4069. + certain about.
  4070. +*/
  4071. +/*
  4072. +#define USE_MACRO_FIXES
  4073. +*/
  4074. +
  4075. +/*
  4076. + gcc-3.0.3-ps2linux has additional min.s and max.s floating point insns. These should be incorporate into mips.md.
  4077. +*/
  4078. +
  4079. +#define FILL_BDSLOT_WITH_NOP
  4080. +
  4081. +/*
  4082. + * Use Gas, target r5900, -msingle-float, 64-bit CPU and longs, split-addr (avoids la insn emits), -mmmi
  4083. + */
  4084. +#undef TARGET_DEFAULT
  4085. +#define TARGET_DEFAULT ( MASK_GAS | MASK_SINGLE_FLOAT | MASK_64BIT \
  4086. + | MASK_LONG64 | MASK_MMI | MASK_VUMM | MASK_SPLIT_ADDR )
  4087. +
  4088. +/*
  4089. + * Even though we're a 64-bit processor, we only support a 32-bit address
  4090. + * space.
  4091. + */
  4092. +#undef Pmode
  4093. +#define Pmode SImode
  4094. +
  4095. +/* 128-bit alignment options */
  4096. +#define DEFAULT_MIPS_ALIGNMENT 128
  4097. +
  4098. +/* TODO: need to make this variable */
  4099. +#undef BIGGEST_ALIGNMENT
  4100. +#define BIGGEST_ALIGNMENT DEFAULT_MIPS_ALIGNMENT
  4101. +
  4102. +#undef SUBTARGET_TARGET_OPTIONS
  4103. +#define SUBTARGET_TARGET_OPTIONS \
  4104. + { "use-128", &mips_use_128_string, \
  4105. + N_("Use 128-bit operations")}, \
  4106. + { "align128", &mips_align128_string, \
  4107. + N_("Use 128-bit alignment")}, \
  4108. + { "no-align128", &mips_no_align128_string, \
  4109. + N_("Don't use 128-bit alignment")}, \
  4110. + { "abi=", &mips_abi_string, \
  4111. + N_("Speciy ABI to use")},
  4112. +
  4113. +/* Stack alignment */
  4114. +#undef STACK_BOUNDARY
  4115. +#define STACK_BOUNDARY \
  4116. + ((mips_abi == ABI_32 || mips_abi == ABI_O64 || (mips_abi == ABI_EABI \
  4117. + && !TARGET_MIPS5900)) \
  4118. + ? 64 : 128)
  4119. +
  4120. +#undef MIPS_STACK_ALIGN
  4121. +#define MIPS_STACK_ALIGN(LOC) \
  4122. + (((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \
  4123. + && mips_alignment != 128 ) \
  4124. + ? ((LOC) + 7) & ~7 \
  4125. + : ((LOC) + 15) & ~15)
  4126. +
  4127. +#define PREFERRED_STACK_BOUNDARY \
  4128. +(mips_alignment == 128 ? 128 : \
  4129. + ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI ) \
  4130. + ? 64 : 128))
  4131. +
  4132. +/* TODO: Find a way to specify default alignments for functions, jumps,
  4133. + and loops. These used to be machine dependant, but now live as -f
  4134. + parameters. */
  4135. +
  4136. +/* prefer .p2align rather than .align (gas assumed) */
  4137. +#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
  4138. + if ((LOG)!=0) \
  4139. + if ((MAX_SKIP)==0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
  4140. + else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP))
  4141. +
  4142. +/* How to output a quadword for the r5900. */
  4143. +#define ASM_OUTPUT_QUADRUPLE_INT(STREAM,VALUE) \
  4144. +do { \
  4145. + if (TARGET_64BIT) \
  4146. + { \
  4147. + fprintf (STREAM, "\t.octa\t"); \
  4148. + if (HOST_BITS_PER_WIDE_INT < 64 || GET_CODE (VALUE) != CONST_INT) \
  4149. + /* We can't use 'X' for negative numbers, because then we won't \
  4150. + get the right value for the upper 32 bits. */ \
  4151. + output_addr_const (STREAM, VALUE); \
  4152. + else \
  4153. + /* We must use 'X', because otherwise LONG_MIN will print as \
  4154. + a number that the Irix 6 assembler won't accept. */ \
  4155. + print_operand (STREAM, VALUE, 'X'); \
  4156. + fprintf (STREAM, "\n"); \
  4157. + } \
  4158. + else \
  4159. + { \
  4160. + assemble_integer (operand_subword ((VALUE), 0, 0, TImode), \
  4161. + UNITS_PER_WORD, 1); \
  4162. + assemble_integer (operand_subword ((VALUE), 1, 0, TImode), \
  4163. + UNITS_PER_WORD, 1); \
  4164. + } \
  4165. +} while (0)
  4166. +
  4167. +
  4168. +#undef CPP_PREDEFINES
  4169. +#define CPP_PREDEFINES "\
  4170. +-D__ELF__ \
  4171. +-Dmips -D_mips -D__mips -D__mips__ \
  4172. +%{!miop: -DR5900 -D_R5900 -D__R5900 -D_EE } \
  4173. +%{miop: -DR3000 -D_3000 -D__3000 } \
  4174. +-DMIPSEL -D_MIPSEL -D__MIPSEL -D__MIPSEL__ \
  4175. +-Acpu(mips) -Amachine(mips) \
  4176. +"
  4177. +
  4178. +/* Default to 32-bit ints and 64-bit longs. */
  4179. +#undef SUBTARGET_CPP_SIZE_SPEC
  4180. +#define SUBTARGET_CPP_SIZE_SPEC "\
  4181. +%{mgp64: -D_MIPS_SZPTR=32 } \
  4182. +%{!mgp64: -D_MIPS_SZPTR=32 } \
  4183. +\
  4184. +%{mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int \
  4185. + -D__SSIZE_TYPE__=long\\ int \
  4186. + -D__PTRDIFF_TYPE__=long\\ int \
  4187. + -D_MIPS_SZLONG=64} \
  4188. +\
  4189. +%{mint64:-D_MIPS_SZINT=64 \
  4190. + %{!mlong64:-D__SIZE_TYPE__=long\\ unsigned\\ int \
  4191. + -D__SSIZE_TYPE__=long\\ int \
  4192. + -D__PTRDIFF_TYPE__=long\\ int \
  4193. + -D_MIPS_SZLONG=64}} \
  4194. +\
  4195. +%{!mint64:-D_MIPS_SZINT=32 \
  4196. + %{!mlong64:-D__SIZE_TYPE__=unsigned\\ int \
  4197. + -D__SSIZE_TYPE__=int \
  4198. + -D__PTRDIFF_TYPE__=int \
  4199. + -D_MIPS_SZLONG=64}} \
  4200. +"
  4201. +
  4202. +#undef SUBTARGET_CPP_SPEC
  4203. +#define SUBTARGET_CPP_SPEC "\
  4204. +%{mfp32: -D_MIPS_FPSET=16}%{!mfp32: -D_MIPS_FPSET=32} \
  4205. +%{mips1: -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS1} \
  4206. +%{mips2: -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS2} \
  4207. +%{mips3: -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS3 -UR3000 -U_R3000} \
  4208. +%{mips4: -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS4 -UR3000 -U_R3000} \
  4209. +%{!mips*: -U__mips -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS3 -D__mips=3 -D__mips64} \
  4210. +%{!mabi=32: %{!mabi=n32: %{!mabi=64: -D__mips_eabi}}} \
  4211. +%{!msoft-float: %{!mdouble-float : -D__mips_single_float}} \
  4212. +%{-D__HAVE_FPU__ } \
  4213. +%{posix: -D_POSIX_SOURCE} \
  4214. +%{.cc: -D__LANGUAGE_C_PLUS_PLUS__ %{!ansi:-DLANGUAGE_C_PLUS_PLUS}} \
  4215. +%{.cxx: -D__LANGUAGE_C_PLUS_PLUS__ %{!ansi:-DLANGUAGE_C_PLUS_PLUS}} \
  4216. +%{.C: -D__LANGUAGE_C_PLUS_PLUS__ %{!ansi:-DLANGUAGE_C_PLUS_PLUS}} \
  4217. +%{.m: -D__LANGUAGE_OBJECTIVE_C__ %{!ansi:-DLANGUAGE_OBJECTIVE_C}} \
  4218. +%{.S: -D__LANGUAGE_ASSEMBLY__ %{!ansi:-DLANGUAGE_ASSEMBLY}} \
  4219. +%{.s: -D__LANGUAGE_ASSEMBLY__ %{!ansi:-DLANGUAGE_ASSEMBLY}} \
  4220. +%{!.S: %{!.s: %{!.cc: %{!.cxx: %{!.C: %{!.m: -D__LANGUAGE_C__ %{!ansi:-DLANGUAGE_C}}}}}} } \
  4221. +%{ansi:-Uunix -Ulinux -Umips -UR3000 -UMIPSEB -UMIPSEL} \
  4222. +%{ffast-math: -D__FAST_MATH__} \
  4223. + "
  4224. +
  4225. +/* The GNU C++ standard library requires that these macros be defined. */
  4226. +#undef CPLUSPLUS_CPP_SPEC
  4227. +#define CPLUSPLUS_CPP_SPEC "\
  4228. +-D__LANGUAGE_C_PLUS_PLUS -D_LANGUAGE_C_PLUS_PLUS \
  4229. +-D_GNU_SOURCE %(cpp) \
  4230. + "
  4231. +
  4232. +#undef SUBTARGET_ASM_SPEC
  4233. +#define SUBTARGET_ASM_SPEC "\
  4234. +%{!march*: %{!miop: -mwarn-short-loop -march=r5900} %{miop: -march=r3000}} \
  4235. +%{!mips*: %{!miop: -mips3 %{!mfp*: -mfp32} %{!mgp*: -mgp64}} %{miop: -mips1 %{!mfp*: -mfp32} %{!mgp*: -mgp32}}} \
  4236. +%{!mabi*: %{!miop: -mabi=eabi}} \
  4237. +%{!mdouble-float: -msingle-float} \
  4238. + "
  4239. +
  4240. +/*
  4241. + * We want to include alignment directives for the r5900 to ensure that
  4242. + * TImode values are properly aligned. It would be best to do this in
  4243. + * mips.h, but it's unclear if all mips assemblers can handle alignments
  4244. + * for local common/bss objects.
  4245. + */
  4246. +#undef ASM_OUTPUT_LOCAL
  4247. +
  4248. +/*
  4249. + * This says how to output an assembler line to define a global common symbol
  4250. + * with size SIZE (in bytes) and alignment ALIGN (in bits).
  4251. + */
  4252. +
  4253. +#undef ASM_OUTPUT_ALIGNED_COMMON
  4254. +#define ASM_OUTPUT_ALIGNED_COMMON(STREAM, NAME, SIZE, ALIGN) \
  4255. +do \
  4256. +{ \
  4257. + mips_declare_object (STREAM, NAME, "\n\t.comm\t", ",%u,", (SIZE)); \
  4258. + fprintf ((STREAM), "%d\n", ((ALIGN) / BITS_PER_UNIT)); \
  4259. +} \
  4260. +while (0)
  4261. +
  4262. +#define POPSECTION_ASM_OP "\t.previous"
  4263. +#define BSS_SECTION_ASM_OP "\t.section\t.bss"
  4264. +#define SBSS_SECTION_ASM_OP "\t.section\t.sbss"
  4265. +#undef ASM_OUTPUT_ALIGNED_LOCAL
  4266. +#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \
  4267. +do \
  4268. + { \
  4269. + if ((SIZE) > 0 && (SIZE) <= mips_section_threshold) \
  4270. + fprintf (STREAM, "%s\n", SBSS_SECTION_ASM_OP); \
  4271. + else \
  4272. + fprintf (STREAM, "%s\n", BSS_SECTION_ASM_OP); \
  4273. + mips_declare_object (STREAM, NAME, "", ":\n", 0); \
  4274. + ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); \
  4275. + ASM_OUTPUT_SKIP (STREAM, SIZE); \
  4276. + fprintf (STREAM, "%s\n", POPSECTION_ASM_OP); \
  4277. + } \
  4278. +while (0)
  4279. +
  4280. +/*
  4281. + * Avoid returning unaligned structures > 64bits, but <= 128bits wide
  4282. + * in registers.
  4283. + *
  4284. + * This avoids a bad interaction between the code to return BLKmode
  4285. + * structures in registers and the wider than word_mode registers
  4286. + * found on the r5900.
  4287. + *
  4288. + * This does not effect returning an aligned 128bit value in a register,
  4289. + * which should work.
  4290. + */
  4291. +
  4292. +#undef RETURN_IN_MEMORY
  4293. +#define RETURN_IN_MEMORY(TYPE) \
  4294. + ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
  4295. + ? TYPE_MODE (TYPE) == BLKmode \
  4296. + : (mips_abi == ABI_EABI && TYPE_MODE (TYPE) == BLKmode \
  4297. + ? (int_size_in_bytes (TYPE) > UNITS_PER_WORD) \
  4298. + : (int_size_in_bytes (TYPE) \
  4299. + > (mips_abi == ABI_EABI ? 2 * UNITS_PER_WORD : 16))))
  4300. +
  4301. +#define EH_FRAME_IN_DATA_SECTION 1
  4302. +
  4303. +/*
  4304. + * This patch is ugly. But it hopefully will put an end to that
  4305. + * 128-bits alignment madness.
  4306. + */
  4307. +
  4308. +#undef CONSTANT_ALIGNMENT
  4309. +#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
  4310. + ((TREE_CODE (EXP) == STRING_CST || TREE_CODE (EXP) == CONSTRUCTOR) \
  4311. + && (ALIGN) < (mips_use_128 ? 128 : 64) ? (mips_use_128 ? 128 : 64) : (ALIGN))
  4312. +
  4313. +#undef DATA_ALIGNMENT
  4314. +#define DATA_ALIGNMENT(TYPE, ALIGN) \
  4315. + ((((ALIGN) < (mips_use_128 ? 128 : 64)) \
  4316. + && (TREE_CODE (TYPE) == ARRAY_TYPE \
  4317. + || TREE_CODE (TYPE) == UNION_TYPE \
  4318. + || TREE_CODE (TYPE) == RECORD_TYPE)) ? (mips_use_128 ? 128 : 64) : (ALIGN))
  4319. diff -burN orig.gcc-3.2.3/gcc/config/mips/t-irx gcc-3.2.3/gcc/config/mips/t-irx
  4320. --- orig.gcc-3.2.3/gcc/config/mips/t-irx 1969-12-31 20:00:00.000000000 -0400
  4321. +++ gcc-3.2.3/gcc/config/mips/t-irx 2007-07-26 13:04:40.000000000 -0300
  4322. @@ -0,0 +1,77 @@
  4323. +CONFIG2_H = $(srcdir)/config/mips/ecoff.h
  4324. +
  4325. +# Don't run fixproto
  4326. +STMP_FIXPROTO =
  4327. +
  4328. +# Suppress building libgcc1.a, since the MIPS compiler port is complete
  4329. +# and does not need anything from libgcc1.a.
  4330. +LIBGCC1 =
  4331. +CROSS_LIBGCC1 =
  4332. +
  4333. +# We must build libgcc2.a with -G 0, in case the user wants to link
  4334. +# without the $gp register.
  4335. +TARGET_LIBGCC2_CFLAGS = -G 0
  4336. +
  4337. +# We want fine grained libraries, so use the new code to build the
  4338. +# floating point emulation libraries.
  4339. +FPBIT = fp-bit.c
  4340. +DPBIT = dp-bit.c
  4341. +
  4342. +dp-bit.c: $(srcdir)/config/fp-bit.c
  4343. + echo '#ifdef __MIPSEL__' > dp-bit.c
  4344. + echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
  4345. + echo '#endif' >> dp-bit.c
  4346. + echo '#define US_SOFTWARE_GOFAST' >> dp-bit.c
  4347. + cat $(srcdir)/config/fp-bit.c >> dp-bit.c
  4348. +
  4349. +fp-bit.c: $(srcdir)/config/fp-bit.c
  4350. + echo '#define FLOAT' > fp-bit.c
  4351. + echo '#ifdef __MIPSEL__' >> fp-bit.c
  4352. + echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
  4353. + echo '#endif' >> fp-bit.c
  4354. + echo '#define US_SOFTWARE_GOFAST' >> fp-bit.c
  4355. + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
  4356. +
  4357. +# Build the libraries for both hard and soft floating point
  4358. +
  4359. +MULTILIB_OPTIONS =
  4360. +MULTILIB_DIRNAMES =
  4361. +MULTILIB_MATCHES =
  4362. +
  4363. +# Library members defined in libgcc2.c.
  4364. +# LIB2FUNCS = _muldi3 _divdi3 _moddi3 _udivdi3 _umoddi3 _negdi2 \
  4365. +# _lshrdi3 _ashldi3 _ashrdi3 _ffsdi2 \
  4366. +# _udiv_w_sdiv _udivmoddi4 _cmpdi2 _ucmpdi2 \
  4367. +# __gcc_bcmp _varargs __dummy
  4368. +
  4369. +
  4370. +# Add additional dependencies to recompile selected modules whenever the
  4371. +# tm.h file changes. The files compiled are:
  4372. +#
  4373. +# gcc.c (*_SPEC changes)
  4374. +# toplev.c (new switches + assembly output changes)
  4375. +# sdbout.c (debug format changes)
  4376. +# dbxout.c (debug format changes)
  4377. +# dwarfout.c (debug format changes)
  4378. +# final.c (assembly output changes)
  4379. +# varasm.c (assembly output changes)
  4380. +# cse.c (cost functions)
  4381. +# insn-output.c (possible ifdef changes in tm.h)
  4382. +# regclass.c (fixed/call used register changes)
  4383. +# explow.c (GO_IF_LEGITIMATE_ADDRESS)
  4384. +# recog.c (GO_IF_LEGITIMATE_ADDRESS)
  4385. +# reload.c (GO_IF_LEGITIMATE_ADDRESS)
  4386. +
  4387. +gcc.o: $(CONFIG2_H)
  4388. +toplev.o: $(CONFIG2_H)
  4389. +sdbout.o: $(CONFIG2_H)
  4390. +dbxout.o: $(CONFIG2_H)
  4391. +dwarfout.o: $(CONFIG2_H)
  4392. +final.o: $(CONFIG2_H)
  4393. +varasm.o: $(CONFIG2_H)
  4394. +cse.o: $(CONFIG2_H)
  4395. +insn-output.o: $(CONFIG2_H)
  4396. +regclass.o: $(CONFIG2_H)
  4397. +explow.o: $(CONFIG2_H)
  4398. +recog.o: $(CONFIG2_H)
  4399. +reload.o: $(CONFIG2_H)
  4400. diff -burN orig.gcc-3.2.3/gcc/config/mips/t-r5900 gcc-3.2.3/gcc/config/mips/t-r5900
  4401. --- orig.gcc-3.2.3/gcc/config/mips/t-r5900 1969-12-31 20:00:00.000000000 -0400
  4402. +++ gcc-3.2.3/gcc/config/mips/t-r5900 2007-07-26 13:04:40.000000000 -0300
  4403. @@ -0,0 +1,56 @@
  4404. +# Suppress building libgcc1.a, since the MIPS compiler port is complete
  4405. +# and does not need anything from libgcc1.a.
  4406. +LIBGCC1 =
  4407. +CROSS_LIBGCC1 =
  4408. +
  4409. +# We must build libgcc2.a with -G 0, in case the user wants to link
  4410. +# without the $gp register.
  4411. +TARGET_LIBGCC2_CFLAGS = -G 0
  4412. +
  4413. +# We want fine grained libraries, so use the new code to build the
  4414. +# floating point emulation libraries.
  4415. +FPBIT = fp-bit.c
  4416. +
  4417. +fp-bit.c: $(srcdir)/config/fp-bit.c
  4418. + echo '#define FLOAT' > fp-bit.c
  4419. + echo '#ifdef __MIPSEL__' >> fp-bit.c
  4420. + echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
  4421. + echo '#endif' >> fp-bit.c
  4422. + echo '#define US_SOFTWARE_GOFAST' >> fp-bit.c
  4423. + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
  4424. +
  4425. +# To reenable the double precision emulation code uncomment the next line and
  4426. +# the 6 lines that follow it.
  4427. +DPBIT = dp-bit.c
  4428. +
  4429. +dp-bit.c: $(srcdir)/config/fp-bit.c
  4430. + echo '#ifdef __MIPSEL__' > dp-bit.c
  4431. + echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
  4432. + echo '#endif' >> dp-bit.c
  4433. + echo '#define US_SOFTWARE_GOFAST' >> dp-bit.c
  4434. + cat $(srcdir)/config/fp-bit.c >> dp-bit.c
  4435. +
  4436. +# Don't let CTOR_LIST end up in sdata section.
  4437. +CRTSTUFF_T_CFLAGS = -G 0
  4438. +
  4439. +# Assemble startup files.
  4440. +$(T)crti.o: $(srcdir)/config/mips/crti5900.asm $(GCC_PASSES)
  4441. + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
  4442. + -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/mips/crti5900.asm
  4443. +
  4444. +$(T)crtn.o: $(srcdir)/config/mips/crtn5900.asm $(GCC_PASSES)
  4445. + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
  4446. + -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/mips/crtn5900.asm
  4447. +
  4448. +MULTILIB_OPTIONS =
  4449. +MULTILIB_DIRNAMES =
  4450. +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
  4451. +
  4452. +#
  4453. +# TImode runtime support
  4454. +#
  4455. +LIBGCC_TIMODE_SRC = $(srcdir)/config/mips/libgcc2-timode.c
  4456. +TIMODE_FUNCS_LIST = _ashlti3 _ashrti3 _cmpti2 _divti3 _ffsti2 _fixdfti _fixunsdfti \
  4457. + _floattidf _floattisf _lshrti3 _modti3 _multi3 _negti2 _ucmpti2 _udivti3 _umodti3
  4458. +
  4459. +LIB2FUNCS_TI = $(TIMODE_FUNCS_LIST)
  4460. diff -burN orig.gcc-3.2.3/gcc/config.gcc gcc-3.2.3/gcc/config.gcc
  4461. --- orig.gcc-3.2.3/gcc/config.gcc 2003-01-30 10:03:42.000000000 -0400
  4462. +++ gcc-3.2.3/gcc/config.gcc 2007-07-26 13:04:40.000000000 -0300
  4463. @@ -1553,6 +1553,10 @@
  4464. *minwg32msv* | *mingw32*)
  4465. ;;
  4466. esac
  4467. + if test x$pass1done = xyes && test x$pass2done = x
  4468. + then
  4469. + host_to_target_tmake_file=i386/t-mingw32
  4470. + fi
  4471. ;;
  4472. i[34567]86-*-uwin*)
  4473. tm_file=i386/uwin.h
  4474. @@ -2387,6 +2391,13 @@
  4475. esac
  4476. tmake_file="t-slibgcc-elf-ver t-linux mips/t-linux"
  4477. extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
  4478. + case $machine in
  4479. + mips*r5900*-*) # Linux for r5900 (EE)
  4480. + tm_file="$tm_file mips/r5900.h"
  4481. + tmake_file="$tmake_file t-r5900"
  4482. + extra_headers="core-mmi.h core-vumm.h"
  4483. + ;;
  4484. + esac
  4485. gnu_ld=yes
  4486. gas=yes
  4487. ;;
  4488. @@ -2583,6 +2594,24 @@
  4489. use_collect2=yes
  4490. fi
  4491. ;;
  4492. +mips*r5900*-*-elf*) # MIPS r5900 ELF, either endian
  4493. + tm_file="dbxelf.h elfos.h mips/r5900.h"
  4494. + tmake_file=mips/t-r5900
  4495. + case $machine in
  4496. + mips*el-*)
  4497. + tm_file="mips/little.h $tm_file"
  4498. + ;;
  4499. + esac
  4500. + gnu_ld=yes
  4501. + gas=yes
  4502. + extra_headers="core-mmi.h core-vumm.h"
  4503. + ;;
  4504. +mipsel-*-irx)
  4505. + tm_file="mips/elfl.h libgloss.h"
  4506. + tmake_file=mips/t-irx
  4507. + target_cpu_default="MASK_GAS|MASK_SOFT_FLOAT"
  4508. + fixincludes=Makefile.in
  4509. + ;;
  4510. mipsel-*-ecoff*)
  4511. tm_file=mips/ecoffl.h
  4512. if test x$stabs = xyes; then
  4513. @@ -3673,5 +3702,8 @@
  4514. host_extra_objs=$extra_host_objs
  4515. host_exeext=$exeext
  4516. pass2done=yes
  4517. + else
  4518. + tmake_file="$tmake_file $host_to_target_tmake_file"
  4519. fi
  4520. fi
  4521. +
  4522. diff -burN orig.gcc-3.2.3/gcc/cp/decl.c gcc-3.2.3/gcc/cp/decl.c
  4523. --- orig.gcc-3.2.3/gcc/cp/decl.c 2003-01-21 15:00:27.000000000 -0400
  4524. +++ gcc-3.2.3/gcc/cp/decl.c 2015-08-10 16:06:57 +0300
  4525. @@ -458,6 +458,10 @@
  4526. ? cp_function_chain->bindings \
  4527. : scope_chain->bindings)
  4528.  
  4529. +#define set_current_binding_level(x) \
  4530. + if(cfun && cp_function_chain->bindings) { cp_function_chain->bindings = (x); } \
  4531. + else { scope_chain->bindings = (x); }
  4532. +
  4533. /* The binding level of the current class, if any. */
  4534.  
  4535. #define class_binding_level scope_chain->class_bindings
  4536. @@ -507,7 +511,7 @@
  4537. are active. */
  4538. memset ((char*) newlevel, 0, sizeof (struct binding_level));
  4539. newlevel->level_chain = current_binding_level;
  4540. - current_binding_level = newlevel;
  4541. + set_current_binding_level(newlevel);
  4542. newlevel->tag_transparent = tag_transparent;
  4543. newlevel->more_cleanups_ok = 1;
  4544.  
  4545. @@ -563,7 +567,7 @@
  4546. #endif /* defined(DEBUG_CP_BINDING_LEVELS) */
  4547. {
  4548. register struct binding_level *level = current_binding_level;
  4549. - current_binding_level = current_binding_level->level_chain;
  4550. + set_current_binding_level(current_binding_level->level_chain);
  4551. level->level_chain = free_binding_level;
  4552. #if 0 /* defined(DEBUG_CP_BINDING_LEVELS) */
  4553. if (level->binding_depth != binding_depth)
  4554. @@ -578,7 +582,9 @@
  4555. suspend_binding_level ()
  4556. {
  4557. if (class_binding_level)
  4558. - current_binding_level = class_binding_level;
  4559. + {
  4560. + set_current_binding_level(class_binding_level);
  4561. + }
  4562.  
  4563. if (global_binding_level)
  4564. {
  4565. @@ -600,7 +606,7 @@
  4566. }
  4567. is_class_level = 0;
  4568. #endif /* defined(DEBUG_CP_BINDING_LEVELS) */
  4569. - current_binding_level = current_binding_level->level_chain;
  4570. + set_current_binding_level(current_binding_level->level_chain);
  4571. find_class_binding_level ();
  4572. }
  4573.  
  4574. @@ -613,7 +619,7 @@
  4575. my_friendly_assert(!class_binding_level, 386);
  4576. /* Also, resuming a non-directly nested namespace is a no-no. */
  4577. my_friendly_assert(b->level_chain == current_binding_level, 386);
  4578. - current_binding_level = b;
  4579. + set_current_binding_level(b);
  4580. #if defined(DEBUG_CP_BINDING_LEVELS)
  4581. b->binding_depth = binding_depth;
  4582. indent ();
  4583. @@ -4291,9 +4297,9 @@
  4584. else
  4585. {
  4586. b = current_binding_level;
  4587. - current_binding_level = level;
  4588. + set_current_binding_level(level);
  4589. x = pushdecl (x);
  4590. - current_binding_level = b;
  4591. + set_current_binding_level(b);
  4592. }
  4593. current_function_decl = function_decl;
  4594. return x;
  4595. @@ -4540,14 +4546,14 @@
  4596. return NULL_TREE;
  4597.  
  4598. ancestor = namespace_ancestor (current_decl_namespace (), used);
  4599. - ud = current_binding_level->using_directives;
  4600. - ud = tree_cons (used, ancestor, ud);
  4601. - current_binding_level->using_directives = ud;
  4602.  
  4603. /* Recursively add all namespaces used. */
  4604. for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
  4605. push_using_directive (TREE_PURPOSE (iter));
  4606.  
  4607. + ud = current_binding_level->using_directives;
  4608. + ud = tree_cons (used, ancestor, ud);
  4609. + current_binding_level->using_directives = ud;
  4610. return ud;
  4611. }
  4612.  
  4613. @@ -6538,7 +6544,7 @@
  4614. current_lang_name = lang_name_c;
  4615.  
  4616. current_function_decl = NULL_TREE;
  4617. - current_binding_level = NULL_BINDING_LEVEL;
  4618. + set_current_binding_level(NULL_BINDING_LEVEL);
  4619. free_binding_level = NULL_BINDING_LEVEL;
  4620.  
  4621. build_common_tree_nodes (flag_signed_char);
  4622. @@ -10124,10 +10130,10 @@
  4623. if (decl_context == NORMAL && !toplevel_bindings_p ())
  4624. {
  4625. struct binding_level *b = current_binding_level;
  4626. - current_binding_level = b->level_chain;
  4627. + set_current_binding_level(b->level_chain);
  4628. if (current_binding_level != 0 && toplevel_bindings_p ())
  4629. decl_context = PARM;
  4630. - current_binding_level = b;
  4631. + set_current_binding_level(b);
  4632. }
  4633.  
  4634. if (name == NULL)
  4635. @@ -13757,7 +13763,7 @@
  4636. FIXME factor out the non-RTL stuff. */
  4637. bl = current_binding_level;
  4638. init_function_start (decl1, input_filename, lineno);
  4639. - current_binding_level = bl;
  4640. + set_current_binding_level(bl);
  4641.  
  4642. /* Even though we're inside a function body, we still don't want to
  4643. call expand_expr to calculate the size of a variable-sized array.
  4644. @@ -14309,20 +14315,11 @@
  4645. if (current_function_return_value)
  4646. {
  4647. tree r = current_function_return_value;
  4648. - tree outer;
  4649. -
  4650. - if (r != error_mark_node
  4651. /* This is only worth doing for fns that return in memory--and
  4652. simpler, since we don't have to worry about promoted modes. */
  4653. - && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)))
  4654. - /* Only allow this for variables declared in the outer scope of
  4655. - the function so we know that their lifetime always ends with a
  4656. - return; see g++.dg/opt/nrv6.C. We could be more flexible if
  4657. - we were to do this optimization in tree-ssa. */
  4658. - && (outer = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl)),
  4659. - chain_member (r, BLOCK_VARS (outer))))
  4660. + if (r != error_mark_node
  4661. + && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
  4662. {
  4663. -
  4664. DECL_ALIGN (r) = DECL_ALIGN (DECL_RESULT (fndecl));
  4665. walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
  4666. nullify_returns_r, r);
  4667. diff -burN orig.gcc-3.2.3/gcc/fixinc/gnu-regex.c gcc-3.2.3/gcc/fixinc/gnu-regex.c
  4668. --- orig.gcc-3.2.3/gcc/fixinc/gnu-regex.c 2002-02-26 20:23:56.000000000 -0400
  4669. +++ gcc-3.2.3/gcc/fixinc/gnu-regex.c 2007-07-26 13:04:40.000000000 -0300
  4670. @@ -26,6 +26,9 @@
  4671. # include <config.h>
  4672. #endif
  4673.  
  4674. +/* XXX :: Should find the correct way for other platforms that have mempcpy. this is a cygwin hack! */
  4675. +#undef HAVE_MEMPCPY
  4676. +
  4677. /* GCC LOCAL: we don't need NLS here. */
  4678. #undef ENABLE_NLS
  4679. /* GCC LOCAL: to handle defining alloca. */
  4680. diff -burN orig.gcc-3.2.3/gcc/fixinc/mkfixinc.sh gcc-3.2.3/gcc/fixinc/mkfixinc.sh
  4681. --- orig.gcc-3.2.3/gcc/fixinc/mkfixinc.sh 2002-01-05 00:06:51.000000000 -0400
  4682. +++ gcc-3.2.3/gcc/fixinc/mkfixinc.sh 2007-07-26 13:04:40.000000000 -0300
  4683. @@ -80,6 +80,8 @@
  4684. i?86-*-mingw32* | \
  4685. i?86-*-uwin* | \
  4686. mips-sgi-irix5cross64 | \
  4687. + mips64r5900el-scei-elf | \
  4688. + mipsel-scei-irx | \
  4689. powerpc-*-eabiaix* | \
  4690. powerpc-*-eabisim* | \
  4691. powerpc-*-eabi* | \
  4692. diff -burN orig.gcc-3.2.3/gcc/glimits.h gcc-3.2.3/gcc/glimits.h
  4693. --- orig.gcc-3.2.3/gcc/glimits.h 2001-08-13 21:53:23.000000000 -0300
  4694. +++ gcc-3.2.3/gcc/glimits.h 2007-07-26 13:04:40.000000000 -0300
  4695. @@ -67,11 +67,11 @@
  4696. /* Minimum and maximum values a `signed long int' can hold.
  4697. (Same as `int'). */
  4698. #ifndef __LONG_MAX__
  4699. -#if defined (__alpha__) || (defined (__sparc__) && defined(__arch64__)) || defined (__sparcv9)
  4700. +#if defined (__alpha__) || (defined (__sparc__) && defined(__arch64__)) || defined (__sparcv9) || defined (__R5900)
  4701. #define __LONG_MAX__ 9223372036854775807L
  4702. #else
  4703. #define __LONG_MAX__ 2147483647L
  4704. -#endif /* __alpha__ || sparc64 */
  4705. +#endif /* __alpha__ || sparc64 || R5900 */
  4706. #endif
  4707. #undef LONG_MIN
  4708. #define LONG_MIN (-LONG_MAX-1)
  4709. diff -burN orig.gcc-3.2.3/gcc/integrate.c gcc-3.2.3/gcc/integrate.c
  4710. --- orig.gcc-3.2.3/gcc/integrate.c 2003-02-03 16:56:29.000000000 -0400
  4711. +++ gcc-3.2.3/gcc/integrate.c 2007-07-26 13:04:40.000000000 -0300
  4712. @@ -358,12 +358,18 @@
  4713. /* Copy the declaration. */
  4714. if (TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL)
  4715. {
  4716. + tree type;
  4717. + type = TREE_TYPE(decl);
  4718. +
  4719. /* For a parameter, we must make an equivalent VAR_DECL, not a
  4720. new PARM_DECL. */
  4721. copy = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
  4722. TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
  4723. TREE_READONLY (copy) = TREE_READONLY (decl);
  4724. TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
  4725. +
  4726. + if (TYPE_RESTRICT(type))
  4727. + DECL_POINTER_ALIAS_SET (copy) = -2;
  4728. }
  4729. else
  4730. {
  4731. diff -burN orig.gcc-3.2.3/gcc/libgcc2-timode.c gcc-3.2.3/gcc/libgcc2-timode.c
  4732. --- orig.gcc-3.2.3/gcc/libgcc2-timode.c 1969-12-31 20:00:00.000000000 -0400
  4733. +++ gcc-3.2.3/gcc/libgcc2-timode.c 2007-07-26 13:04:40.000000000 -0300
  4734. @@ -0,0 +1,792 @@
  4735. +/* GCC rutime support routines for TI mode */
  4736. +
  4737. +/* Copyright (C) 2001 Sony Computer Entertainment Inc.
  4738. + Copyright 2001 Sony Corportaion. */
  4739. +
  4740. +/* This file is derived from libgcc2.c and subject to the original
  4741. + license of libgcc2.c, as follows. */
  4742. +
  4743. +/* Compile this one with gcc. */
  4744. +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
  4745. +
  4746. +This file is part of GNU CC.
  4747. +
  4748. +GNU CC is free software; you can redistribute it and/or modify
  4749. +it under the terms of the GNU General Public License as published by
  4750. +the Free Software Foundation; either version 2, or (at your option)
  4751. +any later version.
  4752. +
  4753. +GNU CC is distributed in the hope that it will be useful,
  4754. +but WITHOUT ANY WARRANTY; without even the implied warranty of
  4755. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4756. +GNU General Public License for more details.
  4757. +
  4758. +You should have received a copy of the GNU General Public License
  4759. +along with GNU CC; see the file COPYING. If not, write to
  4760. +the Free Software Foundation, 59 Temple Place - Suite 330,
  4761. +Boston, MA 02111-1307, USA. */
  4762. +
  4763. +/* As a special exception, if you link this library with other files,
  4764. + some of which are compiled with GCC, to produce an executable,
  4765. + this library does not by itself cause the resulting executable
  4766. + to be covered by the GNU General Public License.
  4767. + This exception does not however invalidate any other reasons why
  4768. + the executable file might be covered by the GNU General Public License. */
  4769. +
  4770. +
  4771. +#include "tconfig.h"
  4772. +
  4773. +/* We disable this when inhibit_libc, so that gcc can still be built without
  4774. + needing header files first. */
  4775. +/* ??? This is not a good solution, since prototypes may be required in
  4776. + some cases for correct code. See also frame.c. */
  4777. +
  4778. +#include "machmode.h"
  4779. +#include "defaults.h"
  4780. +
  4781. +#ifndef LIBGCC2_WORDS_BIG_ENDIAN
  4782. +#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
  4783. +#endif
  4784. +
  4785. +
  4786. +/* In this file, we are interfacing to calls generated by the compiler
  4787. + itself. These calls pass values into these routines which have very
  4788. + specific modes (rather than very specific types), and these
  4789. + compiler-generated calls also expect any return values to have very
  4790. + specific modes (rather than very specific types). Thus, we need to
  4791. + avoid using regular C language type names in this part of the file
  4792. + because the sizes for those types can be configured to be anything.
  4793. + Instead we use the following special type names. */
  4794. +
  4795. +typedef unsigned int UTItype __attribute__((mode(TI)));
  4796. +typedef int TItype __attribute__((mode(TI)));
  4797. +typedef unsigned int UDItype __attribute__((mode(DI)));
  4798. +typedef int DItype __attribute__((mode(DI)));
  4799. +typedef unsigned int UQItype __attribute__((mode(QI)));
  4800. +typedef int QItype __attribute__((mode(QI)));
  4801. +
  4802. +typedef float SFtype __attribute__ ((mode (SF)));
  4803. +typedef float DFtype __attribute__ ((mode (DF)));
  4804. +
  4805. +typedef int word_type __attribute__ ((mode (__word__)));
  4806. +
  4807. +/* Make sure that we don't accidentally use any normal C language
  4808. + built-in type names in the first part of this file. Instead we want
  4809. + to use *only* the type names defined above.
  4810. + The following macro definitions insure that if we *do* accidentally
  4811. + use some normal C language built-in type name, we will get a syntax
  4812. + error. */
  4813. +
  4814. +#define char bogus_type
  4815. +#define short bogus_type
  4816. +#define int bogus_type
  4817. +#define long bogus_type
  4818. +#define unsigned bogus_type
  4819. +#define float bogus_type
  4820. +#define double bogus_type
  4821. +
  4822. +
  4823. +#ifndef BITS_PER_UNIT
  4824. +#define BITS_PER_UNIT 8
  4825. +#endif
  4826. +#ifndef DI_TYPE_SIZE
  4827. +#define DI_TYPE_SIZE 64
  4828. +#endif
  4829. +
  4830. +
  4831. +/* TIstructs are pairs of DItype values in the order determined by
  4832. + LIBGCC2_WORDS_BIG_ENDIAN. */
  4833. +
  4834. +#if LIBGCC2_WORDS_BIG_ENDIAN
  4835. +struct TIstruct {DItype high, low;};
  4836. +#else
  4837. +struct TIstruct {DItype low, high;};
  4838. +#endif
  4839. +
  4840. +/* We need this union to unpack/pack TImode values, since we don't have
  4841. + any arithmetic yet. Incoming TImode parameters are stored into the
  4842. + `ti' field, and the unpacked result is read from the struct `d'. */
  4843. +
  4844. +typedef union
  4845. +{
  4846. + struct TIstruct d;
  4847. + TItype ti;
  4848. +} TIunion;
  4849. +
  4850. +/* for
  4851. + __fixunsdfti
  4852. + __floattidf
  4853. + */
  4854. +#define DI_WORD_SIZE (sizeof (DItype) * BITS_PER_UNIT)
  4855. +#define HIGH_DI_WORD_COEFF (((UTItype) 1) << DI_WORD_SIZE)
  4856. +#define HIGH_DI_HALFWORD_COEFF (((UDItype) 1) << (DI_WORD_SIZE / 2))
  4857. +
  4858. +
  4859. +
  4860. +#if (defined (L_udivti3) || defined (L_divti3) || defined (L_multi3) ||\
  4861. + defined (L_umodti3) || defined (L_modti3))
  4862. +/* ----------------------------------------------------------------- */
  4863. +/* BEGIN: derived from longlog.h */
  4864. +/* for
  4865. + __udivmoddi4
  4866. + __multi3
  4867. + __dviti3
  4868. + __udviti3
  4869. + __modti3
  4870. + __umodti3
  4871. +*/
  4872. +
  4873. +#define __ti_B (((UDItype)1) << (DI_TYPE_SIZE / 2))
  4874. +#define __ti_lowpart(t) ((UDItype) (t) % __ti_B)
  4875. +#define __ti_highpart(t) ((UDItype) (t) / __ti_B)
  4876. +
  4877. +#define umul_ppmm_di(w1, w0, u, v) \
  4878. +do { \
  4879. + UDItype __x0, __x1, __x2, __x3; \
  4880. + UDItype __ul, __vl, __uh, __vh; \
  4881. + \
  4882. + __ul = __ti_lowpart (u); \
  4883. + __uh = __ti_highpart (u); \
  4884. + __vl = __ti_lowpart (v); \
  4885. + __vh = __ti_highpart (v); \
  4886. + \
  4887. + __x0 = (UDItype) __ul * __vl; \
  4888. + __x1 = (UDItype) __ul * __vh; \
  4889. + __x2 = (UDItype) __uh * __vl; \
  4890. + __x3 = (UDItype) __uh * __vh; \
  4891. + \
  4892. + __x1 += __ti_highpart (__x0);/* this can't give carry */ \
  4893. + __x1 += __x2; /* but this indeed can */ \
  4894. + if (__x1 < __x2) /* did we get it? */ \
  4895. + __x3 += __ti_B; /* yes, add it in the proper pos. */ \
  4896. + \
  4897. + (w1) = __x3 + __ti_highpart (__x1); \
  4898. + (w0) = __ti_lowpart (__x1) * __ti_B + __ti_lowpart (__x0); \
  4899. +} while (0)
  4900. +
  4901. +#define __umulditi3(u, v) \
  4902. + ({TIunion __w; \
  4903. + umul_ppmm_di (__w.d.high, __w.d.low, u, v); \
  4904. + __w.ti; })
  4905. +
  4906. +
  4907. +
  4908. +/* Define this unconditionally, so it can be used for debugging. */
  4909. +#define udiv_qrnnd_c_di(q, r, n1, n0, d) \
  4910. + do { \
  4911. + UDItype __d1, __d0, __q1, __q0; \
  4912. + UDItype __r1, __r0, __m; \
  4913. + __d1 = __ti_highpart (d); \
  4914. + __d0 = __ti_lowpart (d); \
  4915. + \
  4916. + __r1 = (n1) % __d1; \
  4917. + __q1 = (n1) / __d1; \
  4918. + __m = (UDItype) __q1 * __d0; \
  4919. + __r1 = __r1 * __ti_B | __ti_highpart (n0); \
  4920. + if (__r1 < __m) \
  4921. + { \
  4922. + __q1--, __r1 += (d); \
  4923. + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
  4924. + if (__r1 < __m) \
  4925. + __q1--, __r1 += (d); \
  4926. + } \
  4927. + __r1 -= __m; \
  4928. + \
  4929. + __r0 = __r1 % __d1; \
  4930. + __q0 = __r1 / __d1; \
  4931. + __m = (UDItype) __q0 * __d0; \
  4932. + __r0 = __r0 * __ti_B | __ti_lowpart (n0); \
  4933. + if (__r0 < __m) \
  4934. + { \
  4935. + __q0--, __r0 += (d); \
  4936. + if (__r0 >= (d)) \
  4937. + if (__r0 < __m) \
  4938. + __q0--, __r0 += (d); \
  4939. + } \
  4940. + __r0 -= __m; \
  4941. + \
  4942. + (q) = (UDItype) __q1 * __ti_B | __q0; \
  4943. + (r) = __r0; \
  4944. + } while (0)
  4945. +
  4946. +
  4947. +#define sub_ddmmss_di(sh, sl, ah, al, bh, bl) \
  4948. + do { \
  4949. + UDItype __x; \
  4950. + __x = (al) - (bl); \
  4951. + (sh) = (ah) - (bh) - (__x > (al)); \
  4952. + (sl) = __x; \
  4953. + } while (0)
  4954. +
  4955. +#define count_leading_zeros_di(count, x) \
  4956. + do { \
  4957. + UDItype __xr = (x); \
  4958. + UDItype __a; \
  4959. + \
  4960. + { \
  4961. + for (__a = DI_TYPE_SIZE - 8; __a > 0; __a -= 8) \
  4962. + if (((__xr >> __a) & 0xff) != 0) \
  4963. + break; \
  4964. + } \
  4965. + \
  4966. + (count) = DI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
  4967. + } while (0)
  4968. +
  4969. +
  4970. +
  4971. +/* END: derived from longlog.h */
  4972. +/* ----------------------------------------------------------------- */
  4973. +#endif /* (defined (L_udivti3) || defined (L_divti3) || defined (L_multi3) ||
  4974. + defined (L_umodti3) || defined (L_modti3)) */
  4975. +
  4976. +
  4977. +#if defined (L_negti2) || defined (L_divti3) || defined (L_modti3)
  4978. +#if defined (L_divti3) || defined (L_modti3)
  4979. +static inline
  4980. +#endif
  4981. +TItype
  4982. +__negti2 (TItype u)
  4983. +{
  4984. + TIunion w;
  4985. + TIunion uu;
  4986. +
  4987. + uu.ti = u;
  4988. +
  4989. + w.d.low = -uu.d.low;
  4990. + w.d.high = -uu.d.high - ((UDItype) w.d.low > 0);
  4991. +
  4992. + return w.ti;
  4993. +}
  4994. +#endif
  4995. +
  4996. +/* Unless shift functions are defined whith full ANSI prototypes,
  4997. + parameter b will be promoted to int if word_type is smaller than an int. */
  4998. +#ifdef L_lshrti3
  4999. +TItype
  5000. +__lshrti3 (TItype u, word_type b)
  5001. +{
  5002. + TIunion w;
  5003. + word_type bm;
  5004. + TIunion uu;
  5005. +
  5006. + if (b == 0)
  5007. + return u;
  5008. +
  5009. + uu.ti = u;
  5010. +
  5011. + bm = (sizeof (DItype) * BITS_PER_UNIT) - b;
  5012. + if (bm <= 0)
  5013. + {
  5014. + w.d.high = 0;
  5015. + w.d.low = (UDItype)uu.d.high >> -bm;
  5016. + }
  5017. + else
  5018. + {
  5019. + UDItype carries = (UDItype)uu.d.high << bm;
  5020. + w.d.high = (UDItype)uu.d.high >> b;
  5021. + w.d.low = ((UDItype)uu.d.low >> b) | carries;
  5022. + }
  5023. +
  5024. + return w.ti;
  5025. +}
  5026. +#endif
  5027. +
  5028. +#ifdef L_ashlti3
  5029. +TItype
  5030. +__ashlti3 (TItype u, word_type b)
  5031. +{
  5032. + TIunion w;
  5033. + word_type bm;
  5034. + TIunion uu;
  5035. +
  5036. + if (b == 0)
  5037. + return u;
  5038. +
  5039. + uu.ti = u;
  5040. +
  5041. + bm = (sizeof (DItype) * BITS_PER_UNIT) - b;
  5042. + if (bm <= 0)
  5043. + {
  5044. + w.d.low = 0;
  5045. + w.d.high = (UDItype)uu.d.low << -bm;
  5046. + }
  5047. + else
  5048. + {
  5049. + UDItype carries = (UDItype)uu.d.low >> bm;
  5050. + w.d.low = (UDItype)uu.d.low << b;
  5051. + w.d.high = ((UDItype)uu.d.high << b) | carries;
  5052. + }
  5053. +
  5054. + return w.ti;
  5055. +}
  5056. +#endif
  5057. +
  5058. +#ifdef L_ashrti3
  5059. +TItype
  5060. +__ashrti3 (TItype u, word_type b)
  5061. +{
  5062. + TIunion w;
  5063. + word_type bm;
  5064. + TIunion uu;
  5065. +
  5066. + if (b == 0)
  5067. + return u;
  5068. +
  5069. + uu.ti = u;
  5070. +
  5071. + bm = (sizeof (DItype) * BITS_PER_UNIT) - b;
  5072. + if (bm <= 0)
  5073. + {
  5074. + /* w.d.high = 1..1 or 0..0 */
  5075. + w.d.high = uu.d.high >> (sizeof (DItype) * BITS_PER_UNIT - 1);
  5076. + w.d.low = uu.d.high >> -bm;
  5077. + }
  5078. + else
  5079. + {
  5080. + UDItype carries = (UDItype)uu.d.high << bm;
  5081. + w.d.high = uu.d.high >> b;
  5082. + w.d.low = ((UDItype)uu.d.low >> b) | carries;
  5083. + }
  5084. +
  5085. + return w.ti;
  5086. +}
  5087. +#endif
  5088. +
  5089. +#ifdef L_ffsti2
  5090. +TItype
  5091. +__ffsti2 (TItype u)
  5092. +{
  5093. + TIunion uu, w;
  5094. + uu.ti = u;
  5095. + w.d.high = 0;
  5096. + w.d.low = __ffsdi2 (uu.d.low);
  5097. + if (w.d.low != 0)
  5098. + return w.ti;
  5099. + w.d.low = __ffsdi2 (uu.d.high);
  5100. + if (w.d.low != 0)
  5101. + {
  5102. + w.d.low += BITS_PER_UNIT * sizeof (DItype);
  5103. + return w.ti;
  5104. + }
  5105. + return w.ti;
  5106. +}
  5107. +#endif
  5108. +
  5109. +
  5110. +#ifdef L_multi3
  5111. +TItype
  5112. +__multi3 (TItype u, TItype v)
  5113. +{
  5114. + TIunion w;
  5115. + TIunion uu, vv;
  5116. +
  5117. + uu.ti = u,
  5118. + vv.ti= v;
  5119. +
  5120. + w.ti = __umulditi3 (uu.d.low, vv.d.low);
  5121. + w.d.high += ((UDItype) uu.d.low * (UDItype) vv.d.high
  5122. + + (UDItype) uu.d.high * (UDItype) vv.d.low);
  5123. +
  5124. + return w.ti;
  5125. +}
  5126. +#endif
  5127. +
  5128. +#if (defined (L_udivti3) || defined (L_divti3) || \
  5129. + defined (L_umodti3) || defined (L_modti3))
  5130. +#define L_udivmodti4
  5131. +#endif
  5132. +
  5133. +#ifdef L_udivmodti4
  5134. +static const UQItype __clz_tab[] =
  5135. +{
  5136. + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  5137. + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  5138. + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  5139. + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  5140. + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  5141. + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  5142. + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  5143. + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  5144. +};
  5145. +
  5146. +#if (defined (L_udivti3) || defined (L_divti3) || \
  5147. + defined (L_umodti3) || defined (L_modti3))
  5148. +static inline
  5149. +#endif
  5150. +UTItype
  5151. +__udivmodti4 (UTItype n, UTItype d, UTItype *rp)
  5152. +{
  5153. + TIunion ww;
  5154. + TIunion nn, dd;
  5155. + TIunion rr;
  5156. + UDItype d0, d1, n0, n1, n2;
  5157. + UDItype q0, q1;
  5158. + UDItype b, bm;
  5159. +
  5160. + nn.ti = n;
  5161. + dd.ti = d;
  5162. +
  5163. + d0 = dd.d.low;
  5164. + d1 = dd.d.high;
  5165. + n0 = nn.d.low;
  5166. + n1 = nn.d.high;
  5167. +
  5168. +
  5169. + if (d1 == 0)
  5170. + {
  5171. + if (d0 > n1)
  5172. + {
  5173. + /* 0q = nn / 0D */
  5174. +
  5175. + count_leading_zeros_di (bm, d0);
  5176. +
  5177. + if (bm != 0)
  5178. + {
  5179. + /* Normalize, i.e. make the most significant bit of the
  5180. + denominator set. */
  5181. +
  5182. + d0 = d0 << bm;
  5183. + n1 = (n1 << bm) | (n0 >> (DI_TYPE_SIZE - bm));
  5184. + n0 = n0 << bm;
  5185. + }
  5186. +
  5187. + udiv_qrnnd_c_di (q0, n0, n1, n0, d0);
  5188. + q1 = 0;
  5189. +
  5190. + /* Remainder in n0 >> bm. */
  5191. + }
  5192. + else
  5193. + {
  5194. + /* qq = NN / 0d */
  5195. +
  5196. + if (d0 == 0)
  5197. + d0 = 1 / d0; /* Divide intentionally by zero. */
  5198. +
  5199. + count_leading_zeros_di (bm, d0);
  5200. +
  5201. + if (bm == 0)
  5202. + {
  5203. + /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
  5204. + conclude (the most significant bit of n1 is set) /\ (the
  5205. + leading quotient digit q1 = 1).
  5206. +
  5207. + This special case is necessary, not an optimization.
  5208. + (Shifts counts of DI_TYPE_SIZE are undefined.) */
  5209. +
  5210. + n1 -= d0;
  5211. + q1 = 1;
  5212. + }
  5213. + else
  5214. + {
  5215. + /* Normalize. */
  5216. +
  5217. + b = DI_TYPE_SIZE - bm;
  5218. +
  5219. + d0 = d0 << bm;
  5220. + n2 = n1 >> b;
  5221. + n1 = (n1 << bm) | (n0 >> b);
  5222. + n0 = n0 << bm;
  5223. +
  5224. + udiv_qrnnd_c_di (q1, n1, n2, n1, d0);
  5225. + }
  5226. +
  5227. + /* n1 != d0... */
  5228. +
  5229. + udiv_qrnnd_c_di (q0, n0, n1, n0, d0);
  5230. +
  5231. + /* Remainder in n0 >> bm. */
  5232. + }
  5233. +
  5234. + if (rp != 0)
  5235. + {
  5236. + rr.d.low = n0 >> bm;
  5237. + rr.d.high = 0;
  5238. + *rp = rr.ti;
  5239. + }
  5240. + }
  5241. + else
  5242. + {
  5243. + if (d1 > n1)
  5244. + {
  5245. + /* 00 = nn / DD */
  5246. +
  5247. + q0 = 0;
  5248. + q1 = 0;
  5249. +
  5250. + /* Remainder in n1n0. */
  5251. + if (rp != 0)
  5252. + {
  5253. + rr.d.low = n0;
  5254. + rr.d.high = n1;
  5255. + *rp = rr.ti;
  5256. + }
  5257. + }
  5258. + else
  5259. + {
  5260. + /* 0q = NN / dd */
  5261. +
  5262. + count_leading_zeros_di (bm, d1);
  5263. + if (bm == 0)
  5264. + {
  5265. + /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
  5266. + conclude (the most significant bit of n1 is set) /\ (the
  5267. + quotient digit q0 = 0 or 1).
  5268. +
  5269. + This special case is necessary, not an optimization. */
  5270. +
  5271. + /* The condition on the next line takes advantage of that
  5272. + n1 >= d1 (true due to program flow). */
  5273. + if (n1 > d1 || n0 >= d0)
  5274. + {
  5275. + q0 = 1;
  5276. + sub_ddmmss_di (n1, n0, n1, n0, d1, d0);
  5277. + }
  5278. + else
  5279. + q0 = 0;
  5280. +
  5281. + q1 = 0;
  5282. +
  5283. + if (rp != 0)
  5284. + {
  5285. + rr.d.low = n0;
  5286. + rr.d.high = n1;
  5287. + *rp = rr.ti;
  5288. + }
  5289. + }
  5290. + else
  5291. + {
  5292. + UDItype m1, m0;
  5293. + /* Normalize. */
  5294. +
  5295. + b = DI_TYPE_SIZE - bm;
  5296. +
  5297. + d1 = (d1 << bm) | (d0 >> b);
  5298. + d0 = d0 << bm;
  5299. + n2 = n1 >> b;
  5300. + n1 = (n1 << bm) | (n0 >> b);
  5301. + n0 = n0 << bm;
  5302. +
  5303. + udiv_qrnnd_c_di (q0, n1, n2, n1, d1);
  5304. + umul_ppmm_di (m1, m0, q0, d0);
  5305. +
  5306. + if (m1 > n1 || (m1 == n1 && m0 > n0))
  5307. + {
  5308. + q0--;
  5309. + sub_ddmmss_di (m1, m0, m1, m0, d1, d0);
  5310. + }
  5311. +
  5312. + q1 = 0;
  5313. +
  5314. + /* Remainder in (n1n0 - m1m0) >> bm. */
  5315. + if (rp != 0)
  5316. + {
  5317. + sub_ddmmss_di (n1, n0, n1, n0, m1, m0);
  5318. + rr.d.low = (n1 << b) | (n0 >> bm);
  5319. + rr.d.high = n1 >> bm;
  5320. + *rp = rr.ti;
  5321. + }
  5322. + }
  5323. + }
  5324. + }
  5325. +
  5326. + ww.d.low = q0;
  5327. + ww.d.high = q1;
  5328. + return ww.ti;
  5329. +}
  5330. +#endif
  5331. +
  5332. +#ifdef L_divti3
  5333. +UTItype __udivmodti4 ();
  5334. +
  5335. +TItype
  5336. +__divti3 (TItype u, TItype v)
  5337. +{
  5338. + word_type c = 0;
  5339. + TIunion uu, vv;
  5340. + TItype w;
  5341. +
  5342. + uu.ti = u;
  5343. + vv.ti = v;
  5344. +
  5345. + if (uu.d.high < 0)
  5346. + c = ~c,
  5347. + uu.ti = __negti2 (uu.ti);
  5348. + if (vv.d.high < 0)
  5349. + c = ~c,
  5350. + vv.ti = __negti2 (vv.ti);
  5351. +
  5352. + w = __udivmodti4 (uu.ti, vv.ti, (UTItype *) 0);
  5353. + if (c)
  5354. + w = __negti2 (w);
  5355. +
  5356. + return w;
  5357. +}
  5358. +#endif
  5359. +
  5360. +#ifdef L_modti3
  5361. +UTItype __udivmodti4 ();
  5362. +
  5363. +TItype
  5364. +__modti3 (TItype u, TItype v)
  5365. +{
  5366. + word_type c = 0;
  5367. + TIunion uu, vv;
  5368. + TItype w;
  5369. +
  5370. + uu.ti = u;
  5371. + vv.ti = v;
  5372. +
  5373. + if (uu.d.high < 0)
  5374. + c = ~c,
  5375. + uu.ti = __negti2 (uu.ti);
  5376. + if (vv.d.high < 0)
  5377. + vv.ti = __negti2 (vv.ti);
  5378. +
  5379. + (void) __udivmodti4 (uu.ti, vv.ti, (UTItype *)&w);
  5380. + if (c)
  5381. + w = __negti2 (w);
  5382. +
  5383. + return w;
  5384. +}
  5385. +#endif
  5386. +
  5387. +#ifdef L_umodti3
  5388. +UTItype __udivmodti4 ();
  5389. +
  5390. +UTItype
  5391. +__umodti3 (UTItype u, UTItype v)
  5392. +{
  5393. + UTItype w;
  5394. +
  5395. + (void) __udivmodti4 (u, v, &w);
  5396. +
  5397. + return w;
  5398. +}
  5399. +#endif
  5400. +
  5401. +
  5402. +#ifdef L_udivti3
  5403. +UTItype __udivmodti4 ();
  5404. +UTItype
  5405. +__udivti3 (UTItype n, UTItype d)
  5406. +{
  5407. + return __udivmodti4 (n, d, (UTItype *) 0);
  5408. +}
  5409. +#endif
  5410. +
  5411. +#ifdef L_cmpti2
  5412. +word_type
  5413. +__cmpti2 (TItype a, TItype b)
  5414. +{
  5415. + TIunion au, bu;
  5416. +
  5417. + au.ti = a, bu.ti = b;
  5418. +
  5419. + if (au.d.high < bu.d.high)
  5420. + return 0;
  5421. + else if (au.d.high > bu.d.high)
  5422. + return 2;
  5423. + if ((UDItype) au.d.low < (UDItype) bu.d.low)
  5424. + return 0;
  5425. + else if ((UDItype) au.d.low > (UDItype) bu.d.low)
  5426. + return 2;
  5427. + return 1;
  5428. +}
  5429. +#endif
  5430. +
  5431. +#ifdef L_ucmpti2
  5432. +word_type
  5433. +__ucmpti2 (UTItype a, UTItype b)
  5434. +{
  5435. + TIunion au, bu;
  5436. +
  5437. + au.ti = a, bu.ti = b;
  5438. +
  5439. + if ((UDItype) au.d.high < (UDItype) bu.d.high)
  5440. + return 0;
  5441. + else if ((UDItype) au.d.high > (UDItype) bu.d.high)
  5442. + return 2;
  5443. + if ((UDItype) au.d.low < (UDItype) bu.d.low)
  5444. + return 0;
  5445. + else if ((UDItype) au.d.low > (UDItype) bu.d.low)
  5446. + return 2;
  5447. + return 1;
  5448. +}
  5449. +#endif
  5450. +
  5451. +
  5452. +/*
  5453. + Followings are not neeeded, because TF or XF mode is not supported.
  5454. + __fixunstfti(), __fixtfdi()
  5455. + __fixunsxfti(), __fixxfti()
  5456. +*/
  5457. +
  5458. +#ifdef L_fixunsdfti
  5459. +TItype
  5460. +__fixunsdfti (DFtype a)
  5461. +{
  5462. + DFtype b;
  5463. + UTItype v;
  5464. +
  5465. + if (a < 0)
  5466. + return 0;
  5467. +
  5468. + /* Compute high word of result, as a flonum. */
  5469. + b = (a / HIGH_DI_WORD_COEFF);
  5470. + /* Convert that to fixed (but not to DItype!),
  5471. + and shift it into the high word. */
  5472. + v = (UDItype) b;
  5473. + v <<= DI_WORD_SIZE;
  5474. + /* Remove high part from the DFtype, leaving the low part as flonum. */
  5475. + a -= (DFtype)v;
  5476. + /* Convert that to fixed (but not to DItype!) and add it in.
  5477. + Sometimes A comes out negative. This is significant, since
  5478. + A has more bits than a long int does. */
  5479. + if (a < 0)
  5480. + v -= (UDItype) (- a);
  5481. + else
  5482. + v += (UDItype) a;
  5483. + return v;
  5484. +}
  5485. +#endif
  5486. +
  5487. +#ifdef L_fixdfti
  5488. +TItype
  5489. +__fixdfti (DFtype a)
  5490. +{
  5491. + if (a < 0)
  5492. + return - __fixunsdfti (-a);
  5493. + return __fixunsdfti (a);
  5494. +}
  5495. +#endif
  5496. +
  5497. +/*
  5498. + Followings are not neeeded, because TF or XF mode is not supported.
  5499. + __floattixf
  5500. + __floattitf
  5501. +*/
  5502. +
  5503. +#ifdef L_floattidf
  5504. +DFtype
  5505. +__floattidf (TItype u)
  5506. +{
  5507. + DFtype d;
  5508. +
  5509. + d = (DItype) (u >> DI_WORD_SIZE);
  5510. + d *= HIGH_DI_HALFWORD_COEFF;
  5511. + d *= HIGH_DI_HALFWORD_COEFF;
  5512. + d += (UDItype) (u & (HIGH_DI_WORD_COEFF - 1));
  5513. +
  5514. + return d;
  5515. +}
  5516. +#endif
  5517. +
  5518. +#ifdef L_floattisf
  5519. +SFtype
  5520. +__floattisf (TItype u)
  5521. +{
  5522. + DFtype df;
  5523. + df = __floattidf (u);
  5524. + return (SFtype) df;
  5525. +}
  5526. +#endif
  5527. diff -burN orig.gcc-3.2.3/gcc/Makefile.in gcc-3.2.3/gcc/Makefile.in
  5528. --- orig.gcc-3.2.3/gcc/Makefile.in 2003-01-28 17:54:07.000000000 -0400
  5529. +++ gcc-3.2.3/gcc/Makefile.in 2007-07-26 13:04:40.000000000 -0300
  5530. @@ -987,6 +987,7 @@
  5531. LIB2FUNCS_ST='$(LIB2FUNCS_ST)' \
  5532. LIB2ADD='$(LIB2ADD)' \
  5533. LIB2ADD_ST='$(LIB2ADD_ST)' \
  5534. + LIB2FUNCS_TI='$(LIB2FUNCS_TI)' \
  5535. LIB2ADDEH='$(LIB2ADDEH)' \
  5536. LIB2ADDEHDEP='$(LIB2ADDEHDEP)' \
  5537. FPBIT='$(FPBIT)' \
  5538. diff -burN orig.gcc-3.2.3/gcc/collect2.c gcc-3.2.3/gcc/collect2.c
  5539. --- orig.gcc-3.2.3/gcc/collect2.c 2009-08-19 16:36:00.000000000 -0500
  5540. +++ gcc-3.2.3/gcc/collect2.c 2009-08-19 16:36:11.000000000 -0500
  5541. @@ -1587,7 +1587,7 @@
  5542. if (redir)
  5543. {
  5544. /* Open response file. */
  5545. - redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
  5546. + redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, 0666);
  5547.  
  5548. /* Duplicate the stdout and stderr file handles
  5549. so they can be restored later. */
  5550. diff -burN orig.gcc-3.2.3/gcc/mklibgcc.in gcc-3.2.3/gcc/mklibgcc.in
  5551. --- orig.gcc-3.2.3/gcc/mklibgcc.in 2003-01-28 17:57:40.000000000 -0400
  5552. +++ gcc-3.2.3/gcc/mklibgcc.in 2007-07-26 13:04:40.000000000 -0300
  5553. @@ -232,6 +232,21 @@
  5554. libgcc2_st_objs="$libgcc2_st_objs ${oname}${objext}"
  5555. done
  5556.  
  5557. +if [ "$LIB2FUNCS_TI" ]; then
  5558. + for name in $LIB2FUNCS_TI; do
  5559. + for ml in $MULTILIBS; do
  5560. + dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
  5561. + flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
  5562. + out="libgcc/${dir}/${name}${objext}"
  5563. +
  5564. + echo $out: $libgcc2_c_dep
  5565. + echo " $gcc_compile" '$(MAYBE_USE_COLLECT2)' $flags -DL$name \
  5566. + -c '$(srcdir)/libgcc2-timode.c' -o $out
  5567. + done
  5568. + libgcc2_objs="$libgcc2_objs ${name}${objext}"
  5569. + done
  5570. +fi
  5571. +
  5572. # SHLIB_MKMAP
  5573. # SHLIB_MKMAP_OPTS
  5574. # SHLIB_MAPFILES
  5575. diff -burN orig.gcc-3.2.3/gcc/toplev.c gcc-3.2.3/gcc/toplev.c
  5576. --- orig.gcc-3.2.3/gcc/toplev.c 2002-11-01 20:57:23.000000000 -0400
  5577. +++ gcc-3.2.3/gcc/toplev.c 2007-07-26 13:04:40.000000000 -0300
  5578. @@ -3469,6 +3469,18 @@
  5579.  
  5580. convert_to_eh_region_ranges ();
  5581.  
  5582. +#ifdef MACHINE_DEPENDENT_REORG_FINAL
  5583. + timevar_push (TV_MACH_DEP);
  5584. + open_dump_file (DFI_mach, decl);
  5585. +
  5586. + MACHINE_DEPENDENT_REORG_FINAL (insns);
  5587. +
  5588. + close_dump_file (DFI_mach, print_rtl, insns);
  5589. + timevar_pop (TV_MACH_DEP);
  5590. +
  5591. + ggc_collect ();
  5592. +#endif
  5593. +
  5594. /* Shorten branches. */
  5595. timevar_push (TV_SHORTEN_BRANCH);
  5596. shorten_branches (get_insns ());
  5597. diff -burN orig.gcc-3.2.3/include/obstack.h gcc-3.2.3/include/obstack.h
  5598. --- orig.gcc-3.2.3/include/obstack.h 2001-03-14 15:44:38.000000000 -0400
  5599. +++ gcc-3.2.3/include/obstack.h 2007-07-26 13:04:40.000000000 -0300
  5600. @@ -423,7 +423,8 @@
  5601. ({ struct obstack *__o = (OBSTACK); \
  5602. if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
  5603. _obstack_newchunk (__o, sizeof (void *)); \
  5604. - *((void **)__o->next_free)++ = ((void *)datum); \
  5605. + *((void **)__o->next_free) = ((void *)datum); \
  5606. + __o->next_free += sizeof(void *); \
  5607. (void) 0; })
  5608.  
  5609. # define obstack_int_grow(OBSTACK,datum) \
  5610. diff -burN orig.gcc-3.2.3/libstdc++-v3/configure.target gcc-3.2.3/libstdc++-v3/configure.target
  5611. --- orig.gcc-3.2.3/libstdc++-v3/configure.target 2002-09-06 15:32:08.000000000 -0300
  5612. +++ gcc-3.2.3/libstdc++-v3/configure.target 2007-07-26 13:04:40.000000000 -0300
  5613. @@ -55,6 +55,9 @@
  5614. m68k | m680[246]0)
  5615. cpu_include_dir="config/cpu/m68k"
  5616. ;;
  5617. + mips)
  5618. + cpu_include_dir="config/cpu/mips"
  5619. + ;;
  5620. powerpc | rs6000)
  5621. cpu_include_dir="config/cpu/powerpc"
  5622. ;;
  5623. diff -burN orig.gcc-3.2.3/libstdc++-v3/libsupc++/pure.cc gcc-3.2.3/libstdc++-v3/libsupc++/pure.cc
  5624. --- orig.gcc-3.2.3/libstdc++-v3/libsupc++/pure.cc 2002-06-28 05:22:38.000000000 -0300
  5625. +++ gcc-3.2.3/libstdc++-v3/libsupc++/pure.cc 2007-07-26 13:04:40.000000000 -0300
  5626. @@ -46,6 +46,6 @@
  5627. extern "C" void
  5628. __cxa_pure_virtual (void)
  5629. {
  5630. - writestr ("pure virtual method called\n");
  5631. +// writestr ("pure virtual method called\n");
  5632. std::terminate ();
  5633. }
  5634. diff -burN orig.gcc-3.2.3/README.PS2 gcc-3.2.3/README.PS2
  5635. --- orig.gcc-3.2.3/README.PS2 1969-12-31 20:00:00.000000000 -0400
  5636. +++ gcc-3.2.3/README.PS2 2007-07-26 13:04:40.000000000 -0300
  5637. @@ -0,0 +1,80 @@
  5638. +Apologies to mrbrown, who's README.PS2 this was based on.
  5639. +GCC for Sony Playstation 2
  5640. +http://www.ps2dev.org/
  5641. +BETA 3 Release 3.2.3-20040214-1
  5642. +==
  5643. +
  5644. +This patch contains a port of the GNU Compiler Collection (http://gcc.gnu.org)
  5645. +version 3.2.3 (prerelease) to the Sony Playstation 2. It supports a C and C++
  5646. +cross-compiler targeting the Emotion Engine (Toshiba MIPS R5900). It is based
  5647. +off of the port that Cygnus (now Red Hat) created for the original PS2 SDK,
  5648. +and contains a number of changes and updates that mrbrown has incorporated,
  5649. +plus some fixes by me.
  5650. +
  5651. +Unfortunately, there is no ChangeLog in this release.
  5652. +
  5653. +The Playstation 2 Linux kit is NOT supported in this release. There are a
  5654. +number of issues related to the deployment of this version of GCC in that
  5655. +environment. This is left as an exercise for the ps2linux folks.
  5656. +
  5657. +You can grab the source to the GCC 3.2.3 release from
  5658. +ftp://ftp.gnu.org/pub/gnu/gcc/gcc-3.2.3.tar.gz or a mirror site.
  5659. +
  5660. +
  5661. +Features
  5662. +--
  5663. +
  5664. +- Basic support for the R5900 and COP1.
  5665. +- Initial support for 128-bit logical/arith operations (pand, pnor, etc.).
  5666. +- Initial support for MMI built-in functions (__builtin_paddb, etc.) and vector
  5667. + types.
  5668. +- The main "feature" of this release is the port to the 3.2.3 compiler and fixes
  5669. + to the HILO1 code, allowing re-enabling of double precision emulation and also
  5670. + C++ global constructor fixes. This release may fix the 64bit shift bug, but
  5671. + if that's the case then it's a side effect of another fix.
  5672. +- Used in conjunction with my binutils-2.13.2.1 patch, you should be able to use
  5673. + -O0 and -O1 without causing bad code generation.
  5674. +- Alignment in bss sections bug fix.
  5675. +
  5676. +To configure the compiler, you can use one of the following configuration
  5677. +names:
  5678. +
  5679. + ee, mips64r5900[el], mipsEE[el]
  5680. +
  5681. +If you don't specify the OS portion of the name, -elf is assumed. Note that
  5682. +even if you leave off the "el", you cannot build for big-endian R5900 (it's
  5683. +explicitly disabled). I always use "ee".
  5684. +
  5685. +
  5686. +Known Bugs
  5687. +--
  5688. +
  5689. +[ I haven't found any serious codegen bugs yet. Mail to the ps2dev forums if
  5690. + you find any. ]
  5691. +
  5692. + If you wish to disable double precision emulation, comment out the text around
  5693. + DPBIT (and the make target that follows it) in gcc/config/mips/t-r5900. If you
  5694. + comment this section out and use double precision FP in your code, you WILL
  5695. + receive link errors when linking with libgcc. You can use this "feature" as a
  5696. + tool to find all misuses of float constants and type conversions in your code.
  5697. + Personally, I had trouble getting libstdc++-v3 to build without double precision
  5698. + emulation but YMMV. It should be possible to configure the compiler and libs
  5699. + to use single precision doubles in place of doubles, however you'd have to make
  5700. + sure that all your libs are built in this manner.
  5701. +
  5702. +
  5703. +Future Work
  5704. +--
  5705. +
  5706. + Move over to gcc 3.4, once it's released. gcc 3.4 includes a re-write of the
  5707. + entire mips back end and it looks a lot cleaner.
  5708. +
  5709. +
  5710. +Contact
  5711. +--
  5712. +
  5713. + Use the forums at www.ps2dev.org or find me on IRC at #ps2dev on EFnet.
  5714. +
  5715. +--
  5716. +MrHTFord (mrhtford_ps2dev@hotmail.com)
  5717. +Friday 14th February 2004.
Add Comment
Please, Sign In to add comment