shithub: riscv

Download patch

ref: ecb298419235bf5721db7e37e91af2d4c28bc783
parent: a9f4ddade4bb5658b19097a11d139265d57b9748
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Sep 7 11:04:56 EDT 2023

7l: support fused multiply-add/sub ops

--- a/sys/src/cmd/7l/asmout.c
+++ b/sys/src/cmd/7l/asmout.c
@@ -24,6 +24,7 @@
 #define	FPCCMP(m,s,type,op)	((m)<<31 | (s)<<29 | 0x1E<<24 | (type)<<22 | 1<<21 | 1<<10 | (op)<<4)
 #define	FPOP1S(m,s,type,op)	((m)<<31 | (s)<<29 | 0x1E<<24 | (type)<<22 | 1<<21 | (op)<<15 | 0x10<<10)
 #define	FPOP2S(m,s,type,op)	((m)<<31 | (s)<<29 | 0x1E<<24 | (type)<<22 | 1<<21 | (op)<<12 | 2<<10)
+#define	FPOP3S(type,op,op2)	(0x1F<<24 | (type)<<22 | (op2)<<21 | (op)<<15)
 #define	FPCVTI(sf,s,type,rmode,op)	((sf)<<31 | (s)<<29 | 0x1E<<24 | (type)<<22 | 1<<21 | (rmode)<<19 | (op)<<16 | 0<<10)
 #define	FPCVTF(sf,s,type,rmode,op,scale)	((sf)<<31 | (s)<<29 | 0x1E<<24 | (type)<<22 | 0<<21 | (rmode)<<19 | (op)<<16 | (scale)<<10)
 #define	ADR(p,o,rt)	((p)<<31 | ((o)&3)<<29 | (0x10<<24) | (((o>>2)&0x7FFFF)<<5) | (rt))
@@ -247,7 +248,7 @@
 		o1 = instoffset;
 		break;
 
-	case 15:	/* mul/mneg/umulh/umull r,[r,]r; madd/msub Rm,Rn,Ra,Rd */
+	case 15:	/* mul/mneg/umulh/umull r,[r,]r; madd/msub Rm,Rn,[Ra,]Rd */
 		o1 = oprrr(p->as);
 		rf = p->from.reg;
 		rt = p->to.reg;
@@ -893,6 +894,17 @@
 		o1 = LD2STR(olsxrr(p->as, v&31, p->to.reg, p->from.reg));
 		o1 |= ((v>>8)&7)<<13 | ((v>>16)&1)<<12;
 		break;
+
+	case 70:	/* fmadd/fmsub Rm,Rn,[Ra,]Rd */
+		o1 = oprrr(p->as);
+		rf = p->from.reg;
+		rt = p->to.reg;
+		r = p->from3.reg;
+		ra = p->reg;
+		if(ra == NREG)
+			ra = rt;
+		o1 |= (rf<<16) | (ra<<10) | (r<<5) | rt;
+		break;
 	}
 
 	if(debug['a'] > 1)
@@ -1149,8 +1161,17 @@
 	case AFMAXNMD:	return FPOP2S(0, 0, 1, 6);
 	case AFMINNMS:	return FPOP2S(0, 0, 0, 7);
 	case AFMINNMD:	return FPOP2S(0, 0, 1, 7);
-	case AFNMULS:		return FPOP2S(0, 0, 0, 8);
+	case AFNMULS:	return FPOP2S(0, 0, 0, 8);
 	case AFNMULD:	return FPOP2S(0, 0, 1, 8);
+
+	case AFMADDS:	return FPOP3S(0, 0, 0);
+	case AFNMADDS:	return FPOP3S(0, 0, 1);
+	case AFMADDD:	return FPOP3S(1, 0, 0);
+	case AFNMADDD:	return FPOP3S(1, 0, 1);
+	case AFMSUBS:	return FPOP3S(0, 1, 0);
+	case AFNMSUBS:	return FPOP3S(0, 1, 1);
+	case AFMSUBD:	return FPOP3S(1, 1, 0);
+	case AFNMSUBD:	return FPOP3S(1, 1, 1);
 
 	case AFCMPS:	return FPCMP(0, 0, 0, 0, 0);
 	case AFCMPD:	return FPCMP(0, 0, 1, 0, 0);
--- a/sys/src/cmd/7l/list.c
+++ b/sys/src/cmd/7l/list.c
@@ -32,15 +32,12 @@
 		if(p->reg == NREG && p->from3.type == D_NONE)
 			return fmtprint(fp, "(%ld)	%A	%D,%D",
 				p->line, a, &p->from, &p->to);
