1// Copyright 2016 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "asm.h"
6
7.macro check_general_purpose reg
8    cmpq $0, \reg
9    jne .Lfail
10.endm
11
12.macro check_xmm reg
13    // toss the register down on the stack in the red zone
14    // so we can compare with zero.
15    // avoids using the more obvious ptest instruction, which is
16    // only present in SSE4.1
17    movdqu \reg, -16(%rsp)
18    cmpq $0, -16(%rsp)
19    jnz .Lfail
20    cmpq $0, -8(%rsp)
21    jnz .Lfail
22.endm
23
24.macro check_ymm reg
25    vptest \reg, \reg
26    jnz .Lfail
27.endm
28
29.macro check_mm reg
30    movq \reg, %rax
31    cmpq $0, %rax
32    jne .Lfail
33.endm
34
35.macro check_segment reg
36    mov \reg, %ax
37    cmpw $0, %ax
38    jne .Lfail
39.endm
40
41# int thread_entry(void *arg)
42FUNCTION(thread_entry)
43    jz .Lfail
44    jc .Lfail
45    js .Lfail
46    jp .Lfail
47
48    check_general_purpose %rax
49    check_general_purpose %rbx
50    check_general_purpose %rcx
51    check_general_purpose %rdx
52    check_general_purpose %rbp
53    check_general_purpose %rsi
54    check_general_purpose %r8
55    check_general_purpose %r9
56    check_general_purpose %r10
57    check_general_purpose %r11
58    check_general_purpose %r12
59    check_general_purpose %r13
60    check_general_purpose %r14
61    check_general_purpose %r15
62
63    # test thread arg
64    movq $0x1234567890abcdef, %rax
65    cmpq %rax, %rdi
66    jne .Lfail
67
68    # Don't check cs/ss since those are set by the kernel explicitly
69    check_segment %ds
70    check_segment %es
71    check_segment %fs
72    check_segment %gs
73
74    check_mm %mm0
75    check_mm %mm1
76    check_mm %mm2
77    check_mm %mm3
78    check_mm %mm4
79    check_mm %mm5
80    check_mm %mm6
81    check_mm %mm7
82
83    check_xmm %xmm0
84    check_xmm %xmm1
85    check_xmm %xmm2
86    check_xmm %xmm3
87    check_xmm %xmm4
88    check_xmm %xmm5
89    check_xmm %xmm6
90    check_xmm %xmm7
91    check_xmm %xmm8
92    check_xmm %xmm9
93    check_xmm %xmm10
94    check_xmm %xmm11
95    check_xmm %xmm12
96    check_xmm %xmm13
97    check_xmm %xmm14
98    check_xmm %xmm15
99
100    # Use Intel Vol 1 section 14.3 procedure for checking if AVX enabled
101
102    mov $1, %eax
103    cpuid
104    # Check for OSXSAVE support (can we use xgetbv)
105    test $(1<<27), %ecx
106    jz .Lno_avx
107    # Check for AVX support
108    test $(1<<28), %ecx
109    jz .Lno_avx
110    # Check for operating system support for AVX
111    mov $0, %ecx
112    xgetbv
113    and $0b110, %eax
114    cmp $0b110, %eax
115    jz .Lno_avx
116
117    check_ymm %ymm0
118    check_ymm %ymm1
119    check_ymm %ymm2
120    check_ymm %ymm3
121    check_ymm %ymm4
122    check_ymm %ymm5
123    check_ymm %ymm6
124    check_ymm %ymm7
125    check_ymm %ymm8
126    check_ymm %ymm9
127    check_ymm %ymm10
128    check_ymm %ymm11
129    check_ymm %ymm12
130    check_ymm %ymm13
131    check_ymm %ymm14
132    check_ymm %ymm15
133.Lno_avx:
134
135    jmp zx_thread_exit@PLT
136.Lfail:
137    jmp print_fail
138