Commit 8d90a34e by Nicolas Capens Committed by Nicolas Capens

Support vector shift by constant for ARM32.

This also fixes the encoding of right shifts with unsigned elements. Bug b/37496338 Change-Id: I9a1dc91359daea5f4391a137b7f9e03bd941146b Reviewed-on: https://chromium-review.googlesource.com/688057Reviewed-by: 's avatarJim Stichnoth <stichnot@chromium.org> Reviewed-on: https://swiftshader-review.googlesource.com/12668Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 48a3fc74
......@@ -3499,34 +3499,19 @@ void AssemblerARM32::vshlqc(Type ElmtTy, const Operand *OpQd,
encodeSIMDShiftImm6(ST_Vshl, ElmtTy, Imm6), Vshl);
}
void AssemblerARM32::vshrqic(Type ElmtTy, const Operand *OpQd,
const Operand *OpQm,
const ConstantInteger32 *Imm6) {
void AssemblerARM32::vshrqc(Type ElmtTy, const Operand *OpQd,
const Operand *OpQm, const ConstantInteger32 *Imm6,
InstARM32::FPSign Sign) {
// VSHR - ARM section A8.8.398, encoding A1:
// vshr Qd, Qm, #Imm
//
// 1111001U1Diiiiiidddd0101LQM1mmmm where Ddddd=Qd, Mmmmm=Qm, iiiiii=Imm6,
// 0=U, 1=Q, 0=L.
assert(isScalarIntegerType(ElmtTy) &&
"vshr expects vector with integer element type");
constexpr const char *Vshr = "vshr";
constexpr IValueT VshrOpcode = B23 | B4;
emitSIMDShiftqqc(VshrOpcode, OpQd, OpQm,
encodeSIMDShiftImm6(ST_Vshr, ElmtTy, Imm6), Vshr);
}
void AssemblerARM32::vshrquc(Type ElmtTy, const Operand *OpQd,
const Operand *OpQm,
const ConstantInteger32 *Imm6) {
// VSHR - ARM section A8.8.398, encoding A1:
// vshr Qd, Qm, #Imm
//
// 1111001U1Diiiiiidddd0101LQM1mmmm where Ddddd=Qd, Mmmmm=Qm, iiiiii=Imm6,
// 0=U, 1=Q, 0=L.
// U=Unsigned, Q=1, L=0.
assert(isScalarIntegerType(ElmtTy) &&
"vshr expects vector with integer element type");
constexpr const char *Vshr = "vshr";
constexpr IValueT VshrOpcode = B23 | B4;
const IValueT VshrOpcode =
(Sign == InstARM32::FS_Unsigned ? B24 : 0) | B23 | B4;
emitSIMDShiftqqc(VshrOpcode, OpQd, OpQm,
encodeSIMDShiftImm6(ST_Vshr, ElmtTy, Imm6), Vshr);
}
......
......@@ -549,11 +549,8 @@ public:
void vshlqc(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
const ConstantInteger32 *OpQn);
void vshrqic(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
const ConstantInteger32 *OpQn);
void vshrquc(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
const ConstantInteger32 *OpQn);
void vshrqc(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
const ConstantInteger32 *OpQn, InstARM32::FPSign Sign);
void vsqrtd(const Operand *OpDd, const Operand *OpDm, CondARM32::Cond Cond);
......
......@@ -999,15 +999,13 @@ template <> void InstARM32Vshr::emitIAS(const Cfg *Func) const {
case IceType_v4i32: {
const Type ElmtTy = typeElementType(DestTy);
const auto *Imm6 = llvm::cast<ConstantInteger32>(getSrc(1));
assert(Sign != InstARM32::FS_None);
switch (Sign) {
case InstARM32::FS_None: // defaults to unsigned.
case InstARM32::FS_Unsigned:
Asm->vshrquc(ElmtTy, Dest, getSrc(0), Imm6);
break;
case InstARM32::FS_Signed:
Asm->vshrqic(ElmtTy, Dest, getSrc(0), Imm6);
case InstARM32::FS_Unsigned:
Asm->vshrqc(ElmtTy, Dest, getSrc(0), Imm6, Sign);
break;
default:
assert(false && "Vshr requires signedness specification.");
}
} break;
}
......
......@@ -2442,6 +2442,8 @@ public:
return legalizeToReg(Target, Swapped ? Src0 : Src1);
}
Operand *src1() const { return Src1; }
protected:
Operand *const Src0;
Operand *const Src1;
......@@ -3436,8 +3438,13 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
_lsl(T, Src0R, Src1R);
}
} else {
auto *Src1R = Srcs.unswappedSrc1R(this);
_vshl(T, Src0R, Src1R)->setSignType(InstARM32::FS_Unsigned);
if (Srcs.hasConstOperand()) {
ConstantInteger32 *ShAmt = llvm::cast<ConstantInteger32>(Srcs.src1());
_vshl(T, Src0R, ShAmt);
} else {
auto *Src1R = Srcs.unswappedSrc1R(this);
_vshl(T, Src0R, Src1R)->setSignType(InstARM32::FS_Unsigned);
}
}
_mov(Dest, T);
return;
......@@ -3455,10 +3462,15 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
_lsr(T, Src0R, Src1R);
}
} else {
auto *Src1R = Srcs.unswappedSrc1R(this);
auto *Src1RNeg = makeReg(Src1R->getType());
_vneg(Src1RNeg, Src1R);
_vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Unsigned);
if (Srcs.hasConstOperand()) {
ConstantInteger32 *ShAmt = llvm::cast<ConstantInteger32>(Srcs.src1());
_vshr(T, Src0R, ShAmt)->setSignType(InstARM32::FS_Unsigned);
} else {
auto *Src1R = Srcs.unswappedSrc1R(this);
auto *Src1RNeg = makeReg(Src1R->getType());
_vneg(Src1RNeg, Src1R);
_vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Unsigned);
}
}
_mov(Dest, T);
return;
......@@ -3475,10 +3487,15 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
_asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this));
}
} else {
auto *Src1R = Srcs.unswappedSrc1R(this);
auto *Src1RNeg = makeReg(Src1R->getType());
_vneg(Src1RNeg, Src1R);
_vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Signed);
if (Srcs.hasConstOperand()) {
ConstantInteger32 *ShAmt = llvm::cast<ConstantInteger32>(Srcs.src1());
_vshr(T, Src0R, ShAmt)->setSignType(InstARM32::FS_Signed);
} else {
auto *Src1R = Srcs.unswappedSrc1R(this);
auto *Src1RNeg = makeReg(Src1R->getType());
_vneg(Src1RNeg, Src1R);
_vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Signed);
}
}
_mov(Dest, T);
return;
......@@ -5251,7 +5268,6 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return;
}
case Intrinsics::Fabs: {
Type DestTy = Dest->getType();
Variable *T = makeReg(DestTy);
_vabs(T, legalizeToReg(Instr->getArg(0)));
_mov(Dest, T);
......@@ -5286,7 +5302,7 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
assert(isScalarFloatingType(Dest->getType()) ||
getFlags().getApplicationBinaryInterface() != ::Ice::ABI_PNaCl);
Variable *Src = legalizeToReg(Instr->getArg(0));
Variable *T = makeReg(Dest->getType());
Variable *T = makeReg(DestTy);
_vsqrt(T, Src);
_mov(Dest, T);
return;
......
......@@ -79,7 +79,7 @@
X(v8i16, 1, 1, 0, 1, 0, 1, v8i1) \
X(v4i32, 1, 1, 0, 1, 0, 1, v4i1) \
X(v4f32, 1, 0, 1, 0, 0, 1, v4i1) \
//#define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsBoolean, IsParam, \
//#define X(tag, IsVec, IsInt, IsFloat, IsIntArith, IsBoolean, IsParam,
// CompareResult)
#endif // SUBZERO_SRC_ICETYPES_DEF
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment