diff options
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonBitTracker.cpp | 14 | ||||
| -rw-r--r-- | llvm/test/CodeGen/Hexagon/bit-ext-sat.ll | 57 | 
2 files changed, 71 insertions, 0 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp index 436f88dcd45..adcea1ea1a0 100644 --- a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp +++ b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp @@ -272,6 +272,9 @@ bool HexagonEvaluator::evaluate(const MachineInstr &MI,    // cases below.    uint16_t W0 = (Reg[0].Reg != 0) ? getRegBitWidth(Reg[0]) : 0; +  // Register id of the 0th operand. It can be 0. +  unsigned Reg0 = Reg[0].Reg; +    switch (Opc) {      // Transfer immediate: @@ -792,6 +795,17 @@ bool HexagonEvaluator::evaluate(const MachineInstr &MI,      case A2_zxth:        return rr0(eZXT(rc(1), 16), Outputs); +    // Saturations + +    case A2_satb: +      return rr0(eSXT(RegisterCell::self(0, W0).regify(Reg0), 8), Outputs); +    case A2_sath: +      return rr0(eSXT(RegisterCell::self(0, W0).regify(Reg0), 16), Outputs); +    case A2_satub: +      return rr0(eZXT(RegisterCell::self(0, W0).regify(Reg0), 8), Outputs); +    case A2_satuh: +      return rr0(eZXT(RegisterCell::self(0, W0).regify(Reg0), 16), Outputs); +      // Bit count:      case S2_cl0: diff --git a/llvm/test/CodeGen/Hexagon/bit-ext-sat.ll b/llvm/test/CodeGen/Hexagon/bit-ext-sat.ll new file mode 100644 index 00000000000..47c49c2364b --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/bit-ext-sat.ll @@ -0,0 +1,57 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +target triple = "hexagon" + +; CHECK-LABEL: xh_sh +; CHECK: sath +; CHECK-NOT: sxth +define i32 @xh_sh(i32 %x) local_unnamed_addr #0 { +entry: +  %0 = tail call i32 @llvm.hexagon.A2.sath(i32 %x) +  %1 = tail call i32 @llvm.hexagon.A2.sxth(i32 %0) +  ret i32 %1 +} + +; CHECK-LABEL: xb_sb +; CHECK: satb +; CHECK-NOT: sxtb +define i32 @xb_sb(i32 %x) local_unnamed_addr #0 { +entry: +  %0 = tail call i32 @llvm.hexagon.A2.satb(i32 %x) +  %1 = tail call i32 @llvm.hexagon.A2.sxtb(i32 %0) +  ret i32 %1 +} + +; CHECK-LABEL: xuh_suh +; CHECK: satuh +; CHECK-NOT: zxth +define i32 @xuh_suh(i32 %x) local_unnamed_addr #0 { +entry: +  %0 = tail call i32 @llvm.hexagon.A2.satuh(i32 %x) +  %1 = tail call i32 @llvm.hexagon.A2.zxth(i32 %0) +  ret i32 %1 +} + +; CHECK-LABEL: xub_sub +; CHECK: satub +; CHECK-NOT: zxtb +define i32 @xub_sub(i32 %x) local_unnamed_addr #0 { +entry: +  %0 = tail call i32 @llvm.hexagon.A2.satub(i32 %x) +  %1 = tail call i32 @llvm.hexagon.A2.zxtb(i32 %0) +  ret i32 %1 +} + + +declare i32 @llvm.hexagon.A2.sxtb(i32) #1 +declare i32 @llvm.hexagon.A2.sxth(i32) #1 +declare i32 @llvm.hexagon.A2.zxtb(i32) #1 +declare i32 @llvm.hexagon.A2.zxth(i32) #1 + +declare i32 @llvm.hexagon.A2.satb(i32) #1 +declare i32 @llvm.hexagon.A2.sath(i32) #1 +declare i32 @llvm.hexagon.A2.satub(i32) #1 +declare i32 @llvm.hexagon.A2.satuh(i32) #1 + +attributes #0 = { nounwind readnone "target-cpu"="hexagonv60" "target-features"="-hvx,-hvx-double,-long-calls" } +attributes #1 = { nounwind readnone }  | 

