ssagen.AddAux(&p.From, v)
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
- case ssa.OpARM64LDP, ssa.OpARM64LDPW, ssa.OpARM64FLDPD, ssa.OpARM64FLDPS:
+ case ssa.OpARM64LDP, ssa.OpARM64LDPW, ssa.OpARM64LDPSW, ssa.OpARM64FLDPD, ssa.OpARM64FLDPS:
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_MEM
p.From.Reg = v.Args[0].Reg()
// arg1=mem
// Returns the tuple <x,y>.
{name: "LDP", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDP", typ: "(UInt64,UInt64)", faultOnNilArg0: true, symEffect: "Read"}, // T=int64 (gp reg destination)
- {name: "LDPW", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDPW", typ: "(UInt32,UInt32)", faultOnNilArg0: true, symEffect: "Read"}, // T=int32 (gp reg destination) ??? extension
+ {name: "LDPW", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDPW", typ: "(UInt32,UInt32)", faultOnNilArg0: true, symEffect: "Read"}, // T=int32 (gp reg destination) unsigned extension
+ {name: "LDPSW", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDPSW", typ: "(Int32,Int32)", faultOnNilArg0: true, symEffect: "Read"}, // T=int32 (gp reg destination) signed extension
{name: "FLDPD", argLength: 2, reg: fpload2, aux: "SymOff", asm: "FLDPD", typ: "(Float64,Float64)", faultOnNilArg0: true, symEffect: "Read"}, // T=float64 (fp reg destination)
{name: "FLDPS", argLength: 2, reg: fpload2, aux: "SymOff", asm: "FLDPS", typ: "(Float32,Float32)", faultOnNilArg0: true, symEffect: "Read"}, // T=float32 (fp reg destination)
OpARM64FMOVDload
OpARM64LDP
OpARM64LDPW
+ OpARM64LDPSW
OpARM64FLDPD
OpARM64FLDPS
OpARM64MOVDloadidx
},
},
},
+ {
+ name: "LDPSW",
+ auxType: auxSymOff,
+ argLen: 2,
+ faultOnNilArg0: true,
+ symEffect: SymRead,
+ asm: arm64.ALDPSW,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
+ },
+ outputs: []outputInfo{
+ {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+ {1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+ },
+ },
+ },
{
name: "FLDPD",
auxType: auxSymOff,
// They must also take an offset in Aux/AuxInt.
var pairableLoads = map[Op]pairableLoadInfo{
OpARM64MOVDload: {8, OpARM64LDP},
- OpARM64MOVWload: {4, OpARM64LDPW},
+ OpARM64MOVWUload: {4, OpARM64LDPW},
+ OpARM64MOVWload: {4, OpARM64LDPSW},
+ // TODO: conceivably we could pair a signed and unsigned load
+ // if we knew the upper bits of one of them weren't being used.
OpARM64FMOVDload: {8, OpARM64FLDPD},
OpARM64FMOVSload: {4, OpARM64FLDPS},
}
return p.a + p.b
}
func dwloadI32(p *struct{ a, b int32 }) int32 {
+ // arm64:"LDPSW\t"
+ return p.a + p.b
+}
+func dwloadU32(p *struct{ a, b uint32 }) uint32 {
// arm64:"LDPW\t"
return p.a + p.b
}
--- /dev/null
+// run
+
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+//go:noinline
+func f(p *[2]int32) (int64, int64) {
+ return int64(p[0]), int64(p[1])
+}
+
+func main() {
+ p := [2]int32{-1, -1}
+ x, y := f(&p)
+ if x != -1 || y != -1 {
+ println(x, y)
+ }
+}