Text file src/cmd/vendor/golang.org/x/sys/unix/asm_zos_s390x.s

     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  //go:build zos && s390x && gc
     6  
     7  #include "textflag.h"
     8  
     9  #define PSALAA            1208(R0)
    10  #define GTAB64(x)           80(x)
    11  #define LCA64(x)            88(x)
    12  #define SAVSTACK_ASYNC(x)  336(x) // in the LCA
    13  #define CAA(x)               8(x)
    14  #define CEECAATHDID(x)     976(x) // in the CAA
    15  #define EDCHPXV(x)        1016(x) // in the CAA
    16  #define GOCB(x)           1104(x) // in the CAA
    17  
    18  // SS_*, where x=SAVSTACK_ASYNC
    19  #define SS_LE(x)             0(x)
    20  #define SS_GO(x)             8(x)
    21  #define SS_ERRNO(x)         16(x)
    22  #define SS_ERRNOJR(x)       20(x)
    23  
    24  // Function Descriptor Offsets
    25  #define __errno  0x156*16
    26  #define __err2ad 0x16C*16
    27  
    28  // Call Instructions
    29  #define LE_CALL    BYTE $0x0D; BYTE $0x76 // BL R7, R6
    30  #define SVC_LOAD   BYTE $0x0A; BYTE $0x08 // SVC 08 LOAD
    31  #define SVC_DELETE BYTE $0x0A; BYTE $0x09 // SVC 09 DELETE
    32  
    33  DATA zosLibVec<>(SB)/8, $0
    34  GLOBL zosLibVec<>(SB), NOPTR, $8
    35  
    36  TEXT ·initZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
    37  	MOVW PSALAA, R8
    38  	MOVD LCA64(R8), R8
    39  	MOVD CAA(R8), R8
    40  	MOVD EDCHPXV(R8), R8
    41  	MOVD R8, zosLibVec<>(SB)
    42  	RET
    43  
    44  TEXT ·GetZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
    45  	MOVD zosLibVec<>(SB), R8
    46  	MOVD R8, ret+0(FP)
    47  	RET
    48  
    49  TEXT ·clearErrno(SB), NOSPLIT, $0-0
    50  	BL   addrerrno<>(SB)
    51  	MOVD $0, 0(R3)
    52  	RET
    53  
    54  // Returns the address of errno in R3.
    55  TEXT addrerrno<>(SB), NOSPLIT|NOFRAME, $0-0
    56  	// Get library control area (LCA).
    57  	MOVW PSALAA, R8
    58  	MOVD LCA64(R8), R8
    59  
    60  	// Get __errno FuncDesc.
    61  	MOVD CAA(R8), R9
    62  	MOVD EDCHPXV(R9), R9
    63  	ADD  $(__errno), R9
    64  	LMG  0(R9), R5, R6
    65  
    66  	// Switch to saved LE stack.
    67  	MOVD SAVSTACK_ASYNC(R8), R9
    68  	MOVD 0(R9), R4
    69  	MOVD $0, 0(R9)
    70  
    71  	// Call __errno function.
    72  	LE_CALL
    73  	NOPH
    74  
    75  	// Switch back to Go stack.
    76  	XOR  R0, R0    // Restore R0 to $0.
    77  	MOVD R4, 0(R9) // Save stack pointer.
    78  	RET
    79  
    80  // func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
    81  TEXT ·svcCall(SB), NOSPLIT, $0
    82  	BL   runtime·save_g(SB)     // Save g and stack pointer
    83  	MOVW PSALAA, R8
    84  	MOVD LCA64(R8), R8
    85  	MOVD SAVSTACK_ASYNC(R8), R9
    86  	MOVD R15, 0(R9)
    87  
    88  	MOVD argv+8(FP), R1   // Move function arguments into registers
    89  	MOVD dsa+16(FP), g
    90  	MOVD fnptr+0(FP), R15
    91  
    92  	BYTE $0x0D // Branch to function
    93  	BYTE $0xEF
    94  
    95  	BL   runtime·load_g(SB)     // Restore g and stack pointer
    96  	MOVW PSALAA, R8
    97  	MOVD LCA64(R8), R8
    98  	MOVD SAVSTACK_ASYNC(R8), R9
    99  	MOVD 0(R9), R15
   100  
   101  	RET
   102  
   103  // func svcLoad(name *byte) unsafe.Pointer
   104  TEXT ·svcLoad(SB), NOSPLIT, $0
   105  	MOVD R15, R2         // Save go stack pointer
   106  	MOVD name+0(FP), R0  // Move SVC args into registers
   107  	MOVD $0x80000000, R1
   108  	MOVD $0, R15
   109  	SVC_LOAD
   110  	MOVW R15, R3         // Save return code from SVC
   111  	MOVD R2, R15         // Restore go stack pointer
   112  	CMP  R3, $0          // Check SVC return code
   113  	BNE  error
   114  
   115  	MOVD $-2, R3       // Reset last bit of entry point to zero
   116  	AND  R0, R3
   117  	MOVD R3, ret+8(FP) // Return entry point returned by SVC
   118  	CMP  R0, R3        // Check if last bit of entry point was set
   119  	BNE  done
   120  
   121  	MOVD R15, R2 // Save go stack pointer
   122  	MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
   123  	SVC_DELETE
   124  	MOVD R2, R15 // Restore go stack pointer
   125  
   126  error:
   127  	MOVD $0, ret+8(FP) // Return 0 on failure
   128  
   129  done:
   130  	XOR R0, R0 // Reset r0 to 0
   131  	RET
   132  
   133  // func svcUnload(name *byte, fnptr unsafe.Pointer) int64
   134  TEXT ·svcUnload(SB), NOSPLIT, $0
   135  	MOVD R15, R2          // Save go stack pointer
   136  	MOVD name+0(FP), R0   // Move SVC args into registers
   137  	MOVD fnptr+8(FP), R15
   138  	SVC_DELETE
   139  	XOR  R0, R0           // Reset r0 to 0
   140  	MOVD R15, R1          // Save SVC return code
   141  	MOVD R2, R15          // Restore go stack pointer
   142  	MOVD R1, ret+16(FP)   // Return SVC return code
   143  	RET
   144  
   145  // func gettid() uint64
   146  TEXT ·gettid(SB), NOSPLIT, $0
   147  	// Get library control area (LCA).
   148  	MOVW PSALAA, R8
   149  	MOVD LCA64(R8), R8
   150  
   151  	// Get CEECAATHDID
   152  	MOVD CAA(R8), R9
   153  	MOVD CEECAATHDID(R9), R9
   154  	MOVD R9, ret+0(FP)
   155  
   156  	RET
   157  
   158  //
   159  // Call LE function, if the return is -1
   160  // errno and errno2 is retrieved
   161  //
   162  TEXT ·CallLeFuncWithErr(SB), NOSPLIT, $0
   163  	MOVW PSALAA, R8
   164  	MOVD LCA64(R8), R8
   165  	MOVD CAA(R8), R9
   166  	MOVD g, GOCB(R9)
   167  
   168  	// Restore LE stack.
   169  	MOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address
   170  	MOVD 0(R9), R4              // R4-> restore previously saved stack frame pointer
   171  
   172  	MOVD parms_base+8(FP), R7 // R7 -> argument array
   173  	MOVD parms_len+16(FP), R8 // R8 number of arguments
   174  
   175  	//  arg 1 ---> R1
   176  	CMP  R8, $0
   177  	BEQ  docall
   178  	SUB  $1, R8
   179  	MOVD 0(R7), R1
   180  
   181  	//  arg 2 ---> R2
   182  	CMP  R8, $0
   183  	BEQ  docall
   184  	SUB  $1, R8
   185  	ADD  $8, R7
   186  	MOVD 0(R7), R2
   187  
   188  	//  arg 3 --> R3
   189  	CMP  R8, $0
   190  	BEQ  docall
   191  	SUB  $1, R8
   192  	ADD  $8, R7
   193  	MOVD 0(R7), R3
   194  
   195  	CMP  R8, $0
   196  	BEQ  docall
   197  	MOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument
   198  
   199  repeat:
   200  	ADD  $8, R7
   201  	MOVD 0(R7), R0      // advance arg pointer by 8 byte
   202  	ADD  $8, R6         // advance LE argument address by 8 byte
   203  	MOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame
   204  	SUB  $1, R8
   205  	CMP  R8, $0
   206  	BNE  repeat
   207  
   208  docall:
   209  	MOVD funcdesc+0(FP), R8 // R8-> function descriptor
   210  	LMG  0(R8), R5, R6
   211  	MOVD $0, 0(R9)          // R9 address of SAVSTACK_ASYNC
   212  	LE_CALL                 // balr R7, R6 (return #1)
   213  	NOPH
   214  	MOVD R3, ret+32(FP)
   215  	CMP  R3, $-1            // compare result to -1
   216  	BNE  done
   217  
   218  	// retrieve errno and errno2
   219  	MOVD  zosLibVec<>(SB), R8
   220  	ADD   $(__errno), R8
   221  	LMG   0(R8), R5, R6
   222  	LE_CALL                   // balr R7, R6 __errno (return #3)
   223  	NOPH
   224  	MOVWZ 0(R3), R3
   225  	MOVD  R3, err+48(FP)
   226  	MOVD  zosLibVec<>(SB), R8
   227  	ADD   $(__err2ad), R8
   228  	LMG   0(R8), R5, R6
   229  	LE_CALL                   // balr R7, R6 __err2ad (return #2)
   230  	NOPH
   231  	MOVW  (R3), R2            // retrieve errno2
   232  	MOVD  R2, errno2+40(FP)   // store in return area
   233  
   234  done:
   235  	MOVD R4, 0(R9)            // Save stack pointer.
   236  	RET
   237  
   238  //
   239  // Call LE function, if the return is 0
   240  // errno and errno2 is retrieved
   241  //
   242  TEXT ·CallLeFuncWithPtrReturn(SB), NOSPLIT, $0
   243  	MOVW PSALAA, R8
   244  	MOVD LCA64(R8), R8
   245  	MOVD CAA(R8), R9
   246  	MOVD g, GOCB(R9)
   247  
   248  	// Restore LE stack.
   249  	MOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address
   250  	MOVD 0(R9), R4              // R4-> restore previously saved stack frame pointer
   251  
   252  	MOVD parms_base+8(FP), R7 // R7 -> argument array
   253  	MOVD parms_len+16(FP), R8 // R8 number of arguments
   254  
   255  	//  arg 1 ---> R1
   256  	CMP  R8, $0
   257  	BEQ  docall
   258  	SUB  $1, R8
   259  	MOVD 0(R7), R1
   260  
   261  	//  arg 2 ---> R2
   262  	CMP  R8, $0
   263  	BEQ  docall
   264  	SUB  $1, R8
   265  	ADD  $8, R7
   266  	MOVD 0(R7), R2
   267  
   268  	//  arg 3 --> R3
   269  	CMP  R8, $0
   270  	BEQ  docall
   271  	SUB  $1, R8
   272  	ADD  $8, R7
   273  	MOVD 0(R7), R3
   274  
   275  	CMP  R8, $0
   276  	BEQ  docall
   277  	MOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument
   278  
   279  repeat:
   280  	ADD  $8, R7
   281  	MOVD 0(R7), R0      // advance arg pointer by 8 byte
   282  	ADD  $8, R6         // advance LE argument address by 8 byte
   283  	MOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame
   284  	SUB  $1, R8
   285  	CMP  R8, $0
   286  	BNE  repeat
   287  
   288  docall:
   289  	MOVD funcdesc+0(FP), R8 // R8-> function descriptor
   290  	LMG  0(R8), R5, R6
   291  	MOVD $0, 0(R9)          // R9 address of SAVSTACK_ASYNC
   292  	LE_CALL                 // balr R7, R6 (return #1)
   293  	NOPH
   294  	MOVD R3, ret+32(FP)
   295  	CMP  R3, $0             // compare result to 0
   296  	BNE  done
   297  
   298  	// retrieve errno and errno2
   299  	MOVD  zosLibVec<>(SB), R8
   300  	ADD   $(__errno), R8
   301  	LMG   0(R8), R5, R6
   302  	LE_CALL                   // balr R7, R6 __errno (return #3)
   303  	NOPH
   304  	MOVWZ 0(R3), R3
   305  	MOVD  R3, err+48(FP)
   306  	MOVD  zosLibVec<>(SB), R8
   307  	ADD   $(__err2ad), R8
   308  	LMG   0(R8), R5, R6
   309  	LE_CALL                   // balr R7, R6 __err2ad (return #2)
   310  	NOPH
   311  	MOVW  (R3), R2            // retrieve errno2
   312  	MOVD  R2, errno2+40(FP)   // store in return area
   313  	XOR   R2, R2
   314  	MOVWZ R2, (R3)            // clear errno2
   315  
   316  done:
   317  	MOVD R4, 0(R9)            // Save stack pointer.
   318  	RET
   319  
   320  //
   321  // function to test if a pointer can be safely dereferenced (content read)
   322  // return 0 for succces
   323  //
   324  TEXT ·ptrtest(SB), NOSPLIT, $0-16
   325  	MOVD arg+0(FP), R10 // test pointer in R10
   326  
   327  	// set up R2 to point to CEECAADMC
   328  	BYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt  2,1208
   329  	BYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22                         // llgtr 2,2
   330  	BYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF                         // nilh  2,32767
   331  	BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg    2,88(2)
   332  	BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg    2,8(2)
   333  	BYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68                         // la    2,872(2)
   334  
   335  	// set up R5 to point to the "shunt" path which set 1 to R3 (failure)
   336  	BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33 // xgr   3,3
   337  	BYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04 // bras  5,lbl1
   338  	BYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01 // lghi  3,1
   339  
   340  	// if r3 is not zero (failed) then branch to finish
   341  	BYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33 // lbl1     ltgr  3,3
   342  	BYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08 // brc   b'0111',lbl2
   343  
   344  	// stomic store shunt address in R5 into CEECAADMC
   345  	BYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg   5,0(2)
   346  
   347  	// now try reading from the test pointer in R10, if it fails it branches to the "lghi" instruction above
   348  	BYTE $0xE3; BYTE $0x9A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg    9,0(10)
   349  
   350  	// finish here, restore 0 into CEECAADMC
   351  	BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99                         // lbl2     xgr   9,9
   352  	BYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg   9,0(2)
   353  	MOVD R3, ret+8(FP)                                                     // result in R3
   354  	RET
   355  
   356  //
   357  // function to test if a untptr can be loaded from a pointer
   358  // return 1: the 8-byte content
   359  //        2: 0 for success, 1 for failure
   360  //
   361  // func safeload(ptr uintptr) ( value uintptr, error uintptr)
   362  TEXT ·safeload(SB), NOSPLIT, $0-24
   363  	MOVD ptr+0(FP), R10                                                    // test pointer in R10
   364  	MOVD $0x0, R6
   365  	BYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt  2,1208
   366  	BYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22                         // llgtr 2,2
   367  	BYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF                         // nilh  2,32767
   368  	BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg    2,88(2)
   369  	BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg    2,8(2)
   370  	BYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68                         // la    2,872(2)
   371  	BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33                         // xgr   3,3
   372  	BYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04                         // bras  5,lbl1
   373  	BYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01                         // lghi  3,1
   374  	BYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33                         // lbl1     ltgr  3,3
   375  	BYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08                         // brc   b'0111',lbl2
   376  	BYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 5,0(2)
   377  	BYTE $0xE3; BYTE $0x6A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg    6,0(10)
   378  	BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99                         // lbl2     xgr   9,9
   379  	BYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg   9,0(2)
   380  	MOVD R6, value+8(FP)                                                   // result in R6
   381  	MOVD R3, error+16(FP)                                                  // error in R3
   382  	RET
   383  

View as plain text