xref: /reactos/sdk/include/asm/asm.inc (revision 019f21ee)
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 CS:NOTHING, DS:NOTHING, ES:NOTHING, 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.altmacro
239
240/* Explicit radix in GAS syntax */
241#define BIN(x) 0b##x
242#define OCT(x) 0##x
243#define DEC(x) x
244#define HEX(x) 0x##x
245
246/* Macro values need to be marked */
247#define VAL(x) \x
248
249/* Due to MASM's reverse syntax, we are forced to use a precompiler macro */
250#define MACRO(...) .macro __VA_ARGS__
251#define ENDM .endm
252
253/* To avoid reverse syntax we provide a new macro .PROC, replacing PROC... */
254.macro .PROC name
255    .func \name
256#ifdef _X86_
257    /* x86 GAS expects a label with _ prefix */
258    _\name:
259#endif
260    \name:
261    .cfi_startproc
262    .equ cfa_current_offset, -8
263.endm
264#define FUNC .PROC
265
266/* ... and .ENDP, replacing ENDP */
267.macro .ENDP
268    .cfi_endproc
269    .endfunc
270.endm
271#define ENDFUNC .ENDP
272
273/* MASM compatible PUBLIC */
274.macro PUBLIC symbol
275    .global \symbol
276.endm
277
278/* No special marking of global labels */
279.macro GLOBAL_LABEL label
280    \label:
281.endm
282
283/* Dummy ASSUME */
284.macro ASSUME p1 p2 p3 p4 p5 p6 p7 p8
285.endm
286
287/* MASM needs an end tag for segments */
288.macro .endcode16
289.endm
290
291/* MASM compatible ALIGN */
292#define ALIGN .align
293
294/* MASM compatible REPEAT, additional ENDR */
295#define REPEAT .rept
296#define ENDR .endr
297
298.macro ljmp segment, offset
299    jmp far ptr \segment:\offset
300.endm
301
302.macro ljmp16 segment, offset
303    jmp far ptr \segment:\offset
304.endm
305
306/* MASM compatible EXTERN */
307.macro EXTERN name
308.endm
309
310/* MASM needs an END tag */
311#define END
312
313.macro .MODEL model
314.endm
315
316.macro .code
317    .text
318.endm
319
320.macro .const
321    .section .rdata
322.endm
323
324/*
325 * See https://docs.microsoft.com/en-us/cpp/assembler/masm/dot-fpo
326 * and https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_fpo_data
327 */
328.macro FPO cdwLocals, cdwParams, cbProlog, cbRegs, fUseBP, cbFrame
329    .if (cbFrame == FRAME_TRAP)
330        .cfi_signal_frame
331    .endif
332.endm
333
334/* Macros for x64 stack unwind OPs */
335
336.macro .allocstack size
337    .cfi_adjust_cfa_offset \size
338    .set cfa_current_offset, cfa_current_offset - \size
339.endm
340
341code = 1
342.macro .pushframe param=0
343    .if (\param)
344        .cfi_adjust_cfa_offset 0x30
345        .set cfa_current_offset, cfa_current_offset - 0x30
346    .else
347        .cfi_adjust_cfa_offset 0x28
348        .set cfa_current_offset, cfa_current_offset - 0x28
349    .endif
350.endm
351
352.macro .pushreg reg
353    .cfi_adjust_cfa_offset 8
354    .equ cfa_current_offset, cfa_current_offset - 8
355    .cfi_offset \reg, cfa_current_offset
356.endm
357
358.macro .savereg reg, offset
359    // checkme!!!
360    .cfi_offset \reg, \offset
361.endm
362
363.macro .savexmm128 reg, offset
364    // checkme!!!
365    .cfi_offset \reg, \offset
366.endm
367
368.macro .setframe reg, offset
369    .cfi_def_cfa reg, \offset
370    .equ cfa_current_offset, \offset
371.endm
372
373.macro .endprolog
374.endm
375
376.macro absolute address
377    __absolute__address__ = \address
378.endm
379
380.macro resb name, size
381    \name = __absolute__address__
382    __absolute__address__ = __absolute__address__ + \size
383.endm
384
385.macro UNIMPLEMENTED2 file, line, func
386    jmp 3f
3871:  .asciz "\func"
3882:  .asciz \file
3893:
390    sub rsp, 0x20
391    lea rcx, MsgUnimplemented[rip]
392    lea rdx, 1b[rip]
393    lea r8, 2b[rip]
394    mov r9, \line
395    call DbgPrint
396    add rsp, 0x20
397.endm
398#define UNIMPLEMENTED UNIMPLEMENTED2 __FILE__, __LINE__,
399
400/* MASM/ML uses ".if" for runtime conditionals, and "if" for compile time
401   conditionals. We therefore use "if", too. .if shouldn't be used at all */
402#define if .if
403#define endif .endif
404#define else .else
405#define elseif .elseif
406
407#define CR  "\r"
408#define LF  "\n"
409#define NUL "\0"
410
411/* CFI annotations */
412#define CFI_STARTPROC .cfi_startproc
413#define CFI_ENDPROC .cfi_endproc
414#define CFI_DEF_CFA .cfi_def_cfa
415#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset
416#define CFI_DEF_CFA_REGISTER .cfi_def_cfa_register
417#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
418#define CFI_OFFSET .cfi_offset
419#define CFI_REGISTER .cfi_register
420#define CFI_REL_OFFSET .cfi_rel_offset
421#define CFI_SAME_VALUE .cfi_same_value
422
423#endif
424
425#endif /* __ASM_INC__ */
426