From cc46cd8eecca578d0166cab883f348d05898e541 Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Mon, 8 Dec 2014 18:33:49 +0000 Subject: [PATCH] [Hexagon] Adding add/sub with saturation. Removing unused def. Cleaning up shift patterns. llvm-svn: 223680 --- llvm/lib/Target/Hexagon/HexagonInstrInfo.td | 32 ++++++++++++------------- llvm/lib/Target/Hexagon/HexagonRegisterInfo.td | 6 +++++ llvm/test/MC/Disassembler/Hexagon/alu32_alu.txt | 4 ++++ 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td index 99a02a9..70f07e6 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td @@ -170,6 +170,18 @@ def A2_combine_lh : T_ALU32_combineh<".l", ".h", 0b011, 0b110, 1>; def A2_combine_ll : T_ALU32_combineh<".l", ".l", 0b011, 0b111, 1>; } +class T_ALU32_3op_sfx MajOp, + bits<3> MinOp, bit OpsRev, bit IsComm> + : T_ALU32_3op<"", MajOp, MinOp, OpsRev, IsComm> { + let AsmString = "$Rd = "#mnemonic#"($Rs, $Rt)"#suffix; +} + +let Defs = [USR_OVF], Itinerary = ALU32_3op_tc_2_SLOT0123, + isCodeGenOnly = 0 in { + def A2_addsat : T_ALU32_3op_sfx<"add", ":sat", 0b110, 0b010, 0, 1>; + def A2_subsat : T_ALU32_3op_sfx<"sub", ":sat", 0b110, 0b110, 1, 0>; +} + multiclass T_ALU32_3op_p MajOp, bits<3> MinOp, bit OpsRev> { def t : T_ALU32_3op_pred; @@ -834,11 +846,10 @@ multiclass ZXTB_base minOp> { let isCodeGenOnly=0 in defm zxtb : ZXTB_base<"zxtb",0b100>, PredNewRel; -let hasSideEffects = 0 in -def COMBINE_ii : ALU32_ii<(outs DoubleRegs:$dst), - (ins s8Imm:$src1, s8Imm:$src2), - "$dst = combine(#$src1, #$src2)", - []>; +def: Pat<(shl I32:$src1, (i32 16)), (A2_aslh I32:$src1)>; +def: Pat<(sra I32:$src1, (i32 16)), (A2_asrh I32:$src1)>; +def: Pat<(sext_inreg I32:$src1, i8), (A2_sxtb I32:$src1)>; +def: Pat<(sext_inreg I32:$src1, i16), (A2_sxth I32:$src1)>; // Mux. def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, @@ -847,17 +858,6 @@ def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, "$dst = vmux($src1, $src2, $src3)", []>; -def : Pat <(shl (i32 IntRegs:$src1), (i32 16)), - (A2_aslh IntRegs:$src1)>; - -def : Pat <(sra (i32 IntRegs:$src1), (i32 16)), - (A2_asrh IntRegs:$src1)>; - -def : Pat <(sext_inreg (i32 IntRegs:$src1), i8), - (A2_sxtb IntRegs:$src1)>; - -def : Pat <(sext_inreg (i32 IntRegs:$src1), i16), - (A2_sxth IntRegs:$src1)>; //===----------------------------------------------------------------------===// // ALU32/PERM - diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td index 9750984..70a1381 100644 --- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.td @@ -97,6 +97,12 @@ let Namespace = "Hexagon" in { def P2 : Rp<2, "p2">, DwarfRegNum<[65]>; def P3 : Rp<3, "p3">, DwarfRegNum<[66]>; + // Fake register to represent USR.OVF bit. Artihmetic/saturating instruc- + // tions modify this bit, and multiple such instructions are allowed in the + // same packet. We need to ignore output dependencies on this bit, but not + // on the entire USR. + def USR_OVF : Rc; + // Control registers. def SA0 : Rc<0, "sa0">, DwarfRegNum<[67]>; def LC0 : Rc<1, "lc0">, DwarfRegNum<[68]>; diff --git a/llvm/test/MC/Disassembler/Hexagon/alu32_alu.txt b/llvm/test/MC/Disassembler/Hexagon/alu32_alu.txt index c90a61d..74d4c73 100644 --- a/llvm/test/MC/Disassembler/Hexagon/alu32_alu.txt +++ b/llvm/test/MC/Disassembler/Hexagon/alu32_alu.txt @@ -4,6 +4,8 @@ # CHECK: r17 = add(r21, #31) 0x11 0xdf 0x15 0xf3 # CHECK: r17 = add(r21, r31) +0x11 0xdf 0x55 0xf6 +# CHECK: r17 = add(r21, r31):sat 0x11 0xdf 0x15 0xf1 # CHECK: r17 = and(r21, r31) 0xf1 0xc3 0x15 0x76 @@ -20,6 +22,8 @@ # CHECK: r17 = sub(#21, r31) 0x11 0xdf 0x35 0xf3 # CHECK: r17 = sub(r31, r21) +0x11 0xdf 0xd5 0xf6 +# CHECK: r17 = sub(r31, r21):sat 0x11 0xc0 0xbf 0x70 # CHECK: r17 = sxtb(r31) 0x15 0xc0 0x31 0x72 -- 2.7.4