[llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp Printer.cpp X86InstrInfo.def X86TargetMachine.cpp X86TargetMachine.h

John Criswell criswell at choi.cs.uiuc.edu
Thu Jun 26 16:42:15 PDT 2003


Changes in directory llvm/lib/Target/X86:

InstSelectSimple.cpp updated: 1.106 -> 1.106.2.1
Printer.cpp updated: 1.35 -> 1.35.2.1
X86InstrInfo.def updated: 1.57 -> 1.57.2.1
X86TargetMachine.cpp updated: 1.17 -> 1.17.2.1
X86TargetMachine.h updated: 1.9 -> 1.9.2.1

---
Log message:

Merged with mainline on Thursday, June 26, 2003.


---
Diffs of the changes:

Index: llvm/lib/Target/X86/InstSelectSimple.cpp
diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.106 llvm/lib/Target/X86/InstSelectSimple.cpp:1.106.2.1
--- llvm/lib/Target/X86/InstSelectSimple.cpp:1.106	Thu Jun  5 14:30:30 2003
+++ llvm/lib/Target/X86/InstSelectSimple.cpp	Thu Jun 26 16:35:24 2003
@@ -1069,8 +1069,6 @@
 /// registers op0Reg and op1Reg, and put the result in DestReg.  The type of the
 /// result should be given as DestTy.
 ///
-/// FIXME: doMultiply should use one of the two address IMUL instructions!
-///
 void ISel::doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI,
                       unsigned DestReg, const Type *DestTy,
                       unsigned op0Reg, unsigned op1Reg) {
@@ -1079,28 +1077,20 @@
   case cFP:              // Floating point multiply
     BMI(BB, MBBI, X86::FpMUL, 2, DestReg).addReg(op0Reg).addReg(op1Reg);
     return;
+  case cInt:
+  case cShort:
+    BMI(BB, MBBI, Class == cInt ? X86::IMULr32 : X86::IMULr16, 2, DestReg)
+      .addReg(op0Reg).addReg(op1Reg);
+    return;
+  case cByte:
+    // Must use the MUL instruction, which forces use of AL...
+    BMI(MBB, MBBI, X86::MOVrr8, 1, X86::AL).addReg(op0Reg);
+    BMI(MBB, MBBI, X86::MULr8, 1).addReg(op1Reg);
+    BMI(MBB, MBBI, X86::MOVrr8, 1, DestReg).addReg(X86::AL);
+    return;
   default:
   case cLong: assert(0 && "doMultiply cannot operate on LONG values!");
-  case cByte:
-  case cShort:
-  case cInt:          // Small integerals, handled below...
-    break;
   }
- 
-  static const unsigned Regs[]     ={ X86::AL    , X86::AX     , X86::EAX     };
-  static const unsigned MulOpcode[]={ X86::MULr8 , X86::MULr16 , X86::MULr32  };
-  static const unsigned MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 };
-  unsigned Reg     = Regs[Class];
-
-  // Emit a MOV to put the first operand into the appropriately-sized
-  // subreg of EAX.
-  BMI(MBB, MBBI, MovOpcode[Class], 1, Reg).addReg(op0Reg);
-  
-  // Emit the appropriate multiply instruction.
-  BMI(MBB, MBBI, MulOpcode[Class], 1).addReg(op1Reg);
-
-  // Emit another MOV to put the result into the destination register.
-  BMI(MBB, MBBI, MovOpcode[Class], 1, DestReg).addReg(Reg);
 }
 
 /// visitMul - Multiplies are not simple binary operators because they must deal
@@ -1126,16 +1116,16 @@
     BuildMI(BB, X86::MOVrr32, 1, OverflowReg).addReg(X86::EDX); // AL*BL >> 32
 
     MachineBasicBlock::iterator MBBI = BB->end();
-    unsigned AHBLReg = makeAnotherReg(Type::UIntTy);
-    doMultiply(BB, MBBI, AHBLReg, Type::UIntTy, Op0Reg+1, Op1Reg); // AH*BL
+    unsigned AHBLReg = makeAnotherReg(Type::UIntTy);   // AH*BL
+    BMI(BB, MBBI, X86::IMULr32, 2, AHBLReg).addReg(Op0Reg+1).addReg(Op1Reg);
 
     unsigned AHBLplusOverflowReg = makeAnotherReg(Type::UIntTy);
     BuildMI(BB, X86::ADDrr32, 2,                         // AH*BL+(AL*BL >> 32)
 	    AHBLplusOverflowReg).addReg(AHBLReg).addReg(OverflowReg);
     
     MBBI = BB->end();
-    unsigned ALBHReg = makeAnotherReg(Type::UIntTy);
-    doMultiply(BB, MBBI, ALBHReg, Type::UIntTy, Op0Reg, Op1Reg+1); // AL*BH
+    unsigned ALBHReg = makeAnotherReg(Type::UIntTy); // AL*BH
+    BMI(BB, MBBI, X86::IMULr32, 2, ALBHReg).addReg(Op0Reg).addReg(Op1Reg+1);
     
     BuildMI(BB, X86::ADDrr32, 2,               // AL*BH + AH*BL + (AL*BL >> 32)
 	    DestReg+1).addReg(AHBLplusOverflowReg).addReg(ALBHReg);
@@ -1189,7 +1179,7 @@
 
   static const unsigned Regs[]     ={ X86::AL    , X86::AX     , X86::EAX     };
   static const unsigned MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 };
-  static const unsigned ExtOpcode[]={ X86::CBW   , X86::CWD    , X86::CDQ     };
+  static const unsigned SarOpcode[]={ X86::SARir8, X86::SARir16, X86::SARir32 };
   static const unsigned ClrOpcode[]={ X86::XORrr8, X86::XORrr16, X86::XORrr32 };
   static const unsigned ExtRegs[]  ={ X86::AH    , X86::DX     , X86::EDX     };
 
