Source file src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/plan9.go

     1  // Copyright 2024 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package s390xasm
     6  
     7  import (
     8  	"fmt"
     9  	"strconv"
    10  	"strings"
    11  )
    12  
    13  var vectorSize = map[int]string{0: "B", 1: "H", 2: "F", 3: "G", 4: "Q"}
    14  var vectorCS = map[int]string{0: "BS", 1: "HS", 2: "FS", 3: "GS"}
    15  
    16  // GoSyntax returns the Go assembler syntax for the instruction.
    17  // The syntax was originally defined by Plan 9.
    18  // The inst relates to single instruction.
    19  // The pc is the program counter of the instruction, used for
    20  // expanding PC-relative addresses into absolute ones.
    21  // The symname function queries the symbol table for the program
    22  // being disassembled. Given a target address it returns the name
    23  // and base address of the symbol containing the target, if any;
    24  // otherwise it returns "", 0.
    25  func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) string {
    26  	if symname == nil {
    27  		symname = func(uint64) (string, uint64) { return "", 0 }
    28  	}
    29  
    30  	var args []string
    31  	opString := inst.Op.String()
    32  	op := strings.ToUpper(opString)
    33  	for i := 0; i < len(inst.Args); i++ {
    34  		if inst.Args[i] == nil {
    35  			break
    36  		}
    37  		switch inst.Args[i].(type) {
    38  		case Disp12, Disp20:
    39  			var temp []string
    40  			switch inst.Args[i+1].(type) {
    41  			case Index: // D(X,B)
    42  				for j := 0; j < 3; j++ {
    43  					temp = append(temp, plan9Arg(&inst, pc, symname, inst.Args[i+j]))
    44  				}
    45  				args = append(args, mem_operandx(temp))
    46  				i = i + 2
    47  			case Base: // D(B)
    48  				for j := 0; j < 2; j++ {
    49  					temp = append(temp, plan9Arg(&inst, pc, symname, inst.Args[i+j]))
    50  				}
    51  				args = append(args, mem_operand(temp))
    52  				i = i + 1
    53  			case VReg: // D(B)
    54  				for j := 0; j < 3; j++ {
    55  					temp = append(temp, plan9Arg(&inst, pc, symname, inst.Args[i+j]))
    56  				}
    57  				args = append(args, mem_operandv(temp))
    58  				i = i + 2
    59  			case Len: // D(L,B)
    60  				for j := 0; j < 3; j++ {
    61  					temp = append(temp, plan9Arg(&inst, pc, symname, inst.Args[i+j]))
    62  				}
    63  				ar1, ar2 := mem_operandl(temp)
    64  				args = append(args, ar1, ar2)
    65  				i = i + 2
    66  			default: // D(R,B)
    67  				for j := 0; j < 3; j++ {
    68  					temp = append(temp, plan9Arg(&inst, pc, symname, inst.Args[i+j]))
    69  				}
    70  				args = append(args, mem_operandx(temp))
    71  				i = i + 2
    72  			}
    73  		default:
    74  			args = append(args, plan9Arg(&inst, pc, symname, inst.Args[i]))
    75  		}
    76  	}
    77  	if strings.HasPrefix(op, "V") || strings.Contains(op, "WFC") || strings.Contains(op, "WFK") {
    78  		args = args[:len(args)-1]
    79  	}
    80  
    81  	switch inst.Op {
    82  	default:
    83  		switch len(args) {
    84  		case 0:
    85  			return op
    86  		case 1:
    87  			return fmt.Sprintf("%s %s", op, args[0])
    88  		case 2:
    89  			if reverseOperandOrder(inst.Op) {
    90  				args[0], args[1] = args[1], args[0]
    91  			}
    92  		case 3:
    93  			if reverseOperandOrder(inst.Op) {
    94  				args[0], args[2] = args[2], args[0]
    95  			} else if reverseAllOperands(inst.Op) {
    96  				args[0], args[1], args[2] = args[1], args[2], args[0]
    97  			}
    98  		case 4:
    99  			if reverseOperandOrder(inst.Op) {
   100  				args[0], args[3] = args[3], args[0]
   101  			} else if reverseAllOperands(inst.Op) {
   102  				args[0], args[1], args[2], args[3] = args[1], args[2], args[3], args[0]
   103  			}
   104  		}
   105  	case LCGR, LCGFR:
   106  		switch inst.Op {
   107  		case LCGR:
   108  			op = "NEG"
   109  		case LCGFR:
   110  			op = "NEGW"
   111  		}
   112  		if args[0] == args[1] {
   113  			args = args[:1]
   114  		} else {
   115  			args[0], args[1] = args[1], args[0]
   116  		}
   117  	case LD, LE, LG, LGF, LLGF, LGH, LLGH, LGB, LLGC, LDY, LEY, LRVG, LRV, LRVH:
   118  		args[0], args[1] = args[1], args[0]
   119  		switch inst.Op {
   120  		case LG:
   121  			op = "MOVD"
   122  		case LGF:
   123  			op = "MOVW"
   124  		case LLGF:
   125  			op = "MOVWZ"
   126  		case LGH:
   127  			op = "MOVH"
   128  		case LLGH:
   129  			op = "MOVHZ"
   130  		case LGB:
   131  			op = "MOVB"
   132  		case LLGC:
   133  			op = "MOVBZ"
   134  		case LDY, LD:
   135  			op = "FMOVD"
   136  		case LEY, LE:
   137  			op = "FMOVS"
   138  		case LRVG:
   139  			op = "MOVDBR"
   140  		case LRV:
   141  			op = "MOVWBR"
   142  		case LRVH:
   143  			op = "MOVHBR"
   144  		}
   145  	case LA, LAY, LARL:
   146  		args[0], args[1] = args[1], args[0]
   147  		op = "MOVD"
   148  
   149  	case LAA, LAAG, LAAL, LAALG, LAN, LANG, LAX, LAXG, LAO, LAOG:
   150  		args[0], args[1] = args[1], args[0]
   151  	case LM, LMY, LMG: // Load Multiple
   152  		switch inst.Op {
   153  		case LM, LMY:
   154  			op = "LMY"
   155  		}
   156  		args[0], args[1], args[2] = args[2], args[0], args[1]
   157  
   158  	case STM, STMY, STMG: // Store Multiple
   159  		switch inst.Op {
   160  		case STM, STMY:
   161  			op = "STMY"
   162  		}
   163  	case ST, STY, STG, STHY, STCY, STRVG, STRV:
   164  		switch inst.Op {
   165  		case ST, STY:
   166  			op = "MOVW"
   167  		case STHY:
   168  			op = "MOVH"
   169  		case STCY:
   170  			op = "MOVB"
   171  		case STG:
   172  			op = "MOVD"
   173  		case STRVG:
   174  			op = "MOVDBR"
   175  		case STRV:
   176  			op = "MOVWBR"
   177  		}
   178  	case LGR, LGFR, LGHR, LGBR, LLGFR, LLGHR, LLGCR, LRVGR, LRVR, LDR:
   179  		switch inst.Op {
   180  		case LGR:
   181  			op = "MOVD"
   182  		case LGFR:
   183  			op = "MOVW"
   184  		case LGHR:
   185  			op = "MOVH"
   186  		case LGBR:
   187  			op = "MOVB"
   188  		case LLGFR:
   189  			op = "MOVWZ"
   190  		case LLGHR:
   191  			op = "MOVHZ"
   192  		case LLGCR:
   193  			op = "MOVBZ"
   194  		case LRVGR:
   195  			op = "MOVDBR"
   196  		case LRVR:
   197  			op = "MOVWBR"
   198  		case LDR:
   199  			op = "FMOVD"
   200  		}
   201  		args[0], args[1] = args[1], args[0]
   202  	case LZDR:
   203  		op = "FMOVD"
   204  		return op + " " + "$0" + ", " + args[0]
   205  	case LZER:
   206  		op = "FMOVS"
   207  		return op + " " + "$0" + ", " + args[0]
   208  	case STD, STDY, STE, STEY:
   209  		switch inst.Op {
   210  		case STD, STDY:
   211  			op = "FMOVD"
   212  		case STE, STEY:
   213  			op = "FMOVS"
   214  		}
   215  
   216  	case LGHI, LLILH, LLIHL, LLIHH, LGFI, LLILF, LLIHF:
   217  		switch inst.Op {
   218  		case LGFI:
   219  			op = "MOVW"
   220  		case LGHI:
   221  			num, err := strconv.ParseInt(args[1][1:], 10, 16)
   222  			if err != nil {
   223  				return fmt.Sprintf("plan9Arg: error in converting ParseInt:%s", err)
   224  			}
   225  			if num == int64(int8(num)) {
   226  				op = "MOVB"
   227  			} else {
   228  				op = "MOVH"
   229  			}
   230  		default:
   231  			op = "MOVD"
   232  		}
   233  		args[0], args[1] = args[1], args[0]
   234  	case ARK, AGRK, ALGRK:
   235  		switch inst.Op {
   236  		case ARK:
   237  			op = "ADDW"
   238  		case AGRK:
   239  			op = "ADD"
   240  		case ALGRK:
   241  			op = "ADDC"
   242  		}
   243  		if args[0] == args[1] {
   244  			args[0], args[1] = args[2], args[0]
   245  			args = args[:2]
   246  		} else {
   247  			args[0], args[2] = args[2], args[0]
   248  		}
   249  	case AGHIK, AHIK, ALGHSIK:
   250  		num, err := strconv.ParseInt(args[2][1:], 10, 32)
   251  		if err != nil {
   252  			return fmt.Sprintf("plan9Arg: error in converting ParseInt:%s", err)
   253  		}
   254  		switch inst.Op {
   255  		case AGHIK:
   256  			if num < 0 {
   257  				op = "SUB"
   258  				args[2] = args[2][:1] + args[2][2:]
   259  			} else {
   260  				op = "ADD"
   261  			}
   262  		case AHIK:
   263  			op = "ADDW"
   264  		case ALGHSIK:
   265  			if num < 0 {
   266  				op = "SUBC"
   267  				args[2] = args[2][:1] + args[2][2:]
   268  			} else {
   269  				op = "ADDC"
   270  			}
   271  		}
   272  		args[0], args[2] = args[2], args[0]
   273  	case AGHI, AHI, AGFI, AFI, AR, ALCGR:
   274  		num, err := strconv.ParseInt(args[1][1:], 10, 32)
   275  		if err != nil {
   276  			return fmt.Sprintf("plan9Arg: error in converting ParseInt:%s", err)
   277  		}
   278  		switch inst.Op {
   279  		case AGHI, AGFI:
   280  			if num < 0 {
   281  				op = "SUB"
   282  				args[1] = args[1][:1] + args[1][2:]
   283  			} else {
   284  				op = "ADD"
   285  			}
   286  		case AHI, AFI, AR:
   287  			op = "ADDW"
   288  		case ALCGR:
   289  			op = "ADDE"
   290  		}
   291  		args[0], args[1] = args[1], args[0]
   292  	case AEBR, ADBR, DDBR, DEBR, MDBR, MEEBR, SDBR, SEBR, LPDBR, LNDBR, LPDFR, LNDFR, LCDFR, LCEBR, LEDBR, LDEBR, SQDBR, SQEBR:
   293  		switch inst.Op {
   294  		case AEBR:
   295  			op = "FADDS"
   296  		case ADBR:
   297  			op = "FADD"
   298  		case DDBR:
   299  			op = "FDIV"
   300  		case DEBR:
   301  			op = "FDIVS"
   302  		case MDBR:
   303  			op = "FMUL"
   304  		case MEEBR:
   305  			op = "FMULS"
   306  		case SDBR:
   307  			op = "FSUB"
   308  		case SEBR:
   309  			op = "FSUBS"
   310  		case LPDBR:
   311  			op = "FABS"
   312  		case LNDBR:
   313  			op = "FNABS"
   314  		case LCDFR:
   315  			op = "FNEG"
   316  		case LCEBR:
   317  			op = "FNEGS"
   318  		case SQDBR:
   319  			op = "FSQRT"
   320  		case SQEBR:
   321  			op = "FSQRTS"
   322  		}
   323  		args[0], args[1] = args[1], args[0]
   324  	case SR, SGR, SLGR, SLFI:
   325  		switch inst.Op {
   326  		case SR, SLFI:
   327  			op = "SUBW"
   328  		case SGR:
   329  			op = "SUB"
   330  		case SLGR:
   331  			op = "SUBC"
   332  		}
   333  		args[0], args[1] = args[1], args[0]
   334  	case SGRK, SLGRK, SRK:
   335  		switch inst.Op {
   336  		case SGRK:
   337  			op = "SUB"
   338  		case SLGRK:
   339  			op = "SUBC"
   340  		case SRK:
   341  			op = "SUBW"
   342  		}
   343  		if args[0] == args[1] {
   344  			args[0], args[1] = args[2], args[0]
   345  			args = args[:2]
   346  		} else {
   347  			args[0], args[2] = args[2], args[0]
   348  		}
   349  	case SLBGR:
   350  		op = "SUBE"
   351  		args[0], args[1] = args[1], args[0]
   352  	case MADBR:
   353  		op = "FMADD"
   354  		args[0], args[1], args[2] = args[1], args[2], args[0]
   355  	case VFM:
   356  		op = "WFMDB"
   357  		args[0], args[1], args[2] = args[1], args[2], args[0]
   358  		args = args[0:3]
   359  	case VFS:
   360  		op = "WFSDB"
   361  		args[0], args[2] = args[2], args[0]
   362  		args = args[0:3]
   363  	case MSGFR, MHI, MSFI, MSGFI:
   364  		switch inst.Op {
   365  		case MSGFR, MHI, MSFI:
   366  			op = "MULLW"
   367  		case MSGFI:
   368  			op = "MULLD"
   369  		}
   370  		args[0], args[1] = args[1], args[0]
   371  
   372  	case NGR, NR, NILL, NILF, NILH, OGR, OR, OILL, OILF, OILH, XGR, XR, XILF:
   373  		op = bitwise_op(inst.Op)
   374  		args[0], args[1] = args[1], args[0]
   375  		switch inst.Op {
   376  		case NILL:
   377  			if int(inst.Args[1].(Sign16)) < 0 {
   378  				op = "ANDW"
   379  			}
   380  
   381  		case NILF:
   382  			if int(inst.Args[1].(Sign32)) < 0 {
   383  				op = "AND"
   384  			}
   385  		case OILF:
   386  			if int(inst.Args[1].(Sign32)) < 0 {
   387  				op = "ORW"
   388  			}
   389  		case XILF:
   390  			if int(inst.Args[1].(Sign32)) < 0 {
   391  				op = "XORW"
   392  			}
   393  		}
   394  
   395  	case NGRK, NRK, OGRK, ORK, XGRK, XRK: // opcode R1, R2, R3
   396  		op = bitwise_op(inst.Op)
   397  		args[0], args[1], args[2] = args[1], args[2], args[0]
   398  	case SLLG, SRLG, SLLK, SRLK, RLL, RLLG, SRAK, SRAG:
   399  		switch inst.Op {
   400  		case SLLG:
   401  			op = "SLD"
   402  		case SRLG:
   403  			op = "SRD"
   404  		case SLLK:
   405  			op = "SLW"
   406  		case SRLK:
   407  			op = "SRW"
   408  		case SRAK:
   409  			op = "SRAW"
   410  		case SRAG:
   411  			op = "SRAD"
   412  		}
   413  		args[0], args[2] = args[2], args[0]
   414  	case TRAP2, SVC:
   415  		op = "SYSALL"
   416  	case CR, CLR, CGR, CLGR, KDBR, CDBR, CEBR, CGHI, CHI, CGFI, CLGFI, CFI, CLFI:
   417  		switch inst.Op {
   418  		case CGHI, CGFI, CGR:
   419  			op = "CMP"
   420  		case CHI, CFI, CR:
   421  			op = "CMPW"
   422  		case CLGFI, CLGR:
   423  			op = "CMPU"
   424  		case CLFI, CLR:
   425  			op = "CMPWU"
   426  		case CDBR:
   427  			op = "FCMPU"
   428  		case KDBR:
   429  			op = "FCMPO"
   430  		}
   431  	case CEFBRA, CDFBRA, CEGBRA, CDGBRA, CELFBR, CDLFBR, CELGBR, CDLGBR, CFEBRA, CFDBRA, CGEBRA, CGDBRA, CLFEBR, CLFDBR, CLGEBR, CLGDBR:
   432  		args[0], args[1] = args[2], args[0]
   433  		args = args[:2]
   434  	case CGRJ, CGIJ:
   435  		mask, err := strconv.Atoi(args[2][1:])
   436  		if err != nil {
   437  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   438  		}
   439  		var check bool
   440  		switch mask & 0xf {
   441  		case 2:
   442  			op = "CMPBGT"
   443  			check = true
   444  		case 4:
   445  			op = "CMPBLT"
   446  			check = true
   447  		case 6:
   448  			op = "CMPBNE"
   449  			check = true
   450  		case 8:
   451  			op = "CMPBEQ"
   452  			check = true
   453  		case 10:
   454  			op = "CMPBGE"
   455  			check = true
   456  		case 12:
   457  			op = "CMPBLE"
   458  			check = true
   459  		}
   460  		if check {
   461  			args[2] = args[3]
   462  			args = args[:3]
   463  		}
   464  	case CLGRJ, CLGIJ:
   465  		mask, err := strconv.Atoi(args[2][1:])
   466  		if err != nil {
   467  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   468  		}
   469  		var check bool
   470  		switch mask & 0xf {
   471  		case 2:
   472  			op = "CMPUBGT"
   473  			check = true
   474  		case 4:
   475  			op = "CMPUBLT"
   476  			check = true
   477  		case 7:
   478  			op = "CMPUBNE"
   479  			check = true
   480  		case 8:
   481  			op = "CMPUBEQ"
   482  			check = true
   483  		case 10:
   484  			op = "CMPUBGE"
   485  			check = true
   486  		case 12:
   487  			op = "CMPUBLE"
   488  			check = true
   489  		}
   490  		if check {
   491  			args[2] = args[3]
   492  			args = args[:3]
   493  		}
   494  	case CLRJ, CRJ, CIJ, CLIJ:
   495  		args[0], args[1], args[2] = args[2], args[0], args[1]
   496  	case BRC, BRCL:
   497  		mask, err := strconv.Atoi(args[0][1:])
   498  		if err != nil {
   499  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   500  		}
   501  		opStr, check := branch_relative_op(mask, inst.Op)
   502  		if opStr != "" {
   503  			op = opStr
   504  		}
   505  		if check {
   506  			args[0] = args[1]
   507  			args = args[:1]
   508  		}
   509  	case BCR:
   510  		mask, err := strconv.Atoi(args[0][1:])
   511  		if err != nil {
   512  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   513  		}
   514  		opStr := branchOnConditionOp(mask, inst.Op)
   515  		if opStr != "" {
   516  			op = opStr
   517  		}
   518  		if op == "SYNC" || op == "NOPH" {
   519  			return op
   520  		}
   521  		if op == "RET" {
   522  			args = args[:0]
   523  			return op
   524  		}
   525  	case LOCGR:
   526  		mask, err := strconv.Atoi(args[2][1:])
   527  		if err != nil {
   528  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   529  		}
   530  		var check bool
   531  		switch mask & 0xf {
   532  		case 2: //Greaterthan (M=2)
   533  			op = "MOVDGT"
   534  			check = true
   535  		case 4: //Lessthan (M=4)
   536  			op = "MOVDLT"
   537  			check = true
   538  		case 7: // Not Equal (M=7)
   539  			op = "MOVDNE"
   540  			check = true
   541  		case 8: // Equal (M=8)
   542  			op = "MOVDEQ"
   543  			check = true
   544  		case 10: // Greaterthan or Equal (M=10)
   545  			op = "MOVDGE"
   546  			check = true
   547  		case 12: // Lessthan or Equal (M=12)
   548  			op = "MOVDLE"
   549  			check = true
   550  		}
   551  		if check {
   552  			args[0], args[1] = args[1], args[0]
   553  			args = args[:2]
   554  		} else {
   555  			args[0], args[2] = args[2], args[0]
   556  		}
   557  	case BRASL:
   558  		op = "CALL" // BL
   559  		args[0] = args[1]
   560  		args = args[:1]
   561  	case X, XY, XG:
   562  		switch inst.Op {
   563  		case X, XY:
   564  			op = "XORW"
   565  		case XG:
   566  			op = "XOR"
   567  		}
   568  	case N, NY, NG, O, OY, OG, XC, NC, OC, MVC, MVCIN, CLC:
   569  		switch inst.Op {
   570  		case N, NY:
   571  			op = "ANDW"
   572  		case NG:
   573  			op = "AND"
   574  		case O, OY:
   575  			op = "ORW"
   576  		case OG:
   577  			op = "OR"
   578  		}
   579  		args[0], args[1] = args[1], args[0]
   580  	case S, SY, SLBG, SLG, SG:
   581  		switch inst.Op {
   582  		case S, SY:
   583  			op = "SUBW"
   584  		case SLBG:
   585  			op = "SUBE"
   586  		case SLG:
   587  			op = "SUBC"
   588  		case SG:
   589  			op = "SUB"
   590  		}
   591  		args[0], args[1] = args[1], args[0]
   592  	case MSG, MSY, MS:
   593  		switch inst.Op {
   594  		case MSG:
   595  			op = "MULLD"
   596  		case MSY, MS:
   597  			op = "MULLW"
   598  		}
   599  	case A, AY, ALCG, ALG, AG:
   600  		switch inst.Op {
   601  		case A, AY:
   602  			op = "ADDW"
   603  		case ALCG:
   604  			op = "ADDE"
   605  		case ALG:
   606  			op = "ADDC"
   607  		case AG:
   608  			op = "ADD"
   609  		}
   610  		args[0], args[1] = args[1], args[0]
   611  	case RISBG, RISBGN, RISBHG, RISBLG, RNSBG, RXSBG, ROSBG:
   612  		switch inst.Op {
   613  		case RNSBG, RXSBG, ROSBG:
   614  			num, err := strconv.Atoi(args[2][1:])
   615  			if err != nil {
   616  				return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   617  			}
   618  			if ((num >> 7) & 0x1) != 0 {
   619  				op = op + "T"
   620  			}
   621  		case RISBG, RISBGN, RISBHG, RISBLG:
   622  			num, err := strconv.Atoi(args[3][1:])
   623  			if err != nil {
   624  				return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   625  			}
   626  			if ((num >> 7) & 0x1) != 0 {
   627  				op = op + "Z"
   628  			}
   629  		}
   630  		if len(args) == 5 {
   631  			args[0], args[1], args[2], args[3], args[4] = args[2], args[3], args[4], args[1], args[0]
   632  		} else {
   633  			args[0], args[1], args[2], args[3] = args[2], args[3], args[1], args[0]
   634  		}
   635  
   636  	case VEC, VECL, VCLZ, VCTZ, VREPI, VPOPCT: //mnemonic V1, V2, M3
   637  		mask, err := strconv.Atoi(args[2][1:])
   638  		if err != nil {
   639  			return fmt.Sprintf("GoSyntax: error in converting Atoi for %q:%s", op, err)
   640  		}
   641  		val := mask & 0x7
   642  		if val >= 0 && val < 4 {
   643  			op = op + vectorSize[val]
   644  			args = args[:2]
   645  		} else {
   646  			return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   647  		}
   648  		switch inst.Op {
   649  		case VCLZ, VCTZ, VREPI, VPOPCT:
   650  			args[0], args[1] = args[1], args[0]
   651  		default:
   652  		}
   653  		//Mnemonic V1, V2, V3, M4 or Mnemonic V1, I2, I3, M4 or Mnemonic V1, V3, I2, M4
   654  	case VA, VS, VACC, VAVG, VAVGL, VMX, VMXL, VMN, VMNL, VGFM, VGM, VREP, VERLLV, VESLV, VSCBI, VSUM, VSUMG, VSUMQ, VMH, VMLH, VML, VME, VMLE, VMO, VMLO:
   655  		mask, err := strconv.Atoi(args[3][1:])
   656  		if err != nil {
   657  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   658  		}
   659  		val := mask & 0x7
   660  		switch inst.Op {
   661  		case VA, VS, VACC, VSCBI:
   662  			if val >= 0 && val < 5 {
   663  				if args[0] == args[2] {
   664  					args[0], args[1] = args[1], args[0]
   665  					args = args[:2]
   666  				} else if inst.Op == VS {
   667  					if args[0] == args[1] {
   668  						args[0] = args[2]
   669  						args = args[:2]
   670  					} else {
   671  						args[0], args[2] = args[2], args[0]
   672  						args = args[:3]
   673  					}
   674  				} else {
   675  					args[0], args[1], args[2] = args[1], args[2], args[0]
   676  					args = args[:3]
   677  				}
   678  				op = op + vectorSize[val]
   679  			} else {
   680  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   681  			}
   682  		case VAVG, VAVGL, VMX, VMXL, VMN, VMNL, VGFM, VGM:
   683  			if val >= 0 && val < 4 {
   684  				op = op + vectorSize[val]
   685  				args[0], args[1], args[2] = args[1], args[2], args[0]
   686  				args = args[:3]
   687  			} else {
   688  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   689  			}
   690  		case VREP, VERLLV, VESLV:
   691  			if val >= 0 && val < 4 {
   692  				op = op + vectorSize[val]
   693  				args[0], args[2] = args[2], args[0]
   694  				args = args[:3]
   695  			} else {
   696  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   697  			}
   698  		case VSUM, VSUMG, VSUMQ:
   699  			var off int
   700  			switch inst.Op {
   701  			case VSUM:
   702  				off = 0
   703  			case VSUMG:
   704  				off = 1
   705  			case VSUMQ:
   706  				off = 2
   707  			}
   708  			if (val > (-1 + off)) && (val < (2 + off)) {
   709  				op = op + vectorSize[val]
   710  			} else {
   711  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   712  			}
   713  			args = args[:3]
   714  		case VML, VMH, VMLH, VME, VMLE, VMO, VMLO:
   715  			if val >= 0 && val < 3 {
   716  				op = op + vectorSize[val]
   717  			}
   718  			if op == "VML" && val == 2 {
   719  				op = op + "W"
   720  			}
   721  			if args[0] == args[2] {
   722  				args[0], args[1] = args[1], args[0]
   723  				args = args[:2]
   724  			} else {
   725  				args[0], args[1], args[2] = args[1], args[2], args[0]
   726  				args = args[:3]
   727  			}
   728  		}
   729  
   730  	case VGFMA, VERIM, VMAH, VMALH: // Mnemonic V1, V2, V3, V4/I4, M5
   731  		mask, err := strconv.Atoi(args[4][1:])
   732  		if err != nil {
   733  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   734  		}
   735  		val := mask & 0x7
   736  		args = args[:4]
   737  		var off int
   738  		switch inst.Op {
   739  		case VMAH, VMALH:
   740  			off = -1
   741  		}
   742  
   743  		if val >= 0 && val < (4+off) {
   744  			op = op + vectorSize[val]
   745  		} else {
   746  			return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   747  		}
   748  		switch inst.Op {
   749  		case VGFMA, VMAH, VMALH:
   750  			args[0], args[1], args[2], args[3] = args[1], args[2], args[3], args[0]
   751  		default:
   752  			args[0], args[3] = args[3], args[0]
   753  		}
   754  	case VSTRC, VFAE, VFEE, VFENE:
   755  		var off uint8
   756  		switch inst.Op {
   757  		case VSTRC:
   758  			off = uint8(1)
   759  		default:
   760  			off = uint8(0)
   761  		}
   762  		m1, err := strconv.Atoi(args[3+off][1:])
   763  		if err != nil {
   764  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   765  		}
   766  		m2, err := strconv.Atoi(args[4+off][1:])
   767  		if err != nil {
   768  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   769  		}
   770  		index := m1 & 0x3
   771  		if index < 0 || index > 2 {
   772  			return fmt.Sprintf("specification exception is recognized for %q with mask values: %v, %v \n", op, m1, m2)
   773  		}
   774  		switch m2 {
   775  		case 0:
   776  			op = op + vectorSize[index]
   777  		case 1:
   778  			op = op + vectorCS[index]
   779  		case 2:
   780  			op = op + "Z" + vectorSize[index]
   781  		case 3:
   782  			op = op + "Z" + vectorCS[index]
   783  		default:
   784  			return fmt.Sprintf("specification exception is recognized for %q with mask values: %v, %v \n", op, m1, m2)
   785  		}
   786  		switch inst.Op {
   787  		case VSTRC:
   788  			args[0], args[1], args[2], args[3] = args[1], args[2], args[3], args[0]
   789  		default:
   790  			args[0], args[1], args[2] = args[1], args[2], args[0]
   791  		}
   792  		args = args[:3+off]
   793  
   794  	case VCEQ, VCH, VCHL: // Mnemonic V1, V2, V3, M4, M5
   795  		m4, err := strconv.Atoi(args[3][1:])
   796  		if err != nil {
   797  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   798  		}
   799  		m5, err := strconv.Atoi(args[4][1:])
   800  		if err != nil {
   801  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   802  		}
   803  		val := (m4 & 0x7)
   804  		if m5 == 0 {
   805  			if val >= 0 && val < 4 {
   806  				op = op + vectorSize[val]
   807  				args[0], args[1], args[2] = args[1], args[2], args[0]
   808  				args = args[:3]
   809  			} else {
   810  				return fmt.Sprintf("specification exception is recognized for %q with mask(m4) value: %v \n", op, m4)
   811  			}
   812  		} else if m5 == 1 {
   813  			if val >= 0 && val < 4 {
   814  				op = op + vectorCS[val]
   815  				args[0], args[1], args[2] = args[1], args[2], args[0]
   816  				args = args[:3]
   817  			} else {
   818  				return fmt.Sprintf("specification exception is recognized for %q with mask(m4) value: %v \n", op, m4)
   819  			}
   820  		} else {
   821  			return fmt.Sprintf("specification exception is recognized for %q with mask(m5) value: %v \n", op, m5)
   822  		}
   823  	case VFMA, VFMS, VMSL: //Mnemonic V1, V2, V3, V4, M5, M6
   824  		m5, err := strconv.Atoi(args[4][1:])
   825  		if err != nil {
   826  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   827  		}
   828  		m6, err := strconv.Atoi(args[5][1:])
   829  		if err != nil {
   830  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   831  		}
   832  		switch inst.Op {
   833  		case VMSL:
   834  			if m5 == 3 && m6 == 8 {
   835  				op = op + "EG"
   836  			} else if m5 == 3 && m6 == 4 {
   837  				op = op + "OG"
   838  			} else if m5 == 3 && m6 == 12 {
   839  				op = op + "EOG"
   840  			} else if m5 == 3 {
   841  				op = op + "G"
   842  			}
   843  		default:
   844  			if m5 == 0 && m6 == 3 {
   845  				op = op + "DB"
   846  			} else if m5 == 8 && m6 == 3 {
   847  				op = "W" + op[1:] + "DB"
   848  			} else {
   849  				return fmt.Sprintf("specification exception is recognized for %q with m5: %v m6: %v \n", op, m5, m6)
   850  			}
   851  		}
   852  		args[0], args[1], args[2], args[3] = args[1], args[2], args[3], args[0]
   853  		args = args[:4]
   854  
   855  	case VFCE, VFCH, VFCHE: //Mnemonic V1,V2,V3,M4,M5,M6
   856  		m4, err := strconv.Atoi(args[3][1:])
   857  		if err != nil {
   858  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   859  		}
   860  		m5, err := strconv.Atoi(args[4][1:])
   861  		if err != nil {
   862  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   863  		}
   864  		m6, err := strconv.Atoi(args[5][1:])
   865  		if err != nil {
   866  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   867  		}
   868  		if m5 == 0 {
   869  			if m4 == 3 && m6 == 0 {
   870  				op = op + "DB"
   871  			} else if m4 == 3 && m6 == 1 {
   872  				op = op + "DBS"
   873  			} else {
   874  				return fmt.Sprintf("specification exception is recognized for %q with m4: %v, m6: %v \n", op, m4, m6)
   875  			}
   876  
   877  		} else if m5 == 8 {
   878  			if m4 == 3 && m6 == 0 {
   879  				op = "W" + op[1:] + "DB"
   880  			} else if m4 == 3 && m6 == 1 {
   881  				op = "W" + op[1:] + "DBS"
   882  			} else {
   883  				return fmt.Sprintf("specification exception is recognized for %q with m4: %v, m6: %v \n", op, m4, m6)
   884  			}
   885  		} else {
   886  			return fmt.Sprintf("specification exception is recognized for %q with m5: %v \n", op, m5)
   887  		}
   888  		args[0], args[1], args[2] = args[1], args[2], args[0]
   889  		args = args[:3]
   890  
   891  	case VFTCI:
   892  		m4, err := strconv.Atoi(args[3][1:])
   893  		if err != nil {
   894  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   895  		}
   896  		m5, err := strconv.Atoi(args[4][1:])
   897  		if err != nil {
   898  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   899  		}
   900  		val := (m4 & 0x7)
   901  		if m5 == 0 {
   902  			switch val {
   903  			case 2:
   904  				op = op + "SB"
   905  			case 3:
   906  				op = op + "DB"
   907  			default:
   908  				return fmt.Sprintf("specification exception is recognized for %q with mask(m4) value: %v \n", op, m4)
   909  			}
   910  		} else if m5 == 8 {
   911  			switch val {
   912  			case 2:
   913  				op = "W" + op[1:] + "SB"
   914  			case 3:
   915  				op = "W" + op[1:] + "DB"
   916  			case 4:
   917  				op = "W" + op[1:] + "XB"
   918  			default:
   919  				return fmt.Sprintf("specification exception is recognized for %q with mask(m4) value: %v \n", op, m4)
   920  			}
   921  		} else {
   922  			return fmt.Sprintf("specification exception is recognized for %q with mask(m5) value: %v \n", op, m5)
   923  		}
   924  		args[0], args[2] = args[2], args[0]
   925  		args = args[:3]
   926  	case VAC, VACCC:
   927  		mask, err := strconv.Atoi(args[4][1:])
   928  		if err != nil {
   929  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   930  		}
   931  		if mask&0x04 == 0 {
   932  			return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   933  		}
   934  		op = op + "Q"
   935  		args[0], args[1], args[2], args[3] = args[1], args[2], args[3], args[0]
   936  		args = args[:4]
   937  	case VL, VLREP:
   938  		switch inst.Op {
   939  		case VL:
   940  			args[0], args[1] = args[1], args[0]
   941  		case VLREP:
   942  			args[0], args[1] = args[1], args[0]
   943  			mask, err := strconv.Atoi(args[2][1:])
   944  			if err != nil {
   945  				return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   946  			}
   947  			if mask >= 0 && mask < 4 {
   948  				op = op + vectorSize[mask]
   949  			}
   950  		}
   951  		args = args[:2]
   952  	case VST, VSTEB, VSTEH, VSTEF, VSTEG, VLEB, VLEH, VLEF, VLEG: //Mnemonic V1, D2(X2,B2), M3
   953  		m, err := strconv.Atoi(args[2][1:])
   954  		if err != nil {
   955  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   956  		}
   957  		switch inst.Op {
   958  		case VST:
   959  			if m == 0 || (m > 2 && m < 5) {
   960  				args = args[:2]
   961  			} else {
   962  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, m)
   963  			}
   964  		case VLEB, VLEH, VLEF, VLEG:
   965  			args[0], args[2] = args[2], args[0]
   966  		default:
   967  			args[0], args[1], args[2] = args[2], args[0], args[1]
   968  		}
   969  	case VSTM, VSTL, VESL, VESRA, VLM, VERLL, VLVG: //Mnemonic V1, V3, D2(B2)[,M4] or V1, R3,D2(B2)
   970  		switch inst.Op {
   971  		case VSTM, VLM:
   972  			m, err := strconv.Atoi(args[3][1:])
   973  			if err != nil {
   974  				return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   975  			}
   976  			if !(m == 0 || (m > 2 && m < 5)) {
   977  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, m)
   978  			}
   979  			if inst.Op == VLM {
   980  				args[0], args[1], args[2] = args[2], args[0], args[1]
   981  			}
   982  			args = args[:3]
   983  		case VESL, VESRA, VERLL, VLVG:
   984  			m, err := strconv.Atoi(args[3][1:])
   985  			if err != nil {
   986  				return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   987  			}
   988  			if m >= 0 && m < 4 {
   989  				op = op + vectorSize[m]
   990  			} else {
   991  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, m)
   992  			}
   993  			switch inst.Op {
   994  			case VLVG:
   995  				args[0], args[2] = args[2], args[0]
   996  				args = args[:3]
   997  			default:
   998  				if args[0] == args[1] {
   999  					args[0] = args[2]
  1000  					args = args[:2]
  1001  					break
  1002  				}
  1003  				args[0], args[2] = args[2], args[0]
  1004  				args = args[:3]
  1005  			}
  1006  		case VSTL:
  1007  			args[0], args[1] = args[1], args[0]
  1008  			args = args[:3]
  1009  		}
  1010  	case VGBM:
  1011  		val, err := strconv.Atoi(args[1][1:])
  1012  		if err != nil {
  1013  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
  1014  		}
  1015  		if val == 0 {
  1016  			op = "VZERO"
  1017  			args = args[:1]
  1018  		} else if val == 0xffff {
  1019  			op = "VONE"
  1020  			args = args[:1]
  1021  		} else {
  1022  			args[0], args[1] = args[1], args[0]
  1023  			args = args[:2]
  1024  		}
  1025  	case VN, VNC, VO, VX, VNO: //mnemonic V1, V2, V3
  1026  		if args[0] == args[2] {
  1027  			args = args[:2]
  1028  			args[0], args[1] = args[1], args[0]
  1029  		} else {
  1030  			args[0], args[1], args[2] = args[1], args[2], args[0]
  1031  		}
  1032  		if op == "VNO" {
  1033  			op = op + "T"
  1034  		}
  1035  	case VGEG, VGEF, VSCEG, VSCEF: //Mnemonic V1, D2(V2, B2), M3
  1036  		args[0], args[2] = args[2], args[0]
  1037  
  1038  	}
  1039  	if args != nil {
  1040  		op += " " + strings.Join(args, ", ")
  1041  	}
  1042  
  1043  	return op
  1044  }
  1045  
  1046  // This function returns corresponding extended mnemonic for the given
  1047  // branch on relative mnemonic.
  1048  func branch_relative_op(mask int, opconst Op) (op string, check bool) {
  1049  	switch mask & 0xf {
  1050  	case 1:
  1051  		op = "BVS"
  1052  		check = true
  1053  	case 2:
  1054  		op = "BGT"
  1055  		check = true
  1056  	case 4:
  1057  		op = "BLT"
  1058  		check = true
  1059  	case 5:
  1060  		op = "BLTU"
  1061  		check = true
  1062  	case 7:
  1063  		op = "BNE"
  1064  		check = true
  1065  	case 8:
  1066  		op = "BEQ"
  1067  		check = true
  1068  	case 10:
  1069  		op = "BGE"
  1070  		check = true
  1071  	case 12:
  1072  		op = "BLE"
  1073  		check = true
  1074  	case 13:
  1075  		op = "BLEU"
  1076  		check = true
  1077  	case 15:
  1078  		op = "BR"
  1079  		check = true
  1080  	}
  1081  	return op, check
  1082  }
  1083  
  1084  // This function returns corresponding extended mnemonic for the given
  1085  // brach on condition mnemonic.
  1086  func branchOnConditionOp(mask int, opconst Op) (op string) {
  1087  	switch mask & 0xf {
  1088  	case 0:
  1089  		op = "NOPH"
  1090  	case 14:
  1091  		op = "SYNC"
  1092  	case 15:
  1093  		op = "RET"
  1094  	}
  1095  	return op
  1096  }
  1097  
  1098  // This function returns corresponding plan9 mnemonic for the native bitwise mnemonic.
  1099  func bitwise_op(op Op) string {
  1100  	var ret string
  1101  	switch op {
  1102  	case NGR, NGRK, NILL:
  1103  		ret = "AND"
  1104  	case NR, NRK, NILH, NILF:
  1105  		ret = "ANDW"
  1106  	case OGR, OGRK, OILF:
  1107  		ret = "OR"
  1108  	case OR, ORK, OILH, OILL:
  1109  		ret = "ORW"
  1110  	case XGR, XGRK, XILF:
  1111  		ret = "XOR"
  1112  	case XR, XRK:
  1113  		ret = "XORW"
  1114  	}
  1115  	return ret
  1116  }
  1117  
  1118  // This function parses memory operand of type D(B)
  1119  func mem_operand(args []string) string {
  1120  	if args[0] != "" && args[1] != "" {
  1121  		args[0] = fmt.Sprintf("%s(%s)", args[0], args[1])
  1122  	} else if args[0] != "" {
  1123  		args[0] = fmt.Sprintf("$%s", args[0])
  1124  	} else if args[1] != "" {
  1125  		args[0] = fmt.Sprintf("(%s)", args[1])
  1126  	} else {
  1127  		args[0] = ""
  1128  	}
  1129  	return args[0]
  1130  }
  1131  
  1132  // This function parses memory operand of type D(X,B)
  1133  func mem_operandx(args []string) string {
  1134  	if args[1] != "" && args[2] != "" {
  1135  		args[1] = fmt.Sprintf("(%s)(%s*1)", args[2], args[1])
  1136  	} else if args[1] != "" {
  1137  		args[1] = fmt.Sprintf("(%s)", args[1])
  1138  	} else if args[2] != "" {
  1139  		args[1] = fmt.Sprintf("(%s)", args[2])
  1140  	} else if args[0] != "" {
  1141  		args[1] = ""
  1142  	}
  1143  	if args[0] != "" && args[1] != "" {
  1144  		args[0] = fmt.Sprintf("%s%s", args[0], args[1])
  1145  	} else if args[0] != "" {
  1146  		args[0] = fmt.Sprintf("$%s", args[0])
  1147  	} else if args[1] != "" {
  1148  		args[0] = fmt.Sprintf("%s", args[1])
  1149  	} else {
  1150  		args[0] = ""
  1151  	}
  1152  	return args[0]
  1153  }
  1154  
  1155  // This function parses memory operand of type D(V,B)
  1156  func mem_operandv(args []string) string {
  1157  	if args[1] != "" && args[2] != "" {
  1158  		args[1] = fmt.Sprintf("(%s)(%s*1)", args[2], args[1])
  1159  	} else if args[1] != "" {
  1160  		args[1] = fmt.Sprintf("(%s*1)", args[1])
  1161  	} else if args[2] != "" {
  1162  		args[1] = fmt.Sprintf("(%s)", args[2])
  1163  	} else if args[0] != "" {
  1164  		args[1] = ""
  1165  	}
  1166  	if args[0] != "" && args[1] != "" {
  1167  		args[0] = fmt.Sprintf("%s%s", args[0], args[1])
  1168  	} else if args[0] != "" {
  1169  		args[0] = fmt.Sprintf("$%s", args[0])
  1170  	} else if args[1] != "" {
  1171  		args[0] = fmt.Sprintf("%s", args[1])
  1172  	} else {
  1173  		args[0] = ""
  1174  	}
  1175  	return args[0]
  1176  }
  1177  
  1178  // This function parses memory operand of type D(L,B)
  1179  func mem_operandl(args []string) (string, string) {
  1180  	if args[0] != "" && args[2] != "" {
  1181  		args[0] = fmt.Sprintf("%s(%s)", args[0], args[2])
  1182  	} else if args[2] != "" {
  1183  		args[0] = fmt.Sprintf("(%s)", args[2])
  1184  	} else {
  1185  		args[0] = fmt.Sprintf("%s", args[0])
  1186  	}
  1187  	return args[0], args[1]
  1188  }
  1189  
  1190  // plan9Arg formats arg (which is the argIndex's arg in inst) according to Plan 9 rules.
  1191  // NOTE: because Plan9Syntax is the only caller of this func, and it receives a copy
  1192  // of inst, it's ok to modify inst.Args here.
  1193  func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
  1194  	switch arg.(type) {
  1195  	case Reg:
  1196  		if arg == R13 {
  1197  			return "g"
  1198  		}
  1199  		return strings.ToUpper(arg.String(pc)[1:])
  1200  	case Base:
  1201  		if arg == R13 {
  1202  			return "g"
  1203  		}
  1204  		s := arg.String(pc)
  1205  		if s != "" {
  1206  			return strings.ToUpper(s[1 : len(s)-1])
  1207  		}
  1208  		return "R0"
  1209  	case Index:
  1210  		if arg == R13 {
  1211  			return "g"
  1212  		}
  1213  		s := arg.String(pc)
  1214  		if s != "" {
  1215  			return strings.ToUpper(s[1:])
  1216  		}
  1217  		return ""
  1218  	case VReg:
  1219  		return strings.ToUpper(arg.String(pc)[1:])
  1220  	case Disp20, Disp12:
  1221  		numstr := arg.String(pc)
  1222  		num, err := strconv.Atoi(numstr[:len(numstr)])
  1223  		if err != nil {
  1224  			return fmt.Sprintf("plan9Arg: error in converting Atoi:%s", err)
  1225  		}
  1226  		if num == 0 {
  1227  			return ""
  1228  		} else {
  1229  			return strconv.Itoa(num)
  1230  		}
  1231  	case RegIm12, RegIm16, RegIm24, RegIm32:
  1232  		addr, err := strconv.ParseUint(arg.String(pc)[2:], 16, 64)
  1233  		if err != nil {
  1234  			return fmt.Sprintf("plan9Arg: error in converting ParseUint:%s", err)
  1235  		}
  1236  		off := int(addr - pc)
  1237  		s, base := symname(addr)
  1238  		if s != "" && addr == base {
  1239  			return fmt.Sprintf("%s(SB)", s)
  1240  		}
  1241  		off = off / inst.Len
  1242  		return fmt.Sprintf("%v(PC)", off)
  1243  	case Imm, Sign8, Sign16, Sign32:
  1244  		numImm := arg.String(pc)
  1245  		switch arg.(type) {
  1246  		case Sign32, Sign16, Imm:
  1247  			num, err := strconv.ParseInt(numImm, 10, 64)
  1248  			if err != nil {
  1249  				return fmt.Sprintf("plan9Arg: error in converting ParseInt:%s", err)
  1250  			}
  1251  			switch inst.Op {
  1252  			case LLIHF:
  1253  				num = num << 32
  1254  			case LLILH:
  1255  				num = num << 16
  1256  			case NILH:
  1257  				num = (num << 16) | int64(0xFFFF)
  1258  			case OILH:
  1259  				num = num << 16
  1260  			}
  1261  			numImm = fmt.Sprintf("%d", num)
  1262  		}
  1263  		return fmt.Sprintf("$%s", numImm)
  1264  	case Mask, Len:
  1265  		num := arg.String(pc)
  1266  		return fmt.Sprintf("$%s", num)
  1267  	}
  1268  	return fmt.Sprintf("???(%v)", arg)
  1269  }
  1270  
  1271  // It checks any 2 args of given instructions to swap or not
  1272  func reverseOperandOrder(op Op) bool {
  1273  	switch op {
  1274  	case LOCR, MLGR:
  1275  		return true
  1276  	case LTEBR, LTDBR, LCDBR, LGDR:
  1277  		return true
  1278  	case VLEIB, VLEIH, VLEIF, VLEIG, VPDI:
  1279  		return true
  1280  	case VSLDB:
  1281  		return true
  1282  	}
  1283  	return false
  1284  }
  1285  
  1286  // It checks whether to reverse all the args of given mnemonic or not
  1287  func reverseAllOperands(op Op) bool {
  1288  	switch op {
  1289  	case VLVGP: //3-operand list
  1290  		return true
  1291  	case VSEL, VPERM: //4-Operand list
  1292  		return true
  1293  	}
  1294  	return false
  1295  }
  1296  

View as plain text