Chapter Contents |
Previous |
Next |
Inline Machine Code Interface |
The following pages define the functions for the inline machine code interface.
_bbwd |
Branch to a Previously Defined Label
#include <code.h> void _bbwd(unsigned short op, unsigned short target);
_bbwd
causes the compiler to generate
a branch instruction whose target is the previously defined label whose
_label
number is specified by
target
. The
op
argument specifies the first halfword of the instruction to generate. Both
arguments to
_bbwd
must be compile-time constants.
The
op
argument must specify one of the
following instructions:
BAL
|
BCT
|
BAS
|
BXH
|
BC
(except
NOP
|
BXLE
|
The
NOP
instruction (0x4700) is not supported.
Also note that any index register in the instruction must be specified as
0.
Optimizations, such as branch folding, may cause the
instructions generated as a result of
_bbwd
to differ from those
expected. However, any such optimizations will not change the effects of the
instructions.
If incorrect arguments are passed to
_bbwd
,
the compiler produces a diagnostic, sets the return code to 8, and generates
an EX 0,* instruction. This instruction causes an execute exception (OS ABEND
code 0C3) if it is actually executed.
Do not use
_bbwd
to generate instructions
that modify registers required by compiled code. See _code for a listing of these registers.
_bbwd
is not portable.
#include <code.h> /* this code multiplies the integers i and j by */ /* repeated addition */ _ldregs(R1+R2+R3, i, j, 0); _label(1); /* LABEL1 EQU * */ _code(R3,0x1a31); /* AR 3,1 */ _bbwd(0x4620,1); /* BCT 2,LABEL1 */
_code
,
_ldregs
,
_bfwd
,
_branch
,
_label
_bfwd |
Branch to a Label Defined Later
#include <code.h> void _bfwd(unsigned short op, unsigned short target)
_bfwd
causes the compiler to generate
a branch instruction with a target that is a label defined later. The
target
argument is the
_label
number of the target
label. The
op
argument specifies the first halfword of the instruction
to generate. Both arguments to
_bfwd
must be compile-time
constants.
The
op
argument must specify one of the
following instructions:
BAL
|
BCT
|
BAS
|
BXH
|
BC
(except
NOP
|
BXLE
|
The
NOP
instruction (0x4700) is not supported.
Also note that any index register in the instruction must be specified as
0.
Optimizations, such as branch folding, may cause the
instructions generated as a result of
_bfwd
to differ from those
expected. However, any such optimizations will not change the effects of the
instructions.
If incorrect arguments are passed to
_bfwd
,
the compiler produces a diagnostic, sets the return code to 8, and generates
an EX 0,* instruction. This instruction causes an execute exception (OS ABEND
code 0C3) if it is actually executed.
Do not use
_bfwd
to generate instructions
that modify registers required by compiled code. See _code for a listing of these registers.
_bfwd
is not portable.
#include <code.h> /* this code multiplies the integers i and j by */ /* repeated addition. unlike the _bbwd example,*/ /* it behaves correctly when j is less than or */ /* equal to 0 */ _ldregs(R1+R2+R3, i, j, 0); _code(0, 0x1222); /* LTR 2,2 */ _bfwd(0x4780, 2); /* BZ LABEL2 */ _bfwd(0x4720, 1); /* BP LABEL1 */ _code(R2, 0x1322); /* LCR 2,2 */ _code(R1, 0x1311); /* LCR 1,1 */ _label(1); /* LABEL1 EQU * */ _code(R3, 0x1a31); /* AR 3,1 */ _bbwd(0x4620, 1); /* BCT 2,LABEL1 */ _label(2); /* LABEL2 EQU * */
_code
,
_ldregs
,
_bbwd
,
_branch
,
_label
_blabel |
Reference a Backward Branch Target
#include <code.h> unsigned _blabel(int n);
_blabel
identifies a branch target
occurring earlier in the compilation than the point at which
_blabel
is called. The argument
n
specifies the
_label
number of the branch target and must be a compile-time constant. A call to
_blabel
should be used only as an argument to the
_branch
function or to a macro that generates a call to this function.
_blabel
returns an encoded form of
the target label that can be interpreted by the
_branch
function.
_blabel
is not portable.
#include <code.h> #include <genl370.h> /* this code multiplies the integers i and j by */ /* repeated addition. this code has the same */ /* effect as the _bbwd example, but uses macros */ /* from genl370.h for readability */ _ldregs(R1+R2+R3, i, j, 0); _label(1); /* LABEL1 EQU * */ AR(3,1); BCT(2,0,_blabel(1)) /* BCT 2,LABEL1 */
_branch |
#include <code.h> void _branch(unsigned mask, unsigned short op, unsigned int target);
_branch
provides a flexible method
for generating branch instructions. All operands of
_branch
must be compile-time constants. Depending on the form of the
target
argument, the
_branch
function behaves as follows:
unsigned
short
value, then
_branch(mask, op, target)
has the
same effect as
_code(mask, op, target)
.
0x00BBzzzz
, where
zzzz
represents any hex digits, then
_branch(mask,
op, target)
has the same effect as
_bbwd(op, 0xzzzz)
. (A
constant of this form is generated by the
_blabel
macro.)
0x00BFzzzz
, where
zzzz
represents any hex digits, then
_branch(mask,
op, target)
has the same effect as
_bfwd(op, 0xzzzz)
. (A
constant of this form is generated by the
_flabel
macro.)
_branch
is not intended for direct
programmer use. It is implemented primarily as a tool for use by the macros
in the SAS/C inline code header files.
When a
0x00BBzzzz
or
0x00BFzzzz
argument is passed to
_branch
, all restrictions
applying to the use of
_bbwd
and
_bfwd
apply to
_branch
. In particular, only permitted branch instructions can be specified,
and use of an index register is not allowed.
If incorrect arguments are passed to
_branch
, the compiler produces a diagnostic, sets the return code to 8, and
generates an EX 0,* instruction. This instruction causes an execute exception
(OS ABEND code 0C3) if it is actually executed.
The mask operand of
_branch
defines the registers
that may be modified by the generated instruction, as with the
_code
function. If the mask is not specified correctly, the effects of
_branch
are unpredictable.
Do not use
_branch
to generate instructions
that modify registers required by compiled code. See _code for a listing of these registers.
_branch
is not portable.
_bbwd
,
_bfwd
,
_blabel
,
_code
,
_flabel
_cc |
Access Hardware Condition Code
#include <svc.h> int _cc(void);
_cc
enables you to access the condition
code set by an SVC, DIAGNOSE, or machine instruction. The following table
shows the hardware condition codes and their most common meanings, the
_cc
function codes, and the mnemonic macros that can be used instead
of the actual values.
Hardware Condition Code | Most Common Meaning of Code |
_cc
Function Returns |
Symbolic Macros for
_cc
Function Return Codes |
---|---|---|---|
0 | equal | 0 | CC0, CCZ, CCE |
1 | less | - 1 | CC1, CCL, CCM |
2 | greater | 2 | CC2, CCH, CCP |
3 | overflow | 3 | CC3, CCO |
Note:
Making the
_cc
condition code 1 for the less
condition (rather than 1) allows the result of
_cc
to be compared with
0 in a natural way.
The condition code is not modified by the execution
of
_cc
.
Declarations for
_cc
and the associated
macros can be obtained by including (via
#include
) either
<code.h>
or
<svc.h>
.
_cc
returns the current hardware condition
code as one of the integers 0, 1,
2, or 3.
If, after an SVC, DIAGNOSE, or machine instruction,
you need to store registers and also access the condition code, you should
use
_stregs
to store the registers first. When it is
followed by a call to
_cc
,
_stregs
does not modify
the condition code, but in some cases,
_cc
may modify register
contents in order to address the area where the condition code is to be stored.
_cc
is not portable.
In general, five instructions are required to reduce
the hardware condition code to an integer value. However, if the only use
of the value returned by
_cc
is in a comparison with 0, only
a single BC instruction is generated.
#include <code.h> #include <genl370.h> #include <stdio.h> /* Add two binary integers together, and print a message */ /* if the sum is negative. */ int sum; short increment; /* halfword */ _ldregs(R2+R3, sum, &increment); AH(2,0,0+b(3)); /* AH 2,0(0,3) */ if (_cc() <0) printf("The sum is negative\n");
_cms202
,
_code
,
_diag
,
_ldregs
,
_ossvc
,
_stregs
_cms202 |
Generate CMS SVC 202 Instruction
#include <svc.h> void _cms202(void);
_cms202
generates an SVC 202 instruction.
It is intended to be used by programs executing under nonbimodal CMS.
_cms202
takes no arguments. (See
_ossvc
for generating OS/390
supervisor calls; also see the descriptions of
SVC202
and
e_SVC202
for other methods of generating an SVC 202 instruction.)
Note:
The
_ossvc
built-in function may be used
to generate an SVC 204 in bimodal CMS.
No value is returned by
_cms202
. To access values
returned in registers, including any return code, use the
_stregs
function.
Use the
_ldregs
function to set
up registers correctly before issuing the SVC 202.
If your program executes under OS/390, you should use
the
_ossvc
built-in function rather than
_cms202
.
_cms202
is not portable.
_cms202
first stores any values currently
in use from general-purpose registers 0, 1, and 15 and clears any information
the compiler had about the contents of those registers. It assumes that these
registers are, or may be, altered by the SVC 202.
_cms202
then saves the
address of the SVC instruction as an aid to traceback production in case the
SVC 202 causes an abend. It then issues an SVC 202 instruction followed by
a fullword (unaligned) 1.
Note:
Refer to the CMS Command
Reference for more details on nucleus extensions.
#include <svc.h> #include <lcio.h> #include <stdio.h> #include <lcstring.h> /* Use the CMS function NUCEXT to determine if the */ /* GLOBALV command is a nucleus extension. */ struct { /* NUCEXT QUERY parameter list. */ char cmd[8] ; /* 'NUCEXT' */ char name[8] ; /* Nucleus extension name. */ char *scblock; /* Receives pointer to SCBLOCK. */ char *query; /* 0xffffffff (identify QUERY) */ }nucx; int rc; /* Copy in the name of the command, padded to */ /* eight characters. */ memcpyp(nucx.cmd,"NUCEXT",8,6,' '); /* Copy in the name of the nucleus extension to be queried, */ /* again padded to eight characters. */ memcpyp(nucx.name,"GLOBALV",8,7,' '); nucx.query = (char *) -1; /* Identify the QUERY function.*/ _ldregs(R1,&nucx); /* R1 -> struct nucx. */ _cms202(); /* Issue SVC 202. */ rc = _stregs(R15); /* If rc == 0, GLOBALV is a */ /* nucleus extension. */ printf("Globalv %s a nucleus extension\n", rc == 0 ? "is" : "is not");
_diag
,
_ldregs
,
_ossvc
,
_stregs
,
SVC202
,
e_SVC202
_code |
Generate a Machine Instruction or Inline Data
#include <code.h> void _code(unsigned mask, unsigned short data1, unsigned short data2, unsigned short data3, unsigned short data4);
_code
provides a flexible method for
generating machine instructions or inline data.
_code
enables you to issue
machine instructions directly from C without the overhead of a subroutine
call. In many cases, you can use either
_code
or the code macros
to generate machine instructions. In general, the code macros are easier
to use, but the
_code
function is more flexible.
_code
generates one to four halfwords of data into the compiled code instruction
stream. Usually this is a machine instruction, but any data can be specified.
_code
takes two to five arguments that must all be compile-time constants.
The first argument,
mask
, is a 32-bit mask. This argument
must be a compile-time constant because the compiler has to know which registers
are needed. General-purpose registers can be specified using the macros R0
through R15, and floating-point registers 0, 2, 4, and 6 can be specified
as F0 through F6, respectively. Multiple registers can be specified by adding
(or logically ORing) the macros, for example, R0+R1 (or R0|R1). Refer to Bit Masks for Using Registers for more information
on the
mask
argument.
After the register mask, the remaining arguments of
_code
are generated on a halfword boundary in the instruction stream.
They are not validated in any way. Any bits in an argument that do not fit
in a
short
are ignored.
The inline machine code interface provides macros for
naming registers that make the register arguments to
_code
more readable when used to generate machine instructions. Refer to the listing
of the
<regs.h>
header file in General Header Files for the macros that can be
used with
_code
.
Use the
_ldregs
function to load
registers used by
_code
; use the
_stregs
function to store
instruction results, and use the
_cc
function to access
the condition code.
_code
returns no value. To access
values returned in registers, use the
_stregs
function; to access
the condition code, use the
_cc
function.
If you specify incorrect arguments for
_code
(for example, the wrong number of arguments or an invalid register mask),
pass two of the compiler produces an error message, sets the return code to
8, and generates an EX 0,* instruction for
_code
. The generated instruction
causes an execute exception (OS ABEND code 0C3) if it is actually executed.
Do not use
_code
to generate instructions
that modify registers required by compiled code, specifically the following:
4 | is used to address constants. |
5 | is the program base register. |
12 | accesses the C Run-Time Anchor Block (CRAB). |
13 | addresses the current automatic storage area. |
If you modify any of these registers, the results are
unpredictable but are likely to include an abend. See the register usage warning
in Usage Notes.
_code
is not portable.
_code
first stores any values currently
in use from general-purpose registers specified by the register mask and then
generates the requested instructions or data.
#include <code.h> /* Generate a call to the CMS DMSFREE macro, */ /* consisting of an SVC 203 instruction, */ /* followed by a halfword of data. */ unsigned amt; char *storage; _ldregs(R0, amt/8); _code(R1, 0x0acb, /* Issue SVC 203 */ 0x1e04); /* specifying DMSFREE function. */ /* store address of allocated memory */ storage =(char *) _stregs(R1);
_diag |
#include <svc.h> void _diag(int n);
_diag
generates a DIAGNOSE instruction,
using 0 and 14 as the register arguments and
n
as the diagnose code.
n
must be a compile-time constant. It is intended to be used by programs
executing under CMS or some other operating system running in a virtual machine
under VM/SP, VM/XA, or VM/ESA.
_diag
returns no value. To access
values returned in registers, including any return code, use the
_stregs
function. To access the condition code set by
_diag
,
use the
_cc
function.
Use the
_ldregs
function to set
up registers correctly before issuing the DIAGNOSE. Do not use
_diag
in a real machine or when in virtual problem state.
_diag
is not portable.
_diag
first stores any values currently
in use from general-purpose registers 0, 1, 14, and 15 and clears any information
the compiler has about the contents of these registers. It assumes these
registers are, or may be, altered by the DIAGNOSE. It then issues a
DIAG 0
,
14
,
n
instruction, where
n
is the specified diagnose code.
#include <svc.h> #include <stdio.h> /* Issue DIAGNOSE X'24' to obtain information about the */ /* virtual console. */ unsigned devaddr, vinfo, rinfo; _ldregs(R0, -1); /* Load -1 to get virtual console information. */ _diag(0x24); /* Ask CP for location and information. */ /* store the results */ _stregs(R0+R14+R15, &devaddr, &vinfo, &rinfo); switch(_cc()) { /* check condition code */ case CC0: printf("Console address is %x\n", (unsigned short) devaddr); break; case CC2: printf("Virtual console at %x, no real console\n", (unsigned short) devaddr); break; case CC3: printf("Virtual console does not exist\n"); break; }
_cc
,
_cms202
,
_ldregs
,
_ossvc
,
_stregs
_flabel |
Reference a Forward Branch Target
#include <code.h> unsigned _flabel(int n);
_flabel
identifies a branch target
occurring later in the compilation than the point at which
_flabel
is called. The argument
n
specifies the
_label
number of the branch target and must be a compile-time constant. A call to
_flabel
should be used only as an argument to the
_branch
function, or to a macro that generates a call to this function.
_flabel
returns an encoded form of
the target label that can be interpreted by the
_branch
function.
_flabel
is not portable.
#include <code.h> #include <genl370.h> /* this code multiplies the integers i and j by */ /* repeated addition. unlike the _blabel example,*/ /* it behaves correctly when j is less than or */ /* equal to 0. this code has the same effect as */ /* the _bfwd example, but uses macros from */ /* genl370.h for readability */ _ldregs(R1+R2+R3, i, j, 0); LTR(2,2); BC(8, 0, _flabel(2)); /* BZ LABEL2 */ BC(2, 0, _flabel(1)); /* BP LABEL1 */ LCR(2,2); LCR(1,1); _label(1); /* LABEL1 EQU * */ AR(3,1); BCT(2, 0, _blabel(1)); /* BCT 2,LABEL1 */ _label(2); /* LABEL2 EQU * */
_label |
Define
an Inline Machine Code Branch Target
#include <code.h> void _label(unsigned short n);
_label
identifies a location in an
inline machine code block as a branch target and associates it with an integer
n
between 1 and 65535.
n
must be a compile-time
constant. More than one definition using the same integer in a single compilation
is permitted. The execution of
_label
has no effect; that
is,
_label
defines a location in the object code but
does not add any instructions there.
See the examples for
_bbwd
,
_bfwd
,
_blabel
and
_flabel
.
_bbwd
,
_bfwd
,
_blabel
,
_flabel
_ldregs |
#include <svc.h> /* Further arguments are any C expressions - see below. */ void _ldregs(unsigned mask,...);
_ldregs
is central to the interface
between the SAS/C Compiler and inline
machine code because it enables you to set up values in machine registers
that are used by subsequent machine instructions.
The first argument,
mask
, is a 32-bit mask.
This argument must be a compile-time constant because the compiler has to
know which registers are needed. General-purpose registers can be specified
using the macros R0 through R15, and floating-point registers 0, 2, 4, and
6 can be specified as F0 through F6, respectively. Multiple registers can
be specified by adding (or logically ORing) the macros, for example, R0+R1
(or R0|R1). Refer to Bit Masks for Using Registers for more information on the
mask
argument.
Remaining arguments specify the values to
be placed
in the registers (low to high) specified by
mask
. Any C expression
that has an integer, pointer, or floating-point type may be used. The number
of arguments, excluding
mask
, must be equal to the number
of one-bits in
mask
; that is, you must supply an expression for
each register. The type of each expression must be valid for the register
in which the value is to be loaded. For example, the effect of attempting
to load a pointer into a floating-point register is unpredictable.
Each call to
_ldregs
starts a new inline
machine code sequence. After the call, the contents of any register not explicitly
specified in the mask are undefined.
Declarations for
_ldregs
and the associated
macros are provided in
<code.h>
as well as
<svc.h>
; either or both can be used.
_ldregs
returns no value.
You can safely use the following registers:
0 - 3, 14, 15 | are general-purpose registers. |
0, 2 | are floating-point registers. |
Do not specify any of the following registers:
See the register usage warning in Usage Notes.
If
you specify incorrect arguments for
_ldregs
(for example, the wrong number of parameters or an invalid register
mask), the compiler produces an error message, sets the return code to 8,
and generates an EX 0,* instruction for
_ldregs
. The generated
instruction causes an execute exception (OS/390 ABEND code 0C3) if it is actually
executed.
_ldregs
is not portable.
_ldregs
first dumps any values currently
in use from the specified registers back to memory. It then clears any information
the compiler had about the contents of the registers. Finally, it loads the
registers with the values of the specified C expressions. The order in which
the registers are loaded is chosen by the compiler, and it is not necessarily
the same as the order of the registers in the mask or the same for every invocation
of
_ldregs
.
#include <regs.h> /* Set register 0 to the value 8 and register 14 */ /* to the address of "field", after first clearing */ /* any values currently in those registers. */ long field; /* After macro expansion, the final effect of this */ /* expression is: _ldregs(0x80020000,8,&field); */ _ldregs(R0+R14,8,&field);
_cc
,
_cms202
,
_code
,
_diag
,
_ossvc
,
_stregs
_osarmsvc |
Generate
OS/390 SVC Instruction without Changing Addressing Mode
void _osarmsvc(int n);
_osarmsvc
returns no
value. To access values returned in registers, use the _stregs
function.
_ossvc |
Generate
OS/390 or CMS SVC Instruction
#include <svc.h> void _ossvc(int n);
The _ossvc
function generates
an SVC instruction that is executed in primary address space mode, even if
the armode
compiler option was specified.
_ossvc
takes one argument (
n
) that specifies the number
of the SVC to generate;
n
is an execution-time constant in
the range of 0 to 255.
_ossvc
returns no value. To access
values returned in registers, use the
_stregs
function.
If you specify incorrect arguments for
_ossvc
(such as the wrong number of arguments or an argument that is not a compile-time
constant in the range 0 to 255), pass two of the compiler produces an error
message, sets the return code to 8, and generates an EX 0,* instruction for
_ossvc
. The generated instruction causes an execute exception (OS/390
ABEND code 0C3) if it is executed.
If your program executes under CMS, you may want to
use the
_cms202
or
_diag
function or both
instead of
_ossvc
, depending on the service required.
_ossvc
is not portable.
#include <svc.h> #include <stdio.h> /* Use MVS SVC 11 to obtain the current time as an */ /* HHMMSShh GMT value. Set register 1 to a bit mask */ /* that requests this form. HHMMSShh is returned in */ /* register 0, and a return code is returned in */ /* register 15. */ int rc = 0; /* return code */ char packed[4] ; /* area for time in HHMMSShh format */ _ldregs(R1,0x82); /* Set bit mask in reg 1. */ _ossvc(11); /* Issue SVC 11. */ _stregs(R0+R15,&packed,&rc); /* returned values */ if (rc == 0) printf("GMT is %2x:%02x:%02x:%02x\n", packed[0] ,packed[1] ,packed[2] ,packed[3] ); return rc;
_cms202
,
_diag
,
_ldregs
,
_stregs
_stregs |
#include <svc.h> /* Further arguments are expressions */ /* of pointer type - see below. */ int _stregs(unsigned mask,...);
_stregs
enables you to save register
values set by an SVC, DIAGNOSE, or machine instruction into memory accessible
to the C program. The call to
_stregs
terminates the
inline machine code sequence.
The first argument,
mask
, is a 32-bit mask.
This argument must be a compile-time constant because the compiler has to
know which registers are needed. General-purpose registers can be specified
using the macros R0 through R15, and floating-point registers 0, 2, 4, and
6 can be specified as F0 through F6, respectively. Multiple registers can
be specified by adding (or logically ORing) the macros, for example, R0+R1
(or R0|R1). Refer to Bit Masks for Using Registers for more information on the
mask
argument.
Remaining arguments specify where each
register is to
be stored, in the order (low to high) specified by
mask
. These arguments can
be either the address of a variable or a C pointer type. If you specify a
pointer, the register is stored in the memory pointed to by the pointer.
If you specify one more register in the mask than the
number of arguments to the function, the value in the highest general-purpose
register in the mask is not stored. Instead, it is returned as the value
of the
_stregs
function call.
Declarations for
_stregs
and the macros
for the register mask can be obtained by including either
<code.h>
or
<svc.h>
.
_stregs
returns the value contained
in the highest numbered general-purpose register specified in the mask. If
no general-purpose register is specified in the mask, the value returned is
unpredictable.
To access the condition code set by an SVC, DIAGNOSE,
or machine instruction, use the
_cc
function.
If you use
_stregs
to obtain the addresses
of run-time control blocks (such as the CRAB), code, or data areas, and then
modify the contents of the control blocks, code, or data areas, your program
is no longer valid C and the results are entirely unpredictable.
Do not use complex expressions, especially ones involving
array indexes, as operands of
_stregs
because register
shortages can occur. If there is a register shortage, a register whose value
was to be stored may be reused. To avoid the problem, assign a complex expression
to a pointer variable and specify the variable as the
_stregs
argument. Alternately, you can use the
_code
function to generate
ST (store) or STM (store multiple) instructions to store values based on one
or more previously loaded addressing registers.
If you specify incorrect arguments for
_stregs
(for example, the wrong number of arguments or an invalid register
mask), pass two of the compiler produces an error message, sets the return
code to 8, and generates an EX 0,* instruction for
_stregs
. The generated
instruction causes an execute exception (OS/390 ABEND code 0C3) if it is actually
executed.
_stregs
is not portable.
_stregs
stores the values from the
specified registers in the places in memory addressed by the expressions.
The sequence in which the registers are stored is determined by the compiler
and is not necessarily the same as the order of the registers in the mask.
Because the register values are not changed, the compiler retains the information
it has about the contents of each register.
#include <svc.h> /* Store the value in register 1 in the C variable reg1, */ /* store the value in register 15 in the area pointed */ /* to by the variable r15 area, and store the value in */ /* floating-point register 0 in the area pointed to */ /* by the variable dp. */ long reg1; long r15area; double * dp; _ldregs(0); /* After macro expansion, the final effect of this */ /* expression is: r15area = _stregs(0x40018000,®1,dp); */ r15area = _stregs(R1+R15+F0,®1,dp);
_cc
,
_cms202
,
_code
,
_diag
,
_ldregs
,
_ossvc
SVC202, e_SVC202 |
Generate
CMS SVC 202 Instruction with Arguments
#include <svc.h> /* macro */ int SVC202(r1plist) /* macro */ int e_SVC202(r0plist, r1plist)
SVC202
and
e_SVC202
(extended SVC
202) generate an SVC 202 instruction. They are intended to be used by programs
executing under nonbimodal CMS.
SVC202
takes a pointer
to a tokenized PLIST defined in your program.
e_SVC202
takes both a pointer
to an untokenized PLIST and a pointer to a tokenized PLIST, both defined in
your program.
Note:
The
_ossvc
built-in function
may be used to generate a SVC 204 in bimodal CMS.
SVC202
and
e_SVC202
are not portable.
SVC202
and
e_SVC202
are implemented
as the following macros:
#define SVC202(r1) (_ldregs(R1,r1),_cms202(),_stregs(R15)) #define e_SVC202(r0,r1) (_ldregs(R0|R1,r0,0x01000000|(unsigned) (r1)), _cms202(),_stregs(R15))
Refer to the description of
_cms202
for an alternate
version of this example. The VM/XA SP
CMS Command Reference contains more details on nucleus extensions.
#include <svc.h> #include <lcstring.h> #include <stdio.h> /* Use the CMS function NUCEXT to determine if the GLOBALV */ /* command is a nucleus extension. */ struct { /* NUCEXT QUERY parameter list */ char cmd[8] ; /* 'NUCEXT' */ char name[8] ; /* nucleus extension name */ char *scblock; /* Receives pointer to SCBLOCK. */ char *query; /* 0xffffffff (identify QUERY) */ nucx; } int rc; /* Copy in the name of the command, padded to */ /* eight characters. */ memcpyp(nucx.cmd,"NUCEXT",8,6,' '); /* Copy in the name of the nucleus extention */ /* to be queried, again padded to eight characters. */ memcpyp(nucx.name,"GLOBALV",8,7,' '); nucx.query = (char *) -1; /* Identify the QUERY function. */ rc=SVC202(&nucx); /* Issue SVC 202. */ printf("Globalv %s a nucleus extension\n", rc == 0 ? "is" : "is not");
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.