An HLASM migration to C that you do NOT want
This example is not from a Semantic Designs' tool.
All migration tools are not created equal. Here is a commercial tool/service we found on the web: Soukhman Assembler to C translator. This result below shows some the original assembler code is woven around translated C code (see this web page for the source of this translation result). The code produced by this tools is clearly translated line by line from HLASM to C (See just the the pure C code here).)
/*A00060|*********************************************************************** 00010000*/
/*A00061|* T R A V E R S A * 00030000*/
/*A00062|* ====================== * 00040000*/
/*A00063|* INPUT: A0000000 F A0000000 * 00050000*/
/*A00064|* B0000000 F B0000000 * 00060000*/
/*A00065|* C0000000 F C0000000 * 00070000*/
/*A00066|* A0000000 I B0000000 * 00080000*/
/*A00067|* B0000000 I C0000000 * 00090000*/
/*A00068|* SORTI='(10,1,CH,A,1,8,CH,A,12,8,CH,A)' * 00091045*/
/*A00069|* OUTPUT: A0000000 F A0000000 ________ NESTED LEVEL * 00100045*/
/*A00070|* B0000000 F B0000000 | FOR 1ST ENTRY * 00110000*/
/*A00071|* C0000000 F C0000000 V * 00120000*/
/*A00072|* A0000000 I B0000000 00000002 * 00130000*/
/*A00073|* A0000000 I C0000000 00000003 * 00140000*/
/*A00074|* B0000000 I C0000000 00000002 * 00150000*/
/*A00075|* THE NUMBER OF F RECORDS SHOULD BE IN PARAMS POS 9 ,8 BYTES ZONED. * 00160000*/
/*A00076|* THE NUMBER OF I RECORDS SHOULD BE IN PARAMS POS 17,8 BYTES ZONED. * 00170000*/
/*A00077|*---------------------------------------------------------------------* 00180000*/
/*A00078|* PROGRAMMER: GURRY SOUKHMAN DATE 02/07/2012 * 00190029*/
/*A00079|* - EXPLANATION: * 00200000*/
/*A00080|* RUN TRAVERSA FROM JCL * 00210029*/
/*A00081|*---------------------------------------------------------------------* 00280000*/
/*A00082| EQUR 00340225*/
/*A00099| COPY PAIREXT 00340308*/
/*A00113|TRAVERSA AMODE 31 00340426*/
/*A00114|TRAVERSA RMODE 24 00340526*/
/*A00115|TRAVERSA CSECT 00342224*/
/*A00116| USING *,R15 00342324*/
/*A00117|BEGIN B START 00342424*/
goto start;
/*A00118| DC AL1(8) 00342524*/
/*A00119| DC CL8'TRAVERSA' 00342625*/
/*A00120|SAVEAREA DS 0F 00342724*/
/*A00121| DC AL4(0) 00342831*/
/*A00122|PRESAVE DC AL4(0) 00342931*/
/*A00123|NEXTSAVE DC AL4(0) 00343031*/
/*A00124|SREG14 DC AL4(0) 00343131*/
/*A00125|SREG15 DC AL4(0) 00343231*/
/*A00126|SREG0 DC 13AL4(0) 00343331*/
/*A00127|SAVEEND DS 0H 00343424*/
/*A00128|START EQU * 00343524*/
/*A00129| DROP R15 00343624*/
/*A00130| STM R14,R12,12(R13) 00343724*/
/*A00131| LR R11,R15 00343825*/
r11 = r15;
/*A00132| USING BEGIN,R11 00343925*/
begin_p = (struct begin**)&r11;
/*A00133| ST R13,PRESAVE 00344024*/
presave = r13;
/*A00134| LA R15,SAVEAREA 00344124*/
r15 = (int)&savearea;
/*A00135| ST R15,8(R13) 00344224*/
*(int *)((char*)r13 + 8) = r15;
/*A00136| LR R13,R15 00344324*/
r13 = r15;
/*A00137|* 00344425*/
/*A00138| OPEN SYSIN 00345337*/
sysin = fopen(sysin_path, "rt");
/*A00144| OPEN INREC 00345437*/
inrec = fopen(inrec_path, "rt");
/*A00150| OPEN (OUTREC,OUTPUT) 00345539*/
outrec = fopen(outrec_path, "wt");
/*A00156| GET SYSIN 00345600*/
if (fgets(r1_sysin,80,sysin) == NULL) {
if(feof(sysin)){
}else{
printf( "ERROR reading file [%s]\n", sysin_path);perror("err");
}
}else{
r1 = (int)&r1_sysin;
}
/*A00161| LR R8,R1 00345700*/
r8 = r1;
/*A00162| BAL R12,INIT 00346018*/
if ((lrc = init())) {
return(lrc);
}
/*A00163|CYCLE GET INREC 00346600*/
if (fgets(r1_inrec,80,inrec) == NULL) {
if(feof(inrec)){
}else{
printf( "ERROR reading file [%s]\n", inrec_path);perror("err");
}
}else{
r1 = (int)&r1_inrec;
}
/*A00171| LR R4,R1 00346701*/
r4 = r1;
/*A00172| BAL R12,PROCESS 00347318*/
if ((lrc = process())) {
return(lrc);
}
/*A00173| B CYCLE 00347418*/
goto cycle;
/*A00174|CALC BAL R12,TERM 00348018*/
if ((lrc = term())) {
return(lrc);
}
/*A00175| CLOSE SYSIN 00348737*/
fclose(sysin);
/*A00181| CLOSE INREC 00349037*/
fclose(inrec);
/*A00187| CLOSE OUTREC 00349137*/
fclose(outrec);
/*A00193| LA R15,DONTWRT 00352028*/
r15 = (int)&dontwrt;
/*A00194| L R13,4(R13) 00352126*/
r13 = *(int *)((char*)r13 + 4);
/*A00195|* L R13,PRESAVE 00352226*/
/*A00196| L R14,12(R13) 00352325*/
r14 = *(int *)((char*)r13 + 12);
/*A00197| LM R0,R12,20(R13) 00352425*/
/*A00198| BR R14 00352525*/
return;
/*A00199|INIT DS 0H 00354025*/
/*A00200| L R1,=A(WL) 00360000*/
r1 = wl;
/*A00201| GETMAIN RC,LV=(R1),SP=SPOOL,LOC=RES + 00371032*/
r1 = malloc(r1);
if(r1 == 0){
r15 = 4;
}else{
r0 = r1;
}
/*A00213| LA R1,0(R1) CLEAR HIGH ORDER BIT 00372006*/
r1 = r1 & 0x7fffffff;
/*A00214| LR R10,R1 00380041*/
r10 = r1;
/*A00215| ST R10,PARMADDR 00390041*/
parmaddr_a = r10;
/*A00216| USING WDSCT,R10 00400041*/
wdsct_p = (struct wdsct**)&r10;
/*A00217| MVI WRECOUT,BLANK BLANK OUT 00410000*/
*(char *)&((*wdsct_p)->wrecout) = blank;
/*A00218| MVC WRECOUT+1(RECLENGO-1),WRECOUT 00420000*/
memcpy((char *)&(*wdsct_p)->wrecout + +1,(char *)&(*wdsct_p)->wrecout,reclengo + -1);
/*A00219| USING GLOBWA,R8 00460000*/
globwa_p = (struct globwa**)&r8;
/*A00220| PACK WD,GLNAME# 00470000*/
sscanf ((*globwa_p)->parmrec.glnamen,"%8lld",&(*wdsct_p)->wd);
/*A00221| CVB R1,WD 00480000*/
decPackedToNumber(&(*wdsct_p)->wd,8,&resscale,&decNmbIns);
r1 = decNumberToInt32(&decNmbIns,&set);
/*A00222| LTR R1,R1 ZERO ? 00490000*/
/*A00226| BZ NULLNUMB YES - ERROR 00500000*/
if (r1 == 0){goto nullnumb;}
/*A00227| ST R1,WNAME# NUMBER OF NAMES 00510000*/
(*wdsct_p)->wnamen = r1;
/*PASSED| 00520000*/
/*A00228| PACK WD,GLCONN# 00530000*/
sscanf ((*globwa_p)->parmrec.glconnn,"%8lld",&(*wdsct_p)->wd);
/*A00229| DROP R8 00540000*/
/*A00230| CVB R2,WD 00550000*/
decPackedToNumber(&(*wdsct_p)->wd,8,&resscale,&decNmbIns);
r2 = decNumberToInt32(&decNmbIns,&set);
/*A00231| LTR R2,R2 ZERO ? 00560000*/
/*A00232| BZ NULLNUMB YES - ERROR 00570000*/
if (r2 == 0){goto nullnumb;}
/*A00233| ST R2,WCONN# NUMBER OF CONNECTIONS 00580000*/
(*wdsct_p)->wconnn = r2;
/*PASSED| 00590000*/
/*A00234| LR R3,R1 # OF NAMES 00600000*/
r3 = r1;
/*A00235| LA R3,2(,R3) ADD 2 FOR 1ST AND LAST FICTIVE ELEMENTS 00610000*/
r3 += 2;
/*A00236| MH R3,=Y(NAMELSLN) MULTIPLY BY ENTRY LENGTH 00620000*/
r3 *= namelsln;
/*A00237| LR R8,R1 # OF NAMES 00630000*/
r8 = r1;
/*A00238| SRL R8,5 DIVIDE BY 32 TO GET #BYTES * 4 00640000*/
r8 = (unsigned)r8 >> 5;
/*A00239| LA R8,1(,R8) ADD 1 00650000*/
r8 += 1;
/*A00240| SLL R8,2 TO GET #BYTES OF USING BIT VEC 00660000*/
r8 <<= 2;
/*A00241| LR R9,R8 MOVE TO R9 AND CLEAR 00670000*/
r9 = r8;
/*A00242| ST R9,WUBVECL LENGTH OF USING BITS VECTOR 00680000*/
(*wdsct_p)->wubvecl = r9;
/*A00243|* 00690027*/
/*A00244| SLL R2,2 /* MEMORY FOR CONNECTION */ 00700000*/
r2 <<= 2;
/*A00245| AR R9,R2 TOTAL SIZE + CONNECTIONS 00710000*/
r9 += r2;
/*A00246| AR R9,R3 TOTAL SIZE + NAMES 00720000*/
r9 += r3;
/*A00247| GETMAIN RC,LV=(R9),SP=SPOOL,LOC=RES 00730040*/
r1 = malloc(r9);
if(r1 == 0){
r15 = 4;
}else{
r0 = r9;
}
/*A00259| BXH R15,R15,ABALLOC 00740000*/
if(r15 != 0){
goto aballoc;
};
/*A00260| ST R0,WTOTSZ AREA SIZE 00750000*/
(*wdsct_p)->wtotsz = r0;
/*A00261| LA R1,0(R1) CLEAR HIGH ORDER BIT 00760000*/
r1 = r1 & 0x7fffffff;
/*A00262| ST R1,WNAMELA ADDRESS OF NAMES LIST 00770000*/
(*wdsct_p)->nameadrs.wnamela = r1;
/*A00263| ST R1,WCURNMA ADDRESS FOR LOAD F 00780000*/
(*wdsct_p)->nameadrs.wcurnma = r1;
/*A00264| MVI 0(R1),BLANK BLANK INTO 1ST FICTIVE NAME 00790000*/
*((char*)r1 + 0)=blank;
/*A00265| LR R2,R1 00800000*/
r2 = r1;
/*A00266| LA R2,NAMELSLN(,R2) 00810000*/
r2 += namelsln;
/*A00267| ST R2,W1NAMEA ADDRESS OF 1ST NAME FOR FIND 00820000*/
(*wdsct_p)->nameadrs.w1namea = r2;
/*A00268| AR R1,R3 ADD NAMES LENGTH 00830045*/
r1 += r3;
/*A00269| ST R1,WUBVECA USING BIT VECTOR ADDRESS 00840000*/
(*wdsct_p)->wubveca = r1;
/*A00270| AR R1,R8 ADD BIT VECTOR LENGTH 00850000*/
r1 += r8;
/*A00271| ST R1,WCONA ADDRESS OF CONNECTIONS 00860000*/
(*wdsct_p)->wcona = r1;
/*A00272| ST R1,WCURCONA CURRENT CONNECTION ADDRESS FOR LOAD I 00870000*/
(*wdsct_p)->wcurcona = r1;
/*A00273| MVC WNXT#,=F'0' FIRST SEQ# 00880000*/
(*wdsct_p)->wnxtn= 0;
/*A00274| B RETURN 00890000*/
goto return;
/*A00275|ABALLOC ABEND 13 00900000*/
printf("ABEND 13 (aballoc)\n");
return 13;
/*A00282|* 00910000*/
/*A00283|PROCESS DS 0H 00920000*/
/*A00284| USING NAMELIST,R8 00930000*/
namelist_p = (struct namelist**)&r8;
/*A00285| USING REC,R4 00940001*/
rec_p = (struct rec**)&r4;
/*A00286| L R10,PARMADDR 00950041*/
r10 = parmaddr_a;
/*A00287| OC WNAMELA,WNAMELA F2757 00960000*/
/*A00288| BZ RETURN F2757 00970000*/
if((*wdsct_p)->nameadrs.wnamela == 0) goto return;
/*A00289| CLI RECID,C'F' NAME WITH ITSELF? 00980000*/
/*A00290| BE ADDNEWNM ADD THE NAME TO THE LIST 00990000*/
if (*(char*)&(*rec_p)->recid == 'F') {
goto addnewnm;
};
/*A00291| CLI WNXT#,X'FF' DID WE CHECK THE NUMBER? 01000000*/
/*A00292| BE PROCREL 01010000*/
if ((char unsigned)(*wdsct_p)->wnxtn == 0xff) {
goto procrel;
};
/*A00293| CLC WNXT#,WNAME# IF THE NUM EQ 01020000*/
/*A00294| BNE GLOBEROR 01030000*/
if ((*wdsct_p)->wnxtn != (*wdsct_p)->wnamen) {
goto globeror;
};
/*A00295| MVI WNXT#,X'FF' WE DID CHECK THE NUMBER 01040000*/
(*wdsct_p)->wnxtn='\xff';
/*A00296| MVC WLASTNMA,WCURNMA LAST NAME LOCATION ADDRESS 01050000*/
(*wdsct_p)->nameadrs.wlastnma = (*wdsct_p)->nameadrs.wcurnma;
/*A00297| MVC WCURNMA,WNAMELA NAME LOCATION ADDRESS 01060000*/
(*wdsct_p)->nameadrs.wcurnma = (*wdsct_p)->nameadrs.wnamela;
/*A00298|* 01061018*/
/*A00299|* MVC OUTAREA+5(15),=C'B PROCREL ' 01062018*/
/*A00300|* ST R1,OUTAREA+12 01063018*/
/*A00301|* WTO TEXT=MYMSG 01064018*/
/*A00302|* 01065018*/
/*A00303| B PROCREL 01070000*/
goto procrel;
/*A00304|GLOBEROR DS 0H 01080000*/
/*A00305| WTO 'PAIRS-NUM IN PARAMS NE NUM OF NAMES' 01090000*/
printf("pairs-num in params ne num of names\n");
/*A00314| B ABEND 01100000*/
goto abend;
/*A00315|NULLNUMB DS 0H 01110000*/
/*A00316| XC WNAMELA,WNAMELA F2757 01120000*/
(*wdsct_p)->nameadrs.wnamela = 0;
/*A00317| WTO 'PAIRS-NUM IN PARAMS IS ZERO' 01130000*/
printf("pairs-num in params is zero\n");
/*A00326|*F2757 B ABEND 01140000*/
/*A00327| LA R15,7 F2757 01150000*/
r15 = 7;
/*A00328| ST R15,HRC F2757 01160000*/
hrc = r15;
/*A00329| B RETURN F2757 01170000*/
goto return;
/*A00330|PROCREL DS 0H 01180000*/
/*A00331| CLI RECID,REC$INC RELATION BETWEEN TWO NAMES 01190000*/
/*A00332| BE ADDRELT ADD THE NAME TO THE BIT TABLE 01200000*/
if (*(char*)&(*rec_p)->recid == recdinc) {
goto addrelt;
};
/*A00333|* ERROR 01210000*/
/*A00334| WTO 'PAIRS-INVALID CODE IN THE INPUT RECORD' 01220000*/
printf("pairs-invalid code in the input record\n");
/*A00346| B ABEND 01230000*/
goto abend;
/*A00347|ADDNEWNM DS 0H 01240000*/
/*A00348| L R8,WCURNMA CURRENT NAME LOCATION ADDRESS 01250000*/
r8 = (*wdsct_p)->nameadrs.wcurnma;
/*A00349| LA R8,NAMELSLN(,R8) NEXT ONE 01260000*/
r8 += namelsln;
/*A00350| MVC NAMEF,NAME1 MOVE THE NAME 01270000*/
memcpy(&(*namelist_p)->namels.namef,&(*rec_p)->name1,8);
/*A00351| XC STARTCON,STARTCON CLEAR ADDRESS OF CONNECTIONS 01280000*/
(*namelist_p)->namels.startcon = 0;
/*A00352| ST R8,WCURNMA NEXT NAME LOCATION 01290000*/
(*wdsct_p)->nameadrs.wcurnma = r8;
/*A00353| L R1,WNXT# ADD 1 TO NUMBER OF NAMES 01300000*/
r1 = (*wdsct_p)->wnxtn;
/*A00354| LA R1,1(,R1) 01310000*/
r1 += 1;
/*A00355| ST R1,WNXT# 01320000*/
(*wdsct_p)->wnxtn = r1;
/*A00356| MVC WRECOUT(RECLENG),REC MOVE RECORD TO OUTPUT 01330044*/
memcpy(&(*wdsct_p)->wrecout,&(**rec_p),recleng);
/*A00357| PUT OUTREC,WRECOUT WRITE A RECORD 01341018*/
fprintf(outrec,"%28.28s\n",&(*wdsct_p)->wrecout);
/*A00363| B RETURN 01350000*/
goto return;
/*A00364|ABEND DS 0H 01360000*/
/*A00365| ABEND 22,DUMP 01370000*/
printf("ABEND 22 (??)\n");
return 22;
/*A00366|ADDRELT DS 0H ADD RELATION BETWEEN TWO NAMES 01380045*/
/*A00373| MVC WTNAME,NAME2 01390000*/
memcpy(&(*wdsct_p)->wtname,&(*rec_p)->name2,8);
/*A00374| BAL R7,FINDSEQ# 01400000*/
if ((lrc = findseqn())) {
return(lrc);
}
/*A00375| L R1,WCURCONA 01410000*/
r1 = (*wdsct_p)->wcurcona;
/*A00376| ST R8,0(R1) ADDRESS OF NAME2 INTO CONNECTIONS 01420000*/
*(int *)((char*)r1 + 0) = r8;
/*A00377| L R8,WCURNMA CURRENT NAME LOCATION ADDRESS 01430000*/
r8 = (*wdsct_p)->nameadrs.wcurnma;
/*A00378| CLC NAMEF,NAME1 THE FIRST NAME = CURRENT NAME ? 01440000*/
/*A00379| BE NEXTCON 01450000*/
if(memcmp(&(*namelist_p)->namels.namef,&(*rec_p)->name1,8) == 0){
goto nextcon;
}
/*A00380| LA R8,NAMELSLN(,R8) NEXT NAME 01460000*/
r8 += namelsln;
/*A00381| ST R1,STARTCON ADDRESS OF CONNECTIONS INTO NEXT NAME 01470000*/
(*namelist_p)->namels.startcon = r1;
/*A00382| CLC NAMEF,NAME1 THE FIRST NAME = NEXT CURRENT NAME ? 01480000*/
/*A00383| BE NEXTCON 01490000*/
if(memcmp(&(*namelist_p)->namels.namef,&(*rec_p)->name1,8) == 0){
goto nextcon;
}
/*A00384| MVC WTNAME,NAME1 01500000*/
memcpy(&(*wdsct_p)->wtname,&(*rec_p)->name1,8);
/*A00385| BAL R7,FINDSEQ# 01510000*/
if ((lrc = findseqn())) {
return(lrc);
}
/*A00386| ST R1,STARTCON ADDRESS OF CONNECTIONS INTO FINDED NAME 01520000*/
(*namelist_p)->namels.startcon = r1;
/*PASSED| 01530000*/
/*A00387|NEXTCON LA R1,4(R1) NEXT CURRENT CONNECTION ADDRESS 01540000*/
r1 += 4;
/*A00388| ST R1,WCURCONA 01550000*/
(*wdsct_p)->wcurcona = r1;
/*A00389| ST R8,WCURNMA 01560000*/
(*wdsct_p)->nameadrs.wcurnma = r8;
/*A00390| B RETURN 01570000*/
goto return;
/*A00391|* 01580000*/
/*A00392|FINDSEQ# DS 0H FIND ADDR OF NAME IN NAME AREA -> R8 01590045*/
/*A00393| LA R2,1 R2 = LOW =1 01600000*/
r2 = 1;
/*A00397| L R3,WNAME# NUMBER OF NAMES 01610000*/
r3 = (*wdsct_p)->wnamen;
/*A00398| LA R3,1(,R3) ADD 1 = HIGH 01620000*/
r3 += 1;
/*A00399|FS010 DS 0H 01630000*/
/*A00400| LR R5,R2 01640000*/
r5 = r2;
/*A00401| AR R5,R3 LOW+HIGH 01650000*/
r5 += r3;
/*A00402| SRA R5,1 LOW+HIGH/2 01660000*/
{int sign= r5 & 0x80000000;r5 = 0x7fffffff & r5;r5 >>= 1;r5 = sign | r5;}
/*A00403| LR R8,R5 01670000*/
r8 = r5;
/*A00404| BCTR R8,0 SUB 1 01680000*/
r8--;
/*A00405| MH R8,=Y(NAMELSLN) MULT BY ENTRY LENGTH 01690000*/
r8 *= namelsln;
/*A00406| A R8,W1NAMEA ADDRESS OF 1ST NAME 01700000*/
r8 = r8 + (*wdsct_p)->nameadrs.w1namea;
/*A00407| CLC WTNAME,NAMEF IS IT THE REQ NAME? 01710000*/
/*A00408| BNE FS020 NO 01720000*/
if(memcmp(&(*wdsct_p)->wtname,&(*namelist_p)->namels.namef,8) != 0){
goto fs020;
}
/*A00409| BR R7 YES - RETURN 01730000*/
return;
/*A00410|FS020 DS 0H 01740000*/
/*A00411| BH FS030 NO 01750000*/
/*No Next Commands */
/*A00412| LR R3,R5 NEW HIGH 01760000*/
r3 = r5;
/*A00413| B FS040 01770000*/
goto fs040;
/*A00414|FS030 DS 0H 01780000*/
/*A00415| LA R2,1(,R5) NEW LOW 01790000*/
r2 = r5 + 1;
/*A00416|FS040 DS 0H 01800000*/
/*A00417| CR R3,R2 01810000*/
/*A00418| BH FS010 WHILE HIGH > LOW 01820000*/
if (r3 > r2) {
goto fs010;
};
/*A00419|*F7270 WTO 'A NAME WAS NOT FOUND IN THE NAMES LIST' 01830000*/
/*A00420|* MVC NOT REENTERABLE ! F7270 01840000*/
/*A00421| MVC ERRNAME,WTNAME MOVE THE NAME F7270 01850000*/
memcpy(&errname,&(*wdsct_p)->wtname,8);
/*A00422| CNOP 0,4 F7270 01860000*/
/*A00423| BAL R1,WTOERNM F7270 01870000*/
if ((lrc = wtoernm())) {
return(lrc);
}
/*A00424| DC AL2(MSGEND-*) F7270 01880000*/
/*A00425| DC B'00000000' F7270 01890000*/
/*A00426| DC B'00000000' F7270 01900000*/
/*A00427| DC C'TRAVERSA-THE NAME:' F7270 01910000*/
/*A00428|ERRNAME DS CL8 F7270 01920000*/
/*A00429| DC C' WAS NOT FOUND IN THE NAMES LIST' F7270 01930000*/
/*A00430|* WTO 'PAIRS-A NAME WAS NOT FOUND IN THE NAMES LIST' F7270 01940000*/
/*A00431|MSGEND EQU * F7270 01950000*/
/*A00432|WTOERNM DS 0H F7270 01960000*/
/*A00433| SVC 35 F7270 01970000*/
/*A00434| B ABEND F7270 01980000*/
goto abend;
/*A00435|* 01990000*/
/*A00436|TERM DS 0H 02000000*/
/*A00437| WTO 'PAIRS-START OF TERM PROCESS' 02010000*/
printf("pairs-start of term process\n");
/*A00446| L R10,PARMADDR 02020041*/
r10 = parmaddr_a;
/*A00447| OC WNAMELA,WNAMELA F2757 02030000*/
/*A00448| BZ RETURN F2757 02040000*/
if((*wdsct_p)->nameadrs.wnamela == 0) goto return;
/*A00449| L R1,WCURCONA 02050000*/
r1 = (*wdsct_p)->wcurcona;
/*A00450| L R8,WCURNMA CURRENT NAME LOCATION ADDRESS 02060000*/
r8 = (*wdsct_p)->nameadrs.wcurnma;
/*A00451| ST R1,NXTSTCON ADDRESS OF CONNECTIONS INTO NEXT NAME 02070000*/
(*namelist_p)->nxtstcon = r1;
/*PASSED| 02080000*/
/*A00455| L R8,WNAMELA 02090000*/
r8 = (*wdsct_p)->nameadrs.wnamela;
/*A00456| ST R8,WHEADNMA THIS IS A FICTIVE NAME 02100000*/
(*wdsct_p)->wheadnma = r8;
/*A00457|LOOPHEAD DS 0H 02110000*/
/*A00458| L R4,WUBVECA 02120000*/
r4 = (*wdsct_p)->wubveca;
/*A00459| L R5,WUBVECL 02130000*/
r5 = (*wdsct_p)->wubvecl;
/*A00460| SLR R7,R7 ZERO PADDING BYTE 02140000*/
r7 = 0;
/*A00461| MVCL R4,R6 CLEAR USING BIT VECTOR 02150000*/
{char pad = *((char*)&r4 + 3);memset(r4,pad,r5);memcpy((char *)r4,r6,r7);}
/*A00462| L R8,WHEADNMA 02160000*/
r8 = (*wdsct_p)->wheadnma;
/*A00463| LA R8,NAMELSLN(,R8) NEXT HEAD 02170000*/
r8 += namelsln;
/*A00464| CL R8,WLASTNMA 02180000*/
/*A00465| BH FREEAREA 02190000*/
if (r8 > (*wdsct_p)->nameadrs.wlastnma) {
goto freearea;
};
/*A00466| ST R8,WHEADNMA 02200000*/
(*wdsct_p)->wheadnma = r8;
/*A00467| ST R8,WCURNMA 02210000*/
(*wdsct_p)->nameadrs.wcurnma = r8;
/*A00468| MVC NAME1O,NAMEF 02220000*/
memcpy(&(*wdsct_p)->wrecout.name1o,&(*namelist_p)->namels.namef,8);
/*A00469| MVI RECIDO,REC$INCO YY 02230000*/
*(char *)&((*wdsct_p)->wrecout.recido) = recdinco;
/*A00470| LA R8,1 02240000*/
r8 = 1;
/*A00471| ST R8,WLEVEL 02250000*/
(*wdsct_p)->wlevel = r8;
/*A00472| MVI WGOSIGN,SSTART 02260000*/
*(char *)&((*wdsct_p)->wgosign) = sstart;
/*A00473|LOOPNAME DS 0H 02270000*/
/*A00474| L R8,WCURNMA 02280000*/
r8 = (*wdsct_p)->nameadrs.wcurnma;
/*A00475| TM WGOSIGN,SUP 02290000*/
/*A00476| BO GORIGHT 02300000*/
if (((*wdsct_p)->wgosign & sup) != 0){
goto goright;
}
/*A00477| LR R3,R8 02310000*/
r3 = r8;
/*A00478| S R3,W1NAMEA 02320000*/
r3 = r3 - (int)(*wdsct_p)->nameadrs.w1namea;
/*A00479| SLR R2,R2 02330000*/
r2 = 0;
/*A00480| D R2,=A(NAMELSLN) NAME NUMBER 02340000*/
llIns = (r2*0x100000000 + r3);
r2 = llIns % namelsln;
r3 = llIns / namelsln;
/*PASSED| 02350000*/
/*A00481| SLR R2,R2 02360000*/
r2 = 0;
/*A00482| D R2,=F'8' DIVIDE BY 8 TO GET BYTE# 02370000*/
llIns = (r2*0x100000000 + r3);
r2 = llIns % 8;
r3 = llIns / 8;
/*A00483| L R6,WUBVECA 02380000*/
r6 = (*wdsct_p)->wubveca;
/*A00484| AR R6,R3 RELATIVE BYTE ADDRESS 02390000*/
r6 += r3;
/*A00485| LA R15,X'80' 02400000*/
r15 = 0x80;
/*A00486| SRL R15,0(R2) 02410000*/
r15 = (unsigned)r15 >> (r2 + 0);
/*PASSED| 02420000*/
/*A00487| STCM R15,B'0001',WBYTE 02430000*/
*((char*)&(*wdsct_p)->wbyte) = (unsigned int)r15 << 24 >> 24;
/*A00488| NC WBYTE(1),0(R6) 02440000*/
(*wdsct_p)->wbyte = (*wdsct_p)->wbyte & *((char*)r6 + 0);
/*A00489| BNZ GORIGHT 02450000*/
if((*wdsct_p)->wbyte != 0) goto goright;
/*A00490|TESTWR DS 0H WRITE WBYTE FOR SSTART,SRIGHT,SDOWN 02460000*/
/*A00491| STCM R15,B'0001',WBYTE 02470000*/
*((char*)&(*wdsct_p)->wbyte) = (unsigned int)r15 << 24 >> 24;
/*A00492| OC 0(1,R6),WBYTE 02480000*/
*((char*)r6 + 0) = *((char*)r6 + 0) | (*wdsct_p)->wbyte;
/*A00493| TM WGOSIGN,SRIGHT+SDOWN 02490000*/
/*A00494| BZ GODOWN 02500000*/
if (((*wdsct_p)->wgosign & (sright + +sdown)) == 0){
goto godown;
}
/*A00495| MVC NAME2O,NAMEF 02510000*/
memcpy(&(*wdsct_p)->wrecout.name2o,&(*namelist_p)->namels.namef,8);
/*A00496| L R15,WLEVEL 02520000*/
r15 = (*wdsct_p)->wlevel;
/*A00497| CVD R15,DTWD 02530000*/
decNumberFromInt32(&decNmbIns,r15);
decPackedFromNumber(&(*wdsct_p)->dtwd,8,&resscale,&decNmbIns);
/*A00498| UNPK NESTLEVL,DTWD+4(4) 02540000*/
decPackedToNumber((char*)(*wdsct_p)->dtwd + +4,4,&resscale,&decNmbIns);
decNumberToString(&decNmbIns,&strIns);
sprintf((*wdsct_p)->wrecout.nestlevl,"%08s",strIns);
/*A00499| OI NESTLEVL+7,X'F0' 02550000*/
/*A00500|** JUMP ADDREC,WRECOUT WRITE A RECORD 02560005*/
/*A00501| PUT OUTREC,WRECOUT WRITE A RECORD 02561018*/
fprintf(outrec,"%28.28s\n",&(*wdsct_p)->wrecout);
/*A00507|GODOWN DS 0H 02570000*/
/*A00511| OC STARTCON,STARTCON 02580000*/
/*A00512| BZ GORIGHT 02590000*/
if((*namelist_p)->namels.startcon == 0) goto goright;
/*A00513| CLC NXTSTCON,STARTCON 02600000*/
/*A00514| BNH GORIGHT 02610000*/
if ((*namelist_p)->nxtstcon <= (*namelist_p)->namels.startcon) {
goto goright;
};
/*A00515| MVC CURCON,STARTCON 02620000*/
(*namelist_p)->namels.curcon = (*namelist_p)->namels.startcon;
/*A00516| MVC PARENCON,WPARENT SG 02630000*/
memcpy(&(*namelist_p)->namels.parencon,&(*wdsct_p)->wparent,4);
/*A00517| ST R8,WPARENT SG 02640000*/
(*wdsct_p)->wparent = r8;
/*A00518| L R8,STARTCON 02650000*/
r8 = (*namelist_p)->namels.startcon;
/*A00519| L R8,0(R8) 02660000*/
r8 = *(int *)((char*)r8 + 0);
/*A00520| ST R8,WCURNMA 02670000*/
(*wdsct_p)->nameadrs.wcurnma = r8;
/*A00521| MVI WGOSIGN,SDOWN 02680000*/
*(char *)&((*wdsct_p)->wgosign) = sdown;
/*A00522| L R3,WLEVEL 02690000*/
r3 = (*wdsct_p)->wlevel;
/*A00523| LA R3,1(R3) 02700000*/
r3 += 1;
/*A00524| ST R3,WLEVEL 02710000*/
(*wdsct_p)->wlevel = r3;
/*A00525| B LOOPNAME 02720000*/
goto loopname;
/*A00526|GORIGHT DS 0H 02730000*/
/*A00527| CLC WLEVEL,=F'1' 02740000*/
/*A00528| BE LOOPHEAD 02750000*/
if ((*wdsct_p)->wlevel == 1) {
goto loophead;
};
/*A00529| L R8,WPARENT 02760000*/
r8 = (*wdsct_p)->wparent;
/*A00530| L R5,CURCON 02770000*/
r5 = (*namelist_p)->namels.curcon;
/*A00531| LA R5,4(R5) NEXT CONNECTION 02780000*/
r5 += 4;
/*A00532| CL R5,NXTSTCON 02790000*/
/*A00533| BNL GOUP 02800000*/
if (r5 >= (*namelist_p)->nxtstcon) {
goto goup;
};
/*A00534| ST R5,CURCON 02810000*/
(*namelist_p)->namels.curcon = r5;
/*A00535| L R5,0(R5) 02820000*/
r5 = *(int *)((char*)r5 + 0);
/*A00536| ST R5,WCURNMA 02830000*/
(*wdsct_p)->nameadrs.wcurnma = r5;
/*A00537| LR R8,R5 02840000*/
r8 = r5;
/*A00538| MVI WGOSIGN,SRIGHT 02850000*/
*(char *)&((*wdsct_p)->wgosign) = sright;
/*A00539| B LOOPNAME 02860000*/
goto loopname;
/*A00540|GOUP DS 0H 02870000*/
/*A00541| ST R8,WCURNMA 02880000*/
(*wdsct_p)->nameadrs.wcurnma = r8;
/*A00542| MVC WPARENT,PARENCON SG 02890000*/
memcpy(&(*wdsct_p)->wparent,&(*namelist_p)->namels.parencon,4);
/*A00543| MVI WGOSIGN,SUP 02900000*/
*(char *)&((*wdsct_p)->wgosign) = sup;
/*A00544| L R8,WLEVEL 02910000*/
r8 = (*wdsct_p)->wlevel;
/*A00545| BCTR R8,0 02920000*/
r8--;
/*A00546| ST R8,WLEVEL 02930000*/
(*wdsct_p)->wlevel = r8;
/*A00547| B LOOPNAME 02940000*/
goto loopname;
/*A00548|FREEAREA DS 0H 02950000*/
/*A00549| L R1,WNAMELA 02960000*/
r1 = (*wdsct_p)->nameadrs.wnamela;
/*A00550| L R0,WTOTSZ TOTAL AREA SIZE 02970000*/
r0 = (*wdsct_p)->wtotsz;
/*A00551| FREEMAIN RU,LV=(R0),A=(R1),SP=SPOOL 02980042*/
free(r1);
/*A00562|RETURN BR R12 02990018*/
return;
/*A00563|MYMSG DC AL2(L'OUTAREA) 02990118*/
/*A00564|OUTAREA DC CL133'+AA' 02990218*/
/*A00565|PARMADDR DS F + 02990318*/
/*A00569|HRC DS F + 02990418*/
/*A00570|*XTSAVE DS F 02990520*/
/*A00571| LTORG 02990618*/
/*A00578|* 02990718*/
/*A00579|SYSIN DCB MACRF=GL,DDNAME=INDD,LRECL=80,DSORG=PS,EODAD=RETURN 02992015*/
/*A00620|INREC DCB MACRF=GL,EODAD=CALC,DDNAME=INREC,LRECL=20,DSORG=PS 02993000*/
/*A00663|OUTREC DCB MACRF=PM,RECFM=FB,DDNAME=OUTREC,DSORG=PS 02994043*/
/*A00664|* 03020000*/
/*A00707|REC DSECT YY 03030000*/
/*A00708|NAME1 DS CL8 FIRST NAME YY 03040000*/
/*A00709| DS CL1 03050000*/
/*A00710|RECID DS CL1 YY 03060000*/
/*A00711|REC$INC EQU C'I' YY 03070000*/
/*A00712| DS CL1 03080000*/
/*A00713|NAME2 DS CL8 SECOND NAME YY 03090000*/
/*A00714| DS CL1 03100000*/
/*A00715|RECLENG EQU *-REC 03110000*/
/*A00716|* 03120000*/
/*A00717|GLOBWA DSECT YY 03130000*/
/*A00718|PARMREC DS 0CL24 03131035*/
/*A00719|GLCONST DS CL8 'TRAVERSA' CONSTANT YY 03140000*/
/*A00720|GLNAME# DS CL8 NUMBER OF NAMES YY 03150000*/
/*A00721|GLCONN# DS CL8 NUMBER OF CONNECTIONS YY 03160000*/
/*A00722|* 03170000*/
/*A00723|NAMELIST DSECT 03210000*/
/*A00724| DS 0F 03220000*/
/*A00725|NAMELS DS 0CL20 03221036*/
/*A00726|NAMEF DS CL8 THE NAME OF THE OBJECT YY 03230000*/
/*A00727|STARTCON DS A ADDRESS OF START CONNECTON CHAIN YYM 03240000*/
/*A00728|PARENCON DS A ADDRESS OF PARENT NAME M 03250000*/
/*A00729|CURCON DS A ADDRESS OF CURRENT CONNECTON CHAIN M 03260000*/
/*A00730|NAMELSLN EQU *-NAMELIST YY 03270000*/
/*A00731|NXTNAMEF DS CL8 THE NAME OF THE NEXT OBJECT M 03280000*/
/*A00732|NXTSTCON DS A ADDRESS OF START CONNECTON CHAIN OF NEXT OBJ M 03290000*/
/*A00733|* 03300000*/
/*A00734|WDSCT DSECT YY 03310000*/
/*A00735|WD DS D WORK AREA YY 03320000*/
/*A00736|WNAME# DS F NUMBER OF NAMES YY 03330000*/
/*A00740|WCONN# DS F NUMBER OF CONNECTIOMS YY? 03340000*/
/*A00741|NAMEADRS DS 0CL16 03341035*/
/*A00742|WNAMELA DS A ADDRESS OF NAMES LIST YY? 03350000*/
/*A00743|W1NAMEA DS A ADDRESS OF 1ST NAME M 03360000*/
/*A00744|*NXTNMA DS A ADDRESS OF NEXT NAME LOCATION YY? 03370000*/
/*A00745|WCURNMA DS A ADDRESS OF CURRENT NAME LOCATION YYM 03380000*/
/*A00746|WLASTNMA DS A ADDRESS OF LAST NAME LOCATION M 03390000*/
/*A00747|WNXT# DS F SEQ# OF NEXT NAME LOCATION YY 03400000*/
/*A00748|WCONA DS A ADDRESS OF CONNECTIONS YYM 03410000*/
/*A00749|WCURCONA DS A CURRENT CONNECTION ADDRESS YYM 03420000*/
/*A00750|WUBVECL DS F BITS VECTOR LENGTH IN BYTES YY? 03430000*/
/*A00751|WUBVECA DS A USING BIT VECTOR ADDRESS YY 03440000*/
/*A00752|WHEADNMA DS A ADDRESS OF HEAD NAME M 03450000*/
/*A00753|WLEVEL DS F CURRENT LEVEL M 03460000*/
/*A00754|WPARENT DS F CURRENT PARENT M 03470000*/
/*A00755|WTOTSZ DS F TOTAL AREA SIZE YY 03480000*/
/*A00756|DTWD DS D 03490000*/
/*A00757|WTNAME DS CL8 NAME WA YY 03500000*/
/*A00758|WBYTE DS C BYTE WA 03510000*/
/*A00759|WCHGSW DS C VECTOR CHANGE SWITCH 03520000*/
/*A00760|WGOSIGN DS C GO SIGN M 03530000*/
/*A00761|SDOWN EQU B'00000001' 03540000*/
/*A00762|SRIGHT EQU B'00000010' 03550000*/
/*A00763|SUP EQU B'00000100' 03560000*/
/*A00764|SSTART EQU B'00000000' 03570000*/
/*A00765|SPOOL EQU 11 03572006*/
/*A00766|WRECOUT DS 0F M 03590000*/
/*A00767|NAME1O DS CL8 FIRST NAME YY 03600000*/
/*A00768| DS CL1 03610000*/
/*A00769|RECIDO DS CL1 YY 03620000*/
/*A00770|REC$INCO EQU C'I' YY 03630000*/
/*A00771| DS CL1 03640000*/
/*A00772|NAME2O DS CL8 SECOND NAME YY 03650000*/
/*A00773| DS CL1 03660000*/
/*A00774|NESTLEVL DS CL8 NESTED LEVEL 03670000*/
/*A00775|RECLENGO EQU *-WRECOUT 03680000*/
/*A00776|WL EQU *-WDSCT 03690000*/
/*A00777|* 03700000*/
/*A00778| END 03710000*/
The ugliness of this speaks for itself. Pardon our public opinion, but this is a truly unmaintainable result, assuming it works. The line by line translation is very simple.
Translated C Code stripped of assembler source
The following code is the above converted code with the intervening assembly language removed. (We extracted it by hand from the above; to be generous, you should pretend that comment lines from the above were copied into this.) This code is just as unreadable if not worse because it has no context; see if you can guess what it does. It retains confusing machine idioms such as register names like r8 are retained, as well as names of peculiar machine instructions decPackedToNumber; these are only pure distractions in the "higher level C code". It contains a rat's nest of gotos (and even starts with one!). It contains some stunningly obscure code fragments: {int sign= r5 & 0x80000000;r5 = 0x7fffffff & r5;r5 >>= 1;r5 = sign | r5;} Various printfs have been added containing text not in the original program; while standard error reporting is useful, it should be relegated to library routines to avoid cluttering the application code. We are unsure where the variable declarations went, if they are indeed generated at all.
goto start; r11 = r15; begin_p = (struct begin**)&r11; presave = r13; r15 = (int)&savearea; *(int *)((char*)r13 + 8) = r15; r13 = r15; sysin = fopen(sysin_path, "rt"); inrec = fopen(inrec_path, "rt"); outrec = fopen(outrec_path, "wt"); if (fgets(r1_sysin,80,sysin) == NULL) { if(feof(sysin)){ }else{ printf( "ERROR reading file [%s]\n", sysin_path);perror("err"); } }else{ r1 = (int)&r1_sysin; } r8 = r1; if ((lrc = init())) { return(lrc); } if (fgets(r1_inrec,80,inrec) == NULL) { if(feof(inrec)){ }else{ printf( "ERROR reading file [%s]\n", inrec_path);perror("err"); } }else{ r1 = (int)&r1_inrec; } r4 = r1; if ((lrc = process())) { return(lrc); } goto cycle; if ((lrc = term())) { return(lrc); } fclose(sysin); fclose(inrec); fclose(outrec); r15 = (int)&dontwrt; r13 = *(int *)((char*)r13 + 4); r14 = *(int *)((char*)r13 + 12); return; r1 = wl; r1 = malloc(r1); if(r1 == 0){ r15 = 4; }else{ r0 = r1; } r1 = r1 & 0x7fffffff; r10 = r1; parmaddr_a = r10; wdsct_p = (struct wdsct**)&r10; *(char *)&((*wdsct_p)->wrecout) = blank; memcpy((char *)&(*wdsct_p)->wrecout + +1,(char *)&(*wdsct_p)->wrecout,reclengo + -1); globwa_p = (struct globwa**)&r8; sscanf ((*globwa_p)->parmrec.glnamen,"%8lld",&(*wdsct_p)->wd); decPackedToNumber(&(*wdsct_p)->wd,8,&resscale,&decNmbIns); r1 = decNumberToInt32(&decNmbIns,&set); if (r1 == 0){goto nullnumb;} (*wdsct_p)->wnamen = r1; sscanf ((*globwa_p)->parmrec.glconnn,"%8lld",&(*wdsct_p)->wd); decPackedToNumber(&(*wdsct_p)->wd,8,&resscale,&decNmbIns); r2 = decNumberToInt32(&decNmbIns,&set); if (r2 == 0){goto nullnumb;} (*wdsct_p)->wconnn = r2; r3 = r1; r3 += 2; r3 *= namelsln; r8 = r1; r8 = (unsigned)r8 >> 5; r8 += 1; r8 <<= 2; r9 = r8; (*wdsct_p)->wubvecl = r9; r2 <<= 2; r9 += r2; r9 += r3; r1 = malloc(r9); if(r1 == 0){ r15 = 4; }else{ r0 = r9; } if(r15 != 0){ goto aballoc; }; (*wdsct_p)->wtotsz = r0; r1 = r1 & 0x7fffffff; (*wdsct_p)->nameadrs.wnamela = r1; (*wdsct_p)->nameadrs.wcurnma = r1; *((char*)r1 + 0)=blank; r2 = r1; r2 += namelsln; (*wdsct_p)->nameadrs.w1namea = r2; r1 += r3; (*wdsct_p)->wubveca = r1; r1 += r8; (*wdsct_p)->wcona = r1; (*wdsct_p)->wcurcona = r1; (*wdsct_p)->wnxtn= 0; goto return; printf("ABEND 13 (aballoc)\n"); return 13; namelist_p = (struct namelist**)&r8; rec_p = (struct rec**)&r4; r10 = parmaddr_a; if((*wdsct_p)->nameadrs.wnamela == 0) goto return; if (*(char*)&(*rec_p)->recid == 'F') { goto addnewnm; }; if ((char unsigned)(*wdsct_p)->wnxtn == 0xff) { goto procrel; }; if ((*wdsct_p)->wnxtn != (*wdsct_p)->wnamen) { goto globeror; }; (*wdsct_p)->wnxtn='\xff'; (*wdsct_p)->nameadrs.wlastnma = (*wdsct_p)->nameadrs.wcurnma; (*wdsct_p)->nameadrs.wcurnma = (*wdsct_p)->nameadrs.wnamela; goto procrel; printf("pairs-num in params ne num of names\n"); goto abend; (*wdsct_p)->nameadrs.wnamela = 0; printf("pairs-num in params is zero\n"); r15 = 7; hrc = r15; goto return; if (*(char*)&(*rec_p)->recid == recdinc) { goto addrelt; }; printf("pairs-invalid code in the input record\n"); goto abend; r8 = (*wdsct_p)->nameadrs.wcurnma; r8 += namelsln; memcpy(&(*namelist_p)->namels.namef,&(*rec_p)->name1,8); (*namelist_p)->namels.startcon = 0; (*wdsct_p)->nameadrs.wcurnma = r8; r1 = (*wdsct_p)->wnxtn; r1 += 1; (*wdsct_p)->wnxtn = r1; memcpy(&(*wdsct_p)->wrecout,&(**rec_p),recleng); fprintf(outrec,"%28.28s\n",&(*wdsct_p)->wrecout); goto return; printf("ABEND 22 (??)\n"); return 22; memcpy(&(*wdsct_p)->wtname,&(*rec_p)->name2,8); if ((lrc = findseqn())) { return(lrc); } r1 = (*wdsct_p)->wcurcona; *(int *)((char*)r1 + 0) = r8; r8 = (*wdsct_p)->nameadrs.wcurnma; if(memcmp(&(*namelist_p)->namels.namef,&(*rec_p)->name1,8) == 0){ goto nextcon; } r8 += namelsln; (*namelist_p)->namels.startcon = r1; if(memcmp(&(*namelist_p)->namels.namef,&(*rec_p)->name1,8) == 0){ goto nextcon; } memcpy(&(*wdsct_p)->wtname,&(*rec_p)->name1,8); if ((lrc = findseqn())) { return(lrc); } (*namelist_p)->namels.startcon = r1; r1 += 4; (*wdsct_p)->wcurcona = r1; (*wdsct_p)->nameadrs.wcurnma = r8; goto return; r2 = 1; r3 = (*wdsct_p)->wnamen; r3 += 1; r5 = r2; r5 += r3; {int sign= r5 & 0x80000000;r5 = 0x7fffffff & r5;r5 >>= 1;r5 = sign | r5;} r8 = r5; r8--; r8 *= namelsln; r8 = r8 + (*wdsct_p)->nameadrs.w1namea; if(memcmp(&(*wdsct_p)->wtname,&(*namelist_p)->namels.namef,8) != 0){ goto fs020; } return; /*No Next Commands */ r3 = r5; goto fs040; r2 = r5 + 1; if (r3 > r2) { goto fs010; }; memcpy(&errname,&(*wdsct_p)->wtname,8); if ((lrc = wtoernm())) { return(lrc); } goto abend; printf("pairs-start of term process\n"); r10 = parmaddr_a; if((*wdsct_p)->nameadrs.wnamela == 0) goto return; r1 = (*wdsct_p)->wcurcona; r8 = (*wdsct_p)->nameadrs.wcurnma; (*namelist_p)->nxtstcon = r1; r8 = (*wdsct_p)->nameadrs.wnamela; (*wdsct_p)->wheadnma = r8; r4 = (*wdsct_p)->wubveca; r5 = (*wdsct_p)->wubvecl; r7 = 0; {char pad = *((char*)&r4 + 3);memset(r4,pad,r5);memcpy((char *)r4,r6,r7);} r8 = (*wdsct_p)->wheadnma; r8 += namelsln; if (r8 > (*wdsct_p)->nameadrs.wlastnma) { goto freearea; }; (*wdsct_p)->wheadnma = r8; (*wdsct_p)->nameadrs.wcurnma = r8; memcpy(&(*wdsct_p)->wrecout.name1o,&(*namelist_p)->namels.namef,8); *(char *)&((*wdsct_p)->wrecout.recido) = recdinco; r8 = 1; (*wdsct_p)->wlevel = r8; *(char *)&((*wdsct_p)->wgosign) = sstart; r8 = (*wdsct_p)->nameadrs.wcurnma; if (((*wdsct_p)->wgosign & sup) != 0){ goto goright; } r3 = r8; r3 = r3 - (int)(*wdsct_p)->nameadrs.w1namea; r2 = 0; llIns = (r2*0x100000000 + r3); r2 = llIns % namelsln; r3 = llIns / namelsln; r2 = 0; llIns = (r2*0x100000000 + r3); r2 = llIns % 8; r3 = llIns / 8; r6 = (*wdsct_p)->wubveca; r6 += r3; r15 = 0x80; r15 = (unsigned)r15 >> (r2 + 0); *((char*)&(*wdsct_p)->wbyte) = (unsigned int)r15 << 24 >> 24; (*wdsct_p)->wbyte = (*wdsct_p)->wbyte & *((char*)r6 + 0); if((*wdsct_p)->wbyte != 0) goto goright; *((char*)&(*wdsct_p)->wbyte) = (unsigned int)r15 << 24 >> 24; *((char*)r6 + 0) = *((char*)r6 + 0) | (*wdsct_p)->wbyte; if (((*wdsct_p)->wgosign & (sright + +sdown)) == 0){ goto godown; } memcpy(&(*wdsct_p)->wrecout.name2o,&(*namelist_p)->namels.namef,8); r15 = (*wdsct_p)->wlevel; decNumberFromInt32(&decNmbIns,r15); decPackedFromNumber(&(*wdsct_p)->dtwd,8,&resscale,&decNmbIns); decPackedToNumber((char*)(*wdsct_p)->dtwd + +4,4,&resscale,&decNmbIns); decNumberToString(&decNmbIns,&strIns); sprintf((*wdsct_p)->wrecout.nestlevl,"%08s",strIns); fprintf(outrec,"%28.28s\n",&(*wdsct_p)->wrecout); if((*namelist_p)->namels.startcon == 0) goto goright; if ((*namelist_p)->nxtstcon <= (*namelist_p)->namels.startcon) { goto goright; }; (*namelist_p)->namels.curcon = (*namelist_p)->namels.startcon; memcpy(&(*namelist_p)->namels.parencon,&(*wdsct_p)->wparent,4); (*wdsct_p)->wparent = r8; r8 = (*namelist_p)->namels.startcon; r8 = *(int *)((char*)r8 + 0); (*wdsct_p)->nameadrs.wcurnma = r8; *(char *)&((*wdsct_p)->wgosign) = sdown; r3 = (*wdsct_p)->wlevel; r3 += 1; (*wdsct_p)->wlevel = r3; goto loopname; if ((*wdsct_p)->wlevel == 1) { goto loophead; }; r8 = (*wdsct_p)->wparent; r5 = (*namelist_p)->namels.curcon; r5 += 4; if (r5 >= (*namelist_p)->nxtstcon) { goto goup; }; (*namelist_p)->namels.curcon = r5; r5 = *(int *)((char*)r5 + 0); (*wdsct_p)->nameadrs.wcurnma = r5; r8 = r5; *(char *)&((*wdsct_p)->wgosign) = sright; goto loopname; (*wdsct_p)->nameadrs.wcurnma = r8; memcpy(&(*wdsct_p)->wparent,&(*namelist_p)->namels.parencon,4); *(char *)&((*wdsct_p)->wgosign) = sup; r8 = (*wdsct_p)->wlevel; r8--; (*wdsct_p)->wlevel = r8; goto loopname; r1 = (*wdsct_p)->nameadrs.wnamela; r0 = (*wdsct_p)->wtotsz; free(r1); return;
The resulting code has the worst of both worlds: it may be legal C, but it isn't idiomatic C. There are no subroutine boundaries anywhere, let alone subroutines with parameters; it is just one giant code blob. The code is littered with gotos making it extremely hard to follow; it even starts with a goto. Register names (r3 r5 r8 etc.) are used showing the codes's assembler roots directly. Worse, note that many assignments to register names are actually useless ("dead"); the result of the assignment isn't actually used and a few lines further down that same register is assigned again. used. There are egregious casts everywhere, which tells us the translator doesn't really understand the types of the variables.
No justification for why this translator produces this result is provided by Soukhman. We can only surmise this is the best they can do with the migration technology they have. To be fair, the author explicitly claims "It is not a fully automated tool. That means after the tool runs, some programmer must clean it up... with very few clues as to what it does. How will she accomplish that?
Showing this code to potential new hires with Java skills will surely drive them away. This loses the "maintainability improvement" and "ease of finding new staff" gains one hopes to gain with a migration; if these are not obtained, where are the real long term cost savings?
While we agree with intention of preserving application functionality during a migration (otherwise, how will you know the migration was successful?), we disagree that this approach achieves the actual goal of maintainable, equivalent code.
If you think the code converted-to-C code is ugly, be sure to
look at what this tool vendor produces when converting to Java. What Java concept does
d.setAsmDsect(EnumAsmRegister.R15,iDM);
(near line A00116) represent?
An example HLASM Migration you might want can be found here.