Index: src/IceTargetLoweringX8632.cpp |
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp |
index 81973d06cd027df3c652d75c789e6d380ff6e352..bf7665052cba593e5f40333c812979abf8c934ba 100644 |
--- a/src/IceTargetLoweringX8632.cpp |
+++ b/src/IceTargetLoweringX8632.cpp |
@@ -758,7 +758,7 @@ Operand *TargetX8632::loOperand(Operand *Operand) { |
if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { |
return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), |
Mem->getOffset(), Mem->getIndex(), |
- Mem->getShift()); |
+ Mem->getShift(), Mem->getSegmentRegister()); |
} |
llvm_unreachable("Unsupported operand type"); |
return NULL; |
@@ -788,7 +788,8 @@ Operand *TargetX8632::hiOperand(Operand *Operand) { |
SymOffset->getName()); |
} |
return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), Offset, |
- Mem->getIndex(), Mem->getShift()); |
+ Mem->getIndex(), Mem->getShift(), |
+ Mem->getSegmentRegister()); |
} |
llvm_unreachable("Unsupported operand type"); |
return NULL; |
@@ -1764,6 +1765,86 @@ void TargetX8632::lowerIcmp(const InstIcmp *Inst) { |
Context.insert(Label); |
} |
+void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
+ switch (Instr->getIntrinsicInfo().ID) { |
+ case AtomicCmpxchg: |
+ case AtomicFence: |
+ case AtomicFenceAll: |
+ case AtomicIsLockFree: |
+ case AtomicLoad: |
+ case AtomicRMW: |
+ case AtomicStore: |
+ case Bswap: |
+ case Ctlz: |
+ case Ctpop: |
+ case Cttz: |
+ Func->setError("Unhandled intrinsic"); |
+ return; |
+ case Longjmp: { |
+ InstCall *Call = makeHelperCall("longjmp", NULL, 2); |
+ Call->addArg(Instr->getArg(0)); |
+ Call->addArg(Instr->getArg(1)); |
+ lowerCall(Call); |
+ break; |
+ } |
+ case Memcpy: { |
+ // In the future, we could potentially emit an inline memcpy/memset, etc. |
+ // for intrinsic calls w/ a known length. |
+ InstCall *Call = makeHelperCall("memcpy", NULL, 3); |
+ Call->addArg(Instr->getArg(0)); |
+ Call->addArg(Instr->getArg(1)); |
+ Call->addArg(Instr->getArg(2)); |
+ lowerCall(Call); |
+ break; |
+ } |
+ case Memmove: { |
+ InstCall *Call = makeHelperCall("memmove", NULL, 3); |
+ Call->addArg(Instr->getArg(0)); |
+ Call->addArg(Instr->getArg(1)); |
+ Call->addArg(Instr->getArg(2)); |
+ lowerCall(Call); |
+ break; |
+ } |
+ case Memset: { |
+ InstCall *Call = makeHelperCall("memset", NULL, 3); |
+ Call->addArg(Instr->getArg(0)); |
+ Call->addArg(Instr->getArg(1)); |
+ Call->addArg(Instr->getArg(2)); |
+ lowerCall(Call); |
+ break; |
+ } |
+ case NaClReadTP: { |
+ Constant *Zero = Ctx->getConstantInt(IceType_i32, 0); |
+ Operand *Src = OperandX8632Mem::create( |
+ Func, IceType_i32, NULL, Zero, NULL, 0, |
+ OperandX8632Mem::Reg_GS); |
+ Variable *Dest = Instr->getDest(); |
+ Variable *T = NULL; |
+ _mov(T, Src); |
+ _mov(Dest, T); |
+ break; |
+ } |
+ case Setjmp: { |
+ InstCall *Call = makeHelperCall("setjmp", Instr->getDest(), 1); |
+ Call->addArg(Instr->getArg(0)); |
+ lowerCall(Call); |
+ break; |
+ } |
+ case Sqrt: |
+ case Stacksave: |
+ case Stackrestore: |
+ Func->setError("Unhandled intrinsic"); |
+ return; |
+ case Trap: |
+ _ud2(); |
+ break; |
+ case UnknownIntrinsic: |
+ Func->setError("Should not be lowering UnknownIntrinsic"); |
+ return; |
+ } |
+ return; |
+} |
+ |
namespace { |
bool isAdd(const Inst *Inst) { |
@@ -1774,7 +1855,7 @@ bool isAdd(const Inst *Inst) { |
return false; |
} |
-void computeAddressOpt(Variable *&Base, Variable *&Index, int32_t &Shift, |
+void computeAddressOpt(Variable *&Base, Variable *&Index, uint16_t &Shift, |
int32_t &Offset) { |
(void)Offset; // TODO: pattern-match for non-zero offsets. |
if (Base == NULL) |
@@ -1955,14 +2036,20 @@ void TargetX8632::doAddressOptLoad() { |
Variable *Dest = Inst->getDest(); |
Operand *Addr = Inst->getSrc(0); |
Variable *Index = NULL; |
- int32_t Shift = 0; |
+ uint16_t Shift = 0; |
int32_t Offset = 0; // TODO: make Constant |
+ // At the ICE level, load instructions should not use the |
Jim Stichnoth
2014/06/12 20:52:07
ICE includes both high-level (close to bitcode) an
jvoung (off chromium)
2014/06/16 20:51:59
Done.
|
+ // segment registers, and computeAddressOpt only works at the level |
+ // of Variables and Constants, not other OperandX8632Mem, so there |
+ // should be no mention of segment registers there either. |
+ OperandX8632Mem::SegmentRegisters SegmentReg = |
Jim Stichnoth
2014/06/12 20:52:07
Mark this const? (here and below)
jvoung (off chromium)
2014/06/16 20:51:59
Done.
|
+ OperandX8632Mem::DefaultSegment; |
Variable *Base = llvm::dyn_cast<Variable>(Addr); |
computeAddressOpt(Base, Index, Shift, Offset); |
if (Base && Addr != Base) { |
Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); |
Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index, |
- Shift); |
+ Shift, SegmentReg); |
Inst->setDeleted(); |
Context.insert(InstLoad::create(Func, Dest, Addr)); |
} |
@@ -2071,14 +2158,20 @@ void TargetX8632::doAddressOptStore() { |
Operand *Data = Inst->getData(); |
Operand *Addr = Inst->getAddr(); |
Variable *Index = NULL; |
- int32_t Shift = 0; |
+ uint16_t Shift = 0; |
int32_t Offset = 0; // TODO: make Constant |
Variable *Base = llvm::dyn_cast<Variable>(Addr); |
+ // At the ICE level, load instructions should not use the |
+ // segment registers, and computeAddressOpt only works at the level |
+ // of Variables and Constants, not other OperandX8632Mem, so there |
+ // should be no mention of segment registers there either. |
+ OperandX8632Mem::SegmentRegisters SegmentReg = |
+ OperandX8632Mem::DefaultSegment; |
computeAddressOpt(Base, Index, Shift, Offset); |
if (Base && Addr != Base) { |
Constant *OffsetOp = Ctx->getConstantInt(IceType_i32, Offset); |
Addr = OperandX8632Mem::create(Func, Data->getType(), Base, OffsetOp, Index, |
- Shift); |
+ Shift, SegmentReg); |
Inst->setDeleted(); |
Context.insert(InstStore::create(Func, Data, Addr)); |
} |
@@ -2139,7 +2232,8 @@ Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, |
if (Base != RegBase || Index != RegIndex) { |
From = |
OperandX8632Mem::create(Func, Mem->getType(), RegBase, |
- Mem->getOffset(), RegIndex, Mem->getShift()); |
+ Mem->getOffset(), RegIndex, Mem->getShift(), |
+ Mem->getSegmentRegister()); |
} |
if (!(Allowed & Legal_Mem)) { |