diff --git a/src/LLVM.zig b/src/LLVM.zig index e3f123b..d8af825 100644 --- a/src/LLVM.zig +++ b/src/LLVM.zig @@ -588,6 +588,10 @@ pub const Builder = opaque { return api.LLVMBuildOr(builder, left, right, ""); } + pub fn create_xor(builder: *Builder, left: *Value, right: *Value) *Value { + return api.LLVMBuildXor(builder, left, right, ""); + } + pub fn create_ret_void(builder: *Builder) void { builder.create_ret(null); } diff --git a/src/converter.zig b/src/converter.zig index 3e179a9..2d204b3 100644 --- a/src/converter.zig +++ b/src/converter.zig @@ -307,6 +307,7 @@ const Converter = struct { lshr, @"and", @"or", + xor, }; fn parse_value(noalias converter: *Converter, noalias thread: *llvm.Thread, expected_type: Type) *llvm.Value { @@ -340,6 +341,7 @@ const Converter = struct { .lshr => thread.builder.create_lshr(left, right), .@"and" => thread.builder.create_and(left, right), .@"or" => thread.builder.create_or(left, right), + .xor => thread.builder.create_xor(left, right), }; const ch = converter.content[converter.offset]; @@ -404,6 +406,10 @@ const Converter = struct { converter.offset += 1; break :blk .@"or"; }, + '^' => blk: { + converter.offset += 1; + break :blk .xor; + }, else => os.abort(), }; diff --git a/src/converter_test.zig b/src/converter_test.zig index 8e24d25..fee7c16 100644 --- a/src/converter_test.zig +++ b/src/converter_test.zig @@ -1,5 +1,6 @@ const lib = @import("lib.zig"); const assert = lib.assert; +const std = @import("std"); const converter = @import("converter.zig"); const BuildMode = converter.BuildMode; @@ -9,7 +10,6 @@ fn invoke(name: []const u8) !void { lib.GlobalState.initialize(); } - const std = @import("std"); comptime assert(lib.is_test); const allocator = std.testing.allocator; @@ -79,42 +79,50 @@ fn invoke_single(options: InvokeWrapper, build_mode: BuildMode, has_debug_info: }); } +fn invsrc(src: std.builtin.SourceLocation) !void { + try invoke(src.fn_name[std.mem.lastIndexOfScalar(u8, src.fn_name, '.').? + 1 ..]); +} + test "minimal" { - try invoke("minimal"); + try invsrc(@src()); } -test "constant add" { - try invoke("constant_add"); +test "constant_add" { + try invsrc(@src()); } -test "constant sub" { - try invoke("constant_sub"); +test "constant_sub" { + try invsrc(@src()); } -test "constant mul" { - try invoke("constant_mul"); +test "constant_mul" { + try invsrc(@src()); } -test "constant div" { - try invoke("constant_div"); +test "constant_div" { + try invsrc(@src()); } -test "constant rem" { - try invoke("constant_rem"); +test "constant_rem" { + try invsrc(@src()); } -test "constant shift left" { - try invoke("constant_shift_left"); +test "constant_shift_left" { + try invsrc(@src()); } -test "constant shift right" { - try invoke("constant_shift_right"); +test "constant_shift_right" { + try invsrc(@src()); } -test "constant and" { - try invoke("constant_and"); +test "constant_and" { + try invsrc(@src()); } -test "constant or" { - try invoke("constant_or"); +test "constant_or" { + try invsrc(@src()); +} + +test "constant_xor" { + try invsrc(@src()); } diff --git a/src/llvm_api.zig b/src/llvm_api.zig index 07492a3..5af1f5e 100644 --- a/src/llvm_api.zig +++ b/src/llvm_api.zig @@ -31,6 +31,7 @@ pub extern fn LLVMBuildAShr(builder: *llvm.Builder, left: *llvm.Value, right: *l pub extern fn LLVMBuildLShr(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value; pub extern fn LLVMBuildAnd(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value; pub extern fn LLVMBuildOr(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value; +pub extern fn LLVMBuildXor(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value; pub extern fn LLVMTypeOf(value: *llvm.Value) *llvm.Type; pub extern fn LLVMGlobalGetValueType(value: *llvm.GlobalValue) *llvm.Type; diff --git a/tests/constant_xor.bbb b/tests/constant_xor.bbb new file mode 100644 index 0000000..78dbee3 --- /dev/null +++ b/tests/constant_xor.bbb @@ -0,0 +1,4 @@ +[export] main = fn [cc(c)] () s32 +{ + return 0 ^ 0; +}