Reactos
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: include/asm/asm.inc
5 * PURPOSE: ASM macros for GAS and MASM/ML64
6 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9#ifndef __ASM_INC__
10#define __ASM_INC__
11
12/*
13 * Common definitions for the FPO macro.
14 * See https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_fpo_data
15 */
16#define FRAME_FPO 0
17#define FRAME_TRAP 1
18#define FRAME_TSS 2
19#define FRAME_NONFPO 3
20
21#ifdef _USE_ML
22
23/* Allow ".name" identifiers */
24OPTION DOTNAME
25
26#ifdef _M_IX86
27.686P
28.XMM
29.MODEL FLAT
30ASSUME FS:NOTHING, GS:NOTHING
31#endif
32
33/* Explicit radix in MASM syntax */
34#define BIN(x) x##y
35#define OCT(x) x##q
36#define DEC(x) x##t
37#define HEX(x) 0##x##h
38
39/* Macro values need not be marked */
40#define VAL(x) x
41
42/* MASM/ML doesn't want explicit [rip] addressing */
43rip = 0
44
45/* Due to MASM's reverse syntax, we are forced to use a precompiler macro */
46#define MACRO(name, ...) name MACRO __VA_ARGS__
47
48/* To avoid reverse syntax we provide a new macro .PROC, replacing PROC... */
49.PROC MACRO name
50__current_function_name EQU %name
51#ifdef _M_IX86
52 %name PROC
53#else
54 %name PROC FRAME
55#endif
56ENDM
57#define FUNC .PROC
58
59/* ... and .ENDP, replacing ENDP */
60.ENDP MACRO
61 %__current_function_name ENDP
62ENDM
63#define ENDFUNC .ENDP
64
65/* Global labels need an extra colon */
66GLOBAL_LABEL MACRO label
67 %label::
68ENDM
69
70/*
71 * See https://docs.microsoft.com/en-us/cpp/assembler/masm/dot-fpo
72 * and https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_fpo_data
73 */
74FPO MACRO cdwLocals, cdwParams, cbProlog, cbRegs, fUseBP, cbFrame
75 .FPO (cdwLocals, cdwParams, cbProlog, cbRegs, fUseBP, cbFrame)
76ENDM
77
78/* MASM doesn't have an ASCII macro */
79.ASCII MACRO text:VARARG
80 DB text
81ENDM
82.ascii MACRO text:VARARG
83 DB text
84ENDM
85
86/* MASM doesn't have an ASCIZ macro */
87.ASCIZ MACRO text:VARARG
88 DB text
89 DB 0
90ENDM
91.asciz MACRO text:VARARG
92 DB text
93 DB 0
94ENDM
95
96.code64 MACRO
97 .code
98ENDM
99
100.code32 MACRO
101 .code
102 .586P
103ENDM
104
105.code16 MACRO
106 ASSUME nothing
107 .text SEGMENT use16 PUBLIC 'CODE'
108 .586P
109ENDM
110
111.endcode16 MACRO
112 .text ENDS
113ENDM
114
115.bss MACRO
116 .DATA?
117 ASSUME nothing
118ENDM
119
120//.text MACRO
121//ENDM
122
123.align MACRO alignment
124 ALIGN alignment
125ENDM
126
127.byte MACRO args:VARARG
128 db args
129ENDM
130
131.short MACRO args:VARARG
132 dw args
133ENDM
134
135.word MACRO args:VARARG
136 dw args
137ENDM
138
139.long MACRO args:VARARG
140 dd args
141ENDM
142
143.quad MACRO args:VARARG
144 dq args
145ENDM
146
147.double MACRO args:VARARG
148 real8 args
149ENDM
150
151.org MACRO value
152 ORG value
153ENDM
154
155.fill MACRO count, size, value
156 REPEAT count
157 if (size EQ 1)
158 DB value
159 elseif (size EQ 2)
160 DW value
161 elseif (size EQ 4)
162 DD value
163 endif
164 ENDM
165ENDM
166
167.skip MACRO size, fill:=<0>
168 DB size DUP (fill)
169ENDM
170
171.space MACRO size, fill:=<0>
172 .skip size, fill
173ENDM
174
175/* OFFset macro */
176#define OFF(x) offset x
177
178#define lXdtPrefix fword ptr
179
180ljmp MACRO segment, offset
181 DB 0EAh
182 DD offset
183 DW segment
184ENDM
185
186ljmp16 MACRO segment, offset
187 DB 0EAh
188 DW offset
189 DW segment
190ENDM
191
192data32 MACRO opcode:VARARG
193 DB 66h
194 opcode
195ENDM
196
197UNIMPLEMENTED2 MACRO file, line, func
198 jmp UNIMPLEMENTED2_IMPL
199UNIMPLEMENTED_MSG: .ascii "WARNING: %s at %s:%d is UNIMPLEMENTED!", 10, 0
200UNIMPLEMENTED_FUNC: .ascii "&func&", 0
201UNIMPLEMENTED_FILE: .ascii file, 0
202EXTERN DbgPrint:PROC
203UNIMPLEMENTED2_IMPL:
204 sub rsp, 28h
205 mov r9, line
206 lea r8, UNIMPLEMENTED_FILE
207 lea rdx, UNIMPLEMENTED_FUNC
208 lea rcx, UNIMPLEMENTED_MSG
209 call DbgPrint
210 add rsp, 28h
211 xor eax, eax
212ENDM
213#define UNIMPLEMENTED UNIMPLEMENTED2 __FILE__, __LINE__,
214
215absolute MACRO address
216 __absolute__address__ = address
217ENDM
218
219resb MACRO name, size
220 name = __absolute__address__
221 __absolute__address__ = __absolute__address__ + size
222ENDM
223
224/* We need this to distinguish repeat from macros */
225#define ENDR ENDM
226
227#define CR 13
228#define LF 10
229#define NUL 0
230
231/* For compatibility with GAS */
232CFI_STARTPROC MACRO start
233ENDM
234CFI_ENDPROC MACRO
235ENDM
236CFI_DEF_CFA MACRO reg:REQ, offset:REQ
237ENDM
238CFI_DEF_CFA_OFFSET MACRO offset:REQ
239ENDM
240CFI_DEF_CFA_REGISTER MACRO reg:REQ
241ENDM
242CFI_ADJUST_CFA_OFFSET MACRO offset:REQ
243ENDM
244CFI_OFFSET MACRO reg:REQ, offset:REQ
245ENDM
246CFI_REGISTER MACRO reg1:REQ, reg2:REQ
247ENDM
248CFI_REL_OFFSET MACRO reg:REQ, offset:REQ
249ENDM
250CFI_SAME_VALUE MACRO reg:REQ
251ENDM
252
253#else /***********************************************************************/
254
255/* Force intel syntax */
256.intel_syntax noprefix
257
258/* Put dwarf debug info in the .dwarf_debug section, which will be properly stripped */
259.cfi_sections .debug_frame
260
261.altmacro
262
263/* Explicit radix in GAS syntax */
264#define BIN(x) 0b##x
265#define OCT(x) 0##x
266#define DEC(x) x
267#define HEX(x) 0x##x
268
269/* Macro values need to be marked */
270#define VAL(x) \x
271
272#define CR "\r"
273#define LF "\n"
274#define NUL "\0"
275
276/* Due to MASM's reverse syntax, we are forced to use a precompiler macro */
277#define MACRO(...) .macro __VA_ARGS__
278#define ENDM .endm
279
280/* To avoid reverse syntax we provide a new macro .PROC, replacing PROC... */
281.macro .PROC name
282 .func \name
283 \name:
284#ifdef _X86_
285 .cfi_startproc
286#else
287 .seh_proc \name
288#endif
289.endm
290#define FUNC .PROC
291
292/* ... and .ENDP, replacing ENDP */
293.macro .ENDP
294#ifdef _X86_
295 .cfi_endproc
296#else
297 .seh_endproc
298#endif
299 .endfunc
300.endm
301#define ENDFUNC .ENDP
302
303/* MASM compatible PUBLIC */
304.macro PUBLIC symbol
305 .global \symbol
306.endm
307
308/* No special marking of global labels */
309.macro GLOBAL_LABEL label
310 \label:
311.endm
312
313/* Dummy ASSUME */
314.macro ASSUME p1 p2 p3 p4 p5 p6 p7 p8
315.endm
316
317/* MASM needs an end tag for segments */
318.macro .endcode16
319.endm
320
321/* MASM compatible ALIGN */
322.macro align x
323 .align x
324.endm
325
326/* MASM compatible REPEAT, additional ENDR */
327#define REPEAT .rept
328#define ENDR .endr
329
330/* OFFset macro */
331#define OFF(x) x
332
333#define lXdtPrefix
334
335.macro ljmp segment, offset
336 .byte 0xEA
337 .long offset
338 .word segment
339.endm
340
341.macro ljmp16 segment, offset
342 .byte 0xEA
343 .word offset
344 .word segment
345.endm
346
347.macro data32 opcode:vararg
348 .byte 0x66
349 opcode
350.endm
351
352.macro retf
353 lret
354.endm
355
356/* MASM compatible EXTERN */
357.macro EXTERN name
358.endm
359
360/* MASM needs an END tag */
361.macro END
362.endm
363
364.macro .MODEL model
365.endm
366
367.macro .code
368 .text
369.endm
370
371.macro .const
372 .section .rdata
373.endm
374
375/*
376 * See https://docs.microsoft.com/en-us/cpp/assembler/masm/dot-fpo
377 * and https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_fpo_data
378 */
379.macro FPO cdwLocals, cdwParams, cbProlog, cbRegs, fUseBP, cbFrame
380 .if (cbFrame == FRAME_TRAP)
381 .cfi_signal_frame
382 .endif
383.endm
384
385/* Macros for x64 stack unwind OPs */
386.macro .allocstack size
387 .seh_stackalloc \size
388.endm
389
390.macro .pushframe param
391 /*
392 * FIXME. .seh_pushframe doesn't accept code argument.
393 * Patch sent.
394 */
395 .seh_pushframe \param
396.endm
397
398.macro .pushreg reg
399 .seh_pushreg \reg
400.endm
401
402.macro .savereg reg, offset
403 .seh_savereg \reg, \offset
404.endm
405
406.macro .savexmm128 reg, offset
407 .seh_savexmm \reg, \offset
408.endm
409
410.macro .setframe reg, offset
411 .seh_setframe \reg, \offset
412.endm
413
414.macro .endprolog
415 .seh_endprologue
416.endm
417
418.macro absolute address
419 __absolute__address__ = \address
420.endm
421
422.macro resb name, size
423 \name = __absolute__address__
424 __absolute__address__ = __absolute__address__ + \size
425.endm
426
427.macro UNIMPLEMENTED2 file, line, func
428 jmp 4f
4291: .ascii "Unimplemented %s (%s:%d)", CR, LF, NUL
4302: .asciz "\func"
4313: .asciz \file
4324:
433 sub rsp, 0x20
434 lea rcx, 1b[rip]
435 lea rdx, 2b[rip]
436 lea r8, 3b[rip]
437 mov r9, \line
438 call DbgPrint
439 add rsp, 0x20
440.endm
441#define UNIMPLEMENTED UNIMPLEMENTED2 __FILE__, __LINE__,
442
443/* MASM/ML uses ".if" for runtime conditionals, and "if" for compile time
444 conditionals. We therefore use "if", too. .if shouldn't be used at all */
445#define if .if
446#define endif .endif
447#define else .else
448#define elseif .elseif
449
450/* CFI annotations */
451#define CFI_STARTPROC .cfi_startproc
452#define CFI_ENDPROC .cfi_endproc
453#define CFI_DEF_CFA .cfi_def_cfa
454#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset
455#define CFI_DEF_CFA_REGISTER .cfi_def_cfa_register
456#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
457#define CFI_OFFSET .cfi_offset
458#define CFI_REGISTER .cfi_register
459#define CFI_REL_OFFSET .cfi_rel_offset
460#define CFI_SAME_VALUE .cfi_same_value
461
462#endif
463
464#endif /* __ASM_INC__ */