Programmatically cause Undefined Instruction exception

arm, cortex-m, gcc, inline-assembly

Solution

Some extra info...

One of GCC's builtins is

void __builtin_trap (void)

This function causes the program to exit abnormally. GCC implements this function by using a target-dependent mechanism (such as intentionally executing an illegal instruction) or by calling abort. The mechanism used may vary from release to release so you should not rely on any particular implementation.

Its implementation for ARMv7 is:

(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")
   (set_attr "conds" "unconditional")]
)

So for ARM mode gcc will generate `0x7f000f0 (f0 00 f0 07)`and for other modes `0xdeff (ff de)` (comes handy when disassembling / debugging).

Also note that:

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)

For LLVM `__builtin_trap` values generated are `0xe7ffdefe` and `0xdefe`:

case ARM::TRAP: {
  // Non-Darwin binutils don't yet support the "trap" mnemonic.
  // FIXME: Remove this special case when they do.
  if (!Subtarget->isTargetDarwin()) {
    //.long 0xe7ffdefe @ trap
    uint32_t Val = 0xe7ffdefeUL;
    OutStreamer.AddComment("trap");
    OutStreamer.EmitIntValue(Val, 4);
    return;
  }
  break;
}
case ARM::tTRAP: {
  // Non-Darwin binutils don't yet support the "trap" mnemonic.
  // FIXME: Remove this special case when they do.
  if (!Subtarget->isTargetDarwin()) {
    //.short 57086 @ trap
    uint16_t Val = 0xdefe;
    OutStreamer.AddComment("trap");
    OutStreamer.EmitIntValue(Val, 2);
    return;
  }
  break;
}

Problem

I want to cause an ARM Cortex-M3 Undefined Instruction exception for the test of my test fixture. The IAR compiler supports this with inline assembly like this: ``` asm("udf.w #0"); ``` Unfortunately the GNU CC inline assembler does not know this opcode for the NXP LPC177x8x. It writes the diagnostic: ``` ccw3kZ46.s:404: Error: bad instruction `udf.w #0' ``` How can I create a function that causes a Undefined Instruction exception?

Original source