diff mbox

[ARM] Implement __builtin_trap

Message ID 000001cef10a$a35819b0$ea084d10$@bolton@arm.com
State New
Headers show

Commit Message

Ian Bolton Dec. 4, 2013, 4:05 p.m. UTC
Hi,

Currently, on ARM, you have to either call abort() or raise(SIGTRAP)
to achieve a handy crash.

This patch allows you to instead call __builtin_trap() which is much
more efficient at falling over because it becomes just a single
instruction that will trap for you.

Two testcases have been added (for ARM and Thumb) and both pass.


Note: This is a modified version of a patch originally submitted by Mark
Mitchell back in 2010, which came in response to PR target/59091.

http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00639.html
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59091

The main update, other than cosmetic differences, is that we've chosen
the same ARM encoding as LLVM for practical purposes.  (The Thumb
encoding in Mark's patch already matched LLVM.)


OK for trunk?

Cheers,
Ian


2013-12-04  Ian Bolton  <ian.bolton@arm.com>
            Mark Mitchell  <mark@codesourcery.com>

gcc/
	* config/arm/arm.md (trap): New pattern.
	* config/arm/types.md: Added a type for trap.

testsuite/
	* gcc.target/arm/builtin-trap.c: New test.
	* gcc.target/arm/thumb-builtin-trap.c: Likewise.

Comments

Joseph Myers Dec. 4, 2013, 5:14 p.m. UTC | #1
On Wed, 4 Dec 2013, Ian Bolton wrote:

> The main update, other than cosmetic differences, is that we've chosen
> the same ARM encoding as LLVM for practical purposes.  (The Thumb
> encoding in Mark's patch already matched LLVM.)

Do the encodings match what plain "udf" does in recent-enough gas (too 
recent for us to assume it in GCC or glibc for now), or is it something 
else?
Ian Bolton Dec. 4, 2013, 6:07 p.m. UTC | #2
> On Wed, 4 Dec 2013, Ian Bolton wrote:
> 
> > The main update, other than cosmetic differences, is that we've
> chosen
> > the same ARM encoding as LLVM for practical purposes.  (The Thumb
> > encoding in Mark's patch already matched LLVM.)
> 
> Do the encodings match what plain "udf" does in recent-enough gas (too
> recent for us to assume it in GCC or glibc for now), or is it something
> else?

Hi Joseph,

Yes, these encodings match the UDF instruction that is defined in the most
recent edition of the ARM architecture reference manual.

Thumb: 0xde00 | imm8  (we chose 0xff for the imm8)
ARM: 0xe7f000f0 | (imm12 << 8) | imm4  (we chose to use 0 for both imms)

So as not to break old versions of gas that don't recognise UDF, the
encoding is output directly.

Apologies if I have over-explained there!

Cheers,
Ian
Ramana Radhakrishnan Dec. 4, 2013, 6:09 p.m. UTC | #3
On 04/12/13 16:05, Ian Bolton wrote:
> Hi,
>
> Currently, on ARM, you have to either call abort() or raise(SIGTRAP)
> to achieve a handy crash.
>
> This patch allows you to instead call __builtin_trap() which is much
> more efficient at falling over because it becomes just a single
> instruction that will trap for you.
>
> Two testcases have been added (for ARM and Thumb) and both pass.
>
>
> Note: This is a modified version of a patch originally submitted by Mark
> Mitchell back in 2010, which came in response to PR target/59091.

The PR came as a result of the A64 implementation of __builtin_trap. The 
original patch was much earlier than that :)

>
> http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00639.html
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59091
>
> The main update, other than cosmetic differences, is that we've chosen
> the same ARM encoding as LLVM for practical purposes.  (The Thumb
> encoding in Mark's patch already matched LLVM.)
>
>
> OK for trunk?

This is OK for trunk. Please put the PR numbers in the changelog entries 
before committing i.e. PR target/59091.

FTR, these match with the encodings for the udf mnemonic with an 
immediate value of 0 in ARM state and #0xff in Thumb state. Obviously we 
cannot put out the udf mnemonic out because an older gas will not 
support it. These immediates were chosen to match the values as in other 
compiler implementations (I know these match with LLVM as something I 
can point to externally) and have been double checked with folks who 
have an avid interest in the kernel world.

Thanks,
Ramana
Richard Earnshaw Dec. 5, 2013, 4:31 p.m. UTC | #4
On 4 Dec 2013, at 16:08, "Ian Bolton" <ian.bolton@arm.com> wrote:

> Hi,
> 
> Currently, on ARM, you have to either call abort() or raise(SIGTRAP)
> to achieve a handy crash.
> 
> This patch allows you to instead call __builtin_trap() which is much
> more efficient at falling over because it becomes just a single
> instruction that will trap for you.
> 
> Two testcases have been added (for ARM and Thumb) and both pass.
> 
> 
> Note: This is a modified version of a patch originally submitted by Mark
> Mitchell back in 2010, which came in response to PR target/59091.
> 
> http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00639.html
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59091
> 
> The main update, other than cosmetic differences, is that we've chosen
> the same ARM encoding as LLVM for practical purposes.  (The Thumb
> encoding in Mark's patch already matched LLVM.)
> 
> 
> OK for trunk?
> 
> Cheers,
> Ian
> 
> 
> 2013-12-04  Ian Bolton  <ian.bolton@arm.com>
>            Mark Mitchell  <mark@codesourcery.com>
> 
> gcc/
>    * config/arm/arm.md (trap): New pattern.
>    * config/arm/types.md: Added a type for trap.
> 
> testsuite/
>    * gcc.target/arm/builtin-trap.c: New test.
>    * gcc.target/arm/thumb-builtin-trap.c: Likewise.
> <aarch32-builtin-trap-v2.txt>

This needs to set the conds attribute to "unconditional".  Otherwise the ARM backend might try to turn this into a conditional instruction.

R.
diff mbox

Patch

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index dd73366..3b7a827 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -9927,6 +9927,22 @@ 
    (set_attr "type" "mov_reg")]
 )
 
+(define_insn "trap"
+  [(trap_if (const_int 1) (const_int 0))]
+  ""
+  "*
+  if (TARGET_ARM)
+    return \".inst\\t0xe7f000f0\";
+  else
+    return \".inst\\t0xdeff\";
+  "
+  [(set (attr "length")
+	(if_then_else (eq_attr "is_thumb" "yes")
+		      (const_int 2)
+		      (const_int 4)))
+   (set_attr "type" "trap")]
+)
+
 
 ;; Patterns to allow combination of arithmetic, cond code and shifts
 
diff --git a/gcc/config/arm/types.md b/gcc/config/arm/types.md
index 1c4b9e3..6351f08 100644
--- a/gcc/config/arm/types.md
+++ b/gcc/config/arm/types.md
@@ -152,6 +152,7 @@ 
 ; store2             store 2 words to memory from arm registers.
 ; store3             store 3 words to memory from arm registers.
 ; store4             store 4 (or more) words to memory from arm registers.
+; trap               cause a trap in the kernel.
 ; udiv               unsigned division.
 ; umaal              unsigned multiply accumulate accumulate long.
 ; umlal              unsigned multiply accumulate long.
@@ -645,6 +646,7 @@ 
   store2,\
   store3,\
   store4,\
+  trap,\
   udiv,\
   umaal,\
   umlal,\
diff --git a/gcc/testsuite/gcc.target/arm/builtin-trap.c b/gcc/testsuite/gcc.target/arm/builtin-trap.c
new file mode 100644
index 0000000..4ff8d25
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/builtin-trap.c
@@ -0,0 +1,10 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target arm32 } */
+
+void
+trap ()
+{
+  __builtin_trap ();
+}
+
+/* { dg-final { scan-assembler "0xe7f000f0" { target { arm_nothumb } } } } */
diff --git a/gcc/testsuite/gcc.target/arm/thumb-builtin-trap.c b/gcc/testsuite/gcc.target/arm/thumb-builtin-trap.c
new file mode 100644
index 0000000..22e90e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb-builtin-trap.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-mthumb" } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+
+void
+trap ()
+{
+  __builtin_trap ();
+}
+
+/* { dg-final { scan-assembler "0xdeff" } } */