8
8
#include "funcdata.h"
9
9
#include "textflag.h"
10
10
11
+ #ifdef GOARM64_LSE
12
+ DATA no_lse_msg<> + 0x00 (SB)/ 64 , $ "This program can only run on ARM64 processors with LSE support.\n"
13
+ GLOBL no_lse_msg<>(SB) , RODATA , $ 64
14
+ #endif
15
+
16
+ // We know for sure th at Linux and FreeBSD allow to read instruction set
17
+ // attribute registers (while some others OSes , like OpenBSD and Darwin ,
18
+ // are not ). Let's be conservative and allow code reading such registers
19
+ // only when we sure this won't lead to sigill.
20
+ #ifdef GOOS_linux
21
+ #define ISA_REGS_READABLE
22
+ #endif
23
+ #ifdef GOOS_freebsd
24
+ #define ISA_REGS_READABLE
25
+ #endif
26
+
27
+ #ifdef GOARM64_LSE
28
+ #ifdef ISA_REGS_READABLE
29
+ #define CHECK_GOARM64_LSE
30
+ #endif
31
+ #endif
32
+
11
33
TEXT runtime·rt0_go(SB) , NOSPLIT|TOPFRAME , $ 0
12
34
// SP = stack ; R0 = argc; R1 = argv
13
35
@@ -77,6 +99,19 @@ nocgo:
77
99
BL runtime·wintls(SB)
78
100
#endif
79
101
102
+ // Check th at CPU we use for execution supports instructions targeted during compile - time.
103
+ #ifdef CHECK_GOARM64_LSE
104
+ // Read the ID_AA64ISAR0_EL1 register
105
+ MRS ID_AA64ISAR0_EL1 , R0
106
+
107
+ // Extract the LSE field (bits [ 23 : 20 ] )
108
+ LSR $ 20 , R0 , R0
109
+ AND $ 0xf , R0 , R0
110
+
111
+ // LSE support is indicated by a non - zero value
112
+ CBZ R0 , no_lse
113
+ #endif
114
+
80
115
MOVW 8 ( RSP ) , R0 // copy argc
81
116
MOVW R0 , - 8 ( RSP )
82
117
MOVD 16 ( RSP ) , R0 // copy argv
@@ -95,6 +130,21 @@ nocgo:
95
130
96
131
// start this M
97
132
BL runtime·mstart(SB)
133
+ UNDEF
134
+
135
+ #ifdef CHECK_GOARM64_LSE
136
+ no_lse:
137
+ MOVD $ 1 , R0 // stderr
138
+ MOVD R0 , 8 ( RSP )
139
+ MOVD $ no_lse_msg<>(SB) , R1 // message address
140
+ MOVD R1 , 16 ( RSP )
141
+ MOVD $ 64 , R2 // message length
142
+ MOVD R2 , 24 ( RSP )
143
+ CALL runtime·write(SB)
144
+ CALL runtime·exit(SB)
145
+ CALL runtime·abort(SB)
146
+ RET
147
+ #endif
98
148
99
149
// Prevent dead - code elimination of debugCallV2 and debugPinnerV1 , which are
100
150
// intended to be called by debuggers.
0 commit comments