On 11/19/20 8:36 PM, Maciej W. Rozycki wrote:
> We have matching insns defined for `sign_extract' and `zero_extract'
> expressions, so make the three named patterns for bitfield operations
> consistent and make `extv' an expander rather than an insn taking a
> SImode, a QImode, and a SImode general operand for the LOC, SIZE, and
> POS operands respectively, like with the `extzv' and `insv' patterns,
> matching the machine instructions and giving the middle end more choice
> as to which actual insn to choose in a given situation.
>
> Given this program:
>
> typedef struct
> {
>   int f0:1;
>   int f1:7;
>   int f8:8;
>   int f16:16;
> } bit_t;
>
> typedef struct
> {
>   unsigned int f0:1;
>   unsigned int f1:7;
>   unsigned int f8:8;
>   unsigned int f16:16;
> } ubit_t;
>
> typedef union
> {
>   bit_t b;
>   int i;
> } bit_u;
>
> typedef union
> {
>   ubit_t b;
>   unsigned int i;
> } ubit_u;
>
> int
> ins1 (bit_u x, int y)
> {
>   asm volatile ("" : "+r" (x), "+r" (y));
>   x.b.f1 = y;
>   return x.i;
> }
>
> int
> ext1 (bit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f1;
> }
>
> unsigned int
> extz1 (ubit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f1;
> }
>
> int
> ins8 (bit_u x, int y)
> {
>   asm volatile ("" : "+r" (x), "+r" (y));
>   x.b.f8 = y;
>   return x.i;
> }
>
> int
> ext8 (bit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f8;
> }
>
> unsigned int
> extz8 (ubit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f8;
> }
>
> int
> ins16 (bit_u x, int y)
> {
>   asm volatile ("" : "+r" (x), "+r" (y));
>   x.b.f16 = y;
>   return x.i;
> }
>
> int
> ext16 (bit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f16;
> }
>
> unsigned int
> extz16 (ubit_u x)
> {
>   asm volatile ("" : "+r" (x));
>   return x.b.f16;
> }
>
> this results in the following code change:
>
> @@ -16,12 +16,12 @@ ins1:
>  .globl ext1
>       .type   ext1, @function
>  ext1:
> -     .word 0 # 19    [c=0]  procedure_entry_mask
> -     subl2 $4,%sp    # 20    [c=32]  addsi3
> +     .word 0 # 18    [c=0]  procedure_entry_mask
> +     subl2 $4,%sp    # 19    [c=32]  addsi3
>       movl 4(%ap),%r0 # 2     [c=16]  movsi_2
> -     cvtbl %r0,%r0   # 7     [c=4]  extendqisi2
> -     ashl $-1,%r0,%r0        # 14    [c=40]  *vax.md:624
> -     ret             # 24    [c=0]  return
> +     extv $1,$7,%r0,%r0      # 7     [c=60]  *extv_non_const
> +     cvtbl %r0,%r0   # 13    [c=4]  extendqisi2
> +     ret             # 23    [c=0]  return
>       .size   ext1, .-ext1
>       .align 1
>  .globl extz1
> @@ -49,12 +49,12 @@ ins8:
>  .globl ext8
>       .type   ext8, @function
>  ext8:
> -     .word 0 # 20    [c=0]  procedure_entry_mask
> -     subl2 $4,%sp    # 21    [c=32]  addsi3
> +     .word 0 # 18    [c=0]  procedure_entry_mask
> +     subl2 $4,%sp    # 19    [c=32]  addsi3
>       movl 4(%ap),%r0 # 2     [c=16]  movsi_2
> -     cvtwl %r0,%r0   # 7     [c=4]  extendhisi2
> -     ashl $-8,%r0,%r0        # 15    [c=40]  *vax.md:624
> -     ret             # 25    [c=0]  return
> +     rotl $24,%r0,%r0        # 13    [c=60]  *extv_non_const
> +     cvtbl %r0,%r0
> +     ret             # 23    [c=0]  return
>       .size   ext8, .-ext8
>       .align 1
>  .globl extz8
>
> If there is a performance degradation with the replacement sequences,
> then it can and should be sorted within `extv_non_const'.
>
>       gcc/
>       * config/vax/vax.md (extv): Rename insn to...
>       (*extv): ... this.
>       (extv): New expander.
OK
jeff

Reply via email to