| ... | @@ -22,8 +22,6 @@ const Liveness = @import("../../Liveness.zig"); | ... | @@ -22,8 +22,6 @@ const Liveness = @import("../../Liveness.zig"); |
| 22 | const Mir = @import("Mir.zig"); | 22 | const Mir = @import("Mir.zig"); |
| 23 | const Module = @import("../../Module.zig"); | 23 | const Module = @import("../../Module.zig"); |
| 24 | const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager; | 24 | const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager; |
| 25 | const RegisterManager = RegisterManagerFn(Self, Register, &allocatable_registers); | | |
| 26 | const RegisterLock = RegisterManager.RegisterLock; | | |
| 27 | const Target = std.Target; | 25 | const Target = std.Target; |
| 28 | const Type = @import("../../type.zig").Type; | 26 | const Type = @import("../../type.zig").Type; |
| 29 | const TypedValue = @import("../../TypedValue.zig"); | 27 | const TypedValue = @import("../../TypedValue.zig"); |
| ... | @@ -31,12 +29,19 @@ const Value = @import("../../value.zig").Value; | ... | @@ -31,12 +29,19 @@ const Value = @import("../../value.zig").Value; |
| 31 | | 29 | |
| 32 | const bits = @import("bits.zig"); | 30 | const bits = @import("bits.zig"); |
| 33 | const abi = @import("abi.zig"); | 31 | const abi = @import("abi.zig"); |
| 34 | const Register = bits.Register; | 32 | |
| 35 | const callee_preserved_regs = abi.callee_preserved_regs; | 33 | const callee_preserved_regs = abi.callee_preserved_regs; |
| 36 | const caller_preserved_regs = abi.caller_preserved_regs; | 34 | const caller_preserved_regs = abi.caller_preserved_regs; |
| 37 | const allocatable_registers = abi.allocatable_registers; | 35 | const allocatable_registers = abi.allocatable_registers; |
| 38 | const c_abi_int_param_regs = abi.c_abi_int_param_regs; | 36 | const c_abi_int_param_regs = abi.c_abi_int_param_regs; |
| 39 | const c_abi_int_return_regs = abi.c_abi_int_return_regs; | 37 | const c_abi_int_return_regs = abi.c_abi_int_return_regs; |
| | 38 | const RegisterManager = RegisterManagerFn(Self, Register, &allocatable_registers, spillInstruction); |
| | 39 | const RegisterLock = RegisterManager.RegisterLock; |
| | 40 | const Register = bits.Register; |
| | 41 | |
| | 42 | const AvxRegisterManager = RegisterManagerFn(Self, AvxRegister, &abi.avx_regs, spillInstructionAvx); |
| | 43 | const AvxRegisterLock = AvxRegisterManager.RegisterLock; |
| | 44 | const AvxRegister = bits.AvxRegister; |
| 40 | | 45 | |
| 41 | const InnerError = error{ | 46 | const InnerError = error{ |
| 42 | OutOfMemory, | 47 | OutOfMemory, |
| ... | @@ -87,7 +92,8 @@ branch_stack: *std.ArrayList(Branch), | ... | @@ -87,7 +92,8 @@ branch_stack: *std.ArrayList(Branch), |
| 87 | // Key is the block instruction | 92 | // Key is the block instruction |
| 88 | blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, BlockData) = .{}, | 93 | blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, BlockData) = .{}, |
| 89 | | 94 | |
| 90 | register_manager: RegisterManager = .{}, | 95 | register_manager: RegisterManager, |
| | 96 | avx_register_manager: AvxRegisterManager, |
| 91 | /// Maps offset to what is stored there. | 97 | /// Maps offset to what is stored there. |
| 92 | stack: std.AutoHashMapUnmanaged(u32, StackAllocation) = .{}, | 98 | stack: std.AutoHashMapUnmanaged(u32, StackAllocation) = .{}, |
| 93 | | 99 | |
| ... | @@ -119,14 +125,16 @@ pub const MCValue = union(enum) { | ... | @@ -119,14 +125,16 @@ pub const MCValue = union(enum) { |
| 119 | /// A pointer-sized integer that fits in a register. | 125 | /// A pointer-sized integer that fits in a register. |
| 120 | /// If the type is a pointer, this is the pointer address in virtual address space. | 126 | /// If the type is a pointer, this is the pointer address in virtual address space. |
| 121 | immediate: u64, | 127 | immediate: u64, |
| 122 | /// The value is in a target-specific register. | 128 | /// The value is in a GP register. |
| 123 | register: Register, | 129 | register: Register, |
| 124 | /// The value is a tuple { wrapped, overflow } where wrapped value is stored in the register, | 130 | /// The value is a tuple { wrapped, overflow } where wrapped value is stored in the GP register, |
| 125 | /// and the operation is an unsigned operation. | 131 | /// and the operation is an unsigned operation. |
| 126 | register_overflow_unsigned: Register, | 132 | register_overflow_unsigned: Register, |
| 127 | /// The value is a tuple { wrapped, overflow } where wrapped value is stored in the register, | 133 | /// The value is a tuple { wrapped, overflow } where wrapped value is stored in the GP register, |
| 128 | /// and the operation is a signed operation. | 134 | /// and the operation is a signed operation. |
| 129 | register_overflow_signed: Register, | 135 | register_overflow_signed: Register, |
| | 136 | /// The value is in an AVX register. |
| | 137 | avx_register: AvxRegister, |
| 130 | /// The value is in memory at a hard-coded address. | 138 | /// The value is in memory at a hard-coded address. |
| 131 | /// If the type is a pointer, it means the pointer address is at this memory location. | 139 | /// If the type is a pointer, it means the pointer address is at this memory location. |
| 132 | memory: u64, | 140 | memory: u64, |
| ... | @@ -295,7 +303,11 @@ pub fn generate( | ... | @@ -295,7 +303,11 @@ pub fn generate( |
| 295 | .mir_to_air_map = if (builtin.mode == .Debug) | 303 | .mir_to_air_map = if (builtin.mode == .Debug) |
| 296 | std.AutoHashMap(Mir.Inst.Index, Air.Inst.Index).init(bin_file.allocator) | 304 | std.AutoHashMap(Mir.Inst.Index, Air.Inst.Index).init(bin_file.allocator) |
| 297 | else {}, | 305 | else {}, |
| | 306 | .register_manager = undefined, |
| | 307 | .avx_register_manager = undefined, |
| 298 | }; | 308 | }; |
| | 309 | function.register_manager = .{ .function = &function }; |
| | 310 | function.avx_register_manager = .{ .function = &function }; |
| 299 | defer function.stack.deinit(bin_file.allocator); | 311 | defer function.stack.deinit(bin_file.allocator); |
| 300 | defer function.blocks.deinit(bin_file.allocator); | 312 | defer function.blocks.deinit(bin_file.allocator); |
| 301 | defer function.exitlude_jump_relocs.deinit(bin_file.allocator); | 313 | defer function.exitlude_jump_relocs.deinit(bin_file.allocator); |
| ... | @@ -387,14 +399,14 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -387,14 +399,14 @@ fn gen(self: *Self) InnerError!void { |
| 387 | if (cc != .Naked) { | 399 | if (cc != .Naked) { |
| 388 | _ = try self.addInst(.{ | 400 | _ = try self.addInst(.{ |
| 389 | .tag = .push, | 401 | .tag = .push, |
| 390 | .ops = (Mir.Ops{ | 402 | .ops = (Mir.Ops(Register, Register){ |
| 391 | .reg1 = .rbp, | 403 | .reg1 = .rbp, |
| 392 | }).encode(), | 404 | }).encode(), |
| 393 | .data = undefined, // unused for push reg, | 405 | .data = undefined, // unused for push reg, |
| 394 | }); | 406 | }); |
| 395 | _ = try self.addInst(.{ | 407 | _ = try self.addInst(.{ |
| 396 | .tag = .mov, | 408 | .tag = .mov, |
| 397 | .ops = (Mir.Ops{ | 409 | .ops = (Mir.Ops(Register, Register){ |
| 398 | .reg1 = .rbp, | 410 | .reg1 = .rbp, |
| 399 | .reg2 = .rsp, | 411 | .reg2 = .rsp, |
| 400 | }).encode(), | 412 | }).encode(), |
| ... | @@ -434,7 +446,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -434,7 +446,7 @@ fn gen(self: *Self) InnerError!void { |
| 434 | // push the callee_preserved_regs that were used | 446 | // push the callee_preserved_regs that were used |
| 435 | const backpatch_push_callee_preserved_regs_i = try self.addInst(.{ | 447 | const backpatch_push_callee_preserved_regs_i = try self.addInst(.{ |
| 436 | .tag = .push_regs_from_callee_preserved_regs, | 448 | .tag = .push_regs_from_callee_preserved_regs, |
| 437 | .ops = (Mir.Ops{ | 449 | .ops = (Mir.Ops(Register, Register){ |
| 438 | .reg1 = .rbp, | 450 | .reg1 = .rbp, |
| 439 | }).encode(), | 451 | }).encode(), |
| 440 | .data = .{ .payload = undefined }, // to be backpatched | 452 | .data = .{ .payload = undefined }, // to be backpatched |
| ... | @@ -476,7 +488,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -476,7 +488,7 @@ fn gen(self: *Self) InnerError!void { |
| 476 | // pop the callee_preserved_regs | 488 | // pop the callee_preserved_regs |
| 477 | _ = try self.addInst(.{ | 489 | _ = try self.addInst(.{ |
| 478 | .tag = .pop_regs_from_callee_preserved_regs, | 490 | .tag = .pop_regs_from_callee_preserved_regs, |
| 479 | .ops = (Mir.Ops{ | 491 | .ops = (Mir.Ops(Register, Register){ |
| 480 | .reg1 = .rbp, | 492 | .reg1 = .rbp, |
| 481 | }).encode(), | 493 | }).encode(), |
| 482 | .data = .{ .payload = callee_preserved_regs_payload }, | 494 | .data = .{ .payload = callee_preserved_regs_payload }, |
| ... | @@ -497,7 +509,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -497,7 +509,7 @@ fn gen(self: *Self) InnerError!void { |
| 497 | | 509 | |
| 498 | _ = try self.addInst(.{ | 510 | _ = try self.addInst(.{ |
| 499 | .tag = .pop, | 511 | .tag = .pop, |
| 500 | .ops = (Mir.Ops{ | 512 | .ops = (Mir.Ops(Register, Register){ |
| 501 | .reg1 = .rbp, | 513 | .reg1 = .rbp, |
| 502 | }).encode(), | 514 | }).encode(), |
| 503 | .data = undefined, | 515 | .data = undefined, |
| ... | @@ -505,7 +517,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -505,7 +517,7 @@ fn gen(self: *Self) InnerError!void { |
| 505 | | 517 | |
| 506 | _ = try self.addInst(.{ | 518 | _ = try self.addInst(.{ |
| 507 | .tag = .ret, | 519 | .tag = .ret, |
| 508 | .ops = (Mir.Ops{ | 520 | .ops = (Mir.Ops(Register, Register){ |
| 509 | .flags = 0b11, | 521 | .flags = 0b11, |
| 510 | }).encode(), | 522 | }).encode(), |
| 511 | .data = undefined, | 523 | .data = undefined, |
| ... | @@ -521,14 +533,14 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -521,14 +533,14 @@ fn gen(self: *Self) InnerError!void { |
| 521 | if (aligned_stack_end > 0) { | 533 | if (aligned_stack_end > 0) { |
| 522 | self.mir_instructions.set(backpatch_stack_sub, .{ | 534 | self.mir_instructions.set(backpatch_stack_sub, .{ |
| 523 | .tag = .sub, | 535 | .tag = .sub, |
| 524 | .ops = (Mir.Ops{ | 536 | .ops = (Mir.Ops(Register, Register){ |
| 525 | .reg1 = .rsp, | 537 | .reg1 = .rsp, |
| 526 | }).encode(), | 538 | }).encode(), |
| 527 | .data = .{ .imm = aligned_stack_end }, | 539 | .data = .{ .imm = aligned_stack_end }, |
| 528 | }); | 540 | }); |
| 529 | self.mir_instructions.set(backpatch_stack_add, .{ | 541 | self.mir_instructions.set(backpatch_stack_add, .{ |
| 530 | .tag = .add, | 542 | .tag = .add, |
| 531 | .ops = (Mir.Ops{ | 543 | .ops = (Mir.Ops(Register, Register){ |
| 532 | .reg1 = .rsp, | 544 | .reg1 = .rsp, |
| 533 | }).encode(), | 545 | }).encode(), |
| 534 | .data = .{ .imm = aligned_stack_end }, | 546 | .data = .{ .imm = aligned_stack_end }, |
| ... | @@ -889,13 +901,27 @@ fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { | ... | @@ -889,13 +901,27 @@ fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue { |
| 889 | self.stack_align = abi_align; | 901 | self.stack_align = abi_align; |
| 890 | | 902 | |
| 891 | if (reg_ok) { | 903 | if (reg_ok) { |
| 892 | // Make sure the type can fit in a register before we try to allocate one. | 904 | switch (elem_ty.zigTypeTag()) { |
| 893 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); | 905 | .Vector => return self.fail("TODO allocRegOrMem for Vector type", .{}), |
| 894 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); | 906 | .Float => { |
| 895 | if (abi_size <= ptr_bytes) { | 907 | // TODO check if AVX available |
| 896 | if (self.register_manager.tryAllocReg(inst)) |reg| { | 908 | const ptr_bytes: u64 = 32; |
| 897 | return MCValue{ .register = registerAlias(reg, abi_size) }; | 909 | if (abi_size <= ptr_bytes) { |
| 898 | } | 910 | if (self.avx_register_manager.tryAllocReg(inst)) |reg| { |
| | 911 | return MCValue{ .avx_register = avxRegisterAlias(reg, abi_size) }; |
| | 912 | } |
| | 913 | } |
| | 914 | }, |
| | 915 | else => { |
| | 916 | // Make sure the type can fit in a register before we try to allocate one. |
| | 917 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); |
| | 918 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); |
| | 919 | if (abi_size <= ptr_bytes) { |
| | 920 | if (self.register_manager.tryAllocReg(inst)) |reg| { |
| | 921 | return MCValue{ .register = registerAlias(reg, abi_size) }; |
| | 922 | } |
| | 923 | } |
| | 924 | }, |
| 899 | } | 925 | } |
| 900 | } | 926 | } |
| 901 | const stack_offset = try self.allocMem(inst, abi_size, abi_align); | 927 | const stack_offset = try self.allocMem(inst, abi_size, abi_align); |
| ... | @@ -920,6 +946,21 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void | ... | @@ -920,6 +946,21 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void |
| 920 | try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv, .{}); | 946 | try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv, .{}); |
| 921 | } | 947 | } |
| 922 | | 948 | |
| | 949 | pub fn spillInstructionAvx(self: *Self, reg: AvxRegister, inst: Air.Inst.Index) !void { |
| | 950 | const stack_mcv = try self.allocRegOrMem(inst, false); |
| | 951 | log.debug("spilling {d} to stack mcv {any}", .{ inst, stack_mcv }); |
| | 952 | const reg_mcv = self.getResolvedInstValue(inst); |
| | 953 | switch (reg_mcv) { |
| | 954 | .avx_register => |other| { |
| | 955 | assert(reg.to256() == other.to256()); |
| | 956 | }, |
| | 957 | else => {}, |
| | 958 | } |
| | 959 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; |
| | 960 | try branch.inst_table.put(self.gpa, inst, stack_mcv); |
| | 961 | try self.genSetStack(self.air.typeOfIndex(inst), stack_mcv.stack_offset, reg_mcv, .{}); |
| | 962 | } |
| | 963 | |
| 923 | pub fn spillCompareFlagsIfOccupied(self: *Self) !void { | 964 | pub fn spillCompareFlagsIfOccupied(self: *Self) !void { |
| 924 | if (self.compare_flags_inst) |inst_to_save| { | 965 | if (self.compare_flags_inst) |inst_to_save| { |
| 925 | const mcv = self.getResolvedInstValue(inst_to_save); | 966 | const mcv = self.getResolvedInstValue(inst_to_save); |
| ... | @@ -1192,7 +1233,7 @@ fn airMin(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1192,7 +1233,7 @@ fn airMin(self: *Self, inst: Air.Inst.Index) !void { |
| 1192 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ty, rhs_mcv); | 1233 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ty, rhs_mcv); |
| 1193 | _ = try self.addInst(.{ | 1234 | _ = try self.addInst(.{ |
| 1194 | .tag = if (signedness == .signed) .cond_mov_lt else .cond_mov_below, | 1235 | .tag = if (signedness == .signed) .cond_mov_lt else .cond_mov_below, |
| 1195 | .ops = (Mir.Ops{ | 1236 | .ops = (Mir.Ops(Register, Register){ |
| 1196 | .reg1 = dst_mcv.register, | 1237 | .reg1 = dst_mcv.register, |
| 1197 | .reg2 = lhs_reg, | 1238 | .reg2 = lhs_reg, |
| 1198 | }).encode(), | 1239 | }).encode(), |
| ... | @@ -1396,7 +1437,7 @@ fn genSetStackTruncatedOverflowCompare( | ... | @@ -1396,7 +1437,7 @@ fn genSetStackTruncatedOverflowCompare( |
| 1396 | }; | 1437 | }; |
| 1397 | _ = try self.addInst(.{ | 1438 | _ = try self.addInst(.{ |
| 1398 | .tag = .cond_set_byte_overflow, | 1439 | .tag = .cond_set_byte_overflow, |
| 1399 | .ops = (Mir.Ops{ | 1440 | .ops = (Mir.Ops(Register, Register){ |
| 1400 | .reg1 = overflow_reg.to8(), | 1441 | .reg1 = overflow_reg.to8(), |
| 1401 | .flags = flags, | 1442 | .flags = flags, |
| 1402 | }).encode(), | 1443 | }).encode(), |
| ... | @@ -1416,7 +1457,7 @@ fn genSetStackTruncatedOverflowCompare( | ... | @@ -1416,7 +1457,7 @@ fn genSetStackTruncatedOverflowCompare( |
| 1416 | const eq_reg = temp_regs[2]; | 1457 | const eq_reg = temp_regs[2]; |
| 1417 | _ = try self.addInst(.{ | 1458 | _ = try self.addInst(.{ |
| 1418 | .tag = .cond_set_byte_eq_ne, | 1459 | .tag = .cond_set_byte_eq_ne, |
| 1419 | .ops = (Mir.Ops{ | 1460 | .ops = (Mir.Ops(Register, Register){ |
| 1420 | .reg1 = eq_reg.to8(), | 1461 | .reg1 = eq_reg.to8(), |
| 1421 | .flags = 0b00, | 1462 | .flags = 0b00, |
| 1422 | }).encode(), | 1463 | }).encode(), |
| ... | @@ -1565,7 +1606,7 @@ fn genIntMulDivOpMir( | ... | @@ -1565,7 +1606,7 @@ fn genIntMulDivOpMir( |
| 1565 | .signed => { | 1606 | .signed => { |
| 1566 | _ = try self.addInst(.{ | 1607 | _ = try self.addInst(.{ |
| 1567 | .tag = .cwd, | 1608 | .tag = .cwd, |
| 1568 | .ops = (Mir.Ops{ | 1609 | .ops = (Mir.Ops(Register, Register){ |
| 1569 | .flags = 0b11, | 1610 | .flags = 0b11, |
| 1570 | }).encode(), | 1611 | }).encode(), |
| 1571 | .data = undefined, | 1612 | .data = undefined, |
| ... | @@ -1574,7 +1615,7 @@ fn genIntMulDivOpMir( | ... | @@ -1574,7 +1615,7 @@ fn genIntMulDivOpMir( |
| 1574 | .unsigned => { | 1615 | .unsigned => { |
| 1575 | _ = try self.addInst(.{ | 1616 | _ = try self.addInst(.{ |
| 1576 | .tag = .xor, | 1617 | .tag = .xor, |
| 1577 | .ops = (Mir.Ops{ | 1618 | .ops = (Mir.Ops(Register, Register){ |
| 1578 | .reg1 = .rdx, | 1619 | .reg1 = .rdx, |
| 1579 | .reg2 = .rdx, | 1620 | .reg2 = .rdx, |
| 1580 | }).encode(), | 1621 | }).encode(), |
| ... | @@ -1596,7 +1637,7 @@ fn genIntMulDivOpMir( | ... | @@ -1596,7 +1637,7 @@ fn genIntMulDivOpMir( |
| 1596 | .register => |reg| { | 1637 | .register => |reg| { |
| 1597 | _ = try self.addInst(.{ | 1638 | _ = try self.addInst(.{ |
| 1598 | .tag = tag, | 1639 | .tag = tag, |
| 1599 | .ops = (Mir.Ops{ | 1640 | .ops = (Mir.Ops(Register, Register){ |
| 1600 | .reg1 = reg, | 1641 | .reg1 = reg, |
| 1601 | }).encode(), | 1642 | }).encode(), |
| 1602 | .data = undefined, | 1643 | .data = undefined, |
| ... | @@ -1605,7 +1646,7 @@ fn genIntMulDivOpMir( | ... | @@ -1605,7 +1646,7 @@ fn genIntMulDivOpMir( |
| 1605 | .stack_offset => |off| { | 1646 | .stack_offset => |off| { |
| 1606 | _ = try self.addInst(.{ | 1647 | _ = try self.addInst(.{ |
| 1607 | .tag = tag, | 1648 | .tag = tag, |
| 1608 | .ops = (Mir.Ops{ | 1649 | .ops = (Mir.Ops(Register, Register){ |
| 1609 | .reg2 = .rbp, | 1650 | .reg2 = .rbp, |
| 1610 | .flags = switch (abi_size) { | 1651 | .flags = switch (abi_size) { |
| 1611 | 1 => 0b00, | 1652 | 1 => 0b00, |
| ... | @@ -1647,7 +1688,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa | ... | @@ -1647,7 +1688,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa |
| 1647 | | 1688 | |
| 1648 | _ = try self.addInst(.{ | 1689 | _ = try self.addInst(.{ |
| 1649 | .tag = .xor, | 1690 | .tag = .xor, |
| 1650 | .ops = (Mir.Ops{ | 1691 | .ops = (Mir.Ops(Register, Register){ |
| 1651 | .reg1 = divisor.to64(), | 1692 | .reg1 = divisor.to64(), |
| 1652 | .reg2 = dividend.to64(), | 1693 | .reg2 = dividend.to64(), |
| 1653 | }).encode(), | 1694 | }).encode(), |
| ... | @@ -1655,7 +1696,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa | ... | @@ -1655,7 +1696,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa |
| 1655 | }); | 1696 | }); |
| 1656 | _ = try self.addInst(.{ | 1697 | _ = try self.addInst(.{ |
| 1657 | .tag = .sar, | 1698 | .tag = .sar, |
| 1658 | .ops = (Mir.Ops{ | 1699 | .ops = (Mir.Ops(Register, Register){ |
| 1659 | .reg1 = divisor.to64(), | 1700 | .reg1 = divisor.to64(), |
| 1660 | .flags = 0b10, | 1701 | .flags = 0b10, |
| 1661 | }).encode(), | 1702 | }).encode(), |
| ... | @@ -1663,7 +1704,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa | ... | @@ -1663,7 +1704,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa |
| 1663 | }); | 1704 | }); |
| 1664 | _ = try self.addInst(.{ | 1705 | _ = try self.addInst(.{ |
| 1665 | .tag = .@"test", | 1706 | .tag = .@"test", |
| 1666 | .ops = (Mir.Ops{ | 1707 | .ops = (Mir.Ops(Register, Register){ |
| 1667 | .reg1 = .rdx, | 1708 | .reg1 = .rdx, |
| 1668 | .reg2 = .rdx, | 1709 | .reg2 = .rdx, |
| 1669 | }).encode(), | 1710 | }).encode(), |
| ... | @@ -1671,7 +1712,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa | ... | @@ -1671,7 +1712,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa |
| 1671 | }); | 1712 | }); |
| 1672 | _ = try self.addInst(.{ | 1713 | _ = try self.addInst(.{ |
| 1673 | .tag = .cond_mov_eq, | 1714 | .tag = .cond_mov_eq, |
| 1674 | .ops = (Mir.Ops{ | 1715 | .ops = (Mir.Ops(Register, Register){ |
| 1675 | .reg1 = divisor.to64(), | 1716 | .reg1 = divisor.to64(), |
| 1676 | .reg2 = .rdx, | 1717 | .reg2 = .rdx, |
| 1677 | }).encode(), | 1718 | }).encode(), |
| ... | @@ -2058,7 +2099,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { | ... | @@ -2058,7 +2099,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 2058 | // mov reg, [rbp - 8] | 2099 | // mov reg, [rbp - 8] |
| 2059 | _ = try self.addInst(.{ | 2100 | _ = try self.addInst(.{ |
| 2060 | .tag = .mov, | 2101 | .tag = .mov, |
| 2061 | .ops = (Mir.Ops{ | 2102 | .ops = (Mir.Ops(Register, Register){ |
| 2062 | .reg1 = addr_reg.to64(), | 2103 | .reg1 = addr_reg.to64(), |
| 2063 | .reg2 = .rbp, | 2104 | .reg2 = .rbp, |
| 2064 | .flags = 0b01, | 2105 | .flags = 0b01, |
| ... | @@ -2143,7 +2184,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2143,7 +2184,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2143 | // lea reg, [rbp] | 2184 | // lea reg, [rbp] |
| 2144 | _ = try self.addInst(.{ | 2185 | _ = try self.addInst(.{ |
| 2145 | .tag = .lea, | 2186 | .tag = .lea, |
| 2146 | .ops = (Mir.Ops{ | 2187 | .ops = (Mir.Ops(Register, Register){ |
| 2147 | .reg1 = addr_reg.to64(), | 2188 | .reg1 = addr_reg.to64(), |
| 2148 | .reg2 = .rbp, | 2189 | .reg2 = .rbp, |
| 2149 | }).encode(), | 2190 | }).encode(), |
| ... | @@ -2154,7 +2195,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2154,7 +2195,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2154 | // lea reg, [rbp] | 2195 | // lea reg, [rbp] |
| 2155 | _ = try self.addInst(.{ | 2196 | _ = try self.addInst(.{ |
| 2156 | .tag = .lea, | 2197 | .tag = .lea, |
| 2157 | .ops = (Mir.Ops{ | 2198 | .ops = (Mir.Ops(Register, Register){ |
| 2158 | .reg1 = addr_reg.to64(), | 2199 | .reg1 = addr_reg.to64(), |
| 2159 | .reg2 = .rbp, | 2200 | .reg2 = .rbp, |
| 2160 | }).encode(), | 2201 | }).encode(), |
| ... | @@ -2222,7 +2263,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2222,7 +2263,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2222 | // mov dst_mcv, [dst_mcv] | 2263 | // mov dst_mcv, [dst_mcv] |
| 2223 | _ = try self.addInst(.{ | 2264 | _ = try self.addInst(.{ |
| 2224 | .tag = .mov, | 2265 | .tag = .mov, |
| 2225 | .ops = (Mir.Ops{ | 2266 | .ops = (Mir.Ops(Register, Register){ |
| 2226 | .flags = 0b01, | 2267 | .flags = 0b01, |
| 2227 | .reg1 = registerAlias(dst_mcv.register, @intCast(u32, elem_abi_size)), | 2268 | .reg1 = registerAlias(dst_mcv.register, @intCast(u32, elem_abi_size)), |
| 2228 | .reg2 = dst_mcv.register, | 2269 | .reg2 = dst_mcv.register, |
| ... | @@ -2456,6 +2497,7 @@ fn reuseOperand( | ... | @@ -2456,6 +2497,7 @@ fn reuseOperand( |
| 2456 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { | 2497 | fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { |
| 2457 | const elem_ty = ptr_ty.elemType(); | 2498 | const elem_ty = ptr_ty.elemType(); |
| 2458 | const abi_size = elem_ty.abiSize(self.target.*); | 2499 | const abi_size = elem_ty.abiSize(self.target.*); |
| | 2500 | std.log.warn("{} => {}, {}", .{ ptr_ty.fmtDebug(), ptr, dst_mcv }); |
| 2459 | switch (ptr) { | 2501 | switch (ptr) { |
| 2460 | .none => unreachable, | 2502 | .none => unreachable, |
| 2461 | .undef => unreachable, | 2503 | .undef => unreachable, |
| ... | @@ -2488,7 +2530,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -2488,7 +2530,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2488 | // mov dst_reg, [reg] | 2530 | // mov dst_reg, [reg] |
| 2489 | _ = try self.addInst(.{ | 2531 | _ = try self.addInst(.{ |
| 2490 | .tag = .mov, | 2532 | .tag = .mov, |
| 2491 | .ops = (Mir.Ops{ | 2533 | .ops = (Mir.Ops(Register, Register){ |
| 2492 | .reg1 = registerAlias(dst_reg, @intCast(u32, abi_size)), | 2534 | .reg1 = registerAlias(dst_reg, @intCast(u32, abi_size)), |
| 2493 | .reg2 = reg, | 2535 | .reg2 = reg, |
| 2494 | .flags = 0b01, | 2536 | .flags = 0b01, |
| ... | @@ -2508,6 +2550,9 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -2508,6 +2550,9 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2508 | else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}), | 2550 | else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}), |
| 2509 | } | 2551 | } |
| 2510 | }, | 2552 | }, |
| | 2553 | .avx_register => { |
| | 2554 | return self.fail("TODO load for AVX register", .{}); |
| | 2555 | }, |
| 2511 | .memory, | 2556 | .memory, |
| 2512 | .got_load, | 2557 | .got_load, |
| 2513 | .direct_load, | 2558 | .direct_load, |
| ... | @@ -2559,7 +2604,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue | ... | @@ -2559,7 +2604,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue |
| 2559 | const fn_owner_decl = mod.declPtr(self.mod_fn.owner_decl); | 2604 | const fn_owner_decl = mod.declPtr(self.mod_fn.owner_decl); |
| 2560 | _ = try self.addInst(.{ | 2605 | _ = try self.addInst(.{ |
| 2561 | .tag = .lea_pie, | 2606 | .tag = .lea_pie, |
| 2562 | .ops = (Mir.Ops{ | 2607 | .ops = (Mir.Ops(Register, Register){ |
| 2563 | .reg1 = registerAlias(reg, abi_size), | 2608 | .reg1 = registerAlias(reg, abi_size), |
| 2564 | .flags = flags, | 2609 | .flags = flags, |
| 2565 | }).encode(), | 2610 | }).encode(), |
| ... | @@ -2582,6 +2627,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue | ... | @@ -2582,6 +2627,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue |
| 2582 | | 2627 | |
| 2583 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { | 2628 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| 2584 | const abi_size = value_ty.abiSize(self.target.*); | 2629 | const abi_size = value_ty.abiSize(self.target.*); |
| | 2630 | std.log.warn("{} => {}, {} => {}", .{ ptr_ty.fmtDebug(), ptr, value_ty.fmtDebug(), value }); |
| 2585 | switch (ptr) { | 2631 | switch (ptr) { |
| 2586 | .none => unreachable, | 2632 | .none => unreachable, |
| 2587 | .undef => unreachable, | 2633 | .undef => unreachable, |
| ... | @@ -2623,7 +2669,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2623,7 +2669,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2623 | }); | 2669 | }); |
| 2624 | _ = try self.addInst(.{ | 2670 | _ = try self.addInst(.{ |
| 2625 | .tag = .mov_mem_imm, | 2671 | .tag = .mov_mem_imm, |
| 2626 | .ops = (Mir.Ops{ | 2672 | .ops = (Mir.Ops(Register, Register){ |
| 2627 | .reg1 = reg.to64(), | 2673 | .reg1 = reg.to64(), |
| 2628 | .flags = switch (abi_size) { | 2674 | .flags = switch (abi_size) { |
| 2629 | 1 => 0b00, | 2675 | 1 => 0b00, |
| ... | @@ -2645,7 +2691,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2645,7 +2691,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2645 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); | 2691 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| 2646 | _ = try self.addInst(.{ | 2692 | _ = try self.addInst(.{ |
| 2647 | .tag = .mov, | 2693 | .tag = .mov, |
| 2648 | .ops = (Mir.Ops{ | 2694 | .ops = (Mir.Ops(Register, Register){ |
| 2649 | .reg1 = reg.to64(), | 2695 | .reg1 = reg.to64(), |
| 2650 | .reg2 = tmp_reg.to64(), | 2696 | .reg2 = tmp_reg.to64(), |
| 2651 | .flags = 0b10, | 2697 | .flags = 0b10, |
| ... | @@ -2661,7 +2707,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2661,7 +2707,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2661 | .register => |src_reg| { | 2707 | .register => |src_reg| { |
| 2662 | _ = try self.addInst(.{ | 2708 | _ = try self.addInst(.{ |
| 2663 | .tag = .mov, | 2709 | .tag = .mov, |
| 2664 | .ops = (Mir.Ops{ | 2710 | .ops = (Mir.Ops(Register, Register){ |
| 2665 | .reg1 = reg.to64(), | 2711 | .reg1 = reg.to64(), |
| 2666 | .reg2 = registerAlias(src_reg, @intCast(u32, abi_size)), | 2712 | .reg2 = registerAlias(src_reg, @intCast(u32, abi_size)), |
| 2667 | .flags = 0b10, | 2713 | .flags = 0b10, |
| ... | @@ -2689,6 +2735,9 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2689,6 +2735,9 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2689 | }, | 2735 | }, |
| 2690 | } | 2736 | } |
| 2691 | }, | 2737 | }, |
| | 2738 | .avx_register => { |
| | 2739 | return self.fail("TODO store for AVX register", .{}); |
| | 2740 | }, |
| 2692 | .got_load, | 2741 | .got_load, |
| 2693 | .direct_load, | 2742 | .direct_load, |
| 2694 | .memory, | 2743 | .memory, |
| ... | @@ -2709,7 +2758,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2709,7 +2758,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2709 | // mov reg, [reg] | 2758 | // mov reg, [reg] |
| 2710 | _ = try self.addInst(.{ | 2759 | _ = try self.addInst(.{ |
| 2711 | .tag = .mov, | 2760 | .tag = .mov, |
| 2712 | .ops = (Mir.Ops{ | 2761 | .ops = (Mir.Ops(Register, Register){ |
| 2713 | .reg1 = addr_reg.to64(), | 2762 | .reg1 = addr_reg.to64(), |
| 2714 | .reg2 = addr_reg.to64(), | 2763 | .reg2 = addr_reg.to64(), |
| 2715 | .flags = 0b01, | 2764 | .flags = 0b01, |
| ... | @@ -2748,7 +2797,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2748,7 +2797,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2748 | } | 2797 | } |
| 2749 | _ = try self.addInst(.{ | 2798 | _ = try self.addInst(.{ |
| 2750 | .tag = .mov_mem_imm, | 2799 | .tag = .mov_mem_imm, |
| 2751 | .ops = (Mir.Ops{ | 2800 | .ops = (Mir.Ops(Register, Register){ |
| 2752 | .reg1 = addr_reg.to64(), | 2801 | .reg1 = addr_reg.to64(), |
| 2753 | .flags = flags, | 2802 | .flags = flags, |
| 2754 | }).encode(), | 2803 | }).encode(), |
| ... | @@ -2758,7 +2807,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2758,7 +2807,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2758 | .register => |reg| { | 2807 | .register => |reg| { |
| 2759 | _ = try self.addInst(.{ | 2808 | _ = try self.addInst(.{ |
| 2760 | .tag = .mov, | 2809 | .tag = .mov, |
| 2761 | .ops = (Mir.Ops{ | 2810 | .ops = (Mir.Ops(Register, Register){ |
| 2762 | .reg1 = addr_reg.to64(), | 2811 | .reg1 = addr_reg.to64(), |
| 2763 | .reg2 = reg, | 2812 | .reg2 = reg, |
| 2764 | .flags = 0b10, | 2813 | .flags = 0b10, |
| ... | @@ -2779,7 +2828,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2779,7 +2828,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2779 | | 2828 | |
| 2780 | _ = try self.addInst(.{ | 2829 | _ = try self.addInst(.{ |
| 2781 | .tag = .mov, | 2830 | .tag = .mov, |
| 2782 | .ops = (Mir.Ops{ | 2831 | .ops = (Mir.Ops(Register, Register){ |
| 2783 | .reg1 = tmp_reg, | 2832 | .reg1 = tmp_reg, |
| 2784 | .reg2 = tmp_reg, | 2833 | .reg2 = tmp_reg, |
| 2785 | .flags = 0b01, | 2834 | .flags = 0b01, |
| ... | @@ -2788,7 +2837,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2788,7 +2837,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2788 | }); | 2837 | }); |
| 2789 | _ = try self.addInst(.{ | 2838 | _ = try self.addInst(.{ |
| 2790 | .tag = .mov, | 2839 | .tag = .mov, |
| 2791 | .ops = (Mir.Ops{ | 2840 | .ops = (Mir.Ops(Register, Register){ |
| 2792 | .reg1 = addr_reg.to64(), | 2841 | .reg1 = addr_reg.to64(), |
| 2793 | .reg2 = tmp_reg, | 2842 | .reg2 = tmp_reg, |
| 2794 | .flags = 0b10, | 2843 | .flags = 0b10, |
| ... | @@ -2806,7 +2855,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2806,7 +2855,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2806 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); | 2855 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| 2807 | _ = try self.addInst(.{ | 2856 | _ = try self.addInst(.{ |
| 2808 | .tag = .mov, | 2857 | .tag = .mov, |
| 2809 | .ops = (Mir.Ops{ | 2858 | .ops = (Mir.Ops(Register, Register){ |
| 2810 | .reg1 = addr_reg.to64(), | 2859 | .reg1 = addr_reg.to64(), |
| 2811 | .reg2 = tmp_reg, | 2860 | .reg2 = tmp_reg, |
| 2812 | .flags = 0b10, | 2861 | .flags = 0b10, |
| ... | @@ -2967,7 +3016,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2967,7 +3016,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2967 | if (signedness == .signed and field_size < 8) { | 3016 | if (signedness == .signed and field_size < 8) { |
| 2968 | _ = try self.addInst(.{ | 3017 | _ = try self.addInst(.{ |
| 2969 | .tag = .mov_sign_extend, | 3018 | .tag = .mov_sign_extend, |
| 2970 | .ops = (Mir.Ops{ | 3019 | .ops = (Mir.Ops(Register, Register){ |
| 2971 | .reg1 = dst_mcv.register, | 3020 | .reg1 = dst_mcv.register, |
| 2972 | .reg2 = registerAlias(dst_mcv.register, field_size), | 3021 | .reg2 = registerAlias(dst_mcv.register, field_size), |
| 2973 | }).encode(), | 3022 | }).encode(), |
| ... | @@ -2998,7 +3047,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2998,7 +3047,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2998 | }; | 3047 | }; |
| 2999 | _ = try self.addInst(.{ | 3048 | _ = try self.addInst(.{ |
| 3000 | .tag = .cond_set_byte_overflow, | 3049 | .tag = .cond_set_byte_overflow, |
| 3001 | .ops = (Mir.Ops{ | 3050 | .ops = (Mir.Ops(Register, Register){ |
| 3002 | .reg1 = dst_reg.to8(), | 3051 | .reg1 = dst_reg.to8(), |
| 3003 | .flags = flags, | 3052 | .flags = flags, |
| 3004 | }).encode(), | 3053 | }).encode(), |
| ... | @@ -3042,7 +3091,7 @@ fn genShiftBinOpMir(self: *Self, tag: Mir.Inst.Tag, ty: Type, reg: Register, shi | ... | @@ -3042,7 +3091,7 @@ fn genShiftBinOpMir(self: *Self, tag: Mir.Inst.Tag, ty: Type, reg: Register, shi |
| 3042 | 1 => { | 3091 | 1 => { |
| 3043 | _ = try self.addInst(.{ | 3092 | _ = try self.addInst(.{ |
| 3044 | .tag = tag, | 3093 | .tag = tag, |
| 3045 | .ops = (Mir.Ops{ | 3094 | .ops = (Mir.Ops(Register, Register){ |
| 3046 | .reg1 = registerAlias(reg, abi_size), | 3095 | .reg1 = registerAlias(reg, abi_size), |
| 3047 | .flags = 0b00, | 3096 | .flags = 0b00, |
| 3048 | }).encode(), | 3097 | }).encode(), |
| ... | @@ -3053,7 +3102,7 @@ fn genShiftBinOpMir(self: *Self, tag: Mir.Inst.Tag, ty: Type, reg: Register, shi | ... | @@ -3053,7 +3102,7 @@ fn genShiftBinOpMir(self: *Self, tag: Mir.Inst.Tag, ty: Type, reg: Register, shi |
| 3053 | else => { | 3102 | else => { |
| 3054 | _ = try self.addInst(.{ | 3103 | _ = try self.addInst(.{ |
| 3055 | .tag = tag, | 3104 | .tag = tag, |
| 3056 | .ops = (Mir.Ops{ | 3105 | .ops = (Mir.Ops(Register, Register){ |
| 3057 | .reg1 = registerAlias(reg, abi_size), | 3106 | .reg1 = registerAlias(reg, abi_size), |
| 3058 | .flags = 0b10, | 3107 | .flags = 0b10, |
| 3059 | }).encode(), | 3108 | }).encode(), |
| ... | @@ -3074,7 +3123,7 @@ fn genShiftBinOpMir(self: *Self, tag: Mir.Inst.Tag, ty: Type, reg: Register, shi | ... | @@ -3074,7 +3123,7 @@ fn genShiftBinOpMir(self: *Self, tag: Mir.Inst.Tag, ty: Type, reg: Register, shi |
| 3074 | | 3123 | |
| 3075 | _ = try self.addInst(.{ | 3124 | _ = try self.addInst(.{ |
| 3076 | .tag = tag, | 3125 | .tag = tag, |
| 3077 | .ops = (Mir.Ops{ | 3126 | .ops = (Mir.Ops(Register, Register){ |
| 3078 | .reg1 = registerAlias(reg, abi_size), | 3127 | .reg1 = registerAlias(reg, abi_size), |
| 3079 | .flags = 0b01, | 3128 | .flags = 0b01, |
| 3080 | }).encode(), | 3129 | }).encode(), |
| ... | @@ -3453,17 +3502,20 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu | ... | @@ -3453,17 +3502,20 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3453 | .register => |src_reg| { | 3502 | .register => |src_reg| { |
| 3454 | _ = try self.addInst(.{ | 3503 | _ = try self.addInst(.{ |
| 3455 | .tag = mir_tag, | 3504 | .tag = mir_tag, |
| 3456 | .ops = (Mir.Ops{ | 3505 | .ops = (Mir.Ops(Register, Register){ |
| 3457 | .reg1 = registerAlias(dst_reg, abi_size), | 3506 | .reg1 = registerAlias(dst_reg, abi_size), |
| 3458 | .reg2 = registerAlias(src_reg, abi_size), | 3507 | .reg2 = registerAlias(src_reg, abi_size), |
| 3459 | }).encode(), | 3508 | }).encode(), |
| 3460 | .data = undefined, | 3509 | .data = undefined, |
| 3461 | }); | 3510 | }); |
| 3462 | }, | 3511 | }, |
| | 3512 | .avx_register => { |
| | 3513 | return self.fail("TODO genBinOp for AVX register", .{}); |
| | 3514 | }, |
| 3463 | .immediate => |imm| { | 3515 | .immediate => |imm| { |
| 3464 | _ = try self.addInst(.{ | 3516 | _ = try self.addInst(.{ |
| 3465 | .tag = mir_tag, | 3517 | .tag = mir_tag, |
| 3466 | .ops = (Mir.Ops{ | 3518 | .ops = (Mir.Ops(Register, Register){ |
| 3467 | .reg1 = registerAlias(dst_reg, abi_size), | 3519 | .reg1 = registerAlias(dst_reg, abi_size), |
| 3468 | }).encode(), | 3520 | }).encode(), |
| 3469 | .data = .{ .imm = @truncate(u32, imm) }, | 3521 | .data = .{ .imm = @truncate(u32, imm) }, |
| ... | @@ -3488,7 +3540,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu | ... | @@ -3488,7 +3540,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3488 | } | 3540 | } |
| 3489 | _ = try self.addInst(.{ | 3541 | _ = try self.addInst(.{ |
| 3490 | .tag = mir_tag, | 3542 | .tag = mir_tag, |
| 3491 | .ops = (Mir.Ops{ | 3543 | .ops = (Mir.Ops(Register, Register){ |
| 3492 | .reg1 = registerAlias(dst_reg, abi_size), | 3544 | .reg1 = registerAlias(dst_reg, abi_size), |
| 3493 | .reg2 = .rbp, | 3545 | .reg2 = .rbp, |
| 3494 | .flags = 0b01, | 3546 | .flags = 0b01, |
| ... | @@ -3498,6 +3550,9 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu | ... | @@ -3498,6 +3550,9 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3498 | }, | 3550 | }, |
| 3499 | } | 3551 | } |
| 3500 | }, | 3552 | }, |
| | 3553 | .avx_register => { |
| | 3554 | return self.fail("TODO genBinOp for AVX register", .{}); |
| | 3555 | }, |
| 3501 | .ptr_stack_offset, .stack_offset => |off| { | 3556 | .ptr_stack_offset, .stack_offset => |off| { |
| 3502 | if (off > math.maxInt(i32)) { | 3557 | if (off > math.maxInt(i32)) { |
| 3503 | return self.fail("stack offset too large", .{}); | 3558 | return self.fail("stack offset too large", .{}); |
| ... | @@ -3515,7 +3570,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu | ... | @@ -3515,7 +3570,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3515 | .register => |src_reg| { | 3570 | .register => |src_reg| { |
| 3516 | _ = try self.addInst(.{ | 3571 | _ = try self.addInst(.{ |
| 3517 | .tag = mir_tag, | 3572 | .tag = mir_tag, |
| 3518 | .ops = (Mir.Ops{ | 3573 | .ops = (Mir.Ops(Register, Register){ |
| 3519 | .reg1 = .rbp, | 3574 | .reg1 = .rbp, |
| 3520 | .reg2 = registerAlias(src_reg, abi_size), | 3575 | .reg2 = registerAlias(src_reg, abi_size), |
| 3521 | .flags = 0b10, | 3576 | .flags = 0b10, |
| ... | @@ -3523,6 +3578,9 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu | ... | @@ -3523,6 +3578,9 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3523 | .data = .{ .imm = @bitCast(u32, -off) }, | 3578 | .data = .{ .imm = @bitCast(u32, -off) }, |
| 3524 | }); | 3579 | }); |
| 3525 | }, | 3580 | }, |
| | 3581 | .avx_register => { |
| | 3582 | return self.fail("TODO genBinOp for AVX register", .{}); |
| | 3583 | }, |
| 3526 | .immediate => |imm| { | 3584 | .immediate => |imm| { |
| 3527 | const tag: Mir.Inst.Tag = switch (mir_tag) { | 3585 | const tag: Mir.Inst.Tag = switch (mir_tag) { |
| 3528 | .add => .add_mem_imm, | 3586 | .add => .add_mem_imm, |
| ... | @@ -3546,7 +3604,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu | ... | @@ -3546,7 +3604,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu |
| 3546 | }); | 3604 | }); |
| 3547 | _ = try self.addInst(.{ | 3605 | _ = try self.addInst(.{ |
| 3548 | .tag = tag, | 3606 | .tag = tag, |
| 3549 | .ops = (Mir.Ops{ | 3607 | .ops = (Mir.Ops(Register, Register){ |
| 3550 | .reg1 = .rbp, | 3608 | .reg1 = .rbp, |
| 3551 | .flags = flags, | 3609 | .flags = flags, |
| 3552 | }).encode(), | 3610 | }).encode(), |
| ... | @@ -3592,6 +3650,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -3592,6 +3650,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 3592 | .ptr_stack_offset => unreachable, | 3650 | .ptr_stack_offset => unreachable, |
| 3593 | .register_overflow_unsigned => unreachable, | 3651 | .register_overflow_unsigned => unreachable, |
| 3594 | .register_overflow_signed => unreachable, | 3652 | .register_overflow_signed => unreachable, |
| | 3653 | .avx_register => unreachable, |
| 3595 | .register => |dst_reg| { | 3654 | .register => |dst_reg| { |
| 3596 | switch (src_mcv) { | 3655 | switch (src_mcv) { |
| 3597 | .none => unreachable, | 3656 | .none => unreachable, |
| ... | @@ -3600,11 +3659,12 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -3600,11 +3659,12 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 3600 | .ptr_stack_offset => unreachable, | 3659 | .ptr_stack_offset => unreachable, |
| 3601 | .register_overflow_unsigned => unreachable, | 3660 | .register_overflow_unsigned => unreachable, |
| 3602 | .register_overflow_signed => unreachable, | 3661 | .register_overflow_signed => unreachable, |
| | 3662 | .avx_register => unreachable, |
| 3603 | .register => |src_reg| { | 3663 | .register => |src_reg| { |
| 3604 | // register, register | 3664 | // register, register |
| 3605 | _ = try self.addInst(.{ | 3665 | _ = try self.addInst(.{ |
| 3606 | .tag = .imul_complex, | 3666 | .tag = .imul_complex, |
| 3607 | .ops = (Mir.Ops{ | 3667 | .ops = (Mir.Ops(Register, Register){ |
| 3608 | .reg1 = registerAlias(dst_reg, abi_size), | 3668 | .reg1 = registerAlias(dst_reg, abi_size), |
| 3609 | .reg2 = registerAlias(src_reg, abi_size), | 3669 | .reg2 = registerAlias(src_reg, abi_size), |
| 3610 | }).encode(), | 3670 | }).encode(), |
| ... | @@ -3617,7 +3677,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -3617,7 +3677,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 3617 | if (math.minInt(i32) <= imm and imm <= math.maxInt(i32)) { | 3677 | if (math.minInt(i32) <= imm and imm <= math.maxInt(i32)) { |
| 3618 | _ = try self.addInst(.{ | 3678 | _ = try self.addInst(.{ |
| 3619 | .tag = .imul_complex, | 3679 | .tag = .imul_complex, |
| 3620 | .ops = (Mir.Ops{ | 3680 | .ops = (Mir.Ops(Register, Register){ |
| 3621 | .reg1 = dst_reg.to32(), | 3681 | .reg1 = dst_reg.to32(), |
| 3622 | .reg2 = dst_reg.to32(), | 3682 | .reg2 = dst_reg.to32(), |
| 3623 | .flags = 0b10, | 3683 | .flags = 0b10, |
| ... | @@ -3633,7 +3693,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -3633,7 +3693,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 3633 | .stack_offset => |off| { | 3693 | .stack_offset => |off| { |
| 3634 | _ = try self.addInst(.{ | 3694 | _ = try self.addInst(.{ |
| 3635 | .tag = .imul_complex, | 3695 | .tag = .imul_complex, |
| 3636 | .ops = (Mir.Ops{ | 3696 | .ops = (Mir.Ops(Register, Register){ |
| 3637 | .reg1 = registerAlias(dst_reg, abi_size), | 3697 | .reg1 = registerAlias(dst_reg, abi_size), |
| 3638 | .reg2 = .rbp, | 3698 | .reg2 = .rbp, |
| 3639 | .flags = 0b01, | 3699 | .flags = 0b01, |
| ... | @@ -3663,6 +3723,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -3663,6 +3723,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 3663 | .ptr_stack_offset => unreachable, | 3723 | .ptr_stack_offset => unreachable, |
| 3664 | .register_overflow_unsigned => unreachable, | 3724 | .register_overflow_unsigned => unreachable, |
| 3665 | .register_overflow_signed => unreachable, | 3725 | .register_overflow_signed => unreachable, |
| | 3726 | .avx_register => unreachable, |
| 3666 | .register => |src_reg| { | 3727 | .register => |src_reg| { |
| 3667 | // copy dst to a register | 3728 | // copy dst to a register |
| 3668 | const dst_reg = try self.copyToTmpRegister(dst_ty, dst_mcv); | 3729 | const dst_reg = try self.copyToTmpRegister(dst_ty, dst_mcv); |
| ... | @@ -3670,7 +3731,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -3670,7 +3731,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 3670 | // register, register | 3731 | // register, register |
| 3671 | _ = try self.addInst(.{ | 3732 | _ = try self.addInst(.{ |
| 3672 | .tag = .imul_complex, | 3733 | .tag = .imul_complex, |
| 3673 | .ops = (Mir.Ops{ | 3734 | .ops = (Mir.Ops(Register, Register){ |
| 3674 | .reg1 = registerAlias(dst_reg, abi_size), | 3735 | .reg1 = registerAlias(dst_reg, abi_size), |
| 3675 | .reg2 = registerAlias(src_reg, abi_size), | 3736 | .reg2 = registerAlias(src_reg, abi_size), |
| 3676 | }).encode(), | 3737 | }).encode(), |
| ... | @@ -3865,6 +3926,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -3865,6 +3926,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3865 | .ptr_stack_offset => { | 3926 | .ptr_stack_offset => { |
| 3866 | return self.fail("TODO implement calling with MCValue.ptr_stack_offset arg", .{}); | 3927 | return self.fail("TODO implement calling with MCValue.ptr_stack_offset arg", .{}); |
| 3867 | }, | 3928 | }, |
| | 3929 | .avx_register => { |
| | 3930 | return self.fail("TODO implement calling with MCValue.avx_register arg", .{}); |
| | 3931 | }, |
| 3868 | .undef => unreachable, | 3932 | .undef => unreachable, |
| 3869 | .immediate => unreachable, | 3933 | .immediate => unreachable, |
| 3870 | .unreach => unreachable, | 3934 | .unreach => unreachable, |
| ... | @@ -3883,7 +3947,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -3883,7 +3947,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3883 | // Adjust the stack | 3947 | // Adjust the stack |
| 3884 | _ = try self.addInst(.{ | 3948 | _ = try self.addInst(.{ |
| 3885 | .tag = .sub, | 3949 | .tag = .sub, |
| 3886 | .ops = (Mir.Ops{ | 3950 | .ops = (Mir.Ops(Register, Register){ |
| 3887 | .reg1 = .rsp, | 3951 | .reg1 = .rsp, |
| 3888 | }).encode(), | 3952 | }).encode(), |
| 3889 | .data = .{ .imm = info.stack_byte_count }, | 3953 | .data = .{ .imm = info.stack_byte_count }, |
| ... | @@ -3909,7 +3973,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -3909,7 +3973,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3909 | unreachable; | 3973 | unreachable; |
| 3910 | _ = try self.addInst(.{ | 3974 | _ = try self.addInst(.{ |
| 3911 | .tag = .call, | 3975 | .tag = .call, |
| 3912 | .ops = (Mir.Ops{ | 3976 | .ops = (Mir.Ops(Register, Register){ |
| 3913 | .flags = 0b01, | 3977 | .flags = 0b01, |
| 3914 | }).encode(), | 3978 | }).encode(), |
| 3915 | .data = .{ .imm = @truncate(u32, got_addr) }, | 3979 | .data = .{ .imm = @truncate(u32, got_addr) }, |
| ... | @@ -3925,7 +3989,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -3925,7 +3989,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3925 | try self.genSetReg(Type.initTag(.usize), .rax, mcv); | 3989 | try self.genSetReg(Type.initTag(.usize), .rax, mcv); |
| 3926 | _ = try self.addInst(.{ | 3990 | _ = try self.addInst(.{ |
| 3927 | .tag = .call, | 3991 | .tag = .call, |
| 3928 | .ops = (Mir.Ops{ | 3992 | .ops = (Mir.Ops(Register, Register){ |
| 3929 | .reg1 = .rax, | 3993 | .reg1 = .rax, |
| 3930 | .flags = 0b01, | 3994 | .flags = 0b01, |
| 3931 | }).encode(), | 3995 | }).encode(), |
| ... | @@ -3943,7 +4007,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -3943,7 +4007,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3943 | // callq *%rax | 4007 | // callq *%rax |
| 3944 | _ = try self.addInst(.{ | 4008 | _ = try self.addInst(.{ |
| 3945 | .tag = .call, | 4009 | .tag = .call, |
| 3946 | .ops = (Mir.Ops{ | 4010 | .ops = (Mir.Ops(Register, Register){ |
| 3947 | .reg1 = .rax, | 4011 | .reg1 = .rax, |
| 3948 | .flags = 0b01, | 4012 | .flags = 0b01, |
| 3949 | }).encode(), | 4013 | }).encode(), |
| ... | @@ -3978,7 +4042,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -3978,7 +4042,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3978 | try self.genSetReg(Type.initTag(.usize), .rax, mcv); | 4042 | try self.genSetReg(Type.initTag(.usize), .rax, mcv); |
| 3979 | _ = try self.addInst(.{ | 4043 | _ = try self.addInst(.{ |
| 3980 | .tag = .call, | 4044 | .tag = .call, |
| 3981 | .ops = (Mir.Ops{ | 4045 | .ops = (Mir.Ops(Register, Register){ |
| 3982 | .reg1 = .rax, | 4046 | .reg1 = .rax, |
| 3983 | .flags = 0b01, | 4047 | .flags = 0b01, |
| 3984 | }).encode(), | 4048 | }).encode(), |
| ... | @@ -3996,7 +4060,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -3996,7 +4060,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3996 | const fn_got_addr = got_addr + got_index * ptr_bytes; | 4060 | const fn_got_addr = got_addr + got_index * ptr_bytes; |
| 3997 | _ = try self.addInst(.{ | 4061 | _ = try self.addInst(.{ |
| 3998 | .tag = .call, | 4062 | .tag = .call, |
| 3999 | .ops = (Mir.Ops{ | 4063 | .ops = (Mir.Ops(Register, Register){ |
| 4000 | .flags = 0b01, | 4064 | .flags = 0b01, |
| 4001 | }).encode(), | 4065 | }).encode(), |
| 4002 | .data = .{ .imm = @intCast(u32, fn_got_addr) }, | 4066 | .data = .{ .imm = @intCast(u32, fn_got_addr) }, |
| ... | @@ -4008,7 +4072,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -4008,7 +4072,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 4008 | try self.genSetReg(Type.initTag(.usize), .rax, mcv); | 4072 | try self.genSetReg(Type.initTag(.usize), .rax, mcv); |
| 4009 | _ = try self.addInst(.{ | 4073 | _ = try self.addInst(.{ |
| 4010 | .tag = .call, | 4074 | .tag = .call, |
| 4011 | .ops = (Mir.Ops{ | 4075 | .ops = (Mir.Ops(Register, Register){ |
| 4012 | .reg1 = .rax, | 4076 | .reg1 = .rax, |
| 4013 | .flags = 0b01, | 4077 | .flags = 0b01, |
| 4014 | }).encode(), | 4078 | }).encode(), |
| ... | @@ -4021,7 +4085,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -4021,7 +4085,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 4021 | // Readjust the stack | 4085 | // Readjust the stack |
| 4022 | _ = try self.addInst(.{ | 4086 | _ = try self.addInst(.{ |
| 4023 | .tag = .add, | 4087 | .tag = .add, |
| 4024 | .ops = (Mir.Ops{ | 4088 | .ops = (Mir.Ops(Register, Register){ |
| 4025 | .reg1 = .rsp, | 4089 | .reg1 = .rsp, |
| 4026 | }).encode(), | 4090 | }).encode(), |
| 4027 | .data = .{ .imm = info.stack_byte_count }, | 4091 | .data = .{ .imm = info.stack_byte_count }, |
| ... | @@ -4081,7 +4145,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4081,7 +4145,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4081 | // which is available if the jump is 127 bytes or less forward. | 4145 | // which is available if the jump is 127 bytes or less forward. |
| 4082 | const jmp_reloc = try self.addInst(.{ | 4146 | const jmp_reloc = try self.addInst(.{ |
| 4083 | .tag = .jmp, | 4147 | .tag = .jmp, |
| 4084 | .ops = (Mir.Ops{ | 4148 | .ops = (Mir.Ops(Register, Register){ |
| 4085 | .flags = 0b00, | 4149 | .flags = 0b00, |
| 4086 | }).encode(), | 4150 | }).encode(), |
| 4087 | .data = .{ .inst = undefined }, | 4151 | .data = .{ .inst = undefined }, |
| ... | @@ -4116,7 +4180,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4116,7 +4180,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4116 | // which is available if the jump is 127 bytes or less forward. | 4180 | // which is available if the jump is 127 bytes or less forward. |
| 4117 | const jmp_reloc = try self.addInst(.{ | 4181 | const jmp_reloc = try self.addInst(.{ |
| 4118 | .tag = .jmp, | 4182 | .tag = .jmp, |
| 4119 | .ops = (Mir.Ops{ | 4183 | .ops = (Mir.Ops(Register, Register){ |
| 4120 | .flags = 0b00, | 4184 | .flags = 0b00, |
| 4121 | }).encode(), | 4185 | }).encode(), |
| 4122 | .data = .{ .inst = undefined }, | 4186 | .data = .{ .inst = undefined }, |
| ... | @@ -4362,7 +4426,7 @@ fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 { | ... | @@ -4362,7 +4426,7 @@ fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 { |
| 4362 | Mir.Inst.Tag.cond_jmp_greater_less; | 4426 | Mir.Inst.Tag.cond_jmp_greater_less; |
| 4363 | return self.addInst(.{ | 4427 | return self.addInst(.{ |
| 4364 | .tag = tag, | 4428 | .tag = tag, |
| 4365 | .ops = (Mir.Ops{ | 4429 | .ops = (Mir.Ops(Register, Register){ |
| 4366 | .flags = flags, | 4430 | .flags = flags, |
| 4367 | }).encode(), | 4431 | }).encode(), |
| 4368 | .data = .{ .inst = undefined }, | 4432 | .data = .{ .inst = undefined }, |
| ... | @@ -4372,7 +4436,7 @@ fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 { | ... | @@ -4372,7 +4436,7 @@ fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 { |
| 4372 | try self.spillCompareFlagsIfOccupied(); | 4436 | try self.spillCompareFlagsIfOccupied(); |
| 4373 | _ = try self.addInst(.{ | 4437 | _ = try self.addInst(.{ |
| 4374 | .tag = .@"test", | 4438 | .tag = .@"test", |
| 4375 | .ops = (Mir.Ops{ | 4439 | .ops = (Mir.Ops(Register, Register){ |
| 4376 | .reg1 = reg, | 4440 | .reg1 = reg, |
| 4377 | .flags = 0b00, | 4441 | .flags = 0b00, |
| 4378 | }).encode(), | 4442 | }).encode(), |
| ... | @@ -4380,7 +4444,7 @@ fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 { | ... | @@ -4380,7 +4444,7 @@ fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 { |
| 4380 | }); | 4444 | }); |
| 4381 | return self.addInst(.{ | 4445 | return self.addInst(.{ |
| 4382 | .tag = .cond_jmp_eq_ne, | 4446 | .tag = .cond_jmp_eq_ne, |
| 4383 | .ops = (Mir.Ops{ | 4447 | .ops = (Mir.Ops(Register, Register){ |
| 4384 | .flags = 0b01, | 4448 | .flags = 0b01, |
| 4385 | }).encode(), | 4449 | }).encode(), |
| 4386 | .data = .{ .inst = undefined }, | 4450 | .data = .{ .inst = undefined }, |
| ... | @@ -4776,7 +4840,7 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4776,7 +4840,7 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void { |
| 4776 | try self.genBody(body); | 4840 | try self.genBody(body); |
| 4777 | _ = try self.addInst(.{ | 4841 | _ = try self.addInst(.{ |
| 4778 | .tag = .jmp, | 4842 | .tag = .jmp, |
| 4779 | .ops = (Mir.Ops{ | 4843 | .ops = (Mir.Ops(Register, Register){ |
| 4780 | .flags = 0b00, | 4844 | .flags = 0b00, |
| 4781 | }).encode(), | 4845 | }).encode(), |
| 4782 | .data = .{ .inst = jmp_target }, | 4846 | .data = .{ .inst = jmp_target }, |
| ... | @@ -4829,7 +4893,7 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u | ... | @@ -4829,7 +4893,7 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u |
| 4829 | .immediate => |imm| { | 4893 | .immediate => |imm| { |
| 4830 | _ = try self.addInst(.{ | 4894 | _ = try self.addInst(.{ |
| 4831 | .tag = .xor, | 4895 | .tag = .xor, |
| 4832 | .ops = (Mir.Ops{ | 4896 | .ops = (Mir.Ops(Register, Register){ |
| 4833 | .reg1 = registerAlias(cond_reg, abi_size), | 4897 | .reg1 = registerAlias(cond_reg, abi_size), |
| 4834 | }).encode(), | 4898 | }).encode(), |
| 4835 | .data = .{ .imm = @intCast(u32, imm) }, | 4899 | .data = .{ .imm = @intCast(u32, imm) }, |
| ... | @@ -4838,7 +4902,7 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u | ... | @@ -4838,7 +4902,7 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u |
| 4838 | .register => |reg| { | 4902 | .register => |reg| { |
| 4839 | _ = try self.addInst(.{ | 4903 | _ = try self.addInst(.{ |
| 4840 | .tag = .xor, | 4904 | .tag = .xor, |
| 4841 | .ops = (Mir.Ops{ | 4905 | .ops = (Mir.Ops(Register, Register){ |
| 4842 | .reg1 = registerAlias(cond_reg, abi_size), | 4906 | .reg1 = registerAlias(cond_reg, abi_size), |
| 4843 | .reg2 = registerAlias(reg, abi_size), | 4907 | .reg2 = registerAlias(reg, abi_size), |
| 4844 | }).encode(), | 4908 | }).encode(), |
| ... | @@ -4860,7 +4924,7 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u | ... | @@ -4860,7 +4924,7 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u |
| 4860 | | 4924 | |
| 4861 | _ = try self.addInst(.{ | 4925 | _ = try self.addInst(.{ |
| 4862 | .tag = .@"test", | 4926 | .tag = .@"test", |
| 4863 | .ops = (Mir.Ops{ | 4927 | .ops = (Mir.Ops(Register, Register){ |
| 4864 | .reg1 = registerAlias(cond_reg, abi_size), | 4928 | .reg1 = registerAlias(cond_reg, abi_size), |
| 4865 | .reg2 = registerAlias(cond_reg, abi_size), | 4929 | .reg2 = registerAlias(cond_reg, abi_size), |
| 4866 | }).encode(), | 4930 | }).encode(), |
| ... | @@ -4868,7 +4932,7 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u | ... | @@ -4868,7 +4932,7 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u |
| 4868 | }); | 4932 | }); |
| 4869 | return self.addInst(.{ | 4933 | return self.addInst(.{ |
| 4870 | .tag = .cond_jmp_eq_ne, | 4934 | .tag = .cond_jmp_eq_ne, |
| 4871 | .ops = (Mir.Ops{ | 4935 | .ops = (Mir.Ops(Register, Register){ |
| 4872 | .flags = 0b00, | 4936 | .flags = 0b00, |
| 4873 | }).encode(), | 4937 | }).encode(), |
| 4874 | .data = .{ .inst = undefined }, | 4938 | .data = .{ .inst = undefined }, |
| ... | @@ -5020,6 +5084,12 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { | ... | @@ -5020,6 +5084,12 @@ fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { |
| 5020 | try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv); | 5084 | try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv); |
| 5021 | break :blk new_mcv; | 5085 | break :blk new_mcv; |
| 5022 | }, | 5086 | }, |
| | 5087 | .avx_register => blk: { |
| | 5088 | // TODO not needed; return operand_mcv ones we can transfer between XMM registers |
| | 5089 | const new_mcv = try self.allocRegOrMem(block, false); |
| | 5090 | try self.setRegOrMem(self.air.typeOfIndex(block), new_mcv, operand_mcv); |
| | 5091 | break :blk new_mcv; |
| | 5092 | }, |
| 5023 | else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}), | 5093 | else => return self.fail("TODO implement block_data.mcv = operand_mcv for {}", .{operand_mcv}), |
| 5024 | }; | 5094 | }; |
| 5025 | } else { | 5095 | } else { |
| ... | @@ -5036,7 +5106,7 @@ fn brVoid(self: *Self, block: Air.Inst.Index) !void { | ... | @@ -5036,7 +5106,7 @@ fn brVoid(self: *Self, block: Air.Inst.Index) !void { |
| 5036 | // Leave the jump offset undefined | 5106 | // Leave the jump offset undefined |
| 5037 | const jmp_reloc = try self.addInst(.{ | 5107 | const jmp_reloc = try self.addInst(.{ |
| 5038 | .tag = .jmp, | 5108 | .tag = .jmp, |
| 5039 | .ops = (Mir.Ops{ | 5109 | .ops = (Mir.Ops(Register, Register){ |
| 5040 | .flags = 0b00, | 5110 | .flags = 0b00, |
| 5041 | }).encode(), | 5111 | }).encode(), |
| 5042 | .data = .{ .inst = undefined }, | 5112 | .data = .{ .inst = undefined }, |
| ... | @@ -5126,7 +5196,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5126,7 +5196,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 5126 | }; | 5196 | }; |
| 5127 | _ = try self.addInst(.{ | 5197 | _ = try self.addInst(.{ |
| 5128 | .tag = .push, | 5198 | .tag = .push, |
| 5129 | .ops = (Mir.Ops{ | 5199 | .ops = (Mir.Ops(Register, Register){ |
| 5130 | .flags = 0b10, | 5200 | .flags = 0b10, |
| 5131 | }).encode(), | 5201 | }).encode(), |
| 5132 | .data = .{ .imm = n }, | 5202 | .data = .{ .imm = n }, |
| ... | @@ -5137,7 +5207,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5137,7 +5207,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 5137 | return self.fail("unrecognized register: '{s}'", .{reg_name}); | 5207 | return self.fail("unrecognized register: '{s}'", .{reg_name}); |
| 5138 | _ = try self.addInst(.{ | 5208 | _ = try self.addInst(.{ |
| 5139 | .tag = .push, | 5209 | .tag = .push, |
| 5140 | .ops = (Mir.Ops{ | 5210 | .ops = (Mir.Ops(Register, Register){ |
| 5141 | .reg1 = reg, | 5211 | .reg1 = reg, |
| 5142 | }).encode(), | 5212 | }).encode(), |
| 5143 | .data = undefined, | 5213 | .data = undefined, |
| ... | @@ -5151,7 +5221,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5151,7 +5221,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 5151 | return self.fail("unrecognized register: '{s}'", .{reg_name}); | 5221 | return self.fail("unrecognized register: '{s}'", .{reg_name}); |
| 5152 | _ = try self.addInst(.{ | 5222 | _ = try self.addInst(.{ |
| 5153 | .tag = .pop, | 5223 | .tag = .pop, |
| 5154 | .ops = (Mir.Ops{ | 5224 | .ops = (Mir.Ops(Register, Register){ |
| 5155 | .reg1 = reg, | 5225 | .reg1 = reg, |
| 5156 | }).encode(), | 5226 | }).encode(), |
| 5157 | .data = undefined, | 5227 | .data = undefined, |
| ... | @@ -5217,6 +5287,7 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void { | ... | @@ -5217,6 +5287,7 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void { |
| 5217 | .none => return, | 5287 | .none => return, |
| 5218 | .immediate => unreachable, | 5288 | .immediate => unreachable, |
| 5219 | .register => |reg| return self.genSetReg(ty, reg, val), | 5289 | .register => |reg| return self.genSetReg(ty, reg, val), |
| | 5290 | .avx_register => |reg| return self.genSetAvxReg(ty, reg, val), |
| 5220 | .stack_offset => |off| return self.genSetStack(ty, off, val, .{}), | 5291 | .stack_offset => |off| return self.genSetStack(ty, off, val, .{}), |
| 5221 | .memory => { | 5292 | .memory => { |
| 5222 | return self.fail("TODO implement setRegOrMem for memory", .{}); | 5293 | return self.fail("TODO implement setRegOrMem for memory", .{}); |
| ... | @@ -5247,6 +5318,9 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -5247,6 +5318,9 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 5247 | .register_overflow_unsigned, | 5318 | .register_overflow_unsigned, |
| 5248 | .register_overflow_signed, | 5319 | .register_overflow_signed, |
| 5249 | => return self.fail("TODO genSetStackArg for register with overflow bit", .{}), | 5320 | => return self.fail("TODO genSetStackArg for register with overflow bit", .{}), |
| | 5321 | .avx_register => { |
| | 5322 | return self.fail("TODO genSetStackArg for AVX register", .{}); |
| | 5323 | }, |
| 5250 | .compare_flags_unsigned, | 5324 | .compare_flags_unsigned, |
| 5251 | .compare_flags_signed, | 5325 | .compare_flags_signed, |
| 5252 | => { | 5326 | => { |
| ... | @@ -5265,7 +5339,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -5265,7 +5339,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 5265 | }); | 5339 | }); |
| 5266 | _ = try self.addInst(.{ | 5340 | _ = try self.addInst(.{ |
| 5267 | .tag = .mov_mem_imm, | 5341 | .tag = .mov_mem_imm, |
| 5268 | .ops = (Mir.Ops{ | 5342 | .ops = (Mir.Ops(Register, Register){ |
| 5269 | .reg1 = .rsp, | 5343 | .reg1 = .rsp, |
| 5270 | .flags = switch (abi_size) { | 5344 | .flags = switch (abi_size) { |
| 5271 | 1 => 0b00, | 5345 | 1 => 0b00, |
| ... | @@ -5301,7 +5375,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -5301,7 +5375,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 5301 | .register => |reg| { | 5375 | .register => |reg| { |
| 5302 | _ = try self.addInst(.{ | 5376 | _ = try self.addInst(.{ |
| 5303 | .tag = .mov, | 5377 | .tag = .mov, |
| 5304 | .ops = (Mir.Ops{ | 5378 | .ops = (Mir.Ops(Register, Register){ |
| 5305 | .reg1 = .rsp, | 5379 | .reg1 = .rsp, |
| 5306 | .reg2 = registerAlias(reg, @intCast(u32, abi_size)), | 5380 | .reg2 = registerAlias(reg, @intCast(u32, abi_size)), |
| 5307 | .flags = 0b10, | 5381 | .flags = 0b10, |
| ... | @@ -5368,7 +5442,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -5368,7 +5442,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5368 | }; | 5442 | }; |
| 5369 | _ = try self.addInst(.{ | 5443 | _ = try self.addInst(.{ |
| 5370 | .tag = .cond_set_byte_overflow, | 5444 | .tag = .cond_set_byte_overflow, |
| 5371 | .ops = (Mir.Ops{ | 5445 | .ops = (Mir.Ops(Register, Register){ |
| 5372 | .reg1 = tmp_reg.to8(), | 5446 | .reg1 = tmp_reg.to8(), |
| 5373 | .flags = flags, | 5447 | .flags = flags, |
| 5374 | }).encode(), | 5448 | }).encode(), |
| ... | @@ -5398,7 +5472,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -5398,7 +5472,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5398 | }); | 5472 | }); |
| 5399 | _ = try self.addInst(.{ | 5473 | _ = try self.addInst(.{ |
| 5400 | .tag = .mov_mem_imm, | 5474 | .tag = .mov_mem_imm, |
| 5401 | .ops = (Mir.Ops{ | 5475 | .ops = (Mir.Ops(Register, Register){ |
| 5402 | .reg1 = base_reg, | 5476 | .reg1 = base_reg, |
| 5403 | .flags = switch (abi_size) { | 5477 | .flags = switch (abi_size) { |
| 5404 | 1 => 0b00, | 5478 | 1 => 0b00, |
| ... | @@ -5420,7 +5494,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -5420,7 +5494,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5420 | }); | 5494 | }); |
| 5421 | _ = try self.addInst(.{ | 5495 | _ = try self.addInst(.{ |
| 5422 | .tag = .mov_mem_imm, | 5496 | .tag = .mov_mem_imm, |
| 5423 | .ops = (Mir.Ops{ | 5497 | .ops = (Mir.Ops(Register, Register){ |
| 5424 | .reg1 = base_reg, | 5498 | .reg1 = base_reg, |
| 5425 | .flags = 0b10, | 5499 | .flags = 0b10, |
| 5426 | }).encode(), | 5500 | }).encode(), |
| ... | @@ -5434,7 +5508,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -5434,7 +5508,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5434 | }); | 5508 | }); |
| 5435 | _ = try self.addInst(.{ | 5509 | _ = try self.addInst(.{ |
| 5436 | .tag = .mov_mem_imm, | 5510 | .tag = .mov_mem_imm, |
| 5437 | .ops = (Mir.Ops{ | 5511 | .ops = (Mir.Ops(Register, Register){ |
| 5438 | .reg1 = base_reg, | 5512 | .reg1 = base_reg, |
| 5439 | .flags = 0b10, | 5513 | .flags = 0b10, |
| 5440 | }).encode(), | 5514 | }).encode(), |
| ... | @@ -5466,7 +5540,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -5466,7 +5540,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5466 | | 5540 | |
| 5467 | _ = try self.addInst(.{ | 5541 | _ = try self.addInst(.{ |
| 5468 | .tag = .mov, | 5542 | .tag = .mov, |
| 5469 | .ops = (Mir.Ops{ | 5543 | .ops = (Mir.Ops(Register, Register){ |
| 5470 | .reg1 = base_reg, | 5544 | .reg1 = base_reg, |
| 5471 | .reg2 = registerAlias(tmp_reg, nearest_power_of_two), | 5545 | .reg2 = registerAlias(tmp_reg, nearest_power_of_two), |
| 5472 | .flags = 0b10, | 5546 | .flags = 0b10, |
| ... | @@ -5484,7 +5558,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -5484,7 +5558,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5484 | } else { | 5558 | } else { |
| 5485 | _ = try self.addInst(.{ | 5559 | _ = try self.addInst(.{ |
| 5486 | .tag = .mov, | 5560 | .tag = .mov, |
| 5487 | .ops = (Mir.Ops{ | 5561 | .ops = (Mir.Ops(Register, Register){ |
| 5488 | .reg1 = base_reg, | 5562 | .reg1 = base_reg, |
| 5489 | .reg2 = registerAlias(reg, @intCast(u32, abi_size)), | 5563 | .reg2 = registerAlias(reg, @intCast(u32, abi_size)), |
| 5490 | .flags = 0b10, | 5564 | .flags = 0b10, |
| ... | @@ -5493,6 +5567,27 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -5493,6 +5567,27 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5493 | }); | 5567 | }); |
| 5494 | } | 5568 | } |
| 5495 | }, | 5569 | }, |
| | 5570 | .avx_register => |reg| { |
| | 5571 | const base_reg = opts.dest_stack_base orelse .rbp; |
| | 5572 | switch (ty.zigTypeTag()) { |
| | 5573 | .Float => switch (ty.tag()) { |
| | 5574 | .f32 => return self.fail("TODO genSetStack for AVX register for f32", .{}), |
| | 5575 | .f64 => { |
| | 5576 | _ = try self.addInst(.{ |
| | 5577 | .tag = .mov_f64, |
| | 5578 | .ops = (Mir.Ops(Register, AvxRegister){ |
| | 5579 | .reg1 = base_reg, |
| | 5580 | .reg2 = reg.to128(), |
| | 5581 | .flags = 0b01, |
| | 5582 | }).encode(), |
| | 5583 | .data = .{ .imm = @bitCast(u32, -stack_offset) }, |
| | 5584 | }); |
| | 5585 | }, |
| | 5586 | else => return self.fail("TODO genSetStack for AVX register for type {}", .{ty.fmtDebug()}), |
| | 5587 | }, |
| | 5588 | else => return self.fail("TODO genSetStack for AVX register for type {}", .{ty.fmtDebug()}), |
| | 5589 | } |
| | 5590 | }, |
| 5496 | .memory, | 5591 | .memory, |
| 5497 | .got_load, | 5592 | .got_load, |
| 5498 | .direct_load, | 5593 | .direct_load, |
| ... | @@ -5569,7 +5664,7 @@ fn genInlineMemcpy( | ... | @@ -5569,7 +5664,7 @@ fn genInlineMemcpy( |
| 5569 | .ptr_stack_offset, .stack_offset => |off| { | 5664 | .ptr_stack_offset, .stack_offset => |off| { |
| 5570 | _ = try self.addInst(.{ | 5665 | _ = try self.addInst(.{ |
| 5571 | .tag = .lea, | 5666 | .tag = .lea, |
| 5572 | .ops = (Mir.Ops{ | 5667 | .ops = (Mir.Ops(Register, Register){ |
| 5573 | .reg1 = dst_addr_reg.to64(), | 5668 | .reg1 = dst_addr_reg.to64(), |
| 5574 | .reg2 = opts.dest_stack_base orelse .rbp, | 5669 | .reg2 = opts.dest_stack_base orelse .rbp, |
| 5575 | }).encode(), | 5670 | }).encode(), |
| ... | @@ -5579,7 +5674,7 @@ fn genInlineMemcpy( | ... | @@ -5579,7 +5674,7 @@ fn genInlineMemcpy( |
| 5579 | .register => |reg| { | 5674 | .register => |reg| { |
| 5580 | _ = try self.addInst(.{ | 5675 | _ = try self.addInst(.{ |
| 5581 | .tag = .mov, | 5676 | .tag = .mov, |
| 5582 | .ops = (Mir.Ops{ | 5677 | .ops = (Mir.Ops(Register, Register){ |
| 5583 | .reg1 = registerAlias(dst_addr_reg, @divExact(reg.size(), 8)), | 5678 | .reg1 = registerAlias(dst_addr_reg, @divExact(reg.size(), 8)), |
| 5584 | .reg2 = reg, | 5679 | .reg2 = reg, |
| 5585 | }).encode(), | 5680 | }).encode(), |
| ... | @@ -5604,7 +5699,7 @@ fn genInlineMemcpy( | ... | @@ -5604,7 +5699,7 @@ fn genInlineMemcpy( |
| 5604 | .ptr_stack_offset, .stack_offset => |off| { | 5699 | .ptr_stack_offset, .stack_offset => |off| { |
| 5605 | _ = try self.addInst(.{ | 5700 | _ = try self.addInst(.{ |
| 5606 | .tag = .lea, | 5701 | .tag = .lea, |
| 5607 | .ops = (Mir.Ops{ | 5702 | .ops = (Mir.Ops(Register, Register){ |
| 5608 | .reg1 = src_addr_reg.to64(), | 5703 | .reg1 = src_addr_reg.to64(), |
| 5609 | .reg2 = opts.source_stack_base orelse .rbp, | 5704 | .reg2 = opts.source_stack_base orelse .rbp, |
| 5610 | }).encode(), | 5705 | }).encode(), |
| ... | @@ -5614,7 +5709,7 @@ fn genInlineMemcpy( | ... | @@ -5614,7 +5709,7 @@ fn genInlineMemcpy( |
| 5614 | .register => |reg| { | 5709 | .register => |reg| { |
| 5615 | _ = try self.addInst(.{ | 5710 | _ = try self.addInst(.{ |
| 5616 | .tag = .mov, | 5711 | .tag = .mov, |
| 5617 | .ops = (Mir.Ops{ | 5712 | .ops = (Mir.Ops(Register, Register){ |
| 5618 | .reg1 = registerAlias(src_addr_reg, @divExact(reg.size(), 8)), | 5713 | .reg1 = registerAlias(src_addr_reg, @divExact(reg.size(), 8)), |
| 5619 | .reg2 = reg, | 5714 | .reg2 = reg, |
| 5620 | }).encode(), | 5715 | }).encode(), |
| ... | @@ -5637,7 +5732,7 @@ fn genInlineMemcpy( | ... | @@ -5637,7 +5732,7 @@ fn genInlineMemcpy( |
| 5637 | // mov rcx, 0 | 5732 | // mov rcx, 0 |
| 5638 | _ = try self.addInst(.{ | 5733 | _ = try self.addInst(.{ |
| 5639 | .tag = .mov, | 5734 | .tag = .mov, |
| 5640 | .ops = (Mir.Ops{ | 5735 | .ops = (Mir.Ops(Register, Register){ |
| 5641 | .reg1 = .rcx, | 5736 | .reg1 = .rcx, |
| 5642 | }).encode(), | 5737 | }).encode(), |
| 5643 | .data = .{ .imm = 0 }, | 5738 | .data = .{ .imm = 0 }, |
| ... | @@ -5646,7 +5741,7 @@ fn genInlineMemcpy( | ... | @@ -5646,7 +5741,7 @@ fn genInlineMemcpy( |
| 5646 | // mov rax, 0 | 5741 | // mov rax, 0 |
| 5647 | _ = try self.addInst(.{ | 5742 | _ = try self.addInst(.{ |
| 5648 | .tag = .mov, | 5743 | .tag = .mov, |
| 5649 | .ops = (Mir.Ops{ | 5744 | .ops = (Mir.Ops(Register, Register){ |
| 5650 | .reg1 = .rax, | 5745 | .reg1 = .rax, |
| 5651 | }).encode(), | 5746 | }).encode(), |
| 5652 | .data = .{ .imm = 0 }, | 5747 | .data = .{ .imm = 0 }, |
| ... | @@ -5656,7 +5751,7 @@ fn genInlineMemcpy( | ... | @@ -5656,7 +5751,7 @@ fn genInlineMemcpy( |
| 5656 | // cmp count, 0 | 5751 | // cmp count, 0 |
| 5657 | const loop_start = try self.addInst(.{ | 5752 | const loop_start = try self.addInst(.{ |
| 5658 | .tag = .cmp, | 5753 | .tag = .cmp, |
| 5659 | .ops = (Mir.Ops{ | 5754 | .ops = (Mir.Ops(Register, Register){ |
| 5660 | .reg1 = count_reg, | 5755 | .reg1 = count_reg, |
| 5661 | }).encode(), | 5756 | }).encode(), |
| 5662 | .data = .{ .imm = 0 }, | 5757 | .data = .{ .imm = 0 }, |
| ... | @@ -5665,14 +5760,14 @@ fn genInlineMemcpy( | ... | @@ -5665,14 +5760,14 @@ fn genInlineMemcpy( |
| 5665 | // je end | 5760 | // je end |
| 5666 | const loop_reloc = try self.addInst(.{ | 5761 | const loop_reloc = try self.addInst(.{ |
| 5667 | .tag = .cond_jmp_eq_ne, | 5762 | .tag = .cond_jmp_eq_ne, |
| 5668 | .ops = (Mir.Ops{ .flags = 0b01 }).encode(), | 5763 | .ops = (Mir.Ops(Register, Register){ .flags = 0b01 }).encode(), |
| 5669 | .data = .{ .inst = undefined }, | 5764 | .data = .{ .inst = undefined }, |
| 5670 | }); | 5765 | }); |
| 5671 | | 5766 | |
| 5672 | // mov tmp, [addr + rcx] | 5767 | // mov tmp, [addr + rcx] |
| 5673 | _ = try self.addInst(.{ | 5768 | _ = try self.addInst(.{ |
| 5674 | .tag = .mov_scale_src, | 5769 | .tag = .mov_scale_src, |
| 5675 | .ops = (Mir.Ops{ | 5770 | .ops = (Mir.Ops(Register, Register){ |
| 5676 | .reg1 = tmp_reg.to8(), | 5771 | .reg1 = tmp_reg.to8(), |
| 5677 | .reg2 = src_addr_reg, | 5772 | .reg2 = src_addr_reg, |
| 5678 | }).encode(), | 5773 | }).encode(), |
| ... | @@ -5682,7 +5777,7 @@ fn genInlineMemcpy( | ... | @@ -5682,7 +5777,7 @@ fn genInlineMemcpy( |
| 5682 | // mov [stack_offset + rax], tmp | 5777 | // mov [stack_offset + rax], tmp |
| 5683 | _ = try self.addInst(.{ | 5778 | _ = try self.addInst(.{ |
| 5684 | .tag = .mov_scale_dst, | 5779 | .tag = .mov_scale_dst, |
| 5685 | .ops = (Mir.Ops{ | 5780 | .ops = (Mir.Ops(Register, Register){ |
| 5686 | .reg1 = dst_addr_reg, | 5781 | .reg1 = dst_addr_reg, |
| 5687 | .reg2 = tmp_reg.to8(), | 5782 | .reg2 = tmp_reg.to8(), |
| 5688 | }).encode(), | 5783 | }).encode(), |
| ... | @@ -5692,7 +5787,7 @@ fn genInlineMemcpy( | ... | @@ -5692,7 +5787,7 @@ fn genInlineMemcpy( |
| 5692 | // add rcx, 1 | 5787 | // add rcx, 1 |
| 5693 | _ = try self.addInst(.{ | 5788 | _ = try self.addInst(.{ |
| 5694 | .tag = .add, | 5789 | .tag = .add, |
| 5695 | .ops = (Mir.Ops{ | 5790 | .ops = (Mir.Ops(Register, Register){ |
| 5696 | .reg1 = .rcx, | 5791 | .reg1 = .rcx, |
| 5697 | }).encode(), | 5792 | }).encode(), |
| 5698 | .data = .{ .imm = 1 }, | 5793 | .data = .{ .imm = 1 }, |
| ... | @@ -5701,7 +5796,7 @@ fn genInlineMemcpy( | ... | @@ -5701,7 +5796,7 @@ fn genInlineMemcpy( |
| 5701 | // add rax, 1 | 5796 | // add rax, 1 |
| 5702 | _ = try self.addInst(.{ | 5797 | _ = try self.addInst(.{ |
| 5703 | .tag = .add, | 5798 | .tag = .add, |
| 5704 | .ops = (Mir.Ops{ | 5799 | .ops = (Mir.Ops(Register, Register){ |
| 5705 | .reg1 = .rax, | 5800 | .reg1 = .rax, |
| 5706 | }).encode(), | 5801 | }).encode(), |
| 5707 | .data = .{ .imm = 1 }, | 5802 | .data = .{ .imm = 1 }, |
| ... | @@ -5710,7 +5805,7 @@ fn genInlineMemcpy( | ... | @@ -5710,7 +5805,7 @@ fn genInlineMemcpy( |
| 5710 | // sub count, 1 | 5805 | // sub count, 1 |
| 5711 | _ = try self.addInst(.{ | 5806 | _ = try self.addInst(.{ |
| 5712 | .tag = .sub, | 5807 | .tag = .sub, |
| 5713 | .ops = (Mir.Ops{ | 5808 | .ops = (Mir.Ops(Register, Register){ |
| 5714 | .reg1 = count_reg, | 5809 | .reg1 = count_reg, |
| 5715 | }).encode(), | 5810 | }).encode(), |
| 5716 | .data = .{ .imm = 1 }, | 5811 | .data = .{ .imm = 1 }, |
| ... | @@ -5719,7 +5814,7 @@ fn genInlineMemcpy( | ... | @@ -5719,7 +5814,7 @@ fn genInlineMemcpy( |
| 5719 | // jmp loop | 5814 | // jmp loop |
| 5720 | _ = try self.addInst(.{ | 5815 | _ = try self.addInst(.{ |
| 5721 | .tag = .jmp, | 5816 | .tag = .jmp, |
| 5722 | .ops = (Mir.Ops{ .flags = 0b00 }).encode(), | 5817 | .ops = (Mir.Ops(Register, Register){ .flags = 0b00 }).encode(), |
| 5723 | .data = .{ .inst = loop_start }, | 5818 | .data = .{ .inst = loop_start }, |
| 5724 | }); | 5819 | }); |
| 5725 | | 5820 | |
| ... | @@ -5751,7 +5846,7 @@ fn genInlineMemset( | ... | @@ -5751,7 +5846,7 @@ fn genInlineMemset( |
| 5751 | .ptr_stack_offset, .stack_offset => |off| { | 5846 | .ptr_stack_offset, .stack_offset => |off| { |
| 5752 | _ = try self.addInst(.{ | 5847 | _ = try self.addInst(.{ |
| 5753 | .tag = .lea, | 5848 | .tag = .lea, |
| 5754 | .ops = (Mir.Ops{ | 5849 | .ops = (Mir.Ops(Register, Register){ |
| 5755 | .reg1 = addr_reg.to64(), | 5850 | .reg1 = addr_reg.to64(), |
| 5756 | .reg2 = opts.dest_stack_base orelse .rbp, | 5851 | .reg2 = opts.dest_stack_base orelse .rbp, |
| 5757 | }).encode(), | 5852 | }).encode(), |
| ... | @@ -5761,7 +5856,7 @@ fn genInlineMemset( | ... | @@ -5761,7 +5856,7 @@ fn genInlineMemset( |
| 5761 | .register => |reg| { | 5856 | .register => |reg| { |
| 5762 | _ = try self.addInst(.{ | 5857 | _ = try self.addInst(.{ |
| 5763 | .tag = .mov, | 5858 | .tag = .mov, |
| 5764 | .ops = (Mir.Ops{ | 5859 | .ops = (Mir.Ops(Register, Register){ |
| 5765 | .reg1 = registerAlias(addr_reg, @divExact(reg.size(), 8)), | 5860 | .reg1 = registerAlias(addr_reg, @divExact(reg.size(), 8)), |
| 5766 | .reg2 = reg, | 5861 | .reg2 = reg, |
| 5767 | }).encode(), | 5862 | }).encode(), |
| ... | @@ -5782,7 +5877,7 @@ fn genInlineMemset( | ... | @@ -5782,7 +5877,7 @@ fn genInlineMemset( |
| 5782 | // cmp rax, -1 | 5877 | // cmp rax, -1 |
| 5783 | const loop_start = try self.addInst(.{ | 5878 | const loop_start = try self.addInst(.{ |
| 5784 | .tag = .cmp, | 5879 | .tag = .cmp, |
| 5785 | .ops = (Mir.Ops{ | 5880 | .ops = (Mir.Ops(Register, Register){ |
| 5786 | .reg1 = .rax, | 5881 | .reg1 = .rax, |
| 5787 | }).encode(), | 5882 | }).encode(), |
| 5788 | .data = .{ .imm = @bitCast(u32, @as(i32, -1)) }, | 5883 | .data = .{ .imm = @bitCast(u32, @as(i32, -1)) }, |
| ... | @@ -5791,7 +5886,7 @@ fn genInlineMemset( | ... | @@ -5791,7 +5886,7 @@ fn genInlineMemset( |
| 5791 | // je end | 5886 | // je end |
| 5792 | const loop_reloc = try self.addInst(.{ | 5887 | const loop_reloc = try self.addInst(.{ |
| 5793 | .tag = .cond_jmp_eq_ne, | 5888 | .tag = .cond_jmp_eq_ne, |
| 5794 | .ops = (Mir.Ops{ .flags = 0b01 }).encode(), | 5889 | .ops = (Mir.Ops(Register, Register){ .flags = 0b01 }).encode(), |
| 5795 | .data = .{ .inst = undefined }, | 5890 | .data = .{ .inst = undefined }, |
| 5796 | }); | 5891 | }); |
| 5797 | | 5892 | |
| ... | @@ -5807,7 +5902,7 @@ fn genInlineMemset( | ... | @@ -5807,7 +5902,7 @@ fn genInlineMemset( |
| 5807 | }); | 5902 | }); |
| 5808 | _ = try self.addInst(.{ | 5903 | _ = try self.addInst(.{ |
| 5809 | .tag = .mov_mem_index_imm, | 5904 | .tag = .mov_mem_index_imm, |
| 5810 | .ops = (Mir.Ops{ | 5905 | .ops = (Mir.Ops(Register, Register){ |
| 5811 | .reg1 = addr_reg, | 5906 | .reg1 = addr_reg, |
| 5812 | }).encode(), | 5907 | }).encode(), |
| 5813 | .data = .{ .payload = payload }, | 5908 | .data = .{ .payload = payload }, |
| ... | @@ -5819,7 +5914,7 @@ fn genInlineMemset( | ... | @@ -5819,7 +5914,7 @@ fn genInlineMemset( |
| 5819 | // sub rax, 1 | 5914 | // sub rax, 1 |
| 5820 | _ = try self.addInst(.{ | 5915 | _ = try self.addInst(.{ |
| 5821 | .tag = .sub, | 5916 | .tag = .sub, |
| 5822 | .ops = (Mir.Ops{ | 5917 | .ops = (Mir.Ops(Register, Register){ |
| 5823 | .reg1 = .rax, | 5918 | .reg1 = .rax, |
| 5824 | }).encode(), | 5919 | }).encode(), |
| 5825 | .data = .{ .imm = 1 }, | 5920 | .data = .{ .imm = 1 }, |
| ... | @@ -5828,7 +5923,7 @@ fn genInlineMemset( | ... | @@ -5828,7 +5923,7 @@ fn genInlineMemset( |
| 5828 | // jmp loop | 5923 | // jmp loop |
| 5829 | _ = try self.addInst(.{ | 5924 | _ = try self.addInst(.{ |
| 5830 | .tag = .jmp, | 5925 | .tag = .jmp, |
| 5831 | .ops = (Mir.Ops{ .flags = 0b00 }).encode(), | 5926 | .ops = (Mir.Ops(Register, Register){ .flags = 0b00 }).encode(), |
| 5832 | .data = .{ .inst = loop_start }, | 5927 | .data = .{ .inst = loop_start }, |
| 5833 | }); | 5928 | }); |
| 5834 | | 5929 | |
| ... | @@ -5836,6 +5931,43 @@ fn genInlineMemset( | ... | @@ -5836,6 +5931,43 @@ fn genInlineMemset( |
| 5836 | try self.performReloc(loop_reloc); | 5931 | try self.performReloc(loop_reloc); |
| 5837 | } | 5932 | } |
| 5838 | | 5933 | |
| | 5934 | fn genSetAvxReg(self: *Self, ty: Type, reg: AvxRegister, mcv: MCValue) InnerError!void { |
| | 5935 | switch (mcv) { |
| | 5936 | .dead => unreachable, |
| | 5937 | .register_overflow_unsigned, |
| | 5938 | .register_overflow_signed, |
| | 5939 | => unreachable, |
| | 5940 | .stack_offset => |off| { |
| | 5941 | if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) { |
| | 5942 | return self.fail("stack offset too large", .{}); |
| | 5943 | } |
| | 5944 | |
| | 5945 | switch (ty.zigTypeTag()) { |
| | 5946 | .Float => { |
| | 5947 | switch (ty.tag()) { |
| | 5948 | .f32 => return self.fail("TODO genSetAvxReg from stack offset for f32", .{}), |
| | 5949 | .f64 => { |
| | 5950 | _ = try self.addInst(.{ |
| | 5951 | .tag = .mov_f64, |
| | 5952 | .ops = (Mir.Ops(AvxRegister, Register){ |
| | 5953 | .reg1 = reg.to128(), |
| | 5954 | .reg2 = .rbp, |
| | 5955 | }).encode(), |
| | 5956 | .data = .{ .imm = @bitCast(u32, -off) }, |
| | 5957 | }); |
| | 5958 | }, |
| | 5959 | else => return self.fail("TODO genSetAvxReg from stack offset for {}", .{ty.fmtDebug()}), |
| | 5960 | } |
| | 5961 | }, |
| | 5962 | else => return self.fail("TODO genSetAvxReg from stack offset for type {}", .{ty.fmtDebug()}), |
| | 5963 | } |
| | 5964 | }, |
| | 5965 | else => |other| { |
| | 5966 | return self.fail("TODO genSetAvxReg from {}", .{other}); |
| | 5967 | }, |
| | 5968 | } |
| | 5969 | } |
| | 5970 | |
| 5839 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { | 5971 | fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void { |
| 5840 | const abi_size = @intCast(u32, ty.abiSize(self.target.*)); | 5972 | const abi_size = @intCast(u32, ty.abiSize(self.target.*)); |
| 5841 | switch (mcv) { | 5973 | switch (mcv) { |
| ... | @@ -5843,13 +5975,14 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5843,13 +5975,14 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5843 | .register_overflow_unsigned, | 5975 | .register_overflow_unsigned, |
| 5844 | .register_overflow_signed, | 5976 | .register_overflow_signed, |
| 5845 | => unreachable, | 5977 | => unreachable, |
| | 5978 | .avx_register => unreachable, |
| 5846 | .ptr_stack_offset => |off| { | 5979 | .ptr_stack_offset => |off| { |
| 5847 | if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) { | 5980 | if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) { |
| 5848 | return self.fail("stack offset too large", .{}); | 5981 | return self.fail("stack offset too large", .{}); |
| 5849 | } | 5982 | } |
| 5850 | _ = try self.addInst(.{ | 5983 | _ = try self.addInst(.{ |
| 5851 | .tag = .lea, | 5984 | .tag = .lea, |
| 5852 | .ops = (Mir.Ops{ | 5985 | .ops = (Mir.Ops(Register, Register){ |
| 5853 | .reg1 = registerAlias(reg, abi_size), | 5986 | .reg1 = registerAlias(reg, abi_size), |
| 5854 | .reg2 = .rbp, | 5987 | .reg2 = .rbp, |
| 5855 | }).encode(), | 5988 | }).encode(), |
| ... | @@ -5889,7 +6022,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5889,7 +6022,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5889 | }; | 6022 | }; |
| 5890 | _ = try self.addInst(.{ | 6023 | _ = try self.addInst(.{ |
| 5891 | .tag = tag, | 6024 | .tag = tag, |
| 5892 | .ops = (Mir.Ops{ | 6025 | .ops = (Mir.Ops(Register, Register){ |
| 5893 | .reg1 = reg.to8(), | 6026 | .reg1 = reg.to8(), |
| 5894 | .flags = flags, | 6027 | .flags = flags, |
| 5895 | }).encode(), | 6028 | }).encode(), |
| ... | @@ -5902,7 +6035,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5902,7 +6035,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5902 | if (x == 0) { | 6035 | if (x == 0) { |
| 5903 | _ = try self.addInst(.{ | 6036 | _ = try self.addInst(.{ |
| 5904 | .tag = .xor, | 6037 | .tag = .xor, |
| 5905 | .ops = (Mir.Ops{ | 6038 | .ops = (Mir.Ops(Register, Register){ |
| 5906 | .reg1 = reg.to32(), | 6039 | .reg1 = reg.to32(), |
| 5907 | .reg2 = reg.to32(), | 6040 | .reg2 = reg.to32(), |
| 5908 | }).encode(), | 6041 | }).encode(), |
| ... | @@ -5914,7 +6047,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5914,7 +6047,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5914 | // Next best case: if we set the lower four bytes, the upper four will be zeroed. | 6047 | // Next best case: if we set the lower four bytes, the upper four will be zeroed. |
| 5915 | _ = try self.addInst(.{ | 6048 | _ = try self.addInst(.{ |
| 5916 | .tag = .mov, | 6049 | .tag = .mov, |
| 5917 | .ops = (Mir.Ops{ | 6050 | .ops = (Mir.Ops(Register, Register){ |
| 5918 | .reg1 = registerAlias(reg, abi_size), | 6051 | .reg1 = registerAlias(reg, abi_size), |
| 5919 | }).encode(), | 6052 | }).encode(), |
| 5920 | .data = .{ .imm = @truncate(u32, x) }, | 6053 | .data = .{ .imm = @truncate(u32, x) }, |
| ... | @@ -5931,7 +6064,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5931,7 +6064,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5931 | const payload = try self.addExtra(Mir.Imm64.encode(x)); | 6064 | const payload = try self.addExtra(Mir.Imm64.encode(x)); |
| 5932 | _ = try self.addInst(.{ | 6065 | _ = try self.addInst(.{ |
| 5933 | .tag = .movabs, | 6066 | .tag = .movabs, |
| 5934 | .ops = (Mir.Ops{ | 6067 | .ops = (Mir.Ops(Register, Register){ |
| 5935 | .reg1 = reg.to64(), | 6068 | .reg1 = reg.to64(), |
| 5936 | }).encode(), | 6069 | }).encode(), |
| 5937 | .data = .{ .payload = payload }, | 6070 | .data = .{ .payload = payload }, |
| ... | @@ -5948,7 +6081,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5948,7 +6081,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5948 | if (abi_size > 4) break :blk; | 6081 | if (abi_size > 4) break :blk; |
| 5949 | _ = try self.addInst(.{ | 6082 | _ = try self.addInst(.{ |
| 5950 | .tag = .mov_sign_extend, | 6083 | .tag = .mov_sign_extend, |
| 5951 | .ops = (Mir.Ops{ | 6084 | .ops = (Mir.Ops(Register, Register){ |
| 5952 | .reg1 = reg.to64(), | 6085 | .reg1 = reg.to64(), |
| 5953 | .reg2 = registerAlias(src_reg, abi_size), | 6086 | .reg2 = registerAlias(src_reg, abi_size), |
| 5954 | }).encode(), | 6087 | }).encode(), |
| ... | @@ -5959,7 +6092,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5959,7 +6092,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5959 | if (abi_size > 2) break :blk; | 6092 | if (abi_size > 2) break :blk; |
| 5960 | _ = try self.addInst(.{ | 6093 | _ = try self.addInst(.{ |
| 5961 | .tag = .mov_zero_extend, | 6094 | .tag = .mov_zero_extend, |
| 5962 | .ops = (Mir.Ops{ | 6095 | .ops = (Mir.Ops(Register, Register){ |
| 5963 | .reg1 = reg.to64(), | 6096 | .reg1 = reg.to64(), |
| 5964 | .reg2 = registerAlias(src_reg, abi_size), | 6097 | .reg2 = registerAlias(src_reg, abi_size), |
| 5965 | }).encode(), | 6098 | }).encode(), |
| ... | @@ -5972,7 +6105,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5972,7 +6105,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5972 | | 6105 | |
| 5973 | _ = try self.addInst(.{ | 6106 | _ = try self.addInst(.{ |
| 5974 | .tag = .mov, | 6107 | .tag = .mov, |
| 5975 | .ops = (Mir.Ops{ | 6108 | .ops = (Mir.Ops(Register, Register){ |
| 5976 | .reg1 = registerAlias(reg, abi_size), | 6109 | .reg1 = registerAlias(reg, abi_size), |
| 5977 | .reg2 = registerAlias(src_reg, abi_size), | 6110 | .reg2 = registerAlias(src_reg, abi_size), |
| 5978 | }).encode(), | 6111 | }).encode(), |
| ... | @@ -5985,7 +6118,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5985,7 +6118,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5985 | try self.loadMemPtrIntoRegister(reg, Type.usize, mcv); | 6118 | try self.loadMemPtrIntoRegister(reg, Type.usize, mcv); |
| 5986 | _ = try self.addInst(.{ | 6119 | _ = try self.addInst(.{ |
| 5987 | .tag = .mov, | 6120 | .tag = .mov, |
| 5988 | .ops = (Mir.Ops{ | 6121 | .ops = (Mir.Ops(Register, Register){ |
| 5989 | .reg1 = registerAlias(reg, abi_size), | 6122 | .reg1 = registerAlias(reg, abi_size), |
| 5990 | .reg2 = reg.to64(), | 6123 | .reg2 = reg.to64(), |
| 5991 | .flags = 0b01, | 6124 | .flags = 0b01, |
| ... | @@ -5998,7 +6131,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -5998,7 +6131,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5998 | // mov reg, [ds:imm32] | 6131 | // mov reg, [ds:imm32] |
| 5999 | _ = try self.addInst(.{ | 6132 | _ = try self.addInst(.{ |
| 6000 | .tag = .mov, | 6133 | .tag = .mov, |
| 6001 | .ops = (Mir.Ops{ | 6134 | .ops = (Mir.Ops(Register, Register){ |
| 6002 | .reg1 = registerAlias(reg, abi_size), | 6135 | .reg1 = registerAlias(reg, abi_size), |
| 6003 | .flags = 0b01, | 6136 | .flags = 0b01, |
| 6004 | }).encode(), | 6137 | }).encode(), |
| ... | @@ -6012,7 +6145,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -6012,7 +6145,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6012 | const payload = try self.addExtra(Mir.Imm64.encode(x)); | 6145 | const payload = try self.addExtra(Mir.Imm64.encode(x)); |
| 6013 | _ = try self.addInst(.{ | 6146 | _ = try self.addInst(.{ |
| 6014 | .tag = .movabs, | 6147 | .tag = .movabs, |
| 6015 | .ops = (Mir.Ops{ | 6148 | .ops = (Mir.Ops(Register, Register){ |
| 6016 | .reg1 = .rax, | 6149 | .reg1 = .rax, |
| 6017 | .flags = 0b01, // imm64 will become moffs64 | 6150 | .flags = 0b01, // imm64 will become moffs64 |
| 6018 | }).encode(), | 6151 | }).encode(), |
| ... | @@ -6025,7 +6158,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -6025,7 +6158,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6025 | // mov reg, [reg + 0x0] | 6158 | // mov reg, [reg + 0x0] |
| 6026 | _ = try self.addInst(.{ | 6159 | _ = try self.addInst(.{ |
| 6027 | .tag = .mov, | 6160 | .tag = .mov, |
| 6028 | .ops = (Mir.Ops{ | 6161 | .ops = (Mir.Ops(Register, Register){ |
| 6029 | .reg1 = registerAlias(reg, abi_size), | 6162 | .reg1 = registerAlias(reg, abi_size), |
| 6030 | .reg2 = reg.to64(), | 6163 | .reg2 = reg.to64(), |
| 6031 | .flags = 0b01, | 6164 | .flags = 0b01, |
| ... | @@ -6051,7 +6184,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -6051,7 +6184,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6051 | }; | 6184 | }; |
| 6052 | _ = try self.addInst(.{ | 6185 | _ = try self.addInst(.{ |
| 6053 | .tag = .mov_sign_extend, | 6186 | .tag = .mov_sign_extend, |
| 6054 | .ops = (Mir.Ops{ | 6187 | .ops = (Mir.Ops(Register, Register){ |
| 6055 | .reg1 = reg.to64(), | 6188 | .reg1 = reg.to64(), |
| 6056 | .reg2 = .rbp, | 6189 | .reg2 = .rbp, |
| 6057 | .flags = flags, | 6190 | .flags = flags, |
| ... | @@ -6067,7 +6200,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -6067,7 +6200,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6067 | }; | 6200 | }; |
| 6068 | _ = try self.addInst(.{ | 6201 | _ = try self.addInst(.{ |
| 6069 | .tag = .mov_zero_extend, | 6202 | .tag = .mov_zero_extend, |
| 6070 | .ops = (Mir.Ops{ | 6203 | .ops = (Mir.Ops(Register, Register){ |
| 6071 | .reg1 = reg.to64(), | 6204 | .reg1 = reg.to64(), |
| 6072 | .reg2 = .rbp, | 6205 | .reg2 = .rbp, |
| 6073 | .flags = flags, | 6206 | .flags = flags, |
| ... | @@ -6081,7 +6214,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -6081,7 +6214,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6081 | | 6214 | |
| 6082 | _ = try self.addInst(.{ | 6215 | _ = try self.addInst(.{ |
| 6083 | .tag = .mov, | 6216 | .tag = .mov, |
| 6084 | .ops = (Mir.Ops{ | 6217 | .ops = (Mir.Ops(Register, Register){ |
| 6085 | .reg1 = registerAlias(reg, abi_size), | 6218 | .reg1 = registerAlias(reg, abi_size), |
| 6086 | .reg2 = .rbp, | 6219 | .reg2 = .rbp, |
| 6087 | .flags = 0b01, | 6220 | .flags = 0b01, |
| ... | @@ -6152,7 +6285,7 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6152,7 +6285,7 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void { |
| 6152 | }; | 6285 | }; |
| 6153 | _ = try self.addInst(.{ | 6286 | _ = try self.addInst(.{ |
| 6154 | .tag = .fld, | 6287 | .tag = .fld, |
| 6155 | .ops = (Mir.Ops{ | 6288 | .ops = (Mir.Ops(Register, Register){ |
| 6156 | .flags = switch (src_ty.abiSize(self.target.*)) { | 6289 | .flags = switch (src_ty.abiSize(self.target.*)) { |
| 6157 | 4 => 0b01, | 6290 | 4 => 0b01, |
| 6158 | 8 => 0b10, | 6291 | 8 => 0b10, |
| ... | @@ -6167,7 +6300,7 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6167,7 +6300,7 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void { |
| 6167 | const stack_dst = try self.allocRegOrMem(inst, false); | 6300 | const stack_dst = try self.allocRegOrMem(inst, false); |
| 6168 | _ = try self.addInst(.{ | 6301 | _ = try self.addInst(.{ |
| 6169 | .tag = .fisttp, | 6302 | .tag = .fisttp, |
| 6170 | .ops = (Mir.Ops{ | 6303 | .ops = (Mir.Ops(Register, Register){ |
| 6171 | .flags = switch (dst_ty.abiSize(self.target.*)) { | 6304 | .flags = switch (dst_ty.abiSize(self.target.*)) { |
| 6172 | 1...2 => 0b00, | 6305 | 1...2 => 0b00, |
| 6173 | 3...4 => 0b01, | 6306 | 3...4 => 0b01, |
| ... | @@ -6271,7 +6404,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -6271,7 +6404,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 6271 | try self.loadMemPtrIntoRegister(reg, src_ty, src_ptr); | 6404 | try self.loadMemPtrIntoRegister(reg, src_ty, src_ptr); |
| 6272 | _ = try self.addInst(.{ | 6405 | _ = try self.addInst(.{ |
| 6273 | .tag = .mov, | 6406 | .tag = .mov, |
| 6274 | .ops = (Mir.Ops{ | 6407 | .ops = (Mir.Ops(Register, Register){ |
| 6275 | .reg1 = reg, | 6408 | .reg1 = reg, |
| 6276 | .reg2 = reg, | 6409 | .reg2 = reg, |
| 6277 | .flags = 0b01, | 6410 | .flags = 0b01, |
| ... | @@ -6840,7 +6973,20 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { | ... | @@ -6840,7 +6973,20 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { |
| 6840 | } else if (size_bytes <= 8) { | 6973 | } else if (size_bytes <= 8) { |
| 6841 | return reg.to64(); | 6974 | return reg.to64(); |
| 6842 | } else { | 6975 | } else { |
| 6843 | unreachable; // TODO handle floating-point registers | 6976 | unreachable; |
| | 6977 | } |
| | 6978 | } |
| | 6979 | |
| | 6980 | /// Returns AVX register wide enough to hold at least `size_bytes`. |
| | 6981 | fn avxRegisterAlias(reg: AvxRegister, size_bytes: u32) AvxRegister { |
| | 6982 | if (size_bytes == 0) { |
| | 6983 | unreachable; // should be comptime known |
| | 6984 | } else if (size_bytes <= 16) { |
| | 6985 | return reg.to128(); |
| | 6986 | } else if (size_bytes <= 32) { |
| | 6987 | return reg.to256(); |
| | 6988 | } else { |
| | 6989 | unreachable; |
| 6844 | } | 6990 | } |
| 6845 | } | 6991 | } |
| 6846 | | 6992 | |