| ... | @@ -2100,8 +2100,22 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2100,8 +2100,22 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2100 | } | 2100 | } |
| 2101 | | 2101 | |
| 2102 | fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Register { | 2102 | fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Register { |
| 2103 | const reg = try self.copyToTmpRegister(index_ty, index); | 2103 | const reg: Register = blk: { |
| 2104 | try self.genIntMulComplexOpMir(index_ty, .{ .register = reg }, .{ .immediate = elem_size }); | 2104 | switch (index) { |
| | 2105 | .immediate => |imm| { |
| | 2106 | // Optimisation: if index MCValue is an immediate, we can multiply in `comptime` |
| | 2107 | // and set the register directly to the scaled offset as an immediate. |
| | 2108 | const reg = try self.register_manager.allocReg(null, gp); |
| | 2109 | try self.genSetReg(index_ty, reg, .{ .immediate = imm * elem_size }); |
| | 2110 | break :blk reg; |
| | 2111 | }, |
| | 2112 | else => { |
| | 2113 | const reg = try self.copyToTmpRegister(index_ty, index); |
| | 2114 | try self.genIntMulComplexOpMir(index_ty, .{ .register = reg }, .{ .immediate = elem_size }); |
| | 2115 | break :blk reg; |
| | 2116 | }, |
| | 2117 | } |
| | 2118 | }; |
| 2105 | return reg; | 2119 | return reg; |
| 2106 | } | 2120 | } |
| 2107 | | 2121 | |