[Beignet] [PATCH 4/9] support 64bit-integer AND(&), OR(|), XOR(^) arithmetic
Homer Hsing
homer.xing at intel.com
Sun Aug 4 22:06:38 PDT 2013
Signed-off-by: Homer Hsing <homer.xing at intel.com>
---
backend/src/backend/gen_context.cpp | 57 ++++++++++++++++++++++++++++++
backend/src/backend/gen_insn_selection.cpp | 24 +++++++++++--
backend/src/backend/gen_insn_selection.hxx | 3 ++
backend/src/ir/instruction.cpp | 1 +
4 files changed, 82 insertions(+), 3 deletions(-)
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index da21ceb..0d72aa2 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -162,6 +162,63 @@ namespace gbe
case SEL_OP_AND: p->AND(dst, src0, src1); break;
case SEL_OP_OR: p->OR (dst, src0, src1); break;
case SEL_OP_XOR: p->XOR(dst, src0, src1); break;
+ case SEL_OP_I64AND:
+ {
+ GenRegister xdst = GenRegister::retype(dst, GEN_TYPE_UQ),
+ xsrc0 = GenRegister::retype(src0, GEN_TYPE_UQ),
+ xsrc1 = GenRegister::retype(src1, GEN_TYPE_UQ);
+ p->push();
+ p->curr.quarterControl = 0;
+ p->curr.nibControl = 0;
+ p->AND(xdst.bottom_half(), xsrc0.bottom_half(), xsrc1.bottom_half());
+ p->AND(xdst.top_half(), xsrc0.top_half(), xsrc1.top_half());
+ p->curr.nibControl = 1;
+ xdst = GenRegister::suboffset(xdst, 4),
+ xsrc0 = GenRegister::suboffset(xsrc0, 4),
+ xsrc1 = GenRegister::suboffset(xsrc1, 4);
+ p->AND(xdst.bottom_half(), xsrc0.bottom_half(), xsrc1.bottom_half());
+ p->AND(xdst.top_half(), xsrc0.top_half(), xsrc1.top_half());
+ p->pop();
+ }
+ break;
+ case SEL_OP_I64OR:
+ {
+ GenRegister xdst = GenRegister::retype(dst, GEN_TYPE_UQ),
+ xsrc0 = GenRegister::retype(src0, GEN_TYPE_UQ),
+ xsrc1 = GenRegister::retype(src1, GEN_TYPE_UQ);
+ p->push();
+ p->curr.quarterControl = 0;
+ p->curr.nibControl = 0;
+ p->OR(xdst.bottom_half(), xsrc0.bottom_half(), xsrc1.bottom_half());
+ p->OR(xdst.top_half(), xsrc0.top_half(), xsrc1.top_half());
+ p->curr.nibControl = 1;
+ xdst = GenRegister::suboffset(xdst, 4),
+ xsrc0 = GenRegister::suboffset(xsrc0, 4),
+ xsrc1 = GenRegister::suboffset(xsrc1, 4);
+ p->OR(xdst.bottom_half(), xsrc0.bottom_half(), xsrc1.bottom_half());
+ p->OR(xdst.top_half(), xsrc0.top_half(), xsrc1.top_half());
+ p->pop();
+ }
+ break;
+ case SEL_OP_I64XOR:
+ {
+ GenRegister xdst = GenRegister::retype(dst, GEN_TYPE_UQ),
+ xsrc0 = GenRegister::retype(src0, GEN_TYPE_UQ),
+ xsrc1 = GenRegister::retype(src1, GEN_TYPE_UQ);
+ p->push();
+ p->curr.quarterControl = 0;
+ p->curr.nibControl = 0;
+ p->XOR(xdst.bottom_half(), xsrc0.bottom_half(), xsrc1.bottom_half());
+ p->XOR(xdst.top_half(), xsrc0.top_half(), xsrc1.top_half());
+ p->curr.nibControl = 1;
+ xdst = GenRegister::suboffset(xdst, 4),
+ xsrc0 = GenRegister::suboffset(xsrc0, 4),
+ xsrc1 = GenRegister::suboffset(xsrc1, 4);
+ p->XOR(xdst.bottom_half(), xsrc0.bottom_half(), xsrc1.bottom_half());
+ p->XOR(xdst.top_half(), xsrc0.top_half(), xsrc1.top_half());
+ p->pop();
+ }
+ break;
case SEL_OP_SHR: p->SHR(dst, src0, src1); break;
case SEL_OP_SHL: p->SHL(dst, src0, src1); break;
case SEL_OP_RSR: p->RSR(dst, src0, src1); break;
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 3d4d60a..df0bfe6 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -423,6 +423,9 @@ namespace gbe
ALU2(AND)
ALU2(OR)
ALU2(XOR)
+ ALU2(I64AND)
+ ALU2(I64OR)
+ ALU2(I64XOR)
ALU2(SHR)
ALU2(SHL)
ALU2(RSR)
@@ -1426,9 +1429,24 @@ namespace gbe
sel.ADD(dst, src0, src1);
sel.pop();
break;
- case OP_XOR: sel.XOR(dst, src0, src1); break;
- case OP_OR: sel.OR(dst, src0, src1); break;
- case OP_AND: sel.AND(dst, src0, src1); break;
+ case OP_XOR:
+ if (type == Type::TYPE_U64 || type == Type::TYPE_S64)
+ sel.I64XOR(dst, src0, src1);
+ else
+ sel.XOR(dst, src0, src1);
+ break;
+ case OP_OR:
+ if (type == Type::TYPE_U64 || type == Type::TYPE_S64)
+ sel.I64OR(dst, src0, src1);
+ else
+ sel.OR(dst, src0, src1);
+ break;
+ case OP_AND:
+ if (type == Type::TYPE_U64 || type == Type::TYPE_S64)
+ sel.I64AND(dst, src0, src1);
+ else
+ sel.AND(dst, src0, src1);
+ break;
case OP_SUB:
if (type == Type::TYPE_U64 || type == Type::TYPE_S64) {
GenRegister t = sel.selReg(sel.reg(RegisterFamily::FAMILY_DWORD), Type::TYPE_S32);
diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx
index 8eeb19f..7664c8f 100644
--- a/backend/src/backend/gen_insn_selection.hxx
+++ b/backend/src/backend/gen_insn_selection.hxx
@@ -14,6 +14,9 @@ DECL_SELECTION_IR(SEL, BinaryInstruction)
DECL_SELECTION_IR(AND, BinaryInstruction)
DECL_SELECTION_IR(OR, BinaryInstruction)
DECL_SELECTION_IR(XOR, BinaryInstruction)
+DECL_SELECTION_IR(I64AND, BinaryInstruction)
+DECL_SELECTION_IR(I64OR, BinaryInstruction)
+DECL_SELECTION_IR(I64XOR, BinaryInstruction)
DECL_SELECTION_IR(SHR, BinaryInstruction)
DECL_SELECTION_IR(SHL, BinaryInstruction)
DECL_SELECTION_IR(RSR, BinaryInstruction)
diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp
index 2589848..f58757b 100644
--- a/backend/src/ir/instruction.cpp
+++ b/backend/src/ir/instruction.cpp
@@ -672,6 +672,7 @@ namespace ir {
static const Type logicalType[] = {TYPE_S8, TYPE_U8,
TYPE_S16, TYPE_U16,
TYPE_S32, TYPE_U32,
+ TYPE_S64, TYPE_U64,
TYPE_BOOL};
static const uint32_t logicalTypeNum = ARRAY_ELEM_NUM(logicalType);
--
1.8.1.2
More information about the Beignet
mailing list