It is simpler to write a macro which supports both signed and unsigned halfword 
values by using an assembly-time expression to adjust it into range, without 
the macro needing to be able to evaluate the operand.

In general, you can transform an n-bit unsigned or signed expression to the 
equivalent signed value by subtracting 2**n if the value is greater than or 
equal to 2**(n-1), using integer division for the comparison.  The only 
complication is that you need to include the value twice in the expression (and 
surround it with parentheses if the value may be specified as an expression and 
operator priority could cause incorrect results).

For example, for a 16-bit value expression &V which may be either signed or 
unsigned, you can use the following:

(&V-((&V)/X'8000')*X'10000')

Note however that out-of-range values will not be detected and could give 
unexpected results.

Jonathan Scott

-----Original Message-----
From: IBM Mainframe Assembler List <ASSEMBLER-LIST@LISTSERV.UGA.EDU> On Behalf 
Of Mark Hammack
Sent: 05 September 2025 21:50
To: ASSEMBLER-LIST@LISTSERV.UGA.EDU
Subject: Re: Execute-Type Instructions

Color me ignorant, but if I’m reading this correctly, in your fist paragraph, 
you use signed halfwords but in the second paragraph, it’s more like signed 
fullwords. So C’FU’ would be X’C6E4’or -14,620. As such, wouldn’t you want to 
subtract X’8000’?

I’m looking at implementing MVHUI (move halfword unsigned) and came up with 
this construct (have not tested yet):


&raw SETA &OP2
.compute Anop ,
&neg SetB (&raw gt 32767)
Aif (not &neg).setconst
&raw SetA (&raw or X’7FFF’)
.setconst Anop ,
MVHHI &OP1,&raw
Aif (not &neg).mend
OIY &OP1,X’80’
.mend Anop ,

*Mark Hammack*
mark.hamm...@gmail.com
214-478-0955 (c)


On Mon, Aug 25, 2025 at 11:52 AM Jonathan Scott < 
00001b5498fc732f-dmarc-requ...@listserv.uga.edu> wrote:

> Halfword signed immediate operands outside the range -32768 to 32767 
> are only tolerated by HLASM when normal checking is disabled using the 
> options
> TYPECHECK(NOSIGNED) or, worse, TYPECHECK(NOMAGNITUDE).  As that can 
> lead to accidents, it is not recommended.
>
> This applies to C'FU', C'LL' and 48000 in the following examples.  
> They can all be made valid by subtracting X'10000', and it is possible 
> to write an expression that will automatically apply that correction 
> when necessary, even for a symbolic value, so it is possible to write 
> a macro which is an unsigned equivalent of MVHHI, provided that the 
> value does not exceed 65535.
>
> And truncation of 65537 to 1 for an immediate operand is only 
> tolerated by HLASM when TYPECHECK(NOMAGNITUDE) is specified.
>
> Of course, there is no such check on what a compiler can generate in 
> binary; if it chooses to list generated instructions as assembler 
> which contains values that are technically out of range, that won't 
> affect the results.
>
> I agree a shift operator in assembler expressions would be useful 
> (along with some other functions and operators).  It was still on the 
> list when I retired, mainly because operators are converted to 1-byte 
> internal codes and there were no free values left in the encoding 
> scheme, so it would have needed a major design change.  Shift 
> functions are available in the macro language, but can only be used if 
> the value is known at macro time.
>
> Jonathan Scott
>
> -----Original Message-----
> From: IBM Mainframe Assembler List <ASSEMBLER-LIST@LISTSERV.UGA.EDU> 
> On Behalf Of Ngan, Robert (DXC Luxoft)
> Sent: 25 August 2025 17:20
> To: ASSEMBLER-LIST@LISTSERV.UGA.EDU
> Subject: Re: Execute-Type Instructions
>
> You would use MVHI where appropriate, but the MVHI immediate operand 
> is a SIGNED halfword, so:
>
>           MVC   XL4a,=C'FULL'
>
> would be coded as:
>
>           MVHHI XL4a+0,C'FU'
>           MVHHI XL4a+2,C'LL'
>
> And:
>
>           MVC   XL4b,=F'48000'
>
> would be coded as:
>
>           MVHHI XL4a+0,0
>           MVHHI XL4a+2,48000
>
> And:
>
>           MVC   XL4b,=F'65537'
>
> would be coded as:
>
>           MVHHI XL4a+0,65537>>16             i.e. 1
>           MVHHI XL4a+2,65537                    which HLASM conveniently
> truncates to 1 for us
>
> There no actual SHIFT operator, so (in general) this is implemented as 
> an arithmetic expression.
>
> Robert Ngan
> DXC Lusoft
>
> -----Original Message-----
> From: IBM Mainframe Assembler List <ASSEMBLER-LIST@LISTSERV.UGA.EDU> 
> On Behalf Of João Reginato
> Sent: Saturday, August 23, 2025 07:53
> To: ASSEMBLER-LIST@LISTSERV.UGA.EDU
> Subject: RES: Execute-Type Instructions
> Importance: Low
>
> [Algumas pessoas que receberam esta mensagem geralmente não receberão 
> emails de 00001deb39c13de1-dmarc-requ...@listserv.uga.edu. Saiba por 
> que isso é importante em https://aka.ms/LearnAboutSenderIdentification 
> ]
>
> Why not just one MVHI instead of two MVHHI?
>
> -----Mensagem original-----
> De: IBM Mainframe Assembler List <ASSEMBLER-LIST@LISTSERV.UGA.EDU> Em 
> nome de Jon Perryman Enviada em: sábado, 23 de agosto de 2025 00:12
> Para: ASSEMBLER-LIST@LISTSERV.UGA.EDU
> Assunto: Re: Execute-Type Instructions
>
> On Fri, 22 Aug 2025 17:00:33 +0000, Ngan, Robert <robert.n...@dxc.com>
> wrote:
>
> >I noticed the COBOL compile generated two MVHHI's to set a fullword 
> >field with a constant value, but did an MVC with an 8-byte constant 
> >when setting two adjacent fullwords.
>
> This makes sense because data is in the pipeline instead of moving from L1.
>
> With inline constants, you eliminated the extra fetch from storage. 
> Ask yourself if it's worth the effort to eliminate the extra L1 
> access. You're running C, Java, Python and ??? where you can save a 
> few dollars instead of a few penniess.
>

Reply via email to