SPL to HP C/XL Migration Guide HP 3000 MPE/iX Computer Systems Edition 2 Manufacturing Part Number: 30231-90001 E1089 U.S.A.
Notice The information contained in this document is subject to change without notice. Hewlett-Packard makes no warranty of any kind with regard to this material, including, but not limited to, the implied warranties of merchantability or fitness for a particular purpose. Hewlett-Packard shall not be liable for errors contained herein or for direct, indirect, special, incidental or consequential damages in connection with the furnishing or use of this material.
SPL to HP C/XL Migration Guide SPL to HP C/XL Migration Guide Printed in U.S.A. 900 Series HP 3000 Computer Systems HP Part No. 30231-90001 Edition Second Edition Printed Oct 1989 E1089 Printing History The following table lists the various printings of this manual, together with the respective release date for each edition or update.
Additional Documentation The following publications provide information that can help you migrate SPL programs to HP C/XL.
Preface The SPL to HP C/XL Migration Guide describes how to convert SPL programs to HP C/XL. It is intended for experienced SPL programmers who are also acquainted with the C language. The guide is organized to parallel the Systems Programming Language Reference Manual. Chapter 2 of this guide corresponds to chapter 1 of the reference manual, and so forth. The topics are presented in the same order. Section Description Chapter 1 Provides a general overview of the migration process.
Conventions This section discusses the notation conventions followed in this manual. "Syntax" deals with the notation used in syntax diagrams. "General" discusses other aspects of textual notation and practices. Syntax Notation computer Description Letters, digits, and special characters displayed in "computer" type are required and should be entered exactly as shown. SPL permits keywords to be upper- or lowercase. HP C/XL differentiates uppercase from lowercase.
elements are stacked within braces, you must select one of those elements. For example: {A} {B} {C} You must select "A" or "B" or "C". Notation [...] Description A horizontal ellipsis enclosed in brackets indicates that the previous element, usually a selection enclosed in brackets or braces, may be repeated one or more times, separated, if necessary, by spaces. For example: [, itemname ] [...] [,...
p- 6
Chapter 1 SPL Migration System Programming Language (SPL) is a language that was developed for the older HP 3000 computer systems, which currently run under the MPE V operating system. HP C/XL is the Hewlett-Packard implementation of the C programming language on the HP Precision Architecture 900 Series HP 3000 computer systems, which run under the MPE XL operating system. This guide will use the terms MPE V and MPE XL to refer to the two distinct architectures and operating environments.
CAUTION Applications running in Compatibility Mode must not execute privileged instructions; they must call only documented, callable MPE V/E or subsystem intrinsics. However, they may enter Privileged Mode and may call MPE V/E privileged intrinsics from Compatibility Mode. Object Code Translation The object code translation program, OCT, which is available on MPE XL machines, translates many of the MPE V instructions in a compiled object file into MPE XL instructions.
HP C/XL is a highly portable version of the C language. SPL programs that rarely use machine-dependent constructs are easy to translate to HP C/XL. Consequently, the first step in any SPL to HP C/XL conversion is to isolate, and, if possible, eliminate the use of machine-dependent SPL features. Machine-dependent SPL features include direct reference to hardware registers, assembly instructions, and explicit stack manipulation.
remaining SPL code (e.g., in subprograms). See the Switch Programming User's Guide for details. The following chapters parallel the Systems Programming Language Reference Manual, section for section, discussing the conversion issues involved.
representations noted above. Floating-point data stored on disk must be converted or replaced if the programs are converted to HP C/XL. The MPE XL intrinsic HPFPCONVERT may be used to convert floating point data to and from the various representations. See the MPE XL Intrinsics Reference Manual for details. Data Storage Alignment On MPE V, a data item whose size is two bytes or greater is aligned on a two-byte boundary.
1-6
Chapter 2 Program Structure This chapter discusses conversion issues that correspond to sections in Chapter 1 of the Systems Programming Language Reference Manual. Introduction SPL is particularly designed to access machine-dependent features of the MPE V operating system. The conversion to HP C/XL requires that these machine-dependent features be removed. Conventions Table 2-1.
| | eight characters are ASCII numeric. | | | | --------------------------------------------------------------------------------------------| | | | Statement labels are identifiers followed | Same as SPL. | | by colon ("label:"). | | | | | --------------------------------------------------------------------------------------------| | | | A compilation unit is bracketed by the | A compilation unit has no special | | reserved words BEGIN and END and terminated | delimiters.
| << comment-text >> | Similar to SPL's << comment-text >>. | | | | | ! comment-text to end of record | | | | | --------------------------------------------------------------------------------------------- Program and Subprogram Structure Table 2-5.
Procedures Table 2-7. Procedures --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | An SPL procedure can be passed parameters, | An HP C/XL function can be passed | | either by reference or by value. | parameters, but always by value.
functions either by declaring them as global (to all functions) or by passing them as parameters. See "SUBROUTINE Declaration". Intrinsics Table 2-9. --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | System and user-defined intrinsics are | System and user-defined intrinsics are | | accessed with the INTRINSIC declaration.
Entry Points Table 2-11. Entry Points --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | Main programs and procedures may have | No equivalent. | | multiple entry points.
Chapter 3 Basic Elements This chapter discusses conversion issues that correspond to sections in Chapter 2 of the Systems Programming Language Reference Manual. Data Storage Formats SPL processes six types of data. Table 3-1.
INTEGER Format Table 3-2. INTEGER Format --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | Type: INTEGER | Type: short int | | | | --------------------------------------------------------------------------------------------| | | | 16-bit signed integer in two's-complement | Same as SPL. | | form.
CAUTION The numeric ranges AND the data storage formats for SPL and HP C/XL 32-bit floating-point data are significantly different. If your application uses REAL floating-point data that depend on extreme values, bit manipulation, or file storage, you may have a problem in migrating to HP C/XL. However, floating-point values may be translated from MPE V format to MPE XL format and back with the MPE XL HPFPCONVERT intrinsic. See the MPE XL Intrinsics Reference Manual for details. LONG Format Table 3-5.
BYTE Format Table 3-6.
Constant Types Table 3-8.
Double Integer Constants Table 3-10.
CAUTION Since MPE XL floating-point format is different from MPE V floating point, REAL and LONG based constants must be carefully translated if they are intended for arithmetic use. Composite Constants Table 3-12.
Equated Integers Table 3-13.
Long Constants Table 3-15. --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | Type: LONG | Type: double | | | | --------------------------------------------------------------------------------------------| | | | long-constant: | real-constant: | | 1. [sign ] fixed-point-number L power | 1.
String Constants Table 3-17.
Identifiers Table 3-18.
Pointers Table 3-20.
Labels Table 3-21. Labels --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | A label is an identifier, followed by a | Same as SPL. | | colon, that prefixes a statement. | | | | | --------------------------------------------------------------------------------------------| | | | Can be declared in a LABEL declaration.
3- 14
Chapter 4 Global Data Declarations This chapter discusses conversion issues that correspond to sections in Chapter 3 of the Systems Programming Language Reference Manual. Types of Declarations Table 4-1.
SPL data declarations have only three general forms: simple, array, and pointer. However, this simplicity is enhanced by the powerful ability to equivalence data of all types and formats and to develop elaborate overlay structures. It is necessary, therefore, to understand the physical relationships between data elements. Much of that is beyond the scope of this guide.
Simple Variable Declarations Table 4-2. Simple Variable Declaration --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | simple-variable-declaration: | simple-variable-declaration: | | | | | [GLOBAL] type variable-defn [,...] ; | [static] type variable-defn [,...
ARRAY Declaration Table 4-3. ARRAY Declaration --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | array-declaration: | array-declaration: | | | | | [GLOBAL] [type ] ARRAY | 1b, 1d with lower <> 0. | | | | | [global-array-defn ,] [...
--------------------------------------------------------------------------------------------| | | | Default type: LOGICAL | Default type: int (= long int) | | | | --------------------------------------------------------------------------------------------| | | | Array declarations specify one-dimensional | Same as SPL. | | vectors of subscripted variables.
next DB secondary location; array IS allocated. 1b. Direct; bounded; variable is cell zero; lower location; array IS allocated. 1c. Same as 1a; initialized. 1d. Same as 1b; initialized. in next DB primary 2a. Indirect; unbounded; variable is pointer to cell zero; pointer in next DB primary location; pointer NOT allocated; array NOT allocated. 2b. Indirect; unbounded; variable is pointer to cell zero; pointer in specified DB primary location; pointer NOT allocated; array NOT allocated. 3a.
zero; cell zero in specified location; array NOT allocated. Indirect (if ref-id is pointer or indirect array); unbounded; variable is pointer to cell zero; cell zero in specified location; pointer in next DB primary location IF specified location is not ref-id cell zero OR IF one array is BYTE and other is not; ELSE pointer location shared with ref-id; pointer IS allocated; array NOT allocated. Array formats 2, 3, 4, 5, 6, 7, and 8 imply methods of data equivalencing or "overlays".
Array Formats 1b and 1d: Bounded Direct Arrays. --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | | | | 1b. INTEGER ARRAY ABC(0:4)=DB; | short int ABC[5]; | | | | | 1b. INTEGER ARRAY ABC(-3:4)=DB; | short int ABC_REF[8]; | | | short int *ABC = &ABC_REF[3]; | | | | | 1d.
Array Formats 7a and 8: Unbounded Equivalenced Arrays. --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | | | | DOUBLE ARRAY EFG(0:25); | long int EFG[26]; | | | | | ... | ... | | | | | 7a. REAL ARRAY ABC(*) = EFG; | float *ABC = &EFG[0]; | | | | | 8. DOUBLE ARRAY ABC(*) = EFG(0); | #define ABC EFG | | | | | 8.
In the second example, the DB area is equivalenced in a union with a structure that places cell zero of reference array ABC_DEF at location DB[10]. The pointer ABC is used to reference the array cells of ABC_REF, thus overcoming the undefined subscript range problem presented by the unbounded direct array in SPL. ABC_REF is a direct array. POINTER Declaration Table 4-4.
| word addresses, generally via LSL and LSR | one to a type short int pointer will | | shift operators. This also affects pointer | increment it by two, thus pointing to the | | arithmetic, since adding one to a byte | next type short int variable. | | pointer increments its address to the next | | | byte, but adding one to an integer pointer | While this is more convenient than the SPL | | increments its address to the next word.
SWITCH Declaration Table 4-6. SWITCH Declaration --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | switch-declaration: | define-directive: | | | | | SWITCH switch-id := label-id0 [,...
DEFINE Declaration and Reference Table 4-8. DEFINE Declaration and Reference --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | define-declaration: | define-directive: | | | | | DEFINE {define-id = text #} [,...
directive in parentheses to ensure correct evaluation of the actual parameters. EQUATE Declaration and Reference Table 4-9.
Chapter 5 Expressions, Assignments, and Scan Statements This chapter discusses conversion issues related to sections in Chapter 4 of the Systems Programming Language Reference Manual. Expression Types Table 5-1.
Table 5-2.
| unsigned long int | any type | Other becomes unsigned long int | | | | | --------------------------------------------------------------------------------------------| | | | | long int | unsigned int | Both become unsigned long int | | | | | --------------------------------------------------------------------------------------------| | | | | long int | not unsigned int | Other becomes long int | | | | | --------------------------------------------------------------------------------------------- When a va
| | Note: The HP C/XL assignment operator, | | | "=", is the SPL equality operator. | | | | --------------------------------------------------------------------------------------------| | | | Indexes are enclosed in parentheses, "( )". | Indexes are enclosed in brackets, "[ ]". | | | | --------------------------------------------------------------------------------------------- SPL allows assignment to the array-id of an indirect array since it is really a pointer.
| ARRAYNAME(0) and NEWARRAY(0) both refer to | | | the same location. | | | | | --------------------------------------------------------------------------------------------| | | | All SPL addresses are 16-bit quantities | All HP C/XL addresses are 32-bit | | that may be stored in integer and logical | quantities. | | variables.
Absolute Addresses Table 5-8. Absolute Addresses --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | absolute-address: | No equivalent.
See "Procedure Call Statement" and "Data Type" for more details about parameters passed by reference. Bit Operations Table 5-10. Bit Operations --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | Bit operations can be used in any | Standard operators handle much of the bit | | expression.
Bit Extraction Table 5-12. Bit Extraction --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | bit-extraction-operation: | No direct equivalent. | | | | | source . ( sbit : len ) | | | | | | source: | | | is a 16-bit value. | | | | | | sbit, len: | | | are values from 0 to 15.
Figure 5-2. HP C/XL BEXTRACT Macro Directive: Bit Extraction _____________________________________________________________ | | | unsigned short int BEXTRACT( SOURCE , SBIT , LEN ) | | unsigned short int SOURCE , SBIT , LEN ; | | { | | return ( (unsigned short int) | | ( ( SOURCE << SBIT ) >> ( 16 - LEN ) ) ) ;| | } | _____________________________________________________________ Figure 5-3.
Bit Concatenation (Merging) Table 5-13. Bit Concatenation --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | bit-concatenation-operation: | No direct equivalent. | | | | | dest CAT source ( dbit : sbit : len ) | | | | | | source: | | | is a 16-bit value from which bits are | | | extracted.
SOURCE is the word from which the bits will be extracted, DBIT is the start bit in the destination word, SBIT is the start bit in the source word, and LEN is the number of bits to be moved. To use it, replace a CAT expression like A CAT B (4:8:4) with BCONCAT(A,B,4,8,4) Step 2: In the HP C/XL program, replace the SPL function procedure with the HP C/XL function in Figure 5-5.
--------------------------------------------------------------------------------------------| | | | Example: | Example: | | | | | operand is LOGICAL or INTEGER: | operand is unsigned short int or short int:| | | | | X := Y & LSL(4) ; | | | | X = Y << 4 ; | | | | --------------------------------------------------------------------------------------------- Please notice that the examples above demonstrate the only simple exact equivalents between SPL and HP C/XL.
Table 5-15.
Figure 5-10. HP C/XL CSL Function: Bit Shift Operation __________________________________________________________________________ | | | unsigned short int CSR(X,C) | | unsigned short int X; | | int C; | | { | | for (;;--C) /*infinite loop, decrementing C after each iteration*/| | { | | if (C == 0) return(X); /*exit, returning X*/ | | X = ((X & 0x0001) << 15) | X >> 1; | | } | | } | __________________________________________________________________________ Figure 5-11.
Figure 5-13. HP C/XL DLSR Directive: Bit Shift Operation _________________________________________________________ | | | #define DASL(X,C) ((int)(((int)X & 0x80000000) | \| | ((int)X << (C)) & 0x7FFFFFFF)) | _________________________________________________________ Figure 5-14. HP C/XL DASL Directive: Bit Shift Operation _______________________________________________ | | | #define DASR(X,C) ((int)((int)X >> (C)))| _______________________________________________ Figure 5-15.
Table 5-17.
| | | | sign: | Same as SPL, except: | | | | | + | ( + is not permitted as a sign) | | | | | | | --------------------------------------------------------------------------------------------| | | | operator: | Same as SPL, except: | | | | | + (addition) | | | (subtraction) | | | * (multiplication) | | | / (division) | | | ^ (exponentiation allows real and long | Convert ^ to pow(x,y ) function.
| 4. addition | | | subtraction | | | | | --------------------------------------------------------------------------------------------- In general, well-formed expressions, with parentheses used to avoid possible confusion, will always yield the same sequence of operations. Care may be necessary to maintain the same precision, because of implicit data conversion. (See "Type Mixing (Arithmetic)" in this chapter). Type Mixing (Arithmetic) Table 5-21.
Logical Expressions Table 5-22.
| | | | + (unsigned addition) | | | (unsigned subtraction) | | | * (unsigned multiplication) | | | / (unsigned division) | | | MOD (unsigned modulus) | % (unsigned modulus) | | ** (unsigned multiplication) | * (unsigned multiplication) | | // (unsigned division) | / (unsigned division) | | MODD (unsigned modulus) | % (unsigned modulus) | | | | | (**, //, and MODD give DOUBLE result) | Use (long int) cast if needed for the | | | conversions from **, //, and MODD.
Conversion Issues SPL NOT Operator. SPL uses the same operator, NOT, for both bitwise negation and Boolean negation. HP C/XL uses two operators: "~" (tilde) for bitwise negation and "!" for Boolean negation. They give different results, as shown in Table 5-23. Table 5-23.
such as these is discouraged, as the resulting HP C/XL code will lack portability and be more difficult to maintain. Numeric Conversion. Unless a logical expression used in a condition clause results in true or false values that are not 65535 or 0 respectively, or a relational (true/false) result is used in a bitwise or numeric operation (not a recommended coding practice), there should be no problem with a simple substitution of operator symbols.
Sequence of Operations (Logical) Table 5-24. Order of Evaluation of Logical Operators --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | Order of evaluation: | Same as SPL, except for the following: | | | | | | bit operations | | 1.
| | | | 4. byte-ref rel-op ( value-group [,...] | 4. (No direct equivalent; | | | | | [, stack-decr ] | convert to format 3) | | | | | 5a. byte-variable = ALPHA | 5a. isalpha ( byte-variable ) | | | | | 5b. byte-variable <> ALPHA | 5b. !isalpha ( byte-variable ) | | | | | 5c. byte-variable = NUMERIC | 5c. isdigit ( byte-variable ) | | | | | 5d. byte-variable <> NUMERIC | 5d. !isdigit ( byte-variable ) | | | | | 5e. byte-variable = SPECIAL | 5e. !isalnum ( byte-variable ) | | | | | 5f.
--------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | A < B(3), (5),3 | strncmp(A,&B[3],5) < 0 | | | | | B(5) >= *PB,(5) | No equivalent | | | | | A <= "string" | strcmp(A,"string") <= 0 | | | | | B = ("ab",%07) | strcmp(B,"ab\7") == 0 | | | | | C <> ALPHA | !isalpha(C) | | | | ------------------------------------------------------
situation. Consider the case where both strings are equal up to a NUL character and different afterward: In HP C/XL notation, A == "ab\0de" (character values 'a', 'b',NUL,'d','e') and B == "ab\0fg" (character values 'a','b',NUL,'f','g') The SPL comparison "A = B,(5)" would be false, because d is less than f. But the HP C/XL comparison "strncmp(A,B,5)==0" would be true, because strncmp stops scanning at the NULs.
| case EQU: /* compare == */ | | while ((count != 0) && (*left == *right)) ADJ;| | break; | | case NEQ: /* compare != */ | | while ((count != 0) && (*left != *right)) ADJ;| | break; | | case GEQ: /* compare >= */ | | while ((count != 0) && (*left >= *right)) ADJ;| | break; | | case GTR: /* compare > */ | | while ((count != 0) && (*left > *right)) ADJ; | | break; | | } | | | | switch (sdec) | | { | | case 0: *raddr = right; | | case 1: *laddr = left; | | case 2: *caddr = count; | | case 3: ; /* nil */ | | }
--------------------------------------------------------------------------------------------| | | | In tests for true and false, an odd value | A nonzero value is true; a zero value is | | is true (bit 15 is on); an even value is | false. | | false (bit 15 is off). | | | | | --------------------------------------------------------------------------------------------- Condition clauses in SPL may appear in IF expressions and in IF, DO, and WHILE statements.
IF Expressions Table 5-27.
| specify a bit field in itself where the | This operation may be performed separately | | value will be deposited. | with the user-defined function BDEPOSIT, | | | described below. | | | | --------------------------------------------------------------------------------------------| | | | May be used as an expression. | Same as SPL. | | Its value is the value stored into the | | | leftmost operand. Its type is the type of | | | the leftmost operand.
Then separate the bit deposit from any multiple assignments and convert it to a procedure call. For example, I.(5:6) := J + K ; would become BDEPOSIT(@I,5,6,J+K); Note that the address of the first parameter is formed with the "@" operator, and that the parameter has been declared type LOGICAL (16 bit word), and passed by value. Within BDEPOSIT, this value is assigned to a pointer to allow the actual value to be accessed.
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.
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.
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.
you may use the HP C/XL equivalent: if isdigit(*(s1-1))...
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 CNT @S1 @D1 := := := := B1 := "test string",0; TOS; <> TOS; TOS; may be replaced with: LEN = MOVESB(S1,"test string",0,&S1,&S1); MOVEX Statement This SPL statement is available only to privileged users accessing extra data segments. Any use of extra data segments should be recoded, utilizing the larger memory space available in HP C/XL.
| In SCAN-UNTIL, scan starts at byte-ref and | | | continues until either test-char or | | | terminal-char is found. | | | | | | In SCAN-WHILE, scan starts at byte-ref and | | | continues until either terminal-char is | | | found or character NOT matching test-char | | | is found. | | | | | | Carry bit in status register is set to one | | | if terminal-char was found; otherwise, it | | | is set to zero. | | | | | | The address of the terminating byte is | | | placed on the stack.
In this case, these statements might become: NUM = strchr(B1,' ') - B1;" or NUM = strcspn(B1,"% "); NOTE The HP C/XL library function memchr that are not terminated by NUL ('\0', information on memchr and its related series of functions, see the HP C/XL can be used to scan strings numeric value 0). For more functions and on the str... Library Reference Manual. The HP C/XL SCANU function, shown in Figure 5-25, duplicates the SCAN-UNTIL operation.
Chapter 6 Program Control Statements This chapter discusses conversion issues that correspond to sections in Chapter 5 of the Systems Programming Language Reference Manual. Program Control SPL has nine basic methods of altering the normal sequential execution of instructions: CASE, DO, FOR, GOTO, IF, RETURN, and WHILE statements, and procedure and subroutine call statements. HP C/XL has equivalents for all these control statements, with some variations in syntax.
Table 6-2. GO TO Statement Examples --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | | | | 1. GO LABEL1; | 1. goto LABEL1; | | GOTO LABEL1; | goto LABEL1; | | GO TO LABEL1; | goto LABEL1; | | | | | 2. SWITCH SWITCHLABEL:=L0,L1,L2; | 2. #define SWITCHLABEL(X) \ | | ...
Table 6-4.
FOR Statement Table 6-7. FOR Statement --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | for-statement: | for-statement: | | | | | 1. FOR test-var := init-val | 1. for ( test-var = init-val ; | | UNTIL end-val | test-var <= end-val ; | | DO loop-statement | test-var ++ ) | | | loop-statement | | | | | 2.
| | | | | Formats 2a and 4a deal with the case where | | | step-val is positive. Formats 2b and 4b | | | handle the case where step-val is negative. | | | There is no easy way to combine the | | | formats. | | | | --------------------------------------------------------------------------------------------- In HP C/XL, the three expressions can actually contain multiple expressions, separated by commas. The last or right-most becomes the value of the expression.
| is executed. If it is false, and the ELSE | | | clause is present, else-statement is | | | executed; if the ELSE clause is omitted, | | | execution falls through to the statement | | | after true-statement. | | | | | --------------------------------------------------------------------------------------------| | | | If the ELSE clause is present, | Regardless of whether the else clause is | | true-statement must not end with a | present, a simple true-statement must end | | semicolon. | with a semicolon.
CASE Statement Table 6-11. CASE Statement --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | case-statement: | switch-statement: | | | | | CASE [*] index OF | switch ( index ) | | | | | BEGIN | " {" | | | | | statement0 ; | case 0: statement0 break ; | | | | | statement1 | case 1: statement1 break ; | | | | | [;...][;] | [...
Table 6-12.
Procedure Call Statement Table 6-13. Procedure Call Statement --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | procedure-call-statement: | function-call-statement: | | | | | 1. procedure-id | 1. function-id ( ) ; | | | | | 2. procedure-id ( ) | 2. function-id ( ) ; | | | | | 3. procedure-id ( actual-parm [,...] )| 3.
| | Fortunately, because SPL is so strict, the | | | conversion boils down to getting the | | | pass-by format correct. | | | | --------------------------------------------------------------------------------------------- Table 6-14.
means of accomplishing the same operation as the SPL example. Stacking Parameters By directly manipulating the hardware stack in MPE V, SPL programmers can set up parameters to a procedure directly and then call the procedure using "*" actual parameters. There is no equivalent in HP C/XL. However, replacing the "*"s in the parameter list with the stacked values is functionally equivalent. (Usually, the procedure call is preceded by assignments to TOS, which can be thus eliminated.
call. OPTION VARIABLE passed procedures require more work, including the fabrication on the stack of a special mask word. In HP C/XL, a function-id may be passed as an actual parameter. There are no particular restrictions on the actual parameter list when the passed function is called.
RETURN Statement Table 6-15. RETURN Statement --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | return-statement: | Similar to SPL: | | | | | 1. RETURN [count ] | 1. return ; | | | | | 2. procedure-id := procedure-id-value | 2a. return procedure-id-value ; | | | | | : | 2b.
6-14
Chapter 7 Machine Level Constructs This chapter discusses conversion issues related to sections in Chapter 6 of the Systems Programming Language Reference Manual. ASSEMBLE Statement Table 7-1. ASSEMBLE Statement --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | assemble-statement: | No equivalent.
7- 2
Chapter 8 Procedures, Intrinsics and Subroutines This chapter discusses conversion issues that correspond to sections in Chapter 7 of the Systems Programming Language Reference Manual. Subprogram Units Table 8-1.
| LOGICAL | unsigned short int | | | | --------------------------------------------------------------------------------------------| | | | BYTE | unsigned char OR unsigned short int | | | | --------------------------------------------------------------------------------------------| | | | REAL | float | | | | --------------------------------------------------------------------------------------------| | | | LONG | double | | | | -------------------------------------------------------------------------------
| "Options" below. | | | | | --------------------------------------------------------------------------------------------| | | | procedure-body: | function-body: | | | | | a. statement | a. " {" statement " }" | | | | | b. BEGIN | b. " {" | | | | | [local-data-declarations ] | [local-declarations ] | | | | | [external/intrinsic-declarations ] | [statement [...] ] | | | | | [local-subroutine-declarations ] | " }" | | | | | [statement [;...
| | return expression ; | | procedure-id := expression | | | | For easier conversion, declare a local | | For example: | variable, e.g., returnvalue, and replace | | | the procedure-id with it in the function | | INTEGER PROCEDURE FUNC ; | body. Then replace all the SPL RETURN | | BEGIN | statements with "return returnvalue" Add | | ... | one before the final "}": | | FUNC := Y + Z ; | | | ... | short int FUNC () ; | | RETURN ; | { | | ... | short int returnvalue ; | | FUNC := A - B ; | ... | | ...
| | parameters. The formal parameters "expect" | | | the converted forms and reconvert them | | | accordingly. HP C/XL does not check | | | parameters. | | | | --------------------------------------------------------------------------------------------| | | | Addresses are 16-bit pointers. | Addresses are 32-bit pointers.
| Prevents the procedure from being called | The static storage class provides similar | | from another segment. Generally used to | functionality. A static function-id will | | keep the procedure-id local. | not be exported to the linker, and | | | therefore will be unknown to other | | | compilation units. | | | | --------------------------------------------------------------------------------------------| | | | INTERRUPT | No equivalent. | | | | | Specifies an external interrupt procedure.
--------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | standard | [auto] (the default case) | | | | --------------------------------------------------------------------------------------------| | | | OWN | static | | | | --------------------------------------------------------------------------------------------| | | | EXTERNAL | ex
| 3b. variable-id = ref-id sign offset | | | | | --------------------------------------------------------------------------------------------| | | | type is required. | Default type: int (= long int) | | | | --------------------------------------------------------------------------------------------| | | | Storage is allocated each time the procedure| Same as SPL. | | is called. If an initial value is defined, | | | it will be assigned each time the procedure | | | is called.
EXTERNAL Simple Variables. Table 8-11. EXTERNAL Local Simple Variables --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | external-simple-variable-declaration: | extern-simple-variable-declaration: | | | | | EXTERNAL type variable-id [,...] ; | extern [type ] variable-id [,...
| 7. array-id (*) = register sign offset| | | | = & array-ref " [" index " ]" ; | | 8a. array-id (*) = ref-id | | | | | | 8b. array-id (*) = ref-id sign offset| init: | | | = " {" value [,...] " }" | | 9. array-id (*) = ref-id ( index ) | | | | | | | index: | | constant-array-decl: | Cell number in array-ref of cell that | | | corresponds to cell zero in SPL array. | | 10. array-id ( lower : upper ) = PB | | | | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | | := value-group [,...
4. Direct; unbounded; variable is cell zero; cell zero in next Q-relative location; array NOT allocated. 5a. Indirect; unbounded; variable is pointer to cell zero; pointer in next Q-relative location; pointer IS allocated; array NOT allocated. 5b. Indirect; unbounded; variable is pointer to cell zero; pointer in specified DB-, Q-, or S-relative location; pointer NOT allocated; array NOT allocated. 6.
Array Format 2: Bounded Indirect Variable Array. --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | | No direct equivalent. | | INTEGER ARRAY ABC ( LOW'VAR : HIGH'VAR ) | | | This is an SPL "indirect" array with | Dynamic arrays are not allowed, but there | | variable bounds.
| | static [type ] * array-id | | | | | | = & array-ref " [" index " ]" ; | | | | | | | | | init: | | | = " {" value [,...] " }" | | | | | | | | | index: | | | Cell number in array-ref of cell that | | | corresponds to cell zero in SPL array.
Local Pointer Declarations See "POINTER Declaration" for further details. Standard Local Pointers. Table 8-15. Standard Local Pointers --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | standard-local-pointer-declaration: | pointer-declaration: | | | | | [type ] POINTER ptr-decl [,...] ; | [type ] ptr-decl [,...
| Default type: LOGICAL | Default type: int (= long int) | | | | --------------------------------------------------------------------------------------------| | | | An OWN local pointer is allocated storage | Same as SPL, using a static local array. | | global to the procedure, in the DB-relative | | | area. It retains its values between | | | successive calls to the procedure.
| | Remove the SPL label declarations. | | | | --------------------------------------------------------------------------------------------| | | | The scope of a local label is the | Same as SPL. | | procedure. | | | | | --------------------------------------------------------------------------------------------- Local SWITCH Declarations See "SWITCH Declaration" for further details. Table 8-19.
You may emulate multiple entry points into an SPL procedure by adding a parameter to the HP C/XL function, and coding a switch statement in the function to goto the appropriate labels based on the value of the parameter. See "Local SWITCH Declarations" above for the format. Entry point identifiers used in calling routines must be changed to the procedure identifier. Alternatively, global #define directives could be used to equate the entry point identifiers with the procedure identifier.
| | | | | #undef equate-id | | | | --------------------------------------------------------------------------------------------| | | | The scope of a local EQUATE declaration is | The scope of a #define directive is not | | the procedure. | local. It is known to all following source | | | code. To turn it off, insert the #undef | | | directive at the end of the function.
| | The user-id option allows you to rename the | | | intrinsic-id for references in your | | | compilation unit. | | | | --------------------------------------------------------------------------------------------- Table 8-25.
| | : | | | | | | #undef function-id | | | | | | 2. #define function-id statement-process | | | | | | : | | | | | | #undef function-id | | | | --------------------------------------------------------------------------------------------| | | | A subroutine is like a procedure that has | No direct equivalent. | | no option or local declaration sections.
It is permitted (but rarely used) to execute a GOTO statement from an SPL subroutine to a label within the body of the enclosing procedure. HP C/XL restricts the goto statement to labels within the same function declaration.
8- 22
Chapter 9 Input/Output This chapter discusses conversion issues that correspond to sections in Chapter 8 of the Systems Programming Language Reference Manual. Introduction to Input/Output SPL has no input/output (I/O) statements; instead, it uses MPE V intrinsics to perform all I/O operations. Similarly, HP C/XL has no I/O statements; it does have its own library header file, , that provides a comprehensive set of macros and functions for I/O capabilities, including high level formatting.
Example Since all I/O operations by MPE V intrinsics use 16-bit data, it is common to equivalence a BYTE array to a previously declared LOGICAL word array. Then data is stored into or extracted from the byte array, while the equivalent word array is passed to the MPE V intrinsics.
#include filenum = _mpe_fileno(filedes ) See the HP C/XL Library Reference Manual for more details. Conflicting Function and Intrinsic Identifiers Five of the functions in the HP C/XL standard library have the same names as MPE intrinsics: fopen, fclose, fread, fwrite, and read. If any of the MPE intrinsics of the same name are used, it is recommended that you rename them with the #pragma intrinsic directive to avoid confusion.
| FUPDATE(filenum,buffer,length ) Update logical record in file | | FWRITE(filenum,buffer,length,ctlcode ) Write logical record to sequential file | | FWRITEDIR(filenum,buffer,length,lrecnum ) Write logical record to direct access file | | HPFOPEN(filenum,status [,itemnum,item ][...
| read(fildes,buf,nbyte ) Read fixed-length binary records from file | | fildes | | remove(filename ) Purge file filename | | rename(oldname,newname ) Rename file | | rewind(stream ) Reset byte position to beginning of file | | stream | | scanf(format [,item ][...
Alternatively, the HP C/XL fread function can be used to read fixed-length binary data into a structure, such as an array or struct. Since fread does not recognize file record boundaries, you need to be sure the sizes you supply add up correctly. The conventional means of performing I/O in HP C/XL is to view data files as a "stream" of text (ASCII characters) in variable-length records.
Numeric Data Input/Output SPL programs use four MPE V intrinsics to convert ASCII data to and from binary format. They are: ASCII Converts 16-bit binary number to ASCII. DASCII Converts 32-bit binary number to ASCII. BINARY Converts ASCII byte string to 16-bit binary. DBINARY Converts ASCII byte string to 32-bit binary. Converting floating-point numbers requires other intrinsics.
The simplicity and flexibility of these routines render the direct use of the MPE intrinsics a highly questionable option. The use of standard HP C/XL library functions in general will greatly improve portability to another operating system such as HP-UX. File Equations Standard attributes of a file used by an HP C/XL program may be modified through the use of MPE XL :FILE commands, just as for SPL.
Chapter 10 Compiler and MPE Commands This chapter discusses conversion issues that correspond to sections in Chapter 9 and 10 of the Systems Programming Language Reference Manual. Compiler Format The compiler listing format for HP C/XL is different from SPL's. For complete information about the HP C/XL compiler, refer to the HP C Reference Manual and the HP C/XL Reference Manual Supplement. Use and Format of Compiler Commands Table 10-1.
See the HP C/XL Reference Manual Supplement for further details. $CONTROL Command The SPL $CONTROL command has 22 options. Table 10-2 describes the available equivalent HP C/XL directives or compiler options. Table 10-2.
The HP C/XL Reference Manual Supplement describes the compiler options and #pragma directives listed above, as well as others not available to SPL. -------------------1 Where an SPL $CONTROL compiler command is replaced by an HP C/XL compiler option, please be aware that the compiler option applies to all of the source being compiled at the same time. These compiler options are convenient because the source remains unmodified, but you do lose the line-by-line toggling of the SPL compiler command.
| | #endif | | | | --------------------------------------------------------------------------------------------| | | | In a case where two switches are used in | This is rendered in HP C/XL as: | | series, you might see: | | | | #if X3 == ON | | $IF X3 = ON | #define GLOBALVAL 99 | | DEFINE GLOBALVAL = 99#; | #endif | | $IF X5 = OFF | #if X5 == OFF | | DEFINE GLOBALVAL = 101#; | #define GLOBALVAL 101 | | $IF | #endif | | | | -----------------------------------------------------------------------------------
$TITLE Command (Page Title in Standard Listing) Table 10-5. $TITLE Command --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | title-command: | title-pragma: | | | | | $TITLE ["title-string " [,...
$COPYRIGHT Command Table 10-7. $COPYRIGHT Command --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | copyright-command: | copyright-pragma: | | | | | $COPYRIGHT "string "[,...
$INCLUDE Command Table 10-8. $INCLUDE Command --------------------------------------------------------------------------------------------| | | | SPL | HP C/XL Equivalent | | | | --------------------------------------------------------------------------------------------| | | | include-command: | include-directive: | | | | | $INCLUDE filename | 1. #include "filename " | | | | | | 2.
10-8
Chapter 11 Step-by-Step SPL HP C/XL Conversion This chapter describes a suggested method for converting SPL programs into HP C/XL. It is by no means the only method, but it is one that works well in a number of common circumstances. The person assigned to the conversion should have a good working knowledge of SPL and the tools (that is, editors) that are used to maintain SPL programs. That person should also be acquainted with the C programming language.
Step Two: Rewrite SPL to Look Like HP C/XL The case sensitivity of HP C/XL is one of the first differences between these two languages that an SPL programmer is liable to notice. Because SPL ignores case, some SPL programs have examples of the same reserved word or variable name appearing in both upper- and lowercase at various points in the source. In HP C/XL, these names will be interpreted as different entities. HP C/XL keywords must be expressed in lowercase.
There are a few HP C/XL reserved words that are also reserved words in SPL, and there always exists the possibility that an SPL variable name has a unique meaning as an HP C/XL reserved word. All keywords in HP C/XL must be in lowercase, but relying on case differences to differentiate between reserved words and variable names is bad practice.
The following are HP C/XL reserved words. Examine the SPL source for any use of these words as variable names. auto break case char continue default do double else enum extern float for goto if int sizeof union long static unsigned register struct void return switch while short typedef You should also avoid the following proposed ANSI C reserved words: const signed volatile SPL array declarations should be examined for cases that have a nonzero lower bound.
Step Three: Convert the Source to HP C/XL If the preceding two steps have been performed carefully, conversion of the SPL source to something acceptable to the HP C/XL compiler may take less time and effort than expected. The major structural changes will be to remove the initial BEGIN, the outer block (call to procedure main), and the final END. HP C/XL will generate code to initiate the running of the program by calling function main.
will be apparent in the use of union declarations, old SPL equivalencing operations, awkward I/O functions, and so on. A frequent reason for equating variable names to arrays in SPL is to overcome the lack of any form of record or structure variables. Wherever possible, the use of union to emulate SPL equivalencing should be examined to determine if the HP C/XL struct declaration is more natural and appropriate.
sults from a literal translation. The features and operations that performed very efficiently under MPE V now may be needlessly complex and quite possibly less efficient. By using the high level constructs of HP C/XL and its extensive library functions, you can develop programs that are maintainable, portable, and will result in extremely efficient runtime code with the optimizing features of the HP C/XL compiler.
11-8
Appendix A SPL Procedures to Replace Special Features The SPL procedures in this appendix perform many of the same operations as the HP C/XL macros and functions in Appendix B. Using these procedures in an SPL program will help to isolate special hardware-dependent operations and greatly simplify the transition to HP C/XL.
PROCEDURE BDEPOSIT(dw,sb,nb,exp); VALUE dw, sb, nb, exp; LOGICAL dw, sb, nb, exp; BEGIN LOGICAL M; POINTER P; nb := 16-nb; sb := nb-sb; M := (%(16)FFFF & LSR(nb)) & LSL(sb); @p := dw; p := (p LAND NOT m) LOR (exp & LSL(sb) LAND m); END; SPL BEXTRACT Procedure: << << << << << << << << << << << << << << Bit Extraction BEXTRACT SPL BIT EXTRACTION >> >> This procedure emulates the SPL bit extraction, for example: >> x := y.
<< << << << << << << << << << << << << << << << << sdec = 3 cnt laddr raddr -- Ignore the last three >> parameters (in SPL, this is >> the default case, deleting >> three stack words). >> sdec = 2 -- Expect only one parameter after>> this, cnt. >> sdec = 1 -- Expect two parameters after >> this, cnt and laddr. >> sdec = 0 -- Expect three parameters after >> this, cnt, laddr, and raddr. >> -- The value of "count" at the conclusion of the >> comparison.
A-4
Appendix B HP C/XL Funtions to Emulate SPL Operations The HP C/XL macro directives and function definitions in this appendix emulate SPL operations that are performed by special features of the SPL language, usually designed to access specific instructions available under the MPE V operating system.
HP C/XL BDEPOSIT Function: Bit Deposit /************************************************************** BDEPOSIT SPL BIT DEPOSIT This emulates the SPL bit deposit operation, for example, I.(5:6) := J + K; Using this function, this may be converted to HP C with: BDEPOSIT(&i,5,6,j+k); The parameters used by BDEPOSIT are: dw -- The address of the destination word. sb -- The starting bit of the deposit field. nb -- The number of bits to deposit. exp -- The expression to deposit into the field specified.
HP C/XL BYTECMP Function: Byte Comparison /************************************************************* BYTECMP SPL COMPARE BYTE STRINGS This emulates the byte string compare expression in SPL, for example: IF A < B,(N),0; NN := TOS; <> @AA := TOS; <> @BB := TOS; <> This may be converted to C with: if (BYTECMP(a,LSS,b,n,0,&nn,&aa,&bb))... The parameters to BYTECMP are: left -- The left address to be compared.
case NEQ: case GEQ: case GTR: /* compare != */ while ((count != 0) && (*left != *right)) ADJ; break; /* compare >= */ while ((count != 0) && (*left >= *right)) ADJ; break; /* compare > */ while ((count != 0) && (*left > *right)) ADJ; break; } switch (sdec) { case 0: *raddr = right; case 1: *laddr = left; case 2: *caddr = count; case 3: ; /* nil */ } return (count == 0); #undef ADJ } HP C/XL MOVEB Function: Move Bytes /************************************************************* MOVEB SPL MOVE BYTES Th
***************************************************************/ short int MOVEB(to,from,count,sdec,source_addr,dest_addr) char *to, *from, **source_addr, **dest_addr; 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_addr = from; case 2: *dest_addr = to; case 3: ; /* nil
*************************************************************/ enum COND {A, AN, AS, N, ANS}; short int MOVEBW(to,from,cond,sdec,source_addr,dest_addr) enum COND cond; char *to, *from, **source_addr, **dest_addr; 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 (
**************************************************************/ short int MOVESB(to,str,sdec,source_addr,dest_addr) char *to, *str, **source_addr, **dest_addr; int sdec; { char *temp; temp = to; while (*str != '\0') *to++ = *str++; switch (sdec) { case 0: ; /* fall through to case 1 */ case 1: *source_addr = str; case 2: *dest_addr = to; case 3: ; /* nil */ } return(to-temp); } HP C/XL MOVEW Function: Move Words /******************************************************************** MOVEW SPL MOVE WORDS Th
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_addr = from; case 2: *dest_addr = to; case 3: ; /* nil */ } return(c); } HP C/XL SCANU Function: Scan Until /******************************************************************* SCANU SPL SCAN UNTIL This emulates the SCAN until statement in SPL, for
case 1: case 2: *scan_addr = ba; ; /* nil */ } return(ba-temp); } HP C/XL SCANW Function: Scan While /******************************************************************** SCANW SPL SCAN WHILE This emulates the SCAN while statement in SPL, for example: NUM := (SCAN B1 WHILE TEST, 0); T := TOS; <> @S1 := TOS; which may be converted to C with: LEN := SCANW(B1,TEST,0,&S1); The parameters to SCANW are: ba -- The address to be scanned. test -- The testword.
HP C/XL Bit Shift Macros and Functions /************************************************************/ #define LSL(x,c) ((unsigned short) ((unsigned short) x << c)) /************************************************************/ #define LSR(x,c) ((unsigned short) ((unsigned short) x >> c)) /************************************************************/ #define ASL(x,c) ((short) ( ((short)x & 0x8000) | \ ((short)x << c) & 0x7FFF) ) /************************************************************/ #define ASR(x,c)