[M68k] Add `TRAP`, `TRAPV`, `BKPT`, `ILLEGAL` instructions
authorIan Douglas Scott <ian@iandouglasscott.com>
Tue, 4 Apr 2023 23:32:14 +0000 (16:32 -0700)
committerMin-Yih Hsu <minyihh@uci.edu>
Tue, 4 Apr 2023 23:45:14 +0000 (16:45 -0700)
This makes it possible to use TRAP to make Linux system calls using
inline assembly for instance.

Differential Revision: https://reviews.llvm.org/D147102

llvm/lib/Target/M68k/AsmParser/M68kAsmParser.cpp
llvm/lib/Target/M68k/M68kInstrControl.td
llvm/test/MC/Disassembler/M68k/trap-break.txt [new file with mode: 0644]
llvm/test/MC/M68k/Control/trap-break.s [new file with mode: 0644]

index 80af08e..59fa782 100644 (file)
@@ -177,6 +177,11 @@ public:
   static std::unique_ptr<M68kOperand> createImm(const MCExpr *Expr, SMLoc Start,
                                                 SMLoc End);
 
+  // Imm for TRAP instruction
+  bool isTrapImm() const;
+  // Imm for BKPT instruction
+  bool isBkptImm() const;
+
   // MoveMask
   bool isMoveMask() const;
   void addMoveMaskOperands(MCInst &Inst, unsigned N) const;
@@ -351,6 +356,22 @@ std::unique_ptr<M68kOperand> M68kOperand::createImm(const MCExpr *Expr,
   return Op;
 }
 
+bool M68kOperand::isTrapImm() const {
+  int64_t Value;
+  if (!isImm() || !Expr->evaluateAsAbsolute(Value))
+    return false;
+
+  return isUInt<4>(Value);
+}
+
+bool M68kOperand::isBkptImm() const {
+  int64_t Value;
+  if (!isImm() || !Expr->evaluateAsAbsolute(Value))
+    return false;
+
+  return isUInt<3>(Value);
+}
+
 // MoveMask
 bool M68kOperand::isMoveMask() const {
   if (!isMemOp())
index 060e0af..2bdbb82 100644 (file)
@@ -351,3 +351,41 @@ def : Pat<(sub MxDRD8:$op, (i8 (MxSetCC_C MxCONDcs, CCR))),
           (ADDX8dd MxDRD8:$op, (MOV8di 0))>;
 def : Pat<(sub MxXRD32:$op, (i32 (MxSetCC_C MxCONDcs, CCR))),
           (ADDX32dd MxDRD32:$op, (MOV32ri 0))>;
+
+//===------------===//
+// Trap / Breakpoint
+//===------------===//
+
+let RenderMethod = "addImmOperands", ParserMethod = "parseImm" in {
+  def MxTrapImm : AsmOperandClass {
+    let Name = "MxTrapImm";
+    let PredicateMethod = "isTrapImm";
+  }
+
+  def MxBkptImm : AsmOperandClass {
+    let Name = "MxBkptImm";
+    let PredicateMethod = "isBkptImm";
+  }
+}
+
+let ParserMatchClass = MxTrapImm in
+def MxTrapimm : MxOp<i8,  MxSize8,  "i">;
+
+let ParserMatchClass = MxBkptImm in
+def MxBkptimm : MxOp<i8,  MxSize8,  "i">;
+
+def TRAP : MxInst<(outs), (ins MxTrapimm:$vect), "trap\t$vect", []> {
+  let Inst = (descend 0b0100, 0b1110, 0b0100, (operand "$vect", 4));
+}
+
+def TRAPV : MxInst<(outs), (ins), "trapv", []> {
+  let Inst = (descend 0b0100, 0b1110, 0b0111, 0b0110);
+}
+
+def BKPT : MxInst<(outs), (ins MxBkptimm:$vect), "bkpt\t$vect", []> {
+  let Inst = (descend 0b0100, 0b1000, 0b0100, 0b1 , (operand "$vect", 3));
+}
+
+def ILLEGAL : MxInst<(outs), (ins), "illegal", []> {
+  let Inst = (descend 0b0100, 0b1010, 0b1111, 0b1100);
+}
diff --git a/llvm/test/MC/Disassembler/M68k/trap-break.txt b/llvm/test/MC/Disassembler/M68k/trap-break.txt
new file mode 100644 (file)
index 0000000..f767b15
--- /dev/null
@@ -0,0 +1,11 @@
+# RUN: llvm-mc -disassemble -triple m68k %s | FileCheck %s
+
+; CHECK: trap #13
+0x4e 0x4d
+# CHECK: bkpt #7
+0x48 0x4f
+# CHECK: trapv
+0x4e 0x76
+# CHECK: illegal
+0x4a 0xfc
+
diff --git a/llvm/test/MC/M68k/Control/trap-break.s b/llvm/test/MC/M68k/Control/trap-break.s
new file mode 100644 (file)
index 0000000..8a98bb1
--- /dev/null
@@ -0,0 +1,14 @@
+; RUN: llvm-mc -triple=m68k -show-encoding %s | FileCheck %s
+
+; CHECK:      trap #13
+; CHECK-SAME: encoding: [0x4e,0x4d]
+trap   #13
+; CHECK:      bkpt #7
+; CHECK-SAME: encoding: [0x48,0x4f]
+bkpt   #7
+; CHECK:      trapv
+; CHECK-SAME: encoding: [0x4e,0x76]
+trapv
+; CHECK:      illegal
+; CHECK-SAME: encoding: [0x4a,0xfc]
+illegal