Commit 7b9873b9 authored by Cherry Zhang's avatar Cherry Zhang

[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: default avatarDavid Chase <drchase@google.com>
parent 4a33af6b
...@@ -79,6 +79,8 @@ var progtable = [arm.ALAST & obj.AMask]obj.ProgInfo{ ...@@ -79,6 +79,8 @@ var progtable = [arm.ALAST & obj.AMask]obj.ProgInfo{
arm.AMULF & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | RightRdwr}, arm.AMULF & obj.AMask: {Flags: gc.SizeF | gc.LeftRead | RightRdwr},
arm.ASUBD & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | RightRdwr}, arm.ASUBD & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | RightRdwr},
arm.ASUBF & obj.AMask: {Flags: gc.SizeF | 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}, arm.ASQRTD & obj.AMask: {Flags: gc.SizeD | gc.LeftRead | RightRdwr},
// Conversions. // Conversions.
......
...@@ -662,6 +662,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { ...@@ -662,6 +662,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
fallthrough fallthrough
case ssa.OpARMMVN, case ssa.OpARMMVN,
ssa.OpARMSQRTD, ssa.OpARMSQRTD,
ssa.OpARMNEGF,
ssa.OpARMNEGD,
ssa.OpARMMOVWF, ssa.OpARMMOVWF,
ssa.OpARMMOVWD, ssa.OpARMMOVWD,
ssa.OpARMMOVFW, ssa.OpARMMOVFW,
......
...@@ -69,9 +69,8 @@ ...@@ -69,9 +69,8 @@
(Neg32 x) -> (RSBconst [0] x) (Neg32 x) -> (RSBconst [0] x)
(Neg16 x) -> (RSBconst [0] x) (Neg16 x) -> (RSBconst [0] x)
(Neg8 x) -> (RSBconst [0] x) (Neg8 x) -> (RSBconst [0] x)
//TODO: implement NEGF, NEGD in assembler and soft float simulator, and use them. (Neg32F x) -> (NEGF x)
(Neg32F x) -> (MULF (MOVFconst [int64(math.Float64bits(-1))]) x) (Neg64F x) -> (NEGD x)
(Neg64F x) -> (MULD (MOVDconst [int64(math.Float64bits(-1))]) x)
(Com32 x) -> (MVN x) (Com32 x) -> (MVN x)
(Com16 x) -> (MVN x) (Com16 x) -> (MVN x)
......
...@@ -181,6 +181,8 @@ func init() { ...@@ -181,6 +181,8 @@ func init() {
// unary ops // unary ops
{name: "MVN", argLength: 1, reg: gp11, asm: "MVN"}, // ^arg0 {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 {name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
// shifts // shifts
......
...@@ -588,6 +588,8 @@ const ( ...@@ -588,6 +588,8 @@ const (
OpARMBIC OpARMBIC
OpARMBICconst OpARMBICconst
OpARMMVN OpARMMVN
OpARMNEGF
OpARMNEGD
OpARMSQRTD OpARMSQRTD
OpARMSLL OpARMSLL
OpARMSLLconst OpARMSLLconst
...@@ -7257,6 +7259,32 @@ var opcodeTable = [...]opInfo{ ...@@ -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", name: "SQRTD",
argLen: 1, argLen: 1,
......
...@@ -11908,12 +11908,12 @@ func rewriteValueAMD64_OpMod16(v *Value, config *Config) bool { ...@@ -11908,12 +11908,12 @@ func rewriteValueAMD64_OpMod16(v *Value, config *Config) bool {
_ = b _ = b
// match: (Mod16 x y) // match: (Mod16 x y)
// cond: // cond:
// result: (Select1 (DIVW x y <&TupleType{config.Frontend().TypeInt16(), config.Frontend().TypeInt16()}>)) // result: (Select1 (DIVW x y))
for { for {
x := v.Args[0] x := v.Args[0]
y := v.Args[1] y := v.Args[1]
v.reset(OpSelect1) 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(x)
v0.AddArg(y) v0.AddArg(y)
v.AddArg(v0) v.AddArg(v0)
...@@ -11925,12 +11925,12 @@ func rewriteValueAMD64_OpMod16u(v *Value, config *Config) bool { ...@@ -11925,12 +11925,12 @@ func rewriteValueAMD64_OpMod16u(v *Value, config *Config) bool {
_ = b _ = b
// match: (Mod16u x y) // match: (Mod16u x y)
// cond: // cond:
// result: (Select1 (DIVWU x y <&TupleType{config.Frontend().TypeUInt16(), config.Frontend().TypeUInt16()}>)) // result: (Select1 (DIVWU x y))
for { for {
x := v.Args[0] x := v.Args[0]
y := v.Args[1] y := v.Args[1]
v.reset(OpSelect1) 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(x)
v0.AddArg(y) v0.AddArg(y)
v.AddArg(v0) v.AddArg(v0)
...@@ -11942,12 +11942,12 @@ func rewriteValueAMD64_OpMod32(v *Value, config *Config) bool { ...@@ -11942,12 +11942,12 @@ func rewriteValueAMD64_OpMod32(v *Value, config *Config) bool {
_ = b _ = b
// match: (Mod32 x y) // match: (Mod32 x y)
// cond: // cond:
// result: (Select1 (DIVL x y <&TupleType{config.Frontend().TypeInt32(), config.Frontend().TypeInt32()}>)) // result: (Select1 (DIVL x y))
for { for {
x := v.Args[0] x := v.Args[0]
y := v.Args[1] y := v.Args[1]
v.reset(OpSelect1) 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(x)
v0.AddArg(y) v0.AddArg(y)
v.AddArg(v0) v.AddArg(v0)
...@@ -11959,12 +11959,12 @@ func rewriteValueAMD64_OpMod32u(v *Value, config *Config) bool { ...@@ -11959,12 +11959,12 @@ func rewriteValueAMD64_OpMod32u(v *Value, config *Config) bool {
_ = b _ = b
// match: (Mod32u x y) // match: (Mod32u x y)
// cond: // cond:
// result: (Select1 (DIVLU x y <&TupleType{config.Frontend().TypeUInt32(), config.Frontend().TypeUInt32()}>)) // result: (Select1 (DIVLU x y))
for { for {
x := v.Args[0] x := v.Args[0]
y := v.Args[1] y := v.Args[1]
v.reset(OpSelect1) 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(x)
v0.AddArg(y) v0.AddArg(y)
v.AddArg(v0) v.AddArg(v0)
...@@ -11976,12 +11976,12 @@ func rewriteValueAMD64_OpMod64(v *Value, config *Config) bool { ...@@ -11976,12 +11976,12 @@ func rewriteValueAMD64_OpMod64(v *Value, config *Config) bool {
_ = b _ = b
// match: (Mod64 x y) // match: (Mod64 x y)
// cond: // cond:
// result: (Select1 (DIVQ x y <&TupleType{config.Frontend().TypeInt64(), config.Frontend().TypeInt64()}>)) // result: (Select1 (DIVQ x y))
for { for {
x := v.Args[0] x := v.Args[0]
y := v.Args[1] y := v.Args[1]
v.reset(OpSelect1) 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(x)
v0.AddArg(y) v0.AddArg(y)
v.AddArg(v0) v.AddArg(v0)
...@@ -11993,12 +11993,12 @@ func rewriteValueAMD64_OpMod64u(v *Value, config *Config) bool { ...@@ -11993,12 +11993,12 @@ func rewriteValueAMD64_OpMod64u(v *Value, config *Config) bool {
_ = b _ = b
// match: (Mod64u x y) // match: (Mod64u x y)
// cond: // cond:
// result: (Select1 (DIVQU x y <&TupleType{config.Frontend().TypeUInt64(), config.Frontend().TypeUInt64()}>)) // result: (Select1 (DIVQU x y))
for { for {
x := v.Args[0] x := v.Args[0]
y := v.Args[1] y := v.Args[1]
v.reset(OpSelect1) 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(x)
v0.AddArg(y) v0.AddArg(y)
v.AddArg(v0) v.AddArg(v0)
...@@ -12010,12 +12010,12 @@ func rewriteValueAMD64_OpMod8(v *Value, config *Config) bool { ...@@ -12010,12 +12010,12 @@ func rewriteValueAMD64_OpMod8(v *Value, config *Config) bool {
_ = b _ = b
// match: (Mod8 x y) // match: (Mod8 x y)
// cond: // cond:
// result: (Select1 (DIVW (SignExt8to16 x) (SignExt8to16 y) <&TupleType{config.Frontend().TypeInt8(), config.Frontend().TypeInt8()}>)) // result: (Select1 (DIVW (SignExt8to16 x) (SignExt8to16 y)))
for { for {
x := v.Args[0] x := v.Args[0]
y := v.Args[1] y := v.Args[1]
v.reset(OpSelect1) 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 := b.NewValue0(v.Line, OpSignExt8to16, config.fe.TypeInt16())
v1.AddArg(x) v1.AddArg(x)
v0.AddArg(v1) v0.AddArg(v1)
...@@ -12031,12 +12031,12 @@ func rewriteValueAMD64_OpMod8u(v *Value, config *Config) bool { ...@@ -12031,12 +12031,12 @@ func rewriteValueAMD64_OpMod8u(v *Value, config *Config) bool {
_ = b _ = b
// match: (Mod8u x y) // match: (Mod8u x y)
// cond: // cond:
// result: (Select1 (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y) <&TupleType{config.Frontend().TypeUInt8(), config.Frontend().TypeUInt8()}>)) // result: (Select1 (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y)))
for { for {
x := v.Args[0] x := v.Args[0]
y := v.Args[1] y := v.Args[1]
v.reset(OpSelect1) 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 := b.NewValue0(v.Line, OpZeroExt8to16, config.fe.TypeUInt16())
v1.AddArg(x) v1.AddArg(x)
v0.AddArg(v1) v0.AddArg(v1)
......
...@@ -10850,13 +10850,10 @@ func rewriteValueARM_OpNeg32F(v *Value, config *Config) bool { ...@@ -10850,13 +10850,10 @@ func rewriteValueARM_OpNeg32F(v *Value, config *Config) bool {
_ = b _ = b
// match: (Neg32F x) // match: (Neg32F x)
// cond: // cond:
// result: (MULF (MOVFconst [int64(math.Float64bits(-1))]) x) // result: (NEGF x)
for { for {
x := v.Args[0] x := v.Args[0]
v.reset(OpARMMULF) v.reset(OpARMNEGF)
v0 := b.NewValue0(v.Line, OpARMMOVFconst, config.fe.TypeFloat32())
v0.AuxInt = int64(math.Float64bits(-1))
v.AddArg(v0)
v.AddArg(x) v.AddArg(x)
return true return true
} }
...@@ -10866,13 +10863,10 @@ func rewriteValueARM_OpNeg64F(v *Value, config *Config) bool { ...@@ -10866,13 +10863,10 @@ func rewriteValueARM_OpNeg64F(v *Value, config *Config) bool {
_ = b _ = b
// match: (Neg64F x) // match: (Neg64F x)
// cond: // cond:
// result: (MULD (MOVDconst [int64(math.Float64bits(-1))]) x) // result: (NEGD x)
for { for {
x := v.Args[0] x := v.Args[0]
v.reset(OpARMMULD) v.reset(OpARMNEGD)
v0 := b.NewValue0(v.Line, OpARMMOVDconst, config.fe.TypeFloat64())
v0.AuxInt = int64(math.Float64bits(-1))
v.AddArg(v0)
v.AddArg(x) v.AddArg(x)
return true return true
} }
......
...@@ -234,6 +234,8 @@ const ( ...@@ -234,6 +234,8 @@ const (
ASQRTD ASQRTD
AABSF AABSF
AABSD AABSD
ANEGF
ANEGD
ASRL ASRL
ASRA ASRA
......
...@@ -59,6 +59,8 @@ var Anames = []string{ ...@@ -59,6 +59,8 @@ var Anames = []string{
"SQRTD", "SQRTD",
"ABSF", "ABSF",
"ABSD", "ABSD",
"NEGF",
"NEGD",
"SRL", "SRL",
"SRA", "SRA",
"SLL", "SLL",
......
...@@ -1434,6 +1434,8 @@ func buildop(ctxt *obj.Link) { ...@@ -1434,6 +1434,8 @@ func buildop(ctxt *obj.Link) {
opset(AMOVDF, r0) opset(AMOVDF, r0)
opset(AABSF, r0) opset(AABSF, r0)
opset(AABSD, r0) opset(AABSD, r0)
opset(ANEGF, r0)
opset(ANEGD, r0)
case ACMPF: case ACMPF:
opset(ACMPD, r0) opset(ACMPD, r0)
...@@ -1930,7 +1932,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ...@@ -1930,7 +1932,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
r := int(p.Reg) r := int(p.Reg)
if r == 0 { if r == 0 {
r = rt 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 r = 0
} }
} }
...@@ -2508,6 +2510,10 @@ func oprrr(ctxt *obj.Link, a obj.As, sc int) uint32 { ...@@ -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 return o | 0xe<<24 | 0xb<<20 | 0<<16 | 0xb<<8 | 0xc<<4
case AABSF: case AABSF:
return o | 0xe<<24 | 0xb<<20 | 0<<16 | 0xa<<8 | 0xc<<4 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: case ACMPD:
return o | 0xe<<24 | 0xb<<20 | 4<<16 | 0xb<<8 | 0xc<<4 return o | 0xe<<24 | 0xb<<20 | 4<<16 | 0xb<<8 | 0xc<<4
case ACMPF: case ACMPF:
......
...@@ -669,7 +669,9 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -669,7 +669,9 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
ASQRTF, ASQRTF,
ASQRTD, ASQRTD,
AABSF, AABSF,
AABSD: AABSD,
ANEGF,
ANEGD:
goto soft goto soft
default: default:
......
...@@ -446,6 +446,23 @@ execute: ...@@ -446,6 +446,23 @@ execute:
} }
return 1 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) case 0xeeb40bc0: // D[regd] :: D[regm] (CMPD)
cmp, nan := fcmp64(fgetd(regd), fgetd(regm)) cmp, nan := fcmp64(fgetd(regd), fgetd(regm))
m.fflag = fstatus(nan, cmp) m.fflag = fstatus(nan, cmp)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment