diff mbox series

[23/31] VAX: Make `extv' an expander matching the remaining bitfield operations

Message ID alpine.LFD.2.21.2011200256570.656242@eddie.linux-mips.org
State Accepted
Headers show
Series VAX: Bring the port up to date (yes, MODE_CC conversion is included) | expand

Commit Message

Maciej W. Rozycki Nov. 20, 2020, 3:36 a.m. UTC
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.
---
 gcc/config/vax/vax.md | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

Comments

Jeff Law Nov. 21, 2020, 5:26 p.m. UTC | #1
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
diff mbox series

Patch

diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index f90ae89391f..d8774cdd36c 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -941,7 +941,15 @@  (define_insn ""
   ""
   "cmpzv %2,%1,%0,%3")
 
-(define_insn "extv"
+(define_expand "extv"
+  [(set (match_operand:SI 0 "general_operand" "")
+	(sign_extract:SI (match_operand:SI 1 "general_operand" "")
+			 (match_operand:QI 2 "general_operand" "")
+			 (match_operand:SI 3 "general_operand" "")))]
+  ""
+  "")
+
+(define_insn "*extv"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 	(sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
 			 (match_operand:QI 2 "general_operand" "g")