@@ -1207,7 +1197,9 @@
 
   if (isSigned) {
     // Emit a sign extension instruction...
-    BuildMI(BB, ExtOpcode[Class], 0);
+    unsigned ShiftResult = makeAnotherReg(I.getType());
+    BuildMI(BB, SarOpcode[Class], 2, ShiftResult).addReg(Op0Reg).addZImm(31);
+    BuildMI(BB, MovOpcode[Class], 1, ExtReg).addReg(ShiftResult);
   } else {
     // If unsigned, emit a zeroing instruction... (reg = xor reg, reg)
     BuildMI(BB, ClrOpcode[Class], 2, ExtReg).addReg(ExtReg).addReg(ExtReg);
@@ -1580,9 +1572,26 @@
 /// visitCastInst - Here we have various kinds of copying with or without
 /// sign extension going on.
 void ISel::visitCastInst(CastInst &CI) {
+  Value *Op = CI.getOperand(0);
+  // If this is a cast from a 32-bit integer to a Long type, and the only uses
+  // of the case are GEP instructions, then the cast does not need to be
+  // generated explicitly, it will be folded into the GEP.
+  if (CI.getType() == Type::LongTy &&
+      (Op->getType() == Type::IntTy || Op->getType() == Type::UIntTy)) {
+    bool AllUsesAreGEPs = true;
+    for (Value::use_iterator I = CI.use_begin(), E = CI.use_end(); I != E; ++I)
+      if (!isa<GetElementPtrInst>(*I)) {
+        AllUsesAreGEPs = false;
+        break;
+      }        
+
+    // No need to codegen this cast if all users are getelementptr instrs...
+    if (AllUsesAreGEPs) return;
+  }
+
   unsigned DestReg = getReg(CI);
   MachineBasicBlock::iterator MI = BB->end();
-  emitCastOperation(BB, MI, CI.getOperand(0), CI.getType(), DestReg);
+  emitCastOperation(BB, MI, Op, CI.getType(), DestReg);
 }
 
 /// emitCastOperation - Common code shared between visitCastInst and
@@ -1936,6 +1945,13 @@
       // indices, we may not know its actual value at code-generation
       // time.
       assert(idx->getType() == Type::LongTy && "Bad GEP array index!");
+
+      // Most GEP instructions use a [cast (int/uint) to LongTy] as their
+      // operand on X86.  Handle this case directly now...
+      if (CastInst *CI = dyn_cast<CastInst>(idx))
+        if (CI->getOperand(0)->getType() == Type::IntTy ||
+            CI->getOperand(0)->getType() == Type::UIntTy)
+          idx = CI->getOperand(0);
 
       // We want to add BaseReg to(idxReg * sizeof ElementType). First, we
       // must find the size of the pointed-to type (Not coincidentally, the next


Index: llvm/lib/Target/X86/Printer.cpp
diff -u llvm/lib/Target/X86/Printer.cpp:1.35 llvm/lib/Target/X86/Printer.cpp:1.35.2.1
--- llvm/lib/Target/X86/Printer.cpp:1.35	Mon May 26 19:03:17 2003
+++ llvm/lib/Target/X86/Printer.cpp	Thu Jun 26 16:35:24 2003
@@ -14,20 +14,41 @@
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "Support/Statistic.h"
+#include "Support/hash_map"
+#include "llvm/Type.h"
+#include "llvm/Constants.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/SlotCalculator.h"
+#include "Support/StringExtras.h"
+#include "llvm/Module.h"
 
 namespace {
+
+
+  std::set<const Value*> MangledGlobals;
   struct Printer : public MachineFunctionPass {
+
     std::ostream &O;
     unsigned ConstIdx;
     Printer(std::ostream &o) : O(o), ConstIdx(0) {}
+    const TargetData *TD;
 
     virtual const char *getPassName() const {
       return "X86 Assembly Printer";
     }
 
-    void printConstantPool(MachineConstantPool *MCP, const TargetData &TD);
-    bool runOnMachineFunction(MachineFunction &F);
+    void printConstantPool(MachineConstantPool *MCP);
+    bool runOnMachineFunction(MachineFunction &F);    
+    std::string ConstantExprToString(const ConstantExpr* CE);
+    std::string valToExprString(const Value* V);
+    bool doInitialization(Module &M);
+    bool doFinalization(Module &M);
+    void PrintZeroBytesToPad(int numBytes);
+    void printConstantValueOnly(const Constant* CV, int numPadBytesAfter = 0);
+    void printSingleConstantValue(const Constant* CV);
   };
+  std::map<const Value *, unsigned> NumberForBB;
 }
 
 /// createX86CodePrinterPass - Print out the specified machine code function to
@@ -38,44 +59,377 @@
   return new Printer(O);
 }
 
