aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/patches/patch-18-llvm-r214802-armv6-cp10-cp11.diff
blob: 17e1c75b711ad1f7eb513192aa02753f6c47166b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Pull in r214802 from upstream llvm trunk (by Renato Golin):

  Allow CP10/CP11 operations on ARMv5/v6

  Those registers are VFP/NEON and vector instructions should be used instead,
  but old cores rely on those co-processors to enable VFP unwinding. This change
  was prompted by the libc++abi's unwinding routine and is also present in many
  legacy low-level bare-metal code that we ought to compile/assemble.

  Fixing bug PR20025 and allowing PR20529 to proceed with a fix in libc++abi.

Pull in r214872 from upstream llvm trunk (by Renato Golin):

  Add tests for cp10/cp11 on ARMv5/6

  Tests for ARMv7/8 are already on diagnostics.s

This enables assembling certain ARM instructions used in libgcc.

Introduced here: http://svnweb.freebsd.org/changeset/base/275265

Index: lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -3118,9 +3118,10 @@ static int MatchCoprocessorOperandName(StringRef N
       return -1;
     switch (Name[1]) {
     default:  return -1;
-    // p10 and p11 are invalid for coproc instructions (reserved for FP/NEON)
-    case '0': return CoprocOp == 'p'? -1: 10;
-    case '1': return CoprocOp == 'p'? -1: 11;
+    // CP10 and CP11 are VFP/NEON and so vector instructions should be used.
+    // However, old cores (v5/v6) did use them in that way.
+    case '0': return 10;
+    case '1': return 11;
     case '2': return 12;
     case '3': return 13;
     case '4': return 14;
@@ -3177,6 +3178,9 @@ ARMAsmParser::parseCoprocNumOperand(OperandVector
   int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
   if (Num == -1)
     return MatchOperand_NoMatch;
+  // ARMv7 and v8 don't allow cp10/cp11 due to VFP/NEON specific instructions
+  if ((hasV7Ops() || hasV8Ops()) && (Num == 10 || Num == 11))
+    return MatchOperand_NoMatch;
 
   Parser.Lex(); // Eat identifier token.
   Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
Index: test/MC/ARM/coproc-diag.s
===================================================================
--- test/MC/ARM/coproc-diag.s
+++ test/MC/ARM/coproc-diag.s
@@ -0,0 +1,10 @@
+# Special test to make sure we don't error on VFP co-proc access
+@ RUN: llvm-mc -triple=armv5 < %s | FileCheck %s
+@ RUN: llvm-mc -triple=armv6 < %s | FileCheck %s
+
+        @ p10 and p11 are reserved for NEON, but accessible on v5/v6
+        ldc  p10, cr0, [r0], {0x20}
+        ldc2 p11, cr0, [r0], {0x21}
+        ldcl p11, cr0, [r0], {0x20}
+
+@ CHECK-NOT: error: invalid operand for instruction