The MASM Forum

64 bit assembler => UASM Assembler Development => Topic started by: dstanfill on August 31, 2016, 09:40:45 AM

Title: Operand types with AVX instructions
Post by: dstanfill on August 31, 2016, 09:40:45 AM
I am working on getting a quite large, quite popular project written in MASM working with HJWASM. I'm running into a discrepancy with accepted argument types.

MASM accepts both of the following as valid and works as expected.
(SUBPD xmm1, xmm2/m128)
subpd xmm1, QWORD PTR memaddr
(SUBSD xmm1, xmm2/m64)
subsd xmm2, QWORD PTR memaddr

In the actual program these are defined as

XPTR  EQU <QWORD PTR>
XMM_BIGVAL EQU XPTR [basemem+offset]

subsd xmm1, XMM_BIGVAL
...
subpd xmm1, XMM_BIGVAL

HJWASM gets upset with a nice Error A2049: Invalid instruction operands. I can fix the subpd by changing XPTR to a XMMWORD PTR, however subsd will throw an error there.

Is there some flag or magic I can use to make HJWASM complain less and behave like MASM in this case (treat all as memory pointers of the right size despite type being QWORD PTR)? Currently I am using hjwasm -elf64 -c -Zm -Zf on Linux x64
Title: Re: Operand types with AVX instructions
Post by: jj2007 on August 31, 2016, 10:56:05 AM
You might try this option:-Zg Generated code is to exactly match Masm's one
Hope it helps - the HJWasm crew seems on holidays.

Other things to try:
OWORD ptr
movlps xmm0, qword ptr [mem]   ; with movhps, often faster than a movupd
Title: Re: Operand types with AVX instructions
Post by: rrr314159 on August 31, 2016, 01:01:19 PM
Do you have the latest HJWASM? It had a problem like this about a year ago: insisting on a prefix, XMMWORD PTR, that ML64 didn't require. Habran fixed it about 6 months ago, IIRC. I'm not quite sure it's the same problem you have, but it was similar. Don't know if the Linux version was also fixed. Try the latest version. If that doesn't help recommend you PM habran, or the rest of the crew.
Title: Re: Operand types with AVX instructions
Post by: hutch-- on August 31, 2016, 01:08:13 PM
ML64 does require the full data size definition on YMM registers.


    vmovntdqa ymm0, YMMWORD PTR [rcx+r10]
    vmovntdq YMMWORD PTR [rdx+r10], ymm0


Is it only an issue of typing ?
Title: Re: Operand types with AVX instructions
Post by: johnsa on August 31, 2016, 09:04:13 PM
I wish we were on holiday! :)

We're busy finalizing v2.15 of HJWASM.. hence being so quiet.

We've fixed the eip/rip related bug that was mentioned on the forums but the bulk of the work has been around implementing VECTORCALL calling convention and standardized simd types.
I'll have a look at this issue and if something crops up that requires attention we'll squeeze it into 2.15
Title: Re: Operand types with AVX instructions
Post by: johnsa on August 31, 2016, 09:18:55 PM
ok,

I've gone through all the scenarios I can think of testing this using the latest hjwasm source and this works perfectly:



.data
        aDouble REAL8 1.0
bDouble REAL8 2.0
XPTR equ <QWORD PTR>
align 16
aVec dq 2 DUP (0)
bVec __m128i <0,0,0,0>

.code
vmovsd xmm0,aDouble
vmovsd xmm1,bDouble
vsubsd xmm1,xmm1,aDouble
vsubsd xmm1,xmm1,qword ptr bDouble
vsubsd xmm1,xmm1,XPTR bDouble
XMEM equ XPTR bDouble+0
vsubsd xmm1,xmm1,XMEM
vmovaps xmm0,aVec
vmovaps xmm1,bVec
XMEM2 equ XPTR aVec+8
vsubsd xmm1,xmm1,XMEM2
XMEM3 equ XPTR aVec+0
XMEM4 equ XPTR bVec+0
vmovaps xmm0,XMEM4
vsubpd xmm0,xmm0,XMEM3

movsd xmm0,aDouble
movsd xmm1,bDouble
subsd xmm1,aDouble
subsd xmm1,qword ptr bDouble
subsd xmm1,XPTR bDouble
XMEM5 equ XPTR bDouble+0
subsd xmm1,XMEM5
movaps xmm0,xmmword ptr aVec
movaps xmm1,bVec
XMEM6 equ XPTR aVec+8
subsd xmm1,XMEM6
XMEM7 equ xmmword ptr aVec+0
XMEM8 equ bVec+0
movaps xmm0,XMEM8
subpd xmm0,XMEM7



