| 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 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 if (!isGPRRegisterDefined(Rd) || !isConditionDefined(Cond)) | 347 if (!isGPRRegisterDefined(Rd) || !isConditionDefined(Cond)) |
| 348 return setNeedsTextFixup(); | 348 return setNeedsTextFixup(); |
| 349 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 349 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 350 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | 350 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | |
| 351 (Type << kTypeShift) | (Opcode << kOpcodeShift) | | 351 (Type << kTypeShift) | (Opcode << kOpcodeShift) | |
| 352 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | | 352 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | |
| 353 (Rd << kRdShift) | Imm12; | 353 (Rd << kRdShift) | Imm12; |
| 354 emitInst(Encoding); | 354 emitInst(Encoding); |
| 355 } | 355 } |
| 356 | 356 |
| 357 void AssemblerARM32::emitType01(IValueT Opcode, const Operand *OpRd, |
| 358 const Operand *OpRn, const Operand *OpSrc1, |
| 359 bool SetFlags, CondARM32::Cond Cond) { |
| 360 IValueT Rd; |
| 361 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| 362 return setNeedsTextFixup(); |
| 363 IValueT Rn; |
| 364 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) |
| 365 return setNeedsTextFixup(); |
| 366 IValueT Src1Value; |
| 367 // TODO(kschimpf) Other possible decodings of add. |
| 368 switch (decodeOperand(OpSrc1, Src1Value)) { |
| 369 default: |
| 370 return setNeedsTextFixup(); |
| 371 case DecodedAsRegister: { |
| 372 // XXX (register) |
| 373 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} |
| 374 // |
| 375 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 376 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
| 377 constexpr IValueT Imm5 = 0; |
| 378 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); |
| 379 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) |
| 380 // Conditions of rule violated. |
| 381 return setNeedsTextFixup(); |
| 382 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, |
| 383 Src1Value); |
| 384 return; |
| 385 } |
| 386 case DecodedAsRotatedImm8: { |
| 387 // XXX (Immediate) |
| 388 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8> |
| 389 // |
| 390 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 391 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8. |
| 392 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) |
| 393 // Conditions of rule violated. |
| 394 return setNeedsTextFixup(); |
| 395 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd, |
| 396 Src1Value); |
| 397 return; |
| 398 } |
| 399 } |
| 400 } |
| 401 |
| 357 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset, | 402 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset, |
| 358 bool Link) { | 403 bool Link) { |
| 359 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and | 404 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and |
| 360 // iiiiiiiiiiiiiiiiiiiiiiii= | 405 // iiiiiiiiiiiiiiiiiiiiiiii= |
| 361 // EncodedBranchOffset(cccc101l000000000000000000000000, Offset); | 406 // EncodedBranchOffset(cccc101l000000000000000000000000, Offset); |
| 362 if (!isConditionDefined(Cond)) | 407 if (!isConditionDefined(Cond)) |
| 363 return setNeedsTextFixup(); | 408 return setNeedsTextFixup(); |
| 364 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 409 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 365 IValueT Encoding = static_cast<int32_t>(Cond) << kConditionShift | | 410 IValueT Encoding = static_cast<int32_t>(Cond) << kConditionShift | |
| 366 5 << kTypeShift | (Link ? 1 : 0) << kLinkShift; | 411 5 << kTypeShift | (Link ? 1 : 0) << kLinkShift; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | | 449 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | |
| 405 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | | 450 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | |
| 406 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | | 451 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | |
| 407 (Rm << kRmShift); | 452 (Rm << kRmShift); |
| 408 emitInst(Encoding); | 453 emitInst(Encoding); |
| 409 } | 454 } |
| 410 | 455 |
| 411 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, | 456 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, |
| 412 const Operand *OpSrc1, bool SetFlags, | 457 const Operand *OpSrc1, bool SetFlags, |
| 413 CondARM32::Cond Cond) { | 458 CondARM32::Cond Cond) { |
| 414 IValueT Rd; | 459 // ADC (register) - ARM section 18.8.2, encoding A1: |
| 415 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 460 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} |
| 416 return setNeedsTextFixup(); | 461 // |
| 417 IValueT Rn; | 462 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 418 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 463 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
| 419 return setNeedsTextFixup(); | 464 // |
| 465 // ADC (Immediate) - ARM section A8.8.1, encoding A1: |
| 466 // adc{s}<c> <Rd>, <Rn>, #<RotatedImm8> |
| 467 // |
| 468 // cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 469 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8. |
| 420 constexpr IValueT Adc = B2 | B0; // 0101 | 470 constexpr IValueT Adc = B2 | B0; // 0101 |
| 421 IValueT Src1Value; | 471 emitType01(Adc, OpRd, OpRn, OpSrc1, SetFlags, Cond); |
| 422 // TODO(kschimpf) Other possible decodings of adc. | |
| 423 switch (decodeOperand(OpSrc1, Src1Value)) { | |
| 424 default: | |
| 425 return setNeedsTextFixup(); | |
| 426 case DecodedAsRegister: { | |
| 427 // ADC (register) - ARM section 18.8.2, encoding A1: | |
| 428 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} | |
| 429 // | |
| 430 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 431 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | |
| 432 constexpr IValueT Imm5 = 0; | |
| 433 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); | |
| 434 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) | |
| 435 // Conditions of rule violated. | |
| 436 return setNeedsTextFixup(); | |
| 437 emitType01(Cond, kInstTypeDataRegister, Adc, SetFlags, Rn, Rd, Src1Value); | |
| 438 return; | |
| 439 } | |
| 440 case DecodedAsRotatedImm8: { | |
| 441 // ADC (Immediate) - ARM section A8.8.1, encoding A1: | |
| 442 // adc{s}<c> <Rd>, <Rn>, #<RotatedImm8> | |
| 443 // | |
| 444 // cccc0010101snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 445 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. | |
| 446 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) | |
| 447 // Conditions of rule violated. | |
| 448 return setNeedsTextFixup(); | |
| 449 emitType01(Cond, kInstTypeDataImmediate, Adc, SetFlags, Rn, Rd, Src1Value); | |
| 450 return; | |
| 451 } | |
| 452 }; | |
| 453 } | 472 } |
| 454 | 473 |
| 455 void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, | 474 void AssemblerARM32::add(const Operand *OpRd, const Operand *OpRn, |
| 456 const Operand *OpSrc1, bool SetFlags, | 475 const Operand *OpSrc1, bool SetFlags, |
| 457 CondARM32::Cond Cond) { | 476 CondARM32::Cond Cond) { |
| 458 IValueT Rd; | 477 // ADD (register) - ARM section A8.8.7, encoding A1: |
| 459 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 478 // add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} |
| 460 return setNeedsTextFixup(); | 479 // ADD (Sp plus register) - ARM section A8.8.11, encoding A1: |
| 461 IValueT Rn; | 480 // add{s}<c> sp, <Rn>, <Rm>{, <shiff>} |
| 462 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 481 // |
| 463 return setNeedsTextFixup(); | 482 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 483 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
| 484 // |
| 485 // ADD (Immediate) - ARM section A8.8.5, encoding A1: |
| 486 // add{s}<c> <Rd>, <Rn>, #<RotatedImm8> |
| 487 // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1. |
| 488 // add{s}<c> <Rd>, sp, #<RotatedImm8> |
| 489 // |
| 490 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 491 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8. |
| 464 constexpr IValueT Add = B2; // 0100 | 492 constexpr IValueT Add = B2; // 0100 |
| 465 IValueT Src1Value; | 493 emitType01(Add, OpRd, OpRn, OpSrc1, SetFlags, Cond); |
| 466 // TODO(kschimpf) Other possible decodings of add. | |
| 467 switch (decodeOperand(OpSrc1, Src1Value)) { | |
| 468 default: | |
| 469 return setNeedsTextFixup(); | |
| 470 case DecodedAsRegister: { | |
| 471 // ADD (register) - ARM section A8.8.7, encoding A1: | |
| 472 // add{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} | |
| 473 // ADD (Sp plus register) - ARM section A8.8.11, encoding A1: | |
| 474 // add{s}<c> sp, <Rn>, <Rm>{, <shiff>} | |
| 475 // | |
| 476 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 477 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | |
| 478 constexpr IValueT Imm5 = 0; | |
| 479 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); | |
| 480 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) | |
| 481 // Conditions of rule violated. | |
| 482 return setNeedsTextFixup(); | |
| 483 emitType01(Cond, kInstTypeDataRegister, Add, SetFlags, Rn, Rd, Src1Value); | |
| 484 return; | |
| 485 } | |
| 486 case DecodedAsRotatedImm8: { | |
| 487 // ADD (Immediate) - ARM section A8.8.5, encoding A1: | |
| 488 // add{s}<c> <Rd>, <Rn>, #<RotatedImm8> | |
| 489 // ADD (SP plus immediate) - ARM section A8.8.9, encoding A1. | |
| 490 // add{s}<c> <Rd>, sp, #<RotatedImm8> | |
| 491 // | |
| 492 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 493 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. | |
| 494 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) | |
| 495 // Conditions of rule violated. | |
| 496 return setNeedsTextFixup(); | |
| 497 emitType01(Cond, kInstTypeDataImmediate, Add, SetFlags, Rn, Rd, Src1Value); | |
| 498 return; | |
| 499 } | |
| 500 } | |
| 501 } | 494 } |
| 502 | 495 |
| 503 void AssemblerARM32::and_(const Operand *OpRd, const Operand *OpRn, | 496 void AssemblerARM32::and_(const Operand *OpRd, const Operand *OpRn, |
| 504 const Operand *OpSrc1, bool SetFlags, | 497 const Operand *OpSrc1, bool SetFlags, |
| 505 CondARM32::Cond Cond) { | 498 CondARM32::Cond Cond) { |
| 506 IValueT Rd; | 499 // AND (register) - ARM section A8.8.14, encoding A1: |
| 507 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 500 // and{s}<c> <Rd>, <Rn>{, <shift>} |
| 508 return setNeedsTextFixup(); | 501 // |
| 509 IValueT Rn; | 502 // cccc0000000snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 510 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 503 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
| 511 return setNeedsTextFixup(); | 504 // |
| 505 // AND (Immediate) - ARM section A8.8.13, encoding A1: |
| 506 // and{s}<c> <Rd>, <Rn>, #<RotatedImm8> |
| 507 // |
| 508 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 509 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. |
| 512 constexpr IValueT And = 0; // 0000 | 510 constexpr IValueT And = 0; // 0000 |
| 513 IValueT Src1Value; | 511 emitType01(And, OpRd, OpRn, OpSrc1, SetFlags, Cond); |
| 514 // TODO(kschimpf) Other possible decodings of add. | |
| 515 switch (decodeOperand(OpSrc1, Src1Value)) { | |
| 516 default: | |
| 517 return setNeedsTextFixup(); | |
| 518 case DecodedAsRegister: { | |
| 519 // AND (register) - ARM section A8.8.14, encoding A1: | |
| 520 // and{s}<c> <Rd>, <Rn>{, <shift>} | |
| 521 // | |
| 522 // cccc0000000snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 523 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | |
| 524 constexpr IValueT Imm5 = 0; | |
| 525 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); | |
| 526 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) | |
| 527 // Conditions of rule violated. | |
| 528 return setNeedsTextFixup(); | |
| 529 emitType01(Cond, kInstTypeDataRegister, And, SetFlags, Rn, Rd, Src1Value); | |
| 530 return; | |
| 531 } | |
| 532 case DecodedAsRotatedImm8: { | |
| 533 // AND (Immediate) - ARM section A8.8.13, encoding A1: | |
| 534 // and{s}<c> <Rd>, <Rn>, #<RotatedImm8> | |
| 535 // | |
| 536 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 537 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. | |
| 538 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) | |
| 539 // Conditions of rule violated. | |
| 540 return setNeedsTextFixup(); | |
| 541 emitType01(Cond, kInstTypeDataImmediate, And, SetFlags, Rn, Rd, Src1Value); | |
| 542 return; | |
| 543 } | |
| 544 } | |
| 545 } | 512 } |
| 546 | 513 |
| 547 void AssemblerARM32::b(Label *L, CondARM32::Cond Cond) { | 514 void AssemblerARM32::b(Label *L, CondARM32::Cond Cond) { |
| 548 emitBranch(L, Cond, false); | 515 emitBranch(L, Cond, false); |
| 549 } | 516 } |
| 550 | 517 |
| 551 void AssemblerARM32::bkpt(uint16_t Imm16) { | 518 void AssemblerARM32::bkpt(uint16_t Imm16) { |
| 552 // BKPT - ARM section A*.8.24 - encoding A1: | 519 // BKPT - ARM section A*.8.24 - encoding A1: |
| 553 // bkpt #<Imm16> | 520 // bkpt #<Imm16> |
| 554 // | 521 // |
| (...skipping 11 matching lines...) Expand all Loading... |
| 566 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. | 533 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. |
| 567 if (!(isGPRRegisterDefined(Rm) && isConditionDefined(Cond))) | 534 if (!(isGPRRegisterDefined(Rm) && isConditionDefined(Cond))) |
| 568 return setNeedsTextFixup(); | 535 return setNeedsTextFixup(); |
| 569 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 536 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 570 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | | 537 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | |
| 571 B21 | (0xfff << 8) | B4 | | 538 B21 | (0xfff << 8) | B4 | |
| 572 (encodeGPRRegister(Rm) << kRmShift); | 539 (encodeGPRRegister(Rm) << kRmShift); |
| 573 emitInst(Encoding); | 540 emitInst(Encoding); |
| 574 } | 541 } |
| 575 | 542 |
| 543 void AssemblerARM32::eor(const Operand *OpRd, const Operand *OpRn, |
| 544 const Operand *OpSrc1, bool SetFlags, |
| 545 CondARM32::Cond Cond) { |
| 546 // EOR (register) - ARM section A*.8.47, encoding A1: |
| 547 // eor{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} |
| 548 // |
| 549 // cccc0000001snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 550 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
| 551 // |
| 552 // EOR (Immediate) - ARM section A8.*.46, encoding A1: |
| 553 // eor{s}<c> <Rd>, <Rn>, #RotatedImm8 |
| 554 // |
| 555 // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 556 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8. |
| 557 constexpr IValueT Eor = B0; // 0001 |
| 558 emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond); |
| 559 } |
| 560 |
| 576 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, | 561 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, |
| 577 CondARM32::Cond Cond) { | 562 CondARM32::Cond Cond) { |
| 578 IValueT Rt; | 563 IValueT Rt; |
| 579 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) | 564 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) |
| 580 return setNeedsTextFixup(); | 565 return setNeedsTextFixup(); |
| 581 IValueT Address; | 566 IValueT Address; |
| 582 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) | 567 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) |
| 583 return setNeedsTextFixup(); | 568 return setNeedsTextFixup(); |
| 584 // LDR (immediate) - ARM section A8.8.63, encoding A1: | 569 // LDR (immediate) - ARM section A8.8.63, encoding A1: |
| 585 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 | 570 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 constexpr IValueT Imm16 = 0; | 669 constexpr IValueT Imm16 = 0; |
| 685 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | B25 | | 670 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | B25 | |
| 686 B24 | B22 | ((Imm16 >> 12) << 16) | Rd << kRdShift | | 671 B24 | B22 | ((Imm16 >> 12) << 16) | Rd << kRdShift | |
| 687 (Imm16 & 0xfff); | 672 (Imm16 & 0xfff); |
| 688 emitInst(Encoding); | 673 emitInst(Encoding); |
| 689 } | 674 } |
| 690 | 675 |
| 691 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn, | 676 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn, |
| 692 const Operand *OpSrc1, bool SetFlags, | 677 const Operand *OpSrc1, bool SetFlags, |
| 693 CondARM32::Cond Cond) { | 678 CondARM32::Cond Cond) { |
| 694 IValueT Rd; | 679 // SBC (register) - ARM section 18.8.162, encoding A1: |
| 695 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 680 // sbc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} |
| 696 return setNeedsTextFixup(); | 681 // |
| 697 IValueT Rn; | 682 // cccc0000110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 698 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 683 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
| 699 return setNeedsTextFixup(); | 684 // |
| 685 // SBC (Immediate) - ARM section A8.8.161, encoding A1: |
| 686 // sbc{s}<c> <Rd>, <Rn>, #<RotatedImm8> |
| 687 // |
| 688 // cccc0010110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 689 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8. |
| 700 constexpr IValueT Sbc = B2 | B1; // 0110 | 690 constexpr IValueT Sbc = B2 | B1; // 0110 |
| 701 IValueT Src1Value; | 691 emitType01(Sbc, OpRd, OpRn, OpSrc1, SetFlags, Cond); |
| 702 // TODO(kschimpf) Other possible decodings of sbc. | |
| 703 switch (decodeOperand(OpSrc1, Src1Value)) { | |
| 704 default: | |
| 705 return setNeedsTextFixup(); | |
| 706 case DecodedAsRegister: { | |
| 707 // SBC (register) - ARM section 18.8.162, encoding A1: | |
| 708 // sbc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} | |
| 709 // | |
| 710 // cccc0000110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 711 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | |
| 712 constexpr IValueT Imm5 = 0; | |
| 713 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); | |
| 714 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) | |
| 715 // Conditions of rule violated. | |
| 716 return setNeedsTextFixup(); | |
| 717 emitType01(Cond, kInstTypeDataRegister, Sbc, SetFlags, Rn, Rd, Src1Value); | |
| 718 return; | |
| 719 } | |
| 720 case DecodedAsRotatedImm8: { | |
| 721 // SBC (Immediate) - ARM section A8.8.161, encoding A1: | |
| 722 // sbc{s}<c> <Rd>, <Rn>, #<RotatedImm8> | |
| 723 // | |
| 724 // cccc0010110snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 725 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. | |
| 726 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) | |
| 727 // Conditions of rule violated. | |
| 728 return setNeedsTextFixup(); | |
| 729 emitType01(Cond, kInstTypeDataImmediate, Sbc, SetFlags, Rn, Rd, Src1Value); | |
| 730 return; | |
| 731 } | |
| 732 }; | |
| 733 } | 692 } |
| 734 | 693 |
| 735 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, | 694 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, |
| 736 CondARM32::Cond Cond) { | 695 CondARM32::Cond Cond) { |
| 737 IValueT Rt; | 696 IValueT Rt; |
| 738 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) | 697 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) |
| 739 return setNeedsTextFixup(); | 698 return setNeedsTextFixup(); |
| 740 IValueT Address; | 699 IValueT Address; |
| 741 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) | 700 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) |
| 742 return setNeedsTextFixup(); | 701 return setNeedsTextFixup(); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 Rm == RegARM32::Encoded_Reg_pc) | 792 Rm == RegARM32::Encoded_Reg_pc) |
| 834 llvm::report_fatal_error("Mul instruction unpredictable on pc"); | 793 llvm::report_fatal_error("Mul instruction unpredictable on pc"); |
| 835 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. | 794 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. |
| 836 constexpr IValueT MulOpcode = 0; | 795 constexpr IValueT MulOpcode = 0; |
| 837 emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags); | 796 emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags); |
| 838 } | 797 } |
| 839 | 798 |
| 840 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, | 799 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, |
| 841 const Operand *OpSrc1, bool SetFlags, | 800 const Operand *OpSrc1, bool SetFlags, |
| 842 CondARM32::Cond Cond) { | 801 CondARM32::Cond Cond) { |
| 843 IValueT Rd; | 802 // SUB (register) - ARM section A8.8.223, encoding A1: |
| 844 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) | 803 // sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} |
| 845 return setNeedsTextFixup(); | 804 // SUB (SP minus register): See ARM section 8.8.226, encoding A1: |
| 846 IValueT Rn; | 805 // sub{s}<c> <Rd>, sp, <Rm>{, <Shift>} |
| 847 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) | 806 // |
| 848 return setNeedsTextFixup(); | 807 // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 808 // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags. |
| 809 // |
| 810 // Sub (Immediate) - ARM section A8.8.222, encoding A1: |
| 811 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8> |
| 812 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1: |
| 813 // sub{s}<c> sp, <Rn>, #<RotatedImm8> |
| 814 // |
| 815 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 816 // s=SetFlags and iiiiiiiiiiii=Src1Value=RotatedImm8 |
| 849 constexpr IValueT Sub = B1; // 0010 | 817 constexpr IValueT Sub = B1; // 0010 |
| 850 IValueT Src1Value; | 818 emitType01(Sub, OpRd, OpRn, OpSrc1, SetFlags, Cond); |
| 851 // TODO(kschimpf) Other possible decodings of sub. | |
| 852 switch (decodeOperand(OpSrc1, Src1Value)) { | |
| 853 default: | |
| 854 return setNeedsTextFixup(); | |
| 855 case DecodedAsRegister: { | |
| 856 // SUB (register) - ARM section A8.8.223, encoding A1: | |
| 857 // sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} | |
| 858 // SUB (SP minus register): See ARM section 8.8.226, encoding A1: | |
| 859 // sub{s}<c> <Rd>, sp, <Rm>{, <Shift>} | |
| 860 // | |
| 861 // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 862 // mmmm=Rm, iiiiii=shift, tt=ShiftKind, and s=SetFlags. | |
| 863 constexpr IValueT Shift = 0; | |
| 864 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Shift); | |
| 865 if (((Rd == RegARM32::Encoded_Reg_pc) && SetFlags)) | |
| 866 // Conditions of rule violated. | |
| 867 return setNeedsTextFixup(); | |
| 868 emitType01(Cond, kInstTypeDataRegister, Sub, SetFlags, Rn, Rd, Src1Value); | |
| 869 return; | |
| 870 } | |
| 871 case DecodedAsRotatedImm8: { | |
| 872 // Sub (Immediate) - ARM section A8.8.222, encoding A1: | |
| 873 // sub{s}<c> <Rd>, <Rn>, #<RotatedImm8> | |
| 874 // Sub (Sp minus immediate) - ARM section A8.*.225, encoding A1: | |
| 875 // sub{s}<c> sp, <Rn>, #<RotatedImm8> | |
| 876 // | |
| 877 // cccc0010010snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | |
| 878 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. | |
| 879 if (Rd == RegARM32::Encoded_Reg_pc) | |
| 880 // Conditions of rule violated. | |
| 881 return setNeedsTextFixup(); | |
| 882 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value); | |
| 883 return; | |
| 884 } | |
| 885 } | |
| 886 } | 819 } |
| 887 | 820 |
| 888 } // end of namespace ARM32 | 821 } // end of namespace ARM32 |
| 889 } // end of namespace Ice | 822 } // end of namespace Ice |
| OLD | NEW |