summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2012-01-12 23:05:03 +0000
committerBill Wendling <isanbard@gmail.com>2012-01-12 23:05:03 +0000
commit86b1a7d61413aed40a68f98f1e8f17fd79ebd7a2 (patch)
treeb8bfa4798e70042333358b64cb79821da4103b9a /lib
parentd578b905de8f9dece45aab2496a88ac548c67348 (diff)
downloadllvm-86b1a7d61413aed40a68f98f1e8f17fd79ebd7a2.tar.gz
llvm-86b1a7d61413aed40a68f98f1e8f17fd79ebd7a2.tar.bz2
llvm-86b1a7d61413aed40a68f98f1e8f17fd79ebd7a2.tar.xz
Fix the code that was WRONG.
The registers are placed into the saved registers list in the reverse order, which is why the original loop was written to loop backwards. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148064 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp65
-rw-r--r--lib/Target/X86/X86FrameLowering.cpp19
2 files changed, 71 insertions, 13 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 82860c2657..1b15cdcc81 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -930,6 +930,71 @@ bool AsmPrinter::doFinalization(Module &M) {
if (const MCSection *S = MAI->getNonexecutableStackSection(OutContext))
OutStreamer.SwitchSection(S);
+ // If we have module flags, then emit them.
+ NamedMDNode *ModFlags = M.getNamedMetadata("llvm.module.flags");
+ if (ModFlags) {
+ const char *ObjCGCName = "Objective-C Garbage Collection";
+ const char *ObjCGCOnlyName = "Objective-C GC Only";
+ const char *ObjCImageInfoVersion = "Objective-C Image Info Version";
+ const char *ObjCImageInfoSec = "Objective-C Image Info Section";
+
+ MDNode *GC = 0;
+ MDNode *GCOnly = 0;
+ MDNode *ImageInfoVersion = 0;
+ MDNode *ImageInfoSec = 0;
+
+ for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {
+ MDNode *MD = ModFlags->getOperand(I);
+ unsigned Behavior = cast<ConstantInt>(MD->getOperand(0))->getZExtValue();
+ (void) Behavior;
+ MDString *Str = cast<MDString>(MD->getOperand(1));
+
+ if (Str->getString() == ObjCImageInfoVersion) {
+ assert(Behavior == 1 && "Invalid behavior for module flag!");
+ ImageInfoVersion = MD;
+ } else if (Str->getString() == ObjCGCName) {
+ assert((Behavior == 1 || Behavior == 3) &&
+ "Invalid behavior for module flag!");
+ GC = MD;
+ } else if (Str->getString() == ObjCGCOnlyName) {
+ if (Behavior == 2) continue; // Ignore the 'require' clause.
+ GCOnly = MD;
+ } else if (Str->getString() == ObjCImageInfoSec) {
+ assert(Behavior == 1 && "Invalid behavior for module flag!");
+ ImageInfoSec = MD;
+ }
+ }
+
+ if (ImageInfoVersion || GC || GCOnly || ImageInfoSec) {
+ // FIXME: Duh!
+ unsigned version = 0;
+ unsigned flags = 0;
+
+ version =
+ cast<ConstantInt>(ImageInfoVersion->getOperand(2))->getZExtValue();
+ if (GC)
+ flags |= cast<ConstantInt>(GC->getOperand(2))->getZExtValue();
+ if (GCOnly)
+ flags |= cast<ConstantInt>(GCOnly->getOperand(2))->getZExtValue();
+
+ Type *Int32Ty = Type::getInt32Ty(M.getContext());
+ Constant *values[2] = {
+ ConstantInt::get(Int32Ty, version),
+ ConstantInt::get(Int32Ty, flags)
+ };
+ ArrayType *AT = ArrayType::get(Int32Ty, 2);
+ StringRef Sec = cast<MDString>(ImageInfoSec->getOperand(2))->getString();
+
+ GlobalVariable *GV =
+ cast<GlobalVariable>(M.getOrInsertGlobal("L_OBJC_IMAGE_INFO", AT));
+ GV->setConstant(true);
+ GV->setSection(Sec);
+ GV->setInitializer(ConstantArray::get(AT, values));
+
+ EmitGlobalVariable(GV);
+ }
+ }
+
// Allow the target to emit any magic that it wants at the end of the file,
// after everything else has gone out.
EmitEndOfAsmFile(M);
diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp
index e5f6752614..5dfc0bb85d 100644
--- a/lib/Target/X86/X86FrameLowering.cpp
+++ b/lib/Target/X86/X86FrameLowering.cpp
@@ -455,26 +455,19 @@ encodeCompactUnwindRegistersWithFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS],
};
const unsigned *CURegs = (Is64Bit ? CU64BitRegs : CU32BitRegs);
- // FIXME: The code below is WRONG and breaks tests on i386, see
- // SingleSource/Regression/C++/EH/ctor_dtor_count.exec
- // SingleSource/Regression/C++/EH/exception_spec_test.exec
- // SingleSource/Regression/C++/EH/function_try_block.exec
- // SingleSource/Regression/C++/EH/throw_rethrow_test.exec
- return ~0U;
-
// Encode the registers in the order they were saved, 3-bits per register. The
- // registers are numbered from 1 to 6.
+ // registers are numbered from 1 to CU_NUM_SAVED_REGS.
uint32_t RegEnc = 0;
- for (int I = 0; I != 6; ++I) {
+ for (int I = CU_NUM_SAVED_REGS, Idx = 0; I != -1; --I) {
unsigned Reg = SavedRegs[I];
- if (Reg == 0) break;
+ if (Reg == 0) continue;
+
int CURegNum = getCompactUnwindRegNum(CURegs, Reg);
- if (CURegNum == -1)
- return ~0U;
+ if (CURegNum == -1) return ~0U;
// Encode the 3-bit register number in order, skipping over 3-bits for each
// register.
- RegEnc |= (CURegNum & 0x7) << ((5 - I) * 3);
+ RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
}
assert((RegEnc & 0x3FFFF) == RegEnc && "Invalid compact register encoding!");