Using the High Halfs of registers
Hello, I've inherited a large (31-bit) application with little documentation and lots and lots of BASRs to subprograms. I can't tell how deep the calls can go, but I've seen over 20 levels deep. I'm looking for a way to keep track of the stack level of a routine that doesn't add much code. There are standard $SAVE and $RETN macros I think I can use to keep track of the stack level. There are also a large number of $TRACE calls where I've added an IIHF statement in the macro to load a global counter (for the number of trace statements in that assembly--there are over 4000 of those in some cases). For example, IIHF R2,&ZTSEQ, where &ZTSEQ is a GLBLA incremented once each time the $TRACE macro is encountered. Sorry for all the background. What I'm looking for are "high-half" versions of LA and BCTR commands, so that the incrementing and decrementing could be done with 2 statements per CSECT--without affecting the low halves of the register. For example in 31-bit land if R2 was always available, I could say "LA R2,1(R2)" at the start of the modules, and "BCTR R2,0" at the end. In this case reg 2 would always be the stack level. I'd also need to keep the application compatible with z9 (OPCODE(ZS3)) or later machines. Can anyone tell me if such statements exist in OPCODE(ZS3)? I can't find them if they are there. TIA, Wendell Lovewell
Re: Using the High Halfs of registers
Unfortunately, a lot of the high half instructions come along (not surprisingly) with the "high-word facility" which is z196 and above. I've never used it, but Add Immediate High (AIH) looks like what you are looking for -- but it's high-word facility. How about the floating point registers? Could you use one of them to hold your depth code? I don't know the FP instruction set at all. I see a number of storage to register adds. I assume the problem here is that you have no spare 32-bit registers, so the otherwise unused high halves appealed? Charles -Original Message- From: IBM Mainframe Assembler List [mailto:ASSEMBLER-LIST@LISTSERV.UGA.EDU] On Behalf Of Wendell Lovewell Sent: Friday, October 27, 2017 4:32 PM To: ASSEMBLER-LIST@LISTSERV.UGA.EDU Subject: Using the High Halfs of registers Hello, I've inherited a large (31-bit) application with little documentation and lots and lots of BASRs to subprograms. I can't tell how deep the calls can go, but I've seen over 20 levels deep. I'm looking for a way to keep track of the stack level of a routine that doesn't add much code. There are standard $SAVE and $RETN macros I think I can use to keep track of the stack level. There are also a large number of $TRACE calls where I've added an IIHF statement in the macro to load a global counter (for the number of trace statements in that assembly--there are over 4000 of those in some cases). For example, IIHF R2,&ZTSEQ, where &ZTSEQ is a GLBLA incremented once each time the $TRACE macro is encountered. Sorry for all the background. What I'm looking for are "high-half" versions of LA and BCTR commands, so that the incrementing and decrementing could be done with 2 statements per CSECT--without affecting the low halves of the register. For example in 31-bit land if R2 was always available, I could say "LA R2,1(R2)" at the start of the modules, and "BCTR R2,0" at the end. In this case reg 2 would always be the stack level. I'd also need to keep the application compatible with z9 (OPCODE(ZS3)) or later machines. Can anyone tell me if such statements exist in OPCODE(ZS3)? I can't find them if they are there. TIA, Wendell Lovewell
Re: Using the High Halfs of registers
On 27 October 2017 at 19:31, Wendell Lovewell wrote: > ... > Sorry for all the background. What I'm looking for are "high-half" > versions of LA and BCTR commands, so that the incrementing and > decrementing could be done with 2 statements per CSECT--without affecting > the low halves of the register. For example in 31-bit land if R2 was > always available, I could say "LA R2,1(R2)" at the start of the modules, > and "BCTR R2,0" at the end. In this case reg 2 would always be the stack > level. > Add Immediate High (AIH). But when was it introduced...? There are no change bars in the -10 edition of the PofO, so before then. > I'd also need to keep the application compatible with z9 (OPCODE(ZS3)) or > later machines. > > Can anyone tell me if such statements exist in OPCODE(ZS3)? I can't find > them if they are there > Sorry - don't know. Tony H.
Re: Using the High Halfs of registers
On 27 October 2017 at 20:12, Charles Mills wrote: > Unfortunately, a lot of the high half instructions come along (not > surprisingly) with the "high-word facility" which is z196 and above. I've > never used it, but Add Immediate High (AIH) looks like what you are looking > for -- but it's high-word facility. Great minds, etc. > How about the floating point registers? Could you use one of them to hold > your depth code? I don't know the FP instruction set at all. I see a > number of storage to register adds. > Or if you aren't otherwise using them, put a 1 in an FPR on entry, and then use the RR instructions to add and subtract it. But of course unless you just want to be sure your counter is zero at appropriate times, you'll need to convert to integer. That's not hard, but then how much unfamiliar stuff would you be introducing for the next programmer? There's always old-style packed decimal. Storage to storage. Probably not as slow as one might expect, but certainly worse than RR or RI type instructions. Tony H.
Re: Using the High Halfs of registers
From: "Tony Harminc" Sent: Saturday, October 28, 2017 11:13 AM On 27 October 2017 at 19:31, Wendell Lovewell wrote: ... Sorry for all the background. What I'm looking for are "high-half" versions of LA and BCTR commands, so that the incrementing and decrementing could be done with 2 statements per CSECT--without affecting the low halves of the register. For example in 31-bit land if R2 was always available, I could say "LA R2,1(R2)" at the start of the modules, and "BCTR R2,0" at the end. In this case reg 2 would always be the stack level. Add Immediate High (AIH). But when was it introduced...? There are no change bars in the -10 edition of the PofO, so before then. Wouldn't it be necessary to clear the high half first? --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
Re: Using the High Halfs of registers
Well, depending on his exact logic, quite possibly yes. Charles -Original Message- From: IBM Mainframe Assembler List [mailto:ASSEMBLER-LIST@LISTSERV.UGA.EDU] On Behalf Of Robin Vowels Sent: Friday, October 27, 2017 6:26 PM To: ASSEMBLER-LIST@LISTSERV.UGA.EDU Subject: Re: Using the High Halfs of registers From: "Tony Harminc" Sent: Saturday, October 28, 2017 11:13 AM > On 27 October 2017 at 19:31, Wendell Lovewell > > wrote: > >> ... >> Sorry for all the background. What I'm looking for are "high-half" >> versions of LA and BCTR commands, so that the incrementing and >> decrementing could be done with 2 statements per CSECT--without >> affecting the low halves of the register. For example in 31-bit land >> if R2 was always available, I could say "LA R2,1(R2)" at the start >> of the modules, and "BCTR R2,0" at the end. In this case reg 2 >> would always be the stack level. >> > > Add Immediate High (AIH). But when was it introduced...? There are no > change bars in the -10 edition of the PofO, so before then. Wouldn't it be necessary to clear the high half first?
Re: Using the High Halfs of registers
According to the 2004 POO (SA22-7832-03), which I believe predates z9, you can: Simulate an LA to clear the high half contents of a register with ICMH Rx,15,=XL4(00) or NG Rx,=XL8() Simulate an LA to increment the count in the high half with AG Rx,=XL8(1) Simulate a BCTR to decrement the count in the high half with AG Rx,=X() > -Original Message- > From: IBM Mainframe Assembler List [mailto:ASSEMBLER- > l...@listserv.uga.edu] On Behalf Of Wendell Lovewell > Sent: Friday, October 27, 2017 4:32 PM > To: ASSEMBLER-LIST@LISTSERV.UGA.EDU > Subject: Using the High Halfs of registers > > Hello, > > I've inherited a large (31-bit) application with little documentation and > lots and lots of > BASRs to subprograms. I can't tell how deep the calls can go, but I've seen > over 20 levels > deep. I'm looking for a way to keep track of the stack level of a routine > that doesn't add > much code. There are standard $SAVE and $RETN macros I think I can use to > keep track > of the stack level. > > There are also a large number of $TRACE calls where I've added an IIHF > statement in the > macro to load a global counter (for the number of trace statements in that > assembly--there > are over 4000 of those in some cases). For example, IIHF R2,&ZTSEQ, where > &ZTSEQ is > a GLBLA incremented once each time the $TRACE macro is encountered. > > Sorry for all the background. What I'm looking for are "high-half" versions > of LA and > BCTR commands, so that the incrementing and decrementing could be done with 2 > statements per CSECT--without affecting the low halves of the register. For > example in 31- > bit land if R2 was always available, I could say "LA R2,1(R2)" at the start > of the modules, > and "BCTR R2,0" at the end. In this case reg 2 would always be the stack > level. > > I'd also need to keep the application compatible with z9 (OPCODE(ZS3)) or > later machines. > > Can anyone tell me if such statements exist in OPCODE(ZS3)? I can't find > them if they are > there.
Re: Using the High Halfs of registers
I believe those are all z Architecture instructions and should work on any z Architecture machine. NIHF might be your best bet for clearing the high half of a register: no storage access. Requires the extended-immediate facility, available on a z9. You could avoid the storage references on the AG's if you had a spare register. You could LHI R0,1/SLLG R0,R0,32/AGR r,R0 for example. Charles -Original Message- From: IBM Mainframe Assembler List [mailto:ASSEMBLER-LIST@LISTSERV.UGA.EDU] On Behalf Of retired mainframer Sent: Saturday, October 28, 2017 1:27 AM To: ASSEMBLER-LIST@LISTSERV.UGA.EDU Subject: Re: Using the High Halfs of registers According to the 2004 POO (SA22-7832-03), which I believe predates z9, you can: Simulate an LA to clear the high half contents of a register with ICMH Rx,15,=XL4(00) or NG Rx,=XL8() Simulate an LA to increment the count in the high half with AG Rx,=XL8(1) Simulate a BCTR to decrement the count in the high half with AG Rx,=X()
Re: Using the High Halfs of registers
Oh, and don't forget 1. IIRC some z/OS services may use (destroy, corrupt, whatever you want to call it) those high halves. Not certain of that -- perhaps Peter or someone will correct me. 2. OTOH it would be polite of you to save and restore your caller's high halves if relevant. IIRC the Assembler Services Guide has save area formats. Charles -Original Message- From: IBM Mainframe Assembler List [mailto:ASSEMBLER-LIST@LISTSERV.UGA.EDU] On Behalf Of Charles Mills Sent: Saturday, October 28, 2017 10:03 AM To: ASSEMBLER-LIST@LISTSERV.UGA.EDU Subject: Re: Using the High Halfs of registers I believe those are all z Architecture instructions and should work on any z Architecture machine. NIHF might be your best bet for clearing the high half of a register: no storage access. Requires the extended-immediate facility, available on a z9. You could avoid the storage references on the AG's if you had a spare register. You could LHI R0,1/SLLG R0,R0,32/AGR r,R0 for example. Charles -Original Message- From: IBM Mainframe Assembler List [mailto:ASSEMBLER-LIST@LISTSERV.UGA.EDU] On Behalf Of retired mainframer Sent: Saturday, October 28, 2017 1:27 AM To: ASSEMBLER-LIST@LISTSERV.UGA.EDU Subject: Re: Using the High Halfs of registers According to the 2004 POO (SA22-7832-03), which I believe predates z9, you can: Simulate an LA to clear the high half contents of a register with ICMH Rx,15,=XL4(00) or NG Rx,=XL8() Simulate an LA to increment the count in the high half with AG Rx,=XL8(1) Simulate a BCTR to decrement the count in the high half with AG Rx,=X()
Re: Using the High Halfs of registers
On 27 October 2017 at 21:26, Robin Vowels wrote: > From: "Tony Harminc" > Sent: Saturday, October 28, 2017 11:13 AM > > Add Immediate High (AIH). But when was it introduced...? There are no >> change bars in the -10 edition of the PofO, so before then. >> > > Wouldn't it be necessary to clear the high half first? > Yes - he mentioned IIHF for that in the original post. Tony H.
Re: Using the High Halfs of registers
All 64 bits of general registers 14, 15, 0, and 1, and the corresponding ARs are volatile across any call or service. This is just an extension of the ancient rule. No IBM service will modify any other register*, and called programs should certainly return all other registers unmodified, too. *: Subject, of course, to well-documented features, or bugs. sas
Re: Using the High Halfs of registers
Thanks Steve, Charles, Tony, Robin & especially "Retired". The application is spread out across 6000+ modules, and some are out of registers. Floating point would probably work, but I've never worked with them either. I'm already using the high half of Reg2, and it appears to be working out. "Retired" suggestion for AG was just what I needed. It didn't occur to me that I could add values with x'' for the low-half of the registers so it wouldn't affect their value.There are 20k calls, so even at 8 bytes each I may not be able to do it. But 8 bytes is probably as good as could be done. Thanks again! Wendell
Re: Using the High Halfs of registers
All 64 bits of general registers 14, 15, 0, and 1, and the corresponding ARs are volatile across any call or service. Actually, the linkage convention is that AR14 and the high half of GR14 are not volatile. That matches what the PR instruction accomplishes (having saved all the regs via BAKR or PC). Of course the high half of GR14 might have been used in the call linkage itself if using something like "BASR" in AMODE 64 to pass control. I won't claim, by the way, that all services meet this "high standard" with respect ot AR14/GR14, so it would be best not to rely much on such behavior, so in general assume that AR14 and all of GR14 are clobbered. Services such as GETMAIN (STORAGE OBTAIN) and FREEMAIN (STORAGE RELEASE) do meet the standard. Peter Relson z/OS Core Technology Design