[Beignet] [PATCH] 64-bit-int: allocate flag register by RA
Homer Hsing
homer.xing at intel.com
Sat Sep 21 19:05:39 PDT 2013
64-bit integer arithmetic now uses flag register allocated by register
allocator.
Signed-off-by: Homer Hsing <homer.xing at intel.com>
---
backend/src/backend/gen_context.cpp | 34 ++++++++++++++----------------
backend/src/backend/gen_insn_selection.cpp | 30 ++++++++++++++------------
backend/src/backend/gen_insn_selection.hpp | 2 +-
backend/src/backend/gen_register.hpp | 9 ++++++++
4 files changed, 43 insertions(+), 32 deletions(-)
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 070c5a8..7804874 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -512,6 +512,7 @@ namespace gbe
GenRegister e = ra->genReg(insn.dst(5));
GenRegister f = ra->genReg(insn.dst(6));
a.type = b.type = c.type = d.type = e.type = f.type = GEN_TYPE_UD;
+ GenRegister flagReg = ra->genReg(insn.dst(7));
GenRegister zero = GenRegister::immud(0);
switch(insn.opcode) {
case SEL_OP_I64SHL:
@@ -524,16 +525,16 @@ namespace gbe
p->SHL(c, e, a);
p->SHL(d, f, a);
p->OR(e, d, b);
- p->MOV(GenRegister::flag(1, 1), GenRegister::immuw(0xFFFF));
+ p->MOV(flagReg, GenRegister::immuw(0xFFFF));
p->curr.predicate = GEN_PREDICATE_NORMAL;
- p->curr.physicalFlag = 1, p->curr.flag = 1, p->curr.subFlag = 1;
+ p->curr.useFlag(flagReg.flag_nr(), flagReg.subnr);
p->CMP(GEN_CONDITIONAL_Z, a, zero);
p->SEL(d, d, e);
p->curr.predicate = GEN_PREDICATE_NONE;
p->AND(a, a, GenRegister::immud(32));
- p->MOV(GenRegister::flag(1, 1), GenRegister::immuw(0xFFFF));
+ p->MOV(flagReg, GenRegister::immuw(0xFFFF));
p->curr.predicate = GEN_PREDICATE_NORMAL;
- p->curr.physicalFlag = 1, p->curr.flag = 1, p->curr.subFlag = 1;
+ p->curr.useFlag(flagReg.flag_nr(), flagReg.subnr);
p->CMP(GEN_CONDITIONAL_Z, a, zero);
p->SEL(d, d, c);
p->SEL(c, c, zero);
@@ -551,16 +552,16 @@ namespace gbe
p->SHR(c, f, a);
p->SHR(d, e, a);
p->OR(e, d, b);
- p->MOV(GenRegister::flag(1, 1), GenRegister::immuw(0xFFFF));
+ p->MOV(flagReg, GenRegister::immuw(0xFFFF));
p->curr.predicate = GEN_PREDICATE_NORMAL;
- p->curr.physicalFlag = 1, p->curr.flag = 1, p->curr.subFlag = 1;
+ p->curr.useFlag(flagReg.flag_nr(), flagReg.subnr);
p->CMP(GEN_CONDITIONAL_Z, a, zero);
p->SEL(d, d, e);
p->curr.predicate = GEN_PREDICATE_NONE;
p->AND(a, a, GenRegister::immud(32));
- p->MOV(GenRegister::flag(1, 1), GenRegister::immuw(0xFFFF));
+ p->MOV(flagReg, GenRegister::immuw(0xFFFF));
p->curr.predicate = GEN_PREDICATE_NORMAL;
- p->curr.physicalFlag = 1, p->curr.flag = 1, p->curr.subFlag = 1;
+ p->curr.useFlag(flagReg.flag_nr(), flagReg.subnr);
p->CMP(GEN_CONDITIONAL_Z, a, zero);
p->SEL(d, d, c);
p->SEL(c, c, zero);
@@ -579,16 +580,16 @@ namespace gbe
p->ASR(c, f, a);
p->SHR(d, e, a);
p->OR(e, d, b);
- p->MOV(GenRegister::flag(1, 1), GenRegister::immuw(0xFFFF));
+ p->MOV(flagReg, GenRegister::immuw(0xFFFF));
p->curr.predicate = GEN_PREDICATE_NORMAL;
- p->curr.physicalFlag = 1, p->curr.flag = 1, p->curr.subFlag = 1;
+ p->curr.useFlag(flagReg.flag_nr(), flagReg.subnr);
p->CMP(GEN_CONDITIONAL_Z, a, zero);
p->SEL(d, d, e);
p->curr.predicate = GEN_PREDICATE_NONE;
p->AND(a, a, GenRegister::immud(32));
- p->MOV(GenRegister::flag(1, 1), GenRegister::immuw(0xFFFF));
+ p->MOV(flagReg, GenRegister::immuw(0xFFFF));
p->curr.predicate = GEN_PREDICATE_NORMAL;
- p->curr.physicalFlag = 1, p->curr.flag = 1, p->curr.subFlag = 1;
+ p->curr.useFlag(flagReg.flag_nr(), flagReg.subnr);
p->CMP(GEN_CONDITIONAL_Z, a, zero);
p->SEL(d, d, c);
p->SEL(c, c, GenRegister::immd(-1));
@@ -622,6 +623,7 @@ namespace gbe
GenRegister high = ra->genReg(insn.dst(1));
GenRegister low = ra->genReg(insn.dst(2));
GenRegister tmp = ra->genReg(insn.dst(3));
+ GenRegister flagReg = ra->genReg(insn.dst(4));
loadTopHalf(high, src);
loadBottomHalf(low, src);
if(!src.is_signed_int()) {
@@ -629,9 +631,7 @@ namespace gbe
} else {
p->push();
p->curr.predicate = GEN_PREDICATE_NONE;
- p->curr.physicalFlag = 1;
- p->curr.flag = 1;
- p->curr.subFlag = 0;
+ p->curr.useFlag(flagReg.flag_nr(), flagReg.subnr);
p->CMP(GEN_CONDITIONAL_GE, high, GenRegister::immud(0x80000000));
p->curr.predicate = GEN_PREDICATE_NORMAL;
p->NOT(high, high);
@@ -642,9 +642,7 @@ namespace gbe
p->pop();
UnsignedI64ToFloat(dest, high, low, tmp);
p->push();
- p->curr.physicalFlag = 1;
- p->curr.flag = 1;
- p->curr.subFlag = 0;
+ p->curr.useFlag(flagReg.flag_nr(), flagReg.subnr);
dest.type = GEN_TYPE_UD;
p->OR(dest, dest, GenRegister::immud(0x80000000));
p->pop();
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index b0b48ba..06d7382 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -419,7 +419,7 @@ namespace gbe
#define ALU3(OP) \
INLINE void OP(Reg dst, Reg src0, Reg src1, Reg src2) { ALU3(SEL_OP_##OP, dst, src0, src1, src2); }
#define I64Shift(OP) \
- INLINE void OP(Reg dst, Reg src0, Reg src1, GenRegister tmp[6]) { I64Shift(SEL_OP_##OP, dst, src0, src1, tmp); }
+ INLINE void OP(Reg dst, Reg src0, Reg src1, GenRegister tmp[7]) { I64Shift(SEL_OP_##OP, dst, src0, src1, tmp); }
ALU1(MOV)
ALU1WithTemp(MOV_DF)
ALU1WithTemp(LOAD_DF_IMM)
@@ -470,13 +470,13 @@ namespace gbe
#undef ALU3
#undef I64Shift
/*! Convert 64-bit integer to 32-bit float */
- void CONVI64_TO_F(Reg dst, Reg src, GenRegister tmp[3]);
+ void CONVI64_TO_F(Reg dst, Reg src, GenRegister tmp[4]);
/*! (x+y)>>1 without mod. overflow */
void I64HADD(Reg dst, Reg src0, Reg src1, GenRegister tmp[4]);
/*! (x+y+1)>>1 without mod. overflow */
void I64RHADD(Reg dst, Reg src0, Reg src1, GenRegister tmp[4]);
/*! Shift a 64-bit integer */
- void I64Shift(SelectionOpcode opcode, Reg dst, Reg src0, Reg src1, GenRegister tmp[6]);
+ void I64Shift(SelectionOpcode opcode, Reg dst, Reg src0, Reg src1, GenRegister tmp[7]);
/*! Compare 64-bit integer */
void I64CMP(uint32_t conditional, Reg src0, Reg src1, GenRegister tmp[3]);
/*! Encode a barrier instruction */
@@ -1079,11 +1079,11 @@ namespace gbe
insn->extra.function = conditional;
}
- void Selection::Opaque::CONVI64_TO_F(Reg dst, Reg src, GenRegister tmp[3]) {
- SelectionInstruction *insn = this->appendInsn(SEL_OP_CONVI64_TO_F, 4, 1);
+ void Selection::Opaque::CONVI64_TO_F(Reg dst, Reg src, GenRegister tmp[4]) {
+ SelectionInstruction *insn = this->appendInsn(SEL_OP_CONVI64_TO_F, 5, 1);
insn->dst(0) = dst;
insn->src(0) = src;
- for(int i = 0; i < 3; i ++)
+ for(int i = 0; i < 4; i ++)
insn->dst(i + 1) = tmp[i];
}
@@ -1105,12 +1105,12 @@ namespace gbe
insn->dst(i + 1) = tmp[i];
}
- void Selection::Opaque::I64Shift(SelectionOpcode opcode, Reg dst, Reg src0, Reg src1, GenRegister tmp[6]) {
- SelectionInstruction *insn = this->appendInsn(opcode, 7, 2);
+ void Selection::Opaque::I64Shift(SelectionOpcode opcode, Reg dst, Reg src0, Reg src1, GenRegister tmp[7]) {
+ SelectionInstruction *insn = this->appendInsn(opcode, 8, 2);
insn->dst(0) = dst;
insn->src(0) = src0;
insn->src(1) = src1;
- for(int i = 0; i < 6; i ++)
+ for(int i = 0; i < 7; i ++)
insn->dst(i + 1) = tmp[i];
}
@@ -1647,27 +1647,30 @@ namespace gbe
break;
case OP_SHL:
if (type == TYPE_S64 || type == TYPE_U64) {
- GenRegister tmp[6];
+ GenRegister tmp[7];
for(int i = 0; i < 6; i ++)
tmp[i] = sel.selReg(sel.reg(FAMILY_DWORD));
+ tmp[6] = sel.selReg(sel.reg(FAMILY_BOOL));
sel.I64SHL(dst, src0, src1, tmp);
} else
sel.SHL(dst, src0, src1);
break;
case OP_SHR:
if (type == TYPE_S64 || type == TYPE_U64) {
- GenRegister tmp[6];
+ GenRegister tmp[7];
for(int i = 0; i < 6; i ++)
tmp[i] = sel.selReg(sel.reg(FAMILY_DWORD));
+ tmp[6] = sel.selReg(sel.reg(FAMILY_BOOL));
sel.I64SHR(dst, src0, src1, tmp);
} else
sel.SHR(dst, src0, src1);
break;
case OP_ASR:
if (type == TYPE_S64 || type == TYPE_U64) {
- GenRegister tmp[6];
+ GenRegister tmp[7];
for(int i = 0; i < 6; i ++)
tmp[i] = sel.selReg(sel.reg(FAMILY_DWORD));
+ tmp[6] = sel.selReg(sel.reg(FAMILY_BOOL));
sel.I64ASR(dst, src0, src1, tmp);
} else
sel.ASR(dst, src0, src1);
@@ -2451,11 +2454,12 @@ namespace gbe
} else if ((dstType == ir::TYPE_S32 || dstType == ir::TYPE_U32) && srcFamily == FAMILY_QWORD) {
sel.CONVI64_TO_I(dst, src);
} else if (dstType == ir::TYPE_FLOAT && srcFamily == FAMILY_QWORD) {
- GenRegister tmp[3];
+ GenRegister tmp[4];
for(int i=0; i<3; i++) {
tmp[i] = sel.selReg(sel.reg(FAMILY_DWORD));
tmp[i].type = GEN_TYPE_UD;
}
+ tmp[3] = sel.selReg(sel.reg(FAMILY_BOOL));
sel.CONVI64_TO_F(dst, src, tmp);
} else if (dst.isdf()) {
ir::Register r = sel.reg(ir::RegisterFamily::FAMILY_QWORD);
diff --git a/backend/src/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp
index 79b73e2..73e81de 100644
--- a/backend/src/backend/gen_insn_selection.hpp
+++ b/backend/src/backend/gen_insn_selection.hpp
@@ -115,7 +115,7 @@ namespace gbe
/*! Gen opcode */
uint8_t opcode;
/*! Number of destinations */
- uint8_t dstNum:3;
+ uint8_t dstNum:4;
/*! Number of sources */
uint8_t srcNum:5;
/*! To store various indices */
diff --git a/backend/src/backend/gen_register.hpp b/backend/src/backend/gen_register.hpp
index ea1bc06..63a9c36 100644
--- a/backend/src/backend/gen_register.hpp
+++ b/backend/src/backend/gen_register.hpp
@@ -158,6 +158,11 @@ namespace gbe
NOT_IMPLEMENTED;
}
}
+ void useFlag(int nr, int subnr) {
+ flag = nr;
+ subFlag = subnr;
+ physicalFlag = 1;
+ }
};
/*! This is a book-keeping structure used to encode both virtual and physical
@@ -286,6 +291,10 @@ namespace gbe
return false;
}
+ INLINE int flag_nr(void) const {
+ return nr & 15;
+ }
+
static INLINE GenRegister h2(GenRegister reg) {
GenRegister r = reg;
r.hstride = GEN_HORIZONTAL_STRIDE_2;
--
1.8.1.2
More information about the Beignet
mailing list