@@ -78,6 +78,30 @@ GLOBL _rt0_amd64_lib_argc<>(SB),NOPTR, $8
78
78
DATA _rt0_amd64_lib_argv<>(SB)/8 , $0
79
79
GLOBL _rt0_amd64_lib_argv<>(SB),NOPTR, $8
80
80
81
+ #ifdef GOAMD64_v2
82
+ DATA bad_proc_msg<>+0x00 (SB)/78 , $"This program can only be run on processors with v2 microarchitecture support.\n"
83
+ #endif
84
+
85
+ #ifdef GOAMD64_v3
86
+ DATA bad_proc_msg<>+0x00 (SB)/78 , $"This program can only be run on processors with v3 microarchitecture support.\n"
87
+ #endif
88
+
89
+ GLOBL bad_proc_msg<>(SB), RODATA, $78
90
+
91
+ // Define a list of AMD64 microarchitecture level features
92
+ // https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels
93
+
94
+ // SSE3 SSSE3 CMPXCHNG16 SSE4.1 SSE4.2 POPCNT
95
+ #define V2_FEATURES_CX (1 << 0 | 1 << 9 | 1 << 13 | 1 << 19 | 1 << 20 | 1 << 23 )
96
+ // LAHF/SAHF
97
+ #define V2_EXT_FEATURES_CX (1 << 0 )
98
+ // FMA MOVBE OSXSAVE AVX F16C
99
+ #define V3_FEATURES_CX (V2_FEATURES_CX | 1 << 12 | 1 << 22 | 1 << 27 | 1 << 28 | 1 << 29 )
100
+ // ABM (FOR LZNCT)
101
+ #define V3_EXT_FEATURES_CX (V2_EXT_FEATURES_CX | 1 << 5 )
102
+ // BMI1 AVX2 BMI2
103
+ #define V3_EXT_FEATURES_BX (1 << 3 | 1 << 5 | 1 << 8 )
104
+
81
105
TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
82
106
// copy arguments forward on an even stack
83
107
MOVQ DI, AX // argc
@@ -101,22 +125,68 @@ TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
101
125
CPUID
102
126
MOVL AX, SI
103
127
CMPL AX, $0
104
- JE nocpuinfo
128
+ #ifdef GOAMD64_v1
129
+ JE nocpuinfo
130
+ #else
131
+ JNE has_cpuinfo
132
+
133
+ bad_proc: // show that the program requires a certain microarchitecture level.
134
+ MOVQ $2 , 0 (SP)
135
+ MOVQ $bad_proc_msg<>(SB), AX
136
+ MOVQ AX, 8 (SP)
137
+ MOVQ $78 , 16 (SP)
138
+ CALL runtime·write(SB)
139
+ MOVQ $1 , 0 (SP)
140
+ CALL runtime·exit(SB)
141
+ CALL runtime·abort(SB)
142
+ #endif
105
143
144
+ has_cpuinfo:
106
145
CMPL BX, $0x756E6547 // "Genu"
107
146
JNE notintel
108
147
CMPL DX, $0x49656E69 // "ineI"
109
148
JNE notintel
110
149
CMPL CX, $0x6C65746E // "ntel"
111
150
JNE notintel
112
151
MOVB $1 , runtime·isIntel(SB)
113
- notintel:
114
152
153
+ notintel:
115
154
// Load EAX=1 cpuid flags
116
155
MOVL $1 , AX
117
156
CPUID
118
157
MOVL AX, runtime·processorVersionInfo(SB)
119
158
159
+ #ifdef GOAMD64_v2
160
+ ANDL $V2_FEATURES_CX, CX
161
+ CMPL CX, $V2_FEATURES_CX
162
+ JNZ bad_proc
163
+ MOVL $0x80000001 , AX
164
+ CPUID
165
+ TESTL $V2_EXT_FEATURES_CX, CX
166
+ JZ bad_proc
167
+ #endif
168
+
169
+ #ifdef GOAMD64_v3
170
+ ANDL $V3_FEATURES_CX, CX
171
+ CMPL CX, $V3_FEATURES_CX
172
+ JNZ bad_proc
173
+ MOVL $7 , AX
174
+ MOVL $0 , CX
175
+ CPUID
176
+ ANDL $V3_EXT_FEATURES_BX, BX
177
+ CMPL BX, $V3_EXT_FEATURES_BX
178
+ JNZ bad_proc
179
+ MOVL $0x80000000 , AX
180
+ CPUID
181
+ CMPL AX, $0x80000001
182
+ JL bad_proc
183
+ MOVL $0x80000001 , AX
184
+ CPUID
185
+ ANDL $V3_EXT_FEATURES_CX, CX
186
+ CMPL CX, $V3_EXT_FEATURES_CX
187
+ JNZ bad_proc
188
+ #endif
189
+
120
190
nocpuinfo:
121
191
// if there is an _cgo_init, call it.
122
192
MOVQ _cgo_init(SB), AX
0 commit comments