+// We dont want identifier names with ., space, -  in them. 
+// So we replace them with _
+static std::string makeNameProper(std::string x) {
+  std::string tmp;
+  for (std::string::iterator sI = x.begin(), sEnd = x.end(); sI != sEnd; sI++)
+    switch (*sI) {
+    case '.': tmp += "d_"; break;
+    case ' ': tmp += "s_"; break;
+    case '-': tmp += "D_"; break;
+    default:  tmp += *sI;
+    }
+
+  return tmp;
+}
+
+std::string getValueName(const Value *V) {
+  if (V->hasName()) { // Print out the label if it exists...
+    
+    // Name mangling occurs as follows:
+    // - If V is not a global, mangling always occurs.
+    // - Otherwise, mangling occurs when any of the following are true:
+    //   1) V has internal linkage
+    //   2) V's name would collide if it is not mangled.
+    //
+    
+    if(const GlobalValue* gv = dyn_cast<GlobalValue>(V)) {
+      if(!gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
+        // No internal linkage, name will not collide -> no mangling.
+        return makeNameProper(gv->getName());
+      }
+    }
+    
+    // Non-global, or global with internal linkage / colliding name -> mangle.
+    return "l" + utostr(V->getType()->getUniqueID()) + "_" +
+      makeNameProper(V->getName());      
+  }
+
+  static int Count = 0;
+  Count++;
+  return "ltmp_" + itostr(Count) + "_" + utostr(V->getType()->getUniqueID());
+}
+
+
+// valToExprString - Helper function for ConstantExprToString().
+// Appends result to argument string S.
+// 
+std::string Printer::valToExprString(const Value* V) {
+  std::string S;
+  bool failed = false;
+  if (const Constant* CV = dyn_cast<Constant>(V)) { // symbolic or known
+    if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV))
+      S += std::string(CB == ConstantBool::True ? "1" : "0");
+    else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV))
+      S += itostr(CI->getValue());
+    else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV))
+      S += utostr(CI->getValue());
+    else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
+      S += ftostr(CFP->getValue());
+    else if (isa<ConstantPointerNull>(CV))
+      S += "0";
+    else if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(CV))
+      S += valToExprString(CPR->getValue());
+    else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV))
+      S += ConstantExprToString(CE);
+    else
+      failed = true;
+  } else if (const GlobalValue* GV = dyn_cast<GlobalValue>(V)) {
+    S += getValueName(GV);
+  }
+  else
+    failed = true;
+
+  if (failed) {
+    assert(0 && "Cannot convert value to string");
+    S += "<illegal-value>";
+  }
+  return S;
+}
+
+// ConstantExprToString() - Convert a ConstantExpr to an asm expression
+// and return this as a string.
+std::string Printer::ConstantExprToString(const ConstantExpr* CE) {
+  std::string S;
+  switch(CE->getOpcode()) {
+  case Instruction::GetElementPtr:
+    { // generate a symbolic expression for the byte address
+      const Value* ptrVal = CE->getOperand(0);
+      std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
+      S += "(" + valToExprString(ptrVal) + ") + ("
+	+ utostr(TD->getIndexedOffset(ptrVal->getType(),idxVec)) + ")";
+      break;
+    }
+
+  case Instruction::Cast:
+    // Support only non-converting casts for now, i.e., a no-op.
+    // This assertion is not a complete check.
+    assert(TD->getTypeSize(CE->getType()) ==
+	   TD->getTypeSize(CE->getOperand(0)->getType()));
+    S += "(" + valToExprString(CE->getOperand(0)) + ")";
+    break;
+
+  case Instruction::Add:
+    S += "(" + valToExprString(CE->getOperand(0)) + ") + ("
+      + valToExprString(CE->getOperand(1)) + ")";
+    break;
+
+  default:
+    assert(0 && "Unsupported operator in ConstantExprToString()");
+    break;
+  }
+
+  return S;
+}
+
+// Print a single constant value.
+void
+Printer::printSingleConstantValue(const Constant* CV)
+{
+  assert(CV->getType() != Type::VoidTy &&
+         CV->getType() != Type::TypeTy &&
+         CV->getType() != Type::LabelTy &&
+         "Unexpected type for Constant");
+  
+  assert((!isa<ConstantArray>(CV) && ! isa<ConstantStruct>(CV))
+         && "Aggregate types should be handled outside this function");
+
+  const Type *type = CV->getType();
+  O << "\t";
+  switch(type->getPrimitiveID())
+    {
+    case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID:
+      O << ".byte";
+      break;
+    case Type::UShortTyID: case Type::ShortTyID:
+      O << ".word";
+      break;
+    case Type::UIntTyID: case Type::IntTyID: case Type::PointerTyID:
+      O << ".long";
+      break;
+    case Type::ULongTyID: case Type::LongTyID:
+      O << ".quad";
+      break;
+    case Type::FloatTyID:
+      O << ".long";
+      break;
+    case Type::DoubleTyID:
+      O << ".quad";
+      break;
+    case Type::ArrayTyID:
+      if ((cast<ArrayType>(type)->getElementType() == Type::UByteTy) ||
+	  (cast<ArrayType>(type)->getElementType() == Type::SByteTy))
+	O << ".string";
+      else
+	assert (0 && "Can't handle printing this type of array");
+      break;
+    default:
+      assert (0 && "Can't handle printing this type of thing");
+      break;
+    }
+  O << "\t";
+  
+  if (type->isPrimitiveType())
+    {
+      if (type->isFloatingPoint()) {
+	// FP Constants are printed as integer constants to avoid losing
+	// precision...
+	double Val = cast<ConstantFP>(CV)->getValue();
+	if (type == Type::FloatTy) {
+	  float FVal = (float)Val;
+	  char *ProxyPtr = (char*)&FVal;        // Abide by C TBAA rules
+	  O << *(unsigned int*)ProxyPtr;            
+	} else if (type == Type::DoubleTy) {
+	  char *ProxyPtr = (char*)&Val;         // Abide by C TBAA rules
+	  O << *(uint64_t*)ProxyPtr;            
+	} else {
+	  assert(0 && "Unknown floating point type!");
+	}
+        
+	O << "\t# " << type->getDescription() << " value: " << Val << "\n";
+      } else {
+	WriteAsOperand(O, CV, false, false) << "\n";
+      }
+    }
+  else if (const ConstantPointerRef* CPR = dyn_cast<ConstantPointerRef>(CV))
+    {
+      // This is a constant address for a global variable or method.
+      // Use the name of the variable or method as the address value.
+      O << getValueName(CPR->getValue()) << "\n";
+    }
+  else if (isa<ConstantPointerNull>(CV))
+    {
+      // Null pointer value
+      O << "0\n";
+    }
+  else if (const ConstantExpr* CE = dyn_cast<ConstantExpr>(CV))
+    {
+      // Constant expression built from operators, constants, and
+      // symbolic addrs
+      O << ConstantExprToString(CE) << "\n";
+    }
+  else
+    {
+      assert(0 && "Unknown elementary type for constant");
+    }
+}
+
+// Can we treat the specified array as a string?  Only if it is an array of
+// ubytes or non-negative sbytes.
+//
+static bool isStringCompatible(const ConstantArray *CVA) {
+  const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
+  if (ETy == Type::UByteTy) return true;
+  if (ETy != Type::SByteTy) return false;
+
+  for (unsigned i = 0; i < CVA->getNumOperands(); ++i)
+    if (cast<ConstantSInt>(CVA->getOperand(i))->getValue() < 0)
+      return false;
+
+  return true;
+}
+
+// toOctal - Convert the low order bits of X into an octal letter
+static inline char toOctal(int X) {
+  return (X&7)+'0';
+}
+
+// getAsCString - Return the specified array as a C compatible string, only if
+// the predicate isStringCompatible is true.
+//
+static std::string getAsCString(const ConstantArray *CVA) {
+  assert(isStringCompatible(CVA) && "Array is not string compatible!");
+
+  std::string Result;
+  const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
+  Result = "\"";
+  for (unsigned i = 0; i < CVA->getNumOperands(); ++i) {
+    unsigned char C = (ETy == Type::SByteTy) ?
+      (unsigned char)cast<ConstantSInt>(CVA->getOperand(i))->getValue() :
+      (unsigned char)cast<ConstantUInt>(CVA->getOperand(i))->getValue();
+
+    if (C == '"') {
+      Result += "\\\"";
+    } else if (C == '\\') {
+      Result += "\\\\";
+    } else if (isprint(C)) {
+      Result += C;
+    } else {
+      switch(C) {
+      case '\a': Result += "\\a"; break;
+      case '\b': Result += "\\b"; break;
+      case '\f': Result += "\\f"; break;
+      case '\n': Result += "\\n"; break;
+      case '\r': Result += "\\r"; break;
+      case '\t': Result += "\\t"; break;
+      case '\v': Result += "\\v"; break;
+      default:
+        Result += '\\';
+        Result += toOctal(C >> 6);
+        Result += toOctal(C >> 3);
+        Result += toOctal(C >> 0);
+        break;
+      }
+    }
+  }
+  Result += "\"";
+  return Result;
+}
+
+// Print a constant value or values (it may be an aggregate).
+// Uses printSingleConstantValue() to print each individual value.
+void
+Printer::printConstantValueOnly(const Constant* CV,
+				int numPadBytesAfter /* = 0 */)
+{
+  const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
+
+  if (CVA && isStringCompatible(CVA))
+    { // print the string alone and return
+      O << "\t" << ".string" << "\t" << getAsCString(CVA) << "\n";
+    }
+  else if (CVA)
+    { // Not a string.  Print the values in successive locations
+      const std::vector<Use> &constValues = CVA->getValues();
+      for (unsigned i=0; i < constValues.size(); i++)
+        printConstantValueOnly(cast<Constant>(constValues[i].get()));
+    }
+  else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
+    { // Print the fields in successive locations. Pad to align if needed!
+      const StructLayout *cvsLayout =
+        TD->getStructLayout(CVS->getType());
+      const std::vector<Use>& constValues = CVS->getValues();
+      unsigned sizeSoFar = 0;
+      for (unsigned i=0, N = constValues.size(); i < N; i++)
+        {
+          const Constant* field = cast<Constant>(constValues[i].get());
+
+          // Check if padding is needed and insert one or more 0s.
+          unsigned fieldSize = TD->getTypeSize(field->getType());
+          int padSize = ((i == N-1? cvsLayout->StructSize
+			  : cvsLayout->MemberOffsets[i+1])
+                         - cvsLayout->MemberOffsets[i]) - fieldSize;
+          sizeSoFar += (fieldSize + padSize);
+
+          // Now print the actual field value
+          printConstantValueOnly(field, padSize);
+        }
+      assert(sizeSoFar == cvsLayout->StructSize &&
+             "Layout of constant struct may be incorrect!");
+    }
+  else
+    printSingleConstantValue(CV);
+
+  if (numPadBytesAfter) {
+    unsigned numBytes = numPadBytesAfter;
+    for ( ; numBytes >= 8; numBytes -= 8)
+      printSingleConstantValue(Constant::getNullValue(Type::ULongTy));
+    if (numBytes >= 4)
+      {
+	printSingleConstantValue(Constant::getNullValue(Type::UIntTy));
+	numBytes -= 4;
+      }
+    while (numBytes--)
+      printSingleConstantValue(Constant::getNullValue(Type::UByteTy));
+  }
+}
 
 // printConstantPool - Print out any constants which have been spilled to
 // memory...
