XTRAN Example — Translate User Function Entry Macro in HP (Digital, Compaq) VAX MACRO to C
This example assumes that the VAX MACRO code to be translated uses a user
macro named ENTRY
to declare a function entry (replacing
.ENTRY
), and that ENTRY
takes a variable number of
operands. The first operand is the function name; the 2nd ff. (if any)
are the names of the function's receiving parameters. The VAX MACRO code
then uses these names as offsets to AP
in the function body to
fetch the calling arguments corresponding to the parameters. Example of
usage:
ENTRY FUNC,PARAM1,PARAM2 ... MOVL @PARAM2(AP),R1 ;GET 2ND PARAM VALUE ... RET
To translate this ENTRY
macro, we use a set
of XTRAN rules ("meta-code") comprising
about 350 non-comment lines of meta-code. If a function declared
with ENTRY
has been declared to XTRAN in
C (for instance, in an include file), the rules pick up the function and
parameter datatypes from the C declaration. Otherwise, they declare the
function and its parameters "unkn".
In the VAX MACRO code below, note that FUNC2
uses a parameter
name that duplicates one of those for FUNC1
. The rules
accommodate this by temporarily qualifying each parameter name with the
function with which it is associated, then removing the qualification before
output.
Note also that FUNC4
isn't declared in C.
Process Flowchart
Here is a flowchart for this process, in which the elements are color coded:
- BLUE for XTRAN versions (runnable programs)
- ORANGE for XTRAN rules (text files)
- RED for
code
Input to XTRAN:
In a C include file fed to XTRAN:
short *func1(long, char *); void func2(short *); long func3(void);
VAX MACRO code to be translated:
ENTRY FUNC1,PARAM1,PARAM2 ;ENTRY FUNC1,PARAM1,PARAM2 MOVB @PARAM2(AP),R1 ;MOVB @PARAM2(AP),R2 RET ;RET ENTRY FUNC2,PARAM1 ;ENTRY FUNC2,PARAM1 MOVW @PARAM1(AP),R2 ;MOVW @PARAM1(AP),R2 RET ;RET ENTRY FUNC3 ;ENTRY FUNC3 CLRL R3 ;CLRL R3 RET ;RET ENTRY FUNC4,P1,P2 ;ENTRY FUNC4,P1,P2 MOVL P2(AP),R4 ;MOVL P2(AP),R4 RET ;RET
Output from XTRAN:
extern char r1; extern short r2; extern long r3; extern long r4; short *func1( long param1, char *param2) { /*entry func1,param1,param2*/ r1 = *param2; /*movb @param2(ap),r2*/ return; /*ret*/ } void func2( short *param1) { /*entry func2,param1*/ r2 = *param1; /*movw @param1(ap),r2*/ return; /*ret*/ } long func3(void) { /*entry func3*/ r3 = 0; /*clrl r3*/ return; /*ret*/ } unkn func4( unkn p1, unkn p2) { /*entry func4,p1,p2*/ r4 = p2; /*movl p2(ap),r4*/ return; /*ret*/ }