ARMMCInstLower.cpp revision 637d89fe0eca4fa2b9c95f6c15eb69a99bae83bc
19cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//===-- ARMMCInstLower.cpp - Convert ARM MachineInstr to an MCInst --------===//
29cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//
39cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//                     The LLVM Compiler Infrastructure
49cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//
59cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// This file is distributed under the University of Illinois Open Source
69cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// License. See LICENSE.TXT for details.
79cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//
89cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//===----------------------------------------------------------------------===//
99cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//
109cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// This file contains code to lower ARM MachineInstrs to their corresponding
119cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner// MCInst records.
129cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//
139cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner//===----------------------------------------------------------------------===//
149cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner
151685caffedd0d0b351e0ec475d2529d90efec2fdJim Grosbach#include "ARM.h"
169cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner#include "ARMMCInstLower.h"
1796bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner#include "llvm/CodeGen/AsmPrinter.h"
1826edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach#include "llvm/Constants.h"
1996bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner#include "llvm/CodeGen/MachineBasicBlock.h"
206f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner#include "llvm/MC/MCAsmInfo.h"
216f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner#include "llvm/MC/MCContext.h"
226f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner#include "llvm/MC/MCExpr.h"
239cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner#include "llvm/MC/MCInst.h"
24d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h"
256f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner#include "llvm/Support/raw_ostream.h"
266f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner#include "llvm/ADT/SmallString.h"
279cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattnerusing namespace llvm;
289cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner
29c686e33d12f84e1e1f5c96eadef851d078bab043Jim GrosbachMCSymbol *ARMMCInstLower::GetGlobalAddressSymbol(const GlobalValue *GV) const {
30c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  return Printer.Mang->getSymbol(GV);
31c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach}
32c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach
33c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbachconst MCSymbolRefExpr *ARMMCInstLower::
34c686e33d12f84e1e1f5c96eadef851d078bab043Jim GrosbachGetSymbolRef(const MachineOperand &MO) const {
35c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  assert(MO.isGlobal() && "Isn't a global address reference?");
36c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach
37c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  const MCSymbolRefExpr *SymRef;
38c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  const MCSymbol *Symbol = GetGlobalAddressSymbol(MO.getGlobal());
39c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach
406f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  switch (MO.getTargetFlags()) {
416f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  default: assert(0 && "Unknown target flag on GV operand");
42c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  case 0:
43c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach    SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx);
44c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach    break;
45c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  case ARMII::MO_LO16:
46c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach    SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx);
47c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach    break;
48c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  case ARMII::MO_HI16:
49c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach    SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_HI16, Ctx);
50c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach    break;
51637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach  case ARMII::MO_PLT:
52637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach    SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, Ctx);
53637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach    break;
546f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  }
55fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
56c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  return SymRef;
576f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner}
586f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner
59637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbachconst MCSymbolRefExpr *ARMMCInstLower::
60292df8eb1f2e8967499161804e85772f5fd3a711Chris LattnerGetExternalSymbolSymbol(const MachineOperand &MO) const {
61637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach  const MCSymbolRefExpr *SymRef;
62637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach  const MCSymbol *Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName());
63637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach
64292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner  switch (MO.getTargetFlags()) {
65637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach  default: assert(0 && "Unknown target flag on external symbol operand");
66637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach  case 0:
67637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach    SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx);
68637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach    break;
69637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach  case ARMII::MO_LO16:
70637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach    SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx);
71637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach    break;
72637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach  case ARMII::MO_HI16:
73637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach    SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_HI16, Ctx);
74637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach    break;
75637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach  case ARMII::MO_PLT:
76637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach    SymRef = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, Ctx);
77637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach    break;
78292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner  }
79fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
80637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach  return SymRef;
81292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner}
82292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner
83292df8eb1f2e8967499161804e85772f5fd3a711Chris Lattner
846f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner
856f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerMCSymbol *ARMMCInstLower::
866f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerGetJumpTableSymbol(const MachineOperand &MO) const {
876f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  SmallString<256> Name;
8896bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner  raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI"
8996bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner    << Printer.getFunctionNumber() << '_' << MO.getIndex();
90fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
916f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  switch (MO.getTargetFlags()) {
92b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach  default: assert(0 && "Unknown target flag on jump table operand");
93b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach  case 0: break;
946f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  }
95fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
966f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  // Create a symbol for the name.
979b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return Ctx.GetOrCreateSymbol(Name.str());
986f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner}
996f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner
1006f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerMCSymbol *ARMMCInstLower::
1016f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerGetConstantPoolIndexSymbol(const MachineOperand &MO) const {
1026f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  SmallString<256> Name;
10396bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner  raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "CPI"
10496bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner    << Printer.getFunctionNumber() << '_' << MO.getIndex();
105fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
1066f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  switch (MO.getTargetFlags()) {
107b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach  default: assert(0 && "Unknown target flag on CPI operand");
108b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach  case 0: break;
1096f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  }
110fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
1116f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  // Create a symbol for the name.
1129b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return Ctx.GetOrCreateSymbol(Name.str());
1136f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner}
114fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
1156f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerMCOperand ARMMCInstLower::
1166f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris LattnerLowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const {
1176f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  // FIXME: We would like an efficient form for this, so we don't have to do a
1186f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  // lot of extra uniquing.
1196f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
120fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
1216f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  switch (MO.getTargetFlags()) {
122b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach  default: assert(0 && "Unknown target flag on Symbol operand");
123b6ec8cae3cf437ea4e3d39ad209a0687df4686c3Jim Grosbach  case 0: break;
1246f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  }
125fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
1266f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  if (!MO.isJTI() && MO.getOffset())
1276f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner    Expr = MCBinaryExpr::CreateAdd(Expr,
1286f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner                                   MCConstantExpr::Create(MO.getOffset(), Ctx),
1296f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner                                   Ctx);
1306f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner  return MCOperand::CreateExpr(Expr);
1316f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner}
1326f99776f6c1d6cc93a62192099a0fd8cc2cc3a0cChris Lattner
133c686e33d12f84e1e1f5c96eadef851d078bab043Jim GrosbachMCOperand ARMMCInstLower::
134c686e33d12f84e1e1f5c96eadef851d078bab043Jim GrosbachLowerSymbolRefOperand(const MachineOperand &MO,
135c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach                      const MCSymbolRefExpr *Sym) const {
136c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  const MCExpr *Expr = Sym;
137c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  if (!MO.isJTI() && MO.getOffset())
138c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach    Expr = MCBinaryExpr::CreateAdd(Expr,
139c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach                                   MCConstantExpr::Create(MO.getOffset(), Ctx),
140c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach                                   Ctx);
141c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach  return MCOperand::CreateExpr(Expr);
142c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach}
143c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach
1449cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner
1459cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattnervoid ARMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
1469cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner  OutMI.setOpcode(MI->getOpcode());
147fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
1489cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
1499cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    const MachineOperand &MO = MI->getOperand(i);
150fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
1519cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    MCOperand MCOp;
1529cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    switch (MO.getType()) {
1539cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    default:
1549cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      MI->dump();
1559cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      assert(0 && "unknown operand type");
1569cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    case MachineOperand::MO_Register:
1571685caffedd0d0b351e0ec475d2529d90efec2fdJim Grosbach      // Ignore all non-CPSR implicit register operands.
1581685caffedd0d0b351e0ec475d2529d90efec2fdJim Grosbach      if (MO.isImplicit() && MO.getReg() != ARM::CPSR) continue;
159e8ea011cc766b37a957d5966655526096bf49feaAnton Korobeynikov      assert(!MO.getSubReg() && "Subregs should be eliminated!");
1609cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      MCOp = MCOperand::CreateReg(MO.getReg());
1619cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      break;
1629cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    case MachineOperand::MO_Immediate:
1639cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      MCOp = MCOperand::CreateImm(MO.getImm());
1649cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      break;
1659cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    case MachineOperand::MO_MachineBasicBlock:
1669cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
1671b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner                       MO.getMBB()->getSymbol(), Ctx));
1689cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      break;
1699cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    case MachineOperand::MO_GlobalAddress:
170c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach      MCOp = LowerSymbolRefOperand(MO, GetSymbolRef(MO));
1719cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      break;
1729cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    case MachineOperand::MO_ExternalSymbol:
173637d89fe0eca4fa2b9c95f6c15eb69a99bae83bcJim Grosbach      MCOp = LowerSymbolRefOperand(MO, GetExternalSymbolSymbol(MO));
1749cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      break;
1759cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    case MachineOperand::MO_JumpTableIndex:
1769cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO));
1779cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      break;
1789cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    case MachineOperand::MO_ConstantPoolIndex:
1799cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
1809cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner      break;
181ddb16df91257e4c4d2be5343e2c7c7ecbfbe8bf4Bob Wilson    case MachineOperand::MO_BlockAddress:
182ddb16df91257e4c4d2be5343e2c7c7ecbfbe8bf4Bob Wilson      MCOp = LowerSymbolOperand(MO, Printer.GetBlockAddressSymbol(
183ddb16df91257e4c4d2be5343e2c7c7ecbfbe8bf4Bob Wilson                                              MO.getBlockAddress()));
184ddb16df91257e4c4d2be5343e2c7c7ecbfbe8bf4Bob Wilson      break;
18526edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach    case MachineOperand::MO_FPImmediate:
1861d51c41a457b99d646e3a9b9fae1e913f7a60dc0Jim Grosbach      APFloat Val = MO.getFPImm()->getValueAPF();
1871d51c41a457b99d646e3a9b9fae1e913f7a60dc0Jim Grosbach      bool ignored;
1881d51c41a457b99d646e3a9b9fae1e913f7a60dc0Jim Grosbach      Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
1891d51c41a457b99d646e3a9b9fae1e913f7a60dc0Jim Grosbach      MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
19026edbcb8d5da5fb65816a97f740c9868fa798df4Jim Grosbach      break;
1919cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    }
192fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
1939cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner    OutMI.addOperand(MCOp);
1949cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner  }
195fc16a8950c671b9434e60702ba31224c39ee133fJim Grosbach
1969cf0eb5e58fa42802af7e5776b39909516ca74e7Chris Lattner}
197