| 543 | }; |
| 544 | |
| 545 | static inline bool pick_fp_opcode(const Vec& reg, uint32_t s_op, uint32_t s_hf, uint32_t v_op, uint32_t v_hf, Opcode* opcode, uint32_t* sz_out) noexcept { |
| 546 | static constexpr uint32_t kQBitIndex = 30; |
| 547 | |
| 548 | static const EncodeFpOpcodeBits sz_bits_table[InstDB::kHF_Count] = { |
| 549 | { B(2) | B(1) , { 0u , 0u, B(22) } }, |
| 550 | { B(2) | B(1) | B(0), { 0u , 0u, 0u } }, |
| 551 | { B(2) | B(1) | B(0), { B(23) | B(22) , 0u, B(22) } }, |
| 552 | { B(2) | B(1) | B(0), { B(22) | B(20) | B(19) , 0u, B(22) } }, |
| 553 | { B(2) | B(1) | B(0), { B(22) | B(21) | B(15) | B(14), 0u, B(22) } }, |
| 554 | { B(2) | B(1) | B(0), { B(23) , 0u, B(22) } } |
| 555 | }; |
| 556 | |
| 557 | if (!reg.has_element_type()) { |
| 558 | // Scalar operation [HSD]. |
| 559 | uint32_t sz = diff(reg.reg_type(), RegType::kVec16); |
| 560 | if (sz > 2u || !Support::bit_test(sz_bits_table[s_hf].size_mask, sz)) { |
| 561 | return false; |
| 562 | } |
| 563 | |
| 564 | opcode->reset(sz_bits_table[s_hf].mask[sz] ^ s_op); |
| 565 | *sz_out = sz; |
| 566 | return s_op != 0; |
| 567 | } |
| 568 | else { |
| 569 | // Vector operation [HSD]. |
| 570 | uint32_t q = diff(reg.reg_type(), RegType::kVec64); |
| 571 | uint32_t sz = diff(reg.element_type(), VecElementType::kH); |
| 572 | |
| 573 | if (q > 1u || sz > 2u || !Support::bit_test(sz_bits_table[v_hf].size_mask, sz)) { |
| 574 | return false; |
| 575 | } |
| 576 | |
| 577 | opcode->reset(sz_bits_table[v_hf].mask[sz] ^ (v_op | (q << kQBitIndex))); |
| 578 | *sz_out = sz; |
| 579 | return v_op != 0; |
| 580 | } |
| 581 | } |
| 582 | |
| 583 | static inline bool pick_fp_opcode(const Vec& reg, uint32_t s_op, uint32_t s_hf, uint32_t v_op, uint32_t v_hf, Opcode* opcode) noexcept { |
| 584 | uint32_t sz; |
no test coverage detected