[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