2 * Copyright 2011 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * Authors: Tom Stellard <thomas.stellard@amd.com>
26 #include "radeon_llvm_emit.h"
27 #include "radeon_elf_util.h"
28 #include "util/u_memory.h"
30 #include <llvm-c/Target.h>
31 #include <llvm-c/TargetMachine.h>
37 #define CPU_STRING_LEN 30
38 #define FS_STRING_LEN 30
39 #define TRIPLE_STRING_LEN 7
42 * Set the shader type we want to compile
44 * @param type shader type to set
46 void radeon_llvm_shader_type(LLVMValueRef F
, unsigned type
)
49 sprintf(Str
, "%1d", type
);
51 LLVMAddTargetDependentFunctionAttr(F
, "ShaderType", Str
);
54 static void init_r600_target() {
55 static unsigned initialized
= 0;
57 LLVMInitializeR600TargetInfo();
58 LLVMInitializeR600Target();
59 LLVMInitializeR600TargetMC();
60 LLVMInitializeR600AsmPrinter();
65 static LLVMTargetRef
get_r600_target() {
66 LLVMTargetRef target
= NULL
;
68 for (target
= LLVMGetFirstTarget(); target
;
69 target
= LLVMGetNextTarget(target
)) {
70 if (!strncmp(LLVMGetTargetName(target
), "r600", 4)) {
76 fprintf(stderr
, "Can't find target r600\n");
83 * Compile an LLVM module to machine code.
85 * @returns 0 for success, 1 for failure
87 unsigned radeon_llvm_compile(LLVMModuleRef M
, struct radeon_shader_binary
*binary
,
88 const char * gpu_family
, unsigned dump
) {
91 LLVMTargetMachineRef tm
;
92 char cpu
[CPU_STRING_LEN
];
93 char fs
[FS_STRING_LEN
];
95 LLVMMemoryBufferRef out_buffer
;
97 const char *buffer_data
;
98 char triple
[TRIPLE_STRING_LEN
];
103 target
= get_r600_target();
108 strncpy(cpu
, gpu_family
, CPU_STRING_LEN
);
109 memset(fs
, 0, sizeof(fs
));
112 strncpy(fs
, "+DumpCode", FS_STRING_LEN
);
114 strncpy(triple
, "r600--", TRIPLE_STRING_LEN
);
115 tm
= LLVMCreateTargetMachine(target
, triple
, cpu
, fs
,
116 LLVMCodeGenLevelDefault
, LLVMRelocDefault
,
117 LLVMCodeModelDefault
);
119 r
= LLVMTargetMachineEmitToMemoryBuffer(tm
, M
, LLVMObjectFile
, &err
,
122 fprintf(stderr
, "%s", err
);
127 buffer_size
= LLVMGetBufferSize(out_buffer
);
128 buffer_data
= LLVMGetBufferStart(out_buffer
);
130 radeon_elf_read(buffer_data
, buffer_size
, binary
, dump
);
132 LLVMDisposeMemoryBuffer(out_buffer
);
133 LLVMDisposeTargetMachine(tm
);