
added loong64 support for gnu format disassembler and plan9 format disassembler in golang.org/x/arch $ go get -u golang.org/x/arch@v0.11.0 $ go mod tidy $ go mod vendor Co-authored-by: Huang Qiqi <huangqiqi@loongson.cn>
542 lines
13 KiB
Go
542 lines
13 KiB
Go
// Copyright 2024 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package loong64asm
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// GoSyntax returns the Go assembler syntax for the instruction.
|
|
// The syntax was originally defined by Plan 9.
|
|
// The pc is the program counter of the instruction, used for
|
|
// expanding PC-relative addresses into absolute ones.
|
|
// The symname function queries the symbol table for the program
|
|
// being disassembled. Given a target address it returns the name
|
|
// and base address of the symbol containing the target, if any;
|
|
// otherwise it returns "", 0.
|
|
func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) string {
|
|
if symname == nil {
|
|
symname = func(uint64) (string, uint64) { return "", 0 }
|
|
}
|
|
if inst.Op == 0 && inst.Enc == 0 {
|
|
return "WORD $0"
|
|
} else if inst.Op == 0 {
|
|
return "?"
|
|
}
|
|
|
|
var args []string
|
|
for _, a := range inst.Args {
|
|
if a == nil {
|
|
break
|
|
}
|
|
args = append(args, plan9Arg(&inst, pc, symname, a))
|
|
}
|
|
|
|
var op string = plan9OpMap[inst.Op]
|
|
if op == "" {
|
|
op = "Unknown " + inst.Op.String()
|
|
}
|
|
|
|
switch inst.Op {
|
|
case BSTRPICK_W, BSTRPICK_D, BSTRINS_W, BSTRINS_D:
|
|
msbw, lsbw := inst.Args[2].(Uimm), inst.Args[3].(Uimm)
|
|
if inst.Op == BSTRPICK_D && msbw.Imm == 15 && lsbw.Imm == 0 {
|
|
op = "MOVHU"
|
|
args = append(args[1:2], args[0:1]...)
|
|
} else {
|
|
args[0], args[2], args[3] = args[2], args[3], args[0]
|
|
}
|
|
|
|
case BCNEZ, BCEQZ:
|
|
args = args[1:2]
|
|
|
|
case BEQ, BNE:
|
|
rj := inst.Args[0].(Reg)
|
|
rd := inst.Args[1].(Reg)
|
|
if rj == rd && inst.Op == BEQ {
|
|
op = "JMP"
|
|
args = args[2:]
|
|
} else if rj == R0 {
|
|
args = args[1:]
|
|
} else if rd == R0 {
|
|
args = append(args[:1], args[2:]...)
|
|
}
|
|
|
|
case BEQZ, BNEZ:
|
|
if inst.Args[0].(Reg) == R0 && inst.Op == BEQ {
|
|
op = "JMP"
|
|
args = args[1:]
|
|
}
|
|
|
|
case BLT, BLTU, BGE, BGEU:
|
|
rj := inst.Args[0].(Reg)
|
|
rd := inst.Args[1].(Reg)
|
|
if rj == rd && (inst.Op == BGE || inst.Op == BGEU) {
|
|
op = "JMP"
|
|
args = args[2:]
|
|
} else if rj == R0 {
|
|
switch inst.Op {
|
|
case BGE:
|
|
op = "BLEZ"
|
|
case BLT:
|
|
op = "BGTZ"
|
|
}
|
|
args = args[1:]
|
|
} else if rd == R0 {
|
|
if !strings.HasSuffix(op, "U") {
|
|
op += "Z"
|
|
}
|
|
args = append(args[:1], args[2:]...)
|
|
}
|
|
|
|
case JIRL:
|
|
rd := inst.Args[0].(Reg)
|
|
rj := inst.Args[1].(Reg)
|
|
regno := uint16(rj) & 31
|
|
off := inst.Args[2].(OffsetSimm).Imm
|
|
if rd == R0 && rj == R1 && off == 0 {
|
|
return fmt.Sprintf("RET")
|
|
} else if rd == R0 && off == 0 {
|
|
return fmt.Sprintf("JMP (R%d)", regno)
|
|
} else if rd == R0 {
|
|
return fmt.Sprintf("JMP %d(R%d)", off, regno)
|
|
}
|
|
return fmt.Sprintf("CALL (R%d)", regno)
|
|
|
|
case LD_B, LD_H, LD_W, LD_D, LD_BU, LD_HU, LD_WU, LL_W, LL_D,
|
|
ST_B, ST_H, ST_W, ST_D, SC_W, SC_D, FLD_S, FLD_D, FST_S, FST_D:
|
|
var off int32
|
|
switch a := inst.Args[2].(type) {
|
|
case Simm16:
|
|
off = signumConvInt32(int32(a.Imm), a.Width)
|
|
case Simm32:
|
|
off = signumConvInt32(int32(a.Imm), a.Width) >> 2
|
|
}
|
|
Iop := strings.ToUpper(inst.Op.String())
|
|
if strings.HasPrefix(Iop, "L") || strings.HasPrefix(Iop, "FL") {
|
|
return fmt.Sprintf("%s %d(%s), %s", op, off, args[1], args[0])
|
|
}
|
|
return fmt.Sprintf("%s %s, %d(%s)", op, args[0], off, args[1])
|
|
|
|
case LDX_B, LDX_H, LDX_W, LDX_D, LDX_BU, LDX_HU, LDX_WU, FLDX_S, FLDX_D,
|
|
STX_B, STX_H, STX_W, STX_D, FSTX_S, FSTX_D:
|
|
Iop := strings.ToUpper(inst.Op.String())
|
|
if strings.HasPrefix(Iop, "L") || strings.HasPrefix(Iop, "FL") {
|
|
return fmt.Sprintf("%s (%s)(%s), %s", op, args[1], args[2], args[0])
|
|
}
|
|
return fmt.Sprintf("%s %s, (%s)(%s)", op, args[0], args[1], args[2])
|
|
|
|
case AMADD_B, AMADD_D, AMADD_DB_B, AMADD_DB_D, AMADD_DB_H, AMADD_DB_W, AMADD_H,
|
|
AMADD_W, AMAND_D, AMAND_DB_D, AMAND_DB_W, AMAND_W, AMCAS_B, AMCAS_D, AMCAS_DB_B,
|
|
AMCAS_DB_D, AMCAS_DB_H, AMCAS_DB_W, AMCAS_H, AMCAS_W, AMMAX_D, AMMAX_DB_D,
|
|
AMMAX_DB_DU, AMMAX_DB_W, AMMAX_DB_WU, AMMAX_DU, AMMAX_W, AMMAX_WU, AMMIN_D,
|
|
AMMIN_DB_D, AMMIN_DB_DU, AMMIN_DB_W, AMMIN_DB_WU, AMMIN_DU, AMMIN_W, AMMIN_WU,
|
|
AMOR_D, AMOR_DB_D, AMOR_DB_W, AMOR_W, AMSWAP_B, AMSWAP_D, AMSWAP_DB_B, AMSWAP_DB_D,
|
|
AMSWAP_DB_H, AMSWAP_DB_W, AMSWAP_H, AMSWAP_W, AMXOR_D, AMXOR_DB_D, AMXOR_DB_W, AMXOR_W:
|
|
return fmt.Sprintf("%s %s, (%s), %s", op, args[1], args[2], args[0])
|
|
|
|
default:
|
|
// Reverse args, placing dest last
|
|
for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
|
|
args[i], args[j] = args[j], args[i]
|
|
}
|
|
switch len(args) { // Special use cases
|
|
case 0, 1:
|
|
if inst.Op != B && inst.Op != BL {
|
|
return op
|
|
}
|
|
|
|
case 3:
|
|
switch a0 := inst.Args[0].(type) {
|
|
case Reg:
|
|
rj := inst.Args[1].(Reg)
|
|
if a0 == rj && a0 != R0 {
|
|
args = args[0:2]
|
|
}
|
|
}
|
|
switch inst.Op {
|
|
case SUB_W, SUB_D, ADDI_W, ADDI_D, ORI:
|
|
rj := inst.Args[1].(Reg)
|
|
if rj == R0 {
|
|
args = append(args[0:1], args[2:]...)
|
|
if inst.Op == SUB_W {
|
|
op = "NEGW"
|
|
} else if inst.Op == SUB_D {
|
|
op = "NEGV"
|
|
} else {
|
|
op = "MOVW"
|
|
}
|
|
}
|
|
|
|
case ANDI:
|
|
ui12 := inst.Args[2].(Uimm)
|
|
if ui12.Imm == uint32(0xff) {
|
|
op = "MOVBU"
|
|
args = args[1:]
|
|
} else if ui12.Imm == 0 && inst.Args[0].(Reg) == R0 && inst.Args[1].(Reg) == R0 {
|
|
return "NOOP"
|
|
}
|
|
|
|
case SLL_W, OR:
|
|
rk := inst.Args[2].(Reg)
|
|
if rk == R0 {
|
|
args = args[1:]
|
|
if inst.Op == SLL_W {
|
|
op = "MOVW"
|
|
} else {
|
|
op = "MOVV"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if args != nil {
|
|
op += " " + strings.Join(args, ", ")
|
|
}
|
|
return op
|
|
}
|
|
|
|
func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
|
|
// Reg: gpr[0, 31] and fpr[0, 31]
|
|
// Fcsr: fcsr[0, 3]
|
|
// Fcc: fcc[0, 7]
|
|
// Uimm: unsigned integer constant
|
|
// Simm16: si16
|
|
// Simm32: si32
|
|
// OffsetSimm: si32
|
|
switch a := arg.(type) {
|
|
case Reg:
|
|
regenum := uint16(a)
|
|
regno := uint16(a) & 0x1f
|
|
// General-purpose register
|
|
if regenum >= uint16(R0) && regenum <= uint16(R31) {
|
|
return fmt.Sprintf("R%d", regno)
|
|
} else { // Float point register
|
|
return fmt.Sprintf("F%d", regno)
|
|
}
|
|
|
|
case Fcsr:
|
|
regno := uint8(a) & 0x1f
|
|
return fmt.Sprintf("FCSR%d", regno)
|
|
|
|
case Fcc:
|
|
regno := uint8(a) & 0x1f
|
|
return fmt.Sprintf("FCC%d", regno)
|
|
|
|
case Uimm:
|
|
return fmt.Sprintf("$%d", a.Imm)
|
|
|
|
case Simm16:
|
|
si16 := signumConvInt32(int32(a.Imm), a.Width)
|
|
return fmt.Sprintf("$%d", si16)
|
|
|
|
case Simm32:
|
|
si32 := signumConvInt32(a.Imm, a.Width)
|
|
return fmt.Sprintf("$%d", si32)
|
|
|
|
case OffsetSimm:
|
|
offs := offsConvInt32(a.Imm, a.Width)
|
|
if inst.Op == B || inst.Op == BL {
|
|
addr := int64(pc) + int64(a.Imm)
|
|
if s, base := symname(uint64(addr)); s != "" && uint64(addr) == base {
|
|
return fmt.Sprintf("%s(SB)", s)
|
|
}
|
|
}
|
|
return fmt.Sprintf("%d(PC)", offs>>2)
|
|
|
|
case SaSimm:
|
|
return fmt.Sprintf("$%d", a)
|
|
|
|
case CodeSimm:
|
|
return fmt.Sprintf("$%d", a)
|
|
|
|
}
|
|
return strings.ToUpper(arg.String())
|
|
}
|
|
|
|
func signumConvInt32(imm int32, width uint8) int32 {
|
|
active := uint32(1<<width) - 1
|
|
signum := uint32(imm) & active
|
|
if ((signum >> (width - 1)) & 0x1) == 1 {
|
|
signum |= ^active
|
|
}
|
|
return int32(signum)
|
|
}
|
|
|
|
func offsConvInt32(imm int32, width uint8) int32 {
|
|
relWidth := width + 2
|
|
return signumConvInt32(imm, relWidth)
|
|
}
|
|
|
|
var plan9OpMap = map[Op]string{
|
|
ADD_W: "ADD",
|
|
ADD_D: "ADDV",
|
|
SUB_W: "SUB",
|
|
SUB_D: "SUBV",
|
|
ADDI_W: "ADD",
|
|
ADDI_D: "ADDV",
|
|
LU12I_W: "LU12IW",
|
|
LU32I_D: "LU32ID",
|
|
LU52I_D: "LU52ID",
|
|
SLT: "SGT",
|
|
SLTU: "SGTU",
|
|
SLTI: "SGT",
|
|
SLTUI: "SGTU",
|
|
PCADDU12I: "PCADDU12I",
|
|
PCALAU12I: "PCALAU12I",
|
|
AND: "AND",
|
|
OR: "OR",
|
|
NOR: "NOR",
|
|
XOR: "XOR",
|
|
ANDI: "AND",
|
|
ORI: "OR",
|
|
XORI: "XOR",
|
|
MUL_W: "MUL",
|
|
MULH_W: "MULH",
|
|
MULH_WU: "MULHU",
|
|
MUL_D: "MULV",
|
|
MULH_D: "MULHV",
|
|
MULH_DU: "MULHVU",
|
|
DIV_W: "DIV",
|
|
DIV_WU: "DIVU",
|
|
DIV_D: "DIVV",
|
|
DIV_DU: "DIVVU",
|
|
MOD_W: "REM",
|
|
MOD_WU: "REMU",
|
|
MOD_D: "REMV",
|
|
MOD_DU: "REMVU",
|
|
SLL_W: "SLL",
|
|
SRL_W: "SRL",
|
|
SRA_W: "SRA",
|
|
ROTR_W: "ROTR",
|
|
SLL_D: "SLLV",
|
|
SRL_D: "SRLV",
|
|
SRA_D: "SRAV",
|
|
ROTR_D: "ROTRV",
|
|
SLLI_W: "SLL",
|
|
SRLI_W: "SRL",
|
|
SRAI_W: "SRA",
|
|
ROTRI_W: "ROTR",
|
|
SLLI_D: "SLLV",
|
|
SRLI_D: "SRLV",
|
|
SRAI_D: "SRAV",
|
|
ROTRI_D: "ROTRV",
|
|
EXT_W_B: "?",
|
|
EXT_W_H: "?",
|
|
BITREV_W: "BITREVW",
|
|
BITREV_D: "BITREVV",
|
|
CLO_W: "CLOW",
|
|
CLO_D: "CLOV",
|
|
CLZ_W: "CLZW",
|
|
CLZ_D: "CLZV",
|
|
CTO_W: "CTOW",
|
|
CTO_D: "CTOV",
|
|
CTZ_W: "CTZW",
|
|
CTZ_D: "CTZV",
|
|
REVB_2H: "REVB2H",
|
|
REVB_2W: "REVB2W",
|
|
REVB_4H: "REVB4H",
|
|
REVB_D: "REVBV",
|
|
BSTRPICK_W: "BSTRPICKW",
|
|
BSTRPICK_D: "BSTRPICKV",
|
|
BSTRINS_W: "BSTRINSW",
|
|
BSTRINS_D: "BSTRINSV",
|
|
MASKEQZ: "MASKEQZ",
|
|
MASKNEZ: "MASKNEZ",
|
|
BCNEZ: "BFPT",
|
|
BCEQZ: "BFPF",
|
|
BEQ: "BEQ",
|
|
BNE: "BNE",
|
|
BEQZ: "BEQ",
|
|
BNEZ: "BNE",
|
|
BLT: "BLT",
|
|
BLTU: "BLTU",
|
|
BGE: "BGE",
|
|
BGEU: "BGEU",
|
|
B: "JMP",
|
|
BL: "CALL",
|
|
LD_B: "MOVB",
|
|
LD_H: "MOVH",
|
|
LD_W: "MOVW",
|
|
LD_D: "MOVV",
|
|
LD_BU: "MOVBU",
|
|
LD_HU: "MOVHU",
|
|
LD_WU: "MOVWU",
|
|
ST_B: "MOVB",
|
|
ST_H: "MOVH",
|
|
ST_W: "MOVW",
|
|
ST_D: "MOVV",
|
|
LDX_B: "MOVB",
|
|
LDX_BU: "MOVBU",
|
|
LDX_D: "MOVV",
|
|
LDX_H: "MOVH",
|
|
LDX_HU: "MOVHU",
|
|
LDX_W: "MOVW",
|
|
LDX_WU: "MOVWU",
|
|
STX_B: "MOVB",
|
|
STX_D: "MOVV",
|
|
STX_H: "MOVH",
|
|
STX_W: "MOVW",
|
|
AMADD_B: "AMADDB",
|
|
AMADD_D: "AMADDV",
|
|
AMADD_DB_B: "AMADDDBB",
|
|
AMADD_DB_D: "AMADDDBV",
|
|
AMADD_DB_H: "AMADDDBH",
|
|
AMADD_DB_W: "AMADDDBW",
|
|
AMADD_H: "AMADDH",
|
|
AMADD_W: "AMADDW",
|
|
AMAND_D: "AMANDV",
|
|
AMAND_DB_D: "AMANDDBV",
|
|
AMAND_DB_W: "AMANDDBW",
|
|
AMAND_W: "AMANDW",
|
|
AMCAS_B: "AMCASB",
|
|
AMCAS_D: "AMCASV",
|
|
AMCAS_DB_B: "AMCASDBB",
|
|
AMCAS_DB_D: "AMCASDBV",
|
|
AMCAS_DB_H: "AMCASDBH",
|
|
AMCAS_DB_W: "AMCASDBW",
|
|
AMCAS_H: "AMCASH",
|
|
AMCAS_W: "AMCASW",
|
|
AMMAX_D: "AMMAXV",
|
|
AMMAX_DB_D: "AMMAXDBV",
|
|
AMMAX_DB_DU: "AMMAXDBVU",
|
|
AMMAX_DB_W: "AMMAXDBW",
|
|
AMMAX_DB_WU: "AMMAXDBWU",
|
|
AMMAX_DU: "AMMAXVU",
|
|
AMMAX_W: "AMMAXW",
|
|
AMMAX_WU: "AMMAXWU",
|
|
AMMIN_D: "AMMINV",
|
|
AMMIN_DB_D: "AMMINDBV",
|
|
AMMIN_DB_DU: "AMMINDBVU",
|
|
AMMIN_DB_W: "AMMINDBW",
|
|
AMMIN_DB_WU: "AMMINDBWU",
|
|
AMMIN_DU: "AMMINVU",
|
|
AMMIN_W: "AMMINW",
|
|
AMMIN_WU: "AMMINWU",
|
|
AMOR_D: "AMORV",
|
|
AMOR_DB_D: "AMORDBV",
|
|
AMOR_DB_W: "AMORDBW",
|
|
AMOR_W: "AMORW",
|
|
AMSWAP_B: "AMSWAPB",
|
|
AMSWAP_D: "AMSWAPV",
|
|
AMSWAP_DB_B: "AMSWAPDBB",
|
|
AMSWAP_DB_D: "AMSWAPDBV",
|
|
AMSWAP_DB_H: "AMSWAPDBH",
|
|
AMSWAP_DB_W: "AMSWAPDBW",
|
|
AMSWAP_H: "AMSWAPH",
|
|
AMSWAP_W: "AMSWAPW",
|
|
AMXOR_D: "AMXORV",
|
|
AMXOR_DB_D: "AMXORDBV",
|
|
AMXOR_DB_W: "AMXORDBW",
|
|
AMXOR_W: "AMXORW",
|
|
LL_W: "LL",
|
|
LL_D: "LLV",
|
|
SC_W: "SC",
|
|
SC_D: "SCV",
|
|
CRCC_W_B_W: "CRCCWBW",
|
|
CRCC_W_D_W: "CRCCWVW",
|
|
CRCC_W_H_W: "CRCCWHW",
|
|
CRCC_W_W_W: "CRCCWWW",
|
|
CRC_W_B_W: "CRCWBW",
|
|
CRC_W_D_W: "CRCWVW",
|
|
CRC_W_H_W: "CRCWHW",
|
|
CRC_W_W_W: "CRCWWW",
|
|
DBAR: "DBAR",
|
|
SYSCALL: "SYSCALL",
|
|
BREAK: "BREAK",
|
|
RDTIMEL_W: "RDTIMELW",
|
|
RDTIMEH_W: "RDTIMEHW",
|
|
RDTIME_D: "RDTIMED",
|
|
CPUCFG: "CPUCFG",
|
|
|
|
// Floating-point instructions
|
|
FADD_S: "ADDF",
|
|
FADD_D: "ADDD",
|
|
FSUB_S: "SUBF",
|
|
FSUB_D: "SUBD",
|
|
FMUL_S: "MULF",
|
|
FMUL_D: "MULD",
|
|
FDIV_S: "DIVF",
|
|
FDIV_D: "DIVD",
|
|
FMSUB_S: "FMSUBF",
|
|
FMSUB_D: "FMSUBD",
|
|
FMADD_S: "FMADDF",
|
|
FMADD_D: "FMADDD",
|
|
FNMADD_S: "FNMADDF",
|
|
FNMADD_D: "FNMADDD",
|
|
FNMSUB_S: "FNMSUBF",
|
|
FNMSUB_D: "FNMSUBD",
|
|
FABS_S: "ABSF",
|
|
FABS_D: "ABSD",
|
|
FNEG_S: "NEGF",
|
|
FNEG_D: "NEGD",
|
|
FSQRT_S: "SQRTF",
|
|
FSQRT_D: "SQRTD",
|
|
FCOPYSIGN_S: "FCOPYSGF",
|
|
FCOPYSIGN_D: "FCOPYSGD",
|
|
FMAX_S: "FMAXF",
|
|
FMAX_D: "FMAXD",
|
|
FMIN_S: "FMINF",
|
|
FMIN_D: "FMIND",
|
|
FCLASS_S: "FCLASSF",
|
|
FCLASS_D: "FCLASSD",
|
|
FCMP_CEQ_S: "CMPEQF",
|
|
FCMP_CEQ_D: "CMPEQD",
|
|
FCMP_SLE_S: "CMPGEF",
|
|
FCMP_SLE_D: "CMPGED",
|
|
FCMP_SLT_S: "CMPGTF",
|
|
FCMP_SLT_D: "CMPGTD",
|
|
FCVT_D_S: "MOVFD",
|
|
FCVT_S_D: "MOVDF",
|
|
FFINT_S_W: "FFINTFW",
|
|
FFINT_S_L: "FFINTFV",
|
|
FFINT_D_W: "FFINTDW",
|
|
FFINT_D_L: "FFINTDV",
|
|
FTINTRM_L_D: "FTINTRMVD",
|
|
FTINTRM_L_S: "FTINTRMVF",
|
|
FTINTRM_W_D: "FTINTRMWD",
|
|
FTINTRM_W_S: "FTINTRMWF",
|
|
FTINTRNE_L_D: "FTINTRNEVD",
|
|
FTINTRNE_L_S: "FTINTRNEVF",
|
|
FTINTRNE_W_D: "FTINTRNEWD",
|
|
FTINTRNE_W_S: "FTINTRNEWF",
|
|
FTINTRP_L_D: "FTINTRPVD",
|
|
FTINTRP_L_S: "FTINTRPVF",
|
|
FTINTRP_W_D: "FTINTRPWD",
|
|
FTINTRP_W_S: "FTINTRPWF",
|
|
FTINTRZ_L_D: "FTINTRZVD",
|
|
FTINTRZ_L_S: "FTINTRZVF",
|
|
FTINTRZ_W_D: "FTINTRZWD",
|
|
FTINTRZ_W_S: "FTINTRZWF",
|
|
FTINT_L_D: "FTINTVD",
|
|
FTINT_L_S: "FTINTVF",
|
|
FTINT_W_D: "FTINTWD",
|
|
FTINT_W_S: "FTINTWF",
|
|
FRINT_S: "FRINTS",
|
|
FRINT_D: "FRINTD",
|
|
FMOV_S: "MOVF",
|
|
FMOV_D: "MOVD",
|
|
MOVGR2FR_W: "MOVW",
|
|
MOVGR2FR_D: "MOVV",
|
|
MOVFR2GR_S: "MOVW",
|
|
MOVFR2GR_D: "MOVV",
|
|
MOVGR2CF: "MOVV",
|
|
MOVCF2GR: "MOVV",
|
|
MOVFCSR2GR: "MOVV",
|
|
MOVGR2FCSR: "MOVV",
|
|
MOVFR2CF: "MOVV",
|
|
MOVCF2FR: "MOVV",
|
|
FLD_S: "MOVF",
|
|
FLD_D: "MOVD",
|
|
FST_S: "MOVF",
|
|
FST_D: "MOVD",
|
|
FLDX_S: "MOVF",
|
|
FLDX_D: "MOVD",
|
|
FSTX_S: "MOVF",
|
|
FSTX_D: "MOVD",
|
|
}
|