diff gcc/config/mep/mep-tramp.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/config/mep/mep-tramp.c	Fri Feb 12 23:39:51 2010 +0900
@@ -0,0 +1,103 @@
+/* Trampoline support for MeP
+   Copyright (C) 2004, 2007 Free Software Foundation, Inc.
+   Contributed by Red Hat Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+  
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+  
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+/*
+  7a0a		ldc $10,$pc
+  c0ae000a	lw $0,10($10)
+  caae000e	lw $10,14($10)
+  10ae		jmp $10
+  00000000	static chain
+  00000000	function address
+*/
+
+static inline int
+cache_config_register(void) {
+  int rv;
+  asm ("ldc\t%0, $ccfg" : "=r" (rv));
+  return rv;
+}
+
+#define ICACHE_SIZE ((cache_config_register() >> 16) & 0x7f)
+#define DCACHE_SIZE (cache_config_register() & 0x7f)
+
+#define ICACHE_DATA_BASE 0x00300000
+#define ICACHE_TAG_BASE  0x00310000
+#define DCACHE_DATA_BASE 0x00320000
+#define DCACHE_TAG_BASE  0x00330000
+
+static inline void
+flush_dcache (int addr)
+{
+  asm volatile ("cache\t0, (%0)" : : "r" (addr));
+}
+
+void
+__mep_trampoline_helper (unsigned long *tramp,
+			 int function_address,
+			 int static_chain);
+
+void
+__mep_trampoline_helper (unsigned long *tramp,
+			 int function_address,
+			 int static_chain)
+{
+  int dsize, isize;
+
+#ifdef __LITTLE_ENDIAN__
+  tramp[0] = 0xc0ae7a0a;
+  tramp[1] = 0xcaae000a;
+  tramp[2] = 0x10ae000e;
+#else
+  tramp[0] = 0x7a0ac0ae;
+  tramp[1] = 0x000acaae;
+  tramp[2] = 0x000e10ae;
+#endif
+  tramp[3] = static_chain;
+  tramp[4] = function_address;
+
+  dsize = DCACHE_SIZE;
+  isize = ICACHE_SIZE;
+
+  if (dsize)
+    {
+      flush_dcache ((int)tramp);
+      flush_dcache ((int)tramp+16);
+    }
+
+  if (isize)
+    {
+      int imask = (isize * 1024) - 1;
+      int tmask = ~imask;
+      unsigned int i;
+      volatile unsigned int *tags;
+
+      imask &= 0xffe0;
+
+      for (i=(unsigned int)tramp; i<(unsigned int)tramp+20; i+=16)
+	{
+	  tags = (unsigned int *)(ICACHE_TAG_BASE + (i & imask));
+	  if ((*tags & tmask) == (i & tmask))
+	    *tags &= ~1;
+	}
+    }
+}