| ... | ... | @@ -103178,6 +103178,19 @@ fn performReloc(self: *CodeGen, reloc: Mir.Inst.Index) void { |
| 103178 | 103178 | .pseudo_j_z_and_np_inst, .pseudo_j_nz_or_p_inst => {}, |
| 103179 | 103179 | else => unreachable, |
| 103180 | 103180 | }, |
| 103181 | .lea => switch (self.mir_instructions.items(.ops)[reloc]) { |
| 103182 | .rm => { |
| 103183 | const rx = self.mir_instructions.items(.data)[reloc].rx; |
| 103184 | assert(rx.fixes == ._); |
| 103185 | const mem_info: Mir.Memory.Info = @bitCast( |
| 103186 | self.mir_extra.items[rx.payload + std.meta.fieldIndex(Mir.Memory, "info").?], |
| 103187 | ); |
| 103188 | assert(mem_info.base == .rip_inst); |
| 103189 | self.mir_extra.items[rx.payload + std.meta.fieldIndex(Mir.Memory, "base").?] = next_inst; |
| 103190 | return; |
| 103191 | }, |
| 103192 | else => unreachable, |
| 103193 | }, |
| 103181 | 103194 | else => unreachable, |
| 103182 | 103195 | } |
| 103183 | 103196 | self.mir_instructions.items(.data)[reloc].inst.inst = next_inst; |
| ... | ... | @@ -103461,7 +103474,10 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 103461 | 103474 | // for the string, we still use the next u32 for the null terminator. |
| 103462 | 103475 | extra_i += clobber.len / 4 + 1; |
| 103463 | 103476 | |
| 103464 | | if (std.mem.eql(u8, clobber, "") or std.mem.eql(u8, clobber, "memory")) { |
| 103477 | if (std.mem.eql(u8, clobber, "") or std.mem.eql(u8, clobber, "memory") or |
| 103478 | std.mem.eql(u8, clobber, "fpsr") or std.mem.eql(u8, clobber, "fpcr") or |
| 103479 | std.mem.eql(u8, clobber, "mxcsr") or std.mem.eql(u8, clobber, "dirflag")) |
| 103480 | { |
| 103465 | 103481 | // ok, sure |
| 103466 | 103482 | } else if (std.mem.eql(u8, clobber, "cc") or |
| 103467 | 103483 | std.mem.eql(u8, clobber, "flags") or |
| ... | ... | @@ -103726,7 +103742,24 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 103726 | 103742 | else |
| 103727 | 103743 | .@"1"; |
| 103728 | 103744 | if (sib_it.next()) |_| return self.fail("invalid memory operand: '{s}'", .{op_str}); |
| 103729 | | op.* = if (std.mem.eql(u8, base_str, "%%dx") and index_str.len == 0) .{ .reg = .dx } else .{ .mem = .{ |
| 103745 | op.* = if (std.mem.eql(u8, base_str, "%%dx") and index_str.len == 0) |
| 103746 | .{ .reg = .dx } |
| 103747 | else if (std.mem.eql(u8, base_str, "%%rip") and index_str.len == 0 and |
| 103748 | Label.isValid(.reference, op_str[0..open])) |
| 103749 | op: { |
| 103750 | const anon = std.ascii.isDigit(op_str[0]); |
| 103751 | const label_gop = try labels.getOrPut(self.gpa, op_str[0..if (anon) 1 else open]); |
| 103752 | if (anon and (op_str[1] == 'b' or op_str[1] == 'B') and !label_gop.found_existing) |
| 103753 | return self.fail("undefined label: '{s}'", .{op_str}); |
| 103754 | if (!label_gop.found_existing) label_gop.value_ptr.* = .{}; |
| 103755 | const pending_relocs = &label_gop.value_ptr.pending_relocs; |
| 103756 | if (if (anon) |
| 103757 | op_str[1] == 'f' or op_str[1] == 'F' |
| 103758 | else |
| 103759 | !label_gop.found_existing or pending_relocs.items.len > 0) |
| 103760 | try pending_relocs.append(self.gpa, @intCast(self.mir_instructions.len)); |
| 103761 | break :op .{ .mem = .{ .base = .{ .rip_inst = label_gop.value_ptr.target } } }; |
| 103762 | } else .{ .mem = .{ |
| 103730 | 103763 | .base = if (base_str.len > 0) |
| 103731 | 103764 | .{ .reg = parseRegName(base_str["%%".len..]) orelse |
| 103732 | 103765 | return self.fail("invalid base register: '{s}'", .{base_str}) } |
| ... | ... | @@ -103770,9 +103803,9 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 103770 | 103803 | } else if (Label.isValid(.reference, op_str)) { |
| 103771 | 103804 | const anon = std.ascii.isDigit(op_str[0]); |
| 103772 | 103805 | const label_gop = try labels.getOrPut(self.gpa, op_str[0..if (anon) 1 else op_str.len]); |
| 103773 | | if (!label_gop.found_existing) label_gop.value_ptr.* = .{}; |
| 103774 | 103806 | if (anon and (op_str[1] == 'b' or op_str[1] == 'B') and !label_gop.found_existing) |
| 103775 | 103807 | return self.fail("undefined label: '{s}'", .{op_str}); |
| 103808 | if (!label_gop.found_existing) label_gop.value_ptr.* = .{}; |
| 103776 | 103809 | const pending_relocs = &label_gop.value_ptr.pending_relocs; |
| 103777 | 103810 | if (if (anon) |
| 103778 | 103811 | op_str[1] == 'f' or op_str[1] == 'F' |
| ... | ... | @@ -105008,7 +105041,7 @@ fn genSetMem( |
| 105008 | 105041 | .none => .{ .immediate = @bitCast(@as(i64, disp)) }, |
| 105009 | 105042 | .reg => |base_reg| .{ .register_offset = .{ .reg = base_reg, .off = disp } }, |
| 105010 | 105043 | .frame => |base_frame_index| .{ .lea_frame = .{ .index = base_frame_index, .off = disp } }, |
| 105011 | | .table => unreachable, |
| 105044 | .table, .rip_inst => unreachable, |
| 105012 | 105045 | .reloc => |sym_index| .{ .lea_symbol = .{ .sym_index = sym_index, .off = disp } }, |
| 105013 | 105046 | }; |
| 105014 | 105047 | switch (src_mcv) { |
| ... | ... | @@ -105118,7 +105151,7 @@ fn genSetMem( |
| 105118 | 105151 | .index = frame_index, |
| 105119 | 105152 | .off = disp, |
| 105120 | 105153 | }).compare(.gte, src_align), |
| 105121 | | .table => unreachable, |
| 105154 | .table, .rip_inst => unreachable, |
| 105122 | 105155 | .reloc => false, |
| 105123 | 105156 | })).write( |
| 105124 | 105157 | self, |
| ... | ... | @@ -105767,7 +105800,7 @@ fn airCmpxchg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 105767 | 105800 | const ptr_lock = switch (ptr_mem.base) { |
| 105768 | 105801 | .none, .frame, .reloc => null, |
| 105769 | 105802 | .reg => |reg| self.register_manager.lockReg(reg), |
| 105770 | | .table => unreachable, |
| 105803 | .table, .rip_inst => unreachable, |
| 105771 | 105804 | }; |
| 105772 | 105805 | defer if (ptr_lock) |lock| self.register_manager.unlockReg(lock); |
| 105773 | 105806 | |
| ... | ... | @@ -105850,7 +105883,7 @@ fn atomicOp( |
| 105850 | 105883 | const mem_lock = switch (ptr_mem.base) { |
| 105851 | 105884 | .none, .frame, .reloc => null, |
| 105852 | 105885 | .reg => |reg| self.register_manager.lockReg(reg), |
| 105853 | | .table => unreachable, |
| 105886 | .table, .rip_inst => unreachable, |
| 105854 | 105887 | }; |
| 105855 | 105888 | defer if (mem_lock) |lock| self.register_manager.unlockReg(lock); |
| 105856 | 105889 | |