uasm 1.0.9+2.57

A library to build the UASM compiler, for usage in build scripts.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
	.x64
	option casemap:none
	option win64:11
	option frame:auto
	option STACKBASE:RSP
	
	ExitProcess proto :DWORD

    includelib <kernel32.lib>
    includelib <user32.lib>


; Define an HVA 2 element structure.
; Both elements are 128bit XMM types.		
	hva2 struct
		a __m128f <>
		b __m128f <>
	hva2 ends

; Define an HVA 3 element structure.
; All elements are 128bit XMM types.	
	hva3 struct
		a __m128f <>
		b __m128f <>
		cc __m128f <>		
	hva3 ends

; Define an HVA 4 element structure.
; All elements are 128bit XMM types.	
	hva4 struct
		a __m128f <>
		b __m128f <>
		cc __m128f <>
		d __m128f <>
	hva4 ends

; Define an HVA 2 element structure.
; All elements are 256bit YMM types.	
	hva22 struct
		a __m256f <>
		b __m256f <>
	hva22 ends

; Define an HVA 4 element structure.
; All elements are 256bit YMM types.	
	hva42 struct
		a __m256f <>
		b __m256f <>
		cc __m256f <>
		d __m256f <>
	hva42 ends

; Define an HFA 2 element structure.
; All elements are floats.	
	hfa2 struct
		f0 real4 0.0
		f1 real4 0.0
	hfa2 ends

; Define an HFA 3 element structure.
; All elements are floats.
	hfa3 struct
		f0 real4 0.0
		f1 real4 0.0
		f2 real4 0.0
	hfa3 ends

; Define an HFA 4 element structure.
; All elements are floats.	
	hfa4 struct
		f0 real4 0.0
		f1 real4 1.0
		f2 real4 2.0
		f3 real4 3.0
	hfa4 ends

; Define an HFA 2 element structure.
; All elements are doubles.	
	hfa5 struct
		d0 real8 0.0
		d1 real8 0.0
	hfa5 ends

; Define an HFA 3 element structure.
; All elements are doubles.
	hfa6 struct
		d0 real8 0.0
		d1 real8 0.0
		d2 real8 0.0
	hfa6 ends

; Define an HFA 4 element structure.
; All elements are doubles.	
	hfa7 struct
		d0 real8 0.0
		d1 real8 0.0
		d2 real8 0.0
		d3 real8 0.0		
	hfa7 ends	

; Declare prototypes for a range of different r-vectorcall combinations.
; Disassembly of the invocation of these procedures will help to understand the calling convention and ABI.		
TestProc      PROTO a:DWORD, b:REAL4
TestProc2     PROTO a:DWORD, b:QWORD
TestProc3     PROTO VECTORCALL a:DWORD, b:REAL4, cc:__m128
TestProc4     PROTO VECTORCALL a:hfa2
TestProc5     PROTO VECTORCALL a:hfa3, b:REAL4
TestProc6     PROTO VECTORCALL a:hfa4
TestProc7     PROTO VECTORCALL a:DWORD, b:REAL4, cc:__m128f, e:DWORD, f:DWORD, cd:__m128
TestProc8     PROTO VECTORCALL a:hfa5
TestProc9     PROTO VECTORCALL a:hfa6
TestProc10    PROTO VECTORCALL a:hfa7
TestProc11    PROTO VECTORCALL a:DWORD, b:REAL4, cc:__m128, d:__m128, e:hva2, f:__m128f
TestProc12    PROTO VECTORCALL a:hfa4, b:hfa4
TestProc13    PROTO VECTORCALL a:hfa4, b:REAL4, cc:REAL4, d:REAL4
TestProc14    PROTO VECTORCALL a:hfa4, b:DWORD, cc:DWORD, d:DWORD, e:DWORD
TestProc15    PROTO VECTORCALL a:hfa4, b:DWORD, cc:DWORD, d:DWORD, e:DWORD, f:DWORD
TestProc16    PROTO VECTORCALL a:DWORD, b:DWORD, cc:DWORD, d:DWORD, e:REAL4, f:REAL4, g:REAL4, h:REAL4
TestProc17    PROTO VECTORCALL a:hfa4, b:REAL4, cc:REAL4, d:REAL4, e:REAL4
TestProc18    PROTO VECTORCALL a:__m128f, b:DWORD, cc:DWORD, d:__m128f
TestProc19    PROTO VECTORCALL a:hfa4, b:DWORD, cc:DWORD, d:__m128f
TestProc20    PROTO VECTORCALL a:hva4, b:hva2, cc:__m128f
TestProc21    PROTO VECTORCALL a:__m128f, b:hva2
TestProcHVA1  PROTO VECTORCALL a:hva2
TestProcHVA2  PROTO VECTORCALL a:hva4
TestProcHVA3  PROTO VECTORCALL a:hva22
TestProcHVA4  PROTO VECTORCALL a:hva42
TestProcHVA5  PROTO VECTORCALL a:hva3
TestProcHVA1x PROTO VECTORCALL i:DWORD, a:hva2
TestProcHVA2x PROTO VECTORCALL i:DWORD, a:hva4
TestProcHVA3x PROTO VECTORCALL i:DWORD, a:hva22
TestProcHVA4x PROTO VECTORCALL i:DWORD, a:hva42
TestProcHVA5x PROTO VECTORCALL i:DWORD, a:REAL4, b:REAL8, cc:REAL4, d:hva42
TestProc22    PROTO VECTORCALL a:DWORD, b:REAL4, cc:hfa4, d:hfa4
TestProc23    PROTO VECTORCALL a:DWORD, b:REAL4, c1:__m128, c2:__m128,c3:__m128,c4:__m128,c5:__m128
TestProc24    PROTO VECTORCALL a:DWORD, b:REAL4, c1:__m128, c2:__m128,c3:__m128,c4:__m128,c5:__m128, c6:__m128f
TestProc25    PROTO VECTORCALL a:DWORD, b:REAL4, cc:__m128f, d:__m128
TestProc26    PROTO VECTORCALL a:__m128f, b:REAL4, cc:REAL4

.data
	
	align 16
	MyVector __m128 { <1.0, 2.0, 3.0, 4.0> }							; Declare a 4-element float SIMD type.
	MyVec4   __m128 { <00001111r, 00002222r, 00003333r, 00004444r> }	; Declare a 4-element float SIMD type (using hex notation).
	MyVector2 __m128f <5.0, 6.0, 7.0, 8.0>								; Declare a 4-element float SIMD type.
	align 16	
	hf1 hfa2 < 9.0, 10.0 >
	align 16	
	hf2 hfa3 < 11.0, 12.0, 13.0 >
	align 16	
	hf3 hfa4 < 4.0, 5.0, 6.0, 7.0 >										; Declare a 4-element float HFA type.
	hf5 hfa5 < 1.0, 2.0 >
	hf6 hfa6 < 1.0, 2.0, 3.0 >
	hf7 hfa7 < 4.0, 5.0, 6.0, 7.0 >	
	align 16	
	hv1 hva2 { <1.0, 2.0, 3.0, 4.0>, <1.0, 2.0, 3.0, 4.0> }
	align 16	
	hv2 hva4 < <1.0, 2.0, 3.0, 4.0>, <1.0, 2.0, 3.0, 4.0>, <1.0, 2.0, 3.0, 4.0>, <1.0, 2.0, 3.0, 4.0> >
	align 32
	hv3 hva22 < <1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0>, <1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0> >
	align 32
	hv4 hva42 < <1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0>, <1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0>, <1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0>, <1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0> >
	hv5 hva3 < <1.0, 2.0, 3.0, 4.0>, <1.0, 2.0, 3.0, 4.0>, <1.0, 2.0, 3.0, 4.0> >
	mvar dd 0
	
.code

