| OLD | NEW | 
|---|
| 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// | 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// | 
| 2 // | 2 // | 
| 3 //                        The Subzero Code Generator | 3 //                        The Subzero Code Generator | 
| 4 // | 4 // | 
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source | 
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. | 
| 7 // | 7 // | 
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// | 
| 9 /// | 9 /// | 
| 10 /// \file | 10 /// \file | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 27 #include "IcePhiLoweringImpl.h" | 27 #include "IcePhiLoweringImpl.h" | 
| 28 #include "IceRegistersARM32.h" | 28 #include "IceRegistersARM32.h" | 
| 29 #include "IceTargetLoweringARM32.def" | 29 #include "IceTargetLoweringARM32.def" | 
| 30 #include "IceUtils.h" | 30 #include "IceUtils.h" | 
| 31 #include "llvm/Support/MathExtras.h" | 31 #include "llvm/Support/MathExtras.h" | 
| 32 | 32 | 
| 33 namespace Ice { | 33 namespace Ice { | 
| 34 | 34 | 
| 35 namespace { | 35 namespace { | 
| 36 | 36 | 
| 37 void UnimplementedError(const ClFlags &Flags) { | 37 // UnimplementedError is defined as a macro so that we can get actual line | 
| 38   if (!Flags.getSkipUnimplemented()) { | 38 // numbers. | 
| 39     // Use llvm_unreachable instead of report_fatal_error, which gives better | 39 #define UnimplementedError(Flags)                                              \ | 
| 40     // stack traces. | 40   do {                                                                         \ | 
| 41     llvm_unreachable("Not yet implemented"); | 41     if (!static_cast<const ClFlags &>(Flags).getSkipUnimplemented()) {         \ | 
| 42     abort(); | 42       /* Use llvm_unreachable instead of report_fatal_error, which gives       \ | 
| 43   } | 43          better stack traces. */                                               \ | 
| 44 } | 44       llvm_unreachable("Not yet implemented");                                 \ | 
|  | 45       abort();                                                                 \ | 
|  | 46     }                                                                          \ | 
|  | 47   } while (0) | 
| 45 | 48 | 
| 46 // The following table summarizes the logic for lowering the icmp instruction | 49 // The following table summarizes the logic for lowering the icmp instruction | 
| 47 // for i32 and narrower types.  Each icmp condition has a clear mapping to an | 50 // for i32 and narrower types.  Each icmp condition has a clear mapping to an | 
| 48 // ARM32 conditional move instruction. | 51 // ARM32 conditional move instruction. | 
| 49 | 52 | 
| 50 const struct TableIcmp32_ { | 53 const struct TableIcmp32_ { | 
| 51   CondARM32::Cond Mapping; | 54   CondARM32::Cond Mapping; | 
| 52 } TableIcmp32[] = { | 55 } TableIcmp32[] = { | 
| 53 #define X(val, is_signed, swapped64, C_32, C1_64, C2_64)                       \ | 56 #define X(val, is_signed, swapped64, C_32, C1_64, C2_64)                       \ | 
| 54   { CondARM32::C_32 }                                                          \ | 57   { CondARM32::C_32 }                                                          \ | 
| (...skipping 2013 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2068       // t1 = trunc Src0RF; Dest = t1 | 2071       // t1 = trunc Src0RF; Dest = t1 | 
| 2069       Variable *T = makeReg(Dest->getType()); | 2072       Variable *T = makeReg(Dest->getType()); | 
| 2070       _mov(T, Src0RF); | 2073       _mov(T, Src0RF); | 
| 2071       if (Dest->getType() == IceType_i1) | 2074       if (Dest->getType() == IceType_i1) | 
| 2072         _and(T, T, Ctx->getConstantInt1(1)); | 2075         _and(T, T, Ctx->getConstantInt1(1)); | 
| 2073       _mov(Dest, T); | 2076       _mov(Dest, T); | 
| 2074     } | 2077     } | 
| 2075     break; | 2078     break; | 
| 2076   } | 2079   } | 
| 2077   case InstCast::Fptrunc: | 2080   case InstCast::Fptrunc: | 
| 2078     UnimplementedError(Func->getContext()->getFlags()); |  | 
| 2079     break; |  | 
| 2080   case InstCast::Fpext: { | 2081   case InstCast::Fpext: { | 
| 2081     UnimplementedError(Func->getContext()->getFlags()); | 2082     // fptrunc: dest.f32 = fptrunc src0.fp64 | 
|  | 2083     // fpext: dest.f64 = fptrunc src0.fp32 | 
|  | 2084     const bool IsTrunc = CastKind == InstCast::Fptrunc; | 
|  | 2085     if (isVectorType(Dest->getType())) { | 
|  | 2086       UnimplementedError(Func->getContext()->getFlags()); | 
|  | 2087       break; | 
|  | 2088     } | 
|  | 2089     assert(Dest->getType() == (IsTrunc ? IceType_f32 : IceType_f64)); | 
|  | 2090     assert(Src0->getType() == (IsTrunc ? IceType_f64 : IceType_f32)); | 
|  | 2091     Variable *Src0R = legalizeToReg(Src0); | 
|  | 2092     Variable *T = makeReg(Dest->getType()); | 
|  | 2093     _vcvt(T, Src0R, IsTrunc ? InstARM32Vcvt::D2s : InstARM32Vcvt::S2d); | 
|  | 2094     _mov(Dest, T); | 
| 2082     break; | 2095     break; | 
| 2083   } | 2096   } | 
| 2084   case InstCast::Fptosi: | 2097   case InstCast::Fptosi: | 
| 2085     UnimplementedError(Func->getContext()->getFlags()); | 2098   case InstCast::Fptoui: { | 
| 2086     // Add a fake def to keep liveness consistent in the meantime. | 2099     // fptosi: | 
| 2087     Context.insert(InstFakeDef::create(Func, Dest)); | 2100     //     t1.fp = vcvt src0.fp | 
|  | 2101     //     t2.i32 = vmov t1.fp | 
|  | 2102     //     dest.int = conv t2.i32     @ Truncates the result if needed. | 
|  | 2103     // fptoui: | 
|  | 2104     //     t1.fp = vcvt src0.fp | 
|  | 2105     //     t2.u32 = vmov t1.fp | 
|  | 2106     //     dest.uint = conv t2.u32    @ Truncates the result if needed. | 
|  | 2107     if (isVectorType(Dest->getType())) { | 
|  | 2108       UnimplementedError(Func->getContext()->getFlags()); | 
|  | 2109       break; | 
|  | 2110     } else if (Dest->getType() == IceType_i64) { | 
|  | 2111       UnimplementedError(Func->getContext()->getFlags()); | 
|  | 2112       break; | 
|  | 2113     } | 
|  | 2114     const bool DestIsSigned = CastKind == InstCast::Fptosi; | 
|  | 2115     Variable *Src0R = legalizeToReg(Src0); | 
|  | 2116     Variable *T_fp = makeReg(IceType_f32); | 
|  | 2117     if (isFloat32Asserting32Or64(Src0->getType())) { | 
|  | 2118       _vcvt(T_fp, Src0R, | 
|  | 2119             DestIsSigned ? InstARM32Vcvt::S2si : InstARM32Vcvt::S2ui); | 
|  | 2120     } else { | 
|  | 2121       _vcvt(T_fp, Src0R, | 
|  | 2122             DestIsSigned ? InstARM32Vcvt::D2si : InstARM32Vcvt::D2ui); | 
|  | 2123     } | 
|  | 2124     Variable *T = makeReg(IceType_i32); | 
|  | 2125     _vmov(T, T_fp); | 
|  | 2126     if (Dest->getType() != IceType_i32) { | 
|  | 2127       Variable *T_1 = makeReg(Dest->getType()); | 
|  | 2128       lowerCast(InstCast::create(Func, InstCast::Trunc, T_1, T)); | 
|  | 2129       T = T_1; | 
|  | 2130     } | 
|  | 2131     _mov(Dest, T); | 
| 2088     break; | 2132     break; | 
| 2089   case InstCast::Fptoui: | 2133   } | 
| 2090     UnimplementedError(Func->getContext()->getFlags()); |  | 
| 2091     break; |  | 
| 2092   case InstCast::Sitofp: | 2134   case InstCast::Sitofp: | 
| 2093     UnimplementedError(Func->getContext()->getFlags()); |  | 
| 2094     break; |  | 
| 2095   case InstCast::Uitofp: { | 2135   case InstCast::Uitofp: { | 
| 2096     UnimplementedError(Func->getContext()->getFlags()); | 2136     // sitofp: | 
|  | 2137     //     t1.i32 = sext src.int    @ sign-extends src0 if needed. | 
|  | 2138     //     t2.fp32 = vmov t1.i32 | 
|  | 2139     //     t3.fp = vcvt.{fp}.s32    @ fp is either f32 or f64 | 
|  | 2140     // uitofp: | 
|  | 2141     //     t1.i32 = zext src.int    @ zero-extends src0 if needed. | 
|  | 2142     //     t2.fp32 = vmov t1.i32 | 
|  | 2143     //     t3.fp = vcvt.{fp}.s32    @ fp is either f32 or f64 | 
|  | 2144     if (isVectorType(Dest->getType())) { | 
|  | 2145       UnimplementedError(Func->getContext()->getFlags()); | 
|  | 2146       break; | 
|  | 2147     } else if (Src0->getType() == IceType_i64) { | 
|  | 2148       UnimplementedError(Func->getContext()->getFlags()); | 
|  | 2149       break; | 
|  | 2150     } | 
|  | 2151     const bool SourceIsSigned = CastKind == InstCast::Sitofp; | 
|  | 2152     if (Src0->getType() != IceType_i32) { | 
|  | 2153       Variable *Src0R_32 = makeReg(IceType_i32); | 
|  | 2154       lowerCast(InstCast::create(Func, SourceIsSigned ? InstCast::Sext | 
|  | 2155                                                       : InstCast::Zext, | 
|  | 2156                                  Src0R_32, Src0)); | 
|  | 2157       Src0 = Src0R_32; | 
|  | 2158     } | 
|  | 2159     Variable *Src0R = legalizeToReg(Src0); | 
|  | 2160     Variable *Src0R_f32 = makeReg(IceType_f32); | 
|  | 2161     _vmov(Src0R_f32, Src0R); | 
|  | 2162     Src0R = Src0R_f32; | 
|  | 2163     Variable *T = makeReg(Dest->getType()); | 
|  | 2164     if (isFloat32Asserting32Or64(Dest->getType())) { | 
|  | 2165       _vcvt(T, Src0R, | 
|  | 2166             SourceIsSigned ? InstARM32Vcvt::Si2s : InstARM32Vcvt::Ui2s); | 
|  | 2167     } else { | 
|  | 2168       _vcvt(T, Src0R, | 
|  | 2169             SourceIsSigned ? InstARM32Vcvt::Si2d : InstARM32Vcvt::Ui2d); | 
|  | 2170     } | 
|  | 2171     _mov(Dest, T); | 
| 2097     break; | 2172     break; | 
| 2098   } | 2173   } | 
| 2099   case InstCast::Bitcast: { | 2174   case InstCast::Bitcast: { | 
| 2100     Operand *Src0 = Inst->getSrc(0); | 2175     Operand *Src0 = Inst->getSrc(0); | 
| 2101     if (Dest->getType() == Src0->getType()) { | 2176     if (Dest->getType() == Src0->getType()) { | 
| 2102       InstAssign *Assign = InstAssign::create(Func, Dest, Src0); | 2177       InstAssign *Assign = InstAssign::create(Func, Dest, Src0); | 
| 2103       lowerAssign(Assign); | 2178       lowerAssign(Assign); | 
| 2104       return; | 2179       return; | 
| 2105     } | 2180     } | 
| 2106     UnimplementedError(Func->getContext()->getFlags()); | 2181     UnimplementedError(Func->getContext()->getFlags()); | 
| (...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3054       << ".eabi_attribute 68, 1   @ Tag_Virtualization_use\n"; | 3129       << ".eabi_attribute 68, 1   @ Tag_Virtualization_use\n"; | 
| 3055   if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { | 3130   if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { | 
| 3056     Str << ".eabi_attribute 44, 2   @ Tag_DIV_use\n"; | 3131     Str << ".eabi_attribute 44, 2   @ Tag_DIV_use\n"; | 
| 3057   } | 3132   } | 
| 3058   // Technically R9 is used for TLS with Sandboxing, and we reserve it. | 3133   // Technically R9 is used for TLS with Sandboxing, and we reserve it. | 
| 3059   // However, for compatibility with current NaCl LLVM, don't claim that. | 3134   // However, for compatibility with current NaCl LLVM, don't claim that. | 
| 3060   Str << ".eabi_attribute 14, 3   @ Tag_ABI_PCS_R9_use: Not used\n"; | 3135   Str << ".eabi_attribute 14, 3   @ Tag_ABI_PCS_R9_use: Not used\n"; | 
| 3061 } | 3136 } | 
| 3062 | 3137 | 
| 3063 } // end of namespace Ice | 3138 } // end of namespace Ice | 
| OLD | NEW | 
|---|