4. ZCON DC Z(0,VAR,0).
3.1.14 NAME Operations 1 NAME Comparisons
3.1.14.2 NAME Assignment
The variable Y in the following examples may only be a NAME variable. The variable X may be either an actual or NAME variable having declared properties identical to Y (refer to Language Specification).
Operation Code
the ZCON index inhibit bits are ignored for the comparison
[LHI Ri,x‘FFFF0000’ ] [IAL Ri,x‘F7FF’ ]
[NR Rx,Ri ]
[NR Ry,Ri ]
-or-
X is a NAME variable, Y is a NAME REMOTE
[L Ry,Y ]
[LH Rx,X ]
[IAL Rx,x‘0800’ ]
(non-aggregate variables only) [SRA Rx,1 ]
[SRR Rx,31 ]
[OHI Rx,X‘8000’ ](PASS only) the ZCON index inhibit bits are ignored for the comparison
[LHI Ri,x‘FFFF0000’ ] [IAL Ri,x‘F7FF’ ]
[NR Rx,Ri ]
[NR Ry,Ri ]
The following apply to all of the above examples:
CR Rx,Ry
BC COND, not-true-label
BC 7, true-label
Note that the compiler emits an RLD card that informs the linkage editor to insert the proper CSECT value into the last four bits inserted by the IAL instruction for non-NAME non-stack variables, to conform to the ZCON format.
Operation Code
NAME(Y)=NAME(X) X and Y are NAME variables
[LH Rx,X ] [STH Rx,Y ] -or-
X and Y are NAME REMOTE variables [L Rx,X ] [ST Rx,Y ] -or-
Operation Code
X is a declared local variable, Y is not REMOTE
[LA Rx,X ] [STH Rx,Y ]
-or-
X is a declared REMOTE variable, Y is a NAME REMOTE
[L Rx,ZCON(X) ] [ST Rx,Y ] -or-
X is a declared local variable, Y is a NAME REMOTE
[LA Rx,X ]
[OHI Rx,x‘8000’ ](PASS only) [IAL Rx,x‘0800’ or x‘0000’]
[ST Rx,Y ] -or-
X is a NAME variable, Y is a NAME REMOTE [LH Rx,X ]
[IAL Rx,x‘0800’ ]
(non-aggregate variables only) [SRA Rx,1 ]
[SRR Rx,31 ]
[OHI Rx,x‘8000’ ](PASS only) [ST Rx,Y ]
Note that the compiler emits an RLD card that informs the linkage editor to insert the proper CSECT value into the last four bits inserted by the IAL instruction for non-NAME non-stack variables, to conform to the ZCON format.
-or-
Operation Code
X and Y are declared local variables, but X was previously converted to a ZCON to accomodate a NAME REMOTE left-hand side variable in a multiple assignment
[LA Rx,X ]
. .
[YCON to ZCON conversion ]
. .
[LR Ry,Rx ] ZCON
[SLL Ry,31 ] to YCON
[OHI Ry,x’7FFF’ ] con-
[NR Rx,Ry ] version
[ST Rx,Y ]
3.1.15 %MACROS
The following %MACROS are recognized by the HAL/S-FC compiler and produce the indicated code.
3.1.15.1 %SVC
The %SVC statement generates a true SVC instruction in which the address portion points to the operand specified.
3.1.15.2 %NAMECOPY
This operation works in the same manner as NAME assignments except that the operands must be structures, but not necessarily having identical properties. See Section 3.1.14.2 for more examples.
3.1.15.3 %COPY
The %COPY statement is used to move data from one location to another without regard to data types. This operation uses the block move algorithm. See section 3.1.17 for examples of the variances of that algorithm. The general form is: %COPY(dest, source, count);
where:
source is the variable name from which data will be moved; dest is the variable name into which data will be moved; and
count is optional and if present indicates the number of halfwords to be moved from source to dest. If count is omitted, the size of the source operand is used to determine a count.
NAME variables are dereferenced in all cases. Use of a NAME variable as dest or source operand will refer to the data pointed to by the NAME variable. The count may also be a NAME variable in which case the count is taken from the storage location pointed to by the NAME variable.
Error checking for %COPY statements is performed when the third argument is a literal or omitted. The following errors may be emitted:
Operation Code
%SVC (α) SVC α
Operation Code
%NAMECOPY(Y,X); LA Rx,X
where X is actual variable STH Rx,Y
The move halfword instruction (MVH) is used to implement the %COPY statement when feasible. If possible, the compiler will optimize the %COPY sequence by performing LED, STED, L, ST or LH, STH sequences instead of using the MVH instruction. This optimization occurs when the compiler is able to determine that no more than eight halfwords need to be moved and that the data alignments match for both source and receiving data areas. When the destination operand of a %COPY statement is REMOTE, a call to MSTR is used to implement the move. Since MSTR expects ZCON inputs, the compiler will perform a YCON to ZCON conversion if the source operand is LOCAL data. The following examples show some of the possible sequences.
A %COPY Warning:
Since the %COPY macro moves data without regard to data type, it can be used to move one character string over another character string even if the character string sizes do not match. A HAL/S CHARACTER string is defined as one halfword descriptor, aligned on a halfword boundary, followed by the data (two characters
packed into each halfword of memory). The string descriptor is organized into two one- byte values: the upper byte contains the maximum number of characters the string can hold and the lower byte contains the actual number of characters in the string.
When the %COPY source is a smaller string than the destination, the destination string's descriptor gets overwritten causing the string to internally become smaller and causing unexpected results in all subsequent uses of the destination. Conversely, when the source is bigger than the destination and the 3rd argument is a literal count or is omitted, the compiler correctly emits a FN106 error ("ELEMENT OR CSECT
BOUNDARY EXCEEDED FOR DESTINATION OF %COPY") if the character strings are declared locally and are non-REMOTE.
Examples:
FN106: When the element boundary is exceeded for non-remote locally declared variables. For example, if the source or destination is a scalar (size of scalar is two halfwords), and the number of halfwords to copy is 4, then the boundary of the variable has been exceeded and an FN106 is emitted. If the source or destination is an array, or element of an array, an FN106 error message is emitted when the location of the array element plus the number of halfwords to copy exceeds the ending position of the array.
FN107: When runtime addressing is generated for a non-remote locally declared variable involved in a %COPY statement. Runtime addressing means the compiler cannot determine the address of a variable during compilation.
FN108: When the source or destination dereferences a pass-by-reference formal parameter.
1. Strings A and B are declared as CHARACTER(20). When the following %COPY statement:
is executed, 11 halfwords (10 halfwords (20 bytes of character data / 2) + 1 halfword of descriptor) are copied in to the memory location containing A. This %COPY statement does not pose any problems because the length of the source and destination strings are the same.
2. String X is declared as CHARACTER(20) and string Z is declared as CHARACTER(15). When the following:
%COPY(X,Z);
is executed, 9 halfwords (8 halfwords ((15 bytes of character data + 1 byte of pad) / 2) + 1 halfword of descriptor) are copied into the memory location containing CHARACTER X. The new maximum character size of string X would be 15. This occurs because the %COPY macro moves the 9 halfwords representing string Z over the first 9 halfwords of string A, and in the process, overwriting X's string descriptor. After this statement, and for the duration of the program's execution, the internal character size of X is 15, not 20, as originally declared! Furthermore, this situation could lead to some unexpected execution results. For example: after the above %COPY statement character B is assigned into character X ("X = B;") by calling the CASR run-time library, the character assignment would not take place. This happens because CASR's checks would detect the size of character X is internally smaller than string B.
3. Using the values in example 2 above, if the user codes the following %COPY statement:
%COPY(Z,X);
the compiler would correctly emit a FN106 error when the 3rd argument is omitted because the destination operand is smaller than the source operand.
Note: The compiler can allow an assignment to exceed the bounds of the receiving data. There are two methods of doing this that could cause problems, and thus should be avoided:
a. A %COPY statement with a variable halfword count field larger than the size of the destination when the destination is local data (this may also go beyond the bounds of a CSECT). The compiler performs bound checking when a literal count is provided but cannot perform these checks when a variable count is used. Local data can be rearranged whenever a compilation unit is modified.
b. Overindexing an arrayed variable (subscript is greater than the receiving data's declared arrayness).
The compiler assumes that arrayed assignments and %COPY are not used in this manner and does not update registers that may have been modified as a result of a violation of these rules.
Operation Code
%COPY(X,Y) L Rx,YCON(X, size of Y)
L Ry,ZCON(Y) MVH Rx,Ry %COPY(X,Y,n) L Rx,YCON(X,n) L Ry,ZCON(Y) MVH Rx,Ry %COPY(X,Y,5) L Ry,Y ST Ry,X L Ry,Y+2 ST Ry,X+2 LH Ry,Y+4 STH Ry,X+4 %COPY(X,Y); L R4,ZCON(Y)
where X and Y are LFXI R5,size of Y
REMOTE L R2,ZCON(X)
SCAL@# MSTR
%COPY(X,Y); LA R4,Y
where X is REMOTE OHI R4,'8000' (PASS only)
and Y is local IAL R4,'0000'
LFXI R5,size of Y
L R2,ZCON(X)
3.1.15.4 %NAMEADD
The %NAMEADD statement adds an integer to a given NAME variable and assigns the result into a separate NAME variable. It consists of three operands as seen below:
%NAMEADD(X, Y, Z) where:
The source (Y) cannot be REMOTE if the destination (X) is non-REMOTE.
The result of the %NAMEADD statement which is placed into the NAME variable, X, is equal to the NAME value of Y plus the integer Z.
In either of the last two examples above, code may be inserted immediately before the ST instruction to clear the ZCON index inhibit bit according to the type of X.
X is any NAME variable.
Y can be either any NAME variable or any HAL variable which is legal in the context NAME(V).
Z is either an integer literal or variable which specifies the amount to be added (which may be negative) from the second operand. (Note: literals must not be signed.)
Operation Code
%NAMEADD(X,Y,5); LA Rx,Y+5
where Y is a non-NAME variable STH Rx,X
and X is non-REMOTE
%NAMEADD(X,Y,Z); LA Rx,Y
where Y is a non-NAME variable AH Rx,Z
and X is non-REMOTE STH Rx,X
%NAMEADD(X,Y,8); LH Rx,Y
where Y is a NAME variable LA Rx,8(Rx)
and X is non-REMOTE STH Rx,X
%NAMEADD(X,Y,8); L Rx,ZCON(Y)
where Y is a non-NAME REMOTE AHI Rx,8
variable and X is NAME REMOTE ST Rx,X
%NAMEADD(X,Y,8); L Rx,Y
where Y is NAME REMOTE AHI Rx,8
and X is NAME REMOTE ST Rx,X
Operation Code
%NAMEADD(X,Y,8); LA Rx,Y+8
where Y is a non-NAME variable
If X is of aggregate type (i.e. ARRAY(3) SCALAR) and Y is of REMOTE singular type (i.e. SCALAR) then the following code is inserted to clear the index inhibit bit:
LFXI Ri,-1
IAL Ri,x"F7FF"
NR Rx,Ri
3.1.15.5 %NAMEBIAS
By convention, the compiler uses an address for aggregate data that is offset a certain number of halfwords (depending on data type) before the actual beginning of the data (see Section 3.1.1.2). The %NAMEBIAS statement performs this zeroth element calculation by determining the positive value needed to point to the first element of the data. It consists of two operands as seen below:
%NAMEBIAS(X,Y) where,
X is a destination variable of integer type
Y is a source variable of any data type (unsubscripted)
The result of the %NAMEBIAS statement is placed into the variable X. Please note that the offset of a NAME variable is the offset of the variable to which it points.
and X is NAME REMOTE IAL Rx,x‘0800’ or x‘0000’
(linker fills in sector num- ber) ST Rx,X %NAMEADD(X,Y,8); LH Rx,Y where Y is a NAME variable LA Rx,8(Rx)
and X is NAME REMOTE STH Rx,x‘0800’
(non-aggregate variables only)
SRA Rx,1
SRR Rx,31
OHI Rx,x‘8000’ (PASS only)
ST Rx,X
Operation Code
%NAMEBIAS(X,Y) LFXI/LHI/L Ry,zeroth element offset of Y where X is a non-NAME variable STH/ST Ry,X