| ... | @@ -5650,9 +5650,62 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5650,9 +5650,62 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { |
| 5650 | | 5650 | |
| 5651 | fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { | 5651 | fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 5652 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 5652 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 5653 | const operand = try self.resolveInst(un_op); | 5653 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 5654 | _ = operand; | 5654 | const addr_reg = try self.register_manager.allocReg(null, gp); |
| 5655 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airCmpLtErrorsLen for {}", .{self.target.cpu.arch}); | 5655 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| | 5656 | defer self.register_manager.unlockReg(addr_lock); |
| | 5657 | |
| | 5658 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| | 5659 | const atom_index = try elf_file.getOrCreateAtomForLazySymbol( |
| | 5660 | .{ .kind = .const_data, .ty = Type.anyerror }, |
| | 5661 | 4, // dword alignment |
| | 5662 | ); |
| | 5663 | const got_addr = elf_file.getAtom(atom_index).getOffsetTableAddress(elf_file); |
| | 5664 | try self.asmRegisterMemory(.mov, addr_reg.to64(), Memory.sib(.qword, .{ |
| | 5665 | .base = .ds, |
| | 5666 | .disp = @intCast(i32, got_addr), |
| | 5667 | })); |
| | 5668 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| | 5669 | const atom_index = try coff_file.getOrCreateAtomForLazySymbol( |
| | 5670 | .{ .kind = .const_data, .ty = Type.anyerror }, |
| | 5671 | 4, // dword alignment |
| | 5672 | ); |
| | 5673 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| | 5674 | try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ |
| | 5675 | .type = .got, |
| | 5676 | .sym_index = sym_index, |
| | 5677 | } }); |
| | 5678 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| | 5679 | const atom_index = try macho_file.getOrCreateAtomForLazySymbol( |
| | 5680 | .{ .kind = .const_data, .ty = Type.anyerror }, |
| | 5681 | 4, // dword alignment |
| | 5682 | ); |
| | 5683 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; |
| | 5684 | try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ |
| | 5685 | .type = .got, |
| | 5686 | .sym_index = sym_index, |
| | 5687 | } }); |
| | 5688 | } else { |
| | 5689 | return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)}); |
| | 5690 | } |
| | 5691 | |
| | 5692 | try self.spillEflagsIfOccupied(); |
| | 5693 | self.eflags_inst = inst; |
| | 5694 | |
| | 5695 | const op_ty = self.air.typeOf(un_op); |
| | 5696 | const op_abi_size = @intCast(u32, op_ty.abiSize(self.target.*)); |
| | 5697 | const op_mcv = try self.resolveInst(un_op); |
| | 5698 | const dst_reg = switch (op_mcv) { |
| | 5699 | .register => |reg| reg, |
| | 5700 | else => try self.copyToTmpRegister(op_ty, op_mcv), |
| | 5701 | }; |
| | 5702 | try self.asmRegisterMemory( |
| | 5703 | .cmp, |
| | 5704 | registerAlias(dst_reg, op_abi_size), |
| | 5705 | Memory.sib(Memory.PtrSize.fromSize(op_abi_size), .{ .base = addr_reg }), |
| | 5706 | ); |
| | 5707 | break :result .{ .eflags = .b }; |
| | 5708 | }; |
| 5656 | return self.finishAir(inst, result, .{ un_op, .none, .none }); | 5709 | return self.finishAir(inst, result, .{ un_op, .none, .none }); |
| 5657 | } | 5710 | } |
| 5658 | | 5711 | |
| ... | @@ -8027,12 +8080,12 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8027,12 +8080,12 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 8027 | try self.asmRegisterMemory(.mov, start_reg.to32(), Memory.sib(.dword, .{ | 8080 | try self.asmRegisterMemory(.mov, start_reg.to32(), Memory.sib(.dword, .{ |
| 8028 | .base = addr_reg.to64(), | 8081 | .base = addr_reg.to64(), |
| 8029 | .scale_index = .{ .scale = 4, .index = err_reg.to64() }, | 8082 | .scale_index = .{ .scale = 4, .index = err_reg.to64() }, |
| 8030 | .disp = 0, | 8083 | .disp = 4, |
| 8031 | })); | 8084 | })); |
| 8032 | try self.asmRegisterMemory(.mov, end_reg.to32(), Memory.sib(.dword, .{ | 8085 | try self.asmRegisterMemory(.mov, end_reg.to32(), Memory.sib(.dword, .{ |
| 8033 | .base = addr_reg.to64(), | 8086 | .base = addr_reg.to64(), |
| 8034 | .scale_index = .{ .scale = 4, .index = err_reg.to64() }, | 8087 | .scale_index = .{ .scale = 4, .index = err_reg.to64() }, |
| 8035 | .disp = 4, | 8088 | .disp = 8, |
| 8036 | })); | 8089 | })); |
| 8037 | try self.asmRegisterRegister(.sub, end_reg.to32(), start_reg.to32()); | 8090 | try self.asmRegisterRegister(.sub, end_reg.to32(), start_reg.to32()); |
| 8038 | try self.asmRegisterMemory(.lea, start_reg.to64(), Memory.sib(.byte, .{ | 8091 | try self.asmRegisterMemory(.lea, start_reg.to64(), Memory.sib(.byte, .{ |