MOVE Statement [ SPL to HP C/XL Migration Guide ] MPE/iX 5.0 Documentation
SPL to HP C/XL Migration Guide
MOVE Statement
Table 5-29. MOVE Statement
---------------------------------------------------------------------------------------------
| | |
| SPL | HP C/XL Equivalent |
| | |
---------------------------------------------------------------------------------------------
| | |
| move-statement: | No direct equivalents. |
| 1. MOVE target := source , ( count ) | 1. (See the MOVEB and MOVEW |
| [, stack-decr] | functions below.) |
| 2. MOVE target := *[PB] , ( count ) | 2. (Convert to format 1.) |
| [, stack-decr] | 3. (See the MOVEB, MOVEW, and MOVESB |
| 3. MOVE target := string-const | functions below.) |
| [, stack-decr] | 4. (Convert to format 3.) |
| 4. MOVE target := ( value-group [,...] ) | 5. (See the MOVEBW function below.) |
| [, stack-decr] | 6. (Convert to format 5.) |
| 5. MOVE target := source WHILE cond | |
| [, stack-decr] | |
| 6. MOVE target := * WHILE cond | |
| [, stack-decr] | |
| | |
---------------------------------------------------------------------------------------------
| | |
| target: | |
| array/pointer-ref | |
| * | |
| | |
| source: | |
| array/pointer-ref | |
| | |
---------------------------------------------------------------------------------------------
| | |
| May be used (without stack-decr) | |
| as an integer expression. | |
| Its value is the number of words | |
| or bytes moved. | |
| | |
---------------------------------------------------------------------------------------------
MOVE statements in SPL are designed to utilize several sophisticated
hardware move instructions. There are byte and word moves which can be
performed unconditionally or dependent upon a test condition. The
destination of the move must be an array or pointer, and the source may
be an array, a pointer, a string constant, or a group of values. Two of
the SPL moves are not directly translatable, for example:
MOVE arrayname := *PB,(count)
MOVE array name := (10(" "),"string",5(""))
The first is non-translatable because there is no register-relative
addressing in HP C/XL; the second, because repeat factors and grouping of
constants into a list are not available. The second case may be handled
by multiple move operations or manual expansion of the repetitions into a
string constant.
NOTE The str... amd mem... series of HP C/XL standard library
functions may also be useful here. The str... functions expect
the string to be terminated with NUL ('\0', numeric value 0). The
mem... functions do not use NUL. See the HP C/XL Library Reference
Manual for details.
Unconditional byte moves may be emulated in HP C/XL by the MOVEB
function, shown in Figure 5-21.
________________________________________________________
| |
| int MOVEB(to,from,count,sdec,source_adr,dest_adr)|
| char *to, *from, **source_adr, **dest_adr; |
| int count, sdec; |
| { |
| int c; |
| c = 0; |
| if (count>0) /* left-to-right move */ |
| do *to++ = *from++; while (++c < count); |
| else if (count<0) /* right-to-left move */|
| { |
| count = -count; |
| do *to-- = *from--; while (++c < count);|
| } |
| switch (sdec) |
| { |
| case 0: ; /* fall through to case 1 */ |
| case 1: *source_adr = from; |
| case 2: *dest_adr = to; |
| case 3: ; /* nil */ |
| } |
| return(c); |
| } |
________________________________________________________
Figure 5-21. HP C/XL MOVEB Function: MOVE Bytes Statement
In MOVEB, to is the target address, from is the source address, count is
the number of bytes to be moved (a positive value means a left-to-right
move, negative means right-to-left), and sdec is is the value which would
have been used as an SPL stack decrement. In this context, sdec = 3 will
cause the function to ignore the last two parameters, which need not be
present. An sdec = 2 will set the value for dest_adr, sdec = 1 or 0 will
set both dest_adr and source_adr. The parameter source_adr is the
address of the next character beyond the final character moved, dest_adr
is the address of the next character beyond the final character moved,
and the return value of the function is the number of bytes moved.
The following emulates the MOVE statement in SPL for byte moves with no
information removed from the stack:
MOVE A1 := A2, (CNT), 0
LEN := TOS; will always be zero
@S1 := TOS;
@D1 := TOS;
NUM := @D1 - @A1; number of bytes moved
This may be converted to HP C/XL as:
NUM = MOVEB(&A1,&A2,CNT,0,&S1,&D1);
The other variants of byte moves (removing one, two, or all three of the
words normally left on the stack after a MOVE) may all be emulated by
this function.
Word moves of 16-bit quantities may be emulated by a minor variation of
MOVEB, the HP C/XL function, MOVEW, shown in Figure 5-22.
______________________________________________________________
| |
| int MOVEW(to,from,count,sdec,source_adr,dest_adr) |
| unsigned short *to, *from, **source_adr, **dest_adr;|
| { |
| int c; |
| c = 0; |
| if (count>0) /* left-to-right move */ |
| do *to++ = *from++; while (++c < count); |
| else if (count<0) /* right-to-left move */ |
| { |
| count = -count; |
| do *to-- = *from--; while (++c < count); |
| } |
| |
| switch (sdec) |
| { |
| case 0: ; /* fall through to case 1 */ |
| case 1: *source_adr = from; |
| case 2: *dest_adr = to; |
| case 3: ; /* nil */ |
| } |
| |
| return(c); |
| } |
______________________________________________________________
Figure 5-22. HP C/XL MOVEW Function: MOVE Words Statement
The MOVE statement with a WHILE condition may be emulated by the HP C/XL
MOVEBW function, shown in Figure 5-23.
MOVEBW is used similarly to MOVEW, but, instead of a count, a condition
is supplied. The condition is chosen from the enum declared as COND that
matches the SPL options.
The SPL operation:
LEN := MOVE B1 := B2 WHILE AS;
@S1 := TOS;
@D1 := TOS;
may be replaced with the HP C/XL function call:
LEN = MOVEBW(B1,B2,AS,0,&S1,&D1);
In SPL, a MOVE-WHILE operation sets a condition code to indicate the type
of the last character of the source that was examined (but not moved).
This is easily tested by standard HP C/XL character functions. For
example, if an SPL MOVE-WHILE statement is followed by:
IF > THEN...<<move stopped on a digit 0-9>>
you may use the HP C/XL equivalent:
if isdigit(*(s1-1)).../* move stopped on a digit */
______________________________________________________________________
| |
| enum COND { A, AN, AS, N, ANS }; |
| |
| int MOVEBW(to,from,cond,sdec,source_adr,dest_adr) |
| enum COND cond; |
| char *to, *from, **source_adr, **dest_adr; |
| int sdec; |
| { |
| char *temp; |
| temp = to; |
| switch (cond) |
| { |
| case A: while (isalpha(*from)) *to++=*from++; |
| break; |
| case AN: while (isalnum(*from)) *to++=*from++; |
| break; |
| case AS: while (isalpha(*from)) *to++=toupper(*from++);|
| break; |
| case N: while (isdigit(*from)) *to++ = *from++; |
| break; |
| case ANS: while (isalnum(*from)) *to++=toupper(*from++);|
| break; |
| } |
| |
| switch (sdec) |
| { |
| case 0: ; /* fall through to case 1 */ |
| case 1: *source_adr = from; |
| case 2: *dest_adr = to; |
| } |
| |
| return(to-temp); |
| } |
______________________________________________________________________
Figure 5-23. HP C/XL MOVEBW Function: MOVE Bytes WHILE Statement
Moving a string constant into a byte array or through a byte pointer may
require the HP C/XL MOVESB function, shown in Figure 5-24.
______________________________________________________
| |
| int MOVESB(to,str,sdec,source_adr,dest_adr) |
| char *to, *str, **source_adr, **dest_adr; |
| int sdec; |
| { |
| char *temp; |
| temp = to; |
| while (*str != '\0') *to++ = *str++; |
| switch (sdec) |
| { |
| case 0: ; /* fall through to case 1 */|
| case 1: *source_adr = str; |
| case 2: *dest_adr = to; |
| case 3: ; /* nil */ |
| } |
| return(to - temp); |
| } |
______________________________________________________
Figure 5-24. HP C/XL MOVESB Function: MOVE String Bytes Statement
This function makes use of the fact that HP C/XL terminates a string with
the NUL character ('\0', numeric value 0).
Consequently, the SPL code
LEN := B1 := "test string",0;
CNT := TOS; <<always zero>>
@S1 := TOS;
@D1 := TOS;
may be replaced with:
LEN = MOVESB(S1,"test string",0,&S1,&S1);
MPE/iX 5.0 Documentation