radv: add initial non-conformant radv vulkan driver
[mesa.git] / src / amd / common / ac_llvm_util.c
1 /*
2 * Copyright 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
15 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18 * USE OR OTHER DEALINGS IN THE SOFTWARE.
19 *
20 * The above copyright notice and this permission notice (including the
21 * next paragraph) shall be included in all copies or substantial portions
22 * of the Software.
23 *
24 */
25 /* based on pieces from si_pipe.c and radeon_llvm_emit.c */
26 #include "ac_llvm_util.h"
27
28 #include <llvm-c/Core.h>
29
30 #include "c11/threads.h"
31
32 #include <assert.h>
33 #include <stdio.h>
34
35 static void ac_init_llvm_target()
36 {
37 #if HAVE_LLVM < 0x0307
38 LLVMInitializeR600TargetInfo();
39 LLVMInitializeR600Target();
40 LLVMInitializeR600TargetMC();
41 LLVMInitializeR600AsmPrinter();
42 #else
43 LLVMInitializeAMDGPUTargetInfo();
44 LLVMInitializeAMDGPUTarget();
45 LLVMInitializeAMDGPUTargetMC();
46 LLVMInitializeAMDGPUAsmPrinter();
47 #endif
48 }
49
50 static once_flag ac_init_llvm_target_once_flag = ONCE_FLAG_INIT;
51
52 static LLVMTargetRef ac_get_llvm_target(const char *triple)
53 {
54 LLVMTargetRef target = NULL;
55 char *err_message = NULL;
56
57 call_once(&ac_init_llvm_target_once_flag, ac_init_llvm_target);
58
59 if (LLVMGetTargetFromTriple(triple, &target, &err_message)) {
60 fprintf(stderr, "Cannot find target for triple %s ", triple);
61 if (err_message) {
62 fprintf(stderr, "%s\n", err_message);
63 }
64 LLVMDisposeMessage(err_message);
65 return NULL;
66 }
67 return target;
68 }
69
70 static const char *ac_get_llvm_processor_name(enum radeon_family family)
71 {
72 switch (family) {
73 case CHIP_TAHITI:
74 return "tahiti";
75 case CHIP_PITCAIRN:
76 return "pitcairn";
77 case CHIP_VERDE:
78 return "verde";
79 case CHIP_OLAND:
80 return "oland";
81 case CHIP_HAINAN:
82 return "hainan";
83 case CHIP_BONAIRE:
84 return "bonaire";
85 case CHIP_KABINI:
86 return "kabini";
87 case CHIP_KAVERI:
88 return "kaveri";
89 case CHIP_HAWAII:
90 return "hawaii";
91 case CHIP_MULLINS:
92 return "mullins";
93 case CHIP_TONGA:
94 return "tonga";
95 case CHIP_ICELAND:
96 return "iceland";
97 case CHIP_CARRIZO:
98 return "carrizo";
99 #if HAVE_LLVM <= 0x0307
100 case CHIP_FIJI:
101 return "tonga";
102 case CHIP_STONEY:
103 return "carrizo";
104 #else
105 case CHIP_FIJI:
106 return "fiji";
107 case CHIP_STONEY:
108 return "stoney";
109 #endif
110 #if HAVE_LLVM <= 0x0308
111 case CHIP_POLARIS10:
112 return "tonga";
113 case CHIP_POLARIS11:
114 return "tonga";
115 #else
116 case CHIP_POLARIS10:
117 return "polaris10";
118 case CHIP_POLARIS11:
119 return "polaris11";
120 #endif
121 default:
122 return "";
123 }
124 }
125
126 LLVMTargetMachineRef ac_create_target_machine(enum radeon_family family)
127 {
128 assert(family >= CHIP_TAHITI);
129
130 const char *triple = "amdgcn--";
131 LLVMTargetRef target = ac_get_llvm_target(triple);
132 LLVMTargetMachineRef tm = LLVMCreateTargetMachine(
133 target,
134 triple,
135 ac_get_llvm_processor_name(family),
136 "+DumpCode,+vgpr-spilling",
137 LLVMCodeGenLevelDefault,
138 LLVMRelocDefault,
139 LLVMCodeModelDefault);
140
141 return tm;
142 }