Index: src/IceTargetLoweringX8632.cpp |
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp |
index af9ebc5a1dc79f02a42d83abc454ec12fb9ad874..b38481b44ef93f34a9596f66ddb28d1ef778a58e 100644 |
--- a/src/IceTargetLoweringX8632.cpp |
+++ b/src/IceTargetLoweringX8632.cpp |
@@ -2596,9 +2596,35 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
_mfence(); |
return; |
} |
- case Intrinsics::Bswap: |
- Func->setError("Unhandled intrinsic"); |
+ case Intrinsics::Bswap: { |
+ Variable *Dest = Instr->getDest(); |
+ Operand *Val = Instr->getArg(0); |
+ // In 32-bit mode, bswap only works on 32-bit arguments, and the |
+ // argument must be a register. Use rotate left for 16-bit bswap. |
+ if (Val->getType() == IceType_i64) { |
+ Variable *T_Lo = legalizeToVar(loOperand(Val)); |
+ Variable *T_Hi = legalizeToVar(hiOperand(Val)); |
+ Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
+ Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
+ _bswap(T_Lo); |
+ _bswap(T_Hi); |
+ _mov(DestLo, T_Hi); |
+ _mov(DestHi, T_Lo); |
+ } else if (Val->getType() == IceType_i32) { |
+ Variable *T = legalizeToVar(Val); |
+ _bswap(T); |
+ _mov(Dest, T); |
+ } else { |
+ assert(Val->getType() == IceType_i16); |
+ Val = legalize(Val); |
+ Constant *Eight = Ctx->getConstantInt(IceType_i16, 8); |
+ Variable *T = NULL; |
+ _mov(T, Val); |
+ _rol(T, Eight); |
+ _mov(Dest, T); |
+ } |
return; |
+ } |
case Intrinsics::Ctpop: { |
Variable *Dest = Instr->getDest(); |
Operand *Val = Instr->getArg(0); |