| author | |
| committer | |
| log | 6778da4516e68c271cb50fe9c252ab4084daf16b |
| tree | 46e3bb0082569ecb678039e36fa2a422ae02a994 |
| parent | f8708e2c4d93eece5b3e131fd2d1b5b210806cd6 |
7 files changed, 354 insertions(+), 46 deletions(-)
src/arch/x86_64/CodeGen.zig+240-21| ... | @@ -4497,14 +4497,15 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4497,14 +4497,15 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void { |
| 4497 | const tag = self.air.instructions.items(.tag)[inst]; | 4497 | const tag = self.air.instructions.items(.tag)[inst]; |
| 4498 | try self.genBinOpMir(switch (ty_bits) { | 4498 | try self.genBinOpMir(switch (ty_bits) { |
| 4499 | // No point using an extra prefix byte for *pd which performs the same operation. | 4499 | // No point using an extra prefix byte for *pd which performs the same operation. |
| 4500 | 32, 64 => switch (tag) { | 4500 | 16, 32, 64, 128 => switch (tag) { |
| 4501 | .neg => .xorps, | 4501 | .neg => .xorps, |
| 4502 | .fabs => .andnps, | 4502 | .fabs => .andnps, |
| 4503 | else => unreachable, | 4503 | else => unreachable, |
| 4504 | }, | 4504 | }, |
| 4505 | else => return self.fail("TODO implement airFloatSign for {}", .{ | 4505 | 80 => return self.fail("TODO implement airFloatSign for {}", .{ |
| 4506 | ty.fmt(self.bin_file.options.module.?), | 4506 | ty.fmt(self.bin_file.options.module.?), |
| 4507 | }), | 4507 | }), |
| 4508 | else => unreachable, | ||
| 4508 | }, vec_ty, dst_mcv, sign_mcv); | 4509 | }, vec_ty, dst_mcv, sign_mcv); |
| 4509 | return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none }); | 4510 | return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none }); |
| 4510 | } | 4511 | } |
| ... | @@ -6112,9 +6113,53 @@ fn genBinOp( | ... | @@ -6112,9 +6113,53 @@ fn genBinOp( |
| 6112 | return dst_mcv; | 6113 | return dst_mcv; |
| 6113 | } | 6114 | } |
| 6114 | 6115 | ||
| 6116 | const dst_reg = registerAlias(dst_mcv.getReg().?, abi_size); | ||
| 6115 | const mir_tag = if (@as(?Mir.Inst.Tag, switch (lhs_ty.zigTypeTag()) { | 6117 | const mir_tag = if (@as(?Mir.Inst.Tag, switch (lhs_ty.zigTypeTag()) { |
| 6116 | else => unreachable, | 6118 | else => unreachable, |
| 6117 | .Float => switch (lhs_ty.floatBits(self.target.*)) { | 6119 | .Float => switch (lhs_ty.floatBits(self.target.*)) { |
| 6120 | 16 => if (self.hasFeature(.f16c)) { | ||
| 6121 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); | ||
| 6122 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | ||
| 6123 | defer self.register_manager.unlockReg(tmp_lock); | ||
| 6124 | |||
| 6125 | if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate( | ||
| 6126 | .vpinsrw, | ||
| 6127 | dst_reg, | ||
| 6128 | dst_reg, | ||
| 6129 | src_mcv.mem(.word), | ||
| 6130 | Immediate.u(1), | ||
| 6131 | ) else try self.asmRegisterRegisterRegister( | ||
| 6132 | .vpunpcklwd, | ||
| 6133 | dst_reg, | ||
| 6134 | dst_reg, | ||
| 6135 | (if (src_mcv.isRegister()) | ||
| 6136 | src_mcv.getReg().? | ||
| 6137 | else | ||
| 6138 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | ||
| 6139 | ); | ||
| 6140 | try self.asmRegisterRegister(.vcvtph2ps, dst_reg, dst_reg); | ||
| 6141 | try self.asmRegisterRegister(.vmovshdup, tmp_reg, dst_reg); | ||
| 6142 | try self.asmRegisterRegisterRegister( | ||
| 6143 | switch (air_tag) { | ||
| 6144 | .add => .vaddss, | ||
| 6145 | .sub => .vsubss, | ||
| 6146 | .div_float, .div_trunc, .div_floor, .div_exact => .vdivss, | ||
| 6147 | .max => .vmaxss, | ||
| 6148 | .min => .vmaxss, | ||
| 6149 | else => unreachable, | ||
| 6150 | }, | ||
| 6151 | dst_reg, | ||
| 6152 | dst_reg, | ||
| 6153 | tmp_reg, | ||
| 6154 | ); | ||
| 6155 | try self.asmRegisterRegisterImmediate( | ||
| 6156 | .vcvtps2ph, | ||
| 6157 | dst_reg, | ||
| 6158 | dst_reg, | ||
| 6159 | Immediate.u(0b1_00), | ||
| 6160 | ); | ||
| 6161 | return dst_mcv; | ||
| 6162 | } else null, | ||
| 6118 | 32 => switch (air_tag) { | 6163 | 32 => switch (air_tag) { |
| 6119 | .add => if (self.hasFeature(.avx)) .vaddss else .addss, | 6164 | .add => if (self.hasFeature(.avx)) .vaddss else .addss, |
| 6120 | .sub => if (self.hasFeature(.avx)) .vsubss else .subss, | 6165 | .sub => if (self.hasFeature(.avx)) .vsubss else .subss, |
| ... | @@ -6141,12 +6186,178 @@ fn genBinOp( | ... | @@ -6141,12 +6186,178 @@ fn genBinOp( |
| 6141 | .min => if (self.hasFeature(.avx)) .vminsd else .minsd, | 6186 | .min => if (self.hasFeature(.avx)) .vminsd else .minsd, |
| 6142 | else => unreachable, | 6187 | else => unreachable, |
| 6143 | }, | 6188 | }, |
| 6144 | 16, 80, 128 => null, | 6189 | 80, 128 => null, |
| 6145 | else => unreachable, | 6190 | else => unreachable, |
| 6146 | }, | 6191 | }, |
| 6147 | .Vector => switch (lhs_ty.childType().zigTypeTag()) { | 6192 | .Vector => switch (lhs_ty.childType().zigTypeTag()) { |
| 6148 | else => null, | 6193 | else => null, |
| 6149 | .Float => switch (lhs_ty.childType().floatBits(self.target.*)) { | 6194 | .Float => switch (lhs_ty.childType().floatBits(self.target.*)) { |
| 6195 | 16 => if (self.hasFeature(.f16c)) switch (lhs_ty.vectorLen()) { | ||
| 6196 | 1 => { | ||
| 6197 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); | ||
| 6198 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | ||
| 6199 | defer self.register_manager.unlockReg(tmp_lock); | ||
| 6200 | |||
| 6201 | if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate( | ||
| 6202 | .vpinsrw, | ||
| 6203 | dst_reg, | ||
| 6204 | dst_reg, | ||
| 6205 | src_mcv.mem(.word), | ||
| 6206 | Immediate.u(1), | ||
| 6207 | ) else try self.asmRegisterRegisterRegister( | ||
| 6208 | .vpunpcklwd, | ||
| 6209 | dst_reg, | ||
| 6210 | dst_reg, | ||
| 6211 | (if (src_mcv.isRegister()) | ||
| 6212 | src_mcv.getReg().? | ||
| 6213 | else | ||
| 6214 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | ||
| 6215 | ); | ||
| 6216 | try self.asmRegisterRegister(.vcvtph2ps, dst_reg, dst_reg); | ||
| 6217 | try self.asmRegisterRegister(.vmovshdup, tmp_reg, dst_reg); | ||
| 6218 | try self.asmRegisterRegisterRegister( | ||
| 6219 | switch (air_tag) { | ||
| 6220 | .add => .vaddss, | ||
| 6221 | .sub => .vsubss, | ||
| 6222 | .div_float, .div_trunc, .div_floor, .div_exact => .vdivss, | ||
| 6223 | .max => .vmaxss, | ||
| 6224 | .min => .vmaxss, | ||
| 6225 | else => unreachable, | ||
| 6226 | }, | ||
| 6227 | dst_reg, | ||
| 6228 | dst_reg, | ||
| 6229 | tmp_reg, | ||
| 6230 | ); | ||
| 6231 | try self.asmRegisterRegisterImmediate( | ||
| 6232 | .vcvtps2ph, | ||
| 6233 | dst_reg, | ||
| 6234 | dst_reg, | ||
| 6235 | Immediate.u(0b1_00), | ||
| 6236 | ); | ||
| 6237 | return dst_mcv; | ||
| 6238 | }, | ||
| 6239 | 2 => { | ||
| 6240 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); | ||
| 6241 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | ||
| 6242 | defer self.register_manager.unlockReg(tmp_lock); | ||
| 6243 | |||
| 6244 | if (src_mcv.isMemory()) try self.asmRegisterMemoryImmediate( | ||
| 6245 | .vpinsrd, | ||
| 6246 | dst_reg, | ||
| 6247 | src_mcv.mem(.dword), | ||
| 6248 | Immediate.u(1), | ||
| 6249 | ) else try self.asmRegisterRegisterRegister( | ||
| 6250 | .vunpcklps, | ||
| 6251 | dst_reg, | ||
| 6252 | dst_reg, | ||
| 6253 | (if (src_mcv.isRegister()) | ||
| 6254 | src_mcv.getReg().? | ||
| 6255 | else | ||
| 6256 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | ||
| 6257 | ); | ||
| 6258 | try self.asmRegisterRegister(.vcvtph2ps, dst_reg, dst_reg); | ||
| 6259 | try self.asmRegisterRegisterRegister(.vmovhlps, tmp_reg, dst_reg, dst_reg); | ||
| 6260 | try self.asmRegisterRegisterRegister( | ||
| 6261 | switch (air_tag) { | ||
| 6262 | .add => .vaddps, | ||
| 6263 | .sub => .vsubps, | ||
| 6264 | .div_float, .div_trunc, .div_floor, .div_exact => .vdivps, | ||
| 6265 | .max => .vmaxps, | ||
| 6266 | .min => .vmaxps, | ||
| 6267 | else => unreachable, | ||
| 6268 | }, | ||
| 6269 | dst_reg, | ||
| 6270 | dst_reg, | ||
| 6271 | tmp_reg, | ||
| 6272 | ); | ||
| 6273 | try self.asmRegisterRegisterImmediate( | ||
| 6274 | .vcvtps2ph, | ||
| 6275 | dst_reg, | ||
| 6276 | dst_reg, | ||
| 6277 | Immediate.u(0b1_00), | ||
| 6278 | ); | ||
| 6279 | return dst_mcv; | ||
| 6280 | }, | ||
| 6281 | 3...4 => { | ||
| 6282 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); | ||
| 6283 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | ||
| 6284 | defer self.register_manager.unlockReg(tmp_lock); | ||
| 6285 | |||
| 6286 | try self.asmRegisterRegister(.vcvtph2ps, dst_reg, dst_reg); | ||
| 6287 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | ||
| 6288 | .vcvtph2ps, | ||
| 6289 | tmp_reg, | ||
| 6290 | src_mcv.mem(.qword), | ||
| 6291 | ) else try self.asmRegisterRegister( | ||
| 6292 | .vcvtph2ps, | ||
| 6293 | tmp_reg, | ||
| 6294 | (if (src_mcv.isRegister()) | ||
| 6295 | src_mcv.getReg().? | ||
| 6296 | else | ||
| 6297 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | ||
| 6298 | ); | ||
| 6299 | try self.asmRegisterRegisterRegister( | ||
| 6300 | switch (air_tag) { | ||
| 6301 | .add => .vaddps, | ||
| 6302 | .sub => .vsubps, | ||
| 6303 | .div_float, .div_trunc, .div_floor, .div_exact => .vdivps, | ||
| 6304 | .max => .vmaxps, | ||
| 6305 | .min => .vmaxps, | ||
| 6306 | else => unreachable, | ||
| 6307 | }, | ||
| 6308 | dst_reg, | ||
| 6309 | dst_reg, | ||
| 6310 | tmp_reg, | ||
| 6311 | ); | ||
| 6312 | try self.asmRegisterRegisterImmediate( | ||
| 6313 | .vcvtps2ph, | ||
| 6314 | dst_reg, | ||
| 6315 | dst_reg, | ||
| 6316 | Immediate.u(0b1_00), | ||
| 6317 | ); | ||
| 6318 | return dst_mcv; | ||
| 6319 | }, | ||
| 6320 | 5...8 => { | ||
| 6321 | const tmp_reg = (try self.register_manager.allocReg(null, sse)).to256(); | ||
| 6322 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | ||
| 6323 | defer self.register_manager.unlockReg(tmp_lock); | ||
| 6324 | |||
| 6325 | try self.asmRegisterRegister(.vcvtph2ps, dst_reg.to256(), dst_reg); | ||
| 6326 | if (src_mcv.isMemory()) try self.asmRegisterMemory( | ||
| 6327 | .vcvtph2ps, | ||
| 6328 | tmp_reg, | ||
| 6329 | src_mcv.mem(.xword), | ||
| 6330 | ) else try self.asmRegisterRegister( | ||
| 6331 | .vcvtph2ps, | ||
| 6332 | tmp_reg, | ||
| 6333 | (if (src_mcv.isRegister()) | ||
| 6334 | src_mcv.getReg().? | ||
| 6335 | else | ||
| 6336 | try self.copyToTmpRegister(rhs_ty, src_mcv)).to128(), | ||
| 6337 | ); | ||
| 6338 | try self.asmRegisterRegisterRegister( | ||
| 6339 | switch (air_tag) { | ||
| 6340 | .add => .vaddps, | ||
| 6341 | .sub => .vsubps, | ||
| 6342 | .div_float, .div_trunc, .div_floor, .div_exact => .vdivps, | ||
| 6343 | .max => .vmaxps, | ||
| 6344 | .min => .vmaxps, | ||
| 6345 | else => unreachable, | ||
| 6346 | }, | ||
| 6347 | dst_reg.to256(), | ||
| 6348 | dst_reg.to256(), | ||
| 6349 | tmp_reg, | ||
| 6350 | ); | ||
| 6351 | try self.asmRegisterRegisterImmediate( | ||
| 6352 | .vcvtps2ph, | ||
| 6353 | dst_reg, | ||
| 6354 | dst_reg.to256(), | ||
| 6355 | Immediate.u(0b1_00), | ||
| 6356 | ); | ||
| 6357 | return dst_mcv; | ||
| 6358 | }, | ||
| 6359 | else => null, | ||
| 6360 | } else null, | ||
| 6150 | 32 => switch (lhs_ty.vectorLen()) { | 6361 | 32 => switch (lhs_ty.vectorLen()) { |
| 6151 | 1 => switch (air_tag) { | 6362 | 1 => switch (air_tag) { |
| 6152 | .add => if (self.hasFeature(.avx)) .vaddss else .addss, | 6363 | .add => if (self.hasFeature(.avx)) .vaddss else .addss, |
| ... | @@ -6223,14 +6434,13 @@ fn genBinOp( | ... | @@ -6223,14 +6434,13 @@ fn genBinOp( |
| 6223 | } else null, | 6434 | } else null, |
| 6224 | else => null, | 6435 | else => null, |
| 6225 | }, | 6436 | }, |
| 6226 | 16, 80, 128 => null, | 6437 | 80, 128 => null, |
| 6227 | else => unreachable, | 6438 | else => unreachable, |
| 6228 | }, | 6439 | }, |
| 6229 | }, | 6440 | }, |
| 6230 | })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{ | 6441 | })) |tag| tag else return self.fail("TODO implement genBinOp for {s} {}", .{ |
| 6231 | @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?), | 6442 | @tagName(air_tag), lhs_ty.fmt(self.bin_file.options.module.?), |
| 6232 | }); | 6443 | }); |
| 6233 | const dst_reg = registerAlias(dst_mcv.getReg().?, abi_size); | ||
| 6234 | if (self.hasFeature(.avx)) { | 6444 | if (self.hasFeature(.avx)) { |
| 6235 | const src1_alias = | 6445 | const src1_alias = |
| 6236 | if (copied_to_dst) dst_reg else registerAlias(lhs_mcv.getReg().?, abi_size); | 6446 | if (copied_to_dst) dst_reg else registerAlias(lhs_mcv.getReg().?, abi_size); |
| ... | @@ -7139,21 +7349,21 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -7139,21 +7349,21 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 7139 | const tmp2_lock = self.register_manager.lockRegAssumeUnused(tmp2_reg); | 7349 | const tmp2_lock = self.register_manager.lockRegAssumeUnused(tmp2_reg); |
| 7140 | defer self.register_manager.unlockReg(tmp2_lock); | 7350 | defer self.register_manager.unlockReg(tmp2_lock); |
| 7141 | 7351 | ||
| 7142 | if (src_mcv.isRegister()) | 7352 | if (src_mcv.isMemory()) try self.asmRegisterRegisterMemoryImmediate( |
| 7143 | try self.asmRegisterRegisterRegister( | 7353 | .vpinsrw, |
| 7144 | .vpunpcklwd, | 7354 | tmp1_reg, |
| 7145 | tmp1_reg, | 7355 | dst_reg.to128(), |
| 7146 | dst_reg.to128(), | 7356 | src_mcv.mem(.word), |
| 7147 | src_mcv.getReg().?.to128(), | 7357 | Immediate.u(1), |
| 7148 | ) | 7358 | ) else try self.asmRegisterRegisterRegister( |
| 7149 | else | 7359 | .vpunpcklwd, |
| 7150 | try self.asmRegisterRegisterMemoryImmediate( | 7360 | tmp1_reg, |
| 7151 | .vpinsrw, | 7361 | dst_reg.to128(), |
| 7152 | tmp1_reg, | 7362 | (if (src_mcv.isRegister()) |
| 7153 | dst_reg.to128(), | 7363 | src_mcv.getReg().? |
| 7154 | src_mcv.mem(.word), | 7364 | else |
| 7155 | Immediate.u(1), | 7365 | try self.copyToTmpRegister(ty, src_mcv)).to128(), |
| 7156 | ); | 7366 | ); |
| 7157 | try self.asmRegisterRegister(.vcvtph2ps, tmp1_reg, tmp1_reg); | 7367 | try self.asmRegisterRegister(.vcvtph2ps, tmp1_reg, tmp1_reg); |
| 7158 | try self.asmRegisterRegister(.vmovshdup, tmp2_reg, tmp1_reg); | 7368 | try self.asmRegisterRegister(.vmovshdup, tmp2_reg, tmp1_reg); |
| 7159 | try self.genBinOpMir(.ucomiss, ty, tmp1_mcv, tmp2_mcv); | 7369 | try self.genBinOpMir(.ucomiss, ty, tmp1_mcv, tmp2_mcv); |
| ... | @@ -8139,7 +8349,16 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.Tag { | ... | @@ -8139,7 +8349,16 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.Tag { |
| 8139 | }, | 8349 | }, |
| 8140 | .Vector => switch (ty.childType().zigTypeTag()) { | 8350 | .Vector => switch (ty.childType().zigTypeTag()) { |
| 8141 | .Float => switch (ty.childType().floatBits(self.target.*)) { | 8351 | .Float => switch (ty.childType().floatBits(self.target.*)) { |
| 8142 | 16 => unreachable, // needs special handling | 8352 | 16 => switch (ty.vectorLen()) { |
| 8353 | 1 => unreachable, // needs special handling | ||
| 8354 | 2 => return if (self.hasFeature(.avx)) .vmovss else .movss, | ||
| 8355 | 3...4 => return if (self.hasFeature(.avx)) .vmovsd else .movsd, | ||
| 8356 | 5...8 => return if (self.hasFeature(.avx)) | ||
| 8357 | if (aligned) .vmovaps else .vmovups | ||
| 8358 | else if (aligned) .movaps else .movups, | ||
| 8359 | 9...16 => if (self.hasFeature(.avx)) return if (aligned) .vmovaps else .vmovups, | ||
| 8360 | else => {}, | ||
| 8361 | }, | ||
| 8143 | 32 => switch (ty.vectorLen()) { | 8362 | 32 => switch (ty.vectorLen()) { |
| 8144 | 1 => return if (self.hasFeature(.avx)) .vmovss else .movss, | 8363 | 1 => return if (self.hasFeature(.avx)) .vmovss else .movss, |
| 8145 | 2...4 => return if (self.hasFeature(.avx)) | 8364 | 2...4 => return if (self.hasFeature(.avx)) |
src/arch/x86_64/Encoding.zig+13-10| ... | @@ -270,7 +270,7 @@ pub const Mnemonic = enum { | ... | @@ -270,7 +270,7 @@ pub const Mnemonic = enum { |
| 270 | divps, divss, | 270 | divps, divss, |
| 271 | maxps, maxss, | 271 | maxps, maxss, |
| 272 | minps, minss, | 272 | minps, minss, |
| 273 | movaps, movss, movups, | 273 | movaps, movhlps, movss, movups, |
| 274 | mulps, mulss, | 274 | mulps, mulss, |
| 275 | orps, | 275 | orps, |
| 276 | pextrw, pinsrw, | 276 | pextrw, pinsrw, |
| ... | @@ -303,6 +303,8 @@ pub const Mnemonic = enum { | ... | @@ -303,6 +303,8 @@ pub const Mnemonic = enum { |
| 303 | // SSE3 | 303 | // SSE3 |
| 304 | movddup, movshdup, movsldup, | 304 | movddup, movshdup, movsldup, |
| 305 | // SSE4.1 | 305 | // SSE4.1 |
| 306 | pextrb, pextrd, pextrq, | ||
| 307 | pinsrb, pinsrd, pinsrq, | ||
| 306 | roundpd, roundps, roundsd, roundss, | 308 | roundpd, roundps, roundsd, roundss, |
| 307 | // AVX | 309 | // AVX |
| 308 | vaddpd, vaddps, vaddsd, vaddss, | 310 | vaddpd, vaddps, vaddsd, vaddss, |
| ... | @@ -311,13 +313,14 @@ pub const Mnemonic = enum { | ... | @@ -311,13 +313,14 @@ pub const Mnemonic = enum { |
| 311 | vmaxpd, vmaxps, vmaxsd, vmaxss, | 313 | vmaxpd, vmaxps, vmaxsd, vmaxss, |
| 312 | vminpd, vminps, vminsd, vminss, | 314 | vminpd, vminps, vminsd, vminss, |
| 313 | vmovapd, vmovaps, | 315 | vmovapd, vmovaps, |
| 314 | vmovddup, | 316 | vmovddup, vmovhlps, |
| 315 | vmovsd, | 317 | vmovsd, |
| 316 | vmovshdup, vmovsldup, | 318 | vmovshdup, vmovsldup, |
| 317 | vmovss, | 319 | vmovss, |
| 318 | vmovupd, vmovups, | 320 | vmovupd, vmovups, |
| 319 | vmulpd, vmulps, vmulsd, vmulss, | 321 | vmulpd, vmulps, vmulsd, vmulss, |
| 320 | vpextrw, vpinsrw, | 322 | vpextrb, vpextrd, vpextrq, vpextrw, |
| 323 | vpinsrb, vpinsrd, vpinsrq, vpinsrw, | ||
| 321 | vpshufhw, vpshuflw, | 324 | vpshufhw, vpshuflw, |
| 322 | vpsrld, vpsrlq, vpsrlw, | 325 | vpsrld, vpsrlq, vpsrlw, |
| 323 | vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd, | 326 | vpunpckhbw, vpunpckhdq, vpunpckhqdq, vpunpckhwd, |
| ... | @@ -359,7 +362,7 @@ pub const Op = enum { | ... | @@ -359,7 +362,7 @@ pub const Op = enum { |
| 359 | cl, | 362 | cl, |
| 360 | r8, r16, r32, r64, | 363 | r8, r16, r32, r64, |
| 361 | rm8, rm16, rm32, rm64, | 364 | rm8, rm16, rm32, rm64, |
| 362 | r32_m16, r64_m16, | 365 | r32_m8, r32_m16, r64_m16, |
| 363 | m8, m16, m32, m64, m80, m128, m256, | 366 | m8, m16, m32, m64, m80, m128, m256, |
| 364 | rel8, rel16, rel32, | 367 | rel8, rel16, rel32, |
| 365 | m, | 368 | m, |
| ... | @@ -444,7 +447,7 @@ pub const Op = enum { | ... | @@ -444,7 +447,7 @@ pub const Op = enum { |
| 444 | pub fn immBitSize(op: Op) u64 { | 447 | pub fn immBitSize(op: Op) u64 { |
| 445 | return switch (op) { | 448 | return switch (op) { |
| 446 | .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable, | 449 | .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable, |
| 447 | .al, .cl, .r8, .rm8 => unreachable, | 450 | .al, .cl, .r8, .rm8, .r32_m8 => unreachable, |
| 448 | .ax, .r16, .rm16 => unreachable, | 451 | .ax, .r16, .rm16 => unreachable, |
| 449 | .eax, .r32, .rm32, .r32_m16 => unreachable, | 452 | .eax, .r32, .rm32, .r32_m16 => unreachable, |
| 450 | .rax, .r64, .rm64, .r64_m16 => unreachable, | 453 | .rax, .r64, .rm64, .r64_m16 => unreachable, |
| ... | @@ -467,7 +470,7 @@ pub const Op = enum { | ... | @@ -467,7 +470,7 @@ pub const Op = enum { |
| 467 | .m8, .m16, .m32, .m64, .m80, .m128, .m256 => unreachable, | 470 | .m8, .m16, .m32, .m64, .m80, .m128, .m256 => unreachable, |
| 468 | .al, .cl, .r8, .rm8 => 8, | 471 | .al, .cl, .r8, .rm8 => 8, |
| 469 | .ax, .r16, .rm16 => 16, | 472 | .ax, .r16, .rm16 => 16, |
| 470 | .eax, .r32, .rm32, .r32_m16 => 32, | 473 | .eax, .r32, .rm32, .r32_m8, .r32_m16 => 32, |
| 471 | .rax, .r64, .rm64, .r64_m16 => 64, | 474 | .rax, .r64, .rm64, .r64_m16 => 64, |
| 472 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => 128, | 475 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => 128, |
| 473 | .ymm, .ymm_m256 => 256, | 476 | .ymm, .ymm_m256 => 256, |
| ... | @@ -480,7 +483,7 @@ pub const Op = enum { | ... | @@ -480,7 +483,7 @@ pub const Op = enum { |
| 480 | .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s, .imm64 => unreachable, | 483 | .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s, .imm64 => unreachable, |
| 481 | .rel8, .rel16, .rel32 => unreachable, | 484 | .rel8, .rel16, .rel32 => unreachable, |
| 482 | .al, .cl, .r8, .ax, .r16, .eax, .r32, .rax, .r64, .xmm, .ymm => unreachable, | 485 | .al, .cl, .r8, .ax, .r16, .eax, .r32, .rax, .r64, .xmm, .ymm => unreachable, |
| 483 | .m8, .rm8 => 8, | 486 | .m8, .rm8, .r32_m8 => 8, |
| 484 | .m16, .rm16, .r32_m16, .r64_m16 => 16, | 487 | .m16, .rm16, .r32_m16, .r64_m16 => 16, |
| 485 | .m32, .rm32, .xmm_m32 => 32, | 488 | .m32, .rm32, .xmm_m32 => 32, |
| 486 | .m64, .rm64, .xmm_m64 => 64, | 489 | .m64, .rm64, .xmm_m64 => 64, |
| ... | @@ -509,7 +512,7 @@ pub const Op = enum { | ... | @@ -509,7 +512,7 @@ pub const Op = enum { |
| 509 | .al, .ax, .eax, .rax, | 512 | .al, .ax, .eax, .rax, |
| 510 | .r8, .r16, .r32, .r64, | 513 | .r8, .r16, .r32, .r64, |
| 511 | .rm8, .rm16, .rm32, .rm64, | 514 | .rm8, .rm16, .rm32, .rm64, |
| 512 | .r32_m16, .r64_m16, | 515 | .r32_m8, .r32_m16, .r64_m16, |
| 513 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128, | 516 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128, |
| 514 | .ymm, .ymm_m256, | 517 | .ymm, .ymm_m256, |
| 515 | => true, | 518 | => true, |
| ... | @@ -535,7 +538,7 @@ pub const Op = enum { | ... | @@ -535,7 +538,7 @@ pub const Op = enum { |
| 535 | // zig fmt: off | 538 | // zig fmt: off |
| 536 | return switch (op) { | 539 | return switch (op) { |
| 537 | .rm8, .rm16, .rm32, .rm64, | 540 | .rm8, .rm16, .rm32, .rm64, |
| 538 | .r32_m16, .r64_m16, | 541 | .r32_m8, .r32_m16, .r64_m16, |
| 539 | .m8, .m16, .m32, .m64, .m80, .m128, .m256, | 542 | .m8, .m16, .m32, .m64, .m80, .m128, .m256, |
| 540 | .m, | 543 | .m, |
| 541 | .xmm_m32, .xmm_m64, .xmm_m128, | 544 | .xmm_m32, .xmm_m64, .xmm_m128, |
| ... | @@ -559,7 +562,7 @@ pub const Op = enum { | ... | @@ -559,7 +562,7 @@ pub const Op = enum { |
| 559 | .al, .ax, .eax, .rax, .cl => .general_purpose, | 562 | .al, .ax, .eax, .rax, .cl => .general_purpose, |
| 560 | .r8, .r16, .r32, .r64 => .general_purpose, | 563 | .r8, .r16, .r32, .r64 => .general_purpose, |
| 561 | .rm8, .rm16, .rm32, .rm64 => .general_purpose, | 564 | .rm8, .rm16, .rm32, .rm64 => .general_purpose, |
| 562 | .r32_m16, .r64_m16 => .general_purpose, | 565 | .r32_m8, .r32_m16, .r64_m16 => .general_purpose, |
| 563 | .sreg => .segment, | 566 | .sreg => .segment, |
| 564 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => .floating_point, | 567 | .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => .floating_point, |
| 565 | .ymm, .ymm_m256 => .floating_point, | 568 | .ymm, .ymm_m256 => .floating_point, |
src/arch/x86_64/Lower.zig+22| ... | @@ -137,6 +137,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -137,6 +137,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 137 | .minps, | 137 | .minps, |
| 138 | .minss, | 138 | .minss, |
| 139 | .movaps, | 139 | .movaps, |
| 140 | .movhlps, | ||
| 140 | .movss, | 141 | .movss, |
| 141 | .movups, | 142 | .movups, |
| 142 | .mulps, | 143 | .mulps, |
| ... | @@ -149,6 +150,8 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -149,6 +150,8 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 149 | .subps, | 150 | .subps, |
| 150 | .subss, | 151 | .subss, |
| 151 | .ucomiss, | 152 | .ucomiss, |
| 153 | .unpckhps, | ||
| 154 | .unpcklps, | ||
| 152 | .xorps, | 155 | .xorps, |
| 153 | 156 | ||
| 154 | .addpd, | 157 | .addpd, |
| ... | @@ -187,12 +190,20 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -187,12 +190,20 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 187 | .subpd, | 190 | .subpd, |
| 188 | .subsd, | 191 | .subsd, |
| 189 | .ucomisd, | 192 | .ucomisd, |
| 193 | .unpckhpd, | ||
| 194 | .unpcklpd, | ||
| 190 | .xorpd, | 195 | .xorpd, |
| 191 | 196 | ||
| 192 | .movddup, | 197 | .movddup, |
| 193 | .movshdup, | 198 | .movshdup, |
| 194 | .movsldup, | 199 | .movsldup, |
| 195 | 200 | ||
| 201 | .pextrb, | ||
| 202 | .pextrd, | ||
| 203 | .pextrq, | ||
| 204 | .pinsrb, | ||
| 205 | .pinsrd, | ||
| 206 | .pinsrq, | ||
| 196 | .roundpd, | 207 | .roundpd, |
| 197 | .roundps, | 208 | .roundps, |
| 198 | .roundsd, | 209 | .roundsd, |
| ... | @@ -221,6 +232,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -221,6 +232,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 221 | .vmovapd, | 232 | .vmovapd, |
| 222 | .vmovaps, | 233 | .vmovaps, |
| 223 | .vmovddup, | 234 | .vmovddup, |
| 235 | .vmovhlps, | ||
| 224 | .vmovsd, | 236 | .vmovsd, |
| 225 | .vmovshdup, | 237 | .vmovshdup, |
| 226 | .vmovsldup, | 238 | .vmovsldup, |
| ... | @@ -231,7 +243,13 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -231,7 +243,13 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 231 | .vmulps, | 243 | .vmulps, |
| 232 | .vmulsd, | 244 | .vmulsd, |
| 233 | .vmulss, | 245 | .vmulss, |
| 246 | .vpextrb, | ||
| 247 | .vpextrd, | ||
| 248 | .vpextrq, | ||
| 234 | .vpextrw, | 249 | .vpextrw, |
| 250 | .vpinsrb, | ||
| 251 | .vpinsrd, | ||
| 252 | .vpinsrq, | ||
| 235 | .vpinsrw, | 253 | .vpinsrw, |
| 236 | .vpshufhw, | 254 | .vpshufhw, |
| 237 | .vpshuflw, | 255 | .vpshuflw, |
| ... | @@ -258,6 +276,10 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { | ... | @@ -258,6 +276,10 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct { |
| 258 | .vsubps, | 276 | .vsubps, |
| 259 | .vsubsd, | 277 | .vsubsd, |
| 260 | .vsubss, | 278 | .vsubss, |
| 279 | .vunpckhpd, | ||
| 280 | .vunpckhps, | ||
| 281 | .vunpcklpd, | ||
| 282 | .vunpcklps, | ||
| 261 | 283 | ||
| 262 | .vcvtph2ps, | 284 | .vcvtph2ps, |
| 263 | .vcvtps2ph, | 285 | .vcvtps2ph, |
src/arch/x86_64/Mir.zig+44| ... | @@ -192,6 +192,8 @@ pub const Inst = struct { | ... | @@ -192,6 +192,8 @@ pub const Inst = struct { |
| 192 | minss, | 192 | minss, |
| 193 | /// Move aligned packed single-precision floating-point values | 193 | /// Move aligned packed single-precision floating-point values |
| 194 | movaps, | 194 | movaps, |
| 195 | /// Move packed single-precision floating-point values high to low | ||
| 196 | movhlps, | ||
| 195 | /// Move scalar single-precision floating-point value | 197 | /// Move scalar single-precision floating-point value |
| 196 | movss, | 198 | movss, |
| 197 | /// Move unaligned packed single-precision floating-point values | 199 | /// Move unaligned packed single-precision floating-point values |
| ... | @@ -216,6 +218,10 @@ pub const Inst = struct { | ... | @@ -216,6 +218,10 @@ pub const Inst = struct { |
| 216 | subss, | 218 | subss, |
| 217 | /// Unordered compare scalar single-precision floating-point values | 219 | /// Unordered compare scalar single-precision floating-point values |
| 218 | ucomiss, | 220 | ucomiss, |
| 221 | /// Unpack and interleave high packed single-precision floating-point values | ||
| 222 | unpckhps, | ||
| 223 | /// Unpack and interleave low packed single-precision floating-point values | ||
| 224 | unpcklps, | ||
| 219 | /// Bitwise logical xor of packed single precision floating-point values | 225 | /// Bitwise logical xor of packed single precision floating-point values |
| 220 | xorps, | 226 | xorps, |
| 221 | 227 | ||
| ... | @@ -291,6 +297,10 @@ pub const Inst = struct { | ... | @@ -291,6 +297,10 @@ pub const Inst = struct { |
| 291 | subsd, | 297 | subsd, |
| 292 | /// Unordered compare scalar double-precision floating-point values | 298 | /// Unordered compare scalar double-precision floating-point values |
| 293 | ucomisd, | 299 | ucomisd, |
| 300 | /// Unpack and interleave high packed double-precision floating-point values | ||
| 301 | unpckhpd, | ||
| 302 | /// Unpack and interleave low packed double-precision floating-point values | ||
| 303 | unpcklpd, | ||
| 294 | /// Bitwise logical xor of packed double precision floating-point values | 304 | /// Bitwise logical xor of packed double precision floating-point values |
| 295 | xorpd, | 305 | xorpd, |
| 296 | 306 | ||
| ... | @@ -301,6 +311,18 @@ pub const Inst = struct { | ... | @@ -301,6 +311,18 @@ pub const Inst = struct { |
| 301 | /// Replicate single floating-point values | 311 | /// Replicate single floating-point values |
| 302 | movsldup, | 312 | movsldup, |
| 303 | 313 | ||
| 314 | /// Extract Byte | ||
| 315 | pextrb, | ||
| 316 | /// Extract Doubleword | ||
| 317 | pextrd, | ||
| 318 | /// Extract Quadword | ||
| 319 | pextrq, | ||
| 320 | /// Insert Byte | ||
| 321 | pinsrb, | ||
| 322 | /// Insert Doubleword | ||
| 323 | pinsrd, | ||
| 324 | /// Insert Quadword | ||
| 325 | pinsrq, | ||
| 304 | /// Round packed double-precision floating-point values | 326 | /// Round packed double-precision floating-point values |
| 305 | roundpd, | 327 | roundpd, |
| 306 | /// Round packed single-precision floating-point values | 328 | /// Round packed single-precision floating-point values |
| ... | @@ -354,6 +376,8 @@ pub const Inst = struct { | ... | @@ -354,6 +376,8 @@ pub const Inst = struct { |
| 354 | vmovapd, | 376 | vmovapd, |
| 355 | /// Move aligned packed single-precision floating-point values | 377 | /// Move aligned packed single-precision floating-point values |
| 356 | vmovaps, | 378 | vmovaps, |
| 379 | /// Move packed single-precision floating-point values high to low | ||
| 380 | vmovhlps, | ||
| 357 | /// Replicate double floating-point values | 381 | /// Replicate double floating-point values |
| 358 | vmovddup, | 382 | vmovddup, |
| 359 | /// Move or merge scalar double-precision floating-point value | 383 | /// Move or merge scalar double-precision floating-point value |
| ... | @@ -376,8 +400,20 @@ pub const Inst = struct { | ... | @@ -376,8 +400,20 @@ pub const Inst = struct { |
| 376 | vmulsd, | 400 | vmulsd, |
| 377 | /// Multiply scalar single-precision floating-point values | 401 | /// Multiply scalar single-precision floating-point values |
| 378 | vmulss, | 402 | vmulss, |
| 403 | /// Extract Byte | ||
| 404 | vpextrb, | ||
| 405 | /// Extract Doubleword | ||
| 406 | vpextrd, | ||
| 407 | /// Extract Quadword | ||
| 408 | vpextrq, | ||
| 379 | /// Extract word | 409 | /// Extract word |
| 380 | vpextrw, | 410 | vpextrw, |
| 411 | /// Insert Byte | ||
| 412 | vpinsrb, | ||
| 413 | /// Insert Doubleword | ||
| 414 | vpinsrd, | ||
| 415 | /// Insert Quadword | ||
| 416 | vpinsrq, | ||
| 381 | /// Insert word | 417 | /// Insert word |
| 382 | vpinsrw, | 418 | vpinsrw, |
| 383 | /// Shuffle packed high words | 419 | /// Shuffle packed high words |
| ... | @@ -430,6 +466,14 @@ pub const Inst = struct { | ... | @@ -430,6 +466,14 @@ pub const Inst = struct { |
| 430 | vsubsd, | 466 | vsubsd, |
| 431 | /// Subtract scalar single-precision floating-point values | 467 | /// Subtract scalar single-precision floating-point values |
| 432 | vsubss, | 468 | vsubss, |
| 469 | /// Unpack and interleave high packed double-precision floating-point values | ||
| 470 | vunpckhpd, | ||
| 471 | /// Unpack and interleave high packed single-precision floating-point values | ||
| 472 | vunpckhps, | ||
| 473 | /// Unpack and interleave low packed double-precision floating-point values | ||
| 474 | vunpcklpd, | ||
| 475 | /// Unpack and interleave low packed single-precision floating-point values | ||
| 476 | vunpcklps, | ||
| 433 | 477 | ||
| 434 | /// Convert 16-bit floating-point values to single-precision floating-point values | 478 | /// Convert 16-bit floating-point values to single-precision floating-point values |
| 435 | vcvtph2ps, | 479 | vcvtph2ps, |
src/arch/x86_64/encodings.zig+20| ... | @@ -865,6 +865,8 @@ pub const table = [_]Entry{ | ... | @@ -865,6 +865,8 @@ pub const table = [_]Entry{ |
| 865 | .{ .movaps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x28 }, 0, .none, .sse }, | 865 | .{ .movaps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x28 }, 0, .none, .sse }, |
| 866 | .{ .movaps, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x0f, 0x29 }, 0, .none, .sse }, | 866 | .{ .movaps, .mr, &.{ .xmm_m128, .xmm }, &.{ 0x0f, 0x29 }, 0, .none, .sse }, |
| 867 | 867 | ||
| 868 | .{ .movhlps, .rm, &.{ .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .none, .sse }, | ||
| 869 | |||
| 868 | .{ .movss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x10 }, 0, .none, .sse }, | 870 | .{ .movss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x10 }, 0, .none, .sse }, |
| 869 | .{ .movss, .mr, &.{ .xmm_m32, .xmm }, &.{ 0xf3, 0x0f, 0x11 }, 0, .none, .sse }, | 871 | .{ .movss, .mr, &.{ .xmm_m32, .xmm }, &.{ 0xf3, 0x0f, 0x11 }, 0, .none, .sse }, |
| 870 | 872 | ||
| ... | @@ -988,8 +990,16 @@ pub const table = [_]Entry{ | ... | @@ -988,8 +990,16 @@ pub const table = [_]Entry{ |
| 988 | .{ .movsldup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x12 }, 0, .none, .sse3 }, | 990 | .{ .movsldup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x12 }, 0, .none, .sse3 }, |
| 989 | 991 | ||
| 990 | // SSE4.1 | 992 | // SSE4.1 |
| 993 | .{ .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 }, | ||
| 995 | .{ .pextrq, .mri, &.{ .rm64, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .long, .sse4_1 }, | ||
| 996 | |||
| 991 | .{ .pextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .none, .sse4_1 }, | 997 | .{ .pextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .none, .sse4_1 }, |
| 992 | 998 | ||
| 999 | .{ .pinsrb, .rmi, &.{ .xmm, .r32_m8, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x20 }, 0, .none, .sse4_1 }, | ||
| 1000 | .{ .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 }, | ||
| 1002 | |||
| 993 | .{ .roundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .none, .sse4_1 }, | 1003 | .{ .roundpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x09 }, 0, .none, .sse4_1 }, |
| 994 | 1004 | ||
| 995 | .{ .roundps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x08 }, 0, .none, .sse4_1 }, | 1005 | .{ .roundps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x08 }, 0, .none, .sse4_1 }, |
| ... | @@ -1062,6 +1072,8 @@ pub const table = [_]Entry{ | ... | @@ -1062,6 +1072,8 @@ pub const table = [_]Entry{ |
| 1062 | .{ .vmovddup, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .vex_128_wig, .avx }, | 1072 | .{ .vmovddup, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .vex_128_wig, .avx }, |
| 1063 | .{ .vmovddup, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .vex_256_wig, .avx }, | 1073 | .{ .vmovddup, .rm, &.{ .ymm, .ymm_m256 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .vex_256_wig, .avx }, |
| 1064 | 1074 | ||
| 1075 | .{ .vmovhlps, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0x0f, 0x12 }, 0, .vex_128_wig, .avx }, | ||
| 1076 | |||
| 1065 | .{ .vmovsd, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx }, | 1077 | .{ .vmovsd, .rvm, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx }, |
| 1066 | .{ .vmovsd, .rm, &.{ .xmm, .m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx }, | 1078 | .{ .vmovsd, .rm, &.{ .xmm, .m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .vex_lig_wig, .avx }, |
| 1067 | .{ .vmovsd, .mvr, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x11 }, 0, .vex_lig_wig, .avx }, | 1079 | .{ .vmovsd, .mvr, &.{ .xmm, .xmm, .xmm }, &.{ 0xf2, 0x0f, 0x11 }, 0, .vex_lig_wig, .avx }, |
| ... | @@ -1098,9 +1110,17 @@ pub const table = [_]Entry{ | ... | @@ -1098,9 +1110,17 @@ pub const table = [_]Entry{ |
| 1098 | 1110 | ||
| 1099 | .{ .vmulss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .vex_lig_wig, .avx }, | 1111 | .{ .vmulss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .vex_lig_wig, .avx }, |
| 1100 | 1112 | ||
| 1113 | .{ .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 }, | ||
| 1115 | .{ .vpextrq, .mri, &.{ .rm64, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .vex_128_w1, .avx }, | ||
| 1116 | |||
| 1101 | .{ .vpextrw, .rmi, &.{ .r32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x15 }, 0, .vex_128_wig, .avx }, | 1117 | .{ .vpextrw, .rmi, &.{ .r32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x15 }, 0, .vex_128_wig, .avx }, |
| 1102 | .{ .vpextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .vex_128_wig, .avx }, | 1118 | .{ .vpextrw, .mri, &.{ .r32_m16, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x15 }, 0, .vex_128_wig, .avx }, |
| 1103 | 1119 | ||
| 1120 | .{ .vpinsrb, .rmi, &.{ .xmm, .r32_m8, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x20 }, 0, .vex_128_w0, .avx }, | ||
| 1121 | .{ .vpinsrd, .rmi, &.{ .xmm, .rm32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .vex_128_w0, .avx }, | ||
| 1122 | .{ .vpinsrq, .rmi, &.{ .xmm, .rm64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x22 }, 0, .vex_128_w1, .avx }, | ||
| 1123 | |||
| 1104 | .{ .vpinsrw, .rvmi, &.{ .xmm, .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .vex_128_wig, .avx }, | 1124 | .{ .vpinsrw, .rvmi, &.{ .xmm, .xmm, .r32_m16, .imm8 }, &.{ 0x66, 0x0f, 0xc4 }, 0, .vex_128_wig, .avx }, |
| 1105 | 1125 | ||
| 1106 | .{ .vpsrlw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_128_wig, .avx }, | 1126 | .{ .vpsrlw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd1 }, 0, .vex_128_wig, .avx }, |
test/behavior/floatop.zig+11-11| ... | @@ -8,6 +8,8 @@ const has_f80_rt = switch (builtin.cpu.arch) { | ... | @@ -8,6 +8,8 @@ const has_f80_rt = switch (builtin.cpu.arch) { |
| 8 | .x86_64, .x86 => true, | 8 | .x86_64, .x86 => true, |
| 9 | else => false, | 9 | else => false, |
| 10 | }; | 10 | }; |
| 11 | const no_x86_64_hardware_f16_support = builtin.zig_backend == .stage2_x86_64 and | ||
| 12 | !std.Target.x86.featureSetHas(builtin.cpu.features, .f16c); | ||
| 11 | 13 | ||
| 12 | const epsilon_16 = 0.001; | 14 | const epsilon_16 = 0.001; |
| 13 | const epsilon = 0.000001; | 15 | const epsilon = 0.000001; |
| ... | @@ -52,8 +54,7 @@ fn testFloatComparisons() !void { | ... | @@ -52,8 +54,7 @@ fn testFloatComparisons() !void { |
| 52 | } | 54 | } |
| 53 | 55 | ||
| 54 | test "different sized float comparisons" { | 56 | test "different sized float comparisons" { |
| 55 | if (builtin.zig_backend == .stage2_x86_64 and | 57 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO |
| 56 | !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest; // TODO | ||
| 57 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 58 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 58 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 59 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 59 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 60 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -152,7 +153,7 @@ fn testSqrtWithVectors() !void { | ... | @@ -152,7 +153,7 @@ fn testSqrtWithVectors() !void { |
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | test "more @sqrt f16 tests" { | 155 | test "more @sqrt f16 tests" { |
| 155 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 156 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO |
| 156 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 157 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 157 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 158 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 158 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 159 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -202,7 +203,7 @@ fn testSqrtLegacy(comptime T: type, x: T) !void { | ... | @@ -202,7 +203,7 @@ fn testSqrtLegacy(comptime T: type, x: T) !void { |
| 202 | } | 203 | } |
| 203 | 204 | ||
| 204 | test "@sin" { | 205 | test "@sin" { |
| 205 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 206 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO |
| 206 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 207 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 207 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 208 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 208 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 209 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -241,7 +242,7 @@ fn testSinWithVectors() !void { | ... | @@ -241,7 +242,7 @@ fn testSinWithVectors() !void { |
| 241 | } | 242 | } |
| 242 | 243 | ||
| 243 | test "@cos" { | 244 | test "@cos" { |
| 244 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 245 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO |
| 245 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 246 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 246 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 247 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 247 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 248 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -280,7 +281,7 @@ fn testCosWithVectors() !void { | ... | @@ -280,7 +281,7 @@ fn testCosWithVectors() !void { |
| 280 | } | 281 | } |
| 281 | 282 | ||
| 282 | test "@exp" { | 283 | test "@exp" { |
| 283 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 284 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO |
| 284 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 285 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 285 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 286 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 286 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 287 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -318,7 +319,7 @@ fn testExpWithVectors() !void { | ... | @@ -318,7 +319,7 @@ fn testExpWithVectors() !void { |
| 318 | } | 319 | } |
| 319 | 320 | ||
| 320 | test "@exp2" { | 321 | test "@exp2" { |
| 321 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 322 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO |
| 322 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 323 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 323 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 324 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 324 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 325 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -403,7 +404,7 @@ test "@log with @vectors" { | ... | @@ -403,7 +404,7 @@ test "@log with @vectors" { |
| 403 | } | 404 | } |
| 404 | 405 | ||
| 405 | test "@log2" { | 406 | test "@log2" { |
| 406 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 407 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO |
| 407 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 408 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 408 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 409 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 409 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 410 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -445,7 +446,7 @@ fn testLog2WithVectors() !void { | ... | @@ -445,7 +446,7 @@ fn testLog2WithVectors() !void { |
| 445 | } | 446 | } |
| 446 | 447 | ||
| 447 | test "@log10" { | 448 | test "@log10" { |
| 448 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 449 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO |
| 449 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 450 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 450 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 451 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 451 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 452 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -881,7 +882,7 @@ fn testTruncLegacy(comptime T: type, x: T) !void { | ... | @@ -881,7 +882,7 @@ fn testTruncLegacy(comptime T: type, x: T) !void { |
| 881 | } | 882 | } |
| 882 | 883 | ||
| 883 | test "negation f16" { | 884 | test "negation f16" { |
| 884 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 885 | if (no_x86_64_hardware_f16_support) return error.SkipZigTest; // TODO |
| 885 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 886 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 886 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 887 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 887 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 888 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1040,7 +1041,6 @@ test "comptime_float zero divided by zero produces zero" { | ... | @@ -1040,7 +1041,6 @@ test "comptime_float zero divided by zero produces zero" { |
| 1040 | } | 1041 | } |
| 1041 | 1042 | ||
| 1042 | test "nan negation f16" { | 1043 | test "nan negation f16" { |
| 1043 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1044 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1044 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1045 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1045 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1046 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1046 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/muladd.zig+4-4| ... | @@ -2,11 +2,11 @@ const std = @import("std"); | ... | @@ -2,11 +2,11 @@ const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | 4 | ||
| 5 | const stage2_x86_64_without_hardware_fma_support = builtin.zig_backend == .stage2_x86_64 and | 5 | const no_x86_64_hardware_fma_support = builtin.zig_backend == .stage2_x86_64 and |
| 6 | !std.Target.x86.featureSetHas(builtin.cpu.features, .fma); | 6 | !std.Target.x86.featureSetHas(builtin.cpu.features, .fma); |
| 7 | 7 | ||
| 8 | test "@mulAdd" { | 8 | test "@mulAdd" { |
| 9 | if (stage2_x86_64_without_hardware_fma_support) return error.SkipZigTest; // TODO | 9 | if (no_x86_64_hardware_fma_support) return error.SkipZigTest; // TODO |
| 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 11 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 12 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 12 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -120,7 +120,7 @@ fn vector32() !void { | ... | @@ -120,7 +120,7 @@ fn vector32() !void { |
| 120 | 120 | ||
| 121 | test "vector f32" { | 121 | test "vector f32" { |
| 122 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 122 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 123 | if (stage2_x86_64_without_hardware_fma_support) return error.SkipZigTest; // TODO | 123 | if (no_x86_64_hardware_fma_support) 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_aarch64) return error.SkipZigTest; // TODO | 125 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 126 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 126 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -143,7 +143,7 @@ fn vector64() !void { | ... | @@ -143,7 +143,7 @@ fn vector64() !void { |
| 143 | 143 | ||
| 144 | test "vector f64" { | 144 | test "vector f64" { |
| 145 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 145 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 146 | if (stage2_x86_64_without_hardware_fma_support) return error.SkipZigTest; // TODO | 146 | if (no_x86_64_hardware_fma_support) return error.SkipZigTest; // TODO |
| 147 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 147 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 148 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 148 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 149 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 149 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |