summaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorJunyan He <junyan.he@linux.intel.com>2015-01-06 18:00:37 +0800
committerZhigang Gong <zhigang.gong@intel.com>2015-01-20 16:08:50 +0800
commite6ad5405e4ad74407c1de3e7b9d48e79a6b55f35 (patch)
treecd189e8a57a7b9b906b28f8506891d17c90c705e /backend
parent46f7fea22f15ac33c93ca7ad335be00d7d2d9f22 (diff)
Modify the split logic in encoder
For the instruction like: MOV(16) rxx<4,4:1>:UQ ryy<4,4:1>:UQ the src or dst will stride 4 lines, which is illegal. The src and dst can not cross more than 2 adjacent lines. We need to split this kind of instruction into two 8 instructions here. Signed-off-by: Junyan He <junyan.he@linux.intel.com> Reviewed-by: "Yang, Rong R" <rong.r.yang@intel.com>
Diffstat (limited to 'backend')
-rw-r--r--backend/src/backend/gen_encoder.cpp69
1 files changed, 58 insertions, 11 deletions
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index b4bcc497..ba10d81e 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -67,8 +67,36 @@ namespace gbe
return false;
}
+ INLINE bool isVectorOfLongs(GenRegister reg) {
+ if (reg.hstride != GEN_HORIZONTAL_STRIDE_0 &&
+ (reg.type == GEN_TYPE_UL || reg.type == GEN_TYPE_L))
+ return true;
+ else
+ return false;
+ }
+
+ INLINE bool isCrossMoreThan2(GenRegister reg) {
+ if (reg.hstride == GEN_HORIZONTAL_STRIDE_0)
+ return false;
+
+ const uint32_t typeSz = typeSize(reg.type);
+ const uint32_t horizontal = stride(reg.hstride);
+ if (horizontal * typeSz * 16 > GEN_REG_SIZE * 2) {
+ return true;
+ }
+ return false;
+ }
+
INLINE bool needToSplitAlu1(GenEncoder *p, GenRegister dst, GenRegister src) {
- if (p->curr.execWidth != 16 || src.hstride == GEN_HORIZONTAL_STRIDE_0) return false;
+ if (p->curr.execWidth != 16) return false;
+ if (isVectorOfLongs(dst) == true) return true;
+ if (isCrossMoreThan2(dst) == true) return true;
+
+ if (src.hstride == GEN_HORIZONTAL_STRIDE_0) return false;
+
+ if (isCrossMoreThan2(src) == true) return true;
+ if (isVectorOfLongs(src) == true) return true;
+
if (isVectorOfBytes(dst) == true &&
((isVectorOfBytes(src) == true && src.hstride == dst.hstride)
|| src.hstride == GEN_HORIZONTAL_STRIDE_0))
@@ -79,15 +107,24 @@ namespace gbe
}
INLINE bool needToSplitAlu2(GenEncoder *p, GenRegister dst, GenRegister src0, GenRegister src1) {
- if (p->curr.execWidth != 16 ||
- (src0.hstride == GEN_HORIZONTAL_STRIDE_0 &&
- src1.hstride == GEN_HORIZONTAL_STRIDE_0))
+ if (p->curr.execWidth != 16) return false;
+ if (isVectorOfLongs(dst) == true) return true;
+ if (isCrossMoreThan2(dst) == true) return true;
+
+ if (src0.hstride == GEN_HORIZONTAL_STRIDE_0 &&
+ src1.hstride == GEN_HORIZONTAL_STRIDE_0)
return false;
+
+ if (isVectorOfLongs(src0) == true) return true;
+ if (isVectorOfLongs(src1) == true) return true;
+ if (isCrossMoreThan2(src0) == true) return true;
+ if (isCrossMoreThan2(src1) == true) return true;
+
if (isVectorOfBytes(dst) == true &&
((isVectorOfBytes(src0) == true && src0.hstride == dst.hstride) ||
- src0.hstride == GEN_HORIZONTAL_STRIDE_0) &&
+ src0.hstride == GEN_HORIZONTAL_STRIDE_0) &&
((isVectorOfBytes(src1) == true && src1.hstride == dst.hstride) ||
- src1.hstride == GEN_HORIZONTAL_STRIDE_0))
+ src1.hstride == GEN_HORIZONTAL_STRIDE_0))
return false;
if (isVectorOfBytes(dst) == true ) return true;
if (isVectorOfBytes(src0) == true) return true;
@@ -95,13 +132,23 @@ namespace gbe
return false;
}
- INLINE bool needToSplitCmp(GenEncoder *p, GenRegister src0, GenRegister src1) {
- if (p->curr.execWidth != 16 ||
- (src0.hstride == GEN_HORIZONTAL_STRIDE_0 &&
- src1.hstride == GEN_HORIZONTAL_STRIDE_0))
+ INLINE bool needToSplitCmp(GenEncoder *p, GenRegister src0, GenRegister src1, GenRegister dst) {
+ if (p->curr.execWidth != 16) return false;
+ if (isVectorOfLongs(dst) == true) return true;
+ if (isCrossMoreThan2(dst) == true) return true;
+
+ if (src0.hstride == GEN_HORIZONTAL_STRIDE_0 &&
+ src1.hstride == GEN_HORIZONTAL_STRIDE_0)
return false;
+
if (isVectorOfBytes(src0) == true) return true;
if (isVectorOfBytes(src1) == true) return true;
+
+ if (isVectorOfLongs(src0) == true) return true;
+ if (isVectorOfLongs(src1) == true) return true;
+ if (isCrossMoreThan2(src0) == true) return true;
+ if (isCrossMoreThan2(src1) == true) return true;
+
if (src0.type == GEN_TYPE_D || src0.type == GEN_TYPE_UD || src0.type == GEN_TYPE_F)
return true;
if (src1.type == GEN_TYPE_D || src1.type == GEN_TYPE_UD || src1.type == GEN_TYPE_F)
@@ -874,7 +921,7 @@ namespace gbe
}
void GenEncoder::CMP(uint32_t conditional, GenRegister src0, GenRegister src1, GenRegister dst) {
- if (needToSplitCmp(this, src0, src1) == false) {
+ if (needToSplitCmp(this, src0, src1, dst) == false) {
if(!GenRegister::isNull(dst) && compactAlu2(this, GEN_OPCODE_CMP, dst, src0, src1, conditional, false)) {
return;
}