Cleanup PPC Altivec registers in CSR lists and improve VRSAVE handling
authorHal Finkel <hfinkel@anl.gov>
Tue, 2 Jul 2013 03:39:34 +0000 (03:39 +0000)
committerHal Finkel <hfinkel@anl.gov>
Tue, 2 Jul 2013 03:39:34 +0000 (03:39 +0000)
There are a couple of (small) related changes here:

1. The printed name of the VRSAVE register has been changed from VRsave to
vrsave in order to match the name accepted by GNU binutils.

2. Support for parsing vrsave has been added to the asm parser (it seems that
there was no test case specifically covering this code, so I've added one).

3. The list of Altivec registers, which was common to all calling conventions,
has been separated out. This allows us to define the base CSR lists, and then
lists for each ABI with Altivec included. This allows SjLj, for example, to
work correctly on non-Altivec targets without using unnatural definitions of
the NoRegs CSR list.

4. VRSAVE is now always reserved on non-Darwin targets and all Altivec
registers are reserved when Altivec is disabled.

With these changes, it is now possible to compile a function containing
__builtin_unwind_init() on Linux/PPC64 with debugging information. This did not
work previously because GNU binutils assumes that all .cfi_offset offsets will
be 8-byte aligned on PPC64 (and errors out if you provide a non-8-byte-aligned
offset). This is not true for the vrsave register, however, because this
register is used only on Darwin, GCC does not bother printing a .cfi_offset
entry for it (even though there is a slot in the stack frame for it as
specified by the ABI). This change allows us to do the same: we will also not
print .cfi_offset directives for vrsave.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185409 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
lib/Target/PowerPC/PPCCallingConv.td
lib/Target/PowerPC/PPCRegisterInfo.cpp
lib/Target/PowerPC/PPCRegisterInfo.td
test/CodeGen/PowerPC/unwind-dw2-g.ll [new file with mode: 0644]
test/MC/PowerPC/ppc64-regs.s [new file with mode: 0644]

index cbe13217f75cd9075d106b827b71a474498019bc..7a654ea8289ec18eb1a9fb003881bda36fcf6637 100644 (file)
@@ -752,6 +752,10 @@ MatchRegisterName(const AsmToken &Tok, unsigned &RegNo, int64_t &IntVal) {
       RegNo = isPPC64()? PPC::CTR8 : PPC::CTR;
       IntVal = 9;
       return false;
+    } else if (Name.equals_lower("vrsave")) {
+      RegNo = PPC::VRSAVE;
+      IntVal = 256;
+      return false;
     } else if (Name.substr(0, 1).equals_lower("r") &&
                !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
       RegNo = isPPC64()? XRegs[IntVal] : RRegs[IntVal];
index c8a29a3d2cfe69efd2a244e6b4c9ecbfc0bd9923..a584188a1016c840840730e4596473a3e70a6aa1 100644 (file)
@@ -105,40 +105,45 @@ def CC_PPC32_SVR4_ByVal : CallingConv<[
   CCCustom<"CC_PPC32_SVR4_Custom_Dummy">
 ]>;
 
+def CSR_Altivec : CalleeSavedRegs<(add V20, V21, V22, V23, V24, V25, V26, V27,
+                                       V28, V29, V30, V31)>;
+
 def CSR_Darwin32 : CalleeSavedRegs<(add R13, R14, R15, R16, R17, R18, R19, R20,
                                         R21, R22, R23, R24, R25, R26, R27, R28,
                                         R29, R30, R31, F14, F15, F16, F17, F18,
                                         F19, F20, F21, F22, F23, F24, F25, F26,
-                                        F27, F28, F29, F30, F31, CR2, CR3, CR4,
-                                        V20, V21, V22, V23, V24, V25, V26, V27,
-                                        V28, V29, V30, V31)>;
+                                        F27, F28, F29, F30, F31, CR2, CR3, CR4
+                                   )>;
+
+def CSR_Darwin32_Altivec : CalleeSavedRegs<(add CSR_Darwin32, CSR_Altivec)>;
 
-def CSR_SVR432   : CalleeSavedRegs<(add R14, R15, R16, R17, R18, R19, R20, VRSAVE,
+def CSR_SVR432   : CalleeSavedRegs<(add R14, R15, R16, R17, R18, R19, R20,
                                         R21, R22, R23, R24, R25, R26, R27, R28,
                                         R29, R30, R31, F14, F15, F16, F17, F18,
                                         F19, F20, F21, F22, F23, F24, F25, F26,
-                                        F27, F28, F29, F30, F31, CR2, CR3, CR4,
-                                        V20, V21, V22, V23, V24, V25, V26, V27,
-                                        V28, V29, V30, V31)>;
+                                        F27, F28, F29, F30, F31, CR2, CR3, CR4
+                                   )>;
+
+def CSR_SVR432_Altivec : CalleeSavedRegs<(add CSR_SVR432, CSR_Altivec)>;
 
 def CSR_Darwin64 : CalleeSavedRegs<(add X13, X14, X15, X16, X17, X18, X19, X20,
                                         X21, X22, X23, X24, X25, X26, X27, X28,
                                         X29, X30, X31, F14, F15, F16, F17, F18,
                                         F19, F20, F21, F22, F23, F24, F25, F26,
-                                        F27, F28, F29, F30, F31, CR2, CR3, CR4,
-                                        V20, V21, V22, V23, V24, V25, V26, V27,
-                                        V28, V29, V30, V31)>;
+                                        F27, F28, F29, F30, F31, CR2, CR3, CR4
+                                   )>;
 
