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, ...@@ -3499,34 +3499,19 @@ void AssemblerARM32::vshlqc(Type ElmtTy, const Operand *OpQd,
encodeSIMDShiftImm6(ST_Vshl, ElmtTy, Imm6), Vshl); encodeSIMDShiftImm6(ST_Vshl, ElmtTy, Imm6), Vshl);
} }
void AssemblerARM32::vshrqic(Type ElmtTy, const Operand *OpQd, void AssemblerARM32::vshrqc(Type ElmtTy, const Operand *OpQd,
const Operand *OpQm, const Operand *OpQm, const ConstantInteger32 *Imm6,
const ConstantInteger32 *Imm6) { InstARM32::FPSign Sign) {
// VSHR - ARM section A8.8.398, encoding A1: // VSHR - ARM section A8.8.398, encoding A1:
// vshr Qd, Qm, #Imm // vshr Qd, Qm, #Imm
// //
// 1111001U1Diiiiiidddd0101LQM1mmmm where Ddddd=Qd, Mmmmm=Qm, iiiiii=Imm6, // 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;
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.
assert(isScalarIntegerType(ElmtTy) && assert(isScalarIntegerType(ElmtTy) &&
"vshr expects vector with integer element type"); "vshr expects vector with integer element type");
constexpr const char *Vshr = "vshr"; 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, emitSIMDShiftqqc(VshrOpcode, OpQd, OpQm,
encodeSIMDShiftImm6(ST_Vshr, ElmtTy, Imm6), Vshr); encodeSIMDShiftImm6(ST_Vshr, ElmtTy, Imm6), Vshr);
} }
......
...@@ -549,11 +549,8 @@ public: ...@@ -549,11 +549,8 @@ public:
void vshlqc(Type ElmtTy, const Operand *OpQd, const Operand *OpQm, void vshlqc(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
const ConstantInteger32 *OpQn); const ConstantInteger32 *OpQn);
void vshrqic(Type ElmtTy, const Operand *OpQd, const Operand *OpQm, void vshrqc(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
const ConstantInteger32 *OpQn); const ConstantInteger32 *OpQn, InstARM32::FPSign Sign);
void vshrquc(Type ElmtTy, const Operand *OpQd, const Operand *OpQm,
const ConstantInteger32 *OpQn);
void vsqrtd(const Operand *OpDd, const Operand *OpDm, CondARM32::Cond Cond); void vsqrtd(const Operand *OpDd, const Operand *OpDm, CondARM32::Cond Cond);
......
...@@ -999,15 +999,13 @@ template <> void InstARM32Vshr::emitIAS(const Cfg *Func) const { ...@@ -999,15 +999,13 @@ template <> void InstARM32Vshr::emitIAS(const Cfg *Func) const {
case IceType_v4i32: { case IceType_v4i32: {
const Type ElmtTy = typeElementType(DestTy); const Type ElmtTy = typeElementType(DestTy);
const auto *Imm6 = llvm::cast<ConstantInteger32>(getSrc(1)); const auto *Imm6 = llvm::cast<ConstantInteger32>(getSrc(1));
assert(Sign != InstARM32::FS_None);
switch (Sign) { 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: case InstARM32::FS_Signed:
Asm->vshrqic(ElmtTy, Dest, getSrc(0), Imm6); case InstARM32::FS_Unsigned:
Asm->vshrqc(ElmtTy, Dest, getSrc(0), Imm6, Sign);
break; break;
default:
assert(false && "Vshr requires signedness specification.");
} }
} break; } break;
} }
......
...@@ -2442,6 +2442,8 @@ public: ...@@ -2442,6 +2442,8 @@ public:
return legalizeToReg(Target, Swapped ? Src0 : Src1); return legalizeToReg(Target, Swapped ? Src0 : Src1);
} }
Operand *src1() const { return Src1; }
protected: protected:
Operand *const Src0; Operand *const Src0;
Operand *const Src1; Operand *const Src1;
...@@ -3436,8 +3438,13 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) { ...@@ -3436,8 +3438,13 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
_lsl(T, Src0R, Src1R); _lsl(T, Src0R, Src1R);
} }
} else { } else {
auto *Src1R = Srcs.unswappedSrc1R(this); if (Srcs.hasConstOperand()) {
_vshl(T, Src0R, Src1R)->setSignType(InstARM32::FS_Unsigned); 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); _mov(Dest, T);
return; return;
...@@ -3455,10 +3462,15 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) { ...@@ -3455,10 +3462,15 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
_lsr(T, Src0R, Src1R); _lsr(T, Src0R, Src1R);
} }
} else { } else {
auto *Src1R = Srcs.unswappedSrc1R(this); if (Srcs.hasConstOperand()) {
auto *Src1RNeg = makeReg(Src1R->getType()); ConstantInteger32 *ShAmt = llvm::cast<ConstantInteger32>(Srcs.src1());
_vneg(Src1RNeg, Src1R); _vshr(T, Src0R, ShAmt)->setSignType(InstARM32::FS_Unsigned);
_vshl(T, Src0R, Src1RNeg)->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); _mov(Dest, T);
return; return;
...@@ -3475,10 +3487,15 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) { ...@@ -3475,10 +3487,15 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
_asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this)); _asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this));
} }
} else { } else {
auto *Src1R = Srcs.unswappedSrc1R(this); if (Srcs.hasConstOperand()) {
auto *Src1RNeg = makeReg(Src1R->getType()); ConstantInteger32 *ShAmt = llvm::cast<ConstantInteger32>(Srcs.src1());
_vneg(Src1RNeg, Src1R); _vshr(T, Src0R, ShAmt)->setSignType(InstARM32::FS_Signed);
_vshl(T, Src0R, Src1RNeg)->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); _mov(Dest, T);
return; return;
...@@ -5251,7 +5268,6 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -5251,7 +5268,6 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return; return;
} }
case Intrinsics::Fabs: { case Intrinsics::Fabs: {
Type DestTy = Dest->getType();
Variable *T = makeReg(DestTy); Variable *T = makeReg(DestTy);
_vabs(T, legalizeToReg(Instr->getArg(0))); _vabs(T, legalizeToReg(Instr->getArg(0)));
_mov(Dest, T); _mov(Dest, T);
...@@ -5286,7 +5302,7 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -5286,7 +5302,7 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
assert(isScalarFloatingType(Dest->getType()) || assert(isScalarFloatingType(Dest->getType()) ||
getFlags().getApplicationBinaryInterface() != ::Ice::ABI_PNaCl); getFlags().getApplicationBinaryInterface() != ::Ice::ABI_PNaCl);
Variable *Src = legalizeToReg(Instr->getArg(0)); Variable *Src = legalizeToReg(Instr->getArg(0));
Variable *T = makeReg(Dest->getType()); Variable *T = makeReg(DestTy);
_vsqrt(T, Src); _vsqrt(T, Src);
_mov(Dest, T); _mov(Dest, T);
return; return;
......
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
X(v8i16, 1, 1, 0, 1, 0, 1, v8i1) \ X(v8i16, 1, 1, 0, 1, 0, 1, v8i1) \
X(v4i32, 1, 1, 0, 1, 0, 1, v4i1) \ X(v4i32, 1, 1, 0, 1, 0, 1, v4i1) \
X(v4f32, 1, 0, 1, 0, 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) // CompareResult)
#endif // SUBZERO_SRC_ICETYPES_DEF #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