[PATCH[[mips] Add octeon branch instructions bbit0/bbit032/bbit1/bbit132
Kai Nacke
kai.nacke at redstar.de
Sun Jan 11 10:06:58 PST 2015
Hi Daniel!
I refined the patch a bit: there was a bug in the instruction pattern.
I also added new patterns with the result that the instructions are now
selected for C code like
if (a & 0x08) { .. }
Test cases are included.
Please review.
Regards,
Kai
On 06.01.2015 07:12, Kai Nacke wrote:
> Hi Daniel,
>
> the attached patch adds the octeon branch instructions
> bbit0/bbit032/bbit1/bbit132. Test case is included. Please review.
>
> BTW: I did not implement the automatic change of the instruction if the
> constant does not fit (e.g. bbit0 $22, 42, foo -> bbit032 $22, 10, foo).
> Do you have an suggestion where to implement this? Thanks.
>
> Regards,
> Kai
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
>From 48cee2095ceac6968d58ce30e1b356232e378044 Mon Sep 17 00:00:00 2001
From: kai <kai at redstar.de>
Date: Sat, 10 Jan 2015 12:21:46 +0100
Subject: [PATCH 1/3] [mips] Add octeon branch instructions
bbit0/bbit032/bbit1/bbit132
This commits adds the octeon branch instructions bbit0/bbit032/bbit1/bbit132.
It also includes patterns for instruction selection and test cases.
---
lib/Target/Mips/Mips64InstrInfo.td | 77 +++++++++++++++++++++++++++++++++++++
lib/Target/Mips/MipsInstrFormats.td | 13 +++++++
test/CodeGen/Mips/octeon.ll | 72 ++++++++++++++++++++++++++++++++++
test/MC/Mips/octeon-instructions.s | 9 +++++
4 files changed, 171 insertions(+)
diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td
index 4e2dcd8..8a40652 100644
--- a/lib/Target/Mips/Mips64InstrInfo.td
+++ b/lib/Target/Mips/Mips64InstrInfo.td
@@ -41,6 +41,36 @@ def immSExt10_64 : PatLeaf<(i64 imm),
def immZExt16_64 : PatLeaf<(i64 imm),
[{ return isInt<16>(N->getZExtValue()); }]>;
+// Transformation function: get log2 of low 32 bits of immediate
+def Log2LO : SDNodeXForm<imm, [{
+ return getImm(N, Log2_64((unsigned) N->getZExtValue()));
+}]>;
+
+// Transformation function: get log2 of high 32 bits of immediate
+def Log2HI : SDNodeXForm<imm, [{
+ return getImm(N, Log2_64((unsigned) (N->getZExtValue() >> 32)));
+}]>;
+
+// Predicate: True if immediate is a power of 2 and fits 32 bits
+def PowerOf2LO : PatLeaf<(imm), [{
+ if (N->getValueType(0) == MVT::i64) {
+ uint64_t Imm = N->getZExtValue();
+ return isPowerOf2_64(Imm) && (Imm & 0xffffffff) == Imm;
+ }
+ else
+ return false;
+}]>;
+
+// Predicate: True if immediate is a power of 2 and exceeds 32 bits
+def PowerOf2HI : PatLeaf<(imm), [{
+ if (N->getValueType(0) == MVT::i64) {
+ uint64_t Imm = N->getZExtValue();
+ return isPowerOf2_64(Imm) && (Imm & 0xffffffff00000000) == Imm;
+ }
+ else
+ return false;
+}]>;
+
//===----------------------------------------------------------------------===//
// Instructions specific format
//===----------------------------------------------------------------------===//
@@ -303,12 +333,47 @@ class SetCC64_I<string opstr, PatFrag cond_op>:
let TwoOperandAliasConstraint = "$rt = $rs";
}
+class CBranchImm<string opstr, DAGOperand opnd, PatFrag cond_op,
+ RegisterOperand RO> :
+ InstSE<(outs), (ins RO:$rs, uimm5_64:$p, opnd:$offset),
+ !strconcat(opstr, "\t$rs, $p, $offset"),
+ [(brcond (i32 (cond_op (and RO:$rs, (shl 1, immZExt5_64:$p)), 0)),
+ bb:$offset)], IIBranch,
+ FrmI, opstr> {
+ let isBranch = 1;
+ let isTerminator = 1;
+ let hasDelaySlot = 1;
+ let Defs = [AT];
+}
+
+class CBranchImm32<string opstr, DAGOperand opnd, PatFrag cond_op,
+ RegisterOperand RO> :
+ InstSE<(outs), (ins RO:$rs, uimm5_64:$p, opnd:$offset),
+ !strconcat(opstr, "\t$rs, $p, $offset"),
+ [(brcond (i32 (cond_op (and RO:$rs, (shl 0x100000000,
+ immZExt5_64:$p)), 0)),
+ bb:$offset)], IIBranch,
+ FrmI, opstr> {
+ let isBranch = 1;
+ let isTerminator = 1;
+ let hasDelaySlot = 1;
+ let Defs = [AT];
+}
+
// Unsigned Byte Add
let Pattern = [(set GPR64Opnd:$rd,
(and (add GPR64Opnd:$rs, GPR64Opnd:$rt), 255))] in
def BADDu : ArithLogicR<"baddu", GPR64Opnd, 1, II_BADDU>,
ADD_FM<0x1c, 0x28>;
+// Branch on Bit Clear /+32
+def BBIT0 : CBranchImm<"bbit0", brtarget, seteq, GPR64Opnd>, BBIT_FM<0x32>;
+def BBIT032: CBranchImm32<"bbit032", brtarget, seteq, GPR64Opnd>, BBIT_FM<0x36>;
+
+// Branch on Bit Set /+32
+def BBIT1 : CBranchImm<"bbit1", brtarget, setne, GPR64Opnd>, BBIT_FM<0x3a>;
+def BBIT132: CBranchImm32<"bbit132", brtarget, setne, GPR64Opnd>, BBIT_FM<0x3e>;
+
// Multiply Doubleword to GPR
let Defs = [HI0, LO0, P0, P1, P2] in
def DMUL : ArithLogicR<"dmul", GPR64Opnd, 1, II_DMUL, mul>,
@@ -438,6 +503,18 @@ def : MipsPat<(i64 (sext_inreg GPR64:$src, i32)),
// bswap MipsPattern
def : MipsPat<(bswap GPR64:$rt), (DSHD (DSBH GPR64:$rt))>;
+// Octeon bbit0/bbit1 MipsPattern
+let Predicates = [HasMips64, HasCnMips] in {
+def : MipsPat<(brcond (i32 (seteq (and i64:$lhs, PowerOf2LO:$mask), 0)), bb:$dst),
+ (BBIT0 i64:$lhs, (Log2LO PowerOf2LO:$mask), bb:$dst)>;
+def : MipsPat<(brcond (i32 (seteq (and i64:$lhs, PowerOf2HI:$mask), 0)), bb:$dst),
+ (BBIT032 i64:$lhs, (Log2HI PowerOf2HI:$mask), bb:$dst)>;
+def : MipsPat<(brcond (i32 (setne (and i64:$lhs, PowerOf2LO:$mask), 0)), bb:$dst),
+ (BBIT1 i64:$lhs, (Log2LO PowerOf2LO:$mask), bb:$dst)>;
+def : MipsPat<(brcond (i32 (setne (and i64:$lhs, PowerOf2HI:$mask), 0)), bb:$dst),
+ (BBIT132 i64:$lhs, (Log2HI PowerOf2HI:$mask), bb:$dst)>;
+}
+
//===----------------------------------------------------------------------===//
// Instruction aliases
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td
index d8dae25..8cc1603 100644
--- a/lib/Target/Mips/MipsInstrFormats.td
+++ b/lib/Target/Mips/MipsInstrFormats.td
@@ -297,6 +297,19 @@ class BGEZ_FM<bits<6> op, bits<5> funct> : StdArch {
let Inst{15-0} = offset;
}
+class BBIT_FM<bits<6> op> : StdArch {
+ bits<5> rs;
+ bits<5> p;
+ bits<16> offset;
+
+ bits<32> Inst;
+
+ let Inst{31-26} = op;
+ let Inst{25-21} = rs;
+ let Inst{20-16} = p;
+ let Inst{15-0} = offset;
+}
+
class SLTI_FM<bits<6> op> : StdArch {
bits<5> rt;
bits<5> rs;
diff --git a/test/CodeGen/Mips/octeon.ll b/test/CodeGen/Mips/octeon.ll
index d5ff9bd..00265f6 100644
--- a/test/CodeGen/Mips/octeon.ll
+++ b/test/CodeGen/Mips/octeon.ll
@@ -27,3 +27,75 @@ entry:
%res = mul i64 %a, %b
ret i64 %res
}
+
+define i64 @bbit0(i64 %a) nounwind {
+entry:
+; OCTEON-LABEL: bbit0:
+; OCTEON: bbit0 $4, 3,
+; MIPS64-LABEL: bbit0:
+; MIPS64: andi
+; MIPS64: beqz
+ %bit = and i64 %a, 8
+ %res = icmp eq i64 %bit, 0
+ br i1 %res, label %endif, label %if
+if:
+ ret i64 48
+
+endif:
+ ret i64 12
+}
+
+define i64 @bbit032(i64 %a) nounwind {
+entry:
+; OCTEON-LABEL: bbit032:
+; OCTEON: bbit032 $4, 3,
+; MIPS64-LABEL: bbit032:
+; MIPS64: daddiu
+; MIPS64: dsll
+; MIPS64: and
+; MIPS64: beqz
+ %bit = and i64 %a, 34359738368
+ %res = icmp eq i64 %bit, 0
+ br i1 %res, label %endif, label %if
+if:
+ ret i64 48
+
+endif:
+ ret i64 12
+}
+
+define i64 @bbit1(i64 %a) nounwind {
+entry:
+; OCTEON-LABEL: bbit1:
+; OCTEON: bbit1 $4, 3,
+; MIPS64-LABEL: bbit1:
+; MIPS64: andi
+; MIPS64: beqz
+ %bit = and i64 %a, 8
+ %res = icmp ne i64 %bit, 0
+ br i1 %res, label %endif, label %if
+if:
+ ret i64 48
+
+endif:
+ ret i64 12
+}
+
+define i64 @bbit132(i64 %a) nounwind {
+entry:
+; OCTEON-LABEL: bbit132:
+; OCTEON: bbit132 $4, 3,
+; MIPS64-LABEL: bbit132:
+; MIPS64: daddiu
+; MIPS64: dsll
+; MIPS64: and
+; MIPS64: beqz
+ %bit = and i64 %a, 34359738368
+ %res = icmp ne i64 %bit, 0
+ br i1 %res, label %endif, label %if
+if:
+ ret i64 48
+
+endif:
+ ret i64 12
+}
diff --git a/test/MC/Mips/octeon-instructions.s b/test/MC/Mips/octeon-instructions.s
index 2922744..e98bbe4 100644
--- a/test/MC/Mips/octeon-instructions.s
+++ b/test/MC/Mips/octeon-instructions.s
@@ -3,6 +3,10 @@
# CHECK: baddu $9, $6, $7 # encoding: [0x70,0xc7,0x48,0x28]
# CHECK: baddu $17, $18, $19 # encoding: [0x72,0x53,0x88,0x28]
# CHECK: baddu $2, $2, $3 # encoding: [0x70,0x43,0x10,0x28]
+# CHECK: bbit0 $19, 22, foo # encoding: [0xca,0x76,A,A]
+# CHECK: bbit032 $fp, 11, foo # encoding: [0xdb,0xcb,A,A]
+# CHECK: bbit1 $3, 31, foo # encoding: [0xe8,0x7f,A,A]
+# CHECK: bbit132 $24, 10, foo # encoding: [0xfb,0x0a,A,A]
# CHECK: cins $25, $10, 22, 2 # encoding: [0x71,0x59,0x15,0xb2]
# CHECK: cins $9, $9, 17, 29 # encoding: [0x71,0x29,0xec,0x72]
# CHECK: cins32 $15, $2, 18, 8 # encoding: [0x70,0x4f,0x44,0xb3]
@@ -46,9 +50,14 @@
# CHECK: vmulu $sp, $10, $17 # encoding: [0x71,0x51,0xe8,0x0f]
# CHECK: vmulu $27, $27, $6 # encoding: [0x73,0x66,0xd8,0x0f]
+foo:
baddu $9, $6, $7
baddu $17, $18, $19
baddu $2, $3
+ bbit0 $19, 22, foo
+ bbit032 $30, 11, foo
+ bbit1 $3, 31, foo
+ bbit132 $24, 10, foo
cins $25, $10, 22, 2
cins $9, 17, 29
cins32 $15, $2, 18, 8
--
1.9.4.msysgit.2
More information about the llvm-commits
mailing list