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

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1356763004: Subzero. ARM32 Fcmp lowering. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: git pull && 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 unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringARM32.def » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 CondARM32::Cond getIcmp32Mapping(InstIcmp::ICond Cond) { 80 CondARM32::Cond getIcmp32Mapping(InstIcmp::ICond Cond) {
81 size_t Index = static_cast<size_t>(Cond); 81 size_t Index = static_cast<size_t>(Cond);
82 assert(Index < llvm::array_lengthof(TableIcmp32)); 82 assert(Index < llvm::array_lengthof(TableIcmp32));
83 return TableIcmp32[Index].Mapping; 83 return TableIcmp32[Index].Mapping;
84 } 84 }
85 85
86 // In some cases, there are x-macros tables for both high-level and low-level 86 // In some cases, there are x-macros tables for both high-level and low-level
87 // instructions/operands that use the same enum key value. The tables are kept 87 // instructions/operands that use the same enum key value. The tables are kept
88 // separate to maintain a proper separation between abstraction layers. There 88 // separate to maintain a proper separation between abstraction layers. There
89 // is a risk that the tables could get out of sync if enum values are reordered 89 // is a risk that the tables could get out of sync if enum values are reordered
90 // or if entries are added or deleted. The following dummy namespaces use 90 // or if entries are added or deleted. The following anonymous namespaces use
91 // static_asserts to ensure everything is kept in sync. 91 // static_asserts to ensure everything is kept in sync.
92 92
93 // Validate the enum values in ICMPARM32_TABLE. 93 // Validate the enum values in ICMPARM32_TABLE.
94 namespace dummy1 { 94 namespace {
95 // Define a temporary set of enum values based on low-level table entries. 95 // Define a temporary set of enum values based on low-level table entries.
96 enum _tmp_enum { 96 enum _icmp_ll_enum {
97 #define X(val, signed, swapped64, C_32, C1_64, C2_64) _tmp_##val, 97 #define X(val, signed, swapped64, C_32, C1_64, C2_64) _icmp_ll_##val,
98 ICMPARM32_TABLE 98 ICMPARM32_TABLE
99 #undef X 99 #undef X
100 _num 100 _num
101 }; 101 };
102 // Define a set of constants based on high-level table entries. 102 // Define a set of constants based on high-level table entries.
103 #define X(tag, str) static const int _table1_##tag = InstIcmp::tag; 103 #define X(tag, str) static constexpr int _icmp_hl_##tag = InstIcmp::tag;
104 ICEINSTICMP_TABLE 104 ICEINSTICMP_TABLE
105 #undef X 105 #undef X
106 // Define a set of constants based on low-level table entries, and ensure the 106 // Define a set of constants based on low-level table entries, and ensure the
107 // table entry keys are consistent. 107 // table entry keys are consistent.
108 #define X(val, signed, swapped64, C_32, C1_64, C2_64) \ 108 #define X(val, signed, swapped64, C_32, C1_64, C2_64) \
109 static const int _table2_##val = _tmp_##val; \
110 static_assert( \ 109 static_assert( \
111 _table1_##val == _table2_##val, \ 110 _icmp_ll_##val == _icmp_hl_##val, \
112 "Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE"); 111 "Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE: " #val);
113 ICMPARM32_TABLE 112 ICMPARM32_TABLE
114 #undef X 113 #undef X
115 // Repeat the static asserts with respect to the high-level table entries in 114 // Repeat the static asserts with respect to the high-level table entries in
116 // case the high-level table has extra entries. 115 // case the high-level table has extra entries.
117 #define X(tag, str) \ 116 #define X(tag, str) \
118 static_assert( \ 117 static_assert( \
119 _table1_##tag == _table2_##tag, \ 118 _icmp_hl_##tag == _icmp_ll_##tag, \
120 "Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE"); 119 "Inconsistency between ICMPARM32_TABLE and ICEINSTICMP_TABLE: " #tag);
121 ICEINSTICMP_TABLE 120 ICEINSTICMP_TABLE
122 #undef X 121 #undef X
123 } // end of namespace dummy1 122 } // end of anonymous namespace
124 123
125 // Stack alignment 124 // Stack alignment
126 const uint32_t ARM32_STACK_ALIGNMENT_BYTES = 16; 125 const uint32_t ARM32_STACK_ALIGNMENT_BYTES = 16;
127 126
128 // Value is in bytes. Return Value adjusted to the next highest multiple of the 127 // Value is in bytes. Return Value adjusted to the next highest multiple of the
129 // stack alignment. 128 // stack alignment.
130 uint32_t applyStackAlignment(uint32_t Value) { 129 uint32_t applyStackAlignment(uint32_t Value) {
131 return Utils::applyAlignment(Value, ARM32_STACK_ALIGNMENT_BYTES); 130 return Utils::applyAlignment(Value, ARM32_STACK_ALIGNMENT_BYTES);
132 } 131 }
133 132
(...skipping 2088 matching lines...) Expand 10 before | Expand all | Expand 10 after
2222 break; 2221 break;
2223 } 2222 }
2224 } 2223 }
2225 } 2224 }
2226 2225
2227 void TargetARM32::lowerExtractElement(const InstExtractElement *Inst) { 2226 void TargetARM32::lowerExtractElement(const InstExtractElement *Inst) {
2228 (void)Inst; 2227 (void)Inst;
2229 UnimplementedError(Func->getContext()->getFlags()); 2228 UnimplementedError(Func->getContext()->getFlags());
2230 } 2229 }
2231 2230
2231 namespace {
2232 // Validates FCMPARM32_TABLE's declaration w.r.t. InstFcmp::FCondition ordering
2233 // (and naming).
2234 enum {
2235 #define X(val, CC0, CC1) _fcmp_ll_##val,
2236 FCMPARM32_TABLE
2237 #undef X
2238 _fcmp_ll_NUM
2239 };
2240
2241 enum {
2242 #define X(tag, str) _fcmp_hl_##tag = InstFcmp::tag,
2243 ICEINSTFCMP_TABLE
2244 #undef X
2245 _fcmp_hl_NUM
2246 };
2247
2248 static_assert(_fcmp_hl_NUM == _fcmp_ll_NUM,
2249 "Inconsistency between high-level and low-level fcmp tags.");
2250 #define X(tag, str) \
2251 static_assert( \
2252 _fcmp_hl_##tag == _fcmp_ll_##tag, \
2253 "Inconsistency between high-level and low-level fcmp tag " #tag);
2254 ICEINSTFCMP_TABLE
2255 #undef X
2256
2257 struct {
2258 CondARM32::Cond CC0;
2259 CondARM32::Cond CC1;
2260 } TableFcmp[] = {
2261 #define X(val, CC0, CC1) \
2262 { CondARM32::CC0, CondARM32::CC1 } \
2263 ,
2264 FCMPARM32_TABLE
2265 #undef X
2266 };
2267 } // end of anonymous namespace
2268
2232 void TargetARM32::lowerFcmp(const InstFcmp *Inst) { 2269 void TargetARM32::lowerFcmp(const InstFcmp *Inst) {
2233 (void)Inst; 2270 Variable *Dest = Inst->getDest();
2234 UnimplementedError(Func->getContext()->getFlags()); 2271 if (isVectorType(Dest->getType())) {
2272 UnimplementedError(Func->getContext()->getFlags());
2273 return;
2274 }
2275
2276 Variable *Src0R = legalizeToReg(Inst->getSrc(0));
2277 Variable *Src1R = legalizeToReg(Inst->getSrc(1));
2278 Variable *T = makeReg(IceType_i32);
2279 _vcmp(Src0R, Src1R);
2280 _mov(T, Ctx->getConstantZero(IceType_i32));
2281 _vmrs();
2282 Operand *One = Ctx->getConstantInt32(1);
2283 InstFcmp::FCond Condition = Inst->getCondition();
2284 assert(Condition < llvm::array_lengthof(TableFcmp));
2285 CondARM32::Cond CC0 = TableFcmp[Condition].CC0;
2286 CondARM32::Cond CC1 = TableFcmp[Condition].CC1;
2287 if (CC0 != CondARM32::kNone) {
2288 _mov(T, One, CC0);
2289 // If this mov is not a maybe mov, but an actual mov (i.e., CC0 == AL), we
2290 // don't want to set_dest_nonkillable so that liveness + dead-code
2291 // elimination will get rid of the previous assignment (i.e., T = 0) above.
2292 if (CC0 != CondARM32::AL)
2293 _set_dest_nonkillable();
2294 }
2295 if (CC1 != CondARM32::kNone) {
2296 assert(CC0 != CondARM32::kNone);
2297 assert(CC1 != CondARM32::AL);
2298 _mov_nonkillable(T, One, CC1);
2299 }
2300 _mov(Dest, T);
2235 } 2301 }
2236 2302
2237 void TargetARM32::lowerIcmp(const InstIcmp *Inst) { 2303 void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
2238 Variable *Dest = Inst->getDest(); 2304 Variable *Dest = Inst->getDest();
2239 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); 2305 Operand *Src0 = legalizeUndef(Inst->getSrc(0));
2240 Operand *Src1 = legalizeUndef(Inst->getSrc(1)); 2306 Operand *Src1 = legalizeUndef(Inst->getSrc(1));
2241 2307
2242 if (isVectorType(Dest->getType())) { 2308 if (isVectorType(Dest->getType())) {
2243 UnimplementedError(Func->getContext()->getFlags()); 2309 UnimplementedError(Func->getContext()->getFlags());
2244 return; 2310 return;
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
2688 Variable *Dest = Inst->getDest(); 2754 Variable *Dest = Inst->getDest();
2689 Type DestTy = Dest->getType(); 2755 Type DestTy = Dest->getType();
2690 Operand *SrcT = Inst->getTrueOperand(); 2756 Operand *SrcT = Inst->getTrueOperand();
2691 Operand *SrcF = Inst->getFalseOperand(); 2757 Operand *SrcF = Inst->getFalseOperand();
2692 Operand *Condition = Inst->getCondition(); 2758 Operand *Condition = Inst->getCondition();
2693 2759
2694 if (isVectorType(DestTy)) { 2760 if (isVectorType(DestTy)) {
2695 UnimplementedError(Func->getContext()->getFlags()); 2761 UnimplementedError(Func->getContext()->getFlags());
2696 return; 2762 return;
2697 } 2763 }
2698 if (isFloatingType(DestTy)) {
2699 UnimplementedError(Func->getContext()->getFlags());
2700 return;
2701 }
2702 // TODO(jvoung): handle folding opportunities. 2764 // TODO(jvoung): handle folding opportunities.
2703 // cmp cond, #0; mov t, SrcF; mov_cond t, SrcT; mov dest, t 2765 // cmp cond, #0; mov t, SrcF; mov_cond t, SrcT; mov dest, t
2704 Variable *CmpOpnd0 = legalizeToReg(Condition); 2766 Variable *CmpOpnd0 = legalizeToReg(Condition);
2705 Operand *CmpOpnd1 = Ctx->getConstantZero(IceType_i32); 2767 Operand *CmpOpnd1 = Ctx->getConstantZero(IceType_i32);
2706 _cmp(CmpOpnd0, CmpOpnd1); 2768 _cmp(CmpOpnd0, CmpOpnd1);
2707 CondARM32::Cond Cond = CondARM32::NE; 2769 static constexpr CondARM32::Cond Cond = CondARM32::NE;
2708 if (DestTy == IceType_i64) { 2770 if (DestTy == IceType_i64) {
2709 SrcT = legalizeUndef(SrcT); 2771 SrcT = legalizeUndef(SrcT);
2710 SrcF = legalizeUndef(SrcF); 2772 SrcF = legalizeUndef(SrcF);
2711 // Set the low portion. 2773 // Set the low portion.
2712 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 2774 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
2713 Variable *TLo = nullptr; 2775 Variable *TLo = nullptr;
2714 Operand *SrcFLo = legalize(loOperand(SrcF), Legal_Reg | Legal_Flex); 2776 Operand *SrcFLo = legalize(loOperand(SrcF), Legal_Reg | Legal_Flex);
2715 _mov(TLo, SrcFLo); 2777 _mov(TLo, SrcFLo);
2716 Operand *SrcTLo = legalize(loOperand(SrcT), Legal_Reg | Legal_Flex); 2778 Operand *SrcTLo = legalize(loOperand(SrcT), Legal_Reg | Legal_Flex);
2717 _mov_nonkillable(TLo, SrcTLo, Cond); 2779 _mov_nonkillable(TLo, SrcTLo, Cond);
2718 _mov(DestLo, TLo); 2780 _mov(DestLo, TLo);
2719 // Set the high portion. 2781 // Set the high portion.
2720 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 2782 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
2721 Variable *THi = nullptr; 2783 Variable *THi = nullptr;
2722 Operand *SrcFHi = legalize(hiOperand(SrcF), Legal_Reg | Legal_Flex); 2784 Operand *SrcFHi = legalize(hiOperand(SrcF), Legal_Reg | Legal_Flex);
2723 _mov(THi, SrcFHi); 2785 _mov(THi, SrcFHi);
2724 Operand *SrcTHi = legalize(hiOperand(SrcT), Legal_Reg | Legal_Flex); 2786 Operand *SrcTHi = legalize(hiOperand(SrcT), Legal_Reg | Legal_Flex);
2725 _mov_nonkillable(THi, SrcTHi, Cond); 2787 _mov_nonkillable(THi, SrcTHi, Cond);
2726 _mov(DestHi, THi); 2788 _mov(DestHi, THi);
2727 return; 2789 return;
2728 } 2790 }
2791
2792 if (isFloatingType(DestTy)) {
2793 Variable *T = makeReg(DestTy);
2794 SrcF = legalizeToReg(SrcF);
2795 assert(DestTy == SrcF->getType());
2796 _vmov(T, SrcF);
2797 SrcT = legalizeToReg(SrcT);
2798 assert(DestTy == SrcT->getType());
2799 _vmov(T, SrcT, Cond);
2800 _set_dest_nonkillable();
2801 _vmov(Dest, T);
2802 return;
2803 }
2804
2729 Variable *T = nullptr; 2805 Variable *T = nullptr;
2730 SrcF = legalize(SrcF, Legal_Reg | Legal_Flex); 2806 SrcF = legalize(SrcF, Legal_Reg | Legal_Flex);
2731 _mov(T, SrcF); 2807 _mov(T, SrcF);
2732 SrcT = legalize(SrcT, Legal_Reg | Legal_Flex); 2808 SrcT = legalize(SrcT, Legal_Reg | Legal_Flex);
2733 _mov_nonkillable(T, SrcT, Cond); 2809 _mov_nonkillable(T, SrcT, Cond);
2734 _mov(Dest, T); 2810 _mov(Dest, T);
2735 } 2811 }
2736 2812
2737 void TargetARM32::lowerStore(const InstStore *Inst) { 2813 void TargetARM32::lowerStore(const InstStore *Inst) {
2738 Operand *Value = Inst->getData(); 2814 Operand *Value = Inst->getData();
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
3278 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; 3354 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n";
3279 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { 3355 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) {
3280 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; 3356 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n";
3281 } 3357 }
3282 // Technically R9 is used for TLS with Sandboxing, and we reserve it. 3358 // Technically R9 is used for TLS with Sandboxing, and we reserve it.
3283 // However, for compatibility with current NaCl LLVM, don't claim that. 3359 // However, for compatibility with current NaCl LLVM, don't claim that.
3284 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 3360 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
3285 } 3361 }
3286 3362
3287 } // end of namespace Ice 3363 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringARM32.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698