-void Printer::printConstantPool(MachineConstantPool *MCP, const TargetData &TD){
+void Printer::printConstantPool(MachineConstantPool *MCP){
   const std::vector<Constant*> &CP = MCP->getConstants();
   if (CP.empty()) return;
 
   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
     O << "\t.section .rodata\n";
-    O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType()) << "\n";
-    O << ".CPI" << i+ConstIdx << ":\t\t\t\t\t;" << *CP[i] << "\n";
-    O << "\t*Constant output not implemented yet!*\n\n";
+    O << "\t.align " << (unsigned)TD->getTypeAlignment(CP[i]->getType()) << "\n";
+    O << ".CPI" << i+ConstIdx << ":\t\t\t\t\t#" << *CP[i] << "\n";
+    printConstantValueOnly (CP[i]);
   }
   ConstIdx += CP.size();  // Don't recycle constant pool index numbers
 }
 
-/// runOnFunction - This uses the X86InstructionInfo::print method
+/// runOnMachineFunction - This uses the X86InstructionInfo::print method
 /// to print assembly for each instruction.
 bool Printer::runOnMachineFunction(MachineFunction &MF) {
   static unsigned BBNumber = 0;
   const TargetMachine &TM = MF.getTarget();
   const TargetInstrInfo &TII = TM.getInstrInfo();
+  TD = &TM.getTargetData();
 
   // Print out constants referenced by the function
-  printConstantPool(MF.getConstantPool(), TM.getTargetData());
+  printConstantPool(MF.getConstantPool());
 
   // Print out labels for the function.
   O << "\t.text\n";
   O << "\t.align 16\n";
-  O << "\t.globl\t" << MF.getFunction()->getName() << "\n";
-  O << "\t.type\t" << MF.getFunction()->getName() << ", @function\n";
-  O << MF.getFunction()->getName() << ":\n";
+  O << "\t.globl\t" << getValueName(MF.getFunction()) << "\n";
+  O << "\t.type\t" << getValueName(MF.getFunction()) << ", @function\n";
+  O << getValueName(MF.getFunction()) << ":\n";
+
+  NumberForBB.clear();
+  for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
+       I != E; ++I) {
+    NumberForBB[I->getBasicBlock()] = BBNumber++;
+  }
 
   // Print out code for the function.
   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
        I != E; ++I) {
     // Print a label for the basic block.
-    O << ".BB" << BBNumber++ << ":\n";
+    O << ".BB" << NumberForBB[I->getBasicBlock()] << ":\t# "
+      << I->getBasicBlock()->getName() << "\n";
     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
 	 II != E; ++II) {
       // Print the assembly for the instruction.
@@ -90,20 +444,20 @@
 
 static bool isScale(const MachineOperand &MO) {
   return MO.isImmediate() &&
-           (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||
-            MO.getImmedValue() == 4 || MO.getImmedValue() == 8);
+    (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||
+     MO.getImmedValue() == 4 || MO.getImmedValue() == 8);
 }
 
 static bool isMem(const MachineInstr *MI, unsigned Op) {
   if (MI->getOperand(Op).isFrameIndex()) return true;
   if (MI->getOperand(Op).isConstantPoolIndex()) return true;
   return Op+4 <= MI->getNumOperands() &&
-         MI->getOperand(Op  ).isRegister() &&isScale(MI->getOperand(Op+1)) &&
-         MI->getOperand(Op+2).isRegister() &&MI->getOperand(Op+3).isImmediate();
+    MI->getOperand(Op  ).isRegister() &&isScale(MI->getOperand(Op+1)) &&
+    MI->getOperand(Op+2).isRegister() &&MI->getOperand(Op+3).isImmediate();
 }
 
 static void printOp(std::ostream &O, const MachineOperand &MO,
-                    const MRegisterInfo &RI) {
+                    const MRegisterInfo &RI, bool elideOffsetKeyword = false) {
   switch (MO.getType()) {
   case MachineOperand::MO_VirtualRegister:
     if (Value *V = MO.getVRegValueOrNull()) {
@@ -123,29 +477,30 @@
     O << (int)MO.getImmedValue();
     return;
   case MachineOperand::MO_PCRelativeDisp:
-    O << "<" << MO.getVRegValue()->getName() << ">";
+    O << ".BB" << NumberForBB[MO.getVRegValue()] << " # PC rel: "
+      << MO.getVRegValue()->getName();
     return;
   case MachineOperand::MO_GlobalAddress:
-    O << "<" << MO.getGlobal()->getName() << ">";
+    if (!elideOffsetKeyword) O << "OFFSET "; O << getValueName(MO.getGlobal());
     return;
   case MachineOperand::MO_ExternalSymbol:
-    O << "<" << MO.getSymbolName() << ">";
+    O << MO.getSymbolName();
     return;
   default:
-    O << "<unknown op ty>"; return;    
+    O << "<unknown operand type>"; return;    
   }
 }
 
 static const std::string sizePtr(const TargetInstrDescriptor &Desc) {
   switch (Desc.TSFlags & X86II::ArgMask) {
-    default: assert(0 && "Unknown arg size!");
-    case X86II::Arg8:   return "BYTE PTR"; 
-    case X86II::Arg16:  return "WORD PTR"; 
-    case X86II::Arg32:  return "DWORD PTR"; 
-    case X86II::Arg64:  return "QWORD PTR"; 
-    case X86II::ArgF32:  return "DWORD PTR"; 
-    case X86II::ArgF64:  return "QWORD PTR"; 
-    case X86II::ArgF80:  return "XWORD PTR"; 
+  default: assert(0 && "Unknown arg size!");
+  case X86II::Arg8:   return "BYTE PTR"; 
+  case X86II::Arg16:  return "WORD PTR"; 
+  case X86II::Arg32:  return "DWORD PTR"; 
+  case X86II::Arg64:  return "QWORD PTR"; 
+  case X86II::ArgF32:  return "DWORD PTR"; 
+  case X86II::ArgF64:  return "QWORD PTR"; 
+  case X86II::ArgF80:  return "XWORD PTR"; 
   }
 }
 
@@ -208,6 +563,10 @@
 
   switch (Desc.TSFlags & X86II::FormMask) {
   case X86II::Pseudo:
+    // Print pseudo-instructions as comments; either they should have been
+    // turned into real instructions by now, or they don't need to be
+    // seen by the assembler (e.g., IMPLICIT_USEs.)
+    O << "# ";
     if (Opcode == X86::PHI) {
       printOp(O, MI->getOperand(0), RI);
       O << " = phi ";
@@ -256,7 +615,7 @@
     O << getName(MI->getOpcode()) << " ";
 
     if (MI->getNumOperands() == 1) {
-      printOp(O, MI->getOperand(0), RI);
+      printOp(O, MI->getOperand(0), RI, true); // Don't print "OFFSET"...
     }
     O << "\n";
     return;
@@ -409,7 +768,7 @@
             MI->getOperand(1).isRegister() || MI->getOperand(1).isImmediate())&&
            "Bad MRMSxR format!");
     assert((MI->getNumOperands() < 3 ||
-        (MI->getOperand(1).isRegister() && MI->getOperand(2).isImmediate())) &&
+	    (MI->getOperand(1).isRegister() && MI->getOperand(2).isImmediate())) &&
            "Bad MRMSxR format!");
 
     if (MI->getNumOperands() > 1 && MI->getOperand(1).isRegister() && 
@@ -456,4 +815,59 @@
   default:
     O << "\tUNKNOWN FORM:\t\t-"; MI->print(O, TM); break;
   }
+}
+
+bool Printer::doInitialization(Module &M)
+{
+  // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly,
+  // with no % decorations on register names.
+  O << "\t.intel_syntax noprefix\n";
+
+  // Ripped from CWriter:
+  // Calculate which global values have names that will collide when we throw
+  // away type information.
+  {  // Scope to delete the FoundNames set when we are done with it...
+    std::set<std::string> FoundNames;
+    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+      if (I->hasName())                      // If the global has a name...
+        if (FoundNames.count(I->getName()))  // And the name is already used
+          MangledGlobals.insert(I);          // Mangle the name
+        else
+          FoundNames.insert(I->getName());   // Otherwise, keep track of name
+
+    for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
+      if (I->hasName())                      // If the global has a name...
+        if (FoundNames.count(I->getName()))  // And the name is already used
+          MangledGlobals.insert(I);          // Mangle the name
+        else
+          FoundNames.insert(I->getName());   // Otherwise, keep track of name
+  }
+
+  return false; // success
+}
+
+bool Printer::doFinalization(Module &M)
+{
+  // Print out module-level global variables here.
+  for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
+    std::string name(getValueName(I));
+    if (I->hasInitializer()) {
+      Constant *C = I->getInitializer();
+      O << "\t.data\n";
+      O << "\t.globl " << name << "\n";
+      O << "\t.type " << name << ", at object\n";
+      O << "\t.size " << name << ","
+	<< (unsigned)TD->getTypeSize(I->getType()) << "\n";
+      O << "\t.align " << (unsigned)TD->getTypeAlignment(C->getType()) << "\n";
+      O << name << ":\t\t\t\t\t#" << *C << "\n";
+      printConstantValueOnly (C);
+    } else {
+      O << "\t.globl " << name << "\n";
+      O << "\t.comm " << name << ", "
+        << (unsigned)TD->getTypeSize(I->getType()) << ", "
+        << (unsigned)TD->getTypeAlignment(I->getType()) << "\n";
+    }
+  }
+  MangledGlobals.clear();
+  return false; // success
 }


