Constant shifts

This commit is contained in:
David Gonzalez Martin 2025-02-21 13:14:10 -06:00
parent dc52283250
commit 99e13a7218
6 changed files with 66 additions and 4 deletions

View File

@ -568,6 +568,18 @@ pub const Builder = opaque {
return api.LLVMBuildURem(builder, left, right, "");
}
pub fn create_shl(builder: *Builder, left: *Value, right: *Value) *Value {
return api.LLVMBuildShl(builder, left, right, "");
}
pub fn create_ashr(builder: *Builder, left: *Value, right: *Value) *Value {
return api.LLVMBuildAShr(builder, left, right, "");
}
pub fn create_lshr(builder: *Builder, left: *Value, right: *Value) *Value {
return api.LLVMBuildLShr(builder, left, right, "");
}
pub fn create_ret_void(builder: *Builder) void {
builder.create_ret(null);
}

View File

@ -302,6 +302,9 @@ const Converter = struct {
sdiv,
urem,
srem,
shl,
ashr,
lshr,
};
fn parse_value(noalias converter: *Converter, noalias thread: *llvm.Thread, expected_type: Type) *llvm.Value {
@ -330,6 +333,9 @@ const Converter = struct {
.udiv => thread.builder.create_udiv(left, right),
.srem => thread.builder.create_srem(left, right),
.urem => thread.builder.create_urem(left, right),
.shl => thread.builder.create_shl(left, right),
.ashr => thread.builder.create_ashr(left, right),
.lshr => thread.builder.create_lshr(left, right),
};
const ch = converter.content[converter.offset];
@ -349,10 +355,10 @@ const Converter = struct {
},
'/' => blk: {
converter.offset += 1;
switch (expected_type.signedness) {
true => break :blk .sdiv,
false => break :blk .udiv,
}
break :blk switch (expected_type.signedness) {
true => .sdiv,
false => .udiv,
};
},
'%' => blk: {
converter.offset += 1;
@ -361,6 +367,31 @@ const Converter = struct {
false => break :blk .urem,
}
},
'<' => blk: {
converter.offset += 1;
break :blk switch (converter.content[converter.offset]) {
'<' => b: {
converter.offset += 1;
break :b .shl;
},
else => os.abort(),
};
},
'>' => blk: {
converter.offset += 1;
break :blk switch (converter.content[converter.offset]) {
'>' => b: {
converter.offset += 1;
break :b switch (expected_type.signedness) {
true => .ashr,
false => .lshr,
};
},
else => os.abort(),
};
},
else => os.abort(),
};

View File

@ -102,3 +102,11 @@ test "constant div" {
test "constant rem" {
try invoke("constant_rem");
}
test "constant shift left" {
try invoke("constant_shift_left");
}
test "constant shift right" {
try invoke("constant_shift_right");
}

View File

@ -26,6 +26,9 @@ pub extern fn LLVMBuildSDiv(builder: *llvm.Builder, left: *llvm.Value, right: *l
pub extern fn LLVMBuildUDiv(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
pub extern fn LLVMBuildSRem(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
pub extern fn LLVMBuildURem(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
pub extern fn LLVMBuildShl(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
pub extern fn LLVMBuildAShr(builder: *llvm.Builder, left: *llvm.Value, right: *llvm.Value, name: [*:0]const u8) *llvm.Value;
pub extern fn LLVMBuildLShr(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;

View File

@ -0,0 +1,4 @@
[export] main = fn [cc(c)] () s32
{
return 0 << 1;
}

View File

@ -0,0 +1,4 @@
[export] main = fn [cc(c)] () s32
{
return 0 >> 1;
}