diff options
author | Richard Musiol <mail@richard-musiol.de> | 2019-09-12 21:05:45 +0200 |
---|---|---|
committer | Richard Musiol <neelance@gmail.com> | 2019-09-19 20:26:22 +0000 |
commit | 1c50fcf853b0382ac6a98e4c84eb90230b37832f (patch) | |
tree | 8a2cae8417dfb56aef62a5978ffa98bb7e6eea3b /src/cmd/compile/internal/wasm | |
parent | d6c2f1e90ed2eb25ca5b00fef9a4d13b01a4a1c5 (diff) | |
download | go-1c50fcf853b0382ac6a98e4c84eb90230b37832f.tar.gz go-1c50fcf853b0382ac6a98e4c84eb90230b37832f.zip |
cmd/compile: add 32 bit float registers/variables on wasm
Before this change, wasm only used float variables with a size of 64 bit
and applied rounding to 32 bit precision where necessary. This change
adds proper 32 bit float variables.
Reduces the size of pkg/js_wasm by 254 bytes.
Change-Id: Ieabe846a8cb283d66def3cdf11e2523b3b31f345
Reviewed-on: https://go-review.googlesource.com/c/go/+/195117
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/wasm')
-rw-r--r-- | src/cmd/compile/internal/wasm/ssa.go | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/src/cmd/compile/internal/wasm/ssa.go b/src/cmd/compile/internal/wasm/ssa.go index 761a40227d..5b366eb08b 100644 --- a/src/cmd/compile/internal/wasm/ssa.go +++ b/src/cmd/compile/internal/wasm/ssa.go @@ -176,18 +176,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { case ssa.OpWasmI64Store8, ssa.OpWasmI64Store16, ssa.OpWasmI64Store32, ssa.OpWasmI64Store, ssa.OpWasmF32Store, ssa.OpWasmF64Store: getValue32(s, v.Args[0]) getValue64(s, v.Args[1]) - if v.Op == ssa.OpWasmF32Store { - s.Prog(wasm.AF32DemoteF64) - } p := s.Prog(v.Op.Asm()) p.To = obj.Addr{Type: obj.TYPE_CONST, Offset: v.AuxInt} case ssa.OpStoreReg: getReg(s, wasm.REG_SP) getValue64(s, v.Args[0]) - if v.Type.Etype == types.TFLOAT32 { - s.Prog(wasm.AF32DemoteF64) - } p := s.Prog(storeOp(v.Type)) gc.AddrAuto(&p.To, v) @@ -246,11 +240,6 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) { panic("wasm: bad LoweredAddr") } - case ssa.OpWasmLoweredRound32F: - getValue64(s, v.Args[0]) - s.Prog(wasm.AF32DemoteF64) - s.Prog(wasm.AF64PromoteF32) - case ssa.OpWasmLoweredConvert: getValue64(s, v.Args[0]) @@ -268,6 +257,9 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) { case ssa.OpWasmI64Const: i64Const(s, v.AuxInt) + case ssa.OpWasmF32Const: + f32Const(s, v.AuxFloat()) + case ssa.OpWasmF64Const: f64Const(s, v.AuxFloat()) @@ -275,9 +267,6 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) { getValue32(s, v.Args[0]) p := s.Prog(v.Op.Asm()) p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: v.AuxInt} - if v.Op == ssa.OpWasmF32Load { - s.Prog(wasm.AF64PromoteF32) - } case ssa.OpWasmI64Eqz: getValue64(s, v.Args[0]) @@ -286,7 +275,9 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) { s.Prog(wasm.AI64ExtendI32U) } - case ssa.OpWasmI64Eq, ssa.OpWasmI64Ne, ssa.OpWasmI64LtS, ssa.OpWasmI64LtU, ssa.OpWasmI64GtS, ssa.OpWasmI64GtU, ssa.OpWasmI64LeS, ssa.OpWasmI64LeU, ssa.OpWasmI64GeS, ssa.OpWasmI64GeU, ssa.OpWasmF64Eq, ssa.OpWasmF64Ne, ssa.OpWasmF64Lt, ssa.OpWasmF64Gt, ssa.OpWasmF64Le, ssa.OpWasmF64Ge: + case ssa.OpWasmI64Eq, ssa.OpWasmI64Ne, ssa.OpWasmI64LtS, ssa.OpWasmI64LtU, ssa.OpWasmI64GtS, ssa.OpWasmI64GtU, ssa.OpWasmI64LeS, ssa.OpWasmI64LeU, ssa.OpWasmI64GeS, ssa.OpWasmI64GeU, + ssa.OpWasmF32Eq, ssa.OpWasmF32Ne, ssa.OpWasmF32Lt, ssa.OpWasmF32Gt, ssa.OpWasmF32Le, ssa.OpWasmF32Ge, + ssa.OpWasmF64Eq, ssa.OpWasmF64Ne, ssa.OpWasmF64Lt, ssa.OpWasmF64Gt, ssa.OpWasmF64Le, ssa.OpWasmF64Ge: getValue64(s, v.Args[0]) getValue64(s, v.Args[1]) s.Prog(v.Op.Asm()) @@ -294,7 +285,9 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) { s.Prog(wasm.AI64ExtendI32U) } - case ssa.OpWasmI64Add, ssa.OpWasmI64Sub, ssa.OpWasmI64Mul, ssa.OpWasmI64DivU, ssa.OpWasmI64RemS, ssa.OpWasmI64RemU, ssa.OpWasmI64And, ssa.OpWasmI64Or, ssa.OpWasmI64Xor, ssa.OpWasmI64Shl, ssa.OpWasmI64ShrS, ssa.OpWasmI64ShrU, ssa.OpWasmF64Add, ssa.OpWasmF64Sub, ssa.OpWasmF64Mul, ssa.OpWasmF64Div, ssa.OpWasmF64Copysign, ssa.OpWasmI64Rotl: + case ssa.OpWasmI64Add, ssa.OpWasmI64Sub, ssa.OpWasmI64Mul, ssa.OpWasmI64DivU, ssa.OpWasmI64RemS, ssa.OpWasmI64RemU, ssa.OpWasmI64And, ssa.OpWasmI64Or, ssa.OpWasmI64Xor, ssa.OpWasmI64Shl, ssa.OpWasmI64ShrS, ssa.OpWasmI64ShrU, ssa.OpWasmI64Rotl, + ssa.OpWasmF32Add, ssa.OpWasmF32Sub, ssa.OpWasmF32Mul, ssa.OpWasmF32Div, ssa.OpWasmF32Copysign, + ssa.OpWasmF64Add, ssa.OpWasmF64Sub, ssa.OpWasmF64Mul, ssa.OpWasmF64Div, ssa.OpWasmF64Copysign: getValue64(s, v.Args[0]) getValue64(s, v.Args[1]) s.Prog(v.Op.Asm()) @@ -316,37 +309,50 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) { } s.Prog(wasm.AI64DivS) - case ssa.OpWasmI64TruncSatF64S: + case ssa.OpWasmI64TruncSatF32S, ssa.OpWasmI64TruncSatF64S: getValue64(s, v.Args[0]) if objabi.GOWASM.SatConv { s.Prog(v.Op.Asm()) } else { + if v.Op == ssa.OpWasmI64TruncSatF32S { + s.Prog(wasm.AF64PromoteF32) + } p := s.Prog(wasm.ACall) p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: gc.WasmTruncS} } - case ssa.OpWasmI64TruncSatF64U: + case ssa.OpWasmI64TruncSatF32U, ssa.OpWasmI64TruncSatF64U: getValue64(s, v.Args[0]) if objabi.GOWASM.SatConv { s.Prog(v.Op.Asm()) } else { + if v.Op == ssa.OpWasmI64TruncSatF32U { + s.Prog(wasm.AF64PromoteF32) + } p := s.Prog(wasm.ACall) p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: gc.WasmTruncU} } - case - ssa.OpWasmF64Neg, ssa.OpWasmF64ConvertI64S, ssa.OpWasmF64ConvertI64U, + case ssa.OpWasmF32DemoteF64: + getValue64(s, v.Args[0]) + s.Prog(v.Op.Asm()) + + case ssa.OpWasmF64PromoteF32: + getValue64(s, v.Args[0]) + s.Prog(v.Op.Asm()) + + case ssa.OpWasmF32ConvertI64S, ssa.OpWasmF32ConvertI64U, + ssa.OpWasmF64ConvertI64S, ssa.OpWasmF64ConvertI64U, ssa.OpWasmI64Extend8S, ssa.OpWasmI64Extend16S, ssa.OpWasmI64Extend32S, - ssa.OpWasmF64Sqrt, ssa.OpWasmF64Trunc, ssa.OpWasmF64Ceil, ssa.OpWasmF64Floor, ssa.OpWasmF64Nearest, ssa.OpWasmF64Abs, ssa.OpWasmI64Ctz, ssa.OpWasmI64Clz, ssa.OpWasmI64Popcnt: + ssa.OpWasmF32Neg, ssa.OpWasmF32Sqrt, ssa.OpWasmF32Trunc, ssa.OpWasmF32Ceil, ssa.OpWasmF32Floor, ssa.OpWasmF32Nearest, ssa.OpWasmF32Abs, + ssa.OpWasmF64Neg, ssa.OpWasmF64Sqrt, ssa.OpWasmF64Trunc, ssa.OpWasmF64Ceil, ssa.OpWasmF64Floor, ssa.OpWasmF64Nearest, ssa.OpWasmF64Abs, + ssa.OpWasmI64Ctz, ssa.OpWasmI64Clz, ssa.OpWasmI64Popcnt: getValue64(s, v.Args[0]) s.Prog(v.Op.Asm()) case ssa.OpLoadReg: p := s.Prog(loadOp(v.Type)) gc.AddrAuto(&p.From, v.Args[0]) - if v.Type.Etype == types.TFLOAT32 { - s.Prog(wasm.AF64PromoteF32) - } case ssa.OpCopy: getValue64(s, v.Args[0]) @@ -359,7 +365,9 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) { func isCmp(v *ssa.Value) bool { switch v.Op { - case ssa.OpWasmI64Eqz, ssa.OpWasmI64Eq, ssa.OpWasmI64Ne, ssa.OpWasmI64LtS, ssa.OpWasmI64LtU, ssa.OpWasmI64GtS, ssa.OpWasmI64GtU, ssa.OpWasmI64LeS, ssa.OpWasmI64LeU, ssa.OpWasmI64GeS, ssa.OpWasmI64GeU, ssa.OpWasmF64Eq, ssa.OpWasmF64Ne, ssa.OpWasmF64Lt, ssa.OpWasmF64Gt, ssa.OpWasmF64Le, ssa.OpWasmF64Ge: + case ssa.OpWasmI64Eqz, ssa.OpWasmI64Eq, ssa.OpWasmI64Ne, ssa.OpWasmI64LtS, ssa.OpWasmI64LtU, ssa.OpWasmI64GtS, ssa.OpWasmI64GtU, ssa.OpWasmI64LeS, ssa.OpWasmI64LeU, ssa.OpWasmI64GeS, ssa.OpWasmI64GeU, + ssa.OpWasmF32Eq, ssa.OpWasmF32Ne, ssa.OpWasmF32Lt, ssa.OpWasmF32Gt, ssa.OpWasmF32Le, ssa.OpWasmF32Ge, + ssa.OpWasmF64Eq, ssa.OpWasmF64Ne, ssa.OpWasmF64Lt, ssa.OpWasmF64Gt, ssa.OpWasmF64Le, ssa.OpWasmF64Ge: return true default: return false @@ -407,6 +415,11 @@ func i64Const(s *gc.SSAGenState, val int64) { p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: val} } +func f32Const(s *gc.SSAGenState, val float64) { + p := s.Prog(wasm.AF32Const) + p.From = obj.Addr{Type: obj.TYPE_FCONST, Val: val} +} + func f64Const(s *gc.SSAGenState, val float64) { p := s.Prog(wasm.AF64Const) p.From = obj.Addr{Type: obj.TYPE_FCONST, Val: val} |