diff --git a/Dockerfile b/Dockerfile index 1772052..e0340d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,6 +26,9 @@ RUN cd llvm/tools && \ # git clone -b release_38 --depth=1 https://github.com/llvm-mirror/libcxxabi.git && \ # git clone https://github.com/llvm-mirror/libunwind.git -b release_38 --depth=1 +RUN cd llvm && \ + git am /build/patches/llvm-*.patch + RUN cd llvm/tools/clang && \ git am /build/patches/clang-*.patch diff --git a/patches/llvm-0001.patch b/patches/llvm-0001.patch new file mode 100644 index 0000000..cd47d5f --- /dev/null +++ b/patches/llvm-0001.patch @@ -0,0 +1,613 @@ +From 2ff44aa1732a823a77e88bd30219e12cb14a4d66 Mon Sep 17 00:00:00 2001 +From: Sam Parker +Date: Tue, 19 Jul 2016 14:44:05 +0000 +Subject: [PATCH 1/3] [ARM] Refactor Thumb2 Mul and Mla instr descs + +Recommitting after r274347 was reverted. This patch introduces some +classes to refactor the 3 and 4 register Thumb2 multiplication +instruction descriptions, plus improved tests for some of those +instructions. + +Differential Revision: https://reviews.llvm.org/D21929 + +Cherry-picked from SVN trunk commit 275979, git mirror commit +aa39b5574e. +--- + lib/Target/ARM/ARMInstrThumb2.td | 470 ++++++++++++--------------------------- + test/CodeGen/ARM/longMAC.ll | 30 ++- + 2 files changed, 169 insertions(+), 331 deletions(-) + +diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td +index fe699b2..64f5dad 100644 +--- a/lib/Target/ARM/ARMInstrThumb2.td ++++ b/lib/Target/ARM/ARMInstrThumb2.td +@@ -536,9 +536,9 @@ class T2FourReg opc22_20, bits<4> opc7_4, +- dag oops, dag iops, InstrItinClass itin, +- string opc, string asm, list pattern> +- : T2I { ++ string opc, list pattern> ++ : T2I<(outs rGPR:$RdLo, rGPR:$RdHi), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64, ++ opc, "\t$RdLo, $RdHi, $Rn, $Rm", pattern> { + bits<4> RdLo; + bits<4> RdHi; + bits<4> Rn; +@@ -552,10 +552,11 @@ class T2MulLong opc22_20, bits<4> opc7_4, + let Inst{7-4} = opc7_4; + let Inst{3-0} = Rm; + } +-class T2MlaLong opc22_20, bits<4> opc7_4, +- dag oops, dag iops, InstrItinClass itin, +- string opc, string asm, list pattern> +- : T2I { ++class T2MlaLong opc22_20, bits<4> opc7_4, string opc> ++ : T2I<(outs rGPR:$RdLo, rGPR:$RdHi), ++ (ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64, ++ opc, "\t$RdLo, $RdHi, $Rn, $Rm", []>, ++ RegConstraint<"$RLo = $RdLo, $RHi = $RdHi"> { + bits<4> RdLo; + bits<4> RdHi; + bits<4> Rn; +@@ -2546,367 +2547,182 @@ def t2MUL: T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32, + let Inst{7-4} = 0b0000; // Multiply + } + +-def t2MLA: T2FourReg< +- (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, +- "mla", "\t$Rd, $Rn, $Rm, $Ra", +- [(set rGPR:$Rd, (add (mul rGPR:$Rn, rGPR:$Rm), rGPR:$Ra))]>, +- Requires<[IsThumb2, UseMulOps]> { ++class T2FourRegMLA op7_4, string opc, list pattern> ++ : T2FourReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, ++ opc, "\t$Rd, $Rn, $Rm, $Ra", pattern>, ++ Requires<[IsThumb2, UseMulOps]> { + let Inst{31-27} = 0b11111; + let Inst{26-23} = 0b0110; + let Inst{22-20} = 0b000; +- let Inst{7-4} = 0b0000; // Multiply ++ let Inst{7-4} = op7_4; + } + +-def t2MLS: T2FourReg< +- (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, +- "mls", "\t$Rd, $Rn, $Rm, $Ra", +- [(set rGPR:$Rd, (sub rGPR:$Ra, (mul rGPR:$Rn, rGPR:$Rm)))]>, +- Requires<[IsThumb2, UseMulOps]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b000; +- let Inst{7-4} = 0b0001; // Multiply and Subtract +-} ++def t2MLA : T2FourRegMLA<0b0000, "mla", ++ [(set rGPR:$Rd, (add (mul rGPR:$Rn, rGPR:$Rm), ++ rGPR:$Ra))]>; ++def t2MLS: T2FourRegMLA<0b0001, "mls", ++ [(set rGPR:$Rd, (sub rGPR:$Ra, (mul rGPR:$Rn, ++ rGPR:$Rm)))]>; + + // Extra precision multiplies with low / high results + let hasSideEffects = 0 in { + let isCommutable = 1 in { +-def t2SMULL : T2MulLong<0b000, 0b0000, +- (outs rGPR:$RdLo, rGPR:$RdHi), +- (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64, +- "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>; +- +-def t2UMULL : T2MulLong<0b010, 0b0000, +- (outs rGPR:$RdLo, rGPR:$RdHi), +- (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64, +- "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>; ++def t2SMULL : T2MulLong<0b000, 0b0000, "smull", []>; ++def t2UMULL : T2MulLong<0b010, 0b0000, "umull", []>; + } // isCommutable + + // Multiply + accumulate +-def t2SMLAL : T2MlaLong<0b100, 0b0000, +- (outs rGPR:$RdLo, rGPR:$RdHi), +- (ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64, +- "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, +- RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">; +- +-def t2UMLAL : T2MlaLong<0b110, 0b0000, +- (outs rGPR:$RdLo, rGPR:$RdHi), +- (ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64, +- "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, +- RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">; +- +-def t2UMAAL : T2MulLong<0b110, 0b0110, +- (outs rGPR:$RdLo, rGPR:$RdHi), +- (ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64, +- "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, +- RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">, +- Requires<[IsThumb2, HasDSP]>; ++def t2SMLAL : T2MlaLong<0b100, 0b0000, "smlal">; ++def t2UMLAL : T2MlaLong<0b110, 0b0000, "umlal">; ++def t2UMAAL : T2MlaLong<0b110, 0b0110, "umaal">, Requires<[IsThumb2, HasDSP]>; + } // hasSideEffects + + // Rounding variants of the below included for disassembly only + + // Most significant word multiply +-def t2SMMUL : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32, +- "smmul", "\t$Rd, $Rn, $Rm", +- [(set rGPR:$Rd, (mulhs rGPR:$Rn, rGPR:$Rm))]>, +- Requires<[IsThumb2, HasDSP]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b101; +- let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) +- let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) +-} +- +-def t2SMMULR : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32, +- "smmulr", "\t$Rd, $Rn, $Rm", []>, +- Requires<[IsThumb2, HasDSP]> { ++class T2SMMUL op7_4, string opc, list pattern> ++ : T2ThreeReg<(outs rGPR:$Rd), ++ (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32, ++ opc, "\t$Rd, $Rn, $Rm", pattern>, ++ Requires<[IsThumb2, HasDSP]> { + let Inst{31-27} = 0b11111; + let Inst{26-23} = 0b0110; + let Inst{22-20} = 0b101; + let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) +- let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) ++ let Inst{7-4} = op7_4; + } ++def t2SMMUL : T2SMMUL<0b0000, "smmul", [(set rGPR:$Rd, (mulhs rGPR:$Rn, ++ rGPR:$Rm))]>; ++def t2SMMULR : T2SMMUL<0b0001, "smmulr", []>; + +-def t2SMMLA : T2FourReg< +- (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, +- "smmla", "\t$Rd, $Rn, $Rm, $Ra", +- [(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]>, ++class T2FourRegSMMLA op22_20, bits<4> op7_4, string opc, ++ list pattern> ++ : T2FourReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, ++ opc, "\t$Rd, $Rn, $Rm, $Ra", pattern>, + Requires<[IsThumb2, HasDSP, UseMulOps]> { + let Inst{31-27} = 0b11111; + let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b101; +- let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) +-} +- +-def t2SMMLAR: T2FourReg< +- (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, +- "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []>, +- Requires<[IsThumb2, HasDSP]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b101; +- let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) +-} +- +-def t2SMMLS: T2FourReg< +- (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, +- "smmls", "\t$Rd, $Rn, $Rm, $Ra", +- [(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]>, +- Requires<[IsThumb2, HasDSP, UseMulOps]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b110; +- let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) +-} +- +-def t2SMMLSR:T2FourReg< +- (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, +- "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []>, +- Requires<[IsThumb2, HasDSP]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b110; +- let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) ++ let Inst{22-20} = op22_20; ++ let Inst{7-4} = op7_4; + } + +-multiclass T2I_smul { +- def BB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, +- !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm", +- [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16), +- (sext_inreg rGPR:$Rm, i16)))]>, +- Requires<[IsThumb2, HasDSP]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b001; +- let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) +- let Inst{7-6} = 0b00; +- let Inst{5-4} = 0b00; +- } +- +- def BT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, +- !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm", +- [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16), +- (sra rGPR:$Rm, (i32 16))))]>, +- Requires<[IsThumb2, HasDSP]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b001; +- let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) +- let Inst{7-6} = 0b00; +- let Inst{5-4} = 0b01; +- } +- +- def TB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, +- !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm", +- [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)), +- (sext_inreg rGPR:$Rm, i16)))]>, +- Requires<[IsThumb2, HasDSP]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b001; +- let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) +- let Inst{7-6} = 0b00; +- let Inst{5-4} = 0b10; +- } +- +- def TT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, +- !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm", +- [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)), +- (sra rGPR:$Rm, (i32 16))))]>, +- Requires<[IsThumb2, HasDSP]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b001; +- let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) +- let Inst{7-6} = 0b00; +- let Inst{5-4} = 0b11; +- } +- +- def WB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, +- !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm", +- []>, +- Requires<[IsThumb2, HasDSP]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b011; +- let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) +- let Inst{7-6} = 0b00; +- let Inst{5-4} = 0b00; +- } ++def t2SMMLA : T2FourRegSMMLA<0b101, 0b0000, "smmla", ++ [(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]>; ++def t2SMMLAR: T2FourRegSMMLA<0b101, 0b0001, "smmlar", []>; ++def t2SMMLS: T2FourRegSMMLA<0b110, 0b0000, "smmls", ++ [(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]>; ++def t2SMMLSR:T2FourRegSMMLA<0b110, 0b0001, "smmlsr", []>; + +- def WT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, +- !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm", +- []>, +- Requires<[IsThumb2, HasDSP]> { ++class T2ThreeRegSMUL op22_20, bits<2> op5_4, string opc, ++ list pattern> ++ : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, opc, ++ "\t$Rd, $Rn, $Rm", pattern>, ++ Requires<[IsThumb2, HasDSP]> { + let Inst{31-27} = 0b11111; + let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b011; ++ let Inst{22-20} = op22_20; + let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) + let Inst{7-6} = 0b00; +- let Inst{5-4} = 0b01; +- } +-} +- +- +-multiclass T2I_smla { +- def BB : T2FourReg< +- (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, +- !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra", +- [(set rGPR:$Rd, (add rGPR:$Ra, +- (opnode (sext_inreg rGPR:$Rn, i16), +- (sext_inreg rGPR:$Rm, i16))))]>, +- Requires<[IsThumb2, HasDSP, UseMulOps]> { ++ let Inst{5-4} = op5_4; ++} ++ ++def t2SMULBB : T2ThreeRegSMUL<0b001, 0b00, "smulbb", ++ [(set rGPR:$Rd, (mul (sext_inreg rGPR:$Rn, i16), ++ (sext_inreg rGPR:$Rm, i16)))]>; ++def t2SMULBT : T2ThreeRegSMUL<0b001, 0b01, "smulbt", ++ [(set rGPR:$Rd, (mul (sext_inreg rGPR:$Rn, i16), ++ (sra rGPR:$Rm, (i32 16))))]>; ++def t2SMULTB : T2ThreeRegSMUL<0b001, 0b10, "smultb", ++ [(set rGPR:$Rd, (mul (sra rGPR:$Rn, (i32 16)), ++ (sext_inreg rGPR:$Rm, i16)))]>; ++def t2SMULTT : T2ThreeRegSMUL<0b001, 0b11, "smultt", ++ [(set rGPR:$Rd, (mul (sra rGPR:$Rn, (i32 16)), ++ (sra rGPR:$Rm, (i32 16))))]>; ++def t2SMULWB : T2ThreeRegSMUL<0b011, 0b00, "smulwb", []>; ++def t2SMULWT : T2ThreeRegSMUL<0b011, 0b01, "smulwt", []>; ++ ++class T2FourRegSMLA op5_4, string opc, list pattern> ++ : T2FourReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMUL16, ++ opc, "\t$Rd, $Rn, $Rm, $Ra", pattern>, ++ Requires<[IsThumb2, HasDSP, UseMulOps]> { + let Inst{31-27} = 0b11111; + let Inst{26-23} = 0b0110; + let Inst{22-20} = 0b001; + let Inst{7-6} = 0b00; +- let Inst{5-4} = 0b00; +- } +- +- def BT : T2FourReg< +- (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, +- !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra", +- [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sext_inreg rGPR:$Rn, i16), +- (sra rGPR:$Rm, (i32 16)))))]>, +- Requires<[IsThumb2, HasDSP, UseMulOps]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b001; +- let Inst{7-6} = 0b00; +- let Inst{5-4} = 0b01; +- } +- +- def TB : T2FourReg< +- (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, +- !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra", +- [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)), +- (sext_inreg rGPR:$Rm, i16))))]>, +- Requires<[IsThumb2, HasDSP, UseMulOps]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b001; +- let Inst{7-6} = 0b00; +- let Inst{5-4} = 0b10; +- } +- +- def TT : T2FourReg< +- (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, +- !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra", +- [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)), +- (sra rGPR:$Rm, (i32 16)))))]>, +- Requires<[IsThumb2, HasDSP, UseMulOps]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b001; +- let Inst{7-6} = 0b00; +- let Inst{5-4} = 0b11; +- } +- +- def WB : T2FourReg< +- (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, +- !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra", +- []>, +- Requires<[IsThumb2, HasDSP, UseMulOps]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b011; +- let Inst{7-6} = 0b00; +- let Inst{5-4} = 0b00; +- } +- +- def WT : T2FourReg< +- (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, +- !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra", +- []>, +- Requires<[IsThumb2, HasDSP, UseMulOps]> { +- let Inst{31-27} = 0b11111; +- let Inst{26-23} = 0b0110; +- let Inst{22-20} = 0b011; +- let Inst{7-6} = 0b00; +- let Inst{5-4} = 0b01; +- } +-} +- +-defm t2SMUL : T2I_smul<"smul", mul>; +-defm t2SMLA : T2I_smla<"smla", mul>; ++ let Inst{5-4} = op5_4; ++} ++ ++def t2SMLABB : T2FourRegSMLA<0b00, "smlabb", ++ [(set rGPR:$Rd, (add rGPR:$Ra, ++ (mul (sext_inreg rGPR:$Rn, i16), ++ (sext_inreg rGPR:$Rm, i16))))]>; ++def t2SMLABT : T2FourRegSMLA<0b01, "smlabt", ++ [(set rGPR:$Rd, (add rGPR:$Ra, (mul (sext_inreg rGPR:$Rn, i16), ++ (sra rGPR:$Rm, (i32 16)))))]>; ++def t2SMLATB : T2FourRegSMLA<0b10, "smlatb", ++ [(set rGPR:$Rd, (add rGPR:$Ra, (mul (sra rGPR:$Rn, (i32 16)), ++ (sext_inreg rGPR:$Rm, i16))))]>; ++def t2SMLATT : T2FourRegSMLA<0b11, "smlatt", ++ [(set rGPR:$Rd, (add rGPR:$Ra, (mul (sra rGPR:$Rn, (i32 16)), ++ (sra rGPR:$Rm, (i32 16)))))]>; ++def t2SMLAWB : T2FourRegSMLA<0b00, "smlawb", []> { ++ let Inst{22-20} = 0b011; ++} ++def t2SMLAWT : T2FourRegSMLA<0b01, "smlawt", []> { ++ let Inst{22-20} = 0b011; ++} ++ ++class T2SMLAL op22_20, bits<4> op7_4, string opc, list pattern> ++ : T2FourReg_mac<1, op22_20, op7_4, ++ (outs rGPR:$Ra, rGPR:$Rd), ++ (ins rGPR:$Rn, rGPR:$Rm), ++ IIC_iMAC64, opc, "\t$Ra, $Rd, $Rn, $Rm", []>, ++ Requires<[IsThumb2, HasDSP]>; + + // Halfword multiple accumulate long: SMLAL +-def t2SMLALBB : T2FourReg_mac<1, 0b100, 0b1000, (outs rGPR:$Ra,rGPR:$Rd), +- (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbb", "\t$Ra, $Rd, $Rn, $Rm", +- [/* For disassembly only; pattern left blank */]>, +- Requires<[IsThumb2, HasDSP]>; +-def t2SMLALBT : T2FourReg_mac<1, 0b100, 0b1001, (outs rGPR:$Ra,rGPR:$Rd), +- (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbt", "\t$Ra, $Rd, $Rn, $Rm", +- [/* For disassembly only; pattern left blank */]>, +- Requires<[IsThumb2, HasDSP]>; +-def t2SMLALTB : T2FourReg_mac<1, 0b100, 0b1010, (outs rGPR:$Ra,rGPR:$Rd), +- (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltb", "\t$Ra, $Rd, $Rn, $Rm", +- [/* For disassembly only; pattern left blank */]>, +- Requires<[IsThumb2, HasDSP]>; +-def t2SMLALTT : T2FourReg_mac<1, 0b100, 0b1011, (outs rGPR:$Ra,rGPR:$Rd), +- (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltt", "\t$Ra, $Rd, $Rn, $Rm", +- [/* For disassembly only; pattern left blank */]>, +- Requires<[IsThumb2, HasDSP]>; +- +-// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD +-def t2SMUAD: T2ThreeReg_mac< +- 0, 0b010, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), +- IIC_iMAC32, "smuad", "\t$Rd, $Rn, $Rm", []>, +- Requires<[IsThumb2, HasDSP]> { ++def t2SMLALBB : T2SMLAL<0b100, 0b1000, "smlalbb", []>; ++def t2SMLALBT : T2SMLAL<0b100, 0b1001, "smlalbt", []>; ++def t2SMLALTB : T2SMLAL<0b100, 0b1010, "smlaltb", []>; ++def t2SMLALTT : T2SMLAL<0b100, 0b1011, "smlaltt", []>; ++ ++class T2DualHalfMul op22_20, bits<4> op7_4, string opc> ++ : T2ThreeReg_mac<0, op22_20, op7_4, ++ (outs rGPR:$Rd), ++ (ins rGPR:$Rn, rGPR:$Rm), ++ IIC_iMAC32, opc, "\t$Rd, $Rn, $Rm", []>, ++ Requires<[IsThumb2, HasDSP]> { + let Inst{15-12} = 0b1111; + } +-def t2SMUADX:T2ThreeReg_mac< +- 0, 0b010, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), +- IIC_iMAC32, "smuadx", "\t$Rd, $Rn, $Rm", []>, +- Requires<[IsThumb2, HasDSP]> { +- let Inst{15-12} = 0b1111; +-} +-def t2SMUSD: T2ThreeReg_mac< +- 0, 0b100, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), +- IIC_iMAC32, "smusd", "\t$Rd, $Rn, $Rm", []>, +- Requires<[IsThumb2, HasDSP]> { +- let Inst{15-12} = 0b1111; +-} +-def t2SMUSDX:T2ThreeReg_mac< +- 0, 0b100, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), +- IIC_iMAC32, "smusdx", "\t$Rd, $Rn, $Rm", []>, +- Requires<[IsThumb2, HasDSP]> { +- let Inst{15-12} = 0b1111; +-} +-def t2SMLAD : T2FourReg_mac< +- 0, 0b010, 0b0000, (outs rGPR:$Rd), +- (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlad", +- "\t$Rd, $Rn, $Rm, $Ra", []>, +- Requires<[IsThumb2, HasDSP]>; +-def t2SMLADX : T2FourReg_mac< +- 0, 0b010, 0b0001, (outs rGPR:$Rd), +- (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smladx", +- "\t$Rd, $Rn, $Rm, $Ra", []>, +- Requires<[IsThumb2, HasDSP]>; +-def t2SMLSD : T2FourReg_mac<0, 0b100, 0b0000, (outs rGPR:$Rd), +- (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsd", +- "\t$Rd, $Rn, $Rm, $Ra", []>, +- Requires<[IsThumb2, HasDSP]>; +-def t2SMLSDX : T2FourReg_mac<0, 0b100, 0b0001, (outs rGPR:$Rd), +- (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsdx", +- "\t$Rd, $Rn, $Rm, $Ra", []>, +- Requires<[IsThumb2, HasDSP]>; +-def t2SMLALD : T2FourReg_mac<1, 0b100, 0b1100, (outs rGPR:$Ra,rGPR:$Rd), +- (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64, "smlald", +- "\t$Ra, $Rd, $Rn, $Rm", []>, +- Requires<[IsThumb2, HasDSP]>; +-def t2SMLALDX : T2FourReg_mac<1, 0b100, 0b1101, (outs rGPR:$Ra,rGPR:$Rd), +- (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaldx", +- "\t$Ra, $Rd, $Rn, $Rm", []>, +- Requires<[IsThumb2, HasDSP]>; +-def t2SMLSLD : T2FourReg_mac<1, 0b101, 0b1100, (outs rGPR:$Ra,rGPR:$Rd), +- (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlsld", +- "\t$Ra, $Rd, $Rn, $Rm", []>, +- Requires<[IsThumb2, HasDSP]>; +-def t2SMLSLDX : T2FourReg_mac<1, 0b101, 0b1101, (outs rGPR:$Ra,rGPR:$Rd), +- (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsldx", +- "\t$Ra, $Rd, $Rn, $Rm", []>, +- Requires<[IsThumb2, HasDSP]>; ++ ++// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD ++def t2SMUAD: T2DualHalfMul<0b010, 0b0000, "smuad">; ++def t2SMUADX: T2DualHalfMul<0b010, 0b0001, "smuadx">; ++def t2SMUSD: T2DualHalfMul<0b100, 0b0000, "smusd">; ++def t2SMUSDX: T2DualHalfMul<0b100, 0b0001, "smusdx">; ++ ++class T2DualHalfMulAdd op22_20, bits<4> op7_4, string opc> ++ : T2FourReg_mac<0, op22_20, op7_4, ++ (outs rGPR:$Rd), ++ (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), ++ IIC_iMAC32, opc, "\t$Rd, $Rn, $Rm, $Ra", []>, ++ Requires<[IsThumb2, HasDSP]>; ++ ++def t2SMLAD : T2DualHalfMulAdd<0b010, 0b0000, "smlad">; ++def t2SMLADX : T2DualHalfMulAdd<0b010, 0b0001, "smladx">; ++def t2SMLSD : T2DualHalfMulAdd<0b100, 0b0000, "smlsd">; ++def t2SMLSDX : T2DualHalfMulAdd<0b100, 0b0001, "smlsdx">; ++ ++class T2DualHalfMulAddLong op22_20, bits<4> op7_4, string opc> ++ : T2FourReg_mac<1, op22_20, op7_4, ++ (outs rGPR:$Ra, rGPR:$Rd), ++ (ins rGPR:$Rn, rGPR:$Rm), ++ IIC_iMAC64, opc, "\t$Ra, $Rd, $Rn, $Rm", []>, ++ Requires<[IsThumb2, HasDSP]>; ++ ++def t2SMLALD : T2DualHalfMulAddLong<0b100, 0b1100, "smlald">; ++def t2SMLALDX : T2DualHalfMulAddLong<0b100, 0b1101, "smlaldx">; ++def t2SMLSLD : T2DualHalfMulAddLong<0b101, 0b1100, "smlsld">; ++def t2SMLSLDX : T2DualHalfMulAddLong<0b101, 0b1101, "smlsldx">; + + //===----------------------------------------------------------------------===// + // Division Instructions. +diff --git a/test/CodeGen/ARM/longMAC.ll b/test/CodeGen/ARM/longMAC.ll +index cc2d745..8edf965 100644 +--- a/test/CodeGen/ARM/longMAC.ll ++++ b/test/CodeGen/ARM/longMAC.ll +@@ -2,6 +2,8 @@ + ; RUN: llc -mtriple=armv7-eabi %s -o - | FileCheck %s --check-prefix=CHECK-V7-LE + ; RUN: llc -mtriple=armeb-eabi %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE + ; RUN: llc -mtriple=armebv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7-BE ++; RUN: llc -mtriple=thumbv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7-THUMB ++; RUN: llc -mtriple=thumbebv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7-THUMB-BE + ; Check generated signed and unsigned multiply accumulate long. + + define i64 @MACLongTest1(i32 %a, i32 %b, i64 %c) { +@@ -118,8 +120,18 @@ define i64 @MACLongTest8(i64 %acc, i32 %lhs, i32 %rhs) { + + define i64 @MACLongTest9(i32 %lhs, i32 %rhs, i32 %lo, i32 %hi) { + ;CHECK-LABEL: MACLongTest9: +-;CHECK-V7-LE:umaal +-;CHECK-V7-BE:umaal ++;CHECK-V7-LE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] ++;CHECK-V7-LE: mov r0, [[RDLO]] ++;CHECK-V7-LE: mov r1, [[RDHI]] ++;CHECK-V7-BE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] ++;CHECK-V7-BE: mov r0, [[RDHI]] ++;CHECK-V7-BE: mov r1, [[RDLO]] ++;CHECK-V7-THUMB: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] ++;CHECK-V7-THUMB: mov r0, [[RDLO]] ++;CHECK-V7-THUMB: mov r1, [[RDHI]] ++;CHECK-V7-THUMB-BE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] ++;CHECK-V7-THUMB-BE: mov r0, [[RDHI]] ++;CHECK-V7-THUMB-BE: mov r1, [[RDLO]] + ;CHECK-NOT:umaal + %conv = zext i32 %lhs to i64 + %conv1 = zext i32 %rhs to i64 +@@ -133,8 +145,18 @@ define i64 @MACLongTest9(i32 %lhs, i32 %rhs, i32 %lo, i32 %hi) { + + define i64 @MACLongTest10(i32 %lhs, i32 %rhs, i32 %lo, i32 %hi) { + ;CHECK-LABEL: MACLongTest10: +-;CHECK-V7-LE:umaal +-;CHECK-V7-BE:umaal ++;CHECK-V7-LE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] ++;CHECK-V7-LE: mov r0, [[RDLO]] ++;CHECK-V7-LE: mov r1, [[RDHI]] ++;CHECK-V7-BE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] ++;CHECK-V7-BE: mov r0, [[RDHI]] ++;CHECK-V7-BE: mov r1, [[RDLO]] ++;CHECK-V7-THUMB: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] ++;CHECK-V7-THUMB: mov r0, [[RDLO]] ++;CHECK-V7-THUMB: mov r1, [[RDHI]] ++;CHECK-V7-THUMB-BE: umaal [[RDLO:r[0-9]+]], [[RDHI:r[0-9]+]], [[LHS:r[0-9]+]], [[RHS:r[0-9]+]] ++;CHECK-V7-THUMB-BE: mov r0, [[RDHI]] ++;CHECK-V7-THUMB-BE: mov r1, [[RDLO]] + ;CHECK-NOT:umaal + %conv = zext i32 %lhs to i64 + %conv1 = zext i32 %rhs to i64 +-- +2.7.4 + diff --git a/patches/llvm-0002.patch b/patches/llvm-0002.patch new file mode 100644 index 0000000..9021b1f --- /dev/null +++ b/patches/llvm-0002.patch @@ -0,0 +1,133 @@ +From 9ce71bff387ce9e30adddf72a29874bbb058dd5a Mon Sep 17 00:00:00 2001 +From: Sam Parker +Date: Mon, 25 Jul 2016 09:20:20 +0000 +Subject: [PATCH 2/3] [ARM] Enable ISel of SMMLS for ARM and Thumb2 + +Use ISelDAGToDAG to recognise the SMMLS instruction pattern. + +Differential Revision: https://reviews.llvm.org/D22562 + +Cherry-picked from SVN trunk commit 276624, git mirror commit +161eae5670. +--- + lib/Target/ARM/ARMISelDAGToDAG.cpp | 30 ++++++++++++++++++++++++++++++ + lib/Target/ARM/ARMInstrThumb2.td | 9 ++++----- + test/CodeGen/ARM/smml.ll | 36 ++++++++++++++++++++++++++++++++++-- + 3 files changed, 68 insertions(+), 7 deletions(-) + +diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp +index 20db3d3..96cb691 100644 +--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp ++++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp +@@ -3037,6 +3037,36 @@ void ARMDAGToDAGISel::Select(SDNode *N) { + return; + } + } ++ case ARMISD::SUBE: { ++ if (!Subtarget->hasV6Ops()) ++ break; ++ // Look for a pattern to match SMMLS ++ // (sube a, (smul_loHi a, b), (subc 0, (smul_LOhi(a, b)))) ++ if (N->getOperand(1).getOpcode() != ISD::SMUL_LOHI || ++ N->getOperand(2).getOpcode() != ARMISD::SUBC) ++ break; ++ ++ if (Subtarget->isThumb()) ++ assert(Subtarget->hasThumb2() && ++ "This pattern should not be generated for Thumb"); ++ ++ SDValue SmulLoHi = N->getOperand(1); ++ SDValue Subc = N->getOperand(2); ++ auto *Zero = dyn_cast(Subc.getOperand(0)); ++ ++ if (!Zero || Zero->getZExtValue() != 0 || ++ Subc.getOperand(1) != SmulLoHi.getValue(0) || ++ N->getOperand(1) != SmulLoHi.getValue(1) || ++ N->getOperand(2) != Subc.getValue(1)) ++ break; ++ ++ unsigned Opc = Subtarget->isThumb2() ? ARM::t2SMMLS : ARM::SMMLS; ++ SDValue Ops[] = { SmulLoHi.getOperand(0), SmulLoHi.getOperand(1), ++ N->getOperand(0), getAL(CurDAG, dl), ++ CurDAG->getRegister(0, MVT::i32) }; ++ ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, MVT::i32, Ops)); ++ return; ++ } + case ISD::LOAD: { + if (Subtarget->isThumb() && Subtarget->hasThumb2()) { + if (tryT2IndexedLoad(N)) +diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td +index 64f5dad..599b552 100644 +--- a/lib/Target/ARM/ARMInstrThumb2.td ++++ b/lib/Target/ARM/ARMInstrThumb2.td +@@ -2606,12 +2606,11 @@ class T2FourRegSMMLA op22_20, bits<4> op7_4, string opc, + let Inst{7-4} = op7_4; + } + +-def t2SMMLA : T2FourRegSMMLA<0b101, 0b0000, "smmla", ++def t2SMMLA : T2FourRegSMMLA<0b101, 0b0000, "smmla", + [(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]>; +-def t2SMMLAR: T2FourRegSMMLA<0b101, 0b0001, "smmlar", []>; +-def t2SMMLS: T2FourRegSMMLA<0b110, 0b0000, "smmls", +- [(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]>; +-def t2SMMLSR:T2FourRegSMMLA<0b110, 0b0001, "smmlsr", []>; ++def t2SMMLAR: T2FourRegSMMLA<0b101, 0b0001, "smmlar", []>; ++def t2SMMLS: T2FourRegSMMLA<0b110, 0b0000, "smmls", []>; ++def t2SMMLSR: T2FourRegSMMLA<0b110, 0b0001, "smmlsr", []>; + + class T2ThreeRegSMUL op22_20, bits<2> op5_4, string opc, + list pattern> +diff --git a/test/CodeGen/ARM/smml.ll b/test/CodeGen/ARM/smml.ll +index fc73eb7..807445f 100644 +--- a/test/CodeGen/ARM/smml.ll ++++ b/test/CodeGen/ARM/smml.ll +@@ -1,8 +1,20 @@ +-; RUN: llc -mtriple=arm-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s ++; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s -check-prefix=CHECK ++; RUN: llc -mtriple=armv6-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V6 ++; RUN: llc -mtriple=armv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-V7 ++; RUN: llc -mtriple=thumb-eabi %s -o - | FileCheck %s -check-prefix=CHECK-THUMB ++; RUN: llc -mtriple=thumbv6-eabi %s -o - | FileCheck %s -check-prefix=CHECK-THUMB ++; RUN: llc -mtriple=thumbv6t2-eabi %s -o - | FileCheck %s -check-prefix=CHECK-THUMBV6T2 ++; RUN: llc -mtriple=thumbv7-eabi %s -o - | FileCheck %s -check-prefix=CHECK-THUMBV7 + +-define i32 @f(i32 %a, i32 %b, i32 %c) nounwind readnone ssp { ++define i32 @Test0(i32 %a, i32 %b, i32 %c) nounwind readnone ssp { + entry: ++; CHECK-LABEL: Test0 + ; CHECK-NOT: smmls ++; CHECK-V6-NOT: smmls ++; CHECK-V7-NOT: smmls ++; CHECK_THUMB-NOT: smmls ++; CHECK-THUMBV6T2-NOT: smmls ++; CHECK-THUMBV7-NOT: smmls + %conv4 = zext i32 %a to i64 + %conv1 = sext i32 %b to i64 + %conv2 = sext i32 %c to i64 +@@ -12,3 +24,23 @@ entry: + %conv3 = trunc i64 %sub to i32 + ret i32 %conv3 + } ++ ++define i32 @Test1(i32 %a, i32 %b, i32 %c) { ++;CHECK-LABEL: Test1 ++;CHECK-NOT: smmls ++;CHECK-THUMB-NOT: smmls ++;CHECK-V6: smmls r0, [[Rn:r[1-2]]], [[Rm:r[1-2]]], r0 ++;CHECK-V7: smmls r0, [[Rn:r[1-2]]], [[Rm:r[1-2]]], r0 ++;CHECK-THUMBV6T2: smmls r0, [[Rn:r[1-2]]], [[Rm:r[1-2]]], r0 ++;CHECK-THUMBV7: smmls r0, [[Rn:r[1-2]]], [[Rm:r[1-2]]], r0 ++entry: ++ %conv = sext i32 %b to i64 ++ %conv1 = sext i32 %c to i64 ++ %mul = mul nsw i64 %conv1, %conv ++ %conv26 = zext i32 %a to i64 ++ %shl = shl nuw i64 %conv26, 32 ++ %sub = sub nsw i64 %shl, %mul ++ %shr7 = lshr i64 %sub, 32 ++ %conv3 = trunc i64 %shr7 to i32 ++ ret i32 %conv3 ++} +-- +2.7.4 + diff --git a/patches/llvm-0003.patch b/patches/llvm-0003.patch new file mode 100644 index 0000000..af20a42 --- /dev/null +++ b/patches/llvm-0003.patch @@ -0,0 +1,70 @@ +From 3b940b64588ea7df1c473021abe3ee3bf32a8294 Mon Sep 17 00:00:00 2001 +From: Renato Golin +Date: Wed, 27 Jul 2016 12:31:58 +0000 +Subject: [PATCH 3/3] [ARM] Set a non-conflicting comment character for + assembly in MSVC mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently, for ARMCOFFMCAsmInfoMicrosoft, no comment character is set, thus the +idefault, '#', is used. + +The hash character doesn't work as comment character in ARM assembly, since '#' +is used for immediate values. + +The comment character is set to ';', which is the comment character used by MS +armasm.exe. (The microsoft armasm.exe uses a different directive syntax than +what LLVM currently supports though, similar to ARM's armasm.) + +This allows inline assembly with immediate constants to be built (and brings the +assembly output from clang -S closer to being possible to assemble). + +A test is added that verifies that ';' is correctly interpreted as comments in +this mode, and verifies that assembling code that includes literal constants +with a '#' works. + +Patch by Martin Storsjö. + +Cherry-picked from SVN trunk commit 276859, git mirror commit +b9c61f0c0404. +--- + lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp | 1 + + test/MC/ARM/Windows/literals-comments.s | 13 +++++++++++++ + 2 files changed, 14 insertions(+) + create mode 100644 test/MC/ARM/Windows/literals-comments.s + +diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp +index 53cd29a..1e062ad 100644 +--- a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp ++++ b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp +@@ -90,6 +90,7 @@ ARMCOFFMCAsmInfoMicrosoft::ARMCOFFMCAsmInfoMicrosoft() { + + PrivateGlobalPrefix = "$M"; + PrivateLabelPrefix = "$M"; ++ CommentString = ";"; + } + + void ARMCOFFMCAsmInfoGNU::anchor() { } +diff --git a/test/MC/ARM/Windows/literals-comments.s b/test/MC/ARM/Windows/literals-comments.s +new file mode 100644 +index 0000000..be98874 +--- /dev/null ++++ b/test/MC/ARM/Windows/literals-comments.s +@@ -0,0 +1,13 @@ ++; RUN: llvm-mc -triple armv7-windows-msvc -filetype obj -o - %s ++ ++ .syntax unified ++ .thumb ++ ++ .text ++ ++ .global function ++ .thumb_func ++function: ++ ; this is a comment ++ mov r0, #42 ; this # was not ++ bx lr +-- +2.7.4 +