diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2023-03-18 05:49:20 -0400 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2023-03-21 08:49:54 +0100 |
| commit | edd63f9abaa7dae1786a4cd91cc3031264bd3ef0 (patch) | |
| tree | 2259ac328fe3d045d0a5ce318b55b611cff7da81 /src/arch/x86_64/encoder.zig | |
| parent | c865c8fb2a910e73e38192a8bd484935bae8f6fc (diff) | |
| download | zig-edd63f9abaa7dae1786a4cd91cc3031264bd3ef0.tar.gz zig-edd63f9abaa7dae1786a4cd91cc3031264bd3ef0.zip | |
x86_64: reimplement inline memcpy and memset
Diffstat (limited to 'src/arch/x86_64/encoder.zig')
| -rw-r--r-- | src/arch/x86_64/encoder.zig | 71 |
1 files changed, 33 insertions, 38 deletions
diff --git a/src/arch/x86_64/encoder.zig b/src/arch/x86_64/encoder.zig index 7e29f95069..2a2d6ea031 100644 --- a/src/arch/x86_64/encoder.zig +++ b/src/arch/x86_64/encoder.zig @@ -15,10 +15,21 @@ pub const Instruction = struct { op2: Operand = .none, op3: Operand = .none, op4: Operand = .none, + prefix: Prefix = .none, encoding: Encoding, pub const Mnemonic = Encoding.Mnemonic; + pub const Prefix = enum(u3) { + none, + lock, + rep, + repe, + repz, + repne, + repnz, + }; + pub const Operand = union(enum) { none, reg: Register, @@ -96,18 +107,16 @@ pub const Instruction = struct { } }; - pub fn new(mnemonic: Mnemonic, args: struct { + pub const Init = struct { + prefix: Prefix = .none, op1: Operand = .none, op2: Operand = .none, op3: Operand = .none, op4: Operand = .none, - }) !Instruction { - const encoding = (try Encoding.findByMnemonic(mnemonic, .{ - .op1 = args.op1, - .op2 = args.op2, - .op3 = args.op3, - .op4 = args.op4, - })) orelse { + }; + + pub fn new(mnemonic: Mnemonic, args: Init) !Instruction { + const encoding = (try Encoding.findByMnemonic(mnemonic, args)) orelse { log.debug("no encoding found for: {s} {s} {s} {s} {s}", .{ @tagName(mnemonic), @tagName(Encoding.Op.fromOperand(args.op1)), @@ -119,6 +128,7 @@ pub const Instruction = struct { }; log.debug("selected encoding: {}", .{encoding}); return .{ + .prefix = args.prefix, .op1 = args.op1, .op2 = args.op2, .op3 = args.op3, @@ -128,6 +138,7 @@ pub const Instruction = struct { } pub fn fmtPrint(inst: Instruction, writer: anytype) !void { + if (inst.prefix != .none) try writer.print("{s} ", .{@tagName(inst.prefix)}); try writer.print("{s}", .{@tagName(inst.encoding.mnemonic)}); const ops = [_]struct { Operand, Encoding.Op }{ .{ inst.op1, inst.encoding.op1 }, @@ -215,6 +226,14 @@ pub const Instruction = struct { const op_en = enc.op_en; var legacy = LegacyPrefixes{}; + + switch (inst.prefix) { + .none => {}, + .lock => legacy.prefix_f0 = true, + .repne, .repnz => legacy.prefix_f2 = true, + .rep, .repe, .repz => legacy.prefix_f3 = true, + } + if (enc.mode == .none) { const bit_size = enc.operandBitSize(); if (bit_size == 16) { @@ -811,15 +830,11 @@ const TestEncode = struct { buffer: [32]u8 = undefined, index: usize = 0, - fn encode(enc: *TestEncode, mnemonic: Instruction.Mnemonic, args: struct { - op1: Instruction.Operand = .none, - op2: Instruction.Operand = .none, - op3: Instruction.Operand = .none, - op4: Instruction.Operand = .none, - }) !void { + fn encode(enc: *TestEncode, mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void { var stream = std.io.fixedBufferStream(&enc.buffer); var count_writer = std.io.countingWriter(stream.writer()); const inst = try Instruction.new(mnemonic, .{ + .prefix = args.prefix, .op1 = args.op1, .op2 = args.op2, .op3 = args.op3, @@ -1447,18 +1462,8 @@ test "lower NP encoding" { try expectEqualHexStrings("\x0f\x05", enc.code(), "syscall"); } -fn invalidInstruction(mnemonic: Instruction.Mnemonic, args: struct { - op1: Instruction.Operand = .none, - op2: Instruction.Operand = .none, - op3: Instruction.Operand = .none, - op4: Instruction.Operand = .none, -}) !void { - const err = Instruction.new(mnemonic, .{ - .op1 = args.op1, - .op2 = args.op2, - .op3 = args.op3, - .op4 = args.op4, - }); +fn invalidInstruction(mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void { + const err = Instruction.new(mnemonic, args); try testing.expectError(error.InvalidInstruction, err); } @@ -1479,18 +1484,8 @@ test "invalid instruction" { try invalidInstruction(.push, .{ .op1 = .{ .imm = Immediate.u(0x1000000000000000) } }); } -fn cannotEncode(mnemonic: Instruction.Mnemonic, args: struct { - op1: Instruction.Operand = .none, - op2: Instruction.Operand = .none, - op3: Instruction.Operand = .none, - op4: Instruction.Operand = .none, -}) !void { - try testing.expectError(error.CannotEncode, Instruction.new(mnemonic, .{ - .op1 = args.op1, - .op2 = args.op2, - .op3 = args.op3, - .op4 = args.op4, - })); +fn cannotEncode(mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void { + try testing.expectError(error.CannotEncode, Instruction.new(mnemonic, args)); } test "cannot encode" { |
