diff options
| author | Guoqi Chen <chenguoqi@loongson.cn> | 2023-04-01 03:43:20 +0800 |
|---|---|---|
| committer | Cherry Mui <cherryyz@google.com> | 2024-05-22 02:04:54 +0000 |
| commit | 504212bbd704a3235da58ecda5f05962c5f30acb (patch) | |
| tree | b48f5eb22b5df5d5e4a0972927a41eec0529e998 /src/cmd/internal/obj | |
| parent | ca17bda85638ae2a1e8e73ae624d83bb5e64ecfd (diff) | |
| download | go-504212bbd704a3235da58ecda5f05962c5f30acb.tar.xz | |
cmd/internal/obj/loong64: add atomic memory access instructions support
The AM* atomic access instruction performs a sequence of “read-modify-write”
operations on a memory cell atomically. Specifically, it retrieves the old
value at the specified address in memory and writes it to the general register
rd, performs some simple operations on the old value in memory and the value
in the general register rk, and then write the result of the operation back
to the memory address pointed to by general register rj.
Go asm syntax:
AM{SWAP/ADD/AND/OR/XOR/MAX/MIN}[DB]{W/V} RK, (RJ), RD
AM{MAX/MIN}[DB]{WU/VU} RK, (RJ), RD
Equivalent platform assembler syntax:
am{swap/add/and/or/xor/max/min}[_db].{w/d} rd, rk, rj
am{max/min}[_db].{wu/du} rd, rk, rj
Ref: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html
Change-Id: I99ea4553ae731675180d63691c19ef334e7e7817
Reviewed-on: https://go-review.googlesource.com/c/go/+/481577
Reviewed-by: Meidan Li <limeidan@loongson.cn>
Reviewed-by: sophie zhao <zhaoxiaolin@loongson.cn>
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Qiqi Huang <huangqiqi@loongson.cn>
Reviewed-by: WANG Xuerui <git@xen0n.name>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/cmd/internal/obj')
| -rw-r--r-- | src/cmd/internal/obj/loong64/a.out.go | 50 | ||||
| -rw-r--r-- | src/cmd/internal/obj/loong64/anames.go | 48 | ||||
| -rw-r--r-- | src/cmd/internal/obj/loong64/asm.go | 79 |
3 files changed, 176 insertions, 1 deletions
diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go index d944fcfcb8..2dd2a085a8 100644 --- a/src/cmd/internal/obj/loong64/a.out.go +++ b/src/cmd/internal/obj/loong64/a.out.go @@ -394,6 +394,56 @@ const ( AMOVVF AMOVVD + // 2.2.7. Atomic Memory Access Instructions + AAMSWAPB + AAMSWAPH + AAMSWAPW + AAMSWAPV + AAMCASB + AAMCASH + AAMCASW + AAMCASV + AAMADDW + AAMADDV + AAMANDW + AAMANDV + AAMORW + AAMORV + AAMXORW + AAMXORV + AAMMAXW + AAMMAXV + AAMMINW + AAMMINV + AAMMAXWU + AAMMAXVU + AAMMINWU + AAMMINVU + AAMSWAPDBB + AAMSWAPDBH + AAMSWAPDBW + AAMSWAPDBV + AAMCASDBB + AAMCASDBH + AAMCASDBW + AAMCASDBV + AAMADDDBW + AAMADDDBV + AAMANDDBW + AAMANDDBV + AAMORDBW + AAMORDBV + AAMXORDBW + AAMXORDBV + AAMMAXDBW + AAMMAXDBV + AAMMINDBW + AAMMINDBV + AAMMAXDBWU + AAMMAXDBVU + AAMMINDBWU + AAMMINDBVU + // 2.2.10. Other Miscellaneous Instructions ARDTIMELW ARDTIMEHW diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go index f61756e7a8..f21e8c9630 100644 --- a/src/cmd/internal/obj/loong64/anames.go +++ b/src/cmd/internal/obj/loong64/anames.go @@ -131,6 +131,54 @@ var Anames = []string{ "MOVDV", "MOVVF", "MOVVD", + "AMSWAPB", + "AMSWAPH", + "AMSWAPW", + "AMSWAPV", + "AMCASB", + "AMCASH", + "AMCASW", + "AMCASV", + "AMADDW", + "AMADDV", + "AMANDW", + "AMANDV", + "AMORW", + "AMORV", + "AMXORW", + "AMXORV", + "AMMAXW", + "AMMAXV", + "AMMINW", + "AMMINV", + "AMMAXWU", + "AMMAXVU", + "AMMINWU", + "AMMINVU", + "AMSWAPDBB", + "AMSWAPDBH", + "AMSWAPDBW", + "AMSWAPDBV", + "AMCASDBB", + "AMCASDBH", + "AMCASDBW", + "AMCASDBV", + "AMADDDBW", + "AMADDDBV", + "AMANDDBW", + "AMANDDBV", + "AMORDBW", + "AMORDBV", + "AMXORDBW", + "AMXORDBV", + "AMMAXDBW", + "AMMAXDBV", + "AMMINDBW", + "AMMINDBV", + "AMMAXDBWU", + "AMMAXDBVU", + "AMMINDBWU", + "AMMINDBVU", "RDTIMELW", "RDTIMEHW", "RDTIMED", diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go index 5b823c09af..4eaf8bf5ed 100644 --- a/src/cmd/internal/obj/loong64/asm.go +++ b/src/cmd/internal/obj/loong64/asm.go @@ -356,7 +356,7 @@ var optab = []Optab{ {ATEQ, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 15, 8, 0, 0}, {ARDTIMELW, C_NONE, C_NONE, C_NONE, C_REG, C_REG, 62, 4, 0, 0}, - + {AAMSWAPW, C_REG, C_NONE, C_NONE, C_ZOREG, C_REG, 66, 4, 0, 0}, {ANOOP, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0}, {obj.APCALIGN, C_SCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, @@ -374,6 +374,63 @@ var optab = []Optab{ {obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0}, } +var atomicInst = map[obj.As]uint32{ + AAMSWAPB: 0x070B8 << 15, // amswap.b + AAMSWAPH: 0x070B9 << 15, // amswap.h + AAMSWAPW: 0x070C0 << 15, // amswap.w + AAMSWAPV: 0x070C1 << 15, // amswap.d + AAMCASB: 0x070B0 << 15, // amcas.b + AAMCASH: 0x070B1 << 15, // amcas.h + AAMCASW: 0x070B2 << 15, // amcas.w + AAMCASV: 0x070B3 << 15, // amcas.d + AAMADDW: 0x070C2 << 15, // amadd.w + AAMADDV: 0x070C3 << 15, // amadd.d + AAMANDW: 0x070C4 << 15, // amand.w + AAMANDV: 0x070C5 << 15, // amand.d + AAMORW: 0x070C6 << 15, // amor.w + AAMORV: 0x070C7 << 15, // amor.d + AAMXORW: 0x070C8 << 15, // amxor.w + AAMXORV: 0x070C9 << 15, // amxor.d + AAMMAXW: 0x070CA << 15, // ammax.w + AAMMAXV: 0x070CB << 15, // ammax.d + AAMMINW: 0x070CC << 15, // ammin.w + AAMMINV: 0x070CD << 15, // ammin.d + AAMMAXWU: 0x070CE << 15, // ammax.wu + AAMMAXVU: 0x070CF << 15, // ammax.du + AAMMINWU: 0x070D0 << 15, // ammin.wu + AAMMINVU: 0x070D1 << 15, // ammin.du + AAMSWAPDBB: 0x070BC << 15, // amswap_db.b + AAMSWAPDBH: 0x070BD << 15, // amswap_db.h + AAMSWAPDBW: 0x070D2 << 15, // amswap_db.w + AAMSWAPDBV: 0x070D3 << 15, // amswap_db.d + AAMCASDBB: 0x070B4 << 15, // amcas_db.b + AAMCASDBH: 0x070B5 << 15, // amcas_db.h + AAMCASDBW: 0x070B6 << 15, // amcas_db.w + AAMCASDBV: 0x070B7 << 15, // amcas_db.d + AAMADDDBW: 0x070D4 << 15, // amadd_db.w + AAMADDDBV: 0x070D5 << 15, // amadd_db.d + AAMANDDBW: 0x070D6 << 15, // amand_db.w + AAMANDDBV: 0x070D7 << 15, // amand_db.d + AAMORDBW: 0x070D8 << 15, // amor_db.w + AAMORDBV: 0x070D9 << 15, // amor_db.d + AAMXORDBW: 0x070DA << 15, // amxor_db.w + AAMXORDBV: 0x070DB << 15, // amxor_db.d + AAMMAXDBW: 0x070DC << 15, // ammax_db.w + AAMMAXDBV: 0x070DD << 15, // ammax_db.d + AAMMINDBW: 0x070DE << 15, // ammin_db.w + AAMMINDBV: 0x070DF << 15, // ammin_db.d + AAMMAXDBWU: 0x070E0 << 15, // ammax_db.wu + AAMMAXDBVU: 0x070E1 << 15, // ammax_db.du + AAMMINDBWU: 0x070E2 << 15, // ammin_db.wu + AAMMINDBVU: 0x070E3 << 15, // ammin_db.du +} + +func IsAtomicInst(as obj.As) bool { + _, ok := atomicInst[as] + + return ok +} + // pcAlignPadLength returns the number of bytes required to align pc to alignedValue, // reporting an error if alignedValue is not a power of two or is out of range. func pcAlignPadLength(ctxt *obj.Link, pc int64, alignedValue int64) int { @@ -1182,6 +1239,14 @@ func buildop(ctxt *obj.Link) { case ANOOP: opset(obj.AUNDEF, r0) + + case AAMSWAPW: + for i := range atomicInst { + if i == AAMSWAPW { + continue + } + opset(i, r0) + } } } } @@ -1817,6 +1882,18 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { rel2.Sym = p.From.Sym rel2.Type = objabi.R_LOONG64_GOT_LO rel2.Add = 0x0 + + case 66: // am* From, To, RegTo2 ==> am* RegTo2, From, To + rk := p.From.Reg + rj := p.To.Reg + rd := p.RegTo2 + + // See section 2.2.7.1 of https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html + // for the register usage constraints. + if rd == rj || rd == rk { + c.ctxt.Diag("illegal register combination: %v\n", p) + } + o1 = OP_RRR(atomicInst[p.As], uint32(rk), uint32(rj), uint32(rd)) } out[0] = o1 |
