[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 New
Headers show
Series
  • VAX: Bring the port up to date (yes, MODE_CC conversion is included)
Related show

Commit Message

Maciej W. Rozycki Nov. 20, 2020, 3:36 a.m.
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(-)

-- 
2.11.0

Comments

Iain Sandoe via Gcc-patches Nov. 21, 2020, 5:26 p.m. | #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

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")