| ... | ... | @@ -132,6 +132,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void { |
| 132 | 132 | .movabs => try emit.mirMovabs(inst), |
| 133 | 133 | |
| 134 | 134 | .fisttp => try emit.mirFisttp(inst), |
| 135 | .fld => try emit.mirFld(inst), |
| 135 | 136 | |
| 136 | 137 | .lea => try emit.mirLea(inst), |
| 137 | 138 | .lea_pie => try emit.mirLeaPie(inst), |
| ... | ... | @@ -710,6 +711,26 @@ fn mirFisttp(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| 710 | 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 | 734 | fn mirShift(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void { |
| 714 | 735 | const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]); |
| 715 | 736 | switch (ops.flags) { |
| ... | ... | @@ -1141,6 +1162,8 @@ const Tag = enum { |
| 1141 | 1162 | fisttp16, |
| 1142 | 1163 | fisttp32, |
| 1143 | 1164 | fisttp64, |
| 1165 | fld32, |
| 1166 | fld64, |
| 1144 | 1167 | jo, |
| 1145 | 1168 | jno, |
| 1146 | 1169 | jb, |
| ... | ... | @@ -1382,6 +1405,8 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode { |
| 1382 | 1405 | .fisttp16 => OpCode.oneByte(0xdf), |
| 1383 | 1406 | .fisttp32 => OpCode.oneByte(0xdb), |
| 1384 | 1407 | .fisttp64 => OpCode.oneByte(0xdd), |
| 1408 | .fld32 => OpCode.oneByte(0xd9), |
| 1409 | .fld64 => OpCode.oneByte(0xdd), |
| 1385 | 1410 | else => null, |
| 1386 | 1411 | }, |
| 1387 | 1412 | .o => return switch (tag) { |
| ... | ... | @@ -1525,6 +1550,8 @@ inline fn getModRmExt(tag: Tag) ?u3 { |
| 1525 | 1550 | .fisttp16 => 0x1, |
| 1526 | 1551 | .fisttp32 => 0x1, |
| 1527 | 1552 | .fisttp64 => 0x1, |
| 1553 | .fld32 => 0x0, |
| 1554 | .fld64 => 0x0, |
| 1528 | 1555 | else => null, |
| 1529 | 1556 | }; |
| 1530 | 1557 | } |