| 778 | (uint32_t(OperandType::k##OP3) << 9)) |
| 779 | |
| 780 | Error Assembler::_emit(InstId inst_id, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* op_ext) { |
| 781 | // Logging/Validation/Error. |
| 782 | constexpr InstOptions kRequiresSpecialHandling = InstOptions::kReserved; |
| 783 | |
| 784 | Error err; |
| 785 | CodeWriter writer(this); |
| 786 | |
| 787 | // Combine all instruction options and also check whether the instruction |
| 788 | // is valid. All options that require special handling (including invalid |
| 789 | // instruction) are handled by the next branch. |
| 790 | InstOptions options = InstOptions(inst_id - 1 >= Inst::_kIdCount - 1) | InstOptions((size_t)(_buffer_end - writer.cursor()) < 4) | inst_options() | forced_inst_options(); |
| 791 | |
| 792 | CondCode inst_cc = BaseInst::extract_arm_cond_code(inst_id); |
| 793 | inst_id = inst_id & uint32_t(InstIdParts::kRealId); |
| 794 | |
| 795 | if (inst_id >= Inst::_kIdCount) { |
| 796 | inst_id = 0; |
| 797 | } |
| 798 | |
| 799 | const InstDB::InstInfo* inst_info = &InstDB::_inst_info_table[inst_id]; |
| 800 | uint32_t encoding_index = inst_info->_encoding_data_index; |
| 801 | |
| 802 | Opcode opcode; |
| 803 | uint32_t isign4; |
| 804 | uint32_t inst_flags; |
| 805 | |
| 806 | const Operand_& o3 = op_ext[EmitterUtils::kOp3]; |
| 807 | const Operand_* rm_rel = nullptr; |
| 808 | |
| 809 | uint32_t multiple_op_data[4]; |
| 810 | uint32_t multiple_op_count; |
| 811 | |
| 812 | // These are only used when instruction uses a relative displacement. |
| 813 | OffsetFormat offset_format; // Offset format. |
| 814 | uint64_t offset_value; // Offset value (if known). |
| 815 | |
| 816 | if (ASMJIT_UNLIKELY(Support::test(options, kRequiresSpecialHandling))) { |
| 817 | if (ASMJIT_UNLIKELY(!_code)) { |
| 818 | return report_error(make_error(Error::kNotInitialized)); |
| 819 | } |
| 820 | |
| 821 | // Unknown instruction. |
| 822 | if (ASMJIT_UNLIKELY(inst_id == 0)) { |
| 823 | goto InvalidInstruction; |
| 824 | } |
| 825 | |
| 826 | // Condition code can only be used with 'B' instruction. |
| 827 | if (ASMJIT_UNLIKELY(inst_cc != CondCode::kAL && inst_id != Inst::kIdB)) { |
| 828 | goto InvalidInstruction; |
| 829 | } |
| 830 | |
| 831 | // Grow request, happens rarely. |
| 832 | err = writer.ensure_space(this, 4); |
| 833 | if (ASMJIT_UNLIKELY(err != Error::kOk)) { |
| 834 | goto Failed; |
| 835 | } |
| 836 | |
| 837 | #ifndef ASMJIT_NO_INTROSPECTION |
nothing calls this directly
no test coverage detected