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

Unified Diff: src/IceTargetLoweringARM32.cpp

Issue 1330933002: Implements int2fp, fp2int, and fp2fp conversions for ARM32. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments. Created 5 years, 3 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
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | tests_lit/llvm2ice_tests/fp.convert.ll » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceTargetLoweringARM32.cpp
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
index 167e37c2dc1e0af621fd215b6902a40f5a759f8f..3e92637123220274a9f35c7207861d874bce6a4f 100644
--- a/src/IceTargetLoweringARM32.cpp
+++ b/src/IceTargetLoweringARM32.cpp
@@ -34,14 +34,17 @@ namespace Ice {
namespace {
-void UnimplementedError(const ClFlags &Flags) {
- if (!Flags.getSkipUnimplemented()) {
- // Use llvm_unreachable instead of report_fatal_error, which gives better
- // stack traces.
- llvm_unreachable("Not yet implemented");
- abort();
- }
-}
+// UnimplementedError is defined as a macro so that we can get actual line
+// numbers.
+#define UnimplementedError(Flags) \
+ do { \
+ if (!static_cast<const ClFlags &>(Flags).getSkipUnimplemented()) { \
+ /* Use llvm_unreachable instead of report_fatal_error, which gives \
+ better stack traces. */ \
+ llvm_unreachable("Not yet implemented"); \
+ abort(); \
+ } \
+ } while (0)
// The following table summarizes the logic for lowering the icmp instruction
// for i32 and narrower types. Each icmp condition has a clear mapping to an
@@ -2075,25 +2078,97 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
break;
}
case InstCast::Fptrunc:
- UnimplementedError(Func->getContext()->getFlags());
- break;
case InstCast::Fpext: {
- UnimplementedError(Func->getContext()->getFlags());
+ // fptrunc: dest.f32 = fptrunc src0.fp64
+ // fpext: dest.f64 = fptrunc src0.fp32
+ const bool IsTrunc = CastKind == InstCast::Fptrunc;
+ if (isVectorType(Dest->getType())) {
+ UnimplementedError(Func->getContext()->getFlags());
+ break;
+ }
+ assert(Dest->getType() == (IsTrunc ? IceType_f32 : IceType_f64));
+ assert(Src0->getType() == (IsTrunc ? IceType_f64 : IceType_f32));
+ Variable *Src0R = legalizeToReg(Src0);
+ Variable *T = makeReg(Dest->getType());
+ _vcvt(T, Src0R, IsTrunc ? InstARM32Vcvt::D2s : InstARM32Vcvt::S2d);
+ _mov(Dest, T);
break;
}
case InstCast::Fptosi:
- UnimplementedError(Func->getContext()->getFlags());
- // Add a fake def to keep liveness consistent in the meantime.
- Context.insert(InstFakeDef::create(Func, Dest));
- break;
- case InstCast::Fptoui:
- UnimplementedError(Func->getContext()->getFlags());
+ case InstCast::Fptoui: {
+ // fptosi:
+ // t1.fp = vcvt src0.fp
+ // t2.i32 = vmov t1.fp
+ // dest.int = conv t2.i32 @ Truncates the result if needed.
+ // fptoui:
+ // t1.fp = vcvt src0.fp
+ // t2.u32 = vmov t1.fp
+ // dest.uint = conv t2.u32 @ Truncates the result if needed.
+ if (isVectorType(Dest->getType())) {
+ UnimplementedError(Func->getContext()->getFlags());
+ break;
+ } else if (Dest->getType() == IceType_i64) {
+ UnimplementedError(Func->getContext()->getFlags());
+ break;
+ }
+ const bool DestIsSigned = CastKind == InstCast::Fptosi;
+ Variable *Src0R = legalizeToReg(Src0);
+ Variable *T_fp = makeReg(IceType_f32);
+ if (isFloat32Asserting32Or64(Src0->getType())) {
+ _vcvt(T_fp, Src0R,
+ DestIsSigned ? InstARM32Vcvt::S2si : InstARM32Vcvt::S2ui);
+ } else {
+ _vcvt(T_fp, Src0R,
+ DestIsSigned ? InstARM32Vcvt::D2si : InstARM32Vcvt::D2ui);
+ }
+ Variable *T = makeReg(IceType_i32);
+ _vmov(T, T_fp);
+ if (Dest->getType() != IceType_i32) {
+ Variable *T_1 = makeReg(Dest->getType());
+ lowerCast(InstCast::create(Func, InstCast::Trunc, T_1, T));
+ T = T_1;
+ }
+ _mov(Dest, T);
break;
+ }
case InstCast::Sitofp:
- UnimplementedError(Func->getContext()->getFlags());
- break;
case InstCast::Uitofp: {
- UnimplementedError(Func->getContext()->getFlags());
+ // sitofp:
+ // t1.i32 = sext src.int @ sign-extends src0 if needed.
+ // t2.fp32 = vmov t1.i32
+ // t3.fp = vcvt.{fp}.s32 @ fp is either f32 or f64
+ // uitofp:
+ // t1.i32 = zext src.int @ zero-extends src0 if needed.
+ // t2.fp32 = vmov t1.i32
+ // t3.fp = vcvt.{fp}.s32 @ fp is either f32 or f64
+ if (isVectorType(Dest->getType())) {
+ UnimplementedError(Func->getContext()->getFlags());
+ break;
+ } else if (Src0->getType() == IceType_i64) {
+ UnimplementedError(Func->getContext()->getFlags());
+ break;
+ }
+ const bool SourceIsSigned = CastKind == InstCast::Sitofp;
+ if (Src0->getType() != IceType_i32) {
+ Variable *Src0R_32 = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, SourceIsSigned ? InstCast::Sext
+ : InstCast::Zext,
+ Src0R_32, Src0));
+ Src0 = Src0R_32;
+ }
+ Variable *Src0R = legalizeToReg(Src0);
+ Variable *Src0R_f32 = makeReg(IceType_f32);
+ _vmov(Src0R_f32, Src0R);
+ Src0R = Src0R_f32;
+ Variable *T = makeReg(Dest->getType());
+ if (isFloat32Asserting32Or64(Dest->getType())) {
+ _vcvt(T, Src0R,
+ SourceIsSigned ? InstARM32Vcvt::Si2s : InstARM32Vcvt::Ui2s);
+ } else {
+ _vcvt(T, Src0R,
+ SourceIsSigned ? InstARM32Vcvt::Si2d : InstARM32Vcvt::Ui2d);
+ }
+ _mov(Dest, T);
break;
}
case InstCast::Bitcast: {
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | tests_lit/llvm2ice_tests/fp.convert.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698