Let me introduce you to the early stages of the llvm backend for the alpha processor
authorAndrew Lenharth <andrewl@lenharth.org>
Sat, 22 Jan 2005 23:41:55 +0000 (23:41 +0000)
committerAndrew Lenharth <andrewl@lenharth.org>
Sat, 22 Jan 2005 23:41:55 +0000 (23:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19764 91177308-0d34-0410-b5e6-96231b3b80d8

15 files changed:
lib/Target/Alpha/Alpha.h [new file with mode: 0644]
lib/Target/Alpha/Alpha.td [new file with mode: 0644]
lib/Target/Alpha/AlphaAsmPrinter.cpp [new file with mode: 0644]
lib/Target/Alpha/AlphaISelPattern.cpp [new file with mode: 0644]
lib/Target/Alpha/AlphaInstrBuilder.h [new file with mode: 0644]
lib/Target/Alpha/AlphaInstrFormats.td [new file with mode: 0644]
lib/Target/Alpha/AlphaInstrInfo.cpp [new file with mode: 0644]
lib/Target/Alpha/AlphaInstrInfo.h [new file with mode: 0644]
lib/Target/Alpha/AlphaInstrInfo.td [new file with mode: 0644]
lib/Target/Alpha/AlphaRegisterInfo.cpp [new file with mode: 0644]
lib/Target/Alpha/AlphaRegisterInfo.h [new file with mode: 0644]
lib/Target/Alpha/AlphaRegisterInfo.td [new file with mode: 0644]
lib/Target/Alpha/AlphaTargetMachine.cpp [new file with mode: 0644]
lib/Target/Alpha/AlphaTargetMachine.h [new file with mode: 0644]
lib/Target/Alpha/Makefile [new file with mode: 0644]

diff --git a/lib/Target/Alpha/Alpha.h b/lib/Target/Alpha/Alpha.h
new file mode 100644 (file)
index 0000000..04daaff
--- /dev/null
@@ -0,0 +1,41 @@
+//===-- Alpha.h - Top-level interface for Alpha representation -*- C++ -*-//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file contains the entry points for global functions defined in the LLVM
+// Alpha back-end.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TARGET_ALPHA_H
+#define TARGET_ALPHA_H
+
+#include <iosfwd>
+
+namespace llvm {
+
+  class FunctionPass;
+  class TargetMachine;
+
+  FunctionPass *createAlphaSimpleInstructionSelector(TargetMachine &TM);
+  FunctionPass *createAlphaCodePrinterPass(std::ostream &OS,
+                                             TargetMachine &TM);
+  FunctionPass *createAlphaPatternInstructionSelector(TargetMachine &TM);
+
+} // end namespace llvm;
+
+// Defines symbolic names for Alpha registers.  This defines a mapping from
+// register name to register number.
+//
+#include "AlphaGenRegisterNames.inc"
+
+// Defines symbolic names for the Alpha instructions.
+//
+#include "AlphaGenInstrNames.inc"
+
+#endif
diff --git a/lib/Target/Alpha/Alpha.td b/lib/Target/Alpha/Alpha.td
new file mode 100644 (file)
index 0000000..e48bea1
--- /dev/null
@@ -0,0 +1,56 @@
+//===- Alpha.td - Describe the Alpha Target Machine ----*- tablegen -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+// Get the target-independent interfaces which we are implementing...
+//
+include "../Target.td"
+
+//Alpha is little endian
+
+//===----------------------------------------------------------------------===//
+// Register File Description
+//===----------------------------------------------------------------------===//
+
+include "AlphaRegisterInfo.td"
+
+//===----------------------------------------------------------------------===//
+// Instruction Descriptions
+//===----------------------------------------------------------------------===//
+
+include "AlphaInstrInfo.td"
+
+def AlphaInstrInfo : InstrInfo {
+  let PHIInst = PHI;
+
+  // Define how we want to layout our target-specific information field.
+ // let TSFlagsFields = [];
+ // let TSFlagsShifts = [];
+}
+
+def Alpha : Target {
+  // Pointers on Alpha are 64-bits in size.
+  let PointerType = i64;
+
+  let CalleeSavedRegisters = 
+       //saved regs
+       [R9, R10, R11, R12, R13, R14, 
+       //Frame pointer
+       R15, 
+       //return address
+       R26, 
+       //Stack Pointer
+       R30,
+         F2, F3, F4, F5, F6, F7, F8, F9];
+
+  // Pull in Instruction Info:
+  let InstructionSet = AlphaInstrInfo;
+}
diff --git a/lib/Target/Alpha/AlphaAsmPrinter.cpp b/lib/Target/Alpha/AlphaAsmPrinter.cpp
new file mode 100644 (file)
index 0000000..85feb9d
--- /dev/null
@@ -0,0 +1,319 @@
+//===-- AlphaAsmPrinter.cpp - Alpha LLVM assembly writer --------------===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file contains a printer that converts from our internal representation
+// of machine-dependent LLVM code to GAS-format Alpha assembly language.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Alpha.h"
+#include "AlphaInstrInfo.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
+
+#include "llvm/Support/Mangler.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
+#include <cctype>
+using namespace llvm;
+
+namespace {
+  Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
+
+  struct AlphaAsmPrinter : public AsmPrinter {
+
+    /// Unique incrementer for label values for referencing Global values.
+    ///
+    unsigned LabelNumber;
+     AlphaAsmPrinter(std::ostream &o, TargetMachine &tm) 
+      : AsmPrinter(o, tm), LabelNumber(0)
+    { }
+
+    /// We name each basic block in a Function with a unique number, so
+    /// that we can consistently refer to them later. This is cleared
+    /// at the beginning of each call to runOnMachineFunction().
+    ///
+    typedef std::map<const Value *, unsigned> ValueMapTy;
+    ValueMapTy NumberForBB;
+
+    virtual const char *getPassName() const {
+      return "Alpha Assembly Printer";
+    }
+    bool printInstruction(const MachineInstr *MI);
+    void printOp(const MachineOperand &MO, bool IsCallOp = false);
+    void printConstantPool(MachineConstantPool *MCP);
+    void printOperand(const MachineInstr *MI, int opNum, MVT::ValueType VT);
+    void printBaseOffsetPair (const MachineInstr *MI, int i, bool brackets=true);
+    void printMachineInstruction(const MachineInstr *MI);
+    bool runOnMachineFunction(MachineFunction &F);    
+    bool doInitialization(Module &M);
+    bool doFinalization(Module &M);
+  };
+} // end of anonymous namespace
+
+/// createAlphaCodePrinterPass - Returns a pass that prints the Alpha
+/// assembly code for a MachineFunction to the given output stream,
+/// using the given target machine description.  This should work
+/// regardless of whether the function is in SSA form.
+///
+FunctionPass *llvm::createAlphaCodePrinterPass (std::ostream &o,
+                                                  TargetMachine &tm) {
+  return new AlphaAsmPrinter(o, tm);
+}
+
+#include "AlphaGenAsmWriter.inc"
+
+void AlphaAsmPrinter::printOperand(const MachineInstr *MI, int opNum, MVT::ValueType VT)
+{
+  const MachineOperand &MO = MI->getOperand(opNum);
+  if (MO.getType() == MachineOperand::MO_MachineRegister) {
+    assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??");
+    O << LowercaseString(TM.getRegisterInfo()->get(MO.getReg()).Name);
+  } else if (MO.isImmediate()) {
+    O << MO.getImmedValue();
+  } else {
+    printOp(MO);
+  }
+}
+
+
+void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
+  const MRegisterInfo &RI = *TM.getRegisterInfo();
+  int new_symbol;
+  
+  switch (MO.getType()) {
+  case MachineOperand::MO_VirtualRegister:
+    if (Value *V = MO.getVRegValueOrNull()) {
+      O << "<" << V->getName() << ">";
+      return;
+    }
+    // FALLTHROUGH
+  case MachineOperand::MO_MachineRegister:
+  case MachineOperand::MO_CCRegister:
+    O << LowercaseString(RI.get(MO.getReg()).Name);
+    return;
+
+  case MachineOperand::MO_SignExtendedImmed:
+  case MachineOperand::MO_UnextendedImmed:
+    std::cerr << "printOp() does not handle immediate values\n";
+    abort();
+    return;
+
+  case MachineOperand::MO_PCRelativeDisp:
+    std::cerr << "Shouldn't use addPCDisp() when building PPC MachineInstrs";
+    abort();
+    return;
+    
+  case MachineOperand::MO_MachineBasicBlock: {
+    MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
+    O << "$LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
+      << "_" << MBBOp->getNumber() << "\t" << CommentString << " "
+      << MBBOp->getBasicBlock()->getName();
+    return;
+  }
+
+  case MachineOperand::MO_ConstantPoolIndex:
+    O << "$CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex();
+    return;
+
+  case MachineOperand::MO_ExternalSymbol:
+    O << MO.getSymbolName();
+    return;
+
+  case MachineOperand::MO_GlobalAddress: 
+    //std::cerr << "Global Addresses?  Are you kidding?\n"
+    //abort();
+    O << Mang->getValueName(MO.getGlobal());
+    return;
+    
+  default:
+    O << "<unknown operand type: " << MO.getType() << ">";
+    return;
+  }
+}
+
+/// printMachineInstruction -- Print out a single Alpha MI to
+/// the current output stream.
+///
+void AlphaAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
+  ++EmittedInsts;
+  if (printInstruction(MI))
+    return; // Printer was automatically generated
+  
+  assert(0 && "Unhandled instruction in asm writer!");
+  abort();
+  return;
+}
+
+
+/// runOnMachineFunction - This uses the printMachineInstruction()
+/// method to print assembly for each instruction.
+///
+bool AlphaAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
+  setupMachineFunction(MF);
+  O << "\n\n";
+
+  if (CurrentFnName.compare("main") == 0)
+    {
+      O << "\n\n#HACK\n\t.text\n\t.ent __main\n__main:\n\tret $31,($26),1\n\t.end __main\n#ENDHACK\n\n";
+    }
+
+  // Print out constants referenced by the function
+  printConstantPool(MF.getConstantPool());
+
+  // Print out labels for the function.
+  O << "\t.text\n";
+  emitAlignment(2);
+  O << "\t.globl\t" << CurrentFnName << "\n";
+  O << "\t.ent\t" << CurrentFnName << "\n";
+
+  O << CurrentFnName << ":\n";
+
+  // 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 << "$LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"
+      << CommentString << " " << I->getBasicBlock()->getName() << "\n";
+    for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
+         II != E; ++II) {
+      // Print the assembly for the instruction.
+      O << "\t";
+      printMachineInstruction(II);
+    }
+  }
+  ++LabelNumber;
+
+  O << "\t.end\t" << CurrentFnName << "\n";
+
+  // We didn't modify anything.
+  return false;
+}
+
+
+/// printConstantPool - Print to the current output stream assembly
+/// representations of the constants in the constant pool MCP. This is
+/// used to print out constants which have been "spilled to memory" by
+/// the code generator.
+///
+void AlphaAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
+  const std::vector<Constant*> &CP = MCP->getConstants();
+  const TargetData &TD = TM.getTargetData();
+  if (CP.empty()) return;
+
+  abort();
+//   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
+//     O << "\t.section\t.rodata\n";
+//     emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType()));
+//     O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString
+//       << *CP[i] << "\n";
+//     //emitGlobalConstant(CP[i]);
+//   }
+}
+
+bool AlphaAsmPrinter::doInitialization(Module &M)
+{
+  AsmPrinter::doInitialization(M);
+  O << "\t.arch ev56\n";
+  return false;
+}
+    
+
+// SwitchSection - Switch to the specified section of the executable if we are
+// not already in it!
+//
+static void SwitchSection(std::ostream &OS, std::string &CurSection,
+                          const char *NewSection) {
+  if (CurSection != NewSection) {
+    CurSection = NewSection;
+    if (!CurSection.empty())
+      OS << "\t" << NewSection << "\n";
+  }
+}
+
+bool AlphaAsmPrinter::doFinalization(Module &M) {
+  const TargetData &TD = TM.getTargetData();
+  std::string CurSection;
+  
+  for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
+    if (I->hasInitializer()) {   // External global require no code
+      O << "\n\n";
+      std::string name = Mang->getValueName(I);
+      Constant *C = I->getInitializer();
+      unsigned Size = TD.getTypeSize(C->getType());
+      unsigned Align = TD.getTypeAlignmentShift(C->getType());
+
+      if (C->isNullValue() && 
+          (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
+           I->hasWeakLinkage() /* FIXME: Verify correct */)) {
+        SwitchSection(O, CurSection, ".data");
+        if (I->hasInternalLinkage())
+          O << "\t.local " << name << "\n";
+        
+        O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
+          << "," << (1 << Align);
+        O << "\t\t# ";
+        WriteAsOperand(O, I, true, true, &M);
+        O << "\n";
+      } else {
+        switch (I->getLinkage()) {
+        case GlobalValue::LinkOnceLinkage:
+        case GlobalValue::WeakLinkage:   // FIXME: Verify correct for weak.
+          // Nonnull linkonce -> weak
+          O << "\t.weak " << name << "\n";
+          SwitchSection(O, CurSection, "");
+          O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
+          break;
+        case GlobalValue::AppendingLinkage:
+          // FIXME: appending linkage variables should go into a section of
+          // their name or something.  For now, just emit them as external.
+        case GlobalValue::ExternalLinkage:
+          // If external or appending, declare as a global symbol
+          O << "\t.globl " << name << "\n";
+          // FALL THROUGH
+        case GlobalValue::InternalLinkage:
+          if (C->isNullValue())
+            SwitchSection(O, CurSection, ".bss");
+          else
+            SwitchSection(O, CurSection, ".data");
+          break;
+        case GlobalValue::GhostLinkage:
+          std::cerr << "GhostLinkage cannot appear in X86AsmPrinter!\n";
+          abort();
+        }
+
+        emitAlignment(Align);
+        O << "\t.type " << name << ",@object\n";
+        O << "\t.size " << name << "," << Size << "\n";
+        O << name << ":\t\t\t\t# ";
+        WriteAsOperand(O, I, true, true, &M);
+        O << " = ";
+        WriteAsOperand(O, C, false, false, &M);
+        O << "\n";
+        emitGlobalConstant(C);
+      }
+    }
+
+  AsmPrinter::doFinalization(M);
+  return false;
+}
diff --git a/lib/Target/Alpha/AlphaISelPattern.cpp b/lib/Target/Alpha/AlphaISelPattern.cpp
new file mode 100644 (file)
index 0000000..4431d8f
--- /dev/null
@@ -0,0 +1,797 @@
+//===-- AlphaISelPattern.cpp - A pattern matching inst selector for Alpha -----===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file defines a pattern matching instruction selector for Alpha.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Alpha.h"
+//#include "X86InstrBuilder.h"
+#include "AlphaRegisterInfo.h"
+#include "llvm/Constants.h"                   // FIXME: REMOVE
+#include "llvm/Function.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/SSARegMap.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/ADT/Statistic.h"
+#include <set>
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+//  AlphaTargetLowering - Alpha Implementation of the TargetLowering interface
+namespace {
+  class AlphaTargetLowering : public TargetLowering {
+    int VarArgsFrameIndex;            // FrameIndex for start of varargs area.
+    unsigned GP; //GOT vreg
+  public:
+    AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) {
+      // Set up the TargetLowering object.
+      addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
+      addRegisterClass(MVT::f64, Alpha::FPRCRegisterClass);
+
+      setOperationAction(ISD::EXTLOAD          , MVT::i1   , Expand);
+      setOperationAction(ISD::EXTLOAD          , MVT::i8   , Expand);
+      setOperationAction(ISD::EXTLOAD          , MVT::i16  , Expand);
+      setOperationAction(ISD::ZEXTLOAD         , MVT::i1   , Expand);
+      setOperationAction(ISD::ZEXTLOAD         , MVT::i8   , Expand);
+      setOperationAction(ISD::ZEXTLOAD         , MVT::i16  , Expand);
+      setOperationAction(ISD::ZEXTLOAD         , MVT::i32  , Expand);
+      setOperationAction(ISD::SEXTLOAD         , MVT::i1   , Expand);
+      setOperationAction(ISD::SEXTLOAD         , MVT::i8   , Expand);
+      setOperationAction(ISD::SEXTLOAD         , MVT::i16  , Expand);
+
+      computeRegisterProperties();
+      
+      //      setOperationUnsupported(ISD::MUL, MVT::i8);
+      //      setOperationUnsupported(ISD::SELECT, MVT::i1);
+      //      setOperationUnsupported(ISD::SELECT, MVT::i8);
+      
+      //      addLegalFPImmediate(+0.0); // FLD0
+      //      addLegalFPImmediate(+1.0); // FLD1
+      //      addLegalFPImmediate(-0.0); // FLD0/FCHS
+      //      addLegalFPImmediate(-1.0); // FLD1/FCHS
+    }
+
+    /// LowerArguments - This hook must be implemented to indicate how we should
+    /// lower the arguments for the specified function, into the specified DAG.
+    virtual std::vector<SDOperand>
+    LowerArguments(Function &F, SelectionDAG &DAG);
+
+    /// LowerCallTo - This hook lowers an abstract call to a function into an
+    /// actual call.
+    virtual std::pair<SDOperand, SDOperand>
+    LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand Callee,
+                ArgListTy &Args, SelectionDAG &DAG);
+
+    virtual std::pair<SDOperand, SDOperand>
+    LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
+
+    virtual std::pair<SDOperand,SDOperand>
+    LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
+                   const Type *ArgTy, SelectionDAG &DAG);
+
+    virtual std::pair<SDOperand, SDOperand>
+    LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
+                            SelectionDAG &DAG);
+
+    void restoreGP(MachineBasicBlock* BB)
+    {
+      BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
+    }
+  };
+}
+
+//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21
+
+//For now, just use variable size stack frame format
+
+//In a standard call, the first six items are passed in registers $16
+//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
+//of argument-to-register correspondence.) The remaining items are
+//collected in a memory argument list that is a naturally aligned
+//array of quadwords. In a standard call, this list, if present, must
+//be passed at 0(SP).
+//7 ... n                      0(SP) ... (n-7)*8(SP)
+
+std::vector<SDOperand>
+AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) 
+{
+  std::vector<SDOperand> ArgValues;
+  
+  // //#define FP    $15
+  // //#define RA    $26
+  // //#define PV    $27
+  // //#define GP    $29
+  // //#define SP    $30
+  
+  //  assert(0 && "TODO");
+  MachineFunction &MF = DAG.getMachineFunction();
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+
+  GP = MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64));
+  MachineBasicBlock& BB = MF.front();
+
+  //Handle the return address
+  //BuildMI(&BB, Alpha::IDEF, 0, Alpha::R26);
+
+  unsigned args[] = {Alpha::R16, Alpha::R17, Alpha::R18, 
+                    Alpha::R19, Alpha::R20, Alpha::R21};
+  std::vector<unsigned> argVreg;
+
+  int count = 0;
+  for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
+    {
+      ++count;
+      assert(count <= 6 && "More than 6 args not supported");
+      assert(getValueType(I->getType()) != MVT::f64 && "No floats yet");
+      BuildMI(&BB, Alpha::IDEF, 0, args[count - 1]);
+      argVreg.push_back(MF.getSSARegMap()->createVirtualRegister(getRegClassFor(MVT::i64)));
+    }
+
+  BuildMI(&BB, Alpha::IDEF, 0, Alpha::R29);
+  BuildMI(&BB, Alpha::BIS, 2, GP).addReg(Alpha::R29).addReg(Alpha::R29);
+  count = 0;
+  for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
+    {
+      BuildMI(&BB, Alpha::BIS, 2, argVreg[count]).addReg(args[count]).addReg(args[count]);
+      
+      SDOperand argt, newroot;
+      switch (getValueType(I->getType()))
+       {
+       case MVT::i64:
+         argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot());
+         break;
+       case MVT::i32:
+         argt = newroot = DAG.getCopyFromReg(argVreg[count], MVT::i32, DAG.getRoot());
+         break;
+       default:
+         newroot = DAG.getCopyFromReg(argVreg[count], MVT::i64, DAG.getRoot());
+         argt =  DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), newroot);
+       }
+      DAG.setRoot(newroot.getValue(1));
+      ArgValues.push_back(argt);
+      ++count;
+    }
+  return ArgValues;
+}
+
+std::pair<SDOperand, SDOperand>
+AlphaTargetLowering::LowerCallTo(SDOperand Chain,
+                                const Type *RetTy, SDOperand Callee,
+                                ArgListTy &Args, SelectionDAG &DAG) {
+  int NumBytes = 0;
+  Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
+                     DAG.getConstant(NumBytes, getPointerTy()));
+  std::vector<SDOperand> args_to_use;
+  for (unsigned i = 0, e = Args.size(); i != e; ++i)
+    {
+      switch (getValueType(Args[i].second)) {
+      default: assert(0 && "Unexpected ValueType for argument!");
+      case MVT::i1:
+      case MVT::i8:
+      case MVT::i16:
+      case MVT::i32:
+       // Promote the integer to 64 bits.  If the input type is signed use a
+       // sign extend, otherwise use a zero extend.
+       if (Args[i].second->isSigned())
+         Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first);
+       else
+         Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first);
+       break;
+      case MVT::i64:
+       break;
+      }
+      args_to_use.push_back(Args[i].first);
+    }
+
+  std::vector<MVT::ValueType> RetVals;
+  MVT::ValueType RetTyVT = getValueType(RetTy);
+  if (RetTyVT != MVT::isVoid)
+    RetVals.push_back(RetTyVT);
+  RetVals.push_back(MVT::Other);
+
+  SDOperand TheCall = SDOperand(DAG.getCall(RetVals, Chain, Callee, args_to_use), 0);
+  Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
+  Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
+                      DAG.getConstant(NumBytes, getPointerTy()));
+   return std::make_pair(TheCall, Chain);
+}
+
+std::pair<SDOperand, SDOperand>
+AlphaTargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
+  //vastart just returns the address of the VarArgsFrameIndex slot.
+  return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64), Chain);
+}
+
+std::pair<SDOperand,SDOperand> AlphaTargetLowering::
+LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
+                const Type *ArgTy, SelectionDAG &DAG) {
+  abort();
+}
+               
+
+std::pair<SDOperand, SDOperand> AlphaTargetLowering::
+LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
+                        SelectionDAG &DAG) {
+  abort();
+}
+
+
+
+
+
+namespace {
+
+  //===--------------------------------------------------------------------===//
+  /// ISel - Alpha specific code to select Alpha machine instructions for
+  /// SelectionDAG operations.
+  ///
+  class ISel : public SelectionDAGISel {
+
+    /// AlphaLowering - This object fully describes how to lower LLVM code to an
+    /// Alpha-specific SelectionDAG.
+    AlphaTargetLowering AlphaLowering;
+
+
+    /// ExprMap - As shared expressions are codegen'd, we keep track of which
+    /// vreg the value is produced in, so we only emit one copy of each compiled
+    /// tree.
+    std::map<SDOperand, unsigned> ExprMap;
+    std::set<SDOperand> LoweredTokens;
+
+  public:
+    ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
+    }
+
+    /// InstructionSelectBasicBlock - This callback is invoked by
+    /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
+    virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
+      // Codegen the basic block.
+      Select(DAG.getRoot());
+
+      // Clear state used for selection.
+      ExprMap.clear();
+      LoweredTokens.clear();
+    }
+
+    unsigned SelectExpr(SDOperand N);
+    void Select(SDOperand N);
+  };
+}
+
+unsigned ISel::SelectExpr(SDOperand N) {
+  unsigned Result;
+  unsigned Tmp1, Tmp2, Tmp3;
+  unsigned Opc = 0;
+
+  SDNode *Node = N.Val;
+
+  unsigned &Reg = ExprMap[N];
+  if (Reg) return Reg;
+
+  if (N.getOpcode() != ISD::CALL)
+    Reg = Result = (N.getValueType() != MVT::Other) ?
+      MakeReg(N.getValueType()) : 1;
+  else {
+    // If this is a call instruction, make sure to prepare ALL of the result
+    // values as well as the chain.
+    if (Node->getNumValues() == 1)
+      Reg = Result = 1;  // Void call, just a chain.
+    else {
+      Result = MakeReg(Node->getValueType(0));
+      ExprMap[N.getValue(0)] = Result;
+      for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
+        ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
+      ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1;
+    }
+  }
+
+  switch (N.getOpcode()) {
+  default:
+    Node->dump();
+    assert(0 && "Node not handled!\n");
+  case ISD::FrameIndex:
+    Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
+    BuildMI(BB, Alpha::LDA, 2, Result).addImm(Tmp1 * 8).addReg(Alpha::R30);
+    return Result;
+  
+  case ISD::EXTLOAD:
+  case ISD::SEXTLOAD:
+    // Make sure we generate both values.
+    if (Result != 1)
+      ExprMap[N.getValue(1)] = 1;   // Generate the token
+    else
+      Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
+    
+    Select(Node->getOperand(0)); // chain
+    Tmp1 = SelectExpr(Node->getOperand(1));
+    switch(Node->getValueType(0)) {
+    default: assert(0 && "Unknown type to sign extend to.");
+    case MVT::i64:
+      switch (cast<MVTSDNode>(Node)->getExtraValueType()) {
+      default:
+        assert(0 && "Bad sign extend!");
+      case MVT::i32:
+       BuildMI(BB, Alpha::LDL, 2, Result).addImm(0).addReg(Tmp1);
+        break;
+      case MVT::i16:
+       BuildMI(BB, Alpha::LDW, 2, Result).addImm(0).addReg(Tmp1);
+        break;
+      case MVT::i8:
+       BuildMI(BB, Alpha::LDB, 2, Result).addImm(0).addReg(Tmp1);
+        break;
+      }
+      break;
+    }
+    return Result;
+
+  case ISD::GlobalAddress:
+    AlphaLowering.restoreGP(BB);
+    BuildMI(BB, Alpha::LOAD_ADDR, 1, Result)
+      .addGlobalAddress(cast<GlobalAddressSDNode>(N)->getGlobal());
+    return Result;
+
+  case ISD::CALL:
+    {
+      Select(N.getOperand(0));
+
+      // The chain for this call is now lowered.
+      ExprMap.insert(std::make_pair(N.getValue(Node->getNumValues()-1), 1));
+      
+      //grab the arguments
+      std::vector<unsigned> argvregs;
+      assert(Node->getNumOperands() < 8 && "Only 6 args supported");
+      for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
+      {
+       argvregs.push_back(SelectExpr(N.getOperand(i)));
+      }
+      for(int i = 0, e = argvregs.size(); i < e; ++i)
+      {
+       unsigned args[] = {Alpha::R16, Alpha::R17, Alpha::R18, 
+                          Alpha::R19, Alpha::R20, Alpha::R21};
+       
+       BuildMI(BB, Alpha::BIS, 2, args[i]).addReg(argvregs[i]).addReg(argvregs[i]);
+      }
+
+    //build the right kind of call
+    if (GlobalAddressSDNode *GASD =
+               dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) 
+      {
+       Select(N.getOperand(0));
+       AlphaLowering.restoreGP(BB);
+       BuildMI(BB, Alpha::CALL, 1).addGlobalAddress(GASD->getGlobal(),true);
+      }
+    else if (ExternalSymbolSDNode *ESSDN =
+            dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) 
+      {
+       Select(N.getOperand(0));
+       AlphaLowering.restoreGP(BB);
+       BuildMI(BB, Alpha::CALL, 0).addExternalSymbol(ESSDN->getSymbol(), true);
+      } 
+    else {
+      Select(N.getOperand(0));
+      Tmp1 = SelectExpr(N.getOperand(1));
+      BuildMI(BB, Alpha::CALL, 1).addReg(Tmp1);
+      AlphaLowering.restoreGP(BB);
+    }
+
+    //push the result into a virtual register
+    //    if (Result != 1)
+    //      BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
+
+    switch (Node->getValueType(0)) {
+    default: assert(0 && "Unknown value type for call result!");
+    case MVT::Other: return 1;
+    case MVT::i1:
+    case MVT::i8:
+    case MVT::i16:
+    case MVT::i32:
+    case MVT::i64:
+      BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R0).addReg(Alpha::R0);
+    break;
+    }
+    return Result+N.ResNo;
+    }    
+  
+  case ISD::SIGN_EXTEND:
+    {
+      std::cerr << "DestT: " << N.getValueType() << "\n";
+      std::cerr << "SrcT: " << N.getOperand(0).getValueType() << "\n";
+      assert(0 && "Sign Extend not there yet");
+      return Result;
+    }
+  case ISD::SIGN_EXTEND_INREG:
+    {
+      Tmp1 = SelectExpr(N.getOperand(0));
+      MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
+      std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
+      switch(MVN->getExtraValueType())
+       {
+       default:
+         assert(0 && "Sign Extend InReg not there yet");
+         break;
+       case MVT::i32:
+         {
+           Tmp2 = MakeReg(MVT::i64);
+           unsigned Tmp3 = MakeReg(MVT::i64);
+           BuildMI(BB, Alpha::LOAD_IMM, 1, Tmp2).addImm(16);
+           BuildMI(BB, Alpha::SL, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
+           BuildMI(BB, Alpha::SRA, 2, Result).addReg(Tmp3).addReg(Tmp2);
+           break;
+         }
+       case MVT::i16:
+         BuildMI(BB, Alpha::SEXTW, 1, Result).addReg(Tmp1);
+         break;
+       case MVT::i8:
+         BuildMI(BB, Alpha::SEXTB, 1, Result).addReg(Tmp1);
+         break;
+       }
+      return Result;
+    }
+  case ISD::ZERO_EXTEND_INREG:
+    {
+      Tmp1 = SelectExpr(N.getOperand(0));
+      MVTSDNode* MVN = dyn_cast<MVTSDNode>(Node);
+      std::cerr << "SrcT: " << MVN->getExtraValueType() << "\n";
+      switch(MVN->getExtraValueType())
+       {
+       default:
+         assert(0 && "Zero Extend InReg not there yet");
+         break;
+       case MVT::i32:
+         {
+           Tmp2 = MakeReg(MVT::i64);
+           BuildMI(BB, Alpha::LOAD_IMM, 1, Tmp2).addImm(0xf0);
+           BuildMI(BB, Alpha::ZAP, 2, Result).addReg(Tmp1).addReg(Tmp2);
+           break;
+         }
+       case MVT::i16:
+           Tmp2 = MakeReg(MVT::i64);
+           BuildMI(BB, Alpha::LOAD_IMM, 1, Tmp2).addImm(0xfc);
+           BuildMI(BB, Alpha::ZAP, 2, Result).addReg(Tmp1).addReg(Tmp2);
+           break;
+       case MVT::i8:
+           Tmp2 = MakeReg(MVT::i64);
+           BuildMI(BB, Alpha::LOAD_IMM, 1, Tmp2).addImm(0xfe);
+           BuildMI(BB, Alpha::ZAP, 2, Result).addReg(Tmp1).addReg(Tmp2);
+           break;
+       }
+      return Result;
+    }
+    
+  case ISD::SETCC:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
+      if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
+       switch (SetCC->getCondition()) {
+       default: assert(0 && "Unknown integer comparison!");
+       case ISD::SETEQ:
+         BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
+         break;
+       case ISD::SETGT:
+         BuildMI(BB, Alpha::CMPLT, 2, Result).addReg(Tmp2).addReg(Tmp1);
+         break;
+       case ISD::SETGE:
+         BuildMI(BB, Alpha::CMPLE, 2, Result).addReg(Tmp2).addReg(Tmp1);
+         break;
+       case ISD::SETLT:
+         BuildMI(BB, Alpha::CMPLT, 2, Result).addReg(Tmp1).addReg(Tmp2);
+         break;
+       case ISD::SETLE:
+         BuildMI(BB, Alpha::CMPLE, 2, Result).addReg(Tmp1).addReg(Tmp2);
+         break;
+       case ISD::SETNE:
+         {
+           unsigned Tmp3 = MakeReg(MVT::i64);
+           BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
+           BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Tmp3).addReg(Alpha::R31);
+           break;
+         }
+       case ISD::SETULT:
+         BuildMI(BB, Alpha::CMPULT, 2, Result).addReg(Tmp1).addReg(Tmp2);
+         break;
+       case ISD::SETUGT:
+         BuildMI(BB, Alpha::CMPULT, 2, Result).addReg(Tmp2).addReg(Tmp1);
+         break;
+       case ISD::SETULE:
+         BuildMI(BB, Alpha::CMPULE, 2, Result).addReg(Tmp1).addReg(Tmp2);
+         break;
+       case ISD::SETUGE:
+         BuildMI(BB, Alpha::CMPULE, 2, Result).addReg(Tmp2).addReg(Tmp1);
+         break;
+       }
+      }
+      else
+       assert(0 && "only integer");
+    }
+    else
+      assert(0 && "Not a setcc in setcc");
+
+    return Result;
+
+  case ISD::CopyFromReg:
+    {
+      if (Result == 1)
+       Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
+      
+      SDOperand Chain   = N.getOperand(0);
+
+      Select(Chain);
+      unsigned r = dyn_cast<RegSDNode>(Node)->getReg();
+      //std::cerr << "CopyFromReg " << Result << " = " << r << "\n";
+      BuildMI(BB, Alpha::BIS, 2, Result).addReg(r).addReg(r);
+      return Result;
+    }
+
+  case ISD::ADD:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, Alpha::ADDQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+  case ISD::SUB:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+
+  case ISD::AND:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, Alpha::AND, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+  case ISD::OR:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, Alpha::BIS, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+  case ISD::XOR:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, Alpha::XOR, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+
+  case ISD::MUL:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, Alpha::MULQ, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+  case ISD::UREM:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+        BuildMI(BB, Alpha::REMQU, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+
+  case ISD::SELECT:
+    {
+      Tmp2 = SelectExpr(N.getOperand(1)); //Use if TRUE
+      Tmp3 = SelectExpr(N.getOperand(2)); //Use if FALSE
+      Tmp1 = SelectExpr(N.getOperand(0)); //Cond
+      // Get the condition into the zero flag.
+      unsigned dummy = MakeReg(MVT::i64);
+      BuildMI(BB, Alpha::BIS, 2, dummy).addReg(Tmp3).addReg(Tmp3);
+      BuildMI(BB, Alpha::CMOVEQ, 2, Result).addReg(Tmp2).addReg(Tmp1);
+      return Result;
+    }
+
+  case ISD::SHL:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, Alpha::SL, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+  case ISD::SRL:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, Alpha::SRL, 1, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+  case ISD::SRA:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, Alpha::SRA, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+
+  case ISD::Constant:
+    {
+      long val = cast<ConstantSDNode>(N)->getValue();
+      BuildMI(BB, Alpha::LOAD_IMM, 1, Result).addImm(val);
+      return Result;
+    }
+
+
+
+  case ISD::LOAD: 
+    {
+      // Make sure we generate both values.
+      if (Result != 1)
+       ExprMap[N.getValue(1)] = 1;   // Generate the token
+      else
+       Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
+      
+      SDOperand Chain   = N.getOperand(0);
+      SDOperand Address = N.getOperand(1);
+
+      if (Address.getOpcode() == ISD::GlobalAddress)
+       {
+         Select(Chain);
+         AlphaLowering.restoreGP(BB);
+         BuildMI(BB, Alpha::LOAD, 1, Result).addGlobalAddress(cast<GlobalAddressSDNode>(Address)->getGlobal());
+       }
+      else
+       {
+         Select(Chain);
+         Tmp2 = SelectExpr(Address);
+         BuildMI(BB, Alpha::LDQ, 2, Result).addImm(0).addReg(Tmp2);
+       }
+      return Result;
+    }
+  }
+
+  return 0;
+}
+
+void ISel::Select(SDOperand N) {
+  unsigned Tmp1, Tmp2, Opc;
+
+  // FIXME: Disable for our current expansion model!
+  if (/*!N->hasOneUse() &&*/ !LoweredTokens.insert(N).second)
+    return;  // Already selected.
+
+  SDNode *Node = N.Val;
+
+  switch (N.getOpcode()) {
+
+  default:
+    Node->dump(); std::cerr << "\n";
+    assert(0 && "Node not handled yet!");
+
+  case ISD::BRCOND: {
+    MachineBasicBlock *Dest =
+      cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
+
+    Select(N.getOperand(0));
+    Tmp1 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
+    return;
+  }
+
+  case ISD::BR: {
+    MachineBasicBlock *Dest =
+      cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
+
+    Select(N.getOperand(0));
+    BuildMI(BB, Alpha::BR, 1, Alpha::R31).addMBB(Dest);
+    return;
+  }
+
+  case ISD::ImplicitDef:
+    Select(N.getOperand(0));
+    BuildMI(BB, Alpha::IDEF, 0, cast<RegSDNode>(N)->getReg());
+    return;
+    
+  case ISD::EntryToken: return;  // Noop
+
+  case ISD::TokenFactor:
+    for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
+      Select(Node->getOperand(i));
+    
+    //N.Val->dump(); std::cerr << "\n";
+    //assert(0 && "Node not handled yet!");
+    
+    return;
+
+  case ISD::CopyToReg:
+    Select(N.getOperand(0));
+    Tmp1 = SelectExpr(N.getOperand(1));
+    Tmp2 = cast<RegSDNode>(N)->getReg();
+    
+    if (Tmp1 != Tmp2) {
+      BuildMI(BB, Alpha::BIS, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
+    }
+    return;
+
+   case ISD::RET:
+     switch (N.getNumOperands()) {
+     default:
+       std::cerr << N.getNumOperands() << "\n";
+       for (unsigned i = 0; i < N.getNumOperands(); ++i)
+        std::cerr << N.getOperand(i).getValueType() << "\n";
+       assert(0 && "Unknown return instruction!");
+     case 2:
+       Select(N.getOperand(0));
+       Tmp1 = SelectExpr(N.getOperand(1));
+       switch (N.getOperand(1).getValueType()) {
+       default: assert(0 && "All other types should have been promoted!!");
+       case MVT::i64:
+        BuildMI(BB, Alpha::BIS, 2, Alpha::R0).addReg(Tmp1).addReg(Tmp1);
+        break;
+       }
+       break;
+     case 1:
+       Select(N.getOperand(0));
+       break;
+     }
+     //Tmp2 = AlphaLowering.getRetAddr();
+     //BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(Tmp2).addReg(Tmp2);
+     BuildMI(BB, Alpha::RETURN, 0); // Just emit a 'ret' instruction
+     return;
+
+  case ISD::STORE: 
+    Select(N.getOperand(0));
+    Tmp1 = SelectExpr(N.getOperand(1)); //value
+    if (N.getOperand(2).getOpcode() == ISD::GlobalAddress)
+      {
+       AlphaLowering.restoreGP(BB);
+       BuildMI(BB, Alpha::STORE, 2).addReg(Tmp1).addGlobalAddress(cast<GlobalAddressSDNode>(N.getOperand(2))->getGlobal());
+      }
+    else
+      {
+       Tmp2 = SelectExpr(N.getOperand(2)); //address
+       BuildMI(BB, Alpha::STQ, 3).addReg(Tmp1).addImm(0).addReg(Tmp2);
+      }
+    return;
+
+  case ISD::EXTLOAD:
+  case ISD::SEXTLOAD:
+  case ISD::ZEXTLOAD:
+  case ISD::LOAD:
+  case ISD::CopyFromReg:
+  case ISD::CALL:
+//   case ISD::DYNAMIC_STACKALLOC:
+    SelectExpr(N);
+    return;
+
+
+  case ISD::TRUNCSTORE: {  // truncstore chain, val, ptr :storety
+    MVT::ValueType StoredTy = cast<MVTSDNode>(Node)->getExtraValueType();
+    assert(StoredTy != MVT::i64 && "Unsupported TRUNCSTORE for this target!");
+
+    Select(N.getOperand(0));
+    Tmp1 = SelectExpr(N.getOperand(1));
+    Tmp2 = SelectExpr(N.getOperand(2));
+
+    switch (StoredTy) {
+    default: assert(0 && "Unhandled Type"); break;
+    case MVT::i8: Opc = Alpha::STB; break;
+    case MVT::i16: Opc = Alpha::STW; break;
+    case MVT::i32: Opc = Alpha::STL; break;
+    }
+
+    BuildMI(BB, Opc, 2).addReg(Tmp1).addImm(0).addReg(Tmp2);
+    return;
+  }
+
+  case ISD::ADJCALLSTACKDOWN:
+  case ISD::ADJCALLSTACKUP:
+    Select(N.getOperand(0));
+    Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
+    
+    Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? Alpha::ADJUSTSTACKDOWN :
+      Alpha::ADJUSTSTACKUP;
+    BuildMI(BB, Opc, 1).addImm(Tmp1);
+    return;
+  }
+  assert(0 && "Should not be reached!");
+}
+
+
+/// createAlphaPatternInstructionSelector - This pass converts an LLVM function
+/// into a machine code representation using pattern matching and a machine
+/// description file.
+///
+FunctionPass *llvm::createAlphaPatternInstructionSelector(TargetMachine &TM) {
+  return new ISel(TM);  
+}
diff --git a/lib/Target/Alpha/AlphaInstrBuilder.h b/lib/Target/Alpha/AlphaInstrBuilder.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/Target/Alpha/AlphaInstrFormats.td b/lib/Target/Alpha/AlphaInstrFormats.td
new file mode 100644 (file)
index 0000000..e7def75
--- /dev/null
@@ -0,0 +1,109 @@
+//===- AlphaInstrFormats.td - Alpha Instruction Formats --*- tablegen -*-=//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+//3.3:
+//Memory
+//Branch
+//Operate
+//Floating-point
+//PALcode
+
+//===----------------------------------------------------------------------===//
+// Instruction format superclass
+//===----------------------------------------------------------------------===//
+
+class InstAlpha<bits<6> op, dag OL, string asmstr> : Instruction {          // Alpha instruction baseline
+  field bits<32> Inst;
+//  let Name = asmstr;
+  let Namespace = "Alpha";
+  let OperandList = OL;
+  let AsmString = asmstr;
+
+  let Inst{31-26} = op;
+}
+
+//3.3.1
+class MForm<bits<6> opcode, dag OL, string asmstr> : InstAlpha<opcode, OL, asmstr> {
+  bits<5> Ra;
+  bits<5> Rb;
+  bits<16> disp;
+
+  let Inst{25-21} = Ra;
+  let Inst{20-16} = Rb;
+  let Inst{15-0} = disp;
+}
+
+//3.3.2
+let isBranch = 1, isTerminator = 1 in
+class BForm<bits<6> opcode, dag OL, string asmstr> : InstAlpha<opcode, OL, asmstr> {
+  bits<5> Ra;
+  bits<21> disp;
+
+  let Inst{25-21} = Ra;
+  let Inst{20-0} = disp;
+}
+
+//3.3.3
+class OForm<bits<6> opcode, bits<7> fun, dag OL, string asmstr> : InstAlpha<opcode, OL, asmstr> {
+  bits<5> Ra;
+  bits<5> Rb;
+  bits<3> SBZ;
+  bits<7> Function = fun;
+  bits<5> Rc;
+
+  let Inst{25-21} = Ra;
+  let Inst{20-16} = Rb;
+  let Inst{15-13} = SBZ;
+  let Inst{12} = 0;
+  let Inst{11-5} = Function;
+  let Inst{4-0} = Rc;
+}
+
+
+class OFormL<bits<6> opcode, dag OL, string asmstr> : InstAlpha<opcode, OL, asmstr> {
+  bits<5> Ra;
+  bits<8> LIT;
+  bits<7> Function;
+  bits<5> Rc;
+
+  let Inst{25-21} = Ra;
+  let Inst{20-13} = LIT;
+  let Inst{12} = 1;
+  let Inst{11-5} = Function;
+  let Inst{4-0} = Rc;
+}
+
+//3.3.4
+class FPForm<bits<6> opcode, dag OL, string asmstr> : InstAlpha<opcode, OL, asmstr> {
+  bits<5> Fa;
+  bits<5> Fb;
+  bits<11> Function;
+  bits<5> Fc;
+
+  let Inst{25-21} = Fa;
+  let Inst{20-16} = Fb;
+  let Inst{15-5} = Function;
+  let Inst{4-0} = Fc;
+}
+
+//3.3.5
+class PALForm<bits<6> opcode, dag OL, string asmstr> : InstAlpha<opcode, OL, asmstr> {
+  bits<26> Function;
+
+  let Inst{25-0} = Function;
+}
+
+
+// Pseudo instructions.
+class PseudoInstAlpha<dag OL, string nm> : InstAlpha<0, OL, nm>  {
+}
diff --git a/lib/Target/Alpha/AlphaInstrInfo.cpp b/lib/Target/Alpha/AlphaInstrInfo.cpp
new file mode 100644 (file)
index 0000000..3ca0ebd
--- /dev/null
@@ -0,0 +1,43 @@
+//===- AlphaInstrInfo.cpp - Alpha Instruction Information ---*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file contains the Alpha implementation of the TargetInstrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Alpha.h"
+#include "AlphaInstrInfo.h"
+#include "AlphaGenInstrInfo.inc"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include <iostream>
+using namespace llvm;
+
+AlphaInstrInfo::AlphaInstrInfo()
+  : TargetInstrInfo(AlphaInsts, sizeof(AlphaInsts)/sizeof(AlphaInsts[0])) { }
+
+
+bool AlphaInstrInfo::isMoveInstr(const MachineInstr& MI,
+                                 unsigned& sourceReg,
+                                 unsigned& destReg) const {
+  //assert(0 && "TODO");
+  MachineOpCode oc = MI.getOpcode();
+  if (oc == Alpha::BIS) {  // or r1, r2, r2
+    assert(MI.getNumOperands() == 3 &&
+           MI.getOperand(0).isRegister() &&
+           MI.getOperand(1).isRegister() &&
+           MI.getOperand(2).isRegister() &&
+           "invalid Alpha BIS instruction!");
+    if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
+      sourceReg = MI.getOperand(1).getReg();
+      destReg = MI.getOperand(0).getReg();
+      return true;
+    }
+  }
+  return false;
+}
diff --git a/lib/Target/Alpha/AlphaInstrInfo.h b/lib/Target/Alpha/AlphaInstrInfo.h
new file mode 100644 (file)
index 0000000..921528e
--- /dev/null
@@ -0,0 +1,42 @@
+//===- AlphaInstrInfo.h - Alpha Instruction Information -----*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file contains the Alpha implementation of the TargetInstrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ALPHAINSTRUCTIONINFO_H
+#define ALPHAINSTRUCTIONINFO_H
+
+#include "llvm/Target/TargetInstrInfo.h"
+#include "AlphaRegisterInfo.h"
+
+namespace llvm {
+
+class AlphaInstrInfo : public TargetInstrInfo {
+  const AlphaRegisterInfo RI;
+public:
+  AlphaInstrInfo();
+
+  /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
+  /// such, whenever a client has an instance of instruction info, it should
+  /// always be able to get register info as well (through this method).
+  ///
+  virtual const MRegisterInfo &getRegisterInfo() const { return RI; }
+
+  /// Return true if the instruction is a register to register move and
+  /// leave the source and dest operands in the passed parameters.
+  ///
+  virtual bool isMoveInstr(const MachineInstr &MI,
+                           unsigned &SrcReg, unsigned &DstReg) const;
+};
+
+}
+
+#endif
diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td
new file mode 100644 (file)
index 0000000..b94c14a
--- /dev/null
@@ -0,0 +1,295 @@
+//===- AlphaInstrInfo.td - The Alpha Instruction Set -----*- tablegen -*-=//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+include "AlphaInstrFormats.td"
+
+  // //#define FP    $15
+  // //#define RA    $26
+  // //#define PV    $27
+  // //#define GP    $29
+  // //#define SP    $30
+
+def s14imm  : Operand<i16>;
+def s16imm  : Operand<i16>;
+def s21imm  : Operand<i32>;
+def s64imm  : Operand<i64>;
+
+def PHI : PseudoInstAlpha<(ops ), "#phi">;
+def IDEF : PseudoInstAlpha<(ops ), "#idef">;
+def WTF : PseudoInstAlpha<(ops ), "#wtf">;
+def ADJUSTSTACKUP : PseudoInstAlpha<(ops ), "ADJUP">;
+def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops ), "ADJDOWN">;
+
+//*****************
+//These are shortcuts, the assembler expands them
+//*****************
+//AT = R28
+//T0-T7 = R1 - R8
+//T8-T11 = R22-R25
+
+let Defs = [R29] in 
+  let Uses = [R27] in
+    def LDGP : PseudoInstAlpha<(ops), "ldgp $$29, 0($$27)">;
+
+let isCall = 1,
+    Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R29],
+    Uses = [R27, R29] in
+      def CALL : PseudoInstAlpha< (ops s64imm:$TARGET), "jsr $TARGET">; //Jump to subroutine
+
+let isReturn = 1, isTerminator = 1 in
+  def RETURN : PseudoInstAlpha<(ops ), "ret $$31,($$26),1">; //Return from subroutine
+
+def LOAD_IMM : PseudoInstAlpha<(ops GPRC:$RC, s64imm:$IMM), "ldiq $RC,$IMM">; //Load Immediate Quadword
+
+let Uses = [R29] in
+  def STORE : PseudoInstAlpha<(ops GPRC:$RA, s64imm:$DISP), "stq $RA,$DISP">; //Store quadword
+
+let Uses = [R29] in
+  def LOAD_ADDR : PseudoInstAlpha<(ops GPRC:$RA, s64imm:$DISP), "lda $RA,$DISP">;  //Load address
+
+let Uses = [R29] in
+  def LOAD : PseudoInstAlpha<(ops GPRC:$RA, s64imm:$DISP), "ldq $RA,$DISP">; //Load quadword
+
+def LDW : PseudoInstAlpha<(ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldw $RA,$DISP($RB)">; // Load sign-extended word
+def LDB : PseudoInstAlpha<(ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldb $RA,$DISP($RB)">; //Load byte
+
+let Uses = [R28, R23, R24, R25, R26] in
+  def REMQU : PseudoInstAlpha<(ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "remqu $RA,$RB,$RC">; //unsigned remander
+
+//***********************
+//Real instructions
+//***********************
+
+//Operation Form:
+def ADDL : OForm<0x10, 0x00, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "addl $RA,$RB,$RC">; //Add longword
+def ADDL_V : OForm< 0x10, 0x40, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ADDL/V $RA,$RB,$RC">;
+def ADDQ : OForm< 0x10, 0x20, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "addq $RA,$RB,$RC">; //Add quadword
+def ADDQ_V : OForm< 0x10, 0x60, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ADDQ/V $RA,$RB,$RC">; 
+def AMASK : OForm< 0x11, 0x61, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "AMASK $RA,$RB,$RC">; //Architecture mask
+def AND : OForm< 0x11, 0x00, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "AND $RA,$RB,$RC">; //Logical product
+def BIC : OForm< 0x11, 0x08, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "BIC $RA,$RB,$RC">; //Bit clear
+def BIS  : OForm<0x11, 0x20, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "bis $RA,$RB,$RC">; //Logical sum
+
+//let isTwoAddress = 1 in {
+ def CMOVEQ : OForm< 0x11, 0x24, 
+       (ops GPRC:$RDEST, GPRC:$RSRC, GPRC:$RCOND), 
+       "cmoveq $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND =  zero
+ def CMOVGE : OForm< 0x11, 0x46, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMOVGE $RA,$RB,$RC">; //CMOVE if Â³ zero
+ def CMOVGT  : OForm<0x11, 0x66, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMOVGT $RA,$RB,$RC">; //CMOVE if > zero
+ def CMOVLBC : OForm< 0x11, 0x16, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMOVLBC $RA,$RB,$RC">; //CMOVE if low bit clear
+ def CMOVLBS : OForm< 0x11, 0x14, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMOVLBS $RA,$RB,$RC">; //CMOVE if low bit set
+ def CMOVLE  : OForm<0x11, 0x64, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMOVLE $RA,$RB,$RC">; //CMOVE if Â£ zero
+ def CMOVLT : OForm< 0x11, 0x44, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMOVLT $RA,$RB,$RC">; //CMOVE if < zero
+ def CMOVNE : OForm< 0x11, 0x26, 
+       (ops GPRC:$RC, GPRC:$DUMMY, GPRC:$RA, GPRC:$RB), 
+       "cmovne $RA,$RB,$RC">; //CMOVE if Â¹ zero
+//}
+
+def CMPBGE : OForm< 0x10, 0x0F, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPBGE $RA,$RB,$RC">; //Compare byte
+def CMPEQ : OForm< 0x10, 0x2D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPEQ $RA,$RB,$RC">; //Compare signed quadword equal
+def CMPLE : OForm< 0x10, 0x6D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPLE $RA,$RB,$RC">; //Compare signed quadword less than or equal
+def CMPLT : OForm< 0x10, 0x4D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPLT $RA,$RB,$RC">; //Compare signed quadword less than
+def CMPULE : OForm< 0x10, 0x3D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPULE $RA,$RB,$RC">; //Compare unsigned quadword less than or equal
+def CMPULT : OForm< 0x10, 0x1D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CMPULT $RA,$RB,$RC">; //Compare unsigned quadword less than
+def CTLZ : OForm< 0x1C, 0x32, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CTLZ $RA,$RB,$RC">; //Count leading zero
+def CTPOP : OForm< 0x1C, 0x30, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CTPOP $RA,$RB,$RC">; //Count population
+def CTTZ  : OForm<0x1C, 0x33, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "CTTZ $RA,$RB,$RC">; //Count trailing zero
+def EQV : OForm< 0x11, 0x48, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EQV $RA,$RB,$RC">; //Logical equivalence
+def EXTBL : OForm< 0x12, 0x06, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTBL $RA,$RB,$RC">; //Extract byte low
+def EXTLH : OForm< 0x12, 0x6A, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTLH $RA,$RB,$RC">; //Extract longword high
+def EXTLL : OForm< 0x12, 0x26, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTLL $RA,$RB,$RC">; //Extract longword low
+def EXTQH : OForm< 0x12, 0x7A, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTQH $RA,$RB,$RC">; //Extract quadword high
+def EXTQ : OForm< 0x12, 0x36, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTQ $RA,$RB,$RC">; //Extract quadword low
+def EXTWH : OForm< 0x12, 0x5A, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTWH $RA,$RB,$RC">; //Extract word high
+def EXTWL : OForm< 0x12, 0x16, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "EXTWL $RA,$RB,$RC">; //Extract word low
+def IMPLVER : OForm< 0x11, 0x6C, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "IMPLVER $RA,$RB,$RC">; //Implementation version
+def INSBL : OForm< 0x12, 0x0B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSBL $RA,$RB,$RC">; //Insert byte low
+def INSLH : OForm< 0x12, 0x67, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSLH $RA,$RB,$RC">; //Insert longword high
+def INSLL : OForm< 0x12, 0x2B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSLL $RA,$RB,$RC">; //Insert longword low
+def INSQH : OForm< 0x12, 0x77, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSQH $RA,$RB,$RC">; //Insert quadword high
+def INSQL : OForm< 0x12, 0x3B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSQL $RA,$RB,$RC">; //Insert quadword low
+def INSWH : OForm< 0x12, 0x57, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSWH $RA,$RB,$RC">; //Insert word high
+def INSWL : OForm< 0x12, 0x1B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "INSWL $RA,$RB,$RC">; //Insert word low
+def MAXSB8  : OForm<0x1C, 0x3E, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum
+def MAXSW4 : OForm< 0x1C, 0x3F, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum
+def MAXUB8  : OForm<0x1C, 0x3C, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum
+def MAXUW4 : OForm< 0x1C, 0x3D, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum
+def MINSB8 : OForm< 0x1C, 0x38, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum
+def MINSW4 : OForm< 0x1C, 0x39, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum
+def MINUB8 : OForm< 0x1C, 0x3A, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum
+def MINUW4 : OForm< 0x1C, 0x3B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum
+def MSKBL : OForm< 0x12, 0x02, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKBL $RA,$RB,$RC">; //Mask byte low
+def MSKLH : OForm< 0x12, 0x62, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKLH $RA,$RB,$RC">; //Mask longword high
+def MSKLL : OForm< 0x12, 0x22, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKLL $RA,$RB,$RC">; //Mask longword low
+def MSKQH : OForm< 0x12, 0x72, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKQH $RA,$RB,$RC">; //Mask quadword high
+def MSKQL : OForm< 0x12, 0x32, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKQL $RA,$RB,$RC">; //Mask quadword low
+def MSKWH : OForm< 0x12, 0x52, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKWH $RA,$RB,$RC">; //Mask word high
+def MSKWL : OForm< 0x12, 0x12, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MSKWL $RA,$RB,$RC">; //Mask word low
+def MULL : OForm< 0x13, 0x00, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MULL $RA,$RB,$RC">; //Multiply longword
+def MULL_V : OForm< 0x13, 0x40, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MULL/V $RA,$RB,$RC">; 
+def MULQ : OForm< 0x13, 0x20, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MULQ $RA,$RB,$RC">; //Multiply quadword
+def MULQ_V : OForm< 0x13, 0x60, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "MULQ/V $RA,$RB,$RC">; 
+def ORNOT : OForm< 0x11, 0x28, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ORNOT $RA,$RB,$RC">; //Logical sum with complement
+def PERR : OForm< 0x1C, 0x31, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "PERR $RA,$RB,$RC">; //Pixel error
+def PKLB : OForm< 0x1C, 0x37, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "PKLB $RA,$RB,$RC">; //Pack longwords to bytes
+def PKWB  : OForm<0x1C, 0x36, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "PKWB $RA,$RB,$RC">; //Pack words to bytes
+def S4ADDL : OForm< 0x10, 0x02, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S4ADDL $RA,$RB,$RC">; //Scaled add longword by 4
+def S4ADDQ : OForm< 0x10, 0x22, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S4ADDQ $RA,$RB,$RC">; //Scaled add quadword by 4
+def S4SUBL : OForm< 0x10, 0x0B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S4SUBL $RA,$RB,$RC">; //Scaled subtract longword by 4
+def S4SUBQ : OForm< 0x10, 0x2B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S4SUBQ $RA,$RB,$RC">; //Scaled subtract quadword by 4
+def S8ADDL : OForm< 0x10, 0x12, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S8ADDL $RA,$RB,$RC">; //Scaled add longword by 8
+def S8ADDQ : OForm< 0x10, 0x32, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S8ADDQ $RA,$RB,$RC">; //Scaled add quadword by 8
+def S8SUBL : OForm< 0x10, 0x1B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S8SUBL $RA,$RB,$RC">; //Scaled subtract longword by 8
+def S8SUBQ : OForm< 0x10, 0x3B, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "S8SUBQ $RA,$RB,$RC">; //Scaled subtract quadword by 8
+def SEXTB : OForm< 0x1C, 0x00, (ops GPRC:$RC, GPRC:$RB), "sextb $RB,$RC">; //Sign extend byte
+def SEXTW : OForm< 0x1C, 0x01, (ops GPRC:$RC, GPRC:$RB), "sextw $RB,$RC">; //Sign extend word
+def SL : OForm< 0x12, 0x39, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SLL $RA,$RB,$RC">; //Shift left logical
+def SRA : OForm< 0x12, 0x3C, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SRA $RA,$RB,$RC">; //Shift right arithmetic
+def SRL : OForm< 0x12, 0x34, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SRL $RA,$RB,$RC">; //Shift right logical
+def SUBL : OForm< 0x10, 0x09, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SUBL $RA,$RB,$RC">; //Subtract longword
+def SUBL_V : OForm< 0x10, 0x49, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SUBL/V $RA,$RB,$RC">; 
+def SUBQ : OForm< 0x10, 0x29, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SUBQ $RA,$RB,$RC">; //Subtract quadword
+def SUBQ_V : OForm< 0x10, 0x69, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "SUBQ/V $RA,$RB,$RC">; 
+def UMULH : OForm< 0x13, 0x30, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "UMULH $RA,$RB,$RC">; //Unsigned multiply quadword high
+def UNPKBL : OForm< 0x1C, 0x35, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords
+def UNPKBW : OForm< 0x1C, 0x34, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words
+def XOR : OForm< 0x11, 0x40, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "XOR $RA,$RB,$RC">; //Logical difference
+def ZAP : OForm< 0x12, 0x30, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ZAP $RA,$RB,$RC">; //Zero bytes
+def ZAPNOT : OForm< 0x12, 0x31, (ops GPRC:$RC, GPRC:$RA, GPRC:$RB), "ZAPNOT $RA,$RB,$RC">; //Zero bytes not
+
+let isReturn = 1, isTerminator = 1 in
+  def RET : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS), "ret $RD,($RS),1">; //Return from subroutine
+
+def JMP : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS), "jmp $RD,($RS),0">; //Jump
+let isCall = 1 in
+  let Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R27, R29] in 
+    def JSR : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to subroutine
+def JSR_COROUTINE : MForm< 0x1A, (ops GPRC:$RD, GPRC:$RS), "jsr_coroutine $RD,($RS),1">; //Jump to subroutine return
+
+def BR : BForm<0x30, (ops GPRC:$RD, s21imm:$DISP), "br $RD,$DISP">; //Branch
+let isCall = 1 in
+  let Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R27, R29] in 
+    def BSR : BForm<0x34, (ops GPRC:$RD, s21imm:$DISP), "bsr $RD,$DISP">; //Branch to subroutine
+
+def STB : MForm<0x0E, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stb $RA,$DISP($RB)">; // Store byte
+def STW : MForm<0x0D, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stw $RA,$DISP($RB)">; // Store word
+def STL : MForm<0x2C, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stl $RA,$DISP($RB)">; // Store longword
+def STQ : MForm<0x2D, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "stq $RA,$DISP($RB)">; //Store quadword
+
+def LDA : MForm<0x08, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "lda $RA,$DISP($RB)">;  //Load address
+
+def LDL : MForm<0x28, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldq $RA,$DISP($RB)">; // Load sign-extended longword
+def LDQ : MForm<0x29, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), "ldq $RA,$DISP($RB)">; //Load quadword
+
+def BEQ : BForm<0x39, (ops GPRC:$RA, s21imm:$DISP), "beq $RA,$DISP">; //Branch if = zero
+def BGE : BForm<0x3E, (ops GPRC:$RA, s21imm:$DISP), "bge $RA,$DISP">; //Branch if >= zero
+def BGT : BForm<0x3F, (ops GPRC:$RA, s21imm:$DISP), "bgt $RA,$DISP">; //Branch if > zero
+def BLBC : BForm<0x38, (ops GPRC:$RA, s21imm:$DISP), "blbc $RA,$DISP">; //Branch if low bit clear
+def BLBS : BForm<0x3C, (ops GPRC:$RA, s21imm:$DISP), "blbs $RA,$DISP">; //Branch if low bit set
+def BLE : BForm<0x3B, (ops GPRC:$RA, s21imm:$DISP), "ble $RA,$DISP">; //Branch if <= zero
+def BLT : BForm<0x3A, (ops GPRC:$RA, s21imm:$DISP), "blt $RA,$DISP">; //Branch if < zero
+def BNE : BForm<0x3D, (ops GPRC:$RA, s21imm:$DISP), "bne $RA,$DISP">; //Branch if != zero
+
+//Mnemonic Format Opcode Description
+//ADDF F-P 15.080 Add F_floating
+//ADDG F-P 15.0A0 Add G_floating
+//ADDS F-P 16.080 Add S_floating
+//ADDT F-P 16.0A0 Add T_floating
+//CALL_PAL Pcd 00 Trap to PALcode
+//ECB Mfc 18.E800 Evict cache block
+//EXCB Mfc 18.0400 Exception barrier
+//FETCH Mfc 18.8000 Prefetch data
+//FETCH_M Mfc 18.A000 Prefetch data, modify intent
+//LDAH Mem 09 Load address high
+//LDBU Mem 0A Load zero-extended byte
+//LDWU Mem 0C Load zero-extended word
+//LDL_L Mem 2A Load sign-extended longword locked
+//LDQ_L Mem 2B Load quadword locked
+//LDQ_U Mem 0B Load unaligned quadword
+//MB Mfc 18.4000 Memory barrier
+//RC Mfc 18.E000 Read and clear
+//RPCC Mfc 18.C000 Read process cycle counter
+//RS Mfc 18.F000 Read and set
+//STL_C Mem 2E Store longword conditional
+//STQ_C Mem 2F Store quadword conditional
+//STQ_U Mem 0F Store unaligned quadword
+//TRAPB Mfc 18.0000 Trap barrier
+//WH64 Mfc 18.F800 Write hint \14 64 bytes
+//WMB Mfc 18.4400 Write memory barrier
+
+
+//CMPGEQ F-P 15.0A5 Compare G_floating equal
+//CMPGLE F-P 15.0A7 Compare G_floating less than or equal
+//CMPGLT F-P 15.0A6 Compare G_floating less than
+//CMPTEQ F-P 16.0A5 Compare T_floating equal
+//CMPTLE F-P 16.0A7 Compare T_floating less than or equal
+//CMPTLT F-P 16.0A6 Compare T_floating less than
+//CMPTUN F-P 16.0A4 Compare T_floating unordered
+//CPYS F-P 17.020 Copy sign
+//CPYSE F-P 17.022 Copy sign and exponent
+//CPYSN F-P 17.021 Copy sign negate
+//CVTDG F-P 15.09E Convert D_floating to G_floating
+//CVTGD F-P 15.0AD Convert G_floating to D_floating
+//CVTGF F-P 15.0AC Convert G_floating to F_floating
+//CVTGQ F-P 15.0AF Convert G_floating to quadword
+//CVTLQ F-P 17.010 Convert longword to quadword
+//CVTQF F-P 15.0BC Convert quadword to F_floating
+//CVTQG F-P 15.0BE Convert quadword to G_floating
+//CVTQL F-P 17.030 Convert quadword to longword
+//CVTQS F-P 16.0BC Convert quadword to S_floating
+//CVTQT F-P 16.0BE Convert quadword to T_floating
+//CVTST F-P 16.2AC Convert S_floating to T_floating
+//CVTTQ F-P 16.0AF Convert T_floating to quadword
+//CVTTS F-P 16.0AC Convert T_floating to S_floating
+//DIVF F-P 15.083 Divide F_floating
+//DIVG F-P 15.0A3 Divide G_floating
+//DIVS F-P 16.083 Divide S_floating
+//DIVT F-P 16.0A3 Divide T_floating
+//FBEQ Bra 31 Floating branch if =  zero
+//FBGE Bra 36 Floating branch if Â³ zero
+//FBGT Bra 37 Floating branch if > zero
+//FBLE Bra 33 Floating branch if Â£ zero
+//FBLT Bra 32 Floating branch if < zero
+//FBNE Bra 35 Floating branch if Â¹ zero
+//FCMOVEQ F-P 17.02A FCMOVE if = zero
+//FCMOVGE F-P 17.02D FCMOVE if Â³ zero
+//FCMOVGT F-P 17.02F FCMOVE if > zero
+//FCMOVLE F-P 17.02E FCMOVE if Â£ zero
+//FCMOVLT F-P 17.02C FCMOVE if < zero
+//FCMOVNE F-P 17.02B FCMOVE if Â¹ zero
+//FTOIS F-P 1C.78 Floating to integer move, S_floating
+//FTOIT F-P 1C.70 Floating to integer move, T_floating
+//ITOFF F-P 14.014 Integer to floating move, F_floating
+//ITOFS F-P 14.004 Integer to floating move, S_floating
+//ITOFT F-P 14.024 Integer to floating move, T_floating
+//LDF Mem 20 Load F_floating
+//LDG Mem 21 Load G_floating
+//LDS Mem 22 Load S_floating
+//LDT Mem 23 Load T_floating
+//MF_FPCR F-P 17.025 Move from FPCR
+//MT_FPCR F-P 17.024 Move to FPCR
+//MULF F-P 15.082 Multiply F_floating
+//MULG F-P 15.0A2 Multiply G_floating
+//MULS F-P 16.082 Multiply S_floating
+//MULT F-P 16.0A2 Multiply T_floating
+//SQRTF F-P 14.08A Square root F_floating
+//SQRTG F-P 14.0AA Square root G_floating
+//SQRTS F-P 14.08B Square root S_floating
+//SQRTT F-P 14.0AB Square root T_floating
+//STF Mem 24 Store F_floating
+//STG Mem 25 Store G_floating
+//STS Mem 26 Store S_floating
+//STT Mem 27 Store T_floating
+//SUBF F-P 15.081 Subtract F_floating
+//SUBG F-P 15.0A1 Subtract G_floating
+//SUBS F-P 16.081 Subtract S_floating
+//SUBT F-P 16.0A1 Subtract T_floating
diff --git a/lib/Target/Alpha/AlphaRegisterInfo.cpp b/lib/Target/Alpha/AlphaRegisterInfo.cpp
new file mode 100644 (file)
index 0000000..58a1a8d
--- /dev/null
@@ -0,0 +1,268 @@
+//===- PPC64RegisterInfo.cpp - PowerPC64 Register Information ---*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file contains the PowerPC64 implementation of the MRegisterInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "reginfo"
+#include "Alpha.h"
+#include "AlphaInstrBuilder.h"
+#include "AlphaRegisterInfo.h"
+#include "llvm/Constants.h"
+#include "llvm/Type.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/STLExtras.h"
+#include <cstdlib>
+#include <iostream>
+using namespace llvm;
+
+
+AlphaRegisterInfo::AlphaRegisterInfo()
+  : AlphaGenRegisterInfo(Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP)
+{
+}
+
+static const TargetRegisterClass *getClass(unsigned SrcReg) {
+  if (Alpha::FPRCRegisterClass->contains(SrcReg))
+    return Alpha::FPRCRegisterClass;
+  assert(Alpha::GPRCRegisterClass->contains(SrcReg) && "Reg not FPR or GPR");
+  return Alpha::GPRCRegisterClass;
+}
+
+void 
+AlphaRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
+                                       MachineBasicBlock::iterator MI,
+                                       unsigned SrcReg, int FrameIdx) const {
+  std::cerr << "Trying to store " << getPrettyName(SrcReg) << " to " << FrameIdx << "\n";
+  //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg);
+  BuildMI(MBB, MI, Alpha::STQ, 3).addReg(SrcReg).addImm(FrameIdx * 8).addReg(Alpha::R30);
+  //  assert(0 && "TODO");
+}
+
+void
+AlphaRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
+                                        MachineBasicBlock::iterator MI,
+                                        unsigned DestReg, int FrameIdx) const{
+  std::cerr << "Trying to load " << getPrettyName(DestReg) << " to " << FrameIdx << "\n";
+  //BuildMI(MBB, MI, Alpha::WTF, 0, DestReg);
+  BuildMI(MBB, MI, Alpha::LDQ, 2, DestReg).addImm(FrameIdx * 8).addReg(Alpha::R30);
+  //  assert(0 && "TODO");
+}
+
+void AlphaRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
+                                     MachineBasicBlock::iterator MI,
+                                     unsigned DestReg, unsigned SrcReg,
+                                     const TargetRegisterClass *RC) const {
+  //  std::cerr << "copyRegToReg " << DestReg << " <- " << SrcReg << "\n";
+  if (RC == Alpha::GPRCRegisterClass) {
+    BuildMI(MBB, MI, Alpha::BIS, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
+//   } else if (RC == Alpha::FPRCRegisterClass) {
+//     BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg);
+  } else { 
+    std::cerr << "Attempt to copy register that is not GPR or FPR";
+     abort();
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Stack Frame Processing methods
+//===----------------------------------------------------------------------===//
+
+// hasFP - Return true if the specified function should have a dedicated frame
+// pointer register.  This is true if the function has variable sized allocas or
+// if frame pointer elimination is disabled.
+//
+static bool hasFP(MachineFunction &MF) {
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+  return MFI->hasVarSizedObjects();
+}
+
+void AlphaRegisterInfo::
+eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
+                              MachineBasicBlock::iterator I) const {
+  if (hasFP(MF)) {
+    assert(0 && "TODO");
+    // If we have a frame pointer, turn the adjcallstackup instruction into a
+    // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP,
+    // <amt>'
+    MachineInstr *Old = I;
+    unsigned Amount = Old->getOperand(0).getImmedValue();
+    if (Amount != 0) {
+      // We need to keep the stack aligned properly.  To do this, we round the
+      // amount of space needed for the outgoing arguments up to the next
+      // alignment boundary.
+      unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
+      Amount = (Amount+Align-1)/Align*Align;
+
+      MachineInstr *New;
+//       if (Old->getOpcode() == X86::ADJCALLSTACKDOWN) {
+//     New=BuildMI(X86::SUB32ri, 1, X86::ESP, MachineOperand::UseAndDef)
+//               .addZImm(Amount);
+//       } else {
+//     assert(Old->getOpcode() == X86::ADJCALLSTACKUP);
+//     New=BuildMI(X86::ADD32ri, 1, X86::ESP, MachineOperand::UseAndDef)
+//               .addZImm(Amount);
+//       }
+
+      // Replace the pseudo instruction with a new instruction...
+      MBB.insert(I, New);
+    }
+  }
+
+  MBB.erase(I);
+}
+
+void
+AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
+  assert(0 && "TODO");
+//   unsigned i = 0;
+//   MachineInstr &MI = *II;
+//   MachineBasicBlock &MBB = *MI.getParent();
+//   MachineFunction &MF = *MBB.getParent();
+  
+//   while (!MI.getOperand(i).isFrameIndex()) {
+//     ++i;
+//     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
+//   }
+
+//   int FrameIndex = MI.getOperand(i).getFrameIndex();
+
+//   // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
+//   MI.SetMachineOperandReg(i, hasFP(MF) ? PPC::R31 : PPC::R1);
+
+//   // Take into account whether it's an add or mem instruction
+//   unsigned OffIdx = (i == 2) ? 1 : 2;
+
+//   // Now add the frame object offset to the offset from r1.
+//   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
+//                MI.getOperand(OffIdx).getImmedValue();
+
+//   // If we're not using a Frame Pointer that has been set to the value of the
+//   // SP before having the stack size subtracted from it, then add the stack size
+//   // to Offset to get the correct offset.
+//   Offset += MF.getFrameInfo()->getStackSize();
+  
+//   if (Offset > 32767 || Offset < -32768) {
+//     // Insert a set of r0 with the full offset value before the ld, st, or add
+//     MachineBasicBlock *MBB = MI.getParent();
+//     MBB->insert(II, BuildMI(PPC::LIS, 1, PPC::R0).addSImm(Offset >> 16));
+//     MBB->insert(II, BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0)
+//       .addImm(Offset));
+//     // convert into indexed form of the instruction
+//     // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
+//     // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
+//     unsigned NewOpcode = 
+//       const_cast<std::map<unsigned, unsigned>& >(ImmToIdxMap)[MI.getOpcode()];
+//     assert(NewOpcode && "No indexed form of load or store available!");
+//     MI.setOpcode(NewOpcode);
+//     MI.SetMachineOperandReg(1, MI.getOperand(i).getReg());
+//     MI.SetMachineOperandReg(2, PPC::R0);
+//   } else {
+//     MI.SetMachineOperandConst(OffIdx, MachineOperand::MO_SignExtendedImmed,
+//                               Offset);
+//   }
+}
+
+
+void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const {
+  MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
+  MachineBasicBlock::iterator MBBI = MBB.begin();
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+  MachineInstr *MI;
+  
+  //handle GOP offset
+  MI = BuildMI(Alpha::LDGP, 0);
+  MBB.insert(MBBI, MI);
+
+  // Get the number of bytes to allocate from the FrameInfo
+  unsigned NumBytes = MFI->getStackSize();
+
+  // Do we need to allocate space on the stack?
+  if (NumBytes == 0) return;
+
+  // Add the size of R30 to  NumBytes size for the store of R30 to the 
+  // stack
+//   std::cerr << "Spillsize of R30 is " << getSpillSize(Alpha::R30) << "\n";
+//   NumBytes = NumBytes + getSpillSize(Alpha::R30)/8;
+
+  // Update frame info to pretend that this is part of the stack...
+  MFI->setStackSize(NumBytes);
+  
+  // adjust stack pointer: r30 -= numbytes
+  
+  if (NumBytes <= 32000) //FIXME: do this better 
+    {
+      MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(-NumBytes).addReg(Alpha::R30);
+      MBB.insert(MBBI, MI);
+    } else {
+      std::cerr << "Too big a stack frame\n";
+      abort();
+    }
+}
+
+void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF,
+                                     MachineBasicBlock &MBB) const {
+  const MachineFrameInfo *MFI = MF.getFrameInfo();
+  MachineBasicBlock::iterator MBBI = prior(MBB.end());
+  MachineInstr *MI;
+  assert((MBBI->getOpcode() == Alpha::RET || MBBI->getOpcode() == Alpha::RETURN) &&
+        "Can only insert epilog into returning blocks");
+  
+  // Get the number of bytes allocated from the FrameInfo...
+  unsigned NumBytes = MFI->getStackSize();
+
+   if (NumBytes != 0) 
+     {
+       if (NumBytes <= 32000) //FIXME: do this better 
+        {
+          MI=BuildMI(Alpha::LDA, 2, Alpha::R30).addImm(NumBytes).addReg(Alpha::R30);
+          MBB.insert(MBBI, MI);
+        } else {
+          std::cerr << "Too big a stack frame\n";
+          abort();
+        }
+     }
+}
+
+#include "AlphaGenRegisterInfo.inc"
+
+const TargetRegisterClass*
+AlphaRegisterInfo::getRegClassForType(const Type* Ty) const {
+  switch (Ty->getTypeID()) {
+    default:              assert(0 && "Invalid type to getClass!");
+    case Type::BoolTyID:
+    case Type::SByteTyID:
+    case Type::UByteTyID:
+    case Type::ShortTyID:
+    case Type::UShortTyID:
+    case Type::IntTyID:
+    case Type::UIntTyID:
+    case Type::PointerTyID:
+    case Type::LongTyID:
+    case Type::ULongTyID:  return &GPRCInstance;
+     
+  case Type::FloatTyID:
+  case Type::DoubleTyID: return &FPRCInstance;
+  }
+}
+
+std::string AlphaRegisterInfo::getPrettyName(unsigned reg)
+{
+  std::string s(RegisterDescriptors[reg].Name);
+  return s;
+}
diff --git a/lib/Target/Alpha/AlphaRegisterInfo.h b/lib/Target/Alpha/AlphaRegisterInfo.h
new file mode 100644 (file)
index 0000000..f29ff80
--- /dev/null
@@ -0,0 +1,57 @@
+//===- AlphaRegisterInfo.h - Alpha Register Information Impl -*- C++ -*-==//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file contains the Alpha implementation of the MRegisterInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ALPHAREGISTERINFO_H
+#define ALPHAREGISTERINFO_H
+
+#include "llvm/Target/MRegisterInfo.h"
+#include "AlphaGenRegisterInfo.h.inc"
+
+namespace llvm {
+
+class Type;
+
+struct AlphaRegisterInfo : public AlphaGenRegisterInfo {
+  AlphaRegisterInfo();
+  const TargetRegisterClass* getRegClassForType(const Type* Ty) const;
+
+  /// Code Generation virtual methods...
+  void storeRegToStackSlot(MachineBasicBlock &MBB,
+                           MachineBasicBlock::iterator MBBI,
+                           unsigned SrcReg, int FrameIndex) const;
+
+  void loadRegFromStackSlot(MachineBasicBlock &MBB,
+                            MachineBasicBlock::iterator MBBI,
+                            unsigned DestReg, int FrameIndex) const;
+  
+  void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+                    unsigned DestReg, unsigned SrcReg,
+                    const TargetRegisterClass *RC) const;
+
+  void eliminateCallFramePseudoInstr(MachineFunction &MF,
+                                     MachineBasicBlock &MBB,
+                                     MachineBasicBlock::iterator I) const;
+
+  void eliminateFrameIndex(MachineBasicBlock::iterator II) const;
+
+  //void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
+
+  void emitPrologue(MachineFunction &MF) const;
+  void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
+
+  static std::string getPrettyName(unsigned reg);
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/lib/Target/Alpha/AlphaRegisterInfo.td b/lib/Target/Alpha/AlphaRegisterInfo.td
new file mode 100644 (file)
index 0000000..80f264b
--- /dev/null
@@ -0,0 +1,93 @@
+//===- AlphaRegisterInfo.td - The Alpha Register File --*- tablegen -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+class AlphaReg<string n> : Register<n> {
+  field bits<5> Num;
+  let Namespace = "Alpha";
+}
+
+// We identify all our registers with a 5-bit ID, for consistency's sake.
+
+// GPR - One of the 32 32-bit general-purpose registers
+class GPR<bits<5> num, string n> : AlphaReg<n> {
+  let Num = num;
+}
+
+// FPR - One of the 32 64-bit floating-point registers
+class FPR<bits<5> num, string n> : AlphaReg<n> {
+  let Num = num;
+}
+
+//#define FP    $15
+//#define RA    $26
+//#define PV    $27
+//#define GP    $29
+//#define SP    $30
+
+// General-purpose registers
+def R0  : GPR< 0,  "$0">;  def R1  : GPR< 1,  "$1">;
+def R2  : GPR< 2,  "$2">;  def R3  : GPR< 3,  "$3">;
+def R4  : GPR< 4,  "$4">;  def R5  : GPR< 5,  "$5">;
+def R6  : GPR< 6,  "$6">;  def R7  : GPR< 7,  "$7">;
+def R8  : GPR< 8,  "$8">;  def R9  : GPR< 9,  "$9">;
+def R10 : GPR<10, "$10">;  def R11 : GPR<11, "$11">;
+def R12 : GPR<12, "$12">;  def R13 : GPR<13, "$13">;
+def R14 : GPR<14, "$14">;  def R15 : GPR<15, "$15">;
+def R16 : GPR<16, "$16">;  def R17 : GPR<17, "$17">;
+def R18 : GPR<18, "$18">;  def R19 : GPR<19, "$19">;
+def R20 : GPR<20, "$20">;  def R21 : GPR<21, "$21">;
+def R22 : GPR<22, "$22">;  def R23 : GPR<23, "$23">;
+def R24 : GPR<24, "$24">;  def R25 : GPR<25, "$25">;
+def R26 : GPR<26, "$26">;  def R27 : GPR<27, "$27">;
+def R28 : GPR<28, "$28">;  def R29 : GPR<29, "$29">;
+def R30 : GPR<30, "$30">;  def R31 : GPR<31, "$31">;
+
+// Floating-point registers
+def F0  : FPR< 0,  "F0">;  def F1  : FPR< 1,  "F1">;
+def F2  : FPR< 2,  "F2">;  def F3  : FPR< 3,  "F3">;
+def F4  : FPR< 4,  "F4">;  def F5  : FPR< 5,  "F5">;
+def F6  : FPR< 6,  "F6">;  def F7  : FPR< 7,  "F7">;
+def F8  : FPR< 8,  "F8">;  def F9  : FPR< 9,  "F9">;
+def F10 : FPR<10, "F10">;  def F11 : FPR<11, "F11">;
+def F12 : FPR<12, "F12">;  def F13 : FPR<13, "F13">;
+def F14 : FPR<14, "F14">;  def F15 : FPR<15, "F15">;
+def F16 : FPR<16, "F16">;  def F17 : FPR<17, "F17">;
+def F18 : FPR<18, "F18">;  def F19 : FPR<19, "F19">;
+def F20 : FPR<20, "F20">;  def F21 : FPR<21, "F21">;
+def F22 : FPR<22, "F22">;  def F23 : FPR<23, "F23">;
+def F24 : FPR<24, "F24">;  def F25 : FPR<25, "F25">;
+def F26 : FPR<26, "F26">;  def F27 : FPR<27, "F27">;
+def F28 : FPR<28, "F28">;  def F29 : FPR<29, "F29">;
+def F30 : FPR<30, "F30">;  def F31 : FPR<31, "F31">;
+
+  // //#define FP    $15
+  // //#define RA    $26
+  // //#define PV    $27
+  // //#define GP    $29
+  // //#define SP    $30
+  // $28 is undefined after any and all calls
+
+/// Register classes
+def GPRC : RegisterClass<i64, 64,
+//Volitle
+     [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R27,
+//Non-Volitile
+     R9, R10, R11, R12, R13, R14, R15, R26, /*R28,*/ R29, R30, R31]>;
+//R28 is reserved for the assembler
+
+//Don't allocate 15, 29, 30, 31
+//Allocation volatiles only for now
+def FPRC : RegisterClass<f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, 
+       F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
+       F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
+
+
diff --git a/lib/Target/Alpha/AlphaTargetMachine.cpp b/lib/Target/Alpha/AlphaTargetMachine.cpp
new file mode 100644 (file)
index 0000000..baf3ca8
--- /dev/null
@@ -0,0 +1,111 @@
+//===-- AlphaTargetMachine.cpp - Define TargetMachine for Alpha -------===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+// 
+//
+//===----------------------------------------------------------------------===//
+
+#include "Alpha.h"
+#include "AlphaTargetMachine.h"
+#include "llvm/Module.h"
+#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetMachineRegistry.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Support/CommandLine.h"
+#include <iostream>
+using namespace llvm;
+
+namespace {
+  // Register the targets
+  RegisterTarget<AlphaTargetMachine> X("alpha", "  Alpha (incomplete)");
+}
+
+AlphaTargetMachine::AlphaTargetMachine( const Module &M, IntrinsicLowering *IL)
+  : TargetMachine("alpha", IL, true), 
+    FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) //TODO: check these
+    //JITInfo(*this)
+{}
+
+bool AlphaTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
+                                         MachineCodeEmitter &MCE)
+{
+  assert(0 && "TODO");
+  return false;
+}
+
+
+/// addPassesToEmitAssembly - Add passes to the specified pass manager
+/// to implement a static compiler for this target.
+///
+bool AlphaTargetMachine::addPassesToEmitAssembly(PassManager &PM,
+                                                   std::ostream &Out) {
+  
+  // FIXME: Implement efficient support for garbage collection intrinsics.
+  PM.add(createLowerGCPass());
+
+  // FIXME: Implement the invoke/unwind instructions!
+  PM.add(createLowerInvokePass());
+
+  // FIXME: Implement the switch instruction in the instruction selector!
+  PM.add(createLowerSwitchPass());
+
+  PM.add(createLowerConstantExpressionsPass());
+
+  // Make sure that no unreachable blocks are instruction selected.
+  PM.add(createUnreachableBlockEliminationPass());
+
+  PM.add(createAlphaPatternInstructionSelector(*this));
+
+  if (PrintMachineCode)
+    PM.add(createMachineFunctionPrinterPass(&std::cerr));
+
+  PM.add(createRegisterAllocator());
+
+  if (PrintMachineCode)
+    PM.add(createMachineFunctionPrinterPass(&std::cerr));
+
+  PM.add(createPrologEpilogCodeInserter());
+  
+  // Must run branch selection immediately preceding the asm printer
+  //PM.add(createAlphaBranchSelectionPass());
+  
+  PM.add(createAlphaCodePrinterPass(Out, *this));
+    
+  PM.add(createMachineCodeDeleter());
+  return false;
+}
+
+//void AlphaJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
+//   // FIXME: Implement efficient support for garbage collection intrinsics.
+//   PM.add(createLowerGCPass());
+
+//   // FIXME: Implement the invoke/unwind instructions!
+//   PM.add(createLowerInvokePass());
+
+//   // FIXME: Implement the switch instruction in the instruction selector!
+//   PM.add(createLowerSwitchPass());
+
+//   PM.add(createLowerConstantExpressionsPass());
+
+//   // Make sure that no unreachable blocks are instruction selected.
+//   PM.add(createUnreachableBlockEliminationPass());
+
+//   PM.add(createPPC32ISelSimple(TM));
+//   PM.add(createRegisterAllocator());
+//   PM.add(createPrologEpilogCodeInserter());
+
+//   // Must run branch selection immediately preceding the asm printer
+//   PM.add(createPPCBranchSelectionPass());
+
+//   if (PrintMachineCode)
+//     PM.add(createMachineFunctionPrinterPass(&std::cerr));
+//}
+
diff --git a/lib/Target/Alpha/AlphaTargetMachine.h b/lib/Target/Alpha/AlphaTargetMachine.h
new file mode 100644 (file)
index 0000000..af18601
--- /dev/null
@@ -0,0 +1,54 @@
+//===-- AlphaTargetMachine.h - Define TargetMachine for PowerPC -*- C++ -*-=//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+// 
+// This file declares the Alpha-specific subclass of TargetMachine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ALPHA_TARGETMACHINE_H
+#define ALPHA_TARGETMACHINE_H
+
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/PassManager.h"
+#include "AlphaInstrInfo.h"
+//#include "AlphaJITInfo.h"
+
+namespace llvm {
+
+class GlobalValue;
+class IntrinsicLowering;
+
+class AlphaTargetMachine : public TargetMachine {
+  AlphaInstrInfo InstrInfo;
+  TargetFrameInfo FrameInfo;
+  //  AlphaJITInfo JITInfo;
+
+public:
+  AlphaTargetMachine(const Module &M, IntrinsicLowering *IL);
+  
+  virtual const AlphaInstrInfo *getInstrInfo() const { return &InstrInfo; }    
+  virtual const TargetFrameInfo  *getFrameInfo() const { return &FrameInfo; }
+  virtual const MRegisterInfo *getRegisterInfo() const {
+    return &InstrInfo.getRegisterInfo();
+  }
+  //  virtual TargetJITInfo *getJITInfo() {
+  //    return &JITInfo;
+  //  }
+  virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
+                                         MachineCodeEmitter &MCE);
+  
+  virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
+  
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/lib/Target/Alpha/Makefile b/lib/Target/Alpha/Makefile
new file mode 100644 (file)
index 0000000..49cb1cd
--- /dev/null
@@ -0,0 +1,20 @@
+##===- lib/Target/Alpha/Makefile -------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+LEVEL = ../../..
+LIBRARYNAME = LLVMAlpha
+TARGET = Alpha
+SHARED_LIBRARY=1
+
+# Make sure that tblgen is run, first thing.
+BUILT_SOURCES = AlphaGenRegisterInfo.h.inc AlphaGenRegisterNames.inc \
+                AlphaGenRegisterInfo.inc AlphaGenInstrNames.inc \
+                AlphaGenInstrInfo.inc AlphaGenCodeEmitter.inc \
+                AlphaGenAsmWriter.inc
+
+include $(LEVEL)/Makefile.common