shithub: riscv

Download patch

ref: 32acb3ebd8ecb684a4db054febc082b99d5957be
parent: bf1dca5be2fda19dc84765ddbf39ae99376b8864
author: cinap_lenrek <[email protected]>
date: Mon Feb 6 13:50:43 EST 2023

7c: eliminate MOVWU r, r instructions when possible

--- a/sys/src/cmd/7c/peep.c
+++ b/sys/src/cmd/7c/peep.c
@@ -5,6 +5,101 @@
 Reg* findpre(Reg *r, Adr *v);
 Reg* findinc(Reg *r, Reg *r2, Adr *v);
 
+static int
+isu32op(Prog *p)
+{
+	switch(p->as){
+	case AADCSW:
+	case AADCW:
+	case AADDSW:
+	case AADDW:
+	case AANDSW:
+	case AANDW:
+	case AASRW:
+	case ABFIW:
+	case ABFMW:
+	case ABFXILW:
+	case ABICSW:
+	case ABICW:
+	case ACBNZW:
+	case ACBZW:
+	case ACCMNW:
+	case ACCMPW:
+	case ACINCW:
+	case ACINVW:
+	case ACLSW:
+	case ACLZW:
+	case ACMNW:
+	case ACNEGW:
+	case ACRC32CW:
+	case ACRC32W:
+	case ACSELW:
+	case ACSETMW:
+	case ACSETW:
+	case ACSINCW:
+	case ACSINVW:
+	case ACSNEGW:
+	case AEONW:
+	case AEORW:
+	case AEXTRW:
+	case ALDARW:
+	case ALDAXPW:
+	case ALDAXRW:
+	case ALDXRW:
+	case ALDXPW:
+	case ALSLW:
+	case ALSRW:
+	case AMADDW:
+	case AMNEGW:
+	case AMOVKW:
+	case AMOVNW:
+	case AMOVZW:
+	case AMSUBW:
+	case AMULW:
+	case AMVNW:
+	case ANEGSW:
+	case ANEGW:
+	case ANGCSW:
+	case ANGCW:
+	case AORNW:
+	case AORRW:
+	case ARBITW:
+	case AREMW:
+	case AREV16W:
+	case AREVW:
+	case ARORW:
+	case ASBCSW:
+	case ASBCW:
+	case ASBFIZW:
+	case ASBFMW:
+	case ASBFXW:
+	case ASDIVW:
+	case ASTXPW:
+	case ASTXRW:
+	case ASTLPW:
+	case ASTLRW:
+	case ASTLXPW:
+	case ASTLXRW:
+	case ASUBSW:
+	case ASUBW:
+	case ASXTBW:
+	case ASXTHW:
+	case ATSTW:
+	case AUBFIZW:
+	case AUBFMW:
+	case AUBFXW:
+	case AUDIVW:
+	case AUREMW:
+	case AUMULL:
+	case AUXTW:
+	case AUXTBW:
+	case AUXTHW:
+	case AMOVWU:
+		return 1;
+	}
+	return 0;
+}
+
 void
 peep(void)
 {
@@ -58,8 +153,7 @@
 				t++;
 			}
 		} else
-		if(p->as == ASXTW
-		&& regtyp(&p->from) && regtyp(&p->to)){
+		if(p->as == ASXTW && p->from.type == D_REG && p->to.type == D_REG){
 			r1 = findpre(r, &p->from);
 			if(r1 != R){
 				p1 = r1->prog;
@@ -69,7 +163,7 @@
 				case AMOVH:
 				case AMOVHU:
 				case AMOVW:
-					if(p1->to.type == p->from.type)
+					if(p1->to.type == p->from.type && p1->to.reg == p->from.reg)
 						p->as = AMOVW;
 					break;
 				}
@@ -76,12 +170,14 @@
 			}
 		} else
 		if((p->as == AMOVB || p->as == AMOVBU || p->as == AMOVH || p->as == AMOVHU || p->as == AMOVWU)
-		&& regtyp(&p->from) && regtyp(&p->to)){
+		&& (p->from.type == D_REG && p->to.type == D_REG)){
 			r1 = findpre(r, &p->from);
 			if(r1 != R){
 				p1 = r1->prog;
-				if(p1->as == p->as && p1->to.type == p->from.type)
-					p->as = AMOV;
+				if(p1->to.type == p->from.type && p1->to.reg == p->from.reg){
+					if(p1->as == p->as || p->as == AMOVWU && isu32op(p1))
+						p->as = AMOVW;
+				}
 			}
 		}