1  
     2  
     3  
     4  
     5  package riscv64asm
     6  
     7  
     8  
     9  
    10  func implicitMask(instOp Op) bool {
    11  	switch instOp {
    12  	case VADC_VIM, VADC_VVM, VADC_VXM, VFMERGE_VFM, VMADC_VIM, VMADC_VVM,
    13  		VMADC_VXM, VMERGE_VIM, VMERGE_VVM, VMERGE_VXM, VMSBC_VVM, VMSBC_VXM,
    14  		VSBC_VVM, VSBC_VXM:
    15  		return true
    16  
    17  	default:
    18  		return false
    19  	}
    20  }
    21  
    22  func imaOrFma(instOp Op) bool {
    23  	switch instOp {
    24  	case VFMACC_VF, VFMACC_VV, VFMADD_VF, VFMADD_VV, VFMSAC_VF, VFMSAC_VV,
    25  		VFMSUB_VF, VFMSUB_VV, VFNMACC_VF, VFNMACC_VV, VFNMADD_VF, VFNMADD_VV,
    26  		VFNMSAC_VF, VFNMSAC_VV, VFNMSUB_VF, VFNMSUB_VV, VFWMACC_VF, VFWMACC_VV,
    27  		VFWMSAC_VF, VFWMSAC_VV, VFWNMACC_VF, VFWNMACC_VV, VFWNMSAC_VF,
    28  		VFWNMSAC_VV, VMACC_VV, VMACC_VX, VMADD_VV, VMADD_VX, VNMSAC_VV,
    29  		VNMSAC_VX, VNMSUB_VV, VNMSUB_VX, VWMACCSU_VV, VWMACCSU_VX, VWMACCUS_VX,
    30  		VWMACCU_VV, VWMACCU_VX, VWMACC_VV, VWMACC_VX:
    31  		return true
    32  
    33  	default:
    34  		return false
    35  	}
    36  }
    37  
    38  func pseudoRVVLoad(instOp Op) string {
    39  	switch instOp {
    40  	case VL1RE8_V:
    41  		return "VL1R.V"
    42  
    43  	case VL2RE8_V:
    44  		return "VL2R.V"
    45  
    46  	case VL4RE8_V:
    47  		return "VL4R.V"
    48  
    49  	case VL8RE8_V:
    50  		return "VL8R.V"
    51  	}
    52  
    53  	return ""
    54  }
    55  
    56  func pseudoRVVArith(instOp Op, rawArgs []Arg, args []string) (string, []string) {
    57  	var op string
    58  
    59  	switch instOp {
    60  	case VRSUB_VX:
    61  		if v, ok := rawArgs[1].(Reg); ok && v == X0 {
    62  			op = "VNEG.V"
    63  			args = append(args[:1], args[2:]...)
    64  		}
    65  
    66  	case VWADD_VX:
    67  		if v, ok := rawArgs[1].(Reg); ok && v == X0 {
    68  			op = "VWCVT.X.X.V"
    69  			args = append(args[:1], args[2:]...)
    70  		}
    71  
    72  	case VWADDU_VX:
    73  		if v, ok := rawArgs[1].(Reg); ok && v == X0 {
    74  			op = "VWCVTU.X.X.V"
    75  			args = append(args[:1], args[2:]...)
    76  		}
    77  
    78  	case VXOR_VI:
    79  		if v, ok := rawArgs[1].(Simm); ok && v.Imm == -1 {
    80  			op = "VNOT.V"
    81  			args = append(args[:1], args[2:]...)
    82  		}
    83  
    84  	case VNSRL_WX:
    85  		if v, ok := rawArgs[1].(Reg); ok && v == X0 {
    86  			op = "VNCVT.X.X.W"
    87  			args = append(args[:1], args[2:]...)
    88  		}
    89  
    90  	case VFSGNJN_VV:
    91  		vs2, ok1 := rawArgs[0].(Reg)
    92  		vs1, ok2 := rawArgs[1].(Reg)
    93  		if ok1 && ok2 && vs1 == vs2 {
    94  			op = "VFNEG.V"
    95  			args = args[1:]
    96  		}
    97  
    98  	case VFSGNJX_VV:
    99  		vs2, ok1 := rawArgs[0].(Reg)
   100  		vs1, ok2 := rawArgs[1].(Reg)
   101  		if ok1 && ok2 && vs1 == vs2 {
   102  			op = "VFABS.V"
   103  			args = args[1:]
   104  		}
   105  
   106  	case VMAND_MM:
   107  		vs2, ok1 := rawArgs[0].(Reg)
   108  		vs1, ok2 := rawArgs[1].(Reg)
   109  		if ok1 && ok2 && vs1 == vs2 {
   110  			op = "VMMV.M"
   111  			args = args[1:]
   112  		}
   113  
   114  	case VMXOR_MM:
   115  		vs2, ok1 := rawArgs[0].(Reg)
   116  		vs1, ok2 := rawArgs[1].(Reg)
   117  		vd, ok3 := rawArgs[2].(Reg)
   118  		if ok1 && ok2 && ok3 && vs1 == vs2 && vd == vs1 {
   119  			op = "VMCLR.M"
   120  			args = args[2:]
   121  		}
   122  
   123  	case VMXNOR_MM:
   124  		vs2, ok1 := rawArgs[0].(Reg)
   125  		vs1, ok2 := rawArgs[1].(Reg)
   126  		vd, ok3 := rawArgs[2].(Reg)
   127  		if ok1 && ok2 && ok3 && vs1 == vs2 && vd == vs1 {
   128  			op = "VMSET.M"
   129  			args = args[2:]
   130  		}
   131  
   132  	case VMNAND_MM:
   133  		vs2, ok1 := rawArgs[0].(Reg)
   134  		vs1, ok2 := rawArgs[1].(Reg)
   135  		if ok1 && ok2 && vs1 == vs2 {
   136  			op = "VMNOT.M"
   137  			args = args[1:]
   138  		}
   139  	}
   140  
   141  	return op, args
   142  }
   143  
View as plain text