-def CSR_SVR464   : CalleeSavedRegs<(add X14, X15, X16, X17, X18, X19, X20, VRSAVE,
+def CSR_Darwin64_Altivec : CalleeSavedRegs<(add CSR_Darwin64, CSR_Altivec)>;
+
+def CSR_SVR464   : CalleeSavedRegs<(add X14, X15, X16, X17, X18, X19, X20,
                                         X21, X22, X23, X24, X25, X26, X27, X28,
                                         X29, X30, X31, F14, F15, F16, F17, F18,
                                         F19, F20, F21, F22, F23, F24, F25, F26,
-                                        F27, F28, F29, F30, F31, CR2, CR3, CR4,
-                                        V20, V21, V22, V23, V24, V25, V26, V27,
-                                        V28, V29, V30, V31)>;
+                                        F27, F28, F29, F30, F31, CR2, CR3, CR4
+                                   )>;
+
 
-def CSR_NoRegs : CalleeSavedRegs<(add VRSAVE)>;
-def CSR_NoRegs_Darwin : CalleeSavedRegs<(add)>;
+def CSR_SVR464_Altivec : CalleeSavedRegs<(add CSR_SVR464, CSR_Altivec)>;
 
-def CSR_NoRegs_Altivec : CalleeSavedRegs<(add (sequence "V%u", 0, 31), VRSAVE)>;
+def CSR_NoRegs : CalleeSavedRegs<(add)>;
 
index 96b5bb69de7d861846c2c2128778e4690e323206..06788fe3b246abccdadb09bb22fa2401b2c2e44b 100644 (file)
@@ -91,32 +91,41 @@ PPCRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
 const uint16_t*
 PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
   if (Subtarget.isDarwinABI())
-    return Subtarget.isPPC64() ? CSR_Darwin64_SaveList :
-                                 CSR_Darwin32_SaveList;
-
-  return Subtarget.isPPC64() ? CSR_SVR464_SaveList : CSR_SVR432_SaveList;
+    return Subtarget.isPPC64() ? (Subtarget.hasAltivec() ?
+                                  CSR_Darwin64_Altivec_SaveList :
+                                  CSR_Darwin64_SaveList) :
+                                 (Subtarget.hasAltivec() ?
+                                  CSR_Darwin32_Altivec_SaveList :
+                                  CSR_Darwin32_SaveList);
+
+  return Subtarget.isPPC64() ? (Subtarget.hasAltivec() ?
+                                CSR_SVR464_Altivec_SaveList :
+                                CSR_SVR464_SaveList) :
+                               (Subtarget.hasAltivec() ?
+                                CSR_SVR432_Altivec_SaveList :
+                                CSR_SVR432_SaveList);
 }
 
 const uint32_t*
 PPCRegisterInfo::getCallPreservedMask(CallingConv::ID CC) const {
   if (Subtarget.isDarwinABI())
-    return Subtarget.isPPC64() ? CSR_Darwin64_RegMask :
-                                 CSR_Darwin32_RegMask;
-
-  return Subtarget.isPPC64() ? CSR_SVR464_RegMask : CSR_SVR432_RegMask;
+    return Subtarget.isPPC64() ? (Subtarget.hasAltivec() ?
+                                  CSR_Darwin64_Altivec_RegMask :
+                                  CSR_Darwin64_RegMask) :
+                                 (Subtarget.hasAltivec() ?
+                                  CSR_Darwin32_Altivec_RegMask :
+                                  CSR_Darwin32_RegMask);
+
+  return Subtarget.isPPC64() ? (Subtarget.hasAltivec() ?
+                                CSR_SVR464_Altivec_RegMask :
+                                CSR_SVR464_RegMask) :
+                               (Subtarget.hasAltivec() ?
+                                CSR_SVR432_Altivec_RegMask :
+                                CSR_SVR432_RegMask);
 }
 
 const uint32_t*
 PPCRegisterInfo::getNoPreservedMask() const {
-  // The naming here is inverted: The CSR_NoRegs_Altivec has the
-  // Altivec registers masked so that they're not saved and restored around
-  // instructions with this preserved mask.
-
-  if (!Subtarget.hasAltivec())
-    return CSR_NoRegs_Altivec_RegMask;
-
-  if (Subtarget.isDarwin())
-    return CSR_NoRegs_Darwin_RegMask;
   return CSR_NoRegs_RegMask;
 }
 
@@ -145,6 +154,9 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
   Reserved.set(PPC::LR8);
   Reserved.set(PPC::RM);
 
+  if (!Subtarget.isDarwinABI() || !Subtarget.hasAltivec())
+    Reserved.set(PPC::VRSAVE);
+
   // The SVR4 ABI reserves r2 and r13
   if (Subtarget.isSVR4ABI()) {
     Reserved.set(PPC::R2);  // System-reserved register
@@ -170,6 +182,12 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
   if (PPCFI->needsFP(MF))
     Reserved.set(PPC::R31);
 
+  // Reserve Altivec registers when Altivec is unavailable.
+  if (!Subtarget.hasAltivec())
+    for (TargetRegisterClass::iterator I = PPC::VRRCRegClass.begin(),
+         IE = PPC::VRRCRegClass.end(); I != IE; ++I)
+      Reserved.set(*I);
+
   return Reserved;
 }
 
index b1b4f06394437f0f5737d5b5fd0448d0eff62868..003e7c3562b32184ec9e31734b00f098d1123081 100644 (file)
@@ -150,7 +150,7 @@ def CTR  : SPR<9, "ctr">, DwarfRegNum<[-2, 66]>;
 def CTR8 : SPR<9, "ctr">, DwarfRegNum<[66, -2]>;
 
 // VRsave register
-def VRSAVE: SPR<256, "VRsave">, DwarfRegNum<[109]>;
+def VRSAVE: SPR<256, "vrsave">, DwarfRegNum<[109]>;
 
 // Carry bit.  In the architecture this is really bit 0 of the XER register
 // (which really is SPR register 1);  this is the only bit interesting to a
