Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |