From 289cabe99308eea6f0881d8abaf54207cdbad4f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Balv=C3=ADn?= Date: Sun, 20 Sep 2026 19:14:43 +0200 Subject: [PATCH] feat(loong64): encode the full LSX and LASX table Assisted-by: GLM 5.3 Flash --- asm/loong64_assemble.go | 58 +++ asm/loong64_encode.go | 461 +++++++++++++++++++- asm/loong64_encode_test.go | 242 ++++++++++ testdata/verify/amdb_loong64.s | 44 ++ testdata/verify/pseudos_loong64.s | 31 ++ testdata/verify/vector_arith_add_loong64.s | 209 +++++++++ testdata/verify/vector_arith_sat_loong64.s | 132 ++++++ testdata/verify/vector_arith_sub_loong64.s | 220 ++++++++++ testdata/verify/vector_bitops_loong64.s | 124 ++++++ testdata/verify/vector_bounds_loong64.s | 419 ++++++++++++++++++ testdata/verify/vector_divmod_loong64.s | 148 +++++++ testdata/verify/vector_fp_loong64.s | 176 ++++++++ testdata/verify/vector_interleave_loong64.s | 68 +++ testdata/verify/vector_logic_loong64.s | 174 ++++++++ testdata/verify/vector_madd_loong64.s | 28 ++ testdata/verify/vector_maddwiden_loong64.s | 204 +++++++++ testdata/verify/vector_msub_loong64.s | 36 ++ testdata/verify/vector_mul_loong64.s | 108 +++++ testdata/verify/vector_mulwiden_loong64.s | 204 +++++++++ testdata/verify/vector_shift_loong64.s | 214 +++++++++ testdata/verify/vector_shuffle_loong64.s | 132 ++++++ testdata/verify/vector_unary_loong64.s | 108 +++++ 22 files changed, 3528 insertions(+), 12 deletions(-) create mode 100644 testdata/verify/amdb_loong64.s create mode 100644 testdata/verify/pseudos_loong64.s create mode 100644 testdata/verify/vector_arith_add_loong64.s create mode 100644 testdata/verify/vector_arith_sat_loong64.s create mode 100644 testdata/verify/vector_arith_sub_loong64.s create mode 100644 testdata/verify/vector_bitops_loong64.s create mode 100644 testdata/verify/vector_bounds_loong64.s create mode 100644 testdata/verify/vector_divmod_loong64.s create mode 100644 testdata/verify/vector_fp_loong64.s create mode 100644 testdata/verify/vector_interleave_loong64.s create mode 100644 testdata/verify/vector_logic_loong64.s create mode 100644 testdata/verify/vector_madd_loong64.s create mode 100644 testdata/verify/vector_maddwiden_loong64.s create mode 100644 testdata/verify/vector_msub_loong64.s create mode 100644 testdata/verify/vector_mul_loong64.s create mode 100644 testdata/verify/vector_mulwiden_loong64.s create mode 100644 testdata/verify/vector_shift_loong64.s create mode 100644 testdata/verify/vector_shuffle_loong64.s create mode 100644 testdata/verify/vector_unary_loong64.s diff --git a/asm/loong64_assemble.go b/asm/loong64_assemble.go index d133987..3855882 100644 --- a/asm/loong64_assemble.go +++ b/asm/loong64_assemble.go @@ -372,6 +372,10 @@ func loong64InstrSize(instr *ast.Instr, fi loong64FrameInfo) int { return len(loong64Return(fi)) } switch mnem { + case "END", "FUNCDATA", "PCDATA": + return 0 // bookkeeping statements contribute no bytes + case "GETCALLERPC": + return 4 // or rd, r1, r0 case "TEQ", "TNE": return 8 // bne/beq over the BREAK, then BREAK case "PRELDX": @@ -480,6 +484,36 @@ func encodeLOONG64Instr(instr *ast.Instr, pc int, offsets map[string]int, fi loo return nil, fmt.Errorf("WORD expects 1 operand, got %d", len(ops)) } return l64wordLE(uint32(immFromOperand(ops[0]))), nil + case "END", "FUNCDATA", "PCDATA", "GETCALLERPC": + // The assembler's bookkeeping statements. END, FUNCDATA and PCDATA + // contribute no bytes, the same shapes GOARCH=loong64 go tool asm + // accepts and emits nothing for; GETCALLERPC reads the caller's + // address out of R1 (RA) as or rd, r1, r0. + switch mnem { + case "END": + if len(ops) != 0 { + return nil, fmt.Errorf("END expects no operands, got %d", len(ops)) + } + return nil, nil + case "FUNCDATA": + if len(ops) != 2 || !isImmOperand(ops[0]) { + return nil, fmt.Errorf("FUNCDATA expects $n, sym(SB)") + } + return nil, nil + case "PCDATA": + if len(ops) != 2 || !isImmOperand(ops[0]) || !isImmOperand(ops[1]) { + return nil, fmt.Errorf("PCDATA expects $n, $n") + } + return nil, nil + } + if len(ops) != 1 || isMemOperand(ops[0]) || loong64RegClass(operandRegName(ops[0])) != l64ClsGR { + return nil, fmt.Errorf("GETCALLERPC expects a general register") + } + rd := loong64RegNum(operandRegName(ops[0])) + if rd < 0 { + return nil, fmt.Errorf("GETCALLERPC: invalid register operand") + } + return l64wordLE(l64rrr(l64movRegTable["MOVV"].op, 0, 1, rd)), nil case "NEGW", "NEGV": // The integer negation pseudo is a subtract from zero: // NEGW src, dst → sub.w r0, src, dst. @@ -2084,6 +2118,30 @@ func encodeLOONG64Vector(instr *ast.Instr, mnem string, fi loong64FrameInfo) ([] return l64wordLE(l64rr(l64InstrTable[mnem].op, vj, fcc)), true, nil } + // Four-register forms (vshuf.b): INSTR va, vk, vj, vd. + if l64Vec4R[mnem] { + if len(ops) != 4 { + return nil, true, fmt.Errorf("%s expects 4 operands, got %d", mnem, len(ops)) + } + va, err := vec(ops[0]) + if err != nil { + return nil, true, err + } + vk, err := vec(ops[1]) + if err != nil { + return nil, true, err + } + vj, err := vec(ops[2]) + if err != nil { + return nil, true, err + } + vd, err := vec(ops[3]) + if err != nil { + return nil, true, err + } + return l64wordLE(l64InstrTable[mnem].op | uint32(va&0x1f)<<15 | uint32(vk&0x1f)<<10 | uint32(vj&0x1f)<<5 | uint32(vd&0x1f)), true, nil + } + // Three-register forms: INSTR vk, vj, vd or INSTR vk, vd (vj = vd). if len(ops) != 2 && len(ops) != 3 { return nil, true, fmt.Errorf("%s expects 2 or 3 operands, got %d", mnem, len(ops)) diff --git a/asm/loong64_encode.go b/asm/loong64_encode.go index dcb9866..99f13d0 100644 --- a/asm/loong64_encode.go +++ b/asm/loong64_encode.go @@ -278,6 +278,7 @@ const ( l64Fpreld // preld (2RI12 + 5-bit hint) l64Fvvv // 3R vector (LSX/LASX): op | vk<<10 | vj<<5 | vd l64Fvcf // vector-to-condition: op | subop<<10 | vj<<5 | fcc + l64Fvvvv // 4R vector shuffle: op | va<<15 | vk<<10 | vj<<5 | vd ) // l64Enc is one instruction's encoding: its bit layout (format) and the @@ -336,6 +337,10 @@ var l64VecImmInfo = map[string]l64VecImmEnc{} // vpcnt.v). var l64Vec2R = map[string]bool{} +// l64Vec4R marks the four-operand vector mnemonics (INSTR va, vk, vj, vd, +// such as vshuf.b). +var l64Vec4R = map[string]bool{} + // l64VmovqOps holds the VMOVQ/XVMOVQ opcode constants (pre-shifted to bit // 15), read off `go tool objdump` of GOARCH=loong64 `go tool asm` kernels. type l64VmovqEnc struct { @@ -445,6 +450,14 @@ func init() { // bank is the FP registers (the toolchain spells it `FFINTDV F0, F1`), // so the entry stays on the 2R integer/FP format. "FFINTDV": 0x474a << 10, + // The rest of the scalar conversions (all F-bank, 2R). + "FFINTFW": 0x4744 << 10, // ffint.s.w + "FFINTFV": 0x4746 << 10, // ffint.s.l + "FFINTDW": 0x4748 << 10, // ffint.d.w + "FTINTWF": 0x46c1 << 10, // ftint.w.s + "FTINTWD": 0x46c2 << 10, // ftint.w.d + "FTINTVF": 0x46c9 << 10, // ftint.l.s + "FTINTVD": 0x46ca << 10, // ftint.l.d } for m, op := range rr { l64InstrTable[m] = l64Enc{format: l64Frr, op: op} @@ -568,6 +581,12 @@ func init() { "AMADDDBW": 0x070D4 << 15, "AMADDDBV": 0x070D5 << 15, "AMANDDBW": 0x070D6 << 15, "AMANDDBV": 0x070D7 << 15, "AMORDBW": 0x070D8 << 15, "AMORDBV": 0x070D9 << 15, + // The remaining _dbar exchange variants (loong64enc1.s). + "AMXORDBW": 0x070DA << 15, "AMXORDBV": 0x070DB << 15, + "AMMAXDBW": 0x070DC << 15, "AMMAXDBV": 0x070DD << 15, + "AMMINDBW": 0x070DE << 15, "AMMINDBV": 0x070DF << 15, + "AMMAXDBWU": 0x070E0 << 15, "AMMAXDBVU": 0x070E1 << 15, + "AMMINDBWU": 0x070E2 << 15, "AMMINDBVU": 0x070E3 << 15, } for m, op := range am { l64InstrTable[m] = l64Enc{format: l64Fam, op: op} @@ -590,6 +609,240 @@ func init() { "XVANDV": {0xEA4C << 15, true}, "XVXORV": {0xEA4E << 15, true}, "XVSEQB": {0xE800 << 15, true}, "XVSEQV": {0xE803 << 15, true}, } + + // The integer and FP add/subtract families: [X]VADD and [X]VSUB by lane + // width, plus the [X]VSADD/[X]VSSUB saturating pairs. + // Opcodes transcribed from the toolchain's loong64enc1.s. + addsub := map[string]l64Vec3Enc{ + "VADDB": {0xE014 << 15, false}, "VADDH": {0xE015 << 15, false}, + "VADDD": {0xE262 << 15, false}, "VADDF": {0xE261 << 15, false}, + "VADDQ": {0xE25A << 15, false}, + "VSUBB": {0xE018 << 15, false}, "VSUBH": {0xE019 << 15, false}, + "VSUBW": {0xE01A << 15, false}, "VSUBV": {0xE01B << 15, false}, + "VSUBQ": {0xE25B << 15, false}, + "VSUBF": {0xE265 << 15, false}, "VSUBD": {0xE266 << 15, false}, + "VSADDB": {0xE08C << 15, false}, "VSADDH": {0xE08D << 15, false}, + "VSADDW": {0xE08E << 15, false}, "VSADDV": {0xE08F << 15, false}, + "VSADDBU": {0xE094 << 15, false}, "VSADDHU": {0xE095 << 15, false}, + "VSADDWU": {0xE096 << 15, false}, "VSADDVU": {0xE097 << 15, false}, + "VSSUBB": {0xE090 << 15, false}, "VSSUBH": {0xE091 << 15, false}, + "VSSUBW": {0xE092 << 15, false}, "VSSUBV": {0xE093 << 15, false}, + "VSSUBBU": {0xE098 << 15, false}, "VSSUBHU": {0xE099 << 15, false}, + "VSSUBWU": {0xE09A << 15, false}, "VSSUBVU": {0xE09B << 15, false}, + "XVADDB": {0xE814 << 15, true}, "XVADDH": {0xE815 << 15, true}, + "XVADDW": {0xE816 << 15, true}, + "XVADDD": {0xEA62 << 15, true}, "XVADDF": {0xEA61 << 15, true}, + "XVADDQ": {0xEA5A << 15, true}, + "XVSUBB": {0xE818 << 15, true}, "XVSUBH": {0xE819 << 15, true}, + "XVSUBW": {0xE81A << 15, true}, "XVSUBV": {0xE81B << 15, true}, + "XVSUBQ": {0xEA5B << 15, true}, + "XVSUBF": {0xEA65 << 15, true}, "XVSUBD": {0xEA66 << 15, true}, + "XVSADDB": {0xE88C << 15, true}, "XVSADDH": {0xE88D << 15, true}, + "XVSADDW": {0xE88E << 15, true}, "XVSADDV": {0xE88F << 15, true}, + "XVSADDBU": {0xE894 << 15, true}, "XVSADDHU": {0xE895 << 15, true}, + "XVSADDWU": {0xE896 << 15, true}, "XVSADDVU": {0xE897 << 15, true}, + "XVSSUBB": {0xE890 << 15, true}, "XVSSUBH": {0xE891 << 15, true}, + "XVSSUBW": {0xE892 << 15, true}, "XVSSUBV": {0xE893 << 15, true}, + "XVSSUBBU": {0xE898 << 15, true}, "XVSSUBHU": {0xE899 << 15, true}, + "XVSSUBWU": {0xE89A << 15, true}, "XVSSUBVU": {0xE89B << 15, true}, + } + + // The multiply families: plain and high-half [X]VMUL/[X]VMUH, the + // widening [X]VMULW{EV,OD} ladder and its accumulating [X]VMADDW twins, + // plus the [X]VMADD/[X]VMSUB fused multiply-add and the [X]VDIV/[X]VMOD + // divide and modulo pairs. + muldiv := map[string]l64Vec3Enc{ + "VMULB": {0xE108 << 15, false}, "VMULH": {0xE109 << 15, false}, + "VMULW": {0xE10A << 15, false}, "VMULV": {0xE10B << 15, false}, + "VMUHB": {0xE10C << 15, false}, "VMUHH": {0xE10D << 15, false}, + "VMUHW": {0xE10E << 15, false}, "VMUHV": {0xE10F << 15, false}, + "VMUHBU": {0xE110 << 15, false}, "VMUHHU": {0xE111 << 15, false}, + "VMUHWU": {0xE112 << 15, false}, "VMUHVU": {0xE113 << 15, false}, + "VMULWEVHB": {0xE120 << 15, false}, "VMULWEVWH": {0xE121 << 15, false}, + "VMULWEVVW": {0xE122 << 15, false}, "VMULWEVQV": {0xE123 << 15, false}, + "VMULWODHB": {0xE124 << 15, false}, "VMULWODWH": {0xE125 << 15, false}, + "VMULWODVW": {0xE126 << 15, false}, "VMULWODQV": {0xE127 << 15, false}, + "VMULWEVHBU": {0xE130 << 15, false}, "VMULWEVWHU": {0xE131 << 15, false}, + "VMULWEVVWU": {0xE132 << 15, false}, "VMULWEVQVU": {0xE133 << 15, false}, + "VMULWODHBU": {0xE134 << 15, false}, "VMULWODWHU": {0xE135 << 15, false}, + "VMULWODVWU": {0xE136 << 15, false}, "VMULWODQVU": {0xE137 << 15, false}, + "VMULWEVHBUB": {0xE140 << 15, false}, "VMULWEVWHUH": {0xE141 << 15, false}, + "VMULWEVVWUW": {0xE142 << 15, false}, "VMULWEVQVUV": {0xE143 << 15, false}, + "VMULWODHBUB": {0xE144 << 15, false}, "VMULWODWHUH": {0xE145 << 15, false}, + "VMULWODVWUW": {0xE146 << 15, false}, "VMULWODQVUV": {0xE147 << 15, false}, + "VMADDB": {0xE150 << 15, false}, "VMADDH": {0xE151 << 15, false}, + "VMADDW": {0xE152 << 15, false}, "VMADDV": {0xE153 << 15, false}, + "VMSUBB": {0xE154 << 15, false}, "VMSUBH": {0xE155 << 15, false}, + "VMSUBW": {0xE156 << 15, false}, "VMSUBV": {0xE157 << 15, false}, + "VMADDWEVHB": {0xE158 << 15, false}, "VMADDWEVWH": {0xE159 << 15, false}, + "VMADDWEVVW": {0xE15A << 15, false}, "VMADDWEVQV": {0xE15B << 15, false}, + "VMADDWODHB": {0xE15C << 15, false}, "VMADDWODWH": {0xE15D << 15, false}, + "VMADDWODVW": {0xE15E << 15, false}, "VMADDWODQV": {0xE15F << 15, false}, + "VMADDWEVHBU": {0xE168 << 15, false}, "VMADDWEVWHU": {0xE169 << 15, false}, + "VMADDWEVVWU": {0xE16A << 15, false}, "VMADDWEVQVU": {0xE16B << 15, false}, + "VMADDWODHBU": {0xE16C << 15, false}, "VMADDWODWHU": {0xE16D << 15, false}, + "VMADDWODVWU": {0xE16E << 15, false}, "VMADDWODQVU": {0xE16F << 15, false}, + "VMADDWEVHBUB": {0xE178 << 15, false}, "VMADDWEVWHUH": {0xE179 << 15, false}, + "VMADDWEVVWUW": {0xE17A << 15, false}, "VMADDWEVQVUV": {0xE17B << 15, false}, + "VMADDWODHBUB": {0xE17C << 15, false}, "VMADDWODWHUH": {0xE17D << 15, false}, + "VMADDWODVWUW": {0xE17E << 15, false}, "VMADDWODQVUV": {0xE17F << 15, false}, + "VDIVB": {0xE1C0 << 15, false}, "VDIVH": {0xE1C1 << 15, false}, + "VDIVW": {0xE1C2 << 15, false}, "VDIVV": {0xE1C3 << 15, false}, + "VMODB": {0xE1C4 << 15, false}, "VMODH": {0xE1C5 << 15, false}, + "VMODW": {0xE1C6 << 15, false}, "VMODV": {0xE1C7 << 15, false}, + "VDIVBU": {0xE1C8 << 15, false}, "VDIVHU": {0xE1C9 << 15, false}, + "VDIVWU": {0xE1CA << 15, false}, "VDIVVU": {0xE1CB << 15, false}, + "VMODBU": {0xE1CC << 15, false}, "VMODHU": {0xE1CD << 15, false}, + "VMODWU": {0xE1CE << 15, false}, "VMODVU": {0xE1CF << 15, false}, + "VMULF": {0xE271 << 15, false}, "VMULD": {0xE272 << 15, false}, + "VDIVF": {0xE275 << 15, false}, "VDIVD": {0xE276 << 15, false}, + "XVMULB": {0xE908 << 15, true}, "XVMULH": {0xE909 << 15, true}, + "XVMULW": {0xE90A << 15, true}, "XVMULV": {0xE90B << 15, true}, + "XVMUHB": {0xE90C << 15, true}, "XVMUHH": {0xE90D << 15, true}, + "XVMUHW": {0xE90E << 15, true}, "XVMUHV": {0xE90F << 15, true}, + "XVMUHBU": {0xE910 << 15, true}, "XVMUHHU": {0xE911 << 15, true}, + "XVMUHWU": {0xE912 << 15, true}, "XVMUHVU": {0xE913 << 15, true}, + "XVMULWEVHB": {0xE920 << 15, true}, "XVMULWEVWH": {0xE921 << 15, true}, + "XVMULWEVVW": {0xE922 << 15, true}, "XVMULWEVQV": {0xE923 << 15, true}, + "XVMULWODHB": {0xE924 << 15, true}, "XVMULWODWH": {0xE925 << 15, true}, + "XVMULWODVW": {0xE926 << 15, true}, "XVMULWODQV": {0xE927 << 15, true}, + "XVMULWEVHBU": {0xE930 << 15, true}, "XVMULWEVWHU": {0xE931 << 15, true}, + "XVMULWEVVWU": {0xE932 << 15, true}, "XVMULWEVQVU": {0xE933 << 15, true}, + "XVMULWODHBU": {0xE934 << 15, true}, "XVMULWODWHU": {0xE935 << 15, true}, + "XVMULWODVWU": {0xE936 << 15, true}, "XVMULWODQVU": {0xE937 << 15, true}, + "XVMULWEVHBUB": {0xE940 << 15, true}, "XVMULWEVWHUH": {0xE941 << 15, true}, + "XVMULWEVVWUW": {0xE942 << 15, true}, "XVMULWEVQVUV": {0xE943 << 15, true}, + "XVMULWODHBUB": {0xE944 << 15, true}, "XVMULWODWHUH": {0xE945 << 15, true}, + "XVMULWODVWUW": {0xE946 << 15, true}, "XVMULWODQVUV": {0xE947 << 15, true}, + "XVMADDB": {0xE950 << 15, true}, "XVMADDH": {0xE951 << 15, true}, + "XVMADDW": {0xE952 << 15, true}, "XVMADDV": {0xE953 << 15, true}, + "XVMSUBB": {0xE954 << 15, true}, "XVMSUBH": {0xE955 << 15, true}, + "XVMSUBW": {0xE956 << 15, true}, "XVMSUBV": {0xE957 << 15, true}, + "XVMADDWEVHB": {0xE958 << 15, true}, "XVMADDWEVWH": {0xE959 << 15, true}, + "XVMADDWEVVW": {0xE95A << 15, true}, "XVMADDWEVQV": {0xE95B << 15, true}, + "XVMADDWODHB": {0xE95C << 15, true}, "XVMADDWODWH": {0xE95D << 15, true}, + "XVMADDWODVW": {0xE95E << 15, true}, "XVMADDWODQV": {0xE95F << 15, true}, + "XVMADDWEVHBU": {0xE968 << 15, true}, "XVMADDWEVWHU": {0xE969 << 15, true}, + "XVMADDWEVVWU": {0xE96A << 15, true}, "XVMADDWEVQVU": {0xE96B << 15, true}, + "XVMADDWODHBU": {0xE96C << 15, true}, "XVMADDWODWHU": {0xE96D << 15, true}, + "XVMADDWODVWU": {0xE96E << 15, true}, "XVMADDWODQVU": {0xE96F << 15, true}, + "XVMADDWEVHBUB": {0xE978 << 15, true}, "XVMADDWEVWHUH": {0xE979 << 15, true}, + "XVMADDWEVVWUW": {0xE97A << 15, true}, "XVMADDWEVQVUV": {0xE97B << 15, true}, + "XVMADDWODHBUB": {0xE97C << 15, true}, "XVMADDWODWHUH": {0xE97D << 15, true}, + "XVMADDWODVWUW": {0xE97E << 15, true}, "XVMADDWODQVUV": {0xE97F << 15, true}, + "XVDIVB": {0xE9C0 << 15, true}, "XVDIVH": {0xE9C1 << 15, true}, + "XVDIVW": {0xE9C2 << 15, true}, "XVDIVV": {0xE9C3 << 15, true}, + "XVMODB": {0xE9C4 << 15, true}, "XVMODH": {0xE9C5 << 15, true}, + "XVMODW": {0xE9C6 << 15, true}, "XVMODV": {0xE9C7 << 15, true}, + "XVDIVBU": {0xE9C8 << 15, true}, "XVDIVHU": {0xE9C9 << 15, true}, + "XVDIVWU": {0xE9CA << 15, true}, "XVDIVVU": {0xE9CB << 15, true}, + "XVMODBU": {0xE9CC << 15, true}, "XVMODHU": {0xE9CD << 15, true}, + "XVMODWU": {0xE9CE << 15, true}, "XVMODVU": {0xE9CF << 15, true}, + "XVMULF": {0xEA71 << 15, true}, "XVMULD": {0xEA72 << 15, true}, + "XVDIVF": {0xEA75 << 15, true}, "XVDIVD": {0xEA76 << 15, true}, + } + + // The lane-wise shifts and rotates (three-register forms; the immediate + // forms live in l64VecImmInfo), the interleave families, the bit + // clear/set/rev register forms, the remaining logic and compare + // spellings, the widening add/subtract ladder and the vector FP + // arithmetic. + vecmisc := map[string]l64Vec3Enc{ + "VSLLB": {0xE1D0 << 15, false}, "VSLLH": {0xE1D1 << 15, false}, + "VSLLW": {0xE1D2 << 15, false}, "VSLLV": {0xE1D3 << 15, false}, + "VSRLB": {0xE1D4 << 15, false}, "VSRLH": {0xE1D5 << 15, false}, + "VSRLW": {0xE1D6 << 15, false}, "VSRLV": {0xE1D7 << 15, false}, + "VSRAH": {0xE1D9 << 15, false}, "VSRAW": {0xE1DA << 15, false}, + "VSRAV": {0xE1DB << 15, false}, + "VROTRB": {0xE1DC << 15, false}, "VROTRH": {0xE1DD << 15, false}, + "VROTRV": {0xE1DF << 15, false}, + "VILVLB": {0xE234 << 15, false}, "VILVLH": {0xE235 << 15, false}, + "VILVLW": {0xE236 << 15, false}, "VILVLV": {0xE237 << 15, false}, + "VILVHB": {0xE238 << 15, false}, "VILVHH": {0xE239 << 15, false}, + "VILVHW": {0xE23A << 15, false}, "VILVHV": {0xE23B << 15, false}, + "VBITCLRB": {0xE218 << 15, false}, "VBITCLRH": {0xE219 << 15, false}, + "VBITCLRW": {0xE21A << 15, false}, "VBITCLRV": {0xE21B << 15, false}, + "VBITSETB": {0xE21C << 15, false}, "VBITSETH": {0xE21D << 15, false}, + "VBITSETW": {0xE21E << 15, false}, "VBITSETV": {0xE21F << 15, false}, + "VBITREVB": {0xE220 << 15, false}, "VBITREVH": {0xE221 << 15, false}, + "VBITREVW": {0xE222 << 15, false}, "VBITREVV": {0xE223 << 15, false}, + "VORV": {0xE24D << 15, false}, "VNORV": {0xE24F << 15, false}, + "VANDNV": {0xE250 << 15, false}, "VORNV": {0xE251 << 15, false}, + "VSEQH": {0xE001 << 15, false}, "VSEQW": {0xE002 << 15, false}, + "VSLTB": {0xE00C << 15, false}, "VSLTH": {0xE00D << 15, false}, + "VSLTW": {0xE00E << 15, false}, "VSLTV": {0xE00F << 15, false}, + "VSLTBU": {0xE010 << 15, false}, "VSLTHU": {0xE011 << 15, false}, + "VSLTWU": {0xE012 << 15, false}, "VSLTVU": {0xE013 << 15, false}, + "VADDWEVHB": {0xE03C << 15, false}, "VADDWEVWH": {0xE03D << 15, false}, + "VADDWEVVW": {0xE03E << 15, false}, "VADDWEVQV": {0xE03F << 15, false}, + "VSUBWEVHB": {0xE040 << 15, false}, "VSUBWEVWH": {0xE041 << 15, false}, + "VSUBWEVVW": {0xE042 << 15, false}, "VSUBWEVQV": {0xE043 << 15, false}, + "VADDWODHB": {0xE044 << 15, false}, "VADDWODWH": {0xE045 << 15, false}, + "VADDWODVW": {0xE046 << 15, false}, "VADDWODQV": {0xE047 << 15, false}, + "VSUBWODHB": {0xE048 << 15, false}, "VSUBWODWH": {0xE049 << 15, false}, + "VSUBWODVW": {0xE04A << 15, false}, "VSUBWODQV": {0xE04B << 15, false}, + "VSUBWEVHBU": {0xE060 << 15, false}, "VSUBWEVWHU": {0xE061 << 15, false}, + "VSUBWEVVWU": {0xE062 << 15, false}, "VSUBWEVQVU": {0xE063 << 15, false}, + "VADDWEVHBU": {0xE05C << 15, false}, "VADDWEVWHU": {0xE05D << 15, false}, + "VADDWEVVWU": {0xE05E << 15, false}, "VADDWEVQVU": {0xE05F << 15, false}, + "VADDWODHBU": {0xE064 << 15, false}, "VADDWODWHU": {0xE065 << 15, false}, + "VADDWODVWU": {0xE066 << 15, false}, "VADDWODQVU": {0xE067 << 15, false}, + "VSUBWODHBU": {0xE068 << 15, false}, "VSUBWODWHU": {0xE069 << 15, false}, + "VSUBWODVWU": {0xE06A << 15, false}, "VSUBWODQVU": {0xE06B << 15, false}, + "VSHUFH": {0xE2F5 << 15, false}, "VSHUFW": {0xE2F6 << 15, false}, + "VSHUFV": {0xE2F7 << 15, false}, + "XVSLLB": {0xE9D0 << 15, true}, "XVSLLH": {0xE9D1 << 15, true}, + "XVSLLW": {0xE9D2 << 15, true}, "XVSLLV": {0xE9D3 << 15, true}, + "XVSRLB": {0xE9D4 << 15, true}, "XVSRLH": {0xE9D5 << 15, true}, + "XVSRLW": {0xE9D6 << 15, true}, "XVSRLV": {0xE9D7 << 15, true}, + "XVSRAB": {0xE9D8 << 15, true}, "XVSRAH": {0xE9D9 << 15, true}, + "XVSRAW": {0xE9DA << 15, true}, "XVSRAV": {0xE9DB << 15, true}, + "XVROTRB": {0xE9DC << 15, true}, "XVROTRH": {0xE9DD << 15, true}, + "XVROTRW": {0xE9DE << 15, true}, "XVROTRV": {0xE9DF << 15, true}, + "XVILVLB": {0xEA34 << 15, true}, "XVILVLH": {0xEA35 << 15, true}, + "XVILVLW": {0xEA36 << 15, true}, "XVILVLV": {0xEA37 << 15, true}, + "XVILVHB": {0xEA38 << 15, true}, "XVILVHH": {0xEA39 << 15, true}, + "XVILVHW": {0xEA3A << 15, true}, "XVILVHV": {0xEA3B << 15, true}, + "XVBITCLRB": {0xEA18 << 15, true}, "XVBITCLRH": {0xEA19 << 15, true}, + "XVBITCLRW": {0xEA1A << 15, true}, "XVBITCLRV": {0xEA1B << 15, true}, + "XVBITSETB": {0xEA1C << 15, true}, "XVBITSETH": {0xEA1D << 15, true}, + "XVBITSETW": {0xEA1E << 15, true}, "XVBITSETV": {0xEA1F << 15, true}, + "XVBITREVB": {0xEA20 << 15, true}, "XVBITREVH": {0xEA21 << 15, true}, + "XVBITREVW": {0xEA22 << 15, true}, "XVBITREVV": {0xEA23 << 15, true}, + "XVORV": {0xEA4D << 15, true}, "XVNORV": {0xEA4F << 15, true}, + "XVANDNV": {0xEA50 << 15, true}, "XVORNV": {0xEA51 << 15, true}, + "XVSEQH": {0xE801 << 15, true}, "XVSEQW": {0xE802 << 15, true}, + "XVSLTB": {0xE80C << 15, true}, "XVSLTH": {0xE80D << 15, true}, + "XVSLTW": {0xE80E << 15, true}, "XVSLTV": {0xE80F << 15, true}, + "XVSLTBU": {0xE810 << 15, true}, "XVSLTHU": {0xE811 << 15, true}, + "XVSLTWU": {0xE812 << 15, true}, "XVSLTVU": {0xE813 << 15, true}, + "XVADDWEVHB": {0xE83C << 15, true}, "XVADDWEVWH": {0xE83D << 15, true}, + "XVADDWEVVW": {0xE83E << 15, true}, "XVADDWEVQV": {0xE83F << 15, true}, + "XVSUBWEVHB": {0xE840 << 15, true}, "XVSUBWEVWH": {0xE841 << 15, true}, + "XVSUBWEVVW": {0xE842 << 15, true}, "XVSUBWEVQV": {0xE843 << 15, true}, + "XVADDWODHB": {0xE844 << 15, true}, "XVADDWODWH": {0xE845 << 15, true}, + "XVADDWODVW": {0xE846 << 15, true}, "XVADDWODQV": {0xE847 << 15, true}, + "XVSUBWODHB": {0xE848 << 15, true}, "XVSUBWODWH": {0xE849 << 15, true}, + "XVSUBWODVW": {0xE84A << 15, true}, "XVSUBWODQV": {0xE84B << 15, true}, + "XVADDWEVHBU": {0xE85C << 15, true}, "XVADDWEVWHU": {0xE85D << 15, true}, + "XVADDWEVVWU": {0xE85E << 15, true}, "XVADDWEVQVU": {0xE85F << 15, true}, + "XVSUBWEVHBU": {0xE860 << 15, true}, "XVSUBWEVWHU": {0xE861 << 15, true}, + "XVSUBWEVVWU": {0xE862 << 15, true}, "XVSUBWEVQVU": {0xE863 << 15, true}, + "XVADDWODHBU": {0xE864 << 15, true}, "XVADDWODWHU": {0xE865 << 15, true}, + "XVADDWODVWU": {0xE866 << 15, true}, "XVADDWODQVU": {0xE867 << 15, true}, + "XVSUBWODHBU": {0xE868 << 15, true}, "XVSUBWODWHU": {0xE869 << 15, true}, + "XVSUBWODVWU": {0xE86A << 15, true}, "XVSUBWODQVU": {0xE86B << 15, true}, + "XVSHUFH": {0xEAF5 << 15, true}, "XVSHUFW": {0xEAF6 << 15, true}, + "XVSHUFV": {0xEAF7 << 15, true}, + } + for _, tab := range []map[string]l64Vec3Enc{addsub, muldiv, vecmisc} { + for m, e := range tab { + if _, dup := vec3[m]; dup { + panic("loong64: duplicate vector mnemonic " + m) + } + vec3[m] = e + } + } for m, e := range vec3 { l64InstrTable[m] = l64Enc{format: l64Fvvv, op: e.op} l64VecBank[m] = e.lasx @@ -597,21 +850,156 @@ func init() { // Immediate forms: INSTR $imm, vj, vd (or INSTR $imm, vd). The immediate // range, bias and field mask are the ones the toolchain encodes: vandi.b - // stores the raw 8-bit constant, vsrai.b stores imm+8 (byte-lane bias), - // vseqi.b and vseqi.d store 5-bit and 7-bit two's-complement values. - // The mnemonics that also have a register form (VSEQB, VSEQV, VSRAB, - // VROTRW) keep their three-register entry in l64InstrTable; the - // dispatcher picks the immediate opcode from l64VecImmInfo by operand - // kind, so the immediate entries must not overwrite the table. + // stores the raw 8-bit constant, vsrari.b stores imm+8 (lane-width + // bias), the si5 compares store 5-bit two's-complement values and vseqi.d + // a 7-bit field the toolchain range-checks down to si5. + // The mnemonics that also have a register form (the shifts, the bit + // clear/set/rev families, VSEQ and the logic immediates) keep their + // three-register entry in l64InstrTable; the dispatcher picks the + // immediate opcode from l64VecImmInfo by operand kind, so the immediate + // entries must not overwrite the table. vecImm := map[string]l64VecImmEnc{ "VANDB": {0xE7A0 << 15, false, 0, 255, 0, 0xFF}, "XVANDB": {0xEFA0 << 15, true, 0, 255, 0, 0xFF}, + "VORB": {0xE7A8 << 15, false, 0, 255, 0, 0xFF}, + "XVORB": {0xEFA8 << 15, true, 0, 255, 0, 0xFF}, + "VXORB": {0xE7B0 << 15, false, 0, 255, 0, 0xFF}, + "XVXORB": {0xEFB0 << 15, true, 0, 255, 0, 0xFF}, + "VNORB": {0xE7B8 << 15, false, 0, 255, 0, 0xFF}, + "XVNORB": {0xEFB8 << 15, true, 0, 255, 0, 0xFF}, "VSEQB": {0xE500 << 15, false, -16, 15, 0, 0x1F}, "XVSEQB": {0xE900 << 15, true, -16, 15, 0, 0x1F}, - "VSEQV": {0xE503 << 15, false, -64, 63, 0, 0x7F}, - "XVSEQV": {0xE903 << 15, true, -64, 63, 0, 0x7F}, - "VSRAB": {0xE668 << 15, false, 0, 7, 8, 0x1F}, - "VROTRW": {0xE541 << 15, false, 0, 31, 0, 0x1F}, + // vseqi.h/w accept the same si5 window as vseqi.b; vseqi.d carries a + // 7-bit field, but the toolchain range-checks it down to si5 as well + // (GOARCH=loong64 go tool asm rejects VSEQV $32 and VSEQV $-64). + "VSEQH": {0xE501 << 15, false, -16, 15, 0, 0x1F}, + "XVSEQH": {0xED01 << 15, true, -16, 15, 0, 0x1F}, + "VSEQW": {0xE502 << 15, false, -16, 15, 0, 0x1F}, + "XVSEQW": {0xED02 << 15, true, -16, 15, 0, 0x1F}, + "VSEQV": {0xE503 << 15, false, -16, 15, 0, 0x7F}, + "XVSEQV": {0xE903 << 15, true, -16, 15, 0, 0x7F}, + // vslti compares against a signed (or, in the U spellings, unsigned) + // si5/ui5 constant. + "VSLTB": {0xE50C << 15, false, -16, 15, 0, 0x1F}, + "XVSLTB": {0xED0C << 15, true, -16, 15, 0, 0x1F}, + "VSLTH": {0xE50D << 15, false, -16, 15, 0, 0x1F}, + "XVSLTH": {0xED0D << 15, true, -16, 15, 0, 0x1F}, + "VSLTW": {0xE50E << 15, false, -16, 15, 0, 0x1F}, + "XVSLTW": {0xED0E << 15, true, -16, 15, 0, 0x1F}, + "VSLTV": {0xE50F << 15, false, -16, 15, 0, 0x1F}, + "XVSLTV": {0xED0F << 15, true, -16, 15, 0, 0x1F}, + "VSLTBU": {0xE510 << 15, false, 0, 31, 0, 0x1F}, + "XVSLTBU": {0xED10 << 15, true, 0, 31, 0, 0x1F}, + "VSLTHU": {0xE511 << 15, false, 0, 31, 0, 0x1F}, + "XVSLTHU": {0xED11 << 15, true, 0, 31, 0, 0x1F}, + "VSLTWU": {0xE512 << 15, false, 0, 31, 0, 0x1F}, + "XVSLTWU": {0xED12 << 15, true, 0, 31, 0, 0x1F}, + "VSLTVU": {0xE513 << 15, false, 0, 31, 0, 0x1F}, + "XVSLTVU": {0xED13 << 15, true, 0, 31, 0, 0x1F}, + // vaddi/vsubi take ui5 constants for every width on this toolchain + // (VADDVU $32 is rejected by the oracle although the field is ui8). + "VADDBU": {0xE514 << 15, false, 0, 31, 0, 0x1F}, + "XVADDBU": {0xED14 << 15, true, 0, 31, 0, 0x1F}, + "VADDHU": {0xE515 << 15, false, 0, 31, 0, 0x1F}, + "XVADDHU": {0xED15 << 15, true, 0, 31, 0, 0x1F}, + "VADDWU": {0xE516 << 15, false, 0, 31, 0, 0x1F}, + "XVADDWU": {0xED16 << 15, true, 0, 31, 0, 0x1F}, + "VADDVU": {0xE517 << 15, false, 0, 31, 0, 0x1F}, + "XVADDVU": {0xED17 << 15, true, 0, 31, 0, 0x1F}, + "VSUBBU": {0xE518 << 15, false, 0, 31, 0, 0x1F}, + "XVSUBBU": {0xED18 << 15, true, 0, 31, 0, 0x1F}, + "VSUBHU": {0xE519 << 15, false, 0, 31, 0, 0x1F}, + "XVSUBHU": {0xED19 << 15, true, 0, 31, 0, 0x1F}, + "VSUBWU": {0xE51A << 15, false, 0, 31, 0, 0x1F}, + "XVSUBWU": {0xED1A << 15, true, 0, 31, 0, 0x1F}, + "VSUBVU": {0xE51B << 15, false, 0, 31, 0, 0x1F}, + "XVSUBVU": {0xED1B << 15, true, 0, 31, 0, 0x1F}, + // The shift/rotate immediates ride in a width-sized field whose upper + // bits carry the lane-width code: vslli.b stores ui3 at [12:0] with + // bits [14:13] inside the opcode, vslli.h ui4 under a 4 bit mask, and + // the .w/.d spellings a raw ui5/ui6. + "VSLLB": {0x732C2000, false, 0, 7, 0, 0x7}, + "XVSLLB": {0x772C2000, true, 0, 7, 0, 0x7}, + "VSLLH": {0x732C4000, false, 0, 15, 0, 0xF}, + "XVSLLH": {0x772C4000, true, 0, 15, 0, 0xF}, + "VSLLW": {0xE659 << 15, false, 0, 31, 0, 0x1F}, + "XVSLLW": {0xEE59 << 15, true, 0, 31, 0, 0x1F}, + "VSLLV": {0xE65A << 15, false, 0, 63, 0, 0x3F}, + "XVSLLV": {0xEE5A << 15, true, 0, 63, 0, 0x3F}, + "VSRLB": {0x73302000, false, 0, 7, 0, 0x7}, + "XVSRLB": {0x77302000, true, 0, 7, 0, 0x7}, + "VSRLH": {0x73304000, false, 0, 15, 0, 0xF}, + "XVSRLH": {0x77304000, true, 0, 15, 0, 0xF}, + "VSRLW": {0xE661 << 15, false, 0, 31, 0, 0x1F}, + "XVSRLW": {0xEE61 << 15, true, 0, 31, 0, 0x1F}, + "VSRLV": {0xE662 << 15, false, 0, 63, 0, 0x3F}, + "XVSRLV": {0xEE62 << 15, true, 0, 63, 0, 0x3F}, + // vsrari/vrotri bias the field so the lane-width code rides above the + // shift amount (.b adds 8, .h 16, .w 32; .d is a raw ui6). + "VSRAB": {0xE668 << 15, false, 0, 7, 8, 0x1F}, + "XVSRAB": {0xEE68 << 15, true, 0, 7, 8, 0x1F}, + "VSRAH": {0x73344000, false, 0, 15, 0, 0xF}, + "XVSRAH": {0x77344000, true, 0, 15, 0, 0xF}, + "VSRAW": {0xE669 << 15, false, 0, 31, 0, 0x1F}, + "XVSRAW": {0xEE69 << 15, true, 0, 31, 0, 0x1F}, + "VSRAV": {0xE66A << 15, false, 0, 63, 0, 0x3F}, + "XVSRAV": {0xEE6A << 15, true, 0, 63, 0, 0x3F}, + "VROTRB": {0x72A02000, false, 0, 7, 0, 0x7}, + "XVROTRB": {0x76A02000, true, 0, 7, 0, 0x7}, + "VROTRH": {0x72A04000, false, 0, 15, 0, 0xF}, + "XVROTRH": {0x76A04000, true, 0, 15, 0, 0xF}, + "VROTRW": {0xE541 << 15, false, 0, 31, 0, 0x1F}, + "XVROTRW": {0xED41 << 15, true, 0, 31, 0, 0x1F}, + "VROTRV": {0xE542 << 15, false, 0, 63, 0, 0x3F}, + "XVROTRV": {0xED42 << 15, true, 0, 63, 0, 0x3F}, + // vbitclri/vbitseti/vbitrevi follow the same width-coded layout. + "VBITCLRB": {0x73102000, false, 0, 7, 0, 0x7}, + "XVBITCLRB": {0x77102000, true, 0, 7, 0, 0x7}, + "VBITCLRH": {0x73104000, false, 0, 15, 0, 0xF}, + "XVBITCLRH": {0x77104000, true, 0, 15, 0, 0xF}, + "VBITCLRW": {0xE621 << 15, false, 0, 31, 0, 0x1F}, + "XVBITCLRW": {0xEE21 << 15, true, 0, 31, 0, 0x1F}, + "VBITCLRV": {0xE622 << 15, false, 0, 63, 0, 0x3F}, + "XVBITCLRV": {0xEE22 << 15, true, 0, 63, 0, 0x3F}, + "VBITSETB": {0x73142000, false, 0, 7, 0, 0x7}, + "XVBITSETB": {0x77142000, true, 0, 7, 0, 0x7}, + "VBITSETH": {0x73144000, false, 0, 15, 0, 0xF}, + "XVBITSETH": {0x77144000, true, 0, 15, 0, 0xF}, + "VBITSETW": {0xE629 << 15, false, 0, 31, 0, 0x1F}, + "XVBITSETW": {0xEE29 << 15, true, 0, 31, 0, 0x1F}, + "VBITSETV": {0xE62A << 15, false, 0, 63, 0, 0x3F}, + "XVBITSETV": {0xEE2A << 15, true, 0, 63, 0, 0x3F}, + "VBITREVB": {0x73182000, false, 0, 7, 0, 0x7}, + "XVBITREVB": {0x77182000, true, 0, 7, 0, 0x7}, + "VBITREVH": {0x73184000, false, 0, 15, 0, 0xF}, + "XVBITREVH": {0x77184000, true, 0, 15, 0, 0xF}, + "VBITREVW": {0xE631 << 15, false, 0, 31, 0, 0x1F}, + "XVBITREVW": {0xEE31 << 15, true, 0, 31, 0, 0x1F}, + "VBITREVV": {0xE632 << 15, false, 0, 63, 0, 0x3F}, + "XVBITREVV": {0xEE32 << 15, true, 0, 63, 0, 0x3F}, + // The 4-bit-select shuffles and the byte-extract/insert permutations + // take ui8 (the .d shuffle ui4 range-checked to 0..15 by the + // toolchain) packing both position nibbles. + "VSHUF4IB": {0xE720 << 15, false, 0, 255, 0, 0xFF}, + "XVSHUF4IB": {0xEF20 << 15, true, 0, 255, 0, 0xFF}, + "VSHUF4IH": {0xE728 << 15, false, 0, 255, 0, 0xFF}, + "XVSHUF4IH": {0xEF28 << 15, true, 0, 255, 0, 0xFF}, + "VSHUF4IW": {0xE730 << 15, false, 0, 255, 0, 0xFF}, + "XVSHUF4IW": {0xEF30 << 15, true, 0, 255, 0, 0xFF}, + "VSHUF4IV": {0xE738 << 15, false, 0, 15, 0, 0xFF}, + "XVSHUF4IV": {0xEF38 << 15, true, 0, 15, 0, 0xFF}, + "VPERMIW": {0xE7C8 << 15, false, 0, 255, 0, 0xFF}, + "XVPERMIW": {0xEFC8 << 15, true, 0, 255, 0, 0xFF}, + "XVPERMIV": {0xEFD0 << 15, true, 0, 255, 0, 0xFF}, + "XVPERMIQ": {0xEFD8 << 15, true, 0, 255, 0, 0xFF}, + "VEXTRINSB": {0xE718 << 15, false, 0, 255, 0, 0xFF}, + "XVEXTRINSB": {0xEF18 << 15, true, 0, 255, 0, 0xFF}, + "VEXTRINSH": {0xE710 << 15, false, 0, 255, 0, 0xFF}, + "XVEXTRINSH": {0xEF10 << 15, true, 0, 255, 0, 0xFF}, + "VEXTRINSW": {0xE708 << 15, false, 0, 255, 0, 0xFF}, + "XVEXTRINSW": {0xEF08 << 15, true, 0, 255, 0, 0xFF}, + "VEXTRINSV": {0xE700 << 15, false, 0, 255, 0, 0xFF}, + "XVEXTRINSV": {0xEF00 << 15, true, 0, 255, 0, 0xFF}, } for m, e := range vecImm { l64VecImmInfo[m] = e @@ -625,22 +1013,71 @@ func init() { "VSETANYEQB": 0xE539<<15 | 8<<10, "XVSETANYEQB": 0xED39<<15 | 8<<10, "VSETANYEQV": 0xE539<<15 | 11<<10, "XVSETANYEQV": 0xED39<<15 | 11<<10, "VSETALLNEV": 0xE539<<15 | 15<<10, "XVSETALLNEV": 0xED39<<15 | 15<<10, + "VSETEQV": 0xE539<<15 | 6<<10, "XVSETEQV": 0xED39<<15 | 6<<10, + "VSETANYEQH": 0xE539<<15 | 9<<10, "XVSETANYEQH": 0xED39<<15 | 9<<10, + "VSETANYEQW": 0xE539<<15 | 10<<10, "XVSETANYEQW": 0xED39<<15 | 10<<10, + "VSETALLNEB": 0xE539<<15 | 12<<10, "XVSETALLNEB": 0xED39<<15 | 12<<10, + "VSETALLNEH": 0xE539<<15 | 13<<10, "XVSETALLNEH": 0xED39<<15 | 13<<10, + "VSETALLNEW": 0xE539<<15 | 14<<10, "XVSETALLNEW": 0xED39<<15 | 14<<10, } for m, op := range vecCf { l64InstrTable[m] = l64Enc{format: l64Fvcf, op: op} l64VecBank[m] = strings.HasPrefix(m, "XV") } - // Lane popcount: INSTR vj, vd (the 2R layout with the opcode extending - // over the unused vk field). + // Lane popcount and the two-operand vector FP/unary spellings: INSTR vj, + // vd (the 2R layout with the opcode extending over the unused vk field; + // the low byte of each constant is the instruction's own sub-op). vec2r := map[string]l64Vec3Enc{ "VPCNTV": {0x1CA70B << 10, false}, "XVPCNTV": {0x1DA70B << 10, true}, } + // The rest of the lane popcounts, the vector negations and the vector FP + // unary conversions (loong64enc1.s). + vec2rMore := map[string]l64Vec3Enc{ + "VPCNTB": {0x1CA708 << 10, false}, "VPCNTH": {0x1CA709 << 10, false}, + "VPCNTW": {0x1CA70A << 10, false}, + "VNEGB": {0x1CA70C << 10, false}, "VNEGH": {0x1CA70D << 10, false}, + "VNEGW": {0x1CA70E << 10, false}, "VNEGV": {0x1CA70F << 10, false}, + "VFCLASSF": {0x1CA735 << 10, false}, "VFCLASSD": {0x1CA736 << 10, false}, + "VFSQRTF": {0x1CA739 << 10, false}, "VFSQRTD": {0x1CA73A << 10, false}, + "VFRECIPF": {0x1CA73D << 10, false}, "VFRECIPD": {0x1CA73E << 10, false}, + "VFRSQRTF": {0x1CA741 << 10, false}, "VFRSQRTD": {0x1CA742 << 10, false}, + "VFRINTF": {0x1CA74D << 10, false}, "VFRINTD": {0x1CA74E << 10, false}, + "VFRINTRMF": {0x1CA751 << 10, false}, "VFRINTRMD": {0x1CA752 << 10, false}, + "VFRINTRPF": {0x1CA755 << 10, false}, "VFRINTRPD": {0x1CA756 << 10, false}, + "VFRINTRZF": {0x1CA759 << 10, false}, "VFRINTRZD": {0x1CA75A << 10, false}, + "VFRINTRNEF": {0x1CA75D << 10, false}, "VFRINTRNED": {0x1CA75E << 10, false}, + "XVPCNTB": {0x1DA708 << 10, true}, "XVPCNTH": {0x1DA709 << 10, true}, + "XVPCNTW": {0x1DA70A << 10, true}, + "XVNEGB": {0x1DA70C << 10, true}, "XVNEGH": {0x1DA70D << 10, true}, + "XVNEGW": {0x1DA70E << 10, true}, "XVNEGV": {0x1DA70F << 10, true}, + "XVFCLASSF": {0x1DA735 << 10, true}, "XVFCLASSD": {0x1DA736 << 10, true}, + "XVFSQRTF": {0x1DA739 << 10, true}, "XVFSQRTD": {0x1DA73A << 10, true}, + "XVFRECIPF": {0x1DA73D << 10, true}, "XVFRECIPD": {0x1DA73E << 10, true}, + "XVFRSQRTF": {0x1DA741 << 10, true}, "XVFRSQRTD": {0x1DA742 << 10, true}, + "XVFRINTF": {0x1DA74D << 10, true}, "XVFRINTD": {0x1DA74E << 10, true}, + "XVFRINTRMF": {0x1DA751 << 10, true}, "XVFRINTRMD": {0x1DA752 << 10, true}, + "XVFRINTRPF": {0x1DA755 << 10, true}, "XVFRINTRPD": {0x1DA756 << 10, true}, + "XVFRINTRZF": {0x1DA759 << 10, true}, "XVFRINTRZD": {0x1DA75A << 10, true}, + "XVFRINTRNEF": {0x1DA75D << 10, true}, "XVFRINTRNED": {0x1DA75E << 10, true}, + } + maps.Copy(vec2r, vec2rMore) for m, e := range vec2r { l64InstrTable[m] = l64Enc{format: l64Frr, op: e.op} l64VecBank[m] = e.lasx l64Vec2R[m] = true } + + // The four-register byte shuffle: INSTR va, vk, vj, vd (the operand the + // table reads in each field position, va at bits [19:15]). + vec4r := map[string]l64Vec3Enc{ + "VSHUFB": {0x0D50 << 16, false}, "XVSHUFB": {0x0D60 << 16, true}, + } + for m, e := range vec4r { + l64InstrTable[m] = l64Enc{format: l64Fvvvv, op: e.op} + l64VecBank[m] = e.lasx + l64Vec4R[m] = true + } } // l64FpMovTable maps (mnemonic, from-class, to-class) to the 2R opcode of the diff --git a/asm/loong64_encode_test.go b/asm/loong64_encode_test.go index 85d5817..19a7a09 100644 --- a/asm/loong64_encode_test.go +++ b/asm/loong64_encode_test.go @@ -507,6 +507,218 @@ TEXT ·v(SB), NOSPLIT, $0 0x4C000020, ) }) + + // The integer and FP add/subtract families with their saturating pairs + // and immediate spellings (loong64enc1.s words). + t.Run("add and subtract families", func(t *testing.T) { + fn := firstTextLOONG64(t, `#include "textflag.h" +TEXT ·v(SB), NOSPLIT, $0 + VADDB V1, V2, V3 + VADDF V1, V2, V3 + VADDD V1, V2, V3 + VSUBD V1, V2, V3 + VSADDV V1, V2, V3 + VSSUBVU V1, V2, V3 + VADDBU $1, V2, V1 + VADDBU $1, V2 + VSUBVU $31, V2 + XVSADDV X3, X2, X1 + XVSUBD X1, X2, X3 + RET +`) + code := assembleLOONG64Helper(t, fn) + wantWords(t, code, + 0x700A0443, // vadd.b + 0x71308443, // vadd.f + 0x71310443, // vadd.d + 0x71330443, // vsub.d + 0x70478443, // vsadd.v + 0x704D8443, // vssub.u.d + 0x728A0441, // vaddi.bu v1, v2, 1 + 0x728A0442, // vaddi.bu v2, v2, 1 (two-operand form) + 0x728DFC42, // vsubi.du v2, v2, 31 (two-operand form) + 0x74478C41, // xvsadd.d x1, x2, x3 + 0x75330443, // xvsub.d x3, x2, x1 + 0x4C000020, + ) + }) + + // The multiply, divide and accumulate families. + t.Run("multiply and divide families", func(t *testing.T) { + fn := firstTextLOONG64(t, `#include "textflag.h" +TEXT ·v(SB), NOSPLIT, $0 + VMULV V1, V2, V3 + VMUHHU V1, V2, V3 + VDIVBU V1, V2, V3 + VMODV V1, V2, V3 + VMADDB V1, V2, V3 + VMSUBV V1, V2, V3 + VMULWEVHB V1, V2, V3 + VMULWODQV V1, V2, V3 + VMADDWEVHBUB V1, V2, V3 + XVDIVD X1, X2, X3 + RET +`) + code := assembleLOONG64Helper(t, fn) + wantWords(t, code, + 0x70858443, // vmul.v + 0x70888443, // vmuh.u.d + 0x70E40443, // vdiv.u.b + 0x70E38443, // vmod.d + 0x70A80443, // vmadd.b + 0x70AB8443, // vmsub.d + 0x70900443, // vmulwev.h.b + 0x70938443, // vmulwod.q.d + 0x70BC0443, // vmaddwev.h.bu.b + 0x753B0443, // xvdiv.d + 0x4C000020, + ) + }) + + // The shift, bit and interleave families in register and immediate + // spellings, with the width-coded shift immediates. + t.Run("shift, bit and interleave families", func(t *testing.T) { + fn := firstTextLOONG64(t, `#include "textflag.h" +TEXT ·v(SB), NOSPLIT, $0 + VSLLV V1, V2, V3 + VROTRB V1, V2, V3 + VBITCLRV V1, V2, V3 + VBITSETW V1, V2, V3 + VBITREVV V1, V2, V3 + VILVLB V1, V2, V3 + VILVHV V1, V2, V3 + VSLLB $7, V1, V2 + VSLLB $5, V1 + VSRLH $15, V1, V2 + VSRAW $31, V1, V2 + VSRAV $63, V1, V2 + VROTRV $63, V1, V2 + VBITCLRB $7, V2, V3 + VBITREVV $63, V2, V3 + VSEQH $-16, V2, V3 + VSLTB $1, V2, V3 + VSLTHU $31, V2, V3 + XVILVLV X3, X2, X1 + XVSLLB $7, X2, X1 + XVSRAV $63, X2, X1 + XVBITREVV $63, X2, X1 + RET +`) + code := assembleLOONG64Helper(t, fn) + wantWords(t, code, + 0x70E98443, // vsll.d + 0x70EE0443, // vrotr.b + 0x710D8443, // vbitclr.d + 0x710F0443, // vbitset.w + 0x71118443, // vbitrev.d + 0x711A0443, // vilvl.b + 0x711D8443, // vilvh.d + 0x732C3C22, // vslli.b v2, v1, 7 + 0x732C3421, // vslli.b v1, v1, 5 (two-operand form) + 0x73307C22, // vsrli.h v2, v1, 15 + 0x7334FC22, // vsrai.w v2, v1, 31 + 0x7335FC22, // vsrai.d v2, v1, 63 + 0x72A1FC22, // vrotri.d v2, v1, 63 + 0x73103C43, // vbitclri.b v3, v2, 7 + 0x7319FC43, // vbitrevi.d v3, v2, 63 + 0x7280C043, // vseqi.h v3, v2, -16 + 0x72860443, // vslti.b v3, v2, 1 + 0x7288FC43, // vslti.hu v3, v2, 31 + 0x751B8C41, // xvilvl.d x1, x2, x3 + 0x772C3C41, // xvslli.b x1, x2, 7 + 0x7735FC41, // xvsrai.d x1, x2, 63 + 0x7719FC41, // xvbitrevi.d x1, x2, 63 + 0x4C000020, + ) + }) + + // The shuffle, select and permutation families, including the + // four-register byte shuffle. + t.Run("shuffle and permutation families", func(t *testing.T) { + fn := firstTextLOONG64(t, `#include "textflag.h" +TEXT ·v(SB), NOSPLIT, $0 + VSHUFH V1, V2, V3 + VSHUFW V1, V2, V3 + VSHUFV V1, V2, V3 + VSHUFB V1, V2, V3, V4 + XVSHUFB X1, X2, X3, X4 + VSHUF4IB $255, V2, V1 + VSHUF4IV $15, V2, V1 + XVSHUF4IV $15, X1, X2 + VEXTRINSB $0x18, V1, V2 + XVEXTRINSV $0x81, X1, X2 + VPERMIW $0x1B, V1, V2 + XVPERMIQ $0x4B, X1, X2 + RET +`) + code := assembleLOONG64Helper(t, fn) + wantWords(t, code, + 0x717A8443, // vshuf.h + 0x717B0443, // vshuf.w + 0x717B8443, // vshuf.d + 0x0D508864, // vshuf.b v4, v3, v2, v1 + 0x0D608864, // xvshuf.b + 0x7393FC41, // vshuf4i.b v1, v2, 255 + 0x739C3C41, // vshuf4i.d v1, v2, 15 + 0x779C3C22, // xvshuf4i.d x2, x1, 15 + 0x738C6022, // vextrins.b v2, v1, 0x18 + 0x77820422, // xvextrins.d x2, x1, 0x81 + 0x73E46C22, // vpermi.w v2, v1, 0x1b + 0x77ED2C22, // xvpermi.q x2, x1, 0x4b + 0x4C000020, + ) + }) + + // The vector FP families, the unary spellings, the compare-to-flag + // additions and the scalar int/float conversions. + t.Run("FP and conversion families", func(t *testing.T) { + fn := firstTextLOONG64(t, `#include "textflag.h" +TEXT ·v(SB), NOSPLIT, $0 + VADDF V1, V2, V3 + VMULF V1, V2, V3 + VFCLASSD V1, V2 + VFSQRTF V1, V2 + VFRECIPD V1, V2 + VFRSQRTF V1, V2 + VFRINTF V1, V2 + VFRINTRNED V1, V2 + VNEGB V1, V2 + VPCNTB V1, V2 + XVNEGV X2, X1 + XVPCNTW X3, X2 + XVFRINTRNEF X1, X2 + VSETEQV V1, FCC0 + VSETANYEQH V1, FCC0 + VSETALLNEB V1, FCC0 + XVSETALLNEW X1, FCC0 + FFINTFW F0, F1 + FTINTVD F0, F1 + RET +`) + code := assembleLOONG64Helper(t, fn) + wantWords(t, code, + 0x71308443, // vfadd.s + 0x71388443, // vfmul.s + 0x729CD822, // vfclass.d + 0x729CE422, // vfsqrt.s + 0x729CF822, // vfrecip.d + 0x729D0422, // vfrsqrt.s + 0x729D3422, // vfrint.s + 0x729D7822, // vfrintne.s + 0x729C3022, // vneg.b + 0x729C2022, // vpcnt.b + 0x769C3C41, // xvneg.d x1, x2 + 0x769C2862, // xvpcnt.w x2, x3 + 0x769D7422, // xvfrintne.s x2, x1 + 0x729C9820, // vseteqz.d fcc0, v1 + 0x729CA420, // vsetanyeqz.h + 0x729CB020, // vsetallnez.b + 0x769CB820, // xvsetallnez.w + 0x011D1001, // ffint.s.w f1, f0 + 0x011B2801, // ftint.l.d f1, f0 + 0x4C000020, + ) + }) } // TestLOONG64_vectorErrors pins the register-class and range diagnostics of @@ -545,6 +757,36 @@ func TestLOONG64_vectorErrors(t *testing.T) { `TEXT ·e(SB), NOSPLIT, $0 VROTRW $32, V1, V2 RET +`, + `TEXT ·e(SB), NOSPLIT, $0 + VADDVU $32, V2 + RET +`, + `TEXT ·e(SB), NOSPLIT, $0 + VSEQV $32, V2, V3 + RET +`, + `TEXT ·e(SB), NOSPLIT, $0 + VSHUF4IV $16, V2, V1 + RET +`, + `TEXT ·e(SB), NOSPLIT, $0 + VEXTRINSB $256, V1, V2 + RET +`, + `TEXT ·e(SB), NOSPLIT, $0 + VSLTV $-17, V2, V3 + RET +`, + // VSHUFB wants four vector registers. + `TEXT ·e(SB), NOSPLIT, $0 + VSHUFB V1, V2, V3 + RET +`, + // The FCC forms still refuse vector registers. + `TEXT ·e(SB), NOSPLIT, $0 + VSETEQV V1, V2 + RET `, // VSET* wants an FCC flag, not a vector register. `TEXT ·e(SB), NOSPLIT, $0 diff --git a/testdata/verify/amdb_loong64.s b/testdata/verify/amdb_loong64.s new file mode 100644 index 0000000..771517c --- /dev/null +++ b/testdata/verify/amdb_loong64.s @@ -0,0 +1,44 @@ +// Differential kernel: the _dbar (acquire/release) atomic exchange +// variants against the Go toolchain's loong64enc1.s rows. + +#include "textflag.h" + +TEXT ·AMXORDBW(SB), NOSPLIT, $0 + AMXORDBW R14, (R13), R12 + RET + +TEXT ·AMXORDBV(SB), NOSPLIT, $0 + AMXORDBV R14, (R13), R12 + RET + +TEXT ·AMMAXDBW(SB), NOSPLIT, $0 + AMMAXDBW R14, (R13), R12 + RET + +TEXT ·AMMAXDBV(SB), NOSPLIT, $0 + AMMAXDBV R14, (R13), R12 + RET + +TEXT ·AMMINDBW(SB), NOSPLIT, $0 + AMMINDBW R14, (R13), R12 + RET + +TEXT ·AMMINDBV(SB), NOSPLIT, $0 + AMMINDBV R14, (R13), R12 + RET + +TEXT ·AMMAXDBWU(SB), NOSPLIT, $0 + AMMAXDBWU R14, (R13), R12 + RET + +TEXT ·AMMAXDBVU(SB), NOSPLIT, $0 + AMMAXDBVU R14, (R13), R12 + RET + +TEXT ·AMMINDBWU(SB), NOSPLIT, $0 + AMMINDBWU R14, (R13), R12 + RET + +TEXT ·AMMINDBVU(SB), NOSPLIT, $0 + AMMINDBVU R14, (R13), R12 + RET diff --git a/testdata/verify/pseudos_loong64.s b/testdata/verify/pseudos_loong64.s new file mode 100644 index 0000000..b495cbd --- /dev/null +++ b/testdata/verify/pseudos_loong64.s @@ -0,0 +1,31 @@ +// Differential kernel: the bookkeeping statements the assembler accepts and +// encodes to nothing (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·end(SB), NOSPLIT, $0 + END + RET + +TEXT ·funcdata(SB), NOSPLIT, $0 + FUNCDATA $0, ref(SB) + RET + +TEXT ·pcdata(SB), NOSPLIT, $0 + PCDATA $0, $1 + PCDATA $1, $-2 + RET + +TEXT ·getcallerpc(SB), NOSPLIT, $0 + GETCALLERPC R4 + RET + +TEXT ·mixed(SB), NOSPLIT, $0 + PCDATA $0, $1 + ADDV R4, R5, R6 + FUNCDATA $1, ref(SB) + GETCALLERPC R7 + RET + +ref: + RET diff --git a/testdata/verify/vector_arith_add_loong64.s b/testdata/verify/vector_arith_add_loong64.s new file mode 100644 index 0000000..5afd6d1 --- /dev/null +++ b/testdata/verify/vector_arith_add_loong64.s @@ -0,0 +1,209 @@ +// Differential kernel: the arith_add vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VADDB(SB), NOSPLIT, $0 + VADDB V1, V2, V3 + RET + +TEXT ·VADDH(SB), NOSPLIT, $0 + VADDH V1, V2, V3 + RET + +TEXT ·VADDQ(SB), NOSPLIT, $0 + VADDQ V1, V2, V3 + RET + +TEXT ·XVADDB(SB), NOSPLIT, $0 + XVADDB X3, X2, X1 + RET + +TEXT ·XVADDH(SB), NOSPLIT, $0 + XVADDH X3, X2, X1 + RET + +TEXT ·XVADDW(SB), NOSPLIT, $0 + XVADDW X3, X2, X1 + RET + +TEXT ·XVADDQ(SB), NOSPLIT, $0 + XVADDQ X3, X2, X1 + RET + +TEXT ·VADDBU(SB), NOSPLIT, $0 + VADDBU $1, V2 + VADDBU $1, V2, V1 + RET + +TEXT ·VADDHU(SB), NOSPLIT, $0 + VADDHU $2, V2, V1 + RET + +TEXT ·VADDWU(SB), NOSPLIT, $0 + VADDWU $3, V2, V1 + RET + +TEXT ·VADDVU(SB), NOSPLIT, $0 + VADDVU $4, V2, V1 + RET + +TEXT ·XVADDBU(SB), NOSPLIT, $0 + XVADDBU $9, X1, X2 + RET + +TEXT ·XVADDHU(SB), NOSPLIT, $0 + XVADDHU $10, X1, X2 + RET + +TEXT ·XVADDWU(SB), NOSPLIT, $0 + XVADDWU $11, X1, X2 + RET + +TEXT ·XVADDVU(SB), NOSPLIT, $0 + XVADDVU $12, X1, X2 + RET + +TEXT ·VADDWEVHB(SB), NOSPLIT, $0 + VADDWEVHB V1, V2, V3 + RET + +TEXT ·VADDWEVWH(SB), NOSPLIT, $0 + VADDWEVWH V1, V2, V3 + RET + +TEXT ·VADDWEVVW(SB), NOSPLIT, $0 + VADDWEVVW V1, V2, V3 + RET + +TEXT ·VADDWEVQV(SB), NOSPLIT, $0 + VADDWEVQV V1, V2, V3 + RET + +TEXT ·VADDWODHB(SB), NOSPLIT, $0 + VADDWODHB V1, V2, V3 + RET + +TEXT ·VADDWODWH(SB), NOSPLIT, $0 + VADDWODWH V1, V2, V3 + RET + +TEXT ·VADDWODVW(SB), NOSPLIT, $0 + VADDWODVW V1, V2, V3 + RET + +TEXT ·VADDWODQV(SB), NOSPLIT, $0 + VADDWODQV V1, V2, V3 + RET + +TEXT ·XVADDWEVHB(SB), NOSPLIT, $0 + XVADDWEVHB X1, X2, X3 + RET + +TEXT ·XVADDWEVWH(SB), NOSPLIT, $0 + XVADDWEVWH X1, X2, X3 + RET + +TEXT ·XVADDWEVVW(SB), NOSPLIT, $0 + XVADDWEVVW X1, X2, X3 + RET + +TEXT ·XVADDWEVQV(SB), NOSPLIT, $0 + XVADDWEVQV X1, X2, X3 + RET + +TEXT ·XVADDWODHB(SB), NOSPLIT, $0 + XVADDWODHB X1, X2, X3 + RET + +TEXT ·XVADDWODWH(SB), NOSPLIT, $0 + XVADDWODWH X1, X2, X3 + RET + +TEXT ·XVADDWODVW(SB), NOSPLIT, $0 + XVADDWODVW X1, X2, X3 + RET + +TEXT ·XVADDWODQV(SB), NOSPLIT, $0 + XVADDWODQV X1, X2, X3 + RET + +TEXT ·VADDWEVHBU(SB), NOSPLIT, $0 + VADDWEVHBU V1, V2, V3 + RET + +TEXT ·VADDWEVWHU(SB), NOSPLIT, $0 + VADDWEVWHU V1, V2, V3 + RET + +TEXT ·VADDWEVVWU(SB), NOSPLIT, $0 + VADDWEVVWU V1, V2, V3 + RET + +TEXT ·VADDWEVQVU(SB), NOSPLIT, $0 + VADDWEVQVU V1, V2, V3 + RET + +TEXT ·VADDWODHBU(SB), NOSPLIT, $0 + VADDWODHBU V1, V2, V3 + RET + +TEXT ·VADDWODWHU(SB), NOSPLIT, $0 + VADDWODWHU V1, V2, V3 + RET + +TEXT ·VADDWODVWU(SB), NOSPLIT, $0 + VADDWODVWU V1, V2, V3 + RET + +TEXT ·VADDWODQVU(SB), NOSPLIT, $0 + VADDWODQVU V1, V2, V3 + RET + +TEXT ·XVADDWEVHBU(SB), NOSPLIT, $0 + XVADDWEVHBU X1, X2, X3 + RET + +TEXT ·XVADDWEVWHU(SB), NOSPLIT, $0 + XVADDWEVWHU X1, X2, X3 + RET + +TEXT ·XVADDWEVVWU(SB), NOSPLIT, $0 + XVADDWEVVWU X1, X2, X3 + RET + +TEXT ·XVADDWEVQVU(SB), NOSPLIT, $0 + XVADDWEVQVU X1, X2, X3 + RET + +TEXT ·XVADDWODHBU(SB), NOSPLIT, $0 + XVADDWODHBU X1, X2, X3 + RET + +TEXT ·XVADDWODWHU(SB), NOSPLIT, $0 + XVADDWODWHU X1, X2, X3 + RET + +TEXT ·XVADDWODVWU(SB), NOSPLIT, $0 + XVADDWODVWU X1, X2, X3 + RET + +TEXT ·XVADDWODQVU(SB), NOSPLIT, $0 + XVADDWODQVU X1, X2, X3 + RET + +TEXT ·VADDF(SB), NOSPLIT, $0 + VADDF V1, V2, V3 + RET + +TEXT ·VADDD(SB), NOSPLIT, $0 + VADDD V1, V2, V3 + RET + +TEXT ·XVADDF(SB), NOSPLIT, $0 + XVADDF X1, X2, X3 + RET + +TEXT ·XVADDD(SB), NOSPLIT, $0 + XVADDD X1, X2, X3 + RET diff --git a/testdata/verify/vector_arith_sat_loong64.s b/testdata/verify/vector_arith_sat_loong64.s new file mode 100644 index 0000000..848cb2d --- /dev/null +++ b/testdata/verify/vector_arith_sat_loong64.s @@ -0,0 +1,132 @@ +// Differential kernel: the arith_sat vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VSADDB(SB), NOSPLIT, $0 + VSADDB V1, V2, V3 + RET + +TEXT ·VSADDH(SB), NOSPLIT, $0 + VSADDH V1, V2, V3 + RET + +TEXT ·VSADDW(SB), NOSPLIT, $0 + VSADDW V1, V2, V3 + RET + +TEXT ·VSADDV(SB), NOSPLIT, $0 + VSADDV V1, V2, V3 + RET + +TEXT ·VSSUBB(SB), NOSPLIT, $0 + VSSUBB V1, V2, V3 + RET + +TEXT ·VSSUBH(SB), NOSPLIT, $0 + VSSUBH V1, V2, V3 + RET + +TEXT ·VSSUBW(SB), NOSPLIT, $0 + VSSUBW V1, V2, V3 + RET + +TEXT ·VSSUBV(SB), NOSPLIT, $0 + VSSUBV V1, V2, V3 + RET + +TEXT ·XVSADDB(SB), NOSPLIT, $0 + XVSADDB X3, X2, X1 + RET + +TEXT ·XVSADDH(SB), NOSPLIT, $0 + XVSADDH X3, X2, X1 + RET + +TEXT ·XVSADDW(SB), NOSPLIT, $0 + XVSADDW X3, X2, X1 + RET + +TEXT ·XVSADDV(SB), NOSPLIT, $0 + XVSADDV X3, X2, X1 + RET + +TEXT ·XVSSUBB(SB), NOSPLIT, $0 + XVSSUBB X3, X2, X1 + RET + +TEXT ·XVSSUBH(SB), NOSPLIT, $0 + XVSSUBH X3, X2, X1 + RET + +TEXT ·XVSSUBW(SB), NOSPLIT, $0 + XVSSUBW X3, X2, X1 + RET + +TEXT ·XVSSUBV(SB), NOSPLIT, $0 + XVSSUBV X3, X2, X1 + RET + +TEXT ·VSADDBU(SB), NOSPLIT, $0 + VSADDBU V1, V2, V3 + RET + +TEXT ·VSADDHU(SB), NOSPLIT, $0 + VSADDHU V1, V2, V3 + RET + +TEXT ·VSADDWU(SB), NOSPLIT, $0 + VSADDWU V1, V2, V3 + RET + +TEXT ·VSADDVU(SB), NOSPLIT, $0 + VSADDVU V1, V2, V3 + RET + +TEXT ·VSSUBBU(SB), NOSPLIT, $0 + VSSUBBU V1, V2, V3 + RET + +TEXT ·VSSUBHU(SB), NOSPLIT, $0 + VSSUBHU V1, V2, V3 + RET + +TEXT ·VSSUBWU(SB), NOSPLIT, $0 + VSSUBWU V1, V2, V3 + RET + +TEXT ·VSSUBVU(SB), NOSPLIT, $0 + VSSUBVU V1, V2, V3 + RET + +TEXT ·XVSADDBU(SB), NOSPLIT, $0 + XVSADDBU X1, X2, X3 + RET + +TEXT ·XVSADDHU(SB), NOSPLIT, $0 + XVSADDHU X1, X2, X3 + RET + +TEXT ·XVSADDWU(SB), NOSPLIT, $0 + XVSADDWU X1, X2, X3 + RET + +TEXT ·XVSADDVU(SB), NOSPLIT, $0 + XVSADDVU X1, X2, X3 + RET + +TEXT ·XVSSUBBU(SB), NOSPLIT, $0 + XVSSUBBU X1, X2, X3 + RET + +TEXT ·XVSSUBHU(SB), NOSPLIT, $0 + XVSSUBHU X1, X2, X3 + RET + +TEXT ·XVSSUBWU(SB), NOSPLIT, $0 + XVSSUBWU X1, X2, X3 + RET + +TEXT ·XVSSUBVU(SB), NOSPLIT, $0 + XVSSUBVU X1, X2, X3 + RET diff --git a/testdata/verify/vector_arith_sub_loong64.s b/testdata/verify/vector_arith_sub_loong64.s new file mode 100644 index 0000000..9a85f9c --- /dev/null +++ b/testdata/verify/vector_arith_sub_loong64.s @@ -0,0 +1,220 @@ +// Differential kernel: the arith_sub vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VSUBB(SB), NOSPLIT, $0 + VSUBB V1, V2, V3 + RET + +TEXT ·VSUBH(SB), NOSPLIT, $0 + VSUBH V1, V2, V3 + RET + +TEXT ·VSUBW(SB), NOSPLIT, $0 + VSUBW V1, V2, V3 + RET + +TEXT ·VSUBV(SB), NOSPLIT, $0 + VSUBV V1, V2, V3 + RET + +TEXT ·VSUBQ(SB), NOSPLIT, $0 + VSUBQ V1, V2, V3 + RET + +TEXT ·XVSUBB(SB), NOSPLIT, $0 + XVSUBB X3, X2, X1 + RET + +TEXT ·XVSUBH(SB), NOSPLIT, $0 + XVSUBH X3, X2, X1 + RET + +TEXT ·XVSUBW(SB), NOSPLIT, $0 + XVSUBW X3, X2, X1 + RET + +TEXT ·XVSUBV(SB), NOSPLIT, $0 + XVSUBV X3, X2, X1 + RET + +TEXT ·XVSUBQ(SB), NOSPLIT, $0 + XVSUBQ X3, X2, X1 + RET + +TEXT ·VSUBBU(SB), NOSPLIT, $0 + VSUBBU $5, V2, V1 + RET + +TEXT ·VSUBHU(SB), NOSPLIT, $0 + VSUBHU $6, V2, V1 + RET + +TEXT ·VSUBWU(SB), NOSPLIT, $0 + VSUBWU $7, V2, V1 + RET + +TEXT ·VSUBVU(SB), NOSPLIT, $0 + VSUBVU $8, V2, V1 + RET + +TEXT ·XVSUBBU(SB), NOSPLIT, $0 + XVSUBBU $13, X1, X2 + RET + +TEXT ·XVSUBHU(SB), NOSPLIT, $0 + XVSUBHU $14, X1, X2 + RET + +TEXT ·XVSUBWU(SB), NOSPLIT, $0 + XVSUBWU $15, X1, X2 + RET + +TEXT ·XVSUBVU(SB), NOSPLIT, $0 + XVSUBVU $16, X1, X2 + RET + +TEXT ·VSUBWEVHB(SB), NOSPLIT, $0 + VSUBWEVHB V1, V2, V3 + RET + +TEXT ·VSUBWEVWH(SB), NOSPLIT, $0 + VSUBWEVWH V1, V2, V3 + RET + +TEXT ·VSUBWEVVW(SB), NOSPLIT, $0 + VSUBWEVVW V1, V2, V3 + RET + +TEXT ·VSUBWEVQV(SB), NOSPLIT, $0 + VSUBWEVQV V1, V2, V3 + RET + +TEXT ·VSUBWODHB(SB), NOSPLIT, $0 + VSUBWODHB V1, V2, V3 + RET + +TEXT ·VSUBWODWH(SB), NOSPLIT, $0 + VSUBWODWH V1, V2, V3 + RET + +TEXT ·VSUBWODVW(SB), NOSPLIT, $0 + VSUBWODVW V1, V2, V3 + RET + +TEXT ·VSUBWODQV(SB), NOSPLIT, $0 + VSUBWODQV V1, V2, V3 + RET + +TEXT ·XVSUBWEVHB(SB), NOSPLIT, $0 + XVSUBWEVHB X1, X2, X3 + RET + +TEXT ·XVSUBWEVWH(SB), NOSPLIT, $0 + XVSUBWEVWH X1, X2, X3 + RET + +TEXT ·XVSUBWEVVW(SB), NOSPLIT, $0 + XVSUBWEVVW X1, X2, X3 + RET + +TEXT ·XVSUBWEVQV(SB), NOSPLIT, $0 + XVSUBWEVQV X1, X2, X3 + RET + +TEXT ·XVSUBWODHB(SB), NOSPLIT, $0 + XVSUBWODHB X1, X2, X3 + RET + +TEXT ·XVSUBWODWH(SB), NOSPLIT, $0 + XVSUBWODWH X1, X2, X3 + RET + +TEXT ·XVSUBWODVW(SB), NOSPLIT, $0 + XVSUBWODVW X1, X2, X3 + RET + +TEXT ·XVSUBWODQV(SB), NOSPLIT, $0 + XVSUBWODQV X1, X2, X3 + RET + +TEXT ·VSUBWEVHBU(SB), NOSPLIT, $0 + VSUBWEVHBU V1, V2, V3 + RET + +TEXT ·VSUBWEVWHU(SB), NOSPLIT, $0 + VSUBWEVWHU V1, V2, V3 + RET + +TEXT ·VSUBWEVVWU(SB), NOSPLIT, $0 + VSUBWEVVWU V1, V2, V3 + RET + +TEXT ·VSUBWEVQVU(SB), NOSPLIT, $0 + VSUBWEVQVU V1, V2, V3 + RET + +TEXT ·VSUBWODHBU(SB), NOSPLIT, $0 + VSUBWODHBU V1, V2, V3 + RET + +TEXT ·VSUBWODWHU(SB), NOSPLIT, $0 + VSUBWODWHU V1, V2, V3 + RET + +TEXT ·VSUBWODVWU(SB), NOSPLIT, $0 + VSUBWODVWU V1, V2, V3 + RET + +TEXT ·VSUBWODQVU(SB), NOSPLIT, $0 + VSUBWODQVU V1, V2, V3 + RET + +TEXT ·XVSUBWEVHBU(SB), NOSPLIT, $0 + XVSUBWEVHBU X1, X2, X3 + RET + +TEXT ·XVSUBWEVWHU(SB), NOSPLIT, $0 + XVSUBWEVWHU X1, X2, X3 + RET + +TEXT ·XVSUBWEVVWU(SB), NOSPLIT, $0 + XVSUBWEVVWU X1, X2, X3 + RET + +TEXT ·XVSUBWEVQVU(SB), NOSPLIT, $0 + XVSUBWEVQVU X1, X2, X3 + RET + +TEXT ·XVSUBWODHBU(SB), NOSPLIT, $0 + XVSUBWODHBU X1, X2, X3 + RET + +TEXT ·XVSUBWODWHU(SB), NOSPLIT, $0 + XVSUBWODWHU X1, X2, X3 + RET + +TEXT ·XVSUBWODVWU(SB), NOSPLIT, $0 + XVSUBWODVWU X1, X2, X3 + RET + +TEXT ·XVSUBWODQVU(SB), NOSPLIT, $0 + XVSUBWODQVU X1, X2, X3 + RET + +TEXT ·VSUBF(SB), NOSPLIT, $0 + VSUBF V1, V2, V3 + RET + +TEXT ·VSUBD(SB), NOSPLIT, $0 + VSUBD V1, V2, V3 + RET + +TEXT ·XVSUBF(SB), NOSPLIT, $0 + XVSUBF X1, X2, X3 + RET + +TEXT ·XVSUBD(SB), NOSPLIT, $0 + XVSUBD X1, X2, X3 + RET diff --git a/testdata/verify/vector_bitops_loong64.s b/testdata/verify/vector_bitops_loong64.s new file mode 100644 index 0000000..58b567a --- /dev/null +++ b/testdata/verify/vector_bitops_loong64.s @@ -0,0 +1,124 @@ +// Differential kernel: the bitops vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VBITCLRB(SB), NOSPLIT, $0 + VBITCLRB V1, V2, V3 + VBITCLRB $7, V2, V3 + RET + +TEXT ·VBITCLRH(SB), NOSPLIT, $0 + VBITCLRH V1, V2, V3 + VBITCLRH $15, V2, V3 + RET + +TEXT ·VBITCLRW(SB), NOSPLIT, $0 + VBITCLRW V1, V2, V3 + VBITCLRW $31, V2, V3 + RET + +TEXT ·VBITCLRV(SB), NOSPLIT, $0 + VBITCLRV V1, V2, V3 + VBITCLRV $63, V2, V3 + RET + +TEXT ·VBITSETB(SB), NOSPLIT, $0 + VBITSETB V1, V2, V3 + VBITSETB $7, V2, V3 + RET + +TEXT ·VBITSETH(SB), NOSPLIT, $0 + VBITSETH V1, V2, V3 + VBITSETH $15, V2, V3 + RET + +TEXT ·VBITSETW(SB), NOSPLIT, $0 + VBITSETW V1, V2, V3 + VBITSETW $31, V2, V3 + RET + +TEXT ·VBITSETV(SB), NOSPLIT, $0 + VBITSETV V1, V2, V3 + VBITSETV $63, V2, V3 + RET + +TEXT ·VBITREVB(SB), NOSPLIT, $0 + VBITREVB V1, V2, V3 + VBITREVB $7, V2, V3 + RET + +TEXT ·VBITREVH(SB), NOSPLIT, $0 + VBITREVH V1, V2, V3 + VBITREVH $15, V2, V3 + RET + +TEXT ·VBITREVW(SB), NOSPLIT, $0 + VBITREVW V1, V2, V3 + VBITREVW $31, V2, V3 + RET + +TEXT ·VBITREVV(SB), NOSPLIT, $0 + VBITREVV V1, V2, V3 + VBITREVV $63, V2, V3 + RET + +TEXT ·XVBITCLRB(SB), NOSPLIT, $0 + XVBITCLRB X3, X2, X1 + XVBITCLRB $7, X2, X1 + RET + +TEXT ·XVBITCLRH(SB), NOSPLIT, $0 + XVBITCLRH X3, X2, X1 + XVBITCLRH $15, X2, X1 + RET + +TEXT ·XVBITCLRW(SB), NOSPLIT, $0 + XVBITCLRW X3, X2, X1 + XVBITCLRW $31, X2, X1 + RET + +TEXT ·XVBITCLRV(SB), NOSPLIT, $0 + XVBITCLRV X3, X2, X1 + XVBITCLRV $63, X2, X1 + RET + +TEXT ·XVBITSETB(SB), NOSPLIT, $0 + XVBITSETB X3, X2, X1 + XVBITSETB $7, X2, X1 + RET + +TEXT ·XVBITSETH(SB), NOSPLIT, $0 + XVBITSETH X3, X2, X1 + XVBITSETH $15, X2, X1 + RET + +TEXT ·XVBITSETW(SB), NOSPLIT, $0 + XVBITSETW X3, X2, X1 + XVBITSETW $31, X2, X1 + RET + +TEXT ·XVBITSETV(SB), NOSPLIT, $0 + XVBITSETV X3, X2, X1 + XVBITSETV $63, X2, X1 + RET + +TEXT ·XVBITREVB(SB), NOSPLIT, $0 + XVBITREVB X3, X2, X1 + XVBITREVB $7, X2, X1 + RET + +TEXT ·XVBITREVH(SB), NOSPLIT, $0 + XVBITREVH X3, X2, X1 + XVBITREVH $15, X2, X1 + RET + +TEXT ·XVBITREVW(SB), NOSPLIT, $0 + XVBITREVW X3, X2, X1 + XVBITREVW $31, X2, X1 + RET + +TEXT ·XVBITREVV(SB), NOSPLIT, $0 + XVBITREVV X3, X2, X1 + XVBITREVV $63, X2, X1 + RET diff --git a/testdata/verify/vector_bounds_loong64.s b/testdata/verify/vector_bounds_loong64.s new file mode 100644 index 0000000..c27ce90 --- /dev/null +++ b/testdata/verify/vector_bounds_loong64.s @@ -0,0 +1,419 @@ +// Differential kernel: immediate range boundaries for the vector +// immediate forms (min, mid and max of each accepted window). + +#include "textflag.h" + +TEXT ·VSEQBbounds(SB), NOSPLIT, $0 + VSEQB $-16, V2, V3 + VSEQB $15, V2, V3 + VSEQB $0, V2, V3 + RET + +TEXT ·VSEQHbounds(SB), NOSPLIT, $0 + VSEQH $-16, V2, V3 + VSEQH $15, V2, V3 + VSEQH $0, V2, V3 + RET + +TEXT ·VSEQWbounds(SB), NOSPLIT, $0 + VSEQW $-16, V2, V3 + VSEQW $15, V2, V3 + VSEQW $0, V2, V3 + RET + +TEXT ·VSEQVbounds(SB), NOSPLIT, $0 + VSEQV $-16, V2, V3 + VSEQV $15, V2, V3 + VSEQV $0, V2, V3 + RET + +TEXT ·VSLTBbounds(SB), NOSPLIT, $0 + VSLTB $-16, V2, V3 + VSLTB $15, V2, V3 + VSLTB $0, V2, V3 + RET + +TEXT ·VSLTHbounds(SB), NOSPLIT, $0 + VSLTH $-16, V2, V3 + VSLTH $15, V2, V3 + VSLTH $0, V2, V3 + RET + +TEXT ·VSLTWbounds(SB), NOSPLIT, $0 + VSLTW $-16, V2, V3 + VSLTW $15, V2, V3 + VSLTW $0, V2, V3 + RET + +TEXT ·VSLTVbounds(SB), NOSPLIT, $0 + VSLTV $-16, V2, V3 + VSLTV $15, V2, V3 + VSLTV $0, V2, V3 + RET + +TEXT ·VSLTBUbounds(SB), NOSPLIT, $0 + VSLTBU $0, V2, V3 + VSLTBU $31, V2, V3 + VSLTBU $15, V2, V3 + RET + +TEXT ·VSLTHUbounds(SB), NOSPLIT, $0 + VSLTHU $0, V2, V3 + VSLTHU $31, V2, V3 + VSLTHU $15, V2, V3 + RET + +TEXT ·VSLTWUbounds(SB), NOSPLIT, $0 + VSLTWU $0, V2, V3 + VSLTWU $31, V2, V3 + VSLTWU $15, V2, V3 + RET + +TEXT ·VSLTVUbounds(SB), NOSPLIT, $0 + VSLTVU $0, V2, V3 + VSLTVU $31, V2, V3 + VSLTVU $15, V2, V3 + RET + +TEXT ·VADDBUbounds(SB), NOSPLIT, $0 + VADDBU $0, V2, V3 + VADDBU $31, V2, V3 + VADDBU $15, V2, V3 + VADDBU $15, V2 + RET + +TEXT ·VADDHUbounds(SB), NOSPLIT, $0 + VADDHU $0, V2, V3 + VADDHU $31, V2, V3 + VADDHU $15, V2, V3 + VADDHU $15, V2 + RET + +TEXT ·VADDWUbounds(SB), NOSPLIT, $0 + VADDWU $0, V2, V3 + VADDWU $31, V2, V3 + VADDWU $15, V2, V3 + VADDWU $15, V2 + RET + +TEXT ·VADDVUbounds(SB), NOSPLIT, $0 + VADDVU $0, V2, V3 + VADDVU $31, V2, V3 + VADDVU $15, V2, V3 + VADDVU $15, V2 + RET + +TEXT ·VSUBBUbounds(SB), NOSPLIT, $0 + VSUBBU $0, V2, V3 + VSUBBU $31, V2, V3 + VSUBBU $15, V2, V3 + VSUBBU $15, V2 + RET + +TEXT ·VSUBHUbounds(SB), NOSPLIT, $0 + VSUBHU $0, V2, V3 + VSUBHU $31, V2, V3 + VSUBHU $15, V2, V3 + VSUBHU $15, V2 + RET + +TEXT ·VSUBWUbounds(SB), NOSPLIT, $0 + VSUBWU $0, V2, V3 + VSUBWU $31, V2, V3 + VSUBWU $15, V2, V3 + VSUBWU $15, V2 + RET + +TEXT ·VSUBVUbounds(SB), NOSPLIT, $0 + VSUBVU $0, V2, V3 + VSUBVU $31, V2, V3 + VSUBVU $15, V2, V3 + VSUBVU $15, V2 + RET + +TEXT ·VANDBbounds(SB), NOSPLIT, $0 + VANDB $0, V2, V3 + VANDB $255, V2, V3 + VANDB $127, V2, V3 + VANDB $127, V2 + RET + +TEXT ·VBITCLRBbounds(SB), NOSPLIT, $0 + VBITCLRB $0, V2, V3 + VBITCLRB $7, V2, V3 + VBITCLRB $3, V2, V3 + VBITCLRB $3, V2 + RET + +TEXT ·VBITCLRHbounds(SB), NOSPLIT, $0 + VBITCLRH $0, V2, V3 + VBITCLRH $15, V2, V3 + VBITCLRH $7, V2, V3 + VBITCLRH $7, V2 + RET + +TEXT ·VBITCLRVbounds(SB), NOSPLIT, $0 + VBITCLRV $0, V2, V3 + VBITCLRV $63, V2, V3 + VBITCLRV $31, V2, V3 + VBITCLRV $31, V2 + RET + +TEXT ·VBITCLRWbounds(SB), NOSPLIT, $0 + VBITCLRW $0, V2, V3 + VBITCLRW $31, V2, V3 + VBITCLRW $15, V2, V3 + VBITCLRW $15, V2 + RET + +TEXT ·VBITREVBbounds(SB), NOSPLIT, $0 + VBITREVB $0, V2, V3 + VBITREVB $7, V2, V3 + VBITREVB $3, V2, V3 + VBITREVB $3, V2 + RET + +TEXT ·VBITREVHbounds(SB), NOSPLIT, $0 + VBITREVH $0, V2, V3 + VBITREVH $15, V2, V3 + VBITREVH $7, V2, V3 + VBITREVH $7, V2 + RET + +TEXT ·VBITREVVbounds(SB), NOSPLIT, $0 + VBITREVV $0, V2, V3 + VBITREVV $63, V2, V3 + VBITREVV $31, V2, V3 + VBITREVV $31, V2 + RET + +TEXT ·VBITREVWbounds(SB), NOSPLIT, $0 + VBITREVW $0, V2, V3 + VBITREVW $31, V2, V3 + VBITREVW $15, V2, V3 + VBITREVW $15, V2 + RET + +TEXT ·VBITSETBbounds(SB), NOSPLIT, $0 + VBITSETB $0, V2, V3 + VBITSETB $7, V2, V3 + VBITSETB $3, V2, V3 + VBITSETB $3, V2 + RET + +TEXT ·VBITSETHbounds(SB), NOSPLIT, $0 + VBITSETH $0, V2, V3 + VBITSETH $15, V2, V3 + VBITSETH $7, V2, V3 + VBITSETH $7, V2 + RET + +TEXT ·VBITSETVbounds(SB), NOSPLIT, $0 + VBITSETV $0, V2, V3 + VBITSETV $63, V2, V3 + VBITSETV $31, V2, V3 + VBITSETV $31, V2 + RET + +TEXT ·VBITSETWbounds(SB), NOSPLIT, $0 + VBITSETW $0, V2, V3 + VBITSETW $31, V2, V3 + VBITSETW $15, V2, V3 + VBITSETW $15, V2 + RET + +TEXT ·VEXTRINSBbounds(SB), NOSPLIT, $0 + VEXTRINSB $0, V2, V3 + VEXTRINSB $255, V2, V3 + VEXTRINSB $127, V2, V3 + VEXTRINSB $127, V2 + RET + +TEXT ·VEXTRINSHbounds(SB), NOSPLIT, $0 + VEXTRINSH $0, V2, V3 + VEXTRINSH $255, V2, V3 + VEXTRINSH $127, V2, V3 + VEXTRINSH $127, V2 + RET + +TEXT ·VEXTRINSVbounds(SB), NOSPLIT, $0 + VEXTRINSV $0, V2, V3 + VEXTRINSV $255, V2, V3 + VEXTRINSV $127, V2, V3 + VEXTRINSV $127, V2 + RET + +TEXT ·VEXTRINSWbounds(SB), NOSPLIT, $0 + VEXTRINSW $0, V2, V3 + VEXTRINSW $255, V2, V3 + VEXTRINSW $127, V2, V3 + VEXTRINSW $127, V2 + RET + +TEXT ·VNORBbounds(SB), NOSPLIT, $0 + VNORB $0, V2, V3 + VNORB $255, V2, V3 + VNORB $127, V2, V3 + VNORB $127, V2 + RET + +TEXT ·VORBbounds(SB), NOSPLIT, $0 + VORB $0, V2, V3 + VORB $255, V2, V3 + VORB $127, V2, V3 + VORB $127, V2 + RET + +TEXT ·VPERMIWbounds(SB), NOSPLIT, $0 + VPERMIW $0, V2, V3 + VPERMIW $255, V2, V3 + VPERMIW $127, V2, V3 + VPERMIW $127, V2 + RET + +TEXT ·VROTRBbounds(SB), NOSPLIT, $0 + VROTRB $0, V2, V3 + VROTRB $7, V2, V3 + VROTRB $3, V2, V3 + VROTRB $3, V2 + RET + +TEXT ·VROTRHbounds(SB), NOSPLIT, $0 + VROTRH $0, V2, V3 + VROTRH $15, V2, V3 + VROTRH $7, V2, V3 + VROTRH $7, V2 + RET + +TEXT ·VROTRVbounds(SB), NOSPLIT, $0 + VROTRV $0, V2, V3 + VROTRV $63, V2, V3 + VROTRV $31, V2, V3 + VROTRV $31, V2 + RET + +TEXT ·VROTRWbounds(SB), NOSPLIT, $0 + VROTRW $0, V2, V3 + VROTRW $31, V2, V3 + VROTRW $15, V2, V3 + VROTRW $15, V2 + RET + +TEXT ·VSHUF4IBbounds(SB), NOSPLIT, $0 + VSHUF4IB $0, V2, V3 + VSHUF4IB $255, V2, V3 + VSHUF4IB $127, V2, V3 + VSHUF4IB $127, V2 + RET + +TEXT ·VSHUF4IHbounds(SB), NOSPLIT, $0 + VSHUF4IH $0, V2, V3 + VSHUF4IH $255, V2, V3 + VSHUF4IH $127, V2, V3 + VSHUF4IH $127, V2 + RET + +TEXT ·VSHUF4IVbounds(SB), NOSPLIT, $0 + VSHUF4IV $0, V2, V3 + VSHUF4IV $15, V2, V3 + VSHUF4IV $7, V2, V3 + VSHUF4IV $7, V2 + RET + +TEXT ·VSHUF4IWbounds(SB), NOSPLIT, $0 + VSHUF4IW $0, V2, V3 + VSHUF4IW $255, V2, V3 + VSHUF4IW $127, V2, V3 + VSHUF4IW $127, V2 + RET + +TEXT ·VSLLBbounds(SB), NOSPLIT, $0 + VSLLB $0, V2, V3 + VSLLB $7, V2, V3 + VSLLB $3, V2, V3 + VSLLB $3, V2 + RET + +TEXT ·VSLLHbounds(SB), NOSPLIT, $0 + VSLLH $0, V2, V3 + VSLLH $15, V2, V3 + VSLLH $7, V2, V3 + VSLLH $7, V2 + RET + +TEXT ·VSLLVbounds(SB), NOSPLIT, $0 + VSLLV $0, V2, V3 + VSLLV $63, V2, V3 + VSLLV $31, V2, V3 + VSLLV $31, V2 + RET + +TEXT ·VSLLWbounds(SB), NOSPLIT, $0 + VSLLW $0, V2, V3 + VSLLW $31, V2, V3 + VSLLW $15, V2, V3 + VSLLW $15, V2 + RET + +TEXT ·VSRABbounds(SB), NOSPLIT, $0 + VSRAB $0, V2, V3 + VSRAB $7, V2, V3 + VSRAB $3, V2, V3 + VSRAB $3, V2 + RET + +TEXT ·VSRAHbounds(SB), NOSPLIT, $0 + VSRAH $0, V2, V3 + VSRAH $15, V2, V3 + VSRAH $7, V2, V3 + VSRAH $7, V2 + RET + +TEXT ·VSRAVbounds(SB), NOSPLIT, $0 + VSRAV $0, V2, V3 + VSRAV $63, V2, V3 + VSRAV $31, V2, V3 + VSRAV $31, V2 + RET + +TEXT ·VSRAWbounds(SB), NOSPLIT, $0 + VSRAW $0, V2, V3 + VSRAW $31, V2, V3 + VSRAW $15, V2, V3 + VSRAW $15, V2 + RET + +TEXT ·VSRLBbounds(SB), NOSPLIT, $0 + VSRLB $0, V2, V3 + VSRLB $7, V2, V3 + VSRLB $3, V2, V3 + VSRLB $3, V2 + RET + +TEXT ·VSRLHbounds(SB), NOSPLIT, $0 + VSRLH $0, V2, V3 + VSRLH $15, V2, V3 + VSRLH $7, V2, V3 + VSRLH $7, V2 + RET + +TEXT ·VSRLVbounds(SB), NOSPLIT, $0 + VSRLV $0, V2, V3 + VSRLV $63, V2, V3 + VSRLV $31, V2, V3 + VSRLV $31, V2 + RET + +TEXT ·VSRLWbounds(SB), NOSPLIT, $0 + VSRLW $0, V2, V3 + VSRLW $31, V2, V3 + VSRLW $15, V2, V3 + VSRLW $15, V2 + RET + +TEXT ·VXORBbounds(SB), NOSPLIT, $0 + VXORB $0, V2, V3 + VXORB $255, V2, V3 + VXORB $127, V2, V3 + VXORB $127, V2 + RET diff --git a/testdata/verify/vector_divmod_loong64.s b/testdata/verify/vector_divmod_loong64.s new file mode 100644 index 0000000..14fd759 --- /dev/null +++ b/testdata/verify/vector_divmod_loong64.s @@ -0,0 +1,148 @@ +// Differential kernel: the divmod vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VDIVB(SB), NOSPLIT, $0 + VDIVB V1, V2, V3 + RET + +TEXT ·VDIVH(SB), NOSPLIT, $0 + VDIVH V1, V2, V3 + RET + +TEXT ·VDIVW(SB), NOSPLIT, $0 + VDIVW V1, V2, V3 + RET + +TEXT ·VDIVV(SB), NOSPLIT, $0 + VDIVV V1, V2, V3 + RET + +TEXT ·VDIVBU(SB), NOSPLIT, $0 + VDIVBU V1, V2, V3 + RET + +TEXT ·VDIVHU(SB), NOSPLIT, $0 + VDIVHU V1, V2, V3 + RET + +TEXT ·VDIVWU(SB), NOSPLIT, $0 + VDIVWU V1, V2, V3 + RET + +TEXT ·VDIVVU(SB), NOSPLIT, $0 + VDIVVU V1, V2, V3 + RET + +TEXT ·VMODB(SB), NOSPLIT, $0 + VMODB V1, V2, V3 + RET + +TEXT ·VMODH(SB), NOSPLIT, $0 + VMODH V1, V2, V3 + RET + +TEXT ·VMODW(SB), NOSPLIT, $0 + VMODW V1, V2, V3 + RET + +TEXT ·VMODV(SB), NOSPLIT, $0 + VMODV V1, V2, V3 + RET + +TEXT ·VMODBU(SB), NOSPLIT, $0 + VMODBU V1, V2, V3 + RET + +TEXT ·VMODHU(SB), NOSPLIT, $0 + VMODHU V1, V2, V3 + RET + +TEXT ·VMODWU(SB), NOSPLIT, $0 + VMODWU V1, V2, V3 + RET + +TEXT ·VMODVU(SB), NOSPLIT, $0 + VMODVU V1, V2, V3 + RET + +TEXT ·XVDIVB(SB), NOSPLIT, $0 + XVDIVB X3, X2, X1 + RET + +TEXT ·XVDIVH(SB), NOSPLIT, $0 + XVDIVH X3, X2, X1 + RET + +TEXT ·XVDIVW(SB), NOSPLIT, $0 + XVDIVW X3, X2, X1 + RET + +TEXT ·XVDIVV(SB), NOSPLIT, $0 + XVDIVV X3, X2, X1 + RET + +TEXT ·XVDIVBU(SB), NOSPLIT, $0 + XVDIVBU X3, X2, X1 + RET + +TEXT ·XVDIVHU(SB), NOSPLIT, $0 + XVDIVHU X3, X2, X1 + RET + +TEXT ·XVDIVWU(SB), NOSPLIT, $0 + XVDIVWU X3, X2, X1 + RET + +TEXT ·XVDIVVU(SB), NOSPLIT, $0 + XVDIVVU X3, X2, X1 + RET + +TEXT ·XVMODB(SB), NOSPLIT, $0 + XVMODB X3, X2, X1 + RET + +TEXT ·XVMODH(SB), NOSPLIT, $0 + XVMODH X3, X2, X1 + RET + +TEXT ·XVMODW(SB), NOSPLIT, $0 + XVMODW X3, X2, X1 + RET + +TEXT ·XVMODV(SB), NOSPLIT, $0 + XVMODV X3, X2, X1 + RET + +TEXT ·XVMODBU(SB), NOSPLIT, $0 + XVMODBU X3, X2, X1 + RET + +TEXT ·XVMODHU(SB), NOSPLIT, $0 + XVMODHU X3, X2, X1 + RET + +TEXT ·XVMODWU(SB), NOSPLIT, $0 + XVMODWU X3, X2, X1 + RET + +TEXT ·XVMODVU(SB), NOSPLIT, $0 + XVMODVU X3, X2, X1 + RET + +TEXT ·VDIVF(SB), NOSPLIT, $0 + VDIVF V1, V2, V3 + RET + +TEXT ·VDIVD(SB), NOSPLIT, $0 + VDIVD V1, V2, V3 + RET + +TEXT ·XVDIVF(SB), NOSPLIT, $0 + XVDIVF X1, X2, X3 + RET + +TEXT ·XVDIVD(SB), NOSPLIT, $0 + XVDIVD X1, X2, X3 + RET diff --git a/testdata/verify/vector_fp_loong64.s b/testdata/verify/vector_fp_loong64.s new file mode 100644 index 0000000..6eb7459 --- /dev/null +++ b/testdata/verify/vector_fp_loong64.s @@ -0,0 +1,176 @@ +// Differential kernel: the fp vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·FFINTFW(SB), NOSPLIT, $0 + FFINTFW F0, F1 + RET + +TEXT ·FFINTFV(SB), NOSPLIT, $0 + FFINTFV F0, F1 + RET + +TEXT ·FFINTDW(SB), NOSPLIT, $0 + FFINTDW F0, F1 + RET + +TEXT ·FTINTWF(SB), NOSPLIT, $0 + FTINTWF F0, F1 + RET + +TEXT ·FTINTWD(SB), NOSPLIT, $0 + FTINTWD F0, F1 + RET + +TEXT ·FTINTVF(SB), NOSPLIT, $0 + FTINTVF F0, F1 + RET + +TEXT ·FTINTVD(SB), NOSPLIT, $0 + FTINTVD F0, F1 + RET + +TEXT ·VFSQRTF(SB), NOSPLIT, $0 + VFSQRTF V1, V2 + RET + +TEXT ·VFSQRTD(SB), NOSPLIT, $0 + VFSQRTD V1, V2 + RET + +TEXT ·VFRECIPF(SB), NOSPLIT, $0 + VFRECIPF V1, V2 + RET + +TEXT ·VFRECIPD(SB), NOSPLIT, $0 + VFRECIPD V1, V2 + RET + +TEXT ·VFRSQRTF(SB), NOSPLIT, $0 + VFRSQRTF V1, V2 + RET + +TEXT ·VFRSQRTD(SB), NOSPLIT, $0 + VFRSQRTD V1, V2 + RET + +TEXT ·XVFSQRTF(SB), NOSPLIT, $0 + XVFSQRTF X2, X1 + RET + +TEXT ·XVFSQRTD(SB), NOSPLIT, $0 + XVFSQRTD X2, X1 + RET + +TEXT ·XVFRECIPF(SB), NOSPLIT, $0 + XVFRECIPF X2, X1 + RET + +TEXT ·XVFRECIPD(SB), NOSPLIT, $0 + XVFRECIPD X2, X1 + RET + +TEXT ·XVFRSQRTF(SB), NOSPLIT, $0 + XVFRSQRTF X2, X1 + RET + +TEXT ·XVFRSQRTD(SB), NOSPLIT, $0 + XVFRSQRTD X2, X1 + RET + +TEXT ·VFRINTRNEF(SB), NOSPLIT, $0 + VFRINTRNEF V1, V2 + RET + +TEXT ·VFRINTRNED(SB), NOSPLIT, $0 + VFRINTRNED V1, V2 + RET + +TEXT ·VFRINTRZF(SB), NOSPLIT, $0 + VFRINTRZF V1, V2 + RET + +TEXT ·VFRINTRZD(SB), NOSPLIT, $0 + VFRINTRZD V1, V2 + RET + +TEXT ·VFRINTRPF(SB), NOSPLIT, $0 + VFRINTRPF V1, V2 + RET + +TEXT ·VFRINTRPD(SB), NOSPLIT, $0 + VFRINTRPD V1, V2 + RET + +TEXT ·VFRINTRMF(SB), NOSPLIT, $0 + VFRINTRMF V1, V2 + RET + +TEXT ·VFRINTRMD(SB), NOSPLIT, $0 + VFRINTRMD V1, V2 + RET + +TEXT ·VFRINTF(SB), NOSPLIT, $0 + VFRINTF V1, V2 + RET + +TEXT ·VFRINTD(SB), NOSPLIT, $0 + VFRINTD V1, V2 + RET + +TEXT ·XVFRINTRNEF(SB), NOSPLIT, $0 + XVFRINTRNEF X1, X2 + RET + +TEXT ·XVFRINTRNED(SB), NOSPLIT, $0 + XVFRINTRNED X1, X2 + RET + +TEXT ·XVFRINTRZF(SB), NOSPLIT, $0 + XVFRINTRZF X1, X2 + RET + +TEXT ·XVFRINTRZD(SB), NOSPLIT, $0 + XVFRINTRZD X1, X2 + RET + +TEXT ·XVFRINTRPF(SB), NOSPLIT, $0 + XVFRINTRPF X1, X2 + RET + +TEXT ·XVFRINTRPD(SB), NOSPLIT, $0 + XVFRINTRPD X1, X2 + RET + +TEXT ·XVFRINTRMF(SB), NOSPLIT, $0 + XVFRINTRMF X1, X2 + RET + +TEXT ·XVFRINTRMD(SB), NOSPLIT, $0 + XVFRINTRMD X1, X2 + RET + +TEXT ·XVFRINTF(SB), NOSPLIT, $0 + XVFRINTF X1, X2 + RET + +TEXT ·XVFRINTD(SB), NOSPLIT, $0 + XVFRINTD X1, X2 + RET + +TEXT ·VFCLASSF(SB), NOSPLIT, $0 + VFCLASSF V1, V2 + RET + +TEXT ·VFCLASSD(SB), NOSPLIT, $0 + VFCLASSD V1, V2 + RET + +TEXT ·XVFCLASSF(SB), NOSPLIT, $0 + XVFCLASSF X1, X2 + RET + +TEXT ·XVFCLASSD(SB), NOSPLIT, $0 + XVFCLASSD X1, X2 + RET diff --git a/testdata/verify/vector_interleave_loong64.s b/testdata/verify/vector_interleave_loong64.s new file mode 100644 index 0000000..c4539f2 --- /dev/null +++ b/testdata/verify/vector_interleave_loong64.s @@ -0,0 +1,68 @@ +// Differential kernel: the interleave vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VILVLB(SB), NOSPLIT, $0 + VILVLB V1, V2, V3 + RET + +TEXT ·VILVLH(SB), NOSPLIT, $0 + VILVLH V1, V2, V3 + RET + +TEXT ·VILVLW(SB), NOSPLIT, $0 + VILVLW V1, V2, V3 + RET + +TEXT ·VILVLV(SB), NOSPLIT, $0 + VILVLV V1, V2, V3 + RET + +TEXT ·VILVHB(SB), NOSPLIT, $0 + VILVHB V1, V2, V3 + RET + +TEXT ·VILVHH(SB), NOSPLIT, $0 + VILVHH V1, V2, V3 + RET + +TEXT ·VILVHW(SB), NOSPLIT, $0 + VILVHW V1, V2, V3 + RET + +TEXT ·VILVHV(SB), NOSPLIT, $0 + VILVHV V1, V2, V3 + RET + +TEXT ·XVILVLB(SB), NOSPLIT, $0 + XVILVLB X3, X2, X1 + RET + +TEXT ·XVILVLH(SB), NOSPLIT, $0 + XVILVLH X3, X2, X1 + RET + +TEXT ·XVILVLW(SB), NOSPLIT, $0 + XVILVLW X3, X2, X1 + RET + +TEXT ·XVILVLV(SB), NOSPLIT, $0 + XVILVLV X3, X2, X1 + RET + +TEXT ·XVILVHB(SB), NOSPLIT, $0 + XVILVHB X3, X2, X1 + RET + +TEXT ·XVILVHH(SB), NOSPLIT, $0 + XVILVHH X3, X2, X1 + RET + +TEXT ·XVILVHW(SB), NOSPLIT, $0 + XVILVHW X3, X2, X1 + RET + +TEXT ·XVILVHV(SB), NOSPLIT, $0 + XVILVHV X3, X2, X1 + RET diff --git a/testdata/verify/vector_logic_loong64.s b/testdata/verify/vector_logic_loong64.s new file mode 100644 index 0000000..438a472 --- /dev/null +++ b/testdata/verify/vector_logic_loong64.s @@ -0,0 +1,174 @@ +// Differential kernel: the logic vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VSEQH(SB), NOSPLIT, $0 + VSEQH V1, V2, V3 + VSEQH $1, V2, V3 + RET + +TEXT ·VSEQW(SB), NOSPLIT, $0 + VSEQW V1, V2, V3 + VSEQW $8, V2, V3 + RET + +TEXT ·XVSEQH(SB), NOSPLIT, $0 + XVSEQH X3, X2, X4 + XVSEQH $3, X2, X4 + RET + +TEXT ·XVSEQW(SB), NOSPLIT, $0 + XVSEQW X3, X2, X4 + XVSEQW $12, X2, X4 + RET + +TEXT ·VSLTB(SB), NOSPLIT, $0 + VSLTB V1, V2, V3 + VSLTB $1, V2, V3 + RET + +TEXT ·VSLTH(SB), NOSPLIT, $0 + VSLTH V1, V2, V3 + VSLTH $-16, V2, V3 + RET + +TEXT ·VSLTW(SB), NOSPLIT, $0 + VSLTW V1, V2, V3 + VSLTW $-16, V2, V3 + RET + +TEXT ·VSLTV(SB), NOSPLIT, $0 + VSLTV V1, V2, V3 + VSLTV $-15, V2, V3 + RET + +TEXT ·XVSLTB(SB), NOSPLIT, $0 + XVSLTB X1, X2, X3 + XVSLTB $1, X2, X3 + RET + +TEXT ·XVSLTH(SB), NOSPLIT, $0 + XVSLTH X1, X2, X3 + XVSLTH $-16, X2, X3 + RET + +TEXT ·XVSLTW(SB), NOSPLIT, $0 + XVSLTW X1, X2, X3 + XVSLTW $-16, X2, X3 + RET + +TEXT ·XVSLTV(SB), NOSPLIT, $0 + XVSLTV X1, X2, X3 + XVSLTV $-16, X2, X3 + RET + +TEXT ·VSLTBU(SB), NOSPLIT, $0 + VSLTBU V1, V2, V3 + VSLTBU $0, V2, V3 + RET + +TEXT ·VSLTHU(SB), NOSPLIT, $0 + VSLTHU V1, V2, V3 + VSLTHU $31, V2, V3 + RET + +TEXT ·VSLTWU(SB), NOSPLIT, $0 + VSLTWU V1, V2, V3 + VSLTWU $16, V2, V3 + RET + +TEXT ·VSLTVU(SB), NOSPLIT, $0 + VSLTVU V1, V2, V3 + VSLTVU $1, V2, V3 + RET + +TEXT ·XVSLTBU(SB), NOSPLIT, $0 + XVSLTBU X1, X2, X3 + XVSLTBU $0, X2, X3 + RET + +TEXT ·XVSLTHU(SB), NOSPLIT, $0 + XVSLTHU X1, X2, X3 + XVSLTHU $31, X2, X3 + RET + +TEXT ·XVSLTWU(SB), NOSPLIT, $0 + XVSLTWU X1, X2, X3 + XVSLTWU $8, X2, X3 + RET + +TEXT ·XVSLTVU(SB), NOSPLIT, $0 + XVSLTVU X1, X2, X3 + XVSLTVU $0, X2, X3 + RET + +TEXT ·VORV(SB), NOSPLIT, $0 + VORV V1, V2, V3 + VORV V1, V2 + RET + +TEXT ·VNORV(SB), NOSPLIT, $0 + VNORV V1, V2, V3 + VNORV V1, V2 + RET + +TEXT ·VANDNV(SB), NOSPLIT, $0 + VANDNV V1, V2, V3 + VANDNV V1, V2 + RET + +TEXT ·VORNV(SB), NOSPLIT, $0 + VORNV V1, V2, V3 + VORNV V1, V2 + RET + +TEXT ·VORB(SB), NOSPLIT, $0 + VORB $64, V2, V3 + VORB $64, V2 + RET + +TEXT ·VXORB(SB), NOSPLIT, $0 + VXORB $128, V2, V3 + VXORB $128, V2 + RET + +TEXT ·VNORB(SB), NOSPLIT, $0 + VNORB $255, V2, V3 + VNORB $255, V2 + RET + +TEXT ·XVORV(SB), NOSPLIT, $0 + XVORV X1, X2, X3 + XVORV X1, X2 + RET + +TEXT ·XVNORV(SB), NOSPLIT, $0 + XVNORV X1, X2, X3 + XVNORV X1, X2 + RET + +TEXT ·XVANDNV(SB), NOSPLIT, $0 + XVANDNV X1, X2, X3 + XVANDNV X1, X2 + RET + +TEXT ·XVORNV(SB), NOSPLIT, $0 + XVORNV X1, X2, X3 + XVORNV X1, X2 + RET + +TEXT ·XVORB(SB), NOSPLIT, $0 + XVORB $1, X2, X3 + XVORB $1, X2 + RET + +TEXT ·XVXORB(SB), NOSPLIT, $0 + XVXORB $127, X2, X3 + XVXORB $127, X2 + RET + +TEXT ·XVNORB(SB), NOSPLIT, $0 + XVNORB $255, X2, X3 + XVNORB $255, X2 + RET diff --git a/testdata/verify/vector_madd_loong64.s b/testdata/verify/vector_madd_loong64.s new file mode 100644 index 0000000..6172764 --- /dev/null +++ b/testdata/verify/vector_madd_loong64.s @@ -0,0 +1,28 @@ +// Differential kernel: the madd vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VMADDB(SB), NOSPLIT, $0 + VMADDB V1, V2, V3 + RET + +TEXT ·VMADDH(SB), NOSPLIT, $0 + VMADDH V1, V2, V3 + RET + +TEXT ·VMADDV(SB), NOSPLIT, $0 + VMADDV V1, V2, V3 + RET + +TEXT ·XVMADDB(SB), NOSPLIT, $0 + XVMADDB X1, X2, X3 + RET + +TEXT ·XVMADDH(SB), NOSPLIT, $0 + XVMADDH X1, X2, X3 + RET + +TEXT ·XVMADDV(SB), NOSPLIT, $0 + XVMADDV X1, X2, X3 + RET diff --git a/testdata/verify/vector_maddwiden_loong64.s b/testdata/verify/vector_maddwiden_loong64.s new file mode 100644 index 0000000..ecf6960 --- /dev/null +++ b/testdata/verify/vector_maddwiden_loong64.s @@ -0,0 +1,204 @@ +// Differential kernel: the maddwiden vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VMADDW(SB), NOSPLIT, $0 + VMADDW V1, V2, V3 + RET + +TEXT ·XVMADDW(SB), NOSPLIT, $0 + XVMADDW X1, X2, X3 + RET + +TEXT ·VMADDWEVHB(SB), NOSPLIT, $0 + VMADDWEVHB V1, V2, V3 + RET + +TEXT ·VMADDWEVWH(SB), NOSPLIT, $0 + VMADDWEVWH V1, V2, V3 + RET + +TEXT ·VMADDWEVVW(SB), NOSPLIT, $0 + VMADDWEVVW V1, V2, V3 + RET + +TEXT ·VMADDWEVQV(SB), NOSPLIT, $0 + VMADDWEVQV V1, V2, V3 + RET + +TEXT ·VMADDWODHB(SB), NOSPLIT, $0 + VMADDWODHB V1, V2, V3 + RET + +TEXT ·VMADDWODWH(SB), NOSPLIT, $0 + VMADDWODWH V1, V2, V3 + RET + +TEXT ·VMADDWODVW(SB), NOSPLIT, $0 + VMADDWODVW V1, V2, V3 + RET + +TEXT ·VMADDWODQV(SB), NOSPLIT, $0 + VMADDWODQV V1, V2, V3 + RET + +TEXT ·XVMADDWEVHB(SB), NOSPLIT, $0 + XVMADDWEVHB X1, X2, X3 + RET + +TEXT ·XVMADDWEVWH(SB), NOSPLIT, $0 + XVMADDWEVWH X1, X2, X3 + RET + +TEXT ·XVMADDWEVVW(SB), NOSPLIT, $0 + XVMADDWEVVW X1, X2, X3 + RET + +TEXT ·XVMADDWEVQV(SB), NOSPLIT, $0 + XVMADDWEVQV X1, X2, X3 + RET + +TEXT ·XVMADDWODHB(SB), NOSPLIT, $0 + XVMADDWODHB X1, X2, X3 + RET + +TEXT ·XVMADDWODWH(SB), NOSPLIT, $0 + XVMADDWODWH X1, X2, X3 + RET + +TEXT ·XVMADDWODVW(SB), NOSPLIT, $0 + XVMADDWODVW X1, X2, X3 + RET + +TEXT ·XVMADDWODQV(SB), NOSPLIT, $0 + XVMADDWODQV X1, X2, X3 + RET + +TEXT ·VMADDWEVHBU(SB), NOSPLIT, $0 + VMADDWEVHBU V1, V2, V3 + RET + +TEXT ·VMADDWEVWHU(SB), NOSPLIT, $0 + VMADDWEVWHU V1, V2, V3 + RET + +TEXT ·VMADDWEVVWU(SB), NOSPLIT, $0 + VMADDWEVVWU V1, V2, V3 + RET + +TEXT ·VMADDWEVQVU(SB), NOSPLIT, $0 + VMADDWEVQVU V1, V2, V3 + RET + +TEXT ·VMADDWODHBU(SB), NOSPLIT, $0 + VMADDWODHBU V1, V2, V3 + RET + +TEXT ·VMADDWODWHU(SB), NOSPLIT, $0 + VMADDWODWHU V1, V2, V3 + RET + +TEXT ·VMADDWODVWU(SB), NOSPLIT, $0 + VMADDWODVWU V1, V2, V3 + RET + +TEXT ·VMADDWODQVU(SB), NOSPLIT, $0 + VMADDWODQVU V1, V2, V3 + RET + +TEXT ·XVMADDWEVHBU(SB), NOSPLIT, $0 + XVMADDWEVHBU X1, X2, X3 + RET + +TEXT ·XVMADDWEVWHU(SB), NOSPLIT, $0 + XVMADDWEVWHU X1, X2, X3 + RET + +TEXT ·XVMADDWEVVWU(SB), NOSPLIT, $0 + XVMADDWEVVWU X1, X2, X3 + RET + +TEXT ·XVMADDWEVQVU(SB), NOSPLIT, $0 + XVMADDWEVQVU X1, X2, X3 + RET + +TEXT ·XVMADDWODHBU(SB), NOSPLIT, $0 + XVMADDWODHBU X1, X2, X3 + RET + +TEXT ·XVMADDWODWHU(SB), NOSPLIT, $0 + XVMADDWODWHU X1, X2, X3 + RET + +TEXT ·XVMADDWODVWU(SB), NOSPLIT, $0 + XVMADDWODVWU X1, X2, X3 + RET + +TEXT ·XVMADDWODQVU(SB), NOSPLIT, $0 + XVMADDWODQVU X1, X2, X3 + RET + +TEXT ·VMADDWEVHBUB(SB), NOSPLIT, $0 + VMADDWEVHBUB V1, V2, V3 + RET + +TEXT ·VMADDWEVWHUH(SB), NOSPLIT, $0 + VMADDWEVWHUH V1, V2, V3 + RET + +TEXT ·VMADDWEVVWUW(SB), NOSPLIT, $0 + VMADDWEVVWUW V1, V2, V3 + RET + +TEXT ·VMADDWEVQVUV(SB), NOSPLIT, $0 + VMADDWEVQVUV V1, V2, V3 + RET + +TEXT ·VMADDWODHBUB(SB), NOSPLIT, $0 + VMADDWODHBUB V1, V2, V3 + RET + +TEXT ·VMADDWODWHUH(SB), NOSPLIT, $0 + VMADDWODWHUH V1, V2, V3 + RET + +TEXT ·VMADDWODVWUW(SB), NOSPLIT, $0 + VMADDWODVWUW V1, V2, V3 + RET + +TEXT ·VMADDWODQVUV(SB), NOSPLIT, $0 + VMADDWODQVUV V1, V2, V3 + RET + +TEXT ·XVMADDWEVHBUB(SB), NOSPLIT, $0 + XVMADDWEVHBUB X1, X2, X3 + RET + +TEXT ·XVMADDWEVWHUH(SB), NOSPLIT, $0 + XVMADDWEVWHUH X1, X2, X3 + RET + +TEXT ·XVMADDWEVVWUW(SB), NOSPLIT, $0 + XVMADDWEVVWUW X1, X2, X3 + RET + +TEXT ·XVMADDWEVQVUV(SB), NOSPLIT, $0 + XVMADDWEVQVUV X1, X2, X3 + RET + +TEXT ·XVMADDWODHBUB(SB), NOSPLIT, $0 + XVMADDWODHBUB X1, X2, X3 + RET + +TEXT ·XVMADDWODWHUH(SB), NOSPLIT, $0 + XVMADDWODWHUH X1, X2, X3 + RET + +TEXT ·XVMADDWODVWUW(SB), NOSPLIT, $0 + XVMADDWODVWUW X1, X2, X3 + RET + +TEXT ·XVMADDWODQVUV(SB), NOSPLIT, $0 + XVMADDWODQVUV X1, X2, X3 + RET diff --git a/testdata/verify/vector_msub_loong64.s b/testdata/verify/vector_msub_loong64.s new file mode 100644 index 0000000..c8c8a28 --- /dev/null +++ b/testdata/verify/vector_msub_loong64.s @@ -0,0 +1,36 @@ +// Differential kernel: the msub vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VMSUBB(SB), NOSPLIT, $0 + VMSUBB V1, V2, V3 + RET + +TEXT ·VMSUBH(SB), NOSPLIT, $0 + VMSUBH V1, V2, V3 + RET + +TEXT ·VMSUBW(SB), NOSPLIT, $0 + VMSUBW V1, V2, V3 + RET + +TEXT ·VMSUBV(SB), NOSPLIT, $0 + VMSUBV V1, V2, V3 + RET + +TEXT ·XVMSUBB(SB), NOSPLIT, $0 + XVMSUBB X1, X2, X3 + RET + +TEXT ·XVMSUBH(SB), NOSPLIT, $0 + XVMSUBH X1, X2, X3 + RET + +TEXT ·XVMSUBW(SB), NOSPLIT, $0 + XVMSUBW X1, X2, X3 + RET + +TEXT ·XVMSUBV(SB), NOSPLIT, $0 + XVMSUBV X1, X2, X3 + RET diff --git a/testdata/verify/vector_mul_loong64.s b/testdata/verify/vector_mul_loong64.s new file mode 100644 index 0000000..79f89c6 --- /dev/null +++ b/testdata/verify/vector_mul_loong64.s @@ -0,0 +1,108 @@ +// Differential kernel: the mul vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VMULB(SB), NOSPLIT, $0 + VMULB V1, V2, V3 + RET + +TEXT ·VMULH(SB), NOSPLIT, $0 + VMULH V1, V2, V3 + RET + +TEXT ·VMULV(SB), NOSPLIT, $0 + VMULV V1, V2, V3 + RET + +TEXT ·VMUHB(SB), NOSPLIT, $0 + VMUHB V1, V2, V3 + RET + +TEXT ·VMUHH(SB), NOSPLIT, $0 + VMUHH V1, V2, V3 + RET + +TEXT ·VMUHW(SB), NOSPLIT, $0 + VMUHW V1, V2, V3 + RET + +TEXT ·VMUHV(SB), NOSPLIT, $0 + VMUHV V1, V2, V3 + RET + +TEXT ·VMUHBU(SB), NOSPLIT, $0 + VMUHBU V1, V2, V3 + RET + +TEXT ·VMUHHU(SB), NOSPLIT, $0 + VMUHHU V1, V2, V3 + RET + +TEXT ·VMUHWU(SB), NOSPLIT, $0 + VMUHWU V1, V2, V3 + RET + +TEXT ·VMUHVU(SB), NOSPLIT, $0 + VMUHVU V1, V2, V3 + RET + +TEXT ·XVMULB(SB), NOSPLIT, $0 + XVMULB X3, X2, X1 + RET + +TEXT ·XVMULH(SB), NOSPLIT, $0 + XVMULH X3, X2, X1 + RET + +TEXT ·XVMULV(SB), NOSPLIT, $0 + XVMULV X3, X2, X1 + RET + +TEXT ·XVMUHB(SB), NOSPLIT, $0 + XVMUHB X3, X2, X1 + RET + +TEXT ·XVMUHH(SB), NOSPLIT, $0 + XVMUHH X3, X2, X1 + RET + +TEXT ·XVMUHW(SB), NOSPLIT, $0 + XVMUHW X3, X2, X1 + RET + +TEXT ·XVMUHV(SB), NOSPLIT, $0 + XVMUHV X3, X2, X1 + RET + +TEXT ·XVMUHBU(SB), NOSPLIT, $0 + XVMUHBU X3, X2, X1 + RET + +TEXT ·XVMUHHU(SB), NOSPLIT, $0 + XVMUHHU X3, X2, X1 + RET + +TEXT ·XVMUHWU(SB), NOSPLIT, $0 + XVMUHWU X3, X2, X1 + RET + +TEXT ·XVMUHVU(SB), NOSPLIT, $0 + XVMUHVU X3, X2, X1 + RET + +TEXT ·VMULF(SB), NOSPLIT, $0 + VMULF V1, V2, V3 + RET + +TEXT ·VMULD(SB), NOSPLIT, $0 + VMULD V1, V2, V3 + RET + +TEXT ·XVMULF(SB), NOSPLIT, $0 + XVMULF X1, X2, X3 + RET + +TEXT ·XVMULD(SB), NOSPLIT, $0 + XVMULD X1, X2, X3 + RET diff --git a/testdata/verify/vector_mulwiden_loong64.s b/testdata/verify/vector_mulwiden_loong64.s new file mode 100644 index 0000000..d6f2f01 --- /dev/null +++ b/testdata/verify/vector_mulwiden_loong64.s @@ -0,0 +1,204 @@ +// Differential kernel: the mulwiden vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VMULW(SB), NOSPLIT, $0 + VMULW V1, V2, V3 + RET + +TEXT ·XVMULW(SB), NOSPLIT, $0 + XVMULW X3, X2, X1 + RET + +TEXT ·VMULWEVHB(SB), NOSPLIT, $0 + VMULWEVHB V1, V2, V3 + RET + +TEXT ·VMULWEVWH(SB), NOSPLIT, $0 + VMULWEVWH V1, V2, V3 + RET + +TEXT ·VMULWEVVW(SB), NOSPLIT, $0 + VMULWEVVW V1, V2, V3 + RET + +TEXT ·VMULWEVQV(SB), NOSPLIT, $0 + VMULWEVQV V1, V2, V3 + RET + +TEXT ·VMULWODHB(SB), NOSPLIT, $0 + VMULWODHB V1, V2, V3 + RET + +TEXT ·VMULWODWH(SB), NOSPLIT, $0 + VMULWODWH V1, V2, V3 + RET + +TEXT ·VMULWODVW(SB), NOSPLIT, $0 + VMULWODVW V1, V2, V3 + RET + +TEXT ·VMULWODQV(SB), NOSPLIT, $0 + VMULWODQV V1, V2, V3 + RET + +TEXT ·VMULWEVHBU(SB), NOSPLIT, $0 + VMULWEVHBU V1, V2, V3 + RET + +TEXT ·VMULWEVWHU(SB), NOSPLIT, $0 + VMULWEVWHU V1, V2, V3 + RET + +TEXT ·VMULWEVVWU(SB), NOSPLIT, $0 + VMULWEVVWU V1, V2, V3 + RET + +TEXT ·VMULWEVQVU(SB), NOSPLIT, $0 + VMULWEVQVU V1, V2, V3 + RET + +TEXT ·VMULWODHBU(SB), NOSPLIT, $0 + VMULWODHBU V1, V2, V3 + RET + +TEXT ·VMULWODWHU(SB), NOSPLIT, $0 + VMULWODWHU V1, V2, V3 + RET + +TEXT ·VMULWODVWU(SB), NOSPLIT, $0 + VMULWODVWU V1, V2, V3 + RET + +TEXT ·VMULWODQVU(SB), NOSPLIT, $0 + VMULWODQVU V1, V2, V3 + RET + +TEXT ·XVMULWEVHB(SB), NOSPLIT, $0 + XVMULWEVHB X1, X2, X3 + RET + +TEXT ·XVMULWEVWH(SB), NOSPLIT, $0 + XVMULWEVWH X1, X2, X3 + RET + +TEXT ·XVMULWEVVW(SB), NOSPLIT, $0 + XVMULWEVVW X1, X2, X3 + RET + +TEXT ·XVMULWEVQV(SB), NOSPLIT, $0 + XVMULWEVQV X1, X2, X3 + RET + +TEXT ·XVMULWODHB(SB), NOSPLIT, $0 + XVMULWODHB X1, X2, X3 + RET + +TEXT ·XVMULWODWH(SB), NOSPLIT, $0 + XVMULWODWH X1, X2, X3 + RET + +TEXT ·XVMULWODVW(SB), NOSPLIT, $0 + XVMULWODVW X1, X2, X3 + RET + +TEXT ·XVMULWODQV(SB), NOSPLIT, $0 + XVMULWODQV X1, X2, X3 + RET + +TEXT ·XVMULWEVHBU(SB), NOSPLIT, $0 + XVMULWEVHBU X1, X2, X3 + RET + +TEXT ·XVMULWEVWHU(SB), NOSPLIT, $0 + XVMULWEVWHU X1, X2, X3 + RET + +TEXT ·XVMULWEVVWU(SB), NOSPLIT, $0 + XVMULWEVVWU X1, X2, X3 + RET + +TEXT ·XVMULWEVQVU(SB), NOSPLIT, $0 + XVMULWEVQVU X1, X2, X3 + RET + +TEXT ·XVMULWODHBU(SB), NOSPLIT, $0 + XVMULWODHBU X1, X2, X3 + RET + +TEXT ·XVMULWODWHU(SB), NOSPLIT, $0 + XVMULWODWHU X1, X2, X3 + RET + +TEXT ·XVMULWODVWU(SB), NOSPLIT, $0 + XVMULWODVWU X1, X2, X3 + RET + +TEXT ·XVMULWODQVU(SB), NOSPLIT, $0 + XVMULWODQVU X1, X2, X3 + RET + +TEXT ·VMULWEVHBUB(SB), NOSPLIT, $0 + VMULWEVHBUB V1, V2, V3 + RET + +TEXT ·VMULWEVWHUH(SB), NOSPLIT, $0 + VMULWEVWHUH V1, V2, V3 + RET + +TEXT ·VMULWEVVWUW(SB), NOSPLIT, $0 + VMULWEVVWUW V1, V2, V3 + RET + +TEXT ·VMULWEVQVUV(SB), NOSPLIT, $0 + VMULWEVQVUV V1, V2, V3 + RET + +TEXT ·VMULWODHBUB(SB), NOSPLIT, $0 + VMULWODHBUB V1, V2, V3 + RET + +TEXT ·VMULWODWHUH(SB), NOSPLIT, $0 + VMULWODWHUH V1, V2, V3 + RET + +TEXT ·VMULWODVWUW(SB), NOSPLIT, $0 + VMULWODVWUW V1, V2, V3 + RET + +TEXT ·VMULWODQVUV(SB), NOSPLIT, $0 + VMULWODQVUV V1, V2, V3 + RET + +TEXT ·XVMULWEVHBUB(SB), NOSPLIT, $0 + XVMULWEVHBUB X1, X2, X3 + RET + +TEXT ·XVMULWEVWHUH(SB), NOSPLIT, $0 + XVMULWEVWHUH X1, X2, X3 + RET + +TEXT ·XVMULWEVVWUW(SB), NOSPLIT, $0 + XVMULWEVVWUW X1, X2, X3 + RET + +TEXT ·XVMULWEVQVUV(SB), NOSPLIT, $0 + XVMULWEVQVUV X1, X2, X3 + RET + +TEXT ·XVMULWODHBUB(SB), NOSPLIT, $0 + XVMULWODHBUB X1, X2, X3 + RET + +TEXT ·XVMULWODWHUH(SB), NOSPLIT, $0 + XVMULWODWHUH X1, X2, X3 + RET + +TEXT ·XVMULWODVWUW(SB), NOSPLIT, $0 + XVMULWODVWUW X1, X2, X3 + RET + +TEXT ·XVMULWODQVUV(SB), NOSPLIT, $0 + XVMULWODQVUV X1, X2, X3 + RET diff --git a/testdata/verify/vector_shift_loong64.s b/testdata/verify/vector_shift_loong64.s new file mode 100644 index 0000000..503b8f9 --- /dev/null +++ b/testdata/verify/vector_shift_loong64.s @@ -0,0 +1,214 @@ +// Differential kernel: the shift vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VSLLB(SB), NOSPLIT, $0 + VSLLB V1, V2, V3 + VSLLB $0, V1, V2 + VSLLB $7, V1, V2 + VSLLB $5, V1 + RET + +TEXT ·VSLLH(SB), NOSPLIT, $0 + VSLLH V1, V2, V3 + VSLLH $0, V1, V2 + VSLLH $15, V1, V2 + VSLLH $10, V1 + RET + +TEXT ·VSLLW(SB), NOSPLIT, $0 + VSLLW V1, V2, V3 + VSLLW $0, V1, V2 + VSLLW $31, V1, V2 + VSLLW $11, V1 + RET + +TEXT ·VSLLV(SB), NOSPLIT, $0 + VSLLV V1, V2, V3 + VSLLV $0, V1, V2 + VSLLV $63, V1, V2 + VSLLV $30, V1 + RET + +TEXT ·VSRLB(SB), NOSPLIT, $0 + VSRLB V1, V2, V3 + VSRLB $0, V1, V2 + VSRLB $7, V1, V2 + VSRLB $4, V1 + RET + +TEXT ·VSRLH(SB), NOSPLIT, $0 + VSRLH V1, V2, V3 + VSRLH $0, V1, V2 + VSRLH $15, V1, V2 + VSRLH $9, V1 + RET + +TEXT ·VSRLW(SB), NOSPLIT, $0 + VSRLW V1, V2, V3 + VSRLW $0, V1, V2 + VSRLW $31, V1, V2 + VSRLW $16, V1 + RET + +TEXT ·VSRLV(SB), NOSPLIT, $0 + VSRLV V1, V2, V3 + VSRLV $0, V1, V2 + VSRLV $63, V1, V2 + VSRLV $40, V1 + RET + +TEXT ·VSRAH(SB), NOSPLIT, $0 + VSRAH V1, V2, V3 + VSRAH $0, V1, V2 + VSRAH $15, V1, V2 + VSRAH $8, V1 + RET + +TEXT ·VSRAW(SB), NOSPLIT, $0 + VSRAW V1, V2, V3 + VSRAW $0, V1, V2 + VSRAW $31, V1, V2 + VSRAW $12, V1 + RET + +TEXT ·VSRAV(SB), NOSPLIT, $0 + VSRAV V1, V2, V3 + VSRAV $0, V1, V2 + VSRAV $63, V1, V2 + VSRAV $50, V1 + RET + +TEXT ·VROTRB(SB), NOSPLIT, $0 + VROTRB V1, V2, V3 + VROTRB $0, V1, V2 + VROTRB $7, V1, V2 + VROTRB $3, V1 + RET + +TEXT ·VROTRH(SB), NOSPLIT, $0 + VROTRH V1, V2, V3 + VROTRH $0, V1, V2 + VROTRH $15, V1, V2 + VROTRH $5, V1 + RET + +TEXT ·VROTRV(SB), NOSPLIT, $0 + VROTRV V1, V2, V3 + VROTRV $0, V1, V2 + VROTRV $63, V1, V2 + VROTRV $52, V1 + RET + +TEXT ·XVSLLB(SB), NOSPLIT, $0 + XVSLLB X3, X2, X1 + XVSLLB $0, X2, X1 + XVSLLB $7, X2, X1 + XVSLLB $4, X2 + RET + +TEXT ·XVSLLH(SB), NOSPLIT, $0 + XVSLLH X3, X2, X1 + XVSLLH $0, X2, X1 + XVSLLH $15, X2, X1 + XVSLLH $8, X2 + RET + +TEXT ·XVSLLW(SB), NOSPLIT, $0 + XVSLLW X3, X2, X1 + XVSLLW $0, X2, X1 + XVSLLW $31, X2, X1 + XVSLLW $13, X2 + RET + +TEXT ·XVSLLV(SB), NOSPLIT, $0 + XVSLLV X3, X2, X1 + XVSLLV $0, X2, X1 + XVSLLV $63, X2, X1 + XVSLLV $36, X2 + RET + +TEXT ·XVSRLB(SB), NOSPLIT, $0 + XVSRLB X3, X2, X1 + XVSRLB $0, X2, X1 + XVSRLB $7, X2, X1 + XVSRLB $5, X2 + RET + +TEXT ·XVSRLH(SB), NOSPLIT, $0 + XVSRLH X3, X2, X1 + XVSRLH $0, X2, X1 + XVSRLH $15, X2, X1 + XVSRLH $9, X2 + RET + +TEXT ·XVSRLW(SB), NOSPLIT, $0 + XVSRLW X3, X2, X1 + XVSRLW $0, X2, X1 + XVSRLW $31, X2, X1 + XVSRLW $14, X2 + RET + +TEXT ·XVSRLV(SB), NOSPLIT, $0 + XVSRLV X3, X2, X1 + XVSRLV $0, X2, X1 + XVSRLV $63, X2, X1 + XVSRLV $45, X2 + RET + +TEXT ·XVSRAB(SB), NOSPLIT, $0 + XVSRAB X3, X2, X1 + XVSRAB $0, X2, X1 + XVSRAB $7, X2, X1 + XVSRAB $6, X2 + RET + +TEXT ·XVSRAH(SB), NOSPLIT, $0 + XVSRAH X3, X2, X1 + XVSRAH $0, X2, X1 + XVSRAH $15, X2, X1 + XVSRAH $10, X2 + RET + +TEXT ·XVSRAW(SB), NOSPLIT, $0 + XVSRAW X3, X2, X1 + XVSRAW $0, X2, X1 + XVSRAW $31, X2, X1 + XVSRAW $16, X2 + RET + +TEXT ·XVSRAV(SB), NOSPLIT, $0 + XVSRAV X3, X2, X1 + XVSRAV $0, X2, X1 + XVSRAV $63, X2, X1 + XVSRAV $48, X2 + RET + +TEXT ·XVROTRB(SB), NOSPLIT, $0 + XVROTRB X3, X2, X1 + XVROTRB $0, X2, X1 + XVROTRB $7, X2, X1 + XVROTRB $3, X2 + RET + +TEXT ·XVROTRH(SB), NOSPLIT, $0 + XVROTRH X3, X2, X1 + XVROTRH $0, X2, X1 + XVROTRH $15, X2, X1 + XVROTRH $13, X2 + RET + +TEXT ·XVROTRW(SB), NOSPLIT, $0 + XVROTRW X3, X2, X1 + XVROTRW $0, X2, X1 + XVROTRW $31, X2, X1 + XVROTRW $24, X2 + RET + +TEXT ·XVROTRV(SB), NOSPLIT, $0 + XVROTRV X3, X2, X1 + XVROTRV $0, X2, X1 + XVROTRV $63, X2, X1 + XVROTRV $52, X2 + RET diff --git a/testdata/verify/vector_shuffle_loong64.s b/testdata/verify/vector_shuffle_loong64.s new file mode 100644 index 0000000..be978dc --- /dev/null +++ b/testdata/verify/vector_shuffle_loong64.s @@ -0,0 +1,132 @@ +// Differential kernel: the shuffle vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VSHUF4IB(SB), NOSPLIT, $0 + VSHUF4IB $0, V2, V1 + VSHUF4IB $16, V2, V1 + VSHUF4IB $255, V2, V1 + RET + +TEXT ·VSHUF4IH(SB), NOSPLIT, $0 + VSHUF4IH $0, V2, V1 + VSHUF4IH $128, V2, V1 + VSHUF4IH $255, V2, V1 + RET + +TEXT ·VSHUF4IW(SB), NOSPLIT, $0 + VSHUF4IW $0, V2, V1 + VSHUF4IW $96, V2, V1 + VSHUF4IW $255, V2, V1 + RET + +TEXT ·VSHUF4IV(SB), NOSPLIT, $0 + VSHUF4IV $0, V2, V1 + VSHUF4IV $8, V2, V1 + VSHUF4IV $15, V2, V1 + RET + +TEXT ·XVSHUF4IB(SB), NOSPLIT, $0 + XVSHUF4IB $0, X1, X2 + XVSHUF4IB $16, X1, X2 + XVSHUF4IB $255, X1, X2 + RET + +TEXT ·XVSHUF4IH(SB), NOSPLIT, $0 + XVSHUF4IH $0, X1, X2 + XVSHUF4IH $128, X1, X2 + XVSHUF4IH $255, X1, X2 + RET + +TEXT ·XVSHUF4IW(SB), NOSPLIT, $0 + XVSHUF4IW $0, X1, X2 + XVSHUF4IW $96, X1, X2 + XVSHUF4IW $255, X1, X2 + RET + +TEXT ·XVSHUF4IV(SB), NOSPLIT, $0 + XVSHUF4IV $0, X1, X2 + XVSHUF4IV $8, X1, X2 + XVSHUF4IV $15, X1, X2 + RET + +TEXT ·VSHUFH(SB), NOSPLIT, $0 + VSHUFH V1, V2, V3 + RET + +TEXT ·VSHUFW(SB), NOSPLIT, $0 + VSHUFW V1, V2, V3 + RET + +TEXT ·VSHUFV(SB), NOSPLIT, $0 + VSHUFV V1, V2, V3 + RET + +TEXT ·XVSHUFH(SB), NOSPLIT, $0 + XVSHUFH X1, X2, X3 + RET + +TEXT ·XVSHUFW(SB), NOSPLIT, $0 + XVSHUFW X1, X2, X3 + RET + +TEXT ·XVSHUFV(SB), NOSPLIT, $0 + XVSHUFV X1, X2, X3 + RET + +TEXT ·VSHUFB(SB), NOSPLIT, $0 + VSHUFB V1, V2, V3, V4 + RET + +TEXT ·XVSHUFB(SB), NOSPLIT, $0 + XVSHUFB X1, X2, X3, X4 + RET + +TEXT ·VPERMIW(SB), NOSPLIT, $0 + VPERMIW $0x1B, V1, V2 + RET + +TEXT ·XVPERMIW(SB), NOSPLIT, $0 + XVPERMIW $0x2B, X1, X2 + RET + +TEXT ·XVPERMIV(SB), NOSPLIT, $0 + XVPERMIV $0x3B, X1, X2 + RET + +TEXT ·XVPERMIQ(SB), NOSPLIT, $0 + XVPERMIQ $0x4B, X1, X2 + RET + +TEXT ·VEXTRINSB(SB), NOSPLIT, $0 + VEXTRINSB $0x18, V1, V2 + RET + +TEXT ·VEXTRINSH(SB), NOSPLIT, $0 + VEXTRINSH $0x27, V1, V2 + RET + +TEXT ·VEXTRINSW(SB), NOSPLIT, $0 + VEXTRINSW $0x36, V1, V2 + RET + +TEXT ·VEXTRINSV(SB), NOSPLIT, $0 + VEXTRINSV $0x45, V1, V2 + RET + +TEXT ·XVEXTRINSB(SB), NOSPLIT, $0 + XVEXTRINSB $0x54, X1, X2 + RET + +TEXT ·XVEXTRINSH(SB), NOSPLIT, $0 + XVEXTRINSH $0x63, X1, X2 + RET + +TEXT ·XVEXTRINSW(SB), NOSPLIT, $0 + XVEXTRINSW $0x72, X1, X2 + RET + +TEXT ·XVEXTRINSV(SB), NOSPLIT, $0 + XVEXTRINSV $0x81, X1, X2 + RET diff --git a/testdata/verify/vector_unary_loong64.s b/testdata/verify/vector_unary_loong64.s new file mode 100644 index 0000000..bb68394 --- /dev/null +++ b/testdata/verify/vector_unary_loong64.s @@ -0,0 +1,108 @@ +// Differential kernel: the unary vector slice against the Go +// toolchain's loong64enc1.s rows (gasm v. go tool asm, byte for byte). + +#include "textflag.h" + +TEXT ·VPCNTB(SB), NOSPLIT, $0 + VPCNTB V1, V2 + RET + +TEXT ·VPCNTH(SB), NOSPLIT, $0 + VPCNTH V1, V2 + RET + +TEXT ·VPCNTW(SB), NOSPLIT, $0 + VPCNTW V1, V2 + RET + +TEXT ·XVPCNTB(SB), NOSPLIT, $0 + XVPCNTB X3, X2 + RET + +TEXT ·XVPCNTH(SB), NOSPLIT, $0 + XVPCNTH X3, X2 + RET + +TEXT ·XVPCNTW(SB), NOSPLIT, $0 + XVPCNTW X3, X2 + RET + +TEXT ·VNEGB(SB), NOSPLIT, $0 + VNEGB V1, V2 + RET + +TEXT ·VNEGH(SB), NOSPLIT, $0 + VNEGH V1, V2 + RET + +TEXT ·VNEGW(SB), NOSPLIT, $0 + VNEGW V1, V2 + RET + +TEXT ·VNEGV(SB), NOSPLIT, $0 + VNEGV V1, V2 + RET + +TEXT ·XVNEGB(SB), NOSPLIT, $0 + XVNEGB X2, X1 + RET + +TEXT ·XVNEGH(SB), NOSPLIT, $0 + XVNEGH X2, X1 + RET + +TEXT ·XVNEGW(SB), NOSPLIT, $0 + XVNEGW X2, X1 + RET + +TEXT ·XVNEGV(SB), NOSPLIT, $0 + XVNEGV X2, X1 + RET + +TEXT ·VSETEQV(SB), NOSPLIT, $0 + VSETEQV V1, FCC0 + RET + +TEXT ·XVSETEQV(SB), NOSPLIT, $0 + XVSETEQV X1, FCC0 + RET + +TEXT ·VSETANYEQH(SB), NOSPLIT, $0 + VSETANYEQH V1, FCC0 + RET + +TEXT ·VSETANYEQW(SB), NOSPLIT, $0 + VSETANYEQW V1, FCC0 + RET + +TEXT ·VSETALLNEB(SB), NOSPLIT, $0 + VSETALLNEB V1, FCC0 + RET + +TEXT ·VSETALLNEH(SB), NOSPLIT, $0 + VSETALLNEH V1, FCC0 + RET + +TEXT ·VSETALLNEW(SB), NOSPLIT, $0 + VSETALLNEW V1, FCC0 + RET + +TEXT ·XVSETANYEQH(SB), NOSPLIT, $0 + XVSETANYEQH X1, FCC0 + RET + +TEXT ·XVSETANYEQW(SB), NOSPLIT, $0 + XVSETANYEQW X1, FCC0 + RET + +TEXT ·XVSETALLNEB(SB), NOSPLIT, $0 + XVSETALLNEB X1, FCC0 + RET + +TEXT ·XVSETALLNEH(SB), NOSPLIT, $0 + XVSETALLNEH X1, FCC0 + RET + +TEXT ·XVSETALLNEW(SB), NOSPLIT, $0 + XVSETALLNEW X1, FCC0 + RET