So this should be working for you with 2.14 ?

one note however, this line of yours should give you a problem:
subpd xmm1, XMM_BIGVAL

subpd expects a full xmm sized source,

XPTR  EQU <QWORD PTR>
XMM_BIGVAL EQU XPTR [basemem+offset]

is going to land up giving you:

qword ptr [basemem+offset] which will work perfect for subSD, but not for PD.
Title: Re: Operand types with AVX instructions
Post by: dstanfill on August 31, 2016, 10:21:18 PM
I pulled down and built from latest git source, version says 2.14.

This is the version that works in ml64

XPTR EQU <QWORD PTR>
XMM_BIGVAL EQU XPTR [mem+offset]

; This works
subpd xmm1, XMM_BIGVAL

; This works also
subsd xmm1, XMM_BIGVAL

However in HJWASM latest (tried -Zg with no effect)
; Try QWORD
XPTR EQU <QWORD PTR>
XMM_BIGVAL EQU XPTR [mem+offset]

; This fails
subpd xmm1, XMM_BIGVAL

; This works
subsd xmm1, XMM_BIGVAL

-------------------------------------------

; Try XMMWORD
XPTR EQU <XMMWORD PTR>
XMM_BIGVAL EQU XPTR [mem+offset]

; This works
subpd xmm1, XMM_BIGVAL

; This fails
subsd xmm1, XMM_BIGVAL


Title: Re: Operand types with AVX instructions
Post by: johnsa on August 31, 2016, 10:38:00 PM
That's completely correct!

you can't execute a packed vector subtraction against a qword, it has to be an xmmword either by declaration/type or via forced type reference.
In this case ML64 is wrong in that it's not warning about the incompatible type.

I have noted however that the vex forms (prefixed with v) will allow it and override the type.
I'll see if I can apply this to the sse forms as well.. even though it's technically wrong and it makes me feel dirty doing it :)
Title: Re: Operand types with AVX instructions
Post by: dstanfill on August 31, 2016, 10:50:51 PM
Oh I agree it makes logical sense, unfortunately the program I am working on is several hundreds of thousands of lines and made quite frequent use of this quirk in ml64. The code definitely works, so I was wishing for a MASM compatibility mode.

I understand saying it is completely correct to deny subpd to deference a QWORD as m128, however I could see allowing subsd and company to dereference a XMMWORD PTR and only access the lower m64.

For me the alternative is a lot of work creating casted QWORD PTRs for several thousand places..

Is there any interest and allowing this behavior to match ml64, perhaps with -Zg? Or should I get to work?
Title: Re: Operand types with AVX instructions
Post by: johnsa on August 31, 2016, 10:52:55 PM
As I mentioned, it appears to allow it in HJWASM when using the vex encoded form:
vsubpd and vsubsd

So given that is already allowed I'll have a look and see if we can make it consistent and do the same for the SSE form.
(It's a bit of a fiddle because they're handled by different instruction tables).

