Commit 9c2c093f by Jim Stichnoth

Subzero: x86-64: Allow immediates in 64-bit instructions.

The original code legalized *all* i64 constants into a register move, creating unnecessary instructions and slightly higher register pressure in most cases. Generally, immediates can be used in 64-bit instructions as long as the immediate can be represented as a sign-extended 32-bit value. BUG= none R=jpp@chromium.org Review URL: https://codereview.chromium.org/2063053002 .
parent 3f5cb6f3
......@@ -295,7 +295,6 @@ void AssemblerX86Base<TraitsType>::mov(Type Ty, const Address &dst,
template <typename TraitsType>
void AssemblerX86Base<TraitsType>::mov(Type Ty, const Address &dst,
const Immediate &imm) {
assert(Ty != IceType_i64 && "i64 not supported yet.");
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
if (Ty == IceType_i16)
emitOperandSizeOverride();
......@@ -2641,7 +2640,7 @@ template <typename TraitsType>
void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister reg,
const Immediate &imm) {
AssemblerBuffer::EnsureCapacity ensured(&Buffer);
assert(Ty == IceType_i16 || Ty == IceType_i32);
assert(Ty == IceType_i16 || Ty == IceType_i32 || Ty == IceType_i64);
if (Ty == IceType_i16)
emitOperandSizeOverride();
emitRexRB(Ty, reg, reg);
......
......@@ -738,6 +738,10 @@ void InstImpl<TraitsType>::emitIASRegOpTyGPR(const Cfg *Func, bool IsLea,
Mem->toAsmAddress(Asm, Target, IsLea));
} else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
(Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue()));
} else if (const auto *Imm = llvm::dyn_cast<ConstantInteger64>(Src)) {
assert(Traits::Is64Bit);
assert(Utils::IsInt(32, Imm->getValue()));
(Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue()));
} else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
const auto FixupKind = (Reloc->getName().hasStdString() &&
Reloc->getName().toString() == GlobalOffsetTable)
......@@ -765,6 +769,10 @@ void InstImpl<TraitsType>::emitIASAddrOpTyGPR(const Cfg *Func, Type Ty,
(Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg);
} else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
(Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Imm->getValue()));
} else if (const auto *Imm = llvm::dyn_cast<ConstantInteger64>(Src)) {
assert(Traits::Is64Bit);
assert(Utils::IsInt(32, Imm->getValue()));
(Asm->*(Emitter.AddrImm))(Ty, Addr, AssemblerImmediate(Imm->getValue()));
} else if (const auto *Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
const auto FixupKind = (Reloc->getName().hasStdString() &&
Reloc->getName().toString() == GlobalOffsetTable)
......@@ -816,6 +824,10 @@ void InstImpl<TraitsType>::emitIASGPRShift(const Cfg *Func, Type Ty,
(Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
} else if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
(Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue()));
} else if (const auto *Imm = llvm::dyn_cast<ConstantInteger64>(Src)) {
assert(Traits::Is64Bit);
assert(Utils::IsInt(32, Imm->getValue()));
(Asm->*(Emitter.GPRImm))(Ty, VarReg, AssemblerImmediate(Imm->getValue()));
} else {
llvm_unreachable("Unexpected operand type");
}
......@@ -2042,7 +2054,8 @@ void InstImpl<TraitsType>::InstX86Mov::emit(const Cfg *Func) const {
Type SrcTy = Src->getType();
Type DestTy = this->getDest()->getType();
if (Traits::Is64Bit && DestTy == IceType_i64 &&
llvm::isa<ConstantInteger64>(Src)) {
llvm::isa<ConstantInteger64>(Src) &&
!Utils::IsInt(32, llvm::cast<ConstantInteger64>(Src)->getValue())) {
Str << "\t"
"movabs"
"\t";
......
......@@ -2228,21 +2228,24 @@ void TargetX86Base<TraitsType>::lowerArithmetic(const InstArithmetic *Instr) {
break;
case InstArithmetic::Shl:
_mov(T, Src0);
if (!llvm::isa<ConstantInteger32>(Src1))
if (!llvm::isa<ConstantInteger32>(Src1) &&
!llvm::isa<ConstantInteger64>(Src1))
Src1 = copyToReg8(Src1, Traits::RegisterSet::Reg_cl);
_shl(T, Src1);
_mov(Dest, T);
break;
case InstArithmetic::Lshr:
_mov(T, Src0);
if (!llvm::isa<ConstantInteger32>(Src1))
if (!llvm::isa<ConstantInteger32>(Src1) &&
!llvm::isa<ConstantInteger64>(Src1))
Src1 = copyToReg8(Src1, Traits::RegisterSet::Reg_cl);
_shr(T, Src1);
_mov(Dest, T);
break;
case InstArithmetic::Ashr:
_mov(T, Src0);
if (!llvm::isa<ConstantInteger32>(Src1))
if (!llvm::isa<ConstantInteger32>(Src1) &&
!llvm::isa<ConstantInteger64>(Src1))
Src1 = copyToReg8(Src1, Traits::RegisterSet::Reg_cl);
_sar(T, Src1);
_mov(Dest, T);
......@@ -7339,11 +7342,13 @@ Operand *TargetX86Base<TraitsType>::legalize(Operand *From, LegalMask Allowed,
// If the operand is a 64 bit constant integer we need to legalize it to a
// register in x86-64.
if (Traits::Is64Bit) {
if (llvm::isa<ConstantInteger64>(Const)) {
if (RegNum.hasValue()) {
assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum);
if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Const)) {
if (!Utils::IsInt(32, C64->getValue())) {
if (RegNum.hasValue()) {
assert(Traits::getGprForType(IceType_i64, RegNum) == RegNum);
}
return copyToReg(Const, RegNum);
}
return copyToReg(Const, RegNum);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment