diff options
| author | antlilja <liljaanton2001@gmail.com> | 2023-08-06 00:58:10 +0200 |
|---|---|---|
| committer | antlilja <liljaanton2001@gmail.com> | 2023-08-06 01:46:57 +0200 |
| commit | 86f61a9d2641300a733eee2edc10f57bb3243c57 (patch) | |
| tree | 8aeaa5fa87b8722e701a7093665c11c43ea7cb62 /src | |
| parent | 2b4ac7c6b3563905178b791f2e15631a9a38f7ff (diff) | |
| download | zig-86f61a9d2641300a733eee2edc10f57bb3243c57.tar.gz zig-86f61a9d2641300a733eee2edc10f57bb3243c57.zip | |
Implement bitop intrinsics in new LLVM IR builder
* llvm.bitreverse
* llvm.bswap
* llvm.ctpop
* llvm.ctlz
* llvm.cttz
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen/llvm/Builder.zig | 40 | ||||
| -rw-r--r-- | src/codegen/llvm/bindings.zig | 15 | ||||
| -rw-r--r-- | src/zig_llvm.cpp | 25 | ||||
| -rw-r--r-- | src/zig_llvm.h | 7 |
4 files changed, 87 insertions, 0 deletions
diff --git a/src/codegen/llvm/Builder.zig b/src/codegen/llvm/Builder.zig index d5caff72b0..5e473cdf7d 100644 --- a/src/codegen/llvm/Builder.zig +++ b/src/codegen/llvm/Builder.zig @@ -2430,6 +2430,11 @@ pub const Function = struct { @"llvm.sqrt.", @"llvm.trunc.", @"llvm.fma.", + @"llvm.bitreverse.", + @"llvm.bswap.", + @"llvm.ctpop.", + @"llvm.ctlz.", + @"llvm.cttz.", @"llvm.sadd.sat.", @"llvm.smax.", @"llvm.smin.", @@ -2572,6 +2577,8 @@ pub const Function = struct { .@"fsub fast", .@"llvm.maxnum.", .@"llvm.minnum.", + .@"llvm.ctlz.", + .@"llvm.cttz.", .@"llvm.sadd.sat.", .@"llvm.smax.", .@"llvm.smin.", @@ -2716,6 +2723,9 @@ pub const Function = struct { .@"llvm.sin.", .@"llvm.sqrt.", .@"llvm.trunc.", + .@"llvm.bitreverse.", + .@"llvm.bswap.", + .@"llvm.ctpop.", => @as(Value, @enumFromInt(instruction.data)).typeOfWip(wip), .getelementptr, .@"getelementptr inbounds", @@ -2783,6 +2793,8 @@ pub const Function = struct { .@"fsub fast", .@"llvm.maxnum.", .@"llvm.minnum.", + .@"llvm.ctlz.", + .@"llvm.cttz.", .@"llvm.sadd.sat.", .@"llvm.smax.", .@"llvm.smin.", @@ -2928,6 +2940,9 @@ pub const Function = struct { .@"llvm.sin.", .@"llvm.sqrt.", .@"llvm.trunc.", + .@"llvm.bitreverse.", + .@"llvm.bswap.", + .@"llvm.ctpop.", => @as(Value, @enumFromInt(instruction.data)).typeOf(function_index, builder), .getelementptr, .@"getelementptr inbounds", @@ -3486,6 +3501,10 @@ pub const WipFunction = struct { .@"llvm.sqrt.", .@"llvm.trunc.", => assert(val.typeOfWip(self).scalarType(self.builder).isFloatingPoint()), + .@"llvm.bitreverse.", + .@"llvm.bswap.", + .@"llvm.ctpop.", + => assert(val.typeOfWip(self).scalarType(self.builder).isInteger(self.builder)), else => unreachable, } try self.ensureUnusedExtraCapacity(1, NoExtra, 0); @@ -3507,6 +3526,9 @@ pub const WipFunction = struct { .@"llvm.sin.", .@"llvm.sqrt.", .@"llvm.trunc.", + .@"llvm.bitreverse.", + .@"llvm.bswap.", + .@"llvm.ctpop.", => {}, else => unreachable, } @@ -3525,6 +3547,9 @@ pub const WipFunction = struct { .@"llvm.sin." => &llvm.Builder.buildSin, .@"llvm.sqrt." => &llvm.Builder.buildSqrt, .@"llvm.trunc." => &llvm.Builder.buildFTrunc, + .@"llvm.bitreverse." => &llvm.Builder.buildBitReverse, + .@"llvm.bswap." => &llvm.Builder.buildBSwap, + .@"llvm.ctpop." => &llvm.Builder.buildCTPop, else => unreachable, }(self.llvm.builder, val.toLlvm(self), instruction.llvmName(self))); } @@ -3602,6 +3627,9 @@ pub const WipFunction = struct { .urem, .xor, => assert(lhs.typeOfWip(self) == rhs.typeOfWip(self)), + .@"llvm.ctlz.", + .@"llvm.cttz.", + => assert(lhs.typeOfWip(self).scalarType(self.builder).isInteger(self.builder) and rhs.typeOfWip(self) == .i1), else => unreachable, } try self.ensureUnusedExtraCapacity(1, Instruction.Binary, 0); @@ -3639,6 +3667,8 @@ pub const WipFunction = struct { .fsub, .@"fsub fast" => &llvm.Builder.buildFSub, .@"llvm.maxnum." => &llvm.Builder.buildMaxNum, .@"llvm.minnum." => &llvm.Builder.buildMinNum, + .@"llvm.ctlz." => &llvm.Builder.buildCTLZ, + .@"llvm.cttz." => &llvm.Builder.buildCTTZ, .@"llvm.sadd.sat." => &llvm.Builder.buildSAddSat, .@"llvm.smax." => &llvm.Builder.buildSMax, .@"llvm.smin." => &llvm.Builder.buildSMin, @@ -4669,6 +4699,8 @@ pub const WipFunction = struct { .@"icmp ult", .@"llvm.maxnum.", .@"llvm.minnum.", + .@"llvm.ctlz.", + .@"llvm.cttz.", .@"llvm.sadd.sat.", .@"llvm.smax.", .@"llvm.smin.", @@ -4809,6 +4841,9 @@ pub const WipFunction = struct { .@"llvm.sin.", .@"llvm.sqrt.", .@"llvm.trunc.", + .@"llvm.bitreverse.", + .@"llvm.bswap.", + .@"llvm.ctpop.", => instruction.data = @intFromEnum(instructions.map(@enumFromInt(instruction.data))), .getelementptr, .@"getelementptr inbounds", @@ -7706,6 +7741,9 @@ pub fn printUnbuffered( .@"llvm.sin.", .@"llvm.sqrt.", .@"llvm.trunc.", + .@"llvm.bitreverse.", + .@"llvm.bswap.", + .@"llvm.ctpop.", => |tag| { const val: Value = @enumFromInt(instruction.data); try writer.print(" {s} {%}\n", .{ @@ -7762,6 +7800,8 @@ pub fn printUnbuffered( }, .@"llvm.maxnum.", .@"llvm.minnum.", + .@"llvm.ctlz.", + .@"llvm.cttz.", .@"llvm.sadd.sat.", .@"llvm.smax.", .@"llvm.smin.", diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index cde4990b92..fd111ac94f 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -1065,6 +1065,21 @@ pub const Builder = opaque { pub const buildFTrunc = ZigLLVMBuildFTrunc; extern fn ZigLLVMBuildFTrunc(builder: *Builder, V: *Value, name: [*:0]const u8) *Value; + pub const buildBitReverse = ZigLLVMBuildBitReverse; + extern fn ZigLLVMBuildBitReverse(builder: *Builder, V: *Value, name: [*:0]const u8) *Value; + + pub const buildBSwap = ZigLLVMBuildBSwap; + extern fn ZigLLVMBuildBSwap(builder: *Builder, V: *Value, name: [*:0]const u8) *Value; + + pub const buildCTPop = ZigLLVMBuildCTPop; + extern fn ZigLLVMBuildCTPop(builder: *Builder, V: *Value, name: [*:0]const u8) *Value; + + pub const buildCTLZ = ZigLLVMBuildCTLZ; + extern fn ZigLLVMBuildCTLZ(builder: *Builder, LHS: *Value, RHS: *Value, name: [*:0]const u8) *Value; + + pub const buildCTTZ = ZigLLVMBuildCTTZ; + extern fn ZigLLVMBuildCTTZ(builder: *Builder, LHS: *Value, RHS: *Value, name: [*:0]const u8) *Value; + pub const buildFMA = ZigLLVMBuildFMA; extern fn ZigLLVMBuildFMA(builder: *Builder, a: *Value, b: *Value, c: *Value, name: [*:0]const u8) *Value; diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 51eabf9661..e6568e97a8 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -546,6 +546,31 @@ LLVMValueRef ZigLLVMBuildFTrunc(LLVMBuilderRef B, LLVMValueRef V, const char *na return wrap(call_inst); } +LLVMValueRef ZigLLVMBuildBitReverse(LLVMBuilderRef B, LLVMValueRef V, const char *name) { + CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::bitreverse, unwrap(V), nullptr, name); + return wrap(call_inst); +} + +LLVMValueRef ZigLLVMBuildBSwap(LLVMBuilderRef B, LLVMValueRef V, const char *name) { + CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::bswap, unwrap(V), nullptr, name); + return wrap(call_inst); +} + +LLVMValueRef ZigLLVMBuildCTPop(LLVMBuilderRef B, LLVMValueRef V, const char *name) { + CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::ctpop, unwrap(V), nullptr, name); + return wrap(call_inst); +} + +LLVMValueRef ZigLLVMBuildCTLZ(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) { + CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::ctlz, unwrap(LHS), unwrap(RHS), nullptr, name); + return wrap(call_inst); +} + +LLVMValueRef ZigLLVMBuildCTTZ(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) { + CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::cttz, unwrap(LHS), unwrap(RHS), nullptr, name); + return wrap(call_inst); +} + LLVMValueRef ZigLLVMBuildFMA(LLVMBuilderRef builder, LLVMValueRef A, LLVMValueRef B, LLVMValueRef C, const char *name) { llvm::Type* types[1] = { unwrap(A)->getType(), diff --git a/src/zig_llvm.h b/src/zig_llvm.h index 93fd1aea75..3f5fefb85b 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -155,6 +155,13 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSin(LLVMBuilderRef builder, LLVMValueRef V ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSqrt(LLVMBuilderRef builder, LLVMValueRef V, const char* name); ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFTrunc(LLVMBuilderRef builder, LLVMValueRef V, const char* name); +ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildBitReverse(LLVMBuilderRef builder, LLVMValueRef V, const char* name); +ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildBSwap(LLVMBuilderRef builder, LLVMValueRef V, const char* name); +ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCTPop(LLVMBuilderRef builder, LLVMValueRef V, const char* name); + +ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCTLZ(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); +ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCTTZ(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); + ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFMA(LLVMBuilderRef builder, LLVMValueRef A, LLVMValueRef B, LLVMValueRef C, const char* name); ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMaxNum(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name); |
