@@ -180114,58 +180114,73 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
180114
180114
}
180115
180115
180116
180116
var mnem_size: struct {
180117
+ op_has_size: std.StaticBitSet(4),
180118
+ size: Memory.Size,
180117
180119
used: bool,
180118
- size: ?Memory.Size,
180119
- fn use(size: *@This()) ?Memory.Size {
180120
+ fn init(size: ?Memory.Size) @This() {
180121
+ return .{
180122
+ .op_has_size = if (size) |_| .initFull() else .initEmpty(),
180123
+ .size = size orelse .none,
180124
+ .used = false,
180125
+ };
180126
+ }
180127
+ fn use(size: *@This(), op_index: usize) ?Memory.Size {
180128
+ if (!size.op_has_size.isSet(op_index)) return null;
180120
180129
size.used = true;
180121
180130
return size.size;
180122
180131
}
180123
- } = .{
180124
- .used = false,
180125
- .size = if (prefix == .directive)
180126
- null
180127
- else if (std.mem.endsWith(u8, mnem_str, "b"))
180128
- .byte
180129
- else if (std.mem.endsWith(u8, mnem_str, "w"))
180130
- .word
180131
- else if (std.mem.endsWith(u8, mnem_str, "l"))
180132
- .dword
180133
- else if (std.mem.endsWith(u8, mnem_str, "q") and
180134
- (std.mem.indexOfScalar(u8, "vp", mnem_str[0]) == null or !std.mem.endsWith(u8, mnem_str, "dq")))
180135
- .qword
180136
- else if (std.mem.endsWith(u8, mnem_str, "t"))
180137
- .tbyte
180138
- else
180139
- null,
180140
- };
180132
+ } = .init(if (prefix == .directive)
180133
+ null
180134
+ else if (std.mem.endsWith(u8, mnem_str, "b"))
180135
+ .byte
180136
+ else if (std.mem.endsWith(u8, mnem_str, "w"))
180137
+ .word
180138
+ else if (std.mem.endsWith(u8, mnem_str, "l"))
180139
+ .dword
180140
+ else if (std.mem.endsWith(u8, mnem_str, "q") and
180141
+ (std.mem.indexOfScalar(u8, "vp", mnem_str[0]) == null or !std.mem.endsWith(u8, mnem_str, "dq")))
180142
+ .qword
180143
+ else if (std.mem.endsWith(u8, mnem_str, "t"))
180144
+ .tbyte
180145
+ else
180146
+ null);
180141
180147
var mnem_tag = while (true) break std.meta.stringToEnum(
180142
180148
encoder.Instruction.Mnemonic,
180143
- mnem_str[0 .. mnem_str.len - @intFromBool(mnem_size.size != null )],
180144
- ) orelse if (mnem_size.size) |_| {
180145
- mnem_size.size = null;
180149
+ mnem_str[0 .. mnem_str.len - @intFromBool(mnem_size.size != .none )],
180150
+ ) orelse if (mnem_size.size != .none) {
180151
+ mnem_size = .init( null) ;
180146
180152
continue;
180147
180153
} else return self.fail("invalid mnemonic: '{s}'", .{mnem_str});
180148
- if (@as(?Memory.Size, switch (mnem_tag) {
180149
- .clflush => .byte,
180150
- .fldcw, .fnstcw, .fstcw, .fnstsw, .fstsw => .word,
180151
- .fldenv, .fnstenv, .fstenv => .none,
180152
- .frstor, .fsave, .fnsave, .fxrstor, .fxrstor64, .fxsave, .fxsave64 => .none,
180153
- .invlpg => .none,
180154
- .invpcid => .xword,
180155
- .ldmxcsr, .stmxcsr, .vldmxcsr, .vstmxcsr => .dword,
180156
- else => null,
180157
- })) |fixed_mnem_size| {
180158
- if (mnem_size.size) |size| if (size != fixed_mnem_size)
180154
+ fixed_mnem_size: {
180155
+ const fixed_mnem_size: Memory.Size = switch (mnem_tag) {
180156
+ .clflush => .byte,
180157
+ .fldcw, .fnstcw, .fstcw, .fnstsw, .fstsw => .word,
180158
+ .fldenv, .fnstenv, .fstenv => .none,
180159
+ .frstor, .fsave, .fnsave, .fxrstor, .fxrstor64, .fxsave, .fxsave64 => .none,
180160
+ .in => {
180161
+ mnem_size.op_has_size.unset(0);
180162
+ break :fixed_mnem_size;
180163
+ },
180164
+ .invlpg => .none,
180165
+ .invpcid => .xword,
180166
+ .ldmxcsr, .stmxcsr, .vldmxcsr, .vstmxcsr => .dword,
180167
+ .out => {
180168
+ mnem_size.op_has_size.unset(1);
180169
+ break :fixed_mnem_size;
180170
+ },
180171
+ else => break :fixed_mnem_size,
180172
+ };
180173
+ if (mnem_size.size != .none and mnem_size.size != fixed_mnem_size)
180159
180174
return self.fail("invalid size: '{s}'", .{mnem_str});
180160
- mnem_size.size = fixed_mnem_size;
180175
+ mnem_size = .init( fixed_mnem_size) ;
180161
180176
}
180162
180177
180163
180178
var ops: [4]Operand = @splat(.none);
180164
180179
var ops_len: usize = 0;
180165
180180
180166
180181
var last_op = false;
180167
180182
var op_it = std.mem.splitScalar(u8, mnem_it.rest(), ',');
180168
- next_op: for (&ops) |*op| {
180183
+ next_op: for (&ops, 0.. ) |*op, op_index | {
180169
180184
const op_str = while (!last_op) {
180170
180185
const full_str = op_it.next() orelse break :next_op;
180171
180186
const code_str = if (std.mem.indexOfScalar(u8, full_str, '#') orelse
@@ -180187,13 +180202,13 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
180187
180202
op.* = .{ .mem = .{
180188
180203
.base = .{ .reg = reg },
180189
180204
.mod = .{ .rm = .{
180190
- .size = mnem_size.use() orelse
180205
+ .size = mnem_size.use(op_index ) orelse
180191
180206
return self.fail("unknown size: '{s}'", .{op_str}),
180192
180207
.disp = disp,
180193
180208
} },
180194
180209
} };
180195
180210
} else {
180196
- if (mnem_size.use()) |size| if (reg.size().bitSize(self.target) != size.bitSize(self.target))
180211
+ if (mnem_size.use(op_index )) |size| if (reg.size().bitSize(self.target) != size.bitSize(self.target))
180197
180212
return self.fail("invalid register size: '{s}'", .{op_str});
180198
180213
op.* = .{ .reg = reg };
180199
180214
}
@@ -180212,14 +180227,14 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
180212
180227
else
180213
180228
return self.fail("invalid modifier: '{s}'", .{modifier}),
180214
180229
.register => |reg| if (std.mem.eql(u8, modifier, ""))
180215
- .{ .reg = if (mnem_size.use()) |size| reg.toSize(size, self.target) else reg }
180230
+ .{ .reg = if (mnem_size.use(op_index )) |size| reg.toSize(size, self.target) else reg }
180216
180231
else
180217
180232
return self.fail("invalid modifier: '{s}'", .{modifier}),
180218
180233
.memory => |addr| if (std.mem.eql(u8, modifier, "") or std.mem.eql(u8, modifier, "P"))
180219
180234
.{ .mem = .{
180220
180235
.base = .{ .reg = .ds },
180221
180236
.mod = .{ .rm = .{
180222
- .size = mnem_size.use() orelse
180237
+ .size = mnem_size.use(op_index ) orelse
180223
180238
return self.fail("unknown size: '{s}'", .{op_str}),
180224
180239
.disp = @intCast(@as(i64, @bitCast(addr))),
180225
180240
} },
@@ -180230,7 +180245,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
180230
180245
.{ .mem = .{
180231
180246
.base = .{ .reg = reg_off.reg },
180232
180247
.mod = .{ .rm = .{
180233
- .size = mnem_size.use() orelse
180248
+ .size = mnem_size.use(op_index ) orelse
180234
180249
return self.fail("unknown size: '{s}'", .{op_str}),
180235
180250
.disp = reg_off.off,
180236
180251
} },
@@ -180241,7 +180256,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
180241
180256
.{ .mem = .{
180242
180257
.base = .{ .frame = frame_addr.index },
180243
180258
.mod = .{ .rm = .{
180244
- .size = mnem_size.use() orelse
180259
+ .size = mnem_size.use(op_index ) orelse
180245
180260
return self.fail("unknown size: '{s}'", .{op_str}),
180246
180261
.disp = frame_addr.off,
180247
180262
} },
@@ -180323,7 +180338,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
180323
180338
else
180324
180339
.none,
180325
180340
.mod = .{ .rm = .{
180326
- .size = mnem_size.use() orelse return self.fail("unknown size: '{s}'", .{op_str}),
180341
+ .size = mnem_size.use(op_index ) orelse return self.fail("unknown size: '{s}'", .{op_str}),
180327
180342
.index = if (index_str.len > 0)
180328
180343
parseRegName(index_str["%%".len..]) orelse
180329
180344
return self.fail("invalid index register: '{s}'", .{op_str})
@@ -180376,14 +180391,14 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
180376
180391
180377
180392
// convert from att syntax to intel syntax
180378
180393
std.mem.reverse(Operand, ops[0..ops_len]);
180379
- if (! mnem_size.used) if ( mnem_size.size) |size| {
180394
+ if (mnem_size.size != .none and ! mnem_size.used) {
180380
180395
comptime var max_mnem_len: usize = 0;
180381
180396
inline for (@typeInfo(encoder.Instruction.Mnemonic).@"enum".fields) |mnem|
180382
180397
max_mnem_len = @max(mnem.name.len, max_mnem_len);
180383
180398
var intel_mnem_buf: [max_mnem_len + 1]u8 = undefined;
180384
180399
const intel_mnem_str = std.fmt.bufPrint(&intel_mnem_buf, "{s}{c}", .{
180385
180400
@tagName(mnem_tag),
180386
- @as(u8, switch (size) {
180401
+ @as(u8, switch (mnem_size. size) {
180387
180402
.byte => 'b',
180388
180403
.word => 'w',
180389
180404
.dword => 'd',
@@ -180393,7 +180408,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
180393
180408
}),
180394
180409
}) catch unreachable;
180395
180410
if (std.meta.stringToEnum(encoder.Instruction.Mnemonic, intel_mnem_str)) |intel_mnem_tag| mnem_tag = intel_mnem_tag;
180396
- };
180411
+ }
180397
180412
const mnem_name = @tagName(mnem_tag);
180398
180413
const mnem_fixed_tag: Mir.Inst.FixedTag = if (prefix == .directive)
180399
180414
.{ ._, .pseudo }
0 commit comments