stage2: x86_64: add new fld instruction
This commit is contained in:
@@ -132,6 +132,7 @@ pub fn lowerMir(emit: *Emit) InnerError!void {
|
||||
.movabs => try emit.mirMovabs(inst),
|
||||
|
||||
.fisttp => try emit.mirFisttp(inst),
|
||||
.fld => try emit.mirFld(inst),
|
||||
|
||||
.lea => try emit.mirLea(inst),
|
||||
.lea_pie => try emit.mirLeaPie(inst),
|
||||
@@ -710,6 +711,26 @@ fn mirFisttp(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
|
||||
return lowerToMEnc(opcode, .{ .memory = mem_or_reg }, emit.code);
|
||||
}
|
||||
|
||||
fn mirFld(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
|
||||
const tag = emit.mir.instructions.items(.tag)[inst];
|
||||
assert(tag == .fld);
|
||||
const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
|
||||
|
||||
// the selecting between operand sizes for this particular `fisttp` instruction
|
||||
// is done via opcode instead of the usual prefixes.
|
||||
|
||||
const opcode: Tag = switch (ops.flags) {
|
||||
0b01 => .fld32,
|
||||
0b10 => .fld64,
|
||||
else => unreachable,
|
||||
};
|
||||
const mem_or_reg = Memory{
|
||||
.base = ops.reg1,
|
||||
.disp = emit.mir.instructions.items(.data)[inst].imm,
|
||||
.ptr_size = Memory.PtrSize.dword_ptr, // to prevent any prefix from being used
|
||||
};
|
||||
return lowerToMEnc(opcode, .{ .memory = mem_or_reg }, emit.code);
|
||||
}
|
||||
fn mirShift(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void {
|
||||
const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
|
||||
switch (ops.flags) {
|
||||
@@ -1141,6 +1162,8 @@ const Tag = enum {
|
||||
fisttp16,
|
||||
fisttp32,
|
||||
fisttp64,
|
||||
fld32,
|
||||
fld64,
|
||||
jo,
|
||||
jno,
|
||||
jb,
|
||||
@@ -1382,6 +1405,8 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode {
|
||||
.fisttp16 => OpCode.oneByte(0xdf),
|
||||
.fisttp32 => OpCode.oneByte(0xdb),
|
||||
.fisttp64 => OpCode.oneByte(0xdd),
|
||||
.fld32 => OpCode.oneByte(0xd9),
|
||||
.fld64 => OpCode.oneByte(0xdd),
|
||||
else => null,
|
||||
},
|
||||
.o => return switch (tag) {
|
||||
@@ -1525,6 +1550,8 @@ inline fn getModRmExt(tag: Tag) ?u3 {
|
||||
.fisttp16 => 0x1,
|
||||
.fisttp32 => 0x1,
|
||||
.fisttp64 => 0x1,
|
||||
.fld32 => 0x0,
|
||||
.fld64 => 0x0,
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -265,6 +265,11 @@ pub const Inst = struct {
|
||||
/// * only supports memory operands as destination
|
||||
fisttp,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b01 dword ptr [reg1 + imm32]
|
||||
/// 0b10 qword ptr [reg1 + imm32]
|
||||
fld,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 inst
|
||||
/// 0b01 reg1
|
||||
|
||||
Reference in New Issue
Block a user