[Beignet] [PATCH V3 1/2] GBE: Add more support of char and short arithmetic
Ruiling Song
ruiling.song at intel.com
Wed Jun 26 00:52:12 PDT 2013
add * / % support of char and short type.
Signed-off-by: Ruiling Song <ruiling.song at intel.com>
---
backend/src/backend/gen_insn_selection.cpp | 87 ++++++++++++++++++++--------
backend/src/llvm/llvm_gen_backend.cpp | 4 +-
2 files changed, 65 insertions(+), 26 deletions(-)
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 8fb2a80..a20eff0 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -1263,6 +1263,54 @@ namespace gbe
this->opcodes.push_back(ir::Opcode(op));
}
+ bool emitDivRemInst(Selection::Opaque &sel, SelectionDAG &dag, ir::Opcode op) const
+ {
+ using namespace ir;
+ const ir::BinaryInstruction &insn = cast<BinaryInstruction>(dag.insn);
+ const Type type = insn.getType();
+ GenRegister dst = sel.selReg(insn.getDst(0), type);
+ GenRegister src0 = sel.selReg(insn.getSrc(0), type);
+ GenRegister src1 = sel.selReg(insn.getSrc(1), type);
+ const uint32_t simdWidth = sel.curr.execWidth;
+ const RegisterFamily family = getFamily(type);
+ uint32_t function = (op == OP_DIV)?
+ GEN_MATH_FUNCTION_INT_DIV_QUOTIENT :
+ GEN_MATH_FUNCTION_INT_DIV_REMAINDER;
+
+ //bytes and shorts must be converted to int for DIV and REM per GEN restriction
+ if((family == FAMILY_WORD || family == FAMILY_BYTE)) {
+ GenRegister tmp0, tmp1;
+ ir::Register reg = sel.reg(FAMILY_DWORD);
+
+ tmp0 = GenRegister::udxgrf(simdWidth, reg);
+ tmp0 = GenRegister::retype(tmp0, GEN_TYPE_D);
+ sel.MOV(tmp0, src0);
+
+ tmp1 = GenRegister::udxgrf(simdWidth, sel.reg(FAMILY_DWORD));
+ tmp1 = GenRegister::retype(tmp1, GEN_TYPE_D);
+ sel.MOV(tmp1, src1);
+
+ sel.MATH(tmp0, function, tmp0, tmp1);
+ GenRegister unpacked;
+ if(family == FAMILY_WORD) {
+ unpacked = GenRegister::unpacked_uw(reg);
+ } else {
+ unpacked = GenRegister::unpacked_ub(reg);
+ }
+ unpacked = GenRegister::retype(unpacked, getGenType(type));
+ sel.MOV(dst, unpacked);
+ } else if (type == TYPE_S32 || type == TYPE_U32 ) {
+ sel.MATH(dst, function, src0, src1);
+ } else if(type == TYPE_FLOAT) {
+ GBE_ASSERT(op != OP_REM);
+ sel.MATH(dst, GEN_MATH_FUNCTION_FDIV, src0, src1);
+ } else {
+ NOT_IMPLEMENTED;
+ }
+ markAllChildren(dag);
+ return true;
+ }
+
INLINE bool emit(Selection::Opaque &sel, SelectionDAG &dag) const
{
using namespace ir;
@@ -1271,29 +1319,20 @@ namespace gbe
const Type type = insn.getType();
GenRegister dst = sel.selReg(insn.getDst(0), type);
- // Immediates not supported
- if (opcode == OP_DIV || opcode == OP_POW) {
- GenRegister src0 = sel.selReg(insn.getSrc(0), type);
- GenRegister src1 = sel.selReg(insn.getSrc(1), type);
- uint32_t function;
- if (type == TYPE_S32 || type == TYPE_U32)
- function = GEN_MATH_FUNCTION_INT_DIV_QUOTIENT;
- else
- function = opcode == OP_DIV ?
- GEN_MATH_FUNCTION_FDIV :
- GEN_MATH_FUNCTION_POW;
- sel.MATH(dst, function, src0, src1);
- markAllChildren(dag);
- return true;
+ if(opcode == OP_DIV || opcode == OP_REM) {
+ return this->emitDivRemInst(sel, dag, opcode);
}
- if (opcode == OP_REM) {
+ // Immediates not supported
+ if (opcode == OP_POW) {
GenRegister src0 = sel.selReg(insn.getSrc(0), type);
GenRegister src1 = sel.selReg(insn.getSrc(1), type);
- if (type == TYPE_U32 || type == TYPE_S32) {
- sel.MATH(dst, GEN_MATH_FUNCTION_INT_DIV_REMAINDER, src0, src1);
- markAllChildren(dag);
- } else
+
+ if(type == TYPE_FLOAT) {
+ sel.MATH(dst, GEN_MATH_FUNCTION_POW, src0, src1);
+ } else {
NOT_IMPLEMENTED;
+ }
+ markAllChildren(dag);
return true;
}
@@ -1355,14 +1394,14 @@ namespace gbe
case OP_SHR: sel.SHR(dst, src0, src1); break;
case OP_ASR: sel.ASR(dst, src0, src1); break;
case OP_MUL:
- if (type == TYPE_FLOAT || type == TYPE_DOUBLE)
- sel.MUL(dst, src0, src1);
- else if (type == TYPE_U32 || type == TYPE_S32) {
+ if (type == TYPE_U32 || type == TYPE_S32) {
sel.pop();
return false;
}
- else
- NOT_IMPLEMENTED;
+ else {
+ GBE_ASSERTM((type != TYPE_S64 && type != TYPE_U64), "64bit integer not supported yet!" );
+ sel.MUL(dst, src0, src1);
+ }
break;
default: NOT_IMPLEMENTED;
}
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 08500ba..e6c0765 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -1276,10 +1276,10 @@ namespace gbe
case Instruction::FSub: ctx.SUB(type, dst, src0, src1); break;
case Instruction::Mul:
case Instruction::FMul: ctx.MUL(type, dst, src0, src1); break;
- case Instruction::URem:
+ case Instruction::URem: ctx.REM(getUnsignedType(ctx, I.getType()), dst, src0, src1); break;
case Instruction::SRem:
case Instruction::FRem: ctx.REM(type, dst, src0, src1); break;
- case Instruction::UDiv:
+ case Instruction::UDiv: ctx.DIV(getUnsignedType(ctx, I.getType()), dst, src0, src1); break;
case Instruction::SDiv:
case Instruction::FDiv: ctx.DIV(type, dst, src0, src1); break;
case Instruction::And: ctx.AND(type, dst, src0, src1); break;
--
1.7.9.5
More information about the Beignet
mailing list