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 |