Index: llvm/lib/Target/X86/X86InstrInfo.def
diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.57 llvm/lib/Target/X86/X86InstrInfo.def:1.57.2.1
--- llvm/lib/Target/X86/X86InstrInfo.def:1.57	Thu Jun  5 14:30:30 2003
+++ llvm/lib/Target/X86/X86InstrInfo.def	Thu Jun 26 16:35:24 2003
@@ -48,7 +48,10 @@
 
 // Arguments to be passed into the I macro
 //  #1: Enum name - This ends up being the opcode symbol in the X86 namespace
-//  #2: Opcode name, as used by the gnu assembler
+//  #2: Opcode name, as used by the Intel assembler. This should be in
+//      ALL CAPS for pseudo-instructions (which the assembler should never
+//      see), or all lowercase for real instructions (which the assembler
+//      should see).
 //  #3: The base opcode for the instruction
 //  #4: Instruction Flags - This should be a field or'd together that contains
 //      constants from the TargetInstrInfo.h file.
@@ -60,7 +63,7 @@
 //
 
 // The first instruction must always be the PHI instruction:
-I(PHI         , "phi",      0,             0, X86II::Pseudo              , NoIR, NoIR)
+I(PHI         , "PHI",      0,             0, X86II::Pseudo              , NoIR, NoIR)
 
 // The second instruction must always be the noop instruction:
 I(NOOP        , "nop",   0x90,             0, X86II::RawFrm | X86II::Void, NoIR, NoIR)             // nop
@@ -72,18 +75,18 @@
 // instruction turns into a noop, but if the frame pointer is retained, this
 // turns into a 'sub ESP, <amount>'.
 //
-I(ADJCALLSTACKDOWN, "adjcallstackdown", 0, 0, X86II::Pseudo,               NoIR, NoIR)
+I(ADJCALLSTACKDOWN, "ADJCALLSTACKDOWN", 0, 0, X86II::Pseudo,               NoIR, NoIR)
 
 // This instruction is used to mark readjustment of the stack after a function
 // call.  If the frame pointer is retained, this becomes a 'add ESP, <amount>'
 // instruction after the call.
