diff -Naur /root/cell/source/spu/gcc/gcc/c-decl.c ./gcc/c-decl.c
--- /root/cell/source/spu/gcc/gcc/c-decl.c	2007-11-26 19:24:26.000000000 +0100
+++ ./gcc/c-decl.c	2008-02-06 19:34:43.000000000 +0100
@@ -6139,6 +6139,9 @@
 	pedwarn ("%q+D is normally a non-static function", decl1);
     }
 
+  DECL_SPECIFIC_TARGET (decl1) = current_target;
+  DECL_PROCESS_NAME (decl1) = current_process_name;
+
   /* Record the decl so that the function name is defined.
      If we already have a decl for this name, and it is a FUNCTION_DECL,
      use the old decl.  */
diff -Naur /root/cell/source/spu/gcc/gcc/common.opt ./gcc/common.opt
--- /root/cell/source/spu/gcc/gcc/common.opt	2007-07-30 03:39:43.000000000 +0200
+++ ./gcc/common.opt	2008-02-06 18:25:30.000000000 +0100
@@ -367,6 +367,14 @@
 Common Joined RejectNegative
 -fdiagnostics-show-location=[once|every-line]	How often to emit source location at the beginning of line-wrapped diagnostics
 
+ftarget=
+Common Joined Var(target_isa_name)
+Filter code to this target architecture
+
+fprocess-name=
+Common Joined Var(target_process_name)
+Compiles SPU application pragmatized with specified name
+
 fdiagnostics-show-option
 Common
 Amend appropriate diagnostic messages with the command line option that controls them
diff -Naur /root/cell/source/spu/gcc/gcc/c-pragma.c ./gcc/c-pragma.c
--- /root/cell/source/spu/gcc/gcc/c-pragma.c	2006-07-13 02:16:16.000000000 +0200
+++ ./gcc/c-pragma.c	2008-02-06 18:26:39.000000000 +0100
@@ -42,6 +42,9 @@
 #define GCC_BAD2(gmsgid, arg) \
   do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0)
 
+tree current_target = NULL_TREE;
+tree current_process_name = NULL_TREE;
+
 typedef struct align_stack GTY(())
 {
   int                  alignment;
@@ -494,6 +497,31 @@
 	     "#pragma extern_prefix not supported on this target");
 }
 
+/* #pragma target */
+static void
+handle_pragma_target (cpp_reader * ARG_UNUSED (dummy))
+{
+  tree target;
+  tree exec_name;
+
+  if (c_lex (&target) == CPP_NAME)
+  {
+    current_target = target;
+
+    if(!strcmp(IDENTIFIER_POINTER(target), "spu")
+       && c_lex(&exec_name) == CPP_STRING)
+    {
+      current_process_name = exec_name;
+    }
+  }
+  else
+  {
+    current_target = NULL_TREE;
+    current_process_name = NULL_TREE;
+  }
+
+}
+
 /* Hook from the front ends to apply the results of one of the preceding
    pragmas that rename variables.  */
 
@@ -706,6 +734,8 @@
 
   c_register_pragma ("GCC", "pch_preprocess", c_common_pch_pragma);
 
+  c_register_pragma (0, "target", handle_pragma_target);
+
 #ifdef REGISTER_TARGET_PRAGMAS
   REGISTER_TARGET_PRAGMAS ();
 #endif
diff -Naur /root/cell/source/spu/gcc/gcc/passes.c ./gcc/passes.c
--- /root/cell/source/spu/gcc/gcc/passes.c	2007-06-28 13:39:47.000000000 +0200
+++ ./gcc/passes.c	2008-02-06 18:58:43.000000000 +0100
@@ -104,6 +104,7 @@
 int dump_flags;
 bool in_gimple_form;
 
+unsigned int abort_function_compilation;
 
 /* This is called from various places for FUNCTION_DECL, VAR_DECL,
    and TYPE_DECL nodes.
@@ -251,7 +252,10 @@
 {
   /* Early return if there were errors.  We can run afoul of our
      consistency checks, and there's not really much point in fixing them.  */
-  return !(rtl_dump_and_exit || flag_syntax_only || errorcount || sorrycount);
+  //if(!abort_function_compilation)
+    return !(rtl_dump_and_exit || flag_syntax_only || errorcount || sorrycount);
+  //else
+  //  return false;
 }
 
 struct tree_opt_pass pass_rest_of_compilation =
@@ -274,7 +278,7 @@
 static bool
 gate_postreload (void)
 {
-  return reload_completed;
+  return reload_completed && !abort_function_compilation;
 }
 
 struct tree_opt_pass pass_postreload =
@@ -294,6 +298,79 @@
   0					/* letter */
 };
 
+static unsigned int
+target_filter (void)
+{
+  fprintf(stderr, "Entering target_filter for %s\n", IDENTIFIER_POINTER(DECL_NAME(cfun->decl)));
+
+  if(DECL_SPECIFIC_TARGET (cfun->decl) && DECL_SPECIFIC_TARGET (cfun->decl) != NULL_TREE
+	&& strcmp(IDENTIFIER_POINTER(DECL_SPECIFIC_TARGET(cfun->decl)), target_isa_name))
+  {
+    struct cgraph_node *node = cgraph_node (cfun->decl); 
+    tree decl = cfun->decl;
+
+    DECL_EXTERNAL (decl) = 1;
+    TREE_PUBLIC (decl) = 1;
+    DECL_ARTIFICIAL (decl) = 1;
+    TREE_NOTHROW (decl) = 1;
+
+    node->needed = 0;
+    node->reachable = 0;
+    node->output = 0;
+
+    abort_function_compilation = true;
+    fprintf(stderr, "Aborting compilation of function %s.\n", 
+        IDENTIFIER_POINTER (DECL_NAME (decl)));
+  }
+  else
+  {
+    /* fprintf(stderr, "Trying to change function name\n"); */
+    if(DECL_PROCESS_NAME (cfun->decl) != NULL_TREE && TREE_STRING_POINTER (DECL_PROCESS_NAME (cfun->decl)))
+    {
+      char tmp[256];
+
+      fprintf(stderr, "Contains process name %s\n", TREE_STRING_POINTER(DECL_PROCESS_NAME(cfun->decl)));
+      sprintf(tmp, "%s_main", TREE_STRING_POINTER (DECL_PROCESS_NAME (cfun->decl)));
+      if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun->decl)), tmp))
+      {
+        char *output_name = NULL;
+        fprintf (stderr, "Changing name to main.\n");
+      
+        /* Set function name to main. */
+        output_name = (char *) alloca (4 + 64);
+        strcpy (output_name, "main");
+      
+        DECL_NAME (cfun->decl) = get_identifier (output_name);
+      
+       /* Create a new SYMBOL_REF rtx for the new name. */
+        if (DECL_RTL (cfun->decl) != NULL)
+        {
+          XEXP (DECL_RTL (cfun->decl), 0) =
+            gen_rtx_SYMBOL_REF (GET_MODE (XEXP (DECL_RTL (cfun->decl), 0)),
+              IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
+				}
+      }
+    }
+  }
+  return 0;
+}
+
+struct tree_opt_pass pass_target_filter =
+{
+  "target_filter",                         /* name */
+  NULL,                                 /* gate */
+  target_filter,                           /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  0,                                    /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_dump_cgraph,                     /* todo_flags_finish */
+  0                                     /* letter */
+};
 
 
 /* The root of the compilation pass tree, once constructed.  */
@@ -644,6 +721,7 @@
   NEXT_PASS (pass_sched);
   NEXT_PASS (pass_local_alloc);
   NEXT_PASS (pass_global_alloc);
+	NEXT_PASS (pass_target_filter);
   NEXT_PASS (pass_postreload);
   *p = NULL;
 
@@ -860,6 +938,9 @@
       if (execute_one_pass (pass) && pass->sub)
         execute_pass_list (pass->sub);
       pass = pass->next;
+
+//      if(abort_function_compilation)
+//        break;
     }
   while (pass);
 }
diff -Naur /root/cell/source/spu/gcc/gcc/tree.h ./gcc/tree.h
--- /root/cell/source/spu/gcc/gcc/tree.h	2007-11-26 19:24:26.000000000 +0100
+++ ./gcc/tree.h	2008-02-06 18:59:40.000000000 +0100
@@ -2060,6 +2060,10 @@
    definition.  */
 #define DECL_ABSTRACT_ORIGIN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.abstract_origin)
 
+/* ISA to which code should be compiled. */
+#define DECL_SPECIFIC_TARGET(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.specific_target)
+#define DECL_PROCESS_NAME(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.process_name)
+
 /* Like DECL_ABSTRACT_ORIGIN, but returns NODE if there's no abstract
    origin.  This is useful when setting the DECL_ABSTRACT_ORIGIN.  */
 #define DECL_ORIGIN(NODE) \
@@ -2255,6 +2259,10 @@
   tree initial;
   tree attributes;
   tree abstract_origin;
+
+  /* Attributes to declarations specified by pragma target */
+  tree specific_target;
+  tree process_name; 
   
   HOST_WIDE_INT pointer_alias_set; 
   /* Points to a structure whose details depend on the language in use.  */
@@ -4199,6 +4207,9 @@
    restricted to creating gimple expressions.  */
 extern bool in_gimple_form;
 
+extern tree current_target;
+extern tree current_process_name;
+
 /* In tree-gimple.c.  */
 extern tree get_base_address (tree t);
 
diff -Naur /root/cell/source/spu/gcc/gcc/tree-optimize.c ./gcc/tree-optimize.c
--- /root/cell/source/spu/gcc/gcc/tree-optimize.c	2006-07-14 04:57:54.000000000 +0200
+++ ./gcc/tree-optimize.c	2007-12-12 19:10:17.000000000 +0100
@@ -416,6 +416,7 @@
   
   tree_register_cfg_hooks ();
   /* Perform all tree transforms and optimizations.  */
+  abort_function_compilation = false;
   execute_pass_list (all_passes);
   
   bitmap_obstack_release (&reg_obstack);
diff -Naur /root/cell/source/spu/gcc/gcc/tree-pass.h ./gcc/tree-pass.h
--- /root/cell/source/spu/gcc/gcc/tree-pass.h	2007-04-05 23:40:53.000000000 +0200
+++ ./gcc/tree-pass.h	2008-02-06 19:00:17.000000000 +0100
@@ -383,4 +383,6 @@
 extern void execute_pass_list (struct tree_opt_pass *);
 extern void execute_ipa_pass_list (struct tree_opt_pass *);
 
+extern unsigned int abort_function_compilation;
+
 #endif /* GCC_TREE_PASS_H */
