]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: handle floating point on ARM
authorCherry Zhang <cherryyz@google.com>
Tue, 31 May 2016 15:27:16 +0000 (11:27 -0400)
committerCherry Zhang <cherryyz@google.com>
Mon, 6 Jun 2016 14:06:38 +0000 (14:06 +0000)
Machine supports (or the runtime simulates in soft float mode)
(u)int32<->float conversions. The frontend rewrites int64<->float
conversions to call to runtime function.

For int64->float32 conversion, the frontend generates

.   .   AS u(100) l(10) tc(1)
.   .   .   NAME-main.~r1 u(1) a(true) g(1) l(9) x(8+0) class(PPARAMOUT) f(1) float32
.   .   .   CALLFUNC u(100) l(10) tc(1) float32
.   .   .   .   NAME-runtime.int64tofloat64 u(1) a(true) x(0+0) class(PFUNC) tc(1) used(true) FUNC-func(int64) float64

The CALLFUNC node has type float32, whereas runtime.int64tofloat64
returns float64. The legacy backend implicitly makes a float64->float32
conversion. The SSA backend does not do implicit conversion, so we
insert an explicit CONV here.

All cmd/compile/internal/gc/testdata/*_ssa.go tests passed.

Progress on SSA for ARM. Still not complete.

Update #15365.

Change-Id: I30937c8ff977271246b068f48224693776804339
Reviewed-on: https://go-review.googlesource.com/23652
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/arm/ssa.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/walk.go
src/cmd/compile/internal/ssa/decompose.go
src/cmd/compile/internal/ssa/gen/ARM.rules
src/cmd/compile/internal/ssa/gen/ARMOps.go
src/cmd/compile/internal/ssa/gen/genericOps.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteARM.go

index f4edbeae3b4e950d0194646871522555348796fd..afee8beeae8f04dc7208c94bbdecb26a9fb6db60 100644 (file)
@@ -5,6 +5,8 @@
 package arm
 
 import (
+       "math"
+
        "cmd/compile/internal/gc"
        "cmd/compile/internal/ssa"
        "cmd/internal/obj"
@@ -29,6 +31,23 @@ var ssaRegToReg = []int16{
        arm.REG_R14,
        arm.REG_R15,
 
+       arm.REG_F0,
+       arm.REG_F1,
+       arm.REG_F2,
+       arm.REG_F3,
+       arm.REG_F4,
+       arm.REG_F5,
+       arm.REG_F6,
+       arm.REG_F7,
+       arm.REG_F8,
+       arm.REG_F9,
+       arm.REG_F10,
+       arm.REG_F11,
+       arm.REG_F12,
+       arm.REG_F13,
+       arm.REG_F14,
+       arm.REG_F15,
+
        arm.REG_CPSR, // flag
        0,            // SB isn't a real register.  We fill an Addr.Reg field with 0 in this case.
 }
@@ -36,7 +55,12 @@ var ssaRegToReg = []int16{
 // loadByType returns the load instruction of the given type.
 func loadByType(t ssa.Type) obj.As {
        if t.IsFloat() {
-               panic("load floating point register is not implemented")
+               switch t.Size() {
+               case 4:
+                       return arm.AMOVF
+               case 8:
+                       return arm.AMOVD
+               }
        } else {
                switch t.Size() {
                case 1:
@@ -61,7 +85,12 @@ func loadByType(t ssa.Type) obj.As {
 // storeByType returns the store instruction of the given type.
 func storeByType(t ssa.Type) obj.As {
        if t.IsFloat() {
-               panic("store floating point register is not implemented")
+               switch t.Size() {
+               case 4:
+                       return arm.AMOVF
+               case 8:
+                       return arm.AMOVD
+               }
        } else {
                switch t.Size() {
                case 1:
@@ -93,7 +122,18 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                if x == y {
                        return
                }
-               p := gc.Prog(arm.AMOVW)
+               as := arm.AMOVW
+               if v.Type.IsFloat() {
+                       switch v.Type.Size() {
+                       case 4:
+                               as = arm.AMOVF
+                       case 8:
+                               as = arm.AMOVD
+                       default:
+                               panic("bad float size")
+                       }
+               }
+               p := gc.Prog(as)
                p.From.Type = obj.TYPE_REG
                p.From.Reg = x
                p.To.Type = obj.TYPE_REG
@@ -172,7 +212,15 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                ssa.OpARMOR,
                ssa.OpARMXOR,
                ssa.OpARMBIC,
-               ssa.OpARMMUL:
+               ssa.OpARMMUL,
+               ssa.OpARMADDF,
+               ssa.OpARMADDD,
+               ssa.OpARMSUBF,
+               ssa.OpARMSUBD,
+               ssa.OpARMMULF,
+               ssa.OpARMMULD,
+               ssa.OpARMDIVF,
+               ssa.OpARMDIVD:
                r := gc.SSARegNum(v)
                r1 := gc.SSARegNum(v.Args[0])
                r2 := gc.SSARegNum(v.Args[1])
@@ -331,10 +379,19 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.From.Offset = v.AuxInt
                p.To.Type = obj.TYPE_REG
                p.To.Reg = gc.SSARegNum(v)
+       case ssa.OpARMMOVFconst,
+               ssa.OpARMMOVDconst:
+               p := gc.Prog(v.Op.Asm())
+               p.From.Type = obj.TYPE_FCONST
+               p.From.Val = math.Float64frombits(uint64(v.AuxInt))
+               p.To.Type = obj.TYPE_REG
+               p.To.Reg = gc.SSARegNum(v)
        case ssa.OpARMCMP,
                ssa.OpARMCMN,
                ssa.OpARMTST,
-               ssa.OpARMTEQ:
+               ssa.OpARMTEQ,
+               ssa.OpARMCMPF,
+               ssa.OpARMCMPD:
                p := gc.Prog(v.Op.Asm())
                p.From.Type = obj.TYPE_REG
                // Special layout in ARM assembly
@@ -354,7 +411,9 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                ssa.OpARMMOVBUload,
                ssa.OpARMMOVHload,
                ssa.OpARMMOVHUload,
-               ssa.OpARMMOVWload:
+               ssa.OpARMMOVWload,
+               ssa.OpARMMOVFload,
+               ssa.OpARMMOVDload:
                p := gc.Prog(v.Op.Asm())
                p.From.Type = obj.TYPE_MEM
                p.From.Reg = gc.SSARegNum(v.Args[0])
@@ -363,7 +422,9 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Reg = gc.SSARegNum(v)
        case ssa.OpARMMOVBstore,
                ssa.OpARMMOVHstore,
-               ssa.OpARMMOVWstore:
+               ssa.OpARMMOVWstore,
+               ssa.OpARMMOVFstore,
+               ssa.OpARMMOVDstore:
                p := gc.Prog(v.Op.Asm())
                p.From.Type = obj.TYPE_REG
                p.From.Reg = gc.SSARegNum(v.Args[1])
@@ -374,11 +435,25 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                ssa.OpARMMOVBUreg,
                ssa.OpARMMOVHreg,
                ssa.OpARMMOVHUreg,
-               ssa.OpARMMVN:
-               if v.Type.IsMemory() {
-                       v.Fatalf("memory operand for %s", v.LongString())
-               }
+               ssa.OpARMMVN,
+               ssa.OpARMSQRTD,
+               ssa.OpARMMOVWF,
+               ssa.OpARMMOVWD,
+               ssa.OpARMMOVFW,
+               ssa.OpARMMOVDW,
+               ssa.OpARMMOVFD,
+               ssa.OpARMMOVDF:
+               p := gc.Prog(v.Op.Asm())
+               p.From.Type = obj.TYPE_REG
+               p.From.Reg = gc.SSARegNum(v.Args[0])
+               p.To.Type = obj.TYPE_REG
+               p.To.Reg = gc.SSARegNum(v)
+       case ssa.OpARMMOVWUF,
+               ssa.OpARMMOVWUD,
+               ssa.OpARMMOVFWU,
+               ssa.OpARMMOVDWU:
                p := gc.Prog(v.Op.Asm())
+               p.Scond = arm.C_UBIT
                p.From.Type = obj.TYPE_REG
                p.From.Reg = gc.SSARegNum(v.Args[0])
                p.To.Type = obj.TYPE_REG
index a2ed15dd4dd0e3e4deb69618ed47debca97d41e1..08544ff5beebd9ce9f862bf98eba246ae5661a2e 100644 (file)
@@ -1323,6 +1323,15 @@ var fpConvOpToSSA = map[twoTypes]twoOpsAndType{
        twoTypes{TFLOAT32, TFLOAT64}: twoOpsAndType{ssa.OpCvt32Fto64F, ssa.OpCopy, TFLOAT64},
 }
 
+// this map is used only for 32-bit arch, and only includes the difference
+// on 32-bit arch, don't use int64<->float conversion for uint32
+var fpConvOpToSSA32 = map[twoTypes]twoOpsAndType{
+       twoTypes{TUINT32, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32Uto32F, TUINT32},
+       twoTypes{TUINT32, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32Uto64F, TUINT32},
+       twoTypes{TFLOAT32, TUINT32}: twoOpsAndType{ssa.OpCvt32Fto32U, ssa.OpCopy, TUINT32},
+       twoTypes{TFLOAT64, TUINT32}: twoOpsAndType{ssa.OpCvt64Fto32U, ssa.OpCopy, TUINT32},
+}
+
 var shiftOpToSSA = map[opAndTwoTypes]ssa.Op{
        opAndTwoTypes{OLSH, TINT8, TUINT8}:   ssa.OpLsh8x8,
        opAndTwoTypes{OLSH, TUINT8, TUINT8}:  ssa.OpLsh8x8,
@@ -1639,6 +1648,11 @@ func (s *state) expr(n *Node) *ssa.Value {
 
                if ft.IsFloat() || tt.IsFloat() {
                        conv, ok := fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]
+                       if s.config.IntSize == 4 {
+                               if conv1, ok1 := fpConvOpToSSA32[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
+                                       conv = conv1
+                               }
+                       }
                        if !ok {
                                s.Fatalf("weird float conversion %s -> %s", ft, tt)
                        }
index 66eb7e97ac6c6dc0a2d2dfbd4fae6586e9f2ab94..f2d27f207c613e87ddab466af20a8e476eaaed11 100644 (file)
@@ -1094,12 +1094,12 @@ opswitch:
 
                        if n.Type.IsFloat() {
                                if n.Left.Type.Etype == TINT64 {
-                                       n = mkcall("int64tofloat64", n.Type, init, conv(n.Left, Types[TINT64]))
+                                       n = conv(mkcall("int64tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TINT64])), n.Type)
                                        break
                                }
 
                                if n.Left.Type.Etype == TUINT64 {
-                                       n = mkcall("uint64tofloat64", n.Type, init, conv(n.Left, Types[TUINT64]))
+                                       n = conv(mkcall("uint64tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TUINT64])), n.Type)
                                        break
                                }
                        }
index 0ee5f532915d5619b72d188c46fff8007d47d31b..08cc1b9dee7c0d3b3e266a3dcd948158cf1cb553 100644 (file)
@@ -94,6 +94,8 @@ func decomposeBuiltIn(f *Func) {
                                f.NamedValues[dataName] = append(f.NamedValues[dataName], data)
                        }
                        delete(f.NamedValues, name)
+               case t.IsFloat():
+                       // floats are never decomposed, even ones bigger than IntSize
                case t.Size() > f.Config.IntSize:
                        f.Unimplementedf("undecomposed named type %s %s", name, t)
                default:
@@ -115,6 +117,8 @@ func decomposeBuiltInPhi(v *Value) {
                decomposeSlicePhi(v)
        case v.Type.IsInterface():
                decomposeInterfacePhi(v)
+       case v.Type.IsFloat():
+               // floats are never decomposed, even ones bigger than IntSize
        case v.Type.Size() > v.Block.Func.Config.IntSize:
                v.Unimplementedf("undecomposed type %s", v.Type)
        }
index f36cf6abaade96b8c654006291909a74d9130dd6..79d18687adb82eb669dc0e2d799588918fed7bbe 100644 (file)
@@ -6,6 +6,8 @@
 (Add32 x y) -> (ADD x y)
 (Add16 x y) -> (ADD x y)
 (Add8 x y) -> (ADD x y)
+(Add32F x y) -> (ADDF x y)
+(Add64F x y) -> (ADDD x y)
 
 (Add32carry x y) -> (ADDS x y)
 (Add32withcarry x y c) -> (ADC x y c)
@@ -14,6 +16,8 @@
 (Sub32 x y) -> (SUB x y)
 (Sub16 x y) -> (SUB x y)
 (Sub8 x y) -> (SUB x y)
+(Sub32F x y) -> (SUBF x y)
+(Sub64F x y) -> (SUBD x y)
 
 (Sub32carry x y) -> (SUBS x y)
 (Sub32withcarry x y c) -> (SBC x y c)
@@ -21,6 +25,8 @@
 (Mul32 x y) -> (MUL x y)
 (Mul16 x y) -> (MUL x y)
 (Mul8 x y) -> (MUL x y)
+(Mul32F x y) -> (MULF x y)
+(Mul64F x y) -> (MULD x y)
 
 (Hmul32 x y) -> (HMUL x y)
 (Hmul32u x y) -> (HMULU x y)
@@ -37,6 +43,8 @@
 (Div16u x y) -> (DIVU (ZeroExt16to32 x) (ZeroExt16to32 y))
 (Div8 x y) -> (DIV (SignExt8to32 x) (SignExt8to32 y))
 (Div8u x y) -> (DIVU (ZeroExt8to32 x) (ZeroExt8to32 y))
+(Div32F x y) -> (DIVF x y)
+(Div64F x y) -> (DIVD x y)
 
 (Mod32 x y) -> (MOD x y)
 (Mod32u x y) -> (MODU x y)
 (Neg32 x) -> (RSBconst [0] x)
 (Neg16 x) -> (RSBconst [0] x)
 (Neg8 x) -> (RSBconst [0] x)
+//TODO: implement NEGF, NEGD in assembler and soft float simulator, and use them.
+(Neg32F x) -> (MULF (MOVFconst [int64(math.Float64bits(-1))]) x)
+(Neg64F x) -> (MULD (MOVDconst [int64(math.Float64bits(-1))]) x)
 
 (Com32 x) -> (MVN x)
 (Com16 x) -> (MVN x)
 (Com8 x) -> (MVN x)
 
+(Sqrt x) -> (SQRTD x)
+
 // boolean ops -- booleans are represented with 0=false, 1=true
 (AndB x y) -> (AND x y)
 (OrB x y) -> (OR x y)
 (Const8 [val]) -> (MOVWconst [val])
 (Const16 [val]) -> (MOVWconst [val])
 (Const32 [val]) -> (MOVWconst [val])
+(Const32F [val]) -> (MOVFconst [val])
+(Const64F [val]) -> (MOVDconst [val])
 (ConstNil) -> (MOVWconst [0])
 (ConstBool [b]) -> (MOVWconst [b])
 
 (Signmask x) -> (SRAconst x [31])
 (Zeromask x) -> (LoweredZeromask x)
 
+// float <-> int conversion
+(Cvt32to32F x) -> (MOVWF x)
+(Cvt32to64F x) -> (MOVWD x)
+(Cvt32Uto32F x) -> (MOVWUF x)
+(Cvt32Uto64F x) -> (MOVWUD x)
+(Cvt32Fto32 x) -> (MOVFW x)
+(Cvt64Fto32 x) -> (MOVDW x)
+(Cvt32Fto32U x) -> (MOVFWU x)
+(Cvt64Fto32U x) -> (MOVDWU x)
+(Cvt32Fto64F x) -> (MOVFD x)
+(Cvt64Fto32F x) -> (MOVDF x)
+
 // comparisons
 (Eq8 x y)  -> (Equal (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
 (Eq16 x y) -> (Equal (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
 (Eq32 x y) -> (Equal (CMP x y))
 (EqPtr x y) -> (Equal (CMP x y))
+(Eq32F x y) -> (Equal (CMPF x y))
+(Eq64F x y) -> (Equal (CMPD x y))
 
 (Neq8 x y)  -> (NotEqual (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
 (Neq16 x y) -> (NotEqual (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
 (Neq32 x y) -> (NotEqual (CMP x y))
 (NeqPtr x y) -> (NotEqual (CMP x y))
+(Neq32F x y) -> (NotEqual (CMPF x y))
+(Neq64F x y) -> (NotEqual (CMPD x y))
 
 (Less8 x y)  -> (LessThan (CMP (SignExt8to32 x) (SignExt8to32 y)))
 (Less16 x y) -> (LessThan (CMP (SignExt16to32 x) (SignExt16to32 y)))
 (Less32 x y) -> (LessThan (CMP x y))
+(Less32F x y) -> (GreaterThan (CMPF y x)) // reverse operands to work around NaN
+(Less64F x y) -> (GreaterThan (CMPD y x)) // reverse operands to work around NaN
 
 (Less8U x y)  -> (LessThanU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
 (Less16U x y) -> (LessThanU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
 (Leq8 x y)  -> (LessEqual (CMP (SignExt8to32 x) (SignExt8to32 y)))
 (Leq16 x y) -> (LessEqual (CMP (SignExt16to32 x) (SignExt16to32 y)))
 (Leq32 x y) -> (LessEqual (CMP x y))
+(Leq32F x y) -> (GreaterEqual (CMPF y x)) // reverse operands to work around NaN
+(Leq64F x y) -> (GreaterEqual (CMPD y x)) // reverse operands to work around NaN
 
 (Leq8U x y)  -> (LessEqualU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
 (Leq16U x y) -> (LessEqualU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
 (Greater8 x y)  -> (GreaterThan (CMP (SignExt8to32 x) (SignExt8to32 y)))
 (Greater16 x y) -> (GreaterThan (CMP (SignExt16to32 x) (SignExt16to32 y)))
 (Greater32 x y) -> (GreaterThan (CMP x y))
+(Greater32F x y) -> (GreaterThan (CMPF x y))
+(Greater64F x y) -> (GreaterThan (CMPD x y))
 
 (Greater8U x y)  -> (GreaterThanU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
 (Greater16U x y) -> (GreaterThanU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
 (Geq8 x y)  -> (GreaterEqual (CMP (SignExt8to32 x) (SignExt8to32 y)))
 (Geq16 x y) -> (GreaterEqual (CMP (SignExt16to32 x) (SignExt16to32 y)))
 (Geq32 x y) -> (GreaterEqual (CMP x y))
+(Geq32F x y) -> (GreaterEqual (CMPF x y))
+(Geq64F x y) -> (GreaterEqual (CMPD x y))
 
 (Geq8U x y)  -> (GreaterEqualU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
 (Geq16U x y) -> (GreaterEqualU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
 (Load <t> ptr mem) && (is16BitInt(t) && isSigned(t)) -> (MOVHload ptr mem)
 (Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) -> (MOVHUload ptr mem)
 (Load <t> ptr mem) && (is32BitInt(t) || isPtr(t)) -> (MOVWload ptr mem)
+(Load <t> ptr mem) && is32BitFloat(t) -> (MOVFload ptr mem)
+(Load <t> ptr mem) && is64BitFloat(t) -> (MOVDload ptr mem)
 
 // stores
 (Store [1] ptr val mem) -> (MOVBstore ptr val mem)
 (Store [2] ptr val mem) -> (MOVHstore ptr val mem)
-(Store [4] ptr val mem) -> (MOVWstore ptr val mem)
+(Store [4] ptr val mem) && !is32BitFloat(val.Type) -> (MOVWstore ptr val mem)
+(Store [4] ptr val mem) && is32BitFloat(val.Type) -> (MOVFstore ptr val mem)
+(Store [8] ptr val mem) && is64BitFloat(val.Type) -> (MOVDstore ptr val mem)
 
 // zero instructions
 //TODO: check alignment?
   (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVWload [off1] {sym1} (ADDconst [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
   (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVFload [off1] {sym1} (ADDconst [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+  (MOVFload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVDload [off1] {sym1} (ADDconst [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+  (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 
 (MOVBstore [off1] {sym1} (ADDconst [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
   (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
   (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 (MOVWstore [off1] {sym1} (ADDconst [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
   (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVFstore [off1] {sym1} (ADDconst [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+  (MOVFstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVDstore [off1] {sym1} (ADDconst [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+  (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 
 (ADD (MUL x y) a) -> (MULA x y a)
 (ADD a (MUL x y)) -> (MULA x y a)
index 4fc723897c733859f7bad3d975b34d5a943f57cc..6a76b0a968114ab159ea05b827d18a9e2ce3485d 100644 (file)
@@ -22,6 +22,8 @@ import "strings"
 // HU            = 16 bit unsigned
 // B (byte)      = 8 bit
 // BU            = 8 bit unsigned
+// F (float)     = 32 bit float
+// D (double)    = 64 bit float
 
 var regNamesARM = []string{
        "R0",
@@ -41,6 +43,23 @@ var regNamesARM = []string{
        "R14", // link
        "R15", // pc
 
+       "F0",
+       "F1",
+       "F2",
+       "F3",
+       "F4",
+       "F5",
+       "F6",
+       "F7",
+       "F8",
+       "F9",
+       "F10",
+       "F11",
+       "F12",
+       "F13",
+       "F14",
+       "F15", // tmp
+
        // pseudo-registers
        "FLAGS",
        "SB",
@@ -73,7 +92,8 @@ func init() {
                gpsp       = gp | buildReg("SP")
                gpspsb     = gpsp | buildReg("SB")
                flags      = buildReg("FLAGS")
-               callerSave = gp | flags
+               fp         = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15")
+               callerSave = gp | fp | flags
        )
        // Common regInfo
        var (
@@ -88,6 +108,14 @@ func init() {
                gp31      = regInfo{inputs: []regMask{gp, gp, gp}, outputs: []regMask{gp}}
                gpload    = regInfo{inputs: []regMask{gpspsb}, outputs: []regMask{gp}}
                gpstore   = regInfo{inputs: []regMask{gpspsb, gp}, outputs: []regMask{}}
+               fp01      = regInfo{inputs: []regMask{}, outputs: []regMask{fp}}
+               fp11      = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
+               fpgp      = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}
+               gpfp      = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}
+               fp21      = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
+               fp2flags  = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{flags}}
+               fpload    = regInfo{inputs: []regMask{gpspsb}, outputs: []regMask{fp}}
+               fpstore   = regInfo{inputs: []regMask{gpspsb, fp}, outputs: []regMask{}}
                readflags = regInfo{inputs: []regMask{flags}, outputs: []regMask{gp}}
        )
        ops := []opData{
@@ -114,6 +142,15 @@ func init() {
                {name: "MULLU", argLength: 2, reg: regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp &^ buildReg("R0")}, clobbers: buildReg("R0")}, asm: "MULLU", commutative: true}, // arg0 * arg1, results 64-bit, high 32-bit in R0
                {name: "MULA", argLength: 3, reg: gp31, asm: "MULA"},                                                                                                                        // arg0 * arg1 + arg2
 
+               {name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
+               {name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1
+               {name: "SUBF", argLength: 2, reg: fp21, asm: "SUBF"},                    // arg0 - arg1
+               {name: "SUBD", argLength: 2, reg: fp21, asm: "SUBD"},                    // arg0 - arg1
+               {name: "MULF", argLength: 2, reg: fp21, asm: "MULF", commutative: true}, // arg0 * arg1
+               {name: "MULD", argLength: 2, reg: fp21, asm: "MULD", commutative: true}, // arg0 * arg1
+               {name: "DIVF", argLength: 2, reg: fp21, asm: "DIVF"},                    // arg0 / arg1
+               {name: "DIVD", argLength: 2, reg: fp21, asm: "DIVD"},                    // arg0 / arg1
+
                {name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, // arg0 & arg1
                {name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int32"}, // arg0 & auxInt
                {name: "OR", argLength: 2, reg: gp21, asm: "ORR", commutative: true},  // arg0 | arg1
@@ -126,6 +163,8 @@ func init() {
                // unary ops
                {name: "MVN", argLength: 1, reg: gp11, asm: "MVN"}, // ^arg0
 
+               {name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
+
                // shifts
                {name: "SLL", argLength: 2, reg: gp21cf, asm: "SLL"},                  // arg0 << arg1, results 0 for large shift
                {name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt
@@ -143,24 +182,43 @@ func init() {
                {name: "TSTconst", argLength: 1, reg: gp1flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & auxInt compare to 0
                {name: "TEQ", argLength: 2, reg: gp2flags, asm: "TEQ", typ: "Flags", commutative: true}, // arg0 ^ arg1 compare to 0
                {name: "TEQconst", argLength: 1, reg: gp1flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ auxInt compare to 0
+               {name: "CMPF", argLength: 2, reg: fp2flags, asm: "CMPF", typ: "Flags"},                  // arg0 compare to arg1, float32
+               {name: "CMPD", argLength: 2, reg: fp2flags, asm: "CMPD", typ: "Flags"},                  // arg0 compare to arg1, float64
 
-               {name: "MOVWconst", argLength: 0, reg: gp01, aux: "Int32", asm: "MOVW", typ: "UInt32", rematerializeable: true}, // 32 low bits of auxint
+               {name: "MOVWconst", argLength: 0, reg: gp01, aux: "Int32", asm: "MOVW", typ: "UInt32", rematerializeable: true},    // 32 low bits of auxint
+               {name: "MOVFconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVF", typ: "Float32", rematerializeable: true}, // auxint as 64-bit float, convert to 32-bit float
+               {name: "MOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVD", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float
 
                {name: "MOVBload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVB", typ: "Int8"},     // load from arg0 + auxInt + aux.  arg1=mem.
                {name: "MOVBUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVBU", typ: "UInt8"},  // load from arg0 + auxInt + aux.  arg1=mem.
                {name: "MOVHload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVH", typ: "Int16"},    // load from arg0 + auxInt + aux.  arg1=mem.
                {name: "MOVHUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVHU", typ: "UInt16"}, // load from arg0 + auxInt + aux.  arg1=mem.
                {name: "MOVWload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVW", typ: "UInt32"},   // load from arg0 + auxInt + aux.  arg1=mem.
+               {name: "MOVFload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVF", typ: "Float32"},  // load from arg0 + auxInt + aux.  arg1=mem.
+               {name: "MOVDload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVD", typ: "Float64"},  // load from arg0 + auxInt + aux.  arg1=mem.
 
                {name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVB", typ: "Mem"}, // store 1 byte of arg1 to arg0 + auxInt + aux.  arg2=mem.
                {name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem"}, // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
                {name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVW", typ: "Mem"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+               {name: "MOVFstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVF", typ: "Mem"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+               {name: "MOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVD", typ: "Mem"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
 
                {name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVBS"},  // move from arg0, sign-extended from byte
                {name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
                {name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVHS"},  // move from arg0, sign-extended from half
                {name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
 
+               {name: "MOVWF", argLength: 1, reg: gpfp, asm: "MOVWF"},  // int32 -> float32
+               {name: "MOVWD", argLength: 1, reg: gpfp, asm: "MOVWD"},  // int32 -> float64
+               {name: "MOVWUF", argLength: 1, reg: gpfp, asm: "MOVWF"}, // uint32 -> float32, set U bit in the instruction
+               {name: "MOVWUD", argLength: 1, reg: gpfp, asm: "MOVWD"}, // uint32 -> float64, set U bit in the instruction
+               {name: "MOVFW", argLength: 1, reg: fpgp, asm: "MOVFW"},  // float32 -> int32
+               {name: "MOVDW", argLength: 1, reg: fpgp, asm: "MOVDW"},  // float64 -> int32
+               {name: "MOVFWU", argLength: 1, reg: fpgp, asm: "MOVFW"}, // float32 -> uint32, set U bit in the instruction
+               {name: "MOVDWU", argLength: 1, reg: fpgp, asm: "MOVDW"}, // float64 -> uint32, set U bit in the instruction
+               {name: "MOVFD", argLength: 1, reg: fp11, asm: "MOVFD"},  // float32 -> float64
+               {name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"},  // float64 -> float32
+
                {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff"},                                // call static function aux.(*gc.Sym).  arg0=mem, auxint=argsize, returns mem
                {name: "CALLclosure", argLength: 3, reg: regInfo{[]regMask{gpsp, buildReg("R7"), 0}, callerSave, nil}, aux: "Int64"}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
                {name: "CALLdefer", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "Int64"},                                  // call deferproc.  arg0=mem, auxint=argsize, returns mem
@@ -290,7 +348,7 @@ func init() {
                blocks:          blocks,
                regnames:        regNamesARM,
                gpregmask:       gp,
-               fpregmask:       0, // fp not implemented yet
+               fpregmask:       fp,
                flagmask:        flags,
                framepointerreg: -1, // not used
        })
index 72b7f6fe824d1d0c1aa21a1c3bdece665f8e62c5..e35da2bb64d5809e10616e049f0bb16e15dbdb13 100644 (file)
@@ -433,6 +433,11 @@ var genericOps = []opData{
        {name: "Signmask", argLength: 1, typ: "Int32"},  // 0 if arg0 >= 0, -1 if arg0 < 0
        {name: "Zeromask", argLength: 1, typ: "UInt32"}, // 0 if arg0 == 0, 0xffffffff if arg0 != 0
 
+       {name: "Cvt32Uto32F", argLength: 1}, // uint32 -> float32, only used on 32-bit arch
+       {name: "Cvt32Uto64F", argLength: 1}, // uint32 -> float64, only used on 32-bit arch
+       {name: "Cvt32Fto32U", argLength: 1}, // float32 -> uint32, only used on 32-bit arch
+       {name: "Cvt64Fto32U", argLength: 1}, // float64 -> uint32, only used on 32-bit arch
+
        // pseudo-ops for breaking Tuple
        {name: "Select0", argLength: 1}, // the first component of a tuple
        {name: "Select1", argLength: 1}, // the second component of a tuple
index 33f700c005c69ce753995d760269d85b584c5913..477f16d4f1f3f2b14191e421dabcb54d061c0352 100644 (file)
@@ -342,6 +342,14 @@ const (
        OpARMSBC
        OpARMMULLU
        OpARMMULA
+       OpARMADDF
+       OpARMADDD
+       OpARMSUBF
+       OpARMSUBD
+       OpARMMULF
+       OpARMMULD
+       OpARMDIVF
+       OpARMDIVD
        OpARMAND
        OpARMANDconst
        OpARMOR
@@ -351,6 +359,7 @@ const (
        OpARMBIC
        OpARMBICconst
        OpARMMVN
+       OpARMSQRTD
        OpARMSLL
        OpARMSLLconst
        OpARMSRL
@@ -366,19 +375,37 @@ const (
        OpARMTSTconst
        OpARMTEQ
        OpARMTEQconst
+       OpARMCMPF
+       OpARMCMPD
        OpARMMOVWconst
+       OpARMMOVFconst
+       OpARMMOVDconst
        OpARMMOVBload
        OpARMMOVBUload
        OpARMMOVHload
        OpARMMOVHUload
        OpARMMOVWload
+       OpARMMOVFload
+       OpARMMOVDload
        OpARMMOVBstore
        OpARMMOVHstore
        OpARMMOVWstore
+       OpARMMOVFstore
+       OpARMMOVDstore
        OpARMMOVBreg
        OpARMMOVBUreg
        OpARMMOVHreg
        OpARMMOVHUreg
+       OpARMMOVWF
+       OpARMMOVWD
+       OpARMMOVWUF
+       OpARMMOVWUD
+       OpARMMOVFW
+       OpARMMOVDW
+       OpARMMOVFWU
+       OpARMMOVDWU
+       OpARMMOVFD
+       OpARMMOVDF
        OpARMCALLstatic
        OpARMCALLclosure
        OpARMCALLdefer
@@ -702,6 +729,10 @@ const (
        OpMul32uhilo
        OpSignmask
        OpZeromask
+       OpCvt32Uto32F
+       OpCvt32Uto64F
+       OpCvt32Fto32U
+       OpCvt64Fto32U
        OpSelect0
        OpSelect1
 )
@@ -3906,7 +3937,7 @@ var opcodeTable = [...]opInfo{
                asm:     arm.AADD,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 144383}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4023,7 +4054,7 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
-                       clobbers: 65536, // FLAGS
+                       clobbers: 4294967296, // FLAGS
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
@@ -4038,7 +4069,7 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
-                       clobbers: 65536, // FLAGS
+                       clobbers: 4294967296, // FLAGS
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
@@ -4053,7 +4084,7 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
-                       clobbers: 65536, // FLAGS
+                       clobbers: 4294967296, // FLAGS
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
@@ -4068,7 +4099,7 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
-                       clobbers: 65536, // FLAGS
+                       clobbers: 4294967296, // FLAGS
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
@@ -4084,7 +4115,7 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
-                       clobbers: 65536, // FLAGS
+                       clobbers: 4294967296, // FLAGS
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
@@ -4097,9 +4128,9 @@ var opcodeTable = [...]opInfo{
                asm:         arm.AADC,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {2, 65536}, // FLAGS
-                               {0, 5119},  // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
-                               {1, 5119},  // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                               {2, 4294967296}, // FLAGS
+                               {0, 5119},       // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                               {1, 5119},       // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4115,7 +4146,7 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
-                       clobbers: 65536, // FLAGS
+                       clobbers: 4294967296, // FLAGS
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
@@ -4127,9 +4158,9 @@ var opcodeTable = [...]opInfo{
                asm:    arm.ASBC,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {2, 65536}, // FLAGS
-                               {0, 5119},  // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
-                               {1, 5119},  // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                               {2, 4294967296}, // FLAGS
+                               {0, 5119},       // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                               {1, 5119},       // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4167,6 +4198,122 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:        "ADDF",
+               argLen:      2,
+               commutative: true,
+               asm:         arm.AADDF,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                               {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:        "ADDD",
+               argLen:      2,
+               commutative: true,
+               asm:         arm.AADDD,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                               {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:   "SUBF",
+               argLen: 2,
+               asm:    arm.ASUBF,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                               {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:   "SUBD",
+               argLen: 2,
+               asm:    arm.ASUBD,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                               {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:        "MULF",
+               argLen:      2,
+               commutative: true,
+               asm:         arm.AMULF,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                               {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:        "MULD",
+               argLen:      2,
+               commutative: true,
+               asm:         arm.AMULD,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                               {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:   "DIVF",
+               argLen: 2,
+               asm:    arm.ADIVF,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                               {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:   "DIVD",
+               argLen: 2,
+               asm:    arm.ADIVD,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                               {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
        {
                name:        "AND",
                argLen:      2,
@@ -4295,6 +4442,19 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:   "SQRTD",
+               argLen: 1,
+               asm:    arm.ASQRTD,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
        {
                name:   "SLL",
                argLen: 2,
@@ -4304,7 +4464,7 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
-                       clobbers: 65536, // FLAGS
+                       clobbers: 4294967296, // FLAGS
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
@@ -4333,7 +4493,7 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
-                       clobbers: 65536, // FLAGS
+                       clobbers: 4294967296, // FLAGS
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
@@ -4362,7 +4522,7 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
-                       clobbers: 65536, // FLAGS
+                       clobbers: 4294967296, // FLAGS
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
@@ -4405,7 +4565,7 @@ var opcodeTable = [...]opInfo{
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
                        outputs: []regMask{
-                               65536, // FLAGS
+                               4294967296, // FLAGS
                        },
                },
        },
@@ -4419,7 +4579,7 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
                        outputs: []regMask{
-                               65536, // FLAGS
+                               4294967296, // FLAGS
                        },
                },
        },
@@ -4433,7 +4593,7 @@ var opcodeTable = [...]opInfo{
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
                        outputs: []regMask{
-                               65536, // FLAGS
+                               4294967296, // FLAGS
                        },
                },
        },
@@ -4447,7 +4607,7 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
                        outputs: []regMask{
-                               65536, // FLAGS
+                               4294967296, // FLAGS
                        },
                },
        },
@@ -4462,7 +4622,7 @@ var opcodeTable = [...]opInfo{
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
                        outputs: []regMask{
-                               65536, // FLAGS
+                               4294967296, // FLAGS
                        },
                },
        },
@@ -4476,7 +4636,7 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
                        outputs: []regMask{
-                               65536, // FLAGS
+                               4294967296, // FLAGS
                        },
                },
        },
@@ -4491,7 +4651,7 @@ var opcodeTable = [...]opInfo{
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
                        outputs: []regMask{
-                               65536, // FLAGS
+                               4294967296, // FLAGS
                        },
                },
        },
@@ -4505,7 +4665,35 @@ var opcodeTable = [...]opInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
                        outputs: []regMask{
-                               65536, // FLAGS
+                               4294967296, // FLAGS
+                       },
+               },
+       },
+       {
+               name:   "CMPF",
+               argLen: 2,
+               asm:    arm.ACMPF,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                               {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294967296, // FLAGS
+                       },
+               },
+       },
+       {
+               name:   "CMPD",
+               argLen: 2,
+               asm:    arm.ACMPD,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                               {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294967296, // FLAGS
                        },
                },
        },
@@ -4521,6 +4709,30 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:              "MOVFconst",
+               auxType:           auxFloat64,
+               argLen:            0,
+               rematerializeable: true,
+               asm:               arm.AMOVF,
+               reg: regInfo{
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:              "MOVDconst",
+               auxType:           auxFloat64,
+               argLen:            0,
+               rematerializeable: true,
+               asm:               arm.AMOVD,
+               reg: regInfo{
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
        {
                name:    "MOVBload",
                auxType: auxSymOff,
@@ -4528,7 +4740,7 @@ var opcodeTable = [...]opInfo{
                asm:     arm.AMOVB,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 144383}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4542,7 +4754,7 @@ var opcodeTable = [...]opInfo{
                asm:     arm.AMOVBU,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 144383}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4556,7 +4768,7 @@ var opcodeTable = [...]opInfo{
                asm:     arm.AMOVH,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 144383}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4570,7 +4782,7 @@ var opcodeTable = [...]opInfo{
                asm:     arm.AMOVHU,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 144383}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4584,13 +4796,41 @@ var opcodeTable = [...]opInfo{
                asm:     arm.AMOVW,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 144383}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
                },
        },
+       {
+               name:    "MOVFload",
+               auxType: auxSymOff,
+               argLen:  2,
+               asm:     arm.AMOVF,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:    "MOVDload",
+               auxType: auxSymOff,
+               argLen:  2,
+               asm:     arm.AMOVD,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
        {
                name:    "MOVBstore",
                auxType: auxSymOff,
@@ -4598,8 +4838,8 @@ var opcodeTable = [...]opInfo{
                asm:     arm.AMOVB,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {1, 5119},   // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
-                               {0, 144383}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                               {1, 5119},       // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
                        },
                },
        },
@@ -4610,8 +4850,8 @@ var opcodeTable = [...]opInfo{
                asm:     arm.AMOVH,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {1, 5119},   // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
-                               {0, 144383}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                               {1, 5119},       // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
                        },
                },
        },
@@ -4622,8 +4862,32 @@ var opcodeTable = [...]opInfo{
                asm:     arm.AMOVW,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {1, 5119},   // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
-                               {0, 144383}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                               {1, 5119},       // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                       },
+               },
+       },
+       {
+               name:    "MOVFstore",
+               auxType: auxSymOff,
+               argLen:  3,
+               asm:     arm.AMOVF,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                               {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:    "MOVDstore",
+               auxType: auxSymOff,
+               argLen:  3,
+               asm:     arm.AMOVD,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 8589947903}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP SB
+                               {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
                        },
                },
        },
@@ -4679,12 +4943,142 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:   "MOVWF",
+               argLen: 1,
+               asm:    arm.AMOVWF,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:   "MOVWD",
+               argLen: 1,
+               asm:    arm.AMOVWD,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:   "MOVWUF",
+               argLen: 1,
+               asm:    arm.AMOVWF,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:   "MOVWUD",
+               argLen: 1,
+               asm:    arm.AMOVWD,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:   "MOVFW",
+               argLen: 1,
+               asm:    arm.AMOVFW,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                       },
+               },
+       },
+       {
+               name:   "MOVDW",
+               argLen: 1,
+               asm:    arm.AMOVDW,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                       },
+               },
+       },
+       {
+               name:   "MOVFWU",
+               argLen: 1,
+               asm:    arm.AMOVFW,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                       },
+               },
+       },
+       {
+               name:   "MOVDWU",
+               argLen: 1,
+               asm:    arm.AMOVDW,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                       },
+               },
+       },
+       {
+               name:   "MOVFD",
+               argLen: 1,
+               asm:    arm.AMOVFD,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
+       {
+               name:   "MOVDF",
+               argLen: 1,
+               asm:    arm.AMOVDF,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+                       outputs: []regMask{
+                               4294901760, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+                       },
+               },
+       },
        {
                name:    "CALLstatic",
                auxType: auxSymOff,
                argLen:  1,
                reg: regInfo{
-                       clobbers: 70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS
+                       clobbers: 8589874175, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 FLAGS
                },
        },
        {
@@ -4696,7 +5090,7 @@ var opcodeTable = [...]opInfo{
                                {1, 128},   // R7
                                {0, 13311}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP
                        },
-                       clobbers: 70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS
+                       clobbers: 8589874175, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 FLAGS
                },
        },
        {
@@ -4704,7 +5098,7 @@ var opcodeTable = [...]opInfo{
                auxType: auxInt64,
                argLen:  1,
                reg: regInfo{
-                       clobbers: 70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS
+                       clobbers: 8589874175, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 FLAGS
                },
        },
        {
@@ -4712,7 +5106,7 @@ var opcodeTable = [...]opInfo{
                auxType: auxInt64,
                argLen:  1,
                reg: regInfo{
-                       clobbers: 70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS
+                       clobbers: 8589874175, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 FLAGS
                },
        },
        {
@@ -4723,7 +5117,7 @@ var opcodeTable = [...]opInfo{
                        inputs: []inputInfo{
                                {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
-                       clobbers: 70655, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 FLAGS
+                       clobbers: 8589874175, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 FLAGS
                },
        },
        {
@@ -4733,7 +5127,7 @@ var opcodeTable = [...]opInfo{
                        inputs: []inputInfo{
                                {0, 13311}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 SP
                        },
-                       clobbers: 65536, // FLAGS
+                       clobbers: 4294967296, // FLAGS
                },
        },
        {
@@ -4741,7 +5135,7 @@ var opcodeTable = [...]opInfo{
                argLen: 1,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 65536}, // FLAGS
+                               {0, 4294967296}, // FLAGS
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4753,7 +5147,7 @@ var opcodeTable = [...]opInfo{
                argLen: 1,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 65536}, // FLAGS
+                               {0, 4294967296}, // FLAGS
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4765,7 +5159,7 @@ var opcodeTable = [...]opInfo{
                argLen: 1,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 65536}, // FLAGS
+                               {0, 4294967296}, // FLAGS
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4777,7 +5171,7 @@ var opcodeTable = [...]opInfo{
                argLen: 1,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 65536}, // FLAGS
+                               {0, 4294967296}, // FLAGS
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4789,7 +5183,7 @@ var opcodeTable = [...]opInfo{
                argLen: 1,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 65536}, // FLAGS
+                               {0, 4294967296}, // FLAGS
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4801,7 +5195,7 @@ var opcodeTable = [...]opInfo{
                argLen: 1,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 65536}, // FLAGS
+                               {0, 4294967296}, // FLAGS
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4813,7 +5207,7 @@ var opcodeTable = [...]opInfo{
                argLen: 1,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 65536}, // FLAGS
+                               {0, 4294967296}, // FLAGS
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4825,7 +5219,7 @@ var opcodeTable = [...]opInfo{
                argLen: 1,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 65536}, // FLAGS
+                               {0, 4294967296}, // FLAGS
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4837,7 +5231,7 @@ var opcodeTable = [...]opInfo{
                argLen: 1,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 65536}, // FLAGS
+                               {0, 4294967296}, // FLAGS
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4849,7 +5243,7 @@ var opcodeTable = [...]opInfo{
                argLen: 1,
                reg: regInfo{
                        inputs: []inputInfo{
-                               {0, 65536}, // FLAGS
+                               {0, 4294967296}, // FLAGS
                        },
                        outputs: []regMask{
                                5119, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
@@ -4861,7 +5255,7 @@ var opcodeTable = [...]opInfo{
                argLen: 1,
                reg: regInfo{
                        outputs: []regMask{
-                               65536, // FLAGS
+                               4294967296, // FLAGS
                        },
                },
        },
@@ -4932,7 +5326,7 @@ var opcodeTable = [...]opInfo{
                                {1, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                                {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
-                       clobbers: 65538, // R1 FLAGS
+                       clobbers: 4294967298, // R1 FLAGS
                },
        },
        {
@@ -4944,7 +5338,7 @@ var opcodeTable = [...]opInfo{
                                {1, 2},    // R1
                                {2, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
                        },
-                       clobbers: 65542, // R1 R2 FLAGS
+                       clobbers: 4294967302, // R1 R2 FLAGS
                },
        },
        {
@@ -6512,6 +6906,26 @@ var opcodeTable = [...]opInfo{
                argLen:  1,
                generic: true,
        },
+       {
+               name:    "Cvt32Uto32F",
+               argLen:  1,
+               generic: true,
+       },
+       {
+               name:    "Cvt32Uto64F",
+               argLen:  1,
+               generic: true,
+       },
+       {
+               name:    "Cvt32Fto32U",
+               argLen:  1,
+               generic: true,
+       },
+       {
+               name:    "Cvt64Fto32U",
+               argLen:  1,
+               generic: true,
+       },
        {
                name:    "Select0",
                argLen:  1,
@@ -6584,10 +6998,26 @@ var registersARM = [...]Register{
        {13, "SP"},
        {14, "R14"},
        {15, "R15"},
-       {16, "FLAGS"},
-       {17, "SB"},
+       {16, "F0"},
+       {17, "F1"},
+       {18, "F2"},
+       {19, "F3"},
+       {20, "F4"},
+       {21, "F5"},
+       {22, "F6"},
+       {23, "F7"},
+       {24, "F8"},
+       {25, "F9"},
+       {26, "F10"},
+       {27, "F11"},
+       {28, "F12"},
+       {29, "F13"},
+       {30, "F14"},
+       {31, "F15"},
+       {32, "FLAGS"},
+       {33, "SB"},
 }
 var gpRegMaskARM = regMask(5119)
-var fpRegMaskARM = regMask(0)
-var flagRegMaskARM = regMask(65536)
+var fpRegMaskARM = regMask(4294901760)
+var flagRegMaskARM = regMask(4294967296)
 var framepointerRegARM = int8(-1)
index d1a191e629295a7dde3133357e24877a01f5b2cd..90fb528f7d64eac750f1fce97cdf9d58c2b9a919 100644 (file)
@@ -14,10 +14,14 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpAdd16(v, config)
        case OpAdd32:
                return rewriteValueARM_OpAdd32(v, config)
+       case OpAdd32F:
+               return rewriteValueARM_OpAdd32F(v, config)
        case OpAdd32carry:
                return rewriteValueARM_OpAdd32carry(v, config)
        case OpAdd32withcarry:
                return rewriteValueARM_OpAdd32withcarry(v, config)
+       case OpAdd64F:
+               return rewriteValueARM_OpAdd64F(v, config)
        case OpAdd8:
                return rewriteValueARM_OpAdd8(v, config)
        case OpAddPtr:
@@ -44,6 +48,10 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpConst16(v, config)
        case OpConst32:
                return rewriteValueARM_OpConst32(v, config)
+       case OpConst32F:
+               return rewriteValueARM_OpConst32F(v, config)
+       case OpConst64F:
+               return rewriteValueARM_OpConst64F(v, config)
        case OpConst8:
                return rewriteValueARM_OpConst8(v, config)
        case OpConstBool:
@@ -52,6 +60,26 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpConstNil(v, config)
        case OpConvert:
                return rewriteValueARM_OpConvert(v, config)
+       case OpCvt32Fto32:
+               return rewriteValueARM_OpCvt32Fto32(v, config)
+       case OpCvt32Fto32U:
+               return rewriteValueARM_OpCvt32Fto32U(v, config)
+       case OpCvt32Fto64F:
+               return rewriteValueARM_OpCvt32Fto64F(v, config)
+       case OpCvt32Uto32F:
+               return rewriteValueARM_OpCvt32Uto32F(v, config)
+       case OpCvt32Uto64F:
+               return rewriteValueARM_OpCvt32Uto64F(v, config)
+       case OpCvt32to32F:
+               return rewriteValueARM_OpCvt32to32F(v, config)
+       case OpCvt32to64F:
+               return rewriteValueARM_OpCvt32to64F(v, config)
+       case OpCvt64Fto32:
+               return rewriteValueARM_OpCvt64Fto32(v, config)
+       case OpCvt64Fto32F:
+               return rewriteValueARM_OpCvt64Fto32F(v, config)
+       case OpCvt64Fto32U:
+               return rewriteValueARM_OpCvt64Fto32U(v, config)
        case OpDeferCall:
                return rewriteValueARM_OpDeferCall(v, config)
        case OpDiv16:
@@ -60,8 +88,12 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpDiv16u(v, config)
        case OpDiv32:
                return rewriteValueARM_OpDiv32(v, config)
+       case OpDiv32F:
+               return rewriteValueARM_OpDiv32F(v, config)
        case OpDiv32u:
                return rewriteValueARM_OpDiv32u(v, config)
+       case OpDiv64F:
+               return rewriteValueARM_OpDiv64F(v, config)
        case OpDiv8:
                return rewriteValueARM_OpDiv8(v, config)
        case OpDiv8u:
@@ -70,6 +102,10 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpEq16(v, config)
        case OpEq32:
                return rewriteValueARM_OpEq32(v, config)
+       case OpEq32F:
+               return rewriteValueARM_OpEq32F(v, config)
+       case OpEq64F:
+               return rewriteValueARM_OpEq64F(v, config)
        case OpEq8:
                return rewriteValueARM_OpEq8(v, config)
        case OpEqB:
@@ -82,8 +118,12 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpGeq16U(v, config)
        case OpGeq32:
                return rewriteValueARM_OpGeq32(v, config)
+       case OpGeq32F:
+               return rewriteValueARM_OpGeq32F(v, config)
        case OpGeq32U:
                return rewriteValueARM_OpGeq32U(v, config)
+       case OpGeq64F:
+               return rewriteValueARM_OpGeq64F(v, config)
        case OpGeq8:
                return rewriteValueARM_OpGeq8(v, config)
        case OpGeq8U:
@@ -98,8 +138,12 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpGreater16U(v, config)
        case OpGreater32:
                return rewriteValueARM_OpGreater32(v, config)
+       case OpGreater32F:
+               return rewriteValueARM_OpGreater32F(v, config)
        case OpGreater32U:
                return rewriteValueARM_OpGreater32U(v, config)
+       case OpGreater64F:
+               return rewriteValueARM_OpGreater64F(v, config)
        case OpGreater8:
                return rewriteValueARM_OpGreater8(v, config)
        case OpGreater8U:
@@ -130,8 +174,12 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpLeq16U(v, config)
        case OpLeq32:
                return rewriteValueARM_OpLeq32(v, config)
+       case OpLeq32F:
+               return rewriteValueARM_OpLeq32F(v, config)
        case OpLeq32U:
                return rewriteValueARM_OpLeq32U(v, config)
+       case OpLeq64F:
+               return rewriteValueARM_OpLeq64F(v, config)
        case OpLeq8:
                return rewriteValueARM_OpLeq8(v, config)
        case OpLeq8U:
@@ -142,8 +190,12 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpLess16U(v, config)
        case OpLess32:
                return rewriteValueARM_OpLess32(v, config)
+       case OpLess32F:
+               return rewriteValueARM_OpLess32F(v, config)
        case OpLess32U:
                return rewriteValueARM_OpLess32U(v, config)
+       case OpLess64F:
+               return rewriteValueARM_OpLess64F(v, config)
        case OpLess8:
                return rewriteValueARM_OpLess8(v, config)
        case OpLess8U:
@@ -186,6 +238,14 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpARMMOVBload(v, config)
        case OpARMMOVBstore:
                return rewriteValueARM_OpARMMOVBstore(v, config)
+       case OpARMMOVDload:
+               return rewriteValueARM_OpARMMOVDload(v, config)
+       case OpARMMOVDstore:
+               return rewriteValueARM_OpARMMOVDstore(v, config)
+       case OpARMMOVFload:
+               return rewriteValueARM_OpARMMOVFload(v, config)
+       case OpARMMOVFstore:
+               return rewriteValueARM_OpARMMOVFstore(v, config)
        case OpARMMOVHUload:
                return rewriteValueARM_OpARMMOVHUload(v, config)
        case OpARMMOVHload:
@@ -214,20 +274,32 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpMul16(v, config)
        case OpMul32:
                return rewriteValueARM_OpMul32(v, config)
+       case OpMul32F:
+               return rewriteValueARM_OpMul32F(v, config)
        case OpMul32uhilo:
                return rewriteValueARM_OpMul32uhilo(v, config)
+       case OpMul64F:
+               return rewriteValueARM_OpMul64F(v, config)
        case OpMul8:
                return rewriteValueARM_OpMul8(v, config)
        case OpNeg16:
                return rewriteValueARM_OpNeg16(v, config)
        case OpNeg32:
                return rewriteValueARM_OpNeg32(v, config)
+       case OpNeg32F:
+               return rewriteValueARM_OpNeg32F(v, config)
+       case OpNeg64F:
+               return rewriteValueARM_OpNeg64F(v, config)
        case OpNeg8:
                return rewriteValueARM_OpNeg8(v, config)
        case OpNeq16:
                return rewriteValueARM_OpNeq16(v, config)
        case OpNeq32:
                return rewriteValueARM_OpNeq32(v, config)
+       case OpNeq32F:
+               return rewriteValueARM_OpNeq32F(v, config)
+       case OpNeq64F:
+               return rewriteValueARM_OpNeq64F(v, config)
        case OpNeq8:
                return rewriteValueARM_OpNeq8(v, config)
        case OpNeqB:
@@ -308,6 +380,8 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpSignExt8to32(v, config)
        case OpSignmask:
                return rewriteValueARM_OpSignmask(v, config)
+       case OpSqrt:
+               return rewriteValueARM_OpSqrt(v, config)
        case OpStaticCall:
                return rewriteValueARM_OpStaticCall(v, config)
        case OpStore:
@@ -316,10 +390,14 @@ func rewriteValueARM(v *Value, config *Config) bool {
                return rewriteValueARM_OpSub16(v, config)
        case OpSub32:
                return rewriteValueARM_OpSub32(v, config)
+       case OpSub32F:
+               return rewriteValueARM_OpSub32F(v, config)
        case OpSub32carry:
                return rewriteValueARM_OpSub32carry(v, config)
        case OpSub32withcarry:
                return rewriteValueARM_OpSub32withcarry(v, config)
+       case OpSub64F:
+               return rewriteValueARM_OpSub64F(v, config)
        case OpSub8:
                return rewriteValueARM_OpSub8(v, config)
        case OpSubPtr:
@@ -448,6 +526,21 @@ func rewriteValueARM_OpAdd32(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpAdd32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Add32F x y)
+       // cond:
+       // result: (ADDF x y)
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMADDF)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
 func rewriteValueARM_OpAdd32carry(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -480,6 +573,21 @@ func rewriteValueARM_OpAdd32withcarry(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpAdd64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Add64F x y)
+       // cond:
+       // result: (ADDD x y)
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMADDD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
 func rewriteValueARM_OpAdd8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -669,6 +777,32 @@ func rewriteValueARM_OpConst32(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpConst32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Const32F [val])
+       // cond:
+       // result: (MOVFconst [val])
+       for {
+               val := v.AuxInt
+               v.reset(OpARMMOVFconst)
+               v.AuxInt = val
+               return true
+       }
+}
+func rewriteValueARM_OpConst64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Const64F [val])
+       // cond:
+       // result: (MOVDconst [val])
+       for {
+               val := v.AuxInt
+               v.reset(OpARMMOVDconst)
+               v.AuxInt = val
+               return true
+       }
+}
 func rewriteValueARM_OpConst8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -722,6 +856,136 @@ func rewriteValueARM_OpConvert(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpCvt32Fto32(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Cvt32Fto32 x)
+       // cond:
+       // result: (MOVFW x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVFW)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt32Fto32U(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Cvt32Fto32U x)
+       // cond:
+       // result: (MOVFWU x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVFWU)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt32Fto64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Cvt32Fto64F x)
+       // cond:
+       // result: (MOVFD x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVFD)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt32Uto32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Cvt32Uto32F x)
+       // cond:
+       // result: (MOVWUF x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVWUF)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt32Uto64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Cvt32Uto64F x)
+       // cond:
+       // result: (MOVWUD x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVWUD)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt32to32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Cvt32to32F x)
+       // cond:
+       // result: (MOVWF x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVWF)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt32to64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Cvt32to64F x)
+       // cond:
+       // result: (MOVWD x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVWD)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt64Fto32(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Cvt64Fto32 x)
+       // cond:
+       // result: (MOVDW x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVDW)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt64Fto32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Cvt64Fto32F x)
+       // cond:
+       // result: (MOVDF x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVDF)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpCvt64Fto32U(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Cvt64Fto32U x)
+       // cond:
+       // result: (MOVDWU x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMOVDWU)
+               v.AddArg(x)
+               return true
+       }
+}
 func rewriteValueARM_OpDeferCall(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -790,6 +1054,21 @@ func rewriteValueARM_OpDiv32(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpDiv32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Div32F x y)
+       // cond:
+       // result: (DIVF x y)
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMDIVF)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
 func rewriteValueARM_OpDiv32u(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -805,6 +1084,21 @@ func rewriteValueARM_OpDiv32u(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpDiv64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Div64F x y)
+       // cond:
+       // result: (DIVD x y)
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMDIVD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
 func rewriteValueARM_OpDiv8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -881,6 +1175,40 @@ func rewriteValueARM_OpEq32(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpEq32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Eq32F x y)
+       // cond:
+       // result: (Equal (CMPF x y))
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMEqual)
+               v0 := b.NewValue0(v.Line, OpARMCMPF, TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+}
+func rewriteValueARM_OpEq64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Eq64F x y)
+       // cond:
+       // result: (Equal (CMPD x y))
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMEqual)
+               v0 := b.NewValue0(v.Line, OpARMCMPD, TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM_OpEq8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -996,6 +1324,23 @@ func rewriteValueARM_OpGeq32(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpGeq32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Geq32F x y)
+       // cond:
+       // result: (GreaterEqual (CMPF x y))
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMGreaterEqual)
+               v0 := b.NewValue0(v.Line, OpARMCMPF, TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM_OpGeq32U(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -1013,6 +1358,23 @@ func rewriteValueARM_OpGeq32U(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpGeq64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Geq64F x y)
+       // cond:
+       // result: (GreaterEqual (CMPD x y))
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMGreaterEqual)
+               v0 := b.NewValue0(v.Line, OpARMCMPD, TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM_OpGeq8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -1140,6 +1502,23 @@ func rewriteValueARM_OpGreater32(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpGreater32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Greater32F x y)
+       // cond:
+       // result: (GreaterThan (CMPF x y))
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMGreaterThan)
+               v0 := b.NewValue0(v.Line, OpARMCMPF, TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM_OpGreater32U(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -1157,6 +1536,23 @@ func rewriteValueARM_OpGreater32U(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpGreater64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Greater64F x y)
+       // cond:
+       // result: (GreaterThan (CMPD x y))
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMGreaterThan)
+               v0 := b.NewValue0(v.Line, OpARMCMPD, TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM_OpGreater8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -1443,6 +1839,23 @@ func rewriteValueARM_OpLeq32(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpLeq32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Leq32F x y)
+       // cond:
+       // result: (GreaterEqual (CMPF y x))
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMGreaterEqual)
+               v0 := b.NewValue0(v.Line, OpARMCMPF, TypeFlags)
+               v0.AddArg(y)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM_OpLeq32U(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -1460,6 +1873,23 @@ func rewriteValueARM_OpLeq32U(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpLeq64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Leq64F x y)
+       // cond:
+       // result: (GreaterEqual (CMPD y x))
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMGreaterEqual)
+               v0 := b.NewValue0(v.Line, OpARMCMPD, TypeFlags)
+               v0.AddArg(y)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM_OpLeq8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -1561,6 +1991,23 @@ func rewriteValueARM_OpLess32(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpLess32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Less32F x y)
+       // cond:
+       // result: (GreaterThan (CMPF y x))
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMGreaterThan)
+               v0 := b.NewValue0(v.Line, OpARMCMPF, TypeFlags)
+               v0.AddArg(y)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM_OpLess32U(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -1578,6 +2025,23 @@ func rewriteValueARM_OpLess32U(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpLess64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Less64F x y)
+       // cond:
+       // result: (GreaterThan (CMPD y x))
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMGreaterThan)
+               v0 := b.NewValue0(v.Line, OpARMCMPD, TypeFlags)
+               v0.AddArg(y)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM_OpLess8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -1713,6 +2177,36 @@ func rewriteValueARM_OpLoad(v *Value, config *Config) bool {
                v.AddArg(mem)
                return true
        }
+       // match: (Load <t> ptr mem)
+       // cond: is32BitFloat(t)
+       // result: (MOVFload ptr mem)
+       for {
+               t := v.Type
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(is32BitFloat(t)) {
+                       break
+               }
+               v.reset(OpARMMOVFload)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Load <t> ptr mem)
+       // cond: is64BitFloat(t)
+       // result: (MOVDload ptr mem)
+       for {
+               t := v.Type
+               ptr := v.Args[0]
+               mem := v.Args[1]
+               if !(is64BitFloat(t)) {
+                       break
+               }
+               v.reset(OpARMMOVDload)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
        return false
 }
 func rewriteValueARM_OpLrot16(v *Value, config *Config) bool {
@@ -2127,6 +2621,126 @@ func rewriteValueARM_OpARMMOVBstore(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValueARM_OpARMMOVDload(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (MOVDload [off1] {sym1} (ADDconst [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpARMMOVDload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVDstore(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (MOVDstore [off1] {sym1} (ADDconst [off2] {sym2} ptr) val mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpARMMOVDstore)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVFload(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (MOVFload [off1] {sym1} (ADDconst [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVFload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpARMMOVFload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVFstore(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (MOVFstore [off1] {sym1} (ADDconst [off2] {sym2} ptr) val mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVFstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpARMMOVFstore)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValueARM_OpARMMOVHUload(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -2583,6 +3197,21 @@ func rewriteValueARM_OpMul32(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpMul32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Mul32F x y)
+       // cond:
+       // result: (MULF x y)
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMMULF)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
 func rewriteValueARM_OpMul32uhilo(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -2598,6 +3227,21 @@ func rewriteValueARM_OpMul32uhilo(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpMul64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Mul64F x y)
+       // cond:
+       // result: (MULD x y)
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMMULD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
 func rewriteValueARM_OpMul8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -2641,6 +3285,38 @@ func rewriteValueARM_OpNeg32(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpNeg32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Neg32F x)
+       // cond:
+       // result: (MULF (MOVFconst [int64(math.Float64bits(-1))]) x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMULF)
+               v0 := b.NewValue0(v.Line, OpARMMOVFconst, config.fe.TypeFloat32())
+               v0.AuxInt = int64(math.Float64bits(-1))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+}
+func rewriteValueARM_OpNeg64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Neg64F x)
+       // cond:
+       // result: (MULD (MOVDconst [int64(math.Float64bits(-1))]) x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMMULD)
+               v0 := b.NewValue0(v.Line, OpARMMOVDconst, config.fe.TypeFloat64())
+               v0.AuxInt = int64(math.Float64bits(-1))
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
+}
 func rewriteValueARM_OpNeg8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -2693,6 +3369,40 @@ func rewriteValueARM_OpNeq32(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpNeq32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Neq32F x y)
+       // cond:
+       // result: (NotEqual (CMPF x y))
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMNotEqual)
+               v0 := b.NewValue0(v.Line, OpARMCMPF, TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+}
+func rewriteValueARM_OpNeq64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Neq64F x y)
+       // cond:
+       // result: (NotEqual (CMPD x y))
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMNotEqual)
+               v0 := b.NewValue0(v.Line, OpARMCMPD, TypeFlags)
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
+}
 func rewriteValueARM_OpNeq8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -3531,6 +4241,19 @@ func rewriteValueARM_OpSignmask(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpSqrt(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Sqrt x)
+       // cond:
+       // result: (SQRTD x)
+       for {
+               x := v.Args[0]
+               v.reset(OpARMSQRTD)
+               v.AddArg(x)
+               return true
+       }
+}
 func rewriteValueARM_OpStaticCall(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -3584,7 +4307,7 @@ func rewriteValueARM_OpStore(v *Value, config *Config) bool {
                return true
        }
        // match: (Store [4] ptr val mem)
-       // cond:
+       // cond: !is32BitFloat(val.Type)
        // result: (MOVWstore ptr val mem)
        for {
                if v.AuxInt != 4 {
@@ -3593,12 +4316,53 @@ func rewriteValueARM_OpStore(v *Value, config *Config) bool {
                ptr := v.Args[0]
                val := v.Args[1]
                mem := v.Args[2]
+               if !(!is32BitFloat(val.Type)) {
+                       break
+               }
                v.reset(OpARMMOVWstore)
                v.AddArg(ptr)
                v.AddArg(val)
                v.AddArg(mem)
                return true
        }
+       // match: (Store [4] ptr val mem)
+       // cond: is32BitFloat(val.Type)
+       // result: (MOVFstore ptr val mem)
+       for {
+               if v.AuxInt != 4 {
+                       break
+               }
+               ptr := v.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(is32BitFloat(val.Type)) {
+                       break
+               }
+               v.reset(OpARMMOVFstore)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (Store [8] ptr val mem)
+       // cond: is64BitFloat(val.Type)
+       // result: (MOVDstore ptr val mem)
+       for {
+               if v.AuxInt != 8 {
+                       break
+               }
+               ptr := v.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(is64BitFloat(val.Type)) {
+                       break
+               }
+               v.reset(OpARMMOVDstore)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
        return false
 }
 func rewriteValueARM_OpSub16(v *Value, config *Config) bool {
@@ -3631,6 +4395,21 @@ func rewriteValueARM_OpSub32(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpSub32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Sub32F x y)
+       // cond:
+       // result: (SUBF x y)
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSUBF)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
 func rewriteValueARM_OpSub32carry(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -3663,6 +4442,21 @@ func rewriteValueARM_OpSub32withcarry(v *Value, config *Config) bool {
                return true
        }
 }
+func rewriteValueARM_OpSub64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Sub64F x y)
+       // cond:
+       // result: (SUBD x y)
+       for {
+               x := v.Args[0]
+               y := v.Args[1]
+               v.reset(OpARMSUBD)
+               v.AddArg(x)
+               v.AddArg(y)
+               return true
+       }
+}
 func rewriteValueARM_OpSub8(v *Value, config *Config) bool {
        b := v.Block
        _ = b