On 11/19/20 8:35 PM, Maciej W. Rozycki wrote:
> The INSV machine instruction is the only computational operation in the
> VAX ISA that keeps condition codes intact. In preparation to MODE_CC
> transition keep patterns apart then that make or do not make use of said
> instruction. For consistency update EXTV and EXTZV instruction uses
> accordingly. In expand SUBREGs will be presented as operands, so handle
> that possibility in the insn condition.
>
> This actually yields better code by avoiding EXTV/EXTZV instructions in
> pseudo-aligned register cases previously resorting to those instructions:
>
> @@ -42,7 +42,7 @@ ins8:
> subl2 $4,%sp # 21 [c=32] addsi3
> movl 4(%ap),%r0 # 2 [c=16] movsi_2
> movl 8(%ap),%r1 # 17 [c=16] movsi_2
> - insv %r1,$8,$8,%r0 # 9 [c=4] *insv_aligned
> + insv %r1,$8,$8,%r0 # 9 [c=4] *insv_2
> ret # 25 [c=0] return
> .size ins8, .-ins8
> .align 1
> @@ -60,12 +60,12 @@ ext8:
> .globl extz8
> .type extz8, @function
> extz8:
> - .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
> - extzv $8,$8,%r0,%r1 # 13 [c=60] *extzv_aligned
> - movl %r1,%r0 # 18 [c=4] movsi_2
> - ret # 24 [c=0] return
> + rotl $24,%r0,%r0 # 13 [c=60] *extzv_non_const
> + movzbl %r0,%r0
> + ret # 23 [c=0] return
> .size extz8, .-extz8
> .align 1
> .globl ins16
> @@ -75,7 +75,7 @@ ins16:
> subl2 $4,%sp # 21 [c=32] addsi3
> movl 4(%ap),%r0 # 2 [c=16] movsi_2
> movl 8(%ap),%r1 # 17 [c=16] movsi_2
> - insv %r1,$16,$16,%r0 # 9 [c=4] *insv_aligned
> + insv %r1,$16,$16,%r0 # 9 [c=4] *insv_2
> ret # 25 [c=0] return
> .size ins16, .-ins16
> .align 1
> @@ -94,8 +94,9 @@ ext16:
> extz16:
> .word 0 # 18 [c=0] procedure_entry_mask
> subl2 $4,%sp # 19 [c=32] addsi3
> - movl 4(%ap),%r1 # 2 [c=16] movsi_2
> - extzv $16,$16,%r1,%r0 # 7 [c=60] *extzv_aligned
> + movl 4(%ap),%r0 # 2 [c=16] movsi_2
> + rotl $16,%r0,%r0 # 7 [c=60] *extzv_non_const
> + movzwl %r0,%r0
> movzwl %r0,%r0 # 13 [c=4] zero_extendhisi2
> ret # 23 [c=0] return
> .size extz16, .-extz16
>
> demonstrated with 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;
> }
>
> It also papers over a regression:
>
> FAIL: gcc.dg/pr83623.c (internal compiler error)
> FAIL: gcc.dg/pr83623.c (test for excess errors)
>
> from an ICE like:
>
> during RTL pass: final
> .../gcc/testsuite/gcc.dg/pr83623.c: In function 'foo':
> .../gcc/testsuite/gcc.dg/pr83623.c:13:1: internal compiler error: in
> change_address_1, at emit-rtl.c:2275
> 0x10a056e3 change_address_1
> .../gcc/emit-rtl.c:2275
> 0x10a0645f adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int,
> int, int, poly_int<1u, long>)
> .../gcc/emit-rtl.c:2409
> 0x11cb588f output_97
> .../gcc/config/vax/vax.md:808
> 0x10aafb2f get_insn_template(int, rtx_insn*)
> .../gcc/final.c:2070
> 0x10ab2b3f final_scan_insn_1
> .../gcc/final.c:3039
> 0x10ab313b final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*)
> .../gcc/final.c:3152
> 0x10aaf887 final_1
> .../gcc/final.c:2020
> 0x10ab703b rest_of_handle_final
> .../gcc/final.c:4658
> 0x10ab757b execute
> .../gcc/final.c:4736
> Please submit a full bug report,
> with preprocessed source if appropriate.
> Please include the complete backtrace with any bug report.
> See <https://gcc.gnu.org/bugs/> for instructions.
> compiler exited with status 1
> FAIL: gcc.dg/pr83623.c (internal compiler error)
>
> triggered by an RTL instruction like:
>
> (insn 17 14 145 (set (reg:SI 1 %r1)
> (zero_extract:SI (mem/c:SI (symbol_ref:SI ("x") <var_decl
> 0x7ffff7f80120 x>) [1 x+0 S4 A128])
> (const_int 16 [0x10])
> (const_int 16 [0x10]))) ".../gcc/testsuite/gcc.dg/pr83623.c":12:9
> 97 {*extzv_aligned}
> (nil))
>
> (where the address cannot be adjusted by 2 for PIC code as requested
> here as it would create an offset external symbol reference) otherwise
> caused by the patterns modified here, addressed next. This indicates
> a further rework is warranted here, but at least problems at hand have
> been fixed.
>
> gcc/
> * config/vax/vax.md (*insv_aligned, *extzv_aligned)
> (*extv_aligned): Reject register bitfield locations that are not
> aligned to the least significant bit; update output statement
> accordingly.
OK
jeff