| ... | @@ -227,89 +227,81 @@ pub const Instruction = struct { | ... | @@ -227,89 +227,81 @@ pub const Instruction = struct { |
| 227 | }; | 227 | }; |
| 228 | } | 228 | } |
| 229 | | 229 | |
| 230 | fn format(op: Operand, bw: *Writer, comptime unused_format_string: []const u8) !void { | 230 | const Format = struct { |
| 231 | _ = op; | | |
| 232 | _ = bw; | | |
| 233 | _ = unused_format_string; | | |
| 234 | @compileError("do not format Operand directly; use fmt() instead"); | | |
| 235 | } | | |
| 236 | | | |
| 237 | const FormatContext = struct { | | |
| 238 | op: Operand, | 231 | op: Operand, |
| 239 | enc_op: Encoding.Op, | 232 | enc_op: Encoding.Op, |
| 240 | }; | | |
| 241 | | 233 | |
| 242 | fn fmtContext(ctx: FormatContext, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void { | 234 | fn default(f: Format, w: *Writer) Writer.Error!void { |
| 243 | _ = unused_format_string; | 235 | const op = f.op; |
| 244 | const op = ctx.op; | 236 | const enc_op = f.enc_op; |
| 245 | const enc_op = ctx.enc_op; | 237 | switch (op) { |
| 246 | switch (op) { | 238 | .none => {}, |
| 247 | .none => {}, | 239 | .reg => |reg| try w.writeAll(@tagName(reg)), |
| 248 | .reg => |reg| try bw.writeAll(@tagName(reg)), | 240 | .mem => |mem| switch (mem) { |
| 249 | .mem => |mem| switch (mem) { | 241 | .rip => |rip| { |
| 250 | .rip => |rip| { | 242 | try w.print("{f} [rip", .{rip.ptr_size}); |
| 251 | try bw.print("{f} [rip", .{rip.ptr_size}); | 243 | if (rip.disp != 0) try w.print(" {c} 0x{x}", .{ |
| 252 | if (rip.disp != 0) try bw.print(" {c} 0x{x}", .{ | 244 | @as(u8, if (rip.disp < 0) '-' else '+'), |
| 253 | @as(u8, if (rip.disp < 0) '-' else '+'), | 245 | @abs(rip.disp), |
| 254 | @abs(rip.disp), | 246 | }); |
| 255 | }); | 247 | try w.writeByte(']'); |
| 256 | try bw.writeByte(']'); | 248 | }, |
| 257 | }, | 249 | .sib => |sib| { |
| 258 | .sib => |sib| { | 250 | try w.print("{f} ", .{sib.ptr_size}); |
| 259 | try bw.print("{f} ", .{sib.ptr_size}); | | |
| 260 | | 251 | |
| 261 | if (mem.isSegmentRegister()) { | 252 | if (mem.isSegmentRegister()) { |
| 262 | return bw.print("{s}:0x{x}", .{ @tagName(sib.base.reg), sib.disp }); | 253 | return w.print("{s}:0x{x}", .{ @tagName(sib.base.reg), sib.disp }); |
| 263 | } | 254 | } |
| 264 | | 255 | |
| 265 | try bw.writeByte('['); | 256 | try w.writeByte('['); |
| 266 | | 257 | |
| 267 | var any = true; | 258 | var any = true; |
| 268 | switch (sib.base) { | 259 | switch (sib.base) { |
| 269 | .none => any = false, | 260 | .none => any = false, |
| 270 | .reg => |reg| try bw.print("{s}", .{@tagName(reg)}), | 261 | .reg => |reg| try w.print("{s}", .{@tagName(reg)}), |
| 271 | .frame => |frame_index| try bw.print("{}", .{frame_index}), | 262 | .frame => |frame_index| try w.print("{}", .{frame_index}), |
| 272 | .table => try bw.print("Table", .{}), | 263 | .table => try w.print("Table", .{}), |
| 273 | .rip_inst => |inst_index| try bw.print("RipInst({d})", .{inst_index}), | 264 | .rip_inst => |inst_index| try w.print("RipInst({d})", .{inst_index}), |
| 274 | .nav => |nav| try bw.print("Nav({d})", .{@intFromEnum(nav)}), | 265 | .nav => |nav| try w.print("Nav({d})", .{@intFromEnum(nav)}), |
| 275 | .uav => |uav| try bw.print("Uav({d})", .{@intFromEnum(uav.val)}), | 266 | .uav => |uav| try w.print("Uav({d})", .{@intFromEnum(uav.val)}), |
| 276 | .lazy_sym => |lazy_sym| try bw.print("LazySym({s}, {d})", .{ | 267 | .lazy_sym => |lazy_sym| try w.print("LazySym({s}, {d})", .{ |
| 277 | @tagName(lazy_sym.kind), | 268 | @tagName(lazy_sym.kind), |
| 278 | @intFromEnum(lazy_sym.ty), | 269 | @intFromEnum(lazy_sym.ty), |
| 279 | }), | 270 | }), |
| 280 | .extern_func => |extern_func| try bw.print("ExternFunc({d})", .{@intFromEnum(extern_func)}), | 271 | .extern_func => |extern_func| try w.print("ExternFunc({d})", .{@intFromEnum(extern_func)}), |
| 281 | } | 272 | } |
| 282 | if (mem.scaleIndex()) |si| { | 273 | if (mem.scaleIndex()) |si| { |
| 283 | if (any) try bw.writeAll(" + "); | 274 | if (any) try w.writeAll(" + "); |
| 284 | try bw.print("{s} * {d}", .{ @tagName(si.index), si.scale }); | 275 | try w.print("{s} * {d}", .{ @tagName(si.index), si.scale }); |
| 285 | any = true; | 276 | any = true; |
| 286 | } | 277 | } |
| 287 | if (sib.disp != 0 or !any) { | 278 | if (sib.disp != 0 or !any) { |
| 288 | if (any) | 279 | if (any) |
| 289 | try bw.print(" {c} ", .{@as(u8, if (sib.disp < 0) '-' else '+')}) | 280 | try w.print(" {c} ", .{@as(u8, if (sib.disp < 0) '-' else '+')}) |
| 290 | else if (sib.disp < 0) | 281 | else if (sib.disp < 0) |
| 291 | try bw.writeByte('-'); | 282 | try w.writeByte('-'); |
| 292 | try bw.print("0x{x}", .{@abs(sib.disp)}); | 283 | try w.print("0x{x}", .{@abs(sib.disp)}); |
| 293 | any = true; | 284 | any = true; |
| 294 | } | 285 | } |
| 295 | | 286 | |
| 296 | try bw.writeByte(']'); | 287 | try w.writeByte(']'); |
| | 288 | }, |
| | 289 | .moffs => |moffs| try w.print("{s}:0x{x}", .{ |
| | 290 | @tagName(moffs.seg), |
| | 291 | moffs.offset, |
| | 292 | }), |
| 297 | }, | 293 | }, |
| 298 | .moffs => |moffs| try bw.print("{s}:0x{x}", .{ | 294 | .imm => |imm| if (enc_op.isSigned()) { |
| 299 | @tagName(moffs.seg), | 295 | const imms = imm.asSigned(enc_op.immBitSize()); |
| 300 | moffs.offset, | 296 | if (imms < 0) try w.writeByte('-'); |
| 301 | }), | 297 | try w.print("0x{x}", .{@abs(imms)}); |
| 302 | }, | 298 | } else try w.print("0x{x}", .{imm.asUnsigned(enc_op.immBitSize())}), |
| 303 | .imm => |imm| if (enc_op.isSigned()) { | 299 | .bytes => unreachable, |
| 304 | const imms = imm.asSigned(enc_op.immBitSize()); | 300 | } |
| 305 | if (imms < 0) try bw.writeByte('-'); | | |
| 306 | try bw.print("0x{x}", .{@abs(imms)}); | | |
| 307 | } else try bw.print("0x{x}", .{imm.asUnsigned(enc_op.immBitSize())}), | | |
| 308 | .bytes => unreachable, | | |
| 309 | } | 301 | } |
| 310 | } | 302 | }; |
| 311 | | 303 | |
| 312 | pub fn fmt(op: Operand, enc_op: Encoding.Op) std.fmt.Formatter(fmtContext) { | 304 | pub fn fmt(op: Operand, enc_op: Encoding.Op) std.fmt.Formatter(Format, Format.default) { |
| 313 | return .{ .data = .{ .op = op, .enc_op = enc_op } }; | 305 | return .{ .data = .{ .op = op, .enc_op = enc_op } }; |
| 314 | } | 306 | } |
| 315 | }; | 307 | }; |
| ... | @@ -361,23 +353,23 @@ pub const Instruction = struct { | ... | @@ -361,23 +353,23 @@ pub const Instruction = struct { |
| 361 | return inst; | 353 | return inst; |
| 362 | } | 354 | } |
| 363 | | 355 | |
| 364 | pub fn format(inst: Instruction, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void { | 356 | pub fn format(inst: Instruction, w: *Writer, comptime unused_format_string: []const u8) Writer.Error!void { |
| 365 | _ = unused_format_string; | 357 | comptime assert(unused_format_string.len == 0); |
| 366 | switch (inst.prefix) { | 358 | switch (inst.prefix) { |
| 367 | .none, .directive => {}, | 359 | .none, .directive => {}, |
| 368 | else => try bw.print("{s} ", .{@tagName(inst.prefix)}), | 360 | else => try w.print("{s} ", .{@tagName(inst.prefix)}), |
| 369 | } | 361 | } |
| 370 | try bw.print("{s}", .{@tagName(inst.encoding.mnemonic)}); | 362 | try w.print("{s}", .{@tagName(inst.encoding.mnemonic)}); |
| 371 | for (inst.ops, inst.encoding.data.ops, 0..) |op, enc, i| { | 363 | for (inst.ops, inst.encoding.data.ops, 0..) |op, enc, i| { |
| 372 | if (op == .none) break; | 364 | if (op == .none) break; |
| 373 | if (i > 0) try bw.writeByte(','); | 365 | if (i > 0) try w.writeByte(','); |
| 374 | try bw.print(" {f}", .{op.fmt(enc)}); | 366 | try w.print(" {f}", .{op.fmt(enc)}); |
| 375 | } | 367 | } |
| 376 | } | 368 | } |
| 377 | | 369 | |
| 378 | pub fn encode(inst: Instruction, bw: *Writer, comptime opts: Options) !void { | 370 | pub fn encode(inst: Instruction, w: *Writer, comptime opts: Options) !void { |
| 379 | assert(inst.prefix != .directive); | 371 | assert(inst.prefix != .directive); |
| 380 | const encoder: Encoder(opts) = .{ .bw = bw }; | 372 | const encoder: Encoder(opts) = .{ .w = w }; |
| 381 | const enc = inst.encoding; | 373 | const enc = inst.encoding; |
| 382 | const data = enc.data; | 374 | const data = enc.data; |
| 383 | | 375 | |
| ... | @@ -785,7 +777,7 @@ pub const Options = struct { allow_frame_locs: bool = false, allow_symbols: bool | ... | @@ -785,7 +777,7 @@ pub const Options = struct { allow_frame_locs: bool = false, allow_symbols: bool |
| 785 | | 777 | |
| 786 | fn Encoder(comptime opts: Options) type { | 778 | fn Encoder(comptime opts: Options) type { |
| 787 | return struct { | 779 | return struct { |
| 788 | bw: *Writer, | 780 | w: *Writer, |
| 789 | | 781 | |
| 790 | const Self = @This(); | 782 | const Self = @This(); |
| 791 | pub const options = opts; | 783 | pub const options = opts; |
| ... | @@ -800,31 +792,31 @@ fn Encoder(comptime opts: Options) type { | ... | @@ -800,31 +792,31 @@ fn Encoder(comptime opts: Options) type { |
| 800 | // Hopefully this path isn't taken very often, so we'll do it the slow way for now | 792 | // Hopefully this path isn't taken very often, so we'll do it the slow way for now |
| 801 | | 793 | |
| 802 | // LOCK | 794 | // LOCK |
| 803 | if (prefixes.prefix_f0) try self.bw.writeByte(0xf0); | 795 | if (prefixes.prefix_f0) try self.w.writeByte(0xf0); |
| 804 | // REPNZ, REPNE, REP, Scalar Double-precision | 796 | // REPNZ, REPNE, REP, Scalar Double-precision |
| 805 | if (prefixes.prefix_f2) try self.bw.writeByte(0xf2); | 797 | if (prefixes.prefix_f2) try self.w.writeByte(0xf2); |
| 806 | // REPZ, REPE, REP, Scalar Single-precision | 798 | // REPZ, REPE, REP, Scalar Single-precision |
| 807 | if (prefixes.prefix_f3) try self.bw.writeByte(0xf3); | 799 | if (prefixes.prefix_f3) try self.w.writeByte(0xf3); |
| 808 | | 800 | |
| 809 | // CS segment override or Branch not taken | 801 | // CS segment override or Branch not taken |
| 810 | if (prefixes.prefix_2e) try self.bw.writeByte(0x2e); | 802 | if (prefixes.prefix_2e) try self.w.writeByte(0x2e); |
| 811 | // DS segment override | 803 | // DS segment override |
| 812 | if (prefixes.prefix_36) try self.bw.writeByte(0x36); | 804 | if (prefixes.prefix_36) try self.w.writeByte(0x36); |
| 813 | // ES segment override | 805 | // ES segment override |
| 814 | if (prefixes.prefix_26) try self.bw.writeByte(0x26); | 806 | if (prefixes.prefix_26) try self.w.writeByte(0x26); |
| 815 | // FS segment override | 807 | // FS segment override |
| 816 | if (prefixes.prefix_64) try self.bw.writeByte(0x64); | 808 | if (prefixes.prefix_64) try self.w.writeByte(0x64); |
| 817 | // GS segment override | 809 | // GS segment override |
| 818 | if (prefixes.prefix_65) try self.bw.writeByte(0x65); | 810 | if (prefixes.prefix_65) try self.w.writeByte(0x65); |
| 819 | | 811 | |
| 820 | // Branch taken | 812 | // Branch taken |
| 821 | if (prefixes.prefix_3e) try self.bw.writeByte(0x3e); | 813 | if (prefixes.prefix_3e) try self.w.writeByte(0x3e); |
| 822 | | 814 | |
| 823 | // Operand size override | 815 | // Operand size override |
| 824 | if (prefixes.prefix_66) try self.bw.writeByte(0x66); | 816 | if (prefixes.prefix_66) try self.w.writeByte(0x66); |
| 825 | | 817 | |
| 826 | // Address size override | 818 | // Address size override |
| 827 | if (prefixes.prefix_67) try self.bw.writeByte(0x67); | 819 | if (prefixes.prefix_67) try self.w.writeByte(0x67); |
| 828 | } | 820 | } |
| 829 | } | 821 | } |
| 830 | | 822 | |
| ... | @@ -832,7 +824,7 @@ fn Encoder(comptime opts: Options) type { | ... | @@ -832,7 +824,7 @@ fn Encoder(comptime opts: Options) type { |
| 832 | /// | 824 | /// |
| 833 | /// Note that this flag is overridden by REX.W, if both are present. | 825 | /// Note that this flag is overridden by REX.W, if both are present. |
| 834 | pub fn prefix16BitMode(self: Self) !void { | 826 | pub fn prefix16BitMode(self: Self) !void { |
| 835 | try self.bw.writeByte(0x66); | 827 | try self.w.writeByte(0x66); |
| 836 | } | 828 | } |
| 837 | | 829 | |
| 838 | /// Encodes a REX prefix byte given all the fields | 830 | /// Encodes a REX prefix byte given all the fields |
| ... | @@ -851,7 +843,7 @@ fn Encoder(comptime opts: Options) type { | ... | @@ -851,7 +843,7 @@ fn Encoder(comptime opts: Options) type { |
| 851 | if (fields.x) byte |= 0b0010; | 843 | if (fields.x) byte |= 0b0010; |
| 852 | if (fields.b) byte |= 0b0001; | 844 | if (fields.b) byte |= 0b0001; |
| 853 | | 845 | |
| 854 | try self.bw.writeByte(byte); | 846 | try self.w.writeByte(byte); |
| 855 | } | 847 | } |
| 856 | | 848 | |
| 857 | /// Encodes a VEX prefix given all the fields | 849 | /// Encodes a VEX prefix given all the fields |
| ... | @@ -859,24 +851,24 @@ fn Encoder(comptime opts: Options) type { | ... | @@ -859,24 +851,24 @@ fn Encoder(comptime opts: Options) type { |
| 859 | /// See struct `Vex` for a description of each field. | 851 | /// See struct `Vex` for a description of each field. |
| 860 | pub fn vex(self: Self, fields: Vex) !void { | 852 | pub fn vex(self: Self, fields: Vex) !void { |
| 861 | if (fields.is3Byte()) { | 853 | if (fields.is3Byte()) { |
| 862 | try self.bw.writeByte(0b1100_0100); | 854 | try self.w.writeByte(0b1100_0100); |
| 863 | | 855 | |
| 864 | try self.bw.writeByte( | 856 | try self.w.writeByte( |
| 865 | @as(u8, ~@intFromBool(fields.r)) << 7 | | 857 | @as(u8, ~@intFromBool(fields.r)) << 7 | |
| 866 | @as(u8, ~@intFromBool(fields.x)) << 6 | | 858 | @as(u8, ~@intFromBool(fields.x)) << 6 | |
| 867 | @as(u8, ~@intFromBool(fields.b)) << 5 | | 859 | @as(u8, ~@intFromBool(fields.b)) << 5 | |
| 868 | @as(u8, @intFromEnum(fields.m)) << 0, | 860 | @as(u8, @intFromEnum(fields.m)) << 0, |
| 869 | ); | 861 | ); |
| 870 | | 862 | |
| 871 | try self.bw.writeByte( | 863 | try self.w.writeByte( |
| 872 | @as(u8, @intFromBool(fields.w)) << 7 | | 864 | @as(u8, @intFromBool(fields.w)) << 7 | |
| 873 | @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 | | 865 | @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 | |
| 874 | @as(u8, @intFromBool(fields.l)) << 2 | | 866 | @as(u8, @intFromBool(fields.l)) << 2 | |
| 875 | @as(u8, @intFromEnum(fields.p)) << 0, | 867 | @as(u8, @intFromEnum(fields.p)) << 0, |
| 876 | ); | 868 | ); |
| 877 | } else { | 869 | } else { |
| 878 | try self.bw.writeByte(0b1100_0101); | 870 | try self.w.writeByte(0b1100_0101); |
| 879 | try self.bw.writeByte( | 871 | try self.w.writeByte( |
| 880 | @as(u8, ~@intFromBool(fields.r)) << 7 | | 872 | @as(u8, ~@intFromBool(fields.r)) << 7 | |
| 881 | @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 | | 873 | @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 | |
| 882 | @as(u8, @intFromBool(fields.l)) << 2 | | 874 | @as(u8, @intFromBool(fields.l)) << 2 | |
| ... | @@ -891,7 +883,7 @@ fn Encoder(comptime opts: Options) type { | ... | @@ -891,7 +883,7 @@ fn Encoder(comptime opts: Options) type { |
| 891 | | 883 | |
| 892 | /// Encodes a 1 byte opcode | 884 | /// Encodes a 1 byte opcode |
| 893 | pub fn opcode_1byte(self: Self, opcode: u8) !void { | 885 | pub fn opcode_1byte(self: Self, opcode: u8) !void { |
| 894 | try self.bw.writeByte(opcode); | 886 | try self.w.writeByte(opcode); |
| 895 | } | 887 | } |
| 896 | | 888 | |
| 897 | /// Encodes a 2 byte opcode | 889 | /// Encodes a 2 byte opcode |
| ... | @@ -900,7 +892,7 @@ fn Encoder(comptime opts: Options) type { | ... | @@ -900,7 +892,7 @@ fn Encoder(comptime opts: Options) type { |
| 900 | /// | 892 | /// |
| 901 | /// encoder.opcode_2byte(0x0f, 0xaf); | 893 | /// encoder.opcode_2byte(0x0f, 0xaf); |
| 902 | pub fn opcode_2byte(self: Self, prefix: u8, opcode: u8) !void { | 894 | pub fn opcode_2byte(self: Self, prefix: u8, opcode: u8) !void { |
| 903 | try self.bw.writeAll(&.{ prefix, opcode }); | 895 | try self.w.writeAll(&.{ prefix, opcode }); |
| 904 | } | 896 | } |
| 905 | | 897 | |
| 906 | /// Encodes a 3 byte opcode | 898 | /// Encodes a 3 byte opcode |
| ... | @@ -909,7 +901,7 @@ fn Encoder(comptime opts: Options) type { | ... | @@ -909,7 +901,7 @@ fn Encoder(comptime opts: Options) type { |
| 909 | /// | 901 | /// |
| 910 | /// encoder.opcode_3byte(0xf2, 0x0f, 0x10); | 902 | /// encoder.opcode_3byte(0xf2, 0x0f, 0x10); |
| 911 | pub fn opcode_3byte(self: Self, prefix_1: u8, prefix_2: u8, opcode: u8) !void { | 903 | pub fn opcode_3byte(self: Self, prefix_1: u8, prefix_2: u8, opcode: u8) !void { |
| 912 | try self.bw.writeAll(&.{ prefix_1, prefix_2, opcode }); | 904 | try self.w.writeAll(&.{ prefix_1, prefix_2, opcode }); |
| 913 | } | 905 | } |
| 914 | | 906 | |
| 915 | /// Encodes a 1 byte opcode with a reg field | 907 | /// Encodes a 1 byte opcode with a reg field |
| ... | @@ -917,7 +909,7 @@ fn Encoder(comptime opts: Options) type { | ... | @@ -917,7 +909,7 @@ fn Encoder(comptime opts: Options) type { |
| 917 | /// Remember to add a REX prefix byte if reg is extended! | 909 | /// Remember to add a REX prefix byte if reg is extended! |
| 918 | pub fn opcode_withReg(self: Self, opcode: u8, reg: u3) !void { | 910 | pub fn opcode_withReg(self: Self, opcode: u8, reg: u3) !void { |
| 919 | assert(opcode & 0b111 == 0); | 911 | assert(opcode & 0b111 == 0); |
| 920 | try self.bw.writeByte(opcode | reg); | 912 | try self.w.writeByte(opcode | reg); |
| 921 | } | 913 | } |
| 922 | | 914 | |
| 923 | // ------ | 915 | // ------ |
| ... | @@ -928,7 +920,7 @@ fn Encoder(comptime opts: Options) type { | ... | @@ -928,7 +920,7 @@ fn Encoder(comptime opts: Options) type { |
| 928 | /// | 920 | /// |
| 929 | /// Remember to add a REX prefix byte if reg or rm are extended! | 921 | /// Remember to add a REX prefix byte if reg or rm are extended! |
| 930 | pub fn modRm(self: Self, mod: u2, reg_or_opx: u3, rm: u3) !void { | 922 | pub fn modRm(self: Self, mod: u2, reg_or_opx: u3, rm: u3) !void { |
| 931 | try self.bw.writeByte(@as(u8, mod) << 6 | @as(u8, reg_or_opx) << 3 | rm); | 923 | try self.w.writeByte(@as(u8, mod) << 6 | @as(u8, reg_or_opx) << 3 | rm); |
| 932 | } | 924 | } |
| 933 | | 925 | |
| 934 | /// Construct a ModR/M byte using direct r/m addressing | 926 | /// Construct a ModR/M byte using direct r/m addressing |
| ... | @@ -1014,7 +1006,7 @@ fn Encoder(comptime opts: Options) type { | ... | @@ -1014,7 +1006,7 @@ fn Encoder(comptime opts: Options) type { |
| 1014 | /// | 1006 | /// |
| 1015 | /// Remember to add a REX prefix byte if index or base are extended! | 1007 | /// Remember to add a REX prefix byte if index or base are extended! |
| 1016 | pub fn sib(self: Self, scale: u2, index: u3, base: u3) !void { | 1008 | pub fn sib(self: Self, scale: u2, index: u3, base: u3) !void { |
| 1017 | try self.bw.writeByte(@as(u8, scale) << 6 | @as(u8, index) << 3 | base); | 1009 | try self.w.writeByte(@as(u8, scale) << 6 | @as(u8, index) << 3 | base); |
| 1018 | } | 1010 | } |
| 1019 | | 1011 | |
| 1020 | /// Construct a SIB byte with scale * index + base, no frills. | 1012 | /// Construct a SIB byte with scale * index + base, no frills. |
| ... | @@ -1106,42 +1098,42 @@ fn Encoder(comptime opts: Options) type { | ... | @@ -1106,42 +1098,42 @@ fn Encoder(comptime opts: Options) type { |
| 1106 | /// | 1098 | /// |
| 1107 | /// It is sign-extended to 64 bits by the cpu. | 1099 | /// It is sign-extended to 64 bits by the cpu. |
| 1108 | pub fn disp8(self: Self, disp: i8) !void { | 1100 | pub fn disp8(self: Self, disp: i8) !void { |
| 1109 | try self.bw.writeByte(@as(u8, @bitCast(disp))); | 1101 | try self.w.writeByte(@as(u8, @bitCast(disp))); |
| 1110 | } | 1102 | } |
| 1111 | | 1103 | |
| 1112 | /// Encode an 32 bit displacement | 1104 | /// Encode an 32 bit displacement |
| 1113 | /// | 1105 | /// |
| 1114 | /// It is sign-extended to 64 bits by the cpu. | 1106 | /// It is sign-extended to 64 bits by the cpu. |
| 1115 | pub fn disp32(self: Self, disp: i32) !void { | 1107 | pub fn disp32(self: Self, disp: i32) !void { |
| 1116 | try self.bw.writeInt(i32, disp, .little); | 1108 | try self.w.writeInt(i32, disp, .little); |
| 1117 | } | 1109 | } |
| 1118 | | 1110 | |
| 1119 | /// Encode an 8 bit immediate | 1111 | /// Encode an 8 bit immediate |
| 1120 | /// | 1112 | /// |
| 1121 | /// It is sign-extended to 64 bits by the cpu. | 1113 | /// It is sign-extended to 64 bits by the cpu. |
| 1122 | pub fn imm8(self: Self, imm: u8) !void { | 1114 | pub fn imm8(self: Self, imm: u8) !void { |
| 1123 | try self.bw.writeByte(imm); | 1115 | try self.w.writeByte(imm); |
| 1124 | } | 1116 | } |
| 1125 | | 1117 | |
| 1126 | /// Encode an 16 bit immediate | 1118 | /// Encode an 16 bit immediate |
| 1127 | /// | 1119 | /// |
| 1128 | /// It is sign-extended to 64 bits by the cpu. | 1120 | /// It is sign-extended to 64 bits by the cpu. |
| 1129 | pub fn imm16(self: Self, imm: u16) !void { | 1121 | pub fn imm16(self: Self, imm: u16) !void { |
| 1130 | try self.bw.writeInt(u16, imm, .little); | 1122 | try self.w.writeInt(u16, imm, .little); |
| 1131 | } | 1123 | } |
| 1132 | | 1124 | |
| 1133 | /// Encode an 32 bit immediate | 1125 | /// Encode an 32 bit immediate |
| 1134 | /// | 1126 | /// |
| 1135 | /// It is sign-extended to 64 bits by the cpu. | 1127 | /// It is sign-extended to 64 bits by the cpu. |
| 1136 | pub fn imm32(self: Self, imm: u32) !void { | 1128 | pub fn imm32(self: Self, imm: u32) !void { |
| 1137 | try self.bw.writeInt(u32, imm, .little); | 1129 | try self.w.writeInt(u32, imm, .little); |
| 1138 | } | 1130 | } |
| 1139 | | 1131 | |
| 1140 | /// Encode an 64 bit immediate | 1132 | /// Encode an 64 bit immediate |
| 1141 | /// | 1133 | /// |
| 1142 | /// It is sign-extended to 64 bits by the cpu. | 1134 | /// It is sign-extended to 64 bits by the cpu. |
| 1143 | pub fn imm64(self: Self, imm: u64) !void { | 1135 | pub fn imm64(self: Self, imm: u64) !void { |
| 1144 | try self.bw.writeInt(u64, imm, .little); | 1136 | try self.w.writeInt(u64, imm, .little); |
| 1145 | } | 1137 | } |
| 1146 | }; | 1138 | }; |
| 1147 | } | 1139 | } |
| ... | @@ -2199,10 +2191,10 @@ const Assembler = struct { | ... | @@ -2199,10 +2191,10 @@ const Assembler = struct { |
| 2199 | }; | 2191 | }; |
| 2200 | } | 2192 | } |
| 2201 | | 2193 | |
| 2202 | pub fn assemble(as: *Assembler, bw: *Writer) !void { | 2194 | pub fn assemble(as: *Assembler, w: *Writer) !void { |
| 2203 | while (try as.next()) |parsed_inst| { | 2195 | while (try as.next()) |parsed_inst| { |
| 2204 | const inst: Instruction = try .new(.none, parsed_inst.mnemonic, &parsed_inst.ops); | 2196 | const inst: Instruction = try .new(.none, parsed_inst.mnemonic, &parsed_inst.ops); |
| 2205 | try inst.encode(bw, .{}); | 2197 | try inst.encode(w, .{}); |
| 2206 | } | 2198 | } |
| 2207 | } | 2199 | } |
| 2208 | | 2200 | |