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:
   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 MSGFR, MHI, MSFI, MSGFI:
   353  		switch inst.Op {
   354  		case MSGFR, MHI, MSFI:
   355  			op = "MULLW"
   356  		case MSGFI:
   357  			op = "MULLD"
   358  		}
   359  		args[0], args[1] = args[1], args[0]
   360  
   361  	case NGR, NR, NILL, NILF, NILH, OGR, OR, OILL, OILF, OILH, XGR, XR, XILF:
   362  		op = bitwise_op(inst.Op)
   363  		args[0], args[1] = args[1], args[0]
   364  		switch inst.Op {
   365  		case NILL:
   366  			if int(inst.Args[1].(Sign16)) < 0 {
   367  				op = "ANDW"
   368  			}
   369  
   370  		case NILF:
   371  			if int(inst.Args[1].(Sign32)) < 0 {
   372  				op = "AND"
   373  			}
   374  		case OILF:
   375  			if int(inst.Args[1].(Sign32)) < 0 {
   376  				op = "ORW"
   377  			}
   378  		case XILF:
   379  			if int(inst.Args[1].(Sign32)) < 0 {
   380  				op = "XORW"
   381  			}
   382  		}
   383  
   384  	case NGRK, NRK, OGRK, ORK, XGRK, XRK: // opcode R1, R2, R3
   385  		op = bitwise_op(inst.Op)
   386  		args[0], args[1], args[2] = args[1], args[2], args[0]
   387  	case SLLG, SRLG, SLLK, SRLK, RLL, RLLG, SRAK, SRAG:
   388  		switch inst.Op {
   389  		case SLLG:
   390  			op = "SLD"
   391  		case SRLG:
   392  			op = "SRD"
   393  		case SLLK:
   394  			op = "SLW"
   395  		case SRLK:
   396  			op = "SRW"
   397  		case SRAK:
   398  			op = "SRAW"
   399  		case SRAG:
   400  			op = "SRAD"
   401  		}
   402  		args[0], args[2] = args[2], args[0]
   403  	case TRAP2, SVC:
   404  		op = "SYSALL"
   405  	case CR, CLR, CGR, CLGR, KDBR, CDBR, CEBR, CGHI, CHI, CGFI, CLGFI, CFI, CLFI:
   406  		switch inst.Op {
   407  		case CGHI, CGFI, CGR:
   408  			op = "CMP"
   409  		case CHI, CFI, CR:
   410  			op = "CMPW"
   411  		case CLGFI, CLGR:
   412  			op = "CMPU"
   413  		case CLFI, CLR:
   414  			op = "CMPWU"
   415  		case CDBR:
   416  			op = "FCMPU"
   417  		case KDBR:
   418  			op = "FCMPO"
   419  		}
   420  	case CEFBRA, CDFBRA, CEGBRA, CDGBRA, CELFBR, CDLFBR, CELGBR, CDLGBR, CFEBRA, CFDBRA, CGEBRA, CGDBRA, CLFEBR, CLFDBR, CLGEBR, CLGDBR:
   421  		args[0], args[1] = args[2], args[0]
   422  		args = args[:2]
   423  	case CGRJ, CGIJ:
   424  		mask, err := strconv.Atoi(args[2][1:])
   425  		if err != nil {
   426  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   427  		}
   428  		var check bool
   429  		switch mask & 0xf {
   430  		case 2:
   431  			op = "CMPBGT"
   432  			check = true
   433  		case 4:
   434  			op = "CMPBLT"
   435  			check = true
   436  		case 6:
   437  			op = "CMPBNE"
   438  			check = true
   439  		case 8:
   440  			op = "CMPBEQ"
   441  			check = true
   442  		case 10:
   443  			op = "CMPBGE"
   444  			check = true
   445  		case 12:
   446  			op = "CMPBLE"
   447  			check = true
   448  		}
   449  		if check {
   450  			args[2] = args[3]
   451  			args = args[:3]
   452  		}
   453  	case CLGRJ, CLGIJ:
   454  		mask, err := strconv.Atoi(args[2][1:])
   455  		if err != nil {
   456  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   457  		}
   458  		var check bool
   459  		switch mask & 0xf {
   460  		case 2:
   461  			op = "CMPUBGT"
   462  			check = true
   463  		case 4:
   464  			op = "CMPUBLT"
   465  			check = true
   466  		case 7:
   467  			op = "CMPUBNE"
   468  			check = true
   469  		case 8:
   470  			op = "CMPUBEQ"
   471  			check = true
   472  		case 10:
   473  			op = "CMPUBGE"
   474  			check = true
   475  		case 12:
   476  			op = "CMPUBLE"
   477  			check = true
   478  		}
   479  		if check {
   480  			args[2] = args[3]
   481  			args = args[:3]
   482  		}
   483  	case CLRJ, CRJ, CIJ, CLIJ:
   484  		args[0], args[1], args[2] = args[2], args[0], args[1]
   485  	case BRC, BRCL:
   486  		mask, err := strconv.Atoi(args[0][1:])
   487  		if err != nil {
   488  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   489  		}
   490  		opStr, check := branch_relative_op(mask, inst.Op)
   491  		if opStr != "" {
   492  			op = opStr
   493  		}
   494  		if check {
   495  			args[0] = args[1]
   496  			args = args[:1]
   497  		}
   498  	case BCR:
   499  		mask, err := strconv.Atoi(args[0][1:])
   500  		if err != nil {
   501  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   502  		}
   503  		opStr, check := branchOnConditionOp(mask, inst.Op)
   504  		if opStr != "" {
   505  			op = opStr
   506  		}
   507  		if op == "SYNC" || op == "NOPH" {
   508  			return op
   509  		}
   510  		if check {
   511  			args[0] = args[1]
   512  			args = args[:1]
   513  		}
   514  	case LOCGR:
   515  		mask, err := strconv.Atoi(args[2][1:])
   516  		if err != nil {
   517  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   518  		}
   519  		var check bool
   520  		switch mask & 0xf {
   521  		case 2: //Greaterthan (M=2)
   522  			op = "MOVDGT"
   523  			check = true
   524  		case 4: //Lessthan (M=4)
   525  			op = "MOVDLT"
   526  			check = true
   527  		case 7: // Not Equal (M=7)
   528  			op = "MOVDNE"
   529  			check = true
   530  		case 8: // Equal (M=8)
   531  			op = "MOVDEQ"
   532  			check = true
   533  		case 10: // Greaterthan or Equal (M=10)
   534  			op = "MOVDGE"
   535  			check = true
   536  		case 12: // Lessthan or Equal (M=12)
   537  			op = "MOVDLE"
   538  			check = true
   539  		}
   540  		if check {
   541  			args[0], args[1] = args[1], args[0]
   542  			args = args[:2]
   543  		} else {
   544  			args[0], args[2] = args[2], args[0]
   545  		}
   546  	case BRASL:
   547  		op = "CALL" // BL
   548  		args[0] = args[1]
   549  		args = args[:1]
   550  	case X, XY, XG:
   551  		switch inst.Op {
   552  		case X, XY:
   553  			op = "XORW"
   554  		case XG:
   555  			op = "XOR"
   556  		}
   557  	case N, NY, NG, O, OY, OG, XC, NC, OC, MVC, MVCIN, CLC:
   558  		switch inst.Op {
   559  		case N, NY:
   560  			op = "ANDW"
   561  		case NG:
   562  			op = "AND"
   563  		case O, OY:
   564  			op = "ORW"
   565  		case OG:
   566  			op = "OR"
   567  		}
   568  		args[0], args[1] = args[1], args[0]
   569  	case S, SY, SLBG, SLG, SG:
   570  		switch inst.Op {
   571  		case S, SY:
   572  			op = "SUBW"
   573  		case SLBG:
   574  			op = "SUBE"
   575  		case SLG:
   576  			op = "SUBC"
   577  		case SG:
   578  			op = "SUB"
   579  		}
   580  		args[0], args[1] = args[1], args[0]
   581  	case MSG, MSY, MS:
   582  		switch inst.Op {
   583  		case MSG:
   584  			op = "MULLD"
   585  		case MSY, MS:
   586  			op = "MULLW"
   587  		}
   588  	case A, AY, ALCG, ALG, AG:
   589  		switch inst.Op {
   590  		case A, AY:
   591  			op = "ADDW"
   592  		case ALCG:
   593  			op = "ADDE"
   594  		case ALG:
   595  			op = "ADDC"
   596  		case AG:
   597  			op = "ADD"
   598  		}
   599  		args[0], args[1] = args[1], args[0]
   600  	case RISBG, RISBGN, RISBHG, RISBLG, RNSBG, RXSBG, ROSBG:
   601  		switch inst.Op {
   602  		case RNSBG, RXSBG, ROSBG:
   603  			num, err := strconv.Atoi(args[2][1:])
   604  			if err != nil {
   605  				return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   606  			}
   607  			if ((num >> 7) & 0x1) != 0 {
   608  				op = op + "T"
   609  			}
   610  		case RISBG, RISBGN, RISBHG, RISBLG:
   611  			num, err := strconv.Atoi(args[3][1:])
   612  			if err != nil {
   613  				return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   614  			}
   615  			if ((num >> 7) & 0x1) != 0 {
   616  				op = op + "Z"
   617  			}
   618  		}
   619  		if len(args) == 5 {
   620  			args[0], args[1], args[2], args[3], args[4] = args[2], args[3], args[4], args[1], args[0]
   621  		} else {
   622  			args[0], args[1], args[2], args[3] = args[2], args[3], args[1], args[0]
   623  		}
   624  
   625  	case VEC, VECL, VCLZ, VCTZ, VREPI, VPOPCT: //mnemonic V1, V2, M3
   626  		mask, err := strconv.Atoi(args[2][1:])
   627  		if err != nil {
   628  			return fmt.Sprintf("GoSyntax: error in converting Atoi for %q:%s", op, err)
   629  		}
   630  		val := mask & 0x7
   631  		if val >= 0 && val < 4 {
   632  			op = op + vectorSize[val]
   633  			args = args[:2]
   634  		} else {
   635  			return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   636  		}
   637  		switch inst.Op {
   638  		case VCLZ, VCTZ, VREPI, VPOPCT:
   639  			args[0], args[1] = args[1], args[0]
   640  		default:
   641  		}
   642  		//Mnemonic V1, V2, V3, M4 or Mnemonic V1, I2, I3, M4 or Mnemonic V1, V3, I2, M4
   643  	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:
   644  		mask, err := strconv.Atoi(args[3][1:])
   645  		if err != nil {
   646  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   647  		}
   648  		val := mask & 0x7
   649  		switch inst.Op {
   650  		case VA, VS, VACC, VSCBI:
   651  			if val >= 0 && val < 5 {
   652  				if args[0] == args[2] {
   653  					args[0], args[1] = args[1], args[0]
   654  					args = args[:2]
   655  				} else if inst.Op == VS {
   656  					if args[0] == args[1] {
   657  						args[0] = args[2]
   658  						args = args[:2]
   659  					} else {
   660  						args[0], args[2] = args[2], args[0]
   661  						args = args[:3]
   662  					}
   663  				} else {
   664  					args[0], args[1], args[2] = args[1], args[2], args[0]
   665  					args = args[:3]
   666  				}
   667  				op = op + vectorSize[val]
   668  			} else {
   669  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   670  			}
   671  		case VAVG, VAVGL, VMX, VMXL, VMN, VMNL, VGFM, VGM:
   672  			if val >= 0 && val < 4 {
   673  				op = op + vectorSize[val]
   674  				args[0], args[1], args[2] = args[1], args[2], args[0]
   675  				args = args[:3]
   676  			} else {
   677  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   678  			}
   679  		case VREP, VERLLV, VESLV:
   680  			if val >= 0 && val < 4 {
   681  				op = op + vectorSize[val]
   682  				args[0], args[2] = args[2], args[0]
   683  				args = args[:3]
   684  			} else {
   685  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   686  			}
   687  		case VSUM, VSUMG, VSUMQ:
   688  			var off int
   689  			switch inst.Op {
   690  			case VSUM:
   691  				off = 0
   692  			case VSUMG:
   693  				off = 1
   694  			case VSUMQ:
   695  				off = 2
   696  			}
   697  			if (val > (-1 + off)) && (val < (2 + off)) {
   698  				op = op + vectorSize[val]
   699  			} else {
   700  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   701  			}
   702  			args = args[:3]
   703  		case VML, VMH, VMLH, VME, VMLE, VMO, VMLO:
   704  			if val >= 0 && val < 3 {
   705  				op = op + vectorSize[val]
   706  			}
   707  			if op == "VML" && val == 2 {
   708  				op = op + "W"
   709  			}
   710  			if args[0] == args[2] {
   711  				args[0], args[1] = args[1], args[0]
   712  				args = args[:2]
   713  			} else {
   714  				args[0], args[1], args[2] = args[1], args[2], args[0]
   715  				args = args[:3]
   716  			}
   717  		}
   718  
   719  	case VGFMA, VERIM, VMAH, VMALH: // Mnemonic V1, V2, V3, V4/I4, M5
   720  		mask, err := strconv.Atoi(args[4][1:])
   721  		if err != nil {
   722  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   723  		}
   724  		val := mask & 0x7
   725  		args = args[:4]
   726  		var off int
   727  		switch inst.Op {
   728  		case VMAH, VMALH:
   729  			off = -1
   730  		}
   731  
   732  		if val >= 0 && val < (4+off) {
   733  			op = op + vectorSize[val]
   734  		} else {
   735  			return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   736  		}
   737  		switch inst.Op {
   738  		case VGFMA, VMAH, VMALH:
   739  			args[0], args[1], args[2], args[3] = args[1], args[2], args[3], args[0]
   740  		default:
   741  			args[0], args[3] = args[3], args[0]
   742  		}
   743  	case VSTRC, VFAE, VFEE, VFENE:
   744  		var off uint8
   745  		switch inst.Op {
   746  		case VSTRC:
   747  			off = uint8(1)
   748  		default:
   749  			off = uint8(0)
   750  		}
   751  		m1, err := strconv.Atoi(args[3+off][1:])
   752  		if err != nil {
   753  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   754  		}
   755  		m2, err := strconv.Atoi(args[4+off][1:])
   756  		if err != nil {
   757  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   758  		}
   759  		index := m1 & 0x3
   760  		if index < 0 || index > 2 {
   761  			return fmt.Sprintf("specification exception is recognized for %q with mask values: %v, %v \n", op, m1, m2)
   762  		}
   763  		switch m2 {
   764  		case 0:
   765  			op = op + vectorSize[index]
   766  		case 1:
   767  			op = op + vectorCS[index]
   768  		case 2:
   769  			op = op + "Z" + vectorSize[index]
   770  		case 3:
   771  			op = op + "Z" + vectorCS[index]
   772  		default:
   773  			return fmt.Sprintf("specification exception is recognized for %q with mask values: %v, %v \n", op, m1, m2)
   774  		}
   775  		switch inst.Op {
   776  		case VSTRC:
   777  			args[0], args[1], args[2], args[3] = args[1], args[2], args[3], args[0]
   778  		default:
   779  			args[0], args[1], args[2] = args[1], args[2], args[0]
   780  		}
   781  		args = args[:3+off]
   782  
   783  	case VCEQ, VCH, VCHL: // Mnemonic V1, V2, V3, M4, M5
   784  		m4, err := strconv.Atoi(args[3][1:])
   785  		if err != nil {
   786  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   787  		}
   788  		m5, err := strconv.Atoi(args[4][1:])
   789  		if err != nil {
   790  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   791  		}
   792  		val := (m4 & 0x7)
   793  		if m5 == 0 {
   794  			if val >= 0 && val < 4 {
   795  				op = op + vectorSize[val]
   796  				args[0], args[1], args[2] = args[1], args[2], args[0]
   797  				args = args[:3]
   798  			} else {
   799  				return fmt.Sprintf("specification exception is recognized for %q with mask(m4) value: %v \n", op, m4)
   800  			}
   801  		} else if m5 == 1 {
   802  			if val >= 0 && val < 4 {
   803  				op = op + vectorCS[val]
   804  				args[0], args[1], args[2] = args[1], args[2], args[0]
   805  				args = args[:3]
   806  			} else {
   807  				return fmt.Sprintf("specification exception is recognized for %q with mask(m4) value: %v \n", op, m4)
   808  			}
   809  		} else {
   810  			return fmt.Sprintf("specification exception is recognized for %q with mask(m5) value: %v \n", op, m5)
   811  		}
   812  	case VFMA, VFMS, VMSL: //Mnemonic V1, V2, V3, V4, M5, M6
   813  		m5, err := strconv.Atoi(args[4][1:])
   814  		if err != nil {
   815  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   816  		}
   817  		m6, err := strconv.Atoi(args[5][1:])
   818  		if err != nil {
   819  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   820  		}
   821  		switch inst.Op {
   822  		case VMSL:
   823  			if m5 == 3 && m6 == 8 {
   824  				op = op + "EG"
   825  			} else if m5 == 3 && m6 == 4 {
   826  				op = op + "OG"
   827  			} else if m5 == 3 && m6 == 12 {
   828  				op = op + "EOG"
   829  			} else if m5 == 3 {
   830  				op = op + "G"
   831  			}
   832  		default:
   833  			if m5 == 0 && m6 == 3 {
   834  				op = op + "DB"
   835  			} else if m5 == 8 && m6 == 3 {
   836  				op = "W" + op[1:] + "DB"
   837  			} else {
   838  				return fmt.Sprintf("specification exception is recognized for %q with m5: %v m6: %v \n", op, m5, m6)
   839  			}
   840  		}
   841  		args[0], args[1], args[2], args[3] = args[1], args[2], args[3], args[0]
   842  		args = args[:4]
   843  
   844  	case VFCE, VFCH, VFCHE: //Mnemonic V1,V2,V3,M4,M5,M6
   845  		m4, err := strconv.Atoi(args[3][1:])
   846  		if err != nil {
   847  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   848  		}
   849  		m5, err := strconv.Atoi(args[4][1:])
   850  		if err != nil {
   851  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   852  		}
   853  		m6, err := strconv.Atoi(args[5][1:])
   854  		if err != nil {
   855  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   856  		}
   857  		if m5 == 0 {
   858  			if m4 == 3 && m6 == 0 {
   859  				op = op + "DB"
   860  			} else if m4 == 3 && m6 == 1 {
   861  				op = op + "DBS"
   862  			} else {
   863  				return fmt.Sprintf("specification exception is recognized for %q with m4: %v, m6: %v \n", op, m4, m6)
   864  			}
   865  
   866  		} else if m5 == 8 {
   867  			if m4 == 3 && m6 == 0 {
   868  				op = "W" + op[1:] + "DB"
   869  			} else if m4 == 3 && m6 == 1 {
   870  				op = "W" + op[1:] + "DBS"
   871  			} else {
   872  				return fmt.Sprintf("specification exception is recognized for %q with m4: %v, m6: %v \n", op, m4, m6)
   873  			}
   874  		} else {
   875  			return fmt.Sprintf("specification exception is recognized for %q with m5: %v \n", op, m5)
   876  		}
   877  		args[0], args[1], args[2] = args[1], args[2], args[0]
   878  		args = args[:3]
   879  
   880  	case VFTCI:
   881  		m4, err := strconv.Atoi(args[3][1:])
   882  		if err != nil {
   883  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   884  		}
   885  		m5, err := strconv.Atoi(args[4][1:])
   886  		if err != nil {
   887  			return fmt.Sprintf("GoSyntax: %q error in converting Atoi:%s", op, err)
   888  		}
   889  		val := (m4 & 0x7)
   890  		if m5 == 0 {
   891  			switch val {
   892  			case 2:
   893  				op = op + "SB"
   894  			case 3:
   895  				op = op + "DB"
   896  			default:
   897  				return fmt.Sprintf("specification exception is recognized for %q with mask(m4) value: %v \n", op, m4)
   898  			}
   899  		} else if m5 == 8 {
   900  			switch val {
   901  			case 2:
   902  				op = "W" + op[1:] + "SB"
   903  			case 3:
   904  				op = "W" + op[1:] + "DB"
   905  			case 4:
   906  				op = "W" + op[1:] + "XB"
   907  			default:
   908  				return fmt.Sprintf("specification exception is recognized for %q with mask(m4) value: %v \n", op, m4)
   909  			}
   910  		} else {
   911  			return fmt.Sprintf("specification exception is recognized for %q with mask(m5) value: %v \n", op, m5)
   912  		}
   913  		args[0], args[2] = args[2], args[0]
   914  		args = args[:3]
   915  	case VAC, VACCC:
   916  		mask, err := strconv.Atoi(args[4][1:])
   917  		if err != nil {
   918  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   919  		}
   920  		if mask&0x04 == 0 {
   921  			return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, mask)
   922  		}
   923  		op = op + "Q"
   924  		args[0], args[1], args[2], args[3] = args[1], args[2], args[3], args[0]
   925  		args = args[:4]
   926  	case VL, VLREP:
   927  		switch inst.Op {
   928  		case VL:
   929  			args[0], args[1] = args[1], args[0]
   930  		case VLREP:
   931  			args[0], args[1] = args[1], args[0]
   932  			mask, err := strconv.Atoi(args[2][1:])
   933  			if err != nil {
   934  				return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   935  			}
   936  			if mask >= 0 && mask < 4 {
   937  				op = op + vectorSize[mask]
   938  			}
   939  		}
   940  		args = args[:2]
   941  	case VST, VSTEB, VSTEH, VSTEF, VSTEG, VLEB, VLEH, VLEF, VLEG: //Mnemonic V1, D2(X2,B2), M3
   942  		m, err := strconv.Atoi(args[2][1:])
   943  		if err != nil {
   944  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   945  		}
   946  		switch inst.Op {
   947  		case VST:
   948  			if m == 0 || (m > 2 && m < 5) {
   949  				args = args[:2]
   950  			} else {
   951  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, m)
   952  			}
   953  		case VLEB, VLEH, VLEF, VLEG:
   954  			args[0], args[2] = args[2], args[0]
   955  		default:
   956  			args[0], args[1], args[2] = args[2], args[0], args[1]
   957  		}
   958  	case VSTM, VSTL, VESL, VESRA, VLM, VERLL, VLVG: //Mnemonic V1, V3, D2(B2)[,M4] or V1, R3,D2(B2)
   959  		switch inst.Op {
   960  		case VSTM, VLM:
   961  			m, err := strconv.Atoi(args[3][1:])
   962  			if err != nil {
   963  				return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   964  			}
   965  			if !(m == 0 || (m > 2 && m < 5)) {
   966  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, m)
   967  			}
   968  			if inst.Op == VLM {
   969  				args[0], args[1], args[2] = args[2], args[0], args[1]
   970  			}
   971  			args = args[:3]
   972  		case VESL, VESRA, VERLL, VLVG:
   973  			m, err := strconv.Atoi(args[3][1:])
   974  			if err != nil {
   975  				return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
   976  			}
   977  			if m >= 0 && m < 4 {
   978  				op = op + vectorSize[m]
   979  			} else {
   980  				return fmt.Sprintf("specification exception is recognized for %q with mask value: %v \n", op, m)
   981  			}
   982  			switch inst.Op {
   983  			case VLVG:
   984  				args[0], args[2] = args[2], args[0]
   985  				args = args[:3]
   986  			default:
   987  				if args[0] == args[1] {
   988  					args[0] = args[2]
   989  					args = args[:2]
   990  					break
   991  				}
   992  				args[0], args[2] = args[2], args[0]
   993  				args = args[:3]
   994  			}
   995  		case VSTL:
   996  			args[0], args[1] = args[1], args[0]
   997  			args = args[:3]
   998  		}
   999  	case VGBM:
  1000  		val, err := strconv.Atoi(args[1][1:])
  1001  		if err != nil {
  1002  			return fmt.Sprintf("GoSyntax: error in converting Atoi:%s", err)
  1003  		}
  1004  		if val == 0 {
  1005  			op = "VZERO"
  1006  			args = args[:1]
  1007  		} else if val == 0xffff {
  1008  			op = "VONE"
  1009  			args = args[:1]
  1010  		} else {
  1011  			args[0], args[1] = args[1], args[0]
  1012  			args = args[:2]
  1013  		}
  1014  	case VN, VNC, VO, VX, VNO: //mnemonic V1, V2, V3
  1015  		if args[0] == args[2] {
  1016  			args = args[:2]
  1017  			args[0], args[1] = args[1], args[0]
  1018  		} else {
  1019  			args[0], args[1], args[2] = args[1], args[2], args[0]
  1020  		}
  1021  		if op == "VNO" {
  1022  			op = op + "T"
  1023  		}
  1024  	case VGEG, VGEF, VSCEG, VSCEF: //Mnemonic V1, D2(V2, B2), M3
  1025  		args[0], args[2] = args[2], args[0]
  1026  
  1027  	}
  1028  	if args != nil {
  1029  		op += " " + strings.Join(args, ", ")
  1030  	}
  1031  
  1032  	return op
  1033  }
  1034  
  1035  // This function returns corresponding extended mnemonic for the given
  1036  // branch on relative mnemonic.
  1037  func branch_relative_op(mask int, opconst Op) (op string, check bool) {
  1038  	switch mask & 0xf {
  1039  	case 2:
  1040  		op = "BGT"
  1041  		check = true
  1042  	case 4:
  1043  		op = "BLT"
  1044  		check = true
  1045  	case 5:
  1046  		op = "BLTU"
  1047  		check = true
  1048  	case 7:
  1049  		op = "BNE"
  1050  		check = true
  1051  	case 8:
  1052  		op = "BEQ"
  1053  		check = true
  1054  	case 10:
  1055  		op = "BGE"
  1056  		check = true
  1057  	case 12:
  1058  		op = "BLE"
  1059  		check = true
  1060  	case 13:
  1061  		op = "BLEU"
  1062  		check = true
  1063  	case 15:
  1064  		op = "JMP" // BR
  1065  		check = true
  1066  	}
  1067  	return op, check
  1068  }
  1069  
  1070  // This function returns corresponding extended mnemonic for the given
  1071  // brach on condition mnemonic.
  1072  func branchOnConditionOp(mask int, opconst Op) (op string, check bool) {
  1073  	switch mask & 0xf {
  1074  	case 0:
  1075  		op = "NOPH"
  1076  	case 14:
  1077  		op = "SYNC"
  1078  	case 15:
  1079  		op = "JMP"
  1080  		check = true
  1081  	}
  1082  	return op, check
  1083  }
  1084  
  1085  // This function returns corresponding plan9 mnemonic for the native bitwise mnemonic.
  1086  func bitwise_op(op Op) string {
  1087  	var ret string
  1088  	switch op {
  1089  	case NGR, NGRK, NILL:
  1090  		ret = "AND"
  1091  	case NR, NRK, NILH, NILF:
  1092  		ret = "ANDW"
  1093  	case OGR, OGRK, OILF:
  1094  		ret = "OR"
  1095  	case OR, ORK, OILH, OILL:
  1096  		ret = "ORW"
  1097  	case XGR, XGRK, XILF:
  1098  		ret = "XOR"
  1099  	case XR, XRK:
  1100  		ret = "XORW"
  1101  	}
  1102  	return ret
  1103  }
  1104  
  1105  // This function parses memory operand of type D(B)
  1106  func mem_operand(args []string) string {
  1107  	if args[0] != "" && args[1] != "" {
  1108  		args[0] = fmt.Sprintf("%s(%s)", args[0], args[1])
  1109  	} else if args[0] != "" {
  1110  		args[0] = fmt.Sprintf("$%s", args[0])
  1111  	} else if args[1] != "" {
  1112  		args[0] = fmt.Sprintf("(%s)", args[1])
  1113  	} else {
  1114  		args[0] = ""
  1115  	}
  1116  	return args[0]
  1117  }
  1118  
  1119  // This function parses memory operand of type D(X,B)
  1120  func mem_operandx(args []string) string {
  1121  	if args[1] != "" && args[2] != "" {
  1122  		args[1] = fmt.Sprintf("(%s)(%s*1)", args[2], args[1])
  1123  	} else if args[1] != "" {
  1124  		args[1] = fmt.Sprintf("(%s)", args[1])
  1125  	} else if args[2] != "" {
  1126  		args[1] = fmt.Sprintf("(%s)", args[2])
  1127  	} else if args[0] != "" {
  1128  		args[1] = ""
  1129  	}
  1130  	if args[0] != "" && args[1] != "" {
  1131  		args[0] = fmt.Sprintf("%s%s", args[0], args[1])
  1132  	} else if args[0] != "" {
  1133  		args[0] = fmt.Sprintf("$%s", args[0])
  1134  	} else if args[1] != "" {
  1135  		args[0] = fmt.Sprintf("%s", args[1])
  1136  	} else {
  1137  		args[0] = ""
  1138  	}
  1139  	return args[0]
  1140  }
  1141  
  1142  // This function parses memory operand of type D(V,B)
  1143  func mem_operandv(args []string) string {
  1144  	if args[1] != "" && args[2] != "" {
  1145  		args[1] = fmt.Sprintf("(%s)(%s*1)", args[2], args[1])
  1146  	} else if args[1] != "" {
  1147  		args[1] = fmt.Sprintf("(%s*1)", args[1])
  1148  	} else if args[2] != "" {
  1149  		args[1] = fmt.Sprintf("(%s)", args[2])
  1150  	} else if args[0] != "" {
  1151  		args[1] = ""
  1152  	}
  1153  	if args[0] != "" && args[1] != "" {
  1154  		args[0] = fmt.Sprintf("%s%s", args[0], args[1])
  1155  	} else if args[0] != "" {
  1156  		args[0] = fmt.Sprintf("$%s", args[0])
  1157  	} else if args[1] != "" {
  1158  		args[0] = fmt.Sprintf("%s", args[1])
  1159  	} else {
  1160  		args[0] = ""
  1161  	}
  1162  	return args[0]
  1163  }
  1164  
  1165  // This function parses memory operand of type D(L,B)
  1166  func mem_operandl(args []string) (string, string) {
  1167  	if args[0] != "" && args[2] != "" {
  1168  		args[0] = fmt.Sprintf("%s(%s)", args[0], args[2])
  1169  	} else if args[2] != "" {
  1170  		args[0] = fmt.Sprintf("(%s)", args[2])
  1171  	} else {
  1172  		args[0] = fmt.Sprintf("%s", args[0])
  1173  	}
  1174  	return args[0], args[1]
  1175  }
  1176  
  1177  // plan9Arg formats arg (which is the argIndex's arg in inst) according to Plan 9 rules.
  1178  // NOTE: because Plan9Syntax is the only caller of this func, and it receives a copy
  1179  // of inst, it's ok to modify inst.Args here.
  1180  func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
  1181  	switch arg.(type) {
  1182  	case Reg:
  1183  		if arg == R13 {
  1184  			return "g"
  1185  		}
  1186  		return strings.ToUpper(arg.String(pc)[1:])
  1187  	case Base:
  1188  		if arg == R13 {
  1189  			return "g"
  1190  		}
  1191  		s := arg.String(pc)
  1192  		if s != "" {
  1193  			return strings.ToUpper(s[1 : len(s)-1])
  1194  		}
  1195  		return "R0"
  1196  	case Index:
  1197  		if arg == R13 {
  1198  			return "g"
  1199  		}
  1200  		s := arg.String(pc)
  1201  		if s != "" {
  1202  			return strings.ToUpper(s[1:])
  1203  		}
  1204  		return ""
  1205  	case VReg:
  1206  		return strings.ToUpper(arg.String(pc)[1:])
  1207  	case Disp20, Disp12:
  1208  		numstr := arg.String(pc)
  1209  		num, err := strconv.Atoi(numstr[:len(numstr)])
  1210  		if err != nil {
  1211  			return fmt.Sprintf("plan9Arg: error in converting Atoi:%s", err)
  1212  		}
  1213  		if num == 0 {
  1214  			return ""
  1215  		} else {
  1216  			return strconv.Itoa(num)
  1217  		}
  1218  	case RegIm12, RegIm16, RegIm24, RegIm32:
  1219  		addr, err := strconv.ParseUint(arg.String(pc)[2:], 16, 64)
  1220  		if err != nil {
  1221  			return fmt.Sprintf("plan9Arg: error in converting ParseUint:%s", err)
  1222  		}
  1223  		off := int(addr - pc)
  1224  		s, base := symname(addr)
  1225  		if s != "" && addr == base {
  1226  			return fmt.Sprintf("%s(SB)", s)
  1227  		}
  1228  		off = off / inst.Len
  1229  		return fmt.Sprintf("%v(PC)", off)
  1230  	case Imm, Sign8, Sign16, Sign32:
  1231  		numImm := arg.String(pc)
  1232  		switch arg.(type) {
  1233  		case Sign32, Sign16, Imm:
  1234  			num, err := strconv.ParseInt(numImm, 10, 64)
  1235  			if err != nil {
  1236  				return fmt.Sprintf("plan9Arg: error in converting ParseInt:%s", err)
  1237  			}
  1238  			switch inst.Op {
  1239  			case LLIHF:
  1240  				num = num << 32
  1241  			case LLILH:
  1242  				num = num << 16
  1243  			case NILH:
  1244  				num = (num << 16) | int64(0xFFFF)
  1245  			case OILH:
  1246  				num = num << 16
  1247  			}
  1248  			numImm = fmt.Sprintf("%d", num)
  1249  		}
  1250  		return fmt.Sprintf("$%s", numImm)
  1251  	case Mask, Len:
  1252  		num := arg.String(pc)
  1253  		return fmt.Sprintf("$%s", num)
  1254  	}
  1255  	return fmt.Sprintf("???(%v)", arg)
  1256  }
  1257  
  1258  // It checks any 2 args of given instructions to swap or not
  1259  func reverseOperandOrder(op Op) bool {
  1260  	switch op {
  1261  	case LOCR, MLGR:
  1262  		return true
  1263  	case LTEBR, LTDBR:
  1264  		return true
  1265  	case VLEIB, VLEIH, VLEIF, VLEIG, VPDI:
  1266  		return true
  1267  	case VSLDB:
  1268  		return true
  1269  	}
  1270  	return false
  1271  }
  1272  
  1273  // It checks whether to reverse all the args of given mnemonic or not
  1274  func reverseAllOperands(op Op) bool {
  1275  	switch op {
  1276  	case VLVGP: //3-operand list
  1277  		return true
  1278  	case VSEL, VPERM: //4-Operand list
  1279  		return true
  1280  	}
  1281  	return false
  1282  }
  1283  

View as plain text