...

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

Documentation: cmd/vendor/golang.org/x/sys/unix

     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
    33DATA zosLibVec<>(SB)/8, $0
    34GLOBL zosLibVec<>(SB), NOPTR, $8
    35
    36TEXT ·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
    44TEXT ·GetZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
    45	MOVD zosLibVec<>(SB), R8
    46	MOVD R8, ret+0(FP)
    47	RET
    48
    49TEXT ·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.
    55TEXT 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)
    81TEXT ·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
   104TEXT ·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
   126error:
   127	MOVD $0, ret+8(FP) // Return 0 on failure
   128
   129done:
   130	XOR R0, R0 // Reset r0 to 0
   131	RET
   132
   133// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
   134TEXT ·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
   146TEXT ·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//
   162TEXT ·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
   199repeat:
   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
   208docall:
   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
   234done:
   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//
   242TEXT ·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
   279repeat:
   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
   288docall:
   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
   316done:
   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//
   324TEXT ·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)
   362TEXT ·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

View as plain text