| ... | @@ -150,6 +150,10 @@ pub const LLVMIRModule = struct { | ... | @@ -150,6 +150,10 @@ pub const LLVMIRModule = struct { |
| 150 | /// referred to in other instructions. This table is cleared before every function is generated. | 150 | /// referred to in other instructions. This table is cleared before every function is generated. |
| 151 | func_inst_table: std.AutoHashMapUnmanaged(*Inst, *const llvm.ValueRef) = .{}, | 151 | func_inst_table: std.AutoHashMapUnmanaged(*Inst, *const llvm.ValueRef) = .{}, |
| 152 | | 152 | |
| | 153 | /// These fields are used to refer to the LLVM value of the function paramaters in an Arg instruction. |
| | 154 | args: []*const llvm.ValueRef = &[_]*const llvm.ValueRef{}, |
| | 155 | arg_index: usize = 0, |
| | 156 | |
| 153 | pub fn create(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*LLVMIRModule { | 157 | pub fn create(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*LLVMIRModule { |
| 154 | const self = try allocator.create(LLVMIRModule); | 158 | const self = try allocator.create(LLVMIRModule); |
| 155 | errdefer allocator.destroy(self); | 159 | errdefer allocator.destroy(self); |
| ... | @@ -289,6 +293,17 @@ pub const LLVMIRModule = struct { | ... | @@ -289,6 +293,17 @@ pub const LLVMIRModule = struct { |
| 289 | | 293 | |
| 290 | const llvm_func = try self.resolveLLVMFunction(func, src); | 294 | const llvm_func = try self.resolveLLVMFunction(func, src); |
| 291 | | 295 | |
| | 296 | // This gets the LLVM values from the function and stores them in `self.args`. |
| | 297 | const fn_param_len = func.owner_decl.typed_value.most_recent.typed_value.ty.fnParamLen(); |
| | 298 | var args = try self.gpa.alloc(*const llvm.ValueRef, fn_param_len); |
| | 299 | defer self.gpa.free(args); |
| | 300 | |
| | 301 | for (args) |*arg, i| { |
| | 302 | arg.* = llvm.getParam(llvm_func, @intCast(c_uint, i)); |
| | 303 | } |
| | 304 | self.args = args; |
| | 305 | self.arg_index = 0; |
| | 306 | |
| 292 | // Make sure no other LLVM values from other functions can be referenced | 307 | // Make sure no other LLVM values from other functions can be referenced |
| 293 | self.func_inst_table.clearRetainingCapacity(); | 308 | self.func_inst_table.clearRetainingCapacity(); |
| 294 | | 309 | |
| ... | @@ -313,6 +328,8 @@ pub const LLVMIRModule = struct { | ... | @@ -313,6 +328,8 @@ pub const LLVMIRModule = struct { |
| 313 | .alloc => try self.genAlloc(inst.castTag(.alloc).?), | 328 | .alloc => try self.genAlloc(inst.castTag(.alloc).?), |
| 314 | .store => try self.genStore(inst.castTag(.store).?), | 329 | .store => try self.genStore(inst.castTag(.store).?), |
| 315 | .load => try self.genLoad(inst.castTag(.load).?), | 330 | .load => try self.genLoad(inst.castTag(.load).?), |
| | 331 | .ret => try self.genRet(inst.castTag(.ret).?), |
| | 332 | .not => try self.genNot(inst.castTag(.not).?), |
| 316 | .dbg_stmt => blk: { | 333 | .dbg_stmt => blk: { |
| 317 | // TODO: implement debug info | 334 | // TODO: implement debug info |
| 318 | break :blk null; | 335 | break :blk null; |
| ... | @@ -370,14 +387,27 @@ pub const LLVMIRModule = struct { | ... | @@ -370,14 +387,27 @@ pub const LLVMIRModule = struct { |
| 370 | return null; | 387 | return null; |
| 371 | } | 388 | } |
| 372 | | 389 | |
| | 390 | fn genRet(self: *LLVMIRModule, inst: *Inst.UnOp) !?*const llvm.ValueRef { |
| | 391 | _ = self.builder.buildRet(try self.resolveInst(inst.operand)); |
| | 392 | return null; |
| | 393 | } |
| | 394 | |
| | 395 | fn genNot(self: *LLVMIRModule, inst: *Inst.UnOp) !?*const llvm.ValueRef { |
| | 396 | return self.builder.buildNot(try self.resolveInst(inst.operand), ""); |
| | 397 | } |
| | 398 | |
| 373 | fn genUnreach(self: *LLVMIRModule, inst: *Inst.NoOp) ?*const llvm.ValueRef { | 399 | fn genUnreach(self: *LLVMIRModule, inst: *Inst.NoOp) ?*const llvm.ValueRef { |
| 374 | _ = self.builder.buildUnreachable(); | 400 | _ = self.builder.buildUnreachable(); |
| 375 | return null; | 401 | return null; |
| 376 | } | 402 | } |
| 377 | | 403 | |
| 378 | fn genArg(self: *LLVMIRModule, inst: *Inst.Arg) !?*const llvm.ValueRef { | 404 | fn genArg(self: *LLVMIRModule, inst: *Inst.Arg) !?*const llvm.ValueRef { |
| 379 | // TODO: implement this | 405 | const arg_val = self.args[self.arg_index]; |
| 380 | return null; | 406 | self.arg_index += 1; |
| | 407 | |
| | 408 | const ptr_val = self.builder.buildAlloca(try self.getLLVMType(inst.base.ty, inst.base.src), ""); |
| | 409 | _ = self.builder.buildStore(arg_val, ptr_val); |
| | 410 | return self.builder.buildLoad(ptr_val, ""); |
| 381 | } | 411 | } |
| 382 | | 412 | |
| 383 | fn genAlloc(self: *LLVMIRModule, inst: *Inst.NoOp) !?*const llvm.ValueRef { | 413 | fn genAlloc(self: *LLVMIRModule, inst: *Inst.NoOp) !?*const llvm.ValueRef { |