UASM 2.35 is available for download.
Changes (and there are a lot!):
1) Fixed a memory leak in symbol table.
2) Fixed UASM32 crash with listing output , as per other thread details.
3) Improved several SystemV prologue and epilogue generation options.
4) Further refactoring and optimisation of all code-paths for the handling of prologue and epilogue.
5) Optimisation of UASM32 executable and changed compiler+settings.
6) We've implemented a completely new handling for movq and vmovq. It has never worked properly since Jwasm, it appears that due to the various operands and addressing modes the standard instruction tables can't deal with it properly so we've cased this one specially to handle all the various options, test piece:
vmovq xmm0,xmm1
movq xmm0,xmm1
movd xmm0,ecx
vmovd xmm0,ecx
movq xmm0,rcx
mov eax,1.0
vmovd xmm0,eax
vpshufd xmm0,xmm0,0
mov eax,2.0
vmovd xmm1,eax
vpshufd xmm1,xmm1,0
vmovq xmm0,rcx
movq xmm0, qword ptr [rcx]
vmovq xmm0, qword ptr [rcx]
movq qword ptr [rcx], xmm0
vmovq qword ptr [rcx], xmm0
movd xmm0, dword ptr [rcx]
vmovd xmm0, dword ptr [rcx]
vmovd [rsi+28], xmm8
vmovq [rsi+28], xmm9
vmovd dword ptr [rsi+28], xmm11
vmovq qword ptr [rsi+28], xmm7
Interestingly, the Intel manuals don't list a MOVQ or VMOVQ xmmN, xmmN mode, but the AMD manuals do, and it works as you would expect moving the lower qword and zero'ing the upper bits.
7) String literals have be brought back in, but to ensure compatibility they must be enabled with OPTION LITERALS:ON (this can be turned off again as required).
Further to this, string literals will only be implemented in an invoke IFF the corresponding procedure argument type is :PTR (this conform with WinInc and LPSTR etc).
This allows a procedure to work as follows:
MyProc PROTO :DWORD, :BYTE, :PTR
invoke MyProc, "abcd", 'a', "This is a literal string"
and the same applies for wide character string literals with L"".
8) PROTOS and PROCS can now have a return type specified (if omitted the default for OS/ABI + wordsize is selected). This is totally backwards compatible and has no impact on existing code, however it opens up some useful new options:
8.1) There is a new built-in variable now @LastReturnType, this is set each time an INVOKE happens to track the return type.
8.2) This has now also allowed the creation of a new macro in the macro library UINVOKE which can automatically determine and utilize the correct EXITM based on the return type:
vcmpss xmm0, UINVOKE(myfuncR4, xmm2), xmm1, 0
mov eax, uinvoke(myfuncD, xmm2)
cmp rbx, uinvoke(myfuncQ, xmm3)
vmovaps xmm0, uinvoke(myfuncX, xmm2)
8.3) Return types are specified as follows:
myfuncR4 PROTO REAL4 :REAL4
myfuncD PROTO DWORD :REAL4
myfuncR4 PROC REAL4 FRAME a:REAL4
xor rax,rax
vmovss xmm0,a
ret
myfuncR4 ENDP
myfuncD PROC DWORD FRAME a:REAL4
xor rax,rax
invoke myfuncQ, xmm0
ret
myfuncD ENDP
The return type can be any supported data-type that would normally be applicable for a return type under the ABI (BYTE, SBYTE, WORD, SWORD, DWORD, SDWORD, QWORD, SQWORD, PTR, REAL4, REAL8, __M128, __m256, __m512, xmmword, oword, ymmword, zmmword ).
The type must be specified on the proto immediately before the parameters but without a name or colon.
On the PROC it should be declared after the language specifier, before FRAME, USES.
9) Several new functions have been added to the macro library:
ASFLOAT, ASDOUBLE, R4P, R8P which all generate something equivalent to: EXITM <REAL4 PTR reg> and this provides additional functionality for point 10.
10) HLL directives now fully support floating point comparisons, examples:
.if(xmm0 < FP4(1.5))
xor eax,eax
.endif
.if(xmm0 > FP4(2))
xor eax,eax
.endif
.if(xmm0 < floatvar1)
xor eax,eax
.endif
.if(xmm0 == floatvar2)
xor eax,eax
.endif
.if(xmm0 < [rdx])
xor eax,eax
.endif
.if(xmm0 == [rdx+rbx])
xor eax,eax
.endif
.if(xmm0 < xmm1)
xor eax,eax
.endif
.if(xmm0 > xmm1)
xor eax,eax
.endif
.if(xmm0 <= xmm1)
xor eax,eax
.endif
.if(xmm0 == xmm3)
xor eax,eax
.endif
.if(real4 ptr xmm0 < xmm1)
xor eax,eax
.endif
.if(xmm0 < real4 ptr xmm1)
xor eax,eax
.endif
.if(asfloat(xmm0) < xmm1)
xor eax,eax
.endif
LOADSD xmm0, 1.0
LOADSD xmm1, 2.0
LOADSD xmm3, 1.0
.if(xmm0 < doublevar1)
xor eax,eax
.endif
.if(xmm0 == doublevar2)
xor eax,eax
.endif
.if(real8 ptr xmm0 < FP8(1.5))
xor eax,eax
.endif
.if(xmm0 < real8 ptr FP8(1.5))
xor eax,eax
.endif
.if(real8 ptr xmm0 < xmm1)
xor eax,eax
.endif
.if(real8 ptr xmm0 > real8 ptr xmm1)
xor eax,eax
.endif
.if(real8 ptr xmm0 <= xmm1)
xor eax,eax
.endif
.if(xmm0 == real8 ptr xmm3)
xor eax,eax
.endif
.if(xmm0 == asdouble(xmm3))
xor eax,eax
.elseif(xmm0 > asdouble(xmm2))
xor eax,eax
.endif
LOADSS xmm0,1.0
LOADSS xmm1,2.0
.while(xmm0 < xmm1)
vaddss xmm0,xmm0,FP4(0.1)
.endw
Cheers!
John