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