From 52f28e9b63b862fa3dafd9330eb76d5874c21574 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sun, 8 Nov 2009 14:27:38 +0000 Subject: [PATCH] Fix invalid operand updates & implement post-inc memory operands git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86466 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/MSP430/MSP430ISelDAGToDAG.cpp | 78 +++++++++++++++----- lib/Target/MSP430/MSP430InstrInfo.td | 32 +++++++++ test/CodeGen/MSP430/postinc.ll | 91 +++++++++++++++++++++++- 3 files changed, 184 insertions(+), 17 deletions(-) diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp index ac01bf81c34..e9e5d34ba51 100644 --- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp +++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp @@ -43,9 +43,6 @@ ViewRMWDAGs("view-msp430-rmw-dags", cl::Hidden, static const bool ViewRMWDAGs = false; #endif -static cl::opt -EnablePostIncOps("enable-msp430-post-inc-ops", cl::Hidden); - STATISTIC(NumLoadMoved, "Number of loads moved below TokenFactor"); @@ -675,7 +672,10 @@ SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDValue Op, VT, MVT::i16, MVT::Other, Ops0, 3); cast(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1); - ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 3)); + // Transfer chain. + ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2)); + // Transfer writeback. + ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1)); return ResNode; } @@ -745,18 +745,64 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) { return ResNode; // Other cases are autogenerated. break; - case ISD::ADD: - if (EnablePostIncOps) { - if (SDNode *ResNode = - SelectIndexedBinOp(Op, - Op.getOperand(0), Op.getOperand(1), - MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) - return ResNode; - else if (SDNode *ResNode = - SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0), - MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) - return ResNode; - } + case ISD::ADD: + if (SDNode *ResNode = + SelectIndexedBinOp(Op, + Op.getOperand(0), Op.getOperand(1), + MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) + return ResNode; + else if (SDNode *ResNode = + SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0), + MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) + return ResNode; + + // Other cases are autogenerated. + break; + case ISD::SUB: + if (SDNode *ResNode = + SelectIndexedBinOp(Op, + Op.getOperand(0), Op.getOperand(1), + MSP430::SUB8rm_POST, MSP430::SUB16rm_POST)) + return ResNode; + + // Other cases are autogenerated. + break; + case ISD::AND: + if (SDNode *ResNode = + SelectIndexedBinOp(Op, + Op.getOperand(0), Op.getOperand(1), + MSP430::AND8rm_POST, MSP430::AND16rm_POST)) + return ResNode; + else if (SDNode *ResNode = + SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0), + MSP430::AND8rm_POST, MSP430::AND16rm_POST)) + return ResNode; + + // Other cases are autogenerated. + break; + case ISD::OR: + if (SDNode *ResNode = + SelectIndexedBinOp(Op, + Op.getOperand(0), Op.getOperand(1), + MSP430::OR8rm_POST, MSP430::OR16rm_POST)) + return ResNode; + else if (SDNode *ResNode = + SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0), + MSP430::OR8rm_POST, MSP430::OR16rm_POST)) + return ResNode; + + // Other cases are autogenerated. + break; + case ISD::XOR: + if (SDNode *ResNode = + SelectIndexedBinOp(Op, + Op.getOperand(0), Op.getOperand(1), + MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) + return ResNode; + else if (SDNode *ResNode = + SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0), + MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) + return ResNode; // Other cases are autogenerated. break; diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td index 33e468df565..aab02983396 100644 --- a/lib/Target/MSP430/MSP430InstrInfo.td +++ b/lib/Target/MSP430/MSP430InstrInfo.td @@ -425,6 +425,14 @@ def AND16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2), [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))), (implicit SRW)]>; +let mayLoad = 1, hasExtraDefRegAllocReq = 1, +Constraints = "$base = $base_wb, $src1 = $dst" in { +def AND8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base), + "and.b\t{@$base+, $dst}", []>; +def AND16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base), + "and.w\t{@$base+, $dst}", []>; +} + let isTwoAddress = 0 in { def AND8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), "and.b\t{$src, $dst}", @@ -484,6 +492,14 @@ def XOR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2), [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))), (implicit SRW)]>; +let mayLoad = 1, hasExtraDefRegAllocReq = 1, +Constraints = "$base = $base_wb, $src1 = $dst" in { +def XOR8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base), + "xor.b\t{@$base+, $dst}", []>; +def XOR16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base), + "xor.w\t{@$base+, $dst}", []>; +} + let isTwoAddress = 0 in { def XOR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), "xor.b\t{$src, $dst}", @@ -541,6 +557,14 @@ def SUB16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2), [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))), (implicit SRW)]>; +let mayLoad = 1, hasExtraDefRegAllocReq = 1, +Constraints = "$base = $base_wb, $src1 = $dst" in { +def SUB8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base), + "sub.b\t{@$base+, $dst}", []>; +def SUB16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base), + "sub.w\t{@$base+, $dst}", []>; +} + let isTwoAddress = 0 in { def SUB8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), "sub.b\t{$src, $dst}", @@ -693,6 +717,14 @@ def OR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2), "bis.w\t{$src2, $dst}", [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>; +let mayLoad = 1, hasExtraDefRegAllocReq = 1, +Constraints = "$base = $base_wb, $src1 = $dst" in { +def OR8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base), + "bis.b\t{@$base+, $dst}", []>; +def OR16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base), + "bis.w\t{@$base+, $dst}", []>; +} + let isTwoAddress = 0 in { def OR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), "bis.b\t{$src, $dst}", diff --git a/test/CodeGen/MSP430/postinc.ll b/test/CodeGen/MSP430/postinc.ll index 424b4f79cd1..8f01b832588 100644 --- a/test/CodeGen/MSP430/postinc.ll +++ b/test/CodeGen/MSP430/postinc.ll @@ -12,7 +12,7 @@ for.body: ; preds = %for.body, %entry %sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; [#uses=1] %arrayidx = getelementptr i16* %a, i16 %i.010 ; [#uses=1] ; CHECK: add: -; CHECK: mov.w @r15+, r11 +; CHECK: add.w @r{{[0-9]+}}+, r{{[0-9]+}} %tmp4 = load i16* %arrayidx ; [#uses=1] %add = add i16 %tmp4, %sum.09 ; [#uses=2] %inc = add i16 %i.010, 1 ; [#uses=2] @@ -23,3 +23,92 @@ for.end: ; preds = %for.body, %entry %sum.0.lcssa = phi i16 [ 0, %entry ], [ %add, %for.body ] ; [#uses=1] ret i16 %sum.0.lcssa } + +define zeroext i16 @sub(i16* nocapture %a, i16 zeroext %n) nounwind readonly { +entry: + %cmp8 = icmp eq i16 %n, 0 ; [#uses=1] + br i1 %cmp8, label %for.end, label %for.body + +for.body: ; preds = %for.body, %entry + %i.010 = phi i16 [ 0, %entry ], [ %inc, %for.body ] ; [#uses=2] + %sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; [#uses=1] + %arrayidx = getelementptr i16* %a, i16 %i.010 ; [#uses=1] +; CHECK: sub: +; CHECK: sub.w @r{{[0-9]+}}+, r{{[0-9]+}} + %tmp4 = load i16* %arrayidx ; [#uses=1] + %add = sub i16 %tmp4, %sum.09 ; [#uses=2] + %inc = add i16 %i.010, 1 ; [#uses=2] + %exitcond = icmp eq i16 %inc, %n ; [#uses=1] + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %sum.0.lcssa = phi i16 [ 0, %entry ], [ %add, %for.body ] ; [#uses=1] + ret i16 %sum.0.lcssa +} + +define zeroext i16 @or(i16* nocapture %a, i16 zeroext %n) nounwind readonly { +entry: + %cmp8 = icmp eq i16 %n, 0 ; [#uses=1] + br i1 %cmp8, label %for.end, label %for.body + +for.body: ; preds = %for.body, %entry + %i.010 = phi i16 [ 0, %entry ], [ %inc, %for.body ] ; [#uses=2] + %sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; [#uses=1] + %arrayidx = getelementptr i16* %a, i16 %i.010 ; [#uses=1] +; CHECK: or: +; CHECK: bis.w @r{{[0-9]+}}+, r{{[0-9]+}} + %tmp4 = load i16* %arrayidx ; [#uses=1] + %add = or i16 %tmp4, %sum.09 ; [#uses=2] + %inc = add i16 %i.010, 1 ; [#uses=2] + %exitcond = icmp eq i16 %inc, %n ; [#uses=1] + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %sum.0.lcssa = phi i16 [ 0, %entry ], [ %add, %for.body ] ; [#uses=1] + ret i16 %sum.0.lcssa +} + +define zeroext i16 @xor(i16* nocapture %a, i16 zeroext %n) nounwind readonly { +entry: + %cmp8 = icmp eq i16 %n, 0 ; [#uses=1] + br i1 %cmp8, label %for.end, label %for.body + +for.body: ; preds = %for.body, %entry + %i.010 = phi i16 [ 0, %entry ], [ %inc, %for.body ] ; [#uses=2] + %sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; [#uses=1] + %arrayidx = getelementptr i16* %a, i16 %i.010 ; [#uses=1] +; CHECK: xor: +; CHECK: xor.w @r{{[0-9]+}}+, r{{[0-9]+}} + %tmp4 = load i16* %arrayidx ; [#uses=1] + %add = xor i16 %tmp4, %sum.09 ; [#uses=2] + %inc = add i16 %i.010, 1 ; [#uses=2] + %exitcond = icmp eq i16 %inc, %n ; [#uses=1] + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %sum.0.lcssa = phi i16 [ 0, %entry ], [ %add, %for.body ] ; [#uses=1] + ret i16 %sum.0.lcssa +} + +define zeroext i16 @and(i16* nocapture %a, i16 zeroext %n) nounwind readonly { +entry: + %cmp8 = icmp eq i16 %n, 0 ; [#uses=1] + br i1 %cmp8, label %for.end, label %for.body + +for.body: ; preds = %for.body, %entry + %i.010 = phi i16 [ 0, %entry ], [ %inc, %for.body ] ; [#uses=2] + %sum.09 = phi i16 [ 0, %entry ], [ %add, %for.body ] ; [#uses=1] + %arrayidx = getelementptr i16* %a, i16 %i.010 ; [#uses=1] +; CHECK: and: +; CHECK: and.w @r{{[0-9]+}}+, r{{[0-9]+}} + %tmp4 = load i16* %arrayidx ; [#uses=1] + %add = and i16 %tmp4, %sum.09 ; [#uses=2] + %inc = add i16 %i.010, 1 ; [#uses=2] + %exitcond = icmp eq i16 %inc, %n ; [#uses=1] + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %sum.0.lcssa = phi i16 [ 0, %entry ], [ %add, %for.body ] ; [#uses=1] + ret i16 %sum.0.lcssa +} + -- 2.34.1