-I(ADJCALLSTACKUP  , "adjcallstackup"  , 0, 0, X86II::Pseudo,               NoIR, NoIR)
+I(ADJCALLSTACKUP  , "ADJCALLSTACKUP"  , 0, 0, X86II::Pseudo,               NoIR, NoIR)
 
 // This pseudo-instruction is used to record implicit uses of physical registers
 // at the end of the function.  This ensures that bad things aren't done to
 // registes that are live on exit from the function (for example, EAX).
 //
-I(IMPLICIT_USE, "implicit_use", 0, 0, X86II::Pseudo, NoIR, NoIR)
+I(IMPLICIT_USE, "IMPLICIT_USE", 0, 0, X86II::Pseudo, NoIR, NoIR)
 
 
 // Flow control instructions
@@ -163,22 +166,24 @@
 
 I(MULr8       , "mul",  0xF6,             0, X86II::MRMS4r | X86II::Void, O_AL, O_AX)       // AX   = AL*R8
 I(MULr16      , "mul",  0xF7,             0, X86II::MRMS4r | X86II::Void |                  // DX:AX= AX*R16
-                                              X86II::OpSize, O_AX, T_AXDX)
+                                             X86II::OpSize, O_AX, T_AXDX)
 I(MULr32      , "mul",  0xF7,             0, X86II::MRMS4r | X86II::Void, O_EAX, T_EAXEDX)  // ED:EA= EA*R32
 
+I(IMULr16     , "imul", 0xAF, M_2_ADDR_FLAG, X86II::MRMSrcReg | X86II::TB |                 // R16 *= R16
+                                             X86II::OpSize, NoIR, NoIR)
+I(IMULr32     , "imul", 0xAF, M_2_ADDR_FLAG, X86II::MRMSrcReg | X86II::TB, NoIR, NoIR)      // R32 *= R32
+
 // unsigned division/remainder
 I(DIVr8       , "div",  0xF6,             0, X86II::MRMS6r | X86II::Void, O_AX, O_AX)       // AX/r8= AL&AH
 I(DIVr16      , "div",  0xF7,             0, X86II::MRMS6r | X86II::Void |                  // ED:EA/r16=AX&DX
-                                              X86II::OpSize, T_AXDX, T_AXDX)
-I(DIVr32      , "div",  0xF7,             0, X86II::MRMS6r | X86II::Void, T_EAXEDX,
-                                                                           T_EAXEDX)         // ED:EA/r32=EA&ED
+                                             X86II::OpSize, T_AXDX, T_AXDX)
+I(DIVr32      , "div",  0xF7,             0, X86II::MRMS6r | X86II::Void, T_EAXEDX,T_EAXEDX)// ED:EA/r32=EA&ED
 
 // signed division/remainder
 I(IDIVr8      , "idiv", 0xF6,             0, X86II::MRMS7r | X86II::Void, O_AX, O_AX)       // AX/r8= AL&AH
 I(IDIVr16     , "idiv", 0xF7,             0, X86II::MRMS7r | X86II::Void |                  // DA/r16=AX&DX
-                                              X86II::OpSize, T_AXDX, T_AXDX)
-I(IDIVr32     , "idiv", 0xF7,             0, X86II::MRMS7r | X86II::Void, T_EAXEDX,
-                                                                           T_EAXEDX)         // DA/r32=EAX&DX
+                                             X86II::OpSize, T_AXDX, T_AXDX)
+I(IDIVr32     , "idiv", 0xF7,             0, X86II::MRMS7r | X86II::Void, T_EAXEDX,T_EAXEDX)// DA/r32=EAX&DX
 
 // Logical operators
 I(ANDrr8      , "and",   0x20, M_2_ADDR_FLAG, X86II::MRMDestReg, NoIR, NoIR)                 // R8  &= R8
@@ -260,12 +265,12 @@
 
 
 // Integer comparisons
-I(CMPrr8      , "cmpb",  0x38,             0, X86II::Void | X86II::MRMDestReg                , NoIR, NoIR) // compare R8,R8
-I(CMPrr16     , "cmpw",  0x39,             0, X86II::Void | X86II::MRMDestReg | X86II::OpSize, NoIR, NoIR) // compare R16,R16
-I(CMPrr32     , "cmpl",  0x39,             0, X86II::Void | X86II::MRMDestReg                , NoIR, NoIR) // compare R32,R32
-I(CMPri8      , "cmpb",  0x80,             0, X86II::Void | X86II::MRMS7r     | X86II::Arg8  , NoIR, NoIR) // compare R8, imm8
-I(CMPri16     , "cmpw",  0x81,             0, X86II::Void | X86II::MRMS7r     | X86II::Arg16 | X86II::OpSize, NoIR, NoIR) // compare R8, imm8
-I(CMPri32     , "cmpl",  0x81,             0, X86II::Void | X86II::MRMS7r     | X86II::Arg32 , NoIR, NoIR) // compare R8, imm8
+I(CMPrr8      , "cmp",  0x38,             0, X86II::Void | X86II::MRMDestReg                , NoIR, NoIR) // compare R8,R8
+I(CMPrr16     , "cmp",  0x39,             0, X86II::Void | X86II::MRMDestReg | X86II::OpSize, NoIR, NoIR) // compare R16,R16
+I(CMPrr32     , "cmp",  0x39,             0, X86II::Void | X86II::MRMDestReg                , NoIR, NoIR) // compare R32,R32
+I(CMPri8      , "cmp",  0x80,             0, X86II::Void | X86II::MRMS7r     | X86II::Arg8  , NoIR, NoIR) // compare R8, imm8
+I(CMPri16     , "cmp",  0x81,             0, X86II::Void | X86II::MRMS7r     | X86II::Arg16 | X86II::OpSize, NoIR, NoIR) // compare R8, imm8
+I(CMPri32     , "cmp",  0x81,             0, X86II::Void | X86II::MRMS7r     | X86II::Arg32 , NoIR, NoIR) // compare R8, imm8
 
 // Sign extenders (first 3 are good for DIV/IDIV; the others are more general)
 I(CBW         , "cbw",   0x98,             0, X86II::Void | X86II::RawFrm | X86II::OpSize, O_AL, O_AH)     // AX = signext(AL)
@@ -299,60 +304,60 @@
 I(FpSETRESULT , "FSETRESULT",0, M_PSEUDO_FLAG | M_TERMINATOR_FLAG,         X86II::Void | X86II::Pseudo | X86II::SpecialFP, NoIR, NoIR)  // ST(0) = FPR
 
 // Floating point loads & stores...            PREFIX      ARGTYPE         ENCODING        FP INST TYPE      REF   MOD
