feat(loong64): encode the full LSX and LASX table
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user