alvinhochun updated this revision to Diff 519869.
alvinhochun edited the summary of this revision.
alvinhochun added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Rebase and add test cases with `offset` operator, and some TODOs/FIXMEs for 
comment


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149579/new/

https://reviews.llvm.org/D149579

Files:
  clang/test/CodeGen/ms-inline-asm-functions.c
  llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
  llvm/test/MC/X86/intel-syntax-branch-fail.s
  llvm/test/MC/X86/intel-syntax-branch.s

Index: llvm/test/MC/X86/intel-syntax-branch.s
===================================================================
--- /dev/null
+++ llvm/test/MC/X86/intel-syntax-branch.s
@@ -0,0 +1,69 @@
+// RUN: llvm-mc -triple i686-unknown-unknown -x86-asm-syntax=intel %s | FileCheck %s --check-prefixes=CHECK-32,CHECK
+// RUN: llvm-mc -triple x86_64-unknown-unknown --defsym X64=1 -x86-asm-syntax=intel %s | FileCheck %s --check-prefixes=CHECK-64,CHECK
+
+t0:
+call direct_branch
+jmp direct_branch
+// CHECK-LABEL: t0:
+// CHECK-64: callq direct_branch
+// CHECK-32: calll direct_branch
+// CHECK:    jmp direct_branch
+
+t1:
+call [fn_ref]
+jmp [fn_ref]
+// CHECK-LABEL: t1:
+// CHECK-64: callq *fn_ref
+// CHECK-64: jmpq *fn_ref
+// CHECK-32: calll *fn_ref
+// CHECK-32: jmpl *fn_ref
+
+.ifdef X64
+
+  t2:
+  call qword ptr [fn_ref]
+  jmp qword ptr [fn_ref]
+  // CHECK-64-LABEL: t2:
+  // CHECK-64: callq *fn_ref
+  // CHECK-64: jmpq *fn_ref
+
+  t3:
+  call qword ptr [rip + fn_ref]
+  jmp qword ptr [rip + fn_ref]
+  // CHECK-64-LABEL: t3:
+  // CHECK-64: callq *fn_ref(%rip)
+  // CHECK-64: jmpq *fn_ref(%rip)
+
+.else
+
+  t4:
+  call dword ptr [fn_ref]
+  jmp dword ptr [fn_ref]
+  // CHECK-32-LABEL: t4:
+  // CHECK-32: calll *fn_ref
+  // CHECK-32: jmpl *fn_ref
+
+  t5:
+  call dword ptr fn_ref
+  jmp dword ptr fn_ref
+  // CHECK-32-LABEL: t5:
+  // CHECK-32: calll *fn_ref
+  // CHECK-32: jmpl *fn_ref
+
+  t6:
+  call dword ptr [offset fn_ref]
+  jmp dword ptr [offset fn_ref]
+  // CHECK-32-LABEL: t6:
+  // CHECK-32: calll *fn_ref
+  // CHECK-32: jmpl *fn_ref
+
+  t7:
+  // FIXME: MASM does not accept this syntax and GAS assembles this as a direct
+  //        call/jump instead of indirect. Consider making this syntax an error?
+  call [offset fn_ref]
+  jmp [offset fn_ref]
+  // CHECK-32-LABEL: t7:
+  // CHECK-32: calll *fn_ref
+  // CHECK-32: jmpl *fn_ref
+
+.endif
Index: llvm/test/MC/X86/intel-syntax-branch-fail.s
===================================================================
--- /dev/null
+++ llvm/test/MC/X86/intel-syntax-branch-fail.s
@@ -0,0 +1,12 @@
+// RUN: not llvm-mc -triple i686-unknown-unknown -x86-asm-syntax=intel %s 2>&1 | FileCheck %s
+
+// TODO: Consider making this syntax an error?
+// call [offset fn_ref]
+// // TODO-CHECK: {{.*}}intel-syntax-branch-fail.s:[[#@LINE+-1]]:1: error: `OFFSET` operator cannot be used in an unconditional branch
+// jmp [offset fn_ref]
+// // TODO-CHECK: {{.*}}intel-syntax-branch-fail.s:[[#@LINE+-1]]:1: error: `OFFSET` operator cannot be used in an unconditional branch
+
+call offset fn_ref
+// CHECK: {{.*}}intel-syntax-branch-fail.s:[[#@LINE+-1]]:1: error: invalid operand for instruction
+jmp offset fn_ref
+// CHECK: {{.*}}intel-syntax-branch-fail.s:[[#@LINE+-1]]:1: error: invalid operand for instruction
Index: llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
===================================================================
--- llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -432,6 +432,7 @@
     InlineAsmIdentifierInfo Info;
     short BracCount = 0;
     bool MemExpr = false;
+    bool BracketUsed = false;
     bool OffsetOperator = false;
     bool AttachToOperandIdx = false;
     bool IsPIC = false;
@@ -454,6 +455,7 @@
     void addImm(int64_t imm) { Imm += imm; }
     short getBracCount() const { return BracCount; }
     bool isMemExpr() const { return MemExpr; }
+    bool isBracketUsed() const { return BracketUsed; }
     bool isOffsetOperator() const { return OffsetOperator; }
     SMLoc getOffsetLoc() const { return OffsetOperatorLoc; }
     unsigned getBaseReg() const { return BaseReg; }
@@ -954,6 +956,7 @@
         break;
       }
       MemExpr = true;
+      BracketUsed = true;
       BracCount++;
       return false;
     }
@@ -2630,9 +2633,9 @@
   unsigned DefaultBaseReg = X86::NoRegister;
   bool MaybeDirectBranchDest = true;
 
+  bool IsUnconditionalBranch =
+      Name.equals_insensitive("jmp") || Name.equals_insensitive("call");
   if (Parser.isParsingMasm()) {
-    bool IsUnconditionalBranch =
-        Name.equals_insensitive("jmp") || Name.equals_insensitive("call");
     if (is64BitMode() && SM.getElementSize() > 0) {
       DefaultBaseReg = X86::RIP;
     }
@@ -2654,6 +2657,14 @@
         }
       }
     }
+  } else if (IsUnconditionalBranch) {
+    // TODO: Consider making the `call [offset fn_ref]` syntax an error?
+#if 0
+    if (!PtrInOperand && SM.isOffsetOperator())
+      return Error(Start, "`OFFSET` operator cannot be used in an unconditional branch");
+#endif
+    if (PtrInOperand || SM.isBracketUsed())
+      MaybeDirectBranchDest = false;
   }
 
   if ((BaseReg || IndexReg || RegNo || DefaultBaseReg != X86::NoRegister))
Index: clang/test/CodeGen/ms-inline-asm-functions.c
===================================================================
--- clang/test/CodeGen/ms-inline-asm-functions.c
+++ clang/test/CodeGen/ms-inline-asm-functions.c
@@ -24,10 +24,9 @@
   __asm call kimport;
   // CHECK:     calll   *({{.*}})
 
-  // Broken case: Call through a global function pointer.
+  // Call through a global function pointer.
   __asm call kptr;
-  // CHECK:     calll   _kptr
-  // CHECK-FIXME: calll   *_kptr
+  // CHECK:     calll   *_kptr
 }
 
 int bar(void) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to