-
Notifications
You must be signed in to change notification settings - Fork 122
/
altmacro.S
132 lines (98 loc) · 2.77 KB
/
altmacro.S
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
/*
# altmacro
Enables the alternate macro mode from now on.
Can also be set as a command line option `--alternate`.
This adds extra capabilities to macros:
- LOCAL
- % string evaluation
# noaltmacro
Turned off `.altmacro`.
*/
#include "lib/common_gas.h"
ENTRY
.altmacro
/*
With altmacro, \ is not needed to expand the arguments.
TODO undocumented?
*/
.macro STRING_ARG x
mov x, %eax
.endm
mov $0, %eax
STRING_ARG $1
ASSERT_EQ($1, %eax)
/* But escaping it still works. */
.macro STRING_ARG_BACKSLASH x
mov \x, %eax
.endm
mov $0, %eax
STRING_ARG $1
ASSERT_EQ($1, %eax)
/* TODO how to avoid expansion? */
/*
# LOCAL
Generates local labels that are impossible to clash.
*/
.macro LOCAL_KEYWORD a="%eax"
LOCAL ok
mov $1, %eax
jmp ok
call assert_fail
ok:
.endm
LOCAL_KEYWORD
LOCAL_KEYWORD
/*
# %
# Percent
Appears to work only on arguments passed or their default values.
*/
.macro PERCENT x
mov $\x, %eax
.endm
mov $0, %eax
PERCENT %1+1
ASSERT_EQ($2, %eax)
.macro PERCENT_DEFAULT x=%1+1
mov $\x, %eax
.endm
mov $0, %eax
PERCENT_DEFAULT 1
ASSERT_EQ($1, %eax)
PERCENT_DEFAULT
ASSERT_EQ($2, %eax)
/*
This is a horrible feature as it makes it impossible to pass registers
as arguments to altmacros without special escaping care...
http://stackoverflow.com/questions/19776992/gas-altmacro-macro-with-a-percent-sign-in-a-default-parameter-fails-with-oper
*/
.macro PERCENT_ESCAPE x
mov \x, %eax
.endm
mov $0, %eax
mov $1, %ebx
PERCENT_ESCAPE <%ebx>
ASSERT_EQ($1, %eax)
.macro PERCENT_ESCAPE_DEFAULT x=<%ebx>
mov \x, %eax
.endm
mov $0, %eax
mov $1, %ebx
PERCENT_ESCAPE_DEFAULT
ASSERT_EQ($1, %eax)
/*
One alternative if we are sure that the argument is a register,
is to put the percent inside the macro:
*/
.macro PERCENT_ESCAPE_REG x
mov %x, %eax
.endm
mov $0, %eax
mov $1, %ebx
PERCENT_ESCAPE_REG ebx
ASSERT_EQ($1, %eax)
/* But this has the downside that we cannot pass immediates like `$1` anymore */
/*PERCENT_ESCAPE_REG $1*/
/* TODO application? */
.noaltmacro
EXIT