| 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 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 290 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 291 AssemblerFixup *F = createTextFixup(Text, InstSize); | 291 AssemblerFixup *F = createTextFixup(Text, InstSize); |
| 292 emitFixup(F); | 292 emitFixup(F); |
| 293 for (SizeT I = 0; I < InstSize; ++I) | 293 for (SizeT I = 0; I < InstSize; ++I) |
| 294 Buffer.emit<char>(0); | 294 Buffer.emit<char>(0); |
| 295 } | 295 } |
| 296 | 296 |
| 297 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Type, | 297 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Type, |
| 298 IValueT Opcode, bool SetCc, IValueT Rn, | 298 IValueT Opcode, bool SetCc, IValueT Rn, |
| 299 IValueT Rd, IValueT Imm12) { | 299 IValueT Rd, IValueT Imm12) { |
| 300 assert(isGPRRegisterDefined(Rd)); | 300 if (!isGPRRegisterDefined(Rd) || !isConditionDefined(Cond)) |
| 301 // TODO(kschimpf): Remove void cast when MINIMAL build allows. | 301 return setNeedsTextFixup(); |
| 302 (void)isGPRRegisterDefined(Rd); | |
| 303 assert(Cond != CondARM32::kNone); | |
| 304 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 302 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 305 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | 303 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | |
| 306 (Type << kTypeShift) | (Opcode << kOpcodeShift) | | 304 (Type << kTypeShift) | (Opcode << kOpcodeShift) | |
| 307 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | | 305 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | |
| 308 (Rd << kRdShift) | Imm12; | 306 (Rd << kRdShift) | Imm12; |
| 309 emitInst(Encoding); | 307 emitInst(Encoding); |
| 310 } | 308 } |
| 311 | 309 |
| 312 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset, | 310 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset, |
| 313 bool Link) { | 311 bool Link) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 333 const IOffsetT Position = Buffer.size(); | 331 const IOffsetT Position = Buffer.size(); |
| 334 // Use the offset field of the branch instruction for linking the sites. | 332 // Use the offset field of the branch instruction for linking the sites. |
| 335 emitType05(Cond, L->getEncodedPosition(), Link); | 333 emitType05(Cond, L->getEncodedPosition(), Link); |
| 336 if (!needsTextFixup()) | 334 if (!needsTextFixup()) |
| 337 L->linkTo(Position); | 335 L->linkTo(Position); |
| 338 } | 336 } |
| 339 | 337 |
| 340 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType, | 338 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType, |
| 341 bool IsLoad, bool IsByte, IValueT Rt, | 339 bool IsLoad, bool IsByte, IValueT Rt, |
| 342 IValueT Address) { | 340 IValueT Address) { |
| 343 assert(isGPRRegisterDefined(Rt)); | 341 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) |
| 344 assert(Cond != CondARM32::kNone); | 342 return setNeedsTextFixup(); |
| 345 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 343 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 346 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | 344 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | |
| 347 (InstType << kTypeShift) | (IsLoad ? L : 0) | | 345 (InstType << kTypeShift) | (IsLoad ? L : 0) | |
| 348 (IsByte ? B : 0) | (Rt << kRdShift) | Address; | 346 (IsByte ? B : 0) | (Rt << kRdShift) | Address; |
| 349 emitInst(Encoding); | 347 emitInst(Encoding); |
| 350 } | 348 } |
| 351 | 349 |
| 350 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, |
| 351 const Operand *OpSrc1, bool SetFlags, |
| 352 CondARM32::Cond Cond) { |
| 353 IValueT Rd; |
| 354 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| 355 return setNeedsTextFixup(); |
| 356 IValueT Rn; |
| 357 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
| 358 return setNeedsTextFixup(); |
| 359 constexpr IValueT Adc = B2 | B0; // 0101 |
| 360 IValueT Src1Value; |
| 361 // TODO(kschimpf) Other possible decodings of adc. |
| 362 switch (decodeOperand(OpSrc1, Src1Value)) { |
| 363 default: |
| 364 return setNeedsTextFixup(); |
| 365 case DecodedAsRotatedImm8: { |
| 366 // ADC (Immediated) = ARM section A8.8.1, encoding A1: |
| 367 // adc{s}<c> <Rd>, <Rn>, #<RotatedImm8> |
| 368 // |
| 369 // cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 370 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8. |
| 371 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) |
| 372 // Conditions of rule violated. |
| 373 return setNeedsTextFixup(); |
| 374 emitType01(Cond, kInstTypeDataImmediate, Adc, SetFlags, Rn, Rd, Src1Value); |
| 375 return; |
| 376 } |
| 377 }; |
| 378 } |
| 379 |
| 352 void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, | 380 void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, |
| 353 const Operand *OpSrc1, bool SetFlags, | 381 const Operand *OpSrc1, bool SetFlags, |
| 354 CondARM32::Cond Cond) { | 382 CondARM32::Cond Cond) { |
| 355 IValueT Rd; | 383 IValueT Rd; |
| 356 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 384 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| 357 return setNeedsTextFixup(); | 385 return setNeedsTextFixup(); |
| 358 IValueT Rn; | 386 IValueT Rn; |
| 359 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 387 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
| 360 return setNeedsTextFixup(); | 388 return setNeedsTextFixup(); |
| 361 constexpr IValueT Add = B2; // 0100 | 389 constexpr IValueT Add = B2; // 0100 |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 // Conditions of rule violated. | 591 // Conditions of rule violated. |
| 564 return setNeedsTextFixup(); | 592 return setNeedsTextFixup(); |
| 565 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value); | 593 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value); |
| 566 return; | 594 return; |
| 567 } | 595 } |
| 568 } | 596 } |
| 569 } | 597 } |
| 570 | 598 |
| 571 } // end of namespace ARM32 | 599 } // end of namespace ARM32 |
| 572 } // end of namespace Ice | 600 } // end of namespace Ice |
| OLD | NEW |