diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s index 955ba63071..fa433d53e1 100644 --- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s +++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s @@ -97,8 +97,6 @@ lable2: MOVV R4, 1(R5) // a404c029 MOVB R4, 1(R5) // a4040029 MOVBU R4, 1(R5) // a4040029 - SC R4, 4096(R5) // a4001021 - SCV R4, 4096(R5) // a4001023 MOVW y+8(FP), R4 // 64408028 MOVWU y+8(FP), R4 // 6440802a MOVV y+8(FP), R4 // 6440c028 @@ -109,8 +107,6 @@ lable2: MOVV 1(R5), R4 // a404c028 MOVB 1(R5), R4 // a4040028 MOVBU 1(R5), R4 // a404002a - LL 4096(R5), R4 // a4001020 - LLV 4096(R5), R4 // a4001022 MOVW $4(R4), R5 // 8510c002 MOVV $4(R4), R5 // 8510c002 MOVW $-1, R4 // 04fcff02 @@ -354,6 +350,18 @@ lable2: AMMAXDBVU R14, (R13), R12 // acb97038 AMMINDBWU R14, (R13), R12 // ac397138 AMMINDBVU R14, (R13), R12 // acb97138 + LL 4096(R5), R4 // a4001020 + LLW 4096(R5), R4 // a4001020 + LLV 4096(R5), R4 // a4001022 + LLACQW (R5), R4 // a4805738 + LLACQV (R5), R4 // a4885738 + SC R4, 4096(R5) // a4001021 + SCW R4, 4096(R5) // a4001021 + SCV R4, 4096(R5) // a4001023 + SCQ R4, R5, (R6) // c4145738 + SCRELW R4, (R6) // c4845738 + SCRELV R4, (R6) // c48c5738 + FMADDF F2, F14, F9, F16 // 30391108 FMADDD F11, F20, F23, F12 // ecd22508 diff --git a/src/cmd/asm/internal/asm/testdata/loong64error.s b/src/cmd/asm/internal/asm/testdata/loong64error.s index 1bc0ddea55..25ef3a85a4 100644 --- a/src/cmd/asm/internal/asm/testdata/loong64error.s +++ b/src/cmd/asm/internal/asm/testdata/loong64error.s @@ -8,7 +8,8 @@ TEXT errors(SB),$0 ADDV16 $1, R4, R5 // ERROR "the constant must be a multiple of 65536." ADDV16 $65535, R4, R5 // ERROR "the constant must be a multiple of 65536." SC R4, 1(R5) // ERROR "offset must be a multiple of 4." + SCW R4, 1(R5) // ERROR "offset must be a multiple of 4." SCV R4, 1(R5) // ERROR "offset must be a multiple of 4." LL 1(R5), R4 // ERROR "offset must be a multiple of 4." + LLW 1(R5), R4 // ERROR "offset must be a multiple of 4." LLV 1(R5), R4 // ERROR "offset must be a multiple of 4." - diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go index d99c256267..0244a8f9e5 100644 --- a/src/cmd/internal/obj/loong64/anames.go +++ b/src/cmd/internal/obj/loong64/anames.go @@ -43,8 +43,6 @@ var Anames = []string{ "DIVU", "DIVW", "DIVWU", - "LL", - "LLV", "LUI", "MOVB", "MOVBU", @@ -77,8 +75,6 @@ var Anames = []string{ "REMU", "REMWU", "RFE", - "SC", - "SCV", "SGT", "SGTU", "SLL", @@ -181,6 +177,17 @@ var Anames = []string{ "AMMAXDBVU", "AMMINDBWU", "AMMINDBVU", + "LL", + "LLW", + "LLV", + "SC", + "SCW", + "SCV", + "SCQ", + "LLACQW", + "LLACQV", + "SCRELW", + "SCRELV", "EXTWB", "EXTWH", "CLOW", diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go index c3ec81cc92..2ed2f23d11 100644 --- a/src/cmd/internal/obj/loong64/asm.go +++ b/src/cmd/internal/obj/loong64/asm.go @@ -247,7 +247,7 @@ var optab = []Optab{ {AVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_VREG, C_NONE, 8, 4, REGZERO, 0}, {AVMOVQ, C_VREG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0}, {AVMOVQ, C_ROFF, C_NONE, C_NONE, C_VREG, C_NONE, 21, 4, 0, 0}, - {AVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_ARNG, C_NONE, 46, 4, 0, 0}, // vldrepl.{b/h/w/d} + {AVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_ARNG, C_NONE, 42, 4, 0, 0}, // vldrepl.{b/h/w/d} // moving data between registers {AVMOVQ, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 1, 4, 0, 0}, {AVMOVQ, C_REG, C_NONE, C_NONE, C_ELEM, C_NONE, 39, 4, 0, 0}, // vinsgr2vr.{b/h/w/d} @@ -262,7 +262,7 @@ var optab = []Optab{ {AXVMOVQ, C_SAUTO, C_NONE, C_NONE, C_XREG, C_NONE, 8, 4, REGZERO, 0}, {AXVMOVQ, C_XREG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0}, {AXVMOVQ, C_ROFF, C_NONE, C_NONE, C_XREG, C_NONE, 21, 4, 0, 0}, - {AXVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_ARNG, C_NONE, 46, 4, 0, 0}, // xvldrepl.{b/h/w/d} + {AXVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_ARNG, C_NONE, 42, 4, 0, 0}, // xvldrepl.{b/h/w/d} // moving data between registers {AXVMOVQ, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 1, 4, 0, 0}, {AXVMOVQ, C_REG, C_NONE, C_NONE, C_ELEM, C_NONE, 39, 4, 0, 0}, // vinsgr2vr.{b/h/w/d} @@ -310,6 +310,10 @@ var optab = []Optab{ {AAMSWAPW, C_REG, C_NONE, C_NONE, C_ZOREG, C_REG, 66, 4, 0, 0}, + {ASCQ, C_REG, C_REG, C_NONE, C_ZOREG, C_NONE, 45, 4, 0, 0}, + {ALLACQW, C_ZOREG, C_NONE, C_NONE, C_REG, C_NONE, 46, 4, 0, 0}, + {ASCRELW, C_REG, C_NONE, C_NONE, C_ZOREG, C_NONE, 46, 4, 0, 0}, + {ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0}, {ASYSCALL, C_U15CON, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0}, @@ -1430,8 +1434,10 @@ func buildop(ctxt *obj.Link) { case AMOVWP: opset(AMOVVP, r0) opset(ASC, r0) + opset(ASCW, r0) opset(ASCV, r0) opset(ALL, r0) + opset(ALLW, r0) opset(ALLV, r0) case ASLL: @@ -1515,6 +1521,7 @@ func buildop(ctxt *obj.Link) { APRELDX, AFSEL, AADDV16, + ASCQ, obj.ANOP, obj.ATEXT, obj.AFUNCDATA, @@ -1573,6 +1580,12 @@ func buildop(ctxt *obj.Link) { opset(i, r0) } + case ALLACQW: + opset(ALLACQV, r0) + + case ASCRELW: + opset(ASCRELV, r0) + // vseq.b vd, vj, vk // vseqi.b vd, vj, si5 case AVSEQB: @@ -2724,7 +2737,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { rd := uint32(p.To.Reg & EXT_REG_MASK) o1 = v | (rj << 5) | rd - case 46: // vmov offset(vj), vd. + case 42: // vmov offset(vj), vd. v, _ := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg, true) if v == 0 { c.ctxt.Diag("illegal arng type combination: %v\n", p) @@ -2756,6 +2769,23 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { } } + case 45: + // sc.q rd, rk, (rj) + o1 = OP_RRR(c.oprrr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg)) + + case 46: + // ll.acq.{w/d} (rj), rd + rj := uint32(p.From.Reg) + rd := uint32(p.To.Reg) + + switch p.As { + case ASCRELW, ASCRELV: + rj = uint32(p.To.Reg) + rd = uint32(p.From.Reg) + } + + o1 = OP_RR(c.oprr(p.As), rj, rd) + case 47: // preld offset(Rbase), $hint offs := c.regoff(&p.From) hint := p.GetFrom3().Offset diff --git a/src/cmd/internal/obj/loong64/inst.go b/src/cmd/internal/obj/loong64/inst.go index f59406eeef..3e9cd0c7dc 100644 --- a/src/cmd/internal/obj/loong64/inst.go +++ b/src/cmd/internal/obj/loong64/inst.go @@ -55,9 +55,6 @@ const ( ADIVW ADIVWU - ALL - ALLV - ALUI AMOVB @@ -99,9 +96,6 @@ const ( ARFE - ASC - ASCV - ASGT ASGTU @@ -228,6 +222,17 @@ const ( AAMMAXDBVU AAMMINDBWU AAMMINDBVU + ALL + ALLW + ALLV + ASC + ASCW + ASCV + ASCQ + ALLACQW + ALLACQV + ASCRELW + ASCRELV // 2.2.3.1 AEXTWB diff --git a/src/cmd/internal/obj/loong64/instOp.go b/src/cmd/internal/obj/loong64/instOp.go index 8d9bb7bbce..c2fa45ae57 100644 --- a/src/cmd/internal/obj/loong64/instOp.go +++ b/src/cmd/internal/obj/loong64/instOp.go @@ -36,6 +36,7 @@ var oprrr = map[obj.As]uint32{ ASGTU: 0x25 << 15, // sltu AMASKEQZ: 0x26 << 15, // maskeqz AMASKNEZ: 0x27 << 15, // masknez + ASCQ: 0x070AE << 15, // sc.q ANOR: 0x28 << 15, // nor AAND: 0x29 << 15, // and AOR: 0x2a << 15, // or @@ -568,6 +569,10 @@ var oprr = map[obj.As]uint32{ ARDTIMELW: 0x18 << 10, // rdtimel.w ARDTIMEHW: 0x19 << 10, // rdtimeh.w ARDTIMED: 0x1a << 10, // rdtime.d + ALLACQW: 0x0E15E0 << 10, // ll.acq.w + ASCRELW: 0x0E15E1 << 10, // sc.rel.w + ALLACQV: 0x0E15E2 << 10, // ll.acq.d + ASCRELV: 0x0E15E3 << 10, // sc.rel.d ATRUNCFV: 0x46a9 << 10, // ftintrz.l.s ATRUNCDV: 0x46aa << 10, // ftintrz.l.d ATRUNCFW: 0x46a1 << 10, // ftintrz.w.s @@ -760,7 +765,9 @@ var opirr = map[obj.As]uint32{ -AMOVD: 0x0ae << 22, // fld.d AMOVD: 0x0af << 22, // fst.d -ALL: 0x020 << 24, // ll.w + -ALLW: 0x020 << 24, // ll.w ASC: 0x021 << 24, // sc.w + ASCW: 0x021 << 24, // sc.w -ALLV: 0x022 << 24, // ll.d ASCV: 0x023 << 24, // sc.d -AMOVWP: 0x24 << 24, // ldptr.w diff --git a/src/internal/cpu/cpu.go b/src/internal/cpu/cpu.go index cf10e36b2d..a2d5524acd 100644 --- a/src/internal/cpu/cpu.go +++ b/src/internal/cpu/cpu.go @@ -92,14 +92,16 @@ var ARM64 struct { // The booleans in Loong64 contain the correspondingly named cpu feature bit. // The struct is padded to avoid false sharing. var Loong64 struct { - _ CacheLinePad - HasLSX bool // support 128-bit vector extension - HasLASX bool // support 256-bit vector extension - HasCRC32 bool // support CRC instruction - HasLAMCAS bool // support AMCAS[_DB].{B/H/W/D} - HasLAM_BH bool // support AM{SWAP/ADD}[_DB].{B/H} instruction - HasDBAR_HINTS bool // supports finer-grained DBAR hints - _ CacheLinePad + _ CacheLinePad + HasLSX bool // support 128-bit vector extension + HasLASX bool // support 256-bit vector extension + HasCRC32 bool // support CRC instruction + HasLAMCAS bool // support AMCAS[_DB].{B/H/W/D} + HasLAM_BH bool // support AM{SWAP/ADD}[_DB].{B/H} instruction + HasLLACQ_SCREL bool // support LLACQ.{W/D}、SCREL.{W/D} instruction + HasSCQ bool // support SC.Q instruction + HasDBAR_HINTS bool // supports finer-grained DBAR hints + _ CacheLinePad } var MIPS64X struct { diff --git a/src/internal/cpu/cpu_loong64.go b/src/internal/cpu/cpu_loong64.go index 520c1157ab..501e90de45 100644 --- a/src/internal/cpu/cpu_loong64.go +++ b/src/internal/cpu/cpu_loong64.go @@ -17,8 +17,10 @@ const ( cpucfg1_CRC32 = 1 << 25 // CPUCFG2 bits - cpucfg2_LAM_BH = 1 << 27 - cpucfg2_LAMCAS = 1 << 28 + cpucfg2_LAM_BH = 1 << 27 + cpucfg2_LAMCAS = 1 << 28 + cpucfg2_LLACQ_SCREL = 1 << 29 + cpucfg2_SCQ = 1 << 30 // CPUCFG3 bits cpucfg3_DBAR_HINTS = 1 << 17 @@ -34,6 +36,8 @@ func doinit() { {Name: "crc32", Feature: &Loong64.HasCRC32}, {Name: "lamcas", Feature: &Loong64.HasLAMCAS}, {Name: "lam_bh", Feature: &Loong64.HasLAM_BH}, + {Name: "llacq_screl", Feature: &Loong64.HasLLACQ_SCREL}, + {Name: "scq", Feature: &Loong64.HasSCQ}, {Name: "dbar_hints", Feature: &Loong64.HasDBAR_HINTS}, } @@ -51,6 +55,8 @@ func doinit() { Loong64.HasCRC32 = cfgIsSet(cfg1, cpucfg1_CRC32) Loong64.HasLAMCAS = cfgIsSet(cfg2, cpucfg2_LAMCAS) Loong64.HasLAM_BH = cfgIsSet(cfg2, cpucfg2_LAM_BH) + Loong64.HasLLACQ_SCREL = cfgIsSet(cfg2, cpucfg2_LLACQ_SCREL) + Loong64.HasSCQ = cfgIsSet(cfg2, cpucfg2_SCQ) Loong64.HasDBAR_HINTS = cfgIsSet(cfg3, cpucfg3_DBAR_HINTS) osInit()