xref: /reactos/sdk/include/asm/asm.inc (revision 9393fc32)
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
175ljmp MACRO segment, offset
176    DB 0EAh
177    DD offset
178    DW segment
179ENDM
180
181ljmp16 MACRO segment, offset
182    DB 0EAh
183    DW offset
184    DW segment
185ENDM
186
187data32 MACRO opcode:VARARG
188    DB 66h
189    opcode
190ENDM
191
192UNIMPLEMENTED MACRO name
193ENDM
194
195absolute MACRO address
196    __absolute__address__ = address
197ENDM
198
199resb MACRO name, size
200    name = __absolute__address__
201    __absolute__address__ = __absolute__address__ + size
202ENDM
203
204/* We need this to distinguish repeat from macros */
205#define ENDR ENDM
206
207#define CR 13
208#define LF 10
209#define NUL 0
210
211/* For compatibility with GAS */
212CFI_STARTPROC MACRO start
213ENDM
214CFI_ENDPROC MACRO
215ENDM
216CFI_DEF_CFA MACRO reg:REQ, offset:REQ
217ENDM
218CFI_DEF_CFA_OFFSET MACRO offset:REQ
219ENDM
220CFI_DEF_CFA_REGISTER MACRO reg:REQ
221ENDM
222CFI_ADJUST_CFA_OFFSET MACRO offset:REQ
223ENDM
224CFI_OFFSET MACRO reg:REQ, offset:REQ
225ENDM
226CFI_REGISTER MACRO reg1:REQ, reg2:REQ
227ENDM
228CFI_REL_OFFSET MACRO reg:REQ, offset:REQ
229ENDM
230CFI_SAME_VALUE MACRO reg:REQ
231ENDM
232
233#else /***********************************************************************/
234
235/* Force intel syntax */
236.intel_syntax noprefix
237
238/* Put dwarf debug info in the .dwarf_debug section, which will be properly stripped */
239.cfi_sections .debug_frame
240
241.altmacro
242
243/* Explicit radix in GAS syntax */
244#define BIN(x) 0b##x
245#define OCT(x) 0##x
246#define DEC(x) x
247#define HEX(x) 0x##x
248
249/* Macro values need to be marked */
250#define VAL(x) \x
251
252#define CR  "\r"
253#define LF  "\n"
254#define NUL "\0"
255
256/* Due to MASM's reverse syntax, we are forced to use a precompiler macro */
257#define MACRO(...) .macro __VA_ARGS__
258#define ENDM .endm
259
260/* To avoid reverse syntax we provide a new macro .PROC, replacing PROC... */
261.macro .PROC name
262    .func \name
263    \name:
264#ifdef _X86_
265    .cfi_startproc
266#else
267    .seh_proc \name
268#endif
269.endm
270#define FUNC .PROC
271
272/* ... and .ENDP, replacing ENDP */
273.macro .ENDP
274#ifdef _X86_
275    .cfi_endproc
276#else
277    .seh_endproc
278#endif
279    .endfunc
280.endm
281#define ENDFUNC .ENDP
282
283/* MASM compatible PUBLIC */
284.macro PUBLIC symbol
285    .global \symbol
286.endm
287
288/* No special marking of global labels */
289.macro GLOBAL_LABEL label
290    \label:
291.endm
292
293/* Dummy ASSUME */
294.macro ASSUME p1 p2 p3 p4 p5 p6 p7 p8
295.endm
296
297/* MASM needs an end tag for segments */
298.macro .endcode16
299.endm
300
301/* MASM compatible ALIGN */
302#define ALIGN .align
303
304/* MASM compatible REPEAT, additional ENDR */
305#define REPEAT .rept
306#define ENDR .endr
307
308.macro ljmp segment, offset
309    jmp far ptr \segment:\offset
310.endm
311
312.macro ljmp16 segment, offset
313    jmp far ptr \segment:\offset
314.endm
315
316.macro retf
317    lret
318.endm
319
320/* MASM compatible EXTERN */
321.macro EXTERN name
322.endm
323
324/* MASM needs an END tag */
325#define END
326
327.macro .MODEL model
328.endm
329
330.macro .code
331    .text
332.endm
333
334.macro .const
335    .section .rdata
336.endm
337
338/*
339 * See https://docs.microsoft.com/en-us/cpp/assembler/masm/dot-fpo
340 * and https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_fpo_data
341 */
342.macro FPO cdwLocals, cdwParams, cbProlog, cbRegs, fUseBP, cbFrame
343    .if (cbFrame == FRAME_TRAP)
344        .cfi_signal_frame
345    .endif
346.endm
347
348/* Macros for x64 stack unwind OPs */
349.macro .allocstack size
350    .seh_stackalloc \size
351.endm
352
353.macro .pushframe param
354    /*
355     * FIXME. .seh_pushframe doesn't accept code argument.
356     * Patch sent.
357     */
358    .seh_pushframe \param
359.endm
360
361.macro .pushreg reg
362    .seh_pushreg \reg
363.endm
364
365.macro .savereg reg, offset
366    .seh_savereg \reg, \offset
367.endm
368
369.macro .savexmm128 reg, offset
370    .seh_savexmm \reg, \offset
371.endm
372
373.macro .setframe reg, offset
374    .seh_setframe \reg, \offset
375.endm
376
377.macro .endprolog
378    .seh_endprologue
379.endm
380
381.macro absolute address
382    __absolute__address__ = \address
383.endm
384
385.macro resb name, size
386    \name = __absolute__address__
387    __absolute__address__ = __absolute__address__ + \size
388.endm
389
390.macro UNIMPLEMENTED2 file, line, func
391    jmp 4f
3921:  .ascii "Unimplemented", CR, LF, NUL
3932:  .asciz "\func"
3943:  .asciz \file
3954:
396    sub rsp, 0x20
397    lea rcx, 1b[rip]
398    lea rdx, 2b[rip]
399    lea r8, 3b[rip]
400    mov r9, \line
401    call DbgPrint
402    add rsp, 0x20
403.endm
404#define UNIMPLEMENTED UNIMPLEMENTED2 __FILE__, __LINE__,
405
406/* MASM/ML uses ".if" for runtime conditionals, and "if" for compile time
407   conditionals. We therefore use "if", too. .if shouldn't be used at all */
408#define if .if
409#define endif .endif
410#define else .else
411#define elseif .elseif
412
413/* CFI annotations */
414#define CFI_STARTPROC .cfi_startproc
415#define CFI_ENDPROC .cfi_endproc
416#define CFI_DEF_CFA .cfi_def_cfa
417#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset
418#define CFI_DEF_CFA_REGISTER .cfi_def_cfa_register
419#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
420#define CFI_OFFSET .cfi_offset
421#define CFI_REGISTER .cfi_register
422#define CFI_REL_OFFSET .cfi_rel_offset
423#define CFI_SAME_VALUE .cfi_same_value
424
425#endif
426
427#endif /* __ASM_INC__ */
428