[llvm-commits] CVS: llvm/lib/Target/SparcV8/InstSelectSimple.cpp SparcV8InstrInfo.td

Brian Gaeke gaeke at cs.uiuc.edu
Wed Mar 3 17:05:01 PST 2004


Changes in directory llvm/lib/Target/SparcV8:

InstSelectSimple.cpp updated: 1.1 -> 1.2
SparcV8InstrInfo.td updated: 1.1 -> 1.2

---
Log message:

Support add - note, still missing important copyConstantToRegister stuff

---
Diffs of the changes:  (+160 -3)

Index: llvm/lib/Target/SparcV8/InstSelectSimple.cpp
diff -u llvm/lib/Target/SparcV8/InstSelectSimple.cpp:1.1 llvm/lib/Target/SparcV8/InstSelectSimple.cpp:1.2
--- llvm/lib/Target/SparcV8/InstSelectSimple.cpp:1.1	Sat Feb 28 18:27:00 2004
+++ llvm/lib/Target/SparcV8/InstSelectSimple.cpp	Wed Mar  3 17:03:14 2004
@@ -12,11 +12,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "SparcV8.h"
+#include "SparcV8InstrInfo.h"
 #include "llvm/Instructions.h"
 #include "llvm/IntrinsicLowering.h"
 #include "llvm/Pass.h"
+#include "llvm/Constants.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/SSARegMap.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/InstVisitor.h"
@@ -54,6 +57,7 @@
       BB = MBBMap[&LLVM_BB];
     }
 
+	void visitBinaryOperator(BinaryOperator &I);
     void visitReturnInst(ReturnInst &RI);
 
     void visitInstruction(Instruction &I) {
@@ -65,9 +69,71 @@
     /// function, lowering any calls to unknown intrinsic functions into the
     /// equivalent LLVM code.
     void LowerUnknownIntrinsicFunctionCalls(Function &F);
+    void visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI);
 
+    /// copyConstantToRegister - Output the instructions required to put the
+    /// specified constant into the specified register.
+    ///
+    void copyConstantToRegister(MachineBasicBlock *MBB,
+                                MachineBasicBlock::iterator IP,
+                                Constant *C, unsigned R);
 
-    void visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI);
+    /// makeAnotherReg - This method returns the next register number we haven't
+    /// yet used.
+    ///
+    /// Long values are handled somewhat specially.  They are always allocated
+    /// as pairs of 32 bit integer values.  The register number returned is the
+    /// lower 32 bits of the long value, and the regNum+1 is the upper 32 bits
+    /// of the long value.
+    ///
+    unsigned makeAnotherReg(const Type *Ty) {
+      assert(dynamic_cast<const SparcV8RegisterInfo*>(TM.getRegisterInfo()) &&
+             "Current target doesn't have SparcV8 reg info??");
+      const SparcV8RegisterInfo *MRI =
+        static_cast<const SparcV8RegisterInfo*>(TM.getRegisterInfo());
+      if (Ty == Type::LongTy || Ty == Type::ULongTy) {
+        const TargetRegisterClass *RC = MRI->getRegClassForType(Type::IntTy);
+        // Create the lower part
+        F->getSSARegMap()->createVirtualRegister(RC);
+        // Create the upper part.
+        return F->getSSARegMap()->createVirtualRegister(RC)-1;
+      }
+
+      // Add the mapping of regnumber => reg class to MachineFunction
+      const TargetRegisterClass *RC = MRI->getRegClassForType(Ty);
+      return F->getSSARegMap()->createVirtualRegister(RC);
+    }
+
+    unsigned getReg(Value &V) { return getReg (&V); } // allow refs.
+    unsigned getReg(Value *V) {
+      // Just append to the end of the current bb.
+      MachineBasicBlock::iterator It = BB->end();
+      return getReg(V, BB, It);
+    }
+    unsigned getReg(Value *V, MachineBasicBlock *MBB,
+                    MachineBasicBlock::iterator IPt) {
+      unsigned &Reg = RegMap[V];
+      if (Reg == 0) {
+        Reg = makeAnotherReg(V->getType());
+        RegMap[V] = Reg;
+      }
+      // If this operand is a constant, emit the code to copy the constant into
+      // the register here...
+      //
+      if (Constant *C = dyn_cast<Constant>(V)) {
+        copyConstantToRegister(MBB, IPt, C, Reg);
+        RegMap.erase(V);  // Assign a new name to this constant if ref'd again
+      } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+        // Move the address of the global into the register
+        //  X86 does:
+        // BuildMI(*MBB, IPt, V8::ORrr, 2, Reg).addReg(G0).addGlobalAddress(GV);
+        //  We need to use SETHI and OR.
+        assert (0 && "Can't move address of global yet");
+        RegMap.erase(V);  // Assign a new name to this address if ref'd again
+      }
+
+      return Reg;
+    }
 
   };
 }
@@ -76,6 +142,40 @@
   return new V8ISel(TM);
 }
 
