bool SelectIntExt(const Instruction *I);
bool SelectMul(const Instruction *I);
bool SelectShift(const Instruction *I, bool IsLeftShift, bool IsArithmetic);
+ bool SelectBitCast(const Instruction *I);
// Utility helper routines.
bool isTypeLegal(Type *Ty, MVT &VT);
return true;
}
+bool AArch64FastISel::SelectBitCast(const Instruction *I) {
+ MVT RetVT, SrcVT;
+
+ if (!isTypeLegal(I->getOperand(0)->getType(), SrcVT))
+ return false;
+ if (!isTypeLegal(I->getType(), RetVT))
+ return false;
+
+ unsigned Opc;
+ if (RetVT == MVT::f32 && SrcVT == MVT::i32)
+ Opc = AArch64::FMOVWSr;
+ else if (RetVT == MVT::f64 && SrcVT == MVT::i64)
+ Opc = AArch64::FMOVXDr;
+ else if (RetVT == MVT::i32 && SrcVT == MVT::f32)
+ Opc = AArch64::FMOVSWr;
+ else if (RetVT == MVT::i64 && SrcVT == MVT::f64)
+ Opc = AArch64::FMOVDXr;
+ else
+ return false;
+
+ unsigned Op0Reg = getRegForValue(I->getOperand(0));
+ if (!Op0Reg)
+ return false;
+ bool Op0IsKill = hasTrivialKill(I->getOperand(0));
+ unsigned ResultReg = FastEmitInst_r(Opc, TLI.getRegClassFor(RetVT),
+ Op0Reg, Op0IsKill);
+
+ if (!ResultReg)
+ return false;
+
+ UpdateValueMap(I, ResultReg);
+ return true;
+}
+
bool AArch64FastISel::TargetSelectInstruction(const Instruction *I) {
switch (I->getOpcode()) {
default:
return SelectShift(I, /*IsLeftShift=*/false, /*IsArithmetic=*/false);
case Instruction::AShr:
return SelectShift(I, /*IsLeftShift=*/false, /*IsArithmetic=*/true);
+ case Instruction::BitCast:
+ return SelectBitCast(I);
}
return false;
// Silence warnings.
%big = zext i16 %in to i64
ret i64 %big
}
+
+define float @bitcast_i32_to_float(i32 %a) {
+ %1 = bitcast i32 %a to float
+ ret float %1
+}
+
+define double @bitcast_i64_to_double(i64 %a) {
+ %1 = bitcast i64 %a to double
+ ret double %1
+}
+
+define i32 @bitcast_float_to_i32(float %a) {
+ %1 = bitcast float %a to i32
+ ret i32 %1
+}
+
+define i64 @bitcast_double_to_i64(double %a) {
+ %1 = bitcast double %a to i64
+ ret i64 %1
+}
+