authorgravatar for miguel.p.paradinha@gmail.commparadinha <miguel.p.paradinha@gmail.com> 2022-03-16 19:15:41+00:00
committergravatar for miguel.p.paradinha@gmail.commparadinha <miguel.p.paradinha@gmail.com> 2022-03-16 21:24:09+00:00
log66ef630006523c673e46a1e8d2496a99881e2452
tree1f1b0f486603f7586c2a3d827524d31524b33ad8
parent972d923f09f90ac15a2f2b13863598b268022d88

stage2: x86_64: add new `fld` instruction


2 files changed, 32 insertions(+), 0 deletions(-)

src/arch/x86_64/Emit.zig+27
...@@ -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),
133133
134 .fisttp => try emit.mirFisttp(inst),134 .fisttp => try emit.mirFisttp(inst),
135 .fld => try emit.mirFld(inst),
135136
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}
712713
714fn 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}
713fn mirShift(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void {734fn 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}
src/arch/x86_64/Mir.zig+5
...@@ -265,6 +265,11 @@ pub const Inst = struct {...@@ -265,6 +265,11 @@ pub const Inst = struct {
265 /// * only supports memory operands as destination265 /// * only supports memory operands as destination
266 fisttp,266 fisttp,
267267
268 /// ops flags: form:
269 /// 0b01 dword ptr [reg1 + imm32]
270 /// 0b10 qword ptr [reg1 + imm32]
271 fld,
272
268 /// ops flags: form:273 /// ops flags: form:
269 /// 0b00 inst274 /// 0b00 inst
270 /// 0b01 reg1275 /// 0b01 reg1