-		else if(p->from.type == D_FREG)
-			return fmtprint(fp, "(%ld)	%A	%D,F%d,%D",
-				p->line, a, &p->from, p->reg, &p->to);
 
 		fmtprint(fp, "(%ld)	%A	%D", p->line, a, &p->from);
 		if(p->from3.type != D_NONE)
 			fmtprint(fp, ",%D", &p->from3);
 		if(p->reg != NREG)
-			fmtprint(fp, ",R%d", p->reg);
+			fmtprint(fp, ",%c%d", p->from.type == D_FREG ? 'F' : 'R', p->reg);
 		fmtprint(fp, ",%D", &p->to);
 		return 0;
 	}
--- a/sys/src/cmd/7l/noop.c
+++ b/sys/src/cmd/7l/noop.c
@@ -275,6 +275,7 @@
 				q->line = p->line;
 				q->as = AB;
 				q->from = zprg.from;
+				q->from3 = zprg.from3;
 				q->to = p->to;
 				q->cond = p->cond;
 				q->link = p->link;
@@ -284,6 +285,7 @@
 				p->from = zprg.from;
 				p->from.type = D_CONST;
 				p->from.offset = autosize;
+				p->from3 = zprg.from3;
 				p->to = zprg.to;
 				p->to.type = D_REG;
 				p->to.reg = REGSP;
@@ -295,6 +297,7 @@
 			q->line = p->line;
 			q->as = AB;
 			q->from = zprg.from;
+			q->from3 = zprg.from3;
 			q->to = p->to;
 			q->cond = p->cond;
 			q->link = p->link;
@@ -305,6 +308,7 @@
 			p->from.type = D_XPRE;
 			p->from.offset = -autosize;
 			p->from.reg = REGSP;
+			p->from3 = zprg.from3;
 			p->to = zprg.to;
 			p->to.type = D_REG;
 			p->to.reg = REGLINK;
--- a/sys/src/cmd/7l/obj.c
+++ b/sys/src/cmd/7l/obj.c
@@ -555,6 +555,7 @@
 {
 	p->as = ANOP;
 	p->from.type = D_NONE;
+	p->from3.type = D_NONE;
 	p->to.type = D_NONE;
 }
 
@@ -1340,6 +1341,7 @@
 			 */
 			p->as = ABL;
 			p->from = zprg.from;
+			p->from3 = zprg.from3;
 			p->to = zprg.to;
 			p->to.type = D_BRANCH;
 			p->cond = ps4;
--- a/sys/src/cmd/7l/optab.c
+++ b/sys/src/cmd/7l/optab.c
@@ -417,6 +417,9 @@
 	{ AFMOVS,	C_FREG,	C_NONE,	C_ADDR,		64, 8, 0,	LTO },
 	{ AFMOVS,	C_ADDR,	C_NONE,	C_FREG,		65, 8, 0,	LFROM },
 
+	{ AFMADDD,	C_FREG,	C_FREG,	C_FREG,		70, 4, 0 },
+	{ AFMADDD,	C_FREG,	C_NONE,	C_FREG,		70, 4, 0 },
+
 	{ AFADDS,	C_FREG,	C_NONE,	C_FREG,		54, 4, 0 },
 	{ AFADDS,	C_FREG,	C_REG,	C_FREG,		54, 4, 0 },
 	{ AFADDS,	C_FCON,	C_NONE,	C_FREG,		54, 4, 0 },
--- a/sys/src/cmd/7l/span.c
+++ b/sys/src/cmd/7l/span.c
@@ -700,6 +700,14 @@
 asregclass(ushort as)
 {
 	switch(as){
+	case AFMADDD:
+	case AFMADDS:
+	case AFMSUBD:
+	case AFMSUBS:
+	case AFNMADDS:
+	case AFNMADDD:
+	case AFNMSUBS:
+	case AFNMSUBD:
 	case AMOVPS:
 	case AMOVPD:
 	case AMOVPQ: return C_FREG;
@@ -1098,6 +1106,15 @@
 			oprange[ASMSUBL] = t;
 			oprange[AUMADDL] = t;
 			oprange[AUMSUBL] = t;
+			break;
+		case AFMADDD:
+			oprange[AFMADDS] = t;
+			oprange[AFMSUBD] = t;
+			oprange[AFMSUBS] = t;
+			oprange[AFNMADDS] = t;
+			oprange[AFNMADDD] = t;
+			oprange[AFNMSUBD] = t;
+			oprange[AFNMSUBS] = t;
 			break;
 		case AREM:
 			oprange[AREMW] = t;