diff options
author | Juergen Ributzka <juergen@apple.com> | 2014-07-30 22:04:25 +0000 |
---|---|---|
committer | Juergen Ributzka <juergen@apple.com> | 2014-07-30 22:04:25 +0000 |
commit | ad3b09037dc88ea514ce061b57f4132a01a0b3ef (patch) | |
tree | 860b4dff38b8ecb02f7e3c356936113a38d61550 /llvm/lib/Target/AArch64/AArch64FastISel.cpp | |
parent | a75cb11f146f0bce624412479e0b4f563acf1c91 (diff) | |
download | bcm5719-llvm-ad3b09037dc88ea514ce061b57f4132a01a0b3ef.tar.gz bcm5719-llvm-ad3b09037dc88ea514ce061b57f4132a01a0b3ef.zip |
[FastISel][AArch64] Create helper functions to create the various multiplies on AArch64.
llvm-svn: 214346
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64FastISel.cpp')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64FastISel.cpp | 94 |
1 files changed, 70 insertions, 24 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp index 5dbcab53b45..1f1dfd7b49e 100644 --- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp +++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp @@ -130,6 +130,12 @@ private: bool UseUnscaled = false); unsigned EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool isZExt); unsigned Emiti1Ext(unsigned SrcReg, MVT DestVT, bool isZExt); + unsigned Emit_MUL_rr(MVT RetVT, unsigned Op0, bool Op0IsKill, + unsigned Op1, bool Op1IsKill); + unsigned Emit_SMULL_rr(MVT RetVT, unsigned Op0, bool Op0IsKill, + unsigned Op1, bool Op1IsKill); + unsigned Emit_UMULL_rr(MVT RetVT, unsigned Op0, bool Op0IsKill, + unsigned Op1, bool Op1IsKill); unsigned Emit_LSL_ri(MVT RetVT, unsigned Op0, bool Op0IsKill, uint64_t Imm); unsigned Emit_LSR_ri(MVT RetVT, unsigned Op0, bool Op0IsKill, uint64_t Imm); unsigned Emit_ASR_ri(MVT RetVT, unsigned Op0, bool Op0IsKill, uint64_t Imm); @@ -1726,6 +1732,62 @@ unsigned AArch64FastISel::Emiti1Ext(unsigned SrcReg, MVT DestVT, bool isZExt) { } } +unsigned AArch64FastISel::Emit_MUL_rr(MVT RetVT, unsigned Op0, bool Op0IsKill, + unsigned Op1, bool Op1IsKill) { + unsigned Opc, ZReg; + switch (RetVT.SimpleTy) { + default: return 0; + case MVT::i8: + case MVT::i16: + case MVT::i32: + RetVT = MVT::i32; + Opc = AArch64::MADDWrrr; ZReg = AArch64::WZR; break; + case MVT::i64: + Opc = AArch64::MADDXrrr; ZReg = AArch64::XZR; break; + } + + // Create the base instruction, then add the operands. + unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT)); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg) + .addReg(Op0, getKillRegState(Op0IsKill)) + .addReg(Op1, getKillRegState(Op1IsKill)) + .addReg(ZReg, getKillRegState(true)); + + return ResultReg; +} + +unsigned AArch64FastISel::Emit_SMULL_rr(MVT RetVT, unsigned Op0, bool Op0IsKill, + unsigned Op1, bool Op1IsKill) { + if (RetVT != MVT::i64) + return 0; + + // Create the base instruction, then add the operands. + unsigned ResultReg = createResultReg(&AArch64::GPR64RegClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::SMADDLrrr), + ResultReg) + .addReg(Op0, getKillRegState(Op0IsKill)) + .addReg(Op1, getKillRegState(Op1IsKill)) + .addReg(AArch64::XZR, getKillRegState(true)); + + return ResultReg; +} + +unsigned AArch64FastISel::Emit_UMULL_rr(MVT RetVT, unsigned Op0, bool Op0IsKill, + unsigned Op1, bool Op1IsKill) { + if (RetVT != MVT::i64) + return 0; + + // Create the base instruction, then add the operands. + unsigned ResultReg = createResultReg(&AArch64::GPR64RegClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::UMADDLrrr), + ResultReg) + .addReg(Op0, getKillRegState(Op0IsKill)) + .addReg(Op1, getKillRegState(Op1IsKill)) + .addReg(AArch64::XZR, getKillRegState(true)); + + return ResultReg; +} + unsigned AArch64FastISel::Emit_LSL_ri(MVT RetVT, unsigned Op0, bool Op0IsKill, uint64_t Shift) { unsigned Opc, ImmR, ImmS; @@ -1930,38 +1992,22 @@ bool AArch64FastISel::SelectMul(const Instruction *I) { SrcVT != MVT::i8) return false; - unsigned Opc; - unsigned ZReg; - switch (SrcVT.SimpleTy) { - default: - return false; - case MVT::i8: - case MVT::i16: - case MVT::i32: - ZReg = AArch64::WZR; - Opc = AArch64::MADDWrrr; - SrcVT = MVT::i32; - break; - case MVT::i64: - ZReg = AArch64::XZR; - Opc = AArch64::MADDXrrr; - break; - } - unsigned Src0Reg = getRegForValue(I->getOperand(0)); if (!Src0Reg) return false; + bool Src0IsKill = hasTrivialKill(I->getOperand(0)); unsigned Src1Reg = getRegForValue(I->getOperand(1)); if (!Src1Reg) return false; + bool Src1IsKill = hasTrivialKill(I->getOperand(1)); + + unsigned ResultReg = + Emit_MUL_rr(SrcVT, Src0Reg, Src0IsKill, Src1Reg, Src1IsKill); + + if (!ResultReg) + return false; - // Create the base instruction, then add the operands. - unsigned ResultReg = createResultReg(TLI.getRegClassFor(SrcVT)); - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg) - .addReg(Src0Reg) - .addReg(Src1Reg) - .addReg(ZReg); UpdateValueMap(I, ResultReg); return true; } |