+enum TypeClass {
+  cByte, cShort, cInt, cFloat, cDouble
+};
+
+static TypeClass getClass (const Type *T) {
+  switch (T->getPrimitiveID ()) {
+    case Type::UByteTyID:  case Type::SByteTyID:  return cByte;
+    case Type::UShortTyID: case Type::ShortTyID:  return cShort;
+    case Type::UIntTyID:   case Type::IntTyID:    return cInt;
+    case Type::FloatTyID:                         return cFloat;
+    case Type::DoubleTyID:                        return cDouble;
+    default:
+      assert (0 && "Type of unknown class passed to getClass?");
+      return cByte;
+  }
+}
+
+/// copyConstantToRegister - Output the instructions required to put the
+/// specified constant into the specified register.
+///
+void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB,
+                                    MachineBasicBlock::iterator IP,
+                                    Constant *C, unsigned R) {
+  if (C->getType()->isIntegral()) {
+    unsigned Class = getClass(C->getType());
+
+    ConstantInt *CI = cast<ConstantInt>(C);
+    // cByte: or %g0, <imm>, <dest>
+    // cShort or cInt: sethi, then or
+    // BuildMI(*MBB, IP, <opcode>, <#regs>, R).addImm(CI->getRawValue());
+  }
+
+  assert (0 && "Can't copy constants into registers yet");
+}
 
 bool V8ISel::runOnFunction(Function &Fn) {
   // First pass over the function, lower any unknown intrinsic functions
@@ -113,11 +213,56 @@
 
 void V8ISel::visitReturnInst(ReturnInst &I) {
   if (I.getNumOperands() == 0) {
-    // Just emit a 'ret' instruction
+    // Just emit a 'jmpl' instruction to return.
     BuildMI(BB, V8::JMPLi, 2, V8::G0).addZImm(8).addReg(V8::I7);
     return;
   }
   visitInstruction(I);
+}
+
+void V8ISel::visitBinaryOperator (BinaryOperator &I) {
+  unsigned DestReg = getReg (I);
+  unsigned Op0Reg = getReg (I.getOperand (0));
+  unsigned Op1Reg = getReg (I.getOperand (1));
+
+  unsigned ResultReg = makeAnotherReg (I.getType ());
+  switch (I.getOpcode ()) {
+    case Instruction::Add: 
+      BuildMI (BB, V8::ADDrr, 2, ResultReg).addReg (Op0Reg).addReg (Op1Reg);
+      break;
+    default:
+	  visitInstruction (I);
+      return;
+  }
+
+  switch (getClass (I.getType ())) {
+    case cByte: 
+	  if (I.getType ()->isSigned ()) { // add byte
+		BuildMI (BB, V8::ANDri, 2, DestReg).addReg (ResultReg).addZImm (0xff);
+	  } else { // add ubyte
+		unsigned TmpReg = makeAnotherReg (I.getType ());
+		BuildMI (BB, V8::SLLri, 2, TmpReg).addReg (ResultReg).addZImm (24);
+		BuildMI (BB, V8::SRAri, 2, DestReg).addReg (TmpReg).addZImm (24);
+	  }
+      break;
+    case cShort:
+	  if (I.getType ()->isSigned ()) { // add short
+		unsigned TmpReg = makeAnotherReg (I.getType ());
+		BuildMI (BB, V8::SLLri, 2, TmpReg).addReg (ResultReg).addZImm (16);
+		BuildMI (BB, V8::SRAri, 2, DestReg).addReg (TmpReg).addZImm (16);
+	  } else { // add ushort
+		unsigned TmpReg = makeAnotherReg (I.getType ());
+		BuildMI (BB, V8::SLLri, 2, TmpReg).addReg (ResultReg).addZImm (24);
+		BuildMI (BB, V8::SRLri, 2, DestReg).addReg (TmpReg).addZImm (24);
+	  }
+      break;
+    case cInt:
+	  BuildMI (BB, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (ResultReg);
+      break;
+    default:
+	  visitInstruction (I);
+      return;
+  }
 }
 
 


Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td
diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.1 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.2
--- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.1	Sat Feb 28 13:45:39 2004
+++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td	Wed Mar  3 17:03:14 2004
@@ -62,7 +62,19 @@
   let Name = "call";
 }
 
-// Section B.25: Jump and Link - p126
+// Section B.11 - Logical Instructions, p. 106
+def ANDri : F3_2<2, 0b000001, "and">;
+def ORrr  : F3_1<2, 0b000010, "or">;
+
+// Section B.12 - Shift Instructions, p. 107
+def SLLri : F3_1<2, 0b100101, "sll">;
+def SRLri : F3_1<2, 0b100110, "srl">;
+def SRAri : F3_1<2, 0b100111, "sra">;
+
+// Section B.13 - Add Instructions, p. 108
+def ADDrr : F3_1<2, 0b000000, "add">;
+
+// Section B.25 - Jump and Link, p. 126
 def JMPLr : F3_1<2, 0b111000, "jmpl">;              // jmpl [rs1+rs2], rd
 def JMPLi : F3_2<2, 0b111000, "jmpl">;              // jmpl [rs1+imm], rd
 





More information about the llvm-commits mailing list