implement runtime @byteSwap and other fixups
* update docs for `@byteSwap`. * fix hash & eql functions for ZigLLVMFnIdBswap not updated to include vector len. this was causing incorrect bswap function being called in unrelated code * fix `@byteSwap` behavior tests only testing comptime and not runtime operations * implement runtime `@byteSwap` * fix incorrect logic in ir_render_vector_to_array and ir_render_array_to_vector with regards to whether or not to bitcast * `@byteSwap` accepts an array operand which it will cast to vector * simplify `@byteSwap` semantic analysis code and various fixes
This commit is contained in:
@@ -4509,9 +4509,7 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *expr_type, BuiltinFn
|
||||
bool is_vector = expr_type->id == ZigTypeIdVector;
|
||||
ZigType *int_type = is_vector ? expr_type->data.vector.elem_type : expr_type;
|
||||
assert(int_type->id == ZigTypeIdInt);
|
||||
uint32_t vector_len = 0;
|
||||
if (is_vector)
|
||||
vector_len = expr_type->data.vector.len;
|
||||
uint32_t vector_len = is_vector ? expr_type->data.vector.len : 0;
|
||||
ZigLLVMFnKey key = {};
|
||||
const char *fn_name;
|
||||
uint32_t n_args;
|
||||
@@ -5563,16 +5561,23 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutable *executable, IrInst
|
||||
// Not an even number of bytes, so we zext 1 byte, then bswap, shift right 1 byte, truncate
|
||||
ZigType *extended_type = get_int_type(g, int_type->data.integral.is_signed,
|
||||
int_type->data.integral.bit_count + 8);
|
||||
if (is_vector)
|
||||
LLVMValueRef shift_amt = LLVMConstInt(get_llvm_type(g, extended_type), 8, false);
|
||||
if (is_vector) {
|
||||
extended_type = get_vector_type(g, expr_type->data.vector.len, extended_type);
|
||||
LLVMValueRef *values = allocate_nonzero<LLVMValueRef>(expr_type->data.vector.len);
|
||||
for (uint32_t i = 0; i < expr_type->data.vector.len; i += 1) {
|
||||
values[i] = shift_amt;
|
||||
}
|
||||
shift_amt = LLVMConstVector(values, expr_type->data.vector.len);
|
||||
free(values);
|
||||
}
|
||||
// aabbcc
|
||||
LLVMValueRef extended = LLVMBuildZExt(g->builder, op, get_llvm_type(g, extended_type), "");
|
||||
// 00aabbcc
|
||||
LLVMValueRef fn_val = get_int_builtin_fn(g, extended_type, BuiltinFnIdBswap);
|
||||
LLVMValueRef swapped = LLVMBuildCall(g->builder, fn_val, &extended, 1, "");
|
||||
// ccbbaa00
|
||||
LLVMValueRef shifted = ZigLLVMBuildLShrExact(g->builder, swapped,
|
||||
LLVMConstInt(get_llvm_type(g, extended_type), 8, false), "");
|
||||
LLVMValueRef shifted = ZigLLVMBuildLShrExact(g->builder, swapped, shift_amt, "");
|
||||
// 00ccbbaa
|
||||
return LLVMBuildTrunc(g->builder, shifted, get_llvm_type(g, expr_type), "");
|
||||
}
|
||||
@@ -5595,7 +5600,7 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutable *executab
|
||||
LLVMValueRef vector = ir_llvm_value(g, instruction->vector);
|
||||
|
||||
ZigType *elem_type = array_type->data.array.child_type;
|
||||
bool bitcast_ok = (elem_type->size_in_bits * 8) == elem_type->abi_size;
|
||||
bool bitcast_ok = elem_type->size_in_bits == elem_type->abi_size * 8;
|
||||
if (bitcast_ok) {
|
||||
LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, result_loc,
|
||||
LLVMPointerType(get_llvm_type(g, instruction->vector->value.type), 0), "");
|
||||
@@ -5629,7 +5634,7 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutable *executab
|
||||
LLVMTypeRef vector_type_ref = get_llvm_type(g, vector_type);
|
||||
|
||||
ZigType *elem_type = vector_type->data.vector.elem_type;
|
||||
bool bitcast_ok = (elem_type->size_in_bits * 8) == elem_type->abi_size;
|
||||
bool bitcast_ok = elem_type->size_in_bits == elem_type->abi_size * 8;
|
||||
if (bitcast_ok) {
|
||||
LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, array_ptr,
|
||||
LLVMPointerType(vector_type_ref, 0), "");
|
||||
@@ -8902,7 +8907,7 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
|
||||
args.append(g->framework_dirs.at(i));
|
||||
}
|
||||
|
||||
//note(dimenus): appending libc headers before c_headers breaks intrinsics
|
||||
//note(dimenus): appending libc headers before c_headers breaks intrinsics
|
||||
//and other compiler specific items
|
||||
// According to Rich Felker libc headers are supposed to go before C language headers.
|
||||
args.append("-isystem");
|
||||
|
||||
Reference in New Issue
Block a user