Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Unified Diff: src/IceTargetLoweringARM32.cpp

Issue 1878943009: Subzero. ARM32. Vector casts. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Adds vcvt assembler lit tests. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceTargetLoweringARM32.cpp
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
index 7a7ed29ab6bd5f62a66a1421681274ad1c78c3f3..b8fa3b684715cff7f043c50973ab870d982c7d75 100644
--- a/src/IceTargetLoweringARM32.cpp
+++ b/src/IceTargetLoweringARM32.cpp
@@ -599,17 +599,6 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
auto *CastInstr = llvm::cast<InstCast>(Instr);
const InstCast::OpKind CastKind = CastInstr->getCastKind();
- if (isVectorType(DestTy) && CastKind != InstCast::Bitcast) {
- // Bitcasting is done with function calls (e.g., v8i1 -> i8), or regular
- // vmov (e.g., v4i32 -> v4f32)
- scalarizeInstruction(
- Dest, [this, CastKind](Variable *Dest, Variable *Src) {
- return Context.insert<InstCast>(CastKind, Dest, Src);
- }, Src0);
- CastInstr->setDeleted();
- return;
- }
-
switch (CastKind) {
default:
return;
@@ -698,6 +687,31 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
Instr->setDeleted();
return;
}
+ case InstCast::Trunc: {
+ if (DestTy == SrcTy) {
+ return;
+ }
+ if (!isVectorType(SrcTy)) {
+ return;
+ }
+ assert(typeNumElements(DestTy) == typeNumElements(SrcTy));
+ assert(typeElementType(DestTy) == IceType_i1);
+ assert(isVectorIntegerType(SrcTy));
+ return;
+ }
+ case InstCast::Sext:
+ case InstCast::Zext: {
+ if (DestTy == SrcTy) {
+ return;
+ }
+ if (!isVectorType(DestTy)) {
+ return;
+ }
+ assert(typeNumElements(DestTy) == typeNumElements(SrcTy));
+ assert(typeElementType(SrcTy) == IceType_i1);
+ assert(isVectorIntegerType(DestTy));
+ return;
+ }
}
llvm::report_fatal_error("Control flow should never have reached here.");
}
@@ -3887,15 +3901,35 @@ void configureBitcastTemporary(Variable64On32 *Var) {
void TargetARM32::lowerCast(const InstCast *Instr) {
InstCast::OpKind CastKind = Instr->getCastKind();
Variable *Dest = Instr->getDest();
+ const Type DestTy = Dest->getType();
Operand *Src0 = legalizeUndef(Instr->getSrc(0));
switch (CastKind) {
default:
Func->setError("Cast type not supported");
return;
case InstCast::Sext: {
- if (isVectorType(Dest->getType())) {
- UnimplementedLoweringError(this, Instr);
- } else if (Dest->getType() == IceType_i64) {
+ if (isVectorType(DestTy)) {
+ Variable *T0 = makeReg(DestTy);
+ Variable *T1 = makeReg(DestTy);
+ ConstantInteger32 *ShAmt = nullptr;
+ switch (DestTy) {
+ default:
+ llvm::report_fatal_error("Unexpected type in vector sext.");
+ case IceType_v16i8:
+ ShAmt = llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(7));
+ break;
+ case IceType_v8i16:
+ ShAmt = llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(15));
+ break;
+ case IceType_v4i32:
+ ShAmt = llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(31));
+ break;
+ }
+ auto *Src0R = legalizeToReg(Src0);
+ _vshl(T0, Src0R, ShAmt);
+ _vshr(T1, T0, ShAmt)->setSignType(InstARM32::FS_Signed);
+ _mov(Dest, T1);
+ } else if (DestTy == IceType_i64) {
// t1=sxtb src; t2= mov t1 asr #31; dst.lo=t1; dst.hi=t2
Constant *ShiftAmt = Ctx->getConstantInt32(31);
auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
@@ -3925,22 +3959,28 @@ void TargetARM32::lowerCast(const InstCast *Instr) {
} else if (Src0->getType() != IceType_i1) {
// t1 = sxt src; dst = t1
Variable *Src0R = legalizeToReg(Src0);
- Variable *T = makeReg(Dest->getType());
+ Variable *T = makeReg(DestTy);
_sxt(T, Src0R);
_mov(Dest, T);
} else {
Constant *_0 = Ctx->getConstantZero(IceType_i32);
- Operand *_m1 = Ctx->getConstantInt(Dest->getType(), -1);
- Variable *T = makeReg(Dest->getType());
+ Operand *_m1 = Ctx->getConstantInt(DestTy, -1);
+ Variable *T = makeReg(DestTy);
lowerInt1ForSelect(T, Src0, _m1, _0);
_mov(Dest, T);
}
break;
}
case InstCast::Zext: {
- if (isVectorType(Dest->getType())) {
- UnimplementedLoweringError(this, Instr);
- } else if (Dest->getType() == IceType_i64) {
+ if (isVectorType(DestTy)) {
+ auto *Mask = makeReg(DestTy);
+ auto *_1 = Ctx->getConstantInt32(1);
+ auto *T = makeReg(DestTy);
+ auto *Src0R = legalizeToReg(Src0);
+ _mov(Mask, _1);
+ _vand(T, Src0R, Mask);
+ _mov(Dest, T);
+ } else if (DestTy == IceType_i64) {
// t1=uxtb src; dst.lo=t1; dst.hi=0
Operand *_0 =
legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex);
@@ -3972,7 +4012,7 @@ void TargetARM32::lowerCast(const InstCast *Instr) {
_mov(T_Hi, _0);
_mov(DestHi, T_Hi);
} else if (Src0->getType() == IceType_i1) {
- Variable *T = makeReg(Dest->getType());
+ Variable *T = makeReg(DestTy);
SafeBoolChain Safe = lowerInt1(T, Src0);
if (Safe == SBC_No) {
@@ -3984,23 +4024,26 @@ void TargetARM32::lowerCast(const InstCast *Instr) {
} else {
// t1 = uxt src; dst = t1
Variable *Src0R = legalizeToReg(Src0);
- Variable *T = makeReg(Dest->getType());
+ Variable *T = makeReg(DestTy);
_uxt(T, Src0R);
_mov(Dest, T);
}
break;
}
case InstCast::Trunc: {
- if (isVectorType(Dest->getType())) {
- UnimplementedLoweringError(this, Instr);
+ if (isVectorType(DestTy)) {
+ auto *T = makeReg(DestTy);
+ auto *Src0R = legalizeToReg(Src0);
+ _mov(T, Src0R);
+ _mov(Dest, T);
} else {
if (Src0->getType() == IceType_i64)
Src0 = loOperand(Src0);
Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex);
// t1 = trunc Src0RF; Dest = t1
- Variable *T = makeReg(Dest->getType());
+ Variable *T = makeReg(DestTy);
_mov(T, Src0RF);
- if (Dest->getType() == IceType_i1)
+ if (DestTy == IceType_i1)
_and(T, T, Ctx->getConstantInt1(1));
_mov(Dest, T);
}
@@ -4011,26 +4054,29 @@ void TargetARM32::lowerCast(const InstCast *Instr) {
// fptrunc: dest.f32 = fptrunc src0.fp64
// fpext: dest.f64 = fptrunc src0.fp32
const bool IsTrunc = CastKind == InstCast::Fptrunc;
- if (isVectorType(Dest->getType())) {
- UnimplementedLoweringError(this, Instr);
- break;
- }
- assert(Dest->getType() == (IsTrunc ? IceType_f32 : IceType_f64));
+ assert(!isVectorType(DestTy));
+ assert(DestTy == (IsTrunc ? IceType_f32 : IceType_f64));
assert(Src0->getType() == (IsTrunc ? IceType_f64 : IceType_f32));
Variable *Src0R = legalizeToReg(Src0);
- Variable *T = makeReg(Dest->getType());
+ Variable *T = makeReg(DestTy);
_vcvt(T, Src0R, IsTrunc ? InstARM32Vcvt::D2s : InstARM32Vcvt::S2d);
_mov(Dest, T);
break;
}
case InstCast::Fptosi:
case InstCast::Fptoui: {
- if (isVectorType(Dest->getType())) {
- UnimplementedLoweringError(this, Instr);
+ const bool DestIsSigned = CastKind == InstCast::Fptosi;
+ Variable *Src0R = legalizeToReg(Src0);
+
+ if (isVectorType(DestTy)) {
+ assert(typeElementType(Src0->getType()) == IceType_f32);
+ auto *T = makeReg(DestTy);
+ _vcvt(T, Src0R,
+ DestIsSigned ? InstARM32Vcvt::Vs2si : InstARM32Vcvt::Vs2ui);
+ _mov(Dest, T);
break;
}
- const bool DestIsSigned = CastKind == InstCast::Fptosi;
const bool Src0IsF32 = isFloat32Asserting32Or64(Src0->getType());
if (llvm::isa<Variable64On32>(Dest)) {
llvm::report_fatal_error("fp-to-i64 should have been pre-lowered.");
@@ -4043,7 +4089,6 @@ void TargetARM32::lowerCast(const InstCast *Instr) {
// t1.fp = vcvt src0.fp
// t2.u32 = vmov t1.fp
// dest.uint = conv t2.u32 @ Truncates the result if needed.
- Variable *Src0R = legalizeToReg(Src0);
Variable *T_fp = makeReg(IceType_f32);
const InstARM32Vcvt::VcvtVariant Conversion =
Src0IsF32 ? (DestIsSigned ? InstARM32Vcvt::S2si : InstARM32Vcvt::S2ui)
@@ -4051,8 +4096,8 @@ void TargetARM32::lowerCast(const InstCast *Instr) {
_vcvt(T_fp, Src0R, Conversion);
Variable *T = makeReg(IceType_i32);
_mov(T, T_fp);
- if (Dest->getType() != IceType_i32) {
- Variable *T_1 = makeReg(Dest->getType());
+ if (DestTy != IceType_i32) {
+ Variable *T_1 = makeReg(DestTy);
lowerCast(InstCast::create(Func, InstCast::Trunc, T_1, T));
T = T_1;
}
@@ -4061,12 +4106,19 @@ void TargetARM32::lowerCast(const InstCast *Instr) {
}
case InstCast::Sitofp:
case InstCast::Uitofp: {
- if (isVectorType(Dest->getType())) {
- UnimplementedLoweringError(this, Instr);
+ const bool SourceIsSigned = CastKind == InstCast::Sitofp;
+
+ if (isVectorType(DestTy)) {
+ assert(typeElementType(DestTy) == IceType_f32);
+ auto *T = makeReg(DestTy);
+ Variable *Src0R = legalizeToReg(Src0);
+ _vcvt(T, Src0R,
+ SourceIsSigned ? InstARM32Vcvt::Vsi2s : InstARM32Vcvt::Vui2s);
+ _mov(Dest, T);
break;
}
- const bool SourceIsSigned = CastKind == InstCast::Sitofp;
- const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType());
+
+ const bool DestIsF32 = isFloat32Asserting32Or64(DestTy);
if (Src0->getType() == IceType_i64) {
llvm::report_fatal_error("i64-to-fp should have been pre-lowered.");
}
@@ -4089,7 +4141,7 @@ void TargetARM32::lowerCast(const InstCast *Instr) {
Variable *Src0R_f32 = makeReg(IceType_f32);
_mov(Src0R_f32, Src0R);
Src0R = Src0R_f32;
- Variable *T = makeReg(Dest->getType());
+ Variable *T = makeReg(DestTy);
const InstARM32Vcvt::VcvtVariant Conversion =
DestIsF32
? (SourceIsSigned ? InstARM32Vcvt::Si2s : InstARM32Vcvt::Ui2s)
@@ -4100,13 +4152,12 @@ void TargetARM32::lowerCast(const InstCast *Instr) {
}
case InstCast::Bitcast: {
Operand *Src0 = Instr->getSrc(0);
- if (Dest->getType() == Src0->getType()) {
+ if (DestTy == Src0->getType()) {
auto *Assign = InstAssign::create(Func, Dest, Src0);
lowerAssign(Assign);
return;
}
- Type DestType = Dest->getType();
- switch (DestType) {
+ switch (DestTy) {
case IceType_NUM:
case IceType_void:
llvm::report_fatal_error("Unexpected bitcast.");
@@ -4126,7 +4177,7 @@ void TargetARM32::lowerCast(const InstCast *Instr) {
case IceType_i32:
case IceType_f32: {
Variable *Src0R = legalizeToReg(Src0);
- Variable *T = makeReg(DestType);
+ Variable *T = makeReg(DestTy);
_mov(T, Src0R);
lowerAssign(InstAssign::create(Func, Dest, T));
break;
@@ -4152,7 +4203,7 @@ void TargetARM32::lowerCast(const InstCast *Instr) {
// vmov T2, T0, T1
// Dest <- T2
assert(Src0->getType() == IceType_i64);
- Variable *T = makeReg(DestType);
+ Variable *T = makeReg(DestTy);
auto *Src64 = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64));
Src64->initHiLo(Func);
configureBitcastTemporary(Src64);
@@ -4176,9 +4227,9 @@ void TargetARM32::lowerCast(const InstCast *Instr) {
case IceType_v16i8:
case IceType_v4f32:
case IceType_v4i32: {
- assert(typeWidthInBytes(DestType) == typeWidthInBytes(Src0->getType()));
- assert(isVectorType(DestType) == isVectorType(Src0->getType()));
- Variable *T = makeReg(DestType);
+ assert(typeWidthInBytes(DestTy) == typeWidthInBytes(Src0->getType()));
+ assert(isVectorType(DestTy) == isVectorType(Src0->getType()));
+ Variable *T = makeReg(DestTy);
_mov(T, Src0);
_mov(Dest, T);
break;

Powered by Google App Engine
This is Rietveld 408576698