| author | |
| committer | |
| log | 2286c19c20897727825a6fd8dd63de1ada6724ee |
| tree | 1d8a36c24bd566626af7944c535364ac18f55ab9 |
| parent | de6cafa80fba3c1fb93bf82b76c1efffbc61bf98 |
| parent | cea9ac772a518ff249d47fc2cb7b2776c786ac07 |
| signature |
27 files changed, 2115 insertions(+), 719 deletions(-)
src/arch/x86_64/CodeGen.zig+1198-381| ... | @@ -1079,9 +1079,9 @@ fn asmSetccRegister(self: *Self, reg: Register, cc: bits.Condition) !void { | ... | @@ -1079,9 +1079,9 @@ fn asmSetccRegister(self: *Self, reg: Register, cc: bits.Condition) !void { |
| 1079 | .fixes = Mir.Inst.Fixes.fromCondition(cc), | 1079 | .fixes = Mir.Inst.Fixes.fromCondition(cc), |
| 1080 | .r1 = reg, | 1080 | .r1 = reg, |
| 1081 | } }, | 1081 | } }, |
| 1082 | .z_and_np, .nz_or_p => .{ .r_scratch = .{ | 1082 | .z_and_np, .nz_or_p => .{ .rr = .{ |
| 1083 | .r1 = reg, | 1083 | .r1 = reg, |
| 1084 | .scratch_reg = (try self.register_manager.allocReg(null, gp)).to8(), | 1084 | .r2 = (try self.register_manager.allocReg(null, gp)).to8(), |
| 1085 | } }, | 1085 | } }, |
| 1086 | }, | 1086 | }, |
| 1087 | }); | 1087 | }); |
| ... | @@ -1120,8 +1120,8 @@ fn asmSetccMemory(self: *Self, m: Memory, cc: bits.Condition) !void { | ... | @@ -1120,8 +1120,8 @@ fn asmSetccMemory(self: *Self, m: Memory, cc: bits.Condition) !void { |
| 1120 | .fixes = Mir.Inst.Fixes.fromCondition(cc), | 1120 | .fixes = Mir.Inst.Fixes.fromCondition(cc), |
| 1121 | .payload = payload, | 1121 | .payload = payload, |
| 1122 | } }, | 1122 | } }, |
| 1123 | .z_and_np, .nz_or_p => .{ .x_scratch = .{ | 1123 | .z_and_np, .nz_or_p => .{ .rx = .{ |
| 1124 | .scratch_reg = (try self.register_manager.allocReg(null, gp)).to8(), | 1124 | .r1 = (try self.register_manager.allocReg(null, gp)).to8(), |
| 1125 | .payload = payload, | 1125 | .payload = payload, |
| 1126 | } }, | 1126 | } }, |
| 1127 | }, | 1127 | }, |
| ... | @@ -1460,6 +1460,15 @@ fn asmMemoryRegister(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, reg: Regist | ... | @@ -1460,6 +1460,15 @@ fn asmMemoryRegister(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, reg: Regist |
| 1460 | } | 1460 | } |
| 1461 | 1461 | ||
| 1462 | fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immediate) !void { | 1462 | fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immediate) !void { |
| 1463 | const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) { | ||
| 1464 | .signed => |s| @bitCast(u32, s), | ||
| 1465 | .unsigned => |u| @intCast(u32, u), | ||
| 1466 | } }); | ||
| 1467 | assert(payload + 1 == switch (m) { | ||
| 1468 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | ||
| 1469 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | ||
| 1470 | else => unreachable, | ||
| 1471 | }); | ||
| 1463 | _ = try self.addInst(.{ | 1472 | _ = try self.addInst(.{ |
| 1464 | .tag = tag[1], | 1473 | .tag = tag[1], |
| 1465 | .ops = switch (m) { | 1474 | .ops = switch (m) { |
| ... | @@ -1475,17 +1484,9 @@ fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immed | ... | @@ -1475,17 +1484,9 @@ fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immed |
| 1475 | }, | 1484 | }, |
| 1476 | .data = .{ .x = .{ | 1485 | .data = .{ .x = .{ |
| 1477 | .fixes = tag[0], | 1486 | .fixes = tag[0], |
| 1478 | .payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) { | 1487 | .payload = payload, |
| 1479 | .signed => |s| @bitCast(u32, s), | ||
| 1480 | .unsigned => |u| @intCast(u32, u), | ||
| 1481 | } }), | ||
| 1482 | } }, | 1488 | } }, |
| 1483 | }); | 1489 | }); |
| 1484 | _ = switch (m) { | ||
| 1485 | .sib => try self.addExtra(Mir.MemorySib.encode(m)), | ||
| 1486 | .rip => try self.addExtra(Mir.MemoryRip.encode(m)), | ||
| 1487 | else => unreachable, | ||
| 1488 | }; | ||
| 1489 | } | 1490 | } |
| 1490 | 1491 | ||
| 1491 | fn asmMemoryRegisterRegister( | 1492 | fn asmMemoryRegisterRegister( |
| ... | @@ -1549,7 +1550,9 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1549,7 +1550,9 @@ fn gen(self: *Self) InnerError!void { |
| 1549 | const backpatch_push_callee_preserved_regs = try self.asmPlaceholder(); | 1550 | const backpatch_push_callee_preserved_regs = try self.asmPlaceholder(); |
| 1550 | try self.asmRegisterRegister(.{ ._, .mov }, .rbp, .rsp); | 1551 | try self.asmRegisterRegister(.{ ._, .mov }, .rbp, .rsp); |
| 1551 | const backpatch_frame_align = try self.asmPlaceholder(); | 1552 | const backpatch_frame_align = try self.asmPlaceholder(); |
| 1553 | const backpatch_frame_align_extra = try self.asmPlaceholder(); | ||
| 1552 | const backpatch_stack_alloc = try self.asmPlaceholder(); | 1554 | const backpatch_stack_alloc = try self.asmPlaceholder(); |
| 1555 | const backpatch_stack_alloc_extra = try self.asmPlaceholder(); | ||
| 1553 | 1556 | ||
| 1554 | switch (self.ret_mcv.long) { | 1557 | switch (self.ret_mcv.long) { |
| 1555 | .none, .unreach => {}, | 1558 | .none, .unreach => {}, |
| ... | @@ -1598,24 +1601,67 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -1598,24 +1601,67 @@ fn gen(self: *Self) InnerError!void { |
| 1598 | const need_stack_adjust = frame_layout.stack_adjust > 0; | 1601 | const need_stack_adjust = frame_layout.stack_adjust > 0; |
| 1599 | const need_save_reg = frame_layout.save_reg_list.count() > 0; | 1602 | const need_save_reg = frame_layout.save_reg_list.count() > 0; |
| 1600 | if (need_frame_align) { | 1603 | if (need_frame_align) { |
| 1604 | const page_align = @as(u32, math.maxInt(u32)) << 12; | ||
| 1601 | self.mir_instructions.set(backpatch_frame_align, .{ | 1605 | self.mir_instructions.set(backpatch_frame_align, .{ |
| 1602 | .tag = .@"and", | 1606 | .tag = .@"and", |
| 1603 | .ops = .ri_s, | 1607 | .ops = .ri_s, |
| 1604 | .data = .{ .ri = .{ | 1608 | .data = .{ .ri = .{ |
| 1605 | .r1 = .rsp, | 1609 | .r1 = .rsp, |
| 1606 | .i = frame_layout.stack_mask, | 1610 | .i = @max(frame_layout.stack_mask, page_align), |
| 1607 | } }, | 1611 | } }, |
| 1608 | }); | 1612 | }); |
| 1613 | if (frame_layout.stack_mask < page_align) { | ||
| 1614 | self.mir_instructions.set(backpatch_frame_align_extra, .{ | ||
| 1615 | .tag = .pseudo, | ||
| 1616 | .ops = .pseudo_probe_align_ri_s, | ||
| 1617 | .data = .{ .ri = .{ | ||
| 1618 | .r1 = .rsp, | ||
| 1619 | .i = ~frame_layout.stack_mask & page_align, | ||
| 1620 | } }, | ||
| 1621 | }); | ||
| 1622 | } | ||
| 1609 | } | 1623 | } |
| 1610 | if (need_stack_adjust) { | 1624 | if (need_stack_adjust) { |
| 1611 | self.mir_instructions.set(backpatch_stack_alloc, .{ | 1625 | const page_size: u32 = 1 << 12; |
| 1612 | .tag = .sub, | 1626 | if (frame_layout.stack_adjust <= page_size) { |
| 1613 | .ops = .ri_s, | 1627 | self.mir_instructions.set(backpatch_stack_alloc, .{ |
| 1614 | .data = .{ .ri = .{ | 1628 | .tag = .sub, |
| 1615 | .r1 = .rsp, | 1629 | .ops = .ri_s, |
| 1616 | .i = frame_layout.stack_adjust, | 1630 | .data = .{ .ri = .{ |
| 1617 | } }, | 1631 | .r1 = .rsp, |
| 1618 | }); | 1632 | .i = frame_layout.stack_adjust, |
| 1633 | } }, | ||
| 1634 | }); | ||
| 1635 | } else if (frame_layout.stack_adjust < | ||
| 1636 | page_size * Lower.pseudo_probe_adjust_unrolled_max_insts) | ||
| 1637 | { | ||
| 1638 | self.mir_instructions.set(backpatch_stack_alloc, .{ | ||
| 1639 | .tag = .pseudo, | ||
| 1640 | .ops = .pseudo_probe_adjust_unrolled_ri_s, | ||
| 1641 | .data = .{ .ri = .{ | ||
| 1642 | .r1 = .rsp, | ||
| 1643 | .i = frame_layout.stack_adjust, | ||
| 1644 | } }, | ||
| 1645 | }); | ||
| 1646 | } else { | ||
| 1647 | self.mir_instructions.set(backpatch_stack_alloc, .{ | ||
| 1648 | .tag = .pseudo, | ||
| 1649 | .ops = .pseudo_probe_adjust_setup_rri_s, | ||
| 1650 | .data = .{ .rri = .{ | ||
| 1651 | .r1 = .rsp, | ||
| 1652 | .r2 = .rax, | ||
| 1653 | .i = frame_layout.stack_adjust, | ||
| 1654 | } }, | ||
| 1655 | }); | ||
| 1656 | self.mir_instructions.set(backpatch_stack_alloc_extra, .{ | ||
| 1657 | .tag = .pseudo, | ||
| 1658 | .ops = .pseudo_probe_adjust_loop_rr, | ||
| 1659 | .data = .{ .rr = .{ | ||
| 1660 | .r1 = .rsp, | ||
| 1661 | .r2 = .rax, | ||
| 1662 | } }, | ||
| 1663 | }); | ||
| 1664 | } | ||
| 1619 | } | 1665 | } |
| 1620 | if (need_frame_align or need_stack_adjust) { | 1666 | if (need_frame_align or need_stack_adjust) { |
| 1621 | self.mir_instructions.set(backpatch_stack_dealloc, .{ | 1667 | self.mir_instructions.set(backpatch_stack_dealloc, .{ |
| ... | @@ -2215,11 +2261,11 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b | ... | @@ -2215,11 +2261,11 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b |
| 2215 | }, | 2261 | }, |
| 2216 | .Vector => switch (ty.childType().zigTypeTag()) { | 2262 | .Vector => switch (ty.childType().zigTypeTag()) { |
| 2217 | .Float => switch (ty.childType().floatBits(self.target.*)) { | 2263 | .Float => switch (ty.childType().floatBits(self.target.*)) { |
| 2218 | 16, 32, 64 => if (self.hasFeature(.avx)) 32 else 16, | 2264 | 16, 32, 64, 128 => if (self.hasFeature(.avx)) 32 else 16, |
| 2219 | 80, 128 => break :need_mem, | 2265 | 80 => break :need_mem, |
| 2220 | else => unreachable, | 2266 | else => unreachable, |
| 2221 | }, | 2267 | }, |
| 2222 | else => break :need_mem, | 2268 | else => if (self.hasFeature(.avx)) 32 else 16, |
| 2223 | }, | 2269 | }, |
| 2224 | else => 8, | 2270 | else => 8, |
| 2225 | })) { | 2271 | })) { |
| ... | @@ -2455,12 +2501,12 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2455,12 +2501,12 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 2455 | } | 2501 | } |
| 2456 | } else if (src_bits == 64 and dst_bits == 32) { | 2502 | } else if (src_bits == 64 and dst_bits == 32) { |
| 2457 | if (self.hasFeature(.avx)) if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( | 2503 | if (self.hasFeature(.avx)) if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( |
| 2458 | .{ .v_, .cvtsd2ss }, | 2504 | .{ .v_ss, .cvtsd2 }, |
| 2459 | dst_reg, | 2505 | dst_reg, |
| 2460 | dst_reg, | 2506 | dst_reg, |
| 2461 | src_mcv.mem(.qword), | 2507 | src_mcv.mem(.qword), |
| 2462 | ) else try self.asmRegisterRegisterRegister( | 2508 | ) else try self.asmRegisterRegisterRegister( |
| 2463 | .{ .v_, .cvtsd2ss }, | 2509 | .{ .v_ss, .cvtsd2 }, |
| 2464 | dst_reg, | 2510 | dst_reg, |
| 2465 | dst_reg, | 2511 | dst_reg, |
| 2466 | (if (src_mcv.isRegister()) | 2512 | (if (src_mcv.isRegister()) |
| ... | @@ -2468,11 +2514,11 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2468,11 +2514,11 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 2468 | else | 2514 | else |
| 2469 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), | 2515 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), |
| 2470 | ) else if (src_mcv.isMemory()) try self.asmRegisterMemory( | 2516 | ) else if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 2471 | .{ ._, .cvtsd2ss }, | 2517 | .{ ._ss, .cvtsd2 }, |
| 2472 | dst_reg, | 2518 | dst_reg, |
| 2473 | src_mcv.mem(.qword), | 2519 | src_mcv.mem(.qword), |
| 2474 | ) else try self.asmRegisterRegister( | 2520 | ) else try self.asmRegisterRegister( |
| 2475 | .{ ._, .cvtsd2ss }, | 2521 | .{ ._ss, .cvtsd2 }, |
| 2476 | dst_reg, | 2522 | dst_reg, |
| 2477 | (if (src_mcv.isRegister()) | 2523 | (if (src_mcv.isRegister()) |
| 2478 | src_mcv.getReg().? | 2524 | src_mcv.getReg().? |
| ... | @@ -2506,22 +2552,22 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2506,22 +2552,22 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 2506 | src_mcv.getReg().? | 2552 | src_mcv.getReg().? |
| 2507 | else | 2553 | else |
| 2508 | try self.copyToTmpRegister(src_ty, src_mcv); | 2554 | try self.copyToTmpRegister(src_ty, src_mcv); |
| 2509 | try self.asmRegisterRegister(.{ .v_, .cvtph2ps }, dst_reg, mat_src_reg.to128()); | 2555 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, mat_src_reg.to128()); |
| 2510 | switch (dst_bits) { | 2556 | switch (dst_bits) { |
| 2511 | 32 => {}, | 2557 | 32 => {}, |
| 2512 | 64 => try self.asmRegisterRegisterRegister(.{ .v_, .cvtss2sd }, dst_reg, dst_reg, dst_reg), | 2558 | 64 => try self.asmRegisterRegisterRegister(.{ .v_sd, .cvtss2 }, dst_reg, dst_reg, dst_reg), |
| 2513 | else => return self.fail("TODO implement airFpext from {} to {}", .{ | 2559 | else => return self.fail("TODO implement airFpext from {} to {}", .{ |
| 2514 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), | 2560 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), |
| 2515 | }), | 2561 | }), |
| 2516 | } | 2562 | } |
| 2517 | } else if (src_bits == 32 and dst_bits == 64) { | 2563 | } else if (src_bits == 32 and dst_bits == 64) { |
| 2518 | if (self.hasFeature(.avx)) if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( | 2564 | if (self.hasFeature(.avx)) if (src_mcv.isMemory()) try self.asmRegisterRegisterMemory( |
| 2519 | .{ .v_, .cvtss2sd }, | 2565 | .{ .v_sd, .cvtss2 }, |
| 2520 | dst_reg, | 2566 | dst_reg, |
| 2521 | dst_reg, | 2567 | dst_reg, |
| 2522 | src_mcv.mem(.dword), | 2568 | src_mcv.mem(.dword), |
| 2523 | ) else try self.asmRegisterRegisterRegister( | 2569 | ) else try self.asmRegisterRegisterRegister( |
| 2524 | .{ .v_, .cvtss2sd }, | 2570 | .{ .v_sd, .cvtss2 }, |
| 2525 | dst_reg, | 2571 | dst_reg, |
| 2526 | dst_reg, | 2572 | dst_reg, |
| 2527 | (if (src_mcv.isRegister()) | 2573 | (if (src_mcv.isRegister()) |
| ... | @@ -2529,11 +2575,11 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2529,11 +2575,11 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 2529 | else | 2575 | else |
| 2530 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), | 2576 | try self.copyToTmpRegister(src_ty, src_mcv)).to128(), |
| 2531 | ) else if (src_mcv.isMemory()) try self.asmRegisterMemory( | 2577 | ) else if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 2532 | .{ ._, .cvtss2sd }, | 2578 | .{ ._sd, .cvtss2 }, |
| 2533 | dst_reg, | 2579 | dst_reg, |
| 2534 | src_mcv.mem(.dword), | 2580 | src_mcv.mem(.dword), |
| 2535 | ) else try self.asmRegisterRegister( | 2581 | ) else try self.asmRegisterRegister( |
| 2536 | .{ ._, .cvtss2sd }, | 2582 | .{ ._sd, .cvtss2 }, |
| 2537 | dst_reg, | 2583 | dst_reg, |
| 2538 | (if (src_mcv.isRegister()) | 2584 | (if (src_mcv.isRegister()) |
| 2539 | src_mcv.getReg().? | 2585 | src_mcv.getReg().? |
| ... | @@ -2754,8 +2800,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2754,8 +2800,10 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 2754 | const result = result: { | 2800 | const result = result: { |
| 2755 | const tag = self.air.instructions.items(.tag)[inst]; | 2801 | const tag = self.air.instructions.items(.tag)[inst]; |
| 2756 | const dst_ty = self.air.typeOfIndex(inst); | 2802 | const dst_ty = self.air.typeOfIndex(inst); |
| 2757 | if (dst_ty.zigTypeTag() == .Float) | 2803 | switch (dst_ty.zigTypeTag()) { |
| 2758 | break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); | 2804 | .Float, .Vector => break :result try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs), |
| 2805 | else => {}, | ||
| 2806 | } | ||
| 2759 | 2807 | ||
| 2760 | const dst_info = dst_ty.intInfo(self.target.*); | 2808 | const dst_info = dst_ty.intInfo(self.target.*); |
| 2761 | var src_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dst_info.signedness) { | 2809 | var src_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dst_info.signedness) { |
| ... | @@ -3421,14 +3469,17 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3421,14 +3469,17 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 3421 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); | 3469 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); |
| 3422 | } | 3470 | } |
| 3423 | 3471 | ||
| 3424 | const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | 3472 | const dst_mcv: MCValue = if (src_mcv.isRegister() and |
| 3473 | self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | ||
| 3425 | src_mcv | 3474 | src_mcv |
| 3475 | else if (self.liveness.isUnused(inst)) | ||
| 3476 | .{ .register = try self.copyToTmpRegister(dst_ty, src_mcv) } | ||
| 3426 | else | 3477 | else |
| 3427 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); | 3478 | try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); |
| 3428 | 3479 | ||
| 3429 | const pl_ty = dst_ty.childType(); | 3480 | const pl_ty = dst_ty.childType(); |
| 3430 | const pl_abi_size = @intCast(i32, pl_ty.abiSize(self.target.*)); | 3481 | const pl_abi_size = @intCast(i32, pl_ty.abiSize(self.target.*)); |
| 3431 | try self.genSetMem(.{ .reg = dst_mcv.register }, pl_abi_size, Type.bool, .{ .immediate = 1 }); | 3482 | try self.genSetMem(.{ .reg = dst_mcv.getReg().? }, pl_abi_size, Type.bool, .{ .immediate = 1 }); |
| 3432 | break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv; | 3483 | break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv; |
| 3433 | }; | 3484 | }; |
| 3434 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 3485 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | @@ -4177,9 +4228,18 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4177,9 +4228,18 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 4177 | 4228 | ||
| 4178 | const src_bits = src_ty.bitSize(self.target.*); | 4229 | const src_bits = src_ty.bitSize(self.target.*); |
| 4179 | if (self.hasFeature(.lzcnt)) { | 4230 | if (self.hasFeature(.lzcnt)) { |
| 4180 | if (src_bits <= 64) { | 4231 | if (src_bits <= 8) { |
| 4232 | const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv); | ||
| 4233 | try self.truncateRegister(src_ty, wide_reg); | ||
| 4234 | try self.genBinOpMir(.{ ._, .lzcnt }, Type.u32, dst_mcv, .{ .register = wide_reg }); | ||
| 4235 | try self.genBinOpMir( | ||
| 4236 | .{ ._, .sub }, | ||
| 4237 | dst_ty, | ||
| 4238 | dst_mcv, | ||
| 4239 | .{ .immediate = 8 + self.regExtraBits(src_ty) }, | ||
| 4240 | ); | ||
| 4241 | } else if (src_bits <= 64) { | ||
| 4181 | try self.genBinOpMir(.{ ._, .lzcnt }, src_ty, dst_mcv, mat_src_mcv); | 4242 | try self.genBinOpMir(.{ ._, .lzcnt }, src_ty, dst_mcv, mat_src_mcv); |
| 4182 | |||
| 4183 | const extra_bits = self.regExtraBits(src_ty); | 4243 | const extra_bits = self.regExtraBits(src_ty); |
| 4184 | if (extra_bits > 0) { | 4244 | if (extra_bits > 0) { |
| 4185 | try self.genBinOpMir(.{ ._, .sub }, dst_ty, dst_mcv, .{ .immediate = extra_bits }); | 4245 | try self.genBinOpMir(.{ ._, .sub }, dst_ty, dst_mcv, .{ .immediate = extra_bits }); |
| ... | @@ -4218,7 +4278,17 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4218,7 +4278,17 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 4218 | const imm_reg = try self.copyToTmpRegister(dst_ty, .{ | 4278 | const imm_reg = try self.copyToTmpRegister(dst_ty, .{ |
| 4219 | .immediate = src_bits ^ (src_bits - 1), | 4279 | .immediate = src_bits ^ (src_bits - 1), |
| 4220 | }); | 4280 | }); |
| 4221 | try self.genBinOpMir(.{ ._, .bsr }, src_ty, dst_mcv, mat_src_mcv); | 4281 | const imm_lock = self.register_manager.lockRegAssumeUnused(imm_reg); |
| 4282 | defer self.register_manager.unlockReg(imm_lock); | ||
| 4283 | |||
| 4284 | if (src_bits <= 8) { | ||
| 4285 | const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv); | ||
| 4286 | const wide_lock = self.register_manager.lockRegAssumeUnused(wide_reg); | ||
| 4287 | defer self.register_manager.unlockReg(wide_lock); | ||
| 4288 | |||
| 4289 | try self.truncateRegister(src_ty, wide_reg); | ||
| 4290 | try self.genBinOpMir(.{ ._, .bsr }, Type.u16, dst_mcv, .{ .register = wide_reg }); | ||
| 4291 | } else try self.genBinOpMir(.{ ._, .bsr }, src_ty, dst_mcv, mat_src_mcv); | ||
| 4222 | 4292 | ||
| 4223 | const cmov_abi_size = @max(@intCast(u32, dst_ty.abiSize(self.target.*)), 2); | 4293 | const cmov_abi_size = @max(@intCast(u32, dst_ty.abiSize(self.target.*)), 2); |
| 4224 | try self.asmCmovccRegisterRegister( | 4294 | try self.asmCmovccRegisterRegister( |
| ... | @@ -4232,7 +4302,20 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4232,7 +4302,20 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 4232 | const imm_reg = try self.copyToTmpRegister(dst_ty, .{ | 4302 | const imm_reg = try self.copyToTmpRegister(dst_ty, .{ |
| 4233 | .immediate = @as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - self.regBitSize(dst_ty)), | 4303 | .immediate = @as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - self.regBitSize(dst_ty)), |
| 4234 | }); | 4304 | }); |
| 4235 | try self.genBinOpMir(.{ ._, .bsr }, src_ty, dst_mcv, mat_src_mcv); | 4305 | const imm_lock = self.register_manager.lockRegAssumeUnused(imm_reg); |
| 4306 | defer self.register_manager.unlockReg(imm_lock); | ||
| 4307 | |||
| 4308 | const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv); | ||
| 4309 | const wide_lock = self.register_manager.lockRegAssumeUnused(wide_reg); | ||
| 4310 | defer self.register_manager.unlockReg(wide_lock); | ||
| 4311 | |||
| 4312 | try self.truncateRegister(src_ty, wide_reg); | ||
| 4313 | try self.genBinOpMir( | ||
| 4314 | .{ ._, .bsr }, | ||
| 4315 | if (src_bits <= 8) Type.u16 else src_ty, | ||
| 4316 | dst_mcv, | ||
| 4317 | .{ .register = wide_reg }, | ||
| 4318 | ); | ||
| 4236 | 4319 | ||
| 4237 | const cmov_abi_size = @max(@intCast(u32, dst_ty.abiSize(self.target.*)), 2); | 4320 | const cmov_abi_size = @max(@intCast(u32, dst_ty.abiSize(self.target.*)), 2); |
| 4238 | try self.asmCmovccRegisterRegister( | 4321 | try self.asmCmovccRegisterRegister( |
| ... | @@ -4274,24 +4357,25 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4274,24 +4357,25 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 4274 | 4357 | ||
| 4275 | if (self.hasFeature(.bmi)) { | 4358 | if (self.hasFeature(.bmi)) { |
| 4276 | if (src_bits <= 64) { | 4359 | if (src_bits <= 64) { |
| 4277 | const extra_bits = self.regExtraBits(src_ty); | 4360 | const extra_bits = self.regExtraBits(src_ty) + @as(u64, if (src_bits <= 8) 8 else 0); |
| 4361 | const wide_ty = if (src_bits <= 8) Type.u16 else src_ty; | ||
| 4278 | const masked_mcv = if (extra_bits > 0) masked: { | 4362 | const masked_mcv = if (extra_bits > 0) masked: { |
| 4279 | const tmp_mcv = tmp: { | 4363 | const tmp_mcv = tmp: { |
| 4280 | if (src_mcv.isImmediate() or self.liveness.operandDies(inst, 0)) | 4364 | if (src_mcv.isImmediate() or self.liveness.operandDies(inst, 0)) |
| 4281 | break :tmp src_mcv; | 4365 | break :tmp src_mcv; |
| 4282 | try self.genSetReg(dst_reg, src_ty, src_mcv); | 4366 | try self.genSetReg(dst_reg, wide_ty, src_mcv); |
| 4283 | break :tmp dst_mcv; | 4367 | break :tmp dst_mcv; |
| 4284 | }; | 4368 | }; |
| 4285 | try self.genBinOpMir( | 4369 | try self.genBinOpMir( |
| 4286 | .{ ._, .@"or" }, | 4370 | .{ ._, .@"or" }, |
| 4287 | src_ty, | 4371 | wide_ty, |
| 4288 | tmp_mcv, | 4372 | tmp_mcv, |
| 4289 | .{ .immediate = (@as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - extra_bits)) << | 4373 | .{ .immediate = (@as(u64, math.maxInt(u64)) >> @intCast(u6, 64 - extra_bits)) << |
| 4290 | @intCast(u6, src_bits) }, | 4374 | @intCast(u6, src_bits) }, |
| 4291 | ); | 4375 | ); |
| 4292 | break :masked tmp_mcv; | 4376 | break :masked tmp_mcv; |
| 4293 | } else mat_src_mcv; | 4377 | } else mat_src_mcv; |
| 4294 | try self.genBinOpMir(.{ ._, .tzcnt }, src_ty, dst_mcv, masked_mcv); | 4378 | try self.genBinOpMir(.{ ._, .tzcnt }, wide_ty, dst_mcv, masked_mcv); |
| 4295 | } else if (src_bits <= 128) { | 4379 | } else if (src_bits <= 128) { |
| 4296 | const tmp_reg = try self.register_manager.allocReg(null, gp); | 4380 | const tmp_reg = try self.register_manager.allocReg(null, gp); |
| 4297 | const tmp_mcv = MCValue{ .register = tmp_reg }; | 4381 | const tmp_mcv = MCValue{ .register = tmp_reg }; |
| ... | @@ -4320,7 +4404,17 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4320,7 +4404,17 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 4320 | return self.fail("TODO airCtz of {}", .{src_ty.fmt(self.bin_file.options.module.?)}); | 4404 | return self.fail("TODO airCtz of {}", .{src_ty.fmt(self.bin_file.options.module.?)}); |
| 4321 | 4405 | ||
| 4322 | const width_reg = try self.copyToTmpRegister(dst_ty, .{ .immediate = src_bits }); | 4406 | const width_reg = try self.copyToTmpRegister(dst_ty, .{ .immediate = src_bits }); |
| 4323 | try self.genBinOpMir(.{ ._, .bsf }, src_ty, dst_mcv, mat_src_mcv); | 4407 | const width_lock = self.register_manager.lockRegAssumeUnused(width_reg); |
| 4408 | defer self.register_manager.unlockReg(width_lock); | ||
| 4409 | |||
| 4410 | if (src_bits <= 8 or !math.isPowerOfTwo(src_bits)) { | ||
| 4411 | const wide_reg = try self.copyToTmpRegister(src_ty, mat_src_mcv); | ||
| 4412 | const wide_lock = self.register_manager.lockRegAssumeUnused(wide_reg); | ||
| 4413 | defer self.register_manager.unlockReg(wide_lock); | ||
| 4414 | |||
| 4415 | try self.truncateRegister(src_ty, wide_reg); | ||
| 4416 | try self.genBinOpMir(.{ ._, .bsf }, Type.u16, dst_mcv, .{ .register = wide_reg }); | ||
| 4417 | } else try self.genBinOpMir(.{ ._, .bsf }, src_ty, dst_mcv, mat_src_mcv); | ||
| 4324 | 4418 | ||
| 4325 | const cmov_abi_size = @max(@intCast(u32, dst_ty.abiSize(self.target.*)), 2); | 4419 | const cmov_abi_size = @max(@intCast(u32, dst_ty.abiSize(self.target.*)), 2); |
| 4326 | try self.asmCmovccRegisterRegister( | 4420 | try self.asmCmovccRegisterRegister( |
| ... | @@ -4632,61 +4726,136 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4632,61 +4726,136 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { |
| 4632 | } | 4726 | } |
| 4633 | 4727 | ||
| 4634 | fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void { | 4728 | fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void { |
| 4729 | const tag = self.air.instructions.items(.tag)[inst]; | ||
| 4635 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 4730 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 4636 | const ty = self.air.typeOf(un_op); | 4731 | const ty = self.air.typeOf(un_op); |
| 4637 | const ty_bits = ty.floatBits(self.target.*); | 4732 | const abi_size: u32 = switch (ty.abiSize(self.target.*)) { |
| 4733 | 1...16 => 16, | ||
| 4734 | 17...32 => 32, | ||
| 4735 | else => return self.fail("TODO implement airFloatSign for {}", .{ | ||
| 4736 | ty.fmt(self.bin_file.options.module.?), | ||
| 4737 | }), | ||
| 4738 | }; | ||
| 4739 | const scalar_bits = ty.scalarType().floatBits(self.target.*); | ||
| 4740 | |||
| 4741 | const src_mcv = try self.resolveInst(un_op); | ||
| 4742 | const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; | ||
| 4743 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 4744 | |||
| 4745 | const dst_mcv: MCValue = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv)) | ||
| 4746 | src_mcv | ||
| 4747 | else if (self.hasFeature(.avx)) | ||
| 4748 | .{ .register = try self.register_manager.allocReg(inst, sse) } | ||
| 4749 | else | ||
| 4750 | try self.copyToRegisterWithInstTracking(inst, ty, src_mcv); | ||
| 4751 | const dst_reg = dst_mcv.getReg().?; | ||
| 4752 | const dst_lock = self.register_manager.lockReg(dst_reg); | ||
| 4753 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 4638 | 4754 | ||
| 4639 | var arena = std.heap.ArenaAllocator.init(self.gpa); | 4755 | var arena = std.heap.ArenaAllocator.init(self.gpa); |
| 4640 | defer arena.deinit(); | 4756 | defer arena.deinit(); |
| 4641 | 4757 | ||
| 4642 | const ExpectedContents = union { | 4758 | const ExpectedContents = struct { |
| 4643 | f16: Value.Payload.Float_16, | 4759 | scalar: union { |
| 4644 | f32: Value.Payload.Float_32, | 4760 | i64: Value.Payload.I64, |
| 4645 | f64: Value.Payload.Float_64, | 4761 | big: struct { |
| 4646 | f80: Value.Payload.Float_80, | 4762 | limbs: [ |
| 4647 | f128: Value.Payload.Float_128, | 4763 | @max( |
| 4764 | std.math.big.int.Managed.default_capacity, | ||
| 4765 | std.math.big.int.calcTwosCompLimbCount(128), | ||
| 4766 | ) | ||
| 4767 | ]std.math.big.Limb, | ||
| 4768 | pl: Value.Payload.BigInt, | ||
| 4769 | }, | ||
| 4770 | }, | ||
| 4771 | repeated: Value.Payload.SubValue, | ||
| 4648 | }; | 4772 | }; |
| 4649 | var stack align(@alignOf(ExpectedContents)) = | 4773 | var stack align(@alignOf(ExpectedContents)) = |
| 4650 | std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); | 4774 | std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); |
| 4651 | 4775 | ||
| 4776 | var int_pl = Type.Payload.Bits{ | ||
| 4777 | .base = .{ .tag = .int_signed }, | ||
| 4778 | .data = scalar_bits, | ||
| 4779 | }; | ||
| 4652 | var vec_pl = Type.Payload.Array{ | 4780 | var vec_pl = Type.Payload.Array{ |
| 4653 | .base = .{ .tag = .vector }, | 4781 | .base = .{ .tag = .vector }, |
| 4654 | .data = .{ | 4782 | .data = .{ |
| 4655 | .len = @divExact(128, ty_bits), | 4783 | .len = @divExact(abi_size * 8, scalar_bits), |
| 4656 | .elem_type = ty, | 4784 | .elem_type = Type.initPayload(&int_pl.base), |
| 4657 | }, | 4785 | }, |
| 4658 | }; | 4786 | }; |
| 4659 | const vec_ty = Type.initPayload(&vec_pl.base); | 4787 | const vec_ty = Type.initPayload(&vec_pl.base); |
| 4660 | 4788 | const sign_val = switch (tag) { | |
| 4661 | var sign_pl = Value.Payload.SubValue{ | 4789 | .neg => try vec_ty.minInt(stack.get(), self.target.*), |
| 4662 | .base = .{ .tag = .repeated }, | 4790 | .fabs => try vec_ty.maxInt(stack.get(), self.target.*), |
| 4663 | .data = try Value.floatToValue(-0.0, stack.get(), ty, self.target.*), | 4791 | else => unreachable, |
| 4664 | }; | 4792 | }; |
| 4665 | const sign_val = Value.initPayload(&sign_pl.base); | ||
| 4666 | 4793 | ||
| 4667 | const sign_mcv = try self.genTypedValue(.{ .ty = vec_ty, .val = sign_val }); | 4794 | const sign_mcv = try self.genTypedValue(.{ .ty = vec_ty, .val = sign_val }); |
| 4668 | 4795 | const sign_mem = if (sign_mcv.isMemory()) | |
| 4669 | const src_mcv = try self.resolveInst(un_op); | 4796 | sign_mcv.mem(Memory.PtrSize.fromSize(abi_size)) |
| 4670 | const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv)) | ||
| 4671 | src_mcv | ||
| 4672 | else | 4797 | else |
| 4673 | try self.copyToRegisterWithInstTracking(inst, ty, src_mcv); | 4798 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 4674 | const dst_lock = self.register_manager.lockReg(dst_mcv.register); | 4799 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, sign_mcv.address()) }, |
| 4675 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 4800 | }); |
| 4676 | 4801 | ||
| 4677 | const tag = self.air.instructions.items(.tag)[inst]; | 4802 | if (self.hasFeature(.avx)) try self.asmRegisterRegisterMemory( |
| 4678 | try self.genBinOpMir(switch (ty_bits) { | 4803 | switch (scalar_bits) { |
| 4679 | // No point using an extra prefix byte for *pd which performs the same operation. | 4804 | 16, 128 => if (abi_size <= 16 or self.hasFeature(.avx2)) switch (tag) { |
| 4680 | 16, 32, 64, 128 => switch (tag) { | 4805 | .neg => .{ .vp_, .xor }, |
| 4681 | .neg => .{ ._ps, .xor }, | 4806 | .fabs => .{ .vp_, .@"and" }, |
| 4682 | .fabs => .{ ._ps, .andn }, | 4807 | else => unreachable, |
| 4808 | } else switch (tag) { | ||
| 4809 | .neg => .{ .v_ps, .xor }, | ||
| 4810 | .fabs => .{ .v_ps, .@"and" }, | ||
| 4811 | else => unreachable, | ||
| 4812 | }, | ||
| 4813 | 32 => switch (tag) { | ||
| 4814 | .neg => .{ .v_ps, .xor }, | ||
| 4815 | .fabs => .{ .v_ps, .@"and" }, | ||
| 4816 | else => unreachable, | ||
| 4817 | }, | ||
| 4818 | 64 => switch (tag) { | ||
| 4819 | .neg => .{ .v_pd, .xor }, | ||
| 4820 | .fabs => .{ .v_pd, .@"and" }, | ||
| 4821 | else => unreachable, | ||
| 4822 | }, | ||
| 4823 | 80 => return self.fail("TODO implement airFloatSign for {}", .{ | ||
| 4824 | ty.fmt(self.bin_file.options.module.?), | ||
| 4825 | }), | ||
| 4683 | else => unreachable, | 4826 | else => unreachable, |
| 4684 | }, | 4827 | }, |
| 4685 | 80 => return self.fail("TODO implement airFloatSign for {}", .{ | 4828 | registerAlias(dst_reg, abi_size), |
| 4686 | ty.fmt(self.bin_file.options.module.?), | 4829 | registerAlias(if (src_mcv.isRegister()) |
| 4687 | }), | 4830 | src_mcv.getReg().? |
| 4688 | else => unreachable, | 4831 | else |
| 4689 | }, vec_ty, dst_mcv, sign_mcv); | 4832 | try self.copyToTmpRegister(ty, src_mcv), abi_size), |
| 4833 | sign_mem, | ||
| 4834 | ) else try self.asmRegisterMemory( | ||
| 4835 | switch (scalar_bits) { | ||
| 4836 | 16, 128 => switch (tag) { | ||
| 4837 | .neg => .{ .p_, .xor }, | ||
| 4838 | .fabs => .{ .p_, .@"and" }, | ||
| 4839 | else => unreachable, | ||
| 4840 | }, | ||
| 4841 | 32 => switch (tag) { | ||
| 4842 | .neg => .{ ._ps, .xor }, | ||
| 4843 | .fabs => .{ ._ps, .@"and" }, | ||
| 4844 | else => unreachable, | ||
| 4845 | }, | ||
| 4846 | 64 => switch (tag) { | ||
| 4847 | .neg => .{ ._pd, .xor }, | ||
| 4848 | .fabs => .{ ._pd, .@"and" }, | ||
| 4849 | else => unreachable, | ||
| 4850 | }, | ||
| 4851 | 80 => return self.fail("TODO implement airFloatSign for {}", .{ | ||
| 4852 | ty.fmt(self.bin_file.options.module.?), | ||
| 4853 | }), | ||
| 4854 | else => unreachable, | ||
| 4855 | }, | ||
| 4856 | registerAlias(dst_reg, abi_size), | ||
| 4857 | sign_mem, | ||
| 4858 | ); | ||
| 4690 | return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none }); | 4859 | return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none }); |
| 4691 | } | 4860 | } |
| 4692 | 4861 | ||
| ... | @@ -4740,7 +4909,6 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4 | ... | @@ -4740,7 +4909,6 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4 |
| 4740 | })) |tag| tag else return self.fail("TODO implement genRound for {}", .{ | 4909 | })) |tag| tag else return self.fail("TODO implement genRound for {}", .{ |
| 4741 | ty.fmt(self.bin_file.options.module.?), | 4910 | ty.fmt(self.bin_file.options.module.?), |
| 4742 | }); | 4911 | }); |
| 4743 | |||
| 4744 | const abi_size = @intCast(u32, ty.abiSize(self.target.*)); | 4912 | const abi_size = @intCast(u32, ty.abiSize(self.target.*)); |
| 4745 | const dst_alias = registerAlias(dst_reg, abi_size); | 4913 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 4746 | switch (mir_tag[0]) { | 4914 | switch (mir_tag[0]) { |
| ... | @@ -4799,7 +4967,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4799,7 +4967,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 4799 | src_mcv.getReg().? | 4967 | src_mcv.getReg().? |
| 4800 | else | 4968 | else |
| 4801 | try self.copyToTmpRegister(ty, src_mcv); | 4969 | try self.copyToTmpRegister(ty, src_mcv); |
| 4802 | try self.asmRegisterRegister(.{ .v_, .cvtph2ps }, dst_reg, mat_src_reg.to128()); | 4970 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, mat_src_reg.to128()); |
| 4803 | try self.asmRegisterRegisterRegister(.{ .v_ss, .sqrt }, dst_reg, dst_reg, dst_reg); | 4971 | try self.asmRegisterRegisterRegister(.{ .v_ss, .sqrt }, dst_reg, dst_reg, dst_reg); |
| 4804 | try self.asmRegisterRegisterImmediate( | 4972 | try self.asmRegisterRegisterImmediate( |
| 4805 | .{ .v_, .cvtps2ph }, | 4973 | .{ .v_, .cvtps2ph }, |
| ... | @@ -4819,7 +4987,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4819,7 +4987,7 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 4819 | 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen()) { | 4987 | 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen()) { |
| 4820 | 1 => { | 4988 | 1 => { |
| 4821 | try self.asmRegisterRegister( | 4989 | try self.asmRegisterRegister( |
| 4822 | .{ .v_, .cvtph2ps }, | 4990 | .{ .v_ps, .cvtph2 }, |
| 4823 | dst_reg, | 4991 | dst_reg, |
| 4824 | (if (src_mcv.isRegister()) | 4992 | (if (src_mcv.isRegister()) |
| 4825 | src_mcv.getReg().? | 4993 | src_mcv.getReg().? |
| ... | @@ -4843,13 +5011,13 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4843,13 +5011,13 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 4843 | 2...8 => { | 5011 | 2...8 => { |
| 4844 | const wide_reg = registerAlias(dst_reg, abi_size * 2); | 5012 | const wide_reg = registerAlias(dst_reg, abi_size * 2); |
| 4845 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 5013 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 4846 | .{ .v_, .cvtph2ps }, | 5014 | .{ .v_ps, .cvtph2 }, |
| 4847 | wide_reg, | 5015 | wide_reg, |
| 4848 | src_mcv.mem(Memory.PtrSize.fromSize( | 5016 | src_mcv.mem(Memory.PtrSize.fromSize( |
| 4849 | @intCast(u32, @divExact(wide_reg.bitSize(), 16)), | 5017 | @intCast(u32, @divExact(wide_reg.bitSize(), 16)), |
| 4850 | )), | 5018 | )), |
| 4851 | ) else try self.asmRegisterRegister( | 5019 | ) else try self.asmRegisterRegister( |
| 4852 | .{ .v_, .cvtph2ps }, | 5020 | .{ .v_ps, .cvtph2 }, |
| 4853 | wide_reg, | 5021 | wide_reg, |
| 4854 | (if (src_mcv.isRegister()) | 5022 | (if (src_mcv.isRegister()) |
| 4855 | src_mcv.getReg().? | 5023 | src_mcv.getReg().? |
| ... | @@ -5256,64 +5424,24 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { | ... | @@ -5256,64 +5424,24 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 5256 | 5424 | ||
| 5257 | fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { | 5425 | fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 5258 | const ptr_field_ty = self.air.typeOfIndex(inst); | 5426 | const ptr_field_ty = self.air.typeOfIndex(inst); |
| 5259 | const mcv = try self.resolveInst(operand); | ||
| 5260 | const ptr_container_ty = self.air.typeOf(operand); | 5427 | const ptr_container_ty = self.air.typeOf(operand); |
| 5261 | const container_ty = ptr_container_ty.childType(); | 5428 | const container_ty = ptr_container_ty.childType(); |
| 5262 | const field_offset = switch (container_ty.containerLayout()) { | 5429 | const field_offset = @intCast(i32, switch (container_ty.containerLayout()) { |
| 5263 | .Auto, .Extern => @intCast(u32, container_ty.structFieldOffset(index, self.target.*)), | 5430 | .Auto, .Extern => container_ty.structFieldOffset(index, self.target.*), |
| 5264 | .Packed => if (container_ty.zigTypeTag() == .Struct and | 5431 | .Packed => if (container_ty.zigTypeTag() == .Struct and |
| 5265 | ptr_field_ty.ptrInfo().data.host_size == 0) | 5432 | ptr_field_ty.ptrInfo().data.host_size == 0) |
| 5266 | container_ty.packedStructFieldByteOffset(index, self.target.*) | 5433 | container_ty.packedStructFieldByteOffset(index, self.target.*) |
| 5267 | else | 5434 | else |
| 5268 | 0, | 5435 | 0, |
| 5269 | }; | 5436 | }); |
| 5270 | |||
| 5271 | const result: MCValue = result: { | ||
| 5272 | switch (mcv) { | ||
| 5273 | .load_frame, .lea_tlv, .load_tlv => { | ||
| 5274 | const offset_reg = try self.copyToTmpRegister(Type.usize, .{ | ||
| 5275 | .immediate = field_offset, | ||
| 5276 | }); | ||
| 5277 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); | ||
| 5278 | defer self.register_manager.unlockReg(offset_reg_lock); | ||
| 5279 | |||
| 5280 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, Type.usize, switch (mcv) { | ||
| 5281 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, | ||
| 5282 | else => mcv, | ||
| 5283 | }); | ||
| 5284 | try self.genBinOpMir(.{ ._, .add }, Type.usize, dst_mcv, .{ .register = offset_reg }); | ||
| 5285 | break :result dst_mcv; | ||
| 5286 | }, | ||
| 5287 | .indirect => |reg_off| break :result .{ .indirect = .{ | ||
| 5288 | .reg = reg_off.reg, | ||
| 5289 | .off = reg_off.off + @intCast(i32, field_offset), | ||
| 5290 | } }, | ||
| 5291 | .lea_frame => |frame_addr| break :result .{ .lea_frame = .{ | ||
| 5292 | .index = frame_addr.index, | ||
| 5293 | .off = frame_addr.off + @intCast(i32, field_offset), | ||
| 5294 | } }, | ||
| 5295 | .register, .register_offset => { | ||
| 5296 | const src_reg = mcv.getReg().?; | ||
| 5297 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); | ||
| 5298 | defer self.register_manager.unlockReg(src_lock); | ||
| 5299 | 5437 | ||
| 5300 | const dst_mcv: MCValue = if (self.reuseOperand(inst, operand, 0, mcv)) | 5438 | const src_mcv = try self.resolveInst(operand); |
| 5301 | mcv | 5439 | const dst_mcv = if (switch (src_mcv) { |
| 5302 | else | 5440 | .immediate, .lea_frame => true, |
| 5303 | .{ .register = try self.copyToTmpRegister(ptr_field_ty, mcv) }; | 5441 | .register, .register_offset => self.reuseOperand(inst, operand, 0, src_mcv), |
| 5304 | break :result .{ .register_offset = .{ | 5442 | else => false, |
| 5305 | .reg = dst_mcv.getReg().?, | 5443 | }) src_mcv else try self.copyToRegisterWithInstTracking(inst, ptr_field_ty, src_mcv); |
| 5306 | .off = switch (dst_mcv) { | 5444 | return dst_mcv.offset(field_offset); |
| 5307 | .register => 0, | ||
| 5308 | .register_offset => |reg_off| reg_off.off, | ||
| 5309 | else => unreachable, | ||
| 5310 | } + @intCast(i32, field_offset), | ||
| 5311 | } }; | ||
| 5312 | }, | ||
| 5313 | else => return self.fail("TODO implement fieldPtr for {}", .{mcv}), | ||
| 5314 | } | ||
| 5315 | }; | ||
| 5316 | return result; | ||
| 5317 | } | 5445 | } |
| 5318 | 5446 | ||
| 5319 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | 5447 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -5324,8 +5452,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5324,8 +5452,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5324 | const index = extra.field_index; | 5452 | const index = extra.field_index; |
| 5325 | 5453 | ||
| 5326 | const container_ty = self.air.typeOf(operand); | 5454 | const container_ty = self.air.typeOf(operand); |
| 5455 | const container_rc = regClassForType(container_ty); | ||
| 5327 | const field_ty = container_ty.structFieldType(index); | 5456 | const field_ty = container_ty.structFieldType(index); |
| 5328 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) break :result .none; | 5457 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) break :result .none; |
| 5458 | const field_rc = regClassForType(field_ty); | ||
| 5459 | const field_is_gp = field_rc.supersetOf(gp); | ||
| 5329 | 5460 | ||
| 5330 | const src_mcv = try self.resolveInst(operand); | 5461 | const src_mcv = try self.resolveInst(operand); |
| 5331 | const field_off = switch (container_ty.containerLayout()) { | 5462 | const field_off = switch (container_ty.containerLayout()) { |
| ... | @@ -5358,7 +5489,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5358,7 +5489,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5358 | return self.fail("TODO implement struct_field_val with large packed field", .{}); | 5489 | return self.fail("TODO implement struct_field_val with large packed field", .{}); |
| 5359 | } | 5490 | } |
| 5360 | 5491 | ||
| 5361 | const dst_reg = try self.register_manager.allocReg(inst, gp); | 5492 | const dst_reg = try self.register_manager.allocReg(if (field_is_gp) inst else null, gp); |
| 5362 | const field_extra_bits = self.regExtraBits(field_ty); | 5493 | const field_extra_bits = self.regExtraBits(field_ty); |
| 5363 | const load_abi_size = | 5494 | const load_abi_size = |
| 5364 | if (field_bit_off < field_extra_bits) field_abi_size else field_abi_size * 2; | 5495 | if (field_bit_off < field_extra_bits) field_abi_size else field_abi_size * 2; |
| ... | @@ -5409,30 +5540,23 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5409,30 +5540,23 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5409 | if (field_extra_bits > 0) try self.truncateRegister(field_ty, dst_reg); | 5540 | if (field_extra_bits > 0) try self.truncateRegister(field_ty, dst_reg); |
| 5410 | 5541 | ||
| 5411 | const dst_mcv = MCValue{ .register = dst_reg }; | 5542 | const dst_mcv = MCValue{ .register = dst_reg }; |
| 5412 | const dst_rc = regClassForType(field_ty); | 5543 | break :result if (field_is_gp) |
| 5413 | if (dst_rc.eql(gp)) break :result dst_mcv; | 5544 | dst_mcv |
| 5414 | 5545 | else | |
| 5415 | const result_reg = try self.register_manager.allocReg(inst, dst_rc); | 5546 | try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv); |
| 5416 | try self.genSetReg(result_reg, field_ty, dst_mcv); | ||
| 5417 | break :result .{ .register = result_reg }; | ||
| 5418 | }, | 5547 | }, |
| 5419 | .register => |reg| { | 5548 | .register => |reg| { |
| 5420 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); | 5549 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); |
| 5421 | defer self.register_manager.unlockReg(reg_lock); | 5550 | defer self.register_manager.unlockReg(reg_lock); |
| 5422 | 5551 | ||
| 5423 | const dst_mcv = if (self.reuseOperand(inst, operand, 0, src_mcv)) | 5552 | const dst_reg = if (src_mcv.isRegister() and field_rc.supersetOf(container_rc) and |
| 5424 | src_mcv | 5553 | self.reuseOperand(inst, operand, 0, src_mcv)) |
| 5554 | src_mcv.getReg().? | ||
| 5425 | else | 5555 | else |
| 5426 | try self.copyToRegisterWithInstTracking( | 5556 | try self.copyToTmpRegister(Type.usize, .{ .register = reg.to64() }); |
| 5427 | inst, | 5557 | const dst_mcv = MCValue{ .register = dst_reg }; |
| 5428 | Type.usize, | 5558 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 5429 | .{ .register = reg.to64() }, | 5559 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 5430 | ); | ||
| 5431 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { | ||
| 5432 | .register => |a_reg| self.register_manager.lockReg(a_reg), | ||
| 5433 | else => null, | ||
| 5434 | }; | ||
| 5435 | defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock); | ||
| 5436 | 5560 | ||
| 5437 | // Shift by struct_field_offset. | 5561 | // Shift by struct_field_offset. |
| 5438 | try self.genShiftBinOpMir( | 5562 | try self.genShiftBinOpMir( |
| ... | @@ -5459,7 +5583,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5459,7 +5583,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5459 | registerAlias(dst_mcv.register, field_byte_size), | 5583 | registerAlias(dst_mcv.register, field_byte_size), |
| 5460 | ); | 5584 | ); |
| 5461 | } | 5585 | } |
| 5462 | break :result dst_mcv; | 5586 | |
| 5587 | break :result if (field_rc.supersetOf(gp)) | ||
| 5588 | dst_mcv | ||
| 5589 | else | ||
| 5590 | try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv); | ||
| 5463 | }, | 5591 | }, |
| 5464 | .register_overflow => |ro| { | 5592 | .register_overflow => |ro| { |
| 5465 | switch (index) { | 5593 | switch (index) { |
| ... | @@ -6339,12 +6467,13 @@ fn genBinOp( | ... | @@ -6339,12 +6467,13 @@ fn genBinOp( |
| 6339 | else | 6467 | else |
| 6340 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | 6468 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), |
| 6341 | ); | 6469 | ); |
| 6342 | try self.asmRegisterRegister(.{ .v_, .cvtph2ps }, dst_reg, dst_reg); | 6470 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); |
| 6343 | try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg); | 6471 | try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg); |
| 6344 | try self.asmRegisterRegisterRegister( | 6472 | try self.asmRegisterRegisterRegister( |
| 6345 | switch (air_tag) { | 6473 | switch (air_tag) { |
| 6346 | .add => .{ .v_ss, .add }, | 6474 | .add => .{ .v_ss, .add }, |
| 6347 | .sub => .{ .v_ss, .sub }, | 6475 | .sub => .{ .v_ss, .sub }, |
| 6476 | .mul => .{ .v_ss, .mul }, | ||
| 6348 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div }, | 6477 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div }, |
| 6349 | .max => .{ .v_ss, .max }, | 6478 | .max => .{ .v_ss, .max }, |
| 6350 | .min => .{ .v_ss, .max }, | 6479 | .min => .{ .v_ss, .max }, |
| ... | @@ -6393,6 +6522,234 @@ fn genBinOp( | ... | @@ -6393,6 +6522,234 @@ fn genBinOp( |
| 6393 | }, | 6522 | }, |
| 6394 | .Vector => switch (lhs_ty.childType().zigTypeTag()) { | 6523 | .Vector => switch (lhs_ty.childType().zigTypeTag()) { |
| 6395 | else => null, | 6524 | else => null, |
| 6525 | .Int => switch (lhs_ty.childType().intInfo(self.target.*).bits) { | ||
| 6526 | 8 => switch (lhs_ty.vectorLen()) { | ||
| 6527 | 1...16 => switch (air_tag) { | ||
| 6528 | .add, | ||
| 6529 | .addwrap, | ||
| 6530 | => if (self.hasFeature(.avx)) .{ .vp_b, .add } else .{ .p_b, .add }, | ||
| 6531 | .sub, | ||
| 6532 | .subwrap, | ||
| 6533 | => if (self.hasFeature(.avx)) .{ .vp_b, .sub } else .{ .p_b, .sub }, | ||
| 6534 | .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" }, | ||
| 6535 | .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" }, | ||
| 6536 | .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor }, | ||
| 6537 | .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) { | ||
| 6538 | .signed => if (self.hasFeature(.avx)) | ||
| 6539 | .{ .vp_b, .mins } | ||
| 6540 | else if (self.hasFeature(.sse4_1)) | ||
| 6541 | .{ .p_b, .mins } | ||
| 6542 | else | ||
| 6543 | null, | ||
| 6544 | .unsigned => if (self.hasFeature(.avx)) | ||
| 6545 | .{ .vp_b, .minu } | ||
| 6546 | else if (self.hasFeature(.sse4_1)) | ||
| 6547 | .{ .p_b, .minu } | ||
| 6548 | else | ||
| 6549 | null, | ||
| 6550 | }, | ||
| 6551 | .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) { | ||
| 6552 | .signed => if (self.hasFeature(.avx)) | ||
| 6553 | .{ .vp_b, .maxs } | ||
| 6554 | else if (self.hasFeature(.sse4_1)) | ||
| 6555 | .{ .p_b, .maxs } | ||
| 6556 | else | ||
| 6557 | null, | ||
| 6558 | .unsigned => if (self.hasFeature(.avx)) | ||
| 6559 | .{ .vp_b, .maxu } | ||
| 6560 | else if (self.hasFeature(.sse4_1)) | ||
| 6561 | .{ .p_b, .maxu } | ||
| 6562 | else | ||
| 6563 | null, | ||
| 6564 | }, | ||
| 6565 | else => null, | ||
| 6566 | }, | ||
| 6567 | 17...32 => switch (air_tag) { | ||
| 6568 | .add, | ||
| 6569 | .addwrap, | ||
| 6570 | => if (self.hasFeature(.avx2)) .{ .vp_b, .add } else null, | ||
| 6571 | .sub, | ||
| 6572 | .subwrap, | ||
| 6573 | => if (self.hasFeature(.avx2)) .{ .vp_b, .sub } else null, | ||
| 6574 | .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null, | ||
| 6575 | .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null, | ||
| 6576 | .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null, | ||
| 6577 | .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) { | ||
| 6578 | .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .mins } else null, | ||
| 6579 | .unsigned => if (self.hasFeature(.avx)) .{ .vp_b, .minu } else null, | ||
| 6580 | }, | ||
| 6581 | .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) { | ||
| 6582 | .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .maxs } else null, | ||
| 6583 | .unsigned => if (self.hasFeature(.avx2)) .{ .vp_b, .maxu } else null, | ||
| 6584 | }, | ||
| 6585 | else => null, | ||
| 6586 | }, | ||
| 6587 | else => null, | ||
| 6588 | }, | ||
| 6589 | 16 => switch (lhs_ty.vectorLen()) { | ||
| 6590 | 1...8 => switch (air_tag) { | ||
| 6591 | .add, | ||
| 6592 | .addwrap, | ||
| 6593 | => if (self.hasFeature(.avx)) .{ .vp_w, .add } else .{ .p_w, .add }, | ||
| 6594 | .sub, | ||
| 6595 | .subwrap, | ||
| 6596 | => if (self.hasFeature(.avx)) .{ .vp_w, .sub } else .{ .p_w, .sub }, | ||
| 6597 | .mul, | ||
| 6598 | .mulwrap, | ||
| 6599 | => if (self.hasFeature(.avx)) .{ .vp_w, .mull } else .{ .p_d, .mull }, | ||
| 6600 | .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" }, | ||
| 6601 | .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" }, | ||
| 6602 | .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor }, | ||
| 6603 | .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) { | ||
| 6604 | .signed => if (self.hasFeature(.avx)) | ||
| 6605 | .{ .vp_w, .mins } | ||
| 6606 | else | ||
| 6607 | .{ .p_w, .mins }, | ||
| 6608 | .unsigned => if (self.hasFeature(.avx)) | ||
| 6609 | .{ .vp_w, .minu } | ||
| 6610 | else | ||
| 6611 | .{ .p_w, .minu }, | ||
| 6612 | }, | ||
| 6613 | .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) { | ||
| 6614 | .signed => if (self.hasFeature(.avx)) | ||
| 6615 | .{ .vp_w, .maxs } | ||
| 6616 | else | ||
| 6617 | .{ .p_w, .maxs }, | ||
| 6618 | .unsigned => if (self.hasFeature(.avx)) | ||
| 6619 | .{ .vp_w, .maxu } | ||
| 6620 | else | ||
| 6621 | .{ .p_w, .maxu }, | ||
| 6622 | }, | ||
| 6623 | else => null, | ||
| 6624 | }, | ||
| 6625 | 9...16 => switch (air_tag) { | ||
| 6626 | .add, | ||
| 6627 | .addwrap, | ||
| 6628 | => if (self.hasFeature(.avx2)) .{ .vp_w, .add } else null, | ||
| 6629 | .sub, | ||
| 6630 | .subwrap, | ||
| 6631 | => if (self.hasFeature(.avx2)) .{ .vp_w, .sub } else null, | ||
| 6632 | .mul, | ||
| 6633 | .mulwrap, | ||
| 6634 | => if (self.hasFeature(.avx2)) .{ .vp_w, .mull } else null, | ||
| 6635 | .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null, | ||
| 6636 | .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null, | ||
| 6637 | .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null, | ||
| 6638 | .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) { | ||
| 6639 | .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .mins } else null, | ||
| 6640 | .unsigned => if (self.hasFeature(.avx)) .{ .vp_w, .minu } else null, | ||
| 6641 | }, | ||
| 6642 | .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) { | ||
| 6643 | .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .maxs } else null, | ||
| 6644 | .unsigned => if (self.hasFeature(.avx2)) .{ .vp_w, .maxu } else null, | ||
| 6645 | }, | ||
| 6646 | else => null, | ||
| 6647 | }, | ||
| 6648 | else => null, | ||
| 6649 | }, | ||
| 6650 | 32 => switch (lhs_ty.vectorLen()) { | ||
| 6651 | 1...4 => switch (air_tag) { | ||
| 6652 | .add, | ||
| 6653 | .addwrap, | ||
| 6654 | => if (self.hasFeature(.avx)) .{ .vp_d, .add } else .{ .p_d, .add }, | ||
| 6655 | .sub, | ||
| 6656 | .subwrap, | ||
| 6657 | => if (self.hasFeature(.avx)) .{ .vp_d, .sub } else .{ .p_d, .sub }, | ||
| 6658 | .mul, | ||
| 6659 | .mulwrap, | ||
| 6660 | => if (self.hasFeature(.avx)) | ||
| 6661 | .{ .vp_d, .mull } | ||
| 6662 | else if (self.hasFeature(.sse4_1)) | ||
| 6663 | .{ .p_d, .mull } | ||
| 6664 | else | ||
| 6665 | null, | ||
| 6666 | .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" }, | ||
| 6667 | .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" }, | ||
| 6668 | .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor }, | ||
| 6669 | .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) { | ||
| 6670 | .signed => if (self.hasFeature(.avx)) | ||
| 6671 | .{ .vp_d, .mins } | ||
| 6672 | else if (self.hasFeature(.sse4_1)) | ||
| 6673 | .{ .p_d, .mins } | ||
| 6674 | else | ||
| 6675 | null, | ||
| 6676 | .unsigned => if (self.hasFeature(.avx)) | ||
| 6677 | .{ .vp_d, .minu } | ||
| 6678 | else if (self.hasFeature(.sse4_1)) | ||
| 6679 | .{ .p_d, .minu } | ||
| 6680 | else | ||
| 6681 | null, | ||
| 6682 | }, | ||
| 6683 | .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) { | ||
| 6684 | .signed => if (self.hasFeature(.avx)) | ||
| 6685 | .{ .vp_d, .maxs } | ||
| 6686 | else if (self.hasFeature(.sse4_1)) | ||
| 6687 | .{ .p_d, .maxs } | ||
| 6688 | else | ||
| 6689 | null, | ||
| 6690 | .unsigned => if (self.hasFeature(.avx)) | ||
| 6691 | .{ .vp_d, .maxu } | ||
| 6692 | else if (self.hasFeature(.sse4_1)) | ||
| 6693 | .{ .p_d, .maxu } | ||
| 6694 | else | ||
| 6695 | null, | ||
| 6696 | }, | ||
| 6697 | else => null, | ||
| 6698 | }, | ||
| 6699 | 5...8 => switch (air_tag) { | ||
| 6700 | .add, | ||
| 6701 | .addwrap, | ||
| 6702 | => if (self.hasFeature(.avx2)) .{ .vp_d, .add } else null, | ||
| 6703 | .sub, | ||
| 6704 | .subwrap, | ||
| 6705 | => if (self.hasFeature(.avx2)) .{ .vp_d, .sub } else null, | ||
| 6706 | .mul, | ||
| 6707 | .mulwrap, | ||
| 6708 | => if (self.hasFeature(.avx2)) .{ .vp_d, .mull } else null, | ||
| 6709 | .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null, | ||
| 6710 | .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null, | ||
| 6711 | .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null, | ||
| 6712 | .min => switch (lhs_ty.childType().intInfo(self.target.*).signedness) { | ||
| 6713 | .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .mins } else null, | ||
| 6714 | .unsigned => if (self.hasFeature(.avx)) .{ .vp_d, .minu } else null, | ||
| 6715 | }, | ||
| 6716 | .max => switch (lhs_ty.childType().intInfo(self.target.*).signedness) { | ||
| 6717 | .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .maxs } else null, | ||
| 6718 | .unsigned => if (self.hasFeature(.avx2)) .{ .vp_d, .maxu } else null, | ||
| 6719 | }, | ||
| 6720 | else => null, | ||
| 6721 | }, | ||
| 6722 | else => null, | ||
| 6723 | }, | ||
| 6724 | 64 => switch (lhs_ty.vectorLen()) { | ||
| 6725 | 1...2 => switch (air_tag) { | ||
| 6726 | .add, | ||
| 6727 | .addwrap, | ||
| 6728 | => if (self.hasFeature(.avx)) .{ .vp_q, .add } else .{ .p_q, .add }, | ||
| 6729 | .sub, | ||
| 6730 | .subwrap, | ||
| 6731 | => if (self.hasFeature(.avx)) .{ .vp_q, .sub } else .{ .p_q, .sub }, | ||
| 6732 | .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" }, | ||
| 6733 | .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" }, | ||
| 6734 | .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor }, | ||
| 6735 | else => null, | ||
| 6736 | }, | ||
| 6737 | 3...4 => switch (air_tag) { | ||
| 6738 | .add, | ||
| 6739 | .addwrap, | ||
| 6740 | => if (self.hasFeature(.avx2)) .{ .vp_q, .add } else null, | ||
| 6741 | .sub, | ||
| 6742 | .subwrap, | ||
| 6743 | => if (self.hasFeature(.avx2)) .{ .vp_q, .sub } else null, | ||
| 6744 | .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null, | ||
| 6745 | .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null, | ||
| 6746 | .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null, | ||
| 6747 | else => null, | ||
| 6748 | }, | ||
| 6749 | else => null, | ||
| 6750 | }, | ||
| 6751 | else => null, | ||
| 6752 | }, | ||
| 6396 | .Float => switch (lhs_ty.childType().floatBits(self.target.*)) { | 6753 | .Float => switch (lhs_ty.childType().floatBits(self.target.*)) { |
| 6397 | 16 => if (self.hasFeature(.f16c)) switch (lhs_ty.vectorLen()) { | 6754 | 16 => if (self.hasFeature(.f16c)) switch (lhs_ty.vectorLen()) { |
| 6398 | 1 => { | 6755 | 1 => { |
| ... | @@ -6415,12 +6772,13 @@ fn genBinOp( | ... | @@ -6415,12 +6772,13 @@ fn genBinOp( |
| 6415 | else | 6772 | else |
| 6416 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | 6773 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), |
| 6417 | ); | 6774 | ); |
| 6418 | try self.asmRegisterRegister(.{ .v_, .cvtph2ps }, dst_reg, dst_reg); | 6775 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); |
| 6419 | try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg); | 6776 | try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp_reg, dst_reg); |
| 6420 | try self.asmRegisterRegisterRegister( | 6777 | try self.asmRegisterRegisterRegister( |
| 6421 | switch (air_tag) { | 6778 | switch (air_tag) { |
| 6422 | .add => .{ .v_ss, .add }, | 6779 | .add => .{ .v_ss, .add }, |
| 6423 | .sub => .{ .v_ss, .sub }, | 6780 | .sub => .{ .v_ss, .sub }, |
| 6781 | .mul => .{ .v_ss, .mul }, | ||
| 6424 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div }, | 6782 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ss, .div }, |
| 6425 | .max => .{ .v_ss, .max }, | 6783 | .max => .{ .v_ss, .max }, |
| 6426 | .min => .{ .v_ss, .max }, | 6784 | .min => .{ .v_ss, .max }, |
| ... | @@ -6457,7 +6815,7 @@ fn genBinOp( | ... | @@ -6457,7 +6815,7 @@ fn genBinOp( |
| 6457 | else | 6815 | else |
| 6458 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | 6816 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), |
| 6459 | ); | 6817 | ); |
| 6460 | try self.asmRegisterRegister(.{ .v_, .cvtph2ps }, dst_reg, dst_reg); | 6818 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); |
| 6461 | try self.asmRegisterRegisterRegister( | 6819 | try self.asmRegisterRegisterRegister( |
| 6462 | .{ .v_ps, .movhl }, | 6820 | .{ .v_ps, .movhl }, |
| 6463 | tmp_reg, | 6821 | tmp_reg, |
| ... | @@ -6468,6 +6826,7 @@ fn genBinOp( | ... | @@ -6468,6 +6826,7 @@ fn genBinOp( |
| 6468 | switch (air_tag) { | 6826 | switch (air_tag) { |
| 6469 | .add => .{ .v_ps, .add }, | 6827 | .add => .{ .v_ps, .add }, |
| 6470 | .sub => .{ .v_ps, .sub }, | 6828 | .sub => .{ .v_ps, .sub }, |
| 6829 | .mul => .{ .v_ps, .mul }, | ||
| 6471 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, | 6830 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, |
| 6472 | .max => .{ .v_ps, .max }, | 6831 | .max => .{ .v_ps, .max }, |
| 6473 | .min => .{ .v_ps, .max }, | 6832 | .min => .{ .v_ps, .max }, |
| ... | @@ -6490,13 +6849,13 @@ fn genBinOp( | ... | @@ -6490,13 +6849,13 @@ fn genBinOp( |
| 6490 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 6849 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 6491 | defer self.register_manager.unlockReg(tmp_lock); | 6850 | defer self.register_manager.unlockReg(tmp_lock); |
| 6492 | 6851 | ||
| 6493 | try self.asmRegisterRegister(.{ .v_, .cvtph2ps }, dst_reg, dst_reg); | 6852 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg, dst_reg); |
| 6494 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 6853 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 6495 | .{ .v_, .cvtph2ps }, | 6854 | .{ .v_ps, .cvtph2 }, |
| 6496 | tmp_reg, | 6855 | tmp_reg, |
| 6497 | src_mcv.mem(.qword), | 6856 | src_mcv.mem(.qword), |
| 6498 | ) else try self.asmRegisterRegister( | 6857 | ) else try self.asmRegisterRegister( |
| 6499 | .{ .v_, .cvtph2ps }, | 6858 | .{ .v_ps, .cvtph2 }, |
| 6500 | tmp_reg, | 6859 | tmp_reg, |
| 6501 | (if (src_mcv.isRegister()) | 6860 | (if (src_mcv.isRegister()) |
| 6502 | src_mcv.getReg().? | 6861 | src_mcv.getReg().? |
| ... | @@ -6507,6 +6866,7 @@ fn genBinOp( | ... | @@ -6507,6 +6866,7 @@ fn genBinOp( |
| 6507 | switch (air_tag) { | 6866 | switch (air_tag) { |
| 6508 | .add => .{ .v_ps, .add }, | 6867 | .add => .{ .v_ps, .add }, |
| 6509 | .sub => .{ .v_ps, .sub }, | 6868 | .sub => .{ .v_ps, .sub }, |
| 6869 | .mul => .{ .v_ps, .mul }, | ||
| 6510 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, | 6870 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, |
| 6511 | .max => .{ .v_ps, .max }, | 6871 | .max => .{ .v_ps, .max }, |
| 6512 | .min => .{ .v_ps, .max }, | 6872 | .min => .{ .v_ps, .max }, |
| ... | @@ -6529,13 +6889,13 @@ fn genBinOp( | ... | @@ -6529,13 +6889,13 @@ fn genBinOp( |
| 6529 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 6889 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 6530 | defer self.register_manager.unlockReg(tmp_lock); | 6890 | defer self.register_manager.unlockReg(tmp_lock); |
| 6531 | 6891 | ||
| 6532 | try self.asmRegisterRegister(.{ .v_, .cvtph2ps }, dst_reg.to256(), dst_reg); | 6892 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, dst_reg.to256(), dst_reg); |
| 6533 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | 6893 | if (src_mcv.isMemory()) try self.asmRegisterMemory( |
| 6534 | .{ .v_, .cvtph2ps }, | 6894 | .{ .v_ps, .cvtph2 }, |
| 6535 | tmp_reg, | 6895 | tmp_reg, |
| 6536 | src_mcv.mem(.xword), | 6896 | src_mcv.mem(.xword), |
| 6537 | ) else try self.asmRegisterRegister( | 6897 | ) else try self.asmRegisterRegister( |
| 6538 | .{ .v_, .cvtph2ps }, | 6898 | .{ .v_ps, .cvtph2 }, |
| 6539 | tmp_reg, | 6899 | tmp_reg, |
| 6540 | (if (src_mcv.isRegister()) | 6900 | (if (src_mcv.isRegister()) |
| 6541 | src_mcv.getReg().? | 6901 | src_mcv.getReg().? |
| ... | @@ -6546,6 +6906,7 @@ fn genBinOp( | ... | @@ -6546,6 +6906,7 @@ fn genBinOp( |
| 6546 | switch (air_tag) { | 6906 | switch (air_tag) { |
| 6547 | .add => .{ .v_ps, .add }, | 6907 | .add => .{ .v_ps, .add }, |
| 6548 | .sub => .{ .v_ps, .sub }, | 6908 | .sub => .{ .v_ps, .sub }, |
| 6909 | .mul => .{ .v_ps, .mul }, | ||
| 6549 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, | 6910 | .div_float, .div_trunc, .div_floor, .div_exact => .{ .v_ps, .div }, |
| 6550 | .max => .{ .v_ps, .max }, | 6911 | .max => .{ .v_ps, .max }, |
| 6551 | .min => .{ .v_ps, .max }, | 6912 | .min => .{ .v_ps, .max }, |
| ... | @@ -6681,7 +7042,7 @@ fn genBinOp( | ... | @@ -6681,7 +7042,7 @@ fn genBinOp( |
| 6681 | ); | 7042 | ); |
| 6682 | } | 7043 | } |
| 6683 | switch (air_tag) { | 7044 | switch (air_tag) { |
| 6684 | .add, .sub, .mul, .div_float, .div_exact => {}, | 7045 | .add, .addwrap, .sub, .subwrap, .mul, .mulwrap, .div_float, .div_exact => {}, |
| 6685 | .div_trunc, .div_floor => try self.genRound( | 7046 | .div_trunc, .div_floor => try self.genRound( |
| 6686 | lhs_ty, | 7047 | lhs_ty, |
| 6687 | dst_reg, | 7048 | dst_reg, |
| ... | @@ -6692,6 +7053,7 @@ fn genBinOp( | ... | @@ -6692,6 +7053,7 @@ fn genBinOp( |
| 6692 | else => unreachable, | 7053 | else => unreachable, |
| 6693 | }, | 7054 | }, |
| 6694 | ), | 7055 | ), |
| 7056 | .bit_and, .bit_or, .xor => {}, | ||
| 6695 | .max, .min => {}, // TODO: unordered select | 7057 | .max, .min => {}, // TODO: unordered select |
| 6696 | else => unreachable, | 7058 | else => unreachable, |
| 6697 | } | 7059 | } |
| ... | @@ -6712,7 +7074,6 @@ fn genBinOpMir( | ... | @@ -6712,7 +7074,6 @@ fn genBinOpMir( |
| 6712 | .dead, | 7074 | .dead, |
| 6713 | .undef, | 7075 | .undef, |
| 6714 | .immediate, | 7076 | .immediate, |
| 6715 | .register_offset, | ||
| 6716 | .eflags, | 7077 | .eflags, |
| 6717 | .register_overflow, | 7078 | .register_overflow, |
| 6718 | .lea_direct, | 7079 | .lea_direct, |
| ... | @@ -6721,7 +7082,9 @@ fn genBinOpMir( | ... | @@ -6721,7 +7082,9 @@ fn genBinOpMir( |
| 6721 | .lea_frame, | 7082 | .lea_frame, |
| 6722 | .reserved_frame, | 7083 | .reserved_frame, |
| 6723 | => unreachable, // unmodifiable destination | 7084 | => unreachable, // unmodifiable destination |
| 6724 | .register => |dst_reg| { | 7085 | .register, .register_offset => { |
| 7086 | assert(dst_mcv.isRegister()); | ||
| 7087 | const dst_reg = dst_mcv.getReg().?; | ||
| 6725 | const dst_alias = registerAlias(dst_reg, abi_size); | 7088 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 6726 | switch (src_mcv) { | 7089 | switch (src_mcv) { |
| 6727 | .none, | 7090 | .none, |
| ... | @@ -7185,13 +7548,13 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { | ... | @@ -7185,13 +7548,13 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { |
| 7185 | switch (self.debug_output) { | 7548 | switch (self.debug_output) { |
| 7186 | .dwarf => |dw| { | 7549 | .dwarf => |dw| { |
| 7187 | const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) { | 7550 | const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) { |
| 7188 | .register => |reg| .{ .register = reg.dwarfLocOp() }, | 7551 | .register => |reg| .{ .register = reg.dwarfNum() }, |
| 7189 | // TODO use a frame index | 7552 | // TODO use a frame index |
| 7190 | .load_frame => return, | 7553 | .load_frame => return, |
| 7191 | //.stack_offset => |off| .{ | 7554 | //.stack_offset => |off| .{ |
| 7192 | // .stack = .{ | 7555 | // .stack = .{ |
| 7193 | // // TODO handle -fomit-frame-pointer | 7556 | // // TODO handle -fomit-frame-pointer |
| 7194 | // .fp_register = Register.rbp.dwarfLocOpDeref(), | 7557 | // .fp_register = Register.rbp.dwarfNum(), |
| 7195 | // .offset = -off, | 7558 | // .offset = -off, |
| 7196 | // }, | 7559 | // }, |
| 7197 | //}, | 7560 | //}, |
| ... | @@ -7223,11 +7586,11 @@ fn genVarDbgInfo( | ... | @@ -7223,11 +7586,11 @@ fn genVarDbgInfo( |
| 7223 | switch (self.debug_output) { | 7586 | switch (self.debug_output) { |
| 7224 | .dwarf => |dw| { | 7587 | .dwarf => |dw| { |
| 7225 | const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) { | 7588 | const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) { |
| 7226 | .register => |reg| .{ .register = reg.dwarfLocOp() }, | 7589 | .register => |reg| .{ .register = reg.dwarfNum() }, |
| 7227 | // TODO use a frame index | 7590 | // TODO use a frame index |
| 7228 | .load_frame, .lea_frame => return, | 7591 | .load_frame, .lea_frame => return, |
| 7229 | //=> |off| .{ .stack = .{ | 7592 | //=> |off| .{ .stack = .{ |
| 7230 | // .fp_register = Register.rbp.dwarfLocOpDeref(), | 7593 | // .fp_register = Register.rbp.dwarfNum(), |
| 7231 | // .offset = -off, | 7594 | // .offset = -off, |
| 7232 | //} }, | 7595 | //} }, |
| 7233 | .memory => |address| .{ .memory = address }, | 7596 | .memory => |address| .{ .memory = address }, |
| ... | @@ -7364,11 +7727,15 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -7364,11 +7727,15 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 7364 | // on linking. | 7727 | // on linking. |
| 7365 | const mod = self.bin_file.options.module.?; | 7728 | const mod = self.bin_file.options.module.?; |
| 7366 | if (self.air.value(callee)) |func_value| { | 7729 | if (self.air.value(callee)) |func_value| { |
| 7367 | if (func_value.castTag(.function)) |func_payload| { | 7730 | if (if (func_value.castTag(.function)) |func_payload| |
| 7368 | const func = func_payload.data; | 7731 | func_payload.data.owner_decl |
| 7369 | 7732 | else if (func_value.castTag(.decl_ref)) |decl_ref_payload| | |
| 7733 | decl_ref_payload.data | ||
| 7734 | else | ||
| 7735 | null) |owner_decl| | ||
| 7736 | { | ||
| 7370 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { | 7737 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 7371 | const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl); | 7738 | const atom_index = try elf_file.getOrCreateAtomForDecl(owner_decl); |
| 7372 | const atom = elf_file.getAtom(atom_index); | 7739 | const atom = elf_file.getAtom(atom_index); |
| 7373 | _ = try atom.getOrCreateOffsetTableEntry(elf_file); | 7740 | _ = try atom.getOrCreateOffsetTableEntry(elf_file); |
| 7374 | const got_addr = atom.getOffsetTableAddress(elf_file); | 7741 | const got_addr = atom.getOffsetTableAddress(elf_file); |
| ... | @@ -7377,17 +7744,17 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -7377,17 +7744,17 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 7377 | .disp = @intCast(i32, got_addr), | 7744 | .disp = @intCast(i32, got_addr), |
| 7378 | })); | 7745 | })); |
| 7379 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | 7746 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 7380 | const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl); | 7747 | const atom = try coff_file.getOrCreateAtomForDecl(owner_decl); |
| 7381 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; | 7748 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; |
| 7382 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); | 7749 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); |
| 7383 | try self.asmRegister(.{ ._, .call }, .rax); | 7750 | try self.asmRegister(.{ ._, .call }, .rax); |
| 7384 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 7751 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 7385 | const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl); | 7752 | const atom = try macho_file.getOrCreateAtomForDecl(owner_decl); |
| 7386 | const sym_index = macho_file.getAtom(atom).getSymbolIndex().?; | 7753 | const sym_index = macho_file.getAtom(atom).getSymbolIndex().?; |
| 7387 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); | 7754 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); |
| 7388 | try self.asmRegister(.{ ._, .call }, .rax); | 7755 | try self.asmRegister(.{ ._, .call }, .rax); |
| 7389 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { | 7756 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| 7390 | const decl_block_index = try p9.seeDecl(func.owner_decl); | 7757 | const decl_block_index = try p9.seeDecl(owner_decl); |
| 7391 | const decl_block = p9.getDeclBlock(decl_block_index); | 7758 | const decl_block = p9.getDeclBlock(decl_block_index); |
| 7392 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); | 7759 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); |
| 7393 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); | 7760 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); |
| ... | @@ -7577,7 +7944,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -7577,7 +7944,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 7577 | else | 7944 | else |
| 7578 | try self.copyToTmpRegister(ty, src_mcv)).to128(), | 7945 | try self.copyToTmpRegister(ty, src_mcv)).to128(), |
| 7579 | ); | 7946 | ); |
| 7580 | try self.asmRegisterRegister(.{ .v_, .cvtph2ps }, tmp1_reg, tmp1_reg); | 7947 | try self.asmRegisterRegister(.{ .v_ps, .cvtph2 }, tmp1_reg, tmp1_reg); |
| 7581 | try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp2_reg, tmp1_reg); | 7948 | try self.asmRegisterRegister(.{ .v_, .movshdup }, tmp2_reg, tmp1_reg); |
| 7582 | try self.genBinOpMir(.{ ._ss, .ucomi }, ty, tmp1_mcv, tmp2_mcv); | 7949 | try self.genBinOpMir(.{ ._ss, .ucomi }, ty, tmp1_mcv, tmp2_mcv); |
| 7583 | } else return self.fail("TODO implement airCmp for {}", .{ | 7950 | } else return self.fail("TODO implement airCmp for {}", .{ |
| ... | @@ -8568,47 +8935,190 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8568,47 +8935,190 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 8568 | return self.finishAirResult(inst, result); | 8935 | return self.finishAirResult(inst, result); |
| 8569 | } | 8936 | } |
| 8570 | 8937 | ||
| 8571 | fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag { | 8938 | const MoveStrategy = union(enum) { |
| 8939 | move: Mir.Inst.FixedTag, | ||
| 8940 | insert_extract: InsertExtract, | ||
| 8941 | vex_insert_extract: InsertExtract, | ||
| 8942 | |||
| 8943 | const InsertExtract = struct { | ||
| 8944 | insert: Mir.Inst.FixedTag, | ||
| 8945 | extract: Mir.Inst.FixedTag, | ||
| 8946 | }; | ||
| 8947 | }; | ||
| 8948 | fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { | ||
| 8572 | switch (ty.zigTypeTag()) { | 8949 | switch (ty.zigTypeTag()) { |
| 8573 | else => return .{ ._, .mov }, | 8950 | else => return .{ .move = .{ ._, .mov } }, |
| 8574 | .Float => switch (ty.floatBits(self.target.*)) { | 8951 | .Float => switch (ty.floatBits(self.target.*)) { |
| 8575 | 16 => unreachable, // needs special handling | 8952 | 16 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{ |
| 8576 | 32 => return if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov }, | 8953 | .insert = .{ .vp_w, .insr }, |
| 8577 | 64 => return if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov }, | 8954 | .extract = .{ .vp_w, .extr }, |
| 8578 | 128 => return if (self.hasFeature(.avx)) | 8955 | } } else .{ .insert_extract = .{ |
| 8579 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } | 8956 | .insert = .{ .p_w, .insr }, |
| 8580 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu }, | 8957 | .extract = .{ .p_w, .extr }, |
| 8958 | } }, | ||
| 8959 | 32 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov } }, | ||
| 8960 | 64 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov } }, | ||
| 8961 | 128 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 8962 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } | ||
| 8963 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, | ||
| 8581 | else => {}, | 8964 | else => {}, |
| 8582 | }, | 8965 | }, |
| 8583 | .Vector => switch (ty.childType().zigTypeTag()) { | 8966 | .Vector => switch (ty.childType().zigTypeTag()) { |
| 8967 | .Int => switch (ty.childType().intInfo(self.target.*).bits) { | ||
| 8968 | 8 => switch (ty.vectorLen()) { | ||
| 8969 | 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{ | ||
| 8970 | .insert = .{ .vp_b, .insr }, | ||
| 8971 | .extract = .{ .vp_b, .extr }, | ||
| 8972 | } } else if (self.hasFeature(.sse4_2)) return .{ .insert_extract = .{ | ||
| 8973 | .insert = .{ .p_b, .insr }, | ||
| 8974 | .extract = .{ .p_b, .extr }, | ||
| 8975 | } }, | ||
| 8976 | 2 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{ | ||
| 8977 | .insert = .{ .vp_w, .insr }, | ||
| 8978 | .extract = .{ .vp_w, .extr }, | ||
| 8979 | } } else .{ .insert_extract = .{ | ||
| 8980 | .insert = .{ .p_w, .insr }, | ||
| 8981 | .extract = .{ .p_w, .extr }, | ||
| 8982 | } }, | ||
| 8983 | 3...4 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 8984 | .{ .v_d, .mov } | ||
| 8985 | else | ||
| 8986 | .{ ._d, .mov } }, | ||
| 8987 | 5...8 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 8988 | .{ .v_q, .mov } | ||
| 8989 | else | ||
| 8990 | .{ ._q, .mov } }, | ||
| 8991 | 9...16 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 8992 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } | ||
| 8993 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, | ||
| 8994 | 17...32 => if (self.hasFeature(.avx)) | ||
| 8995 | return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, | ||
| 8996 | else => {}, | ||
| 8997 | }, | ||
| 8998 | 16 => switch (ty.vectorLen()) { | ||
| 8999 | 1 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{ | ||
| 9000 | .insert = .{ .vp_w, .insr }, | ||
| 9001 | .extract = .{ .vp_w, .extr }, | ||
| 9002 | } } else .{ .insert_extract = .{ | ||
| 9003 | .insert = .{ .p_w, .insr }, | ||
| 9004 | .extract = .{ .p_w, .extr }, | ||
| 9005 | } }, | ||
| 9006 | 2 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9007 | .{ .v_d, .mov } | ||
| 9008 | else | ||
| 9009 | .{ ._d, .mov } }, | ||
| 9010 | 3...4 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9011 | .{ .v_q, .mov } | ||
| 9012 | else | ||
| 9013 | .{ ._q, .mov } }, | ||
| 9014 | 5...8 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9015 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } | ||
| 9016 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, | ||
| 9017 | 9...16 => if (self.hasFeature(.avx)) | ||
| 9018 | return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, | ||
| 9019 | else => {}, | ||
| 9020 | }, | ||
| 9021 | 32 => switch (ty.vectorLen()) { | ||
| 9022 | 1 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9023 | .{ .v_d, .mov } | ||
| 9024 | else | ||
| 9025 | .{ ._d, .mov } }, | ||
| 9026 | 2 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9027 | .{ .v_q, .mov } | ||
| 9028 | else | ||
| 9029 | .{ ._q, .mov } }, | ||
| 9030 | 3...4 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9031 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } | ||
| 9032 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, | ||
| 9033 | 5...8 => if (self.hasFeature(.avx)) | ||
| 9034 | return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, | ||
| 9035 | else => {}, | ||
| 9036 | }, | ||
| 9037 | 64 => switch (ty.vectorLen()) { | ||
| 9038 | 1 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9039 | .{ .v_q, .mov } | ||
| 9040 | else | ||
| 9041 | .{ ._q, .mov } }, | ||
| 9042 | 2 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9043 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } | ||
| 9044 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, | ||
| 9045 | 3...4 => if (self.hasFeature(.avx)) | ||
| 9046 | return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, | ||
| 9047 | else => {}, | ||
| 9048 | }, | ||
| 9049 | 128 => switch (ty.vectorLen()) { | ||
| 9050 | 1 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9051 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } | ||
| 9052 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, | ||
| 9053 | 2 => if (self.hasFeature(.avx)) | ||
| 9054 | return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, | ||
| 9055 | else => {}, | ||
| 9056 | }, | ||
| 9057 | 256 => switch (ty.vectorLen()) { | ||
| 9058 | 1 => if (self.hasFeature(.avx)) | ||
| 9059 | return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, | ||
| 9060 | else => {}, | ||
| 9061 | }, | ||
| 9062 | else => {}, | ||
| 9063 | }, | ||
| 8584 | .Float => switch (ty.childType().floatBits(self.target.*)) { | 9064 | .Float => switch (ty.childType().floatBits(self.target.*)) { |
| 8585 | 16 => switch (ty.vectorLen()) { | 9065 | 16 => switch (ty.vectorLen()) { |
| 8586 | 1 => unreachable, // needs special handling | 9066 | 1 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{ |
| 8587 | 2 => return if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov }, | 9067 | .insert = .{ .vp_w, .insr }, |
| 8588 | 3...4 => return if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov }, | 9068 | .extract = .{ .vp_w, .extr }, |
| 8589 | 5...8 => return if (self.hasFeature(.avx)) | 9069 | } } else .{ .insert_extract = .{ |
| 8590 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } | 9070 | .insert = .{ .p_w, .insr }, |
| 8591 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu }, | 9071 | .extract = .{ .p_w, .extr }, |
| 9072 | } }, | ||
| 9073 | 2 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9074 | .{ .v_d, .mov } | ||
| 9075 | else | ||
| 9076 | .{ ._d, .mov } }, | ||
| 9077 | 3...4 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9078 | .{ .v_q, .mov } | ||
| 9079 | else | ||
| 9080 | .{ ._q, .mov } }, | ||
| 9081 | 5...8 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9082 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } | ||
| 9083 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, | ||
| 8592 | 9...16 => if (self.hasFeature(.avx)) | 9084 | 9...16 => if (self.hasFeature(.avx)) |
| 8593 | return if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }, | 9085 | return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, |
| 8594 | else => {}, | 9086 | else => {}, |
| 8595 | }, | 9087 | }, |
| 8596 | 32 => switch (ty.vectorLen()) { | 9088 | 32 => switch (ty.vectorLen()) { |
| 8597 | 1 => return if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov }, | 9089 | 1 => return .{ .move = if (self.hasFeature(.avx)) |
| 8598 | 2...4 => return if (self.hasFeature(.avx)) | 9090 | .{ .v_ss, .mov } |
| 9091 | else | ||
| 9092 | .{ ._ss, .mov } }, | ||
| 9093 | 2 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9094 | .{ .v_sd, .mov } | ||
| 9095 | else | ||
| 9096 | .{ ._sd, .mov } }, | ||
| 9097 | 3...4 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 8599 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } | 9098 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } |
| 8600 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu }, | 9099 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu } }, |
| 8601 | 5...8 => if (self.hasFeature(.avx)) | 9100 | 5...8 => if (self.hasFeature(.avx)) |
| 8602 | return if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }, | 9101 | return .{ .move = if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } }, |
| 8603 | else => {}, | 9102 | else => {}, |
| 8604 | }, | 9103 | }, |
| 8605 | 64 => switch (ty.vectorLen()) { | 9104 | 64 => switch (ty.vectorLen()) { |
| 8606 | 1 => return if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov }, | 9105 | 1 => return .{ .move = if (self.hasFeature(.avx)) |
| 8607 | 2 => return if (self.hasFeature(.avx)) | 9106 | .{ .v_sd, .mov } |
| 8608 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } | 9107 | else |
| 8609 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu }, | 9108 | .{ ._sd, .mov } }, |
| 9109 | 2 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9110 | if (aligned) .{ .v_pd, .mova } else .{ .v_pd, .movu } | ||
| 9111 | else if (aligned) .{ ._pd, .mova } else .{ ._pd, .movu } }, | ||
| 8610 | 3...4 => if (self.hasFeature(.avx)) | 9112 | 3...4 => if (self.hasFeature(.avx)) |
| 8611 | return if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }, | 9113 | return .{ .move = if (aligned) .{ .v_pd, .mova } else .{ .v_pd, .movu } }, |
| 9114 | else => {}, | ||
| 9115 | }, | ||
| 9116 | 128 => switch (ty.vectorLen()) { | ||
| 9117 | 1 => return .{ .move = if (self.hasFeature(.avx)) | ||
| 9118 | if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } | ||
| 9119 | else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, | ||
| 9120 | 2 => if (self.hasFeature(.avx)) | ||
| 9121 | return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, | ||
| 8612 | else => {}, | 9122 | else => {}, |
| 8613 | }, | 9123 | }, |
| 8614 | else => {}, | 9124 | else => {}, |
| ... | @@ -8616,15 +9126,11 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag { | ... | @@ -8616,15 +9126,11 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag { |
| 8616 | else => {}, | 9126 | else => {}, |
| 8617 | }, | 9127 | }, |
| 8618 | } | 9128 | } |
| 8619 | return self.fail("TODO movMirTag for {}", .{ty.fmt(self.bin_file.options.module.?)}); | 9129 | return self.fail("TODO moveStrategy for {}", .{ty.fmt(self.bin_file.options.module.?)}); |
| 8620 | } | 9130 | } |
| 8621 | 9131 | ||
| 8622 | fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { | 9132 | fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { |
| 8623 | const src_lock = switch (src_mcv) { | 9133 | const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; |
| 8624 | .register => |reg| self.register_manager.lockReg(reg), | ||
| 8625 | .register_overflow => |ro| self.register_manager.lockReg(ro.reg), | ||
| 8626 | else => null, | ||
| 8627 | }; | ||
| 8628 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); | 9134 | defer if (src_lock) |lock| self.register_manager.unlockReg(lock); |
| 8629 | 9135 | ||
| 8630 | switch (dst_mcv) { | 9136 | switch (dst_mcv) { |
| ... | @@ -8720,34 +9226,94 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -8720,34 +9226,94 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 8720 | ); | 9226 | ); |
| 8721 | } | 9227 | } |
| 8722 | }, | 9228 | }, |
| 8723 | .register => |src_reg| if (dst_reg.id() != src_reg.id()) try self.asmRegisterRegister( | 9229 | .register => |src_reg| if (dst_reg.id() != src_reg.id()) switch (dst_reg.class()) { |
| 8724 | if ((dst_reg.class() == .floating_point) == (src_reg.class() == .floating_point)) | 9230 | .general_purpose => switch (src_reg.class()) { |
| 8725 | switch (ty.zigTypeTag()) { | 9231 | .general_purpose => try self.asmRegisterRegister( |
| 8726 | else => .{ ._, .mov }, | 9232 | .{ ._, .mov }, |
| 8727 | .Float, .Vector => .{ ._ps, .mova }, | 9233 | registerAlias(dst_reg, abi_size), |
| 8728 | } | 9234 | registerAlias(src_reg, abi_size), |
| 8729 | else switch (abi_size) { | ||
| 8730 | 2 => return try self.asmRegisterRegisterImmediate( | ||
| 8731 | if (dst_reg.class() == .floating_point) .{ .p_w, .insr } else .{ .p_w, .extr }, | ||
| 8732 | registerAlias(dst_reg, 4), | ||
| 8733 | registerAlias(src_reg, 4), | ||
| 8734 | Immediate.u(0), | ||
| 8735 | ), | 9235 | ), |
| 8736 | 4 => .{ ._d, .mov }, | 9236 | .segment => try self.asmRegisterRegister( |
| 8737 | 8 => .{ ._q, .mov }, | 9237 | .{ ._, .mov }, |
| 8738 | else => return self.fail( | 9238 | registerAlias(dst_reg, abi_size), |
| 8739 | "unsupported register copy from {s} to {s}", | 9239 | src_reg, |
| 8740 | .{ @tagName(src_reg), @tagName(dst_reg) }, | ||
| 8741 | ), | 9240 | ), |
| 9241 | .sse => try self.asmRegisterRegister( | ||
| 9242 | switch (abi_size) { | ||
| 9243 | 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov }, | ||
| 9244 | 5...8 => if (self.hasFeature(.avx)) .{ .v_q, .mov } else .{ ._q, .mov }, | ||
| 9245 | else => unreachable, | ||
| 9246 | }, | ||
| 9247 | registerAlias(dst_reg, @max(abi_size, 4)), | ||
| 9248 | src_reg.to128(), | ||
| 9249 | ), | ||
| 9250 | .x87, .mmx => unreachable, | ||
| 8742 | }, | 9251 | }, |
| 8743 | registerAlias(dst_reg, abi_size), | 9252 | .segment => try self.asmRegisterRegister( |
| 8744 | registerAlias(src_reg, abi_size), | 9253 | .{ ._, .mov }, |
| 8745 | ), | 9254 | dst_reg, |
| 9255 | switch (src_reg.class()) { | ||
| 9256 | .general_purpose, .segment => registerAlias(src_reg, abi_size), | ||
| 9257 | .sse => try self.copyToTmpRegister(ty, src_mcv), | ||
| 9258 | .x87, .mmx => unreachable, | ||
| 9259 | }, | ||
| 9260 | ), | ||
| 9261 | .sse => switch (src_reg.class()) { | ||
| 9262 | .general_purpose => try self.asmRegisterRegister( | ||
| 9263 | switch (abi_size) { | ||
| 9264 | 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov }, | ||
| 9265 | 5...8 => if (self.hasFeature(.avx)) .{ .v_q, .mov } else .{ ._q, .mov }, | ||
| 9266 | else => unreachable, | ||
| 9267 | }, | ||
| 9268 | dst_reg.to128(), | ||
| 9269 | registerAlias(src_reg, @max(abi_size, 4)), | ||
| 9270 | ), | ||
| 9271 | .segment => try self.genSetReg( | ||
| 9272 | dst_reg, | ||
| 9273 | ty, | ||
| 9274 | .{ .register = try self.copyToTmpRegister(ty, src_mcv) }, | ||
| 9275 | ), | ||
| 9276 | .sse => try self.asmRegisterRegister( | ||
| 9277 | if (@as(?Mir.Inst.FixedTag, switch (ty.scalarType().zigTypeTag()) { | ||
| 9278 | else => switch (abi_size) { | ||
| 9279 | 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov }, | ||
| 9280 | 5...8 => if (self.hasFeature(.avx)) .{ .v_q, .mov } else .{ ._q, .mov }, | ||
| 9281 | 9...16 => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else .{ ._, .movdqa }, | ||
| 9282 | 17...32 => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else null, | ||
| 9283 | else => null, | ||
| 9284 | }, | ||
| 9285 | .Float => switch (ty.floatBits(self.target.*)) { | ||
| 9286 | 16, 128 => switch (abi_size) { | ||
| 9287 | 2...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov }, | ||
| 9288 | 5...8 => if (self.hasFeature(.avx)) .{ .v_q, .mov } else .{ ._q, .mov }, | ||
| 9289 | 9...16 => if (self.hasFeature(.avx)) | ||
| 9290 | .{ .v_, .movdqa } | ||
| 9291 | else | ||
| 9292 | .{ ._, .movdqa }, | ||
| 9293 | 17...32 => if (self.hasFeature(.avx)) .{ .v_, .movdqa } else null, | ||
| 9294 | else => null, | ||
| 9295 | }, | ||
| 9296 | 32 => if (self.hasFeature(.avx)) .{ .v_ps, .mova } else .{ ._ps, .mova }, | ||
| 9297 | 64 => if (self.hasFeature(.avx)) .{ .v_pd, .mova } else .{ ._pd, .mova }, | ||
| 9298 | 80 => null, | ||
| 9299 | else => unreachable, | ||
| 9300 | }, | ||
| 9301 | })) |tag| tag else return self.fail("TODO implement genSetReg for {}", .{ | ||
| 9302 | ty.fmt(self.bin_file.options.module.?), | ||
| 9303 | }), | ||
| 9304 | registerAlias(dst_reg, abi_size), | ||
| 9305 | registerAlias(src_reg, abi_size), | ||
| 9306 | ), | ||
| 9307 | .x87, .mmx => unreachable, | ||
| 9308 | }, | ||
| 9309 | .x87, .mmx => unreachable, | ||
| 9310 | }, | ||
| 8746 | .register_offset, | 9311 | .register_offset, |
| 8747 | .indirect, | 9312 | .indirect, |
| 8748 | .load_frame, | 9313 | .load_frame, |
| 8749 | .lea_frame, | 9314 | .lea_frame, |
| 8750 | => { | 9315 | => { |
| 9316 | const dst_alias = registerAlias(dst_reg, abi_size); | ||
| 8751 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), switch (src_mcv) { | 9317 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), switch (src_mcv) { |
| 8752 | .register_offset, .indirect => |reg_off| .{ | 9318 | .register_offset, .indirect => |reg_off| .{ |
| 8753 | .base = .{ .reg = reg_off.reg }, | 9319 | .base = .{ .reg = reg_off.reg }, |
| ... | @@ -8759,71 +9325,81 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -8759,71 +9325,81 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 8759 | }, | 9325 | }, |
| 8760 | else => unreachable, | 9326 | else => unreachable, |
| 8761 | }); | 9327 | }); |
| 8762 | if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16) | 9328 | switch (@as(MoveStrategy, switch (src_mcv) { |
| 8763 | try self.asmRegisterMemoryImmediate( | 9329 | .register_offset => |reg_off| switch (reg_off.off) { |
| 8764 | .{ .p_w, .insr }, | 9330 | 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }), |
| 8765 | registerAlias(dst_reg, abi_size), | 9331 | else => .{ .move = .{ ._, .lea } }, |
| 9332 | }, | ||
| 9333 | .indirect => try self.moveStrategy(ty, false), | ||
| 9334 | .load_frame => |frame_addr| try self.moveStrategy( | ||
| 9335 | ty, | ||
| 9336 | self.getFrameAddrAlignment(frame_addr) >= ty.abiAlignment(self.target.*), | ||
| 9337 | ), | ||
| 9338 | .lea_frame => .{ .move = .{ ._, .lea } }, | ||
| 9339 | else => unreachable, | ||
| 9340 | })) { | ||
| 9341 | .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem), | ||
| 9342 | .insert_extract => |ie| try self.asmRegisterMemoryImmediate( | ||
| 9343 | ie.insert, | ||
| 9344 | dst_alias, | ||
| 8766 | src_mem, | 9345 | src_mem, |
| 8767 | Immediate.u(0), | 9346 | Immediate.u(0), |
| 8768 | ) | 9347 | ), |
| 8769 | else | 9348 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( |
| 8770 | try self.asmRegisterMemory( | 9349 | ie.insert, |
| 8771 | switch (src_mcv) { | 9350 | dst_alias, |
| 8772 | .register_offset => |reg_off| switch (reg_off.off) { | 9351 | dst_alias, |
| 8773 | 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }), | ||
| 8774 | else => .{ ._, .lea }, | ||
| 8775 | }, | ||
| 8776 | .indirect => try self.movMirTag(ty, false), | ||
| 8777 | .load_frame => |frame_addr| try self.movMirTag( | ||
| 8778 | ty, | ||
| 8779 | self.getFrameAddrAlignment(frame_addr) >= ty.abiAlignment(self.target.*), | ||
| 8780 | ), | ||
| 8781 | .lea_frame => .{ ._, .lea }, | ||
| 8782 | else => unreachable, | ||
| 8783 | }, | ||
| 8784 | registerAlias(dst_reg, abi_size), | ||
| 8785 | src_mem, | 9352 | src_mem, |
| 8786 | ); | 9353 | Immediate.u(0), |
| 9354 | ), | ||
| 9355 | } | ||
| 8787 | }, | 9356 | }, |
| 8788 | .memory, .load_direct, .load_got, .load_tlv => { | 9357 | .memory, .load_direct, .load_got, .load_tlv => { |
| 8789 | switch (src_mcv) { | 9358 | switch (src_mcv) { |
| 8790 | .memory => |addr| if (math.cast(i32, @bitCast(i64, addr))) |small_addr| { | 9359 | .memory => |addr| if (math.cast(i32, @bitCast(i64, addr))) |small_addr| { |
| 9360 | const dst_alias = registerAlias(dst_reg, abi_size); | ||
| 8791 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ | 9361 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 8792 | .base = .{ .reg = .ds }, | 9362 | .base = .{ .reg = .ds }, |
| 8793 | .disp = small_addr, | 9363 | .disp = small_addr, |
| 8794 | }); | 9364 | }); |
| 8795 | return if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16) | 9365 | switch (try self.moveStrategy(ty, mem.isAlignedGeneric( |
| 8796 | self.asmRegisterMemoryImmediate( | 9366 | u32, |
| 8797 | .{ .p_w, .insr }, | 9367 | @bitCast(u32, small_addr), |
| 8798 | registerAlias(dst_reg, abi_size), | 9368 | ty.abiAlignment(self.target.*), |
| 9369 | ))) { | ||
| 9370 | .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem), | ||
| 9371 | .insert_extract => |ie| try self.asmRegisterMemoryImmediate( | ||
| 9372 | ie.insert, | ||
| 9373 | dst_alias, | ||
| 8799 | src_mem, | 9374 | src_mem, |
| 8800 | Immediate.u(0), | 9375 | Immediate.u(0), |
| 8801 | ) | 9376 | ), |
| 8802 | else | 9377 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( |
| 8803 | self.asmRegisterMemory( | 9378 | ie.insert, |
| 8804 | try self.movMirTag(ty, mem.isAlignedGeneric( | 9379 | dst_alias, |
| 8805 | u32, | 9380 | dst_alias, |
| 8806 | @bitCast(u32, small_addr), | ||
| 8807 | ty.abiAlignment(self.target.*), | ||
| 8808 | )), | ||
| 8809 | registerAlias(dst_reg, abi_size), | ||
| 8810 | src_mem, | 9381 | src_mem, |
| 8811 | ); | 9382 | Immediate.u(0), |
| 9383 | ), | ||
| 9384 | } | ||
| 8812 | }, | 9385 | }, |
| 8813 | .load_direct => |sym_index| if (!ty.isRuntimeFloat()) { | 9386 | .load_direct => |sym_index| switch (ty.zigTypeTag()) { |
| 8814 | const atom_index = try self.owner.getSymbolIndex(self); | 9387 | else => { |
| 8815 | _ = try self.addInst(.{ | 9388 | const atom_index = try self.owner.getSymbolIndex(self); |
| 8816 | .tag = .mov, | 9389 | _ = try self.addInst(.{ |
| 8817 | .ops = .direct_reloc, | 9390 | .tag = .mov, |
| 8818 | .data = .{ .rx = .{ | 9391 | .ops = .direct_reloc, |
| 8819 | .r1 = dst_reg.to64(), | 9392 | .data = .{ .rx = .{ |
| 8820 | .payload = try self.addExtra(Mir.Reloc{ | 9393 | .r1 = dst_reg.to64(), |
| 8821 | .atom_index = atom_index, | 9394 | .payload = try self.addExtra(Mir.Reloc{ |
| 8822 | .sym_index = sym_index, | 9395 | .atom_index = atom_index, |
| 8823 | }), | 9396 | .sym_index = sym_index, |
| 8824 | } }, | 9397 | }), |
| 8825 | }); | 9398 | } }, |
| 8826 | return; | 9399 | }); |
| 9400 | return; | ||
| 9401 | }, | ||
| 9402 | .Float, .Vector => {}, | ||
| 8827 | }, | 9403 | }, |
| 8828 | .load_got, .load_tlv => {}, | 9404 | .load_got, .load_tlv => {}, |
| 8829 | else => unreachable, | 9405 | else => unreachable, |
| ... | @@ -8833,22 +9409,26 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -8833,22 +9409,26 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 8833 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 9409 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 8834 | defer self.register_manager.unlockReg(addr_lock); | 9410 | defer self.register_manager.unlockReg(addr_lock); |
| 8835 | 9411 | ||
| 9412 | const dst_alias = registerAlias(dst_reg, abi_size); | ||
| 8836 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ | 9413 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 8837 | .base = .{ .reg = addr_reg }, | 9414 | .base = .{ .reg = addr_reg }, |
| 8838 | }); | 9415 | }); |
| 8839 | if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16) | 9416 | switch (try self.moveStrategy(ty, false)) { |
| 8840 | try self.asmRegisterMemoryImmediate( | 9417 | .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem), |
| 8841 | .{ .p_w, .insr }, | 9418 | .insert_extract => |ie| try self.asmRegisterMemoryImmediate( |
| 8842 | registerAlias(dst_reg, abi_size), | 9419 | ie.insert, |
| 9420 | dst_alias, | ||
| 8843 | src_mem, | 9421 | src_mem, |
| 8844 | Immediate.u(0), | 9422 | Immediate.u(0), |
| 8845 | ) | 9423 | ), |
| 8846 | else | 9424 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( |
| 8847 | try self.asmRegisterMemory( | 9425 | ie.insert, |
| 8848 | try self.movMirTag(ty, false), | 9426 | dst_alias, |
| 8849 | registerAlias(dst_reg, abi_size), | 9427 | dst_alias, |
| 8850 | src_mem, | 9428 | src_mem, |
| 8851 | ); | 9429 | Immediate.u(0), |
| 9430 | ), | ||
| 9431 | } | ||
| 8852 | }, | 9432 | }, |
| 8853 | .lea_direct, .lea_got => |sym_index| { | 9433 | .lea_direct, .lea_got => |sym_index| { |
| 8854 | const atom_index = try self.owner.getSymbolIndex(self); | 9434 | const atom_index = try self.owner.getSymbolIndex(self); |
| ... | @@ -8950,36 +9530,33 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -8950,36 +9530,33 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 8950 | Memory.PtrSize.fromSize(abi_size), | 9530 | Memory.PtrSize.fromSize(abi_size), |
| 8951 | .{ .base = base, .disp = disp }, | 9531 | .{ .base = base, .disp = disp }, |
| 8952 | ); | 9532 | ); |
| 8953 | if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16) | 9533 | const src_alias = registerAlias(src_reg, abi_size); |
| 8954 | try self.asmMemoryRegisterImmediate( | 9534 | switch (try self.moveStrategy(ty, switch (base) { |
| 8955 | .{ .p_w, .extr }, | 9535 | .none => mem.isAlignedGeneric( |
| 9536 | u32, | ||
| 9537 | @bitCast(u32, disp), | ||
| 9538 | ty.abiAlignment(self.target.*), | ||
| 9539 | ), | ||
| 9540 | .reg => |reg| switch (reg) { | ||
| 9541 | .es, .cs, .ss, .ds => mem.isAlignedGeneric( | ||
| 9542 | u32, | ||
| 9543 | @bitCast(u32, disp), | ||
| 9544 | ty.abiAlignment(self.target.*), | ||
| 9545 | ), | ||
| 9546 | else => false, | ||
| 9547 | }, | ||
| 9548 | .frame => |frame_index| self.getFrameAddrAlignment( | ||
| 9549 | .{ .index = frame_index, .off = disp }, | ||
| 9550 | ) >= ty.abiAlignment(self.target.*), | ||
| 9551 | })) { | ||
| 9552 | .move => |tag| try self.asmMemoryRegister(tag, dst_mem, src_alias), | ||
| 9553 | .insert_extract, .vex_insert_extract => |ie| try self.asmMemoryRegisterImmediate( | ||
| 9554 | ie.extract, | ||
| 8956 | dst_mem, | 9555 | dst_mem, |
| 8957 | src_reg.to128(), | 9556 | src_alias, |
| 8958 | Immediate.u(0), | 9557 | Immediate.u(0), |
| 8959 | ) | 9558 | ), |
| 8960 | else | 9559 | } |
| 8961 | try self.asmMemoryRegister( | ||
| 8962 | try self.movMirTag(ty, switch (base) { | ||
| 8963 | .none => mem.isAlignedGeneric( | ||
| 8964 | u32, | ||
| 8965 | @bitCast(u32, disp), | ||
| 8966 | ty.abiAlignment(self.target.*), | ||
| 8967 | ), | ||
| 8968 | .reg => |reg| switch (reg) { | ||
| 8969 | .es, .cs, .ss, .ds => mem.isAlignedGeneric( | ||
| 8970 | u32, | ||
| 8971 | @bitCast(u32, disp), | ||
| 8972 | ty.abiAlignment(self.target.*), | ||
| 8973 | ), | ||
| 8974 | else => false, | ||
| 8975 | }, | ||
| 8976 | .frame => |frame_index| self.getFrameAddrAlignment( | ||
| 8977 | .{ .index = frame_index, .off = disp }, | ||
| 8978 | ) >= ty.abiAlignment(self.target.*), | ||
| 8979 | }), | ||
| 8980 | dst_mem, | ||
| 8981 | registerAlias(src_reg, abi_size), | ||
| 8982 | ); | ||
| 8983 | }, | 9560 | }, |
| 8984 | .register_overflow => |ro| { | 9561 | .register_overflow => |ro| { |
| 8985 | try self.genSetMem( | 9562 | try self.genSetMem( |
| ... | @@ -9069,7 +9646,7 @@ fn genInlineMemcpyRegisterRegister( | ... | @@ -9069,7 +9646,7 @@ fn genInlineMemcpyRegisterRegister( |
| 9069 | try self.asmMemoryRegister( | 9646 | try self.asmMemoryRegister( |
| 9070 | switch (src_reg.class()) { | 9647 | switch (src_reg.class()) { |
| 9071 | .general_purpose, .segment => .{ ._, .mov }, | 9648 | .general_purpose, .segment => .{ ._, .mov }, |
| 9072 | .floating_point => .{ ._ss, .mov }, | 9649 | .sse => .{ ._ss, .mov }, |
| 9073 | }, | 9650 | }, |
| 9074 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = dst_reg, .disp = -offset }), | 9651 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = dst_reg, .disp = -offset }), |
| 9075 | registerAlias(src_reg, abi_size), | 9652 | registerAlias(src_reg, abi_size), |
| ... | @@ -9235,10 +9812,10 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9235,10 +9812,10 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 9235 | }); | 9812 | }); |
| 9236 | 9813 | ||
| 9237 | const src_mcv = try self.resolveInst(ty_op.operand); | 9814 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 9238 | const src_reg = switch (src_mcv) { | 9815 | const src_reg = if (src_mcv.isRegister()) |
| 9239 | .register => |reg| reg, | 9816 | src_mcv.getReg().? |
| 9240 | else => try self.copyToTmpRegister(src_ty, src_mcv), | 9817 | else |
| 9241 | }; | 9818 | try self.copyToTmpRegister(src_ty, src_mcv); |
| 9242 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); | 9819 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); |
| 9243 | defer self.register_manager.unlockReg(src_lock); | 9820 | defer self.register_manager.unlockReg(src_lock); |
| 9244 | 9821 | ||
| ... | @@ -9249,23 +9826,23 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9249,23 +9826,23 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 9249 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | 9826 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 9250 | defer self.register_manager.unlockReg(dst_lock); | 9827 | defer self.register_manager.unlockReg(dst_lock); |
| 9251 | 9828 | ||
| 9252 | try self.asmRegisterRegister(switch (dst_ty.floatBits(self.target.*)) { | 9829 | const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (dst_ty.zigTypeTag()) { |
| 9253 | 32 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse)) | 9830 | .Float => switch (dst_ty.floatBits(self.target.*)) { |
| 9254 | .{ ._, .cvtsi2ss } | 9831 | 32 => if (self.hasFeature(.avx)) .{ .v_ss, .cvtsi2 } else .{ ._ss, .cvtsi2 }, |
| 9255 | else | 9832 | 64 => if (self.hasFeature(.avx)) .{ .v_sd, .cvtsi2 } else .{ ._sd, .cvtsi2 }, |
| 9256 | return self.fail("TODO implement airIntToFloat from {} to {} without sse", .{ | 9833 | 16, 80, 128 => null, |
| 9257 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), | 9834 | else => unreachable, |
| 9258 | }), | 9835 | }, |
| 9259 | 64 => if (Target.x86.featureSetHas(self.target.cpu.features, .sse2)) | 9836 | else => null, |
| 9260 | .{ ._, .cvtsi2sd } | 9837 | })) |tag| tag else return self.fail("TODO implement airIntToFloat from {} to {}", .{ |
| 9261 | else | 9838 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), |
| 9262 | return self.fail("TODO implement airIntToFloat from {} to {} without sse2", .{ | 9839 | }); |
| 9263 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), | 9840 | const dst_alias = dst_reg.to128(); |
| 9264 | }), | 9841 | const src_alias = registerAlias(src_reg, src_size); |
| 9265 | else => return self.fail("TODO implement airIntToFloat from {} to {}", .{ | 9842 | switch (mir_tag[0]) { |
| 9266 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), | 9843 | .v_ss, .v_sd => try self.asmRegisterRegisterRegister(mir_tag, dst_alias, dst_alias, src_alias), |
| 9267 | }), | 9844 | else => try self.asmRegisterRegister(mir_tag, dst_alias, src_alias), |
| 9268 | }, dst_reg.to128(), registerAlias(src_reg, src_size)); | 9845 | } |
| 9269 | 9846 | ||
| 9270 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | 9847 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); |
| 9271 | } | 9848 | } |
| ... | @@ -9275,46 +9852,50 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9275,46 +9852,50 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void { |
| 9275 | 9852 | ||
| 9276 | const src_ty = self.air.typeOf(ty_op.operand); | 9853 | const src_ty = self.air.typeOf(ty_op.operand); |
| 9277 | const dst_ty = self.air.typeOfIndex(inst); | 9854 | const dst_ty = self.air.typeOfIndex(inst); |
| 9278 | const operand = try self.resolveInst(ty_op.operand); | 9855 | const dst_bits = @intCast(u32, dst_ty.bitSize(self.target.*)); |
| 9279 | const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*)); | 9856 | const dst_signedness = |
| 9280 | const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); | 9857 | if (dst_ty.isAbiInt()) dst_ty.intInfo(self.target.*).signedness else .unsigned; |
| 9281 | 9858 | ||
| 9282 | switch (src_abi_size) { | 9859 | const dst_size = std.math.divCeil(u32, @max(switch (dst_signedness) { |
| 9283 | 4, 8 => {}, | 9860 | .signed => dst_bits, |
| 9284 | else => |size| return self.fail("TODO load ST(0) with abiSize={}", .{size}), | 9861 | .unsigned => dst_bits + 1, |
| 9285 | } | 9862 | }, 32), 8) catch unreachable; |
| 9286 | if (dst_abi_size > 8) { | 9863 | if (dst_size > 8) return self.fail("TODO implement airFloatToInt from {} to {}", .{ |
| 9287 | return self.fail("TODO convert float with abiSize={}", .{dst_abi_size}); | 9864 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), |
| 9288 | } | 9865 | }); |
| 9289 | 9866 | ||
| 9290 | // move float src to ST(0) | 9867 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 9291 | const frame_addr: FrameAddr = switch (operand) { | 9868 | const src_reg = if (src_mcv.isRegister()) |
| 9292 | .load_frame => |frame_addr| frame_addr, | 9869 | src_mcv.getReg().? |
| 9293 | else => frame_addr: { | 9870 | else |
| 9294 | const frame_index = try self.allocFrameIndex(FrameAlloc.initType(src_ty, self.target.*)); | 9871 | try self.copyToTmpRegister(src_ty, src_mcv); |
| 9295 | try self.genSetMem(.{ .frame = frame_index }, 0, src_ty, operand); | 9872 | const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); |
| 9296 | break :frame_addr .{ .index = frame_index }; | 9873 | defer self.register_manager.unlockReg(src_lock); |
| 9297 | }, | 9874 | |
| 9298 | }; | 9875 | const dst_reg = try self.register_manager.allocReg(inst, regClassForType(dst_ty)); |
| 9299 | try self.asmMemory( | 9876 | const dst_mcv = MCValue{ .register = dst_reg }; |
| 9300 | .{ .f_, .ld }, | 9877 | const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 9301 | Memory.sib(Memory.PtrSize.fromSize(src_abi_size), .{ | 9878 | defer self.register_manager.unlockReg(dst_lock); |
| 9302 | .base = .{ .frame = frame_addr.index }, | ||
| 9303 | .disp = frame_addr.off, | ||
| 9304 | }), | ||
| 9305 | ); | ||
| 9306 | 9879 | ||
| 9307 | // convert | 9880 | try self.asmRegisterRegister( |
| 9308 | const stack_dst = try self.allocRegOrMem(inst, false); | 9881 | if (@as(?Mir.Inst.FixedTag, switch (src_ty.zigTypeTag()) { |
| 9309 | try self.asmMemory( | 9882 | .Float => switch (src_ty.floatBits(self.target.*)) { |
| 9310 | .{ .f_p, .istt }, | 9883 | 32 => if (self.hasFeature(.avx)) .{ .v_, .cvttss2si } else .{ ._, .cvttss2si }, |
| 9311 | Memory.sib(Memory.PtrSize.fromSize(dst_abi_size), .{ | 9884 | 64 => if (self.hasFeature(.avx)) .{ .v_, .cvttsd2si } else .{ ._, .cvttsd2si }, |
| 9312 | .base = .{ .frame = stack_dst.load_frame.index }, | 9885 | 16, 80, 128 => null, |
| 9313 | .disp = stack_dst.load_frame.off, | 9886 | else => unreachable, |
| 9887 | }, | ||
| 9888 | else => null, | ||
| 9889 | })) |tag| tag else return self.fail("TODO implement airFloatToInt from {} to {}", .{ | ||
| 9890 | src_ty.fmt(self.bin_file.options.module.?), dst_ty.fmt(self.bin_file.options.module.?), | ||
| 9314 | }), | 9891 | }), |
| 9892 | registerAlias(dst_reg, dst_size), | ||
| 9893 | src_reg.to128(), | ||
| 9315 | ); | 9894 | ); |
| 9316 | 9895 | ||
| 9317 | return self.finishAir(inst, stack_dst, .{ ty_op.operand, .none, .none }); | 9896 | if (dst_bits < dst_size * 8) try self.truncateRegister(dst_ty, dst_reg); |
| 9897 | |||
| 9898 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | ||
| 9318 | } | 9899 | } |
| 9319 | 9900 | ||
| 9320 | fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { | 9901 | fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -9977,9 +10558,200 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -9977,9 +10558,200 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 9977 | 10558 | ||
| 9978 | fn airSplat(self: *Self, inst: Air.Inst.Index) !void { | 10559 | fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 9979 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 10560 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 9980 | _ = ty_op; | 10561 | const vector_ty = self.air.typeOfIndex(inst); |
| 9981 | return self.fail("TODO implement airSplat for x86_64", .{}); | 10562 | const dst_rc = regClassForType(vector_ty); |
| 9982 | //return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 10563 | const scalar_ty = vector_ty.scalarType(); |
| 10564 | |||
| 10565 | const src_mcv = try self.resolveInst(ty_op.operand); | ||
| 10566 | const result: MCValue = result: { | ||
| 10567 | switch (scalar_ty.zigTypeTag()) { | ||
| 10568 | else => {}, | ||
| 10569 | .Float => switch (scalar_ty.floatBits(self.target.*)) { | ||
| 10570 | 32 => switch (vector_ty.vectorLen()) { | ||
| 10571 | 1 => { | ||
| 10572 | if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; | ||
| 10573 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); | ||
| 10574 | try self.genSetReg(dst_reg, scalar_ty, src_mcv); | ||
| 10575 | break :result .{ .register = dst_reg }; | ||
| 10576 | }, | ||
| 10577 | 2...4 => { | ||
| 10578 | if (self.hasFeature(.avx)) { | ||
| 10579 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); | ||
| 10580 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | ||
| 10581 | .{ .v_ss, .broadcast }, | ||
| 10582 | dst_reg.to128(), | ||
| 10583 | src_mcv.mem(.dword), | ||
| 10584 | ) else { | ||
| 10585 | const src_reg = if (src_mcv.isRegister()) | ||
| 10586 | src_mcv.getReg().? | ||
| 10587 | else | ||
| 10588 | try self.copyToTmpRegister(scalar_ty, src_mcv); | ||
| 10589 | try self.asmRegisterRegisterRegisterImmediate( | ||
| 10590 | .{ .v_ps, .shuf }, | ||
| 10591 | dst_reg.to128(), | ||
| 10592 | src_reg.to128(), | ||
| 10593 | src_reg.to128(), | ||
| 10594 | Immediate.u(0), | ||
| 10595 | ); | ||
| 10596 | } | ||
| 10597 | break :result .{ .register = dst_reg }; | ||
| 10598 | } else { | ||
| 10599 | const dst_mcv = if (src_mcv.isRegister() and | ||
| 10600 | self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | ||
| 10601 | src_mcv | ||
| 10602 | else | ||
| 10603 | try self.copyToRegisterWithInstTracking(inst, scalar_ty, src_mcv); | ||
| 10604 | const dst_reg = dst_mcv.getReg().?; | ||
| 10605 | try self.asmRegisterRegisterImmediate( | ||
| 10606 | .{ ._ps, .shuf }, | ||
| 10607 | dst_reg.to128(), | ||
| 10608 | dst_reg.to128(), | ||
| 10609 | Immediate.u(0), | ||
| 10610 | ); | ||
| 10611 | break :result dst_mcv; | ||
| 10612 | } | ||
| 10613 | }, | ||
| 10614 | 5...8 => if (self.hasFeature(.avx)) { | ||
| 10615 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); | ||
| 10616 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | ||
| 10617 | .{ .v_ss, .broadcast }, | ||
| 10618 | dst_reg.to256(), | ||
| 10619 | src_mcv.mem(.dword), | ||
| 10620 | ) else { | ||
| 10621 | const src_reg = if (src_mcv.isRegister()) | ||
| 10622 | src_mcv.getReg().? | ||
| 10623 | else | ||
| 10624 | try self.copyToTmpRegister(scalar_ty, src_mcv); | ||
| 10625 | if (self.hasFeature(.avx2)) try self.asmRegisterRegister( | ||
| 10626 | .{ .v_ss, .broadcast }, | ||
| 10627 | dst_reg.to256(), | ||
| 10628 | src_reg.to128(), | ||
| 10629 | ) else { | ||
| 10630 | try self.asmRegisterRegisterRegisterImmediate( | ||
| 10631 | .{ .v_ps, .shuf }, | ||
| 10632 | dst_reg.to128(), | ||
| 10633 | src_reg.to128(), | ||
| 10634 | src_reg.to128(), | ||
| 10635 | Immediate.u(0), | ||
| 10636 | ); | ||
| 10637 | try self.asmRegisterRegisterRegisterImmediate( | ||
| 10638 | .{ .v_f128, .insert }, | ||
| 10639 | dst_reg.to256(), | ||
| 10640 | dst_reg.to256(), | ||
| 10641 | dst_reg.to128(), | ||
| 10642 | Immediate.u(1), | ||
| 10643 | ); | ||
| 10644 | } | ||
| 10645 | } | ||
| 10646 | break :result .{ .register = dst_reg }; | ||
| 10647 | }, | ||
| 10648 | else => {}, | ||
| 10649 | }, | ||
| 10650 | 64 => switch (vector_ty.vectorLen()) { | ||
| 10651 | 1 => { | ||
| 10652 | if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; | ||
| 10653 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); | ||
| 10654 | try self.genSetReg(dst_reg, scalar_ty, src_mcv); | ||
| 10655 | break :result .{ .register = dst_reg }; | ||
| 10656 | }, | ||
| 10657 | 2 => { | ||
| 10658 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); | ||
| 10659 | if (self.hasFeature(.sse3)) { | ||
| 10660 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | ||
| 10661 | if (self.hasFeature(.avx)) .{ .v_, .movddup } else .{ ._, .movddup }, | ||
| 10662 | dst_reg.to128(), | ||
| 10663 | src_mcv.mem(.qword), | ||
| 10664 | ) else try self.asmRegisterRegister( | ||
| 10665 | if (self.hasFeature(.avx)) .{ .v_, .movddup } else .{ ._, .movddup }, | ||
| 10666 | dst_reg.to128(), | ||
| 10667 | (if (src_mcv.isRegister()) | ||
| 10668 | src_mcv.getReg().? | ||
| 10669 | else | ||
| 10670 | try self.copyToTmpRegister(scalar_ty, src_mcv)).to128(), | ||
| 10671 | ); | ||
| 10672 | break :result .{ .register = dst_reg }; | ||
| 10673 | } else try self.asmRegisterRegister( | ||
| 10674 | .{ ._ps, .movlh }, | ||
| 10675 | dst_reg.to128(), | ||
| 10676 | (if (src_mcv.isRegister()) | ||
| 10677 | src_mcv.getReg().? | ||
| 10678 | else | ||
| 10679 | try self.copyToTmpRegister(scalar_ty, src_mcv)).to128(), | ||
| 10680 | ); | ||
| 10681 | }, | ||
| 10682 | 3...4 => if (self.hasFeature(.avx)) { | ||
| 10683 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); | ||
| 10684 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | ||
| 10685 | .{ .v_sd, .broadcast }, | ||
| 10686 | dst_reg.to256(), | ||
| 10687 | src_mcv.mem(.qword), | ||
| 10688 | ) else { | ||
| 10689 | const src_reg = if (src_mcv.isRegister()) | ||
| 10690 | src_mcv.getReg().? | ||
| 10691 | else | ||
| 10692 | try self.copyToTmpRegister(scalar_ty, src_mcv); | ||
| 10693 | if (self.hasFeature(.avx2)) try self.asmRegisterRegister( | ||
| 10694 | .{ .v_sd, .broadcast }, | ||
| 10695 | dst_reg.to256(), | ||
| 10696 | src_reg.to128(), | ||
| 10697 | ) else { | ||
| 10698 | try self.asmRegisterRegister( | ||
| 10699 | .{ .v_, .movddup }, | ||
| 10700 | dst_reg.to128(), | ||
| 10701 | src_reg.to128(), | ||
| 10702 | ); | ||
| 10703 | try self.asmRegisterRegisterRegisterImmediate( | ||
| 10704 | .{ .v_f128, .insert }, | ||
| 10705 | dst_reg.to256(), | ||
| 10706 | dst_reg.to256(), | ||
| 10707 | dst_reg.to128(), | ||
| 10708 | Immediate.u(1), | ||
| 10709 | ); | ||
| 10710 | } | ||
| 10711 | } | ||
| 10712 | break :result .{ .register = dst_reg }; | ||
| 10713 | }, | ||
| 10714 | else => {}, | ||
| 10715 | }, | ||
| 10716 | 128 => switch (vector_ty.vectorLen()) { | ||
| 10717 | 1 => { | ||
| 10718 | if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; | ||
| 10719 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); | ||
| 10720 | try self.genSetReg(dst_reg, scalar_ty, src_mcv); | ||
| 10721 | break :result .{ .register = dst_reg }; | ||
| 10722 | }, | ||
| 10723 | 2 => if (self.hasFeature(.avx)) { | ||
| 10724 | const dst_reg = try self.register_manager.allocReg(inst, dst_rc); | ||
| 10725 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | ||
| 10726 | .{ .v_f128, .broadcast }, | ||
| 10727 | dst_reg.to256(), | ||
| 10728 | src_mcv.mem(.xword), | ||
| 10729 | ) else { | ||
| 10730 | const src_reg = if (src_mcv.isRegister()) | ||
| 10731 | src_mcv.getReg().? | ||
| 10732 | else | ||
| 10733 | try self.copyToTmpRegister(scalar_ty, src_mcv); | ||
| 10734 | try self.asmRegisterRegisterRegisterImmediate( | ||
| 10735 | .{ .v_f128, .insert }, | ||
| 10736 | dst_reg.to256(), | ||
| 10737 | src_reg.to256(), | ||
| 10738 | src_reg.to128(), | ||
| 10739 | Immediate.u(1), | ||
| 10740 | ); | ||
| 10741 | } | ||
| 10742 | break :result .{ .register = dst_reg }; | ||
| 10743 | }, | ||
| 10744 | else => {}, | ||
| 10745 | }, | ||
| 10746 | 16, 80 => {}, | ||
| 10747 | else => unreachable, | ||
| 10748 | }, | ||
| 10749 | } | ||
| 10750 | return self.fail("TODO implement airSplat for {}", .{ | ||
| 10751 | vector_ty.fmt(self.bin_file.options.module.?), | ||
| 10752 | }); | ||
| 10753 | }; | ||
| 10754 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | ||
| 9983 | } | 10755 | } |
| 9984 | 10756 | ||
| 9985 | fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | 10757 | fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -10142,9 +10914,46 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -10142,9 +10914,46 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 10142 | fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { | 10914 | fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { |
| 10143 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 10915 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 10144 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; | 10916 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| 10145 | _ = extra; | 10917 | const result: MCValue = result: { |
| 10146 | return self.fail("TODO implement airUnionInit for x86_64", .{}); | 10918 | const union_ty = self.air.typeOfIndex(inst); |
| 10147 | //return self.finishAir(inst, result, .{ extra.init, .none, .none }); | 10919 | const layout = union_ty.unionGetLayout(self.target.*); |
| 10920 | |||
| 10921 | const src_ty = self.air.typeOf(extra.init); | ||
| 10922 | const src_mcv = try self.resolveInst(extra.init); | ||
| 10923 | if (layout.tag_size == 0) { | ||
| 10924 | if (self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv; | ||
| 10925 | |||
| 10926 | const dst_mcv = try self.allocRegOrMem(inst, true); | ||
| 10927 | try self.genCopy(union_ty, dst_mcv, src_mcv); | ||
| 10928 | break :result dst_mcv; | ||
| 10929 | } | ||
| 10930 | |||
| 10931 | const dst_mcv = try self.allocRegOrMem(inst, false); | ||
| 10932 | |||
| 10933 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; | ||
| 10934 | const field_name = union_obj.fields.keys()[extra.field_index]; | ||
| 10935 | const tag_ty = union_ty.unionTagTypeSafety().?; | ||
| 10936 | const field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name).?); | ||
| 10937 | var tag_pl = Value.Payload.U32{ .base = .{ .tag = .enum_field_index }, .data = field_index }; | ||
| 10938 | const tag_val = Value.initPayload(&tag_pl.base); | ||
| 10939 | var tag_int_pl: Value.Payload.U64 = undefined; | ||
| 10940 | const tag_int_val = tag_val.enumToInt(tag_ty, &tag_int_pl); | ||
| 10941 | const tag_int = tag_int_val.toUnsignedInt(self.target.*); | ||
| 10942 | const tag_off = if (layout.tag_align < layout.payload_align) | ||
| 10943 | @intCast(i32, layout.payload_size) | ||
| 10944 | else | ||
| 10945 | 0; | ||
| 10946 | try self.genCopy(tag_ty, dst_mcv.address().offset(tag_off).deref(), .{ .immediate = tag_int }); | ||
| 10947 | |||
| 10948 | const pl_off = if (layout.tag_align < layout.payload_align) | ||
| 10949 | 0 | ||
| 10950 | else | ||
| 10951 | @intCast(i32, layout.tag_size); | ||
| 10952 | try self.genCopy(src_ty, dst_mcv.address().offset(pl_off).deref(), src_mcv); | ||
| 10953 | |||
| 10954 | break :result dst_mcv; | ||
| 10955 | }; | ||
| 10956 | return self.finishAir(inst, result, .{ extra.init, .none, .none }); | ||
| 10148 | } | 10957 | } |
| 10149 | 10958 | ||
| 10150 | fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void { | 10959 | fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void { |
| ... | @@ -10616,13 +11425,21 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { | ... | @@ -10616,13 +11425,21 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { |
| 10616 | reg.to64() | 11425 | reg.to64() |
| 10617 | else | 11426 | else |
| 10618 | unreachable, | 11427 | unreachable, |
| 10619 | .floating_point => if (size_bytes <= 16) | 11428 | .segment => if (size_bytes <= 2) |
| 11429 | reg | ||
| 11430 | else | ||
| 11431 | unreachable, | ||
| 11432 | .x87 => unreachable, | ||
| 11433 | .mmx => if (size_bytes <= 8) | ||
| 11434 | reg | ||
| 11435 | else | ||
| 11436 | unreachable, | ||
| 11437 | .sse => if (size_bytes <= 16) | ||
| 10620 | reg.to128() | 11438 | reg.to128() |
| 10621 | else if (size_bytes <= 32) | 11439 | else if (size_bytes <= 32) |
| 10622 | reg.to256() | 11440 | reg.to256() |
| 10623 | else | 11441 | else |
| 10624 | unreachable, | 11442 | unreachable, |
| 10625 | .segment => unreachable, | ||
| 10626 | }; | 11443 | }; |
| 10627 | } | 11444 | } |
| 10628 | 11445 |
src/arch/x86_64/Encoding.zig+127-75| ... | @@ -233,7 +233,6 @@ pub const Mnemonic = enum { | ... | @@ -233,7 +233,6 @@ pub const Mnemonic = enum { |
| 233 | cmpxchg, cmpxchg8b, cmpxchg16b, | 233 | cmpxchg, cmpxchg8b, cmpxchg16b, |
| 234 | cqo, cwd, cwde, | 234 | cqo, cwd, cwde, |
| 235 | div, | 235 | div, |
| 236 | fisttp, fld, | ||
| 237 | idiv, imul, int3, | 236 | idiv, imul, int3, |
| 238 | ja, jae, jb, jbe, jc, jrcxz, je, jg, jge, jl, jle, jna, jnae, jnb, jnbe, | 237 | ja, jae, jb, jbe, jc, jrcxz, je, jg, jge, jl, jle, jna, jnae, jnb, jnbe, |
| 239 | jnc, jne, jng, jnge, jnl, jnle, jno, jnp, jns, jnz, jo, jp, jpe, jpo, js, jz, | 238 | jnc, jne, jng, jnge, jnl, jnle, jno, jnp, jns, jnz, jo, jp, jpe, jpo, js, jz, |
| ... | @@ -259,21 +258,30 @@ pub const Mnemonic = enum { | ... | @@ -259,21 +258,30 @@ pub const Mnemonic = enum { |
| 259 | @"test", tzcnt, | 258 | @"test", tzcnt, |
| 260 | ud2, | 259 | ud2, |
| 261 | xadd, xchg, xor, | 260 | xadd, xchg, xor, |
| 261 | // X87 | ||
| 262 | fisttp, fld, | ||
| 262 | // MMX | 263 | // MMX |
| 263 | movd, | 264 | movd, movq, |
| 265 | paddb, paddd, paddq, paddsb, paddsw, paddusb, paddusw, paddw, | ||
| 266 | pand, pandn, por, pxor, | ||
| 267 | pmulhw, pmullw, | ||
| 268 | psubb, psubd, psubq, psubsb, psubsw, psubusb, psubusw, psubw, | ||
| 264 | // SSE | 269 | // SSE |
| 265 | addps, addss, | 270 | addps, addss, |
| 266 | andps, | 271 | andps, |
| 267 | andnps, | 272 | andnps, |
| 268 | cmpss, | 273 | cmpss, |
| 269 | cvtsi2ss, | 274 | cvtpi2ps, cvtps2pi, cvtsi2ss, cvtss2si, cvttps2pi, cvttss2si, |
| 270 | divps, divss, | 275 | divps, divss, |
| 271 | maxps, maxss, | 276 | maxps, maxss, |
| 272 | minps, minss, | 277 | minps, minss, |
| 273 | movaps, movhlps, movss, movups, | 278 | movaps, movhlps, movlhps, |
| 279 | movss, movups, | ||
| 274 | mulps, mulss, | 280 | mulps, mulss, |
| 275 | orps, | 281 | orps, |
| 276 | pextrw, pinsrw, | 282 | pextrw, pinsrw, |
| 283 | pmaxsw, pmaxub, pminsw, pminub, | ||
| 284 | shufps, | ||
| 277 | sqrtps, sqrtss, | 285 | sqrtps, sqrtss, |
| 278 | subps, subss, | 286 | subps, subss, |
| 279 | ucomiss, | 287 | ucomiss, |
| ... | @@ -283,12 +291,15 @@ pub const Mnemonic = enum { | ... | @@ -283,12 +291,15 @@ pub const Mnemonic = enum { |
| 283 | andpd, | 291 | andpd, |
| 284 | andnpd, | 292 | andnpd, |
| 285 | //cmpsd, | 293 | //cmpsd, |
| 286 | cvtsd2ss, cvtsi2sd, cvtss2sd, | 294 | cvtdq2pd, cvtdq2ps, cvtpd2dq, cvtpd2pi, cvtpd2ps, cvtpi2pd, |
| 295 | cvtps2dq, cvtps2pd, cvtsd2si, cvtsd2ss, cvtsi2sd, cvtss2sd, | ||
| 296 | cvttpd2dq, cvttpd2pi, cvttps2dq, cvttsd2si, | ||
| 287 | divpd, divsd, | 297 | divpd, divsd, |
| 288 | maxpd, maxsd, | 298 | maxpd, maxsd, |
| 289 | minpd, minsd, | 299 | minpd, minsd, |
| 290 | movapd, | 300 | movapd, |
| 291 | movq, //movd, movsd, | 301 | movdqa, movdqu, |
| 302 | //movsd, | ||
| 292 | movupd, | 303 | movupd, |
| 293 | mulpd, mulsd, | 304 | mulpd, mulsd, |
| 294 | orpd, | 305 | orpd, |
| ... | @@ -296,6 +307,7 @@ pub const Mnemonic = enum { | ... | @@ -296,6 +307,7 @@ pub const Mnemonic = enum { |
| 296 | psrld, psrlq, psrlw, | 307 | psrld, psrlq, psrlw, |
| 297 | punpckhbw, punpckhdq, punpckhqdq, punpckhwd, | 308 | punpckhbw, punpckhdq, punpckhqdq, punpckhwd, |
| 298 | punpcklbw, punpckldq, punpcklqdq, punpcklwd, | 309 | punpcklbw, punpckldq, punpcklqdq, punpcklwd, |
| 310 | shufpd, | ||
| 299 | sqrtpd, sqrtsd, | 311 | sqrtpd, sqrtsd, |
| 300 | subpd, subsd, | 312 | subpd, subsd, |
| 301 | ucomisd, | 313 | ucomisd, |
| ... | @@ -303,31 +315,57 @@ pub const Mnemonic = enum { | ... | @@ -303,31 +315,57 @@ pub const Mnemonic = enum { |
| 303 | // SSE3 | 315 | // SSE3 |
| 304 | movddup, movshdup, movsldup, | 316 | movddup, movshdup, movsldup, |
| 305 | // SSE4.1 | 317 | // SSE4.1 |
| 318 | extractps, | ||
| 319 | insertps, | ||
| 306 | pextrb, pextrd, pextrq, | 320 | pextrb, pextrd, pextrq, |
| 307 | pinsrb, pinsrd, pinsrq, | 321 | pinsrb, pinsrd, pinsrq, |
| 322 | pmaxsb, pmaxsd, pmaxud, pmaxuw, pminsb, pminsd, pminud, pminuw, | ||
| 323 | pmulld, | ||
| 308 | roundpd, roundps, roundsd, roundss, | 324 | roundpd, roundps, roundsd, roundss, |
| 309 | // AVX | 325 | // AVX |
| 310 | vaddpd, vaddps, vaddsd, vaddss, | 326 | vaddpd, vaddps, vaddsd, vaddss, |
| 311 | vcvtsd2ss, vcvtsi2sd, vcvtsi2ss, vcvtss2sd, | 327 | vandnpd, vandnps, vandpd, vandps, |
| 328 | vbroadcastf128, vbroadcastsd, vbroadcastss, | ||
| 329 | vcvtdq2pd, vcvtdq2ps, vcvtpd2dq, vcvtpd2ps, | ||
| 330 | vcvtps2dq, vcvtps2pd, vcvtsd2si, vcvtsd2ss, | ||
| 331 | vcvtsi2sd, vcvtsi2ss, vcvtss2sd, vcvtss2si, | ||
| 332 | vcvttpd2dq, vcvttps2dq, vcvttsd2si, vcvttss2si, | ||
| 312 | vdivpd, vdivps, vdivsd, vdivss, | 333 | vdivpd, vdivps, vdivsd, vdivss, |
| 334 | vextractf128, vextractps, | ||
| 335 | vinsertf128, vinsertps, | ||
| 313 | vmaxpd, vmaxps, vmaxsd, vmaxss, | 336 | vmaxpd, vmaxps, vmaxsd, vmaxss, |
| 314 | vminpd, vminps, vminsd, vminss, | 337 | vminpd, vminps, vminsd, vminss, |
| 315 | vmovapd, vmovaps, | 338 | vmovapd, vmovaps, |
| 316 | vmovddup, vmovhlps, | 339 | vmovd, |
| 340 | vmovddup, | ||
| 341 | vmovdqa, vmovdqu, | ||
| 342 | vmovhlps, vmovlhps, | ||
| 343 | vmovq, | ||
| 317 | vmovsd, | 344 | vmovsd, |
| 318 | vmovshdup, vmovsldup, | 345 | vmovshdup, vmovsldup, |
| 319 | vmovss, | 346 | vmovss, |
| 320 | vmovupd, vmovups, | 347 | vmovupd, vmovups, |
| 321 | vmulpd, vmulps, vmulsd, vmulss, | 348 | vmulpd, vmulps, vmulsd, vmulss, |
| 349 | vorpd, vorps, | ||
| 350 | vpaddb, vpaddd, vpaddq, vpaddsb, vpaddsw, vpaddusb, vpaddusw, vpaddw, | ||
| 351 | vpand, vpandn, | ||
| 322 | vpextrb, vpextrd, vpextrq, vpextrw, | 352 | vpextrb, vpextrd, vpextrq, vpextrw, |
| 323 | vpinsrb, vpinsrd, vpinsrq, vpinsrw, | 353 | vpinsrb, vpinsrd, vpinsrq, vpinsrw, |
| 354 | vpmaxsb, vpmaxsd, vpmaxsw, vpmaxub, vpmaxud, vpmaxuw, | ||
| 355 | vpminsb, vpminsd, vpminsw, vpminub, vpminud, vpminuw, | ||
| 356 | vpmulhw, vpmulld, vpmullw, | ||
| 357 | vpor, | ||
| 324 | vpshufhw, vpshuflw, | 358 | vpshufhw, vpshuflw, |
| 325 | vpsrld, vpsrlq, vpsrlw, | 359 | vpsrld, vpsrlq, vpsrlw, |
| 360 | vpsubb, vpsubd, vpsubq, vpsubsb, vpsubsw, vpsubusb, vpsubusw, vpsubw, | ||
| 326 | vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd, | 361 | vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd, |
| 327 | vpunpcklbw, vpunpckldq, vpunpcklqdq, vpunpcklwd, | 362 | vpunpcklbw, vpunpckldq, vpunpcklqdq, vpunpcklwd, |
| 363 | vpxor, | ||
| 328 | vroundpd, vroundps, vroundsd, vroundss, | 364 | vroundpd, vroundps, vroundsd, vroundss, |
| 365 | vshufpd, vshufps, | ||
| 329 | vsqrtpd, vsqrtps, vsqrtsd, vsqrtss, | 366 | vsqrtpd, vsqrtps, vsqrtsd, vsqrtss, |
| 330 | vsubpd, vsubps, vsubsd, vsubss, | 367 | vsubpd, vsubps, vsubsd, vsubss, |
| 368 | vxorpd, vxorps, | ||
| 331 | // F16C | 369 | // F16C |
| 332 | vcvtph2ps, vcvtps2ph, | 370 | vcvtph2ps, vcvtps2ph, |
| 333 | // FMA | 371 | // FMA |
| ... | @@ -368,80 +406,84 @@ pub const Op = enum { | ... | @@ -368,80 +406,84 @@ pub const Op = enum { |
| 368 | m, | 406 | m, |
| 369 | moffs, | 407 | moffs, |
| 370 | sreg, | 408 | sreg, |
| 409 | st, mm, mm_m64, | ||
| 371 | xmm, xmm_m32, xmm_m64, xmm_m128, | 410 | xmm, xmm_m32, xmm_m64, xmm_m128, |
| 372 | ymm, ymm_m256, | 411 | ymm, ymm_m256, |
| 373 | // zig fmt: on | 412 | // zig fmt: on |
| 374 | 413 | ||
| 375 | pub fn fromOperand(operand: Instruction.Operand) Op { | 414 | pub fn fromOperand(operand: Instruction.Operand) Op { |
| 376 | switch (operand) { | 415 | return switch (operand) { |
| 377 | .none => return .none, | 416 | .none => .none, |
| 378 | 417 | ||
| 379 | .reg => |reg| { | 418 | .reg => |reg| switch (reg.class()) { |
| 380 | switch (reg.class()) { | 419 | .general_purpose => if (reg.to64() == .rax) |
| 381 | .segment => return .sreg, | 420 | switch (reg) { |
| 382 | .floating_point => return switch (reg.bitSize()) { | 421 | .al => .al, |
| 383 | 128 => .xmm, | 422 | .ax => .ax, |
| 384 | 256 => .ymm, | 423 | .eax => .eax, |
| 424 | .rax => .rax, | ||
| 385 | else => unreachable, | 425 | else => unreachable, |
| 386 | }, | 426 | } |
| 387 | .general_purpose => { | 427 | else if (reg == .cl) |
| 388 | if (reg.to64() == .rax) return switch (reg) { | 428 | .cl |
| 389 | .al => .al, | 429 | else switch (reg.bitSize()) { |
| 390 | .ax => .ax, | 430 | 8 => .r8, |
| 391 | .eax => .eax, | 431 | 16 => .r16, |
| 392 | .rax => .rax, | 432 | 32 => .r32, |
| 393 | else => unreachable, | 433 | 64 => .r64, |
| 394 | }; | 434 | else => unreachable, |
| 395 | if (reg == .cl) return .cl; | 435 | }, |
| 396 | return switch (reg.bitSize()) { | 436 | .segment => .sreg, |
| 397 | 8 => .r8, | 437 | .x87 => .st, |
| 398 | 16 => .r16, | 438 | .mmx => .mm, |
| 399 | 32 => .r32, | 439 | .sse => switch (reg.bitSize()) { |
| 400 | 64 => .r64, | 440 | 128 => .xmm, |
| 401 | else => unreachable, | 441 | 256 => .ymm, |
| 402 | }; | 442 | else => unreachable, |
| 403 | }, | 443 | }, |
| 404 | } | ||
| 405 | }, | 444 | }, |
| 406 | 445 | ||
| 407 | .mem => |mem| switch (mem) { | 446 | .mem => |mem| switch (mem) { |
| 408 | .moffs => return .moffs, | 447 | .moffs => .moffs, |
| 409 | .sib, .rip => { | 448 | .sib, .rip => switch (mem.bitSize()) { |
| 410 | const bit_size = mem.bitSize(); | 449 | 8 => .m8, |
| 411 | return switch (bit_size) { | 450 | 16 => .m16, |
| 412 | 8 => .m8, | 451 | 32 => .m32, |
| 413 | 16 => .m16, | 452 | 64 => .m64, |
| 414 | 32 => .m32, | 453 | 80 => .m80, |
| 415 | 64 => .m64, | 454 | 128 => .m128, |
| 416 | 80 => .m80, | 455 | 256 => .m256, |
| 417 | 128 => .m128, | 456 | else => unreachable, |
| 418 | 256 => .m256, | ||
| 419 | else => unreachable, | ||
| 420 | }; | ||
| 421 | }, | 457 | }, |
| 422 | }, | 458 | }, |
| 423 | 459 | ||
| 424 | .imm => |imm| { | 460 | .imm => |imm| switch (imm) { |
| 425 | switch (imm) { | 461 | .signed => |x| if (x == 1) |
| 426 | .signed => |x| { | 462 | .unity |
| 427 | if (x == 1) return .unity; | 463 | else if (math.cast(i8, x)) |_| |
| 428 | if (math.cast(i8, x)) |_| return .imm8s; | 464 | .imm8s |
| 429 | if (math.cast(i16, x)) |_| return .imm16s; | 465 | else if (math.cast(i16, x)) |_| |
| 430 | return .imm32s; | 466 | .imm16s |
| 431 | }, | 467 | else |
| 432 | .unsigned => |x| { | 468 | .imm32s, |
| 433 | if (x == 1) return .unity; | 469 | .unsigned => |x| if (x == 1) |
| 434 | if (math.cast(i8, x)) |_| return .imm8s; | 470 | .unity |
| 435 | if (math.cast(u8, x)) |_| return .imm8; | 471 | else if (math.cast(i8, x)) |_| |
| 436 | if (math.cast(i16, x)) |_| return .imm16s; | 472 | .imm8s |
| 437 | if (math.cast(u16, x)) |_| return .imm16; | 473 | else if (math.cast(u8, x)) |_| |
| 438 | if (math.cast(i32, x)) |_| return .imm32s; | 474 | .imm8 |
| 439 | if (math.cast(u32, x)) |_| return .imm32; | 475 | else if (math.cast(i16, x)) |_| |
| 440 | return .imm64; | 476 | .imm16s |
| 441 | }, | 477 | else if (math.cast(u16, x)) |_| |
| 442 | } | 478 | .imm16 |
| 479 | else if (math.cast(i32, x)) |_| | ||
| 480 | .imm32s | ||
| 481 | else if (math.cast(u32, x)) |_| | ||
| 482 | .imm32 | ||
| 483 | else | ||
| 484 | .imm64, | ||
| 443 | }, | 485 | }, |
| 444 | } | 486 | }; |
| 445 | } | 487 | } |
| 446 | 488 | ||
| 447 | pub fn immBitSize(op: Op) u64 { | 489 | pub fn immBitSize(op: Op) u64 { |
| ... | @@ -451,6 +493,7 @@ pub const Op = enum { | ... | @@ -451,6 +493,7 @@ pub const Op = enum { |
| 451 | .ax, .r16, .rm16 => unreachable, | 493 | .ax, .r16, .rm16 => unreachable, |
| 452 | .eax, .r32, .rm32, .r32_m16 => unreachable, | 494 | .eax, .r32, .rm32, .r32_m16 => unreachable, |
| 453 | .rax, .r64, .rm64, .r64_m16 => unreachable, | 495 | .rax, .r64, .rm64, .r64_m16 => unreachable, |
| 496 | .st, .mm, .mm_m64 => unreachable, | ||
| 454 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => unreachable, | 497 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => unreachable, |
| 455 | .ymm, .ymm_m256 => unreachable, | 498 | .ymm, .ymm_m256 => unreachable, |
| 456 | .m8, .m16, .m32, .m64, .m80, .m128, .m256 => unreachable, | 499 | .m8, .m16, .m32, .m64, .m80, .m128, .m256 => unreachable, |
| ... | @@ -471,7 +514,8 @@ pub const Op = enum { | ... | @@ -471,7 +514,8 @@ pub const Op = enum { |
| 471 | .al, .cl, .r8, .rm8 => 8, | 514 | .al, .cl, .r8, .rm8 => 8, |
| 472 | .ax, .r16, .rm16 => 16, | 515 | .ax, .r16, .rm16 => 16, |
| 473 | .eax, .r32, .rm32, .r32_m8, .r32_m16 => 32, | 516 | .eax, .r32, .rm32, .r32_m8, .r32_m16 => 32, |
| 474 | .rax, .r64, .rm64, .r64_m16 => 64, | 517 | .rax, .r64, .rm64, .r64_m16, .mm, .mm_m64 => 64, |
| 518 | .st => 80, | ||
| 475 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => 128, | 519 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => 128, |
| 476 | .ymm, .ymm_m256 => 256, | 520 | .ymm, .ymm_m256 => 256, |
| 477 | }; | 521 | }; |
| ... | @@ -482,11 +526,11 @@ pub const Op = enum { | ... | @@ -482,11 +526,11 @@ pub const Op = enum { |
| 482 | .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable, | 526 | .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable, |
| 483 | .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s, .imm64 => unreachable, | 527 | .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s, .imm64 => unreachable, |
| 484 | .rel8, .rel16, .rel32 => unreachable, | 528 | .rel8, .rel16, .rel32 => unreachable, |
| 485 | .al, .cl, .r8, .ax, .r16, .eax, .r32, .rax, .r64, .xmm, .ymm => unreachable, | 529 | .al, .cl, .r8, .ax, .r16, .eax, .r32, .rax, .r64, .st, .mm, .xmm, .ymm => unreachable, |
| 486 | .m8, .rm8, .r32_m8 => 8, | 530 | .m8, .rm8, .r32_m8 => 8, |
| 487 | .m16, .rm16, .r32_m16, .r64_m16 => 16, | 531 | .m16, .rm16, .r32_m16, .r64_m16 => 16, |
| 488 | .m32, .rm32, .xmm_m32 => 32, | 532 | .m32, .rm32, .xmm_m32 => 32, |
| 489 | .m64, .rm64, .xmm_m64 => 64, | 533 | .m64, .rm64, .mm_m64, .xmm_m64 => 64, |
| 490 | .m80 => 80, | 534 | .m80 => 80, |
| 491 | .m128, .xmm_m128 => 128, | 535 | .m128, .xmm_m128 => 128, |
| 492 | .m256, .ymm_m256 => 256, | 536 | .m256, .ymm_m256 => 256, |
| ... | @@ -513,6 +557,7 @@ pub const Op = enum { | ... | @@ -513,6 +557,7 @@ pub const Op = enum { |
| 513 | .r8, .r16, .r32, .r64, | 557 | .r8, .r16, .r32, .r64, |
| 514 | .rm8, .rm16, .rm32, .rm64, | 558 | .rm8, .rm16, .rm32, .rm64, |
| 515 | .r32_m8, .r32_m16, .r64_m16, | 559 | .r32_m8, .r32_m16, .r64_m16, |
| 560 | .st, .mm, .mm_m64, | ||
| 516 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128, | 561 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128, |
| 517 | .ymm, .ymm_m256, | 562 | .ymm, .ymm_m256, |
| 518 | => true, | 563 | => true, |
| ... | @@ -541,6 +586,7 @@ pub const Op = enum { | ... | @@ -541,6 +586,7 @@ pub const Op = enum { |
| 541 | .r32_m8, .r32_m16, .r64_m16, | 586 | .r32_m8, .r32_m16, .r64_m16, |
| 542 | .m8, .m16, .m32, .m64, .m80, .m128, .m256, | 587 | .m8, .m16, .m32, .m64, .m80, .m128, .m256, |
| 543 | .m, | 588 | .m, |
| 589 | .mm_m64, | ||
| 544 | .xmm_m32, .xmm_m64, .xmm_m128, | 590 | .xmm_m32, .xmm_m64, .xmm_m128, |
| 545 | .ymm_m256, | 591 | .ymm_m256, |
| 546 | => true, | 592 | => true, |
| ... | @@ -564,8 +610,10 @@ pub const Op = enum { | ... | @@ -564,8 +610,10 @@ pub const Op = enum { |
| 564 | .rm8, .rm16, .rm32, .rm64 => .general_purpose, | 610 | .rm8, .rm16, .rm32, .rm64 => .general_purpose, |
| 565 | .r32_m8, .r32_m16, .r64_m16 => .general_purpose, | 611 | .r32_m8, .r32_m16, .r64_m16 => .general_purpose, |
| 566 | .sreg => .segment, | 612 | .sreg => .segment, |
| 567 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => .floating_point, | 613 | .st => .x87, |
| 568 | .ymm, .ymm_m256 => .floating_point, | 614 | .mm, .mm_m64 => .mmx, |
| 615 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => .sse, | ||
| 616 | .ymm, .ymm_m256 => .sse, | ||
| 569 | }; | 617 | }; |
| 570 | } | 618 | } |
| 571 | 619 | ||
| ... | @@ -682,8 +730,12 @@ pub const Feature = enum { | ... | @@ -682,8 +730,12 @@ pub const Feature = enum { |
| 682 | none, | 730 | none, |
| 683 | avx, | 731 | avx, |
| 684 | avx2, | 732 | avx2, |
| 733 | bmi, | ||
| 685 | f16c, | 734 | f16c, |
| 686 | fma, | 735 | fma, |
| 736 | lzcnt, | ||
| 737 | movbe, | ||
| 738 | popcnt, | ||
| 687 | sse, | 739 | sse, |
| 688 | sse2, | 740 | sse2, |
| 689 | sse3, | 741 | sse3, |
| ... | @@ -705,7 +757,7 @@ fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Op | ... | @@ -705,7 +757,7 @@ fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Op |
| 705 | } | 757 | } |
| 706 | 758 | ||
| 707 | const mnemonic_to_encodings_map = init: { | 759 | const mnemonic_to_encodings_map = init: { |
| 708 | @setEvalBranchQuota(20_000); | 760 | @setEvalBranchQuota(30_000); |
| 709 | const encodings = @import("encodings.zig"); | 761 | const encodings = @import("encodings.zig"); |
| 710 | var entries = encodings.table; | 762 | var entries = encodings.table; |
| 711 | std.sort.sort(encodings.Entry, &entries, {}, struct { | 763 | std.sort.sort(encodings.Entry, &entries, {}, struct { |
src/arch/x86_64/Lower.zig+115-16| ... | @@ -9,19 +9,33 @@ result_insts_len: u8 = undefined, | ... | @@ -9,19 +9,33 @@ result_insts_len: u8 = undefined, |
| 9 | result_relocs_len: u8 = undefined, | 9 | result_relocs_len: u8 = undefined, |
| 10 | result_insts: [ | 10 | result_insts: [ |
| 11 | std.mem.max(usize, &.{ | 11 | std.mem.max(usize, &.{ |
| 12 | 1, // non-pseudo instructions | ||
| 12 | 2, // cmovcc: cmovcc \ cmovcc | 13 | 2, // cmovcc: cmovcc \ cmovcc |
| 13 | 3, // setcc: setcc \ setcc \ logicop | 14 | 3, // setcc: setcc \ setcc \ logicop |
| 14 | 2, // jcc: jcc \ jcc | 15 | 2, // jcc: jcc \ jcc |
| 16 | pseudo_probe_align_insts, | ||
| 17 | pseudo_probe_adjust_unrolled_max_insts, | ||
| 18 | pseudo_probe_adjust_setup_insts, | ||
| 19 | pseudo_probe_adjust_loop_insts, | ||
| 15 | abi.Win64.callee_preserved_regs.len, // push_regs/pop_regs | 20 | abi.Win64.callee_preserved_regs.len, // push_regs/pop_regs |
| 16 | abi.SysV.callee_preserved_regs.len, // push_regs/pop_regs | 21 | abi.SysV.callee_preserved_regs.len, // push_regs/pop_regs |
| 17 | }) | 22 | }) |
| 18 | ]Instruction = undefined, | 23 | ]Instruction = undefined, |
| 19 | result_relocs: [ | 24 | result_relocs: [ |
| 20 | std.mem.max(usize, &.{ | 25 | std.mem.max(usize, &.{ |
| 26 | 1, // jmp/jcc/call/mov/lea: jmp/jcc/call/mov/lea | ||
| 21 | 2, // jcc: jcc \ jcc | 27 | 2, // jcc: jcc \ jcc |
| 28 | 2, // test \ jcc \ probe \ sub \ jmp | ||
| 29 | 1, // probe \ sub \ jcc | ||
| 22 | }) | 30 | }) |
| 23 | ]Reloc = undefined, | 31 | ]Reloc = undefined, |
| 24 | 32 | ||
| 33 | pub const pseudo_probe_align_insts = 5; // test \ jcc \ probe \ sub \ jmp | ||
| 34 | pub const pseudo_probe_adjust_unrolled_max_insts = | ||
| 35 | pseudo_probe_adjust_setup_insts + pseudo_probe_adjust_loop_insts; | ||
| 36 | pub const pseudo_probe_adjust_setup_insts = 2; // mov \ sub | ||
| 37 | pub const pseudo_probe_adjust_loop_insts = 3; // probe \ sub \ jcc | ||
| 38 | |||
| 25 | pub const Error = error{ | 39 | pub const Error = error{ |
| 26 | OutOfMemory, | 40 | OutOfMemory, |
| 27 | LowerFail, | 41 | LowerFail, |
| ... | @@ -62,6 +76,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -62,6 +76,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 62 | else => try lower.generic(inst), | 76 | else => try lower.generic(inst), |
| 63 | .pseudo => switch (inst.ops) { | 77 | .pseudo => switch (inst.ops) { |
| 64 | .pseudo_cmov_z_and_np_rr => { | 78 | .pseudo_cmov_z_and_np_rr => { |
| 79 | assert(inst.data.rr.fixes == ._); | ||
| 65 | try lower.emit(.none, .cmovnz, &.{ | 80 | try lower.emit(.none, .cmovnz, &.{ |
| 66 | .{ .reg = inst.data.rr.r2 }, | 81 | .{ .reg = inst.data.rr.r2 }, |
| 67 | .{ .reg = inst.data.rr.r1 }, | 82 | .{ .reg = inst.data.rr.r1 }, |
| ... | @@ -72,6 +87,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -72,6 +87,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 72 | }); | 87 | }); |
| 73 | }, | 88 | }, |
| 74 | .pseudo_cmov_nz_or_p_rr => { | 89 | .pseudo_cmov_nz_or_p_rr => { |
| 90 | assert(inst.data.rr.fixes == ._); | ||
| 75 | try lower.emit(.none, .cmovnz, &.{ | 91 | try lower.emit(.none, .cmovnz, &.{ |
| 76 | .{ .reg = inst.data.rr.r1 }, | 92 | .{ .reg = inst.data.rr.r1 }, |
| 77 | .{ .reg = inst.data.rr.r2 }, | 93 | .{ .reg = inst.data.rr.r2 }, |
| ... | @@ -84,6 +100,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -84,6 +100,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 84 | .pseudo_cmov_nz_or_p_rm_sib, | 100 | .pseudo_cmov_nz_or_p_rm_sib, |
| 85 | .pseudo_cmov_nz_or_p_rm_rip, | 101 | .pseudo_cmov_nz_or_p_rm_rip, |
| 86 | => { | 102 | => { |
| 103 | assert(inst.data.rx.fixes == ._); | ||
| 87 | try lower.emit(.none, .cmovnz, &.{ | 104 | try lower.emit(.none, .cmovnz, &.{ |
| 88 | .{ .reg = inst.data.rx.r1 }, | 105 | .{ .reg = inst.data.rx.r1 }, |
| 89 | .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) }, | 106 | .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) }, |
| ... | @@ -94,58 +111,63 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -94,58 +111,63 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 94 | }); | 111 | }); |
| 95 | }, | 112 | }, |
| 96 | .pseudo_set_z_and_np_r => { | 113 | .pseudo_set_z_and_np_r => { |
| 114 | assert(inst.data.rr.fixes == ._); | ||
| 97 | try lower.emit(.none, .setz, &.{ | 115 | try lower.emit(.none, .setz, &.{ |
| 98 | .{ .reg = inst.data.r_scratch.r1 }, | 116 | .{ .reg = inst.data.rr.r1 }, |
| 99 | }); | 117 | }); |
| 100 | try lower.emit(.none, .setnp, &.{ | 118 | try lower.emit(.none, .setnp, &.{ |
| 101 | .{ .reg = inst.data.r_scratch.scratch_reg }, | 119 | .{ .reg = inst.data.rr.r2 }, |
| 102 | }); | 120 | }); |
| 103 | try lower.emit(.none, .@"and", &.{ | 121 | try lower.emit(.none, .@"and", &.{ |
| 104 | .{ .reg = inst.data.r_scratch.r1 }, | 122 | .{ .reg = inst.data.rr.r1 }, |
| 105 | .{ .reg = inst.data.r_scratch.scratch_reg }, | 123 | .{ .reg = inst.data.rr.r2 }, |
| 106 | }); | 124 | }); |
| 107 | }, | 125 | }, |
| 108 | .pseudo_set_z_and_np_m_sib, | 126 | .pseudo_set_z_and_np_m_sib, |
| 109 | .pseudo_set_z_and_np_m_rip, | 127 | .pseudo_set_z_and_np_m_rip, |
| 110 | => { | 128 | => { |
| 129 | assert(inst.data.rx.fixes == ._); | ||
| 111 | try lower.emit(.none, .setz, &.{ | 130 | try lower.emit(.none, .setz, &.{ |
| 112 | .{ .mem = lower.mem(inst.ops, inst.data.x_scratch.payload) }, | 131 | .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) }, |
| 113 | }); | 132 | }); |
| 114 | try lower.emit(.none, .setnp, &.{ | 133 | try lower.emit(.none, .setnp, &.{ |
| 115 | .{ .reg = inst.data.x_scratch.scratch_reg }, | 134 | .{ .reg = inst.data.rx.r1 }, |
| 116 | }); | 135 | }); |
| 117 | try lower.emit(.none, .@"and", &.{ | 136 | try lower.emit(.none, .@"and", &.{ |
| 118 | .{ .mem = lower.mem(inst.ops, inst.data.x_scratch.payload) }, | 137 | .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) }, |
| 119 | .{ .reg = inst.data.x_scratch.scratch_reg }, | 138 | .{ .reg = inst.data.rx.r1 }, |
| 120 | }); | 139 | }); |
| 121 | }, | 140 | }, |
| 122 | .pseudo_set_nz_or_p_r => { | 141 | .pseudo_set_nz_or_p_r => { |
| 142 | assert(inst.data.rr.fixes == ._); | ||
| 123 | try lower.emit(.none, .setnz, &.{ | 143 | try lower.emit(.none, .setnz, &.{ |
| 124 | .{ .reg = inst.data.r_scratch.r1 }, | 144 | .{ .reg = inst.data.rr.r1 }, |
| 125 | }); | 145 | }); |
| 126 | try lower.emit(.none, .setp, &.{ | 146 | try lower.emit(.none, .setp, &.{ |
| 127 | .{ .reg = inst.data.r_scratch.scratch_reg }, | 147 | .{ .reg = inst.data.rr.r2 }, |
| 128 | }); | 148 | }); |
| 129 | try lower.emit(.none, .@"or", &.{ | 149 | try lower.emit(.none, .@"or", &.{ |
| 130 | .{ .reg = inst.data.r_scratch.r1 }, | 150 | .{ .reg = inst.data.rr.r1 }, |
| 131 | .{ .reg = inst.data.r_scratch.scratch_reg }, | 151 | .{ .reg = inst.data.rr.r2 }, |
| 132 | }); | 152 | }); |
| 133 | }, | 153 | }, |
| 134 | .pseudo_set_nz_or_p_m_sib, | 154 | .pseudo_set_nz_or_p_m_sib, |
| 135 | .pseudo_set_nz_or_p_m_rip, | 155 | .pseudo_set_nz_or_p_m_rip, |
| 136 | => { | 156 | => { |
| 157 | assert(inst.data.rx.fixes == ._); | ||
| 137 | try lower.emit(.none, .setnz, &.{ | 158 | try lower.emit(.none, .setnz, &.{ |
| 138 | .{ .mem = lower.mem(inst.ops, inst.data.x_scratch.payload) }, | 159 | .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) }, |
| 139 | }); | 160 | }); |
| 140 | try lower.emit(.none, .setp, &.{ | 161 | try lower.emit(.none, .setp, &.{ |
| 141 | .{ .reg = inst.data.x_scratch.scratch_reg }, | 162 | .{ .reg = inst.data.rx.r1 }, |
| 142 | }); | 163 | }); |
| 143 | try lower.emit(.none, .@"or", &.{ | 164 | try lower.emit(.none, .@"or", &.{ |
| 144 | .{ .mem = lower.mem(inst.ops, inst.data.x_scratch.payload) }, | 165 | .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) }, |
| 145 | .{ .reg = inst.data.x_scratch.scratch_reg }, | 166 | .{ .reg = inst.data.rx.r1 }, |
| 146 | }); | 167 | }); |
| 147 | }, | 168 | }, |
| 148 | .pseudo_j_z_and_np_inst => { | 169 | .pseudo_j_z_and_np_inst => { |
| 170 | assert(inst.data.inst.fixes == ._); | ||
| 149 | try lower.emit(.none, .jnz, &.{ | 171 | try lower.emit(.none, .jnz, &.{ |
| 150 | .{ .imm = lower.reloc(.{ .inst = index + 1 }) }, | 172 | .{ .imm = lower.reloc(.{ .inst = index + 1 }) }, |
| 151 | }); | 173 | }); |
| ... | @@ -154,6 +176,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -154,6 +176,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 154 | }); | 176 | }); |
| 155 | }, | 177 | }, |
| 156 | .pseudo_j_nz_or_p_inst => { | 178 | .pseudo_j_nz_or_p_inst => { |
| 179 | assert(inst.data.inst.fixes == ._); | ||
| 157 | try lower.emit(.none, .jnz, &.{ | 180 | try lower.emit(.none, .jnz, &.{ |
| 158 | .{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }) }, | 181 | .{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }) }, |
| 159 | }); | 182 | }); |
| ... | @@ -162,6 +185,78 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -162,6 +185,78 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 162 | }); | 185 | }); |
| 163 | }, | 186 | }, |
| 164 | 187 | ||
| 188 | .pseudo_probe_align_ri_s => { | ||
| 189 | try lower.emit(.none, .@"test", &.{ | ||
| 190 | .{ .reg = inst.data.ri.r1 }, | ||
| 191 | .{ .imm = Immediate.s(@bitCast(i32, inst.data.ri.i)) }, | ||
| 192 | }); | ||
| 193 | try lower.emit(.none, .jz, &.{ | ||
| 194 | .{ .imm = lower.reloc(.{ .inst = index + 1 }) }, | ||
| 195 | }); | ||
| 196 | try lower.emit(.none, .lea, &.{ | ||
| 197 | .{ .reg = inst.data.ri.r1 }, | ||
| 198 | .{ .mem = Memory.sib(.qword, .{ | ||
| 199 | .base = .{ .reg = inst.data.ri.r1 }, | ||
| 200 | .disp = -page_size, | ||
| 201 | }) }, | ||
| 202 | }); | ||
| 203 | try lower.emit(.none, .@"test", &.{ | ||
| 204 | .{ .mem = Memory.sib(.dword, .{ | ||
| 205 | .base = .{ .reg = inst.data.ri.r1 }, | ||
| 206 | }) }, | ||
| 207 | .{ .reg = inst.data.ri.r1.to32() }, | ||
| 208 | }); | ||
| 209 | try lower.emit(.none, .jmp, &.{ | ||
| 210 | .{ .imm = lower.reloc(.{ .inst = index }) }, | ||
| 211 | }); | ||
| 212 | assert(lower.result_insts_len == pseudo_probe_align_insts); | ||
| 213 | }, | ||
| 214 | .pseudo_probe_adjust_unrolled_ri_s => { | ||
| 215 | var offset = page_size; | ||
| 216 | while (offset < @bitCast(i32, inst.data.ri.i)) : (offset += page_size) { | ||
| 217 | try lower.emit(.none, .@"test", &.{ | ||
| 218 | .{ .mem = Memory.sib(.dword, .{ | ||
| 219 | .base = .{ .reg = inst.data.ri.r1 }, | ||
| 220 | .disp = -offset, | ||
| 221 | }) }, | ||
| 222 | .{ .reg = inst.data.ri.r1.to32() }, | ||
| 223 | }); | ||
| 224 | } | ||
| 225 | try lower.emit(.none, .sub, &.{ | ||
| 226 | .{ .reg = inst.data.ri.r1 }, | ||
| 227 | .{ .imm = Immediate.s(@bitCast(i32, inst.data.ri.i)) }, | ||
| 228 | }); | ||
| 229 | assert(lower.result_insts_len <= pseudo_probe_adjust_unrolled_max_insts); | ||
| 230 | }, | ||
| 231 | .pseudo_probe_adjust_setup_rri_s => { | ||
| 232 | try lower.emit(.none, .mov, &.{ | ||
| 233 | .{ .reg = inst.data.rri.r2.to32() }, | ||
| 234 | .{ .imm = Immediate.s(@bitCast(i32, inst.data.rri.i)) }, | ||
| 235 | }); | ||
| 236 | try lower.emit(.none, .sub, &.{ | ||
| 237 | .{ .reg = inst.data.rri.r1 }, | ||
| 238 | .{ .reg = inst.data.rri.r2 }, | ||
| 239 | }); | ||
| 240 | assert(lower.result_insts_len == pseudo_probe_adjust_setup_insts); | ||
| 241 | }, | ||
| 242 | .pseudo_probe_adjust_loop_rr => { | ||
| 243 | try lower.emit(.none, .@"test", &.{ | ||
| 244 | .{ .mem = Memory.sib(.dword, .{ | ||
| 245 | .base = .{ .reg = inst.data.rr.r1 }, | ||
| 246 | .scale_index = .{ .scale = 1, .index = inst.data.rr.r2 }, | ||
| 247 | .disp = -page_size, | ||
| 248 | }) }, | ||
| 249 | .{ .reg = inst.data.rr.r1.to32() }, | ||
| 250 | }); | ||
| 251 | try lower.emit(.none, .sub, &.{ | ||
| 252 | .{ .reg = inst.data.rr.r2 }, | ||
| 253 | .{ .imm = Immediate.s(page_size) }, | ||
| 254 | }); | ||
| 255 | try lower.emit(.none, .jae, &.{ | ||
| 256 | .{ .imm = lower.reloc(.{ .inst = index }) }, | ||
| 257 | }); | ||
| 258 | assert(lower.result_insts_len == pseudo_probe_adjust_loop_insts); | ||
| 259 | }, | ||
| 165 | .pseudo_push_reg_list => try lower.pushPopRegList(.push, inst), | 260 | .pseudo_push_reg_list => try lower.pushPopRegList(.push, inst), |
| 166 | .pseudo_pop_reg_list => try lower.pushPopRegList(.pop, inst), | 261 | .pseudo_pop_reg_list => try lower.pushPopRegList(.pop, inst), |
| 167 | 262 | ||
| ... | @@ -300,6 +395,8 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { | ... | @@ -300,6 +395,8 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 300 | else | 395 | else |
| 301 | .none, | 396 | .none, |
| 302 | }, mnemonic: { | 397 | }, mnemonic: { |
| 398 | @setEvalBranchQuota(2_000); | ||
| 399 | |||
| 303 | comptime var max_len = 0; | 400 | comptime var max_len = 0; |
| 304 | inline for (@typeInfo(Mnemonic).Enum.fields) |field| max_len = @max(field.name.len, max_len); | 401 | inline for (@typeInfo(Mnemonic).Enum.fields) |field| max_len = @max(field.name.len, max_len); |
| 305 | var buf: [max_len]u8 = undefined; | 402 | var buf: [max_len]u8 = undefined; |
| ... | @@ -438,6 +535,8 @@ fn pushPopRegList(lower: *Lower, comptime mnemonic: Mnemonic, inst: Mir.Inst) Er | ... | @@ -438,6 +535,8 @@ fn pushPopRegList(lower: *Lower, comptime mnemonic: Mnemonic, inst: Mir.Inst) Er |
| 438 | }}); | 535 | }}); |
| 439 | } | 536 | } |
| 440 | 537 | ||
| 538 | const page_size: i32 = 1 << 12; | ||
| 539 | |||
| 441 | const abi = @import("abi.zig"); | 540 | const abi = @import("abi.zig"); |
| 442 | const assert = std.debug.assert; | 541 | const assert = std.debug.assert; |
| 443 | const bits = @import("bits.zig"); | 542 | const bits = @import("bits.zig"); |
src/arch/x86_64/Mir.zig+108-24| ... | @@ -236,6 +236,14 @@ pub const Inst = struct { | ... | @@ -236,6 +236,14 @@ pub const Inst = struct { |
| 236 | 236 | ||
| 237 | /// VEX-Encoded ___ | 237 | /// VEX-Encoded ___ |
| 238 | v_, | 238 | v_, |
| 239 | /// VEX-Encoded ___ Byte | ||
| 240 | v_b, | ||
| 241 | /// VEX-Encoded ___ Word | ||
| 242 | v_w, | ||
| 243 | /// VEX-Encoded ___ Doubleword | ||
| 244 | v_d, | ||
| 245 | /// VEX-Encoded ___ QuadWord | ||
| 246 | v_q, | ||
| 239 | /// VEX-Encoded Packed ___ | 247 | /// VEX-Encoded Packed ___ |
| 240 | vp_, | 248 | vp_, |
| 241 | /// VEX-Encoded Packed ___ Byte | 249 | /// VEX-Encoded Packed ___ Byte |
| ... | @@ -256,6 +264,8 @@ pub const Inst = struct { | ... | @@ -256,6 +264,8 @@ pub const Inst = struct { |
| 256 | v_sd, | 264 | v_sd, |
| 257 | /// VEX-Encoded ___ Packed Double-Precision Values | 265 | /// VEX-Encoded ___ Packed Double-Precision Values |
| 258 | v_pd, | 266 | v_pd, |
| 267 | /// VEX-Encoded ___ 128-Bits Of Floating-Point Data | ||
| 268 | v_f128, | ||
| 259 | 269 | ||
| 260 | /// Mask ___ Byte | 270 | /// Mask ___ Byte |
| 261 | k_b, | 271 | k_b, |
| ... | @@ -278,6 +288,7 @@ pub const Inst = struct { | ... | @@ -278,6 +288,7 @@ pub const Inst = struct { |
| 278 | /// Add with carry | 288 | /// Add with carry |
| 279 | adc, | 289 | adc, |
| 280 | /// Add | 290 | /// Add |
| 291 | /// Add packed integers | ||
| 281 | /// Add packed single-precision floating-point values | 292 | /// Add packed single-precision floating-point values |
| 282 | /// Add scalar single-precision floating-point values | 293 | /// Add scalar single-precision floating-point values |
| 283 | /// Add packed double-precision floating-point values | 294 | /// Add packed double-precision floating-point values |
| ... | @@ -410,6 +421,7 @@ pub const Inst = struct { | ... | @@ -410,6 +421,7 @@ pub const Inst = struct { |
| 410 | /// Double precision shift right | 421 | /// Double precision shift right |
| 411 | sh, | 422 | sh, |
| 412 | /// Subtract | 423 | /// Subtract |
| 424 | /// Subtract packed integers | ||
| 413 | /// Subtract packed single-precision floating-point values | 425 | /// Subtract packed single-precision floating-point values |
| 414 | /// Subtract scalar single-precision floating-point values | 426 | /// Subtract scalar single-precision floating-point values |
| 415 | /// Subtract packed double-precision floating-point values | 427 | /// Subtract packed double-precision floating-point values |
| ... | @@ -434,11 +446,45 @@ pub const Inst = struct { | ... | @@ -434,11 +446,45 @@ pub const Inst = struct { |
| 434 | /// Bitwise logical xor of packed double-precision floating-point values | 446 | /// Bitwise logical xor of packed double-precision floating-point values |
| 435 | xor, | 447 | xor, |
| 436 | 448 | ||
| 449 | /// Add packed signed integers with signed saturation | ||
| 450 | adds, | ||
| 451 | /// Add packed unsigned integers with unsigned saturation | ||
| 452 | addus, | ||
| 437 | /// Bitwise logical and not of packed single-precision floating-point values | 453 | /// Bitwise logical and not of packed single-precision floating-point values |
| 438 | /// Bitwise logical and not of packed double-precision floating-point values | 454 | /// Bitwise logical and not of packed double-precision floating-point values |
| 439 | andn, | 455 | andn, |
| 456 | /// Maximum of packed signed integers | ||
| 457 | maxs, | ||
| 458 | /// Maximum of packed unsigned integers | ||
| 459 | maxu, | ||
| 460 | /// Minimum of packed signed integers | ||
| 461 | mins, | ||
| 462 | /// Minimum of packed unsigned integers | ||
| 463 | minu, | ||
| 464 | /// Multiply packed signed integers and store low result | ||
| 465 | mull, | ||
| 466 | /// Multiply packed signed integers and store high result | ||
| 467 | mulh, | ||
| 468 | /// Subtract packed signed integers with signed saturation | ||
| 469 | subs, | ||
| 470 | /// Subtract packed unsigned integers with unsigned saturation | ||
| 471 | subus, | ||
| 472 | |||
| 473 | /// Convert packed doubleword integers to packed single-precision floating-point values | ||
| 474 | /// Convert packed doubleword integers to packed double-precision floating-point values | ||
| 475 | cvtpi2, | ||
| 476 | /// Convert packed single-precision floating-point values to packed doubleword integers | ||
| 477 | cvtps2pi, | ||
| 440 | /// Convert doubleword integer to scalar single-precision floating-point value | 478 | /// Convert doubleword integer to scalar single-precision floating-point value |
| 441 | cvtsi2ss, | 479 | /// Convert doubleword integer to scalar double-precision floating-point value |
| 480 | cvtsi2, | ||
| 481 | /// Convert scalar single-precision floating-point value to doubleword integer | ||
| 482 | cvtss2si, | ||
| 483 | /// Convert with truncation packed single-precision floating-point values to packed doubleword integers | ||
| 484 | cvttps2pi, | ||
| 485 | /// Convert with truncation scalar single-precision floating-point value to doubleword integer | ||
| 486 | cvttss2si, | ||
| 487 | |||
| 442 | /// Maximum of packed single-precision floating-point values | 488 | /// Maximum of packed single-precision floating-point values |
| 443 | /// Maximum of scalar single-precision floating-point values | 489 | /// Maximum of scalar single-precision floating-point values |
| 444 | /// Maximum of packed double-precision floating-point values | 490 | /// Maximum of packed double-precision floating-point values |
| ... | @@ -454,6 +500,8 @@ pub const Inst = struct { | ... | @@ -454,6 +500,8 @@ pub const Inst = struct { |
| 454 | mova, | 500 | mova, |
| 455 | /// Move packed single-precision floating-point values high to low | 501 | /// Move packed single-precision floating-point values high to low |
| 456 | movhl, | 502 | movhl, |
| 503 | /// Move packed single-precision floating-point values low to high | ||
| 504 | movlh, | ||
| 457 | /// Move unaligned packed single-precision floating-point values | 505 | /// Move unaligned packed single-precision floating-point values |
| 458 | /// Move unaligned packed double-precision floating-point values | 506 | /// Move unaligned packed double-precision floating-point values |
| 459 | movu, | 507 | movu, |
| ... | @@ -482,12 +530,40 @@ pub const Inst = struct { | ... | @@ -482,12 +530,40 @@ pub const Inst = struct { |
| 482 | /// Unpack and interleave low packed double-precision floating-point values | 530 | /// Unpack and interleave low packed double-precision floating-point values |
| 483 | unpckl, | 531 | unpckl, |
| 484 | 532 | ||
| 533 | /// Convert packed doubleword integers to packed single-precision floating-point values | ||
| 534 | /// Convert packed doubleword integers to packed double-precision floating-point values | ||
| 535 | cvtdq2, | ||
| 536 | /// Convert packed double-precision floating-point values to packed doubleword integers | ||
| 537 | cvtpd2dq, | ||
| 538 | /// Convert packed double-precision floating-point values to packed doubleword integers | ||
| 539 | cvtpd2pi, | ||
| 540 | /// Convert packed double-precision floating-point values to packed single-precision floating-point values | ||
| 541 | cvtpd2, | ||
| 542 | /// Convert packed single-precision floating-point values to packed doubleword integers | ||
| 543 | cvtps2dq, | ||
| 544 | /// Convert packed single-precision floating-point values to packed double-precision floating-point values | ||
| 545 | cvtps2, | ||
| 546 | /// Convert scalar double-precision floating-point value to doubleword integer | ||
| 547 | cvtsd2si, | ||
| 485 | /// Convert scalar double-precision floating-point value to scalar single-precision floating-point value | 548 | /// Convert scalar double-precision floating-point value to scalar single-precision floating-point value |
| 486 | cvtsd2ss, | 549 | cvtsd2, |
| 487 | /// Convert doubleword integer to scalar double-precision floating-point value | ||
| 488 | cvtsi2sd, | ||
| 489 | /// Convert scalar single-precision floating-point value to scalar double-precision floating-point value | 550 | /// Convert scalar single-precision floating-point value to scalar double-precision floating-point value |
| 490 | cvtss2sd, | 551 | cvtss2, |
| 552 | /// Convert with truncation packed double-precision floating-point values to packed doubleword integers | ||
| 553 | cvttpd2dq, | ||
| 554 | /// Convert with truncation packed double-precision floating-point values to packed doubleword integers | ||
| 555 | cvttpd2pi, | ||
| 556 | /// Convert with truncation packed single-precision floating-point values to packed doubleword integers | ||
| 557 | cvttps2dq, | ||
| 558 | /// Convert with truncation scalar double-precision floating-point value to doubleword integer | ||
| 559 | cvttsd2si, | ||
| 560 | /// Move aligned packed integer values | ||
| 561 | movdqa, | ||
| 562 | /// Move unaligned packed integer values | ||
| 563 | movdqu, | ||
| 564 | /// Packed interleave shuffle of quadruplets of single-precision floating-point values | ||
| 565 | /// Packed interleave shuffle of pairs of double-precision floating-point values | ||
| 566 | shuf, | ||
| 491 | /// Shuffle packed high words | 567 | /// Shuffle packed high words |
| 492 | shufh, | 568 | shufh, |
| 493 | /// Shuffle packed low words | 569 | /// Shuffle packed low words |
| ... | @@ -520,14 +596,22 @@ pub const Inst = struct { | ... | @@ -520,14 +596,22 @@ pub const Inst = struct { |
| 520 | /// Replicate single floating-point values | 596 | /// Replicate single floating-point values |
| 521 | movsldup, | 597 | movsldup, |
| 522 | 598 | ||
| 599 | /// Extract packed floating-point values | ||
| 600 | extract, | ||
| 601 | /// Insert scalar single-precision floating-point value | ||
| 602 | /// Insert packed floating-point values | ||
| 603 | insert, | ||
| 523 | /// Round packed single-precision floating-point values | 604 | /// Round packed single-precision floating-point values |
| 524 | /// Round scalar single-precision floating-point value | 605 | /// Round scalar single-precision floating-point value |
| 525 | /// Round packed double-precision floating-point values | 606 | /// Round packed double-precision floating-point values |
| 526 | /// Round scalar double-precision floating-point value | 607 | /// Round scalar double-precision floating-point value |
| 527 | round, | 608 | round, |
| 528 | 609 | ||
| 610 | /// Load with broadcast floating-point data | ||
| 611 | broadcast, | ||
| 612 | |||
| 529 | /// Convert 16-bit floating-point values to single-precision floating-point values | 613 | /// Convert 16-bit floating-point values to single-precision floating-point values |
| 530 | cvtph2ps, | 614 | cvtph2, |
| 531 | /// Convert single-precision floating-point values to 16-bit floating-point values | 615 | /// Convert single-precision floating-point values to 16-bit floating-point values |
| 532 | cvtps2ph, | 616 | cvtps2ph, |
| 533 | 617 | ||
| ... | @@ -696,27 +780,27 @@ pub const Inst = struct { | ... | @@ -696,27 +780,27 @@ pub const Inst = struct { |
| 696 | pseudo_cmov_nz_or_p_rm_rip, | 780 | pseudo_cmov_nz_or_p_rm_rip, |
| 697 | /// Set byte if zero flag set and parity flag not set | 781 | /// Set byte if zero flag set and parity flag not set |
| 698 | /// Requires a scratch register! | 782 | /// Requires a scratch register! |
| 699 | /// Uses `r_scratch` payload. | 783 | /// Uses `rr` payload. |
| 700 | pseudo_set_z_and_np_r, | 784 | pseudo_set_z_and_np_r, |
| 701 | /// Set byte if zero flag set and parity flag not set | 785 | /// Set byte if zero flag set and parity flag not set |
| 702 | /// Requires a scratch register! | 786 | /// Requires a scratch register! |
| 703 | /// Uses `x_scratch` payload. | 787 | /// Uses `rx` payload. |
| 704 | pseudo_set_z_and_np_m_sib, | 788 | pseudo_set_z_and_np_m_sib, |
| 705 | /// Set byte if zero flag set and parity flag not set | 789 | /// Set byte if zero flag set and parity flag not set |
| 706 | /// Requires a scratch register! | 790 | /// Requires a scratch register! |
| 707 | /// Uses `x_scratch` payload. | 791 | /// Uses `rx` payload. |
| 708 | pseudo_set_z_and_np_m_rip, | 792 | pseudo_set_z_and_np_m_rip, |
| 709 | /// Set byte if zero flag not set or parity flag set | 793 | /// Set byte if zero flag not set or parity flag set |
| 710 | /// Requires a scratch register! | 794 | /// Requires a scratch register! |
| 711 | /// Uses `r_scratch` payload. | 795 | /// Uses `rr` payload. |
| 712 | pseudo_set_nz_or_p_r, | 796 | pseudo_set_nz_or_p_r, |
| 713 | /// Set byte if zero flag not set or parity flag set | 797 | /// Set byte if zero flag not set or parity flag set |
| 714 | /// Requires a scratch register! | 798 | /// Requires a scratch register! |
| 715 | /// Uses `x_scratch` payload. | 799 | /// Uses `rx` payload. |
| 716 | pseudo_set_nz_or_p_m_sib, | 800 | pseudo_set_nz_or_p_m_sib, |
| 717 | /// Set byte if zero flag not set or parity flag set | 801 | /// Set byte if zero flag not set or parity flag set |
| 718 | /// Requires a scratch register! | 802 | /// Requires a scratch register! |
| 719 | /// Uses `x_scratch` payload. | 803 | /// Uses `rx` payload. |
| 720 | pseudo_set_nz_or_p_m_rip, | 804 | pseudo_set_nz_or_p_m_rip, |
| 721 | /// Jump if zero flag set and parity flag not set | 805 | /// Jump if zero flag set and parity flag not set |
| 722 | /// Uses `inst` payload. | 806 | /// Uses `inst` payload. |
| ... | @@ -725,6 +809,18 @@ pub const Inst = struct { | ... | @@ -725,6 +809,18 @@ pub const Inst = struct { |
| 725 | /// Uses `inst` payload. | 809 | /// Uses `inst` payload. |
| 726 | pseudo_j_nz_or_p_inst, | 810 | pseudo_j_nz_or_p_inst, |
| 727 | 811 | ||
| 812 | /// Probe alignment | ||
| 813 | /// Uses `ri` payload | ||
| 814 | pseudo_probe_align_ri_s, | ||
| 815 | /// Probe adjust unrolled | ||
| 816 | /// Uses `ri` payload | ||
| 817 | pseudo_probe_adjust_unrolled_ri_s, | ||
| 818 | /// Probe adjust setup | ||
| 819 | /// Uses `rri` payload | ||
| 820 | pseudo_probe_adjust_setup_rri_s, | ||
| 821 | /// Probe adjust loop | ||
| 822 | /// Uses `rr` payload | ||
| 823 | pseudo_probe_adjust_loop_rr, | ||
| 728 | /// Push registers | 824 | /// Push registers |
| 729 | /// Uses `reg_list` payload. | 825 | /// Uses `reg_list` payload. |
| 730 | pseudo_push_reg_list, | 826 | pseudo_push_reg_list, |
| ... | @@ -821,18 +917,6 @@ pub const Inst = struct { | ... | @@ -821,18 +917,6 @@ pub const Inst = struct { |
| 821 | i: u8, | 917 | i: u8, |
| 822 | payload: u32, | 918 | payload: u32, |
| 823 | }, | 919 | }, |
| 824 | /// Register, scratch register | ||
| 825 | r_scratch: struct { | ||
| 826 | fixes: Fixes = ._, | ||
| 827 | r1: Register, | ||
| 828 | scratch_reg: Register, | ||
| 829 | }, | ||
| 830 | /// Scratch register, followed by Custom payload found in extra. | ||
| 831 | x_scratch: struct { | ||
| 832 | fixes: Fixes = ._, | ||
| 833 | scratch_reg: Register, | ||
| 834 | payload: u32, | ||
| 835 | }, | ||
| 836 | /// Custom payload found in extra. | 920 | /// Custom payload found in extra. |
| 837 | x: struct { | 921 | x: struct { |
| 838 | fixes: Fixes = ._, | 922 | fixes: Fixes = ._, |
src/arch/x86_64/abi.zig+2-28| ... | @@ -165,34 +165,6 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class { | ... | @@ -165,34 +165,6 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class { |
| 165 | }, | 165 | }, |
| 166 | .Vector => { | 166 | .Vector => { |
| 167 | const elem_ty = ty.childType(); | 167 | const elem_ty = ty.childType(); |
| 168 | if (ctx == .arg) { | ||
| 169 | const bit_size = ty.bitSize(target); | ||
| 170 | if (bit_size > 128) { | ||
| 171 | const has_avx512 = target.cpu.features.isEnabled(@enumToInt(std.Target.x86.Feature.avx512f)); | ||
| 172 | if (has_avx512 and bit_size <= 512) return .{ | ||
| 173 | .integer, .integer, .integer, .integer, | ||
| 174 | .integer, .integer, .integer, .integer, | ||
| 175 | }; | ||
| 176 | const has_avx = target.cpu.features.isEnabled(@enumToInt(std.Target.x86.Feature.avx)); | ||
| 177 | if (has_avx and bit_size <= 256) return .{ | ||
| 178 | .integer, .integer, .integer, .integer, | ||
| 179 | .none, .none, .none, .none, | ||
| 180 | }; | ||
| 181 | return memory_class; | ||
| 182 | } | ||
| 183 | if (bit_size > 80) return .{ | ||
| 184 | .integer, .integer, .none, .none, | ||
| 185 | .none, .none, .none, .none, | ||
| 186 | }; | ||
| 187 | if (bit_size > 64) return .{ | ||
| 188 | .x87, .none, .none, .none, | ||
| 189 | .none, .none, .none, .none, | ||
| 190 | }; | ||
| 191 | return .{ | ||
| 192 | .integer, .none, .none, .none, | ||
| 193 | .none, .none, .none, .none, | ||
| 194 | }; | ||
| 195 | } | ||
| 196 | const bits = elem_ty.bitSize(target) * ty.arrayLen(); | 168 | const bits = elem_ty.bitSize(target) * ty.arrayLen(); |
| 197 | if (bits <= 64) return .{ | 169 | if (bits <= 64) return .{ |
| 198 | .sse, .none, .none, .none, | 170 | .sse, .none, .none, .none, |
| ... | @@ -202,6 +174,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class { | ... | @@ -202,6 +174,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class { |
| 202 | .sse, .sseup, .none, .none, | 174 | .sse, .sseup, .none, .none, |
| 203 | .none, .none, .none, .none, | 175 | .none, .none, .none, .none, |
| 204 | }; | 176 | }; |
| 177 | if (ctx == .arg and !std.Target.x86.featureSetHas(target.cpu.features, .avx)) return memory_class; | ||
| 205 | if (bits <= 192) return .{ | 178 | if (bits <= 192) return .{ |
| 206 | .sse, .sseup, .sseup, .none, | 179 | .sse, .sseup, .sseup, .none, |
| 207 | .none, .none, .none, .none, | 180 | .none, .none, .none, .none, |
| ... | @@ -210,6 +183,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class { | ... | @@ -210,6 +183,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class { |
| 210 | .sse, .sseup, .sseup, .sseup, | 183 | .sse, .sseup, .sseup, .sseup, |
| 211 | .none, .none, .none, .none, | 184 | .none, .none, .none, .none, |
| 212 | }; | 185 | }; |
| 186 | if (ctx == .arg and !std.Target.x86.featureSetHas(target.cpu.features, .avx512f)) return memory_class; | ||
| 213 | if (bits <= 320) return .{ | 187 | if (bits <= 320) return .{ |
| 214 | .sse, .sseup, .sseup, .sseup, | 188 | .sse, .sseup, .sseup, .sseup, |
| 215 | .sseup, .none, .none, .none, | 189 | .sseup, .none, .none, .none, |
src/arch/x86_64/bits.zig+38-45| ... | @@ -175,15 +175,21 @@ pub const Register = enum(u7) { | ... | @@ -175,15 +175,21 @@ pub const Register = enum(u7) { |
| 175 | xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, | 175 | xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, |
| 176 | xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, | 176 | xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, |
| 177 | 177 | ||
| 178 | mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, | ||
| 179 | |||
| 180 | st0, st1, st2, st3, st4, st5, st6, st7, | ||
| 181 | |||
| 178 | es, cs, ss, ds, fs, gs, | 182 | es, cs, ss, ds, fs, gs, |
| 179 | 183 | ||
| 180 | none, | 184 | none, |
| 181 | // zig fmt: on | 185 | // zig fmt: on |
| 182 | 186 | ||
| 183 | pub const Class = enum(u2) { | 187 | pub const Class = enum { |
| 184 | general_purpose, | 188 | general_purpose, |
| 185 | floating_point, | ||
| 186 | segment, | 189 | segment, |
| 190 | x87, | ||
| 191 | mmx, | ||
| 192 | sse, | ||
| 187 | }; | 193 | }; |
| 188 | 194 | ||
| 189 | pub fn class(reg: Register) Class { | 195 | pub fn class(reg: Register) Class { |
| ... | @@ -195,8 +201,10 @@ pub const Register = enum(u7) { | ... | @@ -195,8 +201,10 @@ pub const Register = enum(u7) { |
| 195 | @enumToInt(Register.al) ... @enumToInt(Register.r15b) => .general_purpose, | 201 | @enumToInt(Register.al) ... @enumToInt(Register.r15b) => .general_purpose, |
| 196 | @enumToInt(Register.ah) ... @enumToInt(Register.bh) => .general_purpose, | 202 | @enumToInt(Register.ah) ... @enumToInt(Register.bh) => .general_purpose, |
| 197 | 203 | ||
| 198 | @enumToInt(Register.ymm0) ... @enumToInt(Register.ymm15) => .floating_point, | 204 | @enumToInt(Register.ymm0) ... @enumToInt(Register.ymm15) => .sse, |
| 199 | @enumToInt(Register.xmm0) ... @enumToInt(Register.xmm15) => .floating_point, | 205 | @enumToInt(Register.xmm0) ... @enumToInt(Register.xmm15) => .sse, |
| 206 | @enumToInt(Register.mm0) ... @enumToInt(Register.mm7) => .mmx, | ||
| 207 | @enumToInt(Register.st0) ... @enumToInt(Register.st7) => .x87, | ||
| 200 | 208 | ||
| 201 | @enumToInt(Register.es) ... @enumToInt(Register.gs) => .segment, | 209 | @enumToInt(Register.es) ... @enumToInt(Register.gs) => .segment, |
| 202 | 210 | ||
| ... | @@ -216,8 +224,10 @@ pub const Register = enum(u7) { | ... | @@ -216,8 +224,10 @@ pub const Register = enum(u7) { |
| 216 | 224 | ||
| 217 | @enumToInt(Register.ymm0) ... @enumToInt(Register.ymm15) => @enumToInt(Register.ymm0) - 16, | 225 | @enumToInt(Register.ymm0) ... @enumToInt(Register.ymm15) => @enumToInt(Register.ymm0) - 16, |
| 218 | @enumToInt(Register.xmm0) ... @enumToInt(Register.xmm15) => @enumToInt(Register.xmm0) - 16, | 226 | @enumToInt(Register.xmm0) ... @enumToInt(Register.xmm15) => @enumToInt(Register.xmm0) - 16, |
| 227 | @enumToInt(Register.mm0) ... @enumToInt(Register.mm7) => @enumToInt(Register.mm0) - 32, | ||
| 228 | @enumToInt(Register.st0) ... @enumToInt(Register.st7) => @enumToInt(Register.st0) - 40, | ||
| 219 | 229 | ||
| 220 | @enumToInt(Register.es) ... @enumToInt(Register.gs) => @enumToInt(Register.es) - 32, | 230 | @enumToInt(Register.es) ... @enumToInt(Register.gs) => @enumToInt(Register.es) - 48, |
| 221 | 231 | ||
| 222 | else => unreachable, | 232 | else => unreachable, |
| 223 | // zig fmt: on | 233 | // zig fmt: on |
| ... | @@ -236,6 +246,8 @@ pub const Register = enum(u7) { | ... | @@ -236,6 +246,8 @@ pub const Register = enum(u7) { |
| 236 | 246 | ||
| 237 | @enumToInt(Register.ymm0) ... @enumToInt(Register.ymm15) => 256, | 247 | @enumToInt(Register.ymm0) ... @enumToInt(Register.ymm15) => 256, |
| 238 | @enumToInt(Register.xmm0) ... @enumToInt(Register.xmm15) => 128, | 248 | @enumToInt(Register.xmm0) ... @enumToInt(Register.xmm15) => 128, |
| 249 | @enumToInt(Register.mm0) ... @enumToInt(Register.mm7) => 64, | ||
| 250 | @enumToInt(Register.st0) ... @enumToInt(Register.st7) => 80, | ||
| 239 | 251 | ||
| 240 | @enumToInt(Register.es) ... @enumToInt(Register.gs) => 16, | 252 | @enumToInt(Register.es) ... @enumToInt(Register.gs) => 16, |
| 241 | 253 | ||
| ... | @@ -271,6 +283,8 @@ pub const Register = enum(u7) { | ... | @@ -271,6 +283,8 @@ pub const Register = enum(u7) { |
| 271 | 283 | ||
| 272 | @enumToInt(Register.ymm0) ... @enumToInt(Register.ymm15) => @enumToInt(Register.ymm0), | 284 | @enumToInt(Register.ymm0) ... @enumToInt(Register.ymm15) => @enumToInt(Register.ymm0), |
| 273 | @enumToInt(Register.xmm0) ... @enumToInt(Register.xmm15) => @enumToInt(Register.xmm0), | 285 | @enumToInt(Register.xmm0) ... @enumToInt(Register.xmm15) => @enumToInt(Register.xmm0), |
| 286 | @enumToInt(Register.mm0) ... @enumToInt(Register.mm7) => @enumToInt(Register.mm0), | ||
| 287 | @enumToInt(Register.st0) ... @enumToInt(Register.st7) => @enumToInt(Register.st0), | ||
| 274 | 288 | ||
| 275 | @enumToInt(Register.es) ... @enumToInt(Register.gs) => @enumToInt(Register.es), | 289 | @enumToInt(Register.es) ... @enumToInt(Register.gs) => @enumToInt(Register.es), |
| 276 | 290 | ||
| ... | @@ -326,8 +340,8 @@ pub const Register = enum(u7) { | ... | @@ -326,8 +340,8 @@ pub const Register = enum(u7) { |
| 326 | return @intToEnum(Register, @enumToInt(reg) - reg.gpBase() + @enumToInt(Register.al)); | 340 | return @intToEnum(Register, @enumToInt(reg) - reg.gpBase() + @enumToInt(Register.al)); |
| 327 | } | 341 | } |
| 328 | 342 | ||
| 329 | fn fpBase(reg: Register) u7 { | 343 | fn sseBase(reg: Register) u7 { |
| 330 | assert(reg.class() == .floating_point); | 344 | assert(reg.class() == .sse); |
| 331 | return switch (@enumToInt(reg)) { | 345 | return switch (@enumToInt(reg)) { |
| 332 | @enumToInt(Register.ymm0)...@enumToInt(Register.ymm15) => @enumToInt(Register.ymm0), | 346 | @enumToInt(Register.ymm0)...@enumToInt(Register.ymm15) => @enumToInt(Register.ymm0), |
| 333 | @enumToInt(Register.xmm0)...@enumToInt(Register.xmm15) => @enumToInt(Register.xmm0), | 347 | @enumToInt(Register.xmm0)...@enumToInt(Register.xmm15) => @enumToInt(Register.xmm0), |
| ... | @@ -336,49 +350,24 @@ pub const Register = enum(u7) { | ... | @@ -336,49 +350,24 @@ pub const Register = enum(u7) { |
| 336 | } | 350 | } |
| 337 | 351 | ||
| 338 | pub fn to256(reg: Register) Register { | 352 | pub fn to256(reg: Register) Register { |
| 339 | return @intToEnum(Register, @enumToInt(reg) - reg.fpBase() + @enumToInt(Register.ymm0)); | 353 | return @intToEnum(Register, @enumToInt(reg) - reg.sseBase() + @enumToInt(Register.ymm0)); |
| 340 | } | 354 | } |
| 341 | 355 | ||
| 342 | pub fn to128(reg: Register) Register { | 356 | pub fn to128(reg: Register) Register { |
| 343 | return @intToEnum(Register, @enumToInt(reg) - reg.fpBase() + @enumToInt(Register.xmm0)); | 357 | return @intToEnum(Register, @enumToInt(reg) - reg.sseBase() + @enumToInt(Register.xmm0)); |
| 344 | } | ||
| 345 | |||
| 346 | pub fn dwarfLocOp(reg: Register) u8 { | ||
| 347 | return switch (reg.class()) { | ||
| 348 | .general_purpose => switch (reg.to64()) { | ||
| 349 | .rax => DW.OP.reg0, | ||
| 350 | .rdx => DW.OP.reg1, | ||
| 351 | .rcx => DW.OP.reg2, | ||
| 352 | .rbx => DW.OP.reg3, | ||
| 353 | .rsi => DW.OP.reg4, | ||
| 354 | .rdi => DW.OP.reg5, | ||
| 355 | .rbp => DW.OP.reg6, | ||
| 356 | .rsp => DW.OP.reg7, | ||
| 357 | else => @intCast(u8, @enumToInt(reg) - reg.gpBase()) + DW.OP.reg0, | ||
| 358 | }, | ||
| 359 | .floating_point => @intCast(u8, @enumToInt(reg) - reg.fpBase()) + DW.OP.reg17, | ||
| 360 | else => unreachable, | ||
| 361 | }; | ||
| 362 | } | 358 | } |
| 363 | 359 | ||
| 364 | /// DWARF encodings that push a value onto the DWARF stack that is either | 360 | /// DWARF register encoding |
| 365 | /// the contents of a register or the result of adding the contents a given | 361 | pub fn dwarfNum(reg: Register) u6 { |
| 366 | /// register to a given signed offset. | ||
| 367 | pub fn dwarfLocOpDeref(reg: Register) u8 { | ||
| 368 | return switch (reg.class()) { | 362 | return switch (reg.class()) { |
| 369 | .general_purpose => switch (reg.to64()) { | 363 | .general_purpose => if (reg.isExtended()) |
| 370 | .rax => DW.OP.breg0, | 364 | reg.enc() |
| 371 | .rdx => DW.OP.breg1, | 365 | else |
| 372 | .rcx => DW.OP.breg2, | 366 | @truncate(u3, @as(u24, 0o54673120) >> @as(u5, reg.enc()) * 3), |
| 373 | .rbx => DW.OP.breg3, | 367 | .sse => 17 + @as(u6, reg.enc()), |
| 374 | .rsi => DW.OP.breg4, | 368 | .x87 => 33 + @as(u6, reg.enc()), |
| 375 | .rdi => DW.OP.breg5, | 369 | .mmx => 41 + @as(u6, reg.enc()), |
| 376 | .rbp => DW.OP.breg6, | 370 | .segment => 50 + @as(u6, reg.enc()), |
| 377 | .rsp => DW.OP.breg7, | ||
| 378 | else => @intCast(u8, @enumToInt(reg) - reg.gpBase()) + DW.OP.breg0, | ||
| 379 | }, | ||
| 380 | .floating_point => @intCast(u8, @enumToInt(reg) - reg.fpBase()) + DW.OP.breg17, | ||
| 381 | else => unreachable, | ||
| 382 | }; | 371 | }; |
| 383 | } | 372 | } |
| 384 | }; | 373 | }; |
| ... | @@ -392,6 +381,8 @@ test "Register id - different classes" { | ... | @@ -392,6 +381,8 @@ test "Register id - different classes" { |
| 392 | try expect(Register.ymm0.id() == 0b10000); | 381 | try expect(Register.ymm0.id() == 0b10000); |
| 393 | try expect(Register.ymm0.id() != Register.rax.id()); | 382 | try expect(Register.ymm0.id() != Register.rax.id()); |
| 394 | try expect(Register.xmm0.id() == Register.ymm0.id()); | 383 | try expect(Register.xmm0.id() == Register.ymm0.id()); |
| 384 | try expect(Register.xmm0.id() != Register.mm0.id()); | ||
| 385 | try expect(Register.mm0.id() != Register.st0.id()); | ||
| 395 | 386 | ||
| 396 | try expect(Register.es.id() == 0b100000); | 387 | try expect(Register.es.id() == 0b100000); |
| 397 | } | 388 | } |
| ... | @@ -407,7 +398,9 @@ test "Register enc - different classes" { | ... | @@ -407,7 +398,9 @@ test "Register enc - different classes" { |
| 407 | 398 | ||
| 408 | test "Register classes" { | 399 | test "Register classes" { |
| 409 | try expect(Register.r11.class() == .general_purpose); | 400 | try expect(Register.r11.class() == .general_purpose); |
| 410 | try expect(Register.ymm11.class() == .floating_point); | 401 | try expect(Register.ymm11.class() == .sse); |
| 402 | try expect(Register.mm3.class() == .mmx); | ||
| 403 | try expect(Register.st3.class() == .x87); | ||
| 411 | try expect(Register.fs.class() == .segment); | 404 | try expect(Register.fs.class() == .segment); |
| 412 | } | 405 | } |
| 413 | 406 |
src/arch/x86_64/encodings.zig+359-31| ... | @@ -272,14 +272,6 @@ pub const table = [_]Entry{ | ... | @@ -272,14 +272,6 @@ pub const table = [_]Entry{ |
| 272 | .{ .div, .m, &.{ .rm32 }, &.{ 0xf7 }, 6, .none, .none }, | 272 | .{ .div, .m, &.{ .rm32 }, &.{ 0xf7 }, 6, .none, .none }, |
| 273 | .{ .div, .m, &.{ .rm64 }, &.{ 0xf7 }, 6, .long, .none }, | 273 | .{ .div, .m, &.{ .rm64 }, &.{ 0xf7 }, 6, .long, .none }, |
| 274 | 274 | ||
| 275 | .{ .fisttp, .m, &.{ .m16 }, &.{ 0xdf }, 1, .none, .x87 }, | ||
| 276 | .{ .fisttp, .m, &.{ .m32 }, &.{ 0xdb }, 1, .none, .x87 }, | ||
| 277 | .{ .fisttp, .m, &.{ .m64 }, &.{ 0xdd }, 1, .none, .x87 }, | ||
| 278 | |||
| 279 | .{ .fld, .m, &.{ .m32 }, &.{ 0xd9 }, 0, .none, .x87 }, | ||
| 280 | .{ .fld, .m, &.{ .m64 }, &.{ 0xdd }, 0, .none, .x87 }, | ||
| 281 | .{ .fld, .m, &.{ .m80 }, &.{ 0xdb }, 5, .none, .x87 }, | ||
| 282 | |||
| 283 | .{ .idiv, .m, &.{ .rm8 }, &.{ 0xf6 }, 7, .none, .none }, | 275 | .{ .idiv, .m, &.{ .rm8 }, &.{ 0xf6 }, 7, .none, .none }, |
| 284 | .{ .idiv, .m, &.{ .rm8 }, &.{ 0xf6 }, 7, .rex, .none }, | 276 | .{ .idiv, .m, &.{ .rm8 }, &.{ 0xf6 }, 7, .rex, .none }, |
| 285 | .{ .idiv, .m, &.{ .rm16 }, &.{ 0xf7 }, 7, .short, .none }, | 277 | .{ .idiv, .m, &.{ .rm16 }, &.{ 0xf7 }, 7, .short, .none }, |
| ... | @@ -354,9 +346,9 @@ pub const table = [_]Entry{ | ... | @@ -354,9 +346,9 @@ pub const table = [_]Entry{ |
| 354 | .{ .lodsd, .np, &.{}, &.{ 0xad }, 0, .none, .none }, | 346 | .{ .lodsd, .np, &.{}, &.{ 0xad }, 0, .none, .none }, |
| 355 | .{ .lodsq, .np, &.{}, &.{ 0xad }, 0, .long, .none }, | 347 | .{ .lodsq, .np, &.{}, &.{ 0xad }, 0, .long, .none }, |
| 356 | 348 | ||
| 357 | .{ .lzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .short, .none }, | 349 | .{ .lzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .short, .lzcnt }, |
| 358 | .{ .lzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .none, .none }, | 350 | .{ .lzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .none, .lzcnt }, |
| 359 | .{ .lzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .long, .none }, | 351 | .{ .lzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .long, .lzcnt }, |
| 360 | 352 | ||
| 361 | .{ .mfence, .np, &.{}, &.{ 0x0f, 0xae, 0xf0 }, 0, .none, .none }, | 353 | .{ .mfence, .np, &.{}, &.{ 0x0f, 0xae, 0xf0 }, 0, .none, .none }, |
| 362 | 354 | ||
| ... | @@ -395,12 +387,12 @@ pub const table = [_]Entry{ | ... | @@ -395,12 +387,12 @@ pub const table = [_]Entry{ |
| 395 | .{ .mov, .mi, &.{ .rm32, .imm32 }, &.{ 0xc7 }, 0, .none, .none }, | 387 | .{ .mov, .mi, &.{ .rm32, .imm32 }, &.{ 0xc7 }, 0, .none, .none }, |
| 396 | .{ .mov, .mi, &.{ .rm64, .imm32s }, &.{ 0xc7 }, 0, .long, .none }, | 388 | .{ .mov, .mi, &.{ .rm64, .imm32s }, &.{ 0xc7 }, 0, .long, .none }, |
| 397 | 389 | ||
| 398 | .{ .movbe, .rm, &.{ .r16, .m16 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .short, .none }, | 390 | .{ .movbe, .rm, &.{ .r16, .m16 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .short, .movbe }, |
| 399 | .{ .movbe, .rm, &.{ .r32, .m32 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .none, .none }, | 391 | .{ .movbe, .rm, &.{ .r32, .m32 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .none, .movbe }, |
| 400 | .{ .movbe, .rm, &.{ .r64, .m64 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .long, .none }, | 392 | .{ .movbe, .rm, &.{ .r64, .m64 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .long, .movbe }, |
| 401 | .{ .movbe, .mr, &.{ .m16, .r16 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .short, .none }, | 393 | .{ .movbe, .mr, &.{ .m16, .r16 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .short, .movbe }, |
| 402 | .{ .movbe, .mr, &.{ .m32, .r32 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .none, .none }, | 394 | .{ .movbe, .mr, &.{ .m32, .r32 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .none, .movbe }, |
| 403 | .{ .movbe, .mr, &.{ .m64, .r64 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .long, .none }, | 395 | .{ .movbe, .mr, &.{ .m64, .r64 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .long, .movbe }, |
| 404 | 396 | ||
| 405 | .{ .movs, .np, &.{ .m8, .m8 }, &.{ 0xa4 }, 0, .none, .none }, | 397 | .{ .movs, .np, &.{ .m8, .m8 }, &.{ 0xa4 }, 0, .none, .none }, |
| 406 | .{ .movs, .np, &.{ .m16, .m16 }, &.{ 0xa5 }, 0, .short, .none }, | 398 | .{ .movs, .np, &.{ .m16, .m16 }, &.{ 0xa5 }, 0, .short, .none }, |
| ... | @@ -482,9 +474,9 @@ pub const table = [_]Entry{ | ... | @@ -482,9 +474,9 @@ pub const table = [_]Entry{ |
| 482 | .{ .pop, .m, &.{ .rm16 }, &.{ 0x8f }, 0, .short, .none }, | 474 | .{ .pop, .m, &.{ .rm16 }, &.{ 0x8f }, 0, .short, .none }, |
| 483 | .{ .pop, .m, &.{ .rm64 }, &.{ 0x8f }, 0, .none, .none }, | 475 | .{ .pop, .m, &.{ .rm64 }, &.{ 0x8f }, 0, .none, .none }, |
| 484 | 476 | ||
| 485 | .{ .popcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .short, .none }, | 477 | .{ .popcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .short, .popcnt }, |
| 486 | .{ .popcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none, .none }, | 478 | .{ .popcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none, .popcnt }, |
| 487 | .{ .popcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long, .none }, | 479 | .{ .popcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long, .popcnt }, |
| 488 | 480 | ||
| 489 | .{ .push, .o, &.{ .r16 }, &.{ 0x50 }, 0, .short, .none }, | 481 | .{ .push, .o, &.{ .r16 }, &.{ 0x50 }, 0, .short, .none }, |
| 490 | .{ .push, .o, &.{ .r64 }, &.{ 0x50 }, 0, .none, .none }, | 482 | .{ .push, .o, &.{ .r64 }, &.{ 0x50 }, 0, .none, .none }, |
| ... | @@ -784,9 +776,9 @@ pub const table = [_]Entry{ | ... | @@ -784,9 +776,9 @@ pub const table = [_]Entry{ |
| 784 | .{ .@"test", .mr, &.{ .rm32, .r32 }, &.{ 0x85 }, 0, .none, .none }, | 776 | .{ .@"test", .mr, &.{ .rm32, .r32 }, &.{ 0x85 }, 0, .none, .none }, |
| 785 | .{ .@"test", .mr, &.{ .rm64, .r64 }, &.{ 0x85 }, 0, .long, .none }, | 777 | .{ .@"test", .mr, &.{ .rm64, .r64 }, &.{ 0x85 }, 0, .long, .none }, |
| 786 | 778 | ||
| 787 | .{ .tzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .short, .none }, | 779 | .{ .tzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .short, .bmi }, |
| 788 | .{ .tzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .none, .none }, | 780 | .{ .tzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .none, .bmi }, |
| 789 | .{ .tzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .long, .none }, | 781 | .{ .tzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .long, .bmi }, |
| 790 | 782 | ||
| 791 | .{ .ud2, .np, &.{}, &.{ 0x0f, 0x0b }, 0, .none, .none }, | 783 | .{ .ud2, .np, &.{}, &.{ 0x0f, 0x0b }, 0, .none, .none }, |
| 792 | 784 | ||
| ... | @@ -836,6 +828,15 @@ pub const table = [_]Entry{ | ... | @@ -836,6 +828,15 @@ pub const table = [_]Entry{ |
| 836 | .{ .xor, .rm, &.{ .r32, .rm32 }, &.{ 0x33 }, 0, .none, .none }, | 828 | .{ .xor, .rm, &.{ .r32, .rm32 }, &.{ 0x33 }, 0, .none, .none }, |
| 837 | .{ .xor, .rm, &.{ .r64, .rm64 }, &.{ 0x33 }, 0, .long, .none }, | 829 | .{ .xor, .rm, &.{ .r64, .rm64 }, &.{ 0x33 }, 0, .long, .none }, |
| 838 | 830 | ||
| 831 | // X87 | ||
| 832 | .{ .fisttp, .m, &.{ .m16 }, &.{ 0xdf }, 1, .none, .x87 }, | ||
| 833 | .{ .fisttp, .m, &.{ .m32 }, &.{ 0xdb }, 1, .none, .x87 }, | ||
| 834 | .{ .fisttp, .m, &.{ .m64 }, &.{ 0xdd }, 1, .none, .x87 }, | ||
| 835 | |||
| 836 | .{ .fld, .m, &.{ .m32 }, &.{ 0xd9 }, 0, .none, .x87 }, | ||
| 837 | .{ .fld, .m, &.{ .m64 }, &.{ 0xdd }, 0, .none, .x87 }, | ||
| 838 | .{ .fld, .m, &.{ .m80 }, &.{ 0xdb }, 5, .none, .x87 }, | ||
| 839 | |||
| 839 | // SSE | 840 | // SSE |
| 840 | .{ .addps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x58 }, 0, .none, .sse }, | 841 | .{ .addps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x58 }, 0, .none, .sse }, |
| 841 | 842 | ||
| ... | @@ -847,9 +848,21 @@ pub const table = [_]Entry{ | ... | @@ -847,9 +848,21 @@ pub const table = [_]Entry{ |
| 847 | 848 | ||
| 848 | .{ .cmpss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0xf3, 0x0f, 0xc2 }, 0, .none, .sse }, | 849 | .{ .cmpss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0xf3, 0x0f, 0xc2 }, 0, .none, .sse }, |
| 849 | 850 | ||
| 851 | .{ .cvtpi2ps, .rm, &.{ .xmm, .mm_m64 }, &.{ 0x0f, 0x2a }, 0, .none, .sse }, | ||
| 852 | |||
| 853 | .{ .cvtps2pi, .rm, &.{ .mm, .xmm_m64 }, &.{ 0x0f, 0x2d }, 0, .none, .sse }, | ||
| 854 | |||
| 850 | .{ .cvtsi2ss, .rm, &.{ .xmm, .rm32 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .none, .sse }, | 855 | .{ .cvtsi2ss, .rm, &.{ .xmm, .rm32 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .none, .sse }, |
| 851 | .{ .cvtsi2ss, .rm, &.{ .xmm, .rm64 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .long, .sse }, | 856 | .{ .cvtsi2ss, .rm, &.{ .xmm, .rm64 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .long, .sse }, |
| 852 | 857 | ||
| 858 | .{ .cvtss2si, .rm, &.{ .r32, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x2d }, 0, .none, .sse }, | ||
| 859 | .{ .cvtss2si, .rm, &.{ .r64, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x2d }, 0, .long, .sse }, | ||
| 860 | |||
| 861 | .{ .cvttps2pi, .rm, &.{ .mm, .xmm_m64 }, &.{ 0x0f, 0x2c }, 0, .none, .sse }, | ||
| 862 | |||
| 863 | .{ .cvttss2si, .rm, &.{ .r32, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x2c }, 0, .none, .sse }, | ||
| 864 | .{ .cvttss2si, .rm, &.{ .r64, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x2c }, 0, .long, .sse }, | ||
| 865 | |||
| 853 | .{ .divps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5e }, 0, .none, .sse }, | 866 | .{ .divps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5e }, 0, .none, .sse }, |
| 854 | 867 | ||
| 855 | .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .none, .sse }, | 868 | .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .none, .sse }, |
| ... | @@ -867,6 +880,8 @@ pub const table = [_]Entry{ | ... | @@ -867,6 +880,8 @@ pub const table = [_]Entry{ |
| 867 | 880 | ||
| 868 | .{ .movhlps, .rm, &.{ .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .none, .sse }, | 881 | .{ .movhlps, .rm, &.{ .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .none, .sse }, |
| 869 | 882 | ||
| 883 | .{ .movlhps, .rm, &.{ .xmm, .xmm }, &.{ 0x0f, 0x16 }, 0, .none, .sse }, | ||
| 884 | |||
| 870 | .{ .movss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x10 }, 0, .none, .sse }, | 885 | .{ .movss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x10 }, 0, .none, .sse }, |
| 871 | .{ .movss, .mr, &.{ .xmm_m32, .xmm }, &.{ 0xf3, 0x0f, 0x11 }, 0, .none, .sse }, | 886 | .{ .movss, .mr, &.{ .xmm_m32, .xmm }, &.{ 0xf3, 0x0f, 0x11 }, 0, .none, .sse }, |
| 872 | 887 | ||
| ... | @@ -879,14 +894,16 @@ pub const table = [_]Entry{ | ... | @@ -879,14 +894,16 @@ pub const table = [_]Entry{ |
| 879 | 894 | ||
| 880 | .{ .orps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .none, .sse }, | 895 | .{ .orps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .none, .sse }, |
| 881 | 896 | ||
| 882 | .{ .subps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5c }, 0, .none, .sse }, | 897 | .{ .shufps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x0f, 0xc6 }, 0, .none, .sse }, |
| 883 | |||
| 884 | .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .none, .sse }, | ||
| 885 | 898 | ||
| 886 | .{ .sqrtps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x51 }, 0, .none, .sse }, | 899 | .{ .sqrtps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x51 }, 0, .none, .sse }, |
| 887 | 900 | ||
| 888 | .{ .sqrtss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .none, .sse }, | 901 | .{ .sqrtss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .none, .sse }, |
| 889 | 902 | ||
| 903 | .{ .subps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5c }, 0, .none, .sse }, | ||
| 904 | |||
| 905 | .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .none, .sse }, | ||
| 906 | |||
| 890 | .{ .ucomiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2e }, 0, .none, .sse }, | 907 | .{ .ucomiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2e }, 0, .none, .sse }, |
| 891 | 908 | ||
| 892 | .{ .xorps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .none, .sse }, | 909 | .{ .xorps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .none, .sse }, |
| ... | @@ -902,6 +919,25 @@ pub const table = [_]Entry{ | ... | @@ -902,6 +919,25 @@ pub const table = [_]Entry{ |
| 902 | 919 | ||
| 903 | .{ .cmpsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0xf2, 0x0f, 0xc2 }, 0, .none, .sse2 }, | 920 | .{ .cmpsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0xf2, 0x0f, 0xc2 }, 0, .none, .sse2 }, |
| 904 | 921 | ||
| 922 | .{ .cvtdq2pd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0xe6 }, 0, .none, .sse2 }, | ||
| 923 | |||
| 924 | .{ .cvtdq2ps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5b }, 0, .none, .sse2 }, | ||
| 925 | |||
| 926 | .{ .cvtpd2dq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf2, 0x0f, 0xe6 }, 0, .none, .sse2 }, | ||
| 927 | |||
| 928 | .{ .cvtpd2pi, .rm, &.{ .mm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x2d }, 0, .none, .sse2 }, | ||
| 929 | |||
| 930 | .{ .cvtpd2ps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5a }, 0, .none, .sse2 }, | ||
| 931 | |||
| 932 | .{ .cvtpi2pd, .rm, &.{ .xmm, .mm_m64 }, &.{ 0x66, 0x0f, 0x2a }, 0, .none, .sse2 }, | ||
| 933 | |||
| 934 | .{ .cvtps2dq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5b }, 0, .none, .sse2 }, | ||
| 935 | |||
| 936 | .{ .cvtps2pd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x0f, 0x5a }, 0, .none, .sse2 }, | ||
| 937 | |||
| 938 | .{ .cvtsd2si, .rm, &.{ .r32, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x2d }, 0, .none, .sse2 }, | ||
| 939 | .{ .cvtsd2si, .rm, &.{ .r64, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x2d }, 0, .long, .sse2 }, | ||
| 940 | |||
| 905 | .{ .cvtsd2ss, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .none, .sse2 }, | 941 | .{ .cvtsd2ss, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .none, .sse2 }, |
| 906 | 942 | ||
| 907 | .{ .cvtsi2sd, .rm, &.{ .xmm, .rm32 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .none, .sse2 }, | 943 | .{ .cvtsi2sd, .rm, &.{ .xmm, .rm32 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .none, .sse2 }, |
| ... | @@ -909,6 +945,15 @@ pub const table = [_]Entry{ | ... | @@ -909,6 +945,15 @@ pub const table = [_]Entry{ |
| 909 | 945 | ||
| 910 | .{ .cvtss2sd, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5a }, 0, .none, .sse2 }, | 946 | .{ .cvtss2sd, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5a }, 0, .none, .sse2 }, |
| 911 | 947 | ||
| 948 | .{ .cvttpd2dq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe6 }, 0, .none, .sse2 }, | ||
| 949 | |||
| 950 | .{ .cvttpd2pi, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x2c }, 0, .none, .sse2 }, | ||
| 951 | |||
| 952 | .{ .cvttps2dq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x5b }, 0, .none, .sse2 }, | ||
| 953 | |||
| 954 | .{ .cvttsd2si, .rm, &.{ .r32, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x2c }, 0, .none, .sse2 }, | ||
| 955 | .{ .cvttsd2si, .rm, &.{ .r64, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x2c }, 0, .long, .sse2 }, | ||
| 956 | |||
| 912 | .{ .divpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5e }, 0, .none, .sse2 }, | 957 | .{ .divpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5e }, 0, .none, .sse2 }, |
| 913 | 958 | ||
| 914 | .{ .divsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5e }, 0, .none, .sse2 }, | 959 | .{ .divsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5e }, 0, .none, .sse2 }, |
| ... | @@ -925,11 +970,16 @@ pub const table = [_]Entry{ | ... | @@ -925,11 +970,16 @@ pub const table = [_]Entry{ |
| 925 | .{ .movapd, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x29 }, 0, .none, .sse2 }, | 970 | .{ .movapd, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x29 }, 0, .none, .sse2 }, |
| 926 | 971 | ||
| 927 | .{ .movd, .rm, &.{ .xmm, .rm32 }, &.{ 0x66, 0x0f, 0x6e }, 0, .none, .sse2 }, | 972 | .{ .movd, .rm, &.{ .xmm, .rm32 }, &.{ 0x66, 0x0f, 0x6e }, 0, .none, .sse2 }, |
| 928 | .{ .movd, .mr, &.{ .rm32, .xmm }, &.{ 0x66, 0x0f, 0x7e }, 0, .none, .sse2 }, | ||
| 929 | |||
| 930 | .{ .movq, .rm, &.{ .xmm, .rm64 }, &.{ 0x66, 0x0f, 0x6e }, 0, .long, .sse2 }, | 973 | .{ .movq, .rm, &.{ .xmm, .rm64 }, &.{ 0x66, 0x0f, 0x6e }, 0, .long, .sse2 }, |
| 974 | .{ .movd, .mr, &.{ .rm32, .xmm }, &.{ 0x66, 0x0f, 0x7e }, 0, .none, .sse2 }, | ||
| 931 | .{ .movq, .mr, &.{ .rm64, .xmm }, &.{ 0x66, 0x0f, 0x7e }, 0, .long, .sse2 }, | 975 | .{ .movq, .mr, &.{ .rm64, .xmm }, &.{ 0x66, 0x0f, 0x7e }, 0, .long, .sse2 }, |
| 932 | 976 | ||
| 977 | .{ .movdqa, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6f }, 0, .none, .sse2 }, | ||
| 978 | .{ .movdqa, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x7f }, 0, .none, .sse2 }, | ||
| 979 | |||
| 980 | .{ .movdqu, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x6f }, 0, .none, .sse2 }, | ||
| 981 | .{ .movdqu, .mr, &.{ .xmm_m128, .xmm }, &.{ 0xf3, 0x0f, 0x7f }, 0, .none, .sse2 }, | ||
| 982 | |||
| 933 | .{ .movq, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0x7e }, 0, .none, .sse2 }, | 983 | .{ .movq, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0x7e }, 0, .none, .sse2 }, |
| 934 | .{ .movq, .mr, &.{ .xmm_m64, .xmm }, &.{ 0x66, 0x0f, 0xd6 }, 0, .none, .sse2 }, | 984 | .{ .movq, .mr, &.{ .xmm_m64, .xmm }, &.{ 0x66, 0x0f, 0xd6 }, 0, .none, .sse2 }, |
| 935 | 985 | ||
| ... | @@ -942,10 +992,39 @@ pub const table = [_]Entry{ | ... | @@ -942,10 +992,39 @@ pub const table = [_]Entry{ |
| 942 | 992 | ||
| 943 | .{ .orpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x56 }, 0, .none, .sse2 }, | 993 | .{ .orpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x56 }, 0, .none, .sse2 }, |
| 944 | 994 | ||
| 995 | .{ .paddb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfc }, 0, .none, .sse2 }, | ||
| 996 | .{ .paddw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfd }, 0, .none, .sse2 }, | ||
| 997 | .{ .paddd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfe }, 0, .none, .sse2 }, | ||
| 998 | .{ .paddq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd4 }, 0, .none, .sse2 }, | ||
| 999 | |||
| 1000 | .{ .paddsb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xec }, 0, .none, .sse2 }, | ||
| 1001 | .{ .paddsw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xed }, 0, .none, .sse2 }, | ||
| 1002 | |||
| 1003 | .{ .paddusb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdc }, 0, .none, .sse2 }, | ||
| 1004 | .{ .paddusw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdd }, 0, .none, .sse2 }, | ||
| 1005 | |||
| 1006 | .{ .pand, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdb }, 0, .none, .sse2 }, | ||
| 1007 | |||
| 1008 | .{ .pandn, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdf }, 0, .none, .sse2 }, | ||
| 1009 | |||
| 945 | .{ .pextrw, .rmi, &.{ .r32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0xc5 }, 0, .none, .sse2 }, | 1010 | .{ .pextrw, .rmi, &.{ .r32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0xc5 }, 0, .none, .sse2 }, |
| 946 | 1011 | ||
| 947 | .{ .pinsrw, .rmi, &.{ .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .none, .sse2 }, | 1012 | .{ .pinsrw, .rmi, &.{ .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .none, .sse2 }, |
| 948 | 1013 | ||
| 1014 | .{ .pmaxsw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xee }, 0, .none, .sse2 }, | ||
| 1015 | |||
| 1016 | .{ .pmaxub, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xde }, 0, .none, .sse2 }, | ||
| 1017 | |||
| 1018 | .{ .pminsw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xea }, 0, .none, .sse2 }, | ||
| 1019 | |||
| 1020 | .{ .pminub, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xda }, 0, .none, .sse2 }, | ||
| 1021 | |||
| 1022 | .{ .pmulhw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe5 }, 0, .none, .sse2 }, | ||
| 1023 | |||
| 1024 | .{ .pmullw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd5 }, 0, .none, .sse2 }, | ||
| 1025 | |||
| 1026 | .{ .por, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xeb }, 0, .none, .sse2 }, | ||
| 1027 | |||
| 949 | .{ .pshufhw, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0xf3, 0x0f, 0x70 }, 0, .none, .sse2 }, | 1028 | .{ .pshufhw, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0xf3, 0x0f, 0x70 }, 0, .none, .sse2 }, |
| 950 | 1029 | ||
| 951 | .{ .pshuflw, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0xf2, 0x0f, 0x70 }, 0, .none, .sse2 }, | 1030 | .{ .pshuflw, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0xf2, 0x0f, 0x70 }, 0, .none, .sse2 }, |
| ... | @@ -957,6 +1036,18 @@ pub const table = [_]Entry{ | ... | @@ -957,6 +1036,18 @@ pub const table = [_]Entry{ |
| 957 | .{ .psrlq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd3 }, 0, .none, .sse2 }, | 1036 | .{ .psrlq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd3 }, 0, .none, .sse2 }, |
| 958 | .{ .psrlq, .mi, &.{ .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x73 }, 2, .none, .sse2 }, | 1037 | .{ .psrlq, .mi, &.{ .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x73 }, 2, .none, .sse2 }, |
| 959 | 1038 | ||
| 1039 | .{ .psubb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xf8 }, 0, .none, .sse2 }, | ||
| 1040 | .{ .psubw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xf9 }, 0, .none, .sse2 }, | ||
| 1041 | .{ .psubd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfa }, 0, .none, .sse2 }, | ||
| 1042 | |||
| 1043 | .{ .psubsb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe8 }, 0, .none, .sse2 }, | ||
| 1044 | .{ .psubsw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe9 }, 0, .none, .sse2 }, | ||
| 1045 | |||
| 1046 | .{ .psubq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfb }, 0, .none, .sse2 }, | ||
| 1047 | |||
| 1048 | .{ .psubusb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd8 }, 0, .none, .sse2 }, | ||
| 1049 | .{ .psubusw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd9 }, 0, .none, .sse2 }, | ||
| 1050 | |||
| 960 | .{ .punpckhbw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x68 }, 0, .none, .sse2 }, | 1051 | .{ .punpckhbw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x68 }, 0, .none, .sse2 }, |
| 961 | .{ .punpckhwd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x69 }, 0, .none, .sse2 }, | 1052 | .{ .punpckhwd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x69 }, 0, .none, .sse2 }, |
| 962 | .{ .punpckhdq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6a }, 0, .none, .sse2 }, | 1053 | .{ .punpckhdq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6a }, 0, .none, .sse2 }, |
| ... | @@ -967,6 +1058,10 @@ pub const table = [_]Entry{ | ... | @@ -967,6 +1058,10 @@ pub const table = [_]Entry{ |
| 967 | .{ .punpckldq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x62 }, 0, .none, .sse2 }, | 1058 | .{ .punpckldq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x62 }, 0, .none, .sse2 }, |
| 968 | .{ .punpcklqdq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6c }, 0, .none, .sse2 }, | 1059 | .{ .punpcklqdq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6c }, 0, .none, .sse2 }, |
| 969 | 1060 | ||
| 1061 | .{ .pxor, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xef }, 0, .none, .sse2 }, | ||
| 1062 | |||
| 1063 | .{ .shufpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0xc6 }, 0, .none, .sse2 }, | ||
| 1064 | |||
| 970 | .{ .sqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .none, .sse2 }, | 1065 | .{ .sqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .none, .sse2 }, |
| 971 | 1066 | ||
| 972 | .{ .sqrtsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x51 }, 0, .none, .sse2 }, | 1067 | .{ .sqrtsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x51 }, 0, .none, .sse2 }, |
| ... | @@ -990,6 +1085,10 @@ pub const table = [_]Entry{ | ... | @@ -990,6 +1085,10 @@ pub const table = [_]Entry{ |
| 990 | .{ .movsldup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x12 }, 0, .none, .sse3 }, | 1085 | .{ .movsldup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x12 }, 0, .none, .sse3 }, |
| 991 | 1086 | ||
| 992 | // SSE4.1 | 1087 | // SSE4.1 |
| 1088 | .{ .extractps, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x17 }, 0, .none, .sse4_1 }, | ||
| 1089 | |||
| 1090 | .{ .insertps, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x21 }, 0, .none, .sse4_1 }, | ||
| 1091 | |||
| 993 | .{ .pextrb, .mri, &.{ .r32_m8, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x14 }, 0, .none, .sse4_1 }, | 1092 | .{ .pextrb, .mri, &.{ .r32_m8, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x14 }, 0, .none, .sse4_1 }, |
| 994 | .{ .pextrd, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .none, .sse4_1 }, | 1093 | .{ .pextrd, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .none, .sse4_1 }, |
| 995 | .{ .pextrq, .mri, &.{ .rm64, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .long, .sse4_1 }, | 1094 | .{ .pextrq, .mri, &.{ .rm64, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .long, .sse4_1 }, |
| ... | @@ -1000,6 +1099,22 @@ pub const table = [_]Entry{ | ... | @@ -1000,6 +1099,22 @@ pub const table = [_]Entry{ |
| 1000 | .{ .pinsrd, .rmi, &.{ .xmm, .rm32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .none, .sse4_1 }, | 1099 | .{ .pinsrd, .rmi, &.{ .xmm, .rm32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .none, .sse4_1 }, |
| 1001 | .{ .pinsrq, .rmi, &.{ .xmm, .rm64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .long, .sse4_1 }, | 1100 | .{ .pinsrq, .rmi, &.{ .xmm, .rm64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .long, .sse4_1 }, |
| 1002 | 1101 | ||
| 1102 | .{ .pmaxsb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3c }, 0, .none, .sse4_1 }, | ||
| 1103 | .{ .pmaxsd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3d }, 0, .none, .sse4_1 }, | ||
| 1104 | |||
| 1105 | .{ .pmaxuw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3e }, 0, .none, .sse4_1 }, | ||
| 1106 | |||
| 1107 | .{ .pmaxud, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3f }, 0, .none, .sse4_1 }, | ||
| 1108 | |||
| 1109 | .{ .pminsb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x38 }, 0, .none, .sse4_1 }, | ||
| 1110 | .{ .pminsd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x39 }, 0, .none, .sse4_1 }, | ||
| 1111 | |||
| 1112 | .{ .pminuw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3a }, 0, .none, .sse4_1 }, | ||
| 1113 | |||
| 1114 | .{ .pminud, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3b }, 0, .none, .sse4_1 }, | ||
| 1115 | |||
| 1116 | .{ .pmulld, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x40 }, 0, .none, .sse4_1 }, | ||
| 1117 | |||
| 1003 | .{ .roundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .none, .sse4_1 }, | 1118 | .{ .roundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .none, .sse4_1 }, |
| 1004 | 1119 | ||
| 1005 | .{ .roundps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x08 }, 0, .none, .sse4_1 }, | 1120 | .{ .roundps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x08 }, 0, .none, .sse4_1 }, |
| ... | @@ -1019,15 +1134,68 @@ pub const table = [_]Entry{ | ... | @@ -1019,15 +1134,68 @@ pub const table = [_]Entry{ |
| 1019 | 1134 | ||
| 1020 | .{ .vaddss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x58 }, 0, .vex_lig_wig, .avx }, | 1135 | .{ .vaddss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x58 }, 0, .vex_lig_wig, .avx }, |
| 1021 | 1136 | ||
| 1137 | .{ .vandnpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x55 }, 0, .vex_128_wig, .avx }, | ||
| 1138 | .{ .vandnpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x55 }, 0, .vex_256_wig, .avx }, | ||
| 1139 | |||
| 1140 | .{ .vandnps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x55 }, 0, .vex_128_wig, .avx }, | ||
| 1141 | .{ .vandnps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x55 }, 0, .vex_256_wig, .avx }, | ||
| 1142 | |||
| 1143 | .{ .vandpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x54 }, 0, .vex_128_wig, .avx }, | ||
| 1144 | .{ .vandpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x54 }, 0, .vex_256_wig, .avx }, | ||
| 1145 | |||
| 1146 | .{ .vandps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x54 }, 0, .vex_128_wig, .avx }, | ||
| 1147 | .{ .vandps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x54 }, 0, .vex_256_wig, .avx }, | ||
| 1148 | |||
| 1149 | .{ .vbroadcastss, .rm, &.{ .xmm, .m32 }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_128_w0, .avx }, | ||
| 1150 | .{ .vbroadcastss, .rm, &.{ .ymm, .m32 }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx }, | ||
| 1151 | .{ .vbroadcastsd, .rm, &.{ .ymm, .m64 }, &.{ 0x66, 0x0f, 0x38, 0x19 }, 0, .vex_256_w0, .avx }, | ||
| 1152 | .{ .vbroadcastf128, .rm, &.{ .ymm, .m128 }, &.{ 0x66, 0x0f, 0x38, 0x1a }, 0, .vex_256_w0, .avx }, | ||
| 1153 | |||
| 1154 | .{ .vcvtdq2pd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0xe6 }, 0, .vex_128_wig, .avx }, | ||
| 1155 | .{ .vcvtdq2pd, .rm, &.{ .ymm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0xe6 }, 0, .vex_256_wig, .avx }, | ||
| 1156 | |||
| 1157 | .{ .vcvtdq2ps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5b }, 0, .vex_128_wig, .avx }, | ||
| 1158 | .{ .vcvtdq2ps, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x0f, 0x5b }, 0, .vex_256_wig, .avx }, | ||
| 1159 | |||
| 1160 | .{ .vcvtpd2dq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf2, 0x0f, 0xe6 }, 0, .vex_128_wig, .avx }, | ||
| 1161 | .{ .vcvtpd2dq, .rm, &.{ .xmm, .ymm_m256 }, &.{ 0xf2, 0x0f, 0xe6 }, 0, .vex_256_wig, .avx }, | ||
| 1162 | |||
| 1163 | .{ .vcvtpd2ps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5a }, 0, .vex_128_wig, .avx }, | ||
| 1164 | .{ .vcvtpd2ps, .rm, &.{ .xmm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5a }, 0, .vex_256_wig, .avx }, | ||
| 1165 | |||
| 1166 | .{ .vcvtps2dq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5b }, 0, .vex_128_wig, .avx }, | ||
| 1167 | .{ .vcvtps2dq, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5b }, 0, .vex_256_wig, .avx }, | ||
| 1168 | |||
| 1169 | .{ .vcvtps2pd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x0f, 0x5a }, 0, .vex_128_wig, .avx }, | ||
| 1170 | .{ .vcvtps2pd, .rm, &.{ .ymm, .xmm_m128 }, &.{ 0x0f, 0x5a }, 0, .vex_256_wig, .avx }, | ||
| 1171 | |||
| 1172 | .{ .vcvtsd2si, .rm, &.{ .r32, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x2d }, 0, .vex_lig_w0, .sse2 }, | ||
| 1173 | .{ .vcvtsd2si, .rm, &.{ .r64, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x2d }, 0, .vex_lig_w1, .sse2 }, | ||
| 1174 | |||
| 1022 | .{ .vcvtsd2ss, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx }, | 1175 | .{ .vcvtsd2ss, .rvm, &.{ .xmm, .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx }, |
| 1023 | 1176 | ||
| 1024 | .{ .vcvtsi2sd, .rvm, &.{ .xmm, .xmm, .rm32 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .vex_lig_w0, .avx }, | 1177 | .{ .vcvtsi2sd, .rvm, &.{ .xmm, .xmm, .rm32 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .vex_lig_w0, .avx }, |
| 1025 | .{ .vcvtsi2sd, .rvm, &.{ .xmm, .xmm, .rm64 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .vex_lig_w1, .avx }, | 1178 | .{ .vcvtsi2sd, .rvm, &.{ .xmm, .xmm, .rm64 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .vex_lig_w1, .avx }, |
| 1026 | 1179 | ||
| 1027 | .{ .vcvtsi2ss, .rvm, &.{ .xmm, .xmm, .rm32 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .vex_lig_w0, .avx }, | 1180 | .{ .vcvtsi2ss, .rvm, &.{ .xmm, .xmm, .rm32 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .vex_lig_w0, .avx }, |
| 1028 | .{ .vcvtsi2ss, .rvm, &.{ .xmm, .xmm, .rm64 }, &.{ 0xf2, 0x0f, 0x2a }, 0, .vex_lig_w1, .avx }, | 1181 | .{ .vcvtsi2ss, .rvm, &.{ .xmm, .xmm, .rm64 }, &.{ 0xf3, 0x0f, 0x2a }, 0, .vex_lig_w1, .avx }, |
| 1182 | |||
| 1183 | .{ .vcvtss2sd, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx }, | ||
| 1184 | |||
| 1185 | .{ .vcvtss2si, .rm, &.{ .r32, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x2d }, 0, .vex_lig_w0, .avx }, | ||
| 1186 | .{ .vcvtss2si, .rm, &.{ .r64, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x2d }, 0, .vex_lig_w1, .avx }, | ||
| 1187 | |||
| 1188 | .{ .vcvttpd2dq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe6 }, 0, .vex_128_wig, .avx }, | ||
| 1189 | .{ .vcvttpd2dq, .rm, &.{ .xmm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xe6 }, 0, .vex_256_wig, .avx }, | ||
| 1029 | 1190 | ||
| 1030 | .{ .vcvtss2sd, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf2, 0x0f, 0x5a }, 0, .vex_lig_wig, .avx }, | 1191 | .{ .vcvttps2dq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x5b }, 0, .vex_128_wig, .avx }, |
| 1192 | .{ .vcvttps2dq, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0xf3, 0x0f, 0x5b }, 0, .vex_256_wig, .avx }, | ||
| 1193 | |||
| 1194 | .{ .vcvttsd2si, .rm, &.{ .r32, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x2c }, 0, .vex_lig_w0, .sse2 }, | ||
| 1195 | .{ .vcvttsd2si, .rm, &.{ .r64, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x2c }, 0, .vex_lig_w1, .sse2 }, | ||
| 1196 | |||
| 1197 | .{ .vcvttss2si, .rm, &.{ .r32, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x2c }, 0, .vex_lig_w0, .avx }, | ||
| 1198 | .{ .vcvttss2si, .rm, &.{ .r64, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x2c }, 0, .vex_lig_w1, .avx }, | ||
| 1031 | 1199 | ||
| 1032 | .{ .vdivpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5e }, 0, .vex_128_wig, .avx }, | 1200 | .{ .vdivpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5e }, 0, .vex_128_wig, .avx }, |
| 1033 | .{ .vdivpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5e }, 0, .vex_256_wig, .avx }, | 1201 | .{ .vdivpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5e }, 0, .vex_256_wig, .avx }, |
| ... | @@ -1039,6 +1207,14 @@ pub const table = [_]Entry{ | ... | @@ -1039,6 +1207,14 @@ pub const table = [_]Entry{ |
| 1039 | 1207 | ||
| 1040 | .{ .vdivss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .vex_lig_wig, .avx }, | 1208 | .{ .vdivss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .vex_lig_wig, .avx }, |
| 1041 | 1209 | ||
| 1210 | .{ .vextractf128, .mri, &.{ .xmm_m128, .ymm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x19 }, 0, .vex_256_w0, .avx }, | ||
| 1211 | |||
| 1212 | .{ .vextractps, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x17 }, 0, .vex_128_wig, .avx }, | ||
| 1213 | |||
| 1214 | .{ .vinsertf128, .rvmi, &.{ .ymm, .ymm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x18 }, 0, .vex_256_w0, .avx }, | ||
| 1215 | |||
| 1216 | .{ .vinsertps, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x21 }, 0, .vex_128_wig, .avx }, | ||
| 1217 | |||
| 1042 | .{ .vmaxpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_128_wig, .avx }, | 1218 | .{ .vmaxpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_128_wig, .avx }, |
| 1043 | .{ .vmaxpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_256_wig, .avx }, | 1219 | .{ .vmaxpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_256_wig, .avx }, |
| 1044 | 1220 | ||
| ... | @@ -1069,11 +1245,31 @@ pub const table = [_]Entry{ | ... | @@ -1069,11 +1245,31 @@ pub const table = [_]Entry{ |
| 1069 | .{ .vmovaps, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x0f, 0x28 }, 0, .vex_256_wig, .avx }, | 1245 | .{ .vmovaps, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x0f, 0x28 }, 0, .vex_256_wig, .avx }, |
| 1070 | .{ .vmovaps, .mr, &.{ .ymm_m256, .ymm }, &.{ 0x0f, 0x29 }, 0, .vex_256_wig, .avx }, | 1246 | .{ .vmovaps, .mr, &.{ .ymm_m256, .ymm }, &.{ 0x0f, 0x29 }, 0, .vex_256_wig, .avx }, |
| 1071 | 1247 | ||
| 1248 | .{ .vmovd, .rm, &.{ .xmm, .rm32 }, &.{ 0x66, 0x0f, 0x6e }, 0, .vex_128_w0, .avx }, | ||
| 1249 | .{ .vmovq, .rm, &.{ .xmm, .rm64 }, &.{ 0x66, 0x0f, 0x6e }, 0, .vex_128_w1, .avx }, | ||
| 1250 | .{ .vmovd, .mr, &.{ .rm32, .xmm }, &.{ 0x66, 0x0f, 0x7e }, 0, .vex_128_w0, .avx }, | ||
| 1251 | .{ .vmovq, .mr, &.{ .rm64, .xmm }, &.{ 0x66, 0x0f, 0x7e }, 0, .vex_128_w1, .avx }, | ||
| 1252 | |||
| 1072 | .{ .vmovddup, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .vex_128_wig, .avx }, | 1253 | .{ .vmovddup, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .vex_128_wig, .avx }, |
| 1073 | .{ .vmovddup, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .vex_256_wig, .avx }, | 1254 | .{ .vmovddup, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .vex_256_wig, .avx }, |
| 1074 | 1255 | ||
| 1256 | .{ .vmovdqa, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6f }, 0, .vex_128_wig, .avx }, | ||
| 1257 | .{ .vmovdqa, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x7f }, 0, .vex_128_wig, .avx }, | ||
| 1258 | .{ .vmovdqa, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x6f }, 0, .vex_256_wig, .avx }, | ||
| 1259 | .{ .vmovdqa, .mr, &.{ .ymm_m256, .ymm }, &.{ 0x66, 0x0f, 0x7f }, 0, .vex_256_wig, .avx }, | ||
| 1260 | |||
| 1261 | .{ .vmovdqu, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x6f }, 0, .vex_128_wig, .avx }, | ||
| 1262 | .{ .vmovdqu, .mr, &.{ .xmm_m128, .xmm }, &.{ 0xf3, 0x0f, 0x7f }, 0, .vex_128_wig, .avx }, | ||
| 1263 | .{ .vmovdqu, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0xf3, 0x0f, 0x6f }, 0, .vex_256_wig, .avx }, | ||
| 1264 | .{ .vmovdqu, .mr, &.{ .ymm_m256, .ymm }, &.{ 0xf3, 0x0f, 0x7f }, 0, .vex_256_wig, .avx }, | ||
| 1265 | |||
| 1075 | .{ .vmovhlps, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .vex_128_wig, .avx }, | 1266 | .{ .vmovhlps, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .vex_128_wig, .avx }, |
| 1076 | 1267 | ||
| 1268 | .{ .vmovlhps, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0x0f, 0x16 }, 0, .vex_128_wig, .avx }, | ||
| 1269 | |||
| 1270 | .{ .vmovq, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0x7e }, 0, .vex_128_wig, .avx }, | ||
| 1271 | .{ .vmovq, .mr, &.{ .xmm_m64, .xmm }, &.{ 0x66, 0x0f, 0xd6 }, 0, .vex_128_wig, .avx }, | ||
| 1272 | |||
| 1077 | .{ .vmovsd, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx }, | 1273 | .{ .vmovsd, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx }, |
| 1078 | .{ .vmovsd, .rm, &.{ .xmm, .m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx }, | 1274 | .{ .vmovsd, .rm, &.{ .xmm, .m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx }, |
| 1079 | .{ .vmovsd, .mvr, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x11 }, 0, .vex_lig_wig, .avx }, | 1275 | .{ .vmovsd, .mvr, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x11 }, 0, .vex_lig_wig, .avx }, |
| ... | @@ -1110,6 +1306,27 @@ pub const table = [_]Entry{ | ... | @@ -1110,6 +1306,27 @@ pub const table = [_]Entry{ |
| 1110 | 1306 | ||
| 1111 | .{ .vmulss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .vex_lig_wig, .avx }, | 1307 | .{ .vmulss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .vex_lig_wig, .avx }, |
| 1112 | 1308 | ||
| 1309 | .{ .vorpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x56 }, 0, .vex_128_wig, .avx }, | ||
| 1310 | .{ .vorpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x56 }, 0, .vex_256_wig, .avx }, | ||
| 1311 | |||
| 1312 | .{ .vorps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .vex_128_wig, .avx }, | ||
| 1313 | .{ .vorps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x56 }, 0, .vex_256_wig, .avx }, | ||
| 1314 | |||
| 1315 | .{ .vpaddb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfc }, 0, .vex_128_wig, .avx }, | ||
| 1316 | .{ .vpaddw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfd }, 0, .vex_128_wig, .avx }, | ||
| 1317 | .{ .vpaddd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfe }, 0, .vex_128_wig, .avx }, | ||
| 1318 | .{ .vpaddq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd4 }, 0, .vex_128_wig, .avx }, | ||
| 1319 | |||
| 1320 | .{ .vpaddsb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xec }, 0, .vex_128_wig, .avx }, | ||
| 1321 | .{ .vpaddsw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xed }, 0, .vex_128_wig, .avx }, | ||
| 1322 | |||
| 1323 | .{ .vpaddusb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdc }, 0, .vex_128_wig, .avx }, | ||
| 1324 | .{ .vpaddusw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdd }, 0, .vex_128_wig, .avx }, | ||
| 1325 | |||
| 1326 | .{ .vpand, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdb }, 0, .vex_128_wig, .avx }, | ||
| 1327 | |||
| 1328 | .{ .vpandn, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xdf }, 0, .vex_128_wig, .avx }, | ||
| 1329 | |||
| 1113 | .{ .vpextrb, .mri, &.{ .r32_m8, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x14 }, 0, .vex_128_w0, .avx }, | 1330 | .{ .vpextrb, .mri, &.{ .r32_m8, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x14 }, 0, .vex_128_w0, .avx }, |
| 1114 | .{ .vpextrd, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .vex_128_w0, .avx }, | 1331 | .{ .vpextrd, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .vex_128_w0, .avx }, |
| 1115 | .{ .vpextrq, .mri, &.{ .rm64, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .vex_128_w1, .avx }, | 1332 | .{ .vpextrq, .mri, &.{ .rm64, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .vex_128_w1, .avx }, |
| ... | @@ -1123,6 +1340,32 @@ pub const table = [_]Entry{ | ... | @@ -1123,6 +1340,32 @@ pub const table = [_]Entry{ |
| 1123 | 1340 | ||
| 1124 | .{ .vpinsrw, .rvmi, &.{ .xmm, .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .vex_128_wig, .avx }, | 1341 | .{ .vpinsrw, .rvmi, &.{ .xmm, .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .vex_128_wig, .avx }, |
| 1125 | 1342 | ||
| 1343 | .{ .vpmaxsb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3c }, 0, .vex_128_wig, .avx }, | ||
| 1344 | .{ .vpmaxsw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xee }, 0, .vex_128_wig, .avx }, | ||
| 1345 | .{ .vpmaxsd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3d }, 0, .vex_128_wig, .avx }, | ||
| 1346 | |||
| 1347 | .{ .vpmaxub, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xde }, 0, .vex_128_wig, .avx }, | ||
| 1348 | .{ .vpmaxuw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3e }, 0, .vex_128_wig, .avx }, | ||
| 1349 | |||
| 1350 | .{ .vpmaxud, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3f }, 0, .vex_128_wig, .avx }, | ||
| 1351 | |||
| 1352 | .{ .vpminsb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x38 }, 0, .vex_128_wig, .avx }, | ||
| 1353 | .{ .vpminsw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xea }, 0, .vex_128_wig, .avx }, | ||
| 1354 | .{ .vpminsd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x39 }, 0, .vex_128_wig, .avx }, | ||
| 1355 | |||
| 1356 | .{ .vpminub, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xda }, 0, .vex_128_wig, .avx }, | ||
| 1357 | .{ .vpminuw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3a }, 0, .vex_128_wig, .avx }, | ||
| 1358 | |||
| 1359 | .{ .vpminud, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x3b }, 0, .vex_128_wig, .avx }, | ||
| 1360 | |||
| 1361 | .{ .vpmulhw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe5 }, 0, .vex_128_wig, .avx }, | ||
| 1362 | |||
| 1363 | .{ .vpmulld, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x40 }, 0, .vex_128_wig, .avx }, | ||
| 1364 | |||
| 1365 | .{ .vpmullw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd5 }, 0, .vex_128_wig, .avx }, | ||
| 1366 | |||
| 1367 | .{ .vpor, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xeb }, 0, .vex_128_wig, .avx }, | ||
| 1368 | |||
| 1126 | .{ .vpsrlw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_128_wig, .avx }, | 1369 | .{ .vpsrlw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_128_wig, .avx }, |
| 1127 | .{ .vpsrlw, .vmi, &.{ .xmm, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x71 }, 2, .vex_128_wig, .avx }, | 1370 | .{ .vpsrlw, .vmi, &.{ .xmm, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x71 }, 2, .vex_128_wig, .avx }, |
| 1128 | .{ .vpsrld, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd2 }, 0, .vex_128_wig, .avx }, | 1371 | .{ .vpsrld, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd2 }, 0, .vex_128_wig, .avx }, |
| ... | @@ -1130,6 +1373,18 @@ pub const table = [_]Entry{ | ... | @@ -1130,6 +1373,18 @@ pub const table = [_]Entry{ |
| 1130 | .{ .vpsrlq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd3 }, 0, .vex_128_wig, .avx }, | 1373 | .{ .vpsrlq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd3 }, 0, .vex_128_wig, .avx }, |
| 1131 | .{ .vpsrlq, .vmi, &.{ .xmm, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x73 }, 2, .vex_128_wig, .avx }, | 1374 | .{ .vpsrlq, .vmi, &.{ .xmm, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x73 }, 2, .vex_128_wig, .avx }, |
| 1132 | 1375 | ||
| 1376 | .{ .vpsubb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xf8 }, 0, .vex_128_wig, .avx }, | ||
| 1377 | .{ .vpsubw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xf9 }, 0, .vex_128_wig, .avx }, | ||
| 1378 | .{ .vpsubd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfa }, 0, .vex_128_wig, .avx }, | ||
| 1379 | |||
| 1380 | .{ .vpsubsb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe8 }, 0, .vex_128_wig, .avx }, | ||
| 1381 | .{ .vpsubsw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xe9 }, 0, .vex_128_wig, .avx }, | ||
| 1382 | |||
| 1383 | .{ .vpsubq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfb }, 0, .vex_128_wig, .avx }, | ||
| 1384 | |||
| 1385 | .{ .vpsubusb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd8 }, 0, .vex_128_wig, .avx }, | ||
| 1386 | .{ .vpsubusw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd9 }, 0, .vex_128_wig, .avx }, | ||
| 1387 | |||
| 1133 | .{ .vpunpckhbw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x68 }, 0, .vex_128_wig, .avx }, | 1388 | .{ .vpunpckhbw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x68 }, 0, .vex_128_wig, .avx }, |
| 1134 | .{ .vpunpckhwd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x69 }, 0, .vex_128_wig, .avx }, | 1389 | .{ .vpunpckhwd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x69 }, 0, .vex_128_wig, .avx }, |
| 1135 | .{ .vpunpckhdq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6a }, 0, .vex_128_wig, .avx }, | 1390 | .{ .vpunpckhdq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6a }, 0, .vex_128_wig, .avx }, |
| ... | @@ -1140,6 +1395,8 @@ pub const table = [_]Entry{ | ... | @@ -1140,6 +1395,8 @@ pub const table = [_]Entry{ |
| 1140 | .{ .vpunpckldq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x62 }, 0, .vex_128_wig, .avx }, | 1395 | .{ .vpunpckldq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x62 }, 0, .vex_128_wig, .avx }, |
| 1141 | .{ .vpunpcklqdq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6c }, 0, .vex_128_wig, .avx }, | 1396 | .{ .vpunpcklqdq, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6c }, 0, .vex_128_wig, .avx }, |
| 1142 | 1397 | ||
| 1398 | .{ .vpxor, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xef }, 0, .vex_128_wig, .avx }, | ||
| 1399 | |||
| 1143 | .{ .vroundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .vex_128_wig, .avx }, | 1400 | .{ .vroundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .vex_128_wig, .avx }, |
| 1144 | .{ .vroundpd, .rmi, &.{ .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .vex_256_wig, .avx }, | 1401 | .{ .vroundpd, .rmi, &.{ .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .vex_256_wig, .avx }, |
| 1145 | 1402 | ||
| ... | @@ -1150,6 +1407,12 @@ pub const table = [_]Entry{ | ... | @@ -1150,6 +1407,12 @@ pub const table = [_]Entry{ |
| 1150 | 1407 | ||
| 1151 | .{ .vroundss, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .vex_lig_wig, .avx }, | 1408 | .{ .vroundss, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .vex_lig_wig, .avx }, |
| 1152 | 1409 | ||
| 1410 | .{ .vshufpd, .rvmi, &.{ .xmm, .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0xc6 }, 0, .vex_128_wig, .avx }, | ||
| 1411 | .{ .vshufpd, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0xc6 }, 0, .vex_256_wig, .avx }, | ||
| 1412 | |||
| 1413 | .{ .vshufps, .rvmi, &.{ .xmm, .xmm, .xmm_m128, .imm8 }, &.{ 0x0f, 0xc6 }, 0, .vex_128_wig, .avx }, | ||
| 1414 | .{ .vshufps, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x0f, 0xc6 }, 0, .vex_256_wig, .avx }, | ||
| 1415 | |||
| 1153 | .{ .vsqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_128_wig, .avx }, | 1416 | .{ .vsqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_128_wig, .avx }, |
| 1154 | .{ .vsqrtpd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_256_wig, .avx }, | 1417 | .{ .vsqrtpd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x51 }, 0, .vex_256_wig, .avx }, |
| 1155 | 1418 | ||
| ... | @@ -1170,6 +1433,12 @@ pub const table = [_]Entry{ | ... | @@ -1170,6 +1433,12 @@ pub const table = [_]Entry{ |
| 1170 | 1433 | ||
| 1171 | .{ .vsubss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .vex_lig_wig, .avx }, | 1434 | .{ .vsubss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .vex_lig_wig, .avx }, |
| 1172 | 1435 | ||
| 1436 | .{ .vxorpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x57 }, 0, .vex_128_wig, .avx }, | ||
| 1437 | .{ .vxorpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x57 }, 0, .vex_256_wig, .avx }, | ||
| 1438 | |||
| 1439 | .{ .vxorps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .vex_128_wig, .avx }, | ||
| 1440 | .{ .vxorps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x57 }, 0, .vex_256_wig, .avx }, | ||
| 1441 | |||
| 1173 | // F16C | 1442 | // F16C |
| 1174 | .{ .vcvtph2ps, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_128_w0, .f16c }, | 1443 | .{ .vcvtph2ps, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_128_w0, .f16c }, |
| 1175 | .{ .vcvtph2ps, .rm, &.{ .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_256_w0, .f16c }, | 1444 | .{ .vcvtph2ps, .rm, &.{ .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_256_w0, .f16c }, |
| ... | @@ -1201,6 +1470,51 @@ pub const table = [_]Entry{ | ... | @@ -1201,6 +1470,51 @@ pub const table = [_]Entry{ |
| 1201 | .{ .vfmadd231ss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0x66, 0x0f, 0x38, 0xb9 }, 0, .vex_lig_w0, .fma }, | 1470 | .{ .vfmadd231ss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0x66, 0x0f, 0x38, 0xb9 }, 0, .vex_lig_w0, .fma }, |
| 1202 | 1471 | ||
| 1203 | // AVX2 | 1472 | // AVX2 |
| 1473 | .{ .vbroadcastss, .rm, &.{ .xmm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_128_w0, .avx2 }, | ||
| 1474 | .{ .vbroadcastss, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx2 }, | ||
| 1475 | .{ .vbroadcastsd, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x19 }, 0, .vex_256_w0, .avx2 }, | ||
| 1476 | |||
| 1477 | .{ .vpaddb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfc }, 0, .vex_256_wig, .avx2 }, | ||
| 1478 | .{ .vpaddw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfd }, 0, .vex_256_wig, .avx2 }, | ||
| 1479 | .{ .vpaddd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfe }, 0, .vex_256_wig, .avx2 }, | ||
| 1480 | .{ .vpaddq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xd4 }, 0, .vex_256_wig, .avx2 }, | ||
| 1481 | |||
| 1482 | .{ .vpaddsb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xec }, 0, .vex_256_wig, .avx2 }, | ||
| 1483 | .{ .vpaddsw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xed }, 0, .vex_256_wig, .avx2 }, | ||
| 1484 | |||
| 1485 | .{ .vpaddusb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xdc }, 0, .vex_256_wig, .avx2 }, | ||
| 1486 | .{ .vpaddusw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xdd }, 0, .vex_256_wig, .avx2 }, | ||
| 1487 | |||
| 1488 | .{ .vpand, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xdb }, 0, .vex_256_wig, .avx2 }, | ||
| 1489 | |||
| 1490 | .{ .vpandn, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xdf }, 0, .vex_256_wig, .avx2 }, | ||
| 1491 | |||
| 1492 | .{ .vpmaxsb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x3c }, 0, .vex_256_wig, .avx }, | ||
| 1493 | .{ .vpmaxsw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xee }, 0, .vex_256_wig, .avx }, | ||
| 1494 | .{ .vpmaxsd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x3d }, 0, .vex_256_wig, .avx }, | ||
| 1495 | |||
| 1496 | .{ .vpmaxub, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xde }, 0, .vex_256_wig, .avx }, | ||
| 1497 | .{ .vpmaxuw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x3e }, 0, .vex_256_wig, .avx }, | ||
| 1498 | |||
| 1499 | .{ .vpmaxud, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x3f }, 0, .vex_256_wig, .avx }, | ||
| 1500 | |||
| 1501 | .{ .vpminsb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x38 }, 0, .vex_256_wig, .avx }, | ||
| 1502 | .{ .vpminsw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xea }, 0, .vex_256_wig, .avx }, | ||
| 1503 | .{ .vpminsd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x39 }, 0, .vex_256_wig, .avx }, | ||
| 1504 | |||
| 1505 | .{ .vpminub, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xda }, 0, .vex_256_wig, .avx }, | ||
| 1506 | .{ .vpminuw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x3a }, 0, .vex_256_wig, .avx }, | ||
| 1507 | |||
| 1508 | .{ .vpminud, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x3b }, 0, .vex_256_wig, .avx }, | ||
| 1509 | |||
| 1510 | .{ .vpmulhw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xe5 }, 0, .vex_256_wig, .avx }, | ||
| 1511 | |||
| 1512 | .{ .vpmulld, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x40 }, 0, .vex_256_wig, .avx }, | ||
| 1513 | |||
| 1514 | .{ .vpmullw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xd5 }, 0, .vex_256_wig, .avx }, | ||
| 1515 | |||
| 1516 | .{ .vpor, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xeb }, 0, .vex_256_wig, .avx2 }, | ||
| 1517 | |||
| 1204 | .{ .vpsrlw, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_256_wig, .avx2 }, | 1518 | .{ .vpsrlw, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_256_wig, .avx2 }, |
| 1205 | .{ .vpsrlw, .vmi, &.{ .ymm, .ymm, .imm8 }, &.{ 0x66, 0x0f, 0x71 }, 2, .vex_256_wig, .avx2 }, | 1519 | .{ .vpsrlw, .vmi, &.{ .ymm, .ymm, .imm8 }, &.{ 0x66, 0x0f, 0x71 }, 2, .vex_256_wig, .avx2 }, |
| 1206 | .{ .vpsrld, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd2 }, 0, .vex_256_wig, .avx2 }, | 1520 | .{ .vpsrld, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd2 }, 0, .vex_256_wig, .avx2 }, |
| ... | @@ -1208,6 +1522,18 @@ pub const table = [_]Entry{ | ... | @@ -1208,6 +1522,18 @@ pub const table = [_]Entry{ |
| 1208 | .{ .vpsrlq, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd3 }, 0, .vex_256_wig, .avx2 }, | 1522 | .{ .vpsrlq, .rvm, &.{ .ymm, .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd3 }, 0, .vex_256_wig, .avx2 }, |
| 1209 | .{ .vpsrlq, .vmi, &.{ .ymm, .ymm, .imm8 }, &.{ 0x66, 0x0f, 0x73 }, 2, .vex_256_wig, .avx2 }, | 1523 | .{ .vpsrlq, .vmi, &.{ .ymm, .ymm, .imm8 }, &.{ 0x66, 0x0f, 0x73 }, 2, .vex_256_wig, .avx2 }, |
| 1210 | 1524 | ||
| 1525 | .{ .vpsubb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xf8 }, 0, .vex_256_wig, .avx2 }, | ||
| 1526 | .{ .vpsubw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xf9 }, 0, .vex_256_wig, .avx2 }, | ||
| 1527 | .{ .vpsubd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfa }, 0, .vex_256_wig, .avx2 }, | ||
| 1528 | |||
| 1529 | .{ .vpsubsb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xe8 }, 0, .vex_256_wig, .avx2 }, | ||
| 1530 | .{ .vpsubsw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xe9 }, 0, .vex_256_wig, .avx2 }, | ||
| 1531 | |||
| 1532 | .{ .vpsubq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfb }, 0, .vex_256_wig, .avx2 }, | ||
| 1533 | |||
| 1534 | .{ .vpsubusb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xd8 }, 0, .vex_256_wig, .avx2 }, | ||
| 1535 | .{ .vpsubusw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xd9 }, 0, .vex_256_wig, .avx2 }, | ||
| 1536 | |||
| 1211 | .{ .vpunpckhbw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x68 }, 0, .vex_256_wig, .avx2 }, | 1537 | .{ .vpunpckhbw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x68 }, 0, .vex_256_wig, .avx2 }, |
| 1212 | .{ .vpunpckhwd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x69 }, 0, .vex_256_wig, .avx2 }, | 1538 | .{ .vpunpckhwd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x69 }, 0, .vex_256_wig, .avx2 }, |
| 1213 | .{ .vpunpckhdq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x6a }, 0, .vex_256_wig, .avx2 }, | 1539 | .{ .vpunpckhdq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x6a }, 0, .vex_256_wig, .avx2 }, |
| ... | @@ -1217,5 +1543,7 @@ pub const table = [_]Entry{ | ... | @@ -1217,5 +1543,7 @@ pub const table = [_]Entry{ |
| 1217 | .{ .vpunpcklwd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x61 }, 0, .vex_256_wig, .avx2 }, | 1543 | .{ .vpunpcklwd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x61 }, 0, .vex_256_wig, .avx2 }, |
| 1218 | .{ .vpunpckldq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x62 }, 0, .vex_256_wig, .avx2 }, | 1544 | .{ .vpunpckldq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x62 }, 0, .vex_256_wig, .avx2 }, |
| 1219 | .{ .vpunpcklqdq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x6c }, 0, .vex_256_wig, .avx2 }, | 1545 | .{ .vpunpcklqdq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x6c }, 0, .vex_256_wig, .avx2 }, |
| 1546 | |||
| 1547 | .{ .vpxor, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xef }, 0, .vex_256_wig, .avx2 }, | ||
| 1220 | }; | 1548 | }; |
| 1221 | // zig fmt: on | 1549 | // zig fmt: on |
src/codegen.zig+39-9| ... | @@ -380,7 +380,7 @@ pub fn generateSymbol( | ... | @@ -380,7 +380,7 @@ pub fn generateSymbol( |
| 380 | 380 | ||
| 381 | return Result.ok; | 381 | return Result.ok; |
| 382 | }, | 382 | }, |
| 383 | .field_ptr, .elem_ptr => return lowerParentPtr( | 383 | .field_ptr, .elem_ptr, .opt_payload_ptr => return lowerParentPtr( |
| 384 | bin_file, | 384 | bin_file, |
| 385 | src_loc, | 385 | src_loc, |
| 386 | typed_value, | 386 | typed_value, |
| ... | @@ -812,7 +812,6 @@ fn lowerParentPtr( | ... | @@ -812,7 +812,6 @@ fn lowerParentPtr( |
| 812 | reloc_info: RelocInfo, | 812 | reloc_info: RelocInfo, |
| 813 | ) CodeGenError!Result { | 813 | ) CodeGenError!Result { |
| 814 | const target = bin_file.options.target; | 814 | const target = bin_file.options.target; |
| 815 | |||
| 816 | switch (parent_ptr.tag()) { | 815 | switch (parent_ptr.tag()) { |
| 817 | .field_ptr => { | 816 | .field_ptr => { |
| 818 | const field_ptr = parent_ptr.castTag(.field_ptr).?.data; | 817 | const field_ptr = parent_ptr.castTag(.field_ptr).?.data; |
| ... | @@ -858,6 +857,31 @@ fn lowerParentPtr( | ... | @@ -858,6 +857,31 @@ fn lowerParentPtr( |
| 858 | reloc_info.offset(@intCast(u32, elem_ptr.index * elem_ptr.elem_ty.abiSize(target))), | 857 | reloc_info.offset(@intCast(u32, elem_ptr.index * elem_ptr.elem_ty.abiSize(target))), |
| 859 | ); | 858 | ); |
| 860 | }, | 859 | }, |
| 860 | .opt_payload_ptr => { | ||
| 861 | const opt_payload_ptr = parent_ptr.castTag(.opt_payload_ptr).?.data; | ||
| 862 | return lowerParentPtr( | ||
| 863 | bin_file, | ||
| 864 | src_loc, | ||
| 865 | typed_value, | ||
| 866 | opt_payload_ptr.container_ptr, | ||
| 867 | code, | ||
| 868 | debug_output, | ||
| 869 | reloc_info, | ||
| 870 | ); | ||
| 871 | }, | ||
| 872 | .eu_payload_ptr => { | ||
| 873 | const eu_payload_ptr = parent_ptr.castTag(.eu_payload_ptr).?.data; | ||
| 874 | const pl_ty = eu_payload_ptr.container_ty.errorUnionPayload(); | ||
| 875 | return lowerParentPtr( | ||
| 876 | bin_file, | ||
| 877 | src_loc, | ||
| 878 | typed_value, | ||
| 879 | eu_payload_ptr.container_ptr, | ||
| 880 | code, | ||
| 881 | debug_output, | ||
| 882 | reloc_info.offset(@intCast(u32, errUnionPayloadOffset(pl_ty, target))), | ||
| 883 | ); | ||
| 884 | }, | ||
| 861 | .variable, .decl_ref, .decl_ref_mut => |tag| return lowerDeclRef( | 885 | .variable, .decl_ref, .decl_ref_mut => |tag| return lowerDeclRef( |
| 862 | bin_file, | 886 | bin_file, |
| 863 | src_loc, | 887 | src_loc, |
| ... | @@ -1189,12 +1213,16 @@ pub fn genTypedValue( | ... | @@ -1189,12 +1213,16 @@ pub fn genTypedValue( |
| 1189 | .enum_simple => { | 1213 | .enum_simple => { |
| 1190 | return GenResult.mcv(.{ .immediate = field_index.data }); | 1214 | return GenResult.mcv(.{ .immediate = field_index.data }); |
| 1191 | }, | 1215 | }, |
| 1192 | .enum_full, .enum_nonexhaustive => { | 1216 | .enum_numbered, .enum_full, .enum_nonexhaustive => { |
| 1193 | const enum_full = typed_value.ty.cast(Type.Payload.EnumFull).?.data; | 1217 | const enum_values = if (typed_value.ty.castTag(.enum_numbered)) |pl| |
| 1194 | if (enum_full.values.count() != 0) { | 1218 | pl.data.values |
| 1195 | const tag_val = enum_full.values.keys()[field_index.data]; | 1219 | else |
| 1220 | typed_value.ty.cast(Type.Payload.EnumFull).?.data.values; | ||
| 1221 | if (enum_values.count() != 0) { | ||
| 1222 | const tag_val = enum_values.keys()[field_index.data]; | ||
| 1223 | var buf: Type.Payload.Bits = undefined; | ||
| 1196 | return genTypedValue(bin_file, src_loc, .{ | 1224 | return genTypedValue(bin_file, src_loc, .{ |
| 1197 | .ty = enum_full.tag_ty, | 1225 | .ty = typed_value.ty.intTagType(&buf), |
| 1198 | .val = tag_val, | 1226 | .val = tag_val, |
| 1199 | }, owner_decl_index); | 1227 | }, owner_decl_index); |
| 1200 | } else { | 1228 | } else { |
| ... | @@ -1258,9 +1286,10 @@ pub fn genTypedValue( | ... | @@ -1258,9 +1286,10 @@ pub fn genTypedValue( |
| 1258 | } | 1286 | } |
| 1259 | 1287 | ||
| 1260 | pub fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u64 { | 1288 | pub fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u64 { |
| 1289 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return 0; | ||
| 1261 | const payload_align = payload_ty.abiAlignment(target); | 1290 | const payload_align = payload_ty.abiAlignment(target); |
| 1262 | const error_align = Type.anyerror.abiAlignment(target); | 1291 | const error_align = Type.anyerror.abiAlignment(target); |
| 1263 | if (payload_align >= error_align) { | 1292 | if (payload_align >= error_align or !payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 1264 | return 0; | 1293 | return 0; |
| 1265 | } else { | 1294 | } else { |
| 1266 | return mem.alignForwardGeneric(u64, Type.anyerror.abiSize(target), payload_align); | 1295 | return mem.alignForwardGeneric(u64, Type.anyerror.abiSize(target), payload_align); |
| ... | @@ -1268,9 +1297,10 @@ pub fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u64 { | ... | @@ -1268,9 +1297,10 @@ pub fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u64 { |
| 1268 | } | 1297 | } |
| 1269 | 1298 | ||
| 1270 | pub fn errUnionErrorOffset(payload_ty: Type, target: std.Target) u64 { | 1299 | pub fn errUnionErrorOffset(payload_ty: Type, target: std.Target) u64 { |
| 1300 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return 0; | ||
| 1271 | const payload_align = payload_ty.abiAlignment(target); | 1301 | const payload_align = payload_ty.abiAlignment(target); |
| 1272 | const error_align = Type.anyerror.abiAlignment(target); | 1302 | const error_align = Type.anyerror.abiAlignment(target); |
| 1273 | if (payload_align >= error_align) { | 1303 | if (payload_align >= error_align and payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 1274 | return mem.alignForwardGeneric(u64, payload_ty.abiSize(target), error_align); | 1304 | return mem.alignForwardGeneric(u64, payload_ty.abiSize(target), error_align); |
| 1275 | } else { | 1305 | } else { |
| 1276 | return 0; | 1306 | return 0; |
src/link/Dwarf.zig+115-71| ... | @@ -184,12 +184,14 @@ pub const DeclState = struct { | ... | @@ -184,12 +184,14 @@ pub const DeclState = struct { |
| 184 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.pad1)); | 184 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.pad1)); |
| 185 | }, | 185 | }, |
| 186 | .Bool => { | 186 | .Bool => { |
| 187 | try dbg_info_buffer.appendSlice(&[_]u8{ | 187 | try dbg_info_buffer.ensureUnusedCapacity(12); |
| 188 | @enumToInt(AbbrevKind.base_type), | 188 | dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type)); |
| 189 | DW.ATE.boolean, // DW.AT.encoding , DW.FORM.data1 | 189 | // DW.AT.encoding, DW.FORM.data1 |
| 190 | 1, // DW.AT.byte_size, DW.FORM.data1 | 190 | dbg_info_buffer.appendAssumeCapacity(DW.ATE.boolean); |
| 191 | 'b', 'o', 'o', 'l', 0, // DW.AT.name, DW.FORM.string | 191 | // DW.AT.byte_size, DW.FORM.udata |
| 192 | }); | 192 | try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(target)); |
| 193 | // DW.AT.name, DW.FORM.string | ||
| 194 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)}); | ||
| 193 | }, | 195 | }, |
| 194 | .Int => { | 196 | .Int => { |
| 195 | const info = ty.intInfo(target); | 197 | const info = ty.intInfo(target); |
| ... | @@ -200,9 +202,9 @@ pub const DeclState = struct { | ... | @@ -200,9 +202,9 @@ pub const DeclState = struct { |
| 200 | .signed => DW.ATE.signed, | 202 | .signed => DW.ATE.signed, |
| 201 | .unsigned => DW.ATE.unsigned, | 203 | .unsigned => DW.ATE.unsigned, |
| 202 | }); | 204 | }); |
| 203 | // DW.AT.byte_size, DW.FORM.data1 | 205 | // DW.AT.byte_size, DW.FORM.udata |
| 204 | dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target))); | 206 | try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(target)); |
| 205 | // DW.AT.name, DW.FORM.string | 207 | // DW.AT.name, DW.FORM.string |
| 206 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)}); | 208 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)}); |
| 207 | }, | 209 | }, |
| 208 | .Optional => { | 210 | .Optional => { |
| ... | @@ -211,9 +213,9 @@ pub const DeclState = struct { | ... | @@ -211,9 +213,9 @@ pub const DeclState = struct { |
| 211 | dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type)); | 213 | dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type)); |
| 212 | // DW.AT.encoding, DW.FORM.data1 | 214 | // DW.AT.encoding, DW.FORM.data1 |
| 213 | dbg_info_buffer.appendAssumeCapacity(DW.ATE.address); | 215 | dbg_info_buffer.appendAssumeCapacity(DW.ATE.address); |
| 214 | // DW.AT.byte_size, DW.FORM.data1 | 216 | // DW.AT.byte_size, DW.FORM.udata |
| 215 | dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target))); | 217 | try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(target)); |
| 216 | // DW.AT.name, DW.FORM.string | 218 | // DW.AT.name, DW.FORM.string |
| 217 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)}); | 219 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)}); |
| 218 | } else { | 220 | } else { |
| 219 | // Non-pointer optionals are structs: struct { .maybe = *, .val = * } | 221 | // Non-pointer optionals are structs: struct { .maybe = *, .val = * } |
| ... | @@ -221,7 +223,7 @@ pub const DeclState = struct { | ... | @@ -221,7 +223,7 @@ pub const DeclState = struct { |
| 221 | const payload_ty = ty.optionalChild(buf); | 223 | const payload_ty = ty.optionalChild(buf); |
| 222 | // DW.AT.structure_type | 224 | // DW.AT.structure_type |
| 223 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type)); | 225 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type)); |
| 224 | // DW.AT.byte_size, DW.FORM.sdata | 226 | // DW.AT.byte_size, DW.FORM.udata |
| 225 | const abi_size = ty.abiSize(target); | 227 | const abi_size = ty.abiSize(target); |
| 226 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); | 228 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); |
| 227 | // DW.AT.name, DW.FORM.string | 229 | // DW.AT.name, DW.FORM.string |
| ... | @@ -236,7 +238,7 @@ pub const DeclState = struct { | ... | @@ -236,7 +238,7 @@ pub const DeclState = struct { |
| 236 | var index = dbg_info_buffer.items.len; | 238 | var index = dbg_info_buffer.items.len; |
| 237 | try dbg_info_buffer.resize(index + 4); | 239 | try dbg_info_buffer.resize(index + 4); |
| 238 | try self.addTypeRelocGlobal(atom_index, Type.bool, @intCast(u32, index)); | 240 | try self.addTypeRelocGlobal(atom_index, Type.bool, @intCast(u32, index)); |
| 239 | // DW.AT.data_member_location, DW.FORM.sdata | 241 | // DW.AT.data_member_location, DW.FORM.udata |
| 240 | try dbg_info_buffer.ensureUnusedCapacity(6); | 242 | try dbg_info_buffer.ensureUnusedCapacity(6); |
| 241 | dbg_info_buffer.appendAssumeCapacity(0); | 243 | dbg_info_buffer.appendAssumeCapacity(0); |
| 242 | // DW.AT.member | 244 | // DW.AT.member |
| ... | @@ -248,7 +250,7 @@ pub const DeclState = struct { | ... | @@ -248,7 +250,7 @@ pub const DeclState = struct { |
| 248 | index = dbg_info_buffer.items.len; | 250 | index = dbg_info_buffer.items.len; |
| 249 | try dbg_info_buffer.resize(index + 4); | 251 | try dbg_info_buffer.resize(index + 4); |
| 250 | try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(u32, index)); | 252 | try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(u32, index)); |
| 251 | // DW.AT.data_member_location, DW.FORM.sdata | 253 | // DW.AT.data_member_location, DW.FORM.udata |
| 252 | const offset = abi_size - payload_ty.abiSize(target); | 254 | const offset = abi_size - payload_ty.abiSize(target); |
| 253 | try leb128.writeULEB128(dbg_info_buffer.writer(), offset); | 255 | try leb128.writeULEB128(dbg_info_buffer.writer(), offset); |
| 254 | // DW.AT.structure_type delimit children | 256 | // DW.AT.structure_type delimit children |
| ... | @@ -263,8 +265,8 @@ pub const DeclState = struct { | ... | @@ -263,8 +265,8 @@ pub const DeclState = struct { |
| 263 | // DW.AT.structure_type | 265 | // DW.AT.structure_type |
| 264 | try dbg_info_buffer.ensureUnusedCapacity(2); | 266 | try dbg_info_buffer.ensureUnusedCapacity(2); |
| 265 | dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_type)); | 267 | dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_type)); |
| 266 | // DW.AT.byte_size, DW.FORM.sdata | 268 | // DW.AT.byte_size, DW.FORM.udata |
| 267 | dbg_info_buffer.appendAssumeCapacity(ptr_bytes * 2); | 269 | try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(target)); |
| 268 | // DW.AT.name, DW.FORM.string | 270 | // DW.AT.name, DW.FORM.string |
| 269 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)}); | 271 | try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(module)}); |
| 270 | // DW.AT.member | 272 | // DW.AT.member |
| ... | @@ -279,7 +281,7 @@ pub const DeclState = struct { | ... | @@ -279,7 +281,7 @@ pub const DeclState = struct { |
| 279 | var buf = try arena.create(Type.SlicePtrFieldTypeBuffer); | 281 | var buf = try arena.create(Type.SlicePtrFieldTypeBuffer); |
| 280 | const ptr_ty = ty.slicePtrFieldType(buf); | 282 | const ptr_ty = ty.slicePtrFieldType(buf); |
| 281 | try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(u32, index)); | 283 | try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(u32, index)); |
| 282 | // DW.AT.data_member_location, DW.FORM.sdata | 284 | // DW.AT.data_member_location, DW.FORM.udata |
| 283 | try dbg_info_buffer.ensureUnusedCapacity(6); | 285 | try dbg_info_buffer.ensureUnusedCapacity(6); |
| 284 | dbg_info_buffer.appendAssumeCapacity(0); | 286 | dbg_info_buffer.appendAssumeCapacity(0); |
| 285 | // DW.AT.member | 287 | // DW.AT.member |
| ... | @@ -291,7 +293,7 @@ pub const DeclState = struct { | ... | @@ -291,7 +293,7 @@ pub const DeclState = struct { |
| 291 | index = dbg_info_buffer.items.len; | 293 | index = dbg_info_buffer.items.len; |
| 292 | try dbg_info_buffer.resize(index + 4); | 294 | try dbg_info_buffer.resize(index + 4); |
| 293 | try self.addTypeRelocGlobal(atom_index, Type.usize, @intCast(u32, index)); | 295 | try self.addTypeRelocGlobal(atom_index, Type.usize, @intCast(u32, index)); |
| 294 | // DW.AT.data_member_location, DW.FORM.sdata | 296 | // DW.AT.data_member_location, DW.FORM.udata |
| 295 | try dbg_info_buffer.ensureUnusedCapacity(2); | 297 | try dbg_info_buffer.ensureUnusedCapacity(2); |
| 296 | dbg_info_buffer.appendAssumeCapacity(ptr_bytes); | 298 | dbg_info_buffer.appendAssumeCapacity(ptr_bytes); |
| 297 | // DW.AT.structure_type delimit children | 299 | // DW.AT.structure_type delimit children |
| ... | @@ -329,9 +331,8 @@ pub const DeclState = struct { | ... | @@ -329,9 +331,8 @@ pub const DeclState = struct { |
| 329 | .Struct => blk: { | 331 | .Struct => blk: { |
| 330 | // DW.AT.structure_type | 332 | // DW.AT.structure_type |
| 331 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type)); | 333 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type)); |
| 332 | // DW.AT.byte_size, DW.FORM.sdata | 334 | // DW.AT.byte_size, DW.FORM.udata |
| 333 | const abi_size = ty.abiSize(target); | 335 | try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(target)); |
| 334 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); | ||
| 335 | 336 | ||
| 336 | switch (ty.tag()) { | 337 | switch (ty.tag()) { |
| 337 | .tuple, .anon_struct => { | 338 | .tuple, .anon_struct => { |
| ... | @@ -348,7 +349,7 @@ pub const DeclState = struct { | ... | @@ -348,7 +349,7 @@ pub const DeclState = struct { |
| 348 | var index = dbg_info_buffer.items.len; | 349 | var index = dbg_info_buffer.items.len; |
| 349 | try dbg_info_buffer.resize(index + 4); | 350 | try dbg_info_buffer.resize(index + 4); |
| 350 | try self.addTypeRelocGlobal(atom_index, field, @intCast(u32, index)); | 351 | try self.addTypeRelocGlobal(atom_index, field, @intCast(u32, index)); |
| 351 | // DW.AT.data_member_location, DW.FORM.sdata | 352 | // DW.AT.data_member_location, DW.FORM.udata |
| 352 | const field_off = ty.structFieldOffset(field_index, target); | 353 | const field_off = ty.structFieldOffset(field_index, target); |
| 353 | try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); | 354 | try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); |
| 354 | } | 355 | } |
| ... | @@ -380,7 +381,7 @@ pub const DeclState = struct { | ... | @@ -380,7 +381,7 @@ pub const DeclState = struct { |
| 380 | var index = dbg_info_buffer.items.len; | 381 | var index = dbg_info_buffer.items.len; |
| 381 | try dbg_info_buffer.resize(index + 4); | 382 | try dbg_info_buffer.resize(index + 4); |
| 382 | try self.addTypeRelocGlobal(atom_index, field.ty, @intCast(u32, index)); | 383 | try self.addTypeRelocGlobal(atom_index, field.ty, @intCast(u32, index)); |
| 383 | // DW.AT.data_member_location, DW.FORM.sdata | 384 | // DW.AT.data_member_location, DW.FORM.udata |
| 384 | const field_off = ty.structFieldOffset(field_index, target); | 385 | const field_off = ty.structFieldOffset(field_index, target); |
| 385 | try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); | 386 | try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); |
| 386 | } | 387 | } |
| ... | @@ -393,9 +394,8 @@ pub const DeclState = struct { | ... | @@ -393,9 +394,8 @@ pub const DeclState = struct { |
| 393 | .Enum => { | 394 | .Enum => { |
| 394 | // DW.AT.enumeration_type | 395 | // DW.AT.enumeration_type |
| 395 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type)); | 396 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type)); |
| 396 | // DW.AT.byte_size, DW.FORM.sdata | 397 | // DW.AT.byte_size, DW.FORM.udata |
| 397 | const abi_size = ty.abiSize(target); | 398 | try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(target)); |
| 398 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); | ||
| 399 | // DW.AT.name, DW.FORM.string | 399 | // DW.AT.name, DW.FORM.string |
| 400 | const enum_name = try ty.nameAllocArena(arena, module); | 400 | const enum_name = try ty.nameAllocArena(arena, module); |
| 401 | try dbg_info_buffer.ensureUnusedCapacity(enum_name.len + 1); | 401 | try dbg_info_buffer.ensureUnusedCapacity(enum_name.len + 1); |
| ... | @@ -446,7 +446,7 @@ pub const DeclState = struct { | ... | @@ -446,7 +446,7 @@ pub const DeclState = struct { |
| 446 | if (is_tagged) { | 446 | if (is_tagged) { |
| 447 | // DW.AT.structure_type | 447 | // DW.AT.structure_type |
| 448 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type)); | 448 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type)); |
| 449 | // DW.AT.byte_size, DW.FORM.sdata | 449 | // DW.AT.byte_size, DW.FORM.udata |
| 450 | try leb128.writeULEB128(dbg_info_buffer.writer(), layout.abi_size); | 450 | try leb128.writeULEB128(dbg_info_buffer.writer(), layout.abi_size); |
| 451 | // DW.AT.name, DW.FORM.string | 451 | // DW.AT.name, DW.FORM.string |
| 452 | try dbg_info_buffer.ensureUnusedCapacity(union_name.len + 1); | 452 | try dbg_info_buffer.ensureUnusedCapacity(union_name.len + 1); |
| ... | @@ -463,13 +463,13 @@ pub const DeclState = struct { | ... | @@ -463,13 +463,13 @@ pub const DeclState = struct { |
| 463 | const inner_union_index = dbg_info_buffer.items.len; | 463 | const inner_union_index = dbg_info_buffer.items.len; |
| 464 | try dbg_info_buffer.resize(inner_union_index + 4); | 464 | try dbg_info_buffer.resize(inner_union_index + 4); |
| 465 | try self.addTypeRelocLocal(atom_index, @intCast(u32, inner_union_index), 5); | 465 | try self.addTypeRelocLocal(atom_index, @intCast(u32, inner_union_index), 5); |
| 466 | // DW.AT.data_member_location, DW.FORM.sdata | 466 | // DW.AT.data_member_location, DW.FORM.udata |
| 467 | try leb128.writeULEB128(dbg_info_buffer.writer(), payload_offset); | 467 | try leb128.writeULEB128(dbg_info_buffer.writer(), payload_offset); |
| 468 | } | 468 | } |
| 469 | 469 | ||
| 470 | // DW.AT.union_type | 470 | // DW.AT.union_type |
| 471 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.union_type)); | 471 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.union_type)); |
| 472 | // DW.AT.byte_size, DW.FORM.sdata, | 472 | // DW.AT.byte_size, DW.FORM.udata, |
| 473 | try leb128.writeULEB128(dbg_info_buffer.writer(), layout.payload_size); | 473 | try leb128.writeULEB128(dbg_info_buffer.writer(), layout.payload_size); |
| 474 | // DW.AT.name, DW.FORM.string | 474 | // DW.AT.name, DW.FORM.string |
| 475 | if (is_tagged) { | 475 | if (is_tagged) { |
| ... | @@ -490,7 +490,7 @@ pub const DeclState = struct { | ... | @@ -490,7 +490,7 @@ pub const DeclState = struct { |
| 490 | const index = dbg_info_buffer.items.len; | 490 | const index = dbg_info_buffer.items.len; |
| 491 | try dbg_info_buffer.resize(index + 4); | 491 | try dbg_info_buffer.resize(index + 4); |
| 492 | try self.addTypeRelocGlobal(atom_index, field.ty, @intCast(u32, index)); | 492 | try self.addTypeRelocGlobal(atom_index, field.ty, @intCast(u32, index)); |
| 493 | // DW.AT.data_member_location, DW.FORM.sdata | 493 | // DW.AT.data_member_location, DW.FORM.udata |
| 494 | try dbg_info_buffer.append(0); | 494 | try dbg_info_buffer.append(0); |
| 495 | } | 495 | } |
| 496 | // DW.AT.union_type delimit children | 496 | // DW.AT.union_type delimit children |
| ... | @@ -507,7 +507,7 @@ pub const DeclState = struct { | ... | @@ -507,7 +507,7 @@ pub const DeclState = struct { |
| 507 | const index = dbg_info_buffer.items.len; | 507 | const index = dbg_info_buffer.items.len; |
| 508 | try dbg_info_buffer.resize(index + 4); | 508 | try dbg_info_buffer.resize(index + 4); |
| 509 | try self.addTypeRelocGlobal(atom_index, union_obj.tag_ty, @intCast(u32, index)); | 509 | try self.addTypeRelocGlobal(atom_index, union_obj.tag_ty, @intCast(u32, index)); |
| 510 | // DW.AT.data_member_location, DW.FORM.sdata | 510 | // DW.AT.data_member_location, DW.FORM.udata |
| 511 | try leb128.writeULEB128(dbg_info_buffer.writer(), tag_offset); | 511 | try leb128.writeULEB128(dbg_info_buffer.writer(), tag_offset); |
| 512 | 512 | ||
| 513 | // DW.AT.structure_type delimit children | 513 | // DW.AT.structure_type delimit children |
| ... | @@ -534,7 +534,7 @@ pub const DeclState = struct { | ... | @@ -534,7 +534,7 @@ pub const DeclState = struct { |
| 534 | 534 | ||
| 535 | // DW.AT.structure_type | 535 | // DW.AT.structure_type |
| 536 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type)); | 536 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type)); |
| 537 | // DW.AT.byte_size, DW.FORM.sdata | 537 | // DW.AT.byte_size, DW.FORM.udata |
| 538 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); | 538 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); |
| 539 | // DW.AT.name, DW.FORM.string | 539 | // DW.AT.name, DW.FORM.string |
| 540 | const name = try ty.nameAllocArena(arena, module); | 540 | const name = try ty.nameAllocArena(arena, module); |
| ... | @@ -551,7 +551,7 @@ pub const DeclState = struct { | ... | @@ -551,7 +551,7 @@ pub const DeclState = struct { |
| 551 | const index = dbg_info_buffer.items.len; | 551 | const index = dbg_info_buffer.items.len; |
| 552 | try dbg_info_buffer.resize(index + 4); | 552 | try dbg_info_buffer.resize(index + 4); |
| 553 | try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(u32, index)); | 553 | try self.addTypeRelocGlobal(atom_index, payload_ty, @intCast(u32, index)); |
| 554 | // DW.AT.data_member_location, DW.FORM.sdata | 554 | // DW.AT.data_member_location, DW.FORM.udata |
| 555 | try leb128.writeULEB128(dbg_info_buffer.writer(), payload_off); | 555 | try leb128.writeULEB128(dbg_info_buffer.writer(), payload_off); |
| 556 | } | 556 | } |
| 557 | 557 | ||
| ... | @@ -566,7 +566,7 @@ pub const DeclState = struct { | ... | @@ -566,7 +566,7 @@ pub const DeclState = struct { |
| 566 | const index = dbg_info_buffer.items.len; | 566 | const index = dbg_info_buffer.items.len; |
| 567 | try dbg_info_buffer.resize(index + 4); | 567 | try dbg_info_buffer.resize(index + 4); |
| 568 | try self.addTypeRelocGlobal(atom_index, error_ty, @intCast(u32, index)); | 568 | try self.addTypeRelocGlobal(atom_index, error_ty, @intCast(u32, index)); |
| 569 | // DW.AT.data_member_location, DW.FORM.sdata | 569 | // DW.AT.data_member_location, DW.FORM.udata |
| 570 | try leb128.writeULEB128(dbg_info_buffer.writer(), error_off); | 570 | try leb128.writeULEB128(dbg_info_buffer.writer(), error_off); |
| 571 | } | 571 | } |
| 572 | 572 | ||
| ... | @@ -608,23 +608,44 @@ pub const DeclState = struct { | ... | @@ -608,23 +608,44 @@ pub const DeclState = struct { |
| 608 | 608 | ||
| 609 | switch (loc) { | 609 | switch (loc) { |
| 610 | .register => |reg| { | 610 | .register => |reg| { |
| 611 | try dbg_info.ensureUnusedCapacity(3); | 611 | try dbg_info.ensureUnusedCapacity(4); |
| 612 | dbg_info.appendAssumeCapacity(@enumToInt(AbbrevKind.parameter)); | 612 | dbg_info.appendAssumeCapacity(@enumToInt(AbbrevKind.parameter)); |
| 613 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | 613 | // DW.AT.location, DW.FORM.exprloc |
| 614 | 1, // ULEB128 dwarf expression length | 614 | var expr_len = std.io.countingWriter(std.io.null_writer); |
| 615 | reg, | 615 | if (reg < 32) { |
| 616 | }); | 616 | expr_len.writer().writeByte(DW.OP.reg0 + reg) catch unreachable; |
| 617 | } else { | ||
| 618 | expr_len.writer().writeByte(DW.OP.regx) catch unreachable; | ||
| 619 | leb128.writeULEB128(expr_len.writer(), reg) catch unreachable; | ||
| 620 | } | ||
| 621 | leb128.writeULEB128(dbg_info.writer(), expr_len.bytes_written) catch unreachable; | ||
| 622 | if (reg < 32) { | ||
| 623 | dbg_info.appendAssumeCapacity(DW.OP.reg0 + reg); | ||
| 624 | } else { | ||
| 625 | dbg_info.appendAssumeCapacity(DW.OP.regx); | ||
| 626 | leb128.writeULEB128(dbg_info.writer(), reg) catch unreachable; | ||
| 627 | } | ||
| 617 | }, | 628 | }, |
| 618 | .stack => |info| { | 629 | .stack => |info| { |
| 619 | try dbg_info.ensureUnusedCapacity(8); | 630 | try dbg_info.ensureUnusedCapacity(9); |
| 620 | dbg_info.appendAssumeCapacity(@enumToInt(AbbrevKind.parameter)); | 631 | dbg_info.appendAssumeCapacity(@enumToInt(AbbrevKind.parameter)); |
| 621 | const fixup = dbg_info.items.len; | 632 | // DW.AT.location, DW.FORM.exprloc |
| 622 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | 633 | var expr_len = std.io.countingWriter(std.io.null_writer); |
| 623 | 1, // we will backpatch it after we encode the displacement in LEB128 | 634 | if (info.fp_register < 32) { |
| 624 | info.fp_register, // frame pointer | 635 | expr_len.writer().writeByte(DW.OP.breg0 + info.fp_register) catch unreachable; |
| 625 | }); | 636 | } else { |
| 637 | expr_len.writer().writeByte(DW.OP.bregx) catch unreachable; | ||
| 638 | leb128.writeULEB128(expr_len.writer(), info.fp_register) catch unreachable; | ||
| 639 | } | ||
| 640 | leb128.writeILEB128(expr_len.writer(), info.offset) catch unreachable; | ||
| 641 | leb128.writeULEB128(dbg_info.writer(), expr_len.bytes_written) catch unreachable; | ||
| 642 | if (info.fp_register < 32) { | ||
| 643 | dbg_info.appendAssumeCapacity(DW.OP.breg0 + info.fp_register); | ||
| 644 | } else { | ||
| 645 | dbg_info.appendAssumeCapacity(DW.OP.bregx); | ||
| 646 | leb128.writeULEB128(dbg_info.writer(), info.fp_register) catch unreachable; | ||
| 647 | } | ||
| 626 | leb128.writeILEB128(dbg_info.writer(), info.offset) catch unreachable; | 648 | leb128.writeILEB128(dbg_info.writer(), info.offset) catch unreachable; |
| 627 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); | ||
| 628 | }, | 649 | }, |
| 629 | .wasm_local => |value| { | 650 | .wasm_local => |value| { |
| 630 | const leb_size = link.File.Wasm.getULEB128Size(value); | 651 | const leb_size = link.File.Wasm.getULEB128Size(value); |
| ... | @@ -647,8 +668,8 @@ pub const DeclState = struct { | ... | @@ -647,8 +668,8 @@ pub const DeclState = struct { |
| 647 | 668 | ||
| 648 | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); | 669 | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); |
| 649 | const index = dbg_info.items.len; | 670 | const index = dbg_info.items.len; |
| 650 | try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4 | 671 | try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4 |
| 651 | try self.addTypeRelocGlobal(atom_index, ty, @intCast(u32, index)); // DW.AT.type, DW.FORM.ref4 | 672 | try self.addTypeRelocGlobal(atom_index, ty, @intCast(u32, index)); // DW.AT.type, DW.FORM.ref4 |
| 652 | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string | 673 | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string |
| 653 | } | 674 | } |
| 654 | 675 | ||
| ... | @@ -670,22 +691,45 @@ pub const DeclState = struct { | ... | @@ -670,22 +691,45 @@ pub const DeclState = struct { |
| 670 | 691 | ||
| 671 | switch (loc) { | 692 | switch (loc) { |
| 672 | .register => |reg| { | 693 | .register => |reg| { |
| 673 | try dbg_info.ensureUnusedCapacity(2); | 694 | try dbg_info.ensureUnusedCapacity(4); |
| 674 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | 695 | dbg_info.appendAssumeCapacity(@enumToInt(AbbrevKind.parameter)); |
| 675 | 1, // ULEB128 dwarf expression length | 696 | // DW.AT.location, DW.FORM.exprloc |
| 676 | reg, | 697 | var expr_len = std.io.countingWriter(std.io.null_writer); |
| 677 | }); | 698 | if (reg < 32) { |
| 699 | expr_len.writer().writeByte(DW.OP.reg0 + reg) catch unreachable; | ||
| 700 | } else { | ||
| 701 | expr_len.writer().writeByte(DW.OP.regx) catch unreachable; | ||
| 702 | leb128.writeULEB128(expr_len.writer(), reg) catch unreachable; | ||
| 703 | } | ||
| 704 | leb128.writeULEB128(dbg_info.writer(), expr_len.bytes_written) catch unreachable; | ||
| 705 | if (reg < 32) { | ||
| 706 | dbg_info.appendAssumeCapacity(DW.OP.reg0 + reg); | ||
| 707 | } else { | ||
| 708 | dbg_info.appendAssumeCapacity(DW.OP.regx); | ||
| 709 | leb128.writeULEB128(dbg_info.writer(), reg) catch unreachable; | ||
| 710 | } | ||
| 678 | }, | 711 | }, |
| 679 | 712 | ||
| 680 | .stack => |info| { | 713 | .stack => |info| { |
| 681 | try dbg_info.ensureUnusedCapacity(7); | 714 | try dbg_info.ensureUnusedCapacity(9); |
| 682 | const fixup = dbg_info.items.len; | 715 | dbg_info.appendAssumeCapacity(@enumToInt(AbbrevKind.parameter)); |
| 683 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | 716 | // DW.AT.location, DW.FORM.exprloc |
| 684 | 1, // we will backpatch it after we encode the displacement in LEB128 | 717 | var expr_len = std.io.countingWriter(std.io.null_writer); |
| 685 | info.fp_register, | 718 | if (info.fp_register < 32) { |
| 686 | }); | 719 | expr_len.writer().writeByte(DW.OP.breg0 + info.fp_register) catch unreachable; |
| 720 | } else { | ||
| 721 | expr_len.writer().writeByte(DW.OP.bregx) catch unreachable; | ||
| 722 | leb128.writeULEB128(expr_len.writer(), info.fp_register) catch unreachable; | ||
| 723 | } | ||
| 724 | leb128.writeILEB128(expr_len.writer(), info.offset) catch unreachable; | ||
| 725 | leb128.writeULEB128(dbg_info.writer(), expr_len.bytes_written) catch unreachable; | ||
| 726 | if (info.fp_register < 32) { | ||
| 727 | dbg_info.appendAssumeCapacity(DW.OP.breg0 + info.fp_register); | ||
| 728 | } else { | ||
| 729 | dbg_info.appendAssumeCapacity(DW.OP.bregx); | ||
| 730 | leb128.writeULEB128(dbg_info.writer(), info.fp_register) catch unreachable; | ||
| 731 | } | ||
| 687 | leb128.writeILEB128(dbg_info.writer(), info.offset) catch unreachable; | 732 | leb128.writeILEB128(dbg_info.writer(), info.offset) catch unreachable; |
| 688 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); | ||
| 689 | }, | 733 | }, |
| 690 | 734 | ||
| 691 | .wasm_local => |value| { | 735 | .wasm_local => |value| { |
| ... | @@ -790,7 +834,7 @@ pub const DeclState = struct { | ... | @@ -790,7 +834,7 @@ pub const DeclState = struct { |
| 790 | 834 | ||
| 791 | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); | 835 | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); |
| 792 | const index = dbg_info.items.len; | 836 | const index = dbg_info.items.len; |
| 793 | try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4 | 837 | try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4 |
| 794 | try self.addTypeRelocGlobal(atom_index, child_ty, @intCast(u32, index)); | 838 | try self.addTypeRelocGlobal(atom_index, child_ty, @intCast(u32, index)); |
| 795 | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string | 839 | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string |
| 796 | } | 840 | } |
| ... | @@ -993,13 +1037,13 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) | ... | @@ -993,13 +1037,13 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) |
| 993 | // "relocations" and have to be in this fixed place so that functions can be | 1037 | // "relocations" and have to be in this fixed place so that functions can be |
| 994 | // moved in virtual address space. | 1038 | // moved in virtual address space. |
| 995 | assert(dbg_info_low_pc_reloc_index == dbg_info_buffer.items.len); | 1039 | assert(dbg_info_low_pc_reloc_index == dbg_info_buffer.items.len); |
| 996 | dbg_info_buffer.items.len += ptr_width_bytes; // DW.AT.low_pc, DW.FORM.addr | 1040 | dbg_info_buffer.items.len += ptr_width_bytes; // DW.AT.low_pc, DW.FORM.addr |
| 997 | assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len); | 1041 | assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len); |
| 998 | dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4 | 1042 | dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4 |
| 999 | // | 1043 | // |
| 1000 | if (fn_ret_has_bits) { | 1044 | if (fn_ret_has_bits) { |
| 1001 | try decl_state.addTypeRelocGlobal(di_atom_index, fn_ret_type, @intCast(u32, dbg_info_buffer.items.len)); | 1045 | try decl_state.addTypeRelocGlobal(di_atom_index, fn_ret_type, @intCast(u32, dbg_info_buffer.items.len)); |
| 1002 | dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4 | 1046 | dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4 |
| 1003 | } | 1047 | } |
| 1004 | 1048 | ||
| 1005 | dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT.name, DW.FORM.string | 1049 | dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT.name, DW.FORM.string |
| ... | @@ -1619,7 +1663,7 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void { | ... | @@ -1619,7 +1663,7 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void { |
| 1619 | DW.AT.encoding, | 1663 | DW.AT.encoding, |
| 1620 | DW.FORM.data1, | 1664 | DW.FORM.data1, |
| 1621 | DW.AT.byte_size, | 1665 | DW.AT.byte_size, |
| 1622 | DW.FORM.data1, | 1666 | DW.FORM.udata, |
| 1623 | DW.AT.name, | 1667 | DW.AT.name, |
| 1624 | DW.FORM.string, | 1668 | DW.FORM.string, |
| 1625 | 0, | 1669 | 0, |
| ... | @@ -1635,7 +1679,7 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void { | ... | @@ -1635,7 +1679,7 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void { |
| 1635 | DW.TAG.structure_type, | 1679 | DW.TAG.structure_type, |
| 1636 | DW.CHILDREN.yes, // header | 1680 | DW.CHILDREN.yes, // header |
| 1637 | DW.AT.byte_size, | 1681 | DW.AT.byte_size, |
| 1638 | DW.FORM.sdata, | 1682 | DW.FORM.udata, |
| 1639 | DW.AT.name, | 1683 | DW.AT.name, |
| 1640 | DW.FORM.string, | 1684 | DW.FORM.string, |
| 1641 | 0, | 1685 | 0, |
| ... | @@ -1648,14 +1692,14 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void { | ... | @@ -1648,14 +1692,14 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void { |
| 1648 | DW.AT.type, | 1692 | DW.AT.type, |
| 1649 | DW.FORM.ref4, | 1693 | DW.FORM.ref4, |
| 1650 | DW.AT.data_member_location, | 1694 | DW.AT.data_member_location, |
| 1651 | DW.FORM.sdata, | 1695 | DW.FORM.udata, |
| 1652 | 0, | 1696 | 0, |
| 1653 | 0, // table sentinel | 1697 | 0, // table sentinel |
| 1654 | @enumToInt(AbbrevKind.enum_type), | 1698 | @enumToInt(AbbrevKind.enum_type), |
| 1655 | DW.TAG.enumeration_type, | 1699 | DW.TAG.enumeration_type, |
| 1656 | DW.CHILDREN.yes, // header | 1700 | DW.CHILDREN.yes, // header |
| 1657 | DW.AT.byte_size, | 1701 | DW.AT.byte_size, |
| 1658 | DW.FORM.sdata, | 1702 | DW.FORM.udata, |
| 1659 | DW.AT.name, | 1703 | DW.AT.name, |
| 1660 | DW.FORM.string, | 1704 | DW.FORM.string, |
| 1661 | 0, | 1705 | 0, |
| ... | @@ -1673,7 +1717,7 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void { | ... | @@ -1673,7 +1717,7 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void { |
| 1673 | DW.TAG.union_type, | 1717 | DW.TAG.union_type, |
| 1674 | DW.CHILDREN.yes, // header | 1718 | DW.CHILDREN.yes, // header |
| 1675 | DW.AT.byte_size, | 1719 | DW.AT.byte_size, |
| 1676 | DW.FORM.sdata, | 1720 | DW.FORM.udata, |
| 1677 | DW.AT.name, | 1721 | DW.AT.name, |
| 1678 | DW.FORM.string, | 1722 | DW.FORM.string, |
| 1679 | 0, | 1723 | 0, |
| ... | @@ -2628,7 +2672,7 @@ fn addDbgInfoErrorSet( | ... | @@ -2628,7 +2672,7 @@ fn addDbgInfoErrorSet( |
| 2628 | 2672 | ||
| 2629 | // DW.AT.enumeration_type | 2673 | // DW.AT.enumeration_type |
| 2630 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type)); | 2674 | try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type)); |
| 2631 | // DW.AT.byte_size, DW.FORM.sdata | 2675 | // DW.AT.byte_size, DW.FORM.udata |
| 2632 | const abi_size = Type.anyerror.abiSize(target); | 2676 | const abi_size = Type.anyerror.abiSize(target); |
| 2633 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); | 2677 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); |
| 2634 | // DW.AT.name, DW.FORM.string | 2678 | // DW.AT.name, DW.FORM.string |
src/type.zig+11-1| ... | @@ -5433,8 +5433,18 @@ pub const Type = extern union { | ... | @@ -5433,8 +5433,18 @@ pub const Type = extern union { |
| 5433 | } | 5433 | } |
| 5434 | } | 5434 | } |
| 5435 | 5435 | ||
| 5436 | // Works for vectors and vectors of integers. | ||
| 5437 | pub fn maxInt(ty: Type, arena: Allocator, target: Target) !Value { | ||
| 5438 | const scalar = try maxIntScalar(ty.scalarType(), arena, target); | ||
| 5439 | if (ty.zigTypeTag() == .Vector and scalar.tag() != .the_only_possible_value) { | ||
| 5440 | return Value.Tag.repeated.create(arena, scalar); | ||
| 5441 | } else { | ||
| 5442 | return scalar; | ||
| 5443 | } | ||
| 5444 | } | ||
| 5445 | |||
| 5436 | /// Asserts that self.zigTypeTag() == .Int. | 5446 | /// Asserts that self.zigTypeTag() == .Int. |
| 5437 | pub fn maxInt(self: Type, arena: Allocator, target: Target) !Value { | 5447 | pub fn maxIntScalar(self: Type, arena: Allocator, target: Target) !Value { |
| 5438 | assert(self.zigTypeTag() == .Int); | 5448 | assert(self.zigTypeTag() == .Int); |
| 5439 | const info = self.intInfo(target); | 5449 | const info = self.intInfo(target); |
| 5440 | 5450 |
test/behavior/bugs/1277.zig-1| ... | @@ -14,7 +14,6 @@ fn f() i32 { | ... | @@ -14,7 +14,6 @@ fn f() i32 { |
| 14 | test "don't emit an LLVM global for a const function when it's in an optional in a struct" { | 14 | test "don't emit an LLVM global for a const function when it's in an optional in a struct" { |
| 15 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 15 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 16 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 16 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 17 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 18 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 17 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 19 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 18 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 20 | 19 |
test/behavior/bugs/12801-2.zig-1| ... | @@ -16,7 +16,6 @@ const Auto = struct { | ... | @@ -16,7 +16,6 @@ const Auto = struct { |
| 16 | test { | 16 | test { |
| 17 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 17 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 18 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 18 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 19 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 20 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 19 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 21 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 20 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 22 | 21 |
test/behavior/bugs/13366.zig-1| ... | @@ -14,7 +14,6 @@ const Block = struct { | ... | @@ -14,7 +14,6 @@ const Block = struct { |
| 14 | 14 | ||
| 15 | test { | 15 | test { |
| 16 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 16 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 17 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 18 | if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO | 17 | if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO |
| 19 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 18 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 20 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 19 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
test/behavior/cast.zig-1| ... | @@ -153,7 +153,6 @@ test "@intToFloat(f80)" { | ... | @@ -153,7 +153,6 @@ test "@intToFloat(f80)" { |
| 153 | test "@floatToInt" { | 153 | test "@floatToInt" { |
| 154 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 154 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 155 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 155 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 156 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 157 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 156 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 158 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 157 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 159 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 158 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
test/behavior/field_parent_ptr.zig-4| ... | @@ -11,7 +11,6 @@ test "@fieldParentPtr non-first field" { | ... | @@ -11,7 +11,6 @@ test "@fieldParentPtr non-first field" { |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | test "@fieldParentPtr first field" { | 13 | test "@fieldParentPtr first field" { |
| 14 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 15 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 14 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 16 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 15 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 17 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 16 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| ... | @@ -51,7 +50,6 @@ fn testParentFieldPtrFirst(a: *const bool) !void { | ... | @@ -51,7 +50,6 @@ fn testParentFieldPtrFirst(a: *const bool) !void { |
| 51 | } | 50 | } |
| 52 | 51 | ||
| 53 | test "@fieldParentPtr untagged union" { | 52 | test "@fieldParentPtr untagged union" { |
| 54 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 55 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 53 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 56 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 54 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 57 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 55 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -79,7 +77,6 @@ fn testFieldParentPtrUnion(c: *const i32) !void { | ... | @@ -79,7 +77,6 @@ fn testFieldParentPtrUnion(c: *const i32) !void { |
| 79 | } | 77 | } |
| 80 | 78 | ||
| 81 | test "@fieldParentPtr tagged union" { | 79 | test "@fieldParentPtr tagged union" { |
| 82 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 83 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 80 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 84 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 81 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 85 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 82 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -107,7 +104,6 @@ fn testFieldParentPtrTaggedUnion(c: *const i32) !void { | ... | @@ -107,7 +104,6 @@ fn testFieldParentPtrTaggedUnion(c: *const i32) !void { |
| 107 | } | 104 | } |
| 108 | 105 | ||
| 109 | test "@fieldParentPtr extern union" { | 106 | test "@fieldParentPtr extern union" { |
| 110 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 111 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 107 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 112 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 108 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 113 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 109 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
test/behavior/floatop.zig+1-2| ... | @@ -184,7 +184,7 @@ test "more @sqrt f16 tests" { | ... | @@ -184,7 +184,7 @@ test "more @sqrt f16 tests" { |
| 184 | test "another, possibly redundant @sqrt test" { | 184 | test "another, possibly redundant @sqrt test" { |
| 185 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 185 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 186 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 186 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 187 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 187 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO |
| 188 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 188 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 189 | 189 | ||
| 190 | try testSqrtLegacy(f64, 12.0); | 190 | try testSqrtLegacy(f64, 12.0); |
| ... | @@ -532,7 +532,6 @@ fn testFabs() !void { | ... | @@ -532,7 +532,6 @@ fn testFabs() !void { |
| 532 | 532 | ||
| 533 | test "@fabs with vectors" { | 533 | test "@fabs with vectors" { |
| 534 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 534 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 535 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 536 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 535 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 537 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 536 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 538 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 537 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
test/behavior/fn.zig-1| ... | @@ -502,7 +502,6 @@ test "method call with optional pointer first param" { | ... | @@ -502,7 +502,6 @@ test "method call with optional pointer first param" { |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | test "using @ptrCast on function pointers" { | 504 | test "using @ptrCast on function pointers" { |
| 505 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 506 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 505 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 507 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 506 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 508 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 507 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/int_comparison_elision.zig-1| ... | @@ -15,7 +15,6 @@ test "int comparison elision" { | ... | @@ -15,7 +15,6 @@ test "int comparison elision" { |
| 15 | 15 | ||
| 16 | // TODO: support int types > 128 bits wide in other backends | 16 | // TODO: support int types > 128 bits wide in other backends |
| 17 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 17 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 18 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 19 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 18 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 20 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 19 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 21 | 20 |
test/behavior/math.zig-3| ... | @@ -61,7 +61,6 @@ fn assertFalse(b: bool) !void { | ... | @@ -61,7 +61,6 @@ fn assertFalse(b: bool) !void { |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | test "@clz" { | 63 | test "@clz" { |
| 64 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 65 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 64 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 66 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 65 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 67 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 66 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -142,7 +141,6 @@ fn expectVectorsEqual(a: anytype, b: anytype) !void { | ... | @@ -142,7 +141,6 @@ fn expectVectorsEqual(a: anytype, b: anytype) !void { |
| 142 | } | 141 | } |
| 143 | 142 | ||
| 144 | test "@ctz" { | 143 | test "@ctz" { |
| 145 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 146 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 144 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 147 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 145 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 148 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 146 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1612,7 +1610,6 @@ test "absFloat" { | ... | @@ -1612,7 +1610,6 @@ test "absFloat" { |
| 1612 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1610 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1613 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1611 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1614 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1612 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1615 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1616 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1613 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1617 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1614 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1618 | 1615 |
test/behavior/maximum_minimum.zig-1| ... | @@ -146,7 +146,6 @@ test "@min/@max more than two arguments" { | ... | @@ -146,7 +146,6 @@ test "@min/@max more than two arguments" { |
| 146 | 146 | ||
| 147 | test "@min/@max more than two vector arguments" { | 147 | test "@min/@max more than two vector arguments" { |
| 148 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 148 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 149 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 150 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 149 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 151 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 150 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 152 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 151 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/memset.zig-2| ... | @@ -120,7 +120,6 @@ test "memset with large array element, runtime known" { | ... | @@ -120,7 +120,6 @@ test "memset with large array element, runtime known" { |
| 120 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | 120 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; |
| 121 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 121 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 122 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 122 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 123 | if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) return error.SkipZigTest; | ||
| 124 | 123 | ||
| 125 | const A = [128]u64; | 124 | const A = [128]u64; |
| 126 | var buf: [5]A = undefined; | 125 | var buf: [5]A = undefined; |
| ... | @@ -139,7 +138,6 @@ test "memset with large array element, comptime known" { | ... | @@ -139,7 +138,6 @@ test "memset with large array element, comptime known" { |
| 139 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; | 138 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; |
| 140 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 139 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 141 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 140 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 142 | if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .windows) return error.SkipZigTest; | ||
| 143 | 141 | ||
| 144 | const A = [128]u64; | 142 | const A = [128]u64; |
| 145 | var buf: [5]A = undefined; | 143 | var buf: [5]A = undefined; |
test/behavior/optional.zig-2| ... | @@ -74,7 +74,6 @@ test "optional with void type" { | ... | @@ -74,7 +74,6 @@ test "optional with void type" { |
| 74 | test "address of unwrap optional" { | 74 | test "address of unwrap optional" { |
| 75 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 75 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 76 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 76 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 77 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 78 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 77 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 79 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 78 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 80 | 79 | ||
| ... | @@ -365,7 +364,6 @@ test "optional pointer to zero bit optional payload" { | ... | @@ -365,7 +364,6 @@ test "optional pointer to zero bit optional payload" { |
| 365 | } | 364 | } |
| 366 | 365 | ||
| 367 | test "optional pointer to zero bit error union payload" { | 366 | test "optional pointer to zero bit error union payload" { |
| 368 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 369 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 367 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 370 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 368 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 371 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 369 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
test/behavior/struct.zig-1| ... | @@ -1352,7 +1352,6 @@ test "struct field init value is size of the struct" { | ... | @@ -1352,7 +1352,6 @@ test "struct field init value is size of the struct" { |
| 1352 | } | 1352 | } |
| 1353 | 1353 | ||
| 1354 | test "under-aligned struct field" { | 1354 | test "under-aligned struct field" { |
| 1355 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1356 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1355 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1357 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1356 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1358 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1357 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/translate_c_macros.zig-1| ... | @@ -65,7 +65,6 @@ test "cast negative integer to pointer" { | ... | @@ -65,7 +65,6 @@ test "cast negative integer to pointer" { |
| 65 | 65 | ||
| 66 | test "casting to union with a macro" { | 66 | test "casting to union with a macro" { |
| 67 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 67 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 68 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 69 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 68 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 70 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 69 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 71 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 70 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/tuple.zig-1| ... | @@ -367,7 +367,6 @@ test "branching inside tuple literal" { | ... | @@ -367,7 +367,6 @@ test "branching inside tuple literal" { |
| 367 | test "tuple initialized with a runtime known value" { | 367 | test "tuple initialized with a runtime known value" { |
| 368 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 368 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 369 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 369 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 370 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 371 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 370 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 372 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 371 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 373 | 372 |
test/behavior/union.zig-10| ... | @@ -362,7 +362,6 @@ const MultipleChoice = union(enum(u32)) { | ... | @@ -362,7 +362,6 @@ const MultipleChoice = union(enum(u32)) { |
| 362 | D = 1000, | 362 | D = 1000, |
| 363 | }; | 363 | }; |
| 364 | test "simple union(enum(u32))" { | 364 | test "simple union(enum(u32))" { |
| 365 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 366 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 365 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 367 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 366 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 368 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 367 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -641,7 +640,6 @@ test "tagged union with all void fields but a meaningful tag" { | ... | @@ -641,7 +640,6 @@ test "tagged union with all void fields but a meaningful tag" { |
| 641 | } | 640 | } |
| 642 | 641 | ||
| 643 | test "union(enum(u32)) with specified and unspecified tag values" { | 642 | test "union(enum(u32)) with specified and unspecified tag values" { |
| 644 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 645 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 643 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 646 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 644 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 647 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 645 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -821,7 +819,6 @@ test "return union init with void payload" { | ... | @@ -821,7 +819,6 @@ test "return union init with void payload" { |
| 821 | } | 819 | } |
| 822 | 820 | ||
| 823 | test "@unionInit stored to a const" { | 821 | test "@unionInit stored to a const" { |
| 824 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 825 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 822 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 826 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 823 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 827 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 824 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| ... | @@ -994,7 +991,6 @@ test "function call result coerces from tagged union to the tag" { | ... | @@ -994,7 +991,6 @@ test "function call result coerces from tagged union to the tag" { |
| 994 | } | 991 | } |
| 995 | 992 | ||
| 996 | test "cast from anonymous struct to union" { | 993 | test "cast from anonymous struct to union" { |
| 997 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 998 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 994 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 999 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 995 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1000 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 996 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| ... | @@ -1028,7 +1024,6 @@ test "cast from anonymous struct to union" { | ... | @@ -1028,7 +1024,6 @@ test "cast from anonymous struct to union" { |
| 1028 | } | 1024 | } |
| 1029 | 1025 | ||
| 1030 | test "cast from pointer to anonymous struct to pointer to union" { | 1026 | test "cast from pointer to anonymous struct to pointer to union" { |
| 1031 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1032 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1027 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1033 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1028 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1034 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1029 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| ... | @@ -1169,7 +1164,6 @@ test "union enum type gets a separate scope" { | ... | @@ -1169,7 +1164,6 @@ test "union enum type gets a separate scope" { |
| 1169 | } | 1164 | } |
| 1170 | 1165 | ||
| 1171 | test "global variable struct contains union initialized to non-most-aligned field" { | 1166 | test "global variable struct contains union initialized to non-most-aligned field" { |
| 1172 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1173 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1167 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1174 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1168 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1175 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1169 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1199,7 +1193,6 @@ test "global variable struct contains union initialized to non-most-aligned fiel | ... | @@ -1199,7 +1193,6 @@ test "global variable struct contains union initialized to non-most-aligned fiel |
| 1199 | test "union with no result loc initiated with a runtime value" { | 1193 | test "union with no result loc initiated with a runtime value" { |
| 1200 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1194 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1201 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1195 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1202 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1203 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1196 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1204 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1197 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1205 | 1198 | ||
| ... | @@ -1217,7 +1210,6 @@ test "union with no result loc initiated with a runtime value" { | ... | @@ -1217,7 +1210,6 @@ test "union with no result loc initiated with a runtime value" { |
| 1217 | test "union with a large struct field" { | 1210 | test "union with a large struct field" { |
| 1218 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1211 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1219 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1212 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1220 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1221 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1213 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1222 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1214 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1223 | 1215 | ||
| ... | @@ -1288,7 +1280,6 @@ test "extern union most-aligned field is smaller" { | ... | @@ -1288,7 +1280,6 @@ test "extern union most-aligned field is smaller" { |
| 1288 | } | 1280 | } |
| 1289 | 1281 | ||
| 1290 | test "return an extern union from C calling convention" { | 1282 | test "return an extern union from C calling convention" { |
| 1291 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1292 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1283 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1293 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1284 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1294 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1285 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1397,7 +1388,6 @@ test "union and enum field order doesn't match" { | ... | @@ -1397,7 +1388,6 @@ test "union and enum field order doesn't match" { |
| 1397 | } | 1388 | } |
| 1398 | 1389 | ||
| 1399 | test "@unionInit uses tag value instead of field index" { | 1390 | test "@unionInit uses tag value instead of field index" { |
| 1400 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1401 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1391 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1402 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1392 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1403 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1393 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
test/behavior/vector.zig+2-5| ... | @@ -26,7 +26,8 @@ test "implicit cast vector to array - bool" { | ... | @@ -26,7 +26,8 @@ test "implicit cast vector to array - bool" { |
| 26 | 26 | ||
| 27 | test "vector wrap operators" { | 27 | test "vector wrap operators" { |
| 28 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 28 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 29 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 29 | if (builtin.zig_backend == .stage2_x86_64 and |
| 30 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO | ||
| 30 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 31 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 31 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 32 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 32 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 33 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -119,7 +120,6 @@ test "vector float operators" { | ... | @@ -119,7 +120,6 @@ test "vector float operators" { |
| 119 | 120 | ||
| 120 | test "vector bit operators" { | 121 | test "vector bit operators" { |
| 121 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 122 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 122 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 123 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 123 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 124 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 124 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 125 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 125 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1129,7 +1129,6 @@ test "loading the second vector from a slice of vectors" { | ... | @@ -1129,7 +1129,6 @@ test "loading the second vector from a slice of vectors" { |
| 1129 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1129 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1130 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1130 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1131 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1131 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1132 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1133 | 1132 | ||
| 1134 | @setRuntimeSafety(false); | 1133 | @setRuntimeSafety(false); |
| 1135 | var small_bases = [2]@Vector(2, u8){ | 1134 | var small_bases = [2]@Vector(2, u8){ |
| ... | @@ -1219,7 +1218,6 @@ test "zero multiplicand" { | ... | @@ -1219,7 +1218,6 @@ test "zero multiplicand" { |
| 1219 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1218 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1220 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1219 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1221 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1220 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1222 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1223 | 1221 | ||
| 1224 | const zeros = @Vector(2, u32){ 0.0, 0.0 }; | 1222 | const zeros = @Vector(2, u32){ 0.0, 0.0 }; |
| 1225 | var ones = @Vector(2, u32){ 1.0, 1.0 }; | 1223 | var ones = @Vector(2, u32){ 1.0, 1.0 }; |
| ... | @@ -1324,7 +1322,6 @@ test "store to vector in slice" { | ... | @@ -1324,7 +1322,6 @@ test "store to vector in slice" { |
| 1324 | test "addition of vectors represented as strings" { | 1322 | test "addition of vectors represented as strings" { |
| 1325 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1323 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1326 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1324 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1327 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1328 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 1325 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 1329 | 1326 | ||
| 1330 | const V = @Vector(3, u8); | 1327 | const V = @Vector(3, u8); |