diff --git a/test/CodeGen/PowerPC/unwind-dw2-g.ll b/test/CodeGen/PowerPC/unwind-dw2-g.ll
new file mode 100644 (file)
index 0000000..2baac76
--- /dev/null
@@ -0,0 +1,34 @@
+; RUN: llc < %s | FileCheck %s
+target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+; Function Attrs: nounwind
+define void @foo() #0 {
+entry:
+  call void @llvm.eh.unwind.init(), !dbg !9
+  ret void, !dbg !10
+}
+
+; CHECK: @foo
+; CHECK-NOT: .cfi_offset vrsave
+; CHECK: blr
+
+; Function Attrs: nounwind
+declare void @llvm.eh.unwind.init() #0
+
+attributes #0 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!8}
+
+!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.4", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/tmp/unwind-dw2.c] [DW_LANG_C99]
+!1 = metadata !{metadata !"/tmp/unwind-dw2.c", metadata !"/tmp"}
+!2 = metadata !{i32 0}
+!3 = metadata !{metadata !4}
+!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"foo", metadata !"foo", metadata !"", i32 1, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, void ()* @foo, null, null, metadata !2, i32 1} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
+!5 = metadata !{i32 786473, metadata !1}          ; [ DW_TAG_file_type ] [/tmp/unwind-dw2.c]
+!6 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = metadata !{null}
+!8 = metadata !{i32 2, metadata !"Dwarf Version", i32 3}
+!9 = metadata !{i32 2, i32 0, metadata !4, null}
+!10 = metadata !{i32 3, i32 0, metadata !4, null}
diff --git a/test/MC/PowerPC/ppc64-regs.s b/test/MC/PowerPC/ppc64-regs.s
new file mode 100644 (file)
index 0000000..02b1fc5
--- /dev/null
@@ -0,0 +1,235 @@
+# RUN: llvm-mc -triple powerpc64-unknown-unknown --show-encoding %s | FileCheck %s
+
+#CHECK: .cfi_startproc
+#CHECK: .cfi_offset r0, 0
+#CHECK: .cfi_offset r1, 8
+#CHECK: .cfi_offset r2, 16
+#CHECK: .cfi_offset r3, 24
+#CHECK: .cfi_offset r4, 32
+#CHECK: .cfi_offset r5, 40
+#CHECK: .cfi_offset r6, 48
+#CHECK: .cfi_offset r7, 56
+#CHECK: .cfi_offset r8, 64
+#CHECK: .cfi_offset r9, 72
+#CHECK: .cfi_offset r10, 80
+#CHECK: .cfi_offset r11, 88
+#CHECK: .cfi_offset r12, 96
+#CHECK: .cfi_offset r13, 104
+#CHECK: .cfi_offset r14, 112
+#CHECK: .cfi_offset r15, 120
+#CHECK: .cfi_offset r16, 128
+#CHECK: .cfi_offset r17, 136
+#CHECK: .cfi_offset r18, 144
+#CHECK: .cfi_offset r19, 152
+#CHECK: .cfi_offset r20, 160
+#CHECK: .cfi_offset r21, 168
+#CHECK: .cfi_offset r22, 176
+#CHECK: .cfi_offset r22, 184
+#CHECK: .cfi_offset r23, 192
+#CHECK: .cfi_offset r24, 200
+#CHECK: .cfi_offset r25, 208
+#CHECK: .cfi_offset r26, 216
+#CHECK: .cfi_offset r27, 224
+#CHECK: .cfi_offset r28, 232
+#CHECK: .cfi_offset r29, 240
+#CHECK: .cfi_offset r30, 248
+#CHECK: .cfi_offset r31, 256
+
+#CHECK: .cfi_offset f0, 300
+#CHECK: .cfi_offset f1, 308
+#CHECK: .cfi_offset f2, 316
+#CHECK: .cfi_offset f3, 324
+#CHECK: .cfi_offset f4, 332
+#CHECK: .cfi_offset f5, 340
+#CHECK: .cfi_offset f6, 348
+#CHECK: .cfi_offset f7, 356
+#CHECK: .cfi_offset f8, 364
+#CHECK: .cfi_offset f9, 372
+#CHECK: .cfi_offset f10, 380
+#CHECK: .cfi_offset f11, 388
+#CHECK: .cfi_offset f12, 396
+#CHECK: .cfi_offset f13, 404
+#CHECK: .cfi_offset f14, 412
+#CHECK: .cfi_offset f15, 420
+#CHECK: .cfi_offset f16, 428
+#CHECK: .cfi_offset f17, 436
+#CHECK: .cfi_offset f18, 444
+#CHECK: .cfi_offset f19, 452
+#CHECK: .cfi_offset f20, 460
+#CHECK: .cfi_offset f21, 468
+#CHECK: .cfi_offset f22, 476
+#CHECK: .cfi_offset f22, 484
+#CHECK: .cfi_offset f23, 492
+#CHECK: .cfi_offset f24, 500
+#CHECK: .cfi_offset f25, 508
+#CHECK: .cfi_offset f26, 516
+#CHECK: .cfi_offset f27, 524
+#CHECK: .cfi_offset f28, 532
+#CHECK: .cfi_offset f29, 540
+#CHECK: .cfi_offset f30, 548
+#CHECK: .cfi_offset f31, 556
+
+#CHECK: .cfi_offset lr, 600
+#CHECK: .cfi_offset ctr, 608
+#CHECK: .cfi_offset vrsave, 616
+
+#CHECK: .cfi_offset cr0, 620
+#CHECK: .cfi_offset cr1, 621
+#CHECK: .cfi_offset cr2, 622
+#CHECK: .cfi_offset cr3, 623
+#CHECK: .cfi_offset cr4, 624
+#CHECK: .cfi_offset cr5, 625
+#CHECK: .cfi_offset cr6, 626
+#CHECK: .cfi_offset cr7, 627
+
+#CHECK: .cfi_offset v0, 700
+#CHECK: .cfi_offset v1, 716
+#CHECK: .cfi_offset v2, 732
+#CHECK: .cfi_offset v3, 748
+#CHECK: .cfi_offset v4, 764
+#CHECK: .cfi_offset v5, 780
+#CHECK: .cfi_offset v6, 796
+#CHECK: .cfi_offset v7, 812
+#CHECK: .cfi_offset v8, 828
+#CHECK: .cfi_offset v9, 844
+#CHECK: .cfi_offset v10, 860
+#CHECK: .cfi_offset v11, 876
+#CHECK: .cfi_offset v12, 892
+#CHECK: .cfi_offset v13, 908
+#CHECK: .cfi_offset v14, 924
+#CHECK: .cfi_offset v15, 940
+#CHECK: .cfi_offset v16, 956
+#CHECK: .cfi_offset v17, 972
+#CHECK: .cfi_offset v18, 988
+#CHECK: .cfi_offset v19, 1004
+#CHECK: .cfi_offset v20, 1020
+#CHECK: .cfi_offset v21, 1036
+#CHECK: .cfi_offset v22, 1052
+#CHECK: .cfi_offset v22, 1068
+#CHECK: .cfi_offset v23, 1084
+#CHECK: .cfi_offset v24, 1100
+#CHECK: .cfi_offset v25, 1116
+#CHECK: .cfi_offset v26, 1132
+#CHECK: .cfi_offset v27, 1148
+#CHECK: .cfi_offset v28, 1164
+#CHECK: .cfi_offset v29, 1180
+#CHECK: .cfi_offset v30, 1196
+#CHECK: .cfi_offset v31, 1212
+#CHECK: .cfi_endproc
+
+       .cfi_startproc
+       .cfi_offset r0,0
+       .cfi_offset r1,8
+       .cfi_offset r2,16
+       .cfi_offset r3,24
+       .cfi_offset r4,32
+       .cfi_offset r5,40
+       .cfi_offset r6,48
+       .cfi_offset r7,56
+       .cfi_offset r8,64
+       .cfi_offset r9,72
+       .cfi_offset r10,80
+       .cfi_offset r11,88
+       .cfi_offset r12,96
+       .cfi_offset r13,104
+       .cfi_offset r14,112
+       .cfi_offset r15,120
+       .cfi_offset r16,128
+       .cfi_offset r17,136
+       .cfi_offset r18,144
+       .cfi_offset r19,152
+       .cfi_offset r20,160
+       .cfi_offset r21,168
+       .cfi_offset r22,176
+       .cfi_offset r22,184
+       .cfi_offset r23,192
+       .cfi_offset r24,200
+       .cfi_offset r25,208
+       .cfi_offset r26,216
+       .cfi_offset r27,224
+       .cfi_offset r28,232
+       .cfi_offset r29,240
+       .cfi_offset r30,248
+       .cfi_offset r31,256
+
+       .cfi_offset f0,300
+       .cfi_offset f1,308
+       .cfi_offset f2,316
+       .cfi_offset f3,324
+       .cfi_offset f4,332
+       .cfi_offset f5,340
+       .cfi_offset f6,348
+       .cfi_offset f7,356
+       .cfi_offset f8,364
+       .cfi_offset f9,372
+       .cfi_offset f10,380
+       .cfi_offset f11,388
+       .cfi_offset f12,396
+       .cfi_offset f13,404
+       .cfi_offset f14,412
+       .cfi_offset f15,420
+       .cfi_offset f16,428
+       .cfi_offset f17,436
+       .cfi_offset f18,444
+       .cfi_offset f19,452
+       .cfi_offset f20,460
+       .cfi_offset f21,468
+       .cfi_offset f22,476
+       .cfi_offset f22,484
+       .cfi_offset f23,492
+       .cfi_offset f24,500
+       .cfi_offset f25,508
+       .cfi_offset f26,516
+       .cfi_offset f27,524
+       .cfi_offset f28,532
+       .cfi_offset f29,540
+       .cfi_offset f30,548
+       .cfi_offset f31,556
+
+       .cfi_offset lr,600
+       .cfi_offset ctr,608
+       .cfi_offset vrsave,616
+       .cfi_offset cr0,620
+       .cfi_offset cr1,621
+       .cfi_offset cr2,622
+       .cfi_offset cr3,623
+       .cfi_offset cr4,624
+       .cfi_offset cr5,625
+       .cfi_offset cr6,626
+       .cfi_offset cr7,627
+
+       .cfi_offset v0,700
+       .cfi_offset v1,716
+       .cfi_offset v2,732
+       .cfi_offset v3,748
+       .cfi_offset v4,764
+       .cfi_offset v5,780
+       .cfi_offset v6,796
+       .cfi_offset v7,812
+       .cfi_offset v8,828
+       .cfi_offset v9,844
+       .cfi_offset v10,860
+       .cfi_offset v11,876
+       .cfi_offset v12,892
+       .cfi_offset v13,908
+       .cfi_offset v14,924
+       .cfi_offset v15,940
+       .cfi_offset v16,956
+       .cfi_offset v17,972
+       .cfi_offset v18,988
+       .cfi_offset v19,1004
+       .cfi_offset v20,1020
+       .cfi_offset v21,1036
+       .cfi_offset v22,1052
+       .cfi_offset v22,1068
+       .cfi_offset v23,1084
+       .cfi_offset v24,1100
+       .cfi_offset v25,1116
+       .cfi_offset v26,1132
+       .cfi_offset v27,1148
+       .cfi_offset v28,1164
+       .cfi_offset v29,1180
+       .cfi_offset v30,1196
+       .cfi_offset v31,1212
+
+       .cfi_endproc