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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1617993005: Fix vldrs/vstrs handling of immediate offsets in ARM. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 4 years, 11 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 | « no previous file | tests_lit/assembler/arm32/vldr.vstr.imm.ll » ('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/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===//
2 // 2 //
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 // for details. All rights reserved. Use of this source code is governed by a 4 // for details. All rights reserved. Use of this source code is governed by a
5 // BSD-style license that can be found in the LICENSE file. 5 // BSD-style license that can be found in the LICENSE file.
6 // 6 //
7 // Modified by the Subzero authors. 7 // Modified by the Subzero authors.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 // 10 //
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) { 349 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) {
350 const IValueT Immed5 = ShImm->getShAmtImm(); 350 const IValueT Immed5 = ShImm->getShAmtImm();
351 assert(Immed5 < (1 << kShiftImmBits)); 351 assert(Immed5 < (1 << kShiftImmBits));
352 Value = (Immed5 << kShiftImmShift); 352 Value = (Immed5 << kShiftImmShift);
353 return EncodedAsShiftImm5; 353 return EncodedAsShiftImm5;
354 } 354 }
355 return CantEncode; 355 return CantEncode;
356 } 356 }
357 357
358 IValueT encodeImmRegOffset(IValueT Reg, IOffsetT Offset, 358 IValueT encodeImmRegOffset(IValueT Reg, IOffsetT Offset,
359 OperandARM32Mem::AddrMode Mode) { 359 OperandARM32Mem::AddrMode Mode,
360 IValueT OffsetShift = 0) {
360 IValueT Value = Mode | (Reg << kRnShift); 361 IValueT Value = Mode | (Reg << kRnShift);
361 if (Offset < 0) { 362 if (Offset < 0) {
362 Value = (Value ^ U) | -Offset; // Flip U to adjust sign. 363 Offset = -Offset;
363 } else { 364 Value ^= U; // Flip U to adjust sign.
364 Value |= Offset;
365 } 365 }
366 return Value; 366 return Value | (Offset >> OffsetShift);
367 } 367 }
368 368
369 // Encodes immediate register offset using encoding 3. 369 // Encodes immediate register offset using encoding 3.
370 IValueT encodeImmRegOffsetEnc3(IValueT Rn, IOffsetT Imm8, 370 IValueT encodeImmRegOffsetEnc3(IValueT Rn, IOffsetT Imm8,
371 OperandARM32Mem::AddrMode Mode) { 371 OperandARM32Mem::AddrMode Mode) {
372 IValueT Value = Mode | (Rn << kRnShift); 372 IValueT Value = Mode | (Rn << kRnShift);
373 if (Imm8 < 0) { 373 if (Imm8 < 0) {
374 Imm8 = -Imm8; 374 Imm8 = -Imm8;
375 Value = (Value ^ U); 375 Value = (Value ^ U);
376 } 376 }
377 assert(Imm8 < (1 << 8)); 377 assert(Imm8 < (1 << 8));
378 Value = Value | B22 | ((Imm8 & 0xf0) << 4) | (Imm8 & 0x0f); 378 Value = Value | B22 | ((Imm8 & 0xf0) << 4) | (Imm8 & 0x0f);
379 return Value; 379 return Value;
380 } 380 }
381 381
382 IValueT encodeImmRegOffset(OpEncoding AddressEncoding, IValueT Reg, 382 IValueT encodeImmRegOffset(OpEncoding AddressEncoding, IValueT Reg,
383 IOffsetT Offset, OperandARM32Mem::AddrMode Mode) { 383 IOffsetT Offset, OperandARM32Mem::AddrMode Mode) {
384 switch (AddressEncoding) { 384 switch (AddressEncoding) {
385 case DefaultOpEncoding: 385 case DefaultOpEncoding:
386 return encodeImmRegOffset(Reg, Offset, Mode); 386 return encodeImmRegOffset(Reg, Offset, Mode);
387 case ImmRegOffsetDiv4: 387 case ImmRegOffsetDiv4: {
388 assert((Offset & 0x3) == 0); 388 assert((Offset & 0x3) == 0);
389 return encodeImmRegOffset(Reg, Offset >> 2, Mode); 389 constexpr IValueT RightShift2 = 2;
390 return encodeImmRegOffset(Reg, Offset, Mode, RightShift2);
391 }
390 case OpEncoding3: 392 case OpEncoding3:
391 return encodeImmRegOffsetEnc3(Reg, Offset, Mode); 393 return encodeImmRegOffsetEnc3(Reg, Offset, Mode);
392 case OpEncodingMemEx: 394 case OpEncodingMemEx:
393 assert(Offset == 0); 395 assert(Offset == 0);
394 assert(Mode == OperandARM32Mem::Offset); 396 assert(Mode == OperandARM32Mem::Offset);
395 return Reg << kRnShift; 397 return Reg << kRnShift;
396 } 398 }
397 llvm_unreachable("(silence g++ warning)"); 399 llvm_unreachable("(silence g++ warning)");
398 } 400 }
399 401
(...skipping 1835 matching lines...) Expand 10 before | Expand all | Expand 10 after
2235 // vldr<c> <Dd>, [<Rn>{, #+/-<imm>}] 2237 // vldr<c> <Dd>, [<Rn>{, #+/-<imm>}]
2236 // 2238 //
2237 // cccc1101UD01nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd, 2239 // cccc1101UD01nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd,
2238 // iiiiiiii=abs(Imm >> 2), and U=1 if Opcode>=0. 2240 // iiiiiiii=abs(Imm >> 2), and U=1 if Opcode>=0.
2239 constexpr const char *Vldrd = "vldrd"; 2241 constexpr const char *Vldrd = "vldrd";
2240 IValueT Dd = encodeDRegister(OpDd, "Dd", Vldrd); 2242 IValueT Dd = encodeDRegister(OpDd, "Dd", Vldrd);
2241 assert(CondARM32::isDefined(Cond)); 2243 assert(CondARM32::isDefined(Cond));
2242 IValueT Address; 2244 IValueT Address;
2243 EncodedOperand AddressEncoding = 2245 EncodedOperand AddressEncoding =
2244 encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4); 2246 encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4);
2245 if (AddressEncoding != EncodedAsImmRegOffset) 2247 (void)AddressEncoding; // Make MINIMAL build happy.
John 2016/01/22 18:47:40 no need for this comment. This is a pretty common
Karl 2016/01/22 20:42:19 Done.
2246 // TODO(kschimpf) Fix this. 2248 assert(AddressEncoding == EncodedAsImmRegOffset);
2247 return setNeedsTextFixup();
2248 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2249 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2249 IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | B8 | 2250 IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | B8 |
2250 (encodeCondition(Cond) << kConditionShift) | 2251 (encodeCondition(Cond) << kConditionShift) |
2251 (getYInRegYXXXX(Dd) << 22) | 2252 (getYInRegYXXXX(Dd) << 22) |
2252 (getXXXXInRegYXXXX(Dd) << 12) | Address; 2253 (getXXXXInRegYXXXX(Dd) << 12) | Address;
2253 emitInst(Encoding); 2254 emitInst(Encoding);
2254 } 2255 }
2255 2256
2256 void AssemblerARM32::vldrs(const Operand *OpSd, const Operand *OpAddress, 2257 void AssemblerARM32::vldrs(const Operand *OpSd, const Operand *OpAddress,
2257 CondARM32::Cond Cond, const TargetInfo &TInfo) { 2258 CondARM32::Cond Cond, const TargetInfo &TInfo) {
2258 // VDLR - ARM section A8.8.333, encoding A2. 2259 // VDLR - ARM section A8.8.333, encoding A2.
2259 // vldr<c> <Sd>, [<Rn>{, #+/-<imm>]] 2260 // vldr<c> <Sd>, [<Rn>{, #+/-<imm>]]
2260 // 2261 //
2261 // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd, 2262 // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd,
2262 // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0; 2263 // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0;
2263 constexpr const char *Vldrs = "vldrs"; 2264 constexpr const char *Vldrs = "vldrs";
2264 IValueT Sd = encodeSRegister(OpSd, "Sd", Vldrs); 2265 IValueT Sd = encodeSRegister(OpSd, "Sd", Vldrs);
2265 assert(CondARM32::isDefined(Cond)); 2266 assert(CondARM32::isDefined(Cond));
2266 IValueT Address; 2267 IValueT Address;
2267 EncodedOperand AddressEncoding = encodeAddress(OpAddress, Address, TInfo); 2268 EncodedOperand AddressEncoding =
2268 (void)AddressEncoding; 2269 encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4);
2270 (void)AddressEncoding; // Make MINIMAL build happy.
2269 assert(AddressEncoding == EncodedAsImmRegOffset); 2271 assert(AddressEncoding == EncodedAsImmRegOffset);
2270 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2272 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2271 IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | 2273 IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 |
2272 (encodeCondition(Cond) << kConditionShift) | 2274 (encodeCondition(Cond) << kConditionShift) |
2273 (getYInRegXXXXY(Sd) << 22) | 2275 (getYInRegXXXXY(Sd) << 22) |
2274 (getXXXXInRegXXXXY(Sd) << 12) | Address; 2276 (getXXXXInRegXXXXY(Sd) << 12) | Address;
2275 emitInst(Encoding); 2277 emitInst(Encoding);
2276 } 2278 }
2277 2279
2278 void AssemblerARM32::vmuls(const Operand *OpSd, const Operand *OpSn, 2280 void AssemblerARM32::vmuls(const Operand *OpSd, const Operand *OpSn,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2311 // vstr<c> <Dd>, [<Rn>{, #+/-<Imm>}] 2313 // vstr<c> <Dd>, [<Rn>{, #+/-<Imm>}]
2312 // 2314 //
2313 // cccc1101UD00nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd, 2315 // cccc1101UD00nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd,
2314 // iiiiiiii=abs(Imm >> 2), and U=1 if Imm>=0. 2316 // iiiiiiii=abs(Imm >> 2), and U=1 if Imm>=0.
2315 constexpr const char *Vstrd = "vstrd"; 2317 constexpr const char *Vstrd = "vstrd";
2316 IValueT Dd = encodeDRegister(OpDd, "Dd", Vstrd); 2318 IValueT Dd = encodeDRegister(OpDd, "Dd", Vstrd);
2317 assert(CondARM32::isDefined(Cond)); 2319 assert(CondARM32::isDefined(Cond));
2318 IValueT Address; 2320 IValueT Address;
2319 IValueT AddressEncoding = 2321 IValueT AddressEncoding =
2320 encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4); 2322 encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4);
2321 if (AddressEncoding != EncodedAsImmRegOffset) 2323 (void)AddressEncoding; // Make MINIMAL build happy.
2322 // TODO(kschimpf) Fix this. 2324 assert(AddressEncoding == EncodedAsImmRegOffset);
2323 return setNeedsTextFixup();
2324 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2325 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2325 IValueT Encoding = B27 | B26 | B24 | B11 | B9 | B8 | 2326 IValueT Encoding = B27 | B26 | B24 | B11 | B9 | B8 |
2326 (encodeCondition(Cond) << kConditionShift) | 2327 (encodeCondition(Cond) << kConditionShift) |
2327 (getYInRegYXXXX(Dd) << 22) | 2328 (getYInRegYXXXX(Dd) << 22) |
2328 (getXXXXInRegYXXXX(Dd) << 12) | Address; 2329 (getXXXXInRegYXXXX(Dd) << 12) | Address;
2329 emitInst(Encoding); 2330 emitInst(Encoding);
2330 } 2331 }
2331 2332
2332 void AssemblerARM32::vstrs(const Operand *OpSd, const Operand *OpAddress, 2333 void AssemblerARM32::vstrs(const Operand *OpSd, const Operand *OpAddress,
2333 CondARM32::Cond Cond, const TargetInfo &TInfo) { 2334 CondARM32::Cond Cond, const TargetInfo &TInfo) {
2334 // VSTR - ARM section A8.8.413, encoding A2: 2335 // VSTR - ARM section A8.8.413, encoding A2:
2335 // vstr<c> <Sd>, [<Rn>{, #+/-<imm>]] 2336 // vstr<c> <Sd>, [<Rn>{, #+/-<imm>]]
2336 // 2337 //
2337 // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd, 2338 // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd,
2338 // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0; 2339 // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0;
2339 constexpr const char *Vstrs = "vstrs"; 2340 constexpr const char *Vstrs = "vstrs";
2340 IValueT Sd = encodeSRegister(OpSd, "Sd", Vstrs); 2341 IValueT Sd = encodeSRegister(OpSd, "Sd", Vstrs);
2341 assert(CondARM32::isDefined(Cond)); 2342 assert(CondARM32::isDefined(Cond));
2342 IValueT Address; 2343 IValueT Address;
2343 if (encodeAddress(OpAddress, Address, TInfo) != EncodedAsImmRegOffset) 2344 IValueT AddressEncoding =
2344 assert(false); 2345 encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4);
2346 (void)AddressEncoding; // Make MINIMAL build happy.
2347 assert(AddressEncoding == EncodedAsImmRegOffset);
2345 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 2348 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
2346 IValueT Encoding = 2349 IValueT Encoding =
2347 B27 | B26 | B24 | B11 | B9 | (encodeCondition(Cond) << kConditionShift) | 2350 B27 | B26 | B24 | B11 | B9 | (encodeCondition(Cond) << kConditionShift) |
2348 (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sd) << 12) | Address; 2351 (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sd) << 12) | Address;
2349 emitInst(Encoding); 2352 emitInst(Encoding);
2350 } 2353 }
2351 2354
2352 void AssemblerARM32::vsubs(const Operand *OpSd, const Operand *OpSn, 2355 void AssemblerARM32::vsubs(const Operand *OpSd, const Operand *OpSn,
2353 const Operand *OpSm, CondARM32::Cond Cond) { 2356 const Operand *OpSm, CondARM32::Cond Cond) {
2354 // VSUB (floating-point) - ARM section A8.8.415, encoding A2: 2357 // VSUB (floating-point) - ARM section A8.8.415, encoding A2:
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2421 // 2424 //
2422 // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and 2425 // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and
2423 // iiiiiiii=NumConsecRegs. 2426 // iiiiiiii=NumConsecRegs.
2424 constexpr IValueT VpushOpcode = 2427 constexpr IValueT VpushOpcode =
2425 B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9; 2428 B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9;
2426 emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs); 2429 emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs);
2427 } 2430 }
2428 2431
2429 } // end of namespace ARM32 2432 } // end of namespace ARM32
2430 } // end of namespace Ice 2433 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | tests_lit/assembler/arm32/vldr.vstr.imm.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698