MainCRT PROC FRAME
	
	local aba:__m128f

	invoke TestProc26, xmm2, 1.0, 2.0
	
	invoke TestProc12, hf3, hf3                				
	
	invoke TestProc11, 10, 2.0, MyVector2, MyVector, hv1, xmm6	
	invoke TestProc23, 10, 2.0, xmm7, xmm7, xmm7, xmm7, MyVector2
	invoke TestProcHVA5x, mvar, 2.0, FP8(3.0), 4.0, hv4		
	;invoke TestProc25, 1, 1.0, xmm1, xmm2		; overwritten by invoke test
	invoke TestProc22, 2, 1.0, hf3, hf3	
	invoke TestProc24, 10, 2.0, xmm7, xmm7, xmm7, xmm7, MyVector2, MyVector
	invoke TestProc19, hf3, 2, 3, xmm3		    				
	invoke TestProc21, MyVector, hv1
	invoke TestProc15, hf3, 1, 2, 3, 4, 5	    				
	invoke TestProc13, hf3, 1.0, 2.0, 3.0      				
	invoke TestProc18, MyVector, 2, 3, xmm3    				
	invoke TestProc17, hf3, 1.0, 2.0, 3.0, 4.0					
	invoke TestProc16, 1, 2, 3, 4, 1.0, 2.0, 3.0, 4.0			
	invoke TestProc14, hf3, 1, 2, 3, 4							
	invoke TestProc2, 32, CStr("this is text")					
	invoke TestProc3, 40, FP4(1.0), xmm3						
	invoke TestProc3, 40, FP4(1.0), aba						
	invoke TestProc3, 40, FP4(1.0), MyVector2					
	invoke TestProc4, hf1										
	invoke TestProc5, hf2, 1.0 										
	invoke TestProc8, hf5										
	invoke TestProc9, hf6										
	invoke TestProc10, hf7										
	invoke TestProc6, hf3										
	invoke TestProc7, 30, 1.0, MyVector, 10, 20, MyVector2		 
	invoke TestProcHVA1, hv1									
	invoke TestProcHVA2, hv2									
	invoke TestProcHVA3, hv3									
	invoke TestProcHVA4, hv4									
	invoke TestProcHVA5, hv5									
	invoke TestProcHVA1x, eax, hv1								
	invoke TestProcHVA2x, 20, hv2								
	invoke TestProcHVA3x, ebx, hv3								
	invoke TestProcHVA4x, mvar, hv4							
	invoke TestProc20, hv2, hv1, xmm3							
		
	invoke ExitProcess,0

	ret
MainCRT ENDP

TestProc26 PROC VECTORCALL FRAME a:__m128f, b:REAL4, cc:REAL4

vmovaps xmm0,a
vmovss xmm1,b
vmovss xmm2,cc

ret
TestProc26 ENDP

TestProc21 PROC VECTORCALL FRAME a:__m128f, b:hva2

	mov rax,a
	vmovups xmm9,[rax]
	mov rax,b
	vmovups xmm10,[rax]
	vmovups xmm11,[rax+16]
	
	ret
TestProc21 endp

TestProc20 PROC VECTORCALL FRAME a:hva4, b:hva2, cc:__m128f

	ret
TestProc20 endp

; Standard PROC
TestProc PROC FRAME a:DWORD, b:REAL4

	movss xmm10,b
	  
	ret	
TestProc ENDP

; TEST: m128 and m256 local types.
TestProc2 PROC FRAME a:DWORD, b:QWORD
	LOCAL bob2:__m256
	LOCAL bob:__m128
	
	movaps xmm0,bob    ;this should be fine.
	vmovaps xmm0,bob   ;so should this.
	vmovups ymm2,bob2  ;this should be fine always.
	
	mov eax,a
	mov rdi,b
	
	ret	
TestProc2 ENDP

TestProc3 PROC VECTORCALL FRAME uses  xmm7 ymm8 rbx a:DWORD, b:REAL4, cc:__m128
	LOCAL dummy:QWORD

	Mov eax,a   ; this will work.. a will = [rsp+n]  � although smart people would probably just use ecx knowing the argument order�
	mov dummy,rax
	
	;In fastcall b would have been in xmm0, but under vectorcall it's position dependant so would be xmm1
	movss xmm10,b          ;

;	mov rax,cc ; this still needs a QWORD PTR ?
	mov rax,qword ptr cc
	movups xmm11,[rax]  ;

	mov rax,dummy
	
	ret
TestProc3 ENDP

TestProc4 PROC VECTORCALL FRAME a:hfa2

	vmovups xmm0,a ; ensure that a is used to verify it's written correct to shadow space.
	
	ret
TestProc4 ENDP

TestProc8 PROC VECTORCALL FRAME a:hfa5

	vmovups xmm0,a ; ensure that a is used to verify it's written correct to shadow space.
	
	ret
