[Beignet] [PATCH V2 1/2] GBE: Add more support of char and short arithmetic
Ruiling Song
ruiling.song at intel.com
Tue Jun 25 23:45:43 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 | 63 ++++++++++++++++++++++------
backend/src/llvm/llvm_gen_backend.cpp | 4 +-
2 files changed, 53 insertions(+), 14 deletions(-)
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 1e5f514..beae072 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -1260,30 +1260,69 @@ namespace gbe
const Opcode opcode = insn.getOpcode();
const Type type = insn.getType();
GenRegister dst = sel.selReg(insn.getDst(0), type);
+ const uint32_t simdWidth = sel.curr.execWidth;
+ const RegisterFamily family = getFamily(type);
+
+ //bytes and shorts must be converted to int for DIV and REM per GEN restriction
+ if((opcode == OP_DIV || opcode == OP_REM)
+ && (family == FAMILY_WORD || family == FAMILY_BYTE)) {
+ GenRegister src0 = sel.selReg(insn.getSrc(0), type);
+ GenRegister src1 = sel.selReg(insn.getSrc(1), type);
+ uint32_t function = (opcode == OP_DIV)?
+ GEN_MATH_FUNCTION_INT_DIV_QUOTIENT :
+ GEN_MATH_FUNCTION_INT_DIV_REMAINDER;
+ 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);
+
+ markAllChildren(dag);
+ return true;
+ }
// 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)
+ if (type == TYPE_S32 || type == TYPE_U32 ) {
function = GEN_MATH_FUNCTION_INT_DIV_QUOTIENT;
- else
+ sel.MATH(dst, function, src0, src1);
+ } else if(type == TYPE_FLOAT) {
function = opcode == OP_DIV ?
GEN_MATH_FUNCTION_FDIV :
GEN_MATH_FUNCTION_POW;
- sel.MATH(dst, function, src0, src1);
+ sel.MATH(dst, function, src0, src1);
+ } else {
+ NOT_IMPLEMENTED;
+ }
markAllChildren(dag);
return true;
}
if (opcode == OP_REM) {
GenRegister src0 = sel.selReg(insn.getSrc(0), type);
GenRegister src1 = sel.selReg(insn.getSrc(1), type);
- if (type == TYPE_U32 || type == TYPE_S32) {
+ if(type == TYPE_S32 || type == TYPE_U32) {
sel.MATH(dst, GEN_MATH_FUNCTION_INT_DIV_REMAINDER, src0, src1);
- markAllChildren(dag);
- } else
- NOT_IMPLEMENTED;
+ } else {
+ GBE_ASSERTM(0, "Unsupported type in remainder operation!");
+ }
+ markAllChildren(dag);
return true;
}
@@ -1345,14 +1384,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 5b7754c..b0e8c6c 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