Chapter Contents |
Previous |
Next |
Inline Machine Code Interface |
Overview |
The inline machine code interface consists of the following:
CS 14,15,0(1) instruction
CS(14,15,0+b(1)); cs macro
Refer to Macros and Header Files for a detailed description of this example.
<code.h>
,
<regs.h>
, and
<svc.h>
) that provide symbolic definitions used by the built-in functions
and macros.
This chapter provides the following:
Each of the built-in functions is discussed in Functions.
_ldregs, _stregs, and _cc |
Two framing functions,
_ldregs
and
_stregs
, enable you to
set register values before issuing an instruction or series of instructions
and then retrieve values from the registers after the instruction sequence
is completed. Between these framing functions, you can call other built-in
functions or issue macros that resemble assembly instructions. You can use
the
_cc
function to access the condition code set by a generated DIAGNOSE,
SVC, or machine instruction.
_diag, _cms202, and _ossvc |
Several built-in functions issue specific supervisor
call instructions:
_diag
,
_cms202
, and
_ossvc
. Access to the DIAGNOSE instruction
through the
_diag
function opens the way for using the multitude of CMS diagnose
codes. With the
_diag
function, your program can interact with the console, examine
real storage, read the system symbol table, execute timing functions, and
so on. The _ossvc
and _osarmsvc
built-in functions can be used to invoke an OS/390 or CMS
supervisor call to get access to many supervisor services that would otherwise
be available only through the Assembler language. The _ossvc
built-in function always issues the SVC in primary address
space mode, while the _osarmsvc
issues the
SVC in access register mode if the compiler option has been specified.
_code |
The inline machine code interface also provides a very
flexible method for generating machine instructions or inline data. The
_code
function enables you to generate machine instructions directly from C without
the overhead of a subroutine call.
Furthermore, the library provides header files defining
macros to assist you in using
_code
to generate machine instructions.
_label |
The
_label
function defines a location in an inline code
block and associates it with a non-zero
unsigned short
constant. You can transfer
control directly to a label defined with
_label
by using the
_bbwd
,
_bfwd
, or
_branch
function, or indirectly
by using a library macro which calls one of these functions. The same label
value may be assigned more than once in a compilation. The
_bbwd
and
_bfwd
functions always
branch to the nearest definition of the target label in the appropriate direction.
This property allows
_label
to be used in macros that are expanded repeatedly
in a single compilation.
_bbwd and _bfwd |
The
_bbwd
and
_bfwd
functions allow you to generate
selected 370 branch instructions to labels defined with
_label
. The macro specifies
the particular branch operation and any non-target information required by
the instruction, for example, count registers.
All use of these functions and macros must be localized
within a single block of inline code, beginning with an
_ldregs
call, and containing
no C statements other than calls to inline machine code functions. The results
of attempting to branch from one code block to another are unpredictable.
_branch, _blabel, and _flabel |
The
_bbwd
and
_bfwd
functions are not convenient
for symbolic use. For this reason, the
_branch
function and the
_blabel
and
_flabel
macros are provided.
These are more complicated than
_bbwd
and
_bfwd
, but lend themselves more readily
to symbolic use.
_branch
is a variant of
_code
in which the final halfword of an instruction
can be specified in one of two special forms larger than a halfword. One
of these forms is generated by
_blabel
, and the other by
_flabel
. To illustrate,
the
BCT
macro defined in the
<genl370.h>
header file (after expansion of various
inner macros) has the form:
#define BCT(r1,x,s) _branch(0x80000000 >> (r1), 0x4600 | ((r1) << 4) | (x), s)
The following uses of the BCT macro then behave as follows:
BCT(R1, 0, 6+b(3)) /* generates a BCT 1,6(0,3) */ BCT(R1, 0, _blabel(2)) /* same effect as _bbwd(0x4610, 2) */ BCT(R1, 0, _flabel(2)) /* same effect as _bfwd(0x4610, 2) */
The macros in
<genl370.h>
for instructions supported
by
_bfwd
and
_bbwd
have all been defined to use
_branch
.
Code Macros |
Although the
_code
function provides a very flexible method for
generating instructions, many machine instructions can be more easily generated
using code macros. The macros available for use are provided in the following
series of header files:
<genl370.h>
<str370.h>
<dec370.h>
<float370.h>
<ctl370.h>
<supv370.h>
<das370.h>
<io370.h>
<ioxa.h>
<vec370.h>
<lsa320.h>
Two other header files,
<code.h>
and
<regs.h>
, define basic-level
macros that are used by the macros in the header files listed above. You
can use the macros in
<code.h>
to simplify the arguments to the
_code
function. All of these header files are described in detail in Macros and Header Files.
Bit Masks for Using Registers |
Several of the built-in functions
use a 32-bit
mask
argument to indicate which registers the generated machine instructions
should use. Starting from the left of the mask, bits 0 through 15 indicate
whether general purpose registers 0 through 15 are used. Bits 16, 18, 20,
and 22 indicate the use of floating-point registers 0, 2, 4, and 6, respectively.
The remaining bits are not currently used and should be specified as 0.
The
<regs.h>
header file, which is included (via
#include
) in both
<svc.h>
and
<code.h>
, contains macros named R0 through R15
for general registers 0 through 15, and F0, F2, F4, and F6 for floating-point
registers 0, 2, 4, and 6. These macros enable you to symbolically specify
the register mask. For example, coding the
mask
argument in the following way
sets the bit mask to 0xc0010000, which requests the use of registers 0, 1,
and 15:
R0+R1+R15
Registers for Use with the _code_stregs, and _idregs Functions summarizes the use of registers by
_code
,
_ldregs
, and
_stregs
.
When you compile with the
armode
option, you can use the inline machine code functions to execute instructions
that modify the access registers (for instance, CPYA). An access register
is considered to have the same register number as the corresponding general
register. For example, the bit mask R2 indicates that general register 2,
access register 2, or both may be modified by the instruction. See Developing Applications for Use with UNIX System Services OS/390 for more information on
register masks.
Usage Notes |
_ldregs
. If the code sequence does not require any preloaded registers,
begin the sequence with
_ldregs(0)
, which informs the compiler of the start
of a sequence without loading any registers. Note that
_ldregs(0)
is not the same
as
_ldregs(R0)
.
?:
operator or an
if
statement. After the occurrence of a non-machine-code
construct, the contents of registers are unpredictable and, in general, will
not be preserved from any previous machine code function calls.
_stregs
or
_cc
, you must code it last
in the sequence. If you use them both, code
_stregs
before
_cc
. The function
_stregs
will not change the condition code, but the function
_cc
may change register
contents.
_stregs
. The arguments should be pointer variables or the addresses
of
auto
variables. If complex expressions are used, the compiler may
be forced to modify values stored in registers in order to evaluate the expressions.
_ldregs
conflicts with the compiler's assignment of registers to register
variables, the generated code may be suboptimal. General-purpose registers
0 through 3 and 14 through 15 may be used freely, as well as floating-point
registers 0 and 2.
Note that if you need to use floating-point register
4 or 6 and you specify
optimize
, you must use the
freg(0)
option to inhibit
assignment of floating-point register variables.
Registers for Use with the _code_stregs, and _idregs Functions
shows the general-purpose and floating-point registers when they are used
with the
_code,_stregs,
and
_ldregs
functions. No other
registers are used with these functions.
Inline Machine Code Usage Notes |
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.