TestProc8 ENDP


TestProc9 PROC VECTORCALL FRAME a:hfa6

	vmovups xmm0,a ; ensure that a is used to verify it's written correct to shadow space.
	
	ret
TestProc9 ENDP


TestProc10 PROC VECTORCALL FRAME a:hfa7

	vmovups xmm0,a ; ensure that a is used to verify it's written correct to shadow space.
	
	ret
TestProc10 ENDP


TestProc11 PROC VECTORCALL FRAME a:DWORD, b:REAL4, cc:__m128, d:__m128, e:hva2, f:__m128f

	ret
TestProc11 ENDP

TestProc12 PROC VECTORCALL FRAME a:hfa4, b:hfa4

	; In this case, a should have come through in xmm0-xmm3
	mov rax,a
	vmovss xmm9,[rax]
	vmovss xmm10,[rax+4]
	vmovss xmm11,[rax+8]
	vmovss xmm12,[rax+12]
	
	; b should have been passed by reference in rdx
	mov rax,b
	vmovss xmm9,[rax]
	vmovss xmm10,[rax+4]
	vmovss xmm11,[rax+8]
	vmovss xmm12,[rax+12]	
	
	vmovss xmm9,[rdx]
	vmovss xmm10,[rdx+4]
	vmovss xmm11,[rdx+8]
	vmovss xmm12,[rdx+12]
		
	ret
TestProc12 ENDP

TestProc13 PROC VECTORCALL FRAME a:hfa4, b:REAL4, cc:REAL4, d:REAL4

	ret
TestProc13 ENDP

TestProc14 PROC VECTORCALL FRAME a:hfa4, b:DWORD, cc:DWORD, d:DWORD, e:DWORD
	ret
TestProc14 endp

TestProc15 PROC VECTORCALL FRAME a:hfa4, b:DWORD, cc:DWORD, d:DWORD, e:DWORD, f:DWORD

	mov rax,a
	vmovss xmm9,[rax].hfa4.f0
	vmovss xmm10,[rax].hfa4.f1
	vmovss xmm11,[rax].hfa4.f2
	vmovss xmm12,[rax].hfa4.f3
	
	mov ebx,b
	mov ebx,cc
	mov ebx,d
	mov ebx,e
	mov ebx,f
	
	ret
TestProc15 endp

TestProc16 PROC VECTORCALL FRAME a:DWORD, b:DWORD, cc:DWORD, d:DWORD, e:REAL4, f:REAL4, g:REAL4, h:REAL4
	ret
TestProc16 endp

TestProc17 PROC VECTORCALL FRAME a:hfa4, b:REAL4, cc:REAL4, d:REAL4, e:REAL4
	ret
TestProc17 endp

TestProc18 PROC VECTORCALL FRAME a:__m128f, b:DWORD, cc:DWORD, d:__m128f
	ret
TestProc18 endp

TestProc19 PROC VECTORCALL FRAME a:hfa4, b:DWORD, cc:DWORD, d:__m128f
	
	mov rax,a
	
	ret
TestProc19 endp

TestProc5 PROC VECTORCALL FRAME a:hfa3, b:REAL4

	vmovups xmm0,a  ; This ssould be bad.. as HFA3 would have been passed in xmm0, xmm1, xmm2.. as individual floats.
	mov rdi,a       ; This shouldn't be very useful.
	vmovss xmm0,b
	
	ret
TestProc5 ENDP

TestProc6 PROC VECTORCALL FRAME a:hfa4

	vmovups xmm0,a ;ensure that a is used so is written to shadow space.
	
	ret
TestProc6 ENDP

TestProc7 PROC VECTORCALL FRAME uses  xmm7 ymm8 rbx a:DWORD, b:REAL4, cc:__m128f, e:DWORD, f:DWORD, cd:__m128
	LOCAL dummy:QWORD

	Mov eax,a   ; this will work.. a will = [rsp+n]  � although smart people would probably just use ecx knowing the argument order�
	mov dummy,rax
	
	;In fastcall b would have been in xmm0, but under vectorcall it's position dependant so would be xmm1
	movss xmm10,b          ;