-I(FLDr32      , "fld32",   0xD9,            0,                           X86II::ArgF32 | X86II::MRMS0m | X86II::ZeroArgFP, NoIR, NoIR)   // load float
-I(FLDr64      , "fld64",   0xDD,            0,                           X86II::ArgF64 | X86II::MRMS0m | X86II::ZeroArgFP, NoIR, NoIR)   // load double
-I(FLDr80      , "fld80",   0xDB,            0,                           X86II::ArgF80 | X86II::MRMS5m | X86II::ZeroArgFP, NoIR, NoIR)   // load extended
+I(FLDr32      , "fld",   0xD9,            0,                           X86II::ArgF32 | X86II::MRMS0m | X86II::ZeroArgFP, NoIR, NoIR)   // load float
+I(FLDr64      , "fld",   0xDD,            0,                           X86II::ArgF64 | X86II::MRMS0m | X86II::ZeroArgFP, NoIR, NoIR)   // load double
+I(FLDr80      , "fld",   0xDB,            0,                           X86II::ArgF80 | X86II::MRMS5m | X86II::ZeroArgFP, NoIR, NoIR)   // load extended
 I(FLDrr       , "fld"  ,   0xC0,            0, X86II::D9 |               X86II::ArgF80 | X86II::AddRegFrm                , NoIR, NoIR)   // push(ST(i))
-I(FILDr16     , "fild16",  0xDF,            0,                           X86II::Arg16  | X86II::MRMS0m | X86II::ZeroArgFP, NoIR, NoIR)   // load signed short
-I(FILDr32     , "fild32",  0xDB,            0,                           X86II::Arg32  | X86II::MRMS0m | X86II::ZeroArgFP, NoIR, NoIR)   // load signed int
-I(FILDr64     , "fild64",  0xDF,            0,                           X86II::Arg64  | X86II::MRMS5m | X86II::ZeroArgFP, NoIR, NoIR)   // load signed long
+I(FILDr16     , "fild",  0xDF,            0,                           X86II::Arg16  | X86II::MRMS0m | X86II::ZeroArgFP, NoIR, NoIR)   // load signed short
+I(FILDr32     , "fild",  0xDB,            0,                           X86II::Arg32  | X86II::MRMS0m | X86II::ZeroArgFP, NoIR, NoIR)   // load signed int
+I(FILDr64     , "fild",  0xDF,            0,                           X86II::Arg64  | X86II::MRMS5m | X86II::ZeroArgFP, NoIR, NoIR)   // load signed long
 
 
-I(FSTr32      , "fst32",   0xD9,            0,             X86II::Void | X86II::ArgF32 | X86II::MRMS2m | X86II::OneArgFP , NoIR, NoIR)   // store float
-I(FSTr64      , "fst64",   0xDD,            0,             X86II::Void | X86II::ArgF64 | X86II::MRMS2m | X86II::OneArgFP , NoIR, NoIR)   // store double
-I(FSTPr32     , "fst32p",  0xD9,            0,             X86II::Void | X86II::ArgF32 | X86II::MRMS3m                   , NoIR, NoIR)   // store float, pop
-I(FSTPr64     , "fst64p",  0xDD,            0,             X86II::Void | X86II::ArgF64 | X86II::MRMS3m                   , NoIR, NoIR)   // store double, pop
-I(FSTPr80     , "fst80p",  0xDB,            0,             X86II::Void | X86II::ArgF80 | X86II::MRMS7m | X86II::OneArgFP , NoIR, NoIR)   // store extended, pop
+I(FSTr32      , "fst",   0xD9,            0,             X86II::Void | X86II::ArgF32 | X86II::MRMS2m | X86II::OneArgFP , NoIR, NoIR)   // store float
+I(FSTr64      , "fst",   0xDD,            0,             X86II::Void | X86II::ArgF64 | X86II::MRMS2m | X86II::OneArgFP , NoIR, NoIR)   // store double
+I(FSTPr32     , "fstp",  0xD9,            0,             X86II::Void | X86II::ArgF32 | X86II::MRMS3m                   , NoIR, NoIR)   // store float, pop
+I(FSTPr64     , "fstp",  0xDD,            0,             X86II::Void | X86II::ArgF64 | X86II::MRMS3m                   , NoIR, NoIR)   // store double, pop
+I(FSTPr80     , "fstp",  0xDB,            0,             X86II::Void | X86II::ArgF80 | X86II::MRMS7m | X86II::OneArgFP , NoIR, NoIR)   // store extended, pop
 I(FSTrr       , "fst"  ,   0xD0,            0, X86II::DD | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm                , NoIR, NoIR)   // ST(i) = ST(0)
 I(FSTPrr      , "fstp" ,   0xD8,            0, X86II::DD | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm                , NoIR, NoIR)   // ST(i) = ST(0), pop
 
-I(FISTr16     , "fist16",  0xDF,            0,             X86II::Void | X86II::Arg16  | X86II::MRMS2m | X86II::OneArgFP , NoIR, NoIR)   // store signed short
-I(FISTr32     , "fist32",  0xDB,            0,             X86II::Void | X86II::Arg32  | X86II::MRMS2m | X86II::OneArgFP , NoIR, NoIR)   // store signed int
-I(FISTPr16    , "fist16p", 0xDF,            0,             X86II::Void | X86II::Arg16  | X86II::MRMS3m                   , NoIR, NoIR)   // store short, pop
-I(FISTPr32    , "fist32p", 0xDB,            0,             X86II::Void | X86II::Arg32  | X86II::MRMS3m                   , NoIR, NoIR)   // store int, pop
-I(FISTPr64    , "fist64p", 0xDF,            0,             X86II::Void | X86II::Arg64  | X86II::MRMS7m | X86II::OneArgFP , NoIR, NoIR)   // store long, pop
+I(FISTr16     , "fist",  0xDF,            0,             X86II::Void | X86II::Arg16  | X86II::MRMS2m | X86II::OneArgFP , NoIR, NoIR)   // store signed short
+I(FISTr32     , "fist",  0xDB,            0,             X86II::Void | X86II::Arg32  | X86II::MRMS2m | X86II::OneArgFP , NoIR, NoIR)   // store signed int
+I(FISTPr16    , "fistp", 0xDF,            0,             X86II::Void | X86II::Arg16  | X86II::MRMS3m                   , NoIR, NoIR)   // store short, pop
+I(FISTPr32    , "fistp", 0xDB,            0,             X86II::Void | X86II::Arg32  | X86II::MRMS3m                   , NoIR, NoIR)   // store int, pop
+I(FISTPr64    , "fistp", 0xDF,            0,             X86II::Void | X86II::Arg64  | X86II::MRMS7m | X86II::OneArgFP , NoIR, NoIR)   // store long, pop
 
 
 I(FXCH        , "fxch" , 0xC8,              0, X86II::D9 | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm                , O_ST0, O_ST0) // fxch ST(i), ST(0)
 
 // Floating point constant loads...
