Repository: rust
Issue: Missing support for target features on s390x
Labels: O-SystemZ

There are a number of places where rust handles architecture-specific features, in particular:

- the `target_feature` attribute to enable/disable features when compiling parts of the code base
- the `target_feature` conditional compilation option to check for the presence of a feature at compile time
- the `is_`_arch_`_feature_detected!` macro to check for the presence of a feature at run time

All of this seems to be missing for s390x at the moment.

The LLVM back-end does support fine-grained selection of features as defined by the architecture (Principles of Operation).  There is also support for run-time detection on Linux via the HWCAP mechanism and/or the `/proc/cpuinfo` file, however this is somewhat less fine-grained and uses slightly different naming conventions, so there may have to be some selection / name mapping here.

This is the current list of HWCAP values and the associated string in the `features` line in `/proc/cpuinfo`.  Where applicable, I've also listed the corresponding LLVM feature name and architecture level where it was introduced.  Some HWCAP values have no feature name, either because they're assumed to always present (LLVM doesn't support any architecture earlier than arch8), or because they refer to HW features without ISA impact.

```
HWCAP value          /proc           LLVM feature                          arch level
                     cpuinfo

HWCAP_S390_ESAN3     "esan3"         n/a
HWCAP_S390_ZARCH     "zarch"         n/a
HWCAP_S390_STFLE     "stfle"         n/a
HWCAP_S390_MSA       "msa"           n/a
HWCAP_S390_LDISP     "ldisp"         n/a
HWCAP_S390_EIMM      "eimm"          n/a
HWCAP_S390_DFP       "dfp"           n/a
HWCAP_S390_HPAGE     "edat"          n/a
HWCAP_S390_ETF3EH    "etf3eh"        n/a
HWCAP_S390_HIGH_GPRS "highgprs"      "high-word"                           arch9            
HWCAP_S390_TE        "te"            "transactional-execution"             arch10    
HWCAP_S390_VXRS      "vx"            "vector"                              arch11              
HWCAP_S390_VXRS_BCD  "vxd"           "vector-packed-decimal"               arch11  
HWCAP_S390_VXRS_EXT  "vxe"           "vector-enhancements-1"               arch12
HWCAP_S390_GS        "gs"            "guarded-storage"                     arch12    
HWCAP_S390_VXRS_EXT2 "vxe2"          "vector-enhancements-2"               arch13  
HWCAP_S390_VXRS_PDE  "vxp"           "vector-packed-decimal-enhancement"   arch13
HWCAP_S390_SORT      "sort"          "enhanced-sort"                       arch13            
HWCAP_S390_DFLT      "dflt"          "deflate-conversion"                  arch13           
HWCAP_S390_VXRS_PDE2 "vxp2"          "vector-packed-decimal-enhancement-2" arch14
HWCAP_S390_NNPA      "nnpa"          "nnp-assist"                          arch14                
HWCAP_S390_PCI_MIO   "pcimio"        n/a
HWCAP_S390_SIE       "sie"           n/a
```

As an alternative to using HWCAP, it would also be possible to detect the fine-grained facilities available in the hardware.  This could be done either by parsing the `facilities` line in `/proc/cpuinfo`, or else by using the STORE FACILITY LIST EXTENDED instruction.  The advantage would be that the HW facilities match 1:1 to the LLVM features.  The disadvantage is that certain facilities (e.g. "transactional-execution" or "vector") require OS support in addition to HW support, e.g. to swap extended register sets during context switch.  This is correctly handled by checking the HWCAP feature list, but will be missed by just checking for the HW facilities.