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

     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  var riscv64SpecialOperand map[string]riscv.SpecialOperand
    51  
    52  // RISCV64SpecialOperand returns the internal representation of a special operand.
    53  func RISCV64SpecialOperand(name string) riscv.SpecialOperand {
    54  	if riscv64SpecialOperand == nil {
    55  		// Generate mapping when function is first called.
    56  		riscv64SpecialOperand = map[string]riscv.SpecialOperand{}
    57  		for opd := riscv.SPOP_RVV_BEGIN; opd < riscv.SPOP_RVV_END; opd++ {
    58  			riscv64SpecialOperand[opd.String()] = opd
    59  		}
    60  		// Add the CSRs
    61  		for csrCode, csrName := range riscv.CSRs {
    62  			// The set of RVV special operand names and the set of CSR special operands
    63  			// names are disjoint and so can safely share a single namespace. However,
    64  			// it's possible that a future update to the CSRs in inst.go could introduce
    65  			// a conflict. This check ensures that such a conflict does not go
    66  			// unnoticed.
    67  			if _, ok := riscv64SpecialOperand[csrName]; ok {
    68  				panic(fmt.Sprintf("riscv64 special operand %q redefined", csrName))
    69  			}
    70  			riscv64SpecialOperand[csrName] = riscv.SpecialOperand(int(csrCode) + int(riscv.SPOP_CSR_BEGIN))
    71  		}
    72  	}
    73  	if opd, ok := riscv64SpecialOperand[name]; ok {
    74  		return opd
    75  	}
    76  	return riscv.SPOP_END
    77  }
    78  
    79  // RISCV64ValidateVectorType reports whether the given configuration is a
    80  // valid vector type.
    81  func RISCV64ValidateVectorType(vsew, vlmul, vtail, vmask int64) error {
    82  	_, err := riscv.EncodeVectorType(vsew, vlmul, vtail, vmask)
    83  	return err
    84  }
    85  

View as plain text