I'll let you know if it's do-able and if so it will be in 2.15 (which should be available very shortly, as in a day or so once we've finalised the testing our side).
Title: Re: Operand types with AVX instructions
Post by: johnsa on September 02, 2016, 01:48:21 AM
Just to let you know we've got this in and working and setup to only be applied with -Zg switch on.
movaps, movups, addps, addpd, subps, subpd will now all automatically promote the memory reference to xmmword ptr regardless of the type.
This will be up shortly in 2.15
Title: Re: Operand types with AVX instructions
Post by: dstanfill on September 02, 2016, 03:57:23 AM
That is great news, thank you for getting that in there.

Hopefully that is the last issue of compatibility with this project.
Title: Re: Operand types with AVX instructions
Post by: rrr314159 on September 02, 2016, 07:12:18 AM
For those misguided souls who still cling to ML64, please contrast this response from the HJWasm team with Microsoft's responses to the user community. If, that is, you can find any.
Title: Re: Operand types with AVX instructions
Post by: FORTRANS on September 02, 2016, 07:34:46 AM
Hi,

Quote from: rrr314159 on September 02, 2016, 07:12:18 AM
For those misguided souls who still cling to ML64, please contrast this response from the HJWasm team with Microsoft's responses to the user community. If, that is, you can find any.

   Noted.  Kudos to the team.

Regards,

Steve N.
Title: Re: Operand types with AVX instructions
Post by: hutch-- on September 02, 2016, 09:14:20 AM
 :biggrin:

> For those misguided souls who still cling to ML64, please contrast this response from the HJWasm team with Microsoft's responses to the user community. If, that is, you can find any.

With no deference to the HJWASM team, note that MASM has been around since 1982 and is still current with the most recent version dating 2015. Assembler come and assemblers go but MASM just keeps on going.  :P
Title: Re: Operand types with AVX instructions
Post by: jj2007 on September 02, 2016, 09:28:46 AM
Quote from: hutch-- on September 02, 2016, 09:14:20 AMMASM has been around since 1982 and is still current

"Current" but suffering from Alzheimer's disease: It has forgotten invoke, .if, .Repeat, .While, ...
Title: Re: Operand types with AVX instructions
Post by: hutch-- on September 02, 2016, 09:49:30 AM
 :biggrin:

These are the joys of the archetypal MACRO assembler, write your own. There was a time once long ago when MEN[tm] wrote in a real assembler when an assembler was a bad mannered, terse buggy pig that screwed mnemonics together if you got it right. Truly ML64 continues in that tradition but then it was written for assembler programmers who did not need anyone to hold their hot little hand and help them through their many indiscretions.  :P
Title: Re: Operand types with AVX instructions
Post by: jj2007 on September 02, 2016, 10:07:45 AM
Quote from: hutch-- on September 02, 2016, 09:49:30 AMa bad mannered, terse buggy pig that screws mnemonics together

So true :t

Here, a famous assembly programmer expresses it in different, more modern words: (http://www.masmforum.com/board/index.php?topic=13389.msg104791#msg104791)
QuoteThe old brigade with crude mnemonic crunching as some notion of purity left assembler in a shambles, near abandoned and ridiculed in the programming community. The pseudo high level stuff in MASM resurrected it from the dead and made it a living language again. Most would not write C like they did in the middle 80s yet they expect you to write assembler in the way that people cobbled together a few DOS interrupts 25 years ago.

I fully agree with that view 8)
Title: Re: Operand types with AVX instructions
Post by: hutch-- on September 02, 2016, 10:45:33 AM
 :biggrin:

I think you would have needed to have seen the crap that was being cobbled together by the majority in the late 80s, early 90s. There were a few exceptions with very good code but most was trash cobbled together with a few DOS interrupts to patch up defects in the compilers of the time. The last Microsoft COMMAND.COM was well done as was Keith P. Graham's BAT2EXEC but they were exceptions.
Title: Re: Operand types with AVX instructions
Post by: rrr314159 on September 03, 2016, 02:22:20 AM
Quote from: hutch-- on September 02, 2016, 09:49:30 AMThere was a time once long ago when MEN[tm] wrote in a real assembler

In the modern era, MEN[tm] use FASM. The BOY[tm]'s spend half their time using ML64 or HJWasm, the other half is spent debating which is best.
Title: Re: Operand types with AVX instructions
Post by: hutch-- on September 03, 2016, 09:19:04 AM
 :biggrin:

I am sure you would be fluent in all of these to make the comparison.
Title: Re: Operand types with AVX instructions
Post by: rrr314159 on September 03, 2016, 10:50:30 AM
Wrong again! As a beginner I tried FASM and could see it's an excellent tool. However the community just didn't seem interested in supporting an ignorant novice. Then I found masm32.com, where support for beginners (and, in fact, experts also) is far superior, and never looked back. Like you, I've always wanted to check out FASM more seriously someday but there's only so much time one can spend on this sort of thing. I have the vague impression FASM might be the best assembler, but don't actually know that. ML / HJWasm family is good enough for the likes of me, anyway.
Title: Re: Operand types with AVX instructions
Post by: hutch-- on September 03, 2016, 11:52:39 AM
I am inclined to recognise difference rather than notions of better or worse when it comes to various assemblers. I know for certain that FASM is a very good tool, well written, reliable and powerful, the only problem I have with it is that I come from an Intel notation MASM background where FASM uses closer to a TASM style of notation so its a matter of familiarity rather than better or worse.

There are a number of assemblers I like, the GNU AS (GAS) with Intel notation is a good tool close to the running boards, Pelle's POASM works fine but I don't have the time to relearn all of the differences with its macro engine, JWASM could have been a good tool if Japheth had not abandoned it and John and Habran's HJWASM looks like it will be a decent assembler when its finished and supported properly. Much the same comment on Nidud's fork of JWASM.

Some wonder why I have chosen to work with a pig like ML64.EXE and the answer is simple, its a familiar pig with the same 1990 quirky buggy macro engine and while it comes unconfigured like the assemblers of old, with enough work it has an invoke macro that works correctly, a prologue that is reliable and with Vasily's many macros, it has the .IF notation so it can do whatever you need with x64.

Some assume that ML.EXE was easy to work with but in 1997 when Iczelion and I started working on it, it was a ridiculed, badly documented, bad mannered pig that few bothered with. It took a lot of work to get it up and going but it wiped TASM out because it was fundamentally a better tool and was properly supported. What I would like to see with both John and Habran's assembler AND Nidud's fork is a user base that actually got off its arse and contributed the necessary support to get them up and going for a wider community to use. MASM will always have licence limitations as it is owned by Microsoft where the Watcom forks can be used by a wider audience including the "open sauce" gang.

They need documentation like help files, macros, a dedicated library, import libraries and code examples. and here a community could help, its just that most don't want to get off their arse and do any work.
Title: Re: Operand types with AVX instructions
Post by: rrr314159 on September 03, 2016, 12:43:24 PM
Quote from: hutch-- on September 03, 2016, 11:52:39 AMSome wonder why I have chosen to work with a pig like ML64.EXE and the answer is simple, its a familiar pig ...

You can't teach an old dog new tricks.

Quote from: hutch-- on September 03, 2016, 11:52:39 AMWhat I would like to see with both John and Habran's assembler AND Nidud's fork is a user base that actually got off its arse and contributed the necessary support to get them up and going for a wider community to use.

Good luck with that! It's got to be the laziest user base on the planet.
Title: Re: Operand types with AVX instructions
Post by: hutch-- on September 03, 2016, 01:32:19 PM
 :biggrin:

I have this irksome habit of writing my own luck, old dogs can write new tricks.  :P

Shame about that lack of support for HJWASM and Nidud's assembler, with the right support they are both good tools.
Title: Re: Operand types with AVX instructions
Post by: jj2007 on September 03, 2016, 06:19:24 PM
HJWasm and AsmC are both excellent tools, and 99.99% compatible with ML32. There is no reason to write anything specifically for them, just a bit of testing whether the macros work identically. MasmBasic has over 200 macros, they all work in the three assemblers.

With ML64, it's different, simply because HJWasm and AsmC are still excellent tools but their counterpart is a crippled child. It needs macros for elementary language elements like .if

Now, I am willing to concede that one could use a switch for that:
ifidni @Environ(oAssembler), <ML>
  .if MACRO args
  ENDM
endif


What I am not willing to accept is an invoke macro that can't control the number of parameters. This is essential for Windows.
Title: Re: Operand types with AVX instructions
Post by: johnsa on September 03, 2016, 06:56:03 PM

I've done quite a bit of work with FASM (mainly OS level dev stuff) and it is a good tool. For system level coding it's great, but as an assembler to use under Windows etc I find it to be a complete pain.

As much as I am a purist about assembler I also realise that for it be of much value in the broader sense it has to be as simple and practical as possible (especially when writing bigger projects), MASM32 + ML32 gave us that.. HJWASM for 64bit gives that same simplicity and convenience out of the box (plus a bunch of new things we're adding like vectorcall, improved unions, switch, namespaces etc).

Right now for me.. it is the only option, and I don't just say that because I happen to be supporting it :)

I think the work around a solid set of core libraries and includes is a fantastic idea, and I for one am happy to support such an effort in whatever flavour is best decided through democratic process (is there such a thing?)
:)
Title: Re: Operand types with AVX instructions
Post by: rrr314159 on September 03, 2016, 11:47:56 PM
Quote from: jj2007 on September 03, 2016, 06:19:24 PM
HJWasm and AsmC are both excellent tools, and 99.99% compatible with ML32. There is no reason to write anything specifically for them, just a bit of testing whether the macros work identically.

right

Quote from: jj2007With ML64, it's different, simply because HJWasm and AsmC are still excellent tools but their counterpart is a crippled child.

It can be "uncrippled" via creative use of Macros but hard to see why bother. Lack of support is even bigger problem, from my pov. With HJWasm even if the team goes away someday, I have the code and can (at least) read it to answer questions. MS, OTOH, is entirely capable of "updating" Windows someday to make it impossible to use ML without a fee of $10,000 / year and giving first-born child to Bill.

Quote from: jj2007What I am not willing to accept is an invoke macro that can't control the number of parameters. This is essential for Windows.

By "control number of parameters" you mean PROTO-checking? Why is that essential?

Quote from: johnsa on September 03, 2016, 06:56:03 PMI've done quite a bit of work with FASM (mainly OS level dev stuff) and it is a good tool. For system level coding it's great, but as an assembler to use under Windows etc I find it to be a complete pain.

Don't doubt you're right; I have almost no experience with FASM. But can you give a couple examples why it's a pain?

Quote from: johnsaHJWASM for 64bit gives that same simplicity and convenience out of the box (plus a bunch of new things we're adding like vectorcall, improved unions, switch, namespaces etc). I think the work around a solid set of core libraries and includes is a fantastic idea, and I for one am happy to support such an effort ...

Personally I don't care about namespaces and such. But I know many people love C++; to each his own. I think libraries, includes, boring stuff like that, is more important.

Quote from: johnsa... in whatever flavour is best decided through democratic process (is there such a thing?)

Unfortunately democracy simply doesn't work, except in special circumstances like small Swiss villages hundreds of years ago (or whatever). It would be great if everyone were on the same page and worked together, but getting a bunch of independent programmers on the net to cooperate is like herding cats. What's needed is a dictator with a lot of money who tells everyone what to do, and pays them for it. Ain't gonna happen.
Title: Re: Operand types with AVX instructions
Post by: jj2007 on September 04, 2016, 02:11:30 AM
Quote from: rrr314159 on September 03, 2016, 11:47:56 PMBy "control number of parameters" you mean PROTO-checking? Why is that essential?

Would you accept an assembler that from mow eox, someundefined var creates something for you without throwing error messages? Of course, RealMenTM would never commit such typos 8)

Why was invoke invented, if not for parameter checking?
Title: Re: Operand types with AVX instructions
Post by: hutch-- on September 04, 2016, 09:52:44 AM
 :biggrin:

> Why was invoke invented, if not for parameter checking?

Call automation, the type checking came as a bonus.
Title: Re: Operand types with AVX instructions
Post by: rrr314159 on September 04, 2016, 10:52:32 AM
Those who answer questions with questions are doomed to rot in the nth circle of Hell for eternity. Just thought I'd warn you :-)

Good error messages are very desirable. And since the parameter list of a typical function (API calls, not so much one's own functions) is known, and fixed (barring VARARG), then sure, makes sense to give an error if it's typed in wrong. But how much trouble is needed to provide that error message? PROTO's can be a hassle, as we all know.

To use a function like CreateWindowEx, one has to understand it quite thoroughly, consulting the MS documentation. There are many necessary conditions, only one of which is the number of parameters. All the rest of the info is much more important: what each parameter does, which calls must precede CreateWindow, and so forth. In C, with strong typing, there's more justification for checking parameters. For instance it might have a DWORD which could be a handle, an unsigned integer, real, whatever. If you're using a wrong type, that's likely to be an error. But asm just checks DWORD vs BYTE, etc, not very informative; and, of course, the number of them. Is this small amount of info worth the trouble of PROTO's? How can one understand the function well enough to use it, and not be able to count the parameters? And if you do put in an extra NULL, usually it just blows up in your face, so you know something's wrong.

Also, the vast majority of API calls have just zero, one, up to four maybe, parameters. Hardly worth checking.

Finally, probably the majority of API calls, in actual programming practice, are cut-and-pasted. Particularly complicated ones, like CreateWindow. In fact we cut-and-paste the entire section for Window creation, including calls before and after. The first time you use it, you must study it carefully, understand each parameter, and related functionality. Counting up to 12 is far less than 1% of the overall effort. Afterwards you'll probably just cut and paste this standard block of code.

I'm not against error checking "on principle". There isn't one right answer here. Has nothing to do with RealMan(TM)-hood. It's just a question whether the trouble of PROTO'ing is really worth the effort.

As for the rhetorical q, what's invoke for?: it's very convenient to line up the parameter list on one line instead of having to load up the stack (or r8, r9 etc) in the preceding lines. Back when it wasn't built-in everyone rolled their own invoke (or "mycall", whatever) macro, for this reason. There's also the other clauses, USES etc, that can be convenient.
Title: Re: Operand types with AVX instructions
Post by: jj2007 on September 04, 2016, 12:01:01 PM
Quote from: rrr314159 on September 04, 2016, 10:52:32 AMif you do put in an extra NULL, usually it just blows up in your face, so you know something's wrong.

Usually, LEAVE takes care of the stack, and will make sure that your USES does not what you expect it to do. It will be fun 8)


QuoteIt's just a question whether the trouble of PROTO'ing is really worth the effort.

Instead of whining about this incredible effort, have a look at \Masm32\MasmBasic\Res\pt.inc, line 151ff
Title: Re: Operand types with AVX instructions
Post by: rrr314159 on September 04, 2016, 10:02:37 PM
I avoid enter / leave, it can hide mistakes.

jj2007 wrote: "whining about this incredible effort"