mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
parent
427f0025db
commit
a430be097b
1 changed files with 61 additions and 46 deletions
|
|
@ -180113,15 +180113,22 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
var mnem_size: struct {
|
var mnem_size: struct {
|
||||||
|
op_has_size: std.StaticBitSet(4),
|
||||||
|
size: Memory.Size,
|
||||||
used: bool,
|
used: bool,
|
||||||
size: ?Memory.Size,
|
fn init(size: ?Memory.Size) @This() {
|
||||||
fn use(size: *@This()) ?Memory.Size {
|
return .{
|
||||||
|
.op_has_size = if (size) |_| .initFull() else .initEmpty(),
|
||||||
|
.size = size orelse .none,
|
||||||
|
.used = false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
fn use(size: *@This(), op_index: usize) ?Memory.Size {
|
||||||
|
if (!size.op_has_size.isSet(op_index)) return null;
|
||||||
size.used = true;
|
size.used = true;
|
||||||
return size.size;
|
return size.size;
|
||||||
}
|
}
|
||||||
} = .{
|
} = .init(if (prefix == .directive)
|
||||||
.used = false,
|
|
||||||
.size = if (prefix == .directive)
|
|
||||||
null
|
null
|
||||||
else if (std.mem.endsWith(u8, mnem_str, "b"))
|
else if (std.mem.endsWith(u8, mnem_str, "b"))
|
||||||
.byte
|
.byte
|
||||||
|
|
@ -180135,28 +180142,36 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
|
||||||
else if (std.mem.endsWith(u8, mnem_str, "t"))
|
else if (std.mem.endsWith(u8, mnem_str, "t"))
|
||||||
.tbyte
|
.tbyte
|
||||||
else
|
else
|
||||||
null,
|
null);
|
||||||
};
|
|
||||||
var mnem_tag = while (true) break std.meta.stringToEnum(
|
var mnem_tag = while (true) break std.meta.stringToEnum(
|
||||||
encoder.Instruction.Mnemonic,
|
encoder.Instruction.Mnemonic,
|
||||||
mnem_str[0 .. mnem_str.len - @intFromBool(mnem_size.size != null)],
|
mnem_str[0 .. mnem_str.len - @intFromBool(mnem_size.size != .none)],
|
||||||
) orelse if (mnem_size.size) |_| {
|
) orelse if (mnem_size.size != .none) {
|
||||||
mnem_size.size = null;
|
mnem_size = .init(null);
|
||||||
continue;
|
continue;
|
||||||
} else return self.fail("invalid mnemonic: '{s}'", .{mnem_str});
|
} else return self.fail("invalid mnemonic: '{s}'", .{mnem_str});
|
||||||
if (@as(?Memory.Size, switch (mnem_tag) {
|
fixed_mnem_size: {
|
||||||
|
const fixed_mnem_size: Memory.Size = switch (mnem_tag) {
|
||||||
.clflush => .byte,
|
.clflush => .byte,
|
||||||
.fldcw, .fnstcw, .fstcw, .fnstsw, .fstsw => .word,
|
.fldcw, .fnstcw, .fstcw, .fnstsw, .fstsw => .word,
|
||||||
.fldenv, .fnstenv, .fstenv => .none,
|
.fldenv, .fnstenv, .fstenv => .none,
|
||||||
.frstor, .fsave, .fnsave, .fxrstor, .fxrstor64, .fxsave, .fxsave64 => .none,
|
.frstor, .fsave, .fnsave, .fxrstor, .fxrstor64, .fxsave, .fxsave64 => .none,
|
||||||
|
.in => {
|
||||||
|
mnem_size.op_has_size.unset(0);
|
||||||
|
break :fixed_mnem_size;
|
||||||
|
},
|
||||||
.invlpg => .none,
|
.invlpg => .none,
|
||||||
.invpcid => .xword,
|
.invpcid => .xword,
|
||||||
.ldmxcsr, .stmxcsr, .vldmxcsr, .vstmxcsr => .dword,
|
.ldmxcsr, .stmxcsr, .vldmxcsr, .vstmxcsr => .dword,
|
||||||
else => null,
|
.out => {
|
||||||
})) |fixed_mnem_size| {
|
mnem_size.op_has_size.unset(1);
|
||||||
if (mnem_size.size) |size| if (size != fixed_mnem_size)
|
break :fixed_mnem_size;
|
||||||
|
},
|
||||||
|
else => break :fixed_mnem_size,
|
||||||
|
};
|
||||||
|
if (mnem_size.size != .none and mnem_size.size != fixed_mnem_size)
|
||||||
return self.fail("invalid size: '{s}'", .{mnem_str});
|
return self.fail("invalid size: '{s}'", .{mnem_str});
|
||||||
mnem_size.size = fixed_mnem_size;
|
mnem_size = .init(fixed_mnem_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
var ops: [4]Operand = @splat(.none);
|
var ops: [4]Operand = @splat(.none);
|
||||||
|
|
@ -180164,7 +180179,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
|
||||||
|
|
||||||
var last_op = false;
|
var last_op = false;
|
||||||
var op_it = std.mem.splitScalar(u8, mnem_it.rest(), ',');
|
var op_it = std.mem.splitScalar(u8, mnem_it.rest(), ',');
|
||||||
next_op: for (&ops) |*op| {
|
next_op: for (&ops, 0..) |*op, op_index| {
|
||||||
const op_str = while (!last_op) {
|
const op_str = while (!last_op) {
|
||||||
const full_str = op_it.next() orelse break :next_op;
|
const full_str = op_it.next() orelse break :next_op;
|
||||||
const code_str = if (std.mem.indexOfScalar(u8, full_str, '#') orelse
|
const code_str = if (std.mem.indexOfScalar(u8, full_str, '#') orelse
|
||||||
|
|
@ -180186,13 +180201,13 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
|
||||||
op.* = .{ .mem = .{
|
op.* = .{ .mem = .{
|
||||||
.base = .{ .reg = reg },
|
.base = .{ .reg = reg },
|
||||||
.mod = .{ .rm = .{
|
.mod = .{ .rm = .{
|
||||||
.size = mnem_size.use() orelse
|
.size = mnem_size.use(op_index) orelse
|
||||||
return self.fail("unknown size: '{s}'", .{op_str}),
|
return self.fail("unknown size: '{s}'", .{op_str}),
|
||||||
.disp = disp,
|
.disp = disp,
|
||||||
} },
|
} },
|
||||||
} };
|
} };
|
||||||
} else {
|
} else {
|
||||||
if (mnem_size.use()) |size| if (reg.size().bitSize(self.target) != size.bitSize(self.target))
|
if (mnem_size.use(op_index)) |size| if (reg.size().bitSize(self.target) != size.bitSize(self.target))
|
||||||
return self.fail("invalid register size: '{s}'", .{op_str});
|
return self.fail("invalid register size: '{s}'", .{op_str});
|
||||||
op.* = .{ .reg = reg };
|
op.* = .{ .reg = reg };
|
||||||
}
|
}
|
||||||
|
|
@ -180211,14 +180226,14 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
|
||||||
else
|
else
|
||||||
return self.fail("invalid modifier: '{s}'", .{modifier}),
|
return self.fail("invalid modifier: '{s}'", .{modifier}),
|
||||||
.register => |reg| if (std.mem.eql(u8, modifier, ""))
|
.register => |reg| if (std.mem.eql(u8, modifier, ""))
|
||||||
.{ .reg = if (mnem_size.use()) |size| reg.toSize(size, self.target) else reg }
|
.{ .reg = if (mnem_size.use(op_index)) |size| reg.toSize(size, self.target) else reg }
|
||||||
else
|
else
|
||||||
return self.fail("invalid modifier: '{s}'", .{modifier}),
|
return self.fail("invalid modifier: '{s}'", .{modifier}),
|
||||||
.memory => |addr| if (std.mem.eql(u8, modifier, "") or std.mem.eql(u8, modifier, "P"))
|
.memory => |addr| if (std.mem.eql(u8, modifier, "") or std.mem.eql(u8, modifier, "P"))
|
||||||
.{ .mem = .{
|
.{ .mem = .{
|
||||||
.base = .{ .reg = .ds },
|
.base = .{ .reg = .ds },
|
||||||
.mod = .{ .rm = .{
|
.mod = .{ .rm = .{
|
||||||
.size = mnem_size.use() orelse
|
.size = mnem_size.use(op_index) orelse
|
||||||
return self.fail("unknown size: '{s}'", .{op_str}),
|
return self.fail("unknown size: '{s}'", .{op_str}),
|
||||||
.disp = @intCast(@as(i64, @bitCast(addr))),
|
.disp = @intCast(@as(i64, @bitCast(addr))),
|
||||||
} },
|
} },
|
||||||
|
|
@ -180229,7 +180244,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
|
||||||
.{ .mem = .{
|
.{ .mem = .{
|
||||||
.base = .{ .reg = reg_off.reg },
|
.base = .{ .reg = reg_off.reg },
|
||||||
.mod = .{ .rm = .{
|
.mod = .{ .rm = .{
|
||||||
.size = mnem_size.use() orelse
|
.size = mnem_size.use(op_index) orelse
|
||||||
return self.fail("unknown size: '{s}'", .{op_str}),
|
return self.fail("unknown size: '{s}'", .{op_str}),
|
||||||
.disp = reg_off.off,
|
.disp = reg_off.off,
|
||||||
} },
|
} },
|
||||||
|
|
@ -180240,7 +180255,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
|
||||||
.{ .mem = .{
|
.{ .mem = .{
|
||||||
.base = .{ .frame = frame_addr.index },
|
.base = .{ .frame = frame_addr.index },
|
||||||
.mod = .{ .rm = .{
|
.mod = .{ .rm = .{
|
||||||
.size = mnem_size.use() orelse
|
.size = mnem_size.use(op_index) orelse
|
||||||
return self.fail("unknown size: '{s}'", .{op_str}),
|
return self.fail("unknown size: '{s}'", .{op_str}),
|
||||||
.disp = frame_addr.off,
|
.disp = frame_addr.off,
|
||||||
} },
|
} },
|
||||||
|
|
@ -180322,7 +180337,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
|
||||||
else
|
else
|
||||||
.none,
|
.none,
|
||||||
.mod = .{ .rm = .{
|
.mod = .{ .rm = .{
|
||||||
.size = mnem_size.use() orelse return self.fail("unknown size: '{s}'", .{op_str}),
|
.size = mnem_size.use(op_index) orelse return self.fail("unknown size: '{s}'", .{op_str}),
|
||||||
.index = if (index_str.len > 0)
|
.index = if (index_str.len > 0)
|
||||||
parseRegName(index_str["%%".len..]) orelse
|
parseRegName(index_str["%%".len..]) orelse
|
||||||
return self.fail("invalid index register: '{s}'", .{op_str})
|
return self.fail("invalid index register: '{s}'", .{op_str})
|
||||||
|
|
@ -180375,14 +180390,14 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
|
||||||
|
|
||||||
// convert from att syntax to intel syntax
|
// convert from att syntax to intel syntax
|
||||||
std.mem.reverse(Operand, ops[0..ops_len]);
|
std.mem.reverse(Operand, ops[0..ops_len]);
|
||||||
if (!mnem_size.used) if (mnem_size.size) |size| {
|
if (mnem_size.size != .none and !mnem_size.used) {
|
||||||
comptime var max_mnem_len: usize = 0;
|
comptime var max_mnem_len: usize = 0;
|
||||||
inline for (@typeInfo(encoder.Instruction.Mnemonic).@"enum".fields) |mnem|
|
inline for (@typeInfo(encoder.Instruction.Mnemonic).@"enum".fields) |mnem|
|
||||||
max_mnem_len = @max(mnem.name.len, max_mnem_len);
|
max_mnem_len = @max(mnem.name.len, max_mnem_len);
|
||||||
var intel_mnem_buf: [max_mnem_len + 1]u8 = undefined;
|
var intel_mnem_buf: [max_mnem_len + 1]u8 = undefined;
|
||||||
const intel_mnem_str = std.fmt.bufPrint(&intel_mnem_buf, "{s}{c}", .{
|
const intel_mnem_str = std.fmt.bufPrint(&intel_mnem_buf, "{s}{c}", .{
|
||||||
@tagName(mnem_tag),
|
@tagName(mnem_tag),
|
||||||
@as(u8, switch (size) {
|
@as(u8, switch (mnem_size.size) {
|
||||||
.byte => 'b',
|
.byte => 'b',
|
||||||
.word => 'w',
|
.word => 'w',
|
||||||
.dword => 'd',
|
.dword => 'd',
|
||||||
|
|
@ -180392,7 +180407,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
|
||||||
}),
|
}),
|
||||||
}) catch unreachable;
|
}) catch unreachable;
|
||||||
if (std.meta.stringToEnum(encoder.Instruction.Mnemonic, intel_mnem_str)) |intel_mnem_tag| mnem_tag = intel_mnem_tag;
|
if (std.meta.stringToEnum(encoder.Instruction.Mnemonic, intel_mnem_str)) |intel_mnem_tag| mnem_tag = intel_mnem_tag;
|
||||||
};
|
}
|
||||||
const mnem_name = @tagName(mnem_tag);
|
const mnem_name = @tagName(mnem_tag);
|
||||||
const mnem_fixed_tag: Mir.Inst.FixedTag = if (prefix == .directive)
|
const mnem_fixed_tag: Mir.Inst.FixedTag = if (prefix == .directive)
|
||||||
.{ ._, .pseudo }
|
.{ ._, .pseudo }
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue