unsigned AArch64FastISel::AArch64MaterializeInt(const ConstantInt *CI, MVT VT) {
if (VT > MVT::i64)
return 0;
-
- if (!CI->isZero())
- return FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
-
- // Create a copy from the zero register to materialize a "0" value.
- const TargetRegisterClass *RC = (VT == MVT::i64) ? &AArch64::GPR64RegClass
- : &AArch64::GPR32RegClass;
- unsigned ZeroReg = (VT == MVT::i64) ? AArch64::XZR : AArch64::WZR;
- unsigned ResultReg = createResultReg(RC);
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(TargetOpcode::COPY), ResultReg)
- .addReg(ZeroReg, getKillRegState(true));
- return ResultReg;
+ return FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
}
unsigned AArch64FastISel::AArch64MaterializeFP(const ConstantFP *CFP, MVT VT) {
// This checks to see if we can use FMOV instructions to materialize
// a constant, otherwise we have to materialize via the constant pool.
if (TLI.isFPImmLegal(Val, VT)) {
+ unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
+ // Positive zero (+0.0) has to be materialized with a fmov from the zero
+ // register, because the immediate version of fmov cannot encode zero.
+ if (Val.isPosZero()) {
+ unsigned ZReg = Is64Bit ? AArch64::XZR : AArch64::WZR;
+ unsigned Opc = Is64Bit ? AArch64::FMOVDr : AArch64::FMOVSr;
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
+ .addReg(ZReg, getKillRegState(true));
+ return ResultReg;
+ }
int Imm = Is64Bit ? AArch64_AM::getFP64Imm(Val)
: AArch64_AM::getFP32Imm(Val);
unsigned Opc = Is64Bit ? AArch64::FMOVDi : AArch64::FMOVSi;
- unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
.addImm(Imm);
return ResultReg;