-I(FLD0        , "fld0" , 0xEE,              0, X86II::D9 |               X86II::ArgF80 | X86II::RawFrm | X86II::ZeroArgFP, NoIR, NoIR)   // load +0.0
+I(FLD0        , "fldz" , 0xEE,              0, X86II::D9 |               X86II::ArgF80 | X86II::RawFrm | X86II::ZeroArgFP, NoIR, NoIR)   // load +0.0
 I(FLD1        , "fld1" , 0xE8,              0, X86II::D9 |               X86II::ArgF80 | X86II::RawFrm | X86II::ZeroArgFP, NoIR, NoIR)   // load +1.0
 
 // Binary arithmetic operations...
-I(FADDST0r    , "fadd_0",   0xC0,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(0) + ST(i)
-I(FADDrST0    , "fadd_i",   0xC0,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) + ST(0)
-I(FADDPrST0   , "faddp_i",  0xC0,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) + ST(0), pop
-
-I(FSUBRST0r   , "fsubr_0" , 0xE8,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(i) - ST(0)
-I(FSUBrST0    , "fsub_i"  , 0xE8,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) - ST(0)
-I(FSUBPrST0   , "fsubp_i" , 0xE8,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) - ST(0), pop
-
-I(FSUBST0r    , "fsub_0"  , 0xE0,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(0) - ST(i)
-I(FSUBRrST0   , "fsubr_i" , 0xE0,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(0) - ST(i)
-I(FSUBRPrST0  , "fsubrp_i", 0xE0,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(0) - ST(i), pop
-
-I(FMULST0r    , "fmul_0",   0xC8,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(0) * ST(i)
-I(FMULrST0    , "fmul_i",   0xC8,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) * ST(0)
-I(FMULPrST0   , "fmulp_i",  0xC8,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) * ST(0), pop
-
-I(FDIVRST0r   , "fdivr_0" , 0xF8,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(i) / ST(0)
-I(FDIVrST0    , "fdiv_i"  , 0xF8,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) / ST(0)
-I(FDIVPrST0   , "fdivp_i" , 0xF8,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) / ST(0), pop
-
-I(FDIVST0r    , "fdiv_0"  , 0xF0,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(0) / ST(i)
-I(FDIVRrST0   , "fdivr_i" , 0xF0,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(0) / ST(i)
-I(FDIVRPrST0  , "fdivrp_i", 0xF0,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(0) / ST(i), pop
+I(FADDST0r    , "fadd",   0xC0,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(0) + ST(i)
+I(FADDrST0    , "fadd",   0xC0,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) + ST(0)
+I(FADDPrST0   , "faddp",  0xC0,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) + ST(0), pop
+
+I(FSUBRST0r   , "fsubr" , 0xE8,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(i) - ST(0)
+I(FSUBrST0    , "fsub"  , 0xE8,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) - ST(0)
+I(FSUBPrST0   , "fsubp" , 0xE8,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) - ST(0), pop
+
+I(FSUBST0r    , "fsub"  , 0xE0,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(0) - ST(i)
+I(FSUBRrST0   , "fsubr" , 0xE0,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(0) - ST(i)
+I(FSUBRPrST0  , "fsubrp", 0xE0,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(0) - ST(i), pop
+
+I(FMULST0r    , "fmul",   0xC8,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(0) * ST(i)
+I(FMULrST0    , "fmul",   0xC8,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) * ST(0)
+I(FMULPrST0   , "fmulp",  0xC8,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) * ST(0), pop
+
+I(FDIVRST0r   , "fdivr" , 0xF8,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(i) / ST(0)
+I(FDIVrST0    , "fdiv"  , 0xF8,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) / ST(0)
+I(FDIVPrST0   , "fdivp" , 0xF8,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(i) / ST(0), pop
+
+I(FDIVST0r    , "fdiv"  , 0xF0,           0, X86II::D8 |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(0) = ST(0) / ST(i)
+I(FDIVRrST0   , "fdivr" , 0xF0,           0, X86II::DC |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(0) / ST(i)
+I(FDIVRPrST0  , "fdivrp", 0xF0,           0, X86II::DE |               X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // ST(i) = ST(0) / ST(i), pop
 
 // Floating point compares
 I(FUCOMr      , "fucom"   , 0xE0,           0, X86II::DD | X86II::Void | X86II::ArgF80 | X86II::AddRegFrm               , NoIR, NoIR)   // FPSW = compare ST(0) with ST(i)


Index: llvm/lib/Target/X86/X86TargetMachine.cpp
diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.17 llvm/lib/Target/X86/X86TargetMachine.cpp:1.17.2.1
--- llvm/lib/Target/X86/X86TargetMachine.cpp:1.17	Sat Apr 26 15:11:04 2003
+++ llvm/lib/Target/X86/X86TargetMachine.cpp	Thu Jun 26 16:35:24 2003
@@ -41,6 +41,19 @@
   FrameInfo(TargetFrameInfo::StackGrowsDown, 8/*16 for SSE*/, 4) {
 }
 
+// llc backend for x86
+bool X86TargetMachine::addPassesToEmitAssembly(PassManager &PM,
+					       std::ostream &Out) {
+  PM.add(createLowerSwitchPass());
+  PM.add(createSimpleX86InstructionSelector(*this));
+  PM.add(createLocalRegisterAllocator());
+  PM.add(createX86FloatingPointStackifierPass());
+  PM.add(createPrologEpilogCodeInserter());
+  PM.add(createX86PeepholeOptimizerPass());
+  PM.add(createX86CodePrinterPass(Out));
+  return false; // success!
+}
+
 /// addPassesToJITCompile - Add passes to the specified pass manager to
 /// implement a fast dynamic compiler for this target.  Return true if this is
 /// not supported for this target.


Index: llvm/lib/Target/X86/X86TargetMachine.h
diff -u llvm/lib/Target/X86/X86TargetMachine.h:1.9 llvm/lib/Target/X86/X86TargetMachine.h:1.9.2.1
--- llvm/lib/Target/X86/X86TargetMachine.h:1.9	Sat Dec 28 21:13:05 2002
+++ llvm/lib/Target/X86/X86TargetMachine.h	Thu Jun 26 16:35:24 2003
@@ -42,6 +42,8 @@
   ///
   virtual bool addPassesToEmitMachineCode(PassManager &PM,
                                           MachineCodeEmitter &MCE);
+  
+  virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
 };
 
 #endif





More information about the llvm-commits mailing list