Commit 43c87aa4 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/6g, cmd/8g, liblink: improve handling of float constants

* Enable basic constant propagation for floats.
  The constant propagation is still not as aggressive as it could be.
* Implement MOVSS $(0), Xx and MOVSD $(0), Xx as XORPS Xx, Xx.

Sample code:

func f32() float32 {
	var f float32
	return f
}

func f64() float64 {
	var f float64
	return f
}

Before:

"".f32 t=1 size=32 value=0 args=0x8 locals=0x0
	0x0000 00000 (demo.go:3)	TEXT	"".f32+0(SB),4,$0-8
	0x0000 00000 (demo.go:3)	FUNCDATA	$0,gclocals·a7a3692b8e27e823add69ec4239ba55f+0(SB)
	0x0000 00000 (demo.go:3)	FUNCDATA	$1,gclocals·3280bececceccd33cb74587feedb1f9f+0(SB)
	0x0000 00000 (demo.go:3)	MOVSS	$f32.00000000+0(SB),X0
	0x0008 00008 (demo.go:4)	MOVSS	$f32.00000000+0(SB),X0
	0x0010 00016 (demo.go:5)	MOVSS	X0,"".~r0+8(FP)
	0x0016 00022 (demo.go:5)	RET	,
"".f64 t=1 size=32 value=0 args=0x8 locals=0x0
	0x0000 00000 (demo.go:8)	TEXT	"".f64+0(SB),4,$0-8
	0x0000 00000 (demo.go:8)	FUNCDATA	$0,gclocals·a7a3692b8e27e823add69ec4239ba55f+0(SB)
	0x0000 00000 (demo.go:8)	FUNCDATA	$1,gclocals·3280bececceccd33cb74587feedb1f9f+0(SB)
	0x0000 00000 (demo.go:8)	MOVSD	$f64.0000000000000000+0(SB),X0
	0x0008 00008 (demo.go:9)	MOVSD	$f64.0000000000000000+0(SB),X0
	0x0010 00016 (demo.go:10)	MOVSD	X0,"".~r0+8(FP)
	0x0016 00022 (demo.go:10)	RET	,

After:

"".f32 t=1 size=16 value=0 args=0x8 locals=0x0
	0x0000 00000 (demo.go:3)	TEXT	"".f32+0(SB),4,$0-8
	0x0000 00000 (demo.go:3)	FUNCDATA	$0,gclocals·a7a3692b8e27e823add69ec4239ba55f+0(SB)
	0x0000 00000 (demo.go:3)	FUNCDATA	$1,gclocals·3280bececceccd33cb74587feedb1f9f+0(SB)
	0x0000 00000 (demo.go:3)	XORPS	X0,X0
	0x0003 00003 (demo.go:5)	MOVSS	X0,"".~r0+8(FP)
	0x0009 00009 (demo.go:5)	RET	,
"".f64 t=1 size=16 value=0 args=0x8 locals=0x0
	0x0000 00000 (demo.go:8)	TEXT	"".f64+0(SB),4,$0-8
	0x0000 00000 (demo.go:8)	FUNCDATA	$0,gclocals·a7a3692b8e27e823add69ec4239ba55f+0(SB)
	0x0000 00000 (demo.go:8)	FUNCDATA	$1,gclocals·3280bececceccd33cb74587feedb1f9f+0(SB)
	0x0000 00000 (demo.go:8)	XORPS	X0,X0
	0x0003 00003 (demo.go:10)	MOVSD	X0,"".~r0+8(FP)
	0x0009 00009 (demo.go:10)	RET	,

