summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
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
commitee5eaebc58825b9a9334c680cf62d8a8a53f406a (patch)
tree66a322f1bb87747e147714b8585cbb6d9eb30976 /llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
parent18f4629c780c863b05811b80895784607915e653 (diff)
downloadbcm5719-llvm-ee5eaebc58825b9a9334c680cf62d8a8a53f406a.tar.gz
bcm5719-llvm-ee5eaebc58825b9a9334c680cf62d8a8a53f406a.zip
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. llvm-svn: 148064
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 82860c26574..1b15cdcc810 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/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);
OpenPOWER on IntegriCloud