| 575 | } |
| 576 | |
| 577 | static int unpack_vector(InstructionOperand& oper, Register* result) |
| 578 | { |
| 579 | if (oper.operandClass == REG) |
| 580 | { |
| 581 | /* register without an arrangement specification is just a register |
| 582 | examples: "d18", "d6", "v7" */ |
| 583 | if (oper.arrSpec == ARRSPEC_NONE) |
| 584 | { |
| 585 | result[0] = oper.reg[0]; |
| 586 | return 1; |
| 587 | } |
| 588 | |
| 589 | /* require V register with valid arrangement spec |
| 590 | examples: "v17.2s", "v8.4h", "v21.8b" */ |
| 591 | if (oper.reg[0] < REG_V0 || oper.reg[0] > REG_V31) |
| 592 | return 0; |
| 593 | if (oper.arrSpec <= ARRSPEC_NONE || oper.arrSpec > ARRSPEC_1BYTE) |
| 594 | return 0; |
| 595 | |
| 596 | /* lookup, copy result */ |
| 597 | if (oper.laneUsed) |
| 598 | { |
| 599 | ArrangementSpec spec = promote_spec(oper.arrSpec); |
| 600 | |
| 601 | int n_lanes = v_unpack_lookup_sz[spec]; |
| 602 | |
| 603 | if (oper.lane >= n_lanes) |
| 604 | return 0; |
| 605 | |
| 606 | // int n = v_unpack_lookup_sz[spec]; |
| 607 | // for (int i = 0; i < n; ++i) |
| 608 | result[0] = v_unpack_lookup[spec][oper.reg[0] - REG_V0][oper.lane]; |
| 609 | |
| 610 | return 1; |
| 611 | } |
| 612 | |
| 613 | int n = v_unpack_lookup_sz[oper.arrSpec]; |
| 614 | for (int i = 0; i < n; ++i) |
| 615 | result[i] = v_unpack_lookup[oper.arrSpec][oper.reg[0] - REG_V0][i]; |
| 616 | return n; |
| 617 | } |
| 618 | else if (oper.operandClass == MULTI_REG) |
| 619 | { |
| 620 | if (oper.laneUsed) |
| 621 | { |
| 622 | /* multireg with a lane |
| 623 | examples: "ld2 {v17.d, v18.d}[1], [x20]" */ |
| 624 | |
| 625 | ArrangementSpec spec = promote_spec(oper.arrSpec); |
| 626 | |
| 627 | int n = 0; |
| 628 | for (int i = 0; i < 4 && oper.reg[i] != REG_NONE; i++) |
| 629 | { |
| 630 | int n_lanes = v_unpack_lookup_sz[spec]; |
| 631 | if (oper.lane >= n_lanes) |
| 632 | return 0; |
| 633 | result[i] = v_unpack_lookup[spec][oper.reg[i] - REG_V0][oper.lane]; |
| 634 | n += 1; |
no test coverage detected