mirror of
https://github.com/golang/go
synced 2024-11-19 14:34:42 -07:00
[dev.ssa] cmd/internal/obj, etc.: add and use NEGF, NEGD instructions on ARM
Updates #15365. Change-Id: I372a5617c2c7d91de545cac0464809b96711b63a Reviewed-on: https://go-review.googlesource.com/24646 Run-TryBot: Cherry Zhang <cherryyz@google.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
4a33af6bb6
commit
7b9873b9b9
@ -79,6 +79,8 @@ var progtable = [arm.ALAST & obj.AMask]obj.ProgInfo{
|
||||
arm.AMULF & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | RightRdwr},
|
||||
arm.ASUBD & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | RightRdwr},
|
||||
arm.ASUBF & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | RightRdwr},
|
||||
arm.ANEGD & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | RightRdwr},
|
||||
arm.ANEGF & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | RightRdwr},
|
||||
arm.ASQRTD & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | RightRdwr},
|
||||
|
||||
// Conversions.
|
||||
|
@ -662,6 +662,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||
fallthrough
|
||||
case ssa.OpARMMVN,
|
||||
ssa.OpARMSQRTD,
|
||||
ssa.OpARMNEGF,
|
||||
ssa.OpARMNEGD,
|
||||
ssa.OpARMMOVWF,
|
||||
ssa.OpARMMOVWD,
|
||||
ssa.OpARMMOVFW,
|
||||
|
@ -69,9 +69,8 @@
|
||||
(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)
|
||||
(Neg32F x) -> (NEGF x)
|
||||
(Neg64F x) -> (NEGD x)
|
||||
|
||||
(Com32 x) -> (MVN x)
|
||||
(Com16 x) -> (MVN x)
|
||||
|
@ -181,6 +181,8 @@ func init() {
|
||||
// unary ops
|
||||
{name: "MVN", argLength: 1, reg: gp11, asm: "MVN"}, // ^arg0
|
||||
|
||||
{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"}, // -arg0, float32
|
||||
{name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"}, // -arg0, float64
|
||||
{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
|
||||
|
||||
// shifts
|
||||
|
@ -588,6 +588,8 @@ const (
|
||||
OpARMBIC
|
||||
OpARMBICconst
|
||||
OpARMMVN
|
||||
OpARMNEGF
|
||||
OpARMNEGD
|
||||
OpARMSQRTD
|
||||
OpARMSLL
|
||||
OpARMSLLconst
|
||||
@ -7257,6 +7259,32 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NEGF",
|
||||
argLen: 1,
|
||||
asm: arm.ANEGF,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NEGD",
|
||||
argLen: 1,
|
||||
asm: arm.ANEGD,
|
||||
reg: regInfo{
|
||||
inputs: []inputInfo{
|
||||
{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
|
||||
},
|
||||
outputs: []outputInfo{
|
||||
{0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SQRTD",
|
||||
argLen: 1,
|
||||
|
@ -11908,12 +11908,12 @@ func rewriteValueAMD64_OpMod16(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Mod16 x y)
|
||||
// cond:
|
||||
// result: (Select1 (DIVW x y <&TupleType{config.Frontend().TypeInt16(), config.Frontend().TypeInt16()}>))
|
||||
// result: (Select1 (DIVW x y))
|
||||
for {
|
||||
x := v.Args[0]
|
||||
y := v.Args[1]
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVW, &TupleType{config.Frontend().TypeInt16(), config.Frontend().TypeInt16()})
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVW, MakeTuple(config.fe.TypeInt16(), config.fe.TypeInt16()))
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(y)
|
||||
v.AddArg(v0)
|
||||
@ -11925,12 +11925,12 @@ func rewriteValueAMD64_OpMod16u(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Mod16u x y)
|
||||
// cond:
|
||||
// result: (Select1 (DIVWU x y <&TupleType{config.Frontend().TypeUInt16(), config.Frontend().TypeUInt16()}>))
|
||||
// result: (Select1 (DIVWU x y))
|
||||
for {
|
||||
x := v.Args[0]
|
||||
y := v.Args[1]
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVWU, &TupleType{config.Frontend().TypeUInt16(), config.Frontend().TypeUInt16()})
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVWU, MakeTuple(config.fe.TypeUInt16(), config.fe.TypeUInt16()))
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(y)
|
||||
v.AddArg(v0)
|
||||
@ -11942,12 +11942,12 @@ func rewriteValueAMD64_OpMod32(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Mod32 x y)
|
||||
// cond:
|
||||
// result: (Select1 (DIVL x y <&TupleType{config.Frontend().TypeInt32(), config.Frontend().TypeInt32()}>))
|
||||
// result: (Select1 (DIVL x y))
|
||||
for {
|
||||
x := v.Args[0]
|
||||
y := v.Args[1]
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVL, &TupleType{config.Frontend().TypeInt32(), config.Frontend().TypeInt32()})
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVL, MakeTuple(config.fe.TypeInt32(), config.fe.TypeInt32()))
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(y)
|
||||
v.AddArg(v0)
|
||||
@ -11959,12 +11959,12 @@ func rewriteValueAMD64_OpMod32u(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Mod32u x y)
|
||||
// cond:
|
||||
// result: (Select1 (DIVLU x y <&TupleType{config.Frontend().TypeUInt32(), config.Frontend().TypeUInt32()}>))
|
||||
// result: (Select1 (DIVLU x y))
|
||||
for {
|
||||
x := v.Args[0]
|
||||
y := v.Args[1]
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVLU, &TupleType{config.Frontend().TypeUInt32(), config.Frontend().TypeUInt32()})
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVLU, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32()))
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(y)
|
||||
v.AddArg(v0)
|
||||
@ -11976,12 +11976,12 @@ func rewriteValueAMD64_OpMod64(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Mod64 x y)
|
||||
// cond:
|
||||
// result: (Select1 (DIVQ x y <&TupleType{config.Frontend().TypeInt64(), config.Frontend().TypeInt64()}>))
|
||||
// result: (Select1 (DIVQ x y))
|
||||
for {
|
||||
x := v.Args[0]
|
||||
y := v.Args[1]
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVQ, &TupleType{config.Frontend().TypeInt64(), config.Frontend().TypeInt64()})
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVQ, MakeTuple(config.fe.TypeInt64(), config.fe.TypeInt64()))
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(y)
|
||||
v.AddArg(v0)
|
||||
@ -11993,12 +11993,12 @@ func rewriteValueAMD64_OpMod64u(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Mod64u x y)
|
||||
// cond:
|
||||
// result: (Select1 (DIVQU x y <&TupleType{config.Frontend().TypeUInt64(), config.Frontend().TypeUInt64()}>))
|
||||
// result: (Select1 (DIVQU x y))
|
||||
for {
|
||||
x := v.Args[0]
|
||||
y := v.Args[1]
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVQU, &TupleType{config.Frontend().TypeUInt64(), config.Frontend().TypeUInt64()})
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVQU, MakeTuple(config.fe.TypeUInt64(), config.fe.TypeUInt64()))
|
||||
v0.AddArg(x)
|
||||
v0.AddArg(y)
|
||||
v.AddArg(v0)
|
||||
@ -12010,12 +12010,12 @@ func rewriteValueAMD64_OpMod8(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Mod8 x y)
|
||||
// cond:
|
||||
// result: (Select1 (DIVW (SignExt8to16 x) (SignExt8to16 y) <&TupleType{config.Frontend().TypeInt8(), config.Frontend().TypeInt8()}>))
|
||||
// result: (Select1 (DIVW (SignExt8to16 x) (SignExt8to16 y)))
|
||||
for {
|
||||
x := v.Args[0]
|
||||
y := v.Args[1]
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVW, &TupleType{config.Frontend().TypeInt8(), config.Frontend().TypeInt8()})
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVW, MakeTuple(config.fe.TypeInt16(), config.fe.TypeInt16()))
|
||||
v1 := b.NewValue0(v.Line, OpSignExt8to16, config.fe.TypeInt16())
|
||||
v1.AddArg(x)
|
||||
v0.AddArg(v1)
|
||||
@ -12031,12 +12031,12 @@ func rewriteValueAMD64_OpMod8u(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Mod8u x y)
|
||||
// cond:
|
||||
// result: (Select1 (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y) <&TupleType{config.Frontend().TypeUInt8(), config.Frontend().TypeUInt8()}>))
|
||||
// result: (Select1 (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y)))
|
||||
for {
|
||||
x := v.Args[0]
|
||||
y := v.Args[1]
|
||||
v.reset(OpSelect1)
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVWU, &TupleType{config.Frontend().TypeUInt8(), config.Frontend().TypeUInt8()})
|
||||
v0 := b.NewValue0(v.Line, OpAMD64DIVWU, MakeTuple(config.fe.TypeUInt16(), config.fe.TypeUInt16()))
|
||||
v1 := b.NewValue0(v.Line, OpZeroExt8to16, config.fe.TypeUInt16())
|
||||
v1.AddArg(x)
|
||||
v0.AddArg(v1)
|
||||
|
@ -10850,13 +10850,10 @@ func rewriteValueARM_OpNeg32F(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Neg32F x)
|
||||
// cond:
|
||||
// result: (MULF (MOVFconst [int64(math.Float64bits(-1))]) x)
|
||||
// result: (NEGF 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.reset(OpARMNEGF)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
@ -10866,13 +10863,10 @@ func rewriteValueARM_OpNeg64F(v *Value, config *Config) bool {
|
||||
_ = b
|
||||
// match: (Neg64F x)
|
||||
// cond:
|
||||
// result: (MULD (MOVDconst [int64(math.Float64bits(-1))]) x)
|
||||
// result: (NEGD 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.reset(OpARMNEGD)
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
|
@ -234,6 +234,8 @@ const (
|
||||
ASQRTD
|
||||
AABSF
|
||||
AABSD
|
||||
ANEGF
|
||||
ANEGD
|
||||
|
||||
ASRL
|
||||
ASRA
|
||||
|
@ -59,6 +59,8 @@ var Anames = []string{
|
||||
"SQRTD",
|
||||
"ABSF",
|
||||
"ABSD",
|
||||
"NEGF",
|
||||
"NEGD",
|
||||
"SRL",
|
||||
"SRA",
|
||||
"SLL",
|
||||
|
@ -1434,6 +1434,8 @@ func buildop(ctxt *obj.Link) {
|
||||
opset(AMOVDF, r0)
|
||||
opset(AABSF, r0)
|
||||
opset(AABSD, r0)
|
||||
opset(ANEGF, r0)
|
||||
opset(ANEGD, r0)
|
||||
|
||||
case ACMPF:
|
||||
opset(ACMPD, r0)
|
||||
@ -1930,7 +1932,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
||||
r := int(p.Reg)
|
||||
if r == 0 {
|
||||
r = rt
|
||||
if p.As == AMOVF || p.As == AMOVD || p.As == AMOVFD || p.As == AMOVDF || p.As == ASQRTF || p.As == ASQRTD || p.As == AABSF || p.As == AABSD {
|
||||
if p.As == AMOVF || p.As == AMOVD || p.As == AMOVFD || p.As == AMOVDF || p.As == ASQRTF || p.As == ASQRTD || p.As == AABSF || p.As == AABSD || p.As == ANEGF || p.As == ANEGD {
|
||||
r = 0
|
||||
}
|
||||
}
|
||||
@ -2508,6 +2510,10 @@ func oprrr(ctxt *obj.Link, a obj.As, sc int) uint32 {
|
||||
return o | 0xe<<24 | 0xb<<20 | 0<<16 | 0xb<<8 | 0xc<<4
|
||||
case AABSF:
|
||||
return o | 0xe<<24 | 0xb<<20 | 0<<16 | 0xa<<8 | 0xc<<4
|
||||
case ANEGD:
|
||||
return o | 0xe<<24 | 0xb<<20 | 1<<16 | 0xb<<8 | 0x4<<4
|
||||
case ANEGF:
|
||||
return o | 0xe<<24 | 0xb<<20 | 1<<16 | 0xa<<8 | 0x4<<4
|
||||
case ACMPD:
|
||||
return o | 0xe<<24 | 0xb<<20 | 4<<16 | 0xb<<8 | 0xc<<4
|
||||
case ACMPF:
|
||||
|
@ -669,7 +669,9 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
ASQRTF,
|
||||
ASQRTD,
|
||||
AABSF,
|
||||
AABSD:
|
||||
AABSD,
|
||||
ANEGF,
|
||||
ANEGD:
|
||||
goto soft
|
||||
|
||||
default:
|
||||
|
@ -446,6 +446,23 @@ execute:
|
||||
}
|
||||
return 1
|
||||
|
||||
case 0xeeb10b40: // D[regd] = neg D[regm]
|
||||
m.freglo[regd] = m.freglo[regm]
|
||||
m.freghi[regd] = m.freghi[regm] ^ 1<<31
|
||||
|
||||
if fptrace > 0 {
|
||||
print("*** D[", regd, "] = neg D[", regm, "] ", hex(m.freghi[regd]), "-", hex(m.freglo[regd]), "\n")
|
||||
}
|
||||
return 1
|
||||
|
||||
case 0xeeb10a40: // F[regd] = neg F[regm]
|
||||
m.freglo[regd] = m.freglo[regm] ^ 1<<31
|
||||
|
||||
if fptrace > 0 {
|
||||
print("*** F[", regd, "] = neg F[", regm, "] ", hex(m.freglo[regd]), "\n")
|
||||
}
|
||||
return 1
|
||||
|
||||
case 0xeeb40bc0: // D[regd] :: D[regm] (CMPD)
|
||||
cmp, nan := fcmp64(fgetd(regd), fgetd(regm))
|
||||
m.fflag = fstatus(nan, cmp)
|
||||
|
Loading…
Reference in New Issue
Block a user