diff options
Diffstat (limited to 'src/cmd/internal/obj')
| -rw-r--r-- | src/cmd/internal/obj/loong64/asm.go | 35 | ||||
| -rw-r--r-- | src/cmd/internal/obj/loong64/doc.go | 9 |
2 files changed, 43 insertions, 1 deletions
diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go index 1b982f6c86..35b33b9376 100644 --- a/src/cmd/internal/obj/loong64/asm.go +++ b/src/cmd/internal/obj/loong64/asm.go @@ -1983,6 +1983,18 @@ func OP_12IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { return op | (i&0xFFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 } +func OP_11IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { + return op | (i&0x7FF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 +} + +func OP_10IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { + return op | (i&0x3FF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 +} + +func OP_9IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { + return op | (i&0x1FF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 +} + func OP_8IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { return op | (i&0xFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 } @@ -2535,7 +2547,28 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { si := c.regoff(&p.From) Rj := uint32(p.From.Reg & EXT_REG_MASK) Vd := uint32(p.To.Reg & EXT_REG_MASK) - o1 = v | uint32(si<<10) | (Rj << 5) | Vd + switch v & 0xc00000 { + case 0x800000: // [x]vldrepl.b + o1 = OP_12IRR(v, uint32(si), Rj, Vd) + case 0x400000: // [x]vldrepl.h + if si&1 != 0 { + c.ctxt.Diag("%v: offset must be a multiple of 2.\n", p) + } + o1 = OP_11IRR(v, uint32(si>>1), Rj, Vd) + case 0x0: + switch v & 0x300000 { + case 0x200000: // [x]vldrepl.w + if si&3 != 0 { + c.ctxt.Diag("%v: offset must be a multiple of 4.\n", p) + } + o1 = OP_10IRR(v, uint32(si>>2), Rj, Vd) + case 0x100000: // [x]vldrepl.d + if si&7 != 0 { + c.ctxt.Diag("%v: offset must be a multiple of 8.\n", p) + } + o1 = OP_9IRR(v, uint32(si>>3), Rj, Vd) + } + } case 47: // preld offset(Rbase), $hint offs := c.regoff(&p.From) diff --git a/src/cmd/internal/obj/loong64/doc.go b/src/cmd/internal/obj/loong64/doc.go index 6c8f2618a2..20c5a9e0a6 100644 --- a/src/cmd/internal/obj/loong64/doc.go +++ b/src/cmd/internal/obj/loong64/doc.go @@ -220,6 +220,15 @@ Note: In the following sections 3.1 to 3.6, "ui4" (4-bit unsigned int immediate) XVMOVQ offset(Rj), Xd.W8 | xvldrepl.w Xd, Rj, si10 | for i in range(8) : XR[xd].w[i] = load 32 bit memory data from (GR[rj]+SignExtend(si10<<2)) XVMOVQ offset(Rj), Xd.V4 | xvldrepl.d Xd, Rj, si9 | for i in range(4) : XR[xd].d[i] = load 64 bit memory data from (GR[rj]+SignExtend(si9<<3)) + note: In Go assembly, for ease of understanding, offset representing the actual address offset. + However, during platform encoding, the offset is shifted to increase the encodable offset range, as follows: + + Go assembly | platform assembly + VMOVQ 1(R4), V5.B16 | vldrepl.b v5, r4, $1 + VMOVQ 2(R4), V5.H8 | vldrepl.h v5, r4, $1 + VMOVQ 8(R4), V5.W4 | vldrepl.w v5, r4, $2 + VMOVQ 8(R4), V5.V2 | vldrepl.d v5, r4, $1 + # Special instruction encoding definition and description on LoongArch 1. DBAR hint encoding for LA664(Loongson 3A6000) and later micro-architectures, paraphrased |
