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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 413053002: Lower the fcmp instruction for <4 x float> operands. (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Replace uses of std::endl with newlines. Created 6 years, 5 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
OLDNEW
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 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 // This file implements the TargetLoweringX8632 class, which 10 // This file implements the TargetLoweringX8632 class, which
11 // consists almost entirely of the lowering sequence for each 11 // consists almost entirely of the lowering sequence for each
12 // high-level instruction. It also implements 12 // high-level instruction. It also implements
13 // TargetX8632Fast::postLower() which does the simplest possible 13 // TargetX8632Fast::postLower() which does the simplest possible
14 // register allocation for the "fast" target. 14 // register allocation for the "fast" target.
15 // 15 //
16 //===----------------------------------------------------------------------===// 16 //===----------------------------------------------------------------------===//
17 17
18 #include "IceDefs.h" 18 #include "IceDefs.h"
19 #include "IceCfg.h" 19 #include "IceCfg.h"
20 #include "IceCfgNode.h" 20 #include "IceCfgNode.h"
21 #include "IceInstX8632.h" 21 #include "IceInstX8632.h"
22 #include "IceOperand.h" 22 #include "IceOperand.h"
23 #include "IceTargetLoweringX8632.def" 23 #include "IceTargetLoweringX8632.def"
24 #include "IceTargetLoweringX8632.h" 24 #include "IceTargetLoweringX8632.h"
25 25
26 namespace Ice { 26 namespace Ice {
27 27
28 namespace { 28 namespace {
29 29
30 // The following table summarizes the logic for lowering the fcmp instruction. 30 // The following table summarizes the logic for lowering the fcmp
31 // instruction when the operands are floating point scalar values.
31 // There is one table entry for each of the 16 conditions. A comment in 32 // There is one table entry for each of the 16 conditions. A comment in
32 // lowerFcmp() describes the lowering template. In the most general case, there 33 // lowerFcmp() describes the lowering template. In the most general
33 // is a compare followed by two conditional branches, because some fcmp 34 // case, there is a compare followed by two conditional branches,
34 // conditions don't map to a single x86 conditional branch. However, in many 35 // because some fcmp conditions don't map to a single x86 conditional
35 // cases it is possible to swap the operands in the comparison and have a single 36 // branch. However, in many cases it is possible to swap the operands
36 // conditional branch. Since it's quite tedious to validate the table by hand, 37 // in the comparison and have a single conditional branch. Since it's
37 // good execution tests are helpful. 38 // quite tedious to validate the table by hand, good execution tests are
39 // helpful.
38 40
39 const struct TableFcmp_ { 41 const struct TableScalarFcmp_ {
40 uint32_t Default; 42 uint32_t Default;
41 bool SwapOperands; 43 bool SwapOperands;
42 InstX8632::BrCond C1, C2; 44 InstX8632::BrCond C1, C2;
43 } TableFcmp[] = { 45 } TableScalarFcmp[] = {
44 #define X(val, dflt, swap, C1, C2) \ 46 #define X(val, dflt, swap, C1, C2) \
45 { dflt, swap, InstX8632Br::C1, InstX8632Br::C2 } \ 47 { dflt, swap, InstX8632Br::C1, InstX8632Br::C2 } \
46 , 48 ,
47 FCMPX8632_TABLE 49 SCALAR_FCMPX8632_TABLE
48 #undef X 50 #undef X
49 }; 51 };
50 const size_t TableFcmpSize = llvm::array_lengthof(TableFcmp); 52 const size_t TableScalarFcmpSize = llvm::array_lengthof(TableScalarFcmp);
53
54 // The following table summarizes the logic for lowering the fcmp
55 // instruction when the operands are vectors of floating point values.
56 // For most fcmp conditions, there is a clear mapping to a single x86
57 // cmpps instruction variant. Some fcmp conditions require special code
58 // to handle and these are marked in the table with a Cmpps_Invalid
59 // predicate.
60
61 const struct TableVectorFcmp_ {
62 bool SwapOperands;
63 InstX8632Cmpps::CmppsCond Predicate;
64 } TableVectorFcmp[] = {
65 #define X(val, swap, pred) \
66 { swap, InstX8632Cmpps::pred } \
67 ,
68 VECTOR_FCMPX8632_TABLE
69 #undef X
70 };
71 const size_t TableVectorFcmpSize = llvm::array_lengthof(TableVectorFcmp);
51 72
52 // The following table summarizes the logic for lowering the icmp instruction 73 // The following table summarizes the logic for lowering the icmp instruction
53 // for i32 and narrower types. Each icmp condition has a clear mapping to an 74 // for i32 and narrower types. Each icmp condition has a clear mapping to an
54 // x86 conditional branch instruction. 75 // x86 conditional branch instruction.
55 76
56 const struct TableIcmp32_ { 77 const struct TableIcmp32_ {
57 InstX8632::BrCond Mapping; 78 InstX8632::BrCond Mapping;
58 } TableIcmp32[] = { 79 } TableIcmp32[] = {
59 #define X(val, C_32, C1_64, C2_64, C3_64) \ 80 #define X(val, C_32, C1_64, C2_64, C3_64) \
60 { InstX8632Br::C_32 } \ 81 { InstX8632Br::C_32 } \
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 } 147 }
127 148
128 // In some cases, there are x-macros tables for both high-level and 149 // In some cases, there are x-macros tables for both high-level and
129 // low-level instructions/operands that use the same enum key value. 150 // low-level instructions/operands that use the same enum key value.
130 // The tables are kept separate to maintain a proper separation 151 // The tables are kept separate to maintain a proper separation
131 // between abstraction layers. There is a risk that the tables 152 // between abstraction layers. There is a risk that the tables
132 // could get out of sync if enum values are reordered or if entries 153 // could get out of sync if enum values are reordered or if entries
133 // are added or deleted. This dummy function uses static_assert to 154 // are added or deleted. This dummy function uses static_assert to
134 // ensure everything is kept in sync. 155 // ensure everything is kept in sync.
135 void xMacroIntegrityCheck() { 156 void xMacroIntegrityCheck() {
136 // Validate the enum values in FCMPX8632_TABLE. 157 // Validate the enum values in SCALAR_FCMPX8632_TABLE.
137 { 158 {
138 // Define a temporary set of enum values based on low-level 159 // Define a temporary set of enum values based on low-level
139 // table entries. 160 // table entries.
140 enum _tmp_enum { 161 enum _tmp_enum {
141 #define X(val, dflt, swap, C1, C2) _tmp_##val, 162 #define X(val, dflt, swap, C1, C2) _tmp_##val,
142 FCMPX8632_TABLE 163 SCALAR_FCMPX8632_TABLE
143 #undef X 164 #undef X
144 _num 165 _num
145 }; 166 };
146 // Define a set of constants based on high-level table entries. 167 // Define a set of constants based on high-level table entries.
147 #define X(tag, str) static const int _table1_##tag = InstFcmp::tag; 168 #define X(tag, str) static const int _table1_##tag = InstFcmp::tag;
148 ICEINSTFCMP_TABLE; 169 ICEINSTFCMP_TABLE;
149 #undef X 170 #undef X
150 // Define a set of constants based on low-level table entries, 171 // Define a set of constants based on low-level table entries,
151 // and ensure the table entry keys are consistent. 172 // and ensure the table entry keys are consistent.
152 #define X(val, dflt, swap, C1, C2) \ 173 #define X(val, dflt, swap, C1, C2) \
153 static const int _table2_##val = _tmp_##val; \ 174 static const int _table2_##val = _tmp_##val; \
154 STATIC_ASSERT(_table1_##val == _table2_##val); 175 STATIC_ASSERT(_table1_##val == _table2_##val);
155 FCMPX8632_TABLE; 176 SCALAR_FCMPX8632_TABLE;
156 #undef X 177 #undef X
157 // Repeat the static asserts with respect to the high-level 178 // Repeat the static asserts with respect to the high-level
158 // table entries in case the high-level table has extra entries. 179 // table entries in case the high-level table has extra entries.
180 #define X(tag, str) STATIC_ASSERT(_table1_##tag == _table2_##tag);
181 ICEINSTFCMP_TABLE;
182 #undef X
183 }
184
185 // Validate the enum values in VECTOR_FCMPX8632_TABLE.
186 {
187 // Define a temporary set of enum values based on low-level
188 // table entries.
189 enum _tmp_enum {
190 #define X(val, swap, pred) _tmp_##val,
191 VECTOR_FCMPX8632_TABLE
192 #undef X
193 _num
194 };
195 // Define a set of constants based on high-level table entries.
196 #define X(tag, str) static const int _table1_##tag = InstFcmp::tag;
197 ICEINSTFCMP_TABLE;
198 #undef X
199 // Define a set of constants based on low-level table entries,
200 // and ensure the table entry keys are consistent.
201 #define X(val, swap, pred) \
202 static const int _table2_##val = _tmp_##val; \
203 STATIC_ASSERT(_table1_##val == _table2_##val);
204 VECTOR_FCMPX8632_TABLE;
205 #undef X
206 // Repeat the static asserts with respect to the high-level
207 // table entries in case the high-level table has extra entries.
159 #define X(tag, str) STATIC_ASSERT(_table1_##tag == _table2_##tag); 208 #define X(tag, str) STATIC_ASSERT(_table1_##tag == _table2_##tag);
160 ICEINSTFCMP_TABLE; 209 ICEINSTFCMP_TABLE;
161 #undef X 210 #undef X
162 } 211 }
163 212
164 // Validate the enum values in ICMPX8632_TABLE. 213 // Validate the enum values in ICMPX8632_TABLE.
165 { 214 {
166 // Define a temporary set of enum values based on low-level 215 // Define a temporary set of enum values based on low-level
167 // table entries. 216 // table entries.
168 enum _tmp_enum { 217 enum _tmp_enum {
(...skipping 2037 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 2255
2207 // Copy the element to the destination. 2256 // Copy the element to the destination.
2208 Variable *Dest = Inst->getDest(); 2257 Variable *Dest = Inst->getDest();
2209 _mov(Dest, ExtractedElement); 2258 _mov(Dest, ExtractedElement);
2210 } 2259 }
2211 2260
2212 void TargetX8632::lowerFcmp(const InstFcmp *Inst) { 2261 void TargetX8632::lowerFcmp(const InstFcmp *Inst) {
2213 Operand *Src0 = Inst->getSrc(0); 2262 Operand *Src0 = Inst->getSrc(0);
2214 Operand *Src1 = Inst->getSrc(1); 2263 Operand *Src1 = Inst->getSrc(1);
2215 Variable *Dest = Inst->getDest(); 2264 Variable *Dest = Inst->getDest();
2265
2266 if (isVectorType(Dest->getType())) {
2267 InstFcmp::FCond Condition = Inst->getCondition();
2268 size_t Index = static_cast<size_t>(Condition);
2269 assert(Index < TableVectorFcmpSize);
2270
2271 if (TableVectorFcmp[Index].SwapOperands) {
2272 Operand *T = Src0;
2273 Src0 = Src1;
2274 Src1 = T;
2275 }
2276
2277 Variable *T = NULL;
2278
2279 // ALIGNHACK: Without support for stack alignment, both operands to
2280 // cmpps need to be forced into registers. Once support for stack
2281 // alignment is implemented, remove LEGAL_HACK.
2282 #define LEGAL_HACK(Vect) legalizeToVar((Vect))
2283 switch (Condition) {
2284 default: {
2285 InstX8632Cmpps::CmppsCond Predicate = TableVectorFcmp[Index].Predicate;
2286 assert(Predicate != InstX8632Cmpps::Cmpps_Invalid);
2287 T = makeReg(Src0->getType());
2288 _movp(T, Src0);
2289 _cmpps(T, LEGAL_HACK(Src1), Predicate);
2290 } break;
2291 case InstFcmp::False:
2292 T = makeVectorOfZeros(Src0->getType());
2293 break;
2294 case InstFcmp::One: {
2295 // Check both unequal and ordered.
2296 T = makeReg(Src0->getType());
2297 Variable *T2 = makeReg(Src0->getType());
2298 Src1 = LEGAL_HACK(Src1);
2299 _movp(T, Src0);
2300 _cmpps(T, Src1, InstX8632Cmpps::Cmpps_neq);
2301 _movp(T2, Src0);
2302 _cmpps(T2, Src1, InstX8632Cmpps::Cmpps_ord);
2303 _pand(T, T2);
2304 } break;
2305 case InstFcmp::Ueq: {
2306 // Check both equal or unordered.
2307 T = makeReg(Src0->getType());
2308 Variable *T2 = makeReg(Src0->getType());
2309 Src1 = LEGAL_HACK(Src1);
2310 _movp(T, Src0);
2311 _cmpps(T, Src1, InstX8632Cmpps::Cmpps_eq);
2312 _movp(T2, Src0);
2313 _cmpps(T2, Src1, InstX8632Cmpps::Cmpps_unord);
2314 _por(T, T2);
2315 } break;
2316 case InstFcmp::True:
2317 T = makeVectorOfMinusOnes(IceType_v4i32);
2318 break;
2319 }
2320 #undef LEGAL_HACK
2321
2322 _movp(Dest, T);
2323 eliminateNextVectorSextInstruction(Dest);
2324 return;
2325 }
2326
2216 // Lowering a = fcmp cond, b, c 2327 // Lowering a = fcmp cond, b, c
2217 // ucomiss b, c /* only if C1 != Br_None */ 2328 // ucomiss b, c /* only if C1 != Br_None */
2218 // /* but swap b,c order if SwapOperands==true */ 2329 // /* but swap b,c order if SwapOperands==true */
2219 // mov a, <default> 2330 // mov a, <default>
2220 // j<C1> label /* only if C1 != Br_None */ 2331 // j<C1> label /* only if C1 != Br_None */
2221 // j<C2> label /* only if C2 != Br_None */ 2332 // j<C2> label /* only if C2 != Br_None */
2222 // FakeUse(a) /* only if C1 != Br_None */ 2333 // FakeUse(a) /* only if C1 != Br_None */
2223 // mov a, !<default> /* only if C1 != Br_None */ 2334 // mov a, !<default> /* only if C1 != Br_None */
2224 // label: /* only if C1 != Br_None */ 2335 // label: /* only if C1 != Br_None */
2225 InstFcmp::FCond Condition = Inst->getCondition(); 2336 InstFcmp::FCond Condition = Inst->getCondition();
2226 size_t Index = static_cast<size_t>(Condition); 2337 size_t Index = static_cast<size_t>(Condition);
2227 assert(Index < TableFcmpSize); 2338 assert(Index < TableScalarFcmpSize);
2228 if (TableFcmp[Index].SwapOperands) { 2339 if (TableScalarFcmp[Index].SwapOperands) {
2229 Operand *Tmp = Src0; 2340 Operand *Tmp = Src0;
2230 Src0 = Src1; 2341 Src0 = Src1;
2231 Src1 = Tmp; 2342 Src1 = Tmp;
2232 } 2343 }
2233 bool HasC1 = (TableFcmp[Index].C1 != InstX8632Br::Br_None); 2344 bool HasC1 = (TableScalarFcmp[Index].C1 != InstX8632Br::Br_None);
2234 bool HasC2 = (TableFcmp[Index].C2 != InstX8632Br::Br_None); 2345 bool HasC2 = (TableScalarFcmp[Index].C2 != InstX8632Br::Br_None);
2235 if (HasC1) { 2346 if (HasC1) {
2236 Src0 = legalize(Src0); 2347 Src0 = legalize(Src0);
2237 Operand *Src1RM = legalize(Src1, Legal_Reg | Legal_Mem); 2348 Operand *Src1RM = legalize(Src1, Legal_Reg | Legal_Mem);
2238 Variable *T = NULL; 2349 Variable *T = NULL;
2239 _mov(T, Src0); 2350 _mov(T, Src0);
2240 _ucomiss(T, Src1RM); 2351 _ucomiss(T, Src1RM);
2241 } 2352 }
2242 Constant *Default = 2353 Constant *Default =
2243 Ctx->getConstantInt(IceType_i32, TableFcmp[Index].Default); 2354 Ctx->getConstantInt(IceType_i32, TableScalarFcmp[Index].Default);
2244 _mov(Dest, Default); 2355 _mov(Dest, Default);
2245 if (HasC1) { 2356 if (HasC1) {
2246 InstX8632Label *Label = InstX8632Label::create(Func, this); 2357 InstX8632Label *Label = InstX8632Label::create(Func, this);
2247 _br(TableFcmp[Index].C1, Label); 2358 _br(TableScalarFcmp[Index].C1, Label);
2248 if (HasC2) { 2359 if (HasC2) {
2249 _br(TableFcmp[Index].C2, Label); 2360 _br(TableScalarFcmp[Index].C2, Label);
2250 } 2361 }
2251 Context.insert(InstFakeUse::create(Func, Dest)); 2362 Context.insert(InstFakeUse::create(Func, Dest));
2252 Constant *NonDefault = 2363 Constant *NonDefault =
2253 Ctx->getConstantInt(IceType_i32, !TableFcmp[Index].Default); 2364 Ctx->getConstantInt(IceType_i32, !TableScalarFcmp[Index].Default);
2254 _mov(Dest, NonDefault); 2365 _mov(Dest, NonDefault);
2255 Context.insert(Label); 2366 Context.insert(Label);
2256 } 2367 }
2257 } 2368 }
2258 2369
2259 void TargetX8632::lowerIcmp(const InstIcmp *Inst) { 2370 void TargetX8632::lowerIcmp(const InstIcmp *Inst) {
2260 Operand *Src0 = legalize(Inst->getSrc(0)); 2371 Operand *Src0 = legalize(Inst->getSrc(0));
2261 Operand *Src1 = legalize(Inst->getSrc(1)); 2372 Operand *Src1 = legalize(Inst->getSrc(1));
2262 Variable *Dest = Inst->getDest(); 2373 Variable *Dest = Inst->getDest();
2263 2374
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2349 // !(Src0 > Src1) 2460 // !(Src0 > Src1)
2350 _movp(T, Src0); 2461 _movp(T, Src0);
2351 _pcmpgt(T, LEGAL_HACK(Src1)); 2462 _pcmpgt(T, LEGAL_HACK(Src1));
2352 Variable *MinusOne = makeVectorOfMinusOnes(Ty); 2463 Variable *MinusOne = makeVectorOfMinusOnes(Ty);
2353 _pxor(T, MinusOne); 2464 _pxor(T, MinusOne);
2354 } break; 2465 } break;
2355 } 2466 }
2356 #undef LEGAL_HACK 2467 #undef LEGAL_HACK
2357 2468
2358 _movp(Dest, T); 2469 _movp(Dest, T);
2359 2470 eliminateNextVectorSextInstruction(Dest);
2360 // The following pattern occurs often in lowered C and C++ code:
2361 //
2362 // %cmp = icmp pred <n x ty> %src0, %src1
2363 // %cmp.ext = sext <n x i1> %cmp to <n x ty>
2364 //
2365 // We can avoid the sext operation by copying the result from pcmpgt
2366 // and pcmpeq, which is already sign extended, to the result of the
2367 // sext operation
2368 if (InstCast *NextCast =
2369 llvm::dyn_cast_or_null<InstCast>(Context.getNextInst())) {
2370 if (NextCast->getCastKind() == InstCast::Sext &&
2371 NextCast->getSrc(0) == Dest) {
2372 _movp(NextCast->getDest(), T);
2373 // Skip over the instruction.
2374 NextCast->setDeleted();
2375 Context.advanceNext();
2376 }
2377 }
2378
2379 return; 2471 return;
2380 } 2472 }
2381 2473
2382 // If Src1 is an immediate, or known to be a physical register, we can 2474 // If Src1 is an immediate, or known to be a physical register, we can
2383 // allow Src0 to be a memory operand. Otherwise, Src0 must be copied into 2475 // allow Src0 to be a memory operand. Otherwise, Src0 must be copied into
2384 // a physical register. (Actually, either Src0 or Src1 can be chosen for 2476 // a physical register. (Actually, either Src0 or Src1 can be chosen for
2385 // the physical register, but unfortunately we have to commit to one or 2477 // the physical register, but unfortunately we have to commit to one or
2386 // the other before register allocation.) 2478 // the other before register allocation.)
2387 bool IsSrc1ImmOrReg = false; 2479 bool IsSrc1ImmOrReg = false;
2388 if (llvm::isa<Constant>(Src1)) { 2480 if (llvm::isa<Constant>(Src1)) {
(...skipping 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after
3502 Src0 = legalize(Src0, Legal_All, true); 3594 Src0 = legalize(Src0, Legal_All, true);
3503 for (SizeT I = 0; I < NumCases; ++I) { 3595 for (SizeT I = 0; I < NumCases; ++I) {
3504 Operand *Value = Ctx->getConstantInt(IceType_i32, Inst->getValue(I)); 3596 Operand *Value = Ctx->getConstantInt(IceType_i32, Inst->getValue(I));
3505 _cmp(Src0, Value); 3597 _cmp(Src0, Value);
3506 _br(InstX8632Br::Br_e, Inst->getLabel(I)); 3598 _br(InstX8632Br::Br_e, Inst->getLabel(I));
3507 } 3599 }
3508 3600
3509 _br(Inst->getLabelDefault()); 3601 _br(Inst->getLabelDefault());
3510 } 3602 }
3511 3603
3604 // The following pattern occurs often in lowered C and C++ code:
3605 //
3606 // %cmp = fcmp/icmp pred <n x ty> %src0, %src1
3607 // %cmp.ext = sext <n x i1> %cmp to <n x ty>
3608 //
3609 // We can eliminate the sext operation by copying the result of pcmpeqd,
3610 // pcmpgtd, or cmpps (which produce sign extended results) the result of
3611 // the sext operation.
3612 void
3613 TargetX8632::eliminateNextVectorSextInstruction(Variable *SignExtendedResult) {
3614 if (InstCast *NextCast =
3615 llvm::dyn_cast_or_null<InstCast>(Context.getNextInst())) {
3616 if (NextCast->getCastKind() == InstCast::Sext &&
3617 NextCast->getSrc(0) == SignExtendedResult) {
3618 _movp(NextCast->getDest(), legalizeToVar(SignExtendedResult));
3619 // Skip over the instruction.
3620 NextCast->setDeleted();
3621 Context.advanceNext();
3622 }
3623 }
3624 }
3625
3512 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) { 3626 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) {
3513 const SizeT MaxSrcs = 0; 3627 const SizeT MaxSrcs = 0;
3514 Variable *Dest = NULL; 3628 Variable *Dest = NULL;
3515 InstCall *Call = makeHelperCall("ice_unreachable", Dest, MaxSrcs); 3629 InstCall *Call = makeHelperCall("ice_unreachable", Dest, MaxSrcs);
3516 lowerCall(Call); 3630 lowerCall(Call);
3517 } 3631 }
3518 3632
3519 // There is no support for loading or emitting vector constants, so the 3633 // There is no support for loading or emitting vector constants, so the
3520 // vector values returned from makeVectorOfZeros, makeVectorOfOnes, 3634 // vector values returned from makeVectorOfZeros, makeVectorOfOnes,
3521 // etc. are initialized with register operations. 3635 // etc. are initialized with register operations.
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
3898 for (SizeT i = 0; i < Size; ++i) { 4012 for (SizeT i = 0; i < Size; ++i) {
3899 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; 4013 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n";
3900 } 4014 }
3901 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; 4015 Str << "\t.size\t" << MangledName << ", " << Size << "\n";
3902 } 4016 }
3903 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName 4017 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName
3904 << "\n"; 4018 << "\n";
3905 } 4019 }
3906 4020
3907 } // end of namespace Ice 4021 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698