From 40289b041adb299e4474607066b69b89298e5f70 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 7 Jul 2009 05:35:52 +0000 Subject: [PATCH] Add Thumb2 pkhbt / pkhtb. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74895 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrThumb2.td | 29 ++++++++++-- test/CodeGen/Thumb2/thumb2-pack.ll | 73 ++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/Thumb2/thumb2-pack.ll diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index e1a526d2231..e961462983c 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -966,9 +966,6 @@ def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), (or (and (srl GPR:$src, (i32 8)), 0xFF0000), (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>; -///// -/// A8.6.137 REVSH -///// def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), "revsh", " $dst, $src", [(set GPR:$dst, @@ -976,7 +973,31 @@ def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), (or (srl (and GPR:$src, 0xFFFF), (i32 8)), (shl GPR:$src, (i32 8))), i16))]>; -// FIXME: PKHxx etc. +def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt), + "pkhbt", " $dst, $src1, $src2, LSL $shamt", + [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF), + (and (shl GPR:$src2, (i32 imm:$shamt)), + 0xFFFF0000)))]>; + +// Alternate cases for PKHBT where identities eliminate some nodes. +def : T2Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)), + (t2PKHBT GPR:$src1, GPR:$src2, 0)>; +def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)), + (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>; + +def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt), + "pkhtb", " $dst, $src1, $src2, ASR $shamt", + [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000), + (and (sra GPR:$src2, imm16_31:$shamt), + 0xFFFF)))]>; + +// Alternate cases for PKHTB where identities eliminate some nodes. Note that +// a shift amount of 0 is *not legal* here, it is PKHBT instead. +def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))), + (t2PKHTB GPR:$src1, GPR:$src2, 16)>; +def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), + (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)), + (t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>; //===----------------------------------------------------------------------===// // Comparison Instructions... diff --git a/test/CodeGen/Thumb2/thumb2-pack.ll b/test/CodeGen/Thumb2/thumb2-pack.ll new file mode 100644 index 00000000000..dd7729e89b8 --- /dev/null +++ b/test/CodeGen/Thumb2/thumb2-pack.ll @@ -0,0 +1,73 @@ +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | \ +; RUN: grep pkhbt | count 5 +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | \ +; RUN: grep pkhtb | count 4 + +define i32 @test1(i32 %X, i32 %Y) { + %tmp1 = and i32 %X, 65535 ; [#uses=1] + %tmp4 = shl i32 %Y, 16 ; [#uses=1] + %tmp5 = or i32 %tmp4, %tmp1 ; [#uses=1] + ret i32 %tmp5 +} + +define i32 @test1a(i32 %X, i32 %Y) { + %tmp19 = and i32 %X, 65535 ; [#uses=1] + %tmp37 = shl i32 %Y, 16 ; [#uses=1] + %tmp5 = or i32 %tmp37, %tmp19 ; [#uses=1] + ret i32 %tmp5 +} + +define i32 @test2(i32 %X, i32 %Y) { + %tmp1 = and i32 %X, 65535 ; [#uses=1] + %tmp3 = shl i32 %Y, 12 ; [#uses=1] + %tmp4 = and i32 %tmp3, -65536 ; [#uses=1] + %tmp57 = or i32 %tmp4, %tmp1 ; [#uses=1] + ret i32 %tmp57 +} + +define i32 @test3(i32 %X, i32 %Y) { + %tmp19 = and i32 %X, 65535 ; [#uses=1] + %tmp37 = shl i32 %Y, 18 ; [#uses=1] + %tmp5 = or i32 %tmp37, %tmp19 ; [#uses=1] + ret i32 %tmp5 +} + +define i32 @test4(i32 %X, i32 %Y) { + %tmp1 = and i32 %X, 65535 ; [#uses=1] + %tmp3 = and i32 %Y, -65536 ; [#uses=1] + %tmp46 = or i32 %tmp3, %tmp1 ; [#uses=1] + ret i32 %tmp46 +} + +define i32 @test5(i32 %X, i32 %Y) { + %tmp17 = and i32 %X, -65536 ; [#uses=1] + %tmp2 = bitcast i32 %Y to i32 ; [#uses=1] + %tmp4 = lshr i32 %tmp2, 16 ; [#uses=2] + %tmp5 = or i32 %tmp4, %tmp17 ; [#uses=1] + ret i32 %tmp5 +} + +define i32 @test5a(i32 %X, i32 %Y) { + %tmp110 = and i32 %X, -65536 ; [#uses=1] + %tmp37 = lshr i32 %Y, 16 ; [#uses=1] + %tmp39 = bitcast i32 %tmp37 to i32 ; [#uses=1] + %tmp5 = or i32 %tmp39, %tmp110 ; [#uses=1] + ret i32 %tmp5 +} + +define i32 @test6(i32 %X, i32 %Y) { + %tmp1 = and i32 %X, -65536 ; [#uses=1] + %tmp37 = lshr i32 %Y, 12 ; [#uses=1] + %tmp38 = bitcast i32 %tmp37 to i32 ; [#uses=1] + %tmp4 = and i32 %tmp38, 65535 ; [#uses=1] + %tmp59 = or i32 %tmp4, %tmp1 ; [#uses=1] + ret i32 %tmp59 +} + +define i32 @test7(i32 %X, i32 %Y) { + %tmp1 = and i32 %X, -65536 ; [#uses=1] + %tmp3 = ashr i32 %Y, 18 ; [#uses=1] + %tmp4 = and i32 %tmp3, 65535 ; [#uses=1] + %tmp57 = or i32 %tmp4, %tmp1 ; [#uses=1] + ret i32 %tmp57 +}