| ... | @@ -132,6 +132,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void { | ... | @@ -132,6 +132,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void { |
| 132 | .movabs => try emit.mirMovabs(inst), | 132 | .movabs => try emit.mirMovabs(inst), |
| 133 | | 133 | |
| 134 | .fisttp => try emit.mirFisttp(inst), | 134 | .fisttp => try emit.mirFisttp(inst), |
| | 135 | .fld => try emit.mirFld(inst), |
| 135 | | 136 | |
| 136 | .lea => try emit.mirLea(inst), | 137 | .lea => try emit.mirLea(inst), |
| 137 | .lea_pie => try emit.mirLeaPie(inst), | 138 | .lea_pie => try emit.mirLeaPie(inst), |
| ... | @@ -710,6 +711,26 @@ fn mirFisttp(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { | ... | @@ -710,6 +711,26 @@ fn mirFisttp(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| 710 | return lowerToMEnc(opcode, .{ .memory = mem_or_reg }, emit.code); | 711 | return lowerToMEnc(opcode, .{ .memory = mem_or_reg }, emit.code); |
| 711 | } | 712 | } |
| 712 | | 713 | |
| | 714 | fn mirFld(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| | 715 | const tag = emit.mir.instructions.items(.tag)[inst]; |
| | 716 | assert(tag == .fld); |
| | 717 | const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]); |
| | 718 | |
| | 719 | // the selecting between operand sizes for this particular `fisttp` instruction |
| | 720 | // is done via opcode instead of the usual prefixes. |
| | 721 | |
| | 722 | const opcode: Tag = switch (ops.flags) { |
| | 723 | 0b01 => .fld32, |
| | 724 | 0b10 => .fld64, |
| | 725 | else => unreachable, |
| | 726 | }; |
| | 727 | const mem_or_reg = Memory{ |
| | 728 | .base = ops.reg1, |
| | 729 | .disp = emit.mir.instructions.items(.data)[inst].imm, |
| | 730 | .ptr_size = Memory.PtrSize.dword_ptr, // to prevent any prefix from being used |
| | 731 | }; |
| | 732 | return lowerToMEnc(opcode, .{ .memory = mem_or_reg }, emit.code); |
| | 733 | } |
| 713 | fn mirShift(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void { | 734 | fn mirShift(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void { |
| 714 | const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]); | 735 | const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]); |
| 715 | switch (ops.flags) { | 736 | switch (ops.flags) { |
| ... | @@ -1141,6 +1162,8 @@ const Tag = enum { | ... | @@ -1141,6 +1162,8 @@ const Tag = enum { |
| 1141 | fisttp16, | 1162 | fisttp16, |
| 1142 | fisttp32, | 1163 | fisttp32, |
| 1143 | fisttp64, | 1164 | fisttp64, |
| | 1165 | fld32, |
| | 1166 | fld64, |
| 1144 | jo, | 1167 | jo, |
| 1145 | jno, | 1168 | jno, |
| 1146 | jb, | 1169 | jb, |
| ... | @@ -1382,6 +1405,8 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode { | ... | @@ -1382,6 +1405,8 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode { |
| 1382 | .fisttp16 => OpCode.oneByte(0xdf), | 1405 | .fisttp16 => OpCode.oneByte(0xdf), |
| 1383 | .fisttp32 => OpCode.oneByte(0xdb), | 1406 | .fisttp32 => OpCode.oneByte(0xdb), |
| 1384 | .fisttp64 => OpCode.oneByte(0xdd), | 1407 | .fisttp64 => OpCode.oneByte(0xdd), |
| | 1408 | .fld32 => OpCode.oneByte(0xd9), |
| | 1409 | .fld64 => OpCode.oneByte(0xdd), |
| 1385 | else => null, | 1410 | else => null, |
| 1386 | }, | 1411 | }, |
| 1387 | .o => return switch (tag) { | 1412 | .o => return switch (tag) { |
| ... | @@ -1525,6 +1550,8 @@ inline fn getModRmExt(tag: Tag) ?u3 { | ... | @@ -1525,6 +1550,8 @@ inline fn getModRmExt(tag: Tag) ?u3 { |
| 1525 | .fisttp16 => 0x1, | 1550 | .fisttp16 => 0x1, |
| 1526 | .fisttp32 => 0x1, | 1551 | .fisttp32 => 0x1, |
| 1527 | .fisttp64 => 0x1, | 1552 | .fisttp64 => 0x1, |
| | 1553 | .fld32 => 0x0, |
| | 1554 | .fld64 => 0x0, |
| 1528 | else => null, | 1555 | else => null, |
| 1529 | }; | 1556 | }; |
| 1530 | } | 1557 | } |