The Native Mode SPL Compiler for MPE/iX
Programmer's Guide
This guide is for programmers who are using the SPLash! Compiler to migrate SPL code to the MPE/iX platform or who want to continue writing code in SPL and have Native Mode performance.
This document assumes a firm foundation in SPL syntax and methodology. Much of the information in this document stresses the differences between SPLash! and SPL, so you may want to prepare for your compilation project by studying your SPL documentation in addition to this manual. Reference documents for SPL are listed in the section called "Other Sources of Information" in the first chapter of this manual.
Copyright c 1995-2003 Allegro Consultants, Inc.
ALLEGRO CONSULTANTS, INC. MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Allegro Consultants, Inc. shall not be liable for errors contained herein or for incidental or consequential damages in connection with the furnishing, performance or use of this material.
HP-UX, MPE V, MPE XL, and MPE/iX are trademarks of Hewlett- Packard Company.
UNIX is a trademark of AT&T Bell Laboratories.
Allegro Consultants, Inc. 20111 Stevens Creek Blvd., Suite 245 Cupertino, CA 95014-2397 USA (408) 252-2330 voice (408) 200-4488 fax support@allegro.com www.allegro.com 2004-01-01
Table of Contents1. Introduction 2. Installation 3. Before you start 4. Compiling with SPLash! 5. Parameters, Procedures & Conventions 6. Beyond SPL 7. Using XREF 8. Migration Issues 9. Run Time Error Recovery Appendix A : Assemble Appendix B : Intrinsic Changes Appendix C : Compiler Messages Appendix D : SPLash! Debugger Appendix E : SPLash! & Debug/iX Macros Appendix F : Sample Code Appendix G : Technical Background Glossary Index
(top) (index)
1 Introduction
The SPLash! Native Mode Compiler is a compiler for SPL (Systems Programming Language), Hewlett-Packard's powerful block-structured programming language. SPL was originally developed to run under the MPE V operating system and to take advantage of the hardware features of the original family of HP3000 computers. With the advent of Hewlett-Packard Precision Architecture and a new generation of HP3000s, SPLash! offers the features of the original SPL language and the opportunity to take advantage of the full native mode capabilities of the new machines.
SPLash! is a powerful tool for migrating existing SPL applications to Hewllett-Packard's Precision Architecture (HPPA). With SPLash!, there is no need to recode your programs using a different language, nor do you need to maintain original and translated versions of your object code. SPLash! gives you access to native mode performance on HP Precision Architecture machines.
SPLash! was designed for maximum compatibility with its MPE V counterpart. Since the original SPL language was highly dependent on the hardware environment of the MPE V-based HP3000, SPLash! emulates the addressing scheme of these older machines. All constructs supported by SPL are supported by SPLash!, including most ASSEMBLEs, all stack references (such as TOS and stack decrements), and all other statements. The features that SPLash! does not support generally depend on the old 16-bit architecture or other hardware features that do not exist in HP Precision Architecture. Throughout the manual, these differences are discussed as they arise.
Program development with SPLash! involves the usual cycles of editing, compiling, linking, and testing. There are two approaches to choose from in compiling your programs. One approach is based on UDCs that are provided with the product. The second approach is to use command files in the same manner that you would use for any HP compiler product. These approaches are discussed next.
Using SPLash! UDCs
Two UDC files are provided with the SPLash! compiler. The default
UDCs are geared towards program development on the Spectrum, while
the alternate UDCs (contained in
SPLASHV.PUB.SPLASH
) function like
the SPL UDCs (SPL, SPLPREP). The installation job builds the
necessary account structure and initializes the default UDC file,
SPLASHU.PUB.SPLASH
.
When compiling with the default UDCs, SPLash! uses two groups for
storage of intermediate code. These groups are ASM and O. The ASM
group contains the direct output of SPLash!, the assembly language.
The O group is used by the assembler. This is where the assembled
output is stored. The files that are stored in the O group are
native mode object files, (filecode NMOBJ). These files can be
linked together with the LINKEDIT program to produce native mode
programs, native mode executable libraries, or native mode
relocatable libraries.
Using Command Files
If you want to use command files for SPLash! development, you can
choose any one of the four command files provided for that purpose.
These command files are modeled after the command file format that
the HP compilers use. The command files are listed next.
Compilation Command Files
Regardless of the approach you take, it is recommended that you
review at a minimum the chapters
Before you start
,
Compiling with SPLash!
, and
Beyond SPL
.
In most cases, very few changes are required to successfully compile
your original SPL source with SPLash!. If you do need to implement
source code changes, you have several resources to work with. First,
SPLash! CONTROL options are provided that ease migration analysis and
testing of SPL code. Second, a cross-reference utility program,
XREF, is provided to help with the analysis of your SPL code. Third,
several SPLash! debug macros are provided for use with the HP
debugger (see Appendix E). Appendix A discusses native mode and
privileged mode Assemble instructions. And finally, Appendix B covers
intrinsic differences between MPE V and MPE/iX.
This document introduces SPLash! and provides a detailed
reference for programmers. Whether you are migrating existing SPL
applications to HP Precision Architecture machines or whether you are
taking advantage of SPLash!'s powerful language features to
develop new programs, use this document along with Hewlett-Packard's
SPL documentation to obtain the information you need to successfully
implement your design.
The information in this document is organized into eight
chapters and several appendices. Depending on your technical
background and on your purpose for using SPLash!, you may
want to concentrate on certain sections and skip others.
This document is intended to supplement, not replace, Hewlett-Packard's
SPL documentation. For all practical purposes, it is assumed that
SPLash! users have a firm foundation in SPL. The thrust of this
document, then, is to educate on the differences between these two
languages and to provide the knowledge necessary for migrating SPL-based
code to the MPE/iX platform.
Detailed descriptions of SPL syntax and usage can be found
in the following Hewlett-Packard documentation:
HP3000 Computer Systems: Systems Programming Language Textbook
(Part No. 30000-90025)
HP3000 Machine Instruction Set
(Part No. 30000-90022)
HP PASCAL/XL Reference Manual
HP PASCAL/XL Programmer's Guide
HP C/XL Reference Manual
HP C/XL Programmer's Guide
HP Precision Architecture: Precision Architecture and Instruction
Reference, Procedure Calling Conventions Reference Manual
(Part No. 09740-64003)
MPE XL Programmer's Series: System Debug Reference Manual
(Part No. 32650-60017)
The following conventions are used throughout this document.
With the introduction of release 4.0 of the MPE/iX operating system, HP
changed the name of the operating system from MPE XL to MPE/iX.
Throughout this manual, we have tried to be consistent in our use of
MPE/iX versus MPE XL. In most cases, the two words are interchangeable.
This chapter guides you through the installation process, step by step.
There are two methods for installing SPLash! so that you can choose
the installation procedure that best suits your needs.
Updates can be installed over the existing SPLASH account. Or,
SPLash! can be installed in a uniquely named account. The advantage
of the later is that the update can be tested before being rolled
into a production environment.
Before updating the SPLASH account, remove any cataloged SPLASH UDCs.
UDC files may be modified from update to update.
1. Logon as MANAGER.SYS
2. Mount the SPLash! update tape and place the tape drive online.
3. Restore the file
SPLASH.PUB.SYS
by entering the following commands:
4. Edit the passwords in line #1 for MANAGER.SYS in the file
SPLASH.PUB.SYS.
5. Stream the installation job by entering the following command:
When the job for MANAGER.SYS logs off, check the $STDLIST for errors.
If no errors are reported, then SPLash! is ready to use. By default,
the SPLash! UDCs are only set for MGR.SPLASH, however, this is easily
changed by using the SETCATALOG command.
These instructions are very similar to the above with one
exception. Insert the following instruction after step 4.
4.5 After the file
SPLASH.PUB.SYS
is restored, use
a text editor to change the line specifying the account name to the
name of the account where SPLash! will be installed. Initially, this
looks like the following:
Only valid MPE account names can be used.
Note
—The installation job will automatically edit the UDC and
command files so that they can be used from the account that
you specify.
splxl.pub.splash Compile to ASM
splobjxl.pub.splash Compile to OBJ
spllkxl.pub.splash Compile to NMPRG
splxlgo.pub.splash Compile & Execute
(top) (index)
About This Manual
Chapter 1, Introduction,
describes SPLash! at
a high level. It also lists relevant Hewlett Packard publications
that you may want to review as companions to this document.
Chapter 2, Installation,
discusses the account
structure and step by step instructions on how to install your
SPLash! software.
Chapter 3, Before you start,
highlights important differences between the MPE V and MPE/iX
operating systems and identifies conceptual differences
between the original SPL and SPLash!.
Chapter 4, Compiling with SPLash!,
provides
detailed information on the compilation process.
Chapter 5, Parameters, Procedures & Conventions,
introduces SPLash! procedure and parameter calling mechanisms and
other conventions. In addition, it lists important SPLash!
register conventions that you may need to know to successfully debug
your code.
Chapter 6, Beyond SPL,
describes the
options and features that extend SPLash! beyond the capabilities
of the original SPL language.
Chapter 7, Using XREF,
provides an introduction to
this useful cross-reference tool for SPL programs, including
a several examples to get you started.
Chapter 8, Migration Issues,
provides information
to help you successfully migrate an existing SPL application to your
HP Precision Architecture machine using SPLash!. Porting to HP-UX is
also covered in this chapter. Differences in data types, data formats,
and intrinsics are also explained.
Chapter 9, Run Time Error Recovery,
describes the
methods supported by SPLash! for this purpose.
Appendix A, Assemble Instructions,
discusses
how Assemble instructions can affect your migration
when language features are not supported in SPLash!.
Appendix B, Intrinsic Changes
lists the
intrinsics that are not supported under MPE/iX.
Appendix C, Messages
, lists General Messages,
Warning Messages, Error Messages and Internal Error Messages.
Appendix D, SPLash! Debugger,
introduces the
internal SPLash! Debugger
Appendix E, SPLash! & Debug/iX Macros,
provides support for the material on Debugging with a discussion on
the SPLash! Debug macros, highlighting important points as
required. Included also is an introduction to Debug/iX.
Appendix F, Sample Code,
provides sample
programs to illustrate techniques for migrating with SPLash! and
creating new applications using SPLash! extensions.
Appendix G, Technical Background,
discusses the
basic structure in the new architecture and the differences between
MPE V and MPE/iX.
(top) (index)
Other Sources of Information
HP3000 Computer Systems: Systems Programming Language Reference
Manual
(Part No. 30000-90024)
(top) (index)
Typeface Conventions
Bold Important terms. CAPS Command, intrinsic , and filenames.
Italic Publication names, Chapter names, or
to provide emphasis. Fixed Font Screen display and computer output.
<angled brackets> User-specified input is
designated by angled brackets. Terminology
(top) (index)
2 Installation
Introduction
(top) (index)
Overwriting the SPLASH account (default)
:file spltape;dev=tape
:restore *spltape;splash.pub.sys
(Reply to the tape request for "SPLTAPE")
:stream splash.pub.sys
(Reply to the tape request for "SPLTAPE")
(top) (index)
Install in Uniquely Named Account
:setvar accountname "SPLASH"
For example, if you want to install SPLash! in the account named
SPLTEST, you would change the setvar line to the following:
:setvar accountname "SPLTEST"
(top) (index)
When SPLash! was designed, one of the primary objectives was to achieve maximum compatibility with the MPE V based HP3000 environment. Almost all hardware dependent features were implemented, including:
Top of Stack references.
Stack decrements on MOVE, SCAN, and byte
comparisons.
Full MPE V-based HP3000 addressing mode emulation.
Maintenance of all data types.
Virtually all ASSEMBLE statements.
Stack emulation, including register
caching of the top stack words.
As good as SPLash! is at maintaining the MPE V-based HP3000 environment, some facets of the traditional HP3000 architecture were not implemented because they were too specific, required too much overhead at run time, depended upon a property which is non-existent or meaningless in Hewlett-Packard Precision Architecture, or were obsolete. SPLash! will flag these few constructs, should they exist in your code, and outline ways in which you might change your code in order for it to compile and execute in native mode.
An example of how SPLash! flags these constructs is shown below. A
line from an SPL program is shown, along with the error message that
would be generated by SPLash!.
Note
—Almost all of the features not implemented by SPLash!
are instructions accessed by the ASSEMBLE statement.
These features are enumerated in the discussions that follow.
Furthermore, the constructs presented in these discussions are
probably the least commonly used constructs in the SPL language.
Over the years, much SPL code has been written to run in privileged
mode (PM). The rational for this was to eliminate the normal checks
of HP3000 microcode or the MPE operating system, opening up the
opportunity for data to be read or modified anywhere in the system.
The dangers of using PM were, in these cases, outweighed by the
ability to programmatically determine information about the runtime
environment. Given the constraints of the environment, such
information was simply not available through standard MPE interfaces.
Introducing PM code solved the information gap problem.
PM operations in the SPL environment are extremely
difficult, if not impossible, for SPLash! to support. Fortunately,
the paucity of PM support
SPLash! isn't a problem in most cases. Standard
intrinsics, as well as AIF intrinsics, offer standard, replacement
solutions to outdated PM code. The primary focus of this chapter,
then, is pointed towards those rare occurrences where adequate
solutions are either tricky to implement or simply not available.
Background information is provided, however, that may assist you in
developing an optimal solution.
Compatibility Mode & Privileged Mode
Many of the HP3000 PM operations are supported by the
compatibility mode (CM) emulator on MPE/iX, and are therefore
supported by SPLash!. However, a general problem with PM has always
been determining the function and format of the system data
structures being accessed.
For a long time, information on where
system data resided, how it was structured, and exactly what it was
used for was unavailable until HP published the
Systems Tables
Manual
, the MPE System Tables Diagram and other
documentation. Even with these resources available, HP reserved (and
still reserves) the right to change these data structures when it
deems necessary.
Because of these changes to the operating system, simply updating to
a new version of MPE could cause a PM program to run incorrectly or,
at best, give erroneous results. It could also cause system failures
and/or data corruption. This constant necessity to validate the
functions of PM code is one of the prices that is paid for the added
functionality and performance possible by using these programming
techniques. Often, new versions of the operating system contain new
functionality which negates the need for the PM code. For example,
many routines have been written which programmatically determine the
job/session number of the calling program. The necessity to code this
function via PM was removed when the JOBINFO intrinsic was introduced
a few years ago. More recently, the advent of the AIF intrinsics
eliminated similar needs. Both JOBINFO and the AIF intrinsics are
fully supported in SPLash!.
Philosophically, PM operations in SPL are very different from
other types of statements because their semantics are totally
dependent upon the surrounding environment, the data being passed to
them, and the MPE system tables and other objects being accessed.
For example, a standard SPL MOVE statement is very easy to
understand. The concept of moving strings of data from one area of
memory to another is common to all computer systems, and can be
generated on the Series 900 very easily. However, the machine
instruction MFDS (Move From Data Segment) relies upon the existence
of data segments, a concept very specific to the HP3000
hardware architecture. Additionally, it is impossible to determine
from the source code exactly what is the intended purpose of the
MFDS instruction without also examining elements external to the SPL
language itself, such as what system table is being used and what
data within the table is being read. A MOVE statement, on the other
hand, is totally self-contained and easy to understand both by humans
and by the compiler.
In migrating SPL code to the Series 900 machines running under
MPE/iX, it must be realized that this code is being moved to an
environment totally different from that of the traditional
stack-based HP3000.
Not only is the hardware environment dissimilar,
but the operating system (MPE/iX) has been heavily rewritten to run
on this new hardware architecture.
Although the functionality of most of the MPE V tables has been
duplicated in the MPE/iX tables, it cannot be assumed that
these two sets of tables have the same format. Until
Hewlett-Packard publishes an MPE/iX tables manual or its equivalent,
these tables will remain inaccessible. A larger issue also exists:
as of this writing it is uncertain how MPE/iX will map the HP3000
two-level PM scheme (user or privileged) into the four-layer ring security
structure of Hewlett-Packard Precision Architecture. Until these
issues are resolved, a straight migration of some SPL code running in
privileged mode is impossible.
The compatibility mode emulator running under MPE/iX does simulate
most privileged operations. Every attempt has been made to allow
SPLash! to support those privileged operations
that are present in the emulator. However, most are flagged as errors
to point out the use of privileged mode in your code.
Note that although the
operations included in the discussions below (unless otherwise noted)
are not supported in the full release version of SPLash!, all other
operations are supported. Any privileged operations
not explicitly discussed in this documentation are
supported by SPLash!.
In summary, migrating privileged SPL code to the Series 900 will generally
require a close examination of the specific functionality desired by
the code. With this understanding, the following questions should be asked:
2. If so, is there a new MPE/iX or HPPA facility that can be
used, instead of employing PM?
This section documents those CM Instructions that SPLash! does not
support.
Read Switch Register (RSW) Instruction
The Read Switch Register instruction was implemented originally for
the Series II and III HP3000 models. The front panel on these
models contained displays for two registers: the Current Instruction
Register and the Switch Register. For each bit in the switch
register there was a rocker switch, which allowed the operator to
toggle specific bits on and off at will. When the RSW instruction
was executed, it read which switches had been set on, and pushed this
as a 16-bit data word to top of stack. The most common use of this
instruction was by INITIAL, the system startup program. The operator
would toggle in different combinations of bits, which varied with the
startup method (tape or disc).
In a very few, highly specific cases, the switch register was
used as a signal to applications.
On HP-IB systems, the RSW changed slightly and was used to read the
channel and device word from the thumbwheel switch that corresponded
to the button used for system startup. The RSW instruction was of
much less use at this time.
For the 900 Series, no such toggled register exists.
Applications which use this instruction as a signal must be re-coded
to provide this functionality another way. Using message files and
soft interrupts (which did not exist when the Series II/III were
originally created) can provide this signaling capability. A
description of using message files is documented in the
File System
Reference Manual
, HP Part Number 30000-90236.
Memory Instructions
These instructions all depend upon the fact that the HP3000's memory
was partitioned into banks of 64K words each in an attempt to overcome
the 16-bit address limitation. All are privileged, and most are
typically used only by low level system code.
Code employing any of these instructions will have to be re-examined
and may need re-coding per the recommendations in the previous
discussion titled "The Role of Privileged Mode in SPL Environments".
SPLash! supports LDEA, LSEA, SDEA, and SSEA. The file
MDS.INC.SPLASH
contains details on these instructions.
Hardware Dependent Instructions
These instructions are also
highly privileged. These however, depend upon architectural
features of the MPE V-based HP3000's rather than the memory
structure. Some, such as UNLK and LOCK, were implemented to support
multiple CPU's. Others, such as PSDB, PSEB, DISP, and IXIT interact
with the dispatcher and ICS in a way that is highly specific to the
MPE V-based HP3000's. The dispatcher under MPE/iX is not launched
by microcode (there is none), and therefore these instructions have
no meaning. The others are typically used by low level code in the
operating system kernel. These particular opcodes are not even
simulated by the compatibility mode emulator in MPE/iX.
Code employing any of these
instructions will have to re-examined and re-coded per the
recommendations in the discussion (above) titled
"The Role of Privileged Mode in SPL Environments".
Obsolete Instructions
Be sure to read the discussion titled "The Role of Privileged Mode in
SPL Environments" in this document if you have any of the
instructions listed above in your code. These instructions are all
privileged and fall into the category of instructions that were
implemented for specific HP3000 models. For example, the WIO, RIO,
CIO and TIO instructions only existed on the HP3000 Series II/III.
If code employs these instructions, it is highly specific to
a particular HP3000 series and is not transferable to a newer machine,
much less to an HPPA based Series 900. It is suggested that
migration assistance be employed with this type of code.
Limited Support for XEQ Instruction
The XEQ instruction allows a 16-bit word of data to be loaded on the
stack, then executed by the microcode as a 16-bit HP3000 machine
instruction word. This is useful for a variety of tasks.
However, fully implementing this instruction would require that
SPLash! generate a run-time HP3000 machine code interpreter. On MPE
V-based HP3000's, this interpreter is contained within the system
microcode. No such interpreter exists in HPPA, and it was felt that
the overhead was not a cost effective use of machine resources, given
the number of times this instruction is used.
There exists one fairly common use of XEQ which is to build an EXIT
instruction in a Control-Y handler. On stack-based HP3000's, the
operating system deposits a number of words to delete from the stack
when calling a Control-Y handler. The opcodes corresponding to
the EXIT instruction is placed on TOS, the number of words to
decrement is added to it, and XEQ 0 is executed. For this commonly
encountered case, SPLash! will assume that the procedure containing
the XEQ 0 is a Control-Y handler, and handle the procedure
accordingly. See the section on Control-Y in Chapter 8,
Migration
Issues
, for detailed information.
The native mode (NM) Control-Y handling is much simpler to
program, and is armed with the intrinsic XCONTRAP. Unlike the
standard SPL Control-Y environment,
the NM Control-Y handling portion
of MPE/iX cleans up the stack automatically, removing the burden from
the programmer. It is recommended that the Control-Y handler be
rewritten to take advantage of this superior methodology, and thus
remove the ASSEMBLE(XEQ 0) altogether.
Limited Support for PCAL Instruction
Another commonly used non-privileged instruction is PCAL. The PCAL
instruction has three formats. The `PCAL label' format is used to
perform a PCAL instruction to a specific procedure name. This format
assumes the parameters for the procedure specified in PCAL label have
already been loaded onto the stack. SPLash! fully supports this
format.
The `PCAL n' (n > 0) format is used to call a procedure defined by an
entry in the Segment Transfer Table (STT) for that segment. In this case,
`n' is an index into this table. The STT is a table of 16-bit entries
at the end of every code segment. It has a specific format, and
different formats differentiate between internal and external
procedures. This table is known to the system microcode, and is
therefore tied closely to the hardware. In order for SPLash! to
implement the PCAL n format, it would have to simulate the STT, a
structure which does not exist under MPE/iX. Just like the XEQ 0, it
was felt that the use of this format did not warrant simulating a
structure so closely tied to the microcode of the MPE V-based HP3000.
If this format is being used, the PCAL label format should be
used instead.
A special format for PCAL, PCAL 0, is used when it is desirable to
call a procedure whose identity is not known until runtime.
Typically, the intrinsic LOADPROC is called to bind a procedure in an
SL to the calling program. The LOADPROC intrinsic returns a
procedure label (PLABEL) which is a 16-bit quantity exactly matching
the format of an STT entry.
Implementation of this format would
combine the runtime complexities of interpreting the TOS word (like
XEQ 0) and interpreting the STT format (as with PCAL n, above). PCAL
0 is not implemented by SPLash!, but the functionality of dynamic
procedure loading and calling will be accommodated through a
new type of procedure, OPTION DYNAMIC.
Your application will need to be re-coded to use this new
feature. See the file DYNAMIC.INC.SPLASH for several examples.
Loading & Branching Instructions
This includes the set of instructions which loads words of code onto
the stack and all instructions which can do branches. The LDPP and
LDPN instructions were created to allow constants to be loaded from
code. This is done if a constant in a calculation is greater than 8
bits, in which case an immediate instruction could be used. Because
code is not highly differentiated from data in HPPA, instructions
which specifically load code literals do not exist. SPL code that
uses these assemble instructions should be re-coded to employ a
simple TOS := literal (or constant) statement.
The branching machine instructions absolutely depend upon the 16-bit
orientation of MPE V-based HP3000 instruction words. For example,
the statement BR P+20 branches from the current location to the
location 20 machine instructions away. This could very well be
outside of the assemble statement and in the SPL statements occurring
after the assemble.
There is no problem with the p-relative branch
since in standard SPL, those subsequent
statements are translated into 16-bit machine instructions.
The translation of this 16-bit machine instruction word format is
very difficult in HPPA. For this reason, SPLash! does not attempt to
interpret what would have been generated on a stack-based HP3000.
SPL code that employs p-relative addressing must be changed to use a
branch to a label. For example:
Pushing & Setting Registers
These statements are used to manipulate the registers resident on the
HP3000 processor boards. As with any architecture, the use and
philosophy of the registers describes to a large extent the machine
architecture itself. Since HP Precision Architecture is quite
different than the traditional HP3000 architecture, some of the
registers do not translate well to the new architecture.
In order to simulate the SPL environment, SPLash! maintains simulated
copies of most of the HP3000 registers. Thus, Q, S, Z, and the DL
registers are all available for use by the SPLash! programmer. In
standard SPL, pushing the DB register is a privileged operation. In
addition, it pushes the bank number and absolute offset in the bank
onto the stack. As presented in Discussion 1, these concepts have no
meaning on the 32-bit HP Precision Architecture. Pushing of the DB
register now causes SPLash! to push the 32-bit HPPA register pointing
to the simulated DB area in the SPLash! program's native mode (NM) stack.
Pushing and setting of the Status register is partially supported.
Some of the fields within the status register, such as the "right
bit" (which stackop is being executed) are meaningless in HPPA. The
same is true of the code segment number. The following shows the
status register format on MPE V-based HP3000's with the fields that
are supported under SPLash! when executing the PUSH statement or PSHR
instruction:
MYPIN := ABSOLUTE (3) / %25; << CALCULATE PIN NUMBER >>
/\
PRIVILEGED MODE OPERATION, SEE DISCUSSION 11.
***** WARNING 1: w211 @ 03211100 X.PUB.SPLASH
In this case, the ABSOLUTE construct, which is used to reference bank
0 of memory on an MPE V-based HP3000, is flagged as being
privileged. The discussion on flagged instructions that follows
describes the use of the ABSOLUTE function and why it is not
recommended for use in SPLash!
(top) (index)
The Role of Privileged Mode in SPL Environments
1. Is this functionality still necessary under the MPE/iX software
environment and the Hewlett-Packard Precision Architecture hardware
environment?
If the answer to question 2 is yes, then those small portions of SPL
code which employ PM coding techniques should be rewritten to take
advantage of the new MPE/iX functionality. If the answer is no, then
you may have to work with a migration specialist (perhaps from Allegro or
Hewlett-Packard), to resolve the specific issues encountered in your code
migration.
(top) (index)
Unsupported CM Instructions
LDEA LLSH LSEA SDEA SSEA XCHD
DISP IXIT LOCK PAUS PCN PSDB PSEB
RCLK RMSK SCLK SED SMSK UNLK
CIO CMD HALT RIO SIN TIO WIO
BCC BR LDPN LDPP (and related instructions)
Z
must be changed to:
ASSEMBLE (BR P+20);
.
.
.
I := 4 + J; << P + 20 >>
This code is easily handled by SPLash!, in addition to being far more
readable and maintainable.
ASSEMBLE (BR LAB1);
.
.
.
LAB1: I := 4 + J;
PUSH and SET Statements
PSHR and SETR Machine Instructions
| M | I | T | R | O | C | CC | CST # |
M Set to 0 if NM exec level = 3
Set to 1 if NM exec level < 3
I Always set to 1
T Always set to 0
R Always set to 0
O Set as it would be on an MPE V-based HP3000
C Set as it would be on an MPE V-based HP3000
CC Set as it would be on an MPE V-based HP3000
CST # Always set to 0
Setting of the status register is commonly used for
disabling/enabling arithmetic traps. This functionality is provided
by an intrinsic under MPE/iX, and code which sets the T bit to turn off
traps should be modified to use this method. Overflow, Carry, and
Condition Code can be modified by the programmer and then set. All
other fields are unaffected by the SET or SETR operations.
The CON Construct
The CON construct is partially supported by SPLash!. Using CON in
standard SPL, it is possible to drop any sort of data into the code
stream which is subsequently interpreted by the microcode. The most
common uses for CON are to build PB arrays and to form machine
instructions whose assemble mnemonics are not recognized by SPL.
In the case of using CON to assemble PB arrays, the large code
addressing space of the /iX overcomes some of the shortcomings of PB
arrays in standard SPL. For this reason, any uses of CON for PB
arrays should be removed and the array be re-coded to a standard PB
array declaration.
In the case of CON being used to implement other machine
instructions, this need has been removed by the fact that SPLash!
will now implement the commonly used COBOLII instructions as assembly
opcodes. The opcodes that will be supported by
SPLash! are TR (via two new opcodes: TRDB and TRPB),
ENDP, PARC, XBR (but not EDIT). See the example file
PARC.INC.SPLASH for more information.
LLBL Instruction
Like the PCAL 0 instruction, this instruction relies upon the
hardware dependent Segment Transfer Table (STT),
and is not supported by SPLash!. If it
is being used, the code should be rewritten to use the SPLash!
Dynamic procedure facility.
Flagged Instructions
Most of these privileged instructions are supported by SPLash! to
the same extent that they are supported by the compatibility mode
emulator on MPE/iX. They are flagged here as warnings that the
semantics of their operation may change under MPE/iX. Please refer to
the discussion titled "The Role of Privileged Mode in SPL
Environments". See also the file called
MDS.INC.SPLASH
.
SPLash! can be used to compile standalone programs or individual
modules. The output of a standalone program compilation is a native
mode program file (NMPRG). While the output of an individual module
compilation is a native mode object file (NMOBJ). SPLash! NMOBJs
can call or be called from any other native mode language (except for
procedures that are compiled with the $SPLASH compiler option). The
sections that follow review the various SPLash! UDCs and command
files. Several sample compilations using SPLash! are also
offered.
SPLash! is delivered with two different UDC files which are
located in the SPLASH account: SPLASHU (default) and SPLASHV. Each
UDC file contains several UDCs that can be used to compile, assemble,
or link your SPLash! programs. The default UDCs are
oriented towards program development on the /iX, while SPLASHV UDCs
are similar in function to the SPL UDCS.
By default, the SPLASHU UDCs are cataloged when SPLash! is
installed. Please refer to the HP MPE Command Reference manual for
details on the SETCATALOG command if you wish to modify the
SPLash! UDCs.
SPLASHU.PUB.SPLASH
The UDCs in SPLASHU allow SPLash! programs to be compiled,
assembled, and linked as easily as —
The UDCs in
SPLASHU.PUB.SPLASH
provide quick access to the
SPLash! compiler, but they require that you first define the
specific group structure outlined above and then follow the
conventions for maintaining your source and output files.
If you installed the software using the steps outlined in the
Installation
chapter, these groups will have been created for
you.
Each of the UDCs are described next.
SPLASHU UDC Descriptions
SPLASHU.PUB.SPLASH
contains five UDCs for compiling, assembling,
and linking SPLash! programs, as described later in the chapter.
The UDCs in SPLASHV closely parallel the MPE commands: SPL, SPLPREP,
and PREP. They make no assumptions about naming conventions.
SPLASHV UDC Descriptions
SPLLK
Compiles from <source>, assembles, links; the result is in $OLDPASS.
This section discusses UDC parameters for all of the SPLash! UDCs.
CON (EDIT,TR,ENDP,PARC,XBR)
ABSOLUTE LST MABS MDS MFDS
MTDS PLDA PSTA SST (and more)
(top) (index)
4 Compiling with SPLash!
Overview
SPLash! User Defined Commands (UDCs)
spllk foo ! compile, assemble, link
Or,
splash foo ! compile
asmlk foo ! assemble & link
These UDCs make four assumptions that you must follow:
The "lk" suffix for the names of the two UDCs
which link programs follows the examples of the other
native mode compilers in MPE/iX. The ".O" suffix for the assembler
output was inspired by the C language.
A group called ASM exists which will be
used to hold
the assembler output from the SPLash! compiler.
A group called O exists, which will be
used to hold
the assembled files created by the assembler.
Linked programs reside in the PUB group.
Linking is
produced by using the LINK command.
The file to be compiled is
always
in the current logon group.
SPLLK Compiles from <source>.<logon> to <source>.ASM and then
links to <source>.PUB.
spllk source, parm=0, list=$null, info=" ", priv=3, cap="ia, ba",
arecs=40000, orecs=2000, opt="~"
SPLASH Compiles from <source>.<logon> to <source>.ASM.
splash source, parm=0, list=$STDLIST, info=" ", arecs=40000
ASMLK
Assembles <source>.ASM to <source>.O, then links to <source>.
PUB.
asmlk source, opt=" ", priv=3, cap="ia,ba", list=$NULL, arecs=2000
ASMOBJ
Assembles <source>.ASM to <source>.O.
asmobj source, opt=" ", list=$NULL, arecs=2000
SPLOBJ
Compiles and Assembles from <source>.<logon> to <source>.O.
spllk source, parm=0, priv=3, cap = "ia, ba"
SPLASH
Compiles from <source>, resulting in SPLASSM.
splash source, parm=0, list=$STDLIST, info=" "
ASMLK
Assembles <source> to $NEWPASS, then links $OLDPASS to $NEWPASS.
asmlk source=SPLASSM, opt=" ", priv=3, cap="ia,ba", list=$NULL
ASMOBJ
Assembles <source> to $NEWPASS, for deferred linking.
asmobj source=SPLASSM, opt=" ", list=$NULL
UDC Parameters
| Parameter | Default | Description |
|---|---|---|
| source |   | The name of the file to be compiled or assembled. You must specify this parameter; there is no default value. |
| parm | 0 | This parameter is reserved for use by SPLash! developers. Do not specify a value other than the default. Note that this parameter is different from SPL's parameter of the same name. Unlike SPL, the SPLash! compiler automatically opens the formal files SPLTEXT, SPLLIST, and SPLASSM; you need not specify a compilation parameter to accomplish this. |
| priv | 3 | Specifies the privilege level to be assigned
to your program's outer block. When your program runs, it willautomatically execute at this privilege level. Two values are
allowed: 3 = User Mode 2 = Privileged Mode Values 1 and 0, which represent more powerful privileged modes, are not allowed by Hewlett-Packard. The MPE/iX loader will not load a file linked with privilege level 1 or 0. |
| cap | "ia,ba" | Specifies the capabilities to be assigned to
your program when it executes. When coding this parameter, you must specify one or more of the following capabilities, separated
by commas and enclosed in quotes. ia Process can run interactively. ba Process can run in batch. mr Process can access multiple system resources concurrently. ds Process can create and use data segments. ph Process has the ability to perform process handling. It can control or create other processes and can obtain information about executing processes. pm Process can run in privileged mode (that is, at ring level 2) or can call procedures that run in privileged mode. Note that this is different from the priv parameter, described above, which specifies the default execution mode for a program's outer block. You can specify pm for modules as well as programs; they will not begin executing in privileged mode but will be able to switch to privileged mode execution or to call privileged procedures. |
| arecs | 40000 | Specifies the maximum size, in records, for the intermediate assembler file generated by the SPLash! compiler. If this file is not big enough, the compiler will complete its processing and then issue a message indicating how big the file should be. |
| orecs | 2000 | Specifies the maximum size, in records, for the native mode object (NMOBJ) file that the assembler produces after processing the SPLash! compiler output. In MPE/iX, the NMOBJ file is equivalent to SPL's USL file. |
| opt | " " | Specifies optional text that you wish to pass to the assembler. |
| info | " " | Specifies an optional text string that contains compiler directives. Code one or more compiler control options separated by commas; enclose the list in quotes. (See Chapter 6, Beyond SPL for a list of compiler control options.) Do not include a $ before the first option; the SPLash! compiler will automatically insert this symbol. The compiler will interpret this string as the first line of compiler input. |
| list | $STDLIST | The default for the SPLASH UDCs in both SPLASHU and SPLASHV is $STDLIST, for the other UDCs (e.g. ASMLK, ASMOBJ, etc.) the default is $NULL. |
This section shows, through examples, how to use the SPLash! UDCs to compile, assemble, and link a standalone program. These examples use the UDCs provided in SPLASHU which are described earlier in this Chapter. It may be helpful to review that section if you haven't already done so.
Compiling
Suppose you have created a SPLash! program by entering source code into a file named FOO in your logon group. To compile this program, just type:
splash FOO
The "splash" UDC compiles the source file and generates a file with the same name in your ASM group. This new file, FOO.ASM, contains assembly language code. The listing is routed to $STDLIST. Since no additional parameters are specified, the default values are used, as described earlier in this section. Note that, like SPL, SPLash! produces machine code even if syntax errors are found (although this means that the code generation process might fail).
If you wish to specify parameters, you can do so the same way that you would for any UDC: by coding positional values or by preceding values with parameter keywords. Note that if you use positional values, you must specify values in the proper order and separate them with commas. If you use keywords, you can specify the parameters in any order, but you must separate them with semicolons.
For example, using positional parameter values, you can compile the program FOO using a larger intermediate assembler file and send the listing to a deferred printer by typing:
file defer;dev=lp,1;cctl splash BIGFILE, , *DEFER, , 80000
Or, you can compile the program and suppress the listing, using keyword parameters, by specifying:
splash source=FOO; list=$NULL
If you want to compile a larger assembler file (80000 records), and send the listing to a deferred line printer, you would issue the following commands:
file defer;dev=lp,1;cctl splash source=BIGFILE; list=*DEFER; arecs=80000Assembling & Linking
After successfully compiling the program FOO, you must assemble and link it before executing it. You can use the "asmlk" UDC to assemble from FOO.ASM to FOO.O, then link FOO.O to FOO.PUB, by typing:
asmlk FOO
To assemble FOO.ASM to FOO.O and then link FOO.O to FOO.PUB with privlevel 2 (privlev 2 corresponds to MPE V's PM) you would issue the following statement:
asmlk FOO, , 2
This is the privlevel needed to be able to perform "privileged" operations, like opening a file with a negative file code. Note that the MPE XL loader will refuse to load a file linked with privlev 0 or 1.
Alternatively, you can perform the same steps using the "asmobj" UDC with MPE/iX LINK command using the following statements:
asmobj FOO link from=FOO.O; to=FOO.PUBWhen your program consistently compiles cleanly, you may want to compile, assemble, and link in a single step. To do this, use the "spllk" UDC, which is similar to the SPLPREP command. For example:
spllk FOOThis UDC compiles FOO (in the logon group) into FOO.ASM, then assembles it to FOO.O, then links it as FOO.PUB.
These command files are functionally similar to the compiler command files that HP provides with their compiler products. These command files are located in the PUB group. In order to use these files, you should either move them to PUB.SYS or to a group that is in the path (HPPATH) for SPLash! users.
Like HP's compiler command files, SPLash! command files do not rely on the presence of special groups nor are they limited to compiling files in the current group. There are 4 command files for the SPLash! compiler.
Compilation Command Files
| SPLXL | Compiles SPL source to assembler output file. |
| SPLOBJXL | Compiles SPL source to native mode object file. |
| SPLLKXL | Compiles & Links SPL source to native mode program file. |
| SPLXLGO | Compiles & Links SPL source to $OLDPASS, and then runs $OLDPASS. |
Command File Usage
The contents of command file are listed next.
splxl [text][,[asm]][,[list]][,[info]]
[,[parm]][,arecs]
splobjxl [text][,[obj]][,[list]][,[info]]
[,[parm]][,[arecs]][,orecs]
spllkxl [text][,[prog]][,[list]][,[info]]
[,[parm]][,[arecs]][,[orecs]][,[cap]][,priv]
splxlgo [text][,[list]][,[info]]
[,[parm]][,[arecs]][,[orecs]][,[cap]][,priv]
Command File Parameters
The following list describes each of the parameters used in the command files.
text = Source SPL file asm = Output assembler file, defaults to $oldpass obj = Output native mode object file, defaults to $oldpass list = List file, defaults to $stdlist info = Pass options to SPLash!, default is null parm = Pass parms to SPLash!, default is 0 arecs = Max size of assembler output file, default = 40000 records orecs = Max size of native mode object file, default = 2000 records cap = Capabilities for program file, default=IA,BA priv = Priv level for program file, default = 3 (user)
Note —Detailed information on these parameters is explained in the section called UDC Parameter.
$control subprogram
begin
procedure upshift (text', bytes);
value bytes;
byte array text';
integer bytes;
begin
|
Also, we have a program called UPPER.SOURCE which is:
|
In compiling and assembling a module (i.e., not a standalone program), the SPLOBJ UDC is useful.
The next examples illustrate this process using the UPSHIFT module and the program UPPER.SOURCE for both the UDC and the command file approaches to compilation.
Compiling & Assembling with the SPLash! UDCs
chgroup MODULE splobj UPSHIFT, , , "CONTROL SPLASH"
chgroup SOURCE splobj UPPER
Compiling & Assembling with the SPLash! Command Files
Linking
UPPER.PUB is now compiled, linked, and ready to run.
Running
This section discusses using SPLash! to compile a module
which will be used by another native mode language
program.
Note
—SPLash! prefers to pass its parameters on the
stack via SPL, while most other native mode languages
prefer to pass their parameters in a combination of registers
and the stack.
Unlike other NM languages, SPLash!
generates procedures with either type of parameter passing.
The OPTION SPLASH and OPTION NATIVE syntax is used to
state whether a particular procedure uses stack-based (splash)
or register-based (Native) conventions.
The following example uses the same upshift procedure,
but this time it is called from a Pascal/iX program called
UPPAS.
The UPPAS Source File
splobjxl upshift.module,upshift.o,,"control splash"
splobjxl upper.source,upper.o
link from=UPPER.O, UPSHIFT.O; to=UPPER.PUB
run upper.pub;info="hi there"
Mixed Language Compilations Using SPLash!
$os 'mpexl'$ $type_coercion 'representation'$ |
The following commands prepare and run the program. Note that since we are now calling UPSHIFT from Pascal/iX, which uses the native mode conventions for calling procedures, we must identify UPSHIFT as a native mode procedure. We do this with a $CONTROL NATIVE option on the compile.
Compiling & Assembling with the SPLash! UDCs
chgroup MODULE splobj UPSHIFT, , , "CONTROL NATIVE"
Compiles UPSHIFT.MODULE into UPSHIFT.ASM and finally into UPSHIFT.O, marking all unspecified procedures as native mode callable.
chgroup SOURCE pasxl UPPAS, UPPAS.O
Compiling & Assembling with the SPLash! Command Files
splobjxl upshift.module,upshift.o,,"control native"chgroup SOURCE pasxl UPPAS, UPPAS.O
Linking
link from=UPPAS.O, UPSHIFT.O; to=UPPAS.PUB
Running
run UPPAS.PUB;info="hi there"
This section discusses compiling separate modules with SPLash!
and then calling them from both SPLash! programs and from
other native mode language programs.
In the previous example, if the UPSHIFT routine is compiled as:
Compile UPSHIFT.MODULE into UPSHIFT.O, marking all unspecified
procedures as native mode callable.
Then, it can be easily used by other native mode language programs as shown
earlier. But, it can also be called by SPLash! programs
if the procedure is referenced by specifying "OPTION NATIVE"
in its external declaration:
Calling a Module
chgroup MODULE
splobj UPSHIFT, , , "CONTROL NATIVE"
procedure upshift (text', bytes);
value bytes;
byte array text';
integer bytes;
option external, native, nocc;
(top) (index)
This section discusses concepts used throughout this manual. The information in this chapter will effect how you declare variables, procedures, and intrinsics. A table on SPLash! register usage is included at the end of this chapter.
Alignment
The HP Precision Architecture demands that data is "aligned" to a natural
boundary. This means that a 32-bit data item must start at an
address which is a multiple of 32 bits (or 4 bytes), and so on
for 8, 16, 32, and 64-bit data items.
32-bit aligned
Address of a 32-bit item is a multiple of 4 bytes (or 32 bits).
16-bit aligned
Address of a 16-bit item is a multiple of 2 bytes (or 16 bits).
8-bit aligned
Address of a 8-bit item is a multiple of 2 bytes (or 8 bits).
Unfortunately, a small number of intrinsics have parameters that
must
be 32-bit aligned. One example is the GETHEAP intrinsic.
The by-reference pointer parameter (a 32-bit address) must be
32-bit aligned.
Intrinsic
Passing Parameters
Native-Mode Procedures
Refer to the HP manual
Procedure Calling Conventions Reference
Manual
for a complete description of the parameter passing
convention.
Splash-Mode Procedures
Controlling the Mode with Compiler Options
64-bit aligned
Address of a 64-bit item is a multiple of 8 bytes (or 64 bits).
If a program tries to reference data that is not properly
aligned, an "alignment trap" occurs, and the program is aborted.
Most intrinsics with reference parameters are written to allow
un-aligned parameters. This was necessary to be able to migrate
MPE V programs with data that was only 16-bit aligned to native
mode. One example is the FGETINFO intrinsic. The eleventh
parameter, "eof", is a double (32-bit integer) by reference.
Native mode programs that call FGETINFO to determine the eof of a
file need only pass an address that is 16-bit aligned.
In MPE/iX, an intrinsic is solely and specifically a procedure with a
description in the SYSINTR file or the SPLINTR file. The code for
intrinsics resides in
NL.PUB.SYS
or
SL.PUB.SYS
. Most, but not all,
intrinsics are in the NL with uppercase names. In MPE V, the term
"intrinsic" was used in a looser sense to mean any procedure that was
in
SL.PUB.SYS
, including undocumented and uncallable procedures.
SPLash! provides two different methods for passing parameters
to procedures: native-mode and splash-mode.
You can choose one or the other, depending on
the language used in the calling program and the procedure.
A native-mode procedure expects to receive its first four parameters
in registers and the remainder on the native-mode stack. This
is the protocol used by the MPE/iX languages. For example, all
procedures written in Pascal/iX, COBOL/iX, and FORTRAN/iX are
native-mode procedures. While a native-mode procedure can be called
from either a native-mode or splash-mode procedure, it
can only call other native-mode procedures.
Splash-mode procedures expect to receive parameters via the
SPLash!-supported stack. This is the convention established
in SPL, and SPLash! implements this mode primarily to
maintain backward compatibility with existing SPL applications.
A splash-mode procedure can only be called by another splash-mode
procedure. It can call either splash-mode or native-mode procedures,
however.
SPLash! supports compiler control options that can be
specified at compilation time to determine how the compiled program
or subprogram will be called.
$control internal=native | Indicates that all internal procedures, i.e. all procedures actually coded within the module, are native-mode procedures. (Do not confuse the concept of an internal procedure, as defined above, with SPL's "option internal;". They are not related.) |
| $control external=native | Indicates that all external procedures, i.e. procedures defined with the EXTERNAL procedure option, are native-mode procedures. |
| $control native | Specifies that all
procedures, whetherinternal or external, are native-mode procedures. Specifying this
option is equivalent to specifying: $control internal=native, external=native |
| $control internal=splash | Indicates that all internal procedures splash-mode procedures. |
| $control external=splash | Indicates that all external procedures are splash-mode procedures. |
| $control splash | Specifies that all
procedures, whether internal or external, are splash-mode procedures. Specifying this
option is equivalent to specifying: $control internal=splash, external=splash |
OPTION NATIVE Indicates that you are declaring a native-mode procedure.
OPTION SPLASH Indicates that you are declaring a splash-mode procedure.
You can use one of these procedure options for either external or internal procedures. When you specify the parameter passing protocol with a procedure option, it overrides any compiler control options that you specify at compilation time. For example, if you code a procedure with OPTION NATIVE, it will be treated as a native-mode procedure, even if you specify $CONTROL SPLASH at compilation.
If a particular procedure declaration does not specify "splash" or "native", a default is chosen depending on several considerations. The following table shows the various combinations. Defaults were selected based on how separate compilations would most likely be used.
In the following table, combinations that produce the same results for a given type of compilation are grouped together:
compile unit Int= Ext= external forward actual Note# ------- ---- ---- -------- ------- ------ ----- program (none) (none) native splash splash #1 program splash native native splash splash program splash (none) native splash splash program (none) native native splash splashNote 1: This is the default for programs.
program native native native native native program native (none) native native native
program splash splash splash splash splash program (none) splash splash splash splash
program native splash splash native native #2
subprogram (none) (none) native native native #3 subprogram native native native native native subprogram native (none) native native native subprogram (none) native native native native
subprogram splash native native splash splash subprogram splash (none) native splash splash
subprogram splash splash splash splash splash
subprogram (none) splash splash native native #2 subprogram native splash splash native native #2
Note 2: This combination is not meaningful, as native-mode procedures cannot call splash-mode procedures.
Note 3: This is the default for subprograms.
$control native implies $control internal=native, external=native
$control splash implies $control internal=splash, external=splash
The MPE/iX debugger can be a valuable tool for debugging SPLash! programs.
In order to use the MPE/iX debugger most effectively,
it is very helpful to know how SPLash! uses the native mode registers.
If you are comparing the running of a CM SPL program versus
a SPLash! program with the debugger, prep the CM SPL program
with ZERODB, otherwise the un-initialized areas in the CM
program's stack may contain strange, misleading values.
Specifying the $CONTROL STMT option in SPLash! is vital when using
the debugger to debug a program. This option helps you reference
source lines in the SPL file.
R1 Scratch register. Frequently used to split apart
32-bit words into two 16-bit parts, and to formulate
large constants.
R2 Return Address for procedures.
R3 Occasionally used by SPLash! as a scratch register.
R4 DB emulation (contains 32-bit virtual address).
R5 Q emulation (contains 32-bit virtual address).
R6 S emulation (contains 32-bit virtual address).
R7 X emulation (32-bit signed value).
R8 Condition Code.
A value < 0 means CCL, 0 means CCE, and
> 0 means CCG.
R9 Carry emulation.
Bit 31 is used for "carry", and bit 30 is used for "overflow".
R10 Currently unused.
R11 Pointer to base of "extra" return stack. The 64 bytes
below R11 are used for floating point scratch variables.
The bytes above R11 contain information needed for
returning from procedures and subroutines.
R12 Index pointing to last mini-marker in our extra return stack.
R13..R18 Currently unused.
R19..R26 General registers used to evaluate expressions.
Lower registers are used first.
R27 Native mode Data Pointer (DP). Never altered by SPLash!.
R28 Typically gets result of typed Native-mode procedures.
R29 Like R28, but only used when calling a procedure that
has a functional value of 64 bits.
R30 Native mode stack pointer. In native-mode procedures,
and in splash-mode when TRACEPCAL is set, is bumped up at
the start of a procedure/subroutine and down at end of a
procedure/subroutine.
R31 Holds return address when calling certain
native procedures and millicode.
SR1..SR3 Used in expressions using fullvirtual addresses.
SPLash! tends to use SR1 first, then SR2, then SR3.
Register usage:
R0 Stores unwanted bits in register 0.
(top) (index)
6 Beyond SPL
This chapter describes the ways in which SPLash! extends the basic SPL language to provide complete access to the HP3000. Topics include variable declaration, procedure options, compiler dollar options, AIF usage, and non-local jump constructs.
SPLash! has two additional keywords that can be used to declare variables: VIRTUAL and FULLVIRTUAL. Variables can be declared as normal, or have an optional "virtual" or "fullvirtual" preceding them.
A "fullvirtual" variable is one whose address requires a full 64 bits.
VIRTUAL ( ) and FULLVIRTUAL ( ) accept constants
and expressions. Constants and expressions are evaluated and treated as
16-bit addresses to be converted into 32-bit or 64-bit addresses. If the
constant or expression in the parenthesis is a non-byte expression,
then SPLash! performs a word-to-byte conversion before the 16-bit to
32/64-bit conversion.
Note 1
Converting negative constants or expressions into 32-bit
addresses will not be very useful unless you have set $DL to a
non-zero value.
Note 2
The constant value zero (0) is treated as a special case by
VIRTUAL ( ) and FULLVIRTUAL ( ). The constant zero (0) is treated as
0d by VIRTUAL ( ), and 0L0 by FULLVIRTUAL ( ). All other constants
are
(possibly doubled then) added to R4 to convert them into 32/64 bit
addresses. The special treatment of zero (0) preserves compatibility
with earlier releases of SPLash! which allowed constructs like:
@ptr32 := 0; and @ptr64 := 0;
An example of using FULLVIRTUAL is shown below, comparing it to a
similar Pascal/iX procedure:
Constants
SPLash! accepts the dollar sign as a hex constant specifier.
For example,
$1234 == %(16)1234.
As usual, double
precision is indicated by appending a blank, and then a "d". For
example,
$C0000000 d
.
Parameter Types
Procedures with checkable ANYVAR parameters were passed "4" as the
hidden size value, regardless of the size of the actual parameter.
SPLash! will now pass a size of 1 for simple byte variables/pointers,
2 for logical and integer variables/pointers, 4 for real and double
variables/pointers, 8 for long variables/pointers, and 4 for all
array variables.
Although the ANYVAR parameter type was provided
to CALLING Pascal/iX procedures, a SPLash! procedure with body
code can have ANYVAR parameters, with one limitation: the parameters
cannot be directly accessed (because SPLash! cannot detect parameter
type). Furthermore, an actual parameter passed
to an ANYVAR parameter is always passed as a 32-bit address.
The following code fragment shows an example of using ANYVAR parameters:
SPLash!
procedure twice (x);
fullvirtual double x;
begin
x := x * 2;
end;
Pascal/iX
procedure twice (var x : $extnaddr$ integer);
begin
x := x * 2;
end;
|
DB and Q Addresses
In SPL the maximum DB address directly addressable was
DB+255; in SPLash! it is DB+4095. This area is referred to as the
"Primary DB" area. The total amount of DB storage area available is
65535 bytes.
In SPL the maximum Q address directly addressable was Q+127;
in SPLash! it is Q+4095. This area is referred to as the "Primary Q"
area. Note that SPLash! does not detect overflow of Q-relative
storage.
The following options are all available in the "option" statement
of a procedure declaration.
DYNAMIC
Example:
Procedure hpgetprocplabel (procname, plabel, status,
dummy1, dummy2);
value dummy1, dummy2;
double dummy1, dummy2, status, plabel;
byte array procname;
option external, native, extensible, uppercase;
...
move procname := "-PRINTFILEINFO-";
hpgetprocplabel (procname, plabel, status, 0d, 0d);
if status <> 0d then
quit (1);
@pfi := plabel;
pfi (fid); ! calls the dynamic procedure
EXTENSIBLE
Note 1
—At present, internal native-mode procedures declared
with "option extensible" will correctly address their
parameters. This is an oversight on our part in not providing you
a way to declare and code a native-mode
extensible procedure as well as simply call existing ones.
Note 2
—Currently, "extensible" also implies that parameters
may be omitted. If you want to omit parameters,
specify extensible
and
variable.
EXTERNAL
FORWARD
INTERNAL
INTRINSIC
NATIVE
Note
—SPLash! provides "option variable,intrinsic" to simulate
the way PASCAL/iX implements intrinsics with optional parameters. When
invoked, the statement "option variable,intrinsic" tells SPLash!
that the callers of this procedure may omit parameters, however the
"intrinsic" flag tells SPLash! that they should not pass the
hidden parameter mask at Q-4.
SPLash! recognizes all of the compiler control statements of
SPL as well as a number of new options.
SPLash! allows multiple dollar options on a single line. The
word "CONTROL" is optional and all types of compiler options may
be intermixed on a single line. For example, the following code
segments are equivalent:
With the exception of quoted string parameters, options must be
complete on a single line of input. Options using quoted
strings (e.g., COPYRIGHT or TITLE) can be continued on subsequent
lines terminating all lines but the last with an ampersand (&).
If SPLash! is run with an INFO parameter, that text is used as the
initial dollar options.
Currently, SPLash! limits the INFO string to 72 bytes. If SPLash!
detects more than this amount, a warning is generated.
Examples of running SPLash! with an INFO parameter are:
Or,
If
SPLASHG.PUB.SYS
does not exist, no error message is given and no
extra output appears on the compilation listing. However, if
SPLASHG.PUB.SYS
exists, then the records will be listed just as any
other $INCLUDE file records would be listed (assuming $LIST is in
effect).
SPLASHG.PUB.SYS
may be file equated to a different file.
During SPLash!'s first pass it looks at the INFO string for the
option "NOSPLASHG". If the option isn't found, SPLash! opens and
parses the option list in
SPLASHG.PUB.SYS
. Next, the INFO= string is
parsed. After SPLASHG and INFO= are parsed SPLash! proceeds with
processing the remaining code in the source file. Knowing the order
in which SPLash! processes allows you to keep your "standard"
options in SPLASHG, and then override them with INFO= when necessary.
This section lists each option. Descriptions, syntax, and examples
are included as needed.
In showing the syntax of the options, brackets ([ ]) enclose
optional parameters. Braces ({ }) enclose a list of parameters
from which exactly one choice
must
be made. Most options may be
preceded with "[NO]" at the start of the option name.
For example:
$NOASMCOMMENTS ! No comments in .ASM output file.
In some of the options the phrase "at the end of compilation" is
used. This means: "as of the time when the final END. is read.".
Comments in the form of "<<....>>" are allowed in compiler option
lines. Comments of the form "!" throw away the rest of the
option line.
Because SPLash! accepts multiple options on a single line, all
options are listed below in a single alphabetic list, even though
the SPL manual would have grouped "CONTROL" options separately
from options like "IF" and "PAGE".
The ADDRARITHMETIC compile $ option is used to tell SPLash! how to
interpret address arithmetic. By default, SPLash! allows all forms of
address arithmetic. When you use SPLash! to migrate to native mode,
using the ADDRARITHMETIC=WARN option setting can be very helpful in
identifying questionable uses of address arithmetic.
=ALLOW
virtual integer pointer vip;
@vip := @vip + 1; ! BAD, no warning/error
$addrarithmetic = warn
@vip := @vip + 1;
CHECK ADDRESS ARITHMETIC: NATIVE ADDRESSES ARE BYTE-ORIENTED
***** WARNING 1: w340 @ 00016000 T.TEST.SPLISH
@vip := @vip + 1;
ADDRESS ARITHMETIC HAS BEEN DISALLOWED BY $ADDRARITHMETIC=ERROR
***** ERROR 1: e226 @ 00025000 T.TEST.SPLISH
$ADR
$ALIGN
The following example illustrates before and after results from using
the $ALIGN option.
First, run SPLash! without specifying $ALIGN. This is the same
as running SPLash! with $NOALIGN. SPLash! defaults to $NOALIGN.
R#0 $map
R#1 begin
R#2 byte var1;
R#3 long var2;
R#4 byte var3;
R#5 integer var4;
R#6 byte var5;
R#7 double var6;
R#8 end.
Generating: Node # @ Seq # AsmLine#
Outer Block: 32 @ 8 21
Byte
Name Address# Type/Value
--------------- -------- ----------
VAR1 DB+ 0 byte
VAR2 DB+ 2 long <-- not aligned
VAR3 DB+ 10 byte
VAR4 DB+ 12 integer
VAR5 DB+ 14 byte
VAR6 DB+ 16 double <-- not aligned
No errors, no warnings
DB storage = 10 halfwords (20 bytes) <-- SPLash! reports DB used
Unaligned DB = 3 variables <-- SPLash! informs user of
unaligned variables in
DB area.
:splash svar;info="map,mapbyte,align"
R#0 $map,align
R#1 begin
R#2 byte var1;
R#3 long var2;
R#4 byte var3;
R#5 integer var4;
R#6 byte var5;
R#7 double var6;
R#8 end.
Generating: Node # @ Seq # AsmLine#
Outer Block: 32 @ 8 21
Byte
Name Address# Type/Value
--------------- -------- ----------
VAR1 DB+ 0 byte
VAR2 DB+ 8 long <-- 32 bit aligned
VAR3 DB+ 16 byte
VAR4 DB+ 18 integer
VAR5 DB+ 20 byte
VAR6 DB+ 24 double <-- 32 bit aligned
No errors, no warnings
DB storage = 14 halfwords (28 bytes) <-- SPLash! reports DB used
DB ALIGN waste = 4 halfwords (8 bytes) <-- SPLash! shows DB wasted
due to the use of the
$ALIGN compiler option.
Note
—In many cases, using the $ALIGN option has the same
effect on code generation.
When turned off (NOALLOCQ), SPLash! will assume that all local
variables have their storage space allocated by SPLash!, and not by
the user. This allows a small speed gain for many procedures.
The following code will
not
work correctly when NOALLOCQ
is used:
Note
—This option is conceptually different
from the $BIGCOMPILE$ control of Pascal/V, which primarily affects
the compiler's ability to ACCEPT large programs.
The types of breakpoints that can be requested are:
DEBUG/iX B.57.06
DEBUG Intrinsic at: 358.00007004 ?$START$
$1 ($3f) nmdebug > trap list <-- Shows TRAP status
XLIBRARY DISABLED
XARITHMETIC DISABLED
XSYSTEM DISABLED
XCODE DISABLED
BRANCH_TAKEN DISABLED
BEGIN_PROCEDURE DISABLED
END_PROCEDURE DISABLED
LABELS DISABLED
STATEMENTS DISABLED
ENTER_PROGRAM DISABLED
EXIT_PROGRAM DISABLED
$2 ($3f) nmdebug > trap trace_all arm <-- ARM all program-related traps
$3 ($3f) nmdebug > trap <-- Same as TRAP LIST
XLIBRARY DISABLED
XARITHMETIC DISABLED
XSYSTEM DISABLED
XCODE DISABLED
BRANCH_TAKEN DISABLED
BEGIN_PROCEDURE ARMED
END_PROCEDURE ARMED
LABELS ARMED
STATEMENTS ARMED
ENTER_PROGRAM ARMED
EXIT_PROGRAM ARMED
$4 ($3f) nmdebug > trap trace_all disarm <-- Disarm program related
traps
$5 ($3f) nmdebug > trap <-- Same as TRAP LIST
XLIBRARY DISABLED
XARITHMETIC DISABLED
XSYSTEM DISABLED
XCODE DISABLED
BRANCH_TAKEN DISABLED
BEGIN_PROCEDURE DISABLED
END_PROCEDURE DISABLED
LABELS DISABLED
STATEMENTS DISABLED
ENTER_PROGRAM DISABLED
EXIT_PROGRAM DISABLED
$6 ($3f) nmdebug > continue
Use "help trap" at the debug prompt for more information on the trap command.
When a breakpoint is encountered, the code will be trapped by the
operating system. If the specific type of breakpoint encountered is
"armed" for the process (by the debugger), then the debugger
is entered, otherwise execution resumes at the next instruction.
When CARRY = DETECT, the SPLash! compiler emits code that
properly sets or clears the carry bit after arithmetic operations or
type transfer functions.
Example: CARRY generation can be requested by doing the following.
$CARRY = DETECT
I := INTEGER (D);
$CARRY = IGNORE <<if desired>>
Note
—Unless your program really checks CARRY, choose
$CARRY=IGNORE. This is the default setting. Using $CARRY=IGNORE saves
several instructions for every statement that would generate a CARRY
change.
The following example shows the effects of these options. Implied in
this example is that each procedure declaration is followed by a
"body" or by an "option external".
Procedure Return Status Example
$nocc
procedure p5; no
procedure p6; option nocc; no
procedure p7; option intrinsic; no
procedure p8; option nocc, intrinsic; no
$cc
procedure p9; yes
procedure p10;option nocc; no
procedure p11;option intrinsic; yes
procedure p12;option nocc, intrinsic; no
Note
—The twelve examples noted above show that the
"option intrinsic" has no effect on the CC option. It also
demonstrates that NOCC can override $CC, which is the default
setting.
Options & Intrinsics Example
The next example shows that $CC and $NOCC have no effect on intrinsics.
intrinsic binary; yes
intrinsic debug; no (Special case. See Note)
$noccintrin no
intrinsic ctranslate;
$ccintrin, nocc
intrinsic fopen; yes
Note
—Intrinsics that have "special case" code which turns off
condition-code fetching automatically include the following. In
previous versions of SPLash!, only DEBUG contained the special case code.
DEBUG HPCIGETVAR HPDEVCONTROL HPERRREAD
HPCICOMMAND HPCIPUTVAR HPERRDEPTH QUIT
HPCIDELETEVAR HPDEBUG HPERRMSG TERMINATE
CLEANFOR results in significant speedups for FOR loops and is the
default value used by SPLash!. If a program is compiled that
contains a FOR loop which alters the FOR loop control values, then
NOCLEANFOR should be used. In this case, SPLash! will emit extra
code. The FOR loop will execute properly, but slower than it would
otherwise.
FOR loops whose counter variables are of type logical or
double (two SPLash! extensions) are always considered to
be clean for loops.
The desired result is to pick up one byte from ba (4).
Instead, SPLash! picks up one byte from ba (65540).
This happens because we coerced the "-2" into 65534, or $fffe.
A simple patch to the SPLash! compiler to drop the coercion would
have created a bug in the code emitted for:
double (six +
-2)
and would have resulted in a very large negative number.
When $COERCE is selected (default), and SPLash! sees an apparently
negative constant which is being coerced to a logical, warning
#68 will be emitted:
POSSIBLE NEGATIVE CONSTANT COERCED TO LOGICAL
When $NOCOERCE is in effect, and SPLash! sees an constant
(signed or unsigned) used in a dyadic expression with
a logical variable, it will leave it classed as an integer.
For example:
For information about the debugger, run SPLash! interactively
and ask for debugger help as follows:
Note that SPLash! emits much faster code when no DL-DB area is
being used.
Examples:
BATCH True if compiling from a job
INTERACTIVE True if compiling interactively
OLDREALS True if $OLDREALS is in effect
SPLASH True, always
XOLDREALS \ These options exist to maintain backward compatibility
XSPLASH / with previous versions of SPLash!. They are synonyms
for the OLDREALS and SPLASH options.
In addition, $ENDIF and a limited $ELSE are supported. An example
of this would be the following.
SPLash! also generates a warning if a $IF or a $ELSE statement is
found outside of a $IF block. SPLash!, like SPL, does not
support nested $IFs. Therefore, a $ELSE is allowed only if it comes
after a "$IF ...", and no intervening $ELSE or $ENDIFs have occurred.
Likewise, if the compilation ends while a $IF is in effect, SPLash!
generates a warning to that effect.
Note
—"internal" is quoted to differentiate it from the "option
internal" concept.
This option is generally used only with SPLINTR- format files.
The following example illustrates compiling and linking with
$MILLIMOVE, $MILLISCAN, or $FASTMOVE. Note that $FASTMOVE can only be
used for non-overlapping moves.
Otherwise, it is equivalent to:
The NEWDLDB addressing model places negative addresses at their
unsigned equivalent address. In other words, half-word address
-1 would be at 32767, -2 would be at 32766, etc. Byte address -1
would be at byte 65535, -2 would be at 65534, -40000 would be at
25536, and byte address -65536 would be at 0.
Thus, no sign extension or tricky code is necessary to convert
DB-relative byte addresses to 32-bit virtual addresses. SPLash!
simply adds the 16-bit value to R4. For half-word addresses,
the bottom 15 bits are multiplied by 2 and added to R4.
NEWDLDB solves the problem of accessing bytes with addresses above
32767, but at the cost of introducing a problem with programs that do
strange address comparisons. With NONEWDLDB, a negative byte address
will compare LESS than a positive DB byte address. With NEWDLDB, the
comparison will be the opposite. Using NONEWDLDB, a user could count
on being able to SCAN a byte address that was below DB and eventually
encounter DB+0 (and the positive addresses). With NEWDLDB, the same
code would scan off the end of the SPLash! stack and never hit DB+0.
If a program has a large stack
and
is compiled with the DL=#
directive, where "#" is not 0, then NEWDLDB may provide the key
to a successful program.
Procedure Options
Allocates a 32-bit storage cell to hold a plabel. When
a procedure marked "option dynamic" is called, SPLash!
fetches the plabel from the storage cell and executes a
dynamic procedure call on it. This is a high-level
replacement for the "assemble (pcal 0)" construct.
...
double
plabel,
status;
byte array
procname (0 : 64);
...
procedure pfi (fid);
value fid;
integer fid;
option dynamic, native, nocc;
The Dynamic option was a necessary enhancement to allow
the dynamic calling of native-mode procedures, since
(unlike SPL) SPLash! needs to know the exact calling
sequence of a native-mode procedure to pass the parameters
correctly.
The Extensible option tells SPLash! to pass a "hidden"
first parameter to the (native-mode) procedure which
is the parameter number (1-based) of the last valid
parameter of each procedure call.
For example, a call on HPFOPEN with 6 parameters would pass
a hidden "6" in register 26.
As in SPL.
As in SPL.
As in SPL (inhibits exporting of procedure name).
Intrinsic is a (temporary) kludge option. An external
native-mode variable procedure that is also marked as
"intrinsic" will not have a parameter mask passed as a
hidden first parameter. "Intrinsic", along with
variable and extension provides the following combinations:
Goal Options needed Pass parameter mask (via SPL) Variable Omit parameters. Don't pass mask. See VARIABLE. Variable,Intrinsic Omit parameters, and pass # of parameters Extensible
At present, omitted parameters default to 0 (with the
exception of about 24 intrinsics that have non-zero
default values.)
For splash-mode procedures, the Variable option behaves
like SPL. For Native-mode procedures, a parameter
mask is passed only if the procedure was not declared as
"option intrinsic".
SPLash! Compiler Dollar Options
$control segment = foo, errors = 9
$set x9 = on
$if x4=on
$ control list
$if
Or,
$segment=foo, errors = 9, x9=on, if x4=on, $list, $if
In a multiple-option statement, dollar signs ($) are treated like
commas (,).
Dollar Options: INFO parameters and SPLASHG
:run splash.pub.splash;info="control dl=0"
:run splash.pub.splash;info="dl=0, list, set x9=on"
In addition to using an INFO parameter to pass dollar options to
SPLash!, dollar options may be placed in the file
SPLASHG.PUB.SYS
("G" stands for Global). If
SPLASHG.PUB.SYS
exists, then SPLash!
automatically uses its contents as input. Using SPLASHG provides a central
location for placing site-wide, common directives.
Dollar Options: Reference Listing
At the end of this chapter you'll find a table summarizing
the default value and functionality for each dollar control option.
No warnings or errors are generated when SPLash! compiles address
arithmetic statements. This is the default addrarithmetic value.
=WARN
SPLash! generates a warning (#340) when it compiles expressions
of the form:
=ERROR
@variable + expression
@variable - expression
expression - @variable
expression + @variable
This warning is useful if @variable is a native address and
"variable" is a non-byte oriented variable (e.g., integer pointer).
Such address arithmetic is best done by using subscripting, which
works in SPL as well as in SPLash!, and does not rely on the
size of an integer being "1" (SPL) or "2" (SPLash!, native
addresses).
SPLash! generates an error (#226) when it compiles expressions
of the form:
@variable + expression
@variable - expression
expression - @variable
expression + @variable
Due to the SPLash! scanner structure, two error messages will be
displayed. The first refers to the address arithmetic. The second,
which is somewhat misleading, states
TYPE INCOMPATIBILITY
.
Example:
$addrarithmetic=allow
ADR causes SPLash! to report the DB / Q / S relative
address assigned to each variable as the variables are
declared. ADR also displays the addresses of parameters to native mode
procedures (the parameters known at the time of entry).
The format for the ADR output differs from that generated in SPL.
An example for ADR output is listed next.
R#1 $control native
R#2 $control adr
R#3 begin
R#4 integer i,j,k,l,m,n;
******** I DB+ 0 ($0000, %000000)
******** J DB+ 1 ($0001, %000001)
******** K DB+ 2 ($0002, %000002)
******** L DB+ 3 ($0003, %000003)
******** M DB+ 4 ($0004, %000004)
******** N DB+ 5 ($0005, %000005)
R#5
R#6 intrinsic print;
Parameter @ Location
--------------- ---------
Parm#1 @ R26
Parm#2 @ R24
Parm#3 @ R23
R#7 intrinsic createprocess;
Parameter @ Location
--------------- ---------
Parm#1 @ R26
Parm#2 @ R25
Parm#3 @ R24
Parm#4 @ R23
Parm#5 @ PSP-$0034
R#8
R#9 procedure proc1(ii,jj,kk,ll,mm,nn);
R#10 integer ii,jj,kk,ll,mm,nn;
R#11 begin
Parameter @ Location
--------------- ---------
II @ R26
JJ @ R25
KK @ R24
LL @ R23
MM @ PSP-$0034
NN @ PSP-$0038
R#12 2 integer my'i,my'j,my'k;
******** MY'I Q + 1 ($0001, %000001)
******** MY'J Q + 2 ($0002, %000002)
******** MY'K Q + 3 ($0003, %000003)
R#13 2 end;
R#14
R#15 proc1(i,j,k,l,m,n);
R#16 end.
ALIGN tells SPLash! to allocate 32-bit and 64-bit variables on 32-bit
boundaries rather than on 16-bit boundaries. This
applies to outer-block variables and 32 bit variables in
native mode. Using this option can
significantly reduce the number of instructions required to load and
store 32-bit and 64-bit variables.
:splash svar;info="map,mapbyte"
Now, run SPLash! with the $ALIGN compiler option.
$ALIGNED32
If ALIGNED32 is true at of the end of compilation, then
SPLash! assumes that the addresses of all 32-bit variables are
32-bit aligned. Then, instead of emitting a three opcode
sequence to load or store to such a variable, a single LDW or
STW is emitted.
$ALIGNED32ALL
If ALIGNED32ALL is used with $ALIGN, all outer block arrays
(virtual and non-virtual) and all native-procedure arrays
(virtual and non-virtual) will start at those addresses with
a virtual-address of a multiple of at least 4.
$ALLOCQ
When selected (ALLOCQ), SPLash! will not assume that all procedure
local-variables are allocated storage space in a clean manner. This
means that SPLash! will emit extra instructions than would have
been necessary in a cleanly coded program.
integer year;
procedure dumb;
begin
double time = q + 1;
integer date = q + 3;
tos := clock; ! allocates q+1, q+2
tos := calendar; ! allocates q+3
year := calendar.(00:07);
end;
$ALLOWBYTES
If ALLOWBYTES is on at end of compilation, then byte-pointer and
byte array parameters are
not
half-word aligned when passed into
procedures, as they would be on MPE V/E (or when NOALLOWBYTES is
in effect).
$ASMCOMMENT
ASMCOMMENT controls whether or not SPLash! emits comments
along with the generated assembler code. If NOASMCOMMENT
is in effect at the end of the program, then no comments will
be generated. When comments are being generated, the summary at the end of
compilation will list the number of comment lines in the assembler output
(as opposed to code (optionally) plus comments).
$ASMCOPYRIGHT
ASMCOPYRIGHT controls whether or not SPLash! emits $COPYRIGHT and
$VERSION strings into the assembler output.
$BASE = {8, 10, 16}
$BASE = {OCT, DEC, HEX}
Sets the desired output base for use in debugging output.
This option effects listing output when $ADR and $MAP are used.
$BIGDIRECT
When selected, $BIGDIRECT tells SPLash! to allow direct arrays to be
any size up to 32767 halfwords rather than the SPL limit of DB +
4095 halfwords of direct storage.
$BIGPROGRAM
When selected, $BIGPROGRAM allows SPLash! to emit slightly longer
code sequences for branches, enabling very large programs to be
compiled. If SPLash! detects large IF and WHILE statements during
compilation, it will suggest that you enable $BIGPROGRAM.
(top) (index)
$BREAK = {ALL, ENTER, EXIT, FORMAL, LABELs, NONE, STMT, STUBs, SUBRs}
BREAK tells SPLash! to emit breakpoint instructions at specified
places in the code. NOBREAK tells SPLash! not to emit breakpoint
instructions. The values in effect at the end of compilation are the
values used. Breakpoints can be used in conjunction with Debug/XL's
TRAP command. They DO significantly slow a program's execution, so
they should be used only while debugging.
ALL Sets/resets all of the breakpoint types. BREAK=ALL sets all breakpoint types.
NOBREAK=ALL resets all breakpoint types. ENTER Procedure entry. A breakpoint instruction is emitted as the first instruction of every
procedure.
EXIT
Procedure exit. A breakpoint instruction is
emitted as the first instruction of the procedure
exit code of every procedure.
Note —"return"
statements, "exit" opcodes, and "falling off"
the end of a procedure all go through common
exit code. FORMAL
Causes SPLash! to emit a "label" breakpoint at the start of
the code emitted for a "go <formallabel>" statement.
A "proc exit" breakpoint is still emitted just before the
BV instruction for a formal goto if BREAK=EXIT is requested. LABEL
A breakpoint is emitted at every label used by
the programmer. (i.e., labels generated by the
compiler are not included.) NONE
BREAK=NONE suppresses all breakpoints. NOBREAK=NONE
selects all breakpoints. (NONE is the opposite of
ALL.) STMT
Statement. A breakpoint instruction is emitted
at the start of every SPLash! statement. STUB
Stub code. A breakpoint instruction is emitted
at the start of every native-mode stub SPLash!
emits. (Native-mode stubs are used to translate
from stack-based parameters to the native mode
register/stack based parameters.) SUBR
Subroutine entry/exit. A breakpoint instruction
is emitted at the start and exit of every subroutine.
Note
—the breakpoint emitted at the start is a
"proc enter" breakpoint, and the breakpoint emitted
at the exit is a "proc exit" breakpoint.
Once a SPLash! program (or subprogram) is compiled with
breakpoints (and linked), the breakpoints can be used by
doing the following:
run program;debug
$CARRY = {DETECT, IGNORE}
CARRY is maintained in register R9. Bit 31 is used to remember CARRY.
When CARRY = IGNORE, the SPLash! compiler ignores the influence of
any operation (arithmetic or other) on the setting of the carry bit,
with the exception of the SCAN statement.
$CC
If NOCC is set when a procedure declaration is recognized by SPLash!, then
an implicit "option nocc" is added to the procedure's header.
If CC is set (default) when a procedure declaration is seen,
and if no "option nocc" is seen, then the procedure will generate
code to pass back the condition code via the simulated status
register. $CC and $NOCC do not affect intrinsic declarations.
$CCINTRINS
This option changes the effect of $NOCC and $CC. In prior versions of
SPLash!, $NOCC affected both procedures and intrinsics. Now, $NOCC
and $CC affect only those procedures declared with the keyword
"procedure". CCINTRINS affects only those intrinsics declared
via the "intrinsic" keyword. By default, almost all of the intrinsics
will have the CC flag enabled.
! returns CC?
procedure p1; yes
procedure p2; option nocc; no
procedure p3; option intrinsic; yes
procedure p4; option nocc, intrinsic; no
$ccintrin ! the default ! returns CC?
$CHECKSTACK
This option adds checking code to the runtime stack which
calls the QUIT intrinsic if an overflow or underflow condition
is detected. To operate correctly, CHECKSTACK must be linked
with CHECKSP.O.
$CLEANFOR
CLEANFOR tells SPLash! that all FOR loops are "clean". A clean FOR
loop is one that does not index into the stack. Likewise, it does not
change the FOR loop limit value, increment value, or counter address.
$CODE
Accepted, has no affect in SPLash!
$COERCE
When $COERCE is selected, untyped constant numbers (e.g., 2, -2)
used in dyadic expressions with a variable (e.g., FOO + -2)
are automatically coerced to the same type as the variable.
This is correct in most cases, but because SPLash! emits code
to evaluate 16-bit expressions using 32-bit registers, a
problem arises when emitting code for expressions where
constants with a "-" are used. The following example, which
works in SPL ONLY because the logical add operator (LADD)
never causes an overflow, will not work correctly in SPLash!
when COERCE is on:
byte array ba (0:9);
logical six := 6;
ba := ba (six + -2);
Note that this message might appear twice due to a quirk of
SPLash!'s parsing. However, code will be emitted as before.
$COPYRIGHT "text"
Use of the copyright command will cause "text" to be inserted into
the NMOBJ and NMPRG files. COPYRIGHT emits a ".COPYRIGHT" assembler
directive for the first line of text (the assembler limits us to
emitting only one line of copyright text of about 60 characters, the
rest of the copyright text is emitted with assembler ".VERSION"
directives). This command must precede the outer block BEGIN
statement.
$copyright "Copyright 1987 Allegro Consultants, Inc." &
$ "Allegro MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS" &
$ "MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES" &
$ "OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE."
$CSTRINGS
In a future release, this option will allow C style strings.
$DEBUG [debugger command]
If any text follows the "$DEBUG", it is passed to the SPLash!
debugger, executed, and compilation continues. If no text is
present, the debugger is entered and will prompt for input.
In the latter case, the debugger can be exited by typing "/"
or "Exit". Other SPLash! compiler options should not be on the same
line as the $debug option.
run splash.pub.splash
$debug
help
abort
$DEBUGATEND
If DEBUGATEND is true at the end of compilation, it invokes
the SPLash! debugger after generating code.
$DEFINE
Accepted, has no affect in SPLash!. In SPL, the DEFINE
option told the compiler to store the text of "defines" in
a file, not in the stack. This option was used to compile very
large SPL programs. SPLash! always stores the text of defines
outside of its stack.
$DIRECT
DIRECT tells SPLash! to allocate arrays as direct arrays, even
if the "=DB" or "=Q" option was not specified. NODIRECT (the
default) causes SPLash! to obey the normal rules for making
arrays direct or indirect. DIRECT/NODIRECT may be intermixed
at will. Whenever an array declaration is compiled, the last
seen DIRECT/NODIRECT will be used.
$DL = #
Controls the initial (and maximum) size of the DL area for
SPLash! SPLash! will use the largest value seen during a
compilation. The # is the number of half-words (16-bit
words) that should be allocated below DB for DL-DB
addressing. The maximum value is 32767.
$ECHO "text"
The text string will be echoed to $STDLIST via the PRINT
intrinsic.
$EDIT
The $EDIT commands of SPL have not been implemented.
No other compiler options may follow EDIT.
$ERRORS = #
Sets the maximum number of errors allowed during compilation to #. If
# is exceeded, then the compilation terminates. The default is 100.
$EXTERNAL = {SPLASH, NATIVE}
EXTERNAL specifies the default mode of external procedures.
If a procedure is declared as "option external" with
neither SPLASH nor NATIVE being specified, then its mode is
derived from the EXTERNAL= option. This is covered more
fully in the chapter on separate compilation.
$FASTMOVE
Used with $MILLIMOVE to tell SPLash! that MOVE instructions
that follow will not have overlapping source and target
addresses. See $MILLIMOVE for an example.
$FEATURE = {ALLOCQ, CLEANFOR, OPTMOVE, NEWDLDB}
Broken into separate dollar options. (See ALLOCQ, CLEANFOR, OPTMOVE,
and NEWDLDB.)
$FOLLOW = #
$NOFOLLOW
FOLLOW= causes SPLash! to report compilation progress to
the system console every # lines. As a special case, if #
is 0, then SPLash! reports as it starts compiling every
procedure. Progress is reported via the PRINTOP intrinsic.
$GENCODE
If GENCODE is not selected at the end of compilation, then machine
code will not be emitted.
$GENSTAT
If GENSTAT is selected when the "end." statement is detected, then
SPLash! will report its progress in generating code. If NOGENSTAT is
in effect, then the progress reports will be suppressed.
$HARDWARN
If HARDWARN is selected, then all non-suppressed warnings are
treated as errors.
$IF X# = {ON, OFF} THEN
$IF
The IF command is supported as in SPL. Additionally,
compiler options may follow a $IF on the same line, including a
terminating $IF. In SPL anything after the "on" (or "off")
was ignored by SPL. SPLash! doesn't ignore extra text
after the "on" or "off" because it supports limited "OR" and "AND"
capability.
$if x1 = on $list $if
$if x1 = on then
Other options accepted with the IF command include the following.
$if <option> [ <OR | AND> <option> ]
Where option can be one of the following:
X# = ONE
X# = OFF
$IF X1 = ON
...
$ELSE
...
$ENDIF ! or simply, $IF
$IMPORTDB
IMPORTDB is used to tell SPLash! that a native-mode procedure
within a subprogram compilation will be called (directly or
indirectly) from a SPLash! program. IMPORTDB causes such calls
to "import" the SPLash! DB register, which allows these procedures
to access the global variables of the SPLash! program.
NOIMPORTDB tells SPLash! to simply "build" a new DB register
at procedure entry time.
$INCLUDE filename
INCLUDEs may be nested up to 127 deep. QEDIT files are
acceptable, as well as "flat" files, KSAM files, and HFS filenames.
No further compiler options may follow the include filename
on the same line.
$INFO
INFO causes the compiler to emit code that
grabs the INFO string and PARM value via the GETINFO intrinsic
and put the data on the SPLash! emulated stack, just as in MPE V.
NOINFO suppresses this code. When NOINFO is in effect, outer block
variables equated to Q-4, Q-5, and Q-6 are not very useful.
$INNERLIST
If INNERLIST is true at the end of compilation, then the
assembly code generated will be sent to SPLLIST (list file) as well as
to the SPLASSM (Assembler file) file.
$INTERNAL = {SPLASH, NATIVE}
INTERNAL specifies the default mode of non-external
procedures. If an "internal" procedure is declared with
neither SPLASH nor NATIVE being specified, then its mode is
derived from the INTERNAL= option. This is covered more
fully in the chapter on separate compilation.
$LINES = #
$NOLINES
As in SPL, except NOLINES disables pagination completely.
$LIST
As in SPL, except it can be overridden by NEVERLIST.
$LOWERCASEINTRINS
Controls the case of the external names of any intrinsics
declared after this option is detected. If LOWERCASEINTRINS
is selected, then the intrinsics are assumed to have lowercase
external names.
$LOWERCASESEARCH
Tells SPLash! that intrinsic file procedure names
in the SYSINTR- format should be downshifted to lowercase.
$MAIN = "program name"
MAIN is used to define a program name that will be printed
at the top of every page of compiler listing.
$MAP
If MAP is true at the end of compilation, a sorted symbol
table will be produced. The compiler option BASE can be used to
change the RADIX of offsets generated by MAP.
$MAPBYTE
MAPBYTE causes $ADR and $MAP to report BYTE offsets from
DB and Q (instead of half-word offsets like SPL).
$MPE "text"
The MPE command executes the specified text as an MPE command,
by passing it to the COMMAND intrinsic. If an error occurs,
it will be reported to $STDLIST. This command is useful at
the end of a compilation:
$mpe "TELL MGR.SPLASH; Hit the end of the source file"
$MILLIMOVE
NOMILLIMOVE causes MOVE statements and expressions to compile into
inline code. If MILLIMOVE is true, then MOVE statements and
expressions will compile into calls to the SPLash! "move" millicode.
The object file containing the "move" millicode is MOVEO.MILLI and
must be linked into the final program file.
splobjxl testprog info="millimove,milliscan,fastmove"
link from=$oldpass,moveo.milli.splash;to=testprog.pub
$MILLISCAN
NOMILLISCAN causes SCAN statements and expressions to compile
into inline code. If MILLISCAN is true, then SCAN statements and expressions
will compile into calls to the SPLash! "scan" millicode.
The object file containing the "scan" millicode is MOVEO.MILLI
and must be linked into the final program file. See $MILLIMOVE for an
example.
$NATIVE
If NATIVE is true, then this is equivalent to:
$CONTROL INTERNAL=NATIVE, EXTERNAL=NATIVE
$CONTROL INTERNAL=SPLASH, EXTERNAL=SPLASH
$NATIVEONLY
This option must occur before the first BEGIN.
$NEGX
NEGX tells SPLash! that the index register X may contain
negative values. NONEGX tell SPLash! that the index register
will never have a negative value in it. NONEGX saves one
instruction every time an array is indexed with a 16-bit
signed integer.
$NEVERLIST
If NEVERLIST is true, then listing lines are suppressed
regardless of the setting of LIST.
$NEWDLDB
The NEWDLDB feature, which is initially deselected, tells SPLash! to use
the "new" model for DB-negative addressing. In the
default mode (the original implementation), DL-DB addresses
are located below DB (or, below register R4), just as in the
Classic HP3000. With the default (NONEWDLDB),
SPLash! had problems correctly addressing positive byte addresses above 32767,
because sign extension was being done unconditionally, making such
byte addresses appear to be negative. (The Classic HP3000
compares byte addresses to (S-DB) * 2 and then decides if the address
should be considered as negative or as positive.)
$NMPCAL
When NMPCAL is selected, all calls to native-mode procedures are done with
efficient in-line code. When NMPCAL is deselected (i.e. NONMPCAL),
calls to native-mode procedures are done by pushing the parameters
onto the splash-stack and then jumping to a STUB procedure which
pulls the parameters off the splash-stack and puts them into
registers and/or the "native" stack, as per the procedure calling
convention.
$OBISMAIN
Tells SPLash! to name the outer block "main", in