| ... | @@ -1318,37 +1318,38 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1318,37 +1318,38 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1318 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 1318 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 1319 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf); | 1319 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf); |
| 1320 | | 1320 | |
| 1321 | const index_ty = self.air.typeOf(bin_op.rhs); | 1321 | const offset_reg = blk: { |
| 1322 | const index_mcv: MCValue = blk: { | 1322 | const index_ty = self.air.typeOf(bin_op.rhs); |
| 1323 | switch (try self.resolveInst(bin_op.rhs)) { | 1323 | const index_mcv = try self.resolveInst(bin_op.rhs); |
| 1324 | .register => |reg| { | 1324 | const offset_reg = try self.register_manager.allocReg(null, &.{}); |
| 1325 | if (reg.to64() != .rcx) { | 1325 | try self.genSetReg(index_ty, offset_reg, index_mcv); |
| 1326 | try self.register_manager.getReg(.rcx, inst); | 1326 | try self.genIMulOpMir(index_ty, .{ .register = offset_reg }, .{ .immediate = elem_size }); |
| 1327 | } | 1327 | break :blk offset_reg; |
| 1328 | break :blk MCValue{ .register = .rcx }; | | |
| 1329 | }, | | |
| 1330 | else => return self.fail("TODO move index mcv into a register", .{}), | | |
| 1331 | } | | |
| 1332 | }; | 1328 | }; |
| 1333 | | 1329 | |
| 1334 | try self.genIMulOpMir(index_ty, index_mcv, .{ .immediate = elem_size }); | | |
| 1335 | | | |
| 1336 | const dst_mcv = blk: { | 1330 | const dst_mcv = blk: { |
| 1337 | switch (slice_mcv) { | 1331 | switch (slice_mcv) { |
| 1338 | .stack_offset => |unadjusted_off| { | 1332 | .stack_offset => |off| { |
| 1339 | const dst_mcv = try self.allocRegOrMem(inst, false); | 1333 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 1340 | const addr_reg = try self.register_manager.allocReg(null, &.{index_mcv.register}); | 1334 | const addr_reg = try self.register_manager.allocReg(null, &.{offset_reg}); |
| 1341 | const slice_ptr_abi_size = @intCast(u32, slice_ptr_field_type.abiSize(self.target.*)); | 1335 | // mov reg, [rbp - 8] |
| 1342 | const off = unadjusted_off + elem_size; | | |
| 1343 | // lea reg, [rbp - 8 + rcx*1] | | |
| 1344 | _ = try self.addInst(.{ | 1336 | _ = try self.addInst(.{ |
| 1345 | .tag = .lea, | 1337 | .tag = .mov, |
| 1346 | .ops = (Mir.Ops{ | 1338 | .ops = (Mir.Ops{ |
| 1347 | .reg1 = registerAlias(addr_reg, slice_ptr_abi_size), | 1339 | .reg1 = addr_reg.to64(), |
| 1348 | .reg2 = .rbp, | 1340 | .reg2 = .rbp, |
| 1349 | .flags = 0b11, | 1341 | .flags = 0b01, |
| | 1342 | }).encode(), |
| | 1343 | .data = .{ .imm = -@intCast(i32, off + 16) }, |
| | 1344 | }); |
| | 1345 | // add addr, offset |
| | 1346 | _ = try self.addInst(.{ |
| | 1347 | .tag = .add, |
| | 1348 | .ops = (Mir.Ops{ |
| | 1349 | .reg1 = addr_reg.to64(), |
| | 1350 | .reg2 = offset_reg.to64(), |
| 1350 | }).encode(), | 1351 | }).encode(), |
| 1351 | .data = .{ .imm = -@intCast(i32, off) }, | 1352 | .data = undefined, |
| 1352 | }); | 1353 | }); |
| 1353 | try self.load(dst_mcv, .{ .register = addr_reg }, slice_ptr_field_type); | 1354 | try self.load(dst_mcv, .{ .register = addr_reg }, slice_ptr_field_type); |
| 1354 | break :blk dst_mcv; | 1355 | break :blk dst_mcv; |
| ... | @@ -1528,7 +1529,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -1528,7 +1529,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1528 | &.{ reg, .rax, .rcx }, | 1529 | &.{ reg, .rax, .rcx }, |
| 1529 | ); | 1530 | ); |
| 1530 | const addr_reg = regs[0]; | 1531 | const addr_reg = regs[0]; |
| 1531 | const len_reg = regs[1]; | 1532 | const count_reg = regs[1]; |
| 1532 | const tmp_reg = regs[2]; | 1533 | const tmp_reg = regs[2]; |
| 1533 | | 1534 | |
| 1534 | _ = try self.addInst(.{ | 1535 | _ = try self.addInst(.{ |
| ... | @@ -1544,12 +1545,12 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -1544,12 +1545,12 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1544 | try self.register_manager.getReg(.rcx, null); | 1545 | try self.register_manager.getReg(.rcx, null); |
| 1545 | | 1546 | |
| 1546 | // TODO allow for abi size to be u64 | 1547 | // TODO allow for abi size to be u64 |
| 1547 | try self.genSetReg(Type.initTag(.u32), len_reg, .{ .immediate = @intCast(u32, abi_size) }); | 1548 | try self.genSetReg(Type.initTag(.u32), count_reg, .{ .immediate = @intCast(u32, abi_size) }); |
| 1548 | | 1549 | |
| 1549 | return self.genInlineMemcpy( | 1550 | return self.genInlineMemcpy( |
| 1550 | -@intCast(i32, off + abi_size), | 1551 | -@intCast(i32, off + abi_size), |
| 1551 | registerAlias(addr_reg, @divExact(reg.size(), 8)), | 1552 | registerAlias(addr_reg, @divExact(reg.size(), 8)), |
| 1552 | len_reg.to64(), | 1553 | count_reg.to64(), |
| 1553 | tmp_reg.to8(), | 1554 | tmp_reg.to8(), |
| 1554 | ); | 1555 | ); |
| 1555 | }, | 1556 | }, |
| ... | @@ -1592,11 +1593,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1592,11 +1593,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1592 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1593 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1593 | } | 1594 | } |
| 1594 | | 1595 | |
| 1595 | fn airStore(self: *Self, inst: Air.Inst.Index) !void { | 1596 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| 1596 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 1597 | _ = ptr_ty; |
| 1597 | const ptr = try self.resolveInst(bin_op.lhs); | | |
| 1598 | const value = try self.resolveInst(bin_op.rhs); | | |
| 1599 | const elem_ty = self.air.typeOf(bin_op.rhs); | | |
| 1600 | switch (ptr) { | 1598 | switch (ptr) { |
| 1601 | .none => unreachable, | 1599 | .none => unreachable, |
| 1602 | .undef => unreachable, | 1600 | .undef => unreachable, |
| ... | @@ -1605,19 +1603,58 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1605,19 +1603,58 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { |
| 1605 | .compare_flags_unsigned => unreachable, | 1603 | .compare_flags_unsigned => unreachable, |
| 1606 | .compare_flags_signed => unreachable, | 1604 | .compare_flags_signed => unreachable, |
| 1607 | .immediate => |imm| { | 1605 | .immediate => |imm| { |
| 1608 | try self.setRegOrMem(elem_ty, .{ .memory = imm }, value); | 1606 | try self.setRegOrMem(value_ty, .{ .memory = imm }, value); |
| 1609 | }, | 1607 | }, |
| 1610 | .ptr_stack_offset => |off| { | 1608 | .ptr_stack_offset => |off| { |
| 1611 | try self.genSetStack(elem_ty, off, value); | 1609 | try self.genSetStack(value_ty, off, value); |
| 1612 | }, | 1610 | }, |
| 1613 | .ptr_embedded_in_code => |off| { | 1611 | .ptr_embedded_in_code => |off| { |
| 1614 | try self.setRegOrMem(elem_ty, .{ .embedded_in_code = off }, value); | 1612 | try self.setRegOrMem(value_ty, .{ .embedded_in_code = off }, value); |
| 1615 | }, | 1613 | }, |
| 1616 | .embedded_in_code => { | 1614 | .embedded_in_code => { |
| 1617 | return self.fail("TODO implement storing to MCValue.embedded_in_code", .{}); | 1615 | return self.fail("TODO implement storing to MCValue.embedded_in_code", .{}); |
| 1618 | }, | 1616 | }, |
| 1619 | .register => |reg| { | 1617 | .register => |reg| { |
| 1620 | try self.genSetPtrReg(elem_ty, reg, value); | 1618 | switch (value) { |
| | 1619 | .none => unreachable, |
| | 1620 | .undef => unreachable, |
| | 1621 | .dead => unreachable, |
| | 1622 | .unreach => unreachable, |
| | 1623 | .compare_flags_unsigned => unreachable, |
| | 1624 | .compare_flags_signed => unreachable, |
| | 1625 | .immediate => |imm| { |
| | 1626 | const abi_size = value_ty.abiSize(self.target.*); |
| | 1627 | switch (abi_size) { |
| | 1628 | 1, 2, 4 => { |
| | 1629 | // TODO this is wasteful! |
| | 1630 | // introduce new MIR tag specifically for mov [reg + 0], imm |
| | 1631 | const payload = try self.addExtra(Mir.ImmPair{ |
| | 1632 | .dest_off = 0, |
| | 1633 | .operand = @bitCast(i32, @intCast(u32, imm)), |
| | 1634 | }); |
| | 1635 | _ = try self.addInst(.{ |
| | 1636 | .tag = .mov_mem_imm, |
| | 1637 | .ops = (Mir.Ops{ |
| | 1638 | .reg1 = reg.to64(), |
| | 1639 | .flags = switch (abi_size) { |
| | 1640 | 1 => 0b00, |
| | 1641 | 2 => 0b01, |
| | 1642 | 4 => 0b10, |
| | 1643 | else => unreachable, |
| | 1644 | }, |
| | 1645 | }).encode(), |
| | 1646 | .data = .{ .payload = payload }, |
| | 1647 | }); |
| | 1648 | }, |
| | 1649 | else => { |
| | 1650 | return self.fail("TODO implement set pointee with immediate of ABI size {d}", .{abi_size}); |
| | 1651 | }, |
| | 1652 | } |
| | 1653 | }, |
| | 1654 | else => |other| { |
| | 1655 | return self.fail("TODO implement set pointee with {}", .{other}); |
| | 1656 | }, |
| | 1657 | } |
| 1621 | }, | 1658 | }, |
| 1622 | .memory => { | 1659 | .memory => { |
| 1623 | return self.fail("TODO implement storing to MCValue.memory", .{}); | 1660 | return self.fail("TODO implement storing to MCValue.memory", .{}); |
| ... | @@ -1626,6 +1663,15 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1626,6 +1663,15 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { |
| 1626 | return self.fail("TODO implement storing to MCValue.stack_offset", .{}); | 1663 | return self.fail("TODO implement storing to MCValue.stack_offset", .{}); |
| 1627 | }, | 1664 | }, |
| 1628 | } | 1665 | } |
| | 1666 | } |
| | 1667 | |
| | 1668 | fn airStore(self: *Self, inst: Air.Inst.Index) !void { |
| | 1669 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| | 1670 | const ptr = try self.resolveInst(bin_op.lhs); |
| | 1671 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| | 1672 | const value = try self.resolveInst(bin_op.rhs); |
| | 1673 | const value_ty = self.air.typeOf(bin_op.rhs); |
| | 1674 | try self.store(ptr, value, ptr_ty, value_ty); |
| 1629 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); | 1675 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1630 | } | 1676 | } |
| 1631 | | 1677 | |
| ... | @@ -1653,9 +1699,8 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde | ... | @@ -1653,9 +1699,8 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 1653 | | 1699 | |
| 1654 | switch (mcv) { | 1700 | switch (mcv) { |
| 1655 | .ptr_stack_offset => |off| { | 1701 | .ptr_stack_offset => |off| { |
| 1656 | break :result MCValue{ | 1702 | const ptr_stack_offset = off - struct_size + struct_field_offset + struct_field_size; |
| 1657 | .ptr_stack_offset = off + struct_size - struct_field_offset - struct_field_size, | 1703 | break :result MCValue{ .ptr_stack_offset = ptr_stack_offset }; |
| 1658 | }; | | |
| 1659 | }, | 1704 | }, |
| 1660 | else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}), | 1705 | else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}), |
| 1661 | } | 1706 | } |
| ... | @@ -1677,9 +1722,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1677,9 +1722,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1677 | | 1722 | |
| 1678 | switch (mcv) { | 1723 | switch (mcv) { |
| 1679 | .stack_offset => |off| { | 1724 | .stack_offset => |off| { |
| 1680 | break :result MCValue{ | 1725 | const stack_offset = off - struct_size + struct_field_offset + struct_field_size; |
| 1681 | .stack_offset = off + struct_size - struct_field_offset - struct_field_size, | 1726 | break :result MCValue{ .stack_offset = stack_offset }; |
| 1682 | }; | | |
| 1683 | }, | 1727 | }, |
| 1684 | else => return self.fail("TODO implement codegen struct_field_val for {}", .{mcv}), | 1728 | else => return self.fail("TODO implement codegen struct_field_val for {}", .{mcv}), |
| 1685 | } | 1729 | } |
| ... | @@ -1956,7 +2000,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) ! | ... | @@ -1956,7 +2000,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) ! |
| 1956 | .immediate => |imm| { | 2000 | .immediate => |imm| { |
| 1957 | // TODO take into account the type's ABI size when selecting the register alias | 2001 | // TODO take into account the type's ABI size when selecting the register alias |
| 1958 | // register, immediate | 2002 | // register, immediate |
| 1959 | if (imm <= math.maxInt(i32)) { | 2003 | if (math.minInt(i32) <= imm and imm <= math.maxInt(i32)) { |
| 1960 | _ = try self.addInst(.{ | 2004 | _ = try self.addInst(.{ |
| 1961 | .tag = .imul_complex, | 2005 | .tag = .imul_complex, |
| 1962 | .ops = (Mir.Ops{ | 2006 | .ops = (Mir.Ops{ |
| ... | @@ -3166,7 +3210,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -3166,7 +3210,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3166 | | 3210 | |
| 3167 | const regs = try self.register_manager.allocRegs(3, .{ null, null, null }, &.{ .rax, .rcx }); | 3211 | const regs = try self.register_manager.allocRegs(3, .{ null, null, null }, &.{ .rax, .rcx }); |
| 3168 | const addr_reg = regs[0]; | 3212 | const addr_reg = regs[0]; |
| 3169 | const len_reg = regs[1]; | 3213 | const count_reg = regs[1]; |
| 3170 | const tmp_reg = regs[2]; | 3214 | const tmp_reg = regs[2]; |
| 3171 | | 3215 | |
| 3172 | try self.register_manager.getReg(.rax, null); | 3216 | try self.register_manager.getReg(.rax, null); |
| ... | @@ -3182,12 +3226,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -3182,12 +3226,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3182 | }); | 3226 | }); |
| 3183 | | 3227 | |
| 3184 | // TODO allow for abi_size to be u64 | 3228 | // TODO allow for abi_size to be u64 |
| 3185 | try self.genSetReg(Type.initTag(.u32), len_reg, .{ .immediate = @intCast(u32, abi_size) }); | 3229 | try self.genSetReg(Type.initTag(.u32), count_reg, .{ .immediate = @intCast(u32, abi_size) }); |
| 3186 | | 3230 | |
| 3187 | return self.genInlineMemcpy( | 3231 | return self.genInlineMemcpy( |
| 3188 | -@intCast(i32, stack_offset + abi_size), | 3232 | -@intCast(i32, stack_offset + abi_size), |
| 3189 | addr_reg.to64(), | 3233 | addr_reg.to64(), |
| 3190 | len_reg.to64(), | 3234 | count_reg.to64(), |
| 3191 | tmp_reg.to8(), | 3235 | tmp_reg.to8(), |
| 3192 | ); | 3236 | ); |
| 3193 | }, | 3237 | }, |
| ... | @@ -3198,7 +3242,7 @@ fn genInlineMemcpy( | ... | @@ -3198,7 +3242,7 @@ fn genInlineMemcpy( |
| 3198 | self: *Self, | 3242 | self: *Self, |
| 3199 | stack_offset: i32, | 3243 | stack_offset: i32, |
| 3200 | addr_reg: Register, | 3244 | addr_reg: Register, |
| 3201 | len_reg: Register, | 3245 | count_reg: Register, |
| 3202 | tmp_reg: Register, | 3246 | tmp_reg: Register, |
| 3203 | ) InnerError!void { | 3247 | ) InnerError!void { |
| 3204 | // mov rcx, 0 | 3248 | // mov rcx, 0 |
| ... | @@ -3220,20 +3264,19 @@ fn genInlineMemcpy( | ... | @@ -3220,20 +3264,19 @@ fn genInlineMemcpy( |
| 3220 | }); | 3264 | }); |
| 3221 | | 3265 | |
| 3222 | // loop: | 3266 | // loop: |
| 3223 | // cmp rcx, len | 3267 | // cmp count, 0 |
| 3224 | const loop_start = try self.addInst(.{ | 3268 | const loop_start = try self.addInst(.{ |
| 3225 | .tag = .cmp, | 3269 | .tag = .cmp, |
| 3226 | .ops = (Mir.Ops{ | 3270 | .ops = (Mir.Ops{ |
| 3227 | .reg1 = .rcx, | 3271 | .reg1 = count_reg, |
| 3228 | .reg2 = len_reg, | | |
| 3229 | }).encode(), | 3272 | }).encode(), |
| 3230 | .data = undefined, | 3273 | .data = .{ .imm = 0 }, |
| 3231 | }); | 3274 | }); |
| 3232 | | 3275 | |
| 3233 | // jge end | 3276 | // je end |
| 3234 | const loop_reloc = try self.addInst(.{ | 3277 | const loop_reloc = try self.addInst(.{ |
| 3235 | .tag = .cond_jmp_above_below, | 3278 | .tag = .cond_jmp_eq_ne, |
| 3236 | .ops = (Mir.Ops{ .flags = 0b00 }).encode(), | 3279 | .ops = (Mir.Ops{ .flags = 0b01 }).encode(), |
| 3237 | .data = .{ .inst = undefined }, | 3280 | .data = .{ .inst = undefined }, |
| 3238 | }); | 3281 | }); |
| 3239 | | 3282 | |
| ... | @@ -3275,6 +3318,15 @@ fn genInlineMemcpy( | ... | @@ -3275,6 +3318,15 @@ fn genInlineMemcpy( |
| 3275 | .data = .{ .imm = 1 }, | 3318 | .data = .{ .imm = 1 }, |
| 3276 | }); | 3319 | }); |
| 3277 | | 3320 | |
| | 3321 | // sub count, 1 |
| | 3322 | _ = try self.addInst(.{ |
| | 3323 | .tag = .sub, |
| | 3324 | .ops = (Mir.Ops{ |
| | 3325 | .reg1 = count_reg, |
| | 3326 | }).encode(), |
| | 3327 | .data = .{ .imm = 1 }, |
| | 3328 | }); |
| | 3329 | |
| 3278 | // jmp loop | 3330 | // jmp loop |
| 3279 | _ = try self.addInst(.{ | 3331 | _ = try self.addInst(.{ |
| 3280 | .tag = .jmp, | 3332 | .tag = .jmp, |
| ... | @@ -3286,47 +3338,6 @@ fn genInlineMemcpy( | ... | @@ -3286,47 +3338,6 @@ fn genInlineMemcpy( |
| 3286 | try self.performReloc(loop_reloc); | 3338 | try self.performReloc(loop_reloc); |
| 3287 | } | 3339 | } |
| 3288 | | 3340 | |
| 3289 | /// Set pointee via pointer stored in a register. | | |
| 3290 | /// mov [reg], value | | |
| 3291 | fn genSetPtrReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { | | |
| 3292 | switch (mcv) { | | |
| 3293 | .dead => unreachable, | | |
| 3294 | .unreach, .none => return, // Nothing to do. | | |
| 3295 | .immediate => |imm| { | | |
| 3296 | const abi_size = ty.abiSize(self.target.*); | | |
| 3297 | switch (abi_size) { | | |
| 3298 | 1, 2, 4 => { | | |
| 3299 | // TODO this is wasteful! | | |
| 3300 | // introduce new MIR tag specifically for mov [reg + 0], imm | | |
| 3301 | const payload = try self.addExtra(Mir.ImmPair{ | | |
| 3302 | .dest_off = 0, | | |
| 3303 | .operand = @bitCast(i32, @intCast(u32, imm)), | | |
| 3304 | }); | | |
| 3305 | _ = try self.addInst(.{ | | |
| 3306 | .tag = .mov_mem_imm, | | |
| 3307 | .ops = (Mir.Ops{ | | |
| 3308 | .reg1 = reg.to64(), | | |
| 3309 | .flags = switch (abi_size) { | | |
| 3310 | 1 => 0b00, | | |
| 3311 | 2 => 0b01, | | |
| 3312 | 4 => 0b10, | | |
| 3313 | else => unreachable, | | |
| 3314 | }, | | |
| 3315 | }).encode(), | | |
| 3316 | .data = .{ .payload = payload }, | | |
| 3317 | }); | | |
| 3318 | }, | | |
| 3319 | else => { | | |
| 3320 | return self.fail("TODO implement set pointee with immediate of ABI size {d}", .{abi_size}); | | |
| 3321 | }, | | |
| 3322 | } | | |
| 3323 | }, | | |
| 3324 | else => |other| { | | |
| 3325 | return self.fail("TODO implement set pointee with {}", .{other}); | | |
| 3326 | }, | | |
| 3327 | } | | |
| 3328 | } | | |
| 3329 | | | |
| 3330 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { | 3341 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { |
| 3331 | switch (mcv) { | 3342 | switch (mcv) { |
| 3332 | .dead => unreachable, | 3343 | .dead => unreachable, |
| ... | @@ -3749,7 +3760,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { | ... | @@ -3749,7 +3760,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 3749 | if (typed_value.val.tag() == .int_u64) { | 3760 | if (typed_value.val.tag() == .int_u64) { |
| 3750 | return MCValue{ .immediate = typed_value.val.toUnsignedInt() }; | 3761 | return MCValue{ .immediate = typed_value.val.toUnsignedInt() }; |
| 3751 | } | 3762 | } |
| 3752 | return self.fail("TODO codegen more kinds of const pointers", .{}); | 3763 | return self.fail("TODO codegen more kinds of const pointers: {}", .{typed_value.val.tag()}); |
| 3753 | }, | 3764 | }, |
| 3754 | }, | 3765 | }, |
| 3755 | .Int => { | 3766 | .Int => { |