Change-Id: Ie9eb65e324af4f664153d0a7cd22bb16b0fba16d
Reviewed-on: https://go-review.googlesource.com/2053Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent d5e4c406
...@@ -624,7 +624,6 @@ bignodes(void) ...@@ -624,7 +624,6 @@ bignodes(void)
* t = f * t = f
* hard part is conversions. * hard part is conversions.
*/ */
// TODO: lost special constants for floating point. XORPD for 0.0?
void void
gmove(Node *f, Node *t) gmove(Node *f, Node *t)
{ {
......
...@@ -121,7 +121,7 @@ peep(Prog *firstp) ...@@ -121,7 +121,7 @@ peep(Prog *firstp)
case AMOVSS: case AMOVSS:
case AMOVSD: case AMOVSD:
if(regtyp(&p->to)) if(regtyp(&p->to))
if(p->from.type == D_CONST) if(p->from.type == D_CONST || p->from.type == D_FCONST)
conprop(r); conprop(r);
break; break;
} }
...@@ -384,7 +384,7 @@ regtyp(Adr *a) ...@@ -384,7 +384,7 @@ regtyp(Adr *a)
t = a->type; t = a->type;
if(t >= D_AX && t <= D_R15) if(t >= D_AX && t <= D_R15)
return 1; return 1;
if(t >= D_X0 && t <= D_X0+15) if(t >= D_X0 && t <= D_X15)
return 1; return 1;
return 0; return 0;
} }
......
...@@ -120,7 +120,7 @@ peep(Prog *firstp) ...@@ -120,7 +120,7 @@ peep(Prog *firstp)
case AMOVSS: case AMOVSS:
case AMOVSD: case AMOVSD:
if(regtyp(&p->to)) if(regtyp(&p->to))
if(p->from.type == D_CONST) if(p->from.type == D_CONST || p->from.type == D_FCONST)
conprop(r); conprop(r);
break; break;
} }
......
...@@ -241,6 +241,19 @@ progedit(Link *ctxt, Prog *p) ...@@ -241,6 +241,19 @@ progedit(Link *ctxt, Prog *p)
// Rewrite float constants to values stored in memory. // Rewrite float constants to values stored in memory.
switch(p->as) { switch(p->as) {
case AMOVSS:
// Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
if(p->from.type == D_FCONST)
if(p->from.u.dval == 0)
if(p->to.type >= D_X0)
if(p->to.type <= D_X15) {
p->as = AXORPS;
p->from.type = p->to.type;
p->from.index = p->to.index;
break;
}
// fallthrough
case AFMOVF: case AFMOVF:
case AFADDF: case AFADDF:
case AFSUBF: case AFSUBF:
...@@ -250,7 +263,6 @@ progedit(Link *ctxt, Prog *p) ...@@ -250,7 +263,6 @@ progedit(Link *ctxt, Prog *p)
case AFDIVRF: case AFDIVRF:
case AFCOMF: case AFCOMF:
case AFCOMFP: case AFCOMFP:
case AMOVSS:
case AADDSS: case AADDSS:
case ASUBSS: case ASUBSS:
case AMULSS: case AMULSS:
...@@ -274,6 +286,19 @@ progedit(Link *ctxt, Prog *p) ...@@ -274,6 +286,19 @@ progedit(Link *ctxt, Prog *p)
p->from.offset = 0; p->from.offset = 0;
} }
break; break;
case AMOVSD:
// Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
if(p->from.type == D_FCONST)
if(p->from.u.dval == 0)
if(p->to.type >= D_X0)
if(p->to.type <= D_X15) {
p->as = AXORPS;
p->from.type = p->to.type;
p->from.index = p->to.index;
break;
}
// fallthrough
case AFMOVD: case AFMOVD:
case AFADDD: case AFADDD:
...@@ -284,7 +309,6 @@ progedit(Link *ctxt, Prog *p) ...@@ -284,7 +309,6 @@ progedit(Link *ctxt, Prog *p)
case AFDIVRD: case AFDIVRD:
case AFCOMD: case AFCOMD:
case AFCOMDP: case AFCOMDP:
case AMOVSD:
case AADDSD: case AADDSD:
case ASUBSD: case ASUBSD:
case AMULSD: case AMULSD:
......
...@@ -177,6 +177,19 @@ progedit(Link *ctxt, Prog *p) ...@@ -177,6 +177,19 @@ progedit(Link *ctxt, Prog *p)
// Rewrite float constants to values stored in memory. // Rewrite float constants to values stored in memory.
switch(p->as) { switch(p->as) {
case AMOVSS:
// Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
if(p->from.type == D_FCONST)
if(p->from.u.dval == 0)
if(p->to.type >= D_X0)
if(p->to.type <= D_X7) {
p->as = AXORPS;
p->from.type = p->to.type;
p->from.index = p->to.index;
break;
}
// fallthrough
case AFMOVF: case AFMOVF:
case AFADDF: case AFADDF:
case AFSUBF: case AFSUBF:
...@@ -186,7 +199,6 @@ progedit(Link *ctxt, Prog *p) ...@@ -186,7 +199,6 @@ progedit(Link *ctxt, Prog *p)
case AFDIVRF: case AFDIVRF:
case AFCOMF: case AFCOMF:
case AFCOMFP: case AFCOMFP:
case AMOVSS:
case AADDSS: case AADDSS:
case ASUBSS: case ASUBSS:
case AMULSS: case AMULSS:
...@@ -211,6 +223,19 @@ progedit(Link *ctxt, Prog *p) ...@@ -211,6 +223,19 @@ progedit(Link *ctxt, Prog *p)
} }
break; break;
case AMOVSD:
// Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
if(p->from.type == D_FCONST)
if(p->from.u.dval == 0)
if(p->to.type >= D_X0)
if(p->to.type <= D_X7) {
p->as = AXORPS;
p->from.type = p->to.type;
p->from.index = p->to.index;
break;
}
// fallthrough
case AFMOVD: case AFMOVD:
case AFADDD: case AFADDD:
case AFSUBD: case AFSUBD:
...@@ -220,7 +245,6 @@ progedit(Link *ctxt, Prog *p) ...@@ -220,7 +245,6 @@ progedit(Link *ctxt, Prog *p)
case AFDIVRD: case AFDIVRD:
case AFCOMD: case AFCOMD:
case AFCOMDP: case AFCOMDP:
case AMOVSD:
case AADDSD: case AADDSD:
case ASUBSD: case ASUBSD:
case AMULSD: case AMULSD:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment