| ... | ... | @@ -150,6 +150,10 @@ pub const LLVMIRModule = struct { |
| 150 | 150 | /// referred to in other instructions. This table is cleared before every function is generated. |
| 151 | 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 | 157 | pub fn create(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*LLVMIRModule { |
| 154 | 158 | const self = try allocator.create(LLVMIRModule); |
| 155 | 159 | errdefer allocator.destroy(self); |
| ... | ... | @@ -289,6 +293,17 @@ pub const LLVMIRModule = struct { |
| 289 | 293 | |
| 290 | 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 | 307 | // Make sure no other LLVM values from other functions can be referenced |
| 293 | 308 | self.func_inst_table.clearRetainingCapacity(); |
| 294 | 309 | |
| ... | ... | @@ -313,6 +328,8 @@ pub const LLVMIRModule = struct { |
| 313 | 328 | .alloc => try self.genAlloc(inst.castTag(.alloc).?), |
| 314 | 329 | .store => try self.genStore(inst.castTag(.store).?), |
| 315 | 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 | 333 | .dbg_stmt => blk: { |
| 317 | 334 | // TODO: implement debug info |
| 318 | 335 | break :blk null; |
| ... | ... | @@ -370,14 +387,27 @@ pub const LLVMIRModule = struct { |
| 370 | 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 | 399 | fn genUnreach(self: *LLVMIRModule, inst: *Inst.NoOp) ?*const llvm.ValueRef { |
| 374 | 400 | _ = self.builder.buildUnreachable(); |
| 375 | 401 | return null; |
| 376 | 402 | } |
| 377 | 403 | |
| 378 | 404 | fn genArg(self: *LLVMIRModule, inst: *Inst.Arg) !?*const llvm.ValueRef { |
| 379 | | // TODO: implement this |
| 380 | | return null; |
| 405 | const arg_val = self.args[self.arg_index]; |
| 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 | 413 | fn genAlloc(self: *LLVMIRModule, inst: *Inst.NoOp) !?*const llvm.ValueRef { |