summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2013-02-05 17:38:54 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2013-02-05 17:38:54 -0500
commit30185f421711768d6767d6d67a01bb0d78c9721f (patch)
tree303709e2eb0cccd6cc3906581c0a39a18aed84fd /main.c
parent393c97a004a996f076f5a122b9fa0b9236e3c297 (diff)
Arrays and TODO
Diffstat (limited to 'main.c')
-rw-r--r--main.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/main.c b/main.c
index 22bc3ee..eda3be3 100644
--- a/main.c
+++ b/main.c
@@ -111,6 +111,76 @@ avx_supported (assembler_t *as)
}
int
+avx_supported_array (assembler_t *as)
+{
+ enum
+ {
+ NOT_SUPPORTED,
+ DONE
+ };
+
+ static const uint64_t code[] =
+ {
+ I_push, rcx,
+ I_push, rdx,
+ I_mov, eax, IMM (1),
+ I_cpuid,
+ I_and, ecx, IMM (0x18000000),
+ I_cmp, ecx, IMM (0x18000000),
+ I_jne, LABEL (NOT_SUPPORTED),
+ /* processor supports AVX instructions and XGETBV is enabled by OS */
+ I_xor, ecx, ecx, /* specify 0 for XFEATURE_ENABLED_MASK register */
+ I_xgetbv, /* result in EDX:EAX */
+ I_and, al, IMM (0x06),
+ I_cmp, al, IMM (0x06),
+ I_jne, LABEL (NOT_SUPPORTED),
+ I_mov, eax, IMM (1),
+ I_jmp, LABEL (DONE),
+ DEFINE_LABEL (NOT_SUPPORTED),
+ I_xor, rax, rax,
+ DEFINE_LABEL (DONE),
+ I_pop, rdx,
+ I_pop, rcx,
+ I_ret,
+ 0,
+ };
+
+ static const uint64_t code32[] =
+ {
+ I_push, ecx,
+ I_push, edx,
+ I_mov, eax, IMM (1),
+ I_cpuid,
+ I_and, ecx, IMM (0x18000000),
+ I_cmp, ecx, IMM (0x18000000),
+ I_jne, LABEL(NOT_SUPPORTED),
+ I_xor, ecx, ecx,
+ I_xgetbv,
+ I_and, al, IMM (0x06),
+ I_cmp, al, IMM (0x06),
+ I_jne, LABEL (NOT_SUPPORTED),
+ I_mov, eax, IMM (1),
+ I_jmp, LABEL (DONE),
+ DEFINE_LABEL (NOT_SUPPORTED),
+ I_xor, eax, eax,
+ DEFINE_LABEL (DONE),
+ I_pop, edx,
+ I_pop, ecx,
+ I_ret,
+ 0
+ };
+
+ fragment_t *fragment = fragment_new ();
+ uint8_t *c;
+ typedef int (* func) (void);
+
+ fragment_assemble_array (fragment, code);
+ c = assembler_link (as, fragment, NULL);
+
+ return ((func)c)();
+}
+
+int
main ()
{
assembler_t *assembler = assembler_new ("pixman");