;	mov rax,cc ; this still needs a QWORD PTR ?
	mov rax,qword ptr cc
	movups xmm11,[rax]  ;

	mov ebx,e
	mov ecx,f
	
	mov rax,dummy
	
	ret
TestProc7 ENDP

TestProcHVA1 PROC VECTORCALL FRAME uses rbx rsi a:hva2

	ret
TestProcHVA1 ENDP

TestProcHVA2 PROC VECTORCALL FRAME a:hva4

	vmovups xmm0,a
		
	ret
TestProcHVA2 ENDP


TestProcHVA3 PROC VECTORCALL FRAME uses rdi a:hva22

	ret
TestProcHVA3 ENDP

TestProcHVA4 PROC VECTORCALL FRAME a:hva42

	vmovups ymm7,a
	
	ret
TestProcHVA4 endp

TestProcHVA5 PROC VECTORCALL FRAME a:hva3

	vmovups ymm7,a
	
	ret
TestProcHVA5 endp

TestProcHVA1x PROC VECTORCALL FRAME uses rbx rsi i:DWORD, a:hva2

	ret
TestProcHVA1x ENDP

TestProcHVA2x PROC VECTORCALL FRAME i:DWORD, a:hva4

	vmovups xmm0,a
		
	ret
TestProcHVA2x ENDP


TestProcHVA3x PROC VECTORCALL FRAME uses rdi i:DWORD, a:hva22

	ret
TestProcHVA3x ENDP

TestProcHVA4x PROC VECTORCALL FRAME i:DWORD, a:hva42

	vmovups ymm7,a
	
	ret
TestProcHVA4x endp

TestProcHVA5x PROC VECTORCALL FRAME i:DWORD, a:REAL4, b:REAL8, cc:REAL4, d:hva42

	mov eax,i
	vmovss xmm9,a
	vmovsd xmm10,b
	vmovss xmm11,cc
	
	vmovups ymm12,d.a
	vmovups ymm13,d.b
	vmovups ymm14,d.cc
	vmovups ymm15,d.d
	
	ret
TestProcHVA5x endp

TestProc22 PROC VECTORCALL FRAME a:DWORD, b:REAL4, cc:hfa4, d:hfa4

	mov rax,d     ;d should already be in r9
	vmovss xmm11,[rax].hfa4.f0
	vmovss xmm11,[rax].hfa4.f1
	vmovss xmm11,[rax].hfa4.f2
	vmovss xmm11,[rax].hfa4.f3
	
	mov ebx,a
	vmovss xmm11,b
	mov rax,cc
	vmovss xmm11,[rax].hfa4.f0
	vmovss xmm11,[rax].hfa4.f1
	vmovss xmm11,[rax].hfa4.f2
	vmovss xmm11,[rax].hfa4.f3
	
	ret
TestProc22 endp

TestProc23 PROC VECTORCALL FRAME a:DWORD, b:REAL4, c1:__m128, c2:__m128,c3:__m128,c4:__m128,c5:__m128

	mov eax,a
	vmovss xmm9,b
	
	mov rax,c1
	vmovaps xmm0,[rax]
	mov rax,c2
	vmovaps xmm1,[rax]
	mov rax,c3
	vmovaps xmm2,[rax]
	mov rax,c4
	vmovaps xmm3,[rax]
	mov rax,c5
	vmovaps xmm5,[rax]
	
	ret
TestProc23 endp


TestProc24 PROC VECTORCALL FRAME a:DWORD, b:REAL4, c1:__m128, c2:__m128,c3:__m128,c4:__m128,c5:__m128, c6:__m128f

	mov eax,a
	vmovss xmm9,b
	
	mov rax,c1
	vmovaps xmm0,[rax]
	mov rax,c2
	vmovaps xmm1,[rax]
	mov rax,c3
	vmovaps xmm2,[rax]
	mov rax,c4
	vmovaps xmm3,[rax]
	mov rax,c5
	vmovaps xmm5,[rax]
	
	ret
TestProc24 endp

TestProc25 PROC VECTORCALL FRAME a:DWORD, b:REAL4, cc:__m128f, d:__m128

	mov rax,cc
	vmovaps xmm0,[rax]
	mov rax,d
	vmovaps xmm1,[rax]
	
	ret
TestProc25 ENDP

end MainCRT