breaking API changes to all readInt/writeInt functions & more

* add `@bswap` builtin function. See #767
 * comptime evaluation facilities are improved to be able to
   handle a `@ptrCast` with a backing array.
 * `@truncate` allows "truncating" a u0 value to any integer
   type, and the result is always comptime known to be `0`.
 * when specifying pointer alignment in a type expression,
   the alignment value of pointers which do not have addresses
   at runtime is ignored, and always has the default/ABI alignment
 * threw in a fix to freebsd/x86_64.zig to update syntax from
   language changes
 * some improvements are pending #863

closes #638
closes #1733

std lib API changes
 * io.InStream().readIntNe renamed to readIntNative
 * io.InStream().readIntLe renamed to readIntLittle
 * io.InStream().readIntBe renamed to readIntBig
 * introduced io.InStream().readIntForeign
 * io.InStream().readInt has parameter order changed
 * io.InStream().readVarInt has parameter order changed
 * io.InStream().writeIntNe renamed to writeIntNative
 * introduced io.InStream().writeIntForeign
 * io.InStream().writeIntLe renamed to writeIntLittle
 * io.InStream().writeIntBe renamed to writeIntBig
 * io.InStream().writeInt has parameter order changed
 * mem.readInt has different parameters and semantics
 * introduced mem.readIntNative
 * introduced mem.readIntForeign
 * mem.readIntBE renamed to mem.readIntBig and different API
 * mem.readIntLE renamed to mem.readIntLittle and different API
 * introduced mem.readIntSliceNative
 * introduced mem.readIntSliceForeign
 * introduced mem.readIntSliceLittle
 * introduced mem.readIntSliceBig
 * introduced mem.readIntSlice
 * mem.writeInt has different parameters and semantics
 * introduced mem.writeIntNative
 * introduced mem.writeIntForeign
 * mem.writeIntBE renamed to mem.readIntBig and different semantics
 * mem.writeIntLE renamed to mem.readIntLittle and different semantics
 * introduced mem.writeIntSliceForeign
 * introduced mem.writeIntSliceNative
 * introduced mem.writeIntSliceBig
 * introduced mem.writeIntSliceLittle
 * introduced mem.writeIntSlice
 * removed mem.endianSwapIfLe
 * removed mem.endianSwapIfBe
 * removed mem.endianSwapIf
 * added mem.littleToNative
 * added mem.bigToNative
 * added mem.toNative
 * added mem.nativeTo
 * added mem.nativeToLittle
 * added mem.nativeToBig
This commit is contained in:
Andrew Kelley
2018-12-12 20:19:46 -05:00
parent 634d11ab28
commit b883bc873d
34 changed files with 818 additions and 419 deletions

View File

@@ -3814,6 +3814,11 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI
n_args = 1;
key.id = ZigLLVMFnIdPopCount;
key.data.pop_count.bit_count = (uint32_t)int_type->data.integral.bit_count;
} else if (fn_id == BuiltinFnIdBswap) {
fn_name = "bswap";
n_args = 1;
key.id = ZigLLVMFnIdBswap;
key.data.bswap.bit_count = (uint32_t)int_type->data.integral.bit_count;
} else {
zig_unreachable();
}
@@ -5098,6 +5103,29 @@ static LLVMValueRef ir_render_sqrt(CodeGen *g, IrExecutable *executable, IrInstr
return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
}
static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutable *executable, IrInstructionBswap *instruction) {
LLVMValueRef op = ir_llvm_value(g, instruction->op);
ZigType *int_type = instruction->base.value.type;
assert(int_type->id == ZigTypeIdInt);
if (int_type->data.integral.bit_count % 16 == 0) {
LLVMValueRef fn_val = get_int_builtin_fn(g, instruction->base.value.type, BuiltinFnIdBswap);
return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
}
// 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);
// aabbcc
LLVMValueRef extended = LLVMBuildZExt(g->builder, op, extended_type->type_ref, "");
// 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(extended_type->type_ref, 8, false), "");
// 00ccbbaa
return LLVMBuildTrunc(g->builder, shifted, int_type->type_ref, "");
}
static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
AstNode *source_node = instruction->source_node;
Scope *scope = instruction->scope;
@@ -5335,6 +5363,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction);
case IrInstructionIdSqrt:
return ir_render_sqrt(g, executable, (IrInstructionSqrt *)instruction);
case IrInstructionIdBswap:
return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction);
}
zig_unreachable();
}
@@ -6757,6 +6787,7 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);
create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
create_builtin_fn(g, BuiltinFnIdThis, "This", 0);
create_builtin_fn(g, BuiltinFnIdBswap, "bswap", 2);
}
static const char *bool_to_str(bool b) {