...

Source file src/cmd/asm/internal/arch/riscv64.go

Documentation: cmd/asm/internal/arch

     1  // Copyright 2020 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  // This file encapsulates some of the odd characteristics of the RISCV64
     6  // instruction set, to minimize its interaction with the core of the
     7  // assembler.
     8  
     9  package arch
    10  
    11  import (
    12  	"cmd/internal/obj"
    13  	"cmd/internal/obj/riscv"
    14  	"fmt"
    15  )
    16  
    17  // IsRISCV64AMO reports whether op is an AMO instruction that requires
    18  // special handling.
    19  func IsRISCV64AMO(op obj.As) bool {
    20  	switch op {
    21  	case riscv.ASCW, riscv.ASCD, riscv.AAMOSWAPW, riscv.AAMOSWAPD, riscv.AAMOADDW, riscv.AAMOADDD,
    22  		riscv.AAMOANDW, riscv.AAMOANDD, riscv.AAMOORW, riscv.AAMOORD, riscv.AAMOXORW, riscv.AAMOXORD,
    23  		riscv.AAMOMINW, riscv.AAMOMIND, riscv.AAMOMINUW, riscv.AAMOMINUD,
    24  		riscv.AAMOMAXW, riscv.AAMOMAXD, riscv.AAMOMAXUW, riscv.AAMOMAXUD:
    25  		return true
    26  	}
    27  	return false
    28  }
    29  
    30  // IsRISCV64VTypeI reports whether op is a vtype immediate instruction that
    31  // requires special handling.
    32  func IsRISCV64VTypeI(op obj.As) bool {
    33  	return op == riscv.AVSETVLI || op == riscv.AVSETIVLI
    34  }
    35  
    36  // IsRISCV64CSRO reports whether the op is an instruction that uses
    37  // CSR symbolic names and whether that instruction expects a register
    38  // or an immediate source operand.
    39  func IsRISCV64CSRO(op obj.As) (imm bool, ok bool) {
    40  	switch op {
    41  	case riscv.ACSRRCI, riscv.ACSRRSI, riscv.ACSRRWI:
    42  		imm = true
    43  		fallthrough
    44  	case riscv.ACSRRC, riscv.ACSRRS, riscv.ACSRRW:
    45  		ok = true
    46  	}
    47  	return
    48  }
    49  
    50  // IsRISCV64PseudoCSRO reports whether the op is a pseudo instruction
    51  // that uses CSR symbolic names, whether that instruction expects a register
    52  // or an immediate source operand and what the expected index of the operand
    53  // containing the CSR name should be.
    54  func IsRISCV64PseudoCSRO(op obj.As) (imm bool, index int, ok bool) {
    55  	switch op {
    56  	case riscv.ACSRCI, riscv.ACSRSI, riscv.ACSRWI:
    57  		imm, index, ok = true, 1, true
    58  	case riscv.ACSRC, riscv.ACSRS, riscv.ACSRW:
    59  		imm, index, ok = false, 1, true
    60  	case riscv.ACSRR:
    61  		imm, index, ok = false, 0, true
    62  	}
    63  	return
    64  }
    65  
    66  var riscv64SpecialOperand map[string]riscv.SpecialOperand
    67  
    68  // RISCV64SpecialOperand returns the internal representation of a special operand.
    69  func RISCV64SpecialOperand(name string) riscv.SpecialOperand {
    70  	if riscv64SpecialOperand == nil {
    71  		// Generate mapping when function is first called.
    72  		riscv64SpecialOperand = map[string]riscv.SpecialOperand{}
    73  		for opd := riscv.SPOP_RVV_BEGIN; opd < riscv.SPOP_RVV_END; opd++ {
    74  			riscv64SpecialOperand[opd.String()] = opd
    75  		}
    76  		// Add the CSRs
    77  		for csrCode, csrName := range riscv.CSRs {
    78  			// The set of RVV special operand names and the set of CSR special operands
    79  			// names are disjoint and so can safely share a single namespace. However,
    80  			// it's possible that a future update to the CSRs in inst.go could introduce
    81  			// a conflict. This check ensures that such a conflict does not go
    82  			// unnoticed.
    83  			if _, ok := riscv64SpecialOperand[csrName]; ok {
    84  				panic(fmt.Sprintf("riscv64 special operand %q redefined", csrName))
    85  			}
    86  			riscv64SpecialOperand[csrName] = riscv.SpecialOperand(int(csrCode) + int(riscv.SPOP_CSR_BEGIN))
    87  		}
    88  		// Add the FENCE operands
    89  		for opd := riscv.SPOP_FENCE_BEGIN + 1; opd < riscv.SPOP_FENCE_END; opd++ {
    90  			riscv64SpecialOperand[opd.String()] = opd
    91  		}
    92  	}
    93  	if opd, ok := riscv64SpecialOperand[name]; ok {
    94  		return opd
    95  	}
    96  	return riscv.SPOP_END
    97  }
    98  
    99  // RISCV64ValidateVectorType reports whether the given configuration is a
   100  // valid vector type.
   101  func RISCV64ValidateVectorType(vsew, vlmul, vtail, vmask int64) error {
   102  	_, err := riscv.EncodeVectorType(vsew, vlmul, vtail, vmask)
   103  	return err
   104  }
   105  

View as plain text