aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Sparc/InstSelectSimple.cpp
diff options
context:
space:
mode:
authorBrian Gaeke <gaeke@uiuc.edu>2004-06-15 19:16:07 +0000
committerBrian Gaeke <gaeke@uiuc.edu>2004-06-15 19:16:07 +0000
commit9df92825e12afa744385a50a8a829f2eb5d1a6a1 (patch)
treeb8402946c17f171fdb91e42f4e64103bd77fad79 /lib/Target/Sparc/InstSelectSimple.cpp
parent8238c27371d318a373deb162b335d0bd06babe7c (diff)
Support constant GEP expressions.
Support copying long constants to register pairs. Support copying ConstantPointerNulls and ConstantPointerRefs to registers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14175 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc/InstSelectSimple.cpp')
-rw-r--r--lib/Target/Sparc/InstSelectSimple.cpp73
1 files changed, 52 insertions, 21 deletions
diff --git a/lib/Target/Sparc/InstSelectSimple.cpp b/lib/Target/Sparc/InstSelectSimple.cpp
index 55d6af3206..9127682d08 100644
--- a/lib/Target/Sparc/InstSelectSimple.cpp
+++ b/lib/Target/Sparc/InstSelectSimple.cpp
@@ -18,6 +18,7 @@
#include "llvm/Pass.h"
#include "llvm/Constants.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/TargetMachine.h"
@@ -193,15 +194,51 @@ static TypeClass getClassB(const Type *T) {
void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB,
MachineBasicBlock::iterator IP,
Constant *C, unsigned R) {
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ switch (CE->getOpcode()) {
+ case Instruction::GetElementPtr:
+ emitGEPOperation(MBB, IP, CE->getOperand(0),
+ CE->op_begin()+1, CE->op_end(), R);
+ return;
+ default:
+ std::cerr << "Copying this constant expr not yet handled: " << *CE;
+ abort();
+ }
+ }
+
if (C->getType()->isIntegral ()) {
uint64_t Val;
+ unsigned Class = getClassB (C->getType ());
+ if (Class == cLong) {
+ unsigned TmpReg = makeAnotherReg (Type::IntTy);
+ unsigned TmpReg2 = makeAnotherReg (Type::IntTy);
+ // Copy the value into the register pair.
+ // R = top(more-significant) half, R+1 = bottom(less-significant) half
+ uint64_t Val = cast<ConstantInt>(C)->getRawValue();
+ unsigned topHalf = Val & 0xffffffffU;
+ unsigned bottomHalf = Val >> 32;
+ unsigned HH = topHalf >> 10;
+ unsigned HM = topHalf & 0x03ff;
+ unsigned LM = bottomHalf >> 10;
+ unsigned LO = bottomHalf & 0x03ff;
+ BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addImm(HH);
+ BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (TmpReg)
+ .addImm (HM);
+ BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg2).addImm(LM);
+ BuildMI (*MBB, IP, V8::ORri, 2, R+1).addReg (TmpReg2)
+ .addImm (LO);
+ return;
+ }
+
+ assert(Class <= cInt && "Type not handled yet!");
+
if (C->getType() == Type::BoolTy) {
Val = (C == ConstantBool::True);
} else {
ConstantInt *CI = dyn_cast<ConstantInt> (C);
Val = CI->getRawValue ();
}
- switch (getClassB (C->getType ())) {
+ switch (Class) {
case cByte:
BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (V8::G0).addImm((uint8_t)Val);
return;
@@ -220,32 +257,26 @@ void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB,
.addImm (((uint32_t) Val) & 0x03ff);
return;
}
- case cLong: {
- unsigned TmpReg = makeAnotherReg (Type::UIntTy);
- uint32_t topHalf = (uint32_t) (Val >> 32);
- uint32_t bottomHalf = (uint32_t)Val;
-#if 0 // FIXME: This does not appear to be correct; it assigns SSA reg R twice.
- BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addImm (topHalf >> 10);
- BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (TmpReg)
- .addImm (topHalf & 0x03ff);
- BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addImm (bottomHalf >> 10);
- BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (TmpReg)
- .addImm (bottomHalf & 0x03ff);
-#else
- std::cerr << "Offending constant: " << *C << "\n";
- assert (0 && "Can't copy this kind of constant into register yet");
-#endif
- return;
- }
default:
std::cerr << "Offending constant: " << *C << "\n";
assert (0 && "Can't copy this kind of constant into register yet");
return;
}
+ } else if (isa<ConstantPointerNull>(C)) {
+ // Copy zero (null pointer) to the register.
+ BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (V8::G0).addImm (0);
+ } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)) {
+ // Copy it with a SETHI/OR pair; the JIT + asmwriter should recognize
+ // that SETHI %reg,global == SETHI %reg,%hi(global) and
+ // OR %reg,global,%reg == OR %reg,%lo(global),%reg.
+ unsigned TmpReg = makeAnotherReg (C->getType ());
+ BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addGlobalAddress (CPR->getValue());
+ BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (TmpReg)
+ .addGlobalAddress (CPR->getValue ());
+ } else {
+ std::cerr << "Offending constant: " << *C << "\n";
+ assert (0 && "Can't copy this kind of constant into register yet");
}
-
- std::cerr << "Offending constant: " << *C << "\n";
- assert (0 && "Can't copy this kind of constant into register yet");
}
void V8ISel::LoadArgumentsToVirtualRegs (Function *F) {