diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s index 3ff48154e2ba0f..091d2f9089187c 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64.s +++ b/src/cmd/asm/internal/asm/testdata/arm64.s @@ -419,6 +419,9 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8 PRFM 8(R12), PLIL3STRM // 8d0580f9 PRFM (R8), $25 // 190180f9 PRFM 8(R9), $30 // 3e0580f9 + RPRFM (R1), R2, PLDKEEP // 3848a2f8 + RPRFM (RSP), R4, PSTSTRM // fd4ba4f8 + RPRFM (R6), R12, $25 // d978acf8 NOOP // 1f2003d5 HINT $0 // 1f2003d5 DMB $1 diff --git a/src/cmd/asm/internal/asm/testdata/arm64error.s b/src/cmd/asm/internal/asm/testdata/arm64error.s index adb8c588b5f6cb..f9e8870066aecb 100644 --- a/src/cmd/asm/internal/asm/testdata/arm64error.s +++ b/src/cmd/asm/internal/asm/testdata/arm64error.s @@ -462,6 +462,10 @@ TEXT errors(SB),$0 AUTIA1716 $45 // ERROR "illegal combination" AUTIB1716 R0 // ERROR "illegal combination" SB $1 // ERROR "illegal combination" + RPRFM (R1), RSP, PLDKEEP // ERROR "illegal combination" + RPRFM 2(RSP), R4, PSTSTRM // ERROR "illegal combination" + RPRFM (R2), R3, $100 // ERROR "range prefetch immediate must be 0 to 63" + RPRFM (R5), R6, PLDL1KEEP // ERROR "illegal range prefetch operand" // VMUL family invalid arrangement tests VMUL V0.D2, V0.D2, V1.D2 // ERROR "invalid arrangement" diff --git a/src/cmd/compile/internal/ssa/_gen/generic.rules b/src/cmd/compile/internal/ssa/_gen/generic.rules index 672818988893a5..96f5f2cad20946 100644 --- a/src/cmd/compile/internal/ssa/_gen/generic.rules +++ b/src/cmd/compile/internal/ssa/_gen/generic.rules @@ -407,6 +407,11 @@ (Sub(64|32|16|8) (Mul(64|32|16|8) x y) (Mul(64|32|16|8) x z)) => (Mul(64|32|16|8) x (Sub(64|32|16|8) y z)) +// Canonicalize x+x to x << 1. +// This is often slower since most CPUs have more adders than shifters, but it can enable other optimizations. +// Arches who care about this like AMD64 convert x << 1 back to x+x in their arch-specific rules which is useful anyhow. +(Add(64|32|16|8) x x) => (Lsh(64|32|16|8)x64 x (Const64 [1])) + // rewrite shifts of 8/16/32 bit consts into 64 bit consts to reduce // the number of the other rewrite rules for const shifts (Lsh64x32 x (Const32 [c])) => (Lsh64x64 x (Const64 [int64(uint32(c))])) diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index 1b3d6c17d29087..56411cacd2168c 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -553,6 +553,19 @@ func rewriteValuegeneric_OpAdd16(v *Value) bool { } break } + // match: (Add16 x x) + // result: (Lsh16x64 x (Const64 [1])) + for { + x := v_0 + if x != v_1 { + break + } + v.reset(OpLsh16x64) + v0 := b.NewValue0(v.Pos, OpConst64, types.Types[types.TUINT64]) + v0.AuxInt = int64ToAuxInt(1) + v.AddArg2(x, v0) + return true + } // match: (Add16 (Const16 [0]) x) // result: x for { @@ -1166,6 +1179,19 @@ func rewriteValuegeneric_OpAdd32(v *Value) bool { } break } + // match: (Add32 x x) + // result: (Lsh32x64 x (Const64 [1])) + for { + x := v_0 + if x != v_1 { + break + } + v.reset(OpLsh32x64) + v0 := b.NewValue0(v.Pos, OpConst64, types.Types[types.TUINT64]) + v0.AuxInt = int64ToAuxInt(1) + v.AddArg2(x, v0) + return true + } // match: (Add32 (Const32 [0]) x) // result: x for { @@ -1806,6 +1832,19 @@ func rewriteValuegeneric_OpAdd64(v *Value) bool { } break } + // match: (Add64 x x) + // result: (Lsh64x64 x (Const64 [1])) + for { + x := v_0 + if x != v_1 { + break + } + v.reset(OpLsh64x64) + v0 := b.NewValue0(v.Pos, OpConst64, types.Types[types.TUINT64]) + v0.AuxInt = int64ToAuxInt(1) + v.AddArg2(x, v0) + return true + } // match: (Add64 (Const64 [0]) x) // result: x for { @@ -2484,6 +2523,19 @@ func rewriteValuegeneric_OpAdd8(v *Value) bool { } break } + // match: (Add8 x x) + // result: (Lsh8x64 x (Const64 [1])) + for { + x := v_0 + if x != v_1 { + break + } + v.reset(OpLsh8x64) + v0 := b.NewValue0(v.Pos, OpConst64, types.Types[types.TUINT64]) + v0.AuxInt = int64ToAuxInt(1) + v.AddArg2(x, v0) + return true + } // match: (Add8 (Const8 [0]) x) // result: x for { diff --git a/src/cmd/compile/internal/ssagen/intrinsics.go b/src/cmd/compile/internal/ssagen/intrinsics.go index d708bcac18a711..aedc905affe280 100644 --- a/src/cmd/compile/internal/ssagen/intrinsics.go +++ b/src/cmd/compile/internal/ssagen/intrinsics.go @@ -2042,6 +2042,10 @@ func branchTableN(s *state, idx *ssa.Value, intrinsicCall *ir.CallExpr, genOp fu s.startBlock(bPanic) s.rtcall(ir.Syms.PanicSimdImm, false, nil) } + if s.curBlock != nil { + bb := s.endBlock() + bb.AddEdgeTo(jt) + } s.startBlock(jt) jt.Kind = ssa.BlockPlain diff --git a/src/cmd/internal/obj/arm64/a.out.go b/src/cmd/internal/obj/arm64/a.out.go index 6fae75ea0ce9f8..c9713b3c56b5b5 100644 --- a/src/cmd/internal/obj/arm64/a.out.go +++ b/src/cmd/internal/obj/arm64/a.out.go @@ -1006,6 +1006,7 @@ const ( AREVW AROR ARORW + ARPRFM ASB ASBC ASBCS @@ -1482,5 +1483,11 @@ const ( SPOP_J SPOP_JC + // Range PReFetch of Memory (RPRFM) + SPOP_PLDKEEP + SPOP_PSTKEEP + SPOP_PLDSTRM + SPOP_PSTSTRM + SPOP_END ) diff --git a/src/cmd/internal/obj/arm64/anames.go b/src/cmd/internal/obj/arm64/anames.go index 77ee79854ef080..4a905ad4cefc1d 100644 --- a/src/cmd/internal/obj/arm64/anames.go +++ b/src/cmd/internal/obj/arm64/anames.go @@ -353,6 +353,7 @@ var Anames = []string{ "REVW", "ROR", "RORW", + "RPRFM", "SB", "SBC", "SBCS", diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go index e65b336b6eaf8e..c9303cf6be0c4e 100644 --- a/src/cmd/internal/obj/arm64/asm7.go +++ b/src/cmd/internal/obj/arm64/asm7.go @@ -901,6 +901,8 @@ var optab = []Optab{ {AMSR, C_VCON, C_NONE, C_NONE, C_SPOP, C_NONE, 37, 4, 0, 0, 0}, {APRFM, C_UOREG32K, C_NONE, C_NONE, C_SPOP, C_NONE, 91, 4, 0, 0, 0}, {APRFM, C_UOREG32K, C_NONE, C_NONE, C_LCON, C_NONE, 91, 4, 0, 0, 0}, + {ARPRFM, C_ZOREG, C_REG, C_NONE, C_SPOP, C_NONE, 110, 4, 0, 0, 0}, + {ARPRFM, C_ZOREG, C_REG, C_NONE, C_LCON, C_NONE, 110, 4, 0, 0, 0}, {ADMB, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 51, 4, 0, 0, 0}, {AHINT, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 52, 4, 0, 0, 0}, {ASYS, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 50, 4, 0, 0, 0}, @@ -943,6 +945,13 @@ var pstatefield = []struct { {SPOP_DAIFClr, 3<<16 | 4<<12 | 7<<5}, } +var rprfopfield = map[SpecialOperand]uint32{ + SPOP_PLDKEEP: 0, + SPOP_PSTKEEP: 1, + SPOP_PLDSTRM: 4, + SPOP_PSTSTRM: 5, +} + var prfopfield = map[SpecialOperand]uint32{ SPOP_PLDL1KEEP: 0, SPOP_PLDL1STRM: 1, @@ -3416,6 +3425,7 @@ func buildop(ctxt *obj.Link) { AVDUP, AVMOVI, APRFM, + ARPRFM, AVEXT, AVXAR: break @@ -6088,6 +6098,43 @@ func (c *ctxt7) asmout(p *obj.Prog, out []uint32) (count int) { rn := uint32(p.Reg & 31) o1 |= Q<<30 | size<<22 | (rn << 5) | (rd) + case 110: /*rprfm (Rn), Rm, */ + rn := p.From.Reg + rm := p.Reg + var operation uint32 + var ok bool + + // Operation is either a 6-bit immediate or named prefetch operation. + if p.To.Type == obj.TYPE_CONST { + operation = uint32(p.To.Offset) + if operation > 63 { + c.ctxt.Diag("range prefetch immediate must be 0 to 63: %v", p) + } + } else { + operation, ok = rprfopfield[SpecialOperand(p.To.Offset)] + if !ok { + c.ctxt.Diag("illegal range prefetch operand, expected PLDKEEP, PSTKEEP, PLDSTRM or PSTSTRM: %v", p) + } + } + + // 6-bit placement: the 6-bit value is scattered to match the + // architectural encoding (bits 15,13,12,2-0). This is because the + // instructions word reuses fields from the base load/store hint space. + // option2 (bit5) -> bit15 + // option0 (bit4) -> bit13 + // S (bit3) -> bit12 + // Rt<2:0> (bits2-0) -> bits2-0 + // Rt<4:3> are already set by c.opirr() and are fixed for RPRFM. + option2 := (operation & (1 << 5)) << 10 + option0 := (operation & (1 << 4)) << 9 + s := (operation & (1 << 3)) << 9 + rt := (operation & 0x7) + + encodedOperation := option2 | option0 | s | rt + + o1 = c.opirr(p, p.As) + o1 |= (uint32(rm&31) << 16) | (uint32(rn&31) << 5) | uint32(encodedOperation) + case 127: // Generic SVE instruction encoding matched := false @@ -7277,6 +7324,9 @@ func (c *ctxt7) opirr(p *obj.Prog, a obj.As) uint32 { case APRFM: return 0xf9<<24 | 2<<22 + + case ARPRFM: + return 0xf8<<24 | 5<<21 | 18<<10 | 3<<3 } c.ctxt.Diag("%v: bad irr %v", p, a) diff --git a/src/cmd/internal/obj/arm64/specialoperand_string.go b/src/cmd/internal/obj/arm64/specialoperand_string.go index b4dcbc5fda57b9..a8b69d1a31976a 100644 --- a/src/cmd/internal/obj/arm64/specialoperand_string.go +++ b/src/cmd/internal/obj/arm64/specialoperand_string.go @@ -156,12 +156,16 @@ func _() { _ = x[SPOP_C-144] _ = x[SPOP_J-145] _ = x[SPOP_JC-146] - _ = x[SPOP_END-147] + _ = x[SPOP_PLDKEEP-147] + _ = x[SPOP_PSTKEEP-148] + _ = x[SPOP_PLDSTRM-149] + _ = x[SPOP_PSTSTRM-150] + _ = x[SPOP_END-151] } -const _SpecialOperand_name = "PLDL1KEEPPLDL1STRMPLDL2KEEPPLDL2STRMPLDL3KEEPPLDL3STRMPLIL1KEEPPLIL1STRMPLIL2KEEPPLIL2STRMPLIL3KEEPPLIL3STRMPSTL1KEEPPSTL1STRMPSTL2KEEPPSTL2STRMPSTL3KEEPPSTL3STRMVLx2VLx4VMALLE1ISVAE1ISASIDE1ISVAAE1ISVALE1ISVAALE1ISVMALLE1VAE1ASIDE1VAAE1VALE1VAALE1IPAS2E1ISIPAS2LE1ISALLE2ISVAE2ISALLE1ISVALE2ISVMALLS12E1ISIPAS2E1IPAS2LE1ALLE2VAE2ALLE1VALE2VMALLS12E1ALLE3ISVAE3ISVALE3ISALLE3VAE3VALE3VMALLE1OSVAE1OSASIDE1OSVAAE1OSVALE1OSVAALE1OSRVAE1ISRVAAE1ISRVALE1ISRVAALE1ISRVAE1OSRVAAE1OSRVALE1OSRVAALE1OSRVAE1RVAAE1RVALE1RVAALE1RIPAS2E1ISRIPAS2LE1ISALLE2OSVAE2OSALLE1OSVALE2OSVMALLS12E1OSRVAE2ISRVALE2ISIPAS2E1OSRIPAS2E1RIPAS2E1OSIPAS2LE1OSRIPAS2LE1RIPAS2LE1OSRVAE2OSRVALE2OSRVAE2RVALE2ALLE3OSVAE3OSVALE3OSRVAE3ISRVALE3ISRVAE3OSRVALE3OSRVAE3RVALE3IVACISWCSWCISWZVACVACCVAUCIVACIGVACIGSWIGDVACIGDSWCGSWCGDSWCIGSWCIGDSWGVAGZVACGVACCGDVACCGVAPCGDVAPCGVADPCGDVADPCIGVACCIGDVACCVAPCVADPDAIFSetDAIFClrEQNEHSLOMIPLVSVCHILSGELTGTLEALNVCJJCEND" +const _SpecialOperand_name = "PLDL1KEEPPLDL1STRMPLDL2KEEPPLDL2STRMPLDL3KEEPPLDL3STRMPLIL1KEEPPLIL1STRMPLIL2KEEPPLIL2STRMPLIL3KEEPPLIL3STRMPSTL1KEEPPSTL1STRMPSTL2KEEPPSTL2STRMPSTL3KEEPPSTL3STRMVLx2VLx4VMALLE1ISVAE1ISASIDE1ISVAAE1ISVALE1ISVAALE1ISVMALLE1VAE1ASIDE1VAAE1VALE1VAALE1IPAS2E1ISIPAS2LE1ISALLE2ISVAE2ISALLE1ISVALE2ISVMALLS12E1ISIPAS2E1IPAS2LE1ALLE2VAE2ALLE1VALE2VMALLS12E1ALLE3ISVAE3ISVALE3ISALLE3VAE3VALE3VMALLE1OSVAE1OSASIDE1OSVAAE1OSVALE1OSVAALE1OSRVAE1ISRVAAE1ISRVALE1ISRVAALE1ISRVAE1OSRVAAE1OSRVALE1OSRVAALE1OSRVAE1RVAAE1RVALE1RVAALE1RIPAS2E1ISRIPAS2LE1ISALLE2OSVAE2OSALLE1OSVALE2OSVMALLS12E1OSRVAE2ISRVALE2ISIPAS2E1OSRIPAS2E1RIPAS2E1OSIPAS2LE1OSRIPAS2LE1RIPAS2LE1OSRVAE2OSRVALE2OSRVAE2RVALE2ALLE3OSVAE3OSVALE3OSRVAE3ISRVALE3ISRVAE3OSRVALE3OSRVAE3RVALE3IVACISWCSWCISWZVACVACCVAUCIVACIGVACIGSWIGDVACIGDSWCGSWCGDSWCIGSWCIGDSWGVAGZVACGVACCGDVACCGVAPCGDVAPCGVADPCGDVADPCIGVACCIGDVACCVAPCVADPDAIFSetDAIFClrEQNEHSLOMIPLVSVCHILSGELTGTLEALNVCJJCPLDKEEPPSTKEEPPLDSTRMPSTSTRMEND" -var _SpecialOperand_index = [...]uint16{0, 9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99, 108, 117, 126, 135, 144, 153, 162, 166, 170, 179, 185, 193, 200, 207, 215, 222, 226, 232, 237, 242, 248, 257, 267, 274, 280, 287, 294, 306, 313, 321, 326, 330, 335, 340, 350, 357, 363, 370, 375, 379, 384, 393, 399, 407, 414, 421, 429, 436, 444, 452, 461, 468, 476, 484, 493, 498, 504, 510, 517, 527, 538, 545, 551, 558, 565, 577, 584, 592, 601, 609, 619, 629, 638, 649, 656, 664, 669, 675, 682, 688, 695, 702, 710, 717, 725, 730, 736, 740, 743, 746, 750, 753, 757, 761, 766, 771, 775, 781, 786, 790, 795, 800, 806, 809, 813, 818, 824, 829, 835, 841, 848, 854, 861, 865, 870, 877, 884, 886, 888, 890, 892, 894, 896, 898, 900, 902, 904, 906, 908, 910, 912, 914, 916, 917, 918, 920, 923} +var _SpecialOperand_index = [...]uint16{0, 9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99, 108, 117, 126, 135, 144, 153, 162, 166, 170, 179, 185, 193, 200, 207, 215, 222, 226, 232, 237, 242, 248, 257, 267, 274, 280, 287, 294, 306, 313, 321, 326, 330, 335, 340, 350, 357, 363, 370, 375, 379, 384, 393, 399, 407, 414, 421, 429, 436, 444, 452, 461, 468, 476, 484, 493, 498, 504, 510, 517, 527, 538, 545, 551, 558, 565, 577, 584, 592, 601, 609, 619, 629, 638, 649, 656, 664, 669, 675, 682, 688, 695, 702, 710, 717, 725, 730, 736, 740, 743, 746, 750, 753, 757, 761, 766, 771, 775, 781, 786, 790, 795, 800, 806, 809, 813, 818, 824, 829, 835, 841, 848, 854, 861, 865, 870, 877, 884, 886, 888, 890, 892, 894, 896, 898, 900, 902, 904, 906, 908, 910, 912, 914, 916, 917, 918, 920, 927, 934, 941, 948, 951} func (i SpecialOperand) String() string { idx := int(i) - 0 diff --git a/src/go/importer/importer.go b/src/go/importer/importer.go index f0a1f651d2636c..b670d2c0539fcd 100644 --- a/src/go/importer/importer.go +++ b/src/go/importer/importer.go @@ -41,9 +41,10 @@ type Lookup func(path string) (io.ReadCloser, error) // it is assumed that the translation to canonical import paths is being // done by the client of the importer. // -// A lookup function must be provided for correct module-aware operation. -// Deprecated: If lookup is nil, for backwards-compatibility, the importer -// will attempt to resolve imports in the $GOPATH workspace. +// A lookup function must be provided for correct module-aware +// operation. Providing a nil value for lookup is deprecated but, for +// backwards-compatibility, the importer will in this case attempt to +// resolve imports in the $GOPATH workspace. func ForCompiler(fset *token.FileSet, compiler string, lookup Lookup) types.Importer { switch compiler { case "gc": diff --git a/src/internal/runtime/maps/group.go b/src/internal/runtime/maps/group.go index 8f6c38790fae59..2ce4550b32c3b5 100644 --- a/src/internal/runtime/maps/group.go +++ b/src/internal/runtime/maps/group.go @@ -24,6 +24,7 @@ const ( bitsetLSB = 0x0101010101010101 bitsetMSB = 0x8080808080808080 + bitsetL7B = 0x7f7f7f7f7f7f7f7f bitsetEmpty = bitsetLSB * uint64(ctrlEmpty) ) @@ -158,6 +159,11 @@ func (g ctrlGroup) matchH2(h uintptr) bitset { // Note: On AMD64, this is an intrinsic implemented with SIMD instructions. See // note on bitset about the packed intrinsified return value. func ctrlGroupMatchH2(g ctrlGroup, h uintptr) bitset { + v := uint64(g) ^ (bitsetLSB * uint64(h)) + if goarch.IsArm64 == 1 { + v = ^v + return bitset((v&bitsetL7B + bitsetLSB) & (v & bitsetMSB)) + } // NB: This generic matching routine produces false positive matches when // h is 2^N and the control bytes have a seq of 2^N followed by 2^N+1. For // example: if ctrls==0x0302 and h=02, we'll compute v as 0x0100. When we @@ -166,7 +172,6 @@ func ctrlGroupMatchH2(g ctrlGroup, h uintptr) bitset { // just a rare inefficiency. Note that they only occur if there is a real // match and never occur on ctrlEmpty, or ctrlDeleted. The subsequent key // comparisons ensure that there is no correctness issue. - v := uint64(g) ^ (bitsetLSB * uint64(h)) return bitset(((v - bitsetLSB) &^ v) & bitsetMSB) } diff --git a/src/runtime/cgo/gcc_libinit_unix.c b/src/runtime/cgo/gcc_libinit_unix.c index 0ff0454931c256..58cd32b8844925 100644 --- a/src/runtime/cgo/gcc_libinit_unix.c +++ b/src/runtime/cgo/gcc_libinit_unix.c @@ -185,7 +185,9 @@ x_cgo_thread_start(ThreadStart *arg) ThreadStart *ts; /* Make our own copy that can persist after we return. */ + _cgo_tsan_acquire(); ts = malloc(sizeof *ts); + _cgo_tsan_release(); if(ts == nil) { fprintf(stderr, "runtime/cgo: out of memory in thread_start\n"); abort(); diff --git a/test/codegen/shift.go b/test/codegen/shift.go index a073944187e55a..013e8bbc667b7c 100644 --- a/test/codegen/shift.go +++ b/test/codegen/shift.go @@ -120,47 +120,49 @@ func rshConst64x32(v int64) int64 { } func lshConst32x1Add(x int32) int32 { - // amd64:"SHLL [$]2" - // loong64:"SLL [$]2" - // riscv64:"SLLI [$]2" - // ppc64x:"SLW [$]2" -"ADD" + // amd64:-"ADD" "SHLL [$]2" + // loong64:-"ADD" "SLL [$]2" + // riscv64:-"ADD" "SLLI [$]2" + // ppc64x:-"ADD" "SLW [$]2" return (x + x) << 1 } func lshConst64x1Add(x int64) int64 { - // amd64:"SHLQ [$]2" - // loong64:"SLLV [$]2" - // riscv64:"SLLI [$]2" - // ppc64x:"SLD [$]2" -"ADD" + // amd64:-"ADD" "SHLQ [$]2" + // loong64:-"ADD" "SLLV [$]2" + // riscv64:-"ADD" "SLLI [$]2" + // ppc64x:-"ADD" "SLD [$]2" return (x + x) << 1 } func lshConst32x2Add(x int32) int32 { - // amd64:"SHLL [$]3" - // loong64:"SLL [$]3" - // riscv64:"SLLI [$]3" - // ppc64x:"SLW [$]3" -"ADD" + // amd64:-"ADD" "SHLL [$]3" + // loong64:-"ADD" "SLL [$]3" + // riscv64:-"ADD" "SLLI [$]3" + // ppc64x:-"ADD" "SLW [$]3" return (x + x) << 2 } func lshConst64x2Add(x int64) int64 { - // amd64:"SHLQ [$]3" - // loong64:"SLLV [$]3" - // riscv64:"SLLI [$]3" - // ppc64x:"SLD [$]3" -"ADD" + // amd64:-"ADD" "SHLQ [$]3" + // loong64:-"ADD" "SLLV [$]3" + // riscv64:-"ADD" "SLLI [$]3" + // ppc64x:-"ADD" "SLD [$]3" return (x + x) << 2 } func lshConst32x31Add(x int32) int32 { - // loong64:-"SLL " "MOVV R0" - // riscv64:-"SLLI" "MOV [$]0" - // ppc64x:"ADD" "SLW [$]31" -"SLW [$]32" + // amd64:-"ADD" -"SHL" "XORL AX, AX" + // loong64:-"ADD" -"SLL " "MOVV R0" + // riscv64:-"ADD" -"SLLI" "MOV [$]0" + // ppc64x:-"ADD" -"SLW" "MOVD [$]0" return (x + x) << 31 } func lshConst64x63Add(x int64) int64 { - // loong64:-"SLLV" "MOVV R0" - // riscv64:-"SLLI" "MOV [$]0" + // amd64:-"ADD" -"SHL" "XORL AX, AX" + // loong64:-"ADD" -"SLLV" "MOVV R0" + // riscv64:-"ADD" -"SLLI" "MOV [$]0" return (x + x) << 63 }