| ... | @@ -635,6 +635,7 @@ const InstTracking = struct { | ... | @@ -635,6 +635,7 @@ const InstTracking = struct { |
| 635 | } | 635 | } |
| 636 | tracking_log.debug("spill {} from {} to {}", .{ inst, self.short, self.long }); | 636 | tracking_log.debug("spill {} from {} to {}", .{ inst, self.short, self.long }); |
| 637 | try cg.genCopy(cg.typeOfIndex(inst), self.long, self.short, .{}); | 637 | try cg.genCopy(cg.typeOfIndex(inst), self.long, self.short, .{}); |
| | 638 | for (self.short.getRegs()) |reg| if (reg.class() == .x87) try cg.asmRegister(.{ .f_, .free }, reg); |
| 638 | } | 639 | } |
| 639 | | 640 | |
| 640 | fn reuseFrame(self: *InstTracking) void { | 641 | fn reuseFrame(self: *InstTracking) void { |
| ... | @@ -649,7 +650,21 @@ const InstTracking = struct { | ... | @@ -649,7 +650,21 @@ const InstTracking = struct { |
| 649 | } | 650 | } |
| 650 | | 651 | |
| 651 | fn trackSpill(self: *InstTracking, function: *CodeGen, inst: Air.Inst.Index) !void { | 652 | fn trackSpill(self: *InstTracking, function: *CodeGen, inst: Air.Inst.Index) !void { |
| 652 | try function.freeValue(self.short); | 653 | switch (self.short) { |
| | 654 | .register => |reg| function.register_manager.freeReg(reg), |
| | 655 | inline .register_pair, |
| | 656 | .register_triple, |
| | 657 | .register_quadruple, |
| | 658 | => |regs| for (regs) |reg| function.register_manager.freeReg(reg), |
| | 659 | .register_offset, .indirect => |reg_off| function.register_manager.freeReg(reg_off.reg), |
| | 660 | .register_overflow => |reg_ov| { |
| | 661 | function.register_manager.freeReg(reg_ov.reg); |
| | 662 | function.eflags_inst = null; |
| | 663 | }, |
| | 664 | .register_mask => |reg_mask| function.register_manager.freeReg(reg_mask.reg), |
| | 665 | .eflags => function.eflags_inst = null, |
| | 666 | else => {}, // TODO process stack allocation death |
| | 667 | } |
| 653 | self.reuseFrame(); | 668 | self.reuseFrame(); |
| 654 | tracking_log.debug("{} => {} (spilled)", .{ inst, self.* }); | 669 | tracking_log.debug("{} => {} (spilled)", .{ inst, self.* }); |
| 655 | } | 670 | } |
| ... | @@ -1063,10 +1078,16 @@ pub fn generateLazy( | ... | @@ -1063,10 +1078,16 @@ pub fn generateLazy( |
| 1063 | .end_di_column = undefined, // no debug info yet | 1078 | .end_di_column = undefined, // no debug info yet |
| 1064 | }; | 1079 | }; |
| 1065 | defer { | 1080 | defer { |
| | 1081 | function.inst_tracking.deinit(gpa); |
| 1066 | function.mir_instructions.deinit(gpa); | 1082 | function.mir_instructions.deinit(gpa); |
| 1067 | function.mir_extra.deinit(gpa); | 1083 | function.mir_extra.deinit(gpa); |
| 1068 | function.mir_table.deinit(gpa); | 1084 | function.mir_table.deinit(gpa); |
| 1069 | } | 1085 | } |
| | 1086 | try function.inst_tracking.ensureTotalCapacity(gpa, Temp.Index.max); |
| | 1087 | for (0..Temp.Index.max) |temp_index| { |
| | 1088 | const temp: Temp.Index = @enumFromInt(temp_index); |
| | 1089 | function.inst_tracking.putAssumeCapacityNoClobber(temp.toIndex(), .init(.none)); |
| | 1090 | } |
| 1070 | | 1091 | |
| 1071 | function.genLazy(lazy_sym) catch |err| switch (err) { | 1092 | function.genLazy(lazy_sym) catch |err| switch (err) { |
| 1072 | error.CodegenFail => return error.CodegenFail, | 1093 | error.CodegenFail => return error.CodegenFail, |
| ... | @@ -2412,7 +2433,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2412,7 +2433,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2412 | | 2433 | |
| 2413 | try cg.airArg(inst); | 2434 | try cg.airArg(inst); |
| 2414 | | 2435 | |
| 2415 | cg.resetTemps(); | 2436 | try cg.resetTemps(); |
| 2416 | cg.checkInvariantsAfterAirInst(); | 2437 | cg.checkInvariantsAfterAirInst(); |
| 2417 | }, | 2438 | }, |
| 2418 | else => break, | 2439 | else => break, |
| ... | @@ -6348,7 +6369,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -6348,7 +6369,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6348 | .{ .@"1:", .f_p, .st, .dst0t, ._, ._, ._ }, | 6369 | .{ .@"1:", .f_p, .st, .dst0t, ._, ._, ._ }, |
| 6349 | } }, | 6370 | } }, |
| 6350 | }, .{ | 6371 | }, .{ |
| 6351 | .required_features = .{ .@"64bit", .x87, null, null }, | 6372 | .required_features = .{ .x87, null, null, null }, |
| 6352 | .src_constraints = .{ | 6373 | .src_constraints = .{ |
| 6353 | .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, | 6374 | .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, |
| 6354 | .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, | 6375 | .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, |
| ... | @@ -6375,58 +6396,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -6375,58 +6396,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6375 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, | 6396 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| 6376 | .{ ._, .f_, .xam, ._, ._, ._, ._ }, | 6397 | .{ ._, .f_, .xam, ._, ._, ._, ._ }, |
| 6377 | .{ ._, .fn_sw, .st, .tmp1w, ._, ._, ._ }, | 6398 | .{ ._, .fn_sw, .st, .tmp1w, ._, ._, ._ }, |
| 6378 | .{ ._, ._, .@"test", .tmp1b, .si(0b0_1_000_100), ._, ._ }, | 6399 | .{ ._, ._, .@"test", .tmp1b, .si(0b1_000_100), ._, ._ }, |
| 6379 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 6400 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 6380 | .{ ._, .f_, .xch, .src1t, ._, ._, ._ }, | 6401 | .{ ._, .f_, .xch, .src1t, ._, ._, ._ }, |
| 6381 | .{ ._, .f_, .ucom, .src1t, ._, ._, ._ }, | 6402 | .{ ._, .f_, .ucom, .src1t, ._, ._, ._ }, |
| 6382 | .{ ._, .fn_sw, .st, .tmp1w, ._, ._, ._ }, | 6403 | .{ ._, .fn_sw, .st, .tmp1w, ._, ._, ._ }, |
| 6383 | .{ ._, .f_, .xch, .src1t, ._, ._, ._ }, | 6404 | .{ ._, .f_, .xch, .src1t, ._, ._, ._ }, |
| 6384 | .{ ._, ._, .@"test", .tmp1b, .si(0b0_0_000_001), ._, ._ }, | 6405 | .{ ._, ._, .@"test", .tmp1b, .si(0b0_000_001), ._, ._ }, |
| 6385 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 6406 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 6386 | .{ .@"0:", .f_p, .st, .tmp0t, ._, ._, ._ }, | 6407 | .{ .@"0:", .f_p, .st, .tmp0t, ._, ._, ._ }, |
| 6387 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, | 6408 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, |
| 6388 | .{ .@"1:", .f_p, .st, .dst0t, ._, ._, ._ }, | 6409 | .{ .@"1:", .f_p, .st, .dst0t, ._, ._, ._ }, |
| 6389 | } }, | 6410 | } }, |
| 6390 | }, .{ | | |
| 6391 | .required_features = .{ .x87, null, null, null }, | | |
| 6392 | .src_constraints = .{ | | |
| 6393 | .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, | | |
| 6394 | .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, | | |
| 6395 | }, | | |
| 6396 | .patterns = &.{ | | |
| 6397 | .{ .src = .{ .to_x87, .mem }, .commute = .{ 0, 1 } }, | | |
| 6398 | .{ .src = .{ .mem, .to_x87 } }, | | |
| 6399 | .{ .src = .{ .to_x87, .to_x87 } }, | | |
| 6400 | }, | | |
| 6401 | .extra_temps = .{ | | |
| 6402 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, | | |
| 6403 | .{ .type = .u8, .kind = .{ .reg = .ah } }, | | |
| 6404 | .unused, | | |
| 6405 | .unused, | | |
| 6406 | .unused, | | |
| 6407 | .unused, | | |
| 6408 | .unused, | | |
| 6409 | .unused, | | |
| 6410 | .unused, | | |
| 6411 | }, | | |
| 6412 | .dst_temps = .{.{ .mut_rc = .{ .ref = .src1, .rc = .x87 } }}, | | |
| 6413 | .clobbers = .{ .eflags = true }, | | |
| 6414 | .each = .{ .once = &.{ | | |
| 6415 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, | | |
| 6416 | .{ ._, .f_, .ucom, .tmp0t, ._, ._, ._ }, | | |
| 6417 | .{ ._, .fn_sw, .st, .tmp1w, ._, ._, ._ }, | | |
| 6418 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, | | |
| 6419 | .{ ._, ._p, .j, .@"0f", ._, ._, ._ }, | | |
| 6420 | .{ ._, .f_, .xch, .src1t, ._, ._, ._ }, | | |
| 6421 | .{ ._, .f_, .ucom, .src1t, ._, ._, ._ }, | | |
| 6422 | .{ ._, .fn_sw, .st, .tmp1w, ._, ._, ._ }, | | |
| 6423 | .{ ._, .f_, .xch, .src1t, ._, ._, ._ }, | | |
| 6424 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, | | |
| 6425 | .{ ._, ._b, .j, .@"1f", ._, ._, ._ }, | | |
| 6426 | .{ .@"0:", .f_p, .st, .tmp0t, ._, ._, ._ }, | | |
| 6427 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, | | |
| 6428 | .{ .@"1:", .f_p, .st, .dst0t, ._, ._, ._ }, | | |
| 6429 | } }, | | |
| 6430 | }, .{ | 6411 | }, .{ |
| 6431 | .required_features = .{ .x87, .cmov, null, null }, | 6412 | .required_features = .{ .x87, .cmov, null, null }, |
| 6432 | .src_constraints = .{ | 6413 | .src_constraints = .{ |
| ... | @@ -6508,7 +6489,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -6508,7 +6489,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6508 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 6489 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 6509 | } }, | 6490 | } }, |
| 6510 | }, .{ | 6491 | }, .{ |
| 6511 | .required_features = .{ .@"64bit", .x87, null, null }, | 6492 | .required_features = .{ .x87, null, null, null }, |
| 6512 | .src_constraints = .{ | 6493 | .src_constraints = .{ |
| 6513 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, | 6494 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, |
| 6514 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, | 6495 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, |
| ... | @@ -6535,13 +6516,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -6535,13 +6516,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6535 | .{ ._, .f_, .ld, .memia(.src0t, .tmp0, .add_size), ._, ._, ._ }, | 6516 | .{ ._, .f_, .ld, .memia(.src0t, .tmp0, .add_size), ._, ._, ._ }, |
| 6536 | .{ ._, .f_, .xam, ._, ._, ._, ._ }, | 6517 | .{ ._, .f_, .xam, ._, ._, ._, ._ }, |
| 6537 | .{ ._, .fn_sw, .st, .tmp3w, ._, ._, ._ }, | 6518 | .{ ._, .fn_sw, .st, .tmp3w, ._, ._, ._ }, |
| 6538 | .{ ._, ._, .@"test", .tmp3b, .si(0b0_1_000_100), ._, ._ }, | 6519 | .{ ._, ._, .@"test", .tmp3b, .si(0b1_000_100), ._, ._ }, |
| 6539 | .{ ._, ._z, .j, .@"1f", ._, ._, ._ }, | 6520 | .{ ._, ._z, .j, .@"1f", ._, ._, ._ }, |
| 6540 | .{ ._, .f_, .xch, .tmp2t, ._, ._, ._ }, | 6521 | .{ ._, .f_, .xch, .tmp2t, ._, ._, ._ }, |
| 6541 | .{ ._, .f_, .ucom, .tmp2t, ._, ._, ._ }, | 6522 | .{ ._, .f_, .ucom, .tmp2t, ._, ._, ._ }, |
| 6542 | .{ ._, .fn_sw, .st, .tmp3w, ._, ._, ._ }, | 6523 | .{ ._, .fn_sw, .st, .tmp3w, ._, ._, ._ }, |
| 6543 | .{ ._, .f_, .xch, .tmp2t, ._, ._, ._ }, | 6524 | .{ ._, .f_, .xch, .tmp2t, ._, ._, ._ }, |
| 6544 | .{ ._, ._, .@"test", .tmp3b, .si(0b0_0_000_001), ._, ._ }, | 6525 | .{ ._, ._, .@"test", .tmp3b, .si(0b0_000_001), ._, ._ }, |
| 6545 | .{ ._, ._nz, .j, .@"2f", ._, ._, ._ }, | 6526 | .{ ._, ._nz, .j, .@"2f", ._, ._, ._ }, |
| 6546 | .{ .@"1:", .f_p, .st, .tmp1t, ._, ._, ._ }, | 6527 | .{ .@"1:", .f_p, .st, .tmp1t, ._, ._, ._ }, |
| 6547 | .{ ._, .f_, .ld, .tmp2t, ._, ._, ._ }, | 6528 | .{ ._, .f_, .ld, .tmp2t, ._, ._, ._ }, |
| ... | @@ -6550,49 +6531,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -6550,49 +6531,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6550 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, | 6531 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 6551 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 6532 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 6552 | } }, | 6533 | } }, |
| 6553 | }, .{ | | |
| 6554 | .required_features = .{ .x87, null, null, null }, | | |
| 6555 | .src_constraints = .{ | | |
| 6556 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, | | |
| 6557 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, | | |
| 6558 | }, | | |
| 6559 | .patterns = &.{ | | |
| 6560 | .{ .src = .{ .to_mem, .to_mem } }, | | |
| 6561 | }, | | |
| 6562 | .extra_temps = .{ | | |
| 6563 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 6564 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, | | |
| 6565 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, | | |
| 6566 | .{ .type = .u8, .kind = .{ .reg = .ah } }, | | |
| 6567 | .unused, | | |
| 6568 | .unused, | | |
| 6569 | .unused, | | |
| 6570 | .unused, | | |
| 6571 | .unused, | | |
| 6572 | }, | | |
| 6573 | .dst_temps = .{.mem}, | | |
| 6574 | .clobbers = .{ .eflags = true }, | | |
| 6575 | .each = .{ .once = &.{ | | |
| 6576 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | | |
| 6577 | .{ .@"0:", .f_, .ld, .memia(.src1t, .tmp0, .add_size), ._, ._, ._ }, | | |
| 6578 | .{ ._, .f_, .ld, .memia(.src0t, .tmp0, .add_size), ._, ._, ._ }, | | |
| 6579 | .{ ._, .f_, .ucom, .tmp1t, ._, ._, ._ }, | | |
| 6580 | .{ ._, .fn_sw, .st, .tmp3w, ._, ._, ._ }, | | |
| 6581 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, | | |
| 6582 | .{ ._, ._p, .j, .@"1f", ._, ._, ._ }, | | |
| 6583 | .{ ._, .f_, .xch, .tmp2t, ._, ._, ._ }, | | |
| 6584 | .{ ._, .f_, .ucom, .tmp2t, ._, ._, ._ }, | | |
| 6585 | .{ ._, .fn_sw, .st, .tmp3w, ._, ._, ._ }, | | |
| 6586 | .{ ._, .f_, .xch, .tmp2t, ._, ._, ._ }, | | |
| 6587 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, | | |
| 6588 | .{ ._, ._b, .j, .@"2f", ._, ._, ._ }, | | |
| 6589 | .{ .@"1:", .f_p, .st, .tmp1t, ._, ._, ._ }, | | |
| 6590 | .{ ._, .f_, .ld, .tmp2t, ._, ._, ._ }, | | |
| 6591 | .{ .@"2:", .f_p, .st, .memia(.dst0t, .tmp0, .add_size), ._, ._, ._ }, | | |
| 6592 | .{ ._, .f_p, .st, .tmp2t, ._, ._, ._ }, | | |
| 6593 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, | | |
| 6594 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 6595 | } }, | | |
| 6596 | }, .{ | 6534 | }, .{ |
| 6597 | .required_features = .{ .sse, null, null, null }, | 6535 | .required_features = .{ .sse, null, null, null }, |
| 6598 | .src_constraints = .{ | 6536 | .src_constraints = .{ |
| ... | @@ -10271,7 +10209,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -10271,7 +10209,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 10271 | .{ .@"1:", .f_p, .st, .dst0t, ._, ._, ._ }, | 10209 | .{ .@"1:", .f_p, .st, .dst0t, ._, ._, ._ }, |
| 10272 | } }, | 10210 | } }, |
| 10273 | }, .{ | 10211 | }, .{ |
| 10274 | .required_features = .{ .@"64bit", .x87, null, null }, | 10212 | .required_features = .{ .x87, null, null, null }, |
| 10275 | .src_constraints = .{ | 10213 | .src_constraints = .{ |
| 10276 | .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, | 10214 | .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, |
| 10277 | .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, | 10215 | .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, |
| ... | @@ -10298,54 +10236,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -10298,54 +10236,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 10298 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, | 10236 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| 10299 | .{ ._, .f_, .xam, ._, ._, ._, ._ }, | 10237 | .{ ._, .f_, .xam, ._, ._, ._, ._ }, |
| 10300 | .{ ._, .fn_sw, .st, .tmp1w, ._, ._, ._ }, | 10238 | .{ ._, .fn_sw, .st, .tmp1w, ._, ._, ._ }, |
| 10301 | .{ ._, ._, .@"test", .tmp1b, .si(0b0_1_000_100), ._, ._ }, | 10239 | .{ ._, ._, .@"test", .tmp1b, .si(0b1_000_100), ._, ._ }, |
| 10302 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 10240 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 10303 | .{ ._, .f_, .ucom, .src1t, ._, ._, ._ }, | 10241 | .{ ._, .f_, .ucom, .src1t, ._, ._, ._ }, |
| 10304 | .{ ._, .fn_sw, .st, .tmp1w, ._, ._, ._ }, | 10242 | .{ ._, .fn_sw, .st, .tmp1w, ._, ._, ._ }, |
| 10305 | .{ ._, ._, .@"test", .tmp1b, .si(0b0_0_000_001), ._, ._ }, | 10243 | .{ ._, ._, .@"test", .tmp1b, .si(0b0_000_001), ._, ._ }, |
| 10306 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 10244 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 10307 | .{ .@"0:", .f_p, .st, .tmp0t, ._, ._, ._ }, | 10245 | .{ .@"0:", .f_p, .st, .tmp0t, ._, ._, ._ }, |
| 10308 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, | 10246 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, |
| 10309 | .{ .@"1:", .f_p, .st, .dst0t, ._, ._, ._ }, | 10247 | .{ .@"1:", .f_p, .st, .dst0t, ._, ._, ._ }, |
| 10310 | } }, | 10248 | } }, |
| 10311 | }, .{ | | |
| 10312 | .required_features = .{ .x87, null, null, null }, | | |
| 10313 | .src_constraints = .{ | | |
| 10314 | .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, | | |
| 10315 | .{ .scalar_float = .{ .of = .xword, .is = .tbyte } }, | | |
| 10316 | }, | | |
| 10317 | .patterns = &.{ | | |
| 10318 | .{ .src = .{ .to_x87, .mem }, .commute = .{ 0, 1 } }, | | |
| 10319 | .{ .src = .{ .mem, .to_x87 } }, | | |
| 10320 | .{ .src = .{ .to_x87, .to_x87 } }, | | |
| 10321 | }, | | |
| 10322 | .extra_temps = .{ | | |
| 10323 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, | | |
| 10324 | .{ .type = .u8, .kind = .{ .reg = .ah } }, | | |
| 10325 | .unused, | | |
| 10326 | .unused, | | |
| 10327 | .unused, | | |
| 10328 | .unused, | | |
| 10329 | .unused, | | |
| 10330 | .unused, | | |
| 10331 | .unused, | | |
| 10332 | }, | | |
| 10333 | .dst_temps = .{.{ .mut_rc = .{ .ref = .src1, .rc = .x87 } }}, | | |
| 10334 | .clobbers = .{ .eflags = true }, | | |
| 10335 | .each = .{ .once = &.{ | | |
| 10336 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, | | |
| 10337 | .{ ._, .f_, .ucom, .tmp0t, ._, ._, ._ }, | | |
| 10338 | .{ ._, .fn_sw, .st, .tmp1w, ._, ._, ._ }, | | |
| 10339 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, | | |
| 10340 | .{ ._, ._p, .j, .@"0f", ._, ._, ._ }, | | |
| 10341 | .{ ._, .f_, .ucom, .src1t, ._, ._, ._ }, | | |
| 10342 | .{ ._, .fn_sw, .st, .tmp1w, ._, ._, ._ }, | | |
| 10343 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, | | |
| 10344 | .{ ._, ._b, .j, .@"1f", ._, ._, ._ }, | | |
| 10345 | .{ .@"0:", .f_p, .st, .tmp0t, ._, ._, ._ }, | | |
| 10346 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, | | |
| 10347 | .{ .@"1:", .f_p, .st, .dst0t, ._, ._, ._ }, | | |
| 10348 | } }, | | |
| 10349 | }, .{ | 10249 | }, .{ |
| 10350 | .required_features = .{ .x87, .cmov, null, null }, | 10250 | .required_features = .{ .x87, .cmov, null, null }, |
| 10351 | .src_constraints = .{ | 10251 | .src_constraints = .{ |
| ... | @@ -10423,7 +10323,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -10423,7 +10323,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 10423 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 10323 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 10424 | } }, | 10324 | } }, |
| 10425 | }, .{ | 10325 | }, .{ |
| 10426 | .required_features = .{ .@"64bit", .x87, null, null }, | 10326 | .required_features = .{ .x87, null, null, null }, |
| 10427 | .src_constraints = .{ | 10327 | .src_constraints = .{ |
| 10428 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, | 10328 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, |
| 10429 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, | 10329 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, |
| ... | @@ -10450,11 +10350,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -10450,11 +10350,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 10450 | .{ ._, .f_, .ld, .memia(.src0t, .tmp0, .add_size), ._, ._, ._ }, | 10350 | .{ ._, .f_, .ld, .memia(.src0t, .tmp0, .add_size), ._, ._, ._ }, |
| 10451 | .{ ._, .f_, .xam, ._, ._, ._, ._ }, | 10351 | .{ ._, .f_, .xam, ._, ._, ._, ._ }, |
| 10452 | .{ ._, .fn_sw, .st, .tmp3w, ._, ._, ._ }, | 10352 | .{ ._, .fn_sw, .st, .tmp3w, ._, ._, ._ }, |
| 10453 | .{ ._, ._, .@"test", .tmp3b, .si(0b0_1_000_100), ._, ._ }, | 10353 | .{ ._, ._, .@"test", .tmp3b, .si(0b1_000_100), ._, ._ }, |
| 10454 | .{ ._, ._z, .j, .@"1f", ._, ._, ._ }, | 10354 | .{ ._, ._z, .j, .@"1f", ._, ._, ._ }, |
| 10455 | .{ ._, .f_, .ucom, .tmp2t, ._, ._, ._ }, | 10355 | .{ ._, .f_, .ucom, .tmp2t, ._, ._, ._ }, |
| 10456 | .{ ._, .fn_sw, .st, .tmp3w, ._, ._, ._ }, | 10356 | .{ ._, .fn_sw, .st, .tmp3w, ._, ._, ._ }, |
| 10457 | .{ ._, ._, .@"test", .tmp3b, .si(0b0_0_000_001), ._, ._ }, | 10357 | .{ ._, ._, .@"test", .tmp3b, .si(0b0_000_001), ._, ._ }, |
| 10458 | .{ ._, ._nz, .j, .@"2f", ._, ._, ._ }, | 10358 | .{ ._, ._nz, .j, .@"2f", ._, ._, ._ }, |
| 10459 | .{ .@"1:", .f_p, .st, .tmp1t, ._, ._, ._ }, | 10359 | .{ .@"1:", .f_p, .st, .tmp1t, ._, ._, ._ }, |
| 10460 | .{ ._, .f_, .ld, .tmp2t, ._, ._, ._ }, | 10360 | .{ ._, .f_, .ld, .tmp2t, ._, ._, ._ }, |
| ... | @@ -10463,47 +10363,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -10463,47 +10363,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 10463 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, | 10363 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 10464 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 10364 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 10465 | } }, | 10365 | } }, |
| 10466 | }, .{ | | |
| 10467 | .required_features = .{ .x87, null, null, null }, | | |
| 10468 | .src_constraints = .{ | | |
| 10469 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, | | |
| 10470 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, | | |
| 10471 | }, | | |
| 10472 | .patterns = &.{ | | |
| 10473 | .{ .src = .{ .to_mem, .to_mem } }, | | |
| 10474 | }, | | |
| 10475 | .extra_temps = .{ | | |
| 10476 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 10477 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, | | |
| 10478 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, | | |
| 10479 | .{ .type = .u8, .kind = .{ .reg = .ah } }, | | |
| 10480 | .unused, | | |
| 10481 | .unused, | | |
| 10482 | .unused, | | |
| 10483 | .unused, | | |
| 10484 | .unused, | | |
| 10485 | }, | | |
| 10486 | .dst_temps = .{.mem}, | | |
| 10487 | .clobbers = .{ .eflags = true }, | | |
| 10488 | .each = .{ .once = &.{ | | |
| 10489 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | | |
| 10490 | .{ .@"0:", .f_, .ld, .memia(.src1t, .tmp0, .add_size), ._, ._, ._ }, | | |
| 10491 | .{ ._, .f_, .ld, .memia(.src0t, .tmp0, .add_size), ._, ._, ._ }, | | |
| 10492 | .{ ._, .f_, .ucom, .tmp1t, ._, ._, ._ }, | | |
| 10493 | .{ ._, .fn_sw, .st, .tmp3w, ._, ._, ._ }, | | |
| 10494 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, | | |
| 10495 | .{ ._, ._p, .j, .@"1f", ._, ._, ._ }, | | |
| 10496 | .{ ._, .f_, .ucom, .tmp2t, ._, ._, ._ }, | | |
| 10497 | .{ ._, .fn_sw, .st, .tmp3w, ._, ._, ._ }, | | |
| 10498 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, | | |
| 10499 | .{ ._, ._b, .j, .@"2f", ._, ._, ._ }, | | |
| 10500 | .{ .@"1:", .f_p, .st, .tmp1t, ._, ._, ._ }, | | |
| 10501 | .{ ._, .f_, .ld, .tmp2t, ._, ._, ._ }, | | |
| 10502 | .{ .@"2:", .f_p, .st, .memia(.dst0t, .tmp0, .add_size), ._, ._, ._ }, | | |
| 10503 | .{ ._, .f_p, .st, .tmp2t, ._, ._, ._ }, | | |
| 10504 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, | | |
| 10505 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 10506 | } }, | | |
| 10507 | }, .{ | 10366 | }, .{ |
| 10508 | .required_features = .{ .sse, null, null, null }, | 10367 | .required_features = .{ .sse, null, null, null }, |
| 10509 | .src_constraints = .{ | 10368 | .src_constraints = .{ |
| ... | @@ -12186,7 +12045,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -12186,7 +12045,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 12186 | .loop => if (use_old) try cg.airLoop(inst) else { | 12045 | .loop => if (use_old) try cg.airLoop(inst) else { |
| 12187 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; | 12046 | const ty_pl = air_datas[@intFromEnum(inst)].ty_pl; |
| 12188 | const extra = cg.air.extraData(Air.Block, ty_pl.payload); | 12047 | const extra = cg.air.extraData(Air.Block, ty_pl.payload); |
| 12189 | cg.scope_generation += 1; | | |
| 12190 | try cg.loops.putNoClobber(cg.gpa, inst, .{ | 12048 | try cg.loops.putNoClobber(cg.gpa, inst, .{ |
| 12191 | .state = try cg.saveState(), | 12049 | .state = try cg.saveState(), |
| 12192 | .target = @intCast(cg.mir_instructions.len), | 12050 | .target = @intCast(cg.mir_instructions.len), |
| ... | @@ -15808,16 +15666,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -15808,16 +15666,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 15808 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 15666 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 15809 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 15667 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 15810 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 15668 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, |
| 15811 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 15669 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, |
| 15812 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, | 15670 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, |
| 15813 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 15671 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 15814 | .{ .@"1:", ._, .add, .tmp0p, .si(32), ._, ._ }, | 15672 | .{ .@"1:", ._, .add, .tmp0p, .si(32), ._, ._ }, |
| 15815 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 15673 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 15816 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 15674 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 15817 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 15675 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 15818 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 15676 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 15819 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 15677 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 15820 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 15821 | }, | 15678 | }, |
| 15822 | .ne => &.{ | 15679 | .ne => &.{ |
| 15823 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | 15680 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| ... | @@ -15833,16 +15690,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -15833,16 +15690,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 15833 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 15690 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 15834 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 15691 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 15835 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 15692 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, |
| 15836 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 15693 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, |
| 15837 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, | 15694 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, |
| 15838 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 15695 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 15839 | .{ .@"1:", ._, .add, .tmp0p, .si(32), ._, ._ }, | 15696 | .{ .@"1:", ._, .add, .tmp0p, .si(32), ._, ._ }, |
| 15840 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 15697 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 15841 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 15698 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 15842 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 15699 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 15843 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 15700 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 15844 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 15701 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 15845 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 15846 | }, | 15702 | }, |
| 15847 | } }, | 15703 | } }, |
| 15848 | }, .{ | 15704 | }, .{ |
| ... | @@ -15971,16 +15827,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -15971,16 +15827,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 15971 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 15827 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 15972 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 15828 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 15973 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 15829 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, |
| 15974 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 15830 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, |
| 15975 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, | 15831 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, |
| 15976 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 15832 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 15977 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, | 15833 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 15978 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 15834 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 15979 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 15835 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 15980 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 15836 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 15981 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 15837 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 15982 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 15838 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 15983 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 15984 | }, | 15839 | }, |
| 15985 | .ne => &.{ | 15840 | .ne => &.{ |
| 15986 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | 15841 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| ... | @@ -15996,16 +15851,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -15996,16 +15851,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 15996 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 15851 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 15997 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 15852 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 15998 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 15853 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, |
| 15999 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 15854 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, |
| 16000 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, | 15855 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, |
| 16001 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 15856 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 16002 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, | 15857 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 16003 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 15858 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 16004 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 15859 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16005 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 15860 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 16006 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 15861 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 16007 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 15862 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 16008 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 16009 | }, | 15863 | }, |
| 16010 | } }, | 15864 | } }, |
| 16011 | }, .{ | 15865 | }, .{ |
| ... | @@ -16042,16 +15896,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -16042,16 +15896,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 16042 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 15896 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16043 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 15897 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 16044 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 15898 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, |
| 16045 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 15899 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, |
| 16046 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, | 15900 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, |
| 16047 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 15901 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 16048 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, | 15902 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 16049 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 15903 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 16050 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 15904 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16051 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 15905 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 16052 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 15906 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 16053 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 15907 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 16054 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 16055 | }, | 15908 | }, |
| 16056 | .ne => &.{ | 15909 | .ne => &.{ |
| 16057 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | 15910 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| ... | @@ -16067,16 +15920,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -16067,16 +15920,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 16067 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 15920 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16068 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 15921 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 16069 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 15922 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, |
| 16070 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 15923 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, |
| 16071 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, | 15924 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, |
| 16072 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 15925 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 16073 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, | 15926 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 16074 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 15927 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 16075 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 15928 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16076 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 15929 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 16077 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 15930 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 16078 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 15931 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 16079 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 16080 | }, | 15932 | }, |
| 16081 | } }, | 15933 | } }, |
| 16082 | }, .{ | 15934 | }, .{ |
| ... | @@ -16205,16 +16057,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -16205,16 +16057,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 16205 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16057 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16206 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 16058 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 16207 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 16059 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, |
| 16208 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 16060 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, |
| 16209 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, | 16061 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, |
| 16210 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 16062 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 16211 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, | 16063 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 16212 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 16064 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 16213 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16065 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16214 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 16066 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 16215 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 16067 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 16216 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 16068 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 16217 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 16218 | }, | 16069 | }, |
| 16219 | .ne => &.{ | 16070 | .ne => &.{ |
| 16220 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | 16071 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| ... | @@ -16230,16 +16081,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -16230,16 +16081,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 16230 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16081 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16231 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 16082 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 16232 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 16083 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, |
| 16233 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 16084 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, |
| 16234 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, | 16085 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, |
| 16235 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 16086 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 16236 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, | 16087 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 16237 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 16088 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 16238 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16089 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16239 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 16090 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 16240 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 16091 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 16241 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 16092 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 16242 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 16243 | }, | 16093 | }, |
| 16244 | } }, | 16094 | } }, |
| 16245 | }, .{ | 16095 | }, .{ |
| ... | @@ -16276,16 +16126,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -16276,16 +16126,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 16276 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16126 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16277 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 16127 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 16278 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 16128 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, |
| 16279 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 16129 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, |
| 16280 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, | 16130 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, |
| 16281 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 16131 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 16282 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, | 16132 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 16283 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 16133 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 16284 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16134 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16285 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 16135 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 16286 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 16136 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 16287 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 16137 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 16288 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 16289 | }, | 16138 | }, |
| 16290 | .ne => &.{ | 16139 | .ne => &.{ |
| 16291 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | 16140 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| ... | @@ -16301,16 +16150,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -16301,16 +16150,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 16301 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16150 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16302 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 16151 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 16303 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 16152 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, |
| 16304 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 16153 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, |
| 16305 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, | 16154 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, |
| 16306 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 16155 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 16307 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, | 16156 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 16308 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 16157 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 16309 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16158 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16310 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 16159 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 16311 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 16160 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 16312 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 16161 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 16313 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 16314 | }, | 16162 | }, |
| 16315 | } }, | 16163 | } }, |
| 16316 | }, .{ | 16164 | }, .{ |
| ... | @@ -16394,16 +16242,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -16394,16 +16242,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 16394 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16242 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16395 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 16243 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 16396 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, | 16244 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, |
| 16397 | .{ ._, ._r, .sh, .tmp4d, .si(3), ._, ._ }, | 16245 | .{ ._, ._r, .sh, .tmp4d, .ui(3), ._, ._ }, |
| 16398 | .{ ._, ._, .mov, .memid(.dst0b, .tmp4, -1), .tmp2b, ._, ._ }, | 16246 | .{ ._, ._, .mov, .memid(.dst0b, .tmp4, -1), .tmp2b, ._, ._ }, |
| 16399 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 16247 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 16400 | .{ .@"1:", ._, .add, .tmp0p, .si(8), ._, ._ }, | 16248 | .{ .@"1:", ._, .add, .tmp0p, .si(8), ._, ._ }, |
| 16401 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 16249 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 16402 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16250 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16403 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 16251 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 16404 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, | 16252 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 16405 | .{ ._, ._r, .sh, .tmp4d, .si(3), ._, ._ }, | 16253 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 16406 | .{ ._, ._, .mov, .memi(.dst0b, .tmp4), .tmp2b, ._, ._ }, | | |
| 16407 | }, | 16254 | }, |
| 16408 | .ne => &.{ | 16255 | .ne => &.{ |
| 16409 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | 16256 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| ... | @@ -16421,16 +16268,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -16421,16 +16268,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 16421 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16268 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16422 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 16269 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 16423 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, | 16270 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, |
| 16424 | .{ ._, ._r, .sh, .tmp4d, .si(3), ._, ._ }, | 16271 | .{ ._, ._r, .sh, .tmp4d, .ui(3), ._, ._ }, |
| 16425 | .{ ._, ._, .mov, .memid(.dst0b, .tmp4, -1), .tmp2b, ._, ._ }, | 16272 | .{ ._, ._, .mov, .memid(.dst0b, .tmp4, -1), .tmp2b, ._, ._ }, |
| 16426 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 16273 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 16427 | .{ .@"1:", ._, .add, .tmp0p, .si(8), ._, ._ }, | 16274 | .{ .@"1:", ._, .add, .tmp0p, .si(8), ._, ._ }, |
| 16428 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 16275 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 16429 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16276 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16430 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 16277 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 16431 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, | 16278 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 16432 | .{ ._, ._r, .sh, .tmp4d, .si(3), ._, ._ }, | 16279 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 16433 | .{ ._, ._, .mov, .memi(.dst0b, .tmp4), .tmp2b, ._, ._ }, | | |
| 16434 | }, | 16280 | }, |
| 16435 | } }, | 16281 | } }, |
| 16436 | }, .{ | 16282 | }, .{ |
| ... | @@ -16470,16 +16316,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -16470,16 +16316,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 16470 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16316 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16471 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 16317 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 16472 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, | 16318 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, |
| 16473 | .{ ._, ._r, .sh, .tmp4d, .si(3), ._, ._ }, | 16319 | .{ ._, ._r, .sh, .tmp4d, .ui(3), ._, ._ }, |
| 16474 | .{ ._, ._, .mov, .memid(.dst0b, .tmp4, -1), .tmp2b, ._, ._ }, | 16320 | .{ ._, ._, .mov, .memid(.dst0b, .tmp4, -1), .tmp2b, ._, ._ }, |
| 16475 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 16321 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 16476 | .{ .@"1:", ._, .add, .tmp0p, .si(8), ._, ._ }, | 16322 | .{ .@"1:", ._, .add, .tmp0p, .si(8), ._, ._ }, |
| 16477 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 16323 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 16478 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16324 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16479 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 16325 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 16480 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, | 16326 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 16481 | .{ ._, ._r, .sh, .tmp4d, .si(3), ._, ._ }, | 16327 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 16482 | .{ ._, ._, .mov, .memi(.dst0b, .tmp4), .tmp2b, ._, ._ }, | | |
| 16483 | }, | 16328 | }, |
| 16484 | .ne => &.{ | 16329 | .ne => &.{ |
| 16485 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | 16330 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| ... | @@ -16498,16 +16343,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -16498,16 +16343,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 16498 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16343 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16499 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 16344 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 16500 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, | 16345 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, |
| 16501 | .{ ._, ._r, .sh, .tmp4d, .si(3), ._, ._ }, | 16346 | .{ ._, ._r, .sh, .tmp4d, .ui(3), ._, ._ }, |
| 16502 | .{ ._, ._, .mov, .memid(.dst0b, .tmp4, -1), .tmp2b, ._, ._ }, | 16347 | .{ ._, ._, .mov, .memid(.dst0b, .tmp4, -1), .tmp2b, ._, ._ }, |
| 16503 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, | 16348 | .{ ._, ._, .xor, .tmp2b, .tmp2b, ._, ._ }, |
| 16504 | .{ .@"1:", ._, .add, .tmp0p, .si(8), ._, ._ }, | 16349 | .{ .@"1:", ._, .add, .tmp0p, .si(8), ._, ._ }, |
| 16505 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 16350 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 16506 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 16351 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 16507 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 16352 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 16508 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, | 16353 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 16509 | .{ ._, ._r, .sh, .tmp4d, .si(3), ._, ._ }, | 16354 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 16510 | .{ ._, ._, .mov, .memi(.dst0b, .tmp4), .tmp2b, ._, ._ }, | | |
| 16511 | }, | 16355 | }, |
| 16512 | } }, | 16356 | } }, |
| 16513 | }, .{ | 16357 | }, .{ |
| ... | @@ -17059,16 +16903,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -17059,16 +16903,15 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 17059 | .{ ._, ._, .@"test", .tmp1d, .sia(-1, .none, .add_ptr_bit_size), ._, ._ }, | 16903 | .{ ._, ._, .@"test", .tmp1d, .sia(-1, .none, .add_ptr_bit_size), ._, ._ }, |
| 17060 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | 16904 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 17061 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 16905 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, |
| 17062 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 16906 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, |
| 17063 | .{ ._, ._, .mov, .memia(.dst0p, .tmp3, .sub_ptr_size), .tmp2p, ._, ._ }, | 16907 | .{ ._, ._, .mov, .memia(.dst0p, .tmp3, .sub_ptr_size), .tmp2p, ._, ._ }, |
| 17064 | .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ }, | 16908 | .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ }, |
| 17065 | .{ .@"1:", ._, .add, .tmp0p, .si(1), ._, ._ }, | 16909 | .{ .@"1:", ._, .add, .tmp0p, .si(1), ._, ._ }, |
| 17066 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 16910 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 17067 | .{ ._, ._, .@"test", .tmp1d, .sia(-1, .none, .add_ptr_bit_size), ._, ._ }, | 16911 | .{ ._, ._, .@"test", .tmp1d, .sia(-1, .none, .add_ptr_bit_size), ._, ._ }, |
| 17068 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 16912 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 17069 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 16913 | .{ ._, ._r, .sh, .tmp1d, .ui(6), ._, ._ }, |
| 17070 | .{ ._, ._r, .sh, .tmp3d, .si(3), ._, ._ }, | 16914 | .{ ._, ._, .mov, .memsi(.dst0p, .@"8", .tmp1), .tmp2p, ._, ._ }, |
| 17071 | .{ ._, ._, .mov, .memi(.dst0p, .tmp3), .tmp2p, ._, ._ }, | | |
| 17072 | } }, | 16915 | } }, |
| 17073 | }, .{ | 16916 | }, .{ |
| 17074 | .required_features = .{ .f16c, null, null, null }, | 16917 | .required_features = .{ .f16c, null, null, null }, |
| ... | @@ -17809,9 +17652,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -17809,9 +17652,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 17809 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, | 17652 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, |
| 17810 | .{ ._, ._, .@"test", .tmp0d, .si(0b111111), ._, ._ }, | 17653 | .{ ._, ._, .@"test", .tmp0d, .si(0b111111), ._, ._ }, |
| 17811 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 17654 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 17812 | .{ ._, ._, .mov, .tmp5d, .tmp0d, ._, ._ }, | 17655 | .{ ._, ._r, .sh, .tmp0d, .ui(6), ._, ._ }, |
| 17813 | .{ ._, ._r, .sh, .tmp5d, .si(9), ._, ._ }, | 17656 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp0), .tmp1q, ._, ._ }, |
| 17814 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp5), .tmp1q, ._, ._ }, | | |
| 17815 | } }, | 17657 | } }, |
| 17816 | }, .{ | 17658 | }, .{ |
| 17817 | .required_features = .{ .@"64bit", .avx, null, null }, | 17659 | .required_features = .{ .@"64bit", .avx, null, null }, |
| ... | @@ -17864,9 +17706,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -17864,9 +17706,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 17864 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, | 17706 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, |
| 17865 | .{ ._, ._, .@"test", .tmp0d, .si(0b111111), ._, ._ }, | 17707 | .{ ._, ._, .@"test", .tmp0d, .si(0b111111), ._, ._ }, |
| 17866 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 17708 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 17867 | .{ ._, ._, .mov, .tmp5d, .tmp0d, ._, ._ }, | 17709 | .{ ._, ._r, .sh, .tmp0d, .ui(6), ._, ._ }, |
| 17868 | .{ ._, ._r, .sh, .tmp5d, .si(9), ._, ._ }, | 17710 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp0), .tmp1q, ._, ._ }, |
| 17869 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp5), .tmp1q, ._, ._ }, | | |
| 17870 | } }, | 17711 | } }, |
| 17871 | }, .{ | 17712 | }, .{ |
| 17872 | .required_features = .{ .@"64bit", .sse2, .slow_incdec, null }, | 17713 | .required_features = .{ .@"64bit", .sse2, .slow_incdec, null }, |
| ... | @@ -17920,9 +17761,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -17920,9 +17761,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 17920 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, | 17761 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, |
| 17921 | .{ ._, ._, .@"test", .tmp0d, .si(0b111111), ._, ._ }, | 17762 | .{ ._, ._, .@"test", .tmp0d, .si(0b111111), ._, ._ }, |
| 17922 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 17763 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 17923 | .{ ._, ._, .mov, .tmp5d, .tmp0d, ._, ._ }, | 17764 | .{ ._, ._r, .sh, .tmp0d, .ui(6), ._, ._ }, |
| 17924 | .{ ._, ._r, .sh, .tmp5d, .si(9), ._, ._ }, | 17765 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp0), .tmp1q, ._, ._ }, |
| 17925 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp5), .tmp1q, ._, ._ }, | | |
| 17926 | } }, | 17766 | } }, |
| 17927 | }, .{ | 17767 | }, .{ |
| 17928 | .required_features = .{ .@"64bit", .sse2, null, null }, | 17768 | .required_features = .{ .@"64bit", .sse2, null, null }, |
| ... | @@ -17976,9 +17816,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -17976,9 +17816,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 17976 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, | 17816 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, |
| 17977 | .{ ._, ._, .@"test", .tmp0d, .si(0b111111), ._, ._ }, | 17817 | .{ ._, ._, .@"test", .tmp0d, .si(0b111111), ._, ._ }, |
| 17978 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 17818 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 17979 | .{ ._, ._, .mov, .tmp5d, .tmp0d, ._, ._ }, | 17819 | .{ ._, ._r, .sh, .tmp0d, .ui(6), ._, ._ }, |
| 17980 | .{ ._, ._r, .sh, .tmp5d, .si(9), ._, ._ }, | 17820 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp0), .tmp1q, ._, ._ }, |
| 17981 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp5), .tmp1q, ._, ._ }, | | |
| 17982 | } }, | 17821 | } }, |
| 17983 | }, .{ | 17822 | }, .{ |
| 17984 | .required_features = .{ .@"64bit", .sse, .slow_incdec, null }, | 17823 | .required_features = .{ .@"64bit", .sse, .slow_incdec, null }, |
| ... | @@ -18034,9 +17873,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -18034,9 +17873,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 18034 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, | 17873 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, |
| 18035 | .{ ._, ._, .@"test", .tmp0d, .si(0b111111), ._, ._ }, | 17874 | .{ ._, ._, .@"test", .tmp0d, .si(0b111111), ._, ._ }, |
| 18036 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 17875 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 18037 | .{ ._, ._, .mov, .tmp5d, .tmp0d, ._, ._ }, | 17876 | .{ ._, ._r, .sh, .tmp0d, .ui(6), ._, ._ }, |
| 18038 | .{ ._, ._r, .sh, .tmp5d, .si(9), ._, ._ }, | 17877 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp0), .tmp1q, ._, ._ }, |
| 18039 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp5), .tmp1q, ._, ._ }, | | |
| 18040 | } }, | 17878 | } }, |
| 18041 | }, .{ | 17879 | }, .{ |
| 18042 | .required_features = .{ .@"64bit", .sse, null, null }, | 17880 | .required_features = .{ .@"64bit", .sse, null, null }, |
| ... | @@ -18092,9 +17930,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -18092,9 +17930,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 18092 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, | 17930 | .{ ._, ._b, .j, .@"0b", ._, ._, ._ }, |
| 18093 | .{ ._, ._, .@"test", .tmp0d, .si(0b111111), ._, ._ }, | 17931 | .{ ._, ._, .@"test", .tmp0d, .si(0b111111), ._, ._ }, |
| 18094 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 17932 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 18095 | .{ ._, ._, .mov, .tmp5d, .tmp0d, ._, ._ }, | 17933 | .{ ._, ._r, .sh, .tmp0d, .ui(6), ._, ._ }, |
| 18096 | .{ ._, ._r, .sh, .tmp5d, .si(9), ._, ._ }, | 17934 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp0), .tmp1q, ._, ._ }, |
| 18097 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp5), .tmp1q, ._, ._ }, | | |
| 18098 | } }, | 17935 | } }, |
| 18099 | }, .{ | 17936 | }, .{ |
| 18100 | .required_features = .{ .avx, .slow_incdec, null, null }, | 17937 | .required_features = .{ .avx, .slow_incdec, null, null }, |
| ... | @@ -18447,9 +18284,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -18447,9 +18284,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 18447 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 18284 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 18448 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 18285 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 18449 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 18286 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 18450 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, | 18287 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 18451 | .{ ._, ._r, .sh, .tmp4d, .ui(3), ._, ._ }, | 18288 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 18452 | .{ ._, ._, .mov, .memi(.dst0b, .tmp4), .tmp2b, ._, ._ }, | | |
| 18453 | } }, | 18289 | } }, |
| 18454 | }, .{ | 18290 | }, .{ |
| 18455 | .required_features = .{ .sse2, null, null, null }, | 18291 | .required_features = .{ .sse2, null, null, null }, |
| ... | @@ -18497,9 +18333,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -18497,9 +18333,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 18497 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 18333 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 18498 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 18334 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 18499 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 18335 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 18500 | .{ ._, ._, .mov, .tmp4d, .tmp1d, ._, ._ }, | 18336 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 18501 | .{ ._, ._r, .sh, .tmp4d, .ui(3), ._, ._ }, | 18337 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 18502 | .{ ._, ._, .mov, .memi(.dst0b, .tmp4), .tmp2b, ._, ._ }, | | |
| 18503 | } }, | 18338 | } }, |
| 18504 | }, .{ | 18339 | }, .{ |
| 18505 | .required_features = .{ .x87, .cmov, .slow_incdec, null }, | 18340 | .required_features = .{ .x87, .cmov, .slow_incdec, null }, |
| ... | @@ -18557,9 +18392,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -18557,9 +18392,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 18557 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 18392 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 18558 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 18393 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 18559 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 18394 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 18560 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 18395 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 18561 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, | 18396 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 18562 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 18563 | } }, | 18397 | } }, |
| 18564 | }, .{ | 18398 | }, .{ |
| 18565 | .required_features = .{ .x87, .cmov, null, null }, | 18399 | .required_features = .{ .x87, .cmov, null, null }, |
| ... | @@ -18617,9 +18451,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -18617,9 +18451,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 18617 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 18451 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 18618 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 18452 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 18619 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 18453 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 18620 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 18454 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 18621 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, | 18455 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 18622 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 18623 | } }, | 18456 | } }, |
| 18624 | }, .{ | 18457 | }, .{ |
| 18625 | .required_features = .{ .x87, null, null, null }, | 18458 | .required_features = .{ .x87, null, null, null }, |
| ... | @@ -18652,8 +18485,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -18652,8 +18485,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 18652 | .{ ._, .f_, .ld, .memia(.src0q, .tmp0, .add_size), ._, ._, ._ }, | 18485 | .{ ._, .f_, .ld, .memia(.src0q, .tmp0, .add_size), ._, ._, ._ }, |
| 18653 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, | 18486 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, |
| 18654 | .{ ._, .fn_sw, .st, .tmp6w, ._, ._, ._ }, | 18487 | .{ ._, .fn_sw, .st, .tmp6w, ._, ._, ._ }, |
| 18655 | .{ ._, ._, .xor, .tmp6b, .si(0b0_1_000_000), ._, ._ }, | 18488 | .{ ._, ._, .xor, .tmp6b, .si(0b1_000_000), ._, ._ }, |
| 18656 | .{ ._, ._, .@"test", .tmp6b, .si(0b0_1_000_100), ._, ._ }, | 18489 | .{ ._, ._, .@"test", .tmp6b, .si(0b1_000_100), ._, ._ }, |
| 18657 | .{ ._, .fromCond(cc), .set, .tmp3b, ._, ._, ._ }, | 18490 | .{ ._, .fromCond(cc), .set, .tmp3b, ._, ._, ._ }, |
| 18658 | .{ ._, ._l, .ro, .tmp3b, .tmp1b, ._, ._ }, | 18491 | .{ ._, ._l, .ro, .tmp3b, .tmp1b, ._, ._ }, |
| 18659 | .{ ._, ._, .@"or", .tmp2b, .tmp3b, ._, ._ }, | 18492 | .{ ._, ._, .@"or", .tmp2b, .tmp3b, ._, ._ }, |
| ... | @@ -18668,72 +18501,70 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -18668,72 +18501,70 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 18668 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 18501 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 18669 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 18502 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 18670 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 18503 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| | 18504 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| | 18505 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| | 18506 | } }, |
| | 18507 | }, .{ |
| | 18508 | .required_features = .{ .x87, .cmov, .slow_incdec, null }, |
| | 18509 | .src_constraints = .{ |
| | 18510 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, |
| | 18511 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, |
| | 18512 | }, |
| | 18513 | .patterns = &.{ |
| | 18514 | .{ .src = .{ .to_mem, .to_mem } }, |
| | 18515 | }, |
| | 18516 | .extra_temps = .{ |
| | 18517 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| | 18518 | .{ .type = .u32, .kind = .{ .reg = .rcx } }, |
| | 18519 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| | 18520 | .{ .type = .u8, .kind = .{ .rc = .general_purpose } }, |
| | 18521 | .{ .type = .u8, .kind = .{ .rc = .general_purpose } }, |
| | 18522 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 18523 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 18524 | .unused, |
| | 18525 | .unused, |
| | 18526 | }, |
| | 18527 | .dst_temps = .{.mem}, |
| | 18528 | .clobbers = .{ .eflags = true }, |
| | 18529 | .each = .{ .once = &.{ |
| | 18530 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| | 18531 | .{ ._, ._, .xor, .tmp1d, .tmp1d, ._, ._ }, |
| | 18532 | .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ }, |
| | 18533 | .{ .@"0:", ._, .xor, .tmp3d, .tmp3d, ._, ._ }, |
| | 18534 | .{ ._, ._, .xor, .tmp4d, .tmp4d, ._, ._ }, |
| | 18535 | .{ ._, .f_, .ld, .memia(.src1t, .tmp0, .add_size), ._, ._, ._ }, |
| | 18536 | .{ ._, .f_, .ld, .memia(.src0t, .tmp0, .add_size), ._, ._, ._ }, |
| | 18537 | .{ ._, .f_p, .ucomi, .tmp5t, .tmp6t, ._, ._ }, |
| | 18538 | .{ ._, .f_p, .st, .tmp6t, ._, ._, ._ }, |
| | 18539 | .{ ._, .fromCond(cc), .set, .tmp3b, ._, ._, ._ }, |
| | 18540 | .{ ._, switch (cc) { |
| | 18541 | else => unreachable, |
| | 18542 | .e => ._np, |
| | 18543 | .ne => ._p, |
| | 18544 | }, .set, .tmp4b, ._, ._, ._ }, |
| | 18545 | .{ ._, ._, switch (cc) { |
| | 18546 | else => unreachable, |
| | 18547 | .e => .@"and", |
| | 18548 | .ne => .@"or", |
| | 18549 | }, .tmp3b, .tmp4b, ._, ._ }, |
| | 18550 | .{ ._, ._l, .ro, .tmp3b, .tmp1b, ._, ._ }, |
| | 18551 | .{ ._, ._, .@"or", .tmp2b, .tmp3b, ._, ._ }, |
| | 18552 | .{ ._, ._, .lea, .tmp1d, .lead(.none, .tmp1, 1), ._, ._ }, |
| | 18553 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| | 18554 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, |
| 18671 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 18555 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, |
| 18672 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, | 18556 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, |
| 18673 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | 18557 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, |
| | 18558 | .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ }, |
| | 18559 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, |
| | 18560 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| | 18561 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| | 18562 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| | 18563 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| | 18564 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 18674 | } }, | 18565 | } }, |
| 18675 | }, .{ | 18566 | }, .{ |
| 18676 | .required_features = .{ .x87, .cmov, .slow_incdec, null }, | 18567 | .required_features = .{ .x87, .cmov, null, null }, |
| 18677 | .src_constraints = .{ | | |
| 18678 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, | | |
| 18679 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, | | |
| 18680 | }, | | |
| 18681 | .patterns = &.{ | | |
| 18682 | .{ .src = .{ .to_mem, .to_mem } }, | | |
| 18683 | }, | | |
| 18684 | .extra_temps = .{ | | |
| 18685 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 18686 | .{ .type = .u32, .kind = .{ .reg = .rcx } }, | | |
| 18687 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | | |
| 18688 | .{ .type = .u8, .kind = .{ .rc = .general_purpose } }, | | |
| 18689 | .{ .type = .u8, .kind = .{ .rc = .general_purpose } }, | | |
| 18690 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, | | |
| 18691 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, | | |
| 18692 | .unused, | | |
| 18693 | .unused, | | |
| 18694 | }, | | |
| 18695 | .dst_temps = .{.mem}, | | |
| 18696 | .clobbers = .{ .eflags = true }, | | |
| 18697 | .each = .{ .once = &.{ | | |
| 18698 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | | |
| 18699 | .{ ._, ._, .xor, .tmp1d, .tmp1d, ._, ._ }, | | |
| 18700 | .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ }, | | |
| 18701 | .{ .@"0:", ._, .xor, .tmp3d, .tmp3d, ._, ._ }, | | |
| 18702 | .{ ._, ._, .xor, .tmp4d, .tmp4d, ._, ._ }, | | |
| 18703 | .{ ._, .f_, .ld, .memia(.src1t, .tmp0, .add_size), ._, ._, ._ }, | | |
| 18704 | .{ ._, .f_, .ld, .memia(.src0t, .tmp0, .add_size), ._, ._, ._ }, | | |
| 18705 | .{ ._, .f_p, .ucomi, .tmp5t, .tmp6t, ._, ._ }, | | |
| 18706 | .{ ._, .f_p, .st, .tmp6t, ._, ._, ._ }, | | |
| 18707 | .{ ._, .fromCond(cc), .set, .tmp3b, ._, ._, ._ }, | | |
| 18708 | .{ ._, switch (cc) { | | |
| 18709 | else => unreachable, | | |
| 18710 | .e => ._np, | | |
| 18711 | .ne => ._p, | | |
| 18712 | }, .set, .tmp4b, ._, ._, ._ }, | | |
| 18713 | .{ ._, ._, switch (cc) { | | |
| 18714 | else => unreachable, | | |
| 18715 | .e => .@"and", | | |
| 18716 | .ne => .@"or", | | |
| 18717 | }, .tmp3b, .tmp4b, ._, ._ }, | | |
| 18718 | .{ ._, ._l, .ro, .tmp3b, .tmp1b, ._, ._ }, | | |
| 18719 | .{ ._, ._, .@"or", .tmp2b, .tmp3b, ._, ._ }, | | |
| 18720 | .{ ._, ._, .lea, .tmp1d, .lead(.none, .tmp1, 1), ._, ._ }, | | |
| 18721 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | | |
| 18722 | .{ ._, ._nz, .j, .@"1f", ._, ._, ._ }, | | |
| 18723 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | | |
| 18724 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, | | |
| 18725 | .{ ._, ._, .mov, .memid(.dst0b, .tmp3, -1), .tmp2b, ._, ._ }, | | |
| 18726 | .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ }, | | |
| 18727 | .{ .@"1:", ._, .add, .tmp0p, .si(16), ._, ._ }, | | |
| 18728 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 18729 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | | |
| 18730 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | | |
| 18731 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | | |
| 18732 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, | | |
| 18733 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 18734 | } }, | | |
| 18735 | }, .{ | | |
| 18736 | .required_features = .{ .x87, .cmov, null, null }, | | |
| 18737 | .src_constraints = .{ | 18568 | .src_constraints = .{ |
| 18738 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, | 18569 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, |
| 18739 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, | 18570 | .{ .multiple_scalar_float = .{ .of = .xword, .is = .tbyte } }, |
| ... | @@ -18788,9 +18619,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -18788,9 +18619,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 18788 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 18619 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 18789 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 18620 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 18790 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 18621 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 18791 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 18622 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 18792 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, | 18623 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 18793 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 18794 | } }, | 18624 | } }, |
| 18795 | }, .{ | 18625 | }, .{ |
| 18796 | .required_features = .{ .x87, null, null, null }, | 18626 | .required_features = .{ .x87, null, null, null }, |
| ... | @@ -18823,8 +18653,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -18823,8 +18653,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 18823 | .{ ._, .f_, .ld, .memia(.src0t, .tmp0, .add_size), ._, ._, ._ }, | 18653 | .{ ._, .f_, .ld, .memia(.src0t, .tmp0, .add_size), ._, ._, ._ }, |
| 18824 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, | 18654 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, |
| 18825 | .{ ._, .fn_sw, .st, .tmp6w, ._, ._, ._ }, | 18655 | .{ ._, .fn_sw, .st, .tmp6w, ._, ._, ._ }, |
| 18826 | .{ ._, ._, .xor, .tmp6b, .si(0b0_1_000_000), ._, ._ }, | 18656 | .{ ._, ._, .xor, .tmp6b, .si(0b1_000_000), ._, ._ }, |
| 18827 | .{ ._, ._, .@"test", .tmp6b, .si(0b0_1_000_100), ._, ._ }, | 18657 | .{ ._, ._, .@"test", .tmp6b, .si(0b1_000_100), ._, ._ }, |
| 18828 | .{ ._, .fromCond(cc), .set, .tmp3b, ._, ._, ._ }, | 18658 | .{ ._, .fromCond(cc), .set, .tmp3b, ._, ._, ._ }, |
| 18829 | .{ ._, ._l, .ro, .tmp3b, .tmp1b, ._, ._ }, | 18659 | .{ ._, ._l, .ro, .tmp3b, .tmp1b, ._, ._ }, |
| 18830 | .{ ._, ._, .@"or", .tmp2b, .tmp3b, ._, ._ }, | 18660 | .{ ._, ._, .@"or", .tmp2b, .tmp3b, ._, ._ }, |
| ... | @@ -18839,9 +18669,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -18839,9 +18669,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 18839 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 18669 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 18840 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, | 18670 | .{ ._, ._, .@"test", .tmp1d, .si(0b111), ._, ._ }, |
| 18841 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 18671 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 18842 | .{ ._, ._, .mov, .tmp3d, .tmp1d, ._, ._ }, | 18672 | .{ ._, ._r, .sh, .tmp1d, .ui(3), ._, ._ }, |
| 18843 | .{ ._, ._r, .sh, .tmp3d, .ui(3), ._, ._ }, | 18673 | .{ ._, ._, .mov, .memi(.dst0b, .tmp1), .tmp2b, ._, ._ }, |
| 18844 | .{ ._, ._, .mov, .memi(.dst0b, .tmp3), .tmp2b, ._, ._ }, | | |
| 18845 | } }, | 18674 | } }, |
| 18846 | }, .{ | 18675 | }, .{ |
| 18847 | .required_features = .{ .avx, .slow_incdec, null, null }, | 18676 | .required_features = .{ .avx, .slow_incdec, null, null }, |
| ... | @@ -19164,9 +18993,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -19164,9 +18993,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 19164 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 18993 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 19165 | .{ ._, ._, .@"test", .tmp1d, .si(0b111111), ._, ._ }, | 18994 | .{ ._, ._, .@"test", .tmp1d, .si(0b111111), ._, ._ }, |
| 19166 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 18995 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 19167 | .{ ._, ._, .mov, .tmp6d, .tmp1d, ._, ._ }, | 18996 | .{ ._, ._r, .sh, .tmp1d, .ui(6), ._, ._ }, |
| 19168 | .{ ._, ._r, .sh, .tmp6d, .si(9), ._, ._ }, | 18997 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp1), .tmp2q, ._, ._ }, |
| 19169 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp6), .tmp2q, ._, ._ }, | | |
| 19170 | } }, | 18998 | } }, |
| 19171 | }, .{ | 18999 | }, .{ |
| 19172 | .required_features = .{ .@"64bit", .avx, null, null }, | 19000 | .required_features = .{ .@"64bit", .avx, null, null }, |
| ... | @@ -19219,9 +19047,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -19219,9 +19047,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 19219 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 19047 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 19220 | .{ ._, ._, .@"test", .tmp1d, .si(0b111111), ._, ._ }, | 19048 | .{ ._, ._, .@"test", .tmp1d, .si(0b111111), ._, ._ }, |
| 19221 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 19049 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 19222 | .{ ._, ._, .mov, .tmp6d, .tmp1d, ._, ._ }, | 19050 | .{ ._, ._r, .sh, .tmp1d, .ui(6), ._, ._ }, |
| 19223 | .{ ._, ._r, .sh, .tmp6d, .si(9), ._, ._ }, | 19051 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp1), .tmp2q, ._, ._ }, |
| 19224 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp6), .tmp2q, ._, ._ }, | | |
| 19225 | } }, | 19052 | } }, |
| 19226 | }, .{ | 19053 | }, .{ |
| 19227 | .required_features = .{ .@"64bit", .sse2, .slow_incdec, null }, | 19054 | .required_features = .{ .@"64bit", .sse2, .slow_incdec, null }, |
| ... | @@ -19274,9 +19101,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -19274,9 +19101,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 19274 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 19101 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 19275 | .{ ._, ._, .@"test", .tmp1d, .si(0b111111), ._, ._ }, | 19102 | .{ ._, ._, .@"test", .tmp1d, .si(0b111111), ._, ._ }, |
| 19276 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 19103 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 19277 | .{ ._, ._, .mov, .tmp6d, .tmp1d, ._, ._ }, | 19104 | .{ ._, ._r, .sh, .tmp1d, .ui(6), ._, ._ }, |
| 19278 | .{ ._, ._r, .sh, .tmp6d, .si(9), ._, ._ }, | 19105 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp1), .tmp2q, ._, ._ }, |
| 19279 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp6), .tmp2q, ._, ._ }, | | |
| 19280 | } }, | 19106 | } }, |
| 19281 | }, .{ | 19107 | }, .{ |
| 19282 | .required_features = .{ .@"64bit", .sse2, null, null }, | 19108 | .required_features = .{ .@"64bit", .sse2, null, null }, |
| ... | @@ -19329,9 +19155,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -19329,9 +19155,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 19329 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 19155 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 19330 | .{ ._, ._, .@"test", .tmp1d, .si(0b111111), ._, ._ }, | 19156 | .{ ._, ._, .@"test", .tmp1d, .si(0b111111), ._, ._ }, |
| 19331 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 19157 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 19332 | .{ ._, ._, .mov, .tmp6d, .tmp1d, ._, ._ }, | 19158 | .{ ._, ._r, .sh, .tmp1d, .ui(6), ._, ._ }, |
| 19333 | .{ ._, ._r, .sh, .tmp6d, .si(9), ._, ._ }, | 19159 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp1), .tmp2q, ._, ._ }, |
| 19334 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp6), .tmp2q, ._, ._ }, | | |
| 19335 | } }, | 19160 | } }, |
| 19336 | }, .{ | 19161 | }, .{ |
| 19337 | .required_features = .{ .@"64bit", .sse, .slow_incdec, null }, | 19162 | .required_features = .{ .@"64bit", .sse, .slow_incdec, null }, |
| ... | @@ -19384,9 +19209,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -19384,9 +19209,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 19384 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 19209 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 19385 | .{ ._, ._, .@"test", .tmp1d, .si(0b111111), ._, ._ }, | 19210 | .{ ._, ._, .@"test", .tmp1d, .si(0b111111), ._, ._ }, |
| 19386 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 19211 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 19387 | .{ ._, ._, .mov, .tmp6d, .tmp1d, ._, ._ }, | 19212 | .{ ._, ._r, .sh, .tmp1d, .ui(6), ._, ._ }, |
| 19388 | .{ ._, ._r, .sh, .tmp6d, .si(9), ._, ._ }, | 19213 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp1), .tmp2q, ._, ._ }, |
| 19389 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp6), .tmp2q, ._, ._ }, | | |
| 19390 | } }, | 19214 | } }, |
| 19391 | }, .{ | 19215 | }, .{ |
| 19392 | .required_features = .{ .@"64bit", .sse, null, null }, | 19216 | .required_features = .{ .@"64bit", .sse, null, null }, |
| ... | @@ -19439,9 +19263,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -19439,9 +19263,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 19439 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | 19263 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, |
| 19440 | .{ ._, ._, .@"test", .tmp1d, .si(0b111111), ._, ._ }, | 19264 | .{ ._, ._, .@"test", .tmp1d, .si(0b111111), ._, ._ }, |
| 19441 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, | 19265 | .{ ._, ._z, .j, .@"0f", ._, ._, ._ }, |
| 19442 | .{ ._, ._, .mov, .tmp6d, .tmp1d, ._, ._ }, | 19266 | .{ ._, ._r, .sh, .tmp1d, .ui(6), ._, ._ }, |
| 19443 | .{ ._, ._r, .sh, .tmp6d, .si(9), ._, ._ }, | 19267 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp1), .tmp2q, ._, ._ }, |
| 19444 | .{ ._, ._, .mov, .memsi(.dst0q, .@"8", .tmp6), .tmp2q, ._, ._ }, | | |
| 19445 | } }, | 19268 | } }, |
| 19446 | } }, | 19269 | } }, |
| 19447 | }) catch |err| switch (err) { | 19270 | }) catch |err| switch (err) { |
| ... | @@ -19651,11 +19474,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -19651,11 +19474,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 19651 | .each = .{ .once = &.{ | 19474 | .each = .{ .once = &.{ |
| 19652 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | 19475 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| 19653 | .{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -8), ._, ._ }, | 19476 | .{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -8), ._, ._ }, |
| 19654 | .{ ._, ._r, .sa, .tmp1q, .si(63), ._, ._ }, | 19477 | .{ ._, ._r, .sa, .tmp1q, .ui(63), ._, ._ }, |
| 19655 | .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ }, | 19478 | .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ }, |
| 19656 | .{ .@"0:", ._, .mov, .tmp3q, .memia(.src0q, .tmp0, .add_size), ._, ._ }, | 19479 | .{ .@"0:", ._, .mov, .tmp3q, .memia(.src0q, .tmp0, .add_size), ._, ._ }, |
| 19657 | .{ ._, ._, .xor, .tmp3q, .tmp1q, ._, ._ }, | 19480 | .{ ._, ._, .xor, .tmp3q, .tmp1q, ._, ._ }, |
| 19658 | .{ ._, ._r, .sh, .tmp2b, .si(1), ._, ._ }, | 19481 | .{ ._, ._r, .sh, .tmp2b, .ui(1), ._, ._ }, |
| 19659 | .{ ._, ._, .sbb, .tmp3q, .tmp1q, ._, ._ }, | 19482 | .{ ._, ._, .sbb, .tmp3q, .tmp1q, ._, ._ }, |
| 19660 | .{ ._, ._c, .set, .tmp2b, ._, ._, ._ }, | 19483 | .{ ._, ._c, .set, .tmp2b, ._, ._, ._ }, |
| 19661 | .{ ._, ._, .mov, .memia(.dst0q, .tmp0, .add_size), .tmp3q, ._, ._ }, | 19484 | .{ ._, ._, .mov, .memia(.dst0q, .tmp0, .add_size), .tmp3q, ._, ._ }, |
| ... | @@ -20413,11 +20236,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -20413,11 +20236,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 20413 | .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ }, | 20236 | .{ ._, ._, .xor, .tmp0d, .tmp0d, ._, ._ }, |
| 20414 | .{ .@"0:", ._, .mov, .tmp1d, .sa(.none, .add_src0_elem_size), ._, ._ }, | 20237 | .{ .@"0:", ._, .mov, .tmp1d, .sa(.none, .add_src0_elem_size), ._, ._ }, |
| 20415 | .{ ._, ._, .mov, .tmp2q, .memiad(.src0q, .tmp0, .add_src0_elem_size, -8), ._, ._ }, | 20238 | .{ ._, ._, .mov, .tmp2q, .memiad(.src0q, .tmp0, .add_src0_elem_size, -8), ._, ._ }, |
| 20416 | .{ ._, ._r, .sa, .tmp2q, .si(63), ._, ._ }, | 20239 | .{ ._, ._r, .sa, .tmp2q, .ui(63), ._, ._ }, |
| 20417 | .{ ._, ._, .xor, .tmp3d, .tmp3d, ._, ._ }, | 20240 | .{ ._, ._, .xor, .tmp3d, .tmp3d, ._, ._ }, |
| 20418 | .{ .@"1:", ._, .mov, .tmp4q, .memi(.src0q, .tmp0), ._, ._ }, | 20241 | .{ .@"1:", ._, .mov, .tmp4q, .memi(.src0q, .tmp0), ._, ._ }, |
| 20419 | .{ ._, ._, .xor, .tmp4q, .tmp2q, ._, ._ }, | 20242 | .{ ._, ._, .xor, .tmp4q, .tmp2q, ._, ._ }, |
| 20420 | .{ ._, ._r, .sh, .tmp3b, .si(1), ._, ._ }, | 20243 | .{ ._, ._r, .sh, .tmp3b, .ui(1), ._, ._ }, |
| 20421 | .{ ._, ._, .sbb, .tmp4q, .tmp2q, ._, ._ }, | 20244 | .{ ._, ._, .sbb, .tmp4q, .tmp2q, ._, ._ }, |
| 20422 | .{ ._, ._c, .set, .tmp3b, ._, ._, ._ }, | 20245 | .{ ._, ._c, .set, .tmp3b, ._, ._, ._ }, |
| 20423 | .{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp4q, ._, ._ }, | 20246 | .{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp4q, ._, ._ }, |
| ... | @@ -20932,185 +20755,405 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -20932,185 +20755,405 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 20932 | .cmp_gte_optimized, | 20755 | .cmp_gte_optimized, |
| 20933 | .cmp_gt, | 20756 | .cmp_gt, |
| 20934 | .cmp_gt_optimized, | 20757 | .cmp_gt_optimized, |
| 20935 | => |air_tag| if (use_old) try cg.airCmp(inst, switch (air_tag) { | 20758 | => |air_tag| if (use_old) try cg.airCmp(inst, air_tag.toCmpOp().?) else { |
| 20936 | else => unreachable, | | |
| 20937 | .cmp_lt, .cmp_lt_optimized => .lt, | | |
| 20938 | .cmp_lte, .cmp_lte_optimized => .lte, | | |
| 20939 | .cmp_gte, .cmp_gte_optimized => .gte, | | |
| 20940 | .cmp_gt, .cmp_gt_optimized => .gt, | | |
| 20941 | }) else fallback: { | | |
| 20942 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; | 20759 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; |
| 20943 | const scalar_ty = cg.typeOf(bin_op.lhs).scalarType(zcu); | 20760 | const cmp_op = air_tag.toCmpOp().?; |
| 20944 | if (scalar_ty.isRuntimeFloat()) break :fallback try cg.airCmp(inst, switch (air_tag) { | | |
| 20945 | else => unreachable, | | |
| 20946 | .cmp_lt, .cmp_lt_optimized => .lt, | | |
| 20947 | .cmp_lte, .cmp_lte_optimized => .lte, | | |
| 20948 | .cmp_gte, .cmp_gte_optimized => .gte, | | |
| 20949 | .cmp_gt, .cmp_gt_optimized => .gt, | | |
| 20950 | }); | | |
| 20951 | const signedness = if (scalar_ty.isAbiInt(zcu)) | | |
| 20952 | scalar_ty.intInfo(zcu).signedness | | |
| 20953 | else | | |
| 20954 | .unsigned; | | |
| 20955 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); | 20761 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| 20956 | var res: [1]Temp = undefined; | 20762 | var res: [1]Temp = undefined; |
| 20957 | cg.select(&res, &.{.bool}, &ops, switch (@as(Condition, switch (signedness) { | 20763 | (if (cg.floatBits(cg.typeOf(bin_op.lhs))) |_| err: { |
| 20958 | .signed => switch (air_tag) { | 20764 | switch (cmp_op) { |
| 20959 | else => unreachable, | 20765 | else => unreachable, |
| 20960 | .cmp_lt, .cmp_lt_optimized => .l, | 20766 | .lt, .lte => {}, |
| 20961 | .cmp_lte, .cmp_lte_optimized => .le, | 20767 | .gt, .gte => std.mem.swap(Temp, &ops[0], &ops[1]), |
| 20962 | .cmp_gte, .cmp_gte_optimized => .ge, | 20768 | } |
| 20963 | .cmp_gt, .cmp_gt_optimized => .g, | 20769 | break :err cg.select(&res, &.{.bool}, &ops, switch (switch (cmp_op) { |
| 20964 | }, | | |
| 20965 | .unsigned => switch (air_tag) { | | |
| 20966 | else => unreachable, | 20770 | else => unreachable, |
| 20967 | .cmp_lt, .cmp_lt_optimized => .b, | 20771 | .lt, .gt => true, |
| 20968 | .cmp_lte, .cmp_lte_optimized => .be, | 20772 | .lte, .gte => false, |
| 20969 | .cmp_gte, .cmp_gte_optimized => .ae, | 20773 | }) { |
| 20970 | .cmp_gt, .cmp_gt_optimized => .a, | 20774 | inline false, true => |strict| comptime &.{ .{ |
| 20971 | }, | 20775 | .required_features = .{ .f16c, null, null, null }, |
| 20972 | })) { | 20776 | .src_constraints = .{ .{ .float = .word }, .{ .float = .word } }, |
| 20973 | else => unreachable, | 20777 | .patterns = &.{ |
| 20974 | inline .l, .le, .ge, .g, .b, .be, .ae, .a => |cc| comptime &.{ .{ | 20778 | .{ .src = .{ .to_sse, .to_sse }, .commute = .{ 0, 1 } }, |
| 20975 | .src_constraints = .{ .{ .int = .byte }, .{ .int = .byte } }, | 20779 | }, |
| 20976 | .patterns = &.{ | 20780 | .extra_temps = .{ |
| 20977 | .{ .src = .{ .imm8, .mem }, .commute = .{ 0, 1 } }, | 20781 | .{ .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .sse } } }, |
| 20978 | .{ .src = .{ .imm8, .to_gpr }, .commute = .{ 0, 1 } }, | 20782 | .{ .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .sse } } }, |
| 20979 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, | 20783 | .unused, |
| 20980 | }, | 20784 | .unused, |
| 20981 | .dst_temps = .{.{ .cc = cc.commute() }}, | 20785 | .unused, |
| 20982 | .clobbers = .{ .eflags = true }, | 20786 | .unused, |
| 20983 | .each = .{ .once = &.{ | 20787 | .unused, |
| 20984 | .{ ._, ._, .cmp, .src0b, .src1b, ._, ._ }, | 20788 | .unused, |
| 20985 | } }, | 20789 | .unused, |
| 20986 | }, .{ | 20790 | }, |
| 20987 | .src_constraints = .{ .{ .int = .byte }, .{ .int = .byte } }, | 20791 | .dst_temps = .{.{ .cc = switch (strict) { |
| 20988 | .patterns = &.{ | 20792 | true => .a, |
| 20989 | .{ .src = .{ .mem, .imm8 } }, | 20793 | false => .ae, |
| 20990 | .{ .src = .{ .to_gpr, .imm8 } }, | 20794 | } }}, |
| 20991 | .{ .src = .{ .to_gpr, .mem } }, | 20795 | .clobbers = .{ .eflags = true }, |
| 20992 | .{ .src = .{ .to_gpr, .to_gpr } }, | 20796 | .each = .{ .once = &.{ |
| 20993 | }, | 20797 | .{ ._, .v_ps, .cvtph2, .tmp0x, .src0q, ._, ._ }, |
| 20994 | .dst_temps = .{.{ .cc = cc }}, | 20798 | .{ ._, .v_ps, .cvtph2, .tmp1x, .src1q, ._, ._ }, |
| 20995 | .clobbers = .{ .eflags = true }, | 20799 | .{ ._, .v_ss, .ucomi, .tmp0x, .tmp1d, ._, ._ }, |
| 20996 | .each = .{ .once = &.{ | 20800 | } }, |
| 20997 | .{ ._, ._, .cmp, .src0b, .src1b, ._, ._ }, | 20801 | }, .{ |
| 20998 | } }, | 20802 | .required_features = .{ .sse, null, null, null }, |
| 20999 | }, .{ | 20803 | .src_constraints = .{ .{ .float = .word }, .{ .float = .word } }, |
| 21000 | .src_constraints = .{ .{ .int = .word }, .{ .int = .word } }, | 20804 | .patterns = &.{ |
| 21001 | .patterns = &.{ | 20805 | .{ .src = .{ .{ .to_reg = .xmm0 }, .{ .to_reg = .xmm1 } } }, |
| 21002 | .{ .src = .{ .imm16, .mem }, .commute = .{ 0, 1 } }, | 20806 | }, |
| 21003 | .{ .src = .{ .imm16, .to_gpr }, .commute = .{ 0, 1 } }, | 20807 | .call_frame = .{ .alignment = .@"16" }, |
| 21004 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, | 20808 | .extra_temps = .{ |
| 21005 | }, | 20809 | .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } }, |
| 21006 | .dst_temps = .{.{ .cc = cc.commute() }}, | 20810 | .{ .type = .i32, .kind = .{ .reg = .eax } }, |
| 21007 | .clobbers = .{ .eflags = true }, | 20811 | .unused, |
| 21008 | .each = .{ .once = &.{ | 20812 | .unused, |
| 21009 | .{ ._, ._, .cmp, .src0w, .src1w, ._, ._ }, | 20813 | .unused, |
| 21010 | } }, | 20814 | .unused, |
| 21011 | }, .{ | 20815 | .unused, |
| 21012 | .src_constraints = .{ .{ .int = .word }, .{ .int = .word } }, | 20816 | .unused, |
| 21013 | .patterns = &.{ | 20817 | .unused, |
| 21014 | .{ .src = .{ .mem, .imm16 } }, | 20818 | }, |
| 21015 | .{ .src = .{ .to_gpr, .imm16 } }, | 20819 | .dst_temps = .{.{ .cc = switch (strict) { |
| 21016 | .{ .src = .{ .to_gpr, .mem } }, | 20820 | true => .l, |
| 21017 | .{ .src = .{ .to_gpr, .to_gpr } }, | 20821 | false => .le, |
| 21018 | }, | 20822 | } }}, |
| 21019 | .dst_temps = .{.{ .cc = cc }}, | 20823 | .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, |
| 21020 | .clobbers = .{ .eflags = true }, | 20824 | .each = .{ .once = &.{ |
| 21021 | .each = .{ .once = &.{ | 20825 | .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, |
| 21022 | .{ ._, ._, .cmp, .src0w, .src1w, ._, ._ }, | 20826 | .{ ._, ._, .@"test", .tmp1d, .tmp1d, ._, ._ }, |
| 21023 | } }, | 20827 | } }, |
| 21024 | }, .{ | 20828 | }, .{ |
| 21025 | .src_constraints = .{ .{ .int = .dword }, .{ .int = .dword } }, | 20829 | .required_features = .{ .avx, null, null, null }, |
| 21026 | .patterns = &.{ | 20830 | .src_constraints = .{ .{ .float = .dword }, .{ .float = .dword } }, |
| 21027 | .{ .src = .{ .imm32, .mem }, .commute = .{ 0, 1 } }, | 20831 | .patterns = &.{ |
| 21028 | .{ .src = .{ .imm32, .to_gpr }, .commute = .{ 0, 1 } }, | 20832 | .{ .src = .{ .mem, .to_sse }, .commute = .{ 0, 1 } }, |
| 21029 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, | 20833 | .{ .src = .{ .to_sse, .to_sse }, .commute = .{ 0, 1 } }, |
| 21030 | }, | 20834 | }, |
| 21031 | .dst_temps = .{.{ .cc = cc.commute() }}, | 20835 | .dst_temps = .{.{ .cc = switch (strict) { |
| 21032 | .clobbers = .{ .eflags = true }, | 20836 | true => .a, |
| 21033 | .each = .{ .once = &.{ | 20837 | false => .ae, |
| 21034 | .{ ._, ._, .cmp, .src0d, .src1d, ._, ._ }, | 20838 | } }}, |
| 21035 | } }, | 20839 | .clobbers = .{ .eflags = true }, |
| 21036 | }, .{ | 20840 | .each = .{ .once = &.{ |
| 21037 | .src_constraints = .{ .{ .int = .dword }, .{ .int = .dword } }, | 20841 | .{ ._, .v_ss, .ucomi, .src0x, .src1d, ._, ._ }, |
| 21038 | .patterns = &.{ | 20842 | } }, |
| 21039 | .{ .src = .{ .mem, .imm32 } }, | 20843 | }, .{ |
| 21040 | .{ .src = .{ .to_gpr, .imm32 } }, | 20844 | .required_features = .{ .sse, null, null, null }, |
| 21041 | .{ .src = .{ .to_gpr, .mem } }, | 20845 | .src_constraints = .{ .{ .float = .dword }, .{ .float = .dword } }, |
| 21042 | .{ .src = .{ .to_gpr, .to_gpr } }, | 20846 | .patterns = &.{ |
| 21043 | }, | 20847 | .{ .src = .{ .mem, .to_sse }, .commute = .{ 0, 1 } }, |
| 21044 | .dst_temps = .{.{ .cc = cc }}, | 20848 | .{ .src = .{ .to_sse, .to_sse }, .commute = .{ 0, 1 } }, |
| 21045 | .clobbers = .{ .eflags = true }, | 20849 | }, |
| 21046 | .each = .{ .once = &.{ | 20850 | .dst_temps = .{.{ .cc = switch (strict) { |
| 21047 | .{ ._, ._, .cmp, .src0d, .src1d, ._, ._ }, | 20851 | true => .a, |
| 21048 | } }, | 20852 | false => .ae, |
| 21049 | }, .{ | 20853 | } }}, |
| 21050 | .required_features = .{ .@"64bit", null, null, null }, | 20854 | .clobbers = .{ .eflags = true }, |
| 21051 | .src_constraints = .{ .{ .int = .qword }, .{ .int = .qword } }, | 20855 | .each = .{ .once = &.{ |
| 21052 | .patterns = &.{ | 20856 | .{ ._, ._ss, .ucomi, .src0x, .src1d, ._, ._ }, |
| 21053 | .{ .src = .{ .simm32, .mem }, .commute = .{ 0, 1 } }, | 20857 | } }, |
| 21054 | .{ .src = .{ .simm32, .to_gpr }, .commute = .{ 0, 1 } }, | 20858 | }, .{ |
| 21055 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, | 20859 | .required_features = .{ .avx, null, null, null }, |
| 21056 | }, | 20860 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, |
| 21057 | .dst_temps = .{.{ .cc = cc.commute() }}, | 20861 | .patterns = &.{ |
| 21058 | .clobbers = .{ .eflags = true }, | 20862 | .{ .src = .{ .mem, .to_sse }, .commute = .{ 0, 1 } }, |
| 21059 | .each = .{ .once = &.{ | 20863 | .{ .src = .{ .to_sse, .to_sse }, .commute = .{ 0, 1 } }, |
| 21060 | .{ ._, ._, .cmp, .src0q, .src1q, ._, ._ }, | 20864 | }, |
| 21061 | } }, | 20865 | .dst_temps = .{.{ .cc = switch (strict) { |
| 21062 | }, .{ | 20866 | true => .a, |
| 21063 | .required_features = .{ .@"64bit", null, null, null }, | 20867 | false => .ae, |
| 21064 | .src_constraints = .{ .{ .int = .qword }, .{ .int = .qword } }, | 20868 | } }}, |
| 21065 | .patterns = &.{ | 20869 | .clobbers = .{ .eflags = true }, |
| 21066 | .{ .src = .{ .mem, .simm32 } }, | 20870 | .each = .{ .once = &.{ |
| 21067 | .{ .src = .{ .to_gpr, .simm32 } }, | 20871 | .{ ._, .v_sd, .ucomi, .src0x, .src1q, ._, ._ }, |
| 21068 | .{ .src = .{ .to_gpr, .mem } }, | 20872 | } }, |
| 21069 | .{ .src = .{ .to_gpr, .to_gpr } }, | 20873 | }, .{ |
| 21070 | }, | 20874 | .required_features = .{ .sse2, null, null, null }, |
| 21071 | .dst_temps = .{.{ .cc = cc }}, | 20875 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, |
| 21072 | .clobbers = .{ .eflags = true }, | 20876 | .patterns = &.{ |
| 21073 | .each = .{ .once = &.{ | 20877 | .{ .src = .{ .mem, .to_sse }, .commute = .{ 0, 1 } }, |
| 21074 | .{ ._, ._, .cmp, .src0q, .src1q, ._, ._ }, | 20878 | .{ .src = .{ .to_sse, .to_sse }, .commute = .{ 0, 1 } }, |
| 21075 | } }, | 20879 | }, |
| 21076 | }, .{ | 20880 | .dst_temps = .{.{ .cc = switch (strict) { |
| 21077 | .src_constraints = .{ .any_int, .any_int }, | 20881 | true => .a, |
| 21078 | .patterns = &.{ | 20882 | false => .ae, |
| 21079 | .{ .src = .{ .to_mem, .to_mem }, .commute = switch (cc) { | 20883 | } }}, |
| 21080 | else => unreachable, | 20884 | .clobbers = .{ .eflags = true }, |
| 21081 | .l, .ge, .b, .ae => .{ 0, 0 }, | 20885 | .each = .{ .once = &.{ |
| 21082 | .le, .g, .be, .a => .{ 0, 1 }, | 20886 | .{ ._, ._sd, .ucomi, .src0x, .src1q, ._, ._ }, |
| | 20887 | } }, |
| | 20888 | }, .{ |
| | 20889 | .required_features = .{ .x87, .cmov, null, null }, |
| | 20890 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, |
| | 20891 | .patterns = &.{ |
| | 20892 | .{ .src = .{ .to_mem, .to_mem }, .commute = .{ 0, 1 } }, |
| | 20893 | }, |
| | 20894 | .extra_temps = .{ |
| | 20895 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 20896 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 20897 | .unused, |
| | 20898 | .unused, |
| | 20899 | .unused, |
| | 20900 | .unused, |
| | 20901 | .unused, |
| | 20902 | .unused, |
| | 20903 | .unused, |
| | 20904 | }, |
| | 20905 | .dst_temps = .{.{ .cc = switch (strict) { |
| | 20906 | true => .a, |
| | 20907 | false => .ae, |
| | 20908 | } }}, |
| | 20909 | .clobbers = .{ .eflags = true }, |
| | 20910 | .each = .{ .once = &.{ |
| | 20911 | .{ ._, .f_, .ld, .src1q, ._, ._, ._ }, |
| | 20912 | .{ ._, .f_, .ld, .src0q, ._, ._, ._ }, |
| | 20913 | .{ ._, .f_p, .ucomi, .tmp0t, .tmp1t, ._, ._ }, |
| | 20914 | .{ ._, .f_p, .st, .tmp1t, ._, ._, ._ }, |
| | 20915 | } }, |
| | 20916 | }, .{ |
| | 20917 | .required_features = .{ .sahf, .x87, null, null }, |
| | 20918 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, |
| | 20919 | .patterns = &.{ |
| | 20920 | .{ .src = .{ .to_mem, .to_mem }, .commute = .{ 0, 1 } }, |
| | 20921 | }, |
| | 20922 | .extra_temps = .{ |
| | 20923 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 20924 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 20925 | .{ .type = .u8, .kind = .{ .reg = .ah } }, |
| | 20926 | .unused, |
| | 20927 | .unused, |
| | 20928 | .unused, |
| | 20929 | .unused, |
| | 20930 | .unused, |
| | 20931 | .unused, |
| | 20932 | }, |
| | 20933 | .dst_temps = .{.{ .cc = switch (strict) { |
| | 20934 | true => .a, |
| | 20935 | false => .ae, |
| | 20936 | } }}, |
| | 20937 | .clobbers = .{ .eflags = true }, |
| | 20938 | .each = .{ .once = &.{ |
| | 20939 | .{ ._, .f_, .ld, .src1q, ._, ._, ._ }, |
| | 20940 | .{ ._, .f_, .ld, .src0q, ._, ._, ._ }, |
| | 20941 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, |
| | 20942 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 20943 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, |
| | 20944 | } }, |
| | 20945 | }, .{ |
| | 20946 | .required_features = .{ .x87, null, null, null }, |
| | 20947 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, |
| | 20948 | .patterns = &.{ |
| | 20949 | .{ .src = .{ .to_mem, .to_mem }, .commute = .{ 0, 1 } }, |
| | 20950 | }, |
| | 20951 | .extra_temps = .{ |
| | 20952 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 20953 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 20954 | .{ .type = .u8, .kind = .{ .reg = .ah } }, |
| | 20955 | .unused, |
| | 20956 | .unused, |
| | 20957 | .unused, |
| | 20958 | .unused, |
| | 20959 | .unused, |
| | 20960 | .unused, |
| | 20961 | }, |
| | 20962 | .dst_temps = .{.{ .cc = switch (strict) { |
| | 20963 | true => .z, |
| | 20964 | false => .nc, |
| | 20965 | } }}, |
| | 20966 | .clobbers = .{ .eflags = true }, |
| | 20967 | .each = .{ .once = &.{ |
| | 20968 | .{ ._, .f_, .ld, .src1q, ._, ._, ._ }, |
| | 20969 | .{ ._, .f_, .ld, .src0q, ._, ._, ._ }, |
| | 20970 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, |
| | 20971 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 20972 | switch (strict) { |
| | 20973 | true => .{ ._, ._, .@"test", .tmp2b, .si(0b1_000_001), ._, ._ }, |
| | 20974 | false => .{ ._, ._r, .sh, .tmp2b, .ui(1), ._, ._ }, |
| | 20975 | }, |
| | 20976 | } }, |
| | 20977 | }, .{ |
| | 20978 | .required_features = .{ .x87, .cmov, null, null }, |
| | 20979 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, |
| | 20980 | .patterns = &.{ |
| | 20981 | .{ .src = .{ .to_x87, .mem }, .commute = .{ 0, 1 } }, |
| | 20982 | .{ .src = .{ .to_x87, .to_x87 }, .commute = .{ 0, 1 } }, |
| | 20983 | }, |
| | 20984 | .extra_temps = .{ |
| | 20985 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 20986 | .unused, |
| | 20987 | .unused, |
| | 20988 | .unused, |
| | 20989 | .unused, |
| | 20990 | .unused, |
| | 20991 | .unused, |
| | 20992 | .unused, |
| | 20993 | .unused, |
| | 20994 | }, |
| | 20995 | .dst_temps = .{.{ .cc = switch (strict) { |
| | 20996 | true => .a, |
| | 20997 | false => .ae, |
| | 20998 | } }}, |
| | 20999 | .clobbers = .{ .eflags = true }, |
| | 21000 | .each = .{ .once = &.{ |
| | 21001 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| | 21002 | .{ ._, .f_p, .ucomi, .tmp0t, .src1t, ._, ._ }, |
| | 21003 | } }, |
| | 21004 | }, .{ |
| | 21005 | .required_features = .{ .sahf, .x87, null, null }, |
| | 21006 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, |
| | 21007 | .patterns = &.{ |
| | 21008 | .{ .src = .{ .mem, .mem }, .commute = .{ 0, 1 } }, |
| | 21009 | }, |
| | 21010 | .extra_temps = .{ |
| | 21011 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 21012 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 21013 | .{ .type = .u8, .kind = .{ .reg = .ah } }, |
| | 21014 | .unused, |
| | 21015 | .unused, |
| | 21016 | .unused, |
| | 21017 | .unused, |
| | 21018 | .unused, |
| | 21019 | .unused, |
| | 21020 | }, |
| | 21021 | .dst_temps = .{.{ .cc = switch (strict) { |
| | 21022 | true => .a, |
| | 21023 | false => .ae, |
| | 21024 | } }}, |
| | 21025 | .clobbers = .{ .eflags = true }, |
| | 21026 | .each = .{ .once = &.{ |
| | 21027 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, |
| | 21028 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| | 21029 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, |
| | 21030 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21031 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, |
| | 21032 | } }, |
| | 21033 | }, .{ |
| | 21034 | .required_features = .{ .sahf, .x87, null, null }, |
| | 21035 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, |
| | 21036 | .patterns = &.{ |
| | 21037 | .{ .src = .{ .to_x87, .mem }, .commute = .{ 0, 1 } }, |
| | 21038 | .{ .src = .{ .to_x87, .to_x87 }, .commute = .{ 0, 1 } }, |
| | 21039 | }, |
| | 21040 | .extra_temps = .{ |
| | 21041 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 21042 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 21043 | .{ .type = .u8, .kind = .{ .reg = .ah } }, |
| | 21044 | .unused, |
| | 21045 | .unused, |
| | 21046 | .unused, |
| | 21047 | .unused, |
| | 21048 | .unused, |
| | 21049 | .unused, |
| | 21050 | }, |
| | 21051 | .dst_temps = .{.{ .cc = switch (strict) { |
| | 21052 | true => .a, |
| | 21053 | false => .ae, |
| | 21054 | } }}, |
| | 21055 | .clobbers = .{ .eflags = true }, |
| | 21056 | .each = .{ .once = &.{ |
| | 21057 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| | 21058 | .{ ._, .f_p, .ucom, .src1t, ._, ._, ._ }, |
| | 21059 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21060 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, |
| | 21061 | } }, |
| | 21062 | }, .{ |
| | 21063 | .required_features = .{ .x87, null, null, null }, |
| | 21064 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, |
| | 21065 | .patterns = &.{ |
| | 21066 | .{ .src = .{ .mem, .mem }, .commute = .{ 0, 1 } }, |
| | 21067 | }, |
| | 21068 | .extra_temps = .{ |
| | 21069 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 21070 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 21071 | .{ .type = .u8, .kind = .{ .reg = .ah } }, |
| | 21072 | .unused, |
| | 21073 | .unused, |
| | 21074 | .unused, |
| | 21075 | .unused, |
| | 21076 | .unused, |
| | 21077 | .unused, |
| | 21078 | }, |
| | 21079 | .dst_temps = .{.{ .cc = switch (strict) { |
| | 21080 | true => .z, |
| | 21081 | false => .nc, |
| | 21082 | } }}, |
| | 21083 | .clobbers = .{ .eflags = true }, |
| | 21084 | .each = .{ .once = &.{ |
| | 21085 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, |
| | 21086 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| | 21087 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, |
| | 21088 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21089 | switch (strict) { |
| | 21090 | true => .{ ._, ._, .@"test", .tmp2b, .si(0b1_000_001), ._, ._ }, |
| | 21091 | false => .{ ._, ._r, .sh, .tmp2b, .ui(1), ._, ._ }, |
| | 21092 | }, |
| | 21093 | } }, |
| | 21094 | }, .{ |
| | 21095 | .required_features = .{ .x87, null, null, null }, |
| | 21096 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, |
| | 21097 | .patterns = &.{ |
| | 21098 | .{ .src = .{ .to_x87, .mem }, .commute = .{ 0, 1 } }, |
| | 21099 | .{ .src = .{ .to_x87, .to_x87 }, .commute = .{ 0, 1 } }, |
| | 21100 | }, |
| | 21101 | .extra_temps = .{ |
| | 21102 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 21103 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 21104 | .{ .type = .u8, .kind = .{ .reg = .ah } }, |
| | 21105 | .unused, |
| | 21106 | .unused, |
| | 21107 | .unused, |
| | 21108 | .unused, |
| | 21109 | .unused, |
| | 21110 | .unused, |
| | 21111 | }, |
| | 21112 | .dst_temps = .{.{ .cc = switch (strict) { |
| | 21113 | true => .z, |
| | 21114 | false => .nc, |
| | 21115 | } }}, |
| | 21116 | .clobbers = .{ .eflags = true }, |
| | 21117 | .each = .{ .once = &.{ |
| | 21118 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| | 21119 | .{ ._, .f_p, .ucom, .src1t, ._, ._, ._ }, |
| | 21120 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21121 | switch (strict) { |
| | 21122 | true => .{ ._, ._, .@"test", .tmp2b, .si(0b1_000_001), ._, ._ }, |
| | 21123 | false => .{ ._, ._r, .sh, .tmp2b, .ui(1), ._, ._ }, |
| | 21124 | }, |
| | 21125 | } }, |
| | 21126 | }, .{ |
| | 21127 | .required_features = .{ .sse, null, null, null }, |
| | 21128 | .src_constraints = .{ .{ .float = .xword }, .{ .float = .xword } }, |
| | 21129 | .patterns = &.{ |
| | 21130 | .{ .src = .{ .{ .to_reg = .xmm0 }, .{ .to_reg = .xmm1 } } }, |
| | 21131 | }, |
| | 21132 | .call_frame = .{ .alignment = .@"16" }, |
| | 21133 | .extra_temps = .{ |
| | 21134 | .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } }, |
| | 21135 | .{ .type = .i32, .kind = .{ .reg = .eax } }, |
| | 21136 | .unused, |
| | 21137 | .unused, |
| | 21138 | .unused, |
| | 21139 | .unused, |
| | 21140 | .unused, |
| | 21141 | .unused, |
| | 21142 | .unused, |
| | 21143 | }, |
| | 21144 | .dst_temps = .{.{ .cc = switch (strict) { |
| | 21145 | true => .l, |
| | 21146 | false => .le, |
| | 21147 | } }}, |
| | 21148 | .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, |
| | 21149 | .each = .{ .once = &.{ |
| | 21150 | .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, |
| | 21151 | .{ ._, ._, .@"test", .tmp1d, .tmp1d, ._, ._ }, |
| 21083 | } }, | 21152 | } }, |
| 21084 | }, | | |
| 21085 | .extra_temps = .{ | | |
| 21086 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 21087 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | | |
| 21088 | .unused, | | |
| 21089 | .unused, | | |
| 21090 | .unused, | | |
| 21091 | .unused, | | |
| 21092 | .unused, | | |
| 21093 | .unused, | | |
| 21094 | .unused, | | |
| 21095 | }, | | |
| 21096 | .dst_temps = .{.{ .rc = .general_purpose }}, | | |
| 21097 | .clobbers = .{ .eflags = true }, | | |
| 21098 | .each = .{ .once = &.{ | | |
| 21099 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | | |
| 21100 | .{ ._, ._, .xor, .tmp1b, .tmp1b, ._, ._ }, | | |
| 21101 | .{ .@"0:", ._r, .sh, .tmp1b, .si(1), ._, ._ }, | | |
| 21102 | .{ ._, ._, .mov, .tmp1p, .memia(.src0p, .tmp0, .add_size), ._, ._ }, | | |
| 21103 | .{ ._, ._, .sbb, .tmp1p, .memia(.src1p, .tmp0, .add_size), ._, ._ }, | | |
| 21104 | .{ ._, ._c, .set, .tmp1b, ._, ._, ._ }, | | |
| 21105 | .{ ._, .fromCond(switch (cc) { | | |
| 21106 | else => unreachable, | | |
| 21107 | .l, .ge, .b, .ae => cc, | | |
| 21108 | .le, .g, .be, .a => cc.commute(), | | |
| 21109 | }), .set, .dst0b, ._, ._, ._ }, | | |
| 21110 | .{ ._, ._, .add, .tmp0p, .sa(.tmp1, .add_size), ._, ._ }, | | |
| 21111 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 21112 | } }, | 21153 | } }, |
| 21113 | } }, | 21154 | }); |
| | 21155 | } else err: { |
| | 21156 | res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err; |
| 21114 | }) catch |err| switch (err) { | 21157 | }) catch |err| switch (err) { |
| 21115 | error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{ | 21158 | error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{ |
| 21116 | @tagName(air_tag), | 21159 | @tagName(air_tag), |
| ... | @@ -21126,994 +21169,502 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -21126,994 +21169,502 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 21126 | .cmp_eq_optimized, | 21169 | .cmp_eq_optimized, |
| 21127 | .cmp_neq, | 21170 | .cmp_neq, |
| 21128 | .cmp_neq_optimized, | 21171 | .cmp_neq_optimized, |
| 21129 | => |air_tag| if (use_old) try cg.airCmp(inst, switch (air_tag) { | 21172 | => |air_tag| if (use_old) try cg.airCmp(inst, air_tag.toCmpOp().?) else { |
| 21130 | else => unreachable, | | |
| 21131 | .cmp_eq, .cmp_eq_optimized => .eq, | | |
| 21132 | .cmp_neq, .cmp_neq_optimized => .neq, | | |
| 21133 | }) else fallback: { | | |
| 21134 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; | 21173 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; |
| 21135 | const scalar_ty = cg.typeOf(bin_op.lhs).scalarType(zcu); | 21174 | const cmp_op = air_tag.toCmpOp().?; |
| 21136 | if (cg.intInfo(scalar_ty) == null and cg.floatBits(scalar_ty) == null) break :fallback try cg.airCmp(inst, switch (air_tag) { | | |
| 21137 | else => unreachable, | | |
| 21138 | .cmp_eq, .cmp_eq_optimized => .eq, | | |
| 21139 | .cmp_neq, .cmp_neq_optimized => .neq, | | |
| 21140 | }); | | |
| 21141 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); | 21175 | var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }); |
| | 21176 | const ty = cg.typeOf(bin_op.lhs); |
| 21142 | var res: [1]Temp = undefined; | 21177 | var res: [1]Temp = undefined; |
| 21143 | cg.select(&res, &.{.bool}, &ops, switch (@as(Condition, switch (air_tag) { | 21178 | const OptInfo = struct { |
| 21144 | else => unreachable, | 21179 | deaths: [2]Air.Inst.Index, |
| 21145 | .cmp_eq, .cmp_eq_optimized => .e, | 21180 | res: [1]Temp, |
| 21146 | .cmp_neq, .cmp_neq_optimized => .ne, | 21181 | state: State, |
| 21147 | })) { | 21182 | reloc: Mir.Inst.Index, |
| 21148 | else => unreachable, | 21183 | }; |
| 21149 | inline .e, .ne => |cc| comptime &.{ .{ | 21184 | var opt_info: ?OptInfo = null; |
| 21150 | .src_constraints = .{ .{ .int = .byte }, .{ .int = .byte } }, | 21185 | (err: switch (@as(enum { float, int }, if (cg.floatBits(ty)) |_| |
| 21151 | .patterns = &.{ | 21186 | .float |
| 21152 | .{ .src = .{ .mem, .imm8 } }, | 21187 | else if (cg.intInfo(ty)) |_| |
| 21153 | .{ .src = .{ .imm8, .mem }, .commute = .{ 0, 1 } }, | 21188 | .int |
| 21154 | .{ .src = .{ .to_gpr, .imm8 } }, | 21189 | else category: { |
| 21155 | .{ .src = .{ .imm8, .to_gpr }, .commute = .{ 0, 1 } }, | 21190 | const child_ty = ty.optionalChild(zcu); |
| 21156 | .{ .src = .{ .to_gpr, .mem } }, | 21191 | const has_value_off: u31 = @intCast(child_ty.abiSize(zcu)); |
| 21157 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, | 21192 | var has_values: [2]Temp = undefined; |
| 21158 | .{ .src = .{ .to_gpr, .to_gpr } }, | 21193 | opt_info = @as(OptInfo, undefined); |
| 21159 | }, | 21194 | for (&has_values, &ops, &opt_info.?.deaths) |*has_value, *op, *death| { |
| 21160 | .dst_temps = .{.{ .cc = cc }}, | 21195 | has_value.* = try op.read(.bool, .{ .disp = has_value_off }, cg); |
| 21161 | .clobbers = .{ .eflags = true }, | 21196 | const child = try op.read(child_ty, .{}, cg); |
| 21162 | .each = .{ .once = &.{ | 21197 | try op.die(cg); |
| 21163 | .{ ._, ._, .cmp, .src0b, .src1b, ._, ._ }, | 21198 | op.* = child; |
| 21164 | } }, | 21199 | death.* = child.index; |
| 21165 | }, .{ | 21200 | } |
| 21166 | .src_constraints = .{ .{ .int = .word }, .{ .int = .word } }, | 21201 | cg.select( |
| 21167 | .patterns = &.{ | 21202 | &opt_info.?.res, |
| 21168 | .{ .src = .{ .mem, .imm16 } }, | 21203 | &.{.bool}, |
| 21169 | .{ .src = .{ .imm16, .mem }, .commute = .{ 0, 1 } }, | 21204 | &has_values, |
| 21170 | .{ .src = .{ .to_gpr, .imm16 } }, | 21205 | switch (Condition.fromCompareOperatorUnsigned(cmp_op)) { |
| 21171 | .{ .src = .{ .imm16, .to_gpr }, .commute = .{ 0, 1 } }, | 21206 | else => unreachable, |
| 21172 | .{ .src = .{ .to_gpr, .mem } }, | 21207 | inline .e, .ne => |cc| comptime &.{.{ |
| 21173 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, | 21208 | .src_constraints = .{ .{ .size = .byte }, .{ .size = .byte } }, |
| 21174 | .{ .src = .{ .to_gpr, .to_gpr } }, | 21209 | .patterns = &.{ |
| 21175 | }, | 21210 | .{ .src = .{ .mem, .imm8 } }, |
| 21176 | .dst_temps = .{.{ .cc = cc }}, | 21211 | .{ .src = .{ .imm8, .mem }, .commute = .{ 0, 1 } }, |
| 21177 | .clobbers = .{ .eflags = true }, | 21212 | .{ .src = .{ .to_gpr, .imm8 } }, |
| 21178 | .each = .{ .once = &.{ | 21213 | .{ .src = .{ .imm8, .to_gpr }, .commute = .{ 0, 1 } }, |
| 21179 | .{ ._, ._, .cmp, .src0w, .src1w, ._, ._ }, | 21214 | .{ .src = .{ .mem, .to_gpr } }, |
| 21180 | } }, | 21215 | .{ .src = .{ .to_gpr, .mem }, .commute = .{ 0, 1 } }, |
| 21181 | }, .{ | 21216 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| 21182 | .src_constraints = .{ .{ .int = .dword }, .{ .int = .dword } }, | 21217 | }, |
| 21183 | .patterns = &.{ | 21218 | .dst_temps = .{.{ .rc = .general_purpose }}, |
| 21184 | .{ .src = .{ .mem, .imm32 } }, | 21219 | .clobbers = .{ .eflags = true }, |
| 21185 | .{ .src = .{ .imm32, .mem }, .commute = .{ 0, 1 } }, | 21220 | .each = .{ .once = &.{ |
| 21186 | .{ .src = .{ .to_gpr, .imm32 } }, | 21221 | .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ }, |
| 21187 | .{ .src = .{ .imm32, .to_gpr }, .commute = .{ 0, 1 } }, | 21222 | .{ ._, ._, .cmp, .src0b, .src1b, ._, ._ }, |
| 21188 | .{ .src = .{ .to_gpr, .mem } }, | 21223 | .{ ._, .fromCond(cc), .set, .dst0b, ._, ._, ._ }, |
| 21189 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, | 21224 | .{ ._, ._, .@"test", .src0b, .src1b, ._, ._ }, |
| 21190 | .{ .src = .{ .to_gpr, .to_gpr } }, | 21225 | } }, |
| 21191 | }, | 21226 | }}, |
| 21192 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21193 | .clobbers = .{ .eflags = true }, | | |
| 21194 | .each = .{ .once = &.{ | | |
| 21195 | .{ ._, ._, .cmp, .src0d, .src1d, ._, ._ }, | | |
| 21196 | } }, | | |
| 21197 | }, .{ | | |
| 21198 | .required_features = .{ .@"64bit", null, null, null }, | | |
| 21199 | .src_constraints = .{ .{ .int = .qword }, .{ .int = .qword } }, | | |
| 21200 | .patterns = &.{ | | |
| 21201 | .{ .src = .{ .mem, .simm32 } }, | | |
| 21202 | .{ .src = .{ .simm32, .mem }, .commute = .{ 0, 1 } }, | | |
| 21203 | .{ .src = .{ .to_gpr, .simm32 } }, | | |
| 21204 | .{ .src = .{ .simm32, .to_gpr }, .commute = .{ 0, 1 } }, | | |
| 21205 | .{ .src = .{ .to_gpr, .mem } }, | | |
| 21206 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, | | |
| 21207 | .{ .src = .{ .to_gpr, .to_gpr } }, | | |
| 21208 | }, | | |
| 21209 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21210 | .clobbers = .{ .eflags = true }, | | |
| 21211 | .each = .{ .once = &.{ | | |
| 21212 | .{ ._, ._, .cmp, .src0q, .src1q, ._, ._ }, | | |
| 21213 | } }, | | |
| 21214 | }, .{ | | |
| 21215 | .required_features = .{ .sse, .mmx, null, null }, | | |
| 21216 | .src_constraints = .{ .{ .int = .qword }, .{ .int = .qword } }, | | |
| 21217 | .patterns = &.{ | | |
| 21218 | .{ .src = .{ .to_mut_mm, .mem } }, | | |
| 21219 | .{ .src = .{ .mem, .to_mut_mm }, .commute = .{ 0, 1 } }, | | |
| 21220 | .{ .src = .{ .to_mut_mm, .to_mm } }, | | |
| 21221 | }, | | |
| 21222 | .extra_temps = .{ | | |
| 21223 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | | |
| 21224 | .{ .kind = .{ .rc = .mmx } }, | | |
| 21225 | .unused, | | |
| 21226 | .unused, | | |
| 21227 | .unused, | | |
| 21228 | .unused, | | |
| 21229 | .unused, | | |
| 21230 | .unused, | | |
| 21231 | .unused, | | |
| 21232 | }, | | |
| 21233 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21234 | .clobbers = .{ .eflags = true }, | | |
| 21235 | .each = .{ .once = &.{ | | |
| 21236 | .{ ._, .p_, .xor, .tmp1q, .tmp1q, ._, ._ }, | | |
| 21237 | .{ ._, .p_, .xor, .src0q, .src1q, ._, ._ }, | | |
| 21238 | .{ ._, .p_b, .cmpeq, .tmp1q, .src0q, ._, ._ }, | | |
| 21239 | .{ ._, .p_b, .movmsk, .tmp0d, .tmp1q, ._, ._ }, | | |
| 21240 | .{ ._, ._, .xor, .tmp0d, .si(0xff), ._, ._ }, | | |
| 21241 | } }, | | |
| 21242 | }, .{ | | |
| 21243 | .required_features = .{ .avx, null, null, null }, | | |
| 21244 | .src_constraints = .{ .{ .int = .xword }, .{ .int = .xword } }, | | |
| 21245 | .patterns = &.{ | | |
| 21246 | .{ .src = .{ .to_xmm, .mem } }, | | |
| 21247 | .{ .src = .{ .mem, .to_xmm }, .commute = .{ 0, 1 } }, | | |
| 21248 | .{ .src = .{ .to_xmm, .to_xmm } }, | | |
| 21249 | }, | | |
| 21250 | .extra_temps = .{ | | |
| 21251 | .{ .kind = .{ .rc = .sse } }, | | |
| 21252 | .unused, | | |
| 21253 | .unused, | | |
| 21254 | .unused, | | |
| 21255 | .unused, | | |
| 21256 | .unused, | | |
| 21257 | .unused, | | |
| 21258 | .unused, | | |
| 21259 | .unused, | | |
| 21260 | }, | | |
| 21261 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21262 | .clobbers = .{ .eflags = true }, | | |
| 21263 | .each = .{ .once = &.{ | | |
| 21264 | .{ ._, .vp_, .xor, .tmp0x, .src0x, .src1x, ._ }, | | |
| 21265 | .{ ._, .vp_, .@"test", .tmp0x, .tmp0x, ._, ._ }, | | |
| 21266 | } }, | | |
| 21267 | }, .{ | | |
| 21268 | .required_features = .{ .sse4_1, null, null, null }, | | |
| 21269 | .src_constraints = .{ .{ .int = .xword }, .{ .int = .xword } }, | | |
| 21270 | .patterns = &.{ | | |
| 21271 | .{ .src = .{ .to_mut_xmm, .mem } }, | | |
| 21272 | .{ .src = .{ .mem, .to_mut_xmm }, .commute = .{ 0, 1 } }, | | |
| 21273 | .{ .src = .{ .to_mut_xmm, .to_xmm } }, | | |
| 21274 | }, | | |
| 21275 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21276 | .clobbers = .{ .eflags = true }, | | |
| 21277 | .each = .{ .once = &.{ | | |
| 21278 | .{ ._, .p_, .xor, .src0x, .src1x, ._, ._ }, | | |
| 21279 | .{ ._, .p_, .@"test", .src0x, .src0x, ._, ._ }, | | |
| 21280 | } }, | | |
| 21281 | }, .{ | | |
| 21282 | .required_features = .{ .sse2, null, null, null }, | | |
| 21283 | .src_constraints = .{ .{ .int = .xword }, .{ .int = .xword } }, | | |
| 21284 | .patterns = &.{ | | |
| 21285 | .{ .src = .{ .to_mut_xmm, .mem } }, | | |
| 21286 | .{ .src = .{ .mem, .to_mut_xmm }, .commute = .{ 0, 1 } }, | | |
| 21287 | .{ .src = .{ .to_mut_xmm, .to_xmm } }, | | |
| 21288 | }, | | |
| 21289 | .extra_temps = .{ | | |
| 21290 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, | | |
| 21291 | .{ .kind = .{ .rc = .sse } }, | | |
| 21292 | .unused, | | |
| 21293 | .unused, | | |
| 21294 | .unused, | | |
| 21295 | .unused, | | |
| 21296 | .unused, | | |
| 21297 | .unused, | | |
| 21298 | .unused, | | |
| 21299 | }, | | |
| 21300 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21301 | .clobbers = .{ .eflags = true }, | | |
| 21302 | .each = .{ .once = &.{ | | |
| 21303 | .{ ._, .p_, .xor, .tmp1x, .tmp1x, ._, ._ }, | | |
| 21304 | .{ ._, .p_, .xor, .src0x, .src1x, ._, ._ }, | | |
| 21305 | .{ ._, .p_b, .cmpeq, .tmp1x, .src0x, ._, ._ }, | | |
| 21306 | .{ ._, .p_b, .movmsk, .tmp0d, .tmp1x, ._, ._ }, | | |
| 21307 | .{ ._, ._, .xor, .tmp0d, .si(0xffff), ._, ._ }, | | |
| 21308 | } }, | | |
| 21309 | }, .{ | | |
| 21310 | .required_features = .{ .avx2, null, null, null }, | | |
| 21311 | .src_constraints = .{ .{ .int = .yword }, .{ .int = .yword } }, | | |
| 21312 | .patterns = &.{ | | |
| 21313 | .{ .src = .{ .to_ymm, .mem } }, | | |
| 21314 | .{ .src = .{ .mem, .to_ymm }, .commute = .{ 0, 1 } }, | | |
| 21315 | .{ .src = .{ .to_ymm, .to_ymm } }, | | |
| 21316 | }, | 21227 | }, |
| 21317 | .extra_temps = .{ | 21228 | ) catch |err| switch (err) { |
| 21318 | .{ .kind = .{ .rc = .sse } }, | 21229 | error.SelectFailed => unreachable, |
| 21319 | .unused, | 21230 | else => |e| return e, |
| 21320 | .unused, | 21231 | }; |
| 21321 | .unused, | 21232 | for (has_values) |has_value| for (opt_info.?.res) |opt_res| { |
| 21322 | .unused, | 21233 | if (has_value.index == opt_res.index) break; |
| 21323 | .unused, | 21234 | } else try has_value.die(cg); |
| 21324 | .unused, | 21235 | opt_info.?.state = cg.initRetroactiveState(); |
| 21325 | .unused, | 21236 | opt_info.?.state.next_temp_index = cg.next_temp_index; |
| 21326 | .unused, | 21237 | var state = try cg.saveState(); |
| 21327 | }, | 21238 | state.next_temp_index = cg.next_temp_index; |
| 21328 | .dst_temps = .{.{ .cc = cc }}, | 21239 | for (ops) |op| try op.die(cg); |
| 21329 | .clobbers = .{ .eflags = true }, | 21240 | try cg.saveRetroactiveState(&opt_info.?.state); |
| 21330 | .each = .{ .once = &.{ | 21241 | opt_info.?.reloc = try cg.asmJccReloc(.z, undefined); |
| 21331 | .{ ._, .vp_, .xor, .tmp0y, .src0y, .src1y, ._ }, | 21242 | try cg.restoreState(state, &.{}, .{ |
| 21332 | .{ ._, .vp_, .@"test", .tmp0y, .tmp0y, ._, ._ }, | 21243 | .emit_instructions = false, |
| 21333 | } }, | 21244 | .update_tracking = true, |
| 21334 | }, .{ | 21245 | .resurrect = true, |
| 21335 | .required_features = .{ .avx, null, null, null }, | 21246 | .close_scope = true, |
| 21336 | .src_constraints = .{ .{ .int = .yword }, .{ .int = .yword } }, | 21247 | }); |
| 21337 | .patterns = &.{ | 21248 | break :category if (cg.floatBits(child_ty)) |_| .float else .int; |
| 21338 | .{ .src = .{ .to_ymm, .mem } }, | 21249 | })) { |
| 21339 | .{ .src = .{ .mem, .to_ymm }, .commute = .{ 0, 1 } }, | 21250 | .float => { |
| 21340 | .{ .src = .{ .to_ymm, .to_ymm } }, | 21251 | cg.select(&res, &.{.bool}, &ops, switch (switch (air_tag) { |
| 21341 | }, | | |
| 21342 | .extra_temps = .{ | | |
| 21343 | .{ .kind = .{ .rc = .sse } }, | | |
| 21344 | .unused, | | |
| 21345 | .unused, | | |
| 21346 | .unused, | | |
| 21347 | .unused, | | |
| 21348 | .unused, | | |
| 21349 | .unused, | | |
| 21350 | .unused, | | |
| 21351 | .unused, | | |
| 21352 | }, | | |
| 21353 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21354 | .clobbers = .{ .eflags = true }, | | |
| 21355 | .each = .{ .once = &.{ | | |
| 21356 | .{ ._, .v_pd, .xor, .tmp0y, .src0y, .src1y, ._ }, | | |
| 21357 | .{ ._, .vp_, .@"test", .tmp0y, .tmp0y, ._, ._ }, | | |
| 21358 | } }, | | |
| 21359 | }, .{ | | |
| 21360 | .required_features = .{ .avx2, null, null, null }, | | |
| 21361 | .src_constraints = .{ | | |
| 21362 | .{ .remainder_int = .{ .of = .yword, .is = .xword } }, | | |
| 21363 | .{ .remainder_int = .{ .of = .yword, .is = .xword } }, | | |
| 21364 | }, | | |
| 21365 | .patterns = &.{ | | |
| 21366 | .{ .src = .{ .to_mem, .to_mem } }, | | |
| 21367 | }, | | |
| 21368 | .extra_temps = .{ | | |
| 21369 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 21370 | .{ .kind = .{ .rc = .sse } }, | | |
| 21371 | .{ .kind = .{ .rc = .sse } }, | | |
| 21372 | .unused, | | |
| 21373 | .unused, | | |
| 21374 | .unused, | | |
| 21375 | .unused, | | |
| 21376 | .unused, | | |
| 21377 | .unused, | | |
| 21378 | }, | | |
| 21379 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21380 | .clobbers = .{ .eflags = true }, | | |
| 21381 | .each = .{ .once = &.{ | | |
| 21382 | .{ ._, ._, .mov, .tmp0p, .sia(16, .src0, .sub_size), ._, ._ }, | | |
| 21383 | .{ ._, .vp_, .xor, .tmp1y, .tmp1y, .tmp1y, ._ }, | | |
| 21384 | .{ .@"0:", .v_dqu, .mov, .tmp2y, .memiad(.src0y, .tmp0, .add_size, -16), ._, ._ }, | | |
| 21385 | .{ ._, .vp_, .xor, .tmp2y, .tmp2y, .memiad(.src1y, .tmp0, .add_size, -16), ._ }, | | |
| 21386 | .{ ._, .vp_, .@"or", .tmp1y, .tmp1y, .tmp2y, ._ }, | | |
| 21387 | .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ }, | | |
| 21388 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 21389 | .{ ._, .v_dqa, .mov, .tmp2x, .memad(.src0x, .add_size, -16), ._, ._ }, | | |
| 21390 | .{ ._, .vp_, .xor, .tmp2x, .tmp2x, .memad(.src1x, .add_size, -16), ._ }, | | |
| 21391 | .{ ._, .vp_, .@"or", .tmp1y, .tmp1y, .tmp2y, ._ }, | | |
| 21392 | .{ ._, .vp_, .@"test", .tmp1y, .tmp1y, ._, ._ }, | | |
| 21393 | } }, | | |
| 21394 | }, .{ | | |
| 21395 | .required_features = .{ .avx2, null, null, null }, | | |
| 21396 | .src_constraints = .{ | | |
| 21397 | .{ .remainder_int = .{ .of = .yword, .is = .yword } }, | | |
| 21398 | .{ .remainder_int = .{ .of = .yword, .is = .yword } }, | | |
| 21399 | }, | | |
| 21400 | .patterns = &.{ | | |
| 21401 | .{ .src = .{ .to_mem, .to_mem } }, | | |
| 21402 | }, | | |
| 21403 | .extra_temps = .{ | | |
| 21404 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 21405 | .{ .kind = .{ .rc = .sse } }, | | |
| 21406 | .{ .kind = .{ .rc = .sse } }, | | |
| 21407 | .unused, | | |
| 21408 | .unused, | | |
| 21409 | .unused, | | |
| 21410 | .unused, | | |
| 21411 | .unused, | | |
| 21412 | .unused, | | |
| 21413 | }, | | |
| 21414 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21415 | .clobbers = .{ .eflags = true }, | | |
| 21416 | .each = .{ .once = &.{ | | |
| 21417 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | | |
| 21418 | .{ ._, .vp_, .xor, .tmp1y, .tmp1y, .tmp1y, ._ }, | | |
| 21419 | .{ .@"0:", .v_dqu, .mov, .tmp2y, .memia(.src0y, .tmp0, .add_size), ._, ._ }, | | |
| 21420 | .{ ._, .vp_, .xor, .tmp2y, .tmp2y, .memia(.src1y, .tmp0, .add_size), ._ }, | | |
| 21421 | .{ ._, .vp_, .@"or", .tmp1y, .tmp1y, .tmp2y, ._ }, | | |
| 21422 | .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ }, | | |
| 21423 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 21424 | .{ ._, .vp_, .@"test", .tmp1y, .tmp1y, ._, ._ }, | | |
| 21425 | } }, | | |
| 21426 | }, .{ | | |
| 21427 | .required_features = .{ .avx, null, null, null }, | | |
| 21428 | .src_constraints = .{ | | |
| 21429 | .{ .remainder_int = .{ .of = .yword, .is = .xword } }, | | |
| 21430 | .{ .remainder_int = .{ .of = .yword, .is = .xword } }, | | |
| 21431 | }, | | |
| 21432 | .patterns = &.{ | | |
| 21433 | .{ .src = .{ .to_mem, .to_mem } }, | | |
| 21434 | }, | | |
| 21435 | .extra_temps = .{ | | |
| 21436 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 21437 | .{ .kind = .{ .rc = .sse } }, | | |
| 21438 | .{ .kind = .{ .rc = .sse } }, | | |
| 21439 | .unused, | | |
| 21440 | .unused, | | |
| 21441 | .unused, | | |
| 21442 | .unused, | | |
| 21443 | .unused, | | |
| 21444 | .unused, | | |
| 21445 | }, | | |
| 21446 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21447 | .clobbers = .{ .eflags = true }, | | |
| 21448 | .each = .{ .once = &.{ | | |
| 21449 | .{ ._, ._, .mov, .tmp0p, .sia(16, .src0, .sub_size), ._, ._ }, | | |
| 21450 | .{ ._, .v_pd, .xor, .tmp1y, .tmp1y, .tmp1y, ._ }, | | |
| 21451 | .{ .@"0:", .v_pd, .movu, .tmp2y, .memiad(.src0y, .tmp0, .add_size, -16), ._, ._ }, | | |
| 21452 | .{ ._, .v_pd, .xor, .tmp2y, .tmp2y, .memiad(.src1y, .tmp0, .add_size, -16), ._ }, | | |
| 21453 | .{ ._, .v_pd, .@"or", .tmp1y, .tmp1y, .tmp2y, ._ }, | | |
| 21454 | .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ }, | | |
| 21455 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 21456 | .{ ._, .v_pd, .mova, .tmp2x, .memad(.src0x, .add_size, -16), ._, ._ }, | | |
| 21457 | .{ ._, .v_pd, .xor, .tmp2x, .tmp2x, .memad(.src1x, .add_size, -16), ._ }, | | |
| 21458 | .{ ._, .v_pd, .@"or", .tmp1y, .tmp1y, .tmp2y, ._ }, | | |
| 21459 | .{ ._, .vp_, .@"test", .tmp1y, .tmp1y, ._, ._ }, | | |
| 21460 | } }, | | |
| 21461 | }, .{ | | |
| 21462 | .required_features = .{ .avx, null, null, null }, | | |
| 21463 | .src_constraints = .{ | | |
| 21464 | .{ .remainder_int = .{ .of = .yword, .is = .yword } }, | | |
| 21465 | .{ .remainder_int = .{ .of = .yword, .is = .yword } }, | | |
| 21466 | }, | | |
| 21467 | .patterns = &.{ | | |
| 21468 | .{ .src = .{ .to_mem, .to_mem } }, | | |
| 21469 | }, | | |
| 21470 | .extra_temps = .{ | | |
| 21471 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 21472 | .{ .kind = .{ .rc = .sse } }, | | |
| 21473 | .{ .kind = .{ .rc = .sse } }, | | |
| 21474 | .unused, | | |
| 21475 | .unused, | | |
| 21476 | .unused, | | |
| 21477 | .unused, | | |
| 21478 | .unused, | | |
| 21479 | .unused, | | |
| 21480 | }, | | |
| 21481 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21482 | .clobbers = .{ .eflags = true }, | | |
| 21483 | .each = .{ .once = &.{ | | |
| 21484 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | | |
| 21485 | .{ ._, .v_pd, .xor, .tmp1y, .tmp1y, .tmp1y, ._ }, | | |
| 21486 | .{ .@"0:", .v_pd, .movu, .tmp2y, .memia(.src0y, .tmp0, .add_size), ._, ._ }, | | |
| 21487 | .{ ._, .v_pd, .xor, .tmp2y, .tmp2y, .memia(.src1y, .tmp0, .add_size), ._ }, | | |
| 21488 | .{ ._, .v_pd, .@"or", .tmp1y, .tmp1y, .tmp2y, ._ }, | | |
| 21489 | .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ }, | | |
| 21490 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 21491 | .{ ._, .vp_, .@"test", .tmp1y, .tmp1y, ._, ._ }, | | |
| 21492 | } }, | | |
| 21493 | }, .{ | | |
| 21494 | .required_features = .{ .avx, null, null, null }, | | |
| 21495 | .src_constraints = .{ | | |
| 21496 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, | | |
| 21497 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, | | |
| 21498 | }, | | |
| 21499 | .patterns = &.{ | | |
| 21500 | .{ .src = .{ .to_mem, .to_mem } }, | | |
| 21501 | }, | | |
| 21502 | .extra_temps = .{ | | |
| 21503 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 21504 | .{ .kind = .{ .rc = .sse } }, | | |
| 21505 | .{ .kind = .{ .rc = .sse } }, | | |
| 21506 | .unused, | | |
| 21507 | .unused, | | |
| 21508 | .unused, | | |
| 21509 | .unused, | | |
| 21510 | .unused, | | |
| 21511 | .unused, | | |
| 21512 | }, | | |
| 21513 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21514 | .clobbers = .{ .eflags = true }, | | |
| 21515 | .each = .{ .once = &.{ | | |
| 21516 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | | |
| 21517 | .{ ._, .vp_, .xor, .tmp1x, .tmp1x, .tmp1x, ._ }, | | |
| 21518 | .{ .@"0:", .v_dqu, .mov, .tmp2x, .memia(.src0x, .tmp0, .add_size), ._, ._ }, | | |
| 21519 | .{ ._, .vp_, .xor, .tmp2x, .tmp2x, .memia(.src1x, .tmp0, .add_size), ._ }, | | |
| 21520 | .{ ._, .vp_, .@"or", .tmp1x, .tmp1x, .tmp2x, ._ }, | | |
| 21521 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, | | |
| 21522 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 21523 | .{ ._, .vp_, .@"test", .tmp1x, .tmp1x, ._, ._ }, | | |
| 21524 | } }, | | |
| 21525 | }, .{ | | |
| 21526 | .required_features = .{ .sse4_1, null, null, null }, | | |
| 21527 | .src_constraints = .{ | | |
| 21528 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, | | |
| 21529 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, | | |
| 21530 | }, | | |
| 21531 | .patterns = &.{ | | |
| 21532 | .{ .src = .{ .to_mem, .to_mem } }, | | |
| 21533 | }, | | |
| 21534 | .extra_temps = .{ | | |
| 21535 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 21536 | .{ .kind = .{ .rc = .sse } }, | | |
| 21537 | .{ .kind = .{ .rc = .sse } }, | | |
| 21538 | .unused, | | |
| 21539 | .unused, | | |
| 21540 | .unused, | | |
| 21541 | .unused, | | |
| 21542 | .unused, | | |
| 21543 | .unused, | | |
| 21544 | }, | | |
| 21545 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21546 | .clobbers = .{ .eflags = true }, | | |
| 21547 | .each = .{ .once = &.{ | | |
| 21548 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | | |
| 21549 | .{ ._, .p_, .xor, .tmp1x, .tmp1x, ._, ._ }, | | |
| 21550 | .{ .@"0:", ._dqu, .mov, .tmp2x, .memia(.src0x, .tmp0, .add_size), ._, ._ }, | | |
| 21551 | .{ ._, .p_, .xor, .tmp2x, .memia(.src1x, .tmp0, .add_size), ._, ._ }, | | |
| 21552 | .{ ._, .p_, .@"or", .tmp1x, .tmp2x, ._, ._ }, | | |
| 21553 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, | | |
| 21554 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 21555 | .{ ._, .p_, .@"test", .tmp1x, .tmp1x, ._, ._ }, | | |
| 21556 | } }, | | |
| 21557 | }, .{ | | |
| 21558 | .required_features = .{ .sse2, null, null, null }, | | |
| 21559 | .src_constraints = .{ | | |
| 21560 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, | | |
| 21561 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, | | |
| 21562 | }, | | |
| 21563 | .patterns = &.{ | | |
| 21564 | .{ .src = .{ .to_mem, .to_mem } }, | | |
| 21565 | }, | | |
| 21566 | .extra_temps = .{ | | |
| 21567 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 21568 | .{ .kind = .{ .rc = .sse } }, | | |
| 21569 | .{ .kind = .{ .rc = .sse } }, | | |
| 21570 | .unused, | | |
| 21571 | .unused, | | |
| 21572 | .unused, | | |
| 21573 | .unused, | | |
| 21574 | .unused, | | |
| 21575 | .unused, | | |
| 21576 | }, | | |
| 21577 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21578 | .clobbers = .{ .eflags = true }, | | |
| 21579 | .each = .{ .once = &.{ | | |
| 21580 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | | |
| 21581 | .{ ._, .p_, .xor, .tmp1x, .tmp1x, ._, ._ }, | | |
| 21582 | .{ .@"0:", ._dqu, .mov, .tmp2x, .memia(.src0x, .tmp0, .add_size), ._, ._ }, | | |
| 21583 | .{ ._, .p_, .xor, .tmp2x, .memia(.src1x, .tmp0, .add_size), ._, ._ }, | | |
| 21584 | .{ ._, .p_, .@"or", .tmp1x, .tmp2x, ._, ._ }, | | |
| 21585 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, | | |
| 21586 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 21587 | .{ ._, .p_, .xor, .tmp2x, .tmp2x, ._, ._ }, | | |
| 21588 | .{ ._, .p_b, .cmpeq, .tmp1x, .tmp2x, ._, ._ }, | | |
| 21589 | .{ ._, .p_b, .movmsk, .tmp0d, .tmp1x, ._, ._ }, | | |
| 21590 | .{ ._, ._, .cmp, .tmp0d, .si(0xffff), ._, ._ }, | | |
| 21591 | } }, | | |
| 21592 | }, .{ | | |
| 21593 | .required_features = .{ .sse, .mmx, null, null }, | | |
| 21594 | .src_constraints = .{ | | |
| 21595 | .{ .remainder_int = .{ .of = .qword, .is = .qword } }, | | |
| 21596 | .{ .remainder_int = .{ .of = .qword, .is = .qword } }, | | |
| 21597 | }, | | |
| 21598 | .patterns = &.{ | | |
| 21599 | .{ .src = .{ .to_mem, .to_mem } }, | | |
| 21600 | }, | | |
| 21601 | .extra_temps = .{ | | |
| 21602 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 21603 | .{ .kind = .{ .rc = .mmx } }, | | |
| 21604 | .{ .kind = .{ .rc = .mmx } }, | | |
| 21605 | .unused, | | |
| 21606 | .unused, | | |
| 21607 | .unused, | | |
| 21608 | .unused, | | |
| 21609 | .unused, | | |
| 21610 | .unused, | | |
| 21611 | }, | | |
| 21612 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21613 | .clobbers = .{ .eflags = true }, | | |
| 21614 | .each = .{ .once = &.{ | | |
| 21615 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | | |
| 21616 | .{ ._, .p_, .xor, .tmp1q, .tmp1q, ._, ._ }, | | |
| 21617 | .{ .@"0:", ._q, .mov, .tmp2q, .memia(.src0q, .tmp0, .add_size), ._, ._ }, | | |
| 21618 | .{ ._, .p_, .xor, .tmp2q, .memia(.src1q, .tmp0, .add_size), ._, ._ }, | | |
| 21619 | .{ ._, .p_, .@"or", .tmp1q, .tmp2q, ._, ._ }, | | |
| 21620 | .{ ._, ._, .add, .tmp0p, .si(8), ._, ._ }, | | |
| 21621 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 21622 | .{ ._, .p_, .xor, .tmp2q, .tmp2q, ._, ._ }, | | |
| 21623 | .{ ._, .p_b, .cmpeq, .tmp1q, .tmp2q, ._, ._ }, | | |
| 21624 | .{ ._, .p_b, .movmsk, .tmp0d, .tmp1q, ._, ._ }, | | |
| 21625 | .{ ._, ._, .cmp, .tmp0d, .si(0xff), ._, ._ }, | | |
| 21626 | } }, | | |
| 21627 | }, .{ | | |
| 21628 | .src_constraints = .{ | | |
| 21629 | .{ .remainder_int = .{ .of = .qword, .is = .qword } }, | | |
| 21630 | .{ .remainder_int = .{ .of = .qword, .is = .qword } }, | | |
| 21631 | }, | | |
| 21632 | .patterns = &.{ | | |
| 21633 | .{ .src = .{ .to_mem, .to_mem } }, | | |
| 21634 | }, | | |
| 21635 | .extra_temps = .{ | | |
| 21636 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, | | |
| 21637 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | | |
| 21638 | .{ .type = .usize, .kind = .{ .rc = .general_purpose } }, | | |
| 21639 | .unused, | | |
| 21640 | .unused, | | |
| 21641 | .unused, | | |
| 21642 | .unused, | | |
| 21643 | .unused, | | |
| 21644 | .unused, | | |
| 21645 | }, | | |
| 21646 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21647 | .clobbers = .{ .eflags = true }, | | |
| 21648 | .each = .{ .once = &.{ | | |
| 21649 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, | | |
| 21650 | .{ ._, ._, .xor, .tmp1p, .tmp1p, ._, ._ }, | | |
| 21651 | .{ .@"0:", ._, .mov, .tmp2p, .memia(.src0p, .tmp0, .add_size), ._, ._ }, | | |
| 21652 | .{ ._, ._, .xor, .tmp2p, .memia(.src1p, .tmp0, .add_size), ._, ._ }, | | |
| 21653 | .{ ._, ._, .@"or", .tmp1p, .tmp2p, ._, ._ }, | | |
| 21654 | .{ ._, ._, .add, .tmp0p, .sa(.tmp2, .add_size), ._, ._ }, | | |
| 21655 | .{ ._, ._nc, .j, .@"0b", ._, ._, ._ }, | | |
| 21656 | .{ ._, ._, .@"test", .tmp1p, .tmp1p, ._, ._ }, | | |
| 21657 | } }, | | |
| 21658 | }, .{ | | |
| 21659 | .required_features = .{ .f16c, null, null, null }, | | |
| 21660 | .src_constraints = .{ .{ .float = .word }, .{ .float = .word } }, | | |
| 21661 | .patterns = &.{ | | |
| 21662 | .{ .src = .{ .to_sse, .to_sse } }, | | |
| 21663 | }, | | |
| 21664 | .extra_temps = .{ | | |
| 21665 | .{ .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .sse } } }, | | |
| 21666 | .{ .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .sse } } }, | | |
| 21667 | .unused, | | |
| 21668 | .unused, | | |
| 21669 | .unused, | | |
| 21670 | .unused, | | |
| 21671 | .unused, | | |
| 21672 | .unused, | | |
| 21673 | .unused, | | |
| 21674 | }, | | |
| 21675 | .dst_temps = .{.{ .cc = switch (cc) { | | |
| 21676 | else => unreachable, | | |
| 21677 | .e => .z_and_np, | | |
| 21678 | .ne => .nz_or_p, | | |
| 21679 | } }}, | | |
| 21680 | .clobbers = .{ .eflags = true }, | | |
| 21681 | .each = .{ .once = &.{ | | |
| 21682 | .{ ._, .v_ps, .cvtph2, .tmp0x, .src0q, ._, ._ }, | | |
| 21683 | .{ ._, .v_ps, .cvtph2, .tmp1x, .src1q, ._, ._ }, | | |
| 21684 | .{ ._, .v_ss, .ucomi, .tmp0x, .tmp1x, ._, ._ }, | | |
| 21685 | } }, | | |
| 21686 | }, .{ | | |
| 21687 | .required_features = .{ .sse, null, null, null }, | | |
| 21688 | .src_constraints = .{ .{ .float = .word }, .{ .float = .word } }, | | |
| 21689 | .patterns = &.{ | | |
| 21690 | .{ .src = .{ .{ .to_reg = .xmm0 }, .{ .to_reg = .xmm1 } } }, | | |
| 21691 | }, | | |
| 21692 | .call_frame = .{ .alignment = .@"16" }, | | |
| 21693 | .extra_temps = .{ | | |
| 21694 | .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (cc) { | | |
| 21695 | else => unreachable, | | |
| 21696 | .e => "__eqhf2", | | |
| 21697 | .ne => "__nehf2", | | |
| 21698 | } } } }, | | |
| 21699 | .{ .type = .i32, .kind = .{ .reg = .eax } }, | | |
| 21700 | .unused, | | |
| 21701 | .unused, | | |
| 21702 | .unused, | | |
| 21703 | .unused, | | |
| 21704 | .unused, | | |
| 21705 | .unused, | | |
| 21706 | .unused, | | |
| 21707 | }, | | |
| 21708 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21709 | .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, | | |
| 21710 | .each = .{ .once = &.{ | | |
| 21711 | .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, | | |
| 21712 | .{ ._, ._, .@"test", .tmp1d, .tmp1d, ._, ._ }, | | |
| 21713 | } }, | | |
| 21714 | }, .{ | | |
| 21715 | .required_features = .{ .avx, null, null, null }, | | |
| 21716 | .src_constraints = .{ .{ .float = .dword }, .{ .float = .dword } }, | | |
| 21717 | .patterns = &.{ | | |
| 21718 | .{ .src = .{ .to_sse, .mem } }, | | |
| 21719 | .{ .src = .{ .mem, .to_sse }, .commute = .{ 0, 1 } }, | | |
| 21720 | .{ .src = .{ .to_sse, .to_sse } }, | | |
| 21721 | }, | | |
| 21722 | .extra_temps = .{ | | |
| 21723 | .{ .type = .f16, .kind = .{ .rc = .sse } }, | | |
| 21724 | .{ .type = .f16, .kind = .{ .rc = .sse } }, | | |
| 21725 | .unused, | | |
| 21726 | .unused, | | |
| 21727 | .unused, | | |
| 21728 | .unused, | | |
| 21729 | .unused, | | |
| 21730 | .unused, | | |
| 21731 | .unused, | | |
| 21732 | }, | | |
| 21733 | .dst_temps = .{.{ .cc = switch (cc) { | | |
| 21734 | else => unreachable, | | |
| 21735 | .e => .z_and_np, | | |
| 21736 | .ne => .nz_or_p, | | |
| 21737 | } }}, | | |
| 21738 | .clobbers = .{ .eflags = true }, | | |
| 21739 | .each = .{ .once = &.{ | | |
| 21740 | .{ ._, .v_ss, .ucomi, .src0x, .src1d, ._, ._ }, | | |
| 21741 | } }, | | |
| 21742 | }, .{ | | |
| 21743 | .required_features = .{ .sse, null, null, null }, | | |
| 21744 | .src_constraints = .{ .{ .float = .dword }, .{ .float = .dword } }, | | |
| 21745 | .patterns = &.{ | | |
| 21746 | .{ .src = .{ .to_sse, .mem } }, | | |
| 21747 | .{ .src = .{ .mem, .to_sse }, .commute = .{ 0, 1 } }, | | |
| 21748 | .{ .src = .{ .to_sse, .to_sse } }, | | |
| 21749 | }, | | |
| 21750 | .extra_temps = .{ | | |
| 21751 | .{ .type = .f16, .kind = .{ .rc = .sse } }, | | |
| 21752 | .{ .type = .f16, .kind = .{ .rc = .sse } }, | | |
| 21753 | .unused, | | |
| 21754 | .unused, | | |
| 21755 | .unused, | | |
| 21756 | .unused, | | |
| 21757 | .unused, | | |
| 21758 | .unused, | | |
| 21759 | .unused, | | |
| 21760 | }, | | |
| 21761 | .dst_temps = .{.{ .cc = switch (cc) { | | |
| 21762 | else => unreachable, | | |
| 21763 | .e => .z_and_np, | | |
| 21764 | .ne => .nz_or_p, | | |
| 21765 | } }}, | | |
| 21766 | .clobbers = .{ .eflags = true }, | | |
| 21767 | .each = .{ .once = &.{ | | |
| 21768 | .{ ._, ._ss, .ucomi, .src0x, .src1d, ._, ._ }, | | |
| 21769 | } }, | | |
| 21770 | }, .{ | | |
| 21771 | .required_features = .{ .sse, null, null, null }, | | |
| 21772 | .src_constraints = .{ .{ .float = .dword }, .{ .float = .word } }, | | |
| 21773 | .patterns = &.{ | | |
| 21774 | .{ .src = .{ .{ .to_reg = .xmm0 }, .{ .to_reg = .xmm1 } } }, | | |
| 21775 | }, | | |
| 21776 | .call_frame = .{ .alignment = .@"16" }, | | |
| 21777 | .extra_temps = .{ | | |
| 21778 | .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (cc) { | | |
| 21779 | else => unreachable, | | |
| 21780 | .e => "__eqsf2", | | |
| 21781 | .ne => "__nesf2", | | |
| 21782 | } } } }, | | |
| 21783 | .{ .type = .i32, .kind = .{ .reg = .eax } }, | | |
| 21784 | .unused, | | |
| 21785 | .unused, | | |
| 21786 | .unused, | | |
| 21787 | .unused, | | |
| 21788 | .unused, | | |
| 21789 | .unused, | | |
| 21790 | .unused, | | |
| 21791 | }, | | |
| 21792 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21793 | .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, | | |
| 21794 | .each = .{ .once = &.{ | | |
| 21795 | .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, | | |
| 21796 | .{ ._, ._, .@"test", .tmp1d, .tmp1d, ._, ._ }, | | |
| 21797 | } }, | | |
| 21798 | }, .{ | | |
| 21799 | .required_features = .{ .avx, null, null, null }, | | |
| 21800 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, | | |
| 21801 | .patterns = &.{ | | |
| 21802 | .{ .src = .{ .to_sse, .mem } }, | | |
| 21803 | .{ .src = .{ .mem, .to_sse }, .commute = .{ 0, 1 } }, | | |
| 21804 | .{ .src = .{ .to_sse, .to_sse } }, | | |
| 21805 | }, | | |
| 21806 | .extra_temps = .{ | | |
| 21807 | .{ .type = .f16, .kind = .{ .rc = .sse } }, | | |
| 21808 | .{ .type = .f16, .kind = .{ .rc = .sse } }, | | |
| 21809 | .unused, | | |
| 21810 | .unused, | | |
| 21811 | .unused, | | |
| 21812 | .unused, | | |
| 21813 | .unused, | | |
| 21814 | .unused, | | |
| 21815 | .unused, | | |
| 21816 | }, | | |
| 21817 | .dst_temps = .{.{ .cc = switch (cc) { | | |
| 21818 | else => unreachable, | | |
| 21819 | .e => .z_and_np, | | |
| 21820 | .ne => .nz_or_p, | | |
| 21821 | } }}, | | |
| 21822 | .clobbers = .{ .eflags = true }, | | |
| 21823 | .each = .{ .once = &.{ | | |
| 21824 | .{ ._, .v_sd, .ucomi, .src0x, .src1q, ._, ._ }, | | |
| 21825 | } }, | | |
| 21826 | }, .{ | | |
| 21827 | .required_features = .{ .sse2, null, null, null }, | | |
| 21828 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, | | |
| 21829 | .patterns = &.{ | | |
| 21830 | .{ .src = .{ .to_sse, .mem } }, | | |
| 21831 | .{ .src = .{ .mem, .to_sse }, .commute = .{ 0, 1 } }, | | |
| 21832 | .{ .src = .{ .to_sse, .to_sse } }, | | |
| 21833 | }, | | |
| 21834 | .extra_temps = .{ | | |
| 21835 | .{ .type = .f16, .kind = .{ .rc = .sse } }, | | |
| 21836 | .{ .type = .f16, .kind = .{ .rc = .sse } }, | | |
| 21837 | .unused, | | |
| 21838 | .unused, | | |
| 21839 | .unused, | | |
| 21840 | .unused, | | |
| 21841 | .unused, | | |
| 21842 | .unused, | | |
| 21843 | .unused, | | |
| 21844 | }, | | |
| 21845 | .dst_temps = .{.{ .cc = switch (cc) { | | |
| 21846 | else => unreachable, | | |
| 21847 | .e => .z_and_np, | | |
| 21848 | .ne => .nz_or_p, | | |
| 21849 | } }}, | | |
| 21850 | .clobbers = .{ .eflags = true }, | | |
| 21851 | .each = .{ .once = &.{ | | |
| 21852 | .{ ._, ._sd, .ucomi, .src0x, .src1q, ._, ._ }, | | |
| 21853 | } }, | | |
| 21854 | }, .{ | | |
| 21855 | .required_features = .{ .sse, null, null, null }, | | |
| 21856 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, | | |
| 21857 | .patterns = &.{ | | |
| 21858 | .{ .src = .{ .{ .to_reg = .xmm0 }, .{ .to_reg = .xmm1 } } }, | | |
| 21859 | }, | | |
| 21860 | .call_frame = .{ .alignment = .@"16" }, | | |
| 21861 | .extra_temps = .{ | | |
| 21862 | .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (cc) { | | |
| 21863 | else => unreachable, | | |
| 21864 | .e => "__eqdf2", | | |
| 21865 | .ne => "__nedf2", | | |
| 21866 | } } } }, | | |
| 21867 | .{ .type = .i32, .kind = .{ .reg = .eax } }, | | |
| 21868 | .unused, | | |
| 21869 | .unused, | | |
| 21870 | .unused, | | |
| 21871 | .unused, | | |
| 21872 | .unused, | | |
| 21873 | .unused, | | |
| 21874 | .unused, | | |
| 21875 | }, | | |
| 21876 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21877 | .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, | | |
| 21878 | .each = .{ .once = &.{ | | |
| 21879 | .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, | | |
| 21880 | .{ ._, ._, .@"test", .tmp1d, .tmp1d, ._, ._ }, | | |
| 21881 | } }, | | |
| 21882 | }, .{ | | |
| 21883 | .required_features = .{ .x87, .cmov, null, null }, | | |
| 21884 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, | | |
| 21885 | .patterns = &.{ | | |
| 21886 | .{ .src = .{ .to_x87, .mem }, .commute = .{ 0, 1 } }, | | |
| 21887 | .{ .src = .{ .mem, .to_x87 } }, | | |
| 21888 | .{ .src = .{ .to_x87, .to_x87 } }, | | |
| 21889 | }, | | |
| 21890 | .extra_temps = .{ | | |
| 21891 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, | | |
| 21892 | .unused, | | |
| 21893 | .unused, | | |
| 21894 | .unused, | | |
| 21895 | .unused, | | |
| 21896 | .unused, | | |
| 21897 | .unused, | | |
| 21898 | .unused, | | |
| 21899 | .unused, | | |
| 21900 | }, | | |
| 21901 | .dst_temps = .{.{ .cc = switch (cc) { | | |
| 21902 | else => unreachable, | | |
| 21903 | .e => .z_and_np, | | |
| 21904 | .ne => .nz_or_p, | | |
| 21905 | } }}, | | |
| 21906 | .clobbers = .{ .eflags = true }, | | |
| 21907 | .each = .{ .once = &.{ | | |
| 21908 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, | | |
| 21909 | .{ ._, .f_p, .ucomi, .tmp0t, .src1t, ._, ._ }, | | |
| 21910 | } }, | | |
| 21911 | }, .{ | | |
| 21912 | .required_features = .{ .sahf, .x87, null, null }, | | |
| 21913 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, | | |
| 21914 | .patterns = &.{ | | |
| 21915 | .{ .src = .{ .mem, .mem } }, | | |
| 21916 | }, | | |
| 21917 | .extra_temps = .{ | | |
| 21918 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, | | |
| 21919 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, | | |
| 21920 | .{ .type = .u8, .kind = .{ .reg = .ah } }, | | |
| 21921 | .unused, | | |
| 21922 | .unused, | | |
| 21923 | .unused, | | |
| 21924 | .unused, | | |
| 21925 | .unused, | | |
| 21926 | .unused, | | |
| 21927 | }, | | |
| 21928 | .dst_temps = .{.{ .cc = switch (cc) { | | |
| 21929 | else => unreachable, | | |
| 21930 | .e => .z_and_np, | | |
| 21931 | .ne => .nz_or_p, | | |
| 21932 | } }}, | | |
| 21933 | .clobbers = .{ .eflags = true }, | | |
| 21934 | .each = .{ .once = &.{ | | |
| 21935 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, | | |
| 21936 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, | | |
| 21937 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, | | |
| 21938 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, | | |
| 21939 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, | | |
| 21940 | } }, | | |
| 21941 | }, .{ | | |
| 21942 | .required_features = .{ .@"64bit", .x87, null, null }, | | |
| 21943 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, | | |
| 21944 | .patterns = &.{ | | |
| 21945 | .{ .src = .{ .mem, .mem } }, | | |
| 21946 | }, | | |
| 21947 | .extra_temps = .{ | | |
| 21948 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, | | |
| 21949 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, | | |
| 21950 | .{ .type = .u8, .kind = .{ .reg = .ah } }, | | |
| 21951 | .unused, | | |
| 21952 | .unused, | | |
| 21953 | .unused, | | |
| 21954 | .unused, | | |
| 21955 | .unused, | | |
| 21956 | .unused, | | |
| 21957 | }, | | |
| 21958 | .dst_temps = .{.{ .cc = cc }}, | | |
| 21959 | .clobbers = .{ .eflags = true }, | | |
| 21960 | .each = .{ .once = &.{ | | |
| 21961 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, | | |
| 21962 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, | | |
| 21963 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, | | |
| 21964 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, | | |
| 21965 | .{ ._, ._, .xor, .tmp2b, .si(0b0_1_000_000), ._, ._ }, | | |
| 21966 | .{ ._, ._, .@"test", .tmp2b, .si(0b0_1_000_100), ._, ._ }, | | |
| 21967 | } }, | | |
| 21968 | }, .{ | | |
| 21969 | .required_features = .{ .x87, null, null, null }, | | |
| 21970 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, | | |
| 21971 | .patterns = &.{ | | |
| 21972 | .{ .src = .{ .mem, .mem } }, | | |
| 21973 | }, | | |
| 21974 | .extra_temps = .{ | | |
| 21975 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, | | |
| 21976 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, | | |
| 21977 | .{ .type = .u8, .kind = .{ .reg = .ah } }, | | |
| 21978 | .unused, | | |
| 21979 | .unused, | | |
| 21980 | .unused, | | |
| 21981 | .unused, | | |
| 21982 | .unused, | | |
| 21983 | .unused, | | |
| 21984 | }, | | |
| 21985 | .dst_temps = .{.{ .cc = switch (cc) { | | |
| 21986 | else => unreachable, | | |
| 21987 | .e => .z_and_np, | | |
| 21988 | .ne => .nz_or_p, | | |
| 21989 | } }}, | | |
| 21990 | .clobbers = .{ .eflags = true }, | | |
| 21991 | .each = .{ .once = &.{ | | |
| 21992 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, | | |
| 21993 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, | | |
| 21994 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, | | |
| 21995 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, | | |
| 21996 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, | | |
| 21997 | } }, | | |
| 21998 | }, .{ | | |
| 21999 | .required_features = .{ .sahf, .x87, null, null }, | | |
| 22000 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, | | |
| 22001 | .patterns = &.{ | | |
| 22002 | .{ .src = .{ .to_x87, .mem }, .commute = .{ 0, 1 } }, | | |
| 22003 | .{ .src = .{ .mem, .to_x87 } }, | | |
| 22004 | .{ .src = .{ .to_x87, .to_x87 } }, | | |
| 22005 | }, | | |
| 22006 | .extra_temps = .{ | | |
| 22007 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, | | |
| 22008 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, | | |
| 22009 | .{ .type = .u16, .kind = .{ .reg = .ah } }, | | |
| 22010 | .unused, | | |
| 22011 | .unused, | | |
| 22012 | .unused, | | |
| 22013 | .unused, | | |
| 22014 | .unused, | | |
| 22015 | .unused, | | |
| 22016 | }, | | |
| 22017 | .dst_temps = .{.{ .cc = switch (cc) { | | |
| 22018 | else => unreachable, | 21252 | else => unreachable, |
| 22019 | .e => .z_and_np, | 21253 | .cmp_eq, .cmp_neq => false, |
| 22020 | .ne => .nz_or_p, | 21254 | .cmp_eq_optimized, .cmp_neq_optimized => true, |
| 22021 | } }}, | 21255 | }) { |
| 22022 | .clobbers = .{ .eflags = true }, | 21256 | inline false, true => |optimized| comptime &.{ .{ |
| 22023 | .each = .{ .once = &.{ | 21257 | .required_features = .{ .f16c, null, null, null }, |
| 22024 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, | 21258 | .src_constraints = .{ .{ .float = .word }, .{ .float = .word } }, |
| 22025 | .{ ._, .f_p, .ucom, .src1t, ._, ._, ._ }, | 21259 | .patterns = &.{ |
| 22026 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, | 21260 | .{ .src = .{ .to_sse, .to_sse } }, |
| 22027 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, | 21261 | }, |
| 22028 | } }, | 21262 | .extra_temps = .{ |
| 22029 | }, .{ | 21263 | .{ .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .sse } } }, |
| 22030 | .required_features = .{ .@"64bit", .x87, null, null }, | 21264 | .{ .kind = .{ .mut_rc = .{ .ref = .src1, .rc = .sse } } }, |
| 22031 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, | 21265 | .unused, |
| 22032 | .patterns = &.{ | 21266 | .unused, |
| 22033 | .{ .src = .{ .to_x87, .mem }, .commute = .{ 0, 1 } }, | 21267 | .unused, |
| 22034 | .{ .src = .{ .mem, .to_x87 } }, | 21268 | .unused, |
| 22035 | .{ .src = .{ .to_x87, .to_x87 } }, | 21269 | .unused, |
| 22036 | }, | 21270 | .unused, |
| 22037 | .extra_temps = .{ | 21271 | .unused, |
| 22038 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, | 21272 | }, |
| 22039 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, | 21273 | .dst_temps = .{.{ .cc = switch (optimized) { |
| 22040 | .{ .type = .u8, .kind = .{ .reg = .ah } }, | 21274 | false => .z_and_np, |
| 22041 | .unused, | 21275 | true => .z, |
| 22042 | .unused, | 21276 | } }}, |
| 22043 | .unused, | 21277 | .clobbers = .{ .eflags = true }, |
| 22044 | .unused, | 21278 | .each = .{ .once = &.{ |
| 22045 | .unused, | 21279 | .{ ._, .v_ps, .cvtph2, .tmp0x, .src0q, ._, ._ }, |
| 22046 | .unused, | 21280 | .{ ._, .v_ps, .cvtph2, .tmp1x, .src1q, ._, ._ }, |
| 22047 | }, | 21281 | .{ ._, .v_ss, .ucomi, .tmp0x, .tmp1x, ._, ._ }, |
| 22048 | .dst_temps = .{.{ .cc = cc }}, | 21282 | } }, |
| 22049 | .clobbers = .{ .eflags = true }, | 21283 | }, .{ |
| 22050 | .each = .{ .once = &.{ | 21284 | .required_features = .{ .sse, null, null, null }, |
| 22051 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, | 21285 | .src_constraints = .{ .{ .float = .word }, .{ .float = .word } }, |
| 22052 | .{ ._, .f_p, .ucom, .src1t, ._, ._, ._ }, | 21286 | .patterns = &.{ |
| 22053 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, | 21287 | .{ .src = .{ .{ .to_reg = .xmm0 }, .{ .to_reg = .xmm1 } } }, |
| 22054 | .{ ._, ._, .xor, .tmp2b, .si(0b0_1_000_000), ._, ._ }, | 21288 | }, |
| 22055 | .{ ._, ._, .@"test", .tmp2b, .si(0b0_1_000_100), ._, ._ }, | 21289 | .call_frame = .{ .alignment = .@"16" }, |
| 22056 | } }, | 21290 | .extra_temps = .{ |
| 22057 | }, .{ | 21291 | .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmphf2" } } }, |
| 22058 | .required_features = .{ .x87, null, null, null }, | 21292 | .{ .type = .i32, .kind = .{ .reg = .eax } }, |
| 22059 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, | 21293 | .unused, |
| 22060 | .patterns = &.{ | 21294 | .unused, |
| 22061 | .{ .src = .{ .to_x87, .mem }, .commute = .{ 0, 1 } }, | 21295 | .unused, |
| 22062 | .{ .src = .{ .mem, .to_x87 } }, | 21296 | .unused, |
| 22063 | .{ .src = .{ .to_x87, .to_x87 } }, | 21297 | .unused, |
| 22064 | }, | 21298 | .unused, |
| 22065 | .extra_temps = .{ | 21299 | .unused, |
| 22066 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, | 21300 | }, |
| 22067 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, | 21301 | .dst_temps = .{.{ .cc = .z }}, |
| 22068 | .{ .type = .u16, .kind = .{ .reg = .ah } }, | 21302 | .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, |
| 22069 | .unused, | 21303 | .each = .{ .once = &.{ |
| 22070 | .unused, | 21304 | .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, |
| 22071 | .unused, | 21305 | .{ ._, ._, .@"test", .tmp1d, .tmp1d, ._, ._ }, |
| 22072 | .unused, | 21306 | } }, |
| 22073 | .unused, | 21307 | }, .{ |
| 22074 | .unused, | 21308 | .required_features = .{ .avx, null, null, null }, |
| 22075 | }, | 21309 | .src_constraints = .{ .{ .float = .dword }, .{ .float = .dword } }, |
| 22076 | .dst_temps = .{.{ .cc = switch (cc) { | 21310 | .patterns = &.{ |
| | 21311 | .{ .src = .{ .to_sse, .mem } }, |
| | 21312 | .{ .src = .{ .mem, .to_sse }, .commute = .{ 0, 1 } }, |
| | 21313 | .{ .src = .{ .to_sse, .to_sse } }, |
| | 21314 | }, |
| | 21315 | .dst_temps = .{.{ .cc = switch (optimized) { |
| | 21316 | false => .z_and_np, |
| | 21317 | true => .z, |
| | 21318 | } }}, |
| | 21319 | .clobbers = .{ .eflags = true }, |
| | 21320 | .each = .{ .once = &.{ |
| | 21321 | .{ ._, .v_ss, .ucomi, .src0x, .src1d, ._, ._ }, |
| | 21322 | } }, |
| | 21323 | }, .{ |
| | 21324 | .required_features = .{ .sse, null, null, null }, |
| | 21325 | .src_constraints = .{ .{ .float = .dword }, .{ .float = .dword } }, |
| | 21326 | .patterns = &.{ |
| | 21327 | .{ .src = .{ .to_sse, .mem } }, |
| | 21328 | .{ .src = .{ .mem, .to_sse }, .commute = .{ 0, 1 } }, |
| | 21329 | .{ .src = .{ .to_sse, .to_sse } }, |
| | 21330 | }, |
| | 21331 | .dst_temps = .{.{ .cc = switch (optimized) { |
| | 21332 | false => .z_and_np, |
| | 21333 | true => .z, |
| | 21334 | } }}, |
| | 21335 | .clobbers = .{ .eflags = true }, |
| | 21336 | .each = .{ .once = &.{ |
| | 21337 | .{ ._, ._ss, .ucomi, .src0x, .src1d, ._, ._ }, |
| | 21338 | } }, |
| | 21339 | }, .{ |
| | 21340 | .required_features = .{ .avx, null, null, null }, |
| | 21341 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, |
| | 21342 | .patterns = &.{ |
| | 21343 | .{ .src = .{ .to_sse, .mem } }, |
| | 21344 | .{ .src = .{ .mem, .to_sse }, .commute = .{ 0, 1 } }, |
| | 21345 | .{ .src = .{ .to_sse, .to_sse } }, |
| | 21346 | }, |
| | 21347 | .dst_temps = .{.{ .cc = switch (optimized) { |
| | 21348 | false => .z_and_np, |
| | 21349 | true => .z, |
| | 21350 | } }}, |
| | 21351 | .clobbers = .{ .eflags = true }, |
| | 21352 | .each = .{ .once = &.{ |
| | 21353 | .{ ._, .v_sd, .ucomi, .src0x, .src1q, ._, ._ }, |
| | 21354 | } }, |
| | 21355 | }, .{ |
| | 21356 | .required_features = .{ .sse2, null, null, null }, |
| | 21357 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, |
| | 21358 | .patterns = &.{ |
| | 21359 | .{ .src = .{ .to_sse, .mem } }, |
| | 21360 | .{ .src = .{ .mem, .to_sse }, .commute = .{ 0, 1 } }, |
| | 21361 | .{ .src = .{ .to_sse, .to_sse } }, |
| | 21362 | }, |
| | 21363 | .dst_temps = .{.{ .cc = switch (optimized) { |
| | 21364 | false => .z_and_np, |
| | 21365 | true => .z, |
| | 21366 | } }}, |
| | 21367 | .clobbers = .{ .eflags = true }, |
| | 21368 | .each = .{ .once = &.{ |
| | 21369 | .{ ._, ._sd, .ucomi, .src0x, .src1q, ._, ._ }, |
| | 21370 | } }, |
| | 21371 | }, .{ |
| | 21372 | .required_features = .{ .x87, .cmov, null, null }, |
| | 21373 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, |
| | 21374 | .patterns = &.{ |
| | 21375 | .{ .src = .{ .to_mem, .to_mem }, .commute = .{ 0, 1 } }, |
| | 21376 | }, |
| | 21377 | .extra_temps = .{ |
| | 21378 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 21379 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 21380 | .unused, |
| | 21381 | .unused, |
| | 21382 | .unused, |
| | 21383 | .unused, |
| | 21384 | .unused, |
| | 21385 | .unused, |
| | 21386 | .unused, |
| | 21387 | }, |
| | 21388 | .dst_temps = .{.{ .cc = switch (optimized) { |
| | 21389 | false => .z_and_np, |
| | 21390 | true => .z, |
| | 21391 | } }}, |
| | 21392 | .clobbers = .{ .eflags = true }, |
| | 21393 | .each = .{ .once = &.{ |
| | 21394 | .{ ._, .f_, .ld, .src1q, ._, ._, ._ }, |
| | 21395 | .{ ._, .f_, .ld, .src0q, ._, ._, ._ }, |
| | 21396 | .{ ._, .f_p, .ucomi, .tmp0t, .tmp1t, ._, ._ }, |
| | 21397 | .{ ._, .f_p, .st, .tmp1t, ._, ._, ._ }, |
| | 21398 | } }, |
| | 21399 | }, .{ |
| | 21400 | .required_features = .{ .sahf, .x87, null, null }, |
| | 21401 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, |
| | 21402 | .patterns = &.{ |
| | 21403 | .{ .src = .{ .to_mem, .to_mem }, .commute = .{ 0, 1 } }, |
| | 21404 | }, |
| | 21405 | .extra_temps = .{ |
| | 21406 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 21407 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 21408 | .{ .type = .u8, .kind = .{ .reg = .ah } }, |
| | 21409 | .unused, |
| | 21410 | .unused, |
| | 21411 | .unused, |
| | 21412 | .unused, |
| | 21413 | .unused, |
| | 21414 | .unused, |
| | 21415 | }, |
| | 21416 | .dst_temps = .{.{ .cc = switch (optimized) { |
| | 21417 | false => .z_and_np, |
| | 21418 | true => .z, |
| | 21419 | } }}, |
| | 21420 | .clobbers = .{ .eflags = true }, |
| | 21421 | .each = .{ .once = &.{ |
| | 21422 | .{ ._, .f_, .ld, .src1q, ._, ._, ._ }, |
| | 21423 | .{ ._, .f_, .ld, .src0q, ._, ._, ._ }, |
| | 21424 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, |
| | 21425 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21426 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, |
| | 21427 | } }, |
| | 21428 | }, .{ |
| | 21429 | .required_features = .{ .x87, null, null, null }, |
| | 21430 | .src_constraints = .{ .{ .float = .qword }, .{ .float = .qword } }, |
| | 21431 | .patterns = &.{ |
| | 21432 | .{ .src = .{ .to_mem, .to_mem } }, |
| | 21433 | }, |
| | 21434 | .extra_temps = .{ |
| | 21435 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 21436 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 21437 | .{ .type = .u8, .kind = .{ .reg = .ah } }, |
| | 21438 | .unused, |
| | 21439 | .unused, |
| | 21440 | .unused, |
| | 21441 | .unused, |
| | 21442 | .unused, |
| | 21443 | .unused, |
| | 21444 | }, |
| | 21445 | .dst_temps = .{.{ .cc = switch (optimized) { |
| | 21446 | false => .z, |
| | 21447 | true => .nz, |
| | 21448 | } }}, |
| | 21449 | .clobbers = .{ .eflags = true }, |
| | 21450 | .each = .{ .once = switch (optimized) { |
| | 21451 | false => &.{ |
| | 21452 | .{ ._, .f_, .ld, .src1q, ._, ._, ._ }, |
| | 21453 | .{ ._, .f_, .ld, .src0q, ._, ._, ._ }, |
| | 21454 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, |
| | 21455 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21456 | .{ ._, ._, .xor, .tmp2b, .si(0b1_000_000), ._, ._ }, |
| | 21457 | .{ ._, ._, .@"test", .tmp2b, .si(0b1_000_100), ._, ._ }, |
| | 21458 | }, |
| | 21459 | true => &.{ |
| | 21460 | .{ ._, .f_, .ld, .src1q, ._, ._, ._ }, |
| | 21461 | .{ ._, .f_, .ld, .src0q, ._, ._, ._ }, |
| | 21462 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, |
| | 21463 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21464 | .{ ._, ._, .@"test", .tmp2b, .si(0b1_000_000), ._, ._ }, |
| | 21465 | }, |
| | 21466 | } }, |
| | 21467 | }, .{ |
| | 21468 | .required_features = .{ .x87, .cmov, null, null }, |
| | 21469 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, |
| | 21470 | .patterns = &.{ |
| | 21471 | .{ .src = .{ .to_x87, .mem }, .commute = .{ 0, 1 } }, |
| | 21472 | .{ .src = .{ .mem, .to_x87 } }, |
| | 21473 | .{ .src = .{ .to_x87, .to_x87 } }, |
| | 21474 | }, |
| | 21475 | .extra_temps = .{ |
| | 21476 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 21477 | .unused, |
| | 21478 | .unused, |
| | 21479 | .unused, |
| | 21480 | .unused, |
| | 21481 | .unused, |
| | 21482 | .unused, |
| | 21483 | .unused, |
| | 21484 | .unused, |
| | 21485 | }, |
| | 21486 | .dst_temps = .{.{ .cc = switch (optimized) { |
| | 21487 | false => .z_and_np, |
| | 21488 | true => .z, |
| | 21489 | } }}, |
| | 21490 | .clobbers = .{ .eflags = true }, |
| | 21491 | .each = .{ .once = &.{ |
| | 21492 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| | 21493 | .{ ._, .f_p, .ucomi, .tmp0t, .src1t, ._, ._ }, |
| | 21494 | } }, |
| | 21495 | }, .{ |
| | 21496 | .required_features = .{ .sahf, .x87, null, null }, |
| | 21497 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, |
| | 21498 | .patterns = &.{ |
| | 21499 | .{ .src = .{ .mem, .mem } }, |
| | 21500 | }, |
| | 21501 | .extra_temps = .{ |
| | 21502 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 21503 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 21504 | .{ .type = .u8, .kind = .{ .reg = .ah } }, |
| | 21505 | .unused, |
| | 21506 | .unused, |
| | 21507 | .unused, |
| | 21508 | .unused, |
| | 21509 | .unused, |
| | 21510 | .unused, |
| | 21511 | }, |
| | 21512 | .dst_temps = .{.{ .cc = switch (optimized) { |
| | 21513 | false => .z_and_np, |
| | 21514 | true => .z, |
| | 21515 | } }}, |
| | 21516 | .clobbers = .{ .eflags = true }, |
| | 21517 | .each = .{ .once = &.{ |
| | 21518 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, |
| | 21519 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| | 21520 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, |
| | 21521 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21522 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, |
| | 21523 | } }, |
| | 21524 | }, .{ |
| | 21525 | .required_features = .{ .sahf, .x87, null, null }, |
| | 21526 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, |
| | 21527 | .patterns = &.{ |
| | 21528 | .{ .src = .{ .to_x87, .mem }, .commute = .{ 0, 1 } }, |
| | 21529 | .{ .src = .{ .mem, .to_x87 } }, |
| | 21530 | .{ .src = .{ .to_x87, .to_x87 } }, |
| | 21531 | }, |
| | 21532 | .extra_temps = .{ |
| | 21533 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 21534 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 21535 | .{ .type = .u8, .kind = .{ .reg = .ah } }, |
| | 21536 | .unused, |
| | 21537 | .unused, |
| | 21538 | .unused, |
| | 21539 | .unused, |
| | 21540 | .unused, |
| | 21541 | .unused, |
| | 21542 | }, |
| | 21543 | .dst_temps = .{.{ .cc = switch (optimized) { |
| | 21544 | false => .z_and_np, |
| | 21545 | true => .z, |
| | 21546 | } }}, |
| | 21547 | .clobbers = .{ .eflags = true }, |
| | 21548 | .each = .{ .once = &.{ |
| | 21549 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| | 21550 | .{ ._, .f_p, .ucom, .src1t, ._, ._, ._ }, |
| | 21551 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21552 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, |
| | 21553 | } }, |
| | 21554 | }, .{ |
| | 21555 | .required_features = .{ .x87, null, null, null }, |
| | 21556 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, |
| | 21557 | .patterns = &.{ |
| | 21558 | .{ .src = .{ .mem, .mem } }, |
| | 21559 | }, |
| | 21560 | .extra_temps = .{ |
| | 21561 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 21562 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 21563 | .{ .type = .u8, .kind = .{ .reg = .ah } }, |
| | 21564 | .unused, |
| | 21565 | .unused, |
| | 21566 | .unused, |
| | 21567 | .unused, |
| | 21568 | .unused, |
| | 21569 | .unused, |
| | 21570 | }, |
| | 21571 | .dst_temps = .{.{ .cc = switch (optimized) { |
| | 21572 | false => .z, |
| | 21573 | true => .nz, |
| | 21574 | } }}, |
| | 21575 | .clobbers = .{ .eflags = true }, |
| | 21576 | .each = .{ .once = switch (optimized) { |
| | 21577 | false => &.{ |
| | 21578 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, |
| | 21579 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| | 21580 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, |
| | 21581 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21582 | .{ ._, ._, .xor, .tmp2b, .si(0b1_000_000), ._, ._ }, |
| | 21583 | .{ ._, ._, .@"test", .tmp2b, .si(0b1_000_100), ._, ._ }, |
| | 21584 | }, |
| | 21585 | true => &.{ |
| | 21586 | .{ ._, .f_, .ld, .src1t, ._, ._, ._ }, |
| | 21587 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| | 21588 | .{ ._, .f_pp, .ucom, ._, ._, ._, ._ }, |
| | 21589 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21590 | .{ ._, ._, .@"test", .tmp2b, .si(0b1_000_000), ._, ._ }, |
| | 21591 | }, |
| | 21592 | } }, |
| | 21593 | }, .{ |
| | 21594 | .required_features = .{ .x87, null, null, null }, |
| | 21595 | .src_constraints = .{ .{ .float = .tbyte }, .{ .float = .tbyte } }, |
| | 21596 | .patterns = &.{ |
| | 21597 | .{ .src = .{ .to_x87, .mem }, .commute = .{ 0, 1 } }, |
| | 21598 | .{ .src = .{ .mem, .to_x87 } }, |
| | 21599 | .{ .src = .{ .to_x87, .to_x87 } }, |
| | 21600 | }, |
| | 21601 | .extra_temps = .{ |
| | 21602 | .{ .type = .f80, .kind = .{ .reg = .st6 } }, |
| | 21603 | .{ .type = .f80, .kind = .{ .reg = .st7 } }, |
| | 21604 | .{ .type = .u8, .kind = .{ .reg = .ah } }, |
| | 21605 | .unused, |
| | 21606 | .unused, |
| | 21607 | .unused, |
| | 21608 | .unused, |
| | 21609 | .unused, |
| | 21610 | .unused, |
| | 21611 | }, |
| | 21612 | .dst_temps = .{.{ .cc = switch (optimized) { |
| | 21613 | false => .z, |
| | 21614 | true => .nz, |
| | 21615 | } }}, |
| | 21616 | .clobbers = .{ .eflags = true }, |
| | 21617 | .each = .{ .once = switch (optimized) { |
| | 21618 | false => &.{ |
| | 21619 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| | 21620 | .{ ._, .f_p, .ucom, .src1t, ._, ._, ._ }, |
| | 21621 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21622 | .{ ._, ._, .xor, .tmp2b, .si(0b1_000_000), ._, ._ }, |
| | 21623 | .{ ._, ._, .@"test", .tmp2b, .si(0b1_000_100), ._, ._ }, |
| | 21624 | }, |
| | 21625 | true => &.{ |
| | 21626 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, |
| | 21627 | .{ ._, .f_p, .ucom, .src1t, ._, ._, ._ }, |
| | 21628 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, |
| | 21629 | .{ ._, ._, .@"test", .tmp2b, .si(0b1_000_000), ._, ._ }, |
| | 21630 | }, |
| | 21631 | } }, |
| | 21632 | }, .{ |
| | 21633 | .required_features = .{ .sse, null, null, null }, |
| | 21634 | .src_constraints = .{ .{ .float = .xword }, .{ .float = .xword } }, |
| | 21635 | .patterns = &.{ |
| | 21636 | .{ .src = .{ .{ .to_reg = .xmm0 }, .{ .to_reg = .xmm1 } } }, |
| | 21637 | }, |
| | 21638 | .call_frame = .{ .alignment = .@"16" }, |
| | 21639 | .extra_temps = .{ |
| | 21640 | .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__cmptf2" } } }, |
| | 21641 | .{ .type = .i32, .kind = .{ .reg = .eax } }, |
| | 21642 | .unused, |
| | 21643 | .unused, |
| | 21644 | .unused, |
| | 21645 | .unused, |
| | 21646 | .unused, |
| | 21647 | .unused, |
| | 21648 | .unused, |
| | 21649 | }, |
| | 21650 | .dst_temps = .{.{ .cc = .z }}, |
| | 21651 | .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, |
| | 21652 | .each = .{ .once = &.{ |
| | 21653 | .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, |
| | 21654 | .{ ._, ._, .@"test", .tmp1d, .tmp1d, ._, ._ }, |
| | 21655 | } }, |
| | 21656 | } }, |
| | 21657 | }) catch |err| break :err err; |
| | 21658 | switch (cmp_op) { |
| 22077 | else => unreachable, | 21659 | else => unreachable, |
| 22078 | .e => .z_and_np, | 21660 | .eq => {}, |
| 22079 | .ne => .nz_or_p, | 21661 | .neq => { |
| 22080 | } }}, | 21662 | const cc = &res[0].unwrap(cg).temp.tracking(cg).short.eflags; |
| 22081 | .clobbers = .{ .eflags = true }, | 21663 | cc.* = cc.negate(); |
| 22082 | .each = .{ .once = &.{ | 21664 | }, |
| 22083 | .{ ._, .f_, .ld, .src0t, ._, ._, ._ }, | 21665 | } |
| 22084 | .{ ._, .f_p, .ucom, .src1t, ._, ._, ._ }, | 21666 | }, |
| 22085 | .{ ._, .fn_sw, .st, .tmp2w, ._, ._, ._ }, | 21667 | .int => res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err, |
| 22086 | .{ ._, ._, .sahf, ._, ._, ._, ._ }, | | |
| 22087 | } }, | | |
| 22088 | }, .{ | | |
| 22089 | .required_features = .{ .sse, null, null, null }, | | |
| 22090 | .src_constraints = .{ .{ .float = .xword }, .{ .float = .xword } }, | | |
| 22091 | .patterns = &.{ | | |
| 22092 | .{ .src = .{ .{ .to_reg = .xmm0 }, .{ .to_reg = .xmm1 } } }, | | |
| 22093 | }, | | |
| 22094 | .call_frame = .{ .alignment = .@"16" }, | | |
| 22095 | .extra_temps = .{ | | |
| 22096 | .{ .type = .usize, .kind = .{ .symbol = &.{ .name = switch (cc) { | | |
| 22097 | else => unreachable, | | |
| 22098 | .e => "__eqtf2", | | |
| 22099 | .ne => "__netf2", | | |
| 22100 | } } } }, | | |
| 22101 | .{ .type = .i32, .kind = .{ .reg = .eax } }, | | |
| 22102 | .unused, | | |
| 22103 | .unused, | | |
| 22104 | .unused, | | |
| 22105 | .unused, | | |
| 22106 | .unused, | | |
| 22107 | .unused, | | |
| 22108 | .unused, | | |
| 22109 | }, | | |
| 22110 | .dst_temps = .{.{ .cc = cc }}, | | |
| 22111 | .clobbers = .{ .eflags = true, .caller_preserved = .ccc }, | | |
| 22112 | .each = .{ .once = &.{ | | |
| 22113 | .{ ._, ._, .call, .tmp0d, ._, ._, ._ }, | | |
| 22114 | .{ ._, ._, .@"test", .tmp1d, .tmp1d, ._, ._ }, | | |
| 22115 | } }, | | |
| 22116 | } }, | | |
| 22117 | }) catch |err| switch (err) { | 21668 | }) catch |err| switch (err) { |
| 22118 | error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{ | 21669 | error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{ |
| 22119 | @tagName(air_tag), | 21670 | @tagName(air_tag), |
| ... | @@ -22123,6 +21674,22 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -22123,6 +21674,22 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 22123 | }), | 21674 | }), |
| 22124 | else => |e| return e, | 21675 | else => |e| return e, |
| 22125 | }; | 21676 | }; |
| | 21677 | if (opt_info) |*oi| { |
| | 21678 | for (ops) |op| for (res) |r| { |
| | 21679 | if (op.index == r.index) break; |
| | 21680 | } else try op.die(cg); |
| | 21681 | try cg.genCopy(.bool, oi.res[0].tracking(cg).short, res[0].tracking(cg).short, .{}); |
| | 21682 | try res[0].die(cg); |
| | 21683 | res[0] = oi.res[0]; |
| | 21684 | try cg.restoreState(oi.state, &oi.deaths, .{ |
| | 21685 | .emit_instructions = true, |
| | 21686 | .update_tracking = true, |
| | 21687 | .resurrect = true, |
| | 21688 | .close_scope = true, |
| | 21689 | }); |
| | 21690 | cg.performReloc(oi.reloc); |
| | 21691 | @memset(&ops, res[0]); |
| | 21692 | } |
| 22126 | try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg); | 21693 | try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg); |
| 22127 | }, | 21694 | }, |
| 22128 | | 21695 | |
| ... | @@ -22169,7 +21736,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -22169,7 +21736,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 22169 | .data = .{ .func = old_inline_func }, | 21736 | .data = .{ .func = old_inline_func }, |
| 22170 | }); | 21737 | }); |
| 22171 | }, | 21738 | }, |
| 22172 | .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => if (use_old) try cg.airDbgVar(inst) else if (cg.debug_output != .none) { | 21739 | .dbg_var_ptr, |
| | 21740 | .dbg_var_val, |
| | 21741 | .dbg_arg_inline, |
| | 21742 | => if (use_old) try cg.airDbgVar(inst) else if (cg.debug_output != .none) { |
| 22173 | const pl_op = air_datas[@intFromEnum(inst)].pl_op; | 21743 | const pl_op = air_datas[@intFromEnum(inst)].pl_op; |
| 22174 | var ops = try cg.tempsFromOperands(inst, .{pl_op.operand}); | 21744 | var ops = try cg.tempsFromOperands(inst, .{pl_op.operand}); |
| 22175 | var mcv = ops[0].tracking(cg).short; | 21745 | var mcv = ops[0].tracking(cg).short; |
| ... | @@ -22776,7 +22346,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -22776,7 +22346,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 22776 | .work_group_size => unreachable, | 22346 | .work_group_size => unreachable, |
| 22777 | .work_group_id => unreachable, | 22347 | .work_group_id => unreachable, |
| 22778 | } | 22348 | } |
| 22779 | cg.resetTemps(); | 22349 | try cg.resetTemps(); |
| 22780 | cg.checkInvariantsAfterAirInst(); | 22350 | cg.checkInvariantsAfterAirInst(); |
| 22781 | } | 22351 | } |
| 22782 | verbose_tracking_log.debug("{}", .{cg.fmtTracking()}); | 22352 | verbose_tracking_log.debug("{}", .{cg.fmtTracking()}); |
| ... | @@ -22798,9 +22368,6 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -22798,9 +22368,6 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 22798 | const ret_reg = param_regs[0]; | 22368 | const ret_reg = param_regs[0]; |
| 22799 | const enum_mcv = MCValue{ .register = param_regs[1] }; | 22369 | const enum_mcv = MCValue{ .register = param_regs[1] }; |
| 22800 | | 22370 | |
| 22801 | const epilogue_relocs = try self.gpa.alloc(Mir.Inst.Index, enum_ty.enumFieldCount(zcu)); | | |
| 22802 | defer self.gpa.free(epilogue_relocs); | | |
| 22803 | | | |
| 22804 | const data_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 22371 | const data_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 22805 | const data_lock = self.register_manager.lockRegAssumeUnused(data_reg); | 22372 | const data_lock = self.register_manager.lockRegAssumeUnused(data_reg); |
| 22806 | defer self.register_manager.unlockReg(data_lock); | 22373 | defer self.register_manager.unlockReg(data_lock); |
| ... | @@ -22808,12 +22375,21 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -22808,12 +22375,21 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 22808 | | 22375 | |
| 22809 | var data_off: i32 = 0; | 22376 | var data_off: i32 = 0; |
| 22810 | const tag_names = enum_ty.enumFields(zcu); | 22377 | const tag_names = enum_ty.enumFields(zcu); |
| 22811 | for (epilogue_relocs, 0..) |*epilogue_reloc, tag_index| { | 22378 | for (0..enum_ty.enumFieldCount(zcu)) |tag_index| { |
| | 22379 | var arg_temp = try self.tempInit(enum_ty, enum_mcv); |
| | 22380 | |
| 22812 | const tag_name_len = tag_names.get(ip)[tag_index].length(ip); | 22381 | const tag_name_len = tag_names.get(ip)[tag_index].length(ip); |
| 22813 | const tag_val = try pt.enumValueFieldIndex(enum_ty, @intCast(tag_index)); | 22382 | const tag_val = try pt.enumValueFieldIndex(enum_ty, @intCast(tag_index)); |
| 22814 | const tag_mcv = try self.genTypedValue(tag_val); | 22383 | var tag_temp = try self.tempFromValue(tag_val); |
| 22815 | try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv); | 22384 | const cc_temp = arg_temp.cmpInts(.neq, &tag_temp, self) catch |err| switch (err) { |
| 22816 | const skip_reloc = try self.asmJccReloc(.ne, undefined); | 22385 | error.SelectFailed => unreachable, |
| | 22386 | else => |e| return e, |
| | 22387 | }; |
| | 22388 | try arg_temp.die(self); |
| | 22389 | try tag_temp.die(self); |
| | 22390 | const skip_reloc = try self.asmJccReloc(cc_temp.tracking(self).short.eflags, undefined); |
| | 22391 | try cc_temp.die(self); |
| | 22392 | try self.resetTemps(); |
| 22817 | | 22393 | |
| 22818 | try self.genSetMem( | 22394 | try self.genSetMem( |
| 22819 | .{ .reg = ret_reg }, | 22395 | .{ .reg = ret_reg }, |
| ... | @@ -22823,17 +22399,14 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -22823,17 +22399,14 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 22823 | .{}, | 22399 | .{}, |
| 22824 | ); | 22400 | ); |
| 22825 | try self.genSetMem(.{ .reg = ret_reg }, 8, .usize, .{ .immediate = tag_name_len }, .{}); | 22401 | try self.genSetMem(.{ .reg = ret_reg }, 8, .usize, .{ .immediate = tag_name_len }, .{}); |
| | 22402 | try self.asmOpOnly(.{ ._, .ret }); |
| 22826 | | 22403 | |
| 22827 | epilogue_reloc.* = try self.asmJmpReloc(undefined); | | |
| 22828 | self.performReloc(skip_reloc); | 22404 | self.performReloc(skip_reloc); |
| 22829 | | 22405 | |
| 22830 | data_off += @intCast(tag_name_len + 1); | 22406 | data_off += @intCast(tag_name_len + 1); |
| 22831 | } | 22407 | } |
| 22832 | | 22408 | |
| 22833 | try self.asmOpOnly(.{ ._2, .ud }); | 22409 | try self.asmOpOnly(.{ ._2, .ud }); |
| 22834 | | | |
| 22835 | for (epilogue_relocs) |reloc| self.performReloc(reloc); | | |
| 22836 | try self.asmOpOnly(.{ ._, .ret }); | | |
| 22837 | }, | 22410 | }, |
| 22838 | else => return self.fail( | 22411 | else => return self.fail( |
| 22839 | "TODO implement {s} for {}", | 22412 | "TODO implement {s} for {}", |
| ... | @@ -23103,10 +22676,12 @@ fn regClassForType(self: *CodeGen, ty: Type) Register.Class { | ... | @@ -23103,10 +22676,12 @@ fn regClassForType(self: *CodeGen, ty: Type) Register.Class { |
| 23103 | const elem_ty = ty.childType(zcu); | 22676 | const elem_ty = ty.childType(zcu); |
| 23104 | return if (elem_ty.toIntern() == .bool_type) | 22677 | return if (elem_ty.toIntern() == .bool_type) |
| 23105 | .general_purpose | 22678 | .general_purpose |
| 23106 | else if (self.floatBits(elem_ty) == 80) | 22679 | else if (self.floatBits(elem_ty)) |float_bits| |
| 23107 | .x87 | 22680 | if (float_bits == 80) .x87 else .sse |
| | 22681 | else if (self.intInfo(elem_ty)) |_| |
| | 22682 | .sse |
| 23108 | else | 22683 | else |
| 23109 | .sse; | 22684 | .general_purpose; |
| 23110 | } | 22685 | } |
| 23111 | | 22686 | |
| 23112 | fn regSetForRegClass(rc: Register.Class) RegisterManager.RegisterBitSet { | 22687 | fn regSetForRegClass(rc: Register.Class) RegisterManager.RegisterBitSet { |
| ... | @@ -23149,14 +22724,19 @@ const State = struct { | ... | @@ -23149,14 +22724,19 @@ const State = struct { |
| 23149 | registers: RegisterManager.TrackedRegisters, | 22724 | registers: RegisterManager.TrackedRegisters, |
| 23150 | reg_tracking: [RegisterManager.RegisterBitSet.bit_length]InstTracking, | 22725 | reg_tracking: [RegisterManager.RegisterBitSet.bit_length]InstTracking, |
| 23151 | free_registers: RegisterManager.RegisterBitSet, | 22726 | free_registers: RegisterManager.RegisterBitSet, |
| | 22727 | next_temp_index: Temp.Index, |
| 23152 | inst_tracking_len: u32, | 22728 | inst_tracking_len: u32, |
| 23153 | scope_generation: u32, | 22729 | scope_generation: u32, |
| 23154 | }; | 22730 | }; |
| 23155 | | 22731 | |
| 23156 | fn initRetroactiveState(self: *CodeGen) State { | 22732 | fn initRetroactiveState(self: *CodeGen) State { |
| | 22733 | const scope_generation = self.scope_generation + 1; |
| | 22734 | self.scope_generation = scope_generation; |
| | 22735 | |
| 23157 | var state: State = undefined; | 22736 | var state: State = undefined; |
| | 22737 | state.next_temp_index = @enumFromInt(0); |
| 23158 | state.inst_tracking_len = @intCast(self.inst_tracking.count()); | 22738 | state.inst_tracking_len = @intCast(self.inst_tracking.count()); |
| 23159 | state.scope_generation = self.scope_generation; | 22739 | state.scope_generation = scope_generation; |
| 23160 | return state; | 22740 | return state; |
| 23161 | } | 22741 | } |
| 23162 | | 22742 | |
| ... | @@ -23185,6 +22765,11 @@ fn restoreState(self: *CodeGen, state: State, deaths: []const Air.Inst.Index, co | ... | @@ -23185,6 +22765,11 @@ fn restoreState(self: *CodeGen, state: State, deaths: []const Air.Inst.Index, co |
| 23185 | close_scope: bool, | 22765 | close_scope: bool, |
| 23186 | }) !void { | 22766 | }) !void { |
| 23187 | if (opts.close_scope) { | 22767 | if (opts.close_scope) { |
| | 22768 | for ( |
| | 22769 | self.inst_tracking.keys()[@intFromEnum(state.next_temp_index)..@intFromEnum(self.next_temp_index)], |
| | 22770 | self.inst_tracking.values()[@intFromEnum(state.next_temp_index)..@intFromEnum(self.next_temp_index)], |
| | 22771 | ) |inst, *tracking| try tracking.die(self, inst); |
| | 22772 | self.next_temp_index = state.next_temp_index; |
| 23188 | for ( | 22773 | for ( |
| 23189 | self.inst_tracking.keys()[state.inst_tracking_len..], | 22774 | self.inst_tracking.keys()[state.inst_tracking_len..], |
| 23190 | self.inst_tracking.values()[state.inst_tracking_len..], | 22775 | self.inst_tracking.values()[state.inst_tracking_len..], |
| ... | @@ -23192,10 +22777,16 @@ fn restoreState(self: *CodeGen, state: State, deaths: []const Air.Inst.Index, co | ... | @@ -23192,10 +22777,16 @@ fn restoreState(self: *CodeGen, state: State, deaths: []const Air.Inst.Index, co |
| 23192 | self.inst_tracking.shrinkRetainingCapacity(state.inst_tracking_len); | 22777 | self.inst_tracking.shrinkRetainingCapacity(state.inst_tracking_len); |
| 23193 | } | 22778 | } |
| 23194 | | 22779 | |
| 23195 | if (opts.resurrect) for ( | 22780 | if (opts.resurrect) { |
| 23196 | self.inst_tracking.keys()[Temp.Index.max..state.inst_tracking_len], | 22781 | for ( |
| 23197 | self.inst_tracking.values()[Temp.Index.max..state.inst_tracking_len], | 22782 | self.inst_tracking.keys()[0..@intFromEnum(state.next_temp_index)], |
| 23198 | ) |inst, *tracking| try tracking.resurrect(self, inst, state.scope_generation); | 22783 | self.inst_tracking.values()[0..@intFromEnum(state.next_temp_index)], |
| | 22784 | ) |inst, *tracking| try tracking.resurrect(self, inst, state.scope_generation); |
| | 22785 | for ( |
| | 22786 | self.inst_tracking.keys()[Temp.Index.max..state.inst_tracking_len], |
| | 22787 | self.inst_tracking.values()[Temp.Index.max..state.inst_tracking_len], |
| | 22788 | ) |inst, *tracking| try tracking.resurrect(self, inst, state.scope_generation); |
| | 22789 | } |
| 23199 | for (deaths) |death| try self.processDeath(death); | 22790 | for (deaths) |death| try self.processDeath(death); |
| 23200 | | 22791 | |
| 23201 | const ExpectedContents = [@typeInfo(RegisterManager.TrackedRegisters).array.len]RegisterLock; | 22792 | const ExpectedContents = [@typeInfo(RegisterManager.TrackedRegisters).array.len]RegisterLock; |
| ... | @@ -27359,12 +26950,12 @@ fn airBitReverse(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -27359,12 +26950,12 @@ fn airBitReverse(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 27359 | try self.asmRegisterImmediate(.{ ._, .@"and" }, tmp, imm_0000_1111); | 26950 | try self.asmRegisterImmediate(.{ ._, .@"and" }, tmp, imm_0000_1111); |
| 27360 | try self.asmRegisterImmediate(.{ ._, .@"and" }, dst, imm_0000_1111); | 26951 | try self.asmRegisterImmediate(.{ ._, .@"and" }, dst, imm_0000_1111); |
| 27361 | } | 26952 | } |
| 27362 | // tmp = temp1 & 0x0F...0F | 26953 | // tmp = temp1 & 0x0f...0f |
| 27363 | // dst = (temp1 >> 4) & 0x0F...0F | 26954 | // dst = (temp1 >> 4) & 0x0f...0f |
| 27364 | try self.asmRegisterImmediate(.{ ._l, .sh }, tmp, .u(4)); | 26955 | try self.asmRegisterImmediate(.{ ._l, .sh }, tmp, .u(4)); |
| 27365 | // tmp = (temp1 & 0x0F...0F) << 4 | 26956 | // tmp = (temp1 & 0x0f...0f) << 4 |
| 27366 | try self.asmRegisterRegister(.{ ._, .@"or" }, dst, tmp); | 26957 | try self.asmRegisterRegister(.{ ._, .@"or" }, dst, tmp); |
| 27367 | // dst = temp2 = ((temp1 >> 4) & 0x0F...0F) | ((temp1 & 0x0F...0F) << 4) | 26958 | // dst = temp2 = ((temp1 >> 4) & 0x0f...0f) | ((temp1 & 0x0f...0f) << 4) |
| 27368 | try self.asmRegisterRegister(.{ ._, .mov }, tmp, dst); | 26959 | try self.asmRegisterRegister(.{ ._, .mov }, tmp, dst); |
| 27369 | // tmp = temp2 | 26960 | // tmp = temp2 |
| 27370 | try self.asmRegisterImmediate(.{ ._r, .sh }, dst, .u(2)); | 26961 | try self.asmRegisterImmediate(.{ ._r, .sh }, dst, .u(2)); |
| ... | @@ -33520,7 +33111,6 @@ fn genTry( | ... | @@ -33520,7 +33111,6 @@ fn genTry( |
| 33520 | if (operand.toIndex()) |operand_inst| try self.processDeath(operand_inst); | 33111 | if (operand.toIndex()) |operand_inst| try self.processDeath(operand_inst); |
| 33521 | } | 33112 | } |
| 33522 | | 33113 | |
| 33523 | self.scope_generation += 1; | | |
| 33524 | const state = try self.saveState(); | 33114 | const state = try self.saveState(); |
| 33525 | | 33115 | |
| 33526 | for (liveness_cond_br.else_deaths) |death| try self.processDeath(death); | 33116 | for (liveness_cond_br.else_deaths) |death| try self.processDeath(death); |
| ... | @@ -33596,7 +33186,6 @@ fn airCondBr(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -33596,7 +33186,6 @@ fn airCondBr(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 33596 | if (pl_op.operand.toIndex()) |op_inst| try self.processDeath(op_inst); | 33186 | if (pl_op.operand.toIndex()) |op_inst| try self.processDeath(op_inst); |
| 33597 | } | 33187 | } |
| 33598 | | 33188 | |
| 33599 | self.scope_generation += 1; | | |
| 33600 | const state = try self.saveState(); | 33189 | const state = try self.saveState(); |
| 33601 | const reloc = try self.genCondBrMir(cond_ty, cond); | 33190 | const reloc = try self.genCondBrMir(cond_ty, cond); |
| 33602 | | 33191 | |
| ... | @@ -33978,7 +33567,6 @@ fn airLoop(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -33978,7 +33567,6 @@ fn airLoop(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 33978 | const loop = self.air.extraData(Air.Block, ty_pl.payload); | 33567 | const loop = self.air.extraData(Air.Block, ty_pl.payload); |
| 33979 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]); | 33568 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]); |
| 33980 | | 33569 | |
| 33981 | self.scope_generation += 1; | | |
| 33982 | const state = try self.saveState(); | 33570 | const state = try self.saveState(); |
| 33983 | | 33571 | |
| 33984 | try self.loops.putNoClobber(self.gpa, inst, .{ | 33572 | try self.loops.putNoClobber(self.gpa, inst, .{ |
| ... | @@ -33995,7 +33583,6 @@ fn lowerBlock(self: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index | ... | @@ -33995,7 +33583,6 @@ fn lowerBlock(self: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index |
| 33995 | const inst_tracking_i = self.inst_tracking.count(); | 33583 | const inst_tracking_i = self.inst_tracking.count(); |
| 33996 | self.inst_tracking.putAssumeCapacityNoClobber(inst, .init(.unreach)); | 33584 | self.inst_tracking.putAssumeCapacityNoClobber(inst, .init(.unreach)); |
| 33997 | | 33585 | |
| 33998 | self.scope_generation += 1; | | |
| 33999 | try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() }); | 33586 | try self.blocks.putNoClobber(self.gpa, inst, .{ .state = self.initRetroactiveState() }); |
| 34000 | const liveness = self.liveness.getBlock(inst); | 33587 | const liveness = self.liveness.getBlock(inst); |
| 34001 | | 33588 | |
| ... | @@ -34033,6 +33620,8 @@ fn lowerSwitchBr( | ... | @@ -34033,6 +33620,8 @@ fn lowerSwitchBr( |
| 34033 | ) !void { | 33620 | ) !void { |
| 34034 | const zcu = self.pt.zcu; | 33621 | const zcu = self.pt.zcu; |
| 34035 | const condition_ty = self.typeOf(switch_br.operand); | 33622 | const condition_ty = self.typeOf(switch_br.operand); |
| | 33623 | const condition_int_info = self.intInfo(condition_ty).?; |
| | 33624 | const condition_int_ty = try self.pt.intType(condition_int_info.signedness, condition_int_info.bits); |
| 34036 | | 33625 | |
| 34037 | const ExpectedContents = extern struct { | 33626 | const ExpectedContents = extern struct { |
| 34038 | liveness_deaths: [1 << 8 | 1]Air.Inst.Index, | 33627 | liveness_deaths: [1 << 8 | 1]Air.Inst.Index, |
| ... | @@ -34043,7 +33632,6 @@ fn lowerSwitchBr( | ... | @@ -34043,7 +33632,6 @@ fn lowerSwitchBr( |
| 34043 | std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa); | 33632 | std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa); |
| 34044 | const allocator = stack.get(); | 33633 | const allocator = stack.get(); |
| 34045 | | 33634 | |
| 34046 | self.scope_generation += 1; | | |
| 34047 | const state = try self.saveState(); | 33635 | const state = try self.saveState(); |
| 34048 | | 33636 | |
| 34049 | const liveness = try self.liveness.getSwitchBr(allocator, inst, switch_br.cases_len + 1); | 33637 | const liveness = try self.liveness.getSwitchBr(allocator, inst, switch_br.cases_len + 1); |
| ... | @@ -34104,8 +33692,17 @@ fn lowerSwitchBr( | ... | @@ -34104,8 +33692,17 @@ fn lowerSwitchBr( |
| 34104 | .{ .air_ref = Air.internedToRef(min.?.toIntern()) }, | 33692 | .{ .air_ref = Air.internedToRef(min.?.toIntern()) }, |
| 34105 | ); | 33693 | ); |
| 34106 | const else_reloc = if (switch_br.else_body_len > 0) else_reloc: { | 33694 | const else_reloc = if (switch_br.else_body_len > 0) else_reloc: { |
| 34107 | try self.genBinOpMir(.{ ._, .cmp }, condition_ty, condition_index, .{ .immediate = table_len - 1 }); | 33695 | var cond_temp = try self.tempInit(condition_ty, condition_index); |
| 34108 | break :else_reloc try self.asmJccReloc(.a, undefined); | 33696 | var table_max_temp = try self.tempFromValue(try self.pt.intValue(condition_int_ty, table_len - 1)); |
| | 33697 | const cc_temp = cond_temp.cmpInts(.gt, &table_max_temp, self) catch |err| switch (err) { |
| | 33698 | error.SelectFailed => unreachable, |
| | 33699 | else => |e| return e, |
| | 33700 | }; |
| | 33701 | try cond_temp.die(self); |
| | 33702 | try table_max_temp.die(self); |
| | 33703 | const else_reloc = try self.asmJccReloc(cc_temp.tracking(self).short.eflags, undefined); |
| | 33704 | try cc_temp.die(self); |
| | 33705 | break :else_reloc else_reloc; |
| 34109 | } else undefined; | 33706 | } else undefined; |
| 34110 | const table_start: u31 = @intCast(self.mir_table.items.len); | 33707 | const table_start: u31 = @intCast(self.mir_table.items.len); |
| 34111 | { | 33708 | { |
| ... | @@ -34207,7 +33804,6 @@ fn lowerSwitchBr( | ... | @@ -34207,7 +33804,6 @@ fn lowerSwitchBr( |
| 34207 | return; | 33804 | return; |
| 34208 | } | 33805 | } |
| 34209 | | 33806 | |
| 34210 | const signedness = if (condition_ty.isAbiInt(zcu)) condition_ty.intInfo(zcu).signedness else .unsigned; | | |
| 34211 | var cases_it = switch_br.iterateCases(); | 33807 | var cases_it = switch_br.iterateCases(); |
| 34212 | while (cases_it.next()) |case| { | 33808 | while (cases_it.next()) |case| { |
| 34213 | var relocs = try allocator.alloc(Mir.Inst.Index, case.items.len + case.ranges.len); | 33809 | var relocs = try allocator.alloc(Mir.Inst.Index, case.items.len + case.ranges.len); |
| ... | @@ -34223,49 +33819,70 @@ fn lowerSwitchBr( | ... | @@ -34223,49 +33819,70 @@ fn lowerSwitchBr( |
| 34223 | else => unreachable, | 33819 | else => unreachable, |
| 34224 | }, | 33820 | }, |
| 34225 | else => cc: { | 33821 | else => cc: { |
| 34226 | try self.genBinOpMir(.{ ._, .cmp }, condition_ty, condition, item_mcv); | 33822 | var cond_temp = try self.tempInit(condition_ty, condition); |
| 34227 | break :cc .e; | 33823 | var item_temp = try self.tempInit(condition_ty, item_mcv); |
| | 33824 | const cc_temp = cond_temp.cmpInts(.eq, &item_temp, self) catch |err| switch (err) { |
| | 33825 | error.SelectFailed => unreachable, |
| | 33826 | else => |e| return e, |
| | 33827 | }; |
| | 33828 | try cond_temp.die(self); |
| | 33829 | try item_temp.die(self); |
| | 33830 | const cc = cc_temp.tracking(self).short.eflags; |
| | 33831 | try cc_temp.die(self); |
| | 33832 | try self.resetTemps(); |
| | 33833 | break :cc cc; |
| 34228 | }, | 33834 | }, |
| 34229 | }; | 33835 | }; |
| 34230 | reloc.* = try self.asmJccReloc(cc, undefined); | 33836 | reloc.* = try self.asmJccReloc(cc, undefined); |
| 34231 | } | 33837 | } |
| 34232 | | 33838 | |
| 34233 | for (case.ranges, relocs[case.items.len..]) |range, *reloc| { | 33839 | for (case.ranges, relocs[case.items.len..]) |range, *reloc| { |
| | 33840 | var cond_temp = try self.tempInit(condition_ty, condition); |
| 34234 | const min_mcv = try self.resolveInst(range[0]); | 33841 | const min_mcv = try self.resolveInst(range[0]); |
| 34235 | const max_mcv = try self.resolveInst(range[1]); | 33842 | const max_mcv = try self.resolveInst(range[1]); |
| 34236 | // `null` means always false. | 33843 | // `null` means always false. |
| 34237 | const lt_min: ?Condition = switch (condition) { | 33844 | const lt_min = cc: switch (condition) { |
| 34238 | .eflags => |cc| switch (min_mcv.immediate) { | 33845 | .eflags => |cc| switch (min_mcv.immediate) { |
| 34239 | 0 => null, // condition never <0 | 33846 | 0 => null, // condition never <0 |
| 34240 | 1 => cc.negate(), | 33847 | 1 => cc.negate(), |
| 34241 | else => unreachable, | 33848 | else => unreachable, |
| 34242 | }, | 33849 | }, |
| 34243 | else => cc: { | 33850 | else => { |
| 34244 | try self.genBinOpMir(.{ ._, .cmp }, condition_ty, condition, min_mcv); | 33851 | var min_temp = try self.tempInit(condition_ty, min_mcv); |
| 34245 | break :cc switch (signedness) { | 33852 | const cc_temp = cond_temp.cmpInts(.lt, &min_temp, self) catch |err| switch (err) { |
| 34246 | .unsigned => .b, | 33853 | error.SelectFailed => unreachable, |
| 34247 | .signed => .l, | 33854 | else => |e| return e, |
| 34248 | }; | 33855 | }; |
| | 33856 | try min_temp.die(self); |
| | 33857 | const cc = cc_temp.tracking(self).short.eflags; |
| | 33858 | try cc_temp.die(self); |
| | 33859 | break :cc cc; |
| 34249 | }, | 33860 | }, |
| 34250 | }; | 33861 | }; |
| 34251 | const lt_min_reloc = if (lt_min) |cc| r: { | 33862 | const lt_min_reloc = if (lt_min) |cc| r: { |
| 34252 | break :r try self.asmJccReloc(cc, undefined); | 33863 | break :r try self.asmJccReloc(cc, undefined); |
| 34253 | } else null; | 33864 | } else null; |
| 34254 | // `null` means always true. | 33865 | // `null` means always true. |
| 34255 | const lte_max: ?Condition = switch (condition) { | 33866 | const lte_max = switch (condition) { |
| 34256 | .eflags => |cc| switch (max_mcv.immediate) { | 33867 | .eflags => |cc| switch (max_mcv.immediate) { |
| 34257 | 0 => cc.negate(), | 33868 | 0 => cc.negate(), |
| 34258 | 1 => null, // condition always >=1 | 33869 | 1 => null, // condition always >=1 |
| 34259 | else => unreachable, | 33870 | else => unreachable, |
| 34260 | }, | 33871 | }, |
| 34261 | else => cc: { | 33872 | else => cc: { |
| 34262 | try self.genBinOpMir(.{ ._, .cmp }, condition_ty, condition, max_mcv); | 33873 | var max_temp = try self.tempInit(condition_ty, max_mcv); |
| 34263 | break :cc switch (signedness) { | 33874 | const cc_temp = cond_temp.cmpInts(.lte, &max_temp, self) catch |err| switch (err) { |
| 34264 | .unsigned => .be, | 33875 | error.SelectFailed => unreachable, |
| 34265 | .signed => .le, | 33876 | else => |e| return e, |
| 34266 | }; | 33877 | }; |
| | 33878 | try max_temp.die(self); |
| | 33879 | const cc = cc_temp.tracking(self).short.eflags; |
| | 33880 | try cc_temp.die(self); |
| | 33881 | break :cc cc; |
| 34267 | }, | 33882 | }, |
| 34268 | }; | 33883 | }; |
| | 33884 | try cond_temp.die(self); |
| | 33885 | try self.resetTemps(); |
| 34269 | // "Success" case is in `reloc`.... | 33886 | // "Success" case is in `reloc`.... |
| 34270 | if (lte_max) |cc| { | 33887 | if (lte_max) |cc| { |
| 34271 | reloc.* = try self.asmJccReloc(cc, undefined); | 33888 | reloc.* = try self.asmJccReloc(cc, undefined); |
| ... | @@ -34350,7 +33967,6 @@ fn airLoopSwitchBr(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -34350,7 +33967,6 @@ fn airLoopSwitchBr(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 34350 | // Ensure a register is available for dispatch. | 33967 | // Ensure a register is available for dispatch. |
| 34351 | if (!mat_cond.isRegister()) _ = try self.register_manager.allocReg(null, abi.RegisterClass.gp); | 33968 | if (!mat_cond.isRegister()) _ = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 34352 | | 33969 | |
| 34353 | self.scope_generation += 1; | | |
| 34354 | const state = try self.saveState(); | 33970 | const state = try self.saveState(); |
| 34355 | | 33971 | |
| 34356 | try self.loops.putNoClobber(self.gpa, inst, .{ | 33972 | try self.loops.putNoClobber(self.gpa, inst, .{ |
| ... | @@ -34403,6 +34019,8 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -34403,6 +34019,8 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 34403 | | 34019 | |
| 34404 | if (self.loop_switches.getPtr(br.block_inst)) |table| { | 34020 | if (self.loop_switches.getPtr(br.block_inst)) |table| { |
| 34405 | const condition_ty = self.typeOf(br.operand); | 34021 | const condition_ty = self.typeOf(br.operand); |
| | 34022 | const condition_int_info = self.intInfo(condition_ty).?; |
| | 34023 | const condition_int_ty = try self.pt.intType(condition_int_info.signedness, condition_int_info.bits); |
| 34406 | const condition_mcv = block_tracking.short; | 34024 | const condition_mcv = block_tracking.short; |
| 34407 | try self.spillEflagsIfOccupied(); | 34025 | try self.spillEflagsIfOccupied(); |
| 34408 | if (table.min.orderAgainstZero(self.pt.zcu).compare(.neq)) try self.genBinOpMir( | 34026 | if (table.min.orderAgainstZero(self.pt.zcu).compare(.neq)) try self.genBinOpMir( |
| ... | @@ -34414,12 +34032,28 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void { | ... | @@ -34414,12 +34032,28 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 34414 | switch (table.else_relocs) { | 34032 | switch (table.else_relocs) { |
| 34415 | .@"unreachable" => {}, | 34033 | .@"unreachable" => {}, |
| 34416 | .forward => |*else_relocs| { | 34034 | .forward => |*else_relocs| { |
| 34417 | try self.genBinOpMir(.{ ._, .cmp }, condition_ty, condition_mcv, .{ .immediate = table.len - 1 }); | 34035 | var cond_temp = try self.tempInit(condition_ty, condition_mcv); |
| 34418 | try else_relocs.append(self.gpa, try self.asmJccReloc(.a, undefined)); | 34036 | var table_max_temp = try self.tempFromValue(try self.pt.intValue(condition_int_ty, table.len - 1)); |
| | 34037 | const cc_temp = cond_temp.cmpInts(.gt, &table_max_temp, self) catch |err| switch (err) { |
| | 34038 | error.SelectFailed => unreachable, |
| | 34039 | else => |e| return e, |
| | 34040 | }; |
| | 34041 | try cond_temp.die(self); |
| | 34042 | try table_max_temp.die(self); |
| | 34043 | try else_relocs.append(self.gpa, try self.asmJccReloc(cc_temp.tracking(self).short.eflags, undefined)); |
| | 34044 | try cc_temp.die(self); |
| 34419 | }, | 34045 | }, |
| 34420 | .backward => |else_reloc| { | 34046 | .backward => |else_reloc| { |
| 34421 | try self.genBinOpMir(.{ ._, .cmp }, condition_ty, condition_mcv, .{ .immediate = table.len - 1 }); | 34047 | var cond_temp = try self.tempInit(condition_ty, condition_mcv); |
| 34422 | _ = try self.asmJccReloc(.a, else_reloc); | 34048 | var table_max_temp = try self.tempFromValue(try self.pt.intValue(condition_int_ty, table.len - 1)); |
| | 34049 | const cc_temp = cond_temp.cmpInts(.gt, &table_max_temp, self) catch |err| switch (err) { |
| | 34050 | error.SelectFailed => unreachable, |
| | 34051 | else => |e| return e, |
| | 34052 | }; |
| | 34053 | try cond_temp.die(self); |
| | 34054 | try table_max_temp.die(self); |
| | 34055 | _ = try self.asmJccReloc(cc_temp.tracking(self).short.eflags, else_reloc); |
| | 34056 | try cc_temp.die(self); |
| 34423 | }, | 34057 | }, |
| 34424 | } | 34058 | } |
| 34425 | { | 34059 | { |
| ... | @@ -35754,21 +35388,21 @@ fn genSetReg( | ... | @@ -35754,21 +35388,21 @@ fn genSetReg( |
| 35754 | => unreachable, | 35388 | => unreachable, |
| 35755 | .undef => if (opts.safety) switch (dst_reg.class()) { | 35389 | .undef => if (opts.safety) switch (dst_reg.class()) { |
| 35756 | .general_purpose => switch (abi_size) { | 35390 | .general_purpose => switch (abi_size) { |
| 35757 | 1 => try self.asmRegisterImmediate(.{ ._, .mov }, dst_reg.to8(), .u(0xAA)), | 35391 | 1 => try self.asmRegisterImmediate(.{ ._, .mov }, dst_reg.to8(), .u(0xaa)), |
| 35758 | 2 => try self.asmRegisterImmediate(.{ ._, .mov }, dst_reg.to16(), .u(0xAAAA)), | 35392 | 2 => try self.asmRegisterImmediate(.{ ._, .mov }, dst_reg.to16(), .u(0xaaaa)), |
| 35759 | 3...4 => try self.asmRegisterImmediate( | 35393 | 3...4 => try self.asmRegisterImmediate( |
| 35760 | .{ ._, .mov }, | 35394 | .{ ._, .mov }, |
| 35761 | dst_reg.to32(), | 35395 | dst_reg.to32(), |
| 35762 | .s(@as(i32, @bitCast(@as(u32, 0xAAAAAAAA)))), | 35396 | .s(@as(i32, @bitCast(@as(u32, 0xaaaaaaaa)))), |
| 35763 | ), | 35397 | ), |
| 35764 | 5...8 => try self.asmRegisterImmediate( | 35398 | 5...8 => try self.asmRegisterImmediate( |
| 35765 | .{ ._, .mov }, | 35399 | .{ ._, .mov }, |
| 35766 | dst_reg.to64(), | 35400 | dst_reg.to64(), |
| 35767 | .u(0xAAAAAAAAAAAAAAAA), | 35401 | .u(0xaaaaaaaaaaaaaaaa), |
| 35768 | ), | 35402 | ), |
| 35769 | else => unreachable, | 35403 | else => unreachable, |
| 35770 | }, | 35404 | }, |
| 35771 | .segment, .x87, .mmx, .sse => { | 35405 | .segment, .mmx, .sse => { |
| 35772 | const full_ty = try pt.vectorType(.{ | 35406 | const full_ty = try pt.vectorType(.{ |
| 35773 | .len = self.vectorSize(.float), | 35407 | .len = self.vectorSize(.float), |
| 35774 | .child = .u8_type, | 35408 | .child = .u8_type, |
| ... | @@ -35780,6 +35414,9 @@ fn genSetReg( | ... | @@ -35780,6 +35414,9 @@ fn genSetReg( |
| 35780 | } })), | 35414 | } })), |
| 35781 | ), opts); | 35415 | ), opts); |
| 35782 | }, | 35416 | }, |
| | 35417 | .x87 => try self.genSetReg(dst_reg, .f80, try self.genTypedValue( |
| | 35418 | try pt.floatValue(.f80, @as(f80, @bitCast(@as(u80, 0xaaaaaaaaaaaaaaaaaaaa)))), |
| | 35419 | ), opts), |
| 35783 | .ip, .cr, .dr => unreachable, | 35420 | .ip, .cr, .dr => unreachable, |
| 35784 | }, | 35421 | }, |
| 35785 | .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()), | 35422 | .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()), |
| ... | @@ -40161,8 +39798,16 @@ fn resolveCallingConventionValues( | ... | @@ -40161,8 +39798,16 @@ fn resolveCallingConventionValues( |
| 40161 | const zcu = pt.zcu; | 39798 | const zcu = pt.zcu; |
| 40162 | const ip = &zcu.intern_pool; | 39799 | const ip = &zcu.intern_pool; |
| 40163 | const cc = fn_info.cc; | 39800 | const cc = fn_info.cc; |
| 40164 | const param_types = try self.gpa.alloc(Type, fn_info.param_types.len + var_args.len); | 39801 | |
| 40165 | defer self.gpa.free(param_types); | 39802 | const ExpectedContents = extern struct { |
| | 39803 | param_types: [32][@sizeOf(Type)]u8 align(@alignOf(Type)), |
| | 39804 | }; |
| | 39805 | var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) = |
| | 39806 | std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa); |
| | 39807 | const allocator = stack.get(); |
| | 39808 | |
| | 39809 | const param_types = try allocator.alloc(Type, fn_info.param_types.len + var_args.len); |
| | 39810 | defer allocator.free(param_types); |
| 40166 | | 39811 | |
| 40167 | for (param_types[0..fn_info.param_types.len], fn_info.param_types.get(ip)) |*dest, src| | 39812 | for (param_types[0..fn_info.param_types.len], fn_info.param_types.get(ip)) |*dest, src| |
| 40168 | dest.* = .fromInterned(src); | 39813 | dest.* = .fromInterned(src); |
| ... | @@ -40735,6 +40380,11 @@ fn hasFeature(cg: *CodeGen, feature: std.Target.x86.Feature) bool { | ... | @@ -40735,6 +40380,11 @@ fn hasFeature(cg: *CodeGen, feature: std.Target.x86.Feature) bool { |
| 40735 | .ReleaseSmall => true, | 40380 | .ReleaseSmall => true, |
| 40736 | }, | 40381 | }, |
| 40737 | .mmx => false, | 40382 | .mmx => false, |
| | 40383 | .sahf => switch (cg.target.cpu.arch) { |
| | 40384 | else => unreachable, |
| | 40385 | .x86 => true, |
| | 40386 | .x86_64 => null, |
| | 40387 | }, |
| 40738 | else => null, | 40388 | else => null, |
| 40739 | } orelse std.Target.x86.featureSetHas(cg.target.cpu.features, feature); | 40389 | } orelse std.Target.x86.featureSetHas(cg.target.cpu.features, feature); |
| 40740 | } | 40390 | } |
| ... | @@ -40746,8 +40396,7 @@ fn typeOf(self: *CodeGen, inst: Air.Inst.Ref) Type { | ... | @@ -40746,8 +40396,7 @@ fn typeOf(self: *CodeGen, inst: Air.Inst.Ref) Type { |
| 40746 | } | 40396 | } |
| 40747 | | 40397 | |
| 40748 | fn typeOfIndex(self: *CodeGen, inst: Air.Inst.Index) Type { | 40398 | fn typeOfIndex(self: *CodeGen, inst: Air.Inst.Index) Type { |
| 40749 | const temp: Temp = .{ .index = inst }; | 40399 | return Temp.typeOf(.{ .index = inst }, self); |
| 40750 | return temp.typeOf(self); | | |
| 40751 | } | 40400 | } |
| 40752 | | 40401 | |
| 40753 | fn intCompilerRtAbiName(int_bits: u32) u8 { | 40402 | fn intCompilerRtAbiName(int_bits: u32) u8 { |
| ... | @@ -40777,980 +40426,1922 @@ fn floatCompilerRtAbiType(self: *CodeGen, ty: Type, other_ty: Type) Type { | ... | @@ -40777,980 +40426,1922 @@ fn floatCompilerRtAbiType(self: *CodeGen, ty: Type, other_ty: Type) Type { |
| 40777 | return ty; | 40426 | return ty; |
| 40778 | } | 40427 | } |
| 40779 | | 40428 | |
| 40780 | fn floatLibcAbiPrefix(ty: Type) []const u8 { | 40429 | fn floatLibcAbiPrefix(ty: Type) []const u8 { |
| 40781 | return switch (ty.toIntern()) { | 40430 | return switch (ty.toIntern()) { |
| 40782 | .f16_type, .f80_type => "__", | 40431 | .f16_type, .f80_type => "__", |
| 40783 | .f32_type, .f64_type, .f128_type, .c_longdouble_type => "", | 40432 | .f32_type, .f64_type, .f128_type, .c_longdouble_type => "", |
| 40784 | else => unreachable, | 40433 | else => unreachable, |
| 40785 | }; | 40434 | }; |
| 40786 | } | 40435 | } |
| | 40436 | |
| | 40437 | fn floatLibcAbiSuffix(ty: Type) []const u8 { |
| | 40438 | return switch (ty.toIntern()) { |
| | 40439 | .f16_type => "h", |
| | 40440 | .f32_type => "f", |
| | 40441 | .f64_type => "", |
| | 40442 | .f80_type => "x", |
| | 40443 | .f128_type => "q", |
| | 40444 | .c_longdouble_type => "l", |
| | 40445 | else => unreachable, |
| | 40446 | }; |
| | 40447 | } |
| | 40448 | |
| | 40449 | fn promoteInt(self: *CodeGen, ty: Type) Type { |
| | 40450 | const pt = self.pt; |
| | 40451 | const zcu = pt.zcu; |
| | 40452 | const int_info: InternPool.Key.IntType = switch (ty.toIntern()) { |
| | 40453 | .bool_type => .{ .signedness = .unsigned, .bits = 1 }, |
| | 40454 | else => if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else return ty, |
| | 40455 | }; |
| | 40456 | for ([_]Type{ |
| | 40457 | .c_int, .c_uint, |
| | 40458 | .c_long, .c_ulong, |
| | 40459 | .c_longlong, .c_ulonglong, |
| | 40460 | }) |promote_ty| { |
| | 40461 | const promote_info = promote_ty.intInfo(zcu); |
| | 40462 | if (int_info.signedness == .signed and promote_info.signedness == .unsigned) continue; |
| | 40463 | if (int_info.bits + @intFromBool(int_info.signedness == .unsigned and |
| | 40464 | promote_info.signedness == .signed) <= promote_info.bits) return promote_ty; |
| | 40465 | } |
| | 40466 | return ty; |
| | 40467 | } |
| | 40468 | |
| | 40469 | fn promoteVarArg(self: *CodeGen, ty: Type) Type { |
| | 40470 | if (!ty.isRuntimeFloat()) return self.promoteInt(ty); |
| | 40471 | switch (ty.floatBits(self.target.*)) { |
| | 40472 | 32, 64 => return .f64, |
| | 40473 | else => |float_bits| { |
| | 40474 | assert(float_bits == self.target.cTypeBitSize(.longdouble)); |
| | 40475 | return .c_longdouble; |
| | 40476 | }, |
| | 40477 | } |
| | 40478 | } |
| | 40479 | |
| | 40480 | fn unalignedSize(cg: *CodeGen, ty: Type) u64 { |
| | 40481 | const zcu = cg.pt.zcu; |
| | 40482 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { |
| | 40483 | .vector_type => |vector_type| Type.fromInterned(vector_type.child).abiSize(zcu) * vector_type.len, |
| | 40484 | else => ty.abiSize(zcu), |
| | 40485 | }; |
| | 40486 | } |
| | 40487 | |
| | 40488 | fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int { |
| | 40489 | const zcu = cg.pt.zcu; |
| | 40490 | const ip = &zcu.intern_pool; |
| | 40491 | var ty_index = ty.ip_index; |
| | 40492 | while (true) switch (ip.indexToKey(ty_index)) { |
| | 40493 | .int_type => |int_type| return int_type, |
| | 40494 | .ptr_type => |ptr_type| return switch (ptr_type.flags.size) { |
| | 40495 | .one, .many, .c => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() }, |
| | 40496 | .slice => null, |
| | 40497 | }, |
| | 40498 | .opt_type => |opt_child| return if (!Type.fromInterned(opt_child).hasRuntimeBitsIgnoreComptime(zcu)) |
| | 40499 | .{ .signedness = .unsigned, .bits = 1 } |
| | 40500 | else switch (ip.indexToKey(opt_child)) { |
| | 40501 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { |
| | 40502 | .one, .many => switch (ptr_type.flags.is_allowzero) { |
| | 40503 | false => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() }, |
| | 40504 | true => null, |
| | 40505 | }, |
| | 40506 | .slice, .c => null, |
| | 40507 | }, |
| | 40508 | else => null, |
| | 40509 | }, |
| | 40510 | .error_union_type => |error_union_type| return if (!Type.fromInterned(error_union_type.payload_type) |
| | 40511 | .hasRuntimeBitsIgnoreComptime(zcu)) .{ .signedness = .unsigned, .bits = zcu.errorSetBits() } else null, |
| | 40512 | .simple_type => |simple_type| return switch (simple_type) { |
| | 40513 | .bool => .{ .signedness = .unsigned, .bits = 1 }, |
| | 40514 | .anyerror => .{ .signedness = .unsigned, .bits = zcu.errorSetBits() }, |
| | 40515 | .isize => .{ .signedness = .signed, .bits = cg.target.ptrBitWidth() }, |
| | 40516 | .usize => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() }, |
| | 40517 | .c_char => .{ .signedness = cg.target.charSignedness(), .bits = cg.target.cTypeBitSize(.char) }, |
| | 40518 | .c_short => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.short) }, |
| | 40519 | .c_ushort => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.short) }, |
| | 40520 | .c_int => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.int) }, |
| | 40521 | .c_uint => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.int) }, |
| | 40522 | .c_long => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.long) }, |
| | 40523 | .c_ulong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.long) }, |
| | 40524 | .c_longlong => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.longlong) }, |
| | 40525 | .c_ulonglong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.longlong) }, |
| | 40526 | .f16, .f32, .f64, .f80, .f128, .c_longdouble => null, |
| | 40527 | .anyopaque, |
| | 40528 | .void, |
| | 40529 | .type, |
| | 40530 | .comptime_int, |
| | 40531 | .comptime_float, |
| | 40532 | .noreturn, |
| | 40533 | .null, |
| | 40534 | .undefined, |
| | 40535 | .enum_literal, |
| | 40536 | .adhoc_inferred_error_set, |
| | 40537 | .generic_poison, |
| | 40538 | => unreachable, |
| | 40539 | }, |
| | 40540 | .struct_type => { |
| | 40541 | const loaded_struct = ip.loadStructType(ty_index); |
| | 40542 | switch (loaded_struct.layout) { |
| | 40543 | .auto, .@"extern" => return null, |
| | 40544 | .@"packed" => ty_index = loaded_struct.backingIntTypeUnordered(ip), |
| | 40545 | } |
| | 40546 | }, |
| | 40547 | .union_type => return switch (ip.loadUnionType(ty_index).flagsUnordered(ip).layout) { |
| | 40548 | .auto, .@"extern" => null, |
| | 40549 | .@"packed" => .{ .signedness = .unsigned, .bits = @intCast(ty.bitSize(zcu)) }, |
| | 40550 | }, |
| | 40551 | .enum_type => ty_index = ip.loadEnumType(ty_index).tag_ty, |
| | 40552 | .error_set_type, .inferred_error_set_type => return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() }, |
| | 40553 | else => return null, |
| | 40554 | }; |
| | 40555 | } |
| | 40556 | |
| | 40557 | fn floatBits(cg: *CodeGen, ty: Type) ?u16 { |
| | 40558 | return if (ty.isRuntimeFloat()) ty.floatBits(cg.target.*) else null; |
| | 40559 | } |
| | 40560 | |
| | 40561 | const Temp = struct { |
| | 40562 | index: Air.Inst.Index, |
| | 40563 | |
| | 40564 | fn unwrap(temp: Temp, cg: *CodeGen) union(enum) { |
| | 40565 | ref: Air.Inst.Ref, |
| | 40566 | temp: Index, |
| | 40567 | err_ret_trace, |
| | 40568 | } { |
| | 40569 | switch (temp.index.unwrap()) { |
| | 40570 | .ref => |ref| return .{ .ref = ref }, |
| | 40571 | .target => |target_index| { |
| | 40572 | if (temp.index == err_ret_trace_index) return .err_ret_trace; |
| | 40573 | const temp_index: Index = @enumFromInt(target_index); |
| | 40574 | assert(temp_index.isValid(cg)); |
| | 40575 | return .{ .temp = temp_index }; |
| | 40576 | }, |
| | 40577 | } |
| | 40578 | } |
| | 40579 | |
| | 40580 | fn typeOf(temp: Temp, cg: *CodeGen) Type { |
| | 40581 | return switch (temp.unwrap(cg)) { |
| | 40582 | .ref => switch (cg.air.instructions.items(.tag)[@intFromEnum(temp.index)]) { |
| | 40583 | .loop_switch_br => cg.typeOf(cg.air.unwrapSwitch(temp.index).operand), |
| | 40584 | else => cg.air.typeOfIndex(temp.index, &cg.pt.zcu.intern_pool), |
| | 40585 | }, |
| | 40586 | .temp => |temp_index| temp_index.typeOf(cg), |
| | 40587 | .err_ret_trace => .usize, |
| | 40588 | }; |
| | 40589 | } |
| | 40590 | |
| | 40591 | fn isMut(temp: Temp, cg: *CodeGen) bool { |
| | 40592 | return switch (temp.unwrap(cg)) { |
| | 40593 | .ref, .err_ret_trace => false, |
| | 40594 | .temp => |temp_index| switch (temp_index.tracking(cg).short) { |
| | 40595 | .none, |
| | 40596 | .unreach, |
| | 40597 | .dead, |
| | 40598 | .undef, |
| | 40599 | .immediate, |
| | 40600 | .eflags, |
| | 40601 | .register_offset, |
| | 40602 | .register_mask, |
| | 40603 | .memory, |
| | 40604 | .load_symbol, |
| | 40605 | .lea_symbol, |
| | 40606 | .indirect, |
| | 40607 | .load_direct, |
| | 40608 | .lea_direct, |
| | 40609 | .load_got, |
| | 40610 | .lea_got, |
| | 40611 | .load_tlv, |
| | 40612 | .lea_tlv, |
| | 40613 | .lea_frame, |
| | 40614 | .elementwise_regs_then_frame, |
| | 40615 | .reserved_frame, |
| | 40616 | .air_ref, |
| | 40617 | => false, |
| | 40618 | .register, |
| | 40619 | .register_pair, |
| | 40620 | .register_triple, |
| | 40621 | .register_quadruple, |
| | 40622 | .register_overflow, |
| | 40623 | => true, |
| | 40624 | .load_frame => |frame_addr| !frame_addr.index.isNamed(), |
| | 40625 | }, |
| | 40626 | }; |
| | 40627 | } |
| | 40628 | |
| | 40629 | fn tracking(temp: Temp, cg: *CodeGen) InstTracking { |
| | 40630 | return cg.inst_tracking.get(temp.index).?; |
| | 40631 | } |
| | 40632 | |
| | 40633 | fn getOffset(temp: Temp, off: i32, cg: *CodeGen) !Temp { |
| | 40634 | const new_temp_index = cg.next_temp_index; |
| | 40635 | cg.temp_type[@intFromEnum(new_temp_index)] = .usize; |
| | 40636 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| | 40637 | switch (temp.tracking(cg).short) { |
| | 40638 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| | 40639 | .register => |reg| { |
| | 40640 | const new_reg = |
| | 40641 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| | 40642 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| | 40643 | try cg.asmRegisterMemory(.{ ._, .lea }, new_reg.to64(), .{ |
| | 40644 | .base = .{ .reg = reg.to64() }, |
| | 40645 | .mod = .{ .rm = .{ |
| | 40646 | .size = .qword, |
| | 40647 | .disp = off, |
| | 40648 | } }, |
| | 40649 | }); |
| | 40650 | }, |
| | 40651 | .register_offset => |reg_off| { |
| | 40652 | const new_reg = |
| | 40653 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| | 40654 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| | 40655 | try cg.asmRegisterMemory(.{ ._, .lea }, new_reg.to64(), .{ |
| | 40656 | .base = .{ .reg = reg_off.reg.to64() }, |
| | 40657 | .mod = .{ .rm = .{ |
| | 40658 | .size = .qword, |
| | 40659 | .disp = reg_off.off + off, |
| | 40660 | } }, |
| | 40661 | }); |
| | 40662 | }, |
| | 40663 | .lea_symbol => |sym_off| new_temp_index.tracking(cg).* = .init(.{ .lea_symbol = .{ |
| | 40664 | .sym_index = sym_off.sym_index, |
| | 40665 | .off = sym_off.off + off, |
| | 40666 | } }), |
| | 40667 | .load_frame => |frame_addr| { |
| | 40668 | const new_reg = |
| | 40669 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| | 40670 | new_temp_index.tracking(cg).* = .init(.{ .register_offset = .{ |
| | 40671 | .reg = new_reg, |
| | 40672 | .off = off, |
| | 40673 | } }); |
| | 40674 | try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ |
| | 40675 | .base = .{ .frame = frame_addr.index }, |
| | 40676 | .mod = .{ .rm = .{ |
| | 40677 | .size = .qword, |
| | 40678 | .disp = frame_addr.off, |
| | 40679 | } }, |
| | 40680 | }); |
| | 40681 | }, |
| | 40682 | .lea_frame => |frame_addr| new_temp_index.tracking(cg).* = .init(.{ .lea_frame = .{ |
| | 40683 | .index = frame_addr.index, |
| | 40684 | .off = frame_addr.off + off, |
| | 40685 | } }), |
| | 40686 | } |
| | 40687 | return .{ .index = new_temp_index.toIndex() }; |
| | 40688 | } |
| | 40689 | |
| | 40690 | fn toOffset(temp: *Temp, off: i32, cg: *CodeGen) !void { |
| | 40691 | if (off == 0) return; |
| | 40692 | switch (temp.unwrap(cg)) { |
| | 40693 | .ref, .err_ret_trace => {}, |
| | 40694 | .temp => |temp_index| { |
| | 40695 | const temp_tracking = temp_index.tracking(cg); |
| | 40696 | switch (temp_tracking.short) { |
| | 40697 | else => {}, |
| | 40698 | .register => |reg| { |
| | 40699 | try cg.freeValue(temp_tracking.long); |
| | 40700 | temp_tracking.* = .init(.{ .register_offset = .{ |
| | 40701 | .reg = reg, |
| | 40702 | .off = off, |
| | 40703 | } }); |
| | 40704 | return; |
| | 40705 | }, |
| | 40706 | .register_offset => |reg_off| { |
| | 40707 | try cg.freeValue(temp_tracking.long); |
| | 40708 | temp_tracking.* = .init(.{ .register_offset = .{ |
| | 40709 | .reg = reg_off.reg, |
| | 40710 | .off = reg_off.off + off, |
| | 40711 | } }); |
| | 40712 | return; |
| | 40713 | }, |
| | 40714 | .lea_symbol => |sym_off| { |
| | 40715 | assert(std.meta.eql(temp_tracking.long.lea_symbol, sym_off)); |
| | 40716 | temp_tracking.* = .init(.{ .lea_symbol = .{ |
| | 40717 | .sym_index = sym_off.sym_index, |
| | 40718 | .off = sym_off.off + off, |
| | 40719 | } }); |
| | 40720 | return; |
| | 40721 | }, |
| | 40722 | .lea_frame => |frame_addr| { |
| | 40723 | assert(std.meta.eql(temp_tracking.long.lea_frame, frame_addr)); |
| | 40724 | temp_tracking.* = .init(.{ .lea_frame = .{ |
| | 40725 | .index = frame_addr.index, |
| | 40726 | .off = frame_addr.off + off, |
| | 40727 | } }); |
| | 40728 | return; |
| | 40729 | }, |
| | 40730 | } |
| | 40731 | }, |
| | 40732 | } |
| | 40733 | const new_temp = try temp.getOffset(off, cg); |
| | 40734 | try temp.die(cg); |
| | 40735 | temp.* = new_temp; |
| | 40736 | } |
| | 40737 | |
| | 40738 | fn getLimb(temp: Temp, limb_ty: Type, limb_index: u28, cg: *CodeGen) !Temp { |
| | 40739 | const new_temp_index = cg.next_temp_index; |
| | 40740 | cg.temp_type[@intFromEnum(new_temp_index)] = limb_ty; |
| | 40741 | switch (temp.tracking(cg).short) { |
| | 40742 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| | 40743 | .immediate => |imm| { |
| | 40744 | assert(limb_index == 0); |
| | 40745 | new_temp_index.tracking(cg).* = .init(.{ .immediate = imm }); |
| | 40746 | }, |
| | 40747 | .register => |reg| { |
| | 40748 | assert(limb_index == 0); |
| | 40749 | const new_reg = |
| | 40750 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| | 40751 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| | 40752 | try cg.asmRegisterRegister(.{ ._, .mov }, new_reg.to64(), reg.to64()); |
| | 40753 | }, |
| | 40754 | .register_pair => |regs| { |
| | 40755 | const new_reg = |
| | 40756 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| | 40757 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| | 40758 | try cg.asmRegisterRegister(.{ ._, .mov }, new_reg.to64(), regs[limb_index].to64()); |
| | 40759 | }, |
| | 40760 | .register_offset => |reg_off| { |
| | 40761 | assert(limb_index == 0); |
| | 40762 | const new_reg = |
| | 40763 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| | 40764 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| | 40765 | try cg.asmRegisterMemory(.{ ._, .lea }, new_reg.to64(), .{ |
| | 40766 | .base = .{ .reg = reg_off.reg.to64() }, |
| | 40767 | .mod = .{ .rm = .{ |
| | 40768 | .size = .qword, |
| | 40769 | .disp = reg_off.off + @as(u31, limb_index) * 8, |
| | 40770 | } }, |
| | 40771 | }); |
| | 40772 | }, |
| | 40773 | .load_symbol => |sym_off| { |
| | 40774 | const new_reg = |
| | 40775 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| | 40776 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| | 40777 | try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ |
| | 40778 | .base = .{ .reloc = sym_off.sym_index }, |
| | 40779 | .mod = .{ .rm = .{ |
| | 40780 | .size = .qword, |
| | 40781 | .disp = sym_off.off + @as(u31, limb_index) * 8, |
| | 40782 | } }, |
| | 40783 | }); |
| | 40784 | }, |
| | 40785 | .lea_symbol => |sym_off| { |
| | 40786 | assert(limb_index == 0); |
| | 40787 | new_temp_index.tracking(cg).* = .init(.{ .lea_symbol = sym_off }); |
| | 40788 | }, |
| | 40789 | .load_frame => |frame_addr| { |
| | 40790 | const new_reg = |
| | 40791 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| | 40792 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| | 40793 | try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ |
| | 40794 | .base = .{ .frame = frame_addr.index }, |
| | 40795 | .mod = .{ .rm = .{ |
| | 40796 | .size = .qword, |
| | 40797 | .disp = frame_addr.off + @as(u31, limb_index) * 8, |
| | 40798 | } }, |
| | 40799 | }); |
| | 40800 | }, |
| | 40801 | .lea_frame => |frame_addr| { |
| | 40802 | assert(limb_index == 0); |
| | 40803 | new_temp_index.tracking(cg).* = .init(.{ .lea_frame = frame_addr }); |
| | 40804 | }, |
| | 40805 | } |
| | 40806 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| | 40807 | return .{ .index = new_temp_index.toIndex() }; |
| | 40808 | } |
| | 40809 | |
| | 40810 | fn toLimb(temp: *Temp, limb_ty: Type, limb_index: u28, cg: *CodeGen) !void { |
| | 40811 | switch (temp.unwrap(cg)) { |
| | 40812 | .ref => {}, |
| | 40813 | .temp => |temp_index| { |
| | 40814 | const temp_tracking = temp_index.tracking(cg); |
| | 40815 | switch (temp_tracking.short) { |
| | 40816 | else => {}, |
| | 40817 | .register, .lea_symbol, .lea_frame => { |
| | 40818 | assert(limb_index == 0); |
| | 40819 | cg.temp_type[@intFromEnum(temp_index)] = limb_ty; |
| | 40820 | return; |
| | 40821 | }, |
| | 40822 | .register_pair => |regs| { |
| | 40823 | switch (temp_tracking.long) { |
| | 40824 | .none, .reserved_frame => {}, |
| | 40825 | else => temp_tracking.long = |
| | 40826 | temp_tracking.long.address().offset(@as(u31, limb_index) * 8).deref(), |
| | 40827 | } |
| | 40828 | for (regs, 0..) |reg, reg_index| if (reg_index != limb_index) |
| | 40829 | cg.register_manager.freeReg(reg); |
| | 40830 | temp_tracking.* = .init(.{ .register = regs[limb_index] }); |
| | 40831 | cg.temp_type[@intFromEnum(temp_index)] = limb_ty; |
| | 40832 | return; |
| | 40833 | }, |
| | 40834 | .load_symbol => |sym_off| { |
| | 40835 | assert(std.meta.eql(temp_tracking.long.load_symbol, sym_off)); |
| | 40836 | temp_tracking.* = .init(.{ .load_symbol = .{ |
| | 40837 | .sym_index = sym_off.sym_index, |
| | 40838 | .off = sym_off.off + @as(u31, limb_index) * 8, |
| | 40839 | } }); |
| | 40840 | cg.temp_type[@intFromEnum(temp_index)] = limb_ty; |
| | 40841 | return; |
| | 40842 | }, |
| | 40843 | .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) { |
| | 40844 | assert(std.meta.eql(temp_tracking.long.load_frame, frame_addr)); |
| | 40845 | temp_tracking.* = .init(.{ .load_frame = .{ |
| | 40846 | .index = frame_addr.index, |
| | 40847 | .off = frame_addr.off + @as(u31, limb_index) * 8, |
| | 40848 | } }); |
| | 40849 | cg.temp_type[@intFromEnum(temp_index)] = limb_ty; |
| | 40850 | return; |
| | 40851 | }, |
| | 40852 | } |
| | 40853 | }, |
| | 40854 | .err_ret_trace => unreachable, |
| | 40855 | } |
| | 40856 | const new_temp = try temp.getLimb(limb_ty, limb_index, cg); |
| | 40857 | try temp.die(cg); |
| | 40858 | temp.* = new_temp; |
| | 40859 | } |
| | 40860 | |
| | 40861 | fn toSlicePtr(temp: *Temp, cg: *CodeGen) !void { |
| | 40862 | const temp_ty = temp.typeOf(cg); |
| | 40863 | if (temp_ty.isSlice(cg.pt.zcu)) try temp.toLimb(temp_ty.slicePtrFieldType(cg.pt.zcu), 0, cg); |
| | 40864 | } |
| | 40865 | |
| | 40866 | fn toSliceLen(temp: *Temp, cg: *CodeGen) !void { |
| | 40867 | try temp.toLimb(.usize, 1, cg); |
| | 40868 | } |
| | 40869 | |
| | 40870 | fn toReg(temp: *Temp, new_reg: Register, cg: *CodeGen) !bool { |
| | 40871 | const val, const ty: Type = val_ty: switch (temp.unwrap(cg)) { |
| | 40872 | .ref => |ref| .{ temp.tracking(cg).short, cg.typeOf(ref) }, |
| | 40873 | .temp => |temp_index| { |
| | 40874 | const temp_tracking = temp_index.tracking(cg); |
| | 40875 | if (temp_tracking.short == .register and |
| | 40876 | temp_tracking.short.register == new_reg) return false; |
| | 40877 | break :val_ty .{ temp_tracking.short, temp_index.typeOf(cg) }; |
| | 40878 | }, |
| | 40879 | .err_ret_trace => .{ temp.tracking(cg).short, .usize }, |
| | 40880 | }; |
| | 40881 | const new_temp_index = cg.next_temp_index; |
| | 40882 | try cg.register_manager.getReg(new_reg, new_temp_index.toIndex()); |
| | 40883 | cg.temp_type[@intFromEnum(new_temp_index)] = ty; |
| | 40884 | try cg.genSetReg(new_reg, ty, val, .{}); |
| | 40885 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| | 40886 | try temp.die(cg); |
| | 40887 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| | 40888 | temp.* = .{ .index = new_temp_index.toIndex() }; |
| | 40889 | return true; |
| | 40890 | } |
| | 40891 | |
| | 40892 | fn toRegClass(temp: *Temp, mut: bool, rc: Register.Class, cg: *CodeGen) !bool { |
| | 40893 | const val = temp.tracking(cg).short; |
| | 40894 | if (!mut or temp.isMut(cg)) switch (val) { |
| | 40895 | else => {}, |
| | 40896 | .register => |reg| if (reg.class() == rc) return false, |
| | 40897 | .register_offset => |reg_off| if (reg_off.reg.class() == rc and reg_off.off == 0) return false, |
| | 40898 | }; |
| | 40899 | const ty = temp.typeOf(cg); |
| | 40900 | const new_temp_index = cg.next_temp_index; |
| | 40901 | cg.temp_type[@intFromEnum(new_temp_index)] = ty; |
| | 40902 | const new_reg = try cg.register_manager.allocReg(new_temp_index.toIndex(), regSetForRegClass(rc)); |
| | 40903 | try cg.genSetReg(new_reg, ty, val, .{}); |
| | 40904 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); |
| | 40905 | try temp.die(cg); |
| | 40906 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| | 40907 | temp.* = .{ .index = new_temp_index.toIndex() }; |
| | 40908 | return true; |
| | 40909 | } |
| | 40910 | |
| | 40911 | fn toPair(first_temp: *Temp, second_temp: *Temp, cg: *CodeGen) !void { |
| | 40912 | while (true) for ([_]*Temp{ first_temp, second_temp }) |part_temp| { |
| | 40913 | if (try part_temp.toRegClass(true, .general_purpose, cg)) break; |
| | 40914 | } else break; |
| | 40915 | const first_temp_tracking = first_temp.unwrap(cg).temp.tracking(cg); |
| | 40916 | const second_temp_tracking = second_temp.unwrap(cg).temp.tracking(cg); |
| | 40917 | const result: MCValue = .{ .register_pair = .{ |
| | 40918 | first_temp_tracking.short.register, |
| | 40919 | second_temp_tracking.short.register, |
| | 40920 | } }; |
| | 40921 | const result_temp_index = cg.next_temp_index; |
| | 40922 | const result_temp: Temp = .{ .index = result_temp_index.toIndex() }; |
| | 40923 | assert(cg.reuseTemp(result_temp.index, first_temp.index, first_temp_tracking)); |
| | 40924 | assert(cg.reuseTemp(result_temp.index, second_temp.index, second_temp_tracking)); |
| | 40925 | cg.temp_type[@intFromEnum(result_temp_index)] = .slice_const_u8; |
| | 40926 | result_temp_index.tracking(cg).* = .init(result); |
| | 40927 | first_temp.* = result_temp; |
| | 40928 | second_temp.* = result_temp; |
| | 40929 | } |
| | 40930 | |
| | 40931 | fn asMask(temp: Temp, info: MaskInfo, cg: *CodeGen) void { |
| | 40932 | assert(info.scalar != .none); |
| | 40933 | const mcv = &temp.unwrap(cg).temp.tracking(cg).short; |
| | 40934 | const reg = mcv.register; |
| | 40935 | mcv.* = .{ .register_mask = .{ .reg = reg, .info = info } }; |
| | 40936 | } |
| 40787 | | 40937 | |
| 40788 | fn floatLibcAbiSuffix(ty: Type) []const u8 { | 40938 | fn toLea(temp: *Temp, cg: *CodeGen) !bool { |
| 40789 | return switch (ty.toIntern()) { | 40939 | switch (temp.tracking(cg).short) { |
| 40790 | .f16_type => "h", | 40940 | .none, |
| 40791 | .f32_type => "f", | 40941 | .unreach, |
| 40792 | .f64_type => "", | 40942 | .dead, |
| 40793 | .f80_type => "x", | 40943 | .undef, |
| 40794 | .f128_type => "q", | 40944 | .eflags, |
| 40795 | .c_longdouble_type => "l", | 40945 | .register_pair, |
| 40796 | else => unreachable, | 40946 | .register_triple, |
| 40797 | }; | 40947 | .register_quadruple, |
| 40798 | } | 40948 | .register_overflow, |
| | 40949 | .register_mask, |
| | 40950 | .elementwise_regs_then_frame, |
| | 40951 | .reserved_frame, |
| | 40952 | .air_ref, |
| | 40953 | => unreachable, // not a valid pointer |
| | 40954 | .immediate, |
| | 40955 | .register, |
| | 40956 | .register_offset, |
| | 40957 | .lea_direct, |
| | 40958 | .lea_got, |
| | 40959 | .lea_tlv, |
| | 40960 | .lea_frame, |
| | 40961 | => return false, |
| | 40962 | .memory, |
| | 40963 | .indirect, |
| | 40964 | .load_symbol, |
| | 40965 | .load_direct, |
| | 40966 | .load_got, |
| | 40967 | .load_tlv, |
| | 40968 | .load_frame, |
| | 40969 | => return temp.toRegClass(true, .general_purpose, cg), |
| | 40970 | .lea_symbol => |sym_off| { |
| | 40971 | const off = sym_off.off; |
| | 40972 | if (off == 0) return false; |
| | 40973 | try temp.toOffset(-off, cg); |
| | 40974 | while (try temp.toRegClass(true, .general_purpose, cg)) {} |
| | 40975 | try temp.toOffset(off, cg); |
| | 40976 | return true; |
| | 40977 | }, |
| | 40978 | } |
| | 40979 | } |
| 40799 | | 40980 | |
| 40800 | fn promoteInt(self: *CodeGen, ty: Type) Type { | 40981 | fn toMemory(temp: *Temp, cg: *CodeGen) !bool { |
| 40801 | const pt = self.pt; | 40982 | const temp_tracking = temp.tracking(cg); |
| 40802 | const zcu = pt.zcu; | 40983 | if (temp_tracking.short.isMemory()) return false; |
| 40803 | const int_info: InternPool.Key.IntType = switch (ty.toIntern()) { | 40984 | const new_temp_index = cg.next_temp_index; |
| 40804 | .bool_type => .{ .signedness = .unsigned, .bits = 1 }, | 40985 | const ty = temp.typeOf(cg); |
| 40805 | else => if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else return ty, | 40986 | cg.temp_type[@intFromEnum(new_temp_index)] = ty; |
| 40806 | }; | 40987 | const new_frame_index = try cg.allocFrameIndex(.initSpill(ty, cg.pt.zcu)); |
| 40807 | for ([_]Type{ | 40988 | try cg.genSetMem(.{ .frame = new_frame_index }, 0, ty, temp_tracking.short, .{}); |
| 40808 | .c_int, .c_uint, | 40989 | new_temp_index.tracking(cg).* = .init(.{ .load_frame = .{ .index = new_frame_index } }); |
| 40809 | .c_long, .c_ulong, | 40990 | try temp.die(cg); |
| 40810 | .c_longlong, .c_ulonglong, | 40991 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| 40811 | }) |promote_ty| { | 40992 | temp.* = .{ .index = new_temp_index.toIndex() }; |
| 40812 | const promote_info = promote_ty.intInfo(zcu); | 40993 | return true; |
| 40813 | if (int_info.signedness == .signed and promote_info.signedness == .unsigned) continue; | | |
| 40814 | if (int_info.bits + @intFromBool(int_info.signedness == .unsigned and | | |
| 40815 | promote_info.signedness == .signed) <= promote_info.bits) return promote_ty; | | |
| 40816 | } | 40994 | } |
| 40817 | return ty; | | |
| 40818 | } | | |
| 40819 | | 40995 | |
| 40820 | fn promoteVarArg(self: *CodeGen, ty: Type) Type { | 40996 | // hack around linker relocation bugs |
| 40821 | if (!ty.isRuntimeFloat()) return self.promoteInt(ty); | 40997 | fn toBase(temp: *Temp, cg: *CodeGen) !bool { |
| 40822 | switch (ty.floatBits(self.target.*)) { | 40998 | const temp_tracking = temp.tracking(cg); |
| 40823 | 32, 64 => return .f64, | 40999 | if (temp_tracking.short.isBase()) return false; |
| 40824 | else => |float_bits| { | 41000 | if (try temp.toMemory(cg)) return true; |
| 40825 | assert(float_bits == self.target.cTypeBitSize(.longdouble)); | 41001 | const new_temp_index = cg.next_temp_index; |
| 40826 | return .c_longdouble; | 41002 | cg.temp_type[@intFromEnum(new_temp_index)] = temp.typeOf(cg); |
| 40827 | }, | 41003 | const new_reg = |
| | 41004 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); |
| | 41005 | try cg.genSetReg(new_reg, .usize, temp_tracking.short.address(), .{}); |
| | 41006 | new_temp_index.tracking(cg).* = .init(.{ .indirect = .{ .reg = new_reg } }); |
| | 41007 | try temp.die(cg); |
| | 41008 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); |
| | 41009 | temp.* = .{ .index = new_temp_index.toIndex() }; |
| | 41010 | return true; |
| 40828 | } | 41011 | } |
| 40829 | } | | |
| 40830 | | 41012 | |
| 40831 | fn unalignedSize(cg: *CodeGen, ty: Type) u64 { | 41013 | const AccessOptions = struct { |
| 40832 | const zcu = cg.pt.zcu; | 41014 | disp: i32 = 0, |
| 40833 | return switch (zcu.intern_pool.indexToKey(ty.toIntern())) { | 41015 | safe: bool = false, |
| 40834 | .vector_type => |vector_type| Type.fromInterned(vector_type.child).abiSize(zcu) * vector_type.len, | | |
| 40835 | else => ty.abiSize(zcu), | | |
| 40836 | }; | 41016 | }; |
| 40837 | } | | |
| 40838 | | 41017 | |
| 40839 | fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int { | 41018 | fn load(ptr: *Temp, val_ty: Type, opts: AccessOptions, cg: *CodeGen) !Temp { |
| 40840 | const zcu = cg.pt.zcu; | 41019 | const val = try cg.tempAlloc(val_ty); |
| 40841 | const ip = &zcu.intern_pool; | 41020 | try ptr.toOffset(opts.disp, cg); |
| 40842 | var ty_index = ty.ip_index; | 41021 | while (try ptr.toLea(cg)) {} |
| 40843 | while (true) switch (ip.indexToKey(ty_index)) { | 41022 | const val_mcv = val.tracking(cg).short; |
| 40844 | .int_type => |int_type| return int_type, | 41023 | switch (val_mcv) { |
| 40845 | .ptr_type => |ptr_type| return switch (ptr_type.flags.size) { | 41024 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| 40846 | .one, .many, .c => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() }, | 41025 | .register => |val_reg| try ptr.loadReg(val_ty, registerAlias( |
| 40847 | .slice => null, | 41026 | val_reg, |
| 40848 | }, | 41027 | @intCast(val_ty.abiSize(cg.pt.zcu)), |
| 40849 | .opt_type => |opt_child| return if (!Type.fromInterned(opt_child).hasRuntimeBitsIgnoreComptime(zcu)) | 41028 | ), cg), |
| 40850 | .{ .signedness = .unsigned, .bits = 1 } | 41029 | inline .register_pair, |
| 40851 | else switch (ip.indexToKey(opt_child)) { | 41030 | .register_triple, |
| 40852 | .ptr_type => |ptr_type| switch (ptr_type.flags.size) { | 41031 | .register_quadruple, |
| 40853 | .one, .many => switch (ptr_type.flags.is_allowzero) { | 41032 | => |val_regs| for (val_regs) |val_reg| { |
| 40854 | false => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() }, | 41033 | try ptr.loadReg(val_ty, val_reg, cg); |
| 40855 | true => null, | 41034 | try ptr.toOffset(@divExact(val_reg.bitSize(), 8), cg); |
| 40856 | }, | 41035 | while (try ptr.toLea(cg)) {} |
| 40857 | .slice, .c => null, | | |
| 40858 | }, | 41036 | }, |
| 40859 | else => null, | 41037 | .register_offset => |val_reg_off| switch (val_reg_off.off) { |
| 40860 | }, | 41038 | 0 => try ptr.loadReg(val_ty, registerAlias( |
| 40861 | .error_union_type => |error_union_type| return if (!Type.fromInterned(error_union_type.payload_type) | 41039 | val_reg_off.reg, |
| 40862 | .hasRuntimeBitsIgnoreComptime(zcu)) .{ .signedness = .unsigned, .bits = zcu.errorSetBits() } else null, | 41040 | @intCast(val_ty.abiSize(cg.pt.zcu)), |
| 40863 | .simple_type => |simple_type| return switch (simple_type) { | 41041 | ), cg), |
| 40864 | .bool => .{ .signedness = .unsigned, .bits = 1 }, | 41042 | else => unreachable, |
| 40865 | .anyerror => .{ .signedness = .unsigned, .bits = zcu.errorSetBits() }, | 41043 | }, |
| 40866 | .isize => .{ .signedness = .signed, .bits = cg.target.ptrBitWidth() }, | 41044 | .memory, .indirect, .load_frame, .load_symbol => { |
| 40867 | .usize => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() }, | 41045 | var val_ptr = try cg.tempInit(.usize, val_mcv.address()); |
| 40868 | .c_char => .{ .signedness = cg.target.charSignedness(), .bits = cg.target.cTypeBitSize(.char) }, | 41046 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); |
| 40869 | .c_short => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.short) }, | 41047 | try val_ptr.memcpy(ptr, &len, cg); |
| 40870 | .c_ushort => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.short) }, | 41048 | try val_ptr.die(cg); |
| 40871 | .c_int => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.int) }, | 41049 | try len.die(cg); |
| 40872 | .c_uint => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.int) }, | 41050 | }, |
| 40873 | .c_long => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.long) }, | 41051 | } |
| 40874 | .c_ulong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.long) }, | 41052 | return val; |
| 40875 | .c_longlong => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.longlong) }, | 41053 | } |
| 40876 | .c_ulonglong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.longlong) }, | 41054 | |
| 40877 | .f16, .f32, .f64, .f80, .f128, .c_longdouble => null, | 41055 | fn store(ptr: *Temp, val: *Temp, opts: AccessOptions, cg: *CodeGen) !void { |
| 40878 | .anyopaque, | 41056 | const val_ty = val.typeOf(cg); |
| 40879 | .void, | 41057 | try ptr.toOffset(opts.disp, cg); |
| 40880 | .type, | 41058 | while (try ptr.toLea(cg)) {} |
| 40881 | .comptime_int, | 41059 | val_to_gpr: while (true) : (while (try ptr.toLea(cg) or |
| 40882 | .comptime_float, | 41060 | try val.toRegClass(false, .general_purpose, cg)) |
| 40883 | .noreturn, | 41061 | {}) { |
| 40884 | .null, | 41062 | const val_mcv = val.tracking(cg).short; |
| 40885 | .undefined, | 41063 | switch (val_mcv) { |
| 40886 | .enum_literal, | 41064 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| 40887 | .adhoc_inferred_error_set, | 41065 | .undef => if (opts.safe) { |
| 40888 | .generic_poison, | 41066 | var pat = try cg.tempInit(.u8, .{ .immediate = 0xaa }); |
| 40889 | => unreachable, | 41067 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); |
| 40890 | }, | 41068 | try ptr.memset(&pat, &len, cg); |
| 40891 | .struct_type => { | 41069 | try pat.die(cg); |
| 40892 | const loaded_struct = ip.loadStructType(ty_index); | 41070 | try len.die(cg); |
| 40893 | switch (loaded_struct.layout) { | 41071 | }, |
| 40894 | .auto, .@"extern" => return null, | 41072 | .immediate => |val_imm| { |
| 40895 | .@"packed" => ty_index = loaded_struct.backingIntTypeUnordered(ip), | 41073 | const val_op: Immediate = if (std.math.cast(u31, val_imm)) |val_uimm31| |
| | 41074 | .u(val_uimm31) |
| | 41075 | else if (std.math.cast(i32, @as(i64, @bitCast(val_imm)))) |val_simm32| |
| | 41076 | .s(val_simm32) |
| | 41077 | else |
| | 41078 | continue :val_to_gpr; |
| | 41079 | // hack around linker relocation bugs |
| | 41080 | switch (ptr.tracking(cg).short) { |
| | 41081 | else => {}, |
| | 41082 | .lea_symbol => while (try ptr.toRegClass(false, .general_purpose, cg)) {}, |
| | 41083 | } |
| | 41084 | try cg.asmMemoryImmediate( |
| | 41085 | .{ ._, .mov }, |
| | 41086 | try ptr.tracking(cg).short.deref().mem(cg, .{ |
| | 41087 | .size = cg.memSize(val_ty), |
| | 41088 | }), |
| | 41089 | val_op, |
| | 41090 | ); |
| | 41091 | }, |
| | 41092 | .eflags => |cc| { |
| | 41093 | // hack around linker relocation bugs |
| | 41094 | switch (ptr.tracking(cg).short) { |
| | 41095 | else => {}, |
| | 41096 | .lea_symbol => while (try ptr.toRegClass(false, .general_purpose, cg)) {}, |
| | 41097 | } |
| | 41098 | try cg.asmSetccMemory( |
| | 41099 | cc, |
| | 41100 | try ptr.tracking(cg).short.deref().mem(cg, .{ .size = .byte }), |
| | 41101 | ); |
| | 41102 | }, |
| | 41103 | .register => |val_reg| try ptr.storeRegs(val_ty, &.{registerAlias( |
| | 41104 | val_reg, |
| | 41105 | @intCast(val_ty.abiSize(cg.pt.zcu)), |
| | 41106 | )}, cg), |
| | 41107 | inline .register_pair, |
| | 41108 | .register_triple, |
| | 41109 | .register_quadruple, |
| | 41110 | => |val_regs| try ptr.storeRegs(val_ty, &val_regs, cg), |
| | 41111 | .register_offset => |val_reg_off| switch (val_reg_off.off) { |
| | 41112 | 0 => try ptr.storeRegs(val_ty, &.{registerAlias( |
| | 41113 | val_reg_off.reg, |
| | 41114 | @intCast(val_ty.abiSize(cg.pt.zcu)), |
| | 41115 | )}, cg), |
| | 41116 | else => continue :val_to_gpr, |
| | 41117 | }, |
| | 41118 | .register_overflow => |val_reg_ov| { |
| | 41119 | const ip = &cg.pt.zcu.intern_pool; |
| | 41120 | const first_ty: Type = .fromInterned(first_ty: switch (ip.indexToKey(val_ty.toIntern())) { |
| | 41121 | .tuple_type => |tuple_type| { |
| | 41122 | const tuple_field_types = tuple_type.types.get(ip); |
| | 41123 | assert(tuple_field_types.len == 2 and tuple_field_types[1] == .u1_type); |
| | 41124 | break :first_ty tuple_field_types[0]; |
| | 41125 | }, |
| | 41126 | .opt_type => |opt_child| { |
| | 41127 | assert(!val_ty.optionalReprIsPayload(cg.pt.zcu)); |
| | 41128 | break :first_ty opt_child; |
| | 41129 | }, |
| | 41130 | else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, val_ty.fmt(cg.pt) }), |
| | 41131 | }); |
| | 41132 | const first_size: u31 = @intCast(first_ty.abiSize(cg.pt.zcu)); |
| | 41133 | try ptr.storeRegs(first_ty, &.{registerAlias(val_reg_ov.reg, first_size)}, cg); |
| | 41134 | try ptr.toOffset(first_size, cg); |
| | 41135 | try cg.asmSetccMemory( |
| | 41136 | val_reg_ov.eflags, |
| | 41137 | try ptr.tracking(cg).short.deref().mem(cg, .{ .size = .byte }), |
| | 41138 | ); |
| | 41139 | }, |
| | 41140 | .lea_frame, .lea_symbol => continue :val_to_gpr, |
| | 41141 | .memory, .indirect, .load_frame, .load_symbol => { |
| | 41142 | var val_ptr = try cg.tempInit(.usize, val_mcv.address()); |
| | 41143 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); |
| | 41144 | try ptr.memcpy(&val_ptr, &len, cg); |
| | 41145 | try val_ptr.die(cg); |
| | 41146 | try len.die(cg); |
| | 41147 | }, |
| 40896 | } | 41148 | } |
| 40897 | }, | 41149 | break; |
| 40898 | .union_type => return switch (ip.loadUnionType(ty_index).flagsUnordered(ip).layout) { | 41150 | } |
| 40899 | .auto, .@"extern" => null, | 41151 | } |
| 40900 | .@"packed" => .{ .signedness = .unsigned, .bits = @intCast(ty.bitSize(zcu)) }, | | |
| 40901 | }, | | |
| 40902 | .enum_type => ty_index = ip.loadEnumType(ty_index).tag_ty, | | |
| 40903 | .error_set_type, .inferred_error_set_type => return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() }, | | |
| 40904 | else => return null, | | |
| 40905 | }; | | |
| 40906 | } | | |
| 40907 | | 41152 | |
| 40908 | fn floatBits(cg: *CodeGen, ty: Type) ?u16 { | 41153 | fn read(src: *Temp, val_ty: Type, opts: AccessOptions, cg: *CodeGen) !Temp { |
| 40909 | return if (ty.isRuntimeFloat()) ty.floatBits(cg.target.*) else null; | 41154 | var val = try cg.tempAlloc(val_ty); |
| 40910 | } | 41155 | while (try src.toBase(cg)) {} |
| | 41156 | const val_mcv = val.tracking(cg).short; |
| | 41157 | switch (val_mcv) { |
| | 41158 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| | 41159 | .register => |val_reg| try src.readReg(opts.disp, val_ty, registerAlias( |
| | 41160 | val_reg, |
| | 41161 | @intCast(val_ty.abiSize(cg.pt.zcu)), |
| | 41162 | ), cg), |
| | 41163 | inline .register_pair, .register_triple, .register_quadruple => |val_regs| { |
| | 41164 | var disp = opts.disp; |
| | 41165 | for (val_regs) |val_reg| { |
| | 41166 | try src.readReg(disp, val_ty, val_reg, cg); |
| | 41167 | disp += @divExact(val_reg.bitSize(), 8); |
| | 41168 | } |
| | 41169 | }, |
| | 41170 | .register_offset => |val_reg_off| switch (val_reg_off.off) { |
| | 41171 | 0 => try src.readReg(opts.disp, val_ty, registerAlias( |
| | 41172 | val_reg_off.reg, |
| | 41173 | @intCast(val_ty.abiSize(cg.pt.zcu)), |
| | 41174 | ), cg), |
| | 41175 | else => unreachable, |
| | 41176 | }, |
| | 41177 | .memory, .indirect, .load_frame, .load_symbol => { |
| | 41178 | var val_ptr = try cg.tempInit(.usize, val_mcv.address()); |
| | 41179 | var src_ptr = |
| | 41180 | try cg.tempInit(.usize, src.tracking(cg).short.address().offset(opts.disp)); |
| | 41181 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); |
| | 41182 | try val_ptr.memcpy(&src_ptr, &len, cg); |
| | 41183 | try val_ptr.die(cg); |
| | 41184 | try src_ptr.die(cg); |
| | 41185 | try len.die(cg); |
| | 41186 | }, |
| | 41187 | } |
| | 41188 | return val; |
| | 41189 | } |
| 40911 | | 41190 | |
| 40912 | const Temp = struct { | 41191 | fn write(dst: *Temp, val: *Temp, opts: AccessOptions, cg: *CodeGen) !void { |
| 40913 | index: Air.Inst.Index, | 41192 | const val_ty = val.typeOf(cg); |
| | 41193 | while (try dst.toBase(cg)) {} |
| | 41194 | val_to_gpr: while (true) : (while (try dst.toBase(cg) or |
| | 41195 | try val.toRegClass(false, .general_purpose, cg)) |
| | 41196 | {}) { |
| | 41197 | const val_mcv = val.tracking(cg).short; |
| | 41198 | switch (val_mcv) { |
| | 41199 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), |
| | 41200 | .undef => if (opts.safe) { |
| | 41201 | var dst_ptr = try cg.tempInit(.usize, dst.tracking(cg).short.address().offset(opts.disp)); |
| | 41202 | var pat = try cg.tempInit(.u8, .{ .immediate = 0xaa }); |
| | 41203 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); |
| | 41204 | try dst_ptr.memset(&pat, &len, cg); |
| | 41205 | try dst_ptr.die(cg); |
| | 41206 | try pat.die(cg); |
| | 41207 | try len.die(cg); |
| | 41208 | }, |
| | 41209 | .immediate => |val_imm| { |
| | 41210 | const val_op: Immediate = if (std.math.cast(u31, val_imm)) |val_uimm31| |
| | 41211 | .u(val_uimm31) |
| | 41212 | else if (std.math.cast(i32, @as(i64, @bitCast(val_imm)))) |val_simm32| |
| | 41213 | .s(val_simm32) |
| | 41214 | else |
| | 41215 | continue :val_to_gpr; |
| | 41216 | try cg.asmMemoryImmediate( |
| | 41217 | .{ ._, .mov }, |
| | 41218 | try dst.tracking(cg).short.mem(cg, .{ |
| | 41219 | .size = cg.memSize(val_ty), |
| | 41220 | .disp = opts.disp, |
| | 41221 | }), |
| | 41222 | val_op, |
| | 41223 | ); |
| | 41224 | }, |
| | 41225 | .eflags => |cc| try cg.asmSetccMemory( |
| | 41226 | cc, |
| | 41227 | try dst.tracking(cg).short.mem(cg, .{ |
| | 41228 | .size = .byte, |
| | 41229 | .disp = opts.disp, |
| | 41230 | }), |
| | 41231 | ), |
| | 41232 | .register => |val_reg| try dst.writeRegs(opts.disp, val_ty, &.{registerAlias( |
| | 41233 | val_reg, |
| | 41234 | @intCast(val_ty.abiSize(cg.pt.zcu)), |
| | 41235 | )}, cg), |
| | 41236 | inline .register_pair, |
| | 41237 | .register_triple, |
| | 41238 | .register_quadruple, |
| | 41239 | => |val_regs| try dst.writeRegs(opts.disp, val_ty, &val_regs, cg), |
| | 41240 | .register_offset => |val_reg_off| switch (val_reg_off.off) { |
| | 41241 | 0 => try dst.writeRegs(opts.disp, val_ty, &.{registerAlias( |
| | 41242 | val_reg_off.reg, |
| | 41243 | @intCast(val_ty.abiSize(cg.pt.zcu)), |
| | 41244 | )}, cg), |
| | 41245 | else => continue :val_to_gpr, |
| | 41246 | }, |
| | 41247 | .register_overflow => |val_reg_ov| { |
| | 41248 | const ip = &cg.pt.zcu.intern_pool; |
| | 41249 | const first_ty: Type = .fromInterned(first_ty: switch (ip.indexToKey(val_ty.toIntern())) { |
| | 41250 | .tuple_type => |tuple_type| { |
| | 41251 | const tuple_field_types = tuple_type.types.get(ip); |
| | 41252 | assert(tuple_field_types.len == 2 and tuple_field_types[1] == .u1_type); |
| | 41253 | break :first_ty tuple_field_types[0]; |
| | 41254 | }, |
| | 41255 | .opt_type => |opt_child| { |
| | 41256 | assert(!val_ty.optionalReprIsPayload(cg.pt.zcu)); |
| | 41257 | break :first_ty opt_child; |
| | 41258 | }, |
| | 41259 | else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, val_ty.fmt(cg.pt) }), |
| | 41260 | }); |
| | 41261 | const first_size: u31 = @intCast(first_ty.abiSize(cg.pt.zcu)); |
| | 41262 | try dst.writeRegs(opts.disp, first_ty, &.{registerAlias(val_reg_ov.reg, first_size)}, cg); |
| | 41263 | try cg.asmSetccMemory( |
| | 41264 | val_reg_ov.eflags, |
| | 41265 | try dst.tracking(cg).short.mem(cg, .{ |
| | 41266 | .size = .byte, |
| | 41267 | .disp = opts.disp + first_size, |
| | 41268 | }), |
| | 41269 | ); |
| | 41270 | }, |
| | 41271 | .lea_frame, .lea_symbol => continue :val_to_gpr, |
| | 41272 | .memory, .indirect, .load_frame, .load_symbol => { |
| | 41273 | var dst_ptr = |
| | 41274 | try cg.tempInit(.usize, dst.tracking(cg).short.address().offset(opts.disp)); |
| | 41275 | var val_ptr = try cg.tempInit(.usize, val_mcv.address()); |
| | 41276 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); |
| | 41277 | try dst_ptr.memcpy(&val_ptr, &len, cg); |
| | 41278 | try dst_ptr.die(cg); |
| | 41279 | try val_ptr.die(cg); |
| | 41280 | try len.die(cg); |
| | 41281 | }, |
| | 41282 | } |
| | 41283 | break; |
| | 41284 | } |
| | 41285 | } |
| 40914 | | 41286 | |
| 40915 | fn unwrap(temp: Temp, cg: *CodeGen) union(enum) { | 41287 | fn loadReg(ptr: *Temp, dst_ty: Type, dst_reg: Register, cg: *CodeGen) !void { |
| 40916 | ref: Air.Inst.Ref, | 41288 | const dst_rc = dst_reg.class(); |
| 40917 | temp: Index, | 41289 | const strat = try cg.moveStrategy(dst_ty, dst_rc, false); |
| 40918 | err_ret_trace, | 41290 | // hack around linker relocation bugs |
| 40919 | } { | 41291 | switch (ptr.tracking(cg).short) { |
| 40920 | switch (temp.index.unwrap()) { | 41292 | else => {}, |
| 40921 | .ref => |ref| return .{ .ref = ref }, | 41293 | .lea_symbol => |sym_off| if (dst_rc != .general_purpose or sym_off.off != 0) |
| 40922 | .target => |target_index| { | 41294 | while (try ptr.toRegClass(false, .general_purpose, cg)) {}, |
| 40923 | if (temp.index == err_ret_trace_index) return .err_ret_trace; | 41295 | } |
| 40924 | const temp_index: Index = @enumFromInt(target_index); | 41296 | try strat.read(cg, dst_reg, try ptr.tracking(cg).short.deref().mem(cg, .{ |
| 40925 | assert(temp_index.isValid(cg)); | 41297 | .size = .fromBitSize(@min(8 * dst_ty.abiSize(cg.pt.zcu), dst_reg.bitSize())), |
| 40926 | return .{ .temp = temp_index }; | 41298 | })); |
| 40927 | }, | 41299 | } |
| | 41300 | |
| | 41301 | fn storeRegs(ptr: *Temp, src_ty: Type, src_regs: []const Register, cg: *CodeGen) !void { |
| | 41302 | var part_disp: u31 = 0; |
| | 41303 | var deferred_disp: u31 = 0; |
| | 41304 | var src_abi_size: u32 = @intCast(src_ty.abiSize(cg.pt.zcu)); |
| | 41305 | for (src_regs) |src_reg| { |
| | 41306 | const src_rc = src_reg.class(); |
| | 41307 | const part_bit_size = @min(8 * src_abi_size, src_reg.bitSize()); |
| | 41308 | const part_size = @divExact(part_bit_size, 8); |
| | 41309 | if (src_rc == .x87 or std.math.isPowerOfTwo(part_size)) { |
| | 41310 | // hack around linker relocation bugs |
| | 41311 | switch (ptr.tracking(cg).short) { |
| | 41312 | else => {}, |
| | 41313 | .lea_symbol => while (try ptr.toRegClass(false, .general_purpose, cg)) {}, |
| | 41314 | } |
| | 41315 | const strat = try cg.moveStrategy(src_ty, src_rc, false); |
| | 41316 | try strat.write(cg, try ptr.tracking(cg).short.deref().mem(cg, .{ |
| | 41317 | .size = .fromBitSize(part_bit_size), |
| | 41318 | .disp = part_disp, |
| | 41319 | }), registerAlias(src_reg, part_size)); |
| | 41320 | } else { |
| | 41321 | const frame_size = std.math.ceilPowerOfTwoAssert(u32, part_size); |
| | 41322 | const frame_index = try cg.allocFrameIndex(.init(.{ |
| | 41323 | .size = frame_size, |
| | 41324 | .alignment = .fromNonzeroByteUnits(frame_size), |
| | 41325 | })); |
| | 41326 | const strat = try cg.moveStrategy(src_ty, src_rc, true); |
| | 41327 | try strat.write(cg, .{ |
| | 41328 | .base = .{ .frame = frame_index }, |
| | 41329 | .mod = .{ .rm = .{ .size = .fromSize(frame_size) } }, |
| | 41330 | }, registerAlias(src_reg, frame_size)); |
| | 41331 | try ptr.toOffset(deferred_disp, cg); |
| | 41332 | deferred_disp = 0; |
| | 41333 | var src_ptr = try cg.tempInit(.usize, .{ .lea_frame = .{ .index = frame_index } }); |
| | 41334 | var len = try cg.tempInit(.usize, .{ .immediate = src_abi_size }); |
| | 41335 | try ptr.memcpy(&src_ptr, &len, cg); |
| | 41336 | try src_ptr.die(cg); |
| | 41337 | try len.die(cg); |
| | 41338 | } |
| | 41339 | part_disp += part_size; |
| | 41340 | deferred_disp += part_size; |
| | 41341 | src_abi_size -= part_size; |
| 40928 | } | 41342 | } |
| 40929 | } | 41343 | } |
| 40930 | | 41344 | |
| 40931 | fn typeOf(temp: Temp, cg: *CodeGen) Type { | 41345 | fn readReg(src: Temp, disp: i32, dst_ty: Type, dst_reg: Register, cg: *CodeGen) !void { |
| 40932 | return switch (temp.unwrap(cg)) { | 41346 | const strat = try cg.moveStrategy(dst_ty, dst_reg.class(), false); |
| 40933 | .ref => switch (cg.air.instructions.items(.tag)[@intFromEnum(temp.index)]) { | 41347 | try strat.read(cg, dst_reg, try src.tracking(cg).short.mem(cg, .{ |
| 40934 | .loop_switch_br => cg.typeOf(cg.air.unwrapSwitch(temp.index).operand), | 41348 | .size = .fromBitSize(@min(8 * dst_ty.abiSize(cg.pt.zcu), dst_reg.bitSize())), |
| 40935 | else => cg.air.typeOfIndex(temp.index, &cg.pt.zcu.intern_pool), | 41349 | .disp = disp, |
| 40936 | }, | 41350 | })); |
| 40937 | .temp => |temp_index| temp_index.typeOf(cg), | | |
| 40938 | .err_ret_trace => .usize, | | |
| 40939 | }; | | |
| 40940 | } | 41351 | } |
| 40941 | | 41352 | |
| 40942 | fn isMut(temp: Temp, cg: *CodeGen) bool { | 41353 | fn writeRegs(dst: Temp, disp: i32, src_ty: Type, src_regs: []const Register, cg: *CodeGen) !void { |
| 40943 | return switch (temp.unwrap(cg)) { | 41354 | var part_disp = disp; |
| 40944 | .ref, .err_ret_trace => false, | 41355 | var src_abi_size: u32 = @intCast(src_ty.abiSize(cg.pt.zcu)); |
| 40945 | .temp => |temp_index| switch (temp_index.tracking(cg).short) { | 41356 | for (src_regs) |src_reg| { |
| 40946 | .none, | 41357 | const src_rc = src_reg.class(); |
| 40947 | .unreach, | 41358 | const part_bit_size = @min(8 * src_abi_size, src_reg.bitSize()); |
| 40948 | .dead, | 41359 | const part_size = @divExact(part_bit_size, 8); |
| 40949 | .undef, | 41360 | if (src_rc == .x87 or std.math.isPowerOfTwo(part_size)) { |
| 40950 | .immediate, | 41361 | const strat = try cg.moveStrategy(src_ty, src_rc, false); |
| 40951 | .eflags, | 41362 | try strat.write(cg, try dst.tracking(cg).short.mem(cg, .{ |
| 40952 | .register_offset, | 41363 | .size = .fromBitSize(part_bit_size), |
| 40953 | .register_mask, | 41364 | .disp = part_disp, |
| 40954 | .memory, | 41365 | }), registerAlias(src_reg, part_size)); |
| 40955 | .load_symbol, | 41366 | } else { |
| 40956 | .lea_symbol, | 41367 | const frame_size = std.math.ceilPowerOfTwoAssert(u32, part_size); |
| 40957 | .indirect, | 41368 | const frame_index = try cg.allocFrameIndex(.init(.{ |
| 40958 | .load_direct, | 41369 | .size = frame_size, |
| 40959 | .lea_direct, | 41370 | .alignment = .fromNonzeroByteUnits(frame_size), |
| 40960 | .load_got, | 41371 | })); |
| 40961 | .lea_got, | 41372 | const strat = try cg.moveStrategy(src_ty, src_rc, true); |
| 40962 | .load_tlv, | 41373 | try strat.write(cg, .{ |
| 40963 | .lea_tlv, | 41374 | .base = .{ .frame = frame_index }, |
| 40964 | .lea_frame, | 41375 | .mod = .{ .rm = .{ .size = .fromSize(frame_size) } }, |
| 40965 | .elementwise_regs_then_frame, | 41376 | }, registerAlias(src_reg, frame_size)); |
| 40966 | .reserved_frame, | 41377 | var dst_ptr = try cg.tempInit(.usize, dst.tracking(cg).short.address()); |
| 40967 | .air_ref, | 41378 | try dst_ptr.toOffset(part_disp, cg); |
| 40968 | => false, | 41379 | var src_ptr = try cg.tempInit(.usize, .{ .lea_frame = .{ .index = frame_index } }); |
| 40969 | .register, | 41380 | var len = try cg.tempInit(.usize, .{ .immediate = src_abi_size }); |
| 40970 | .register_pair, | 41381 | try dst_ptr.memcpy(&src_ptr, &len, cg); |
| 40971 | .register_triple, | 41382 | try dst_ptr.die(cg); |
| 40972 | .register_quadruple, | 41383 | try src_ptr.die(cg); |
| 40973 | .register_overflow, | 41384 | try len.die(cg); |
| 40974 | => true, | 41385 | } |
| 40975 | .load_frame => |frame_addr| !frame_addr.index.isNamed(), | 41386 | part_disp += part_size; |
| 40976 | }, | 41387 | src_abi_size -= part_size; |
| 40977 | }; | 41388 | } |
| 40978 | } | 41389 | } |
| 40979 | | 41390 | |
| 40980 | fn tracking(temp: Temp, cg: *CodeGen) InstTracking { | 41391 | fn memcpy(dst: *Temp, src: *Temp, len: *Temp, cg: *CodeGen) !void { |
| 40981 | return cg.inst_tracking.get(temp.index).?; | 41392 | while (true) for ([_]*Temp{ dst, src, len }, [_]Register{ .rdi, .rsi, .rcx }) |temp, reg| { |
| | 41393 | if (try temp.toReg(reg, cg)) break; |
| | 41394 | } else break; |
| | 41395 | try cg.asmOpOnly(.{ .@"rep _sb", .mov }); |
| 40982 | } | 41396 | } |
| 40983 | | 41397 | |
| 40984 | fn getOffset(temp: Temp, off: i32, cg: *CodeGen) !Temp { | 41398 | fn memset(dst: *Temp, val: *Temp, len: *Temp, cg: *CodeGen) !void { |
| 40985 | const new_temp_index = cg.next_temp_index; | 41399 | while (true) for ([_]*Temp{ dst, val, len }, [_]Register{ .rdi, .rax, .rcx }) |temp, reg| { |
| 40986 | cg.temp_type[@intFromEnum(new_temp_index)] = .usize; | 41400 | if (try temp.toReg(reg, cg)) break; |
| 40987 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); | 41401 | } else break; |
| 40988 | switch (temp.tracking(cg).short) { | 41402 | try cg.asmOpOnly(.{ .@"rep _sb", .sto }); |
| 40989 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | 41403 | } |
| 40990 | .register => |reg| { | 41404 | |
| 40991 | const new_reg = | 41405 | /// Supports any `op` using `cg.intInfo(lhs.typeOf(cg)).?.signedness` as the signedness. |
| 40992 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 41406 | /// Returns `error.SelectFailed` when `cg.intInfo(lhs.typeOf(cg)) == null`. |
| 40993 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); | 41407 | fn cmpInts(lhs: *Temp, op: std.math.CompareOperator, rhs: *Temp, cg: *CodeGen) !Temp { |
| 40994 | try cg.asmRegisterMemory(.{ ._, .lea }, new_reg.to64(), .{ | 41408 | var ops: [2]Temp = .{ lhs.*, rhs.* }; |
| 40995 | .base = .{ .reg = reg.to64() }, | 41409 | var res: [1]Temp = undefined; |
| 40996 | .mod = .{ .rm = .{ | 41410 | switch (op) { |
| 40997 | .size = .qword, | 41411 | .lt, .lte, .gte, .gt => { |
| 40998 | .disp = off, | 41412 | const commute = switch (op) { |
| | 41413 | .lt, .gte => false, |
| | 41414 | .lte, .gt => true, |
| | 41415 | else => unreachable, |
| | 41416 | }; |
| | 41417 | if (commute) std.mem.swap(Temp, &ops[0], &ops[1]); |
| | 41418 | try cg.select(&res, &.{.bool}, &ops, comptime &.{ .{ |
| | 41419 | .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte } }, |
| | 41420 | .patterns = &.{ |
| | 41421 | .{ .src = .{ .imm8, .mem }, .commute = .{ 0, 1 } }, |
| | 41422 | .{ .src = .{ .imm8, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41423 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41424 | }, |
| | 41425 | .dst_temps = .{.{ .cc = .g }}, |
| | 41426 | .clobbers = .{ .eflags = true }, |
| | 41427 | .each = .{ .once = &.{ |
| | 41428 | .{ ._, ._, .cmp, .src0b, .src1b, ._, ._ }, |
| 40999 | } }, | 41429 | } }, |
| 41000 | }); | 41430 | }, .{ |
| 41001 | }, | 41431 | .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte } }, |
| 41002 | .register_offset => |reg_off| { | 41432 | .patterns = &.{ |
| 41003 | const new_reg = | 41433 | .{ .src = .{ .mem, .imm8 } }, |
| 41004 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 41434 | .{ .src = .{ .to_gpr, .imm8 } }, |
| 41005 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); | 41435 | .{ .src = .{ .to_gpr, .mem } }, |
| 41006 | try cg.asmRegisterMemory(.{ ._, .lea }, new_reg.to64(), .{ | 41436 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| 41007 | .base = .{ .reg = reg_off.reg.to64() }, | 41437 | }, |
| 41008 | .mod = .{ .rm = .{ | 41438 | .dst_temps = .{.{ .cc = .l }}, |
| 41009 | .size = .qword, | 41439 | .clobbers = .{ .eflags = true }, |
| 41010 | .disp = reg_off.off + off, | 41440 | .each = .{ .once = &.{ |
| | 41441 | .{ ._, ._, .cmp, .src0b, .src1b, ._, ._ }, |
| | 41442 | } }, |
| | 41443 | }, .{ |
| | 41444 | .src_constraints = .{ .{ .unsigned_int = .byte }, .{ .unsigned_int = .byte } }, |
| | 41445 | .patterns = &.{ |
| | 41446 | .{ .src = .{ .imm8, .mem }, .commute = .{ 0, 1 } }, |
| | 41447 | .{ .src = .{ .imm8, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41448 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41449 | }, |
| | 41450 | .dst_temps = .{.{ .cc = .a }}, |
| | 41451 | .clobbers = .{ .eflags = true }, |
| | 41452 | .each = .{ .once = &.{ |
| | 41453 | .{ ._, ._, .cmp, .src0b, .src1b, ._, ._ }, |
| | 41454 | } }, |
| | 41455 | }, .{ |
| | 41456 | .src_constraints = .{ .{ .unsigned_int = .byte }, .{ .unsigned_int = .byte } }, |
| | 41457 | .patterns = &.{ |
| | 41458 | .{ .src = .{ .mem, .imm8 } }, |
| | 41459 | .{ .src = .{ .to_gpr, .imm8 } }, |
| | 41460 | .{ .src = .{ .to_gpr, .mem } }, |
| | 41461 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| | 41462 | }, |
| | 41463 | .dst_temps = .{.{ .cc = .b }}, |
| | 41464 | .clobbers = .{ .eflags = true }, |
| | 41465 | .each = .{ .once = &.{ |
| | 41466 | .{ ._, ._, .cmp, .src0b, .src1b, ._, ._ }, |
| | 41467 | } }, |
| | 41468 | }, .{ |
| | 41469 | .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word } }, |
| | 41470 | .patterns = &.{ |
| | 41471 | .{ .src = .{ .imm16, .mem }, .commute = .{ 0, 1 } }, |
| | 41472 | .{ .src = .{ .imm16, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41473 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41474 | }, |
| | 41475 | .dst_temps = .{.{ .cc = .g }}, |
| | 41476 | .clobbers = .{ .eflags = true }, |
| | 41477 | .each = .{ .once = &.{ |
| | 41478 | .{ ._, ._, .cmp, .src0w, .src1w, ._, ._ }, |
| | 41479 | } }, |
| | 41480 | }, .{ |
| | 41481 | .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word } }, |
| | 41482 | .patterns = &.{ |
| | 41483 | .{ .src = .{ .mem, .imm16 } }, |
| | 41484 | .{ .src = .{ .to_gpr, .imm16 } }, |
| | 41485 | .{ .src = .{ .to_gpr, .mem } }, |
| | 41486 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| | 41487 | }, |
| | 41488 | .dst_temps = .{.{ .cc = .l }}, |
| | 41489 | .clobbers = .{ .eflags = true }, |
| | 41490 | .each = .{ .once = &.{ |
| | 41491 | .{ ._, ._, .cmp, .src0w, .src1w, ._, ._ }, |
| | 41492 | } }, |
| | 41493 | }, .{ |
| | 41494 | .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word } }, |
| | 41495 | .patterns = &.{ |
| | 41496 | .{ .src = .{ .imm16, .mem }, .commute = .{ 0, 1 } }, |
| | 41497 | .{ .src = .{ .imm16, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41498 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41499 | }, |
| | 41500 | .dst_temps = .{.{ .cc = .a }}, |
| | 41501 | .clobbers = .{ .eflags = true }, |
| | 41502 | .each = .{ .once = &.{ |
| | 41503 | .{ ._, ._, .cmp, .src0w, .src1w, ._, ._ }, |
| | 41504 | } }, |
| | 41505 | }, .{ |
| | 41506 | .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word } }, |
| | 41507 | .patterns = &.{ |
| | 41508 | .{ .src = .{ .mem, .imm16 } }, |
| | 41509 | .{ .src = .{ .to_gpr, .imm16 } }, |
| | 41510 | .{ .src = .{ .to_gpr, .mem } }, |
| | 41511 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| | 41512 | }, |
| | 41513 | .dst_temps = .{.{ .cc = .b }}, |
| | 41514 | .clobbers = .{ .eflags = true }, |
| | 41515 | .each = .{ .once = &.{ |
| | 41516 | .{ ._, ._, .cmp, .src0w, .src1w, ._, ._ }, |
| | 41517 | } }, |
| | 41518 | }, .{ |
| | 41519 | .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword } }, |
| | 41520 | .patterns = &.{ |
| | 41521 | .{ .src = .{ .imm32, .mem }, .commute = .{ 0, 1 } }, |
| | 41522 | .{ .src = .{ .imm32, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41523 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41524 | }, |
| | 41525 | .dst_temps = .{.{ .cc = .g }}, |
| | 41526 | .clobbers = .{ .eflags = true }, |
| | 41527 | .each = .{ .once = &.{ |
| | 41528 | .{ ._, ._, .cmp, .src0d, .src1d, ._, ._ }, |
| | 41529 | } }, |
| | 41530 | }, .{ |
| | 41531 | .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword } }, |
| | 41532 | .patterns = &.{ |
| | 41533 | .{ .src = .{ .mem, .imm32 } }, |
| | 41534 | .{ .src = .{ .to_gpr, .imm32 } }, |
| | 41535 | .{ .src = .{ .to_gpr, .mem } }, |
| | 41536 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| | 41537 | }, |
| | 41538 | .dst_temps = .{.{ .cc = .l }}, |
| | 41539 | .clobbers = .{ .eflags = true }, |
| | 41540 | .each = .{ .once = &.{ |
| | 41541 | .{ ._, ._, .cmp, .src0d, .src1d, ._, ._ }, |
| | 41542 | } }, |
| | 41543 | }, .{ |
| | 41544 | .src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword } }, |
| | 41545 | .patterns = &.{ |
| | 41546 | .{ .src = .{ .imm32, .mem }, .commute = .{ 0, 1 } }, |
| | 41547 | .{ .src = .{ .imm32, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41548 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41549 | }, |
| | 41550 | .dst_temps = .{.{ .cc = .a }}, |
| | 41551 | .clobbers = .{ .eflags = true }, |
| | 41552 | .each = .{ .once = &.{ |
| | 41553 | .{ ._, ._, .cmp, .src0d, .src1d, ._, ._ }, |
| | 41554 | } }, |
| | 41555 | }, .{ |
| | 41556 | .src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword } }, |
| | 41557 | .patterns = &.{ |
| | 41558 | .{ .src = .{ .mem, .imm32 } }, |
| | 41559 | .{ .src = .{ .to_gpr, .imm32 } }, |
| | 41560 | .{ .src = .{ .to_gpr, .mem } }, |
| | 41561 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| | 41562 | }, |
| | 41563 | .dst_temps = .{.{ .cc = .b }}, |
| | 41564 | .clobbers = .{ .eflags = true }, |
| | 41565 | .each = .{ .once = &.{ |
| | 41566 | .{ ._, ._, .cmp, .src0d, .src1d, ._, ._ }, |
| | 41567 | } }, |
| | 41568 | }, .{ |
| | 41569 | .required_features = .{ .@"64bit", null, null, null }, |
| | 41570 | .src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword } }, |
| | 41571 | .patterns = &.{ |
| | 41572 | .{ .src = .{ .simm32, .mem }, .commute = .{ 0, 1 } }, |
| | 41573 | .{ .src = .{ .simm32, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41574 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41575 | }, |
| | 41576 | .dst_temps = .{.{ .cc = .g }}, |
| | 41577 | .clobbers = .{ .eflags = true }, |
| | 41578 | .each = .{ .once = &.{ |
| | 41579 | .{ ._, ._, .cmp, .src0q, .src1q, ._, ._ }, |
| | 41580 | } }, |
| | 41581 | }, .{ |
| | 41582 | .required_features = .{ .@"64bit", null, null, null }, |
| | 41583 | .src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword } }, |
| | 41584 | .patterns = &.{ |
| | 41585 | .{ .src = .{ .mem, .simm32 } }, |
| | 41586 | .{ .src = .{ .to_gpr, .simm32 } }, |
| | 41587 | .{ .src = .{ .to_gpr, .mem } }, |
| | 41588 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| | 41589 | }, |
| | 41590 | .dst_temps = .{.{ .cc = .l }}, |
| | 41591 | .clobbers = .{ .eflags = true }, |
| | 41592 | .each = .{ .once = &.{ |
| | 41593 | .{ ._, ._, .cmp, .src0q, .src1q, ._, ._ }, |
| | 41594 | } }, |
| | 41595 | }, .{ |
| | 41596 | .required_features = .{ .@"64bit", null, null, null }, |
| | 41597 | .src_constraints = .{ .{ .unsigned_int = .qword }, .{ .unsigned_int = .qword } }, |
| | 41598 | .patterns = &.{ |
| | 41599 | .{ .src = .{ .simm32, .mem }, .commute = .{ 0, 1 } }, |
| | 41600 | .{ .src = .{ .simm32, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41601 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41602 | }, |
| | 41603 | .dst_temps = .{.{ .cc = .a }}, |
| | 41604 | .clobbers = .{ .eflags = true }, |
| | 41605 | .each = .{ .once = &.{ |
| | 41606 | .{ ._, ._, .cmp, .src0q, .src1q, ._, ._ }, |
| | 41607 | } }, |
| | 41608 | }, .{ |
| | 41609 | .required_features = .{ .@"64bit", null, null, null }, |
| | 41610 | .src_constraints = .{ .{ .unsigned_int = .qword }, .{ .unsigned_int = .qword } }, |
| | 41611 | .patterns = &.{ |
| | 41612 | .{ .src = .{ .mem, .simm32 } }, |
| | 41613 | .{ .src = .{ .to_gpr, .simm32 } }, |
| | 41614 | .{ .src = .{ .to_gpr, .mem } }, |
| | 41615 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| | 41616 | }, |
| | 41617 | .dst_temps = .{.{ .cc = .b }}, |
| | 41618 | .clobbers = .{ .eflags = true }, |
| | 41619 | .each = .{ .once = &.{ |
| | 41620 | .{ ._, ._, .cmp, .src0q, .src1q, ._, ._ }, |
| | 41621 | } }, |
| | 41622 | }, .{ |
| | 41623 | .required_features = .{ .@"64bit", null, null, null }, |
| | 41624 | .src_constraints = .{ |
| | 41625 | .{ .signed_remainder_int = .{ .of = .qword, .is = .qword } }, |
| | 41626 | .{ .signed_remainder_int = .{ .of = .qword, .is = .qword } }, |
| | 41627 | }, |
| | 41628 | .patterns = &.{ |
| | 41629 | .{ .src = .{ .to_mem, .to_mem } }, |
| | 41630 | }, |
| | 41631 | .extra_temps = .{ |
| | 41632 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| | 41633 | .{ .type = .i64, .kind = .{ .rc = .general_purpose } }, |
| | 41634 | .unused, |
| | 41635 | .unused, |
| | 41636 | .unused, |
| | 41637 | .unused, |
| | 41638 | .unused, |
| | 41639 | .unused, |
| | 41640 | .unused, |
| | 41641 | }, |
| | 41642 | .dst_temps = .{.{ .cc = .l }}, |
| | 41643 | .clobbers = .{ .eflags = true }, |
| | 41644 | .each = .{ .once = &.{ |
| | 41645 | .{ ._, ._, .mov, .tmp0p, .sia(1, .src0, .sub_size_div_8), ._, ._ }, |
| | 41646 | .{ ._, ._c, .cl, ._, ._, ._, ._ }, |
| | 41647 | .{ .@"0:", ._, .mov, .tmp1q, .memsiad(.src0q, .@"8", .tmp0, .add_size, -8), ._, ._ }, |
| | 41648 | .{ ._, ._, .sbb, .tmp1q, .memsiad(.src1q, .@"8", .tmp0, .add_size, -8), ._, ._ }, |
| | 41649 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, |
| | 41650 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| | 41651 | .{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -8), ._, ._ }, |
| | 41652 | .{ ._, ._, .sbb, .tmp1q, .memad(.src1q, .add_size, -8), ._, ._ }, |
| | 41653 | } }, |
| | 41654 | }, .{ |
| | 41655 | .required_features = .{ .@"64bit", null, null, null }, |
| | 41656 | .src_constraints = .{ |
| | 41657 | .{ .unsigned_remainder_int = .{ .of = .qword, .is = .qword } }, |
| | 41658 | .{ .unsigned_remainder_int = .{ .of = .qword, .is = .qword } }, |
| | 41659 | }, |
| | 41660 | .patterns = &.{ |
| | 41661 | .{ .src = .{ .to_mem, .to_mem } }, |
| | 41662 | }, |
| | 41663 | .extra_temps = .{ |
| | 41664 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| | 41665 | .{ .type = .u64, .kind = .{ .rc = .general_purpose } }, |
| | 41666 | .unused, |
| | 41667 | .unused, |
| | 41668 | .unused, |
| | 41669 | .unused, |
| | 41670 | .unused, |
| | 41671 | .unused, |
| | 41672 | .unused, |
| | 41673 | }, |
| | 41674 | .dst_temps = .{.{ .cc = .b }}, |
| | 41675 | .clobbers = .{ .eflags = true }, |
| | 41676 | .each = .{ .once = &.{ |
| | 41677 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size_div_8), ._, ._ }, |
| | 41678 | .{ ._, ._c, .cl, ._, ._, ._, ._ }, |
| | 41679 | .{ .@"0:", ._, .mov, .tmp1q, .memsia(.src0q, .@"8", .tmp0, .add_size), ._, ._ }, |
| | 41680 | .{ ._, ._, .sbb, .tmp1q, .memsia(.src1q, .@"8", .tmp0, .add_size), ._, ._ }, |
| | 41681 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, |
| | 41682 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| | 41683 | } }, |
| | 41684 | }, .{ |
| | 41685 | .src_constraints = .{ |
| | 41686 | .{ .signed_remainder_int = .{ .of = .dword, .is = .dword } }, |
| | 41687 | .{ .signed_remainder_int = .{ .of = .dword, .is = .dword } }, |
| | 41688 | }, |
| | 41689 | .patterns = &.{ |
| | 41690 | .{ .src = .{ .to_mem, .to_mem } }, |
| | 41691 | }, |
| | 41692 | .extra_temps = .{ |
| | 41693 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| | 41694 | .{ .type = .i32, .kind = .{ .rc = .general_purpose } }, |
| | 41695 | .unused, |
| | 41696 | .unused, |
| | 41697 | .unused, |
| | 41698 | .unused, |
| | 41699 | .unused, |
| | 41700 | .unused, |
| | 41701 | .unused, |
| | 41702 | }, |
| | 41703 | .dst_temps = .{.{ .cc = .l }}, |
| | 41704 | .clobbers = .{ .eflags = true }, |
| | 41705 | .each = .{ .once = &.{ |
| | 41706 | .{ ._, ._, .mov, .tmp0p, .sia(1, .src0, .sub_size_div_4), ._, ._ }, |
| | 41707 | .{ ._, ._c, .cl, ._, ._, ._, ._ }, |
| | 41708 | .{ .@"0:", ._, .mov, .tmp1q, .memsiad(.src0q, .@"4", .tmp0, .add_size, -4), ._, ._ }, |
| | 41709 | .{ ._, ._, .sbb, .tmp1q, .memsiad(.src1q, .@"4", .tmp0, .add_size, -4), ._, ._ }, |
| | 41710 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, |
| | 41711 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| | 41712 | .{ ._, ._, .mov, .tmp1q, .memad(.src0q, .add_size, -4), ._, ._ }, |
| | 41713 | .{ ._, ._, .sbb, .tmp1q, .memad(.src1q, .add_size, -4), ._, ._ }, |
| | 41714 | } }, |
| | 41715 | }, .{ |
| | 41716 | .src_constraints = .{ |
| | 41717 | .{ .unsigned_remainder_int = .{ .of = .dword, .is = .dword } }, |
| | 41718 | .{ .unsigned_remainder_int = .{ .of = .dword, .is = .dword } }, |
| | 41719 | }, |
| | 41720 | .patterns = &.{ |
| | 41721 | .{ .src = .{ .to_mem, .to_mem } }, |
| | 41722 | }, |
| | 41723 | .extra_temps = .{ |
| | 41724 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| | 41725 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| | 41726 | .unused, |
| | 41727 | .unused, |
| | 41728 | .unused, |
| | 41729 | .unused, |
| | 41730 | .unused, |
| | 41731 | .unused, |
| | 41732 | .unused, |
| | 41733 | }, |
| | 41734 | .dst_temps = .{.{ .cc = .b }}, |
| | 41735 | .clobbers = .{ .eflags = true }, |
| | 41736 | .each = .{ .once = &.{ |
| | 41737 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size_div_4), ._, ._ }, |
| | 41738 | .{ ._, ._c, .cl, ._, ._, ._, ._ }, |
| | 41739 | .{ .@"0:", ._, .mov, .tmp1q, .memsia(.src0q, .@"4", .tmp0, .add_size), ._, ._ }, |
| | 41740 | .{ ._, ._, .sbb, .tmp1q, .memsia(.src1q, .@"4", .tmp0, .add_size), ._, ._ }, |
| | 41741 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, |
| | 41742 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 41011 | } }, | 41743 | } }, |
| 41012 | }); | | |
| 41013 | }, | | |
| 41014 | .lea_symbol => |sym_off| new_temp_index.tracking(cg).* = .init(.{ .lea_symbol = .{ | | |
| 41015 | .sym_index = sym_off.sym_index, | | |
| 41016 | .off = sym_off.off + off, | | |
| 41017 | } }), | | |
| 41018 | .load_frame => |frame_addr| { | | |
| 41019 | const new_reg = | | |
| 41020 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | | |
| 41021 | new_temp_index.tracking(cg).* = .init(.{ .register_offset = .{ | | |
| 41022 | .reg = new_reg, | | |
| 41023 | .off = off, | | |
| 41024 | } }); | 41744 | } }); |
| 41025 | try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ | 41745 | if (commute) std.mem.swap(Temp, &ops[0], &ops[1]); |
| 41026 | .base = .{ .frame = frame_addr.index }, | 41746 | }, |
| 41027 | .mod = .{ .rm = .{ | 41747 | .eq, .neq => { |
| 41028 | .size = .qword, | 41748 | try cg.select(&res, &.{.bool}, &ops, comptime &.{ .{ |
| 41029 | .disp = frame_addr.off, | 41749 | .src_constraints = .{ .{ .int = .byte }, .{ .int = .byte } }, |
| | 41750 | .patterns = &.{ |
| | 41751 | .{ .src = .{ .mem, .imm8 } }, |
| | 41752 | .{ .src = .{ .imm8, .mem }, .commute = .{ 0, 1 } }, |
| | 41753 | .{ .src = .{ .to_gpr, .imm8 } }, |
| | 41754 | .{ .src = .{ .imm8, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41755 | .{ .src = .{ .to_gpr, .mem } }, |
| | 41756 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41757 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| | 41758 | }, |
| | 41759 | .dst_temps = .{.{ .cc = .e }}, |
| | 41760 | .clobbers = .{ .eflags = true }, |
| | 41761 | .each = .{ .once = &.{ |
| | 41762 | .{ ._, ._, .cmp, .src0b, .src1b, ._, ._ }, |
| 41030 | } }, | 41763 | } }, |
| 41031 | }); | 41764 | }, .{ |
| 41032 | }, | 41765 | .src_constraints = .{ .{ .int = .word }, .{ .int = .word } }, |
| 41033 | .lea_frame => |frame_addr| new_temp_index.tracking(cg).* = .init(.{ .lea_frame = .{ | 41766 | .patterns = &.{ |
| 41034 | .index = frame_addr.index, | 41767 | .{ .src = .{ .mem, .imm16 } }, |
| 41035 | .off = frame_addr.off + off, | 41768 | .{ .src = .{ .imm16, .mem }, .commute = .{ 0, 1 } }, |
| 41036 | } }), | 41769 | .{ .src = .{ .to_gpr, .imm16 } }, |
| 41037 | } | 41770 | .{ .src = .{ .imm16, .to_gpr }, .commute = .{ 0, 1 } }, |
| 41038 | return .{ .index = new_temp_index.toIndex() }; | 41771 | .{ .src = .{ .to_gpr, .mem } }, |
| 41039 | } | 41772 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, |
| 41040 | | 41773 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| 41041 | fn toOffset(temp: *Temp, off: i32, cg: *CodeGen) !void { | | |
| 41042 | if (off == 0) return; | | |
| 41043 | switch (temp.unwrap(cg)) { | | |
| 41044 | .ref, .err_ret_trace => {}, | | |
| 41045 | .temp => |temp_index| { | | |
| 41046 | const temp_tracking = temp_index.tracking(cg); | | |
| 41047 | switch (temp_tracking.short) { | | |
| 41048 | else => {}, | | |
| 41049 | .register => |reg| { | | |
| 41050 | try cg.freeValue(temp_tracking.long); | | |
| 41051 | temp_tracking.* = .init(.{ .register_offset = .{ | | |
| 41052 | .reg = reg, | | |
| 41053 | .off = off, | | |
| 41054 | } }); | | |
| 41055 | return; | | |
| 41056 | }, | 41774 | }, |
| 41057 | .register_offset => |reg_off| { | 41775 | .dst_temps = .{.{ .cc = .e }}, |
| 41058 | try cg.freeValue(temp_tracking.long); | 41776 | .clobbers = .{ .eflags = true }, |
| 41059 | temp_tracking.* = .init(.{ .register_offset = .{ | 41777 | .each = .{ .once = &.{ |
| 41060 | .reg = reg_off.reg, | 41778 | .{ ._, ._, .cmp, .src0w, .src1w, ._, ._ }, |
| 41061 | .off = reg_off.off + off, | 41779 | } }, |
| 41062 | } }); | 41780 | }, .{ |
| 41063 | return; | 41781 | .src_constraints = .{ .{ .int = .dword }, .{ .int = .dword } }, |
| | 41782 | .patterns = &.{ |
| | 41783 | .{ .src = .{ .mem, .imm32 } }, |
| | 41784 | .{ .src = .{ .imm32, .mem }, .commute = .{ 0, 1 } }, |
| | 41785 | .{ .src = .{ .to_gpr, .imm32 } }, |
| | 41786 | .{ .src = .{ .imm32, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41787 | .{ .src = .{ .to_gpr, .mem } }, |
| | 41788 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41789 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| 41064 | }, | 41790 | }, |
| 41065 | .lea_symbol => |sym_off| { | 41791 | .dst_temps = .{.{ .cc = .e }}, |
| 41066 | assert(std.meta.eql(temp_tracking.long.lea_symbol, sym_off)); | 41792 | .clobbers = .{ .eflags = true }, |
| 41067 | temp_tracking.* = .init(.{ .lea_symbol = .{ | 41793 | .each = .{ .once = &.{ |
| 41068 | .sym_index = sym_off.sym_index, | 41794 | .{ ._, ._, .cmp, .src0d, .src1d, ._, ._ }, |
| 41069 | .off = sym_off.off + off, | 41795 | } }, |
| 41070 | } }); | 41796 | }, .{ |
| 41071 | return; | 41797 | .required_features = .{ .@"64bit", null, null, null }, |
| | 41798 | .src_constraints = .{ .{ .int = .qword }, .{ .int = .qword } }, |
| | 41799 | .patterns = &.{ |
| | 41800 | .{ .src = .{ .mem, .simm32 } }, |
| | 41801 | .{ .src = .{ .simm32, .mem }, .commute = .{ 0, 1 } }, |
| | 41802 | .{ .src = .{ .to_gpr, .simm32 } }, |
| | 41803 | .{ .src = .{ .simm32, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41804 | .{ .src = .{ .to_gpr, .mem } }, |
| | 41805 | .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } }, |
| | 41806 | .{ .src = .{ .to_gpr, .to_gpr } }, |
| 41072 | }, | 41807 | }, |
| 41073 | .lea_frame => |frame_addr| { | 41808 | .dst_temps = .{.{ .cc = .e }}, |
| 41074 | assert(std.meta.eql(temp_tracking.long.lea_frame, frame_addr)); | 41809 | .clobbers = .{ .eflags = true }, |
| 41075 | temp_tracking.* = .init(.{ .lea_frame = .{ | 41810 | .each = .{ .once = &.{ |
| 41076 | .index = frame_addr.index, | 41811 | .{ ._, ._, .cmp, .src0q, .src1q, ._, ._ }, |
| 41077 | .off = frame_addr.off + off, | 41812 | } }, |
| 41078 | } }); | 41813 | }, .{ |
| 41079 | return; | 41814 | .required_features = .{ .sse, .mmx, null, null }, |
| | 41815 | .src_constraints = .{ .{ .int = .qword }, .{ .int = .qword } }, |
| | 41816 | .patterns = &.{ |
| | 41817 | .{ .src = .{ .to_mut_mm, .mem } }, |
| | 41818 | .{ .src = .{ .mem, .to_mut_mm }, .commute = .{ 0, 1 } }, |
| | 41819 | .{ .src = .{ .to_mut_mm, .to_mm } }, |
| | 41820 | }, |
| | 41821 | .extra_temps = .{ |
| | 41822 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| | 41823 | .{ .kind = .{ .rc = .mmx } }, |
| | 41824 | .unused, |
| | 41825 | .unused, |
| | 41826 | .unused, |
| | 41827 | .unused, |
| | 41828 | .unused, |
| | 41829 | .unused, |
| | 41830 | .unused, |
| | 41831 | }, |
| | 41832 | .dst_temps = .{.{ .cc = .z }}, |
| | 41833 | .clobbers = .{ .eflags = true }, |
| | 41834 | .each = .{ .once = &.{ |
| | 41835 | .{ ._, .p_, .xor, .tmp1q, .tmp1q, ._, ._ }, |
| | 41836 | .{ ._, .p_, .xor, .src0q, .src1q, ._, ._ }, |
| | 41837 | .{ ._, .p_b, .cmpeq, .tmp1q, .src0q, ._, ._ }, |
| | 41838 | .{ ._, .p_b, .movmsk, .tmp0d, .tmp1q, ._, ._ }, |
| | 41839 | .{ ._, ._, .cmp, .tmp0b, .si(-1), ._, ._ }, |
| | 41840 | } }, |
| | 41841 | }, .{ |
| | 41842 | .required_features = .{ .avx, null, null, null }, |
| | 41843 | .src_constraints = .{ .{ .int = .xword }, .{ .int = .xword } }, |
| | 41844 | .patterns = &.{ |
| | 41845 | .{ .src = .{ .to_xmm, .mem } }, |
| | 41846 | .{ .src = .{ .mem, .to_xmm }, .commute = .{ 0, 1 } }, |
| | 41847 | .{ .src = .{ .to_xmm, .to_xmm } }, |
| | 41848 | }, |
| | 41849 | .extra_temps = .{ |
| | 41850 | .{ .kind = .{ .rc = .sse } }, |
| | 41851 | .unused, |
| | 41852 | .unused, |
| | 41853 | .unused, |
| | 41854 | .unused, |
| | 41855 | .unused, |
| | 41856 | .unused, |
| | 41857 | .unused, |
| | 41858 | .unused, |
| 41080 | }, | 41859 | }, |
| 41081 | } | 41860 | .dst_temps = .{.{ .cc = .z }}, |
| 41082 | }, | 41861 | .clobbers = .{ .eflags = true }, |
| 41083 | } | 41862 | .each = .{ .once = &.{ |
| 41084 | const new_temp = try temp.getOffset(off, cg); | 41863 | .{ ._, .vp_, .xor, .tmp0x, .src0x, .src1x, ._ }, |
| 41085 | try temp.die(cg); | 41864 | .{ ._, .vp_, .@"test", .tmp0x, .tmp0x, ._, ._ }, |
| 41086 | temp.* = new_temp; | | |
| 41087 | } | | |
| 41088 | | | |
| 41089 | fn getLimb(temp: Temp, limb_ty: Type, limb_index: u28, cg: *CodeGen) !Temp { | | |
| 41090 | const new_temp_index = cg.next_temp_index; | | |
| 41091 | cg.temp_type[@intFromEnum(new_temp_index)] = limb_ty; | | |
| 41092 | switch (temp.tracking(cg).short) { | | |
| 41093 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | | |
| 41094 | .immediate => |imm| { | | |
| 41095 | assert(limb_index == 0); | | |
| 41096 | new_temp_index.tracking(cg).* = .init(.{ .immediate = imm }); | | |
| 41097 | }, | | |
| 41098 | .register => |reg| { | | |
| 41099 | assert(limb_index == 0); | | |
| 41100 | const new_reg = | | |
| 41101 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | | |
| 41102 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); | | |
| 41103 | try cg.asmRegisterRegister(.{ ._, .mov }, new_reg.to64(), reg.to64()); | | |
| 41104 | }, | | |
| 41105 | .register_pair => |regs| { | | |
| 41106 | const new_reg = | | |
| 41107 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | | |
| 41108 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); | | |
| 41109 | try cg.asmRegisterRegister(.{ ._, .mov }, new_reg.to64(), regs[limb_index].to64()); | | |
| 41110 | }, | | |
| 41111 | .register_offset => |reg_off| { | | |
| 41112 | assert(limb_index == 0); | | |
| 41113 | const new_reg = | | |
| 41114 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | | |
| 41115 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); | | |
| 41116 | try cg.asmRegisterMemory(.{ ._, .lea }, new_reg.to64(), .{ | | |
| 41117 | .base = .{ .reg = reg_off.reg.to64() }, | | |
| 41118 | .mod = .{ .rm = .{ | | |
| 41119 | .size = .qword, | | |
| 41120 | .disp = reg_off.off + @as(u31, limb_index) * 8, | | |
| 41121 | } }, | 41865 | } }, |
| 41122 | }); | 41866 | }, .{ |
| 41123 | }, | 41867 | .required_features = .{ .sse4_1, null, null, null }, |
| 41124 | .load_symbol => |sym_off| { | 41868 | .src_constraints = .{ .{ .int = .xword }, .{ .int = .xword } }, |
| 41125 | const new_reg = | 41869 | .patterns = &.{ |
| 41126 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 41870 | .{ .src = .{ .to_mut_xmm, .mem } }, |
| 41127 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); | 41871 | .{ .src = .{ .mem, .to_mut_xmm }, .commute = .{ 0, 1 } }, |
| 41128 | try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ | 41872 | .{ .src = .{ .to_mut_xmm, .to_xmm } }, |
| 41129 | .base = .{ .reloc = sym_off.sym_index }, | 41873 | }, |
| 41130 | .mod = .{ .rm = .{ | 41874 | .dst_temps = .{.{ .cc = .z }}, |
| 41131 | .size = .qword, | 41875 | .clobbers = .{ .eflags = true }, |
| 41132 | .disp = sym_off.off + @as(u31, limb_index) * 8, | 41876 | .each = .{ .once = &.{ |
| | 41877 | .{ ._, .p_, .xor, .src0x, .src1x, ._, ._ }, |
| | 41878 | .{ ._, .p_, .@"test", .src0x, .src0x, ._, ._ }, |
| 41133 | } }, | 41879 | } }, |
| 41134 | }); | 41880 | }, .{ |
| 41135 | }, | 41881 | .required_features = .{ .sse2, .fast_imm16, null, null }, |
| 41136 | .lea_symbol => |sym_off| { | 41882 | .src_constraints = .{ .{ .int = .xword }, .{ .int = .xword } }, |
| 41137 | assert(limb_index == 0); | 41883 | .patterns = &.{ |
| 41138 | new_temp_index.tracking(cg).* = .init(.{ .lea_symbol = sym_off }); | 41884 | .{ .src = .{ .to_mut_xmm, .mem } }, |
| 41139 | }, | 41885 | .{ .src = .{ .mem, .to_mut_xmm }, .commute = .{ 0, 1 } }, |
| 41140 | .load_frame => |frame_addr| { | 41886 | .{ .src = .{ .to_mut_xmm, .to_xmm } }, |
| 41141 | const new_reg = | 41887 | }, |
| 41142 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 41888 | .extra_temps = .{ |
| 41143 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); | 41889 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 41144 | try cg.asmRegisterMemory(.{ ._, .mov }, new_reg.to64(), .{ | 41890 | .{ .kind = .{ .rc = .sse } }, |
| 41145 | .base = .{ .frame = frame_addr.index }, | 41891 | .unused, |
| 41146 | .mod = .{ .rm = .{ | 41892 | .unused, |
| 41147 | .size = .qword, | 41893 | .unused, |
| 41148 | .disp = frame_addr.off + @as(u31, limb_index) * 8, | 41894 | .unused, |
| | 41895 | .unused, |
| | 41896 | .unused, |
| | 41897 | .unused, |
| | 41898 | }, |
| | 41899 | .dst_temps = .{.{ .cc = .z }}, |
| | 41900 | .clobbers = .{ .eflags = true }, |
| | 41901 | .each = .{ .once = &.{ |
| | 41902 | .{ ._, .p_, .xor, .tmp1x, .tmp1x, ._, ._ }, |
| | 41903 | .{ ._, .p_, .xor, .src0x, .src1x, ._, ._ }, |
| | 41904 | .{ ._, .p_b, .cmpeq, .tmp1x, .src0x, ._, ._ }, |
| | 41905 | .{ ._, .p_b, .movmsk, .tmp0d, .tmp1x, ._, ._ }, |
| | 41906 | .{ ._, ._, .cmp, .tmp0w, .si(-1), ._, ._ }, |
| 41149 | } }, | 41907 | } }, |
| 41150 | }); | 41908 | }, .{ |
| 41151 | }, | 41909 | .required_features = .{ .sse2, null, null, null }, |
| 41152 | .lea_frame => |frame_addr| { | 41910 | .src_constraints = .{ .{ .int = .xword }, .{ .int = .xword } }, |
| 41153 | assert(limb_index == 0); | 41911 | .patterns = &.{ |
| 41154 | new_temp_index.tracking(cg).* = .init(.{ .lea_frame = frame_addr }); | 41912 | .{ .src = .{ .to_mut_xmm, .mem } }, |
| 41155 | }, | 41913 | .{ .src = .{ .mem, .to_mut_xmm }, .commute = .{ 0, 1 } }, |
| 41156 | } | 41914 | .{ .src = .{ .to_mut_xmm, .to_xmm } }, |
| 41157 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); | | |
| 41158 | return .{ .index = new_temp_index.toIndex() }; | | |
| 41159 | } | | |
| 41160 | | | |
| 41161 | fn toLimb(temp: *Temp, limb_ty: Type, limb_index: u28, cg: *CodeGen) !void { | | |
| 41162 | switch (temp.unwrap(cg)) { | | |
| 41163 | .ref => {}, | | |
| 41164 | .temp => |temp_index| { | | |
| 41165 | const temp_tracking = temp_index.tracking(cg); | | |
| 41166 | switch (temp_tracking.short) { | | |
| 41167 | else => {}, | | |
| 41168 | .register, .lea_symbol, .lea_frame => { | | |
| 41169 | assert(limb_index == 0); | | |
| 41170 | cg.temp_type[@intFromEnum(temp_index)] = limb_ty; | | |
| 41171 | return; | | |
| 41172 | }, | 41915 | }, |
| 41173 | .register_pair => |regs| { | 41916 | .extra_temps = .{ |
| 41174 | switch (temp_tracking.long) { | 41917 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 41175 | .none, .reserved_frame => {}, | 41918 | .{ .kind = .{ .rc = .sse } }, |
| 41176 | else => temp_tracking.long = | 41919 | .unused, |
| 41177 | temp_tracking.long.address().offset(@as(u31, limb_index) * 8).deref(), | 41920 | .unused, |
| 41178 | } | 41921 | .unused, |
| 41179 | for (regs, 0..) |reg, reg_index| if (reg_index != limb_index) | 41922 | .unused, |
| 41180 | cg.register_manager.freeReg(reg); | 41923 | .unused, |
| 41181 | temp_tracking.* = .init(.{ .register = regs[limb_index] }); | 41924 | .unused, |
| 41182 | cg.temp_type[@intFromEnum(temp_index)] = limb_ty; | 41925 | .unused, |
| 41183 | return; | | |
| 41184 | }, | 41926 | }, |
| 41185 | .load_symbol => |sym_off| { | 41927 | .dst_temps = .{.{ .cc = .z }}, |
| 41186 | assert(std.meta.eql(temp_tracking.long.load_symbol, sym_off)); | 41928 | .clobbers = .{ .eflags = true }, |
| 41187 | temp_tracking.* = .init(.{ .load_symbol = .{ | 41929 | .each = .{ .once = &.{ |
| 41188 | .sym_index = sym_off.sym_index, | 41930 | .{ ._, .p_, .xor, .tmp1x, .tmp1x, ._, ._ }, |
| 41189 | .off = sym_off.off + @as(u31, limb_index) * 8, | 41931 | .{ ._, .p_, .xor, .src0x, .src1x, ._, ._ }, |
| 41190 | } }); | 41932 | .{ ._, .p_b, .cmpeq, .tmp1x, .src0x, ._, ._ }, |
| 41191 | cg.temp_type[@intFromEnum(temp_index)] = limb_ty; | 41933 | .{ ._, .p_b, .movmsk, .tmp0d, .tmp1x, ._, ._ }, |
| 41192 | return; | 41934 | .{ ._, ._, .xor, .tmp0d, .si(0xffff), ._, ._ }, |
| | 41935 | } }, |
| | 41936 | }, .{ |
| | 41937 | .required_features = .{ .avx2, null, null, null }, |
| | 41938 | .src_constraints = .{ .{ .int = .yword }, .{ .int = .yword } }, |
| | 41939 | .patterns = &.{ |
| | 41940 | .{ .src = .{ .to_ymm, .mem } }, |
| | 41941 | .{ .src = .{ .mem, .to_ymm }, .commute = .{ 0, 1 } }, |
| | 41942 | .{ .src = .{ .to_ymm, .to_ymm } }, |
| 41193 | }, | 41943 | }, |
| 41194 | .load_frame => |frame_addr| if (!frame_addr.index.isNamed()) { | 41944 | .extra_temps = .{ |
| 41195 | assert(std.meta.eql(temp_tracking.long.load_frame, frame_addr)); | 41945 | .{ .kind = .{ .rc = .sse } }, |
| 41196 | temp_tracking.* = .init(.{ .load_frame = .{ | 41946 | .unused, |
| 41197 | .index = frame_addr.index, | 41947 | .unused, |
| 41198 | .off = frame_addr.off + @as(u31, limb_index) * 8, | 41948 | .unused, |
| 41199 | } }); | 41949 | .unused, |
| 41200 | cg.temp_type[@intFromEnum(temp_index)] = limb_ty; | 41950 | .unused, |
| 41201 | return; | 41951 | .unused, |
| | 41952 | .unused, |
| | 41953 | .unused, |
| 41202 | }, | 41954 | }, |
| 41203 | } | 41955 | .dst_temps = .{.{ .cc = .z }}, |
| 41204 | }, | 41956 | .clobbers = .{ .eflags = true }, |
| 41205 | .err_ret_trace => unreachable, | 41957 | .each = .{ .once = &.{ |
| 41206 | } | 41958 | .{ ._, .vp_, .xor, .tmp0y, .src0y, .src1y, ._ }, |
| 41207 | const new_temp = try temp.getLimb(limb_ty, limb_index, cg); | 41959 | .{ ._, .vp_, .@"test", .tmp0y, .tmp0y, ._, ._ }, |
| 41208 | try temp.die(cg); | 41960 | } }, |
| 41209 | temp.* = new_temp; | 41961 | }, .{ |
| 41210 | } | 41962 | .required_features = .{ .avx, null, null, null }, |
| 41211 | | 41963 | .src_constraints = .{ .{ .int = .yword }, .{ .int = .yword } }, |
| 41212 | fn toSlicePtr(temp: *Temp, cg: *CodeGen) !void { | 41964 | .patterns = &.{ |
| 41213 | const temp_ty = temp.typeOf(cg); | 41965 | .{ .src = .{ .to_ymm, .mem } }, |
| 41214 | if (temp_ty.isSlice(cg.pt.zcu)) try temp.toLimb(temp_ty.slicePtrFieldType(cg.pt.zcu), 0, cg); | 41966 | .{ .src = .{ .mem, .to_ymm }, .commute = .{ 0, 1 } }, |
| 41215 | } | 41967 | .{ .src = .{ .to_ymm, .to_ymm } }, |
| 41216 | | 41968 | }, |
| 41217 | fn toSliceLen(temp: *Temp, cg: *CodeGen) !void { | 41969 | .extra_temps = .{ |
| 41218 | try temp.toLimb(.usize, 1, cg); | 41970 | .{ .kind = .{ .rc = .sse } }, |
| 41219 | } | 41971 | .unused, |
| 41220 | | 41972 | .unused, |
| 41221 | fn toReg(temp: *Temp, new_reg: Register, cg: *CodeGen) !bool { | 41973 | .unused, |
| 41222 | const val, const ty: Type = val_ty: switch (temp.unwrap(cg)) { | 41974 | .unused, |
| 41223 | .ref => |ref| .{ temp.tracking(cg).short, cg.typeOf(ref) }, | 41975 | .unused, |
| 41224 | .temp => |temp_index| { | 41976 | .unused, |
| 41225 | const temp_tracking = temp_index.tracking(cg); | 41977 | .unused, |
| 41226 | if (temp_tracking.short == .register and | 41978 | .unused, |
| 41227 | temp_tracking.short.register == new_reg) return false; | 41979 | }, |
| 41228 | break :val_ty .{ temp_tracking.short, temp_index.typeOf(cg) }; | 41980 | .dst_temps = .{.{ .cc = .z }}, |
| 41229 | }, | 41981 | .clobbers = .{ .eflags = true }, |
| 41230 | .err_ret_trace => .{ temp.tracking(cg).short, .usize }, | 41982 | .each = .{ .once = &.{ |
| 41231 | }; | 41983 | .{ ._, .v_pd, .xor, .tmp0y, .src0y, .src1y, ._ }, |
| 41232 | const new_temp_index = cg.next_temp_index; | 41984 | .{ ._, .vp_, .@"test", .tmp0y, .tmp0y, ._, ._ }, |
| 41233 | try cg.register_manager.getReg(new_reg, new_temp_index.toIndex()); | 41985 | } }, |
| 41234 | cg.temp_type[@intFromEnum(new_temp_index)] = ty; | 41986 | }, .{ |
| 41235 | try cg.genSetReg(new_reg, ty, val, .{}); | 41987 | .required_features = .{ .avx2, null, null, null }, |
| 41236 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); | 41988 | .src_constraints = .{ |
| 41237 | try temp.die(cg); | 41989 | .{ .remainder_int = .{ .of = .yword, .is = .xword } }, |
| 41238 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); | 41990 | .{ .remainder_int = .{ .of = .yword, .is = .xword } }, |
| 41239 | temp.* = .{ .index = new_temp_index.toIndex() }; | 41991 | }, |
| 41240 | return true; | 41992 | .patterns = &.{ |
| 41241 | } | 41993 | .{ .src = .{ .to_mem, .to_mem } }, |
| 41242 | | 41994 | }, |
| 41243 | fn toRegClass(temp: *Temp, mut: bool, rc: Register.Class, cg: *CodeGen) !bool { | 41995 | .extra_temps = .{ |
| 41244 | const val = temp.tracking(cg).short; | 41996 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 41245 | if (!mut or temp.isMut(cg)) switch (val) { | 41997 | .{ .kind = .{ .rc = .sse } }, |
| 41246 | else => {}, | 41998 | .unused, |
| 41247 | .register => |reg| if (reg.class() == rc) return false, | 41999 | .unused, |
| 41248 | .register_offset => |reg_off| if (reg_off.reg.class() == rc and reg_off.off == 0) return false, | 42000 | .unused, |
| 41249 | }; | 42001 | .unused, |
| 41250 | const ty = temp.typeOf(cg); | 42002 | .unused, |
| 41251 | const new_temp_index = cg.next_temp_index; | 42003 | .unused, |
| 41252 | cg.temp_type[@intFromEnum(new_temp_index)] = ty; | 42004 | .unused, |
| 41253 | const new_reg = try cg.register_manager.allocReg(new_temp_index.toIndex(), regSetForRegClass(rc)); | 42005 | }, |
| 41254 | try cg.genSetReg(new_reg, ty, val, .{}); | 42006 | .dst_temps = .{.{ .cc = .z }}, |
| 41255 | new_temp_index.tracking(cg).* = .init(.{ .register = new_reg }); | 42007 | .clobbers = .{ .eflags = true }, |
| 41256 | try temp.die(cg); | 42008 | .each = .{ .once = &.{ |
| 41257 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); | 42009 | .{ ._, ._, .mov, .tmp0p, .sia(16, .src0, .sub_size), ._, ._ }, |
| 41258 | temp.* = .{ .index = new_temp_index.toIndex() }; | 42010 | .{ .@"0:", .v_dqu, .mov, .tmp1y, .memiad(.src0y, .tmp0, .add_size, -16), ._, ._ }, |
| 41259 | return true; | 42011 | .{ ._, .vp_, .xor, .tmp1y, .tmp1y, .memiad(.src1y, .tmp0, .add_size, -16), ._ }, |
| 41260 | } | 42012 | .{ ._, .vp_, .@"test", .tmp1y, .tmp1y, ._, ._ }, |
| 41261 | | 42013 | .{ ._, ._nz, .j, .@"0f", ._, ._, ._ }, |
| 41262 | fn toPair(first_temp: *Temp, second_temp: *Temp, cg: *CodeGen) !void { | 42014 | .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ }, |
| 41263 | while (true) for ([_]*Temp{ first_temp, second_temp }) |part_temp| { | 42015 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 41264 | if (try part_temp.toRegClass(true, .general_purpose, cg)) break; | 42016 | .{ ._, .v_dqa, .mov, .tmp1x, .memad(.src0x, .add_size, -16), ._, ._ }, |
| 41265 | } else break; | 42017 | .{ ._, .vp_, .xor, .tmp1x, .tmp1x, .memad(.src1x, .add_size, -16), ._ }, |
| 41266 | const first_temp_tracking = first_temp.unwrap(cg).temp.tracking(cg); | 42018 | .{ ._, .vp_, .@"test", .tmp1x, .tmp1x, ._, ._ }, |
| 41267 | const second_temp_tracking = second_temp.unwrap(cg).temp.tracking(cg); | 42019 | } }, |
| 41268 | const result: MCValue = .{ .register_pair = .{ | 42020 | }, .{ |
| 41269 | first_temp_tracking.short.register, | 42021 | .required_features = .{ .avx, null, null, null }, |
| 41270 | second_temp_tracking.short.register, | 42022 | .src_constraints = .{ |
| 41271 | } }; | 42023 | .{ .remainder_int = .{ .of = .yword, .is = .xword } }, |
| 41272 | const result_temp_index = cg.next_temp_index; | 42024 | .{ .remainder_int = .{ .of = .yword, .is = .xword } }, |
| 41273 | const result_temp: Temp = .{ .index = result_temp_index.toIndex() }; | 42025 | }, |
| 41274 | assert(cg.reuseTemp(result_temp.index, first_temp.index, first_temp_tracking)); | 42026 | .patterns = &.{ |
| 41275 | assert(cg.reuseTemp(result_temp.index, second_temp.index, second_temp_tracking)); | 42027 | .{ .src = .{ .to_mem, .to_mem } }, |
| 41276 | cg.temp_type[@intFromEnum(result_temp_index)] = .slice_const_u8; | 42028 | }, |
| 41277 | result_temp_index.tracking(cg).* = .init(result); | 42029 | .extra_temps = .{ |
| 41278 | first_temp.* = result_temp; | 42030 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 41279 | second_temp.* = result_temp; | 42031 | .{ .kind = .{ .rc = .sse } }, |
| 41280 | } | 42032 | .unused, |
| 41281 | | 42033 | .unused, |
| 41282 | fn asMask(temp: Temp, info: MaskInfo, cg: *CodeGen) void { | 42034 | .unused, |
| 41283 | assert(info.scalar != .none); | 42035 | .unused, |
| 41284 | const mcv = &temp.unwrap(cg).temp.tracking(cg).short; | 42036 | .unused, |
| 41285 | const reg = mcv.register; | 42037 | .unused, |
| 41286 | mcv.* = .{ .register_mask = .{ .reg = reg, .info = info } }; | 42038 | .unused, |
| 41287 | } | 42039 | }, |
| 41288 | | 42040 | .dst_temps = .{.{ .cc = .z }}, |
| 41289 | fn toLea(temp: *Temp, cg: *CodeGen) !bool { | 42041 | .clobbers = .{ .eflags = true }, |
| 41290 | switch (temp.tracking(cg).short) { | 42042 | .each = .{ .once = &.{ |
| 41291 | .none, | 42043 | .{ ._, ._, .mov, .tmp0p, .sia(16, .src0, .sub_size), ._, ._ }, |
| 41292 | .unreach, | 42044 | .{ .@"0:", .v_pd, .movu, .tmp1y, .memiad(.src0y, .tmp0, .add_size, -16), ._, ._ }, |
| 41293 | .dead, | 42045 | .{ ._, .v_pd, .xor, .tmp1y, .tmp1y, .memiad(.src1y, .tmp0, .add_size, -16), ._ }, |
| 41294 | .undef, | 42046 | .{ ._, .vp_, .@"test", .tmp1y, .tmp1y, ._, ._ }, |
| 41295 | .eflags, | 42047 | .{ ._, ._nz, .j, .@"0f", ._, ._, ._ }, |
| 41296 | .register_pair, | 42048 | .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ }, |
| 41297 | .register_triple, | 42049 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 41298 | .register_quadruple, | 42050 | .{ ._, .v_pd, .mova, .tmp1x, .memad(.src0x, .add_size, -16), ._, ._ }, |
| 41299 | .register_overflow, | 42051 | .{ ._, .v_pd, .xor, .tmp1x, .tmp1x, .memad(.src1x, .add_size, -16), ._ }, |
| 41300 | .register_mask, | 42052 | .{ ._, .vp_, .@"test", .tmp1x, .tmp1x, ._, ._ }, |
| 41301 | .elementwise_regs_then_frame, | 42053 | } }, |
| 41302 | .reserved_frame, | 42054 | }, .{ |
| 41303 | .air_ref, | 42055 | .required_features = .{ .avx2, null, null, null }, |
| 41304 | => unreachable, // not a valid pointer | 42056 | .src_constraints = .{ |
| 41305 | .immediate, | 42057 | .{ .remainder_int = .{ .of = .yword, .is = .yword } }, |
| 41306 | .register, | 42058 | .{ .remainder_int = .{ .of = .yword, .is = .yword } }, |
| 41307 | .register_offset, | 42059 | }, |
| 41308 | .lea_direct, | 42060 | .patterns = &.{ |
| 41309 | .lea_got, | 42061 | .{ .src = .{ .to_mem, .to_mem } }, |
| 41310 | .lea_tlv, | 42062 | }, |
| 41311 | .lea_frame, | 42063 | .extra_temps = .{ |
| 41312 | => return false, | 42064 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 41313 | .memory, | 42065 | .{ .kind = .{ .rc = .sse } }, |
| 41314 | .indirect, | 42066 | .unused, |
| 41315 | .load_symbol, | 42067 | .unused, |
| 41316 | .load_direct, | 42068 | .unused, |
| 41317 | .load_got, | 42069 | .unused, |
| 41318 | .load_tlv, | 42070 | .unused, |
| 41319 | .load_frame, | 42071 | .unused, |
| 41320 | => return temp.toRegClass(true, .general_purpose, cg), | 42072 | .unused, |
| 41321 | .lea_symbol => |sym_off| { | 42073 | }, |
| 41322 | const off = sym_off.off; | 42074 | .dst_temps = .{.{ .cc = .z }}, |
| 41323 | if (off == 0) return false; | 42075 | .clobbers = .{ .eflags = true }, |
| 41324 | try temp.toOffset(-off, cg); | 42076 | .each = .{ .once = &.{ |
| 41325 | while (try temp.toRegClass(true, .general_purpose, cg)) {} | 42077 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| 41326 | try temp.toOffset(off, cg); | 42078 | .{ .@"0:", .v_dqu, .mov, .tmp1y, .memia(.src0y, .tmp0, .add_size), ._, ._ }, |
| 41327 | return true; | 42079 | .{ ._, .vp_, .xor, .tmp1y, .tmp1y, .memia(.src1y, .tmp0, .add_size), ._ }, |
| 41328 | }, | 42080 | .{ ._, .vp_, .@"test", .tmp1y, .tmp1y, ._, ._ }, |
| 41329 | } | 42081 | .{ ._, ._nz, .j, .@"0f", ._, ._, ._ }, |
| 41330 | } | 42082 | .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ }, |
| 41331 | | 42083 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 41332 | fn toMemory(temp: *Temp, cg: *CodeGen) !bool { | 42084 | } }, |
| 41333 | const temp_tracking = temp.tracking(cg); | 42085 | }, .{ |
| 41334 | if (temp_tracking.short.isMemory()) return false; | 42086 | .required_features = .{ .avx, null, null, null }, |
| 41335 | const new_temp_index = cg.next_temp_index; | 42087 | .src_constraints = .{ |
| 41336 | const ty = temp.typeOf(cg); | 42088 | .{ .remainder_int = .{ .of = .yword, .is = .yword } }, |
| 41337 | cg.temp_type[@intFromEnum(new_temp_index)] = ty; | 42089 | .{ .remainder_int = .{ .of = .yword, .is = .yword } }, |
| 41338 | const new_frame_index = try cg.allocFrameIndex(.initSpill(ty, cg.pt.zcu)); | 42090 | }, |
| 41339 | try cg.genSetMem(.{ .frame = new_frame_index }, 0, ty, temp_tracking.short, .{}); | 42091 | .patterns = &.{ |
| 41340 | new_temp_index.tracking(cg).* = .init(.{ .load_frame = .{ .index = new_frame_index } }); | 42092 | .{ .src = .{ .to_mem, .to_mem } }, |
| 41341 | try temp.die(cg); | 42093 | }, |
| 41342 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); | 42094 | .extra_temps = .{ |
| 41343 | temp.* = .{ .index = new_temp_index.toIndex() }; | 42095 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 41344 | return true; | 42096 | .{ .kind = .{ .rc = .sse } }, |
| 41345 | } | 42097 | .unused, |
| 41346 | | 42098 | .unused, |
| 41347 | // hack around linker relocation bugs | 42099 | .unused, |
| 41348 | fn toBase(temp: *Temp, cg: *CodeGen) !bool { | 42100 | .unused, |
| 41349 | const temp_tracking = temp.tracking(cg); | 42101 | .unused, |
| 41350 | if (temp_tracking.short.isBase()) return false; | 42102 | .unused, |
| 41351 | if (try temp.toMemory(cg)) return true; | 42103 | .unused, |
| 41352 | const new_temp_index = cg.next_temp_index; | 42104 | }, |
| 41353 | cg.temp_type[@intFromEnum(new_temp_index)] = temp.typeOf(cg); | 42105 | .dst_temps = .{.{ .cc = .z }}, |
| 41354 | const new_reg = | 42106 | .clobbers = .{ .eflags = true }, |
| 41355 | try cg.register_manager.allocReg(new_temp_index.toIndex(), abi.RegisterClass.gp); | 42107 | .each = .{ .once = &.{ |
| 41356 | try cg.genSetReg(new_reg, .usize, temp_tracking.short.address(), .{}); | 42108 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| 41357 | new_temp_index.tracking(cg).* = .init(.{ .indirect = .{ .reg = new_reg } }); | 42109 | .{ .@"0:", .v_pd, .movu, .tmp1y, .memia(.src0y, .tmp0, .add_size), ._, ._ }, |
| 41358 | try temp.die(cg); | 42110 | .{ ._, .v_pd, .xor, .tmp1y, .tmp1y, .memia(.src1y, .tmp0, .add_size), ._ }, |
| 41359 | cg.next_temp_index = @enumFromInt(@intFromEnum(new_temp_index) + 1); | 42111 | .{ ._, .vp_, .@"test", .tmp1y, .tmp1y, ._, ._ }, |
| 41360 | temp.* = .{ .index = new_temp_index.toIndex() }; | 42112 | .{ ._, ._nz, .j, .@"0f", ._, ._, ._ }, |
| 41361 | return true; | 42113 | .{ ._, ._, .add, .tmp0p, .si(32), ._, ._ }, |
| 41362 | } | 42114 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 41363 | | 42115 | } }, |
| 41364 | const AccessOptions = struct { | 42116 | }, .{ |
| 41365 | disp: i32 = 0, | 42117 | .required_features = .{ .avx, null, null, null }, |
| 41366 | safe: bool = false, | 42118 | .src_constraints = .{ |
| 41367 | }; | 42119 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, |
| 41368 | | 42120 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, |
| 41369 | fn load(ptr: *Temp, val_ty: Type, opts: AccessOptions, cg: *CodeGen) !Temp { | 42121 | }, |
| 41370 | const val = try cg.tempAlloc(val_ty); | 42122 | .patterns = &.{ |
| 41371 | try ptr.toOffset(opts.disp, cg); | 42123 | .{ .src = .{ .to_mem, .to_mem } }, |
| 41372 | while (try ptr.toLea(cg)) {} | 42124 | }, |
| 41373 | const val_mcv = val.tracking(cg).short; | 42125 | .extra_temps = .{ |
| 41374 | switch (val_mcv) { | 42126 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 41375 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | 42127 | .{ .kind = .{ .rc = .sse } }, |
| 41376 | .register => |val_reg| try ptr.loadReg(val_ty, registerAlias( | 42128 | .unused, |
| 41377 | val_reg, | 42129 | .unused, |
| 41378 | @intCast(val_ty.abiSize(cg.pt.zcu)), | 42130 | .unused, |
| 41379 | ), cg), | 42131 | .unused, |
| 41380 | inline .register_pair, | 42132 | .unused, |
| 41381 | .register_triple, | 42133 | .unused, |
| 41382 | .register_quadruple, | 42134 | .unused, |
| 41383 | => |val_regs| for (val_regs) |val_reg| { | 42135 | }, |
| 41384 | try ptr.loadReg(val_ty, val_reg, cg); | 42136 | .dst_temps = .{.{ .cc = .z }}, |
| 41385 | try ptr.toOffset(@divExact(val_reg.bitSize(), 8), cg); | 42137 | .clobbers = .{ .eflags = true }, |
| 41386 | while (try ptr.toLea(cg)) {} | 42138 | .each = .{ .once = &.{ |
| 41387 | }, | 42139 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| 41388 | .register_offset => |val_reg_off| switch (val_reg_off.off) { | 42140 | .{ .@"0:", .v_dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_size), ._, ._ }, |
| 41389 | 0 => try ptr.loadReg(val_ty, registerAlias( | 42141 | .{ ._, .vp_, .xor, .tmp1x, .tmp1x, .memia(.src1x, .tmp0, .add_size), ._ }, |
| 41390 | val_reg_off.reg, | 42142 | .{ ._, .vp_, .@"test", .tmp1x, .tmp1x, ._, ._ }, |
| 41391 | @intCast(val_ty.abiSize(cg.pt.zcu)), | 42143 | .{ ._, ._nz, .j, .@"0f", ._, ._, ._ }, |
| 41392 | ), cg), | 42144 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 41393 | else => unreachable, | 42145 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 41394 | }, | 42146 | } }, |
| 41395 | .memory, .indirect, .load_frame, .load_symbol => { | 42147 | }, .{ |
| 41396 | var val_ptr = try cg.tempInit(.usize, val_mcv.address()); | 42148 | .required_features = .{ .sse4_1, null, null, null }, |
| 41397 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); | 42149 | .src_constraints = .{ |
| 41398 | try val_ptr.memcpy(ptr, &len, cg); | 42150 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, |
| 41399 | try val_ptr.die(cg); | 42151 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, |
| 41400 | try len.die(cg); | 42152 | }, |
| 41401 | }, | 42153 | .patterns = &.{ |
| 41402 | } | 42154 | .{ .src = .{ .to_mem, .to_mem } }, |
| 41403 | return val; | 42155 | }, |
| 41404 | } | 42156 | .extra_temps = .{ |
| 41405 | | 42157 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 41406 | fn store(ptr: *Temp, val: *Temp, opts: AccessOptions, cg: *CodeGen) !void { | 42158 | .{ .kind = .{ .rc = .sse } }, |
| 41407 | const val_ty = val.typeOf(cg); | 42159 | .unused, |
| 41408 | try ptr.toOffset(opts.disp, cg); | 42160 | .unused, |
| 41409 | while (try ptr.toLea(cg)) {} | 42161 | .unused, |
| 41410 | val_to_gpr: while (true) : (while (try ptr.toLea(cg) or | 42162 | .unused, |
| 41411 | try val.toRegClass(false, .general_purpose, cg)) | 42163 | .unused, |
| 41412 | {}) { | 42164 | .unused, |
| 41413 | const val_mcv = val.tracking(cg).short; | 42165 | .unused, |
| 41414 | switch (val_mcv) { | 42166 | }, |
| 41415 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | 42167 | .dst_temps = .{.{ .cc = .z }}, |
| 41416 | .undef => if (opts.safe) { | 42168 | .clobbers = .{ .eflags = true }, |
| 41417 | var pat = try cg.tempInit(.u8, .{ .immediate = 0xaa }); | 42169 | .each = .{ .once = &.{ |
| 41418 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); | 42170 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| 41419 | try ptr.memset(&pat, &len, cg); | 42171 | .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_size), ._, ._ }, |
| 41420 | try pat.die(cg); | 42172 | .{ ._, .p_, .xor, .tmp1x, .memia(.src1x, .tmp0, .add_size), ._, ._ }, |
| 41421 | try len.die(cg); | 42173 | .{ ._, .p_, .@"test", .tmp1x, .tmp1x, ._, ._ }, |
| 41422 | }, | 42174 | .{ ._, ._nz, .j, .@"0f", ._, ._, ._ }, |
| 41423 | .immediate => |val_imm| { | 42175 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 41424 | const val_op: Immediate = if (std.math.cast(u31, val_imm)) |val_uimm31| | 42176 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 41425 | .u(val_uimm31) | 42177 | } }, |
| 41426 | else if (std.math.cast(i32, @as(i64, @bitCast(val_imm)))) |val_simm32| | 42178 | }, .{ |
| 41427 | .s(val_simm32) | 42179 | .required_features = .{ .sse2, .fast_imm16, null, null }, |
| 41428 | else | 42180 | .src_constraints = .{ |
| 41429 | continue :val_to_gpr; | 42181 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, |
| 41430 | // hack around linker relocation bugs | 42182 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, |
| 41431 | switch (ptr.tracking(cg).short) { | 42183 | }, |
| 41432 | else => {}, | 42184 | .patterns = &.{ |
| 41433 | .lea_symbol => while (try ptr.toRegClass(false, .general_purpose, cg)) {}, | 42185 | .{ .src = .{ .to_mem, .to_mem } }, |
| 41434 | } | 42186 | }, |
| 41435 | try cg.asmMemoryImmediate( | 42187 | .extra_temps = .{ |
| 41436 | .{ ._, .mov }, | 42188 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 41437 | try ptr.tracking(cg).short.deref().mem(cg, .{ | 42189 | .{ .kind = .{ .rc = .sse } }, |
| 41438 | .size = cg.memSize(val_ty), | 42190 | .{ .type = .u16, .kind = .{ .rc = .general_purpose } }, |
| 41439 | }), | 42191 | .unused, |
| 41440 | val_op, | 42192 | .unused, |
| 41441 | ); | 42193 | .unused, |
| 41442 | }, | 42194 | .unused, |
| 41443 | .eflags => |cc| { | 42195 | .unused, |
| 41444 | // hack around linker relocation bugs | 42196 | .unused, |
| 41445 | switch (ptr.tracking(cg).short) { | 42197 | }, |
| 41446 | else => {}, | 42198 | .dst_temps = .{.{ .cc = .z }}, |
| 41447 | .lea_symbol => while (try ptr.toRegClass(false, .general_purpose, cg)) {}, | 42199 | .clobbers = .{ .eflags = true }, |
| 41448 | } | 42200 | .each = .{ .once = &.{ |
| 41449 | try cg.asmSetccMemory( | 42201 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| 41450 | cc, | 42202 | .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_size), ._, ._ }, |
| 41451 | try ptr.tracking(cg).short.deref().mem(cg, .{ .size = .byte }), | 42203 | .{ ._, .p_b, .cmpeq, .tmp1x, .memia(.src1x, .tmp0, .add_size), ._, ._ }, |
| 41452 | ); | 42204 | .{ ._, .p_b, .movmsk, .tmp2d, .tmp1x, ._, ._ }, |
| 41453 | }, | 42205 | .{ ._, ._, .cmp, .tmp2w, .si(-1), ._, ._ }, |
| 41454 | .register => |val_reg| try ptr.storeRegs(val_ty, &.{registerAlias( | 42206 | .{ ._, ._nz, .j, .@"0f", ._, ._, ._ }, |
| 41455 | val_reg, | 42207 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 41456 | @intCast(val_ty.abiSize(cg.pt.zcu)), | 42208 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 41457 | )}, cg), | 42209 | } }, |
| 41458 | inline .register_pair, | 42210 | }, .{ |
| 41459 | .register_triple, | 42211 | .required_features = .{ .sse2, null, null, null }, |
| 41460 | .register_quadruple, | 42212 | .src_constraints = .{ |
| 41461 | => |val_regs| try ptr.storeRegs(val_ty, &val_regs, cg), | 42213 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, |
| 41462 | .register_offset => |val_reg_off| switch (val_reg_off.off) { | 42214 | .{ .remainder_int = .{ .of = .xword, .is = .xword } }, |
| 41463 | 0 => try ptr.storeRegs(val_ty, &.{registerAlias( | 42215 | }, |
| 41464 | val_reg_off.reg, | 42216 | .patterns = &.{ |
| 41465 | @intCast(val_ty.abiSize(cg.pt.zcu)), | 42217 | .{ .src = .{ .to_mem, .to_mem } }, |
| 41466 | )}, cg), | 42218 | }, |
| 41467 | else => continue :val_to_gpr, | 42219 | .extra_temps = .{ |
| 41468 | }, | 42220 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 41469 | .register_overflow => |val_reg_ov| { | 42221 | .{ .kind = .{ .rc = .sse } }, |
| 41470 | const ip = &cg.pt.zcu.intern_pool; | 42222 | .{ .type = .u16, .kind = .{ .rc = .general_purpose } }, |
| 41471 | const first_ty: Type = .fromInterned(first_ty: switch (ip.indexToKey(val_ty.toIntern())) { | 42223 | .unused, |
| 41472 | .tuple_type => |tuple_type| { | 42224 | .unused, |
| 41473 | const tuple_field_types = tuple_type.types.get(ip); | 42225 | .unused, |
| 41474 | assert(tuple_field_types.len == 2 and tuple_field_types[1] == .u1_type); | 42226 | .unused, |
| 41475 | break :first_ty tuple_field_types[0]; | 42227 | .unused, |
| 41476 | }, | 42228 | .unused, |
| 41477 | .opt_type => |opt_child| { | 42229 | }, |
| 41478 | assert(!val_ty.optionalReprIsPayload(cg.pt.zcu)); | 42230 | .dst_temps = .{.{ .cc = .z }}, |
| 41479 | break :first_ty opt_child; | 42231 | .clobbers = .{ .eflags = true }, |
| 41480 | }, | 42232 | .each = .{ .once = &.{ |
| 41481 | else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, val_ty.fmt(cg.pt) }), | 42233 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| 41482 | }); | 42234 | .{ .@"0:", ._dqa, .mov, .tmp1x, .memia(.src0x, .tmp0, .add_size), ._, ._ }, |
| 41483 | const first_size: u31 = @intCast(first_ty.abiSize(cg.pt.zcu)); | 42235 | .{ ._, .p_b, .cmpeq, .tmp1x, .memia(.src1x, .tmp0, .add_size), ._, ._ }, |
| 41484 | try ptr.storeRegs(first_ty, &.{registerAlias(val_reg_ov.reg, first_size)}, cg); | 42236 | .{ ._, .p_b, .movmsk, .tmp2d, .tmp1x, ._, ._ }, |
| 41485 | try ptr.toOffset(first_size, cg); | 42237 | .{ ._, ._, .xor, .tmp2d, .ui(0xffff), ._, ._ }, |
| 41486 | try cg.asmSetccMemory( | 42238 | .{ ._, ._nz, .j, .@"0f", ._, ._, ._ }, |
| 41487 | val_reg_ov.eflags, | 42239 | .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ }, |
| 41488 | try ptr.tracking(cg).short.deref().mem(cg, .{ .size = .byte }), | 42240 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 41489 | ); | 42241 | } }, |
| 41490 | }, | 42242 | }, .{ |
| 41491 | .lea_frame, .lea_symbol => continue :val_to_gpr, | 42243 | .required_features = .{ .sse, .mmx, null, null }, |
| 41492 | .memory, .indirect, .load_frame, .load_symbol => { | 42244 | .src_constraints = .{ |
| 41493 | var val_ptr = try cg.tempInit(.usize, val_mcv.address()); | 42245 | .{ .remainder_int = .{ .of = .qword, .is = .qword } }, |
| 41494 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); | 42246 | .{ .remainder_int = .{ .of = .qword, .is = .qword } }, |
| 41495 | try ptr.memcpy(&val_ptr, &len, cg); | 42247 | }, |
| 41496 | try val_ptr.die(cg); | 42248 | .patterns = &.{ |
| 41497 | try len.die(cg); | 42249 | .{ .src = .{ .to_mem, .to_mem } }, |
| 41498 | }, | 42250 | }, |
| 41499 | } | 42251 | .extra_temps = .{ |
| 41500 | break; | 42252 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 41501 | } | 42253 | .{ .kind = .{ .rc = .mmx } }, |
| 41502 | } | 42254 | .{ .type = .u8, .kind = .{ .rc = .general_purpose } }, |
| 41503 | | 42255 | .unused, |
| 41504 | fn read(src: *Temp, val_ty: Type, opts: AccessOptions, cg: *CodeGen) !Temp { | 42256 | .unused, |
| 41505 | var val = try cg.tempAlloc(val_ty); | 42257 | .unused, |
| 41506 | while (try src.toBase(cg)) {} | 42258 | .unused, |
| 41507 | const val_mcv = val.tracking(cg).short; | 42259 | .unused, |
| 41508 | switch (val_mcv) { | 42260 | .unused, |
| 41509 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | 42261 | }, |
| 41510 | .register => |val_reg| try src.readReg(opts.disp, val_ty, registerAlias( | 42262 | .dst_temps = .{.{ .cc = .z }}, |
| 41511 | val_reg, | 42263 | .clobbers = .{ .eflags = true }, |
| 41512 | @intCast(val_ty.abiSize(cg.pt.zcu)), | 42264 | .each = .{ .once = &.{ |
| 41513 | ), cg), | 42265 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| 41514 | inline .register_pair, .register_triple, .register_quadruple => |val_regs| { | 42266 | .{ .@"0:", ._q, .mov, .tmp1q, .memia(.src0q, .tmp0, .add_size), ._, ._ }, |
| 41515 | var disp = opts.disp; | 42267 | .{ ._, .p_b, .cmpeq, .tmp1q, .memia(.src1q, .tmp0, .add_size), ._, ._ }, |
| 41516 | for (val_regs) |val_reg| { | 42268 | .{ ._, .p_b, .movmsk, .tmp2d, .tmp1q, ._, ._ }, |
| 41517 | try src.readReg(disp, val_ty, val_reg, cg); | 42269 | .{ ._, ._, .cmp, .tmp2b, .si(-1), ._, ._ }, |
| 41518 | disp += @divExact(val_reg.bitSize(), 8); | 42270 | .{ ._, ._nz, .j, .@"0f", ._, ._, ._ }, |
| 41519 | } | 42271 | .{ ._, ._, .add, .tmp0p, .si(8), ._, ._ }, |
| 41520 | }, | 42272 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 41521 | .register_offset => |val_reg_off| switch (val_reg_off.off) { | 42273 | } }, |
| 41522 | 0 => try src.readReg(opts.disp, val_ty, registerAlias( | 42274 | }, .{ |
| 41523 | val_reg_off.reg, | 42275 | .required_features = .{ .@"64bit", null, null, null }, |
| 41524 | @intCast(val_ty.abiSize(cg.pt.zcu)), | 42276 | .src_constraints = .{ |
| 41525 | ), cg), | 42277 | .{ .remainder_int = .{ .of = .qword, .is = .qword } }, |
| 41526 | else => unreachable, | 42278 | .{ .remainder_int = .{ .of = .qword, .is = .qword } }, |
| 41527 | }, | 42279 | }, |
| 41528 | .memory, .indirect, .load_frame, .load_symbol => { | 42280 | .patterns = &.{ |
| 41529 | var val_ptr = try cg.tempInit(.usize, val_mcv.address()); | 42281 | .{ .src = .{ .to_mem, .to_mem } }, |
| 41530 | var src_ptr = | 42282 | }, |
| 41531 | try cg.tempInit(.usize, src.tracking(cg).short.address().offset(opts.disp)); | 42283 | .extra_temps = .{ |
| 41532 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); | 42284 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| 41533 | try val_ptr.memcpy(&src_ptr, &len, cg); | 42285 | .{ .type = .u64, .kind = .{ .rc = .general_purpose } }, |
| 41534 | try val_ptr.die(cg); | 42286 | .unused, |
| 41535 | try src_ptr.die(cg); | 42287 | .unused, |
| 41536 | try len.die(cg); | 42288 | .unused, |
| | 42289 | .unused, |
| | 42290 | .unused, |
| | 42291 | .unused, |
| | 42292 | .unused, |
| | 42293 | }, |
| | 42294 | .dst_temps = .{.{ .cc = .z }}, |
| | 42295 | .clobbers = .{ .eflags = true }, |
| | 42296 | .each = .{ .once = &.{ |
| | 42297 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| | 42298 | .{ .@"0:", ._, .mov, .tmp1q, .memia(.src0q, .tmp0, .add_size), ._, ._ }, |
| | 42299 | .{ ._, ._, .xor, .tmp1q, .memia(.src1q, .tmp0, .add_size), ._, ._ }, |
| | 42300 | .{ ._, ._nz, .j, .@"0f", ._, ._, ._ }, |
| | 42301 | .{ ._, ._, .add, .tmp0p, .si(8), ._, ._ }, |
| | 42302 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| | 42303 | } }, |
| | 42304 | }, .{ |
| | 42305 | .src_constraints = .{ |
| | 42306 | .{ .remainder_int = .{ .of = .dword, .is = .dword } }, |
| | 42307 | .{ .remainder_int = .{ .of = .dword, .is = .dword } }, |
| | 42308 | }, |
| | 42309 | .patterns = &.{ |
| | 42310 | .{ .src = .{ .to_mem, .to_mem } }, |
| | 42311 | }, |
| | 42312 | .extra_temps = .{ |
| | 42313 | .{ .type = .isize, .kind = .{ .rc = .general_purpose } }, |
| | 42314 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| | 42315 | .unused, |
| | 42316 | .unused, |
| | 42317 | .unused, |
| | 42318 | .unused, |
| | 42319 | .unused, |
| | 42320 | .unused, |
| | 42321 | .unused, |
| | 42322 | }, |
| | 42323 | .dst_temps = .{.{ .cc = .z }}, |
| | 42324 | .clobbers = .{ .eflags = true }, |
| | 42325 | .each = .{ .once = &.{ |
| | 42326 | .{ ._, ._, .mov, .tmp0p, .sa(.src0, .sub_size), ._, ._ }, |
| | 42327 | .{ .@"0:", ._, .mov, .tmp1d, .memia(.src0d, .tmp0, .add_size), ._, ._ }, |
| | 42328 | .{ ._, ._, .xor, .tmp1d, .memia(.src1d, .tmp0, .add_size), ._, ._ }, |
| | 42329 | .{ ._, ._nz, .j, .@"0f", ._, ._, ._ }, |
| | 42330 | .{ ._, ._, .add, .tmp0p, .si(4), ._, ._ }, |
| | 42331 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| | 42332 | } }, |
| | 42333 | } }); |
| 41537 | }, | 42334 | }, |
| 41538 | } | 42335 | } |
| 41539 | return val; | 42336 | if (switch (op) { |
| 41540 | } | 42337 | .lt, .gt, .eq => false, |
| 41541 | | 42338 | .lte, .gte, .neq => true, |
| 41542 | fn write(dst: *Temp, val: *Temp, opts: AccessOptions, cg: *CodeGen) !void { | 42339 | }) { |
| 41543 | const val_ty = val.typeOf(cg); | 42340 | const cc = &res[0].unwrap(cg).temp.tracking(cg).short.eflags; |
| 41544 | while (try dst.toBase(cg)) {} | 42341 | cc.* = cc.negate(); |
| 41545 | val_to_gpr: while (true) : (while (try dst.toBase(cg) or | | |
| 41546 | try val.toRegClass(false, .general_purpose, cg)) | | |
| 41547 | {}) { | | |
| 41548 | const val_mcv = val.tracking(cg).short; | | |
| 41549 | switch (val_mcv) { | | |
| 41550 | else => |mcv| std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | | |
| 41551 | .undef => if (opts.safe) { | | |
| 41552 | var dst_ptr = try cg.tempInit(.usize, dst.tracking(cg).short.address().offset(opts.disp)); | | |
| 41553 | var pat = try cg.tempInit(.u8, .{ .immediate = 0xaa }); | | |
| 41554 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); | | |
| 41555 | try dst_ptr.memset(&pat, &len, cg); | | |
| 41556 | try dst_ptr.die(cg); | | |
| 41557 | try pat.die(cg); | | |
| 41558 | try len.die(cg); | | |
| 41559 | }, | | |
| 41560 | .immediate => |val_imm| { | | |
| 41561 | const val_op: Immediate = if (std.math.cast(u31, val_imm)) |val_uimm31| | | |
| 41562 | .u(val_uimm31) | | |
| 41563 | else if (std.math.cast(i32, @as(i64, @bitCast(val_imm)))) |val_simm32| | | |
| 41564 | .s(val_simm32) | | |
| 41565 | else | | |
| 41566 | continue :val_to_gpr; | | |
| 41567 | try cg.asmMemoryImmediate( | | |
| 41568 | .{ ._, .mov }, | | |
| 41569 | try dst.tracking(cg).short.mem(cg, .{ | | |
| 41570 | .size = cg.memSize(val_ty), | | |
| 41571 | .disp = opts.disp, | | |
| 41572 | }), | | |
| 41573 | val_op, | | |
| 41574 | ); | | |
| 41575 | }, | | |
| 41576 | .eflags => |cc| try cg.asmSetccMemory( | | |
| 41577 | cc, | | |
| 41578 | try dst.tracking(cg).short.mem(cg, .{ | | |
| 41579 | .size = .byte, | | |
| 41580 | .disp = opts.disp, | | |
| 41581 | }), | | |
| 41582 | ), | | |
| 41583 | .register => |val_reg| try dst.writeRegs(opts.disp, val_ty, &.{registerAlias( | | |
| 41584 | val_reg, | | |
| 41585 | @intCast(val_ty.abiSize(cg.pt.zcu)), | | |
| 41586 | )}, cg), | | |
| 41587 | inline .register_pair, | | |
| 41588 | .register_triple, | | |
| 41589 | .register_quadruple, | | |
| 41590 | => |val_regs| try dst.writeRegs(opts.disp, val_ty, &val_regs, cg), | | |
| 41591 | .register_offset => |val_reg_off| switch (val_reg_off.off) { | | |
| 41592 | 0 => try dst.writeRegs(opts.disp, val_ty, &.{registerAlias( | | |
| 41593 | val_reg_off.reg, | | |
| 41594 | @intCast(val_ty.abiSize(cg.pt.zcu)), | | |
| 41595 | )}, cg), | | |
| 41596 | else => continue :val_to_gpr, | | |
| 41597 | }, | | |
| 41598 | .register_overflow => |val_reg_ov| { | | |
| 41599 | const ip = &cg.pt.zcu.intern_pool; | | |
| 41600 | const first_ty: Type = .fromInterned(first_ty: switch (ip.indexToKey(val_ty.toIntern())) { | | |
| 41601 | .tuple_type => |tuple_type| { | | |
| 41602 | const tuple_field_types = tuple_type.types.get(ip); | | |
| 41603 | assert(tuple_field_types.len == 2 and tuple_field_types[1] == .u1_type); | | |
| 41604 | break :first_ty tuple_field_types[0]; | | |
| 41605 | }, | | |
| 41606 | .opt_type => |opt_child| { | | |
| 41607 | assert(!val_ty.optionalReprIsPayload(cg.pt.zcu)); | | |
| 41608 | break :first_ty opt_child; | | |
| 41609 | }, | | |
| 41610 | else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, val_ty.fmt(cg.pt) }), | | |
| 41611 | }); | | |
| 41612 | const first_size: u31 = @intCast(first_ty.abiSize(cg.pt.zcu)); | | |
| 41613 | try dst.writeRegs(opts.disp, first_ty, &.{registerAlias(val_reg_ov.reg, first_size)}, cg); | | |
| 41614 | try cg.asmSetccMemory( | | |
| 41615 | val_reg_ov.eflags, | | |
| 41616 | try dst.tracking(cg).short.mem(cg, .{ | | |
| 41617 | .size = .byte, | | |
| 41618 | .disp = opts.disp + first_size, | | |
| 41619 | }), | | |
| 41620 | ); | | |
| 41621 | }, | | |
| 41622 | .lea_frame, .lea_symbol => continue :val_to_gpr, | | |
| 41623 | .memory, .indirect, .load_frame, .load_symbol => { | | |
| 41624 | var dst_ptr = | | |
| 41625 | try cg.tempInit(.usize, dst.tracking(cg).short.address().offset(opts.disp)); | | |
| 41626 | var val_ptr = try cg.tempInit(.usize, val_mcv.address()); | | |
| 41627 | var len = try cg.tempInit(.usize, .{ .immediate = val_ty.abiSize(cg.pt.zcu) }); | | |
| 41628 | try dst_ptr.memcpy(&val_ptr, &len, cg); | | |
| 41629 | try dst_ptr.die(cg); | | |
| 41630 | try val_ptr.die(cg); | | |
| 41631 | try len.die(cg); | | |
| 41632 | }, | | |
| 41633 | } | | |
| 41634 | break; | | |
| 41635 | } | | |
| 41636 | } | | |
| 41637 | | | |
| 41638 | fn loadReg(ptr: *Temp, dst_ty: Type, dst_reg: Register, cg: *CodeGen) !void { | | |
| 41639 | const dst_rc = dst_reg.class(); | | |
| 41640 | const strat = try cg.moveStrategy(dst_ty, dst_rc, false); | | |
| 41641 | // hack around linker relocation bugs | | |
| 41642 | switch (ptr.tracking(cg).short) { | | |
| 41643 | else => {}, | | |
| 41644 | .lea_symbol => |sym_off| if (dst_rc != .general_purpose or sym_off.off != 0) | | |
| 41645 | while (try ptr.toRegClass(false, .general_purpose, cg)) {}, | | |
| 41646 | } | | |
| 41647 | try strat.read(cg, dst_reg, try ptr.tracking(cg).short.deref().mem(cg, .{ | | |
| 41648 | .size = .fromBitSize(@min(8 * dst_ty.abiSize(cg.pt.zcu), dst_reg.bitSize())), | | |
| 41649 | })); | | |
| 41650 | } | | |
| 41651 | | | |
| 41652 | fn storeRegs(ptr: *Temp, src_ty: Type, src_regs: []const Register, cg: *CodeGen) !void { | | |
| 41653 | var part_disp: u31 = 0; | | |
| 41654 | var deferred_disp: u31 = 0; | | |
| 41655 | var src_abi_size: u32 = @intCast(src_ty.abiSize(cg.pt.zcu)); | | |
| 41656 | for (src_regs) |src_reg| { | | |
| 41657 | const src_rc = src_reg.class(); | | |
| 41658 | const part_bit_size = @min(8 * src_abi_size, src_reg.bitSize()); | | |
| 41659 | const part_size = @divExact(part_bit_size, 8); | | |
| 41660 | if (src_rc == .x87 or std.math.isPowerOfTwo(part_size)) { | | |
| 41661 | // hack around linker relocation bugs | | |
| 41662 | switch (ptr.tracking(cg).short) { | | |
| 41663 | else => {}, | | |
| 41664 | .lea_symbol => while (try ptr.toRegClass(false, .general_purpose, cg)) {}, | | |
| 41665 | } | | |
| 41666 | const strat = try cg.moveStrategy(src_ty, src_rc, false); | | |
| 41667 | try strat.write(cg, try ptr.tracking(cg).short.deref().mem(cg, .{ | | |
| 41668 | .size = .fromBitSize(part_bit_size), | | |
| 41669 | .disp = part_disp, | | |
| 41670 | }), registerAlias(src_reg, part_size)); | | |
| 41671 | } else { | | |
| 41672 | const frame_size = std.math.ceilPowerOfTwoAssert(u32, part_size); | | |
| 41673 | const frame_index = try cg.allocFrameIndex(.init(.{ | | |
| 41674 | .size = frame_size, | | |
| 41675 | .alignment = .fromNonzeroByteUnits(frame_size), | | |
| 41676 | })); | | |
| 41677 | const strat = try cg.moveStrategy(src_ty, src_rc, true); | | |
| 41678 | try strat.write(cg, .{ | | |
| 41679 | .base = .{ .frame = frame_index }, | | |
| 41680 | .mod = .{ .rm = .{ .size = .fromSize(frame_size) } }, | | |
| 41681 | }, registerAlias(src_reg, frame_size)); | | |
| 41682 | try ptr.toOffset(deferred_disp, cg); | | |
| 41683 | deferred_disp = 0; | | |
| 41684 | var src_ptr = try cg.tempInit(.usize, .{ .lea_frame = .{ .index = frame_index } }); | | |
| 41685 | var len = try cg.tempInit(.usize, .{ .immediate = src_abi_size }); | | |
| 41686 | try ptr.memcpy(&src_ptr, &len, cg); | | |
| 41687 | try src_ptr.die(cg); | | |
| 41688 | try len.die(cg); | | |
| 41689 | } | | |
| 41690 | part_disp += part_size; | | |
| 41691 | deferred_disp += part_size; | | |
| 41692 | src_abi_size -= part_size; | | |
| 41693 | } | | |
| 41694 | } | | |
| 41695 | | | |
| 41696 | fn readReg(src: Temp, disp: i32, dst_ty: Type, dst_reg: Register, cg: *CodeGen) !void { | | |
| 41697 | const strat = try cg.moveStrategy(dst_ty, dst_reg.class(), false); | | |
| 41698 | try strat.read(cg, dst_reg, try src.tracking(cg).short.mem(cg, .{ | | |
| 41699 | .size = .fromBitSize(@min(8 * dst_ty.abiSize(cg.pt.zcu), dst_reg.bitSize())), | | |
| 41700 | .disp = disp, | | |
| 41701 | })); | | |
| 41702 | } | | |
| 41703 | | | |
| 41704 | fn writeRegs(dst: Temp, disp: i32, src_ty: Type, src_regs: []const Register, cg: *CodeGen) !void { | | |
| 41705 | var part_disp = disp; | | |
| 41706 | var src_abi_size: u32 = @intCast(src_ty.abiSize(cg.pt.zcu)); | | |
| 41707 | for (src_regs) |src_reg| { | | |
| 41708 | const src_rc = src_reg.class(); | | |
| 41709 | const part_bit_size = @min(8 * src_abi_size, src_reg.bitSize()); | | |
| 41710 | const part_size = @divExact(part_bit_size, 8); | | |
| 41711 | if (src_rc == .x87 or std.math.isPowerOfTwo(part_size)) { | | |
| 41712 | const strat = try cg.moveStrategy(src_ty, src_rc, false); | | |
| 41713 | try strat.write(cg, try dst.tracking(cg).short.mem(cg, .{ | | |
| 41714 | .size = .fromBitSize(part_bit_size), | | |
| 41715 | .disp = part_disp, | | |
| 41716 | }), registerAlias(src_reg, part_size)); | | |
| 41717 | } else { | | |
| 41718 | const frame_size = std.math.ceilPowerOfTwoAssert(u32, part_size); | | |
| 41719 | const frame_index = try cg.allocFrameIndex(.init(.{ | | |
| 41720 | .size = frame_size, | | |
| 41721 | .alignment = .fromNonzeroByteUnits(frame_size), | | |
| 41722 | })); | | |
| 41723 | const strat = try cg.moveStrategy(src_ty, src_rc, true); | | |
| 41724 | try strat.write(cg, .{ | | |
| 41725 | .base = .{ .frame = frame_index }, | | |
| 41726 | .mod = .{ .rm = .{ .size = .fromSize(frame_size) } }, | | |
| 41727 | }, registerAlias(src_reg, frame_size)); | | |
| 41728 | var dst_ptr = try cg.tempInit(.usize, dst.tracking(cg).short.address()); | | |
| 41729 | try dst_ptr.toOffset(part_disp, cg); | | |
| 41730 | var src_ptr = try cg.tempInit(.usize, .{ .lea_frame = .{ .index = frame_index } }); | | |
| 41731 | var len = try cg.tempInit(.usize, .{ .immediate = src_abi_size }); | | |
| 41732 | try dst_ptr.memcpy(&src_ptr, &len, cg); | | |
| 41733 | try dst_ptr.die(cg); | | |
| 41734 | try src_ptr.die(cg); | | |
| 41735 | try len.die(cg); | | |
| 41736 | } | | |
| 41737 | part_disp += part_size; | | |
| 41738 | src_abi_size -= part_size; | | |
| 41739 | } | 42342 | } |
| 41740 | } | 42343 | lhs.*, rhs.* = ops; |
| 41741 | | 42344 | return res[0]; |
| 41742 | fn memcpy(dst: *Temp, src: *Temp, len: *Temp, cg: *CodeGen) !void { | | |
| 41743 | while (true) for ([_]*Temp{ dst, src, len }, [_]Register{ .rdi, .rsi, .rcx }) |temp, reg| { | | |
| 41744 | if (try temp.toReg(reg, cg)) break; | | |
| 41745 | } else break; | | |
| 41746 | try cg.asmOpOnly(.{ .@"rep _sb", .mov }); | | |
| 41747 | } | | |
| 41748 | | | |
| 41749 | fn memset(dst: *Temp, val: *Temp, len: *Temp, cg: *CodeGen) !void { | | |
| 41750 | while (true) for ([_]*Temp{ dst, val, len }, [_]Register{ .rdi, .rax, .rcx }) |temp, reg| { | | |
| 41751 | if (try temp.toReg(reg, cg)) break; | | |
| 41752 | } else break; | | |
| 41753 | try cg.asmOpOnly(.{ .@"rep _sb", .sto }); | | |
| 41754 | } | 42345 | } |
| 41755 | | 42346 | |
| 41756 | fn finish( | 42347 | fn finish( |
| ... | @@ -41790,7 +42381,7 @@ const Temp = struct { | ... | @@ -41790,7 +42381,7 @@ const Temp = struct { |
| 41790 | } | 42381 | } |
| 41791 | } | 42382 | } |
| 41792 | | 42383 | |
| 41793 | const Index = enum(u4) { | 42384 | const Index = enum(u5) { |
| 41794 | _, | 42385 | _, |
| 41795 | | 42386 | |
| 41796 | fn toIndex(index: Index) Air.Inst.Index { | 42387 | fn toIndex(index: Index) Air.Inst.Index { |
| ... | @@ -41837,12 +42428,20 @@ const Temp = struct { | ... | @@ -41837,12 +42428,20 @@ const Temp = struct { |
| 41837 | }; | 42428 | }; |
| 41838 | }; | 42429 | }; |
| 41839 | | 42430 | |
| 41840 | fn resetTemps(cg: *CodeGen) void { | 42431 | fn resetTemps(cg: *CodeGen) !void { |
| | 42432 | var any_valid = false; |
| 41841 | for (0..@intFromEnum(cg.next_temp_index)) |temp_index| { | 42433 | for (0..@intFromEnum(cg.next_temp_index)) |temp_index| { |
| 41842 | const temp: Temp.Index = @enumFromInt(temp_index); | 42434 | const temp: Temp.Index = @enumFromInt(temp_index); |
| 41843 | assert(!temp.isValid(cg)); | 42435 | if (temp.isValid(cg)) { |
| | 42436 | any_valid = true; |
| | 42437 | tracking_log.err("failed to kill {}: {}", .{ |
| | 42438 | temp.toIndex(), |
| | 42439 | cg.temp_type[temp_index].fmt(cg.pt), |
| | 42440 | }); |
| | 42441 | } |
| 41844 | cg.temp_type[temp_index] = undefined; | 42442 | cg.temp_type[temp_index] = undefined; |
| 41845 | } | 42443 | } |
| | 42444 | if (any_valid) return cg.fail("failed to kill all temps", .{}); |
| 41846 | cg.next_temp_index = @enumFromInt(0); | 42445 | cg.next_temp_index = @enumFromInt(0); |
| 41847 | } | 42446 | } |
| 41848 | | 42447 | |
| ... | @@ -42228,6 +42827,8 @@ const Select = struct { | ... | @@ -42228,6 +42827,8 @@ const Select = struct { |
| 42228 | signed_po2_int: Memory.Size, | 42827 | signed_po2_int: Memory.Size, |
| 42229 | unsigned_po2_or_exact_int: Memory.Size, | 42828 | unsigned_po2_or_exact_int: Memory.Size, |
| 42230 | remainder_int: OfIsSizes, | 42829 | remainder_int: OfIsSizes, |
| | 42830 | signed_remainder_int: OfIsSizes, |
| | 42831 | unsigned_remainder_int: OfIsSizes, |
| 42231 | exact_remainder_int: OfIsSizes, | 42832 | exact_remainder_int: OfIsSizes, |
| 42232 | signed_or_exact_remainder_int: OfIsSizes, | 42833 | signed_or_exact_remainder_int: OfIsSizes, |
| 42233 | unsigned_or_exact_remainder_int: OfIsSizes, | 42834 | unsigned_or_exact_remainder_int: OfIsSizes, |
| ... | @@ -42342,6 +42943,10 @@ const Select = struct { | ... | @@ -42342,6 +42943,10 @@ const Select = struct { |
| 42342 | of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1 | 42943 | of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1 |
| 42343 | else | 42944 | else |
| 42344 | false, | 42945 | false, |
| | 42946 | .signed_remainder_int => |of_is| if (cg.intInfo(ty)) |int_info| int_info.signedness == .signed and |
| | 42947 | of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1 else false, |
| | 42948 | .unsigned_remainder_int => |of_is| if (cg.intInfo(ty)) |int_info| int_info.signedness == .unsigned and |
| | 42949 | of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1 else false, |
| 42345 | .exact_remainder_int => |of_is| if (cg.intInfo(ty)) |int_info| | 42950 | .exact_remainder_int => |of_is| if (cg.intInfo(ty)) |int_info| |
| 42346 | of_is.is.bitSize(cg.target) == (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1 | 42951 | of_is.is.bitSize(cg.target) == (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1 |
| 42347 | else | 42952 | else |
| ... | @@ -42749,6 +43354,7 @@ const Select = struct { | ... | @@ -42749,6 +43354,7 @@ const Select = struct { |
| 42749 | const add_size: Adjust = .{ .sign = .pos, .lhs = .size, .op = .mul, .rhs = .@"1" }; | 43354 | const add_size: Adjust = .{ .sign = .pos, .lhs = .size, .op = .mul, .rhs = .@"1" }; |
| 42750 | const add_size_div_8: Adjust = .{ .sign = .pos, .lhs = .size, .op = .div, .rhs = .@"8" }; | 43355 | const add_size_div_8: Adjust = .{ .sign = .pos, .lhs = .size, .op = .div, .rhs = .@"8" }; |
| 42751 | const sub_size_div_8: Adjust = .{ .sign = .neg, .lhs = .size, .op = .div, .rhs = .@"8" }; | 43356 | const sub_size_div_8: Adjust = .{ .sign = .neg, .lhs = .size, .op = .div, .rhs = .@"8" }; |
| | 43357 | const sub_size_div_4: Adjust = .{ .sign = .neg, .lhs = .size, .op = .div, .rhs = .@"4" }; |
| 42752 | const sub_size: Adjust = .{ .sign = .neg, .lhs = .size, .op = .mul, .rhs = .@"1" }; | 43358 | const sub_size: Adjust = .{ .sign = .neg, .lhs = .size, .op = .mul, .rhs = .@"1" }; |
| 42753 | const add_size_sub_elem_size: Adjust = .{ .sign = .pos, .lhs = .size_sub_elem_size, .op = .mul, .rhs = .@"1" }; | 43359 | const add_size_sub_elem_size: Adjust = .{ .sign = .pos, .lhs = .size_sub_elem_size, .op = .mul, .rhs = .@"1" }; |
| 42754 | const add_src0_unaligned_size: Adjust = .{ .sign = .pos, .lhs = .src0_unaligned_size, .op = .mul, .rhs = .@"1" }; | 43360 | const add_src0_unaligned_size: Adjust = .{ .sign = .pos, .lhs = .src0_unaligned_size, .op = .mul, .rhs = .@"1" }; |