1
0
mirror of https://github.com/golang/go synced 2024-10-04 13:21:22 -06:00

[dev.ssa] cmd/compile: handle floating point on ARM

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>
This commit is contained in:
Cherry Zhang 2016-05-31 11:27:16 -04:00
parent e78d90beeb
commit 59e11d7827
9 changed files with 1507 additions and 76 deletions

View 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,15 +435,29 @@ 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
p.To.Reg = gc.SSARegNum(v)
case ssa.OpARMCALLstatic:
if v.Aux.(*gc.Sym) == gc.Deferreturn.Sym {
// Deferred calls will appear to be returning to

View 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)
}

View 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
}
}

View 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)
}

View 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)
@ -61,11 +69,16 @@
(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)
@ -143,6 +156,8 @@
(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])
@ -164,20 +179,38 @@
(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)))
@ -186,6 +219,8 @@
(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)))
@ -194,6 +229,8 @@
(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)))
@ -202,6 +239,8 @@
(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)))
@ -218,11 +257,15 @@
(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?
@ -336,6 +379,10 @@
(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)
@ -343,6 +390,10 @@
(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)

View 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
})

View 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

View 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)

File diff suppressed because it is too large Load Diff