Index: gcc/testsuite/gcc.target/arm/thumb-builtin-trap.c
===================================================================
--- gcc/testsuite/gcc.target/arm/thumb-builtin-trap.c	(revision 0)
+++ gcc/testsuite/gcc.target/arm/thumb-builtin-trap.c	(revision 0)
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-mthumb" }  */
+
+void trap ()
+{
+  __builtin_trap ();
+}
+
+/* { dg-final { scan-assembler "0xdeff" } } */
Index: gcc/testsuite/gcc.target/arm/builtin-trap.c
===================================================================
--- gcc/testsuite/gcc.target/arm/builtin-trap.c	(revision 0)
+++ gcc/testsuite/gcc.target/arm/builtin-trap.c	(revision 0)
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm32 } */
+
+void trap ()
+{
+  __builtin_trap ();
+}
+
+/* { dg-final { scan-assembler "0xe7ffffff" } } */
Index: gcc/config/arm/arm.md
===================================================================
--- gcc/config/arm/arm.md	(revision 163924)
+++ gcc/config/arm/arm.md	(working copy)
@@ -8496,6 +8496,26 @@
 		      (const_int 4)))]
 )
 
+;; Generate an invalid instruction.  The instructions chosen are
+;; documented as permanently UNDEFINED, so we can rely on the fact
+;; that no future version of the architecture will use them.  The
+;; instructions used are chosen so as to be distinct from he
+;; instructions that the Linux kernel interprets as software
+;; breakpoints.
+(define_insn "trap"
+  [(trap_if (const_int 1) (const_int 0))]
+  ""
+  "*
+  if (TARGET_ARM)
+    return \".inst\\t0xe7ffffff\";
+  else
+    return \".inst\\t0xdeff\";
+  "
+  [(set (attr "length")
+	(if_then_else (eq_attr "is_thumb" "yes")
+		      (const_int 2)
+		      (const_int 4)))]
+)
 
 ;; Patterns to allow combination of arithmetic, cond code and shifts
 
