mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
d6c2f1e90e
commit
1c50fcf853
10 changed files with 802 additions and 375 deletions
|
|
@ -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}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue