1 /************************************************************************** 2 * 3 * Copyright 2009 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 29 /** 30 * @file 31 * Helper functions for manipulation structures. 32 * 33 * @author Jose Fonseca <jfonseca (at) vmware.com> 34 */ 35 36 37 #include "util/u_debug.h" 38 #include "util/u_memory.h" 39 40 #include "lp_bld_const.h" 41 #include "lp_bld_debug.h" 42 #include "lp_bld_struct.h" 43 44 45 LLVMValueRef 46 lp_build_struct_get_ptr(struct gallivm_state *gallivm, 47 LLVMValueRef ptr, 48 unsigned member, 49 const char *name) 50 { 51 LLVMValueRef indices[2]; 52 LLVMValueRef member_ptr; 53 assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind); 54 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMStructTypeKind); 55 indices[0] = lp_build_const_int32(gallivm, 0); 56 indices[1] = lp_build_const_int32(gallivm, member); 57 member_ptr = LLVMBuildGEP(gallivm->builder, ptr, indices, Elements(indices), ""); 58 lp_build_name(member_ptr, "%s.%s_ptr", LLVMGetValueName(ptr), name); 59 return member_ptr; 60 } 61 62 63 LLVMValueRef 64 lp_build_struct_get(struct gallivm_state *gallivm, 65 LLVMValueRef ptr, 66 unsigned member, 67 const char *name) 68 { 69 LLVMValueRef member_ptr; 70 LLVMValueRef res; 71 assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind); 72 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMStructTypeKind); 73 member_ptr = lp_build_struct_get_ptr(gallivm, ptr, member, name); 74 res = LLVMBuildLoad(gallivm->builder, member_ptr, ""); 75 lp_build_name(res, "%s.%s", LLVMGetValueName(ptr), name); 76 return res; 77 } 78 79 80 LLVMValueRef 81 lp_build_array_get_ptr(struct gallivm_state *gallivm, 82 LLVMValueRef ptr, 83 LLVMValueRef index) 84 { 85 LLVMValueRef indices[2]; 86 LLVMValueRef element_ptr; 87 assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind); 88 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMArrayTypeKind); 89 indices[0] = lp_build_const_int32(gallivm, 0); 90 indices[1] = index; 91 element_ptr = LLVMBuildGEP(gallivm->builder, ptr, indices, Elements(indices), ""); 92 #ifdef DEBUG 93 lp_build_name(element_ptr, "&%s[%s]", 94 LLVMGetValueName(ptr), LLVMGetValueName(index)); 95 #endif 96 return element_ptr; 97 } 98 99 100 LLVMValueRef 101 lp_build_array_get(struct gallivm_state *gallivm, 102 LLVMValueRef ptr, 103 LLVMValueRef index) 104 { 105 LLVMValueRef element_ptr; 106 LLVMValueRef res; 107 assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind); 108 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMArrayTypeKind); 109 element_ptr = lp_build_array_get_ptr(gallivm, ptr, index); 110 res = LLVMBuildLoad(gallivm->builder, element_ptr, ""); 111 #ifdef DEBUG 112 lp_build_name(res, "%s[%s]", LLVMGetValueName(ptr), LLVMGetValueName(index)); 113 #endif 114 return res; 115 } 116 117 118 void 119 lp_build_array_set(struct gallivm_state *gallivm, 120 LLVMValueRef ptr, 121 LLVMValueRef index, 122 LLVMValueRef value) 123 { 124 LLVMValueRef element_ptr; 125 assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind); 126 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMArrayTypeKind); 127 element_ptr = lp_build_array_get_ptr(gallivm, ptr, index); 128 LLVMBuildStore(gallivm->builder, value, element_ptr); 129 } 130 131 132 LLVMValueRef 133 lp_build_pointer_get(LLVMBuilderRef builder, 134 LLVMValueRef ptr, 135 LLVMValueRef index) 136 { 137 LLVMValueRef element_ptr; 138 LLVMValueRef res; 139 assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind); 140 element_ptr = LLVMBuildGEP(builder, ptr, &index, 1, ""); 141 res = LLVMBuildLoad(builder, element_ptr, ""); 142 #ifdef DEBUG 143 lp_build_name(res, "%s[%s]", LLVMGetValueName(ptr), LLVMGetValueName(index)); 144 #endif 145 return res; 146 } 147 148 149 LLVMValueRef 150 lp_build_pointer_get_unaligned(LLVMBuilderRef builder, 151 LLVMValueRef ptr, 152 LLVMValueRef index, 153 unsigned alignment) 154 { 155 LLVMValueRef element_ptr; 156 LLVMValueRef res; 157 assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind); 158 element_ptr = LLVMBuildGEP(builder, ptr, &index, 1, ""); 159 res = LLVMBuildLoad(builder, element_ptr, ""); 160 lp_set_load_alignment(res, alignment); 161 #ifdef DEBUG 162 lp_build_name(res, "%s[%s]", LLVMGetValueName(ptr), LLVMGetValueName(index)); 163 #endif 164 return res; 165 } 166 167 168 void 169 lp_build_pointer_set(LLVMBuilderRef builder, 170 LLVMValueRef ptr, 171 LLVMValueRef index, 172 LLVMValueRef value) 173 { 174 LLVMValueRef element_ptr; 175 element_ptr = LLVMBuildGEP(builder, ptr, &index, 1, ""); 176 LLVMBuildStore(builder, value, element_ptr); 177 } 178 179 180 void 181 lp_build_pointer_set_unaligned(LLVMBuilderRef builder, 182 LLVMValueRef ptr, 183 LLVMValueRef index, 184 LLVMValueRef value, 185 unsigned alignment) 186 { 187 LLVMValueRef element_ptr; 188 LLVMValueRef instr; 189 element_ptr = LLVMBuildGEP(builder, ptr, &index, 1, ""); 190 instr = LLVMBuildStore(builder, value, element_ptr); 191 lp_set_store_alignment(instr, alignment); 192 } 193