re PR go/89123 (Too many go test failures on s390x-linux)

PR go/89123
    internal/cpu, runtime: add S/390 CPU capability support
    
    Patch by Robin Dapp.
    
    Updates https://gcc.gnu.org/PR89123
    
    Reviewed-on: https://go-review.googlesource.com/c/162887

From-SVN: r268941
This commit is contained in:
Ian Lance Taylor 2019-02-15 14:51:10 +00:00
parent 7b54753033
commit a72128258b
4 changed files with 138 additions and 17 deletions

View File

@ -1,4 +1,4 @@
6877c95a5f44c3ab4f492d2000ce07771341d7b7
0563f2d018cdb2cd685c254bac5ceb38396d0a27
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.

View File

@ -70,3 +70,118 @@ struct xgetbv_ret xgetbv(void) {
#pragma GCC pop_options
#endif /* defined(__i386__) || defined(__x86_64__) */
#ifdef __s390__
struct facilityList {
uint64_t bits[4];
};
struct queryResult {
uint64_t bits[2];
};
struct facilityList stfle(void)
__asm__(GOSYM_PREFIX "internal..z2fcpu.stfle")
__attribute__((no_split_stack));
struct facilityList stfle(void) {
struct facilityList ret;
__asm__ ("la %%r1, %[ret]\t\n"
"lghi %%r0, 3\t\n" // last doubleword index to store
"xc 0(32,%%r1), 0(%%r1)\t\n" // clear 4 doublewords (32 bytes)
".long 0xb2b01000\t\n" // store facility list extended (STFLE)
:[ret] "=Q" (ret) : : "r0", "r1", "cc");
return ret;
}
struct queryResult kmQuery(void)
__asm__(GOSYM_PREFIX "internal..z2fcpu.kmQuery")
__attribute__((no_split_stack));
struct queryResult kmQuery() {
struct queryResult ret;
__asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KM-Query)
"la %%r1, %[ret]\t\n"
".long 0xb92e0024\t\n" // cipher message (KM)
:[ret] "=Q" (ret) : : "r0", "r1", "cc");
return ret;
}
struct queryResult kmcQuery(void)
__asm__(GOSYM_PREFIX "internal..z2fcpu.kmcQuery")
__attribute__((no_split_stack));
struct queryResult kmcQuery() {
struct queryResult ret;
__asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KMC-Query)
"la %%r1, %[ret]\t\n"
".long 0xb92f0024\t\n" // cipher message with chaining (KMC)
:[ret] "=Q" (ret) : : "r0", "r1", "cc");
return ret;
}
struct queryResult kmctrQuery(void)
__asm__(GOSYM_PREFIX "internal..z2fcpu.kmctrQuery")
__attribute__((no_split_stack));
struct queryResult kmctrQuery() {
struct queryResult ret;
__asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KMCTR-Query)
"la %%r1, %[ret]\t\n"
".long 0xb92d4024\t\n" // cipher message with counter (KMCTR)
:[ret] "=Q" (ret) : : "r0", "r1", "cc");
return ret;
}
struct queryResult kmaQuery(void)
__asm__(GOSYM_PREFIX "internal..z2fcpu.kmaQuery")
__attribute__((no_split_stack));
struct queryResult kmaQuery() {
struct queryResult ret;
__asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KMA-Query)
"la %%r1, %[ret]\t\n"
".long 0xb9296024\t\n" // cipher message with authentication (KMA)
:[ret] "=Q" (ret) : : "r0", "r1", "cc");
return ret;
}
struct queryResult kimdQuery(void)
__asm__(GOSYM_PREFIX "internal..z2fcpu.kimdQuery")
__attribute__((no_split_stack));
struct queryResult kimdQuery() {
struct queryResult ret;
__asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KIMD-Query)
"la %%r1, %[ret]\t\n"
".long 0xb93e0024\t\n" // compute intermediate message digest (KIMD)
:[ret] "=Q" (ret) : : "r0", "r1", "cc");
return ret;
}
struct queryResult klmdQuery(void)
__asm__(GOSYM_PREFIX "internal..z2fcpu.klmdQuery")
__attribute__((no_split_stack));
struct queryResult klmdQuery() {
struct queryResult ret;
__asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KLMD-Query)
"la %%r1, %[ret]\t\n"
".long 0xb93f0024\t\n" // compute last message digest (KLMD)
:[ret] "=Q" (ret) : : "r0", "r1", "cc");
return ret;
}
#endif /* defined(__s390__) */

View File

@ -98,13 +98,13 @@ func (s *facilityList) Has(fs ...facility) bool {
// The following feature detection functions are defined in cpu_s390x.s.
// They are likely to be expensive to call so the results should be cached.
func stfle() facilityList { panic("not implemented for gccgo") }
func kmQuery() queryResult { panic("not implemented for gccgo") }
func kmcQuery() queryResult { panic("not implemented for gccgo") }
func kmctrQuery() queryResult { panic("not implemented for gccgo") }
func kmaQuery() queryResult { panic("not implemented for gccgo") }
func kimdQuery() queryResult { panic("not implemented for gccgo") }
func klmdQuery() queryResult { panic("not implemented for gccgo") }
func stfle() facilityList
func kmQuery() queryResult
func kmcQuery() queryResult
func kmctrQuery() queryResult
func kmaQuery() queryResult
func kimdQuery() queryResult
func klmdQuery() queryResult
func doinit() {
options = []option{
@ -122,14 +122,6 @@ func doinit() {
aes := []function{aes128, aes192, aes256}
facilities := stfle()
S390X.HasZArch = facilities.Has(zarch)
S390X.HasSTFLE = facilities.Has(stflef)
S390X.HasLDisp = facilities.Has(ldisp)
S390X.HasEImm = facilities.Has(eimm)
S390X.HasDFP = facilities.Has(dfp)
S390X.HasETF3Enhanced = facilities.Has(etf3eh)
S390X.HasMSA = facilities.Has(msa)
if S390X.HasMSA {
// cipher message
km, kmc := kmQuery(), kmcQuery()

View File

@ -8,12 +8,26 @@ import "internal/cpu"
const (
// bit masks taken from bits/hwcap.h
_HWCAP_S390_VX = 2048 // vector facility
_HWCAP_S390_ZARCH = 2
_HWCAP_S390_STFLE = 4
_HWCAP_S390_MSA = 8
_HWCAP_S390_LDISP = 16
_HWCAP_S390_EIMM = 32
_HWCAP_S390_DFP = 64
_HWCAP_S390_ETF3EH = 256
_HWCAP_S390_VX = 2048 // vector facility
)
func archauxv(tag, val uintptr) {
switch tag {
case _AT_HWCAP: // CPU capability bit flags
cpu.S390X.HasZArch = val&_HWCAP_S390_ZARCH != 0
cpu.S390X.HasSTFLE = val&_HWCAP_S390_STFLE != 0
cpu.S390X.HasMSA = val&_HWCAP_S390_MSA != 0
cpu.S390X.HasLDisp = val&_HWCAP_S390_LDISP != 0
cpu.S390X.HasEImm = val&_HWCAP_S390_EIMM != 0
cpu.S390X.HasDFP = val&_HWCAP_S390_DFP != 0
cpu.S390X.HasETF3Enhanced = val&_HWCAP_S390_ETF3EH != 0
cpu.S390X.HasVX = val&_HWCAP_S390_VX != 0
}
}