|
83 | 83 |
|
84 | 84 | ;;; ??? pack
|
85 | 85 |
|
| 86 | +(define_insn "riscv_bitmanip_packsi" |
| 87 | + [(set (match_operand:SI 0 "register_operand" "=r") |
| 88 | + (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r") (const_int 65280)) |
| 89 | + (ashift:SI (match_operand:SI 2 "register_operand" "r") (const_int 16))))] |
| 90 | + "TARGET_ZBP" |
| 91 | + { return TARGET_64BIT ? "packw\t%0,%1,%2" : "pack\t%0,%1,%2"; } |
| 92 | + [(set_attr "type" "bitmanip") |
| 93 | + (set_attr "length" "4")]) |
| 94 | + |
| 95 | +(define_insn "riscv_bitmanip_packdi" |
| 96 | + [(set (match_operand:DI 0 "register_operand" "=r") |
| 97 | + (ior:DI (and:SI (match_operand:DI 1 "register_operand" "r") (const_int 65280)) |
| 98 | + (ashift:DI (match_operand:DI 2 "register_operand" "r") (const_int 32))))] |
| 99 | + "TARGET_ZBP && TARGET_64BIT" |
| 100 | + "pack\t%0,%1,%2" |
| 101 | + [(set_attr "type" "bitmanip") |
| 102 | + (set_attr "length" "4")]) |
| 103 | + |
| 104 | +(define_insn "riscv_bitmanip_packusi" |
| 105 | + [(set (match_operand:SI 0 "register_operand" "=r") |
| 106 | + (ior:SI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") (const_int 16)) |
| 107 | + (and:SI (match_operand:SI 2 "register_operand" "r") (const_int 65280))))] |
| 108 | + "TARGET_ZBP" |
| 109 | + { return TARGET_64BIT ? "packuw\t%0,%1,%2" : "packu\t%0,%1,%2"; } |
| 110 | + [(set_attr "type" "bitmanip") |
| 111 | + (set_attr "length" "4")]) |
| 112 | + |
| 113 | +(define_insn "riscv_bitmanip_packudi" |
| 114 | + [(set (match_operand:DI 0 "register_operand" "=r") |
| 115 | + (ior:DI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") (const_int 32)) |
| 116 | + (and:DI (match_operand:SI 2 "register_operand" "r") (const_int 65280))))] |
| 117 | + "TARGET_ZBP && TARGET_64BIT" |
| 118 | + "packu\t%0,%1,%2" |
| 119 | + [(set_attr "type" "bitmanip") |
| 120 | + (set_attr "length" "4")]) |
| 121 | + |
| 122 | +(define_insn "riscv_bitmanip_packh<mode>" |
| 123 | +[(set (match_operand:X 0 "register_operand" "=r") |
| 124 | + (ior:X (and:X (match_operand:X 1 "register_operand" "r") |
| 125 | + (const_int 255)) |
| 126 | + (ashift:X (and:X (match_operand:X 2 "register_operand" "r") |
| 127 | + (const_int 255)) |
| 128 | + (const_int 8))))] |
| 129 | + "TARGET_ZBP" |
| 130 | + "packh\t%0,%1,%2" |
| 131 | + [(set_attr "type" "packh") |
| 132 | + (set_attr "length" "4")] |
| 133 | +) |
| 134 | + |
86 | 135 | (define_insn "*zero_extendhi<GPR:mode>2_bitmanip"
|
87 | 136 | [(set (match_operand:GPR 0 "register_operand" "=r,r")
|
88 | 137 | (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
|
|
480 | 529 | l<SHORT:size>\t%0,%1"
|
481 | 530 | [(set_attr "type" "bitmanip")
|
482 | 531 | (set_attr "length" "4")])
|
| 532 | + |
| 533 | +;; By the time we reach this, gcc has changed |
| 534 | +;; `(a&0ff)<<8` into `(a<<8)&0xFF00`, despite the fact |
| 535 | +;; it's worse on RISC-V (need to set up the constant |
| 536 | +;; for the shift vs. andi/slli) |
| 537 | +;; Keep an easily recognizable subtree |
| 538 | +(define_insn_and_split "*extractB0toB1" |
| 539 | +[(set (match_operand:SI 0 "register_operand" "=r") |
| 540 | + (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") |
| 541 | + (const_int 8)) |
| 542 | + (const_int 65280)))] |
| 543 | +"!TARGET_64BIT" |
| 544 | +"#" |
| 545 | +"!TARGET_64BIT" |
| 546 | +[(set (match_dup 0) (and:SI (match_dup 1) (const_int 255))) |
| 547 | + (set (match_dup 0) (ashift:SI (match_dup 0) (const_int 8))) |
| 548 | +] |
| 549 | +"" |
| 550 | +) |
| 551 | + |
| 552 | +(define_insn_and_split "*extractB0toB2" |
| 553 | +[(set (match_operand:SI 0 "register_operand" "=r") |
| 554 | + (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") |
| 555 | + (const_int 16)) |
| 556 | + (const_int 16711680)))] |
| 557 | +"!TARGET_64BIT" |
| 558 | +"#" |
| 559 | +"!TARGET_64BIT" |
| 560 | +[(set (match_dup 0) (and:SI (match_dup 1) (const_int 255))) |
| 561 | + (set (match_dup 0) (ashift:SI (match_dup 0) (const_int 16))) |
| 562 | +] |
| 563 | +"" |
| 564 | +) |
| 565 | + |
| 566 | +;; remove useless bswap after packh/packh/pack |
| 567 | +;; just permute the operands and remove the bswap |
| 568 | +(define_peephole2 |
| 569 | + [(set (match_operand:SI 5 "register_operand") |
| 570 | + (ior:SI (and:SI (match_operand:SI 1 "register_operand") |
| 571 | + (const_int 255)) |
| 572 | + (ashift:SI (and:SI (match_operand:SI 2 "register_operand") |
| 573 | + (const_int 255)) |
| 574 | + (const_int 8)))) |
| 575 | + (set (match_operand:SI 6 "register_operand") |
| 576 | + (ior:SI (and:SI (match_operand:SI 3 "register_operand") |
| 577 | + (const_int 255)) |
| 578 | + (ashift:SI (and:SI (match_operand:SI 4 "register_operand") |
| 579 | + (const_int 255)) |
| 580 | + (const_int 8)))) |
| 581 | + (set (match_operand:SI 7 "register_operand") |
| 582 | + (ior:SI (and:SI (match_dup 6) (const_int 65280)) |
| 583 | + (ashift:SI (match_dup 5) (const_int 16)))) |
| 584 | + (set (match_operand:SI 0 "register_operand") |
| 585 | + (bswap:SI (match_dup 7)))] |
| 586 | + "TARGET_ZBP && |
| 587 | + !TARGET_64BIT && |
| 588 | + (REGNO (operands[5]) == REGNO (operands[0]) || |
| 589 | + peep2_reg_dead_p (4, operands[5])) && |
| 590 | + (REGNO (operands[6]) == REGNO (operands[0]) || |
| 591 | + peep2_reg_dead_p (4, operands[6])) && |
| 592 | + (REGNO (operands[7]) == REGNO (operands[0]) || |
| 593 | + peep2_reg_dead_p (4, operands[7])) && |
| 594 | + REGNO (operands[5]) != REGNO (operands[3]) && |
| 595 | + REGNO (operands[5]) != REGNO (operands[4]) && |
| 596 | + REGNO (operands[5]) != REGNO (operands[6])" |
| 597 | + [(set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))] |
| 598 | +{ |
| 599 | + emit_insn(gen_riscv_bitmanip_packhsi(operands[5], operands[2], operands[1])); |
| 600 | + emit_insn(gen_riscv_bitmanip_packhsi(operands[6], operands[4], operands[3])); |
| 601 | + emit_insn(gen_riscv_bitmanip_packsi(operands[0], operands[5], operands[6])); |
| 602 | + //printf("matched %d [packh/packh/pack/bswap = packh/packh/pack]\n", 0); |
| 603 | + DONE; |
| 604 | +}) |
0 commit comments