2021-12-02 17:54:14 +01:00
|
|
|
// Copyright 2020 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
//go:build zos && s390x && gc
|
|
|
|
|
|
|
|
#include "textflag.h"
|
|
|
|
|
|
|
|
#define PSALAA 1208(R0)
|
|
|
|
#define GTAB64(x) 80(x)
|
|
|
|
#define LCA64(x) 88(x)
|
2024-09-05 19:38:25 +02:00
|
|
|
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA
|
2021-12-02 17:54:14 +01:00
|
|
|
#define CAA(x) 8(x)
|
2024-09-05 19:38:25 +02:00
|
|
|
#define CEECAATHDID(x) 976(x) // in the CAA
|
|
|
|
#define EDCHPXV(x) 1016(x) // in the CAA
|
|
|
|
#define GOCB(x) 1104(x) // in the CAA
|
2021-12-02 17:54:14 +01:00
|
|
|
|
|
|
|
// SS_*, where x=SAVSTACK_ASYNC
|
|
|
|
#define SS_LE(x) 0(x)
|
|
|
|
#define SS_GO(x) 8(x)
|
|
|
|
#define SS_ERRNO(x) 16(x)
|
|
|
|
#define SS_ERRNOJR(x) 20(x)
|
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
// Function Descriptor Offsets
|
|
|
|
#define __errno 0x156*16
|
|
|
|
#define __err2ad 0x16C*16
|
2021-12-02 17:54:14 +01:00
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
// Call Instructions
|
|
|
|
#define LE_CALL BYTE $0x0D; BYTE $0x76 // BL R7, R6
|
|
|
|
#define SVC_LOAD BYTE $0x0A; BYTE $0x08 // SVC 08 LOAD
|
|
|
|
#define SVC_DELETE BYTE $0x0A; BYTE $0x09 // SVC 09 DELETE
|
|
|
|
|
|
|
|
DATA zosLibVec<>(SB)/8, $0
|
|
|
|
GLOBL zosLibVec<>(SB), NOPTR, $8
|
|
|
|
|
|
|
|
TEXT ·initZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
|
|
|
|
MOVW PSALAA, R8
|
|
|
|
MOVD LCA64(R8), R8
|
|
|
|
MOVD CAA(R8), R8
|
|
|
|
MOVD EDCHPXV(R8), R8
|
|
|
|
MOVD R8, zosLibVec<>(SB)
|
|
|
|
RET
|
|
|
|
|
|
|
|
TEXT ·GetZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
|
|
|
|
MOVD zosLibVec<>(SB), R8
|
|
|
|
MOVD R8, ret+0(FP)
|
|
|
|
RET
|
|
|
|
|
|
|
|
TEXT ·clearErrno(SB), NOSPLIT, $0-0
|
|
|
|
BL addrerrno<>(SB)
|
|
|
|
MOVD $0, 0(R3)
|
2021-12-02 17:54:14 +01:00
|
|
|
RET
|
|
|
|
|
|
|
|
// Returns the address of errno in R3.
|
2024-09-05 19:38:25 +02:00
|
|
|
TEXT addrerrno<>(SB), NOSPLIT|NOFRAME, $0-0
|
2021-12-02 17:54:14 +01:00
|
|
|
// Get library control area (LCA).
|
2024-09-05 19:38:25 +02:00
|
|
|
MOVW PSALAA, R8
|
|
|
|
MOVD LCA64(R8), R8
|
2021-12-02 17:54:14 +01:00
|
|
|
|
|
|
|
// Get __errno FuncDesc.
|
2024-09-05 19:38:25 +02:00
|
|
|
MOVD CAA(R8), R9
|
|
|
|
MOVD EDCHPXV(R9), R9
|
|
|
|
ADD $(__errno), R9
|
|
|
|
LMG 0(R9), R5, R6
|
2021-12-02 17:54:14 +01:00
|
|
|
|
|
|
|
// Switch to saved LE stack.
|
2024-09-05 19:38:25 +02:00
|
|
|
MOVD SAVSTACK_ASYNC(R8), R9
|
|
|
|
MOVD 0(R9), R4
|
|
|
|
MOVD $0, 0(R9)
|
2021-12-02 17:54:14 +01:00
|
|
|
|
|
|
|
// Call __errno function.
|
|
|
|
LE_CALL
|
|
|
|
NOPH
|
|
|
|
|
|
|
|
// Switch back to Go stack.
|
2024-09-05 19:38:25 +02:00
|
|
|
XOR R0, R0 // Restore R0 to $0.
|
|
|
|
MOVD R4, 0(R9) // Save stack pointer.
|
2021-12-02 17:54:14 +01:00
|
|
|
RET
|
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
|
|
|
|
TEXT ·svcCall(SB), NOSPLIT, $0
|
|
|
|
BL runtime·save_g(SB) // Save g and stack pointer
|
|
|
|
MOVW PSALAA, R8
|
|
|
|
MOVD LCA64(R8), R8
|
|
|
|
MOVD SAVSTACK_ASYNC(R8), R9
|
|
|
|
MOVD R15, 0(R9)
|
2021-12-02 17:54:14 +01:00
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
MOVD argv+8(FP), R1 // Move function arguments into registers
|
|
|
|
MOVD dsa+16(FP), g
|
|
|
|
MOVD fnptr+0(FP), R15
|
2021-12-02 17:54:14 +01:00
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
BYTE $0x0D // Branch to function
|
|
|
|
BYTE $0xEF
|
2021-12-02 17:54:14 +01:00
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
BL runtime·load_g(SB) // Restore g and stack pointer
|
|
|
|
MOVW PSALAA, R8
|
|
|
|
MOVD LCA64(R8), R8
|
|
|
|
MOVD SAVSTACK_ASYNC(R8), R9
|
|
|
|
MOVD 0(R9), R15
|
2021-12-02 17:54:14 +01:00
|
|
|
|
|
|
|
RET
|
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
// func svcLoad(name *byte) unsafe.Pointer
|
|
|
|
TEXT ·svcLoad(SB), NOSPLIT, $0
|
|
|
|
MOVD R15, R2 // Save go stack pointer
|
|
|
|
MOVD name+0(FP), R0 // Move SVC args into registers
|
|
|
|
MOVD $0x80000000, R1
|
|
|
|
MOVD $0, R15
|
|
|
|
SVC_LOAD
|
|
|
|
MOVW R15, R3 // Save return code from SVC
|
|
|
|
MOVD R2, R15 // Restore go stack pointer
|
|
|
|
CMP R3, $0 // Check SVC return code
|
|
|
|
BNE error
|
|
|
|
|
|
|
|
MOVD $-2, R3 // Reset last bit of entry point to zero
|
|
|
|
AND R0, R3
|
|
|
|
MOVD R3, ret+8(FP) // Return entry point returned by SVC
|
|
|
|
CMP R0, R3 // Check if last bit of entry point was set
|
|
|
|
BNE done
|
|
|
|
|
|
|
|
MOVD R15, R2 // Save go stack pointer
|
|
|
|
MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
|
|
|
|
SVC_DELETE
|
|
|
|
MOVD R2, R15 // Restore go stack pointer
|
2021-12-02 17:54:14 +01:00
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
error:
|
|
|
|
MOVD $0, ret+8(FP) // Return 0 on failure
|
2021-12-02 17:54:14 +01:00
|
|
|
|
|
|
|
done:
|
2024-09-05 19:38:25 +02:00
|
|
|
XOR R0, R0 // Reset r0 to 0
|
2021-12-02 17:54:14 +01:00
|
|
|
RET
|
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
|
|
|
|
TEXT ·svcUnload(SB), NOSPLIT, $0
|
|
|
|
MOVD R15, R2 // Save go stack pointer
|
|
|
|
MOVD name+0(FP), R0 // Move SVC args into registers
|
|
|
|
MOVD fnptr+8(FP), R15
|
|
|
|
SVC_DELETE
|
|
|
|
XOR R0, R0 // Reset r0 to 0
|
|
|
|
MOVD R15, R1 // Save SVC return code
|
|
|
|
MOVD R2, R15 // Restore go stack pointer
|
|
|
|
MOVD R1, ret+16(FP) // Return SVC return code
|
|
|
|
RET
|
2021-12-02 17:54:14 +01:00
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
// func gettid() uint64
|
|
|
|
TEXT ·gettid(SB), NOSPLIT, $0
|
2021-12-02 17:54:14 +01:00
|
|
|
// Get library control area (LCA).
|
2024-09-05 19:38:25 +02:00
|
|
|
MOVW PSALAA, R8
|
|
|
|
MOVD LCA64(R8), R8
|
2021-12-02 17:54:14 +01:00
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
// Get CEECAATHDID
|
|
|
|
MOVD CAA(R8), R9
|
|
|
|
MOVD CEECAATHDID(R9), R9
|
|
|
|
MOVD R9, ret+0(FP)
|
2021-12-02 17:54:14 +01:00
|
|
|
|
|
|
|
RET
|
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
//
|
|
|
|
// Call LE function, if the return is -1
|
|
|
|
// errno and errno2 is retrieved
|
|
|
|
//
|
|
|
|
TEXT ·CallLeFuncWithErr(SB), NOSPLIT, $0
|
|
|
|
MOVW PSALAA, R8
|
|
|
|
MOVD LCA64(R8), R8
|
|
|
|
MOVD CAA(R8), R9
|
|
|
|
MOVD g, GOCB(R9)
|
2021-12-02 17:54:14 +01:00
|
|
|
|
|
|
|
// Restore LE stack.
|
2024-09-05 19:38:25 +02:00
|
|
|
MOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address
|
|
|
|
MOVD 0(R9), R4 // R4-> restore previously saved stack frame pointer
|
|
|
|
|
|
|
|
MOVD parms_base+8(FP), R7 // R7 -> argument array
|
|
|
|
MOVD parms_len+16(FP), R8 // R8 number of arguments
|
|
|
|
|
|
|
|
// arg 1 ---> R1
|
|
|
|
CMP R8, $0
|
|
|
|
BEQ docall
|
|
|
|
SUB $1, R8
|
|
|
|
MOVD 0(R7), R1
|
|
|
|
|
|
|
|
// arg 2 ---> R2
|
|
|
|
CMP R8, $0
|
|
|
|
BEQ docall
|
|
|
|
SUB $1, R8
|
|
|
|
ADD $8, R7
|
|
|
|
MOVD 0(R7), R2
|
|
|
|
|
|
|
|
// arg 3 --> R3
|
|
|
|
CMP R8, $0
|
|
|
|
BEQ docall
|
|
|
|
SUB $1, R8
|
|
|
|
ADD $8, R7
|
|
|
|
MOVD 0(R7), R3
|
|
|
|
|
|
|
|
CMP R8, $0
|
|
|
|
BEQ docall
|
|
|
|
MOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument
|
|
|
|
|
|
|
|
repeat:
|
|
|
|
ADD $8, R7
|
|
|
|
MOVD 0(R7), R0 // advance arg pointer by 8 byte
|
|
|
|
ADD $8, R6 // advance LE argument address by 8 byte
|
|
|
|
MOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame
|
|
|
|
SUB $1, R8
|
|
|
|
CMP R8, $0
|
|
|
|
BNE repeat
|
|
|
|
|
|
|
|
docall:
|
|
|
|
MOVD funcdesc+0(FP), R8 // R8-> function descriptor
|
|
|
|
LMG 0(R8), R5, R6
|
|
|
|
MOVD $0, 0(R9) // R9 address of SAVSTACK_ASYNC
|
|
|
|
LE_CALL // balr R7, R6 (return #1)
|
|
|
|
NOPH
|
|
|
|
MOVD R3, ret+32(FP)
|
|
|
|
CMP R3, $-1 // compare result to -1
|
|
|
|
BNE done
|
|
|
|
|
|
|
|
// retrieve errno and errno2
|
|
|
|
MOVD zosLibVec<>(SB), R8
|
|
|
|
ADD $(__errno), R8
|
|
|
|
LMG 0(R8), R5, R6
|
|
|
|
LE_CALL // balr R7, R6 __errno (return #3)
|
2021-12-02 17:54:14 +01:00
|
|
|
NOPH
|
2024-09-05 19:38:25 +02:00
|
|
|
MOVWZ 0(R3), R3
|
|
|
|
MOVD R3, err+48(FP)
|
|
|
|
MOVD zosLibVec<>(SB), R8
|
|
|
|
ADD $(__err2ad), R8
|
|
|
|
LMG 0(R8), R5, R6
|
|
|
|
LE_CALL // balr R7, R6 __err2ad (return #2)
|
|
|
|
NOPH
|
|
|
|
MOVW (R3), R2 // retrieve errno2
|
|
|
|
MOVD R2, errno2+40(FP) // store in return area
|
|
|
|
|
2021-12-02 17:54:14 +01:00
|
|
|
done:
|
2024-09-05 19:38:25 +02:00
|
|
|
MOVD R4, 0(R9) // Save stack pointer.
|
2021-12-02 17:54:14 +01:00
|
|
|
RET
|
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
//
|
|
|
|
// Call LE function, if the return is 0
|
|
|
|
// errno and errno2 is retrieved
|
|
|
|
//
|
|
|
|
TEXT ·CallLeFuncWithPtrReturn(SB), NOSPLIT, $0
|
|
|
|
MOVW PSALAA, R8
|
|
|
|
MOVD LCA64(R8), R8
|
|
|
|
MOVD CAA(R8), R9
|
|
|
|
MOVD g, GOCB(R9)
|
2021-12-02 17:54:14 +01:00
|
|
|
|
|
|
|
// Restore LE stack.
|
2024-09-05 19:38:25 +02:00
|
|
|
MOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address
|
|
|
|
MOVD 0(R9), R4 // R4-> restore previously saved stack frame pointer
|
|
|
|
|
|
|
|
MOVD parms_base+8(FP), R7 // R7 -> argument array
|
|
|
|
MOVD parms_len+16(FP), R8 // R8 number of arguments
|
|
|
|
|
|
|
|
// arg 1 ---> R1
|
|
|
|
CMP R8, $0
|
|
|
|
BEQ docall
|
|
|
|
SUB $1, R8
|
|
|
|
MOVD 0(R7), R1
|
|
|
|
|
|
|
|
// arg 2 ---> R2
|
|
|
|
CMP R8, $0
|
|
|
|
BEQ docall
|
|
|
|
SUB $1, R8
|
|
|
|
ADD $8, R7
|
|
|
|
MOVD 0(R7), R2
|
|
|
|
|
|
|
|
// arg 3 --> R3
|
|
|
|
CMP R8, $0
|
|
|
|
BEQ docall
|
|
|
|
SUB $1, R8
|
|
|
|
ADD $8, R7
|
|
|
|
MOVD 0(R7), R3
|
|
|
|
|
|
|
|
CMP R8, $0
|
|
|
|
BEQ docall
|
|
|
|
MOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument
|
|
|
|
|
|
|
|
repeat:
|
|
|
|
ADD $8, R7
|
|
|
|
MOVD 0(R7), R0 // advance arg pointer by 8 byte
|
|
|
|
ADD $8, R6 // advance LE argument address by 8 byte
|
|
|
|
MOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame
|
|
|
|
SUB $1, R8
|
|
|
|
CMP R8, $0
|
|
|
|
BNE repeat
|
|
|
|
|
|
|
|
docall:
|
|
|
|
MOVD funcdesc+0(FP), R8 // R8-> function descriptor
|
|
|
|
LMG 0(R8), R5, R6
|
|
|
|
MOVD $0, 0(R9) // R9 address of SAVSTACK_ASYNC
|
|
|
|
LE_CALL // balr R7, R6 (return #1)
|
2021-12-02 17:54:14 +01:00
|
|
|
NOPH
|
2024-09-05 19:38:25 +02:00
|
|
|
MOVD R3, ret+32(FP)
|
|
|
|
CMP R3, $0 // compare result to 0
|
|
|
|
BNE done
|
|
|
|
|
|
|
|
// retrieve errno and errno2
|
|
|
|
MOVD zosLibVec<>(SB), R8
|
|
|
|
ADD $(__errno), R8
|
|
|
|
LMG 0(R8), R5, R6
|
|
|
|
LE_CALL // balr R7, R6 __errno (return #3)
|
2021-12-02 17:54:14 +01:00
|
|
|
NOPH
|
2024-09-05 19:38:25 +02:00
|
|
|
MOVWZ 0(R3), R3
|
|
|
|
MOVD R3, err+48(FP)
|
|
|
|
MOVD zosLibVec<>(SB), R8
|
|
|
|
ADD $(__err2ad), R8
|
|
|
|
LMG 0(R8), R5, R6
|
|
|
|
LE_CALL // balr R7, R6 __err2ad (return #2)
|
|
|
|
NOPH
|
|
|
|
MOVW (R3), R2 // retrieve errno2
|
|
|
|
MOVD R2, errno2+40(FP) // store in return area
|
|
|
|
XOR R2, R2
|
|
|
|
MOVWZ R2, (R3) // clear errno2
|
2021-12-02 17:54:14 +01:00
|
|
|
|
|
|
|
done:
|
2024-09-05 19:38:25 +02:00
|
|
|
MOVD R4, 0(R9) // Save stack pointer.
|
2021-12-02 17:54:14 +01:00
|
|
|
RET
|
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
//
|
|
|
|
// function to test if a pointer can be safely dereferenced (content read)
|
|
|
|
// return 0 for succces
|
|
|
|
//
|
|
|
|
TEXT ·ptrtest(SB), NOSPLIT, $0-16
|
|
|
|
MOVD arg+0(FP), R10 // test pointer in R10
|
|
|
|
|
|
|
|
// set up R2 to point to CEECAADMC
|
|
|
|
BYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt 2,1208
|
|
|
|
BYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22 // llgtr 2,2
|
|
|
|
BYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF // nilh 2,32767
|
|
|
|
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg 2,88(2)
|
|
|
|
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg 2,8(2)
|
|
|
|
BYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68 // la 2,872(2)
|
|
|
|
|
|
|
|
// set up R5 to point to the "shunt" path which set 1 to R3 (failure)
|
|
|
|
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33 // xgr 3,3
|
|
|
|
BYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04 // bras 5,lbl1
|
|
|
|
BYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01 // lghi 3,1
|
|
|
|
|
|
|
|
// if r3 is not zero (failed) then branch to finish
|
|
|
|
BYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33 // lbl1 ltgr 3,3
|
|
|
|
BYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08 // brc b'0111',lbl2
|
|
|
|
|
|
|
|
// stomic store shunt address in R5 into CEECAADMC
|
|
|
|
BYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 5,0(2)
|
|
|
|
|
|
|
|
// now try reading from the test pointer in R10, if it fails it branches to the "lghi" instruction above
|
|
|
|
BYTE $0xE3; BYTE $0x9A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg 9,0(10)
|
|
|
|
|
|
|
|
// finish here, restore 0 into CEECAADMC
|
|
|
|
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99 // lbl2 xgr 9,9
|
|
|
|
BYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 9,0(2)
|
|
|
|
MOVD R3, ret+8(FP) // result in R3
|
2021-12-02 17:54:14 +01:00
|
|
|
RET
|
|
|
|
|
2024-09-05 19:38:25 +02:00
|
|
|
//
|
|
|
|
// function to test if a untptr can be loaded from a pointer
|
|
|
|
// return 1: the 8-byte content
|
|
|
|
// 2: 0 for success, 1 for failure
|
|
|
|
//
|
|
|
|
// func safeload(ptr uintptr) ( value uintptr, error uintptr)
|
|
|
|
TEXT ·safeload(SB), NOSPLIT, $0-24
|
|
|
|
MOVD ptr+0(FP), R10 // test pointer in R10
|
|
|
|
MOVD $0x0, R6
|
|
|
|
BYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt 2,1208
|
|
|
|
BYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22 // llgtr 2,2
|
|
|
|
BYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF // nilh 2,32767
|
|
|
|
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg 2,88(2)
|
|
|
|
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg 2,8(2)
|
|
|
|
BYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68 // la 2,872(2)
|
|
|
|
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33 // xgr 3,3
|
|
|
|
BYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04 // bras 5,lbl1
|
|
|
|
BYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01 // lghi 3,1
|
|
|
|
BYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33 // lbl1 ltgr 3,3
|
|
|
|
BYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08 // brc b'0111',lbl2
|
|
|
|
BYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 5,0(2)
|
|
|
|
BYTE $0xE3; BYTE $0x6A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg 6,0(10)
|
|
|
|
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99 // lbl2 xgr 9,9
|
|
|
|
BYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 9,0(2)
|
|
|
|
MOVD R6, value+8(FP) // result in R6
|
|
|
|
MOVD R3, error+16(FP) // error in R3
|
2021-12-02 17:54:14 +01:00
|
|
|
RET
|