| author | |
| committer | |
| log | b8f00ae337a9c36cb33181292c5b6ba345add9ab |
| tree | 1b20786f3a34cd765e8653d1833f4c21f0d644e1 |
| parent | 24d76500d2d0220d313b5f79c880855b776d61c2 |
4 files changed, 112 insertions(+), 34 deletions(-)
src/arch/x86_64/CodeGen.zig+91-33| ... | ... | @@ -5385,46 +5385,104 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 5385 | 5385 | const mod = self.bin_file.options.module.?; |
| 5386 | 5386 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 5387 | 5387 | const ty = self.typeOf(ty_op.operand); |
| 5388 | const scalar_ty = ty.scalarType(mod); | |
| 5389 | 5388 | |
| 5390 | switch (scalar_ty.zigTypeTag(mod)) { | |
| 5391 | .Int => if (ty.zigTypeTag(mod) == .Vector) { | |
| 5392 | return self.fail("TODO implement airAbs for {}", .{ty.fmt(mod)}); | |
| 5393 | } else { | |
| 5394 | if (ty.abiSize(mod) > 8) { | |
| 5395 | return self.fail("TODO implement abs for integer abi sizes larger than 8", .{}); | |
| 5396 | } | |
| 5397 | const src_mcv = try self.resolveInst(ty_op.operand); | |
| 5398 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ty, src_mcv); | |
| 5389 | const result: MCValue = result: { | |
| 5390 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) { | |
| 5391 | else => null, | |
| 5392 | .Int => { | |
| 5393 | if (ty.abiSize(mod) > 8) { | |
| 5394 | return self.fail("TODO implement abs for integer abi sizes larger than 8", .{}); | |
| 5395 | } | |
| 5396 | const src_mcv = try self.resolveInst(ty_op.operand); | |
| 5397 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ty, src_mcv); | |
| 5399 | 5398 | |
| 5400 | try self.genUnOpMir(.{ ._, .neg }, ty, dst_mcv); | |
| 5399 | try self.genUnOpMir(.{ ._, .neg }, ty, dst_mcv); | |
| 5401 | 5400 | |
| 5402 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(mod))), 2); | |
| 5403 | switch (src_mcv) { | |
| 5404 | .register => |val_reg| try self.asmCmovccRegisterRegister( | |
| 5405 | registerAlias(dst_mcv.register, cmov_abi_size), | |
| 5406 | registerAlias(val_reg, cmov_abi_size), | |
| 5407 | .l, | |
| 5408 | ), | |
| 5409 | .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory( | |
| 5410 | registerAlias(dst_mcv.register, cmov_abi_size), | |
| 5411 | src_mcv.mem(Memory.PtrSize.fromSize(cmov_abi_size)), | |
| 5412 | .l, | |
| 5413 | ), | |
| 5414 | else => { | |
| 5415 | const val_reg = try self.copyToTmpRegister(ty, src_mcv); | |
| 5416 | try self.asmCmovccRegisterRegister( | |
| 5401 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(mod))), 2); | |
| 5402 | switch (src_mcv) { | |
| 5403 | .register => |val_reg| try self.asmCmovccRegisterRegister( | |
| 5417 | 5404 | registerAlias(dst_mcv.register, cmov_abi_size), |
| 5418 | 5405 | registerAlias(val_reg, cmov_abi_size), |
| 5419 | 5406 | .l, |
| 5420 | ); | |
| 5407 | ), | |
| 5408 | .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory( | |
| 5409 | registerAlias(dst_mcv.register, cmov_abi_size), | |
| 5410 | src_mcv.mem(Memory.PtrSize.fromSize(cmov_abi_size)), | |
| 5411 | .l, | |
| 5412 | ), | |
| 5413 | else => { | |
| 5414 | const val_reg = try self.copyToTmpRegister(ty, src_mcv); | |
| 5415 | try self.asmCmovccRegisterRegister( | |
| 5416 | registerAlias(dst_mcv.register, cmov_abi_size), | |
| 5417 | registerAlias(val_reg, cmov_abi_size), | |
| 5418 | .l, | |
| 5419 | ); | |
| 5420 | }, | |
| 5421 | } | |
| 5422 | break :result dst_mcv; | |
| 5423 | }, | |
| 5424 | .Float => return self.floatSign(inst, ty_op.operand, ty), | |
| 5425 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { | |
| 5426 | else => null, | |
| 5427 | .Int => switch (ty.childType(mod).intInfo(mod).bits) { | |
| 5428 | else => null, | |
| 5429 | 8 => switch (ty.vectorLen(mod)) { | |
| 5430 | else => null, | |
| 5431 | 1...16 => if (self.hasFeature(.avx)) | |
| 5432 | .{ .vp_b, .abs } | |
| 5433 | else if (self.hasFeature(.ssse3)) | |
| 5434 | .{ .p_b, .abs } | |
| 5435 | else | |
| 5436 | null, | |
| 5437 | 17...32 => if (self.hasFeature(.avx2)) .{ .vp_b, .abs } else null, | |
| 5438 | }, | |
| 5439 | 16 => switch (ty.vectorLen(mod)) { | |
| 5440 | else => null, | |
| 5441 | 1...8 => if (self.hasFeature(.avx)) | |
| 5442 | .{ .vp_w, .abs } | |
| 5443 | else if (self.hasFeature(.ssse3)) | |
| 5444 | .{ .p_w, .abs } | |
| 5445 | else | |
| 5446 | null, | |
| 5447 | 9...16 => if (self.hasFeature(.avx2)) .{ .vp_w, .abs } else null, | |
| 5448 | }, | |
| 5449 | 32 => switch (ty.vectorLen(mod)) { | |
| 5450 | else => null, | |
| 5451 | 1...4 => if (self.hasFeature(.avx)) | |
| 5452 | .{ .vp_d, .abs } | |
| 5453 | else if (self.hasFeature(.ssse3)) | |
| 5454 | .{ .p_d, .abs } | |
| 5455 | else | |
| 5456 | null, | |
| 5457 | 5...8 => if (self.hasFeature(.avx2)) .{ .vp_d, .abs } else null, | |
| 5458 | }, | |
| 5421 | 5459 | }, |
| 5422 | } | |
| 5423 | return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none }); | |
| 5424 | }, | |
| 5425 | .Float => return self.floatSign(inst, ty_op.operand, ty), | |
| 5426 | else => unreachable, | |
| 5427 | } | |
| 5460 | .Float => return self.floatSign(inst, ty_op.operand, ty), | |
| 5461 | }, | |
| 5462 | }) orelse return self.fail("TODO implement airAbs for {}", .{ty.fmt(mod)}); | |
| 5463 | ||
| 5464 | const abi_size: u32 = @intCast(ty.abiSize(mod)); | |
| 5465 | const src_mcv = try self.resolveInst(ty_op.operand); | |
| 5466 | const dst_reg = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) | |
| 5467 | src_mcv.getReg().? | |
| 5468 | else | |
| 5469 | try self.register_manager.allocReg(inst, self.regClassForType(ty)); | |
| 5470 | const dst_alias = registerAlias(dst_reg, abi_size); | |
| 5471 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | |
| 5472 | mir_tag, | |
| 5473 | dst_alias, | |
| 5474 | src_mcv.mem(self.memPtrSize(ty)), | |
| 5475 | ) else try self.asmRegisterRegister( | |
| 5476 | mir_tag, | |
| 5477 | dst_alias, | |
| 5478 | registerAlias(if (src_mcv.isRegister()) | |
| 5479 | src_mcv.getReg().? | |
| 5480 | else | |
| 5481 | try self.copyToTmpRegister(ty, src_mcv), abi_size), | |
| 5482 | ); | |
| 5483 | break :result .{ .register = dst_reg }; | |
| 5484 | }; | |
| 5485 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | |
| 5428 | 5486 | } |
| 5429 | 5487 | |
| 5430 | 5488 | fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
src/arch/x86_64/Encoding.zig+4| ... | ... | @@ -316,6 +316,8 @@ pub const Mnemonic = enum { |
| 316 | 316 | xorpd, |
| 317 | 317 | // SSE3 |
| 318 | 318 | movddup, movshdup, movsldup, |
| 319 | // SSSE3 | |
| 320 | pabsb, pabsd, pabsw, | |
| 319 | 321 | // SSE4.1 |
| 320 | 322 | blendpd, blendps, blendvpd, blendvps, |
| 321 | 323 | extractps, |
| ... | ... | @@ -353,6 +355,7 @@ pub const Mnemonic = enum { |
| 353 | 355 | vmovupd, vmovups, |
| 354 | 356 | vmulpd, vmulps, vmulsd, vmulss, |
| 355 | 357 | vorpd, vorps, |
| 358 | vpabsb, vpabsd, vpabsw, | |
| 356 | 359 | vpackssdw, vpacksswb, vpackusdw, vpackuswb, |
| 357 | 360 | vpaddb, vpaddd, vpaddq, vpaddsb, vpaddsw, vpaddusb, vpaddusw, vpaddw, |
| 358 | 361 | vpand, vpandn, |
| ... | ... | @@ -750,6 +753,7 @@ pub const Feature = enum { |
| 750 | 753 | sse2, |
| 751 | 754 | sse3, |
| 752 | 755 | sse4_1, |
| 756 | ssse3, | |
| 753 | 757 | x87, |
| 754 | 758 | }; |
| 755 | 759 |
src/arch/x86_64/encodings.zig+16| ... | ... | @@ -1108,6 +1108,14 @@ pub const table = [_]Entry{ |
| 1108 | 1108 | |
| 1109 | 1109 | .{ .movsldup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x12 }, 0, .none, .sse3 }, |
| 1110 | 1110 | |
| 1111 | // SSSE3 | |
| 1112 | .{ .pabsb, .rm, &.{ .mm, .mm_m64 }, &.{ 0x0f, 0x38, 0x1c }, 0, .none, .ssse3 }, | |
| 1113 | .{ .pabsb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x1c }, 0, .none, .ssse3 }, | |
| 1114 | .{ .pabsd, .rm, &.{ .mm, .mm_m64 }, &.{ 0x0f, 0x38, 0x1e }, 0, .none, .ssse3 }, | |
| 1115 | .{ .pabsd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x1e }, 0, .none, .ssse3 }, | |
| 1116 | .{ .pabsw, .rm, &.{ .mm, .mm_m64 }, &.{ 0x0f, 0x38, 0x1d }, 0, .none, .ssse3 }, | |
| 1117 | .{ .pabsw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x1d }, 0, .none, .ssse3 }, | |
| 1118 | ||
| 1111 | 1119 | // SSE4.1 |
| 1112 | 1120 | .{ .blendpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0d }, 0, .none, .sse4_1 }, |
| 1113 | 1121 | |
| ... | ... | @@ -1368,6 +1376,10 @@ pub const table = [_]Entry{ |
| 1368 | 1376 | .{ .vorps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .vex_128_wig, .avx }, |
| 1369 | 1377 | .{ .vorps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x56 }, 0, .vex_256_wig, .avx }, |
| 1370 | 1378 | |
| 1379 | .{ .vpabsb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x1c }, 0, .vex_128_wig, .avx }, | |
| 1380 | .{ .vpabsd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x1e }, 0, .vex_128_wig, .avx }, | |
| 1381 | .{ .vpabsw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x1d }, 0, .vex_128_wig, .avx }, | |
| 1382 | ||
| 1371 | 1383 | .{ .vpacksswb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x63 }, 0, .vex_128_wig, .avx }, |
| 1372 | 1384 | .{ .vpackssdw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6b }, 0, .vex_128_wig, .avx }, |
| 1373 | 1385 | |
| ... | ... | @@ -1537,6 +1549,10 @@ pub const table = [_]Entry{ |
| 1537 | 1549 | .{ .vbroadcastss, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx2 }, |
| 1538 | 1550 | .{ .vbroadcastsd, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x19 }, 0, .vex_256_w0, .avx2 }, |
| 1539 | 1551 | |
| 1552 | .{ .vpabsb, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x1c }, 0, .vex_256_wig, .avx2 }, | |
| 1553 | .{ .vpabsd, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x1e }, 0, .vex_256_wig, .avx2 }, | |
| 1554 | .{ .vpabsw, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x1d }, 0, .vex_256_wig, .avx2 }, | |
| 1555 | ||
| 1540 | 1556 | .{ .vpacksswb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x63 }, 0, .vex_256_wig, .avx2 }, |
| 1541 | 1557 | .{ .vpackssdw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x6b }, 0, .vex_256_wig, .avx2 }, |
| 1542 | 1558 |
test/behavior/abs.zig+1-1| ... | ... | @@ -280,7 +280,7 @@ test "@abs float vectors" { |
| 280 | 280 | try testAbsFloatVectors(f16, 16); |
| 281 | 281 | try comptime testAbsFloatVectors(f16, 17); |
| 282 | 282 | |
| 283 | try testAbsFloatVectors(f32, 17); | |
| 283 | try testAbsFloatVectors(f32, 1); | |
| 284 | 284 | try comptime testAbsFloatVectors(f32, 1); |
| 285 | 285 | try testAbsFloatVectors(f32, 1); |
| 286 | 286 | try comptime testAbsFloatVectors(f32, 2); |