Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: src/IceInstX86BaseImpl.h

Issue 1273153002: Subzero. Native 64-bit int arithmetic on x86-64. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fixes tests & make format Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceInstX86Base.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceInstX86BaseImpl.h
diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h
index 29565580dc2a88edc230406008db932da03a8eee..d2512d7005411bf95a3b631deb611167d449cd4a 100644
--- a/src/IceInstX86BaseImpl.h
+++ b/src/IceInstX86BaseImpl.h
@@ -717,7 +717,8 @@ void emitIASRegOpTyGPR(
} else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
(Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue()));
} else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
- AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc);
+ AssemblerFixup *Fixup =
+ Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc);
(Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup));
} else if (const auto Split = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) {
@@ -746,7 +747,8 @@ void emitIASAddrOpTyGPR(
} else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
(Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue()));
} else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
- AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc);
+ AssemblerFixup *Fixup =
+ Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc);
(Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup));
} else {
llvm_unreachable("Unexpected operand type");
@@ -917,8 +919,8 @@ void emitIASRegOpTyXMM(
template <class Machine, typename DReg_t, typename SReg_t,
DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)>
-void emitIASCastRegOp(const Cfg *Func, Type DispatchTy, const Variable *Dest,
- const Operand *Src,
+void emitIASCastRegOp(const Cfg *Func, Type DestTy, const Variable *Dest,
+ Type SrcTy, const Operand *Src,
const typename InstX86Base<Machine>::Traits::Assembler::
template CastEmitterRegOp<DReg_t, SReg_t> &Emitter) {
typename InstX86Base<Machine>::Traits::Assembler *Asm =
@@ -928,18 +930,18 @@ void emitIASCastRegOp(const Cfg *Func, Type DispatchTy, const Variable *Dest,
if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
if (SrcVar->hasReg()) {
SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
- (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg);
+ (Asm->*(Emitter.RegReg))(DestTy, DestReg, SrcTy, SrcReg);
} else {
typename InstX86Base<Machine>::Traits::Address SrcStackAddr =
static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
Func->getTarget())
->stackVarToAsmOperand(SrcVar);
- (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr);
+ (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, SrcStackAddr);
}
} else if (const auto Mem = llvm::dyn_cast<
typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) {
Mem->emitSegmentOverride(Asm);
- (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm));
+ (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, Mem->toAsmAddress(Asm));
} else {
llvm_unreachable("Unexpected operand type");
}
@@ -1375,17 +1377,26 @@ void InstX86Cbwdq<Machine>::emit(const Cfg *Func) const {
case IceType_i8:
assert(this->getDest()->getRegNum() ==
InstX86Base<Machine>::Traits::RegisterSet::Reg_eax);
- Str << "\tcbtw";
+ Str << "\t"
+ << "cbtw";
break;
case IceType_i16:
assert(this->getDest()->getRegNum() ==
InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
- Str << "\tcwtd";
+ Str << "\t"
+ << "cwtd";
break;
case IceType_i32:
assert(this->getDest()->getRegNum() ==
InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
- Str << "\tcltd";
+ Str << "\t"
+ << "cltd";
+ break;
+ case IceType_i64:
+ assert(this->getDest()->getRegNum() ==
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
+ Str << "\t"
+ << "cdto";
break;
}
}
@@ -1418,6 +1429,11 @@ void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const {
InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
Asm->cdq();
break;
+ case IceType_i64:
+ assert(this->getDest()->getRegNum() ==
+ InstX86Base<Machine>::Traits::RegisterSet::Reg_edx);
+ Asm->cqo();
+ break;
}
}
@@ -1580,7 +1596,8 @@ void InstX86Cmov<Machine>::emitIAS(const Cfg *Func) const {
assert(this->getSrcSize() == 2);
Operand *Src = this->getSrc(1);
Type SrcTy = Src->getType();
- assert(SrcTy == IceType_i16 || SrcTy == IceType_i32);
+ assert(SrcTy == IceType_i16 || SrcTy == IceType_i32 ||
+ (InstX86Base<Machine>::Traits::Is64Bit));
typename InstX86Base<Machine>::Traits::Assembler *Asm =
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>();
if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) {
@@ -1802,7 +1819,11 @@ void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const {
switch (Variant) {
case Si2ss: {
assert(isScalarIntegerType(SrcTy));
- assert(typeWidthInBytes(SrcTy) <= 4);
+ if (!InstX86Base<Machine>::Traits::Is64Bit) {
+ assert(typeWidthInBytes(SrcTy) <= 4);
+ } else {
+ assert(SrcTy == IceType_i32 || SrcTy == IceType_i64);
+ }
assert(isScalarFloatingType(DestTy));
static const typename InstX86Base<Machine>::Traits::Assembler::
template CastEmitterRegOp<
@@ -1816,13 +1837,17 @@ void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const {
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm,
InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>(
- Func, DestTy, Dest, Src, Emitter);
+ Func, DestTy, Dest, SrcTy, Src, Emitter);
return;
}
case Tss2si: {
assert(isScalarFloatingType(SrcTy));
assert(isScalarIntegerType(DestTy));
- assert(typeWidthInBytes(DestTy) <= 4);
+ if (!InstX86Base<Machine>::Traits::Is64Bit) {
+ assert(typeWidthInBytes(DestTy) <= 4);
+ } else {
+ assert(DestTy == IceType_i32 || DestTy == IceType_i64);
+ }
static const typename InstX86Base<Machine>::Traits::Assembler::
template CastEmitterRegOp<
typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister,
@@ -1835,7 +1860,7 @@ void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const {
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister,
InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR,
InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>(
- Func, SrcTy, Dest, Src, Emitter);
+ Func, DestTy, Dest, SrcTy, Src, Emitter);
return;
}
case Float2float: {
@@ -2232,6 +2257,10 @@ template <class Machine> void InstX86Lea<Machine>::emit(const Cfg *Func) const {
this->getDest()->emit(Func);
}
+inline bool isIntegerConstant(const Operand *Op) {
+ return llvm::isa<ConstantInteger32>(Op) || llvm::isa<ConstantInteger64>(Op);
+}
+
template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const {
if (!BuildDefs::dump())
return;
@@ -2240,11 +2269,16 @@ template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const {
Operand *Src = this->getSrc(0);
Type SrcTy = Src->getType();
Type DestTy = this->getDest()->getType();
- Str << "\tmov"
- << (!isScalarFloatingType(DestTy)
- ? this->getWidthString(SrcTy)
- : InstX86Base<Machine>::Traits::TypeAttributes[DestTy].SdSsString)
- << "\t";
+ if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 &&
+ isIntegerConstant(Src)) {
+ Str << "\tmovabs\t";
+ } else {
+ Str << "\tmov"
+ << (!isScalarFloatingType(DestTy)
+ ? this->getWidthString(SrcTy)
+ : InstX86Base<Machine>::Traits::TypeAttributes[DestTy]
+ .SdSsString) << "\t";
+ }
// For an integer truncation operation, src is wider than dest.
// Ideally, we use a mov instruction whose data width matches the
// narrower dest. This is a problem if e.g. src is a register like
@@ -2308,6 +2342,20 @@ void InstX86Mov<Machine>::emitIAS(const Cfg *Func) const {
assert(isScalarIntegerType(DestTy));
// Widen DestTy for truncation (see above note). We should only do this
// when both Src and Dest are integer types.
+ if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 &&
+ isIntegerConstant(Src)) {
+ uint64_t Value = -1;
+ if (const auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src)) {
+ Value = C64->getValue();
+ } else {
+ Value = llvm::cast<ConstantInteger32>(Src)->getValue();
+ }
+ Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>()
+ ->movabs(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+ Dest->getRegNum()),
+ Value);
+ return;
+ }
if (isScalarIntegerType(SrcTy)) {
DestTy = SrcTy;
}
@@ -2351,14 +2399,19 @@ void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const {
const auto SrcVar = llvm::cast<Variable>(this->getSrc(0));
// For insert/extract element (one of Src/Dest is an Xmm vector and
// the other is an int type).
- if (SrcVar->getType() == IceType_i32) {
- assert(isVectorType(Dest->getType()));
+ if (SrcVar->getType() == IceType_i32 ||
+ (InstX86Base<Machine>::Traits::Is64Bit &&
+ SrcVar->getType() == IceType_i64)) {
+ assert(isVectorType(Dest->getType()) ||
+ (isScalarFloatingType(Dest->getType()) &&
+ typeWidthInBytes(SrcVar->getType()) ==
+ typeWidthInBytes(Dest->getType())));
assert(Dest->hasReg());
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg =
InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
Dest->getRegNum());
if (SrcVar->hasReg()) {
- Asm->movd(DestReg,
+ Asm->movd(SrcVar->getType(), DestReg,
InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
SrcVar->getRegNum()));
} else {
@@ -2366,17 +2419,23 @@ void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const {
static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
Func->getTarget())
->stackVarToAsmOperand(SrcVar));
- Asm->movd(DestReg, StackAddr);
+ Asm->movd(SrcVar->getType(), DestReg, StackAddr);
}
} else {
- assert(isVectorType(SrcVar->getType()));
+ assert(isVectorType(SrcVar->getType()) ||
+ (isScalarFloatingType(SrcVar->getType()) &&
+ typeWidthInBytes(SrcVar->getType()) ==
+ typeWidthInBytes(Dest->getType())));
assert(SrcVar->hasReg());
- assert(Dest->getType() == IceType_i32);
+ assert(Dest->getType() == IceType_i32 ||
+ (InstX86Base<Machine>::Traits::Is64Bit &&
+ Dest->getType() == IceType_i64));
typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg =
InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm(
SrcVar->getRegNum());
if (Dest->hasReg()) {
- Asm->movd(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
+ Asm->movd(Dest->getType(),
+ InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR(
Dest->getRegNum()),
SrcReg);
} else {
@@ -2384,7 +2443,7 @@ void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const {
static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>(
Func->getTarget())
->stackVarToAsmOperand(Dest));
- Asm->movd(StackAddr, SrcReg);
+ Asm->movd(Dest->getType(), StackAddr, SrcReg);
}
}
}
« no previous file with comments | « src/IceInstX86Base.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698