authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-23 17:51:19+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-23 18:49:40+01:00
logd23a1487bd397ce86108ae2727b67a1d0614f7a9
treec0c87facf901c419f6f2aa08d0eeff98c18574e4
parenta70b4068c6a8585da8b0a28326010807e5c427c1

stage2: add lowering of ZO encoding

ZO (probably) stands for zero operands encoding which is effectively only the opcode.

1 files changed, 22 insertions(+), 7 deletions(-)

src/arch/x86_64/Emit.zig+22-7
...@@ -185,13 +185,11 @@ fn fixupRelocs(emit: *Emit) InnerError!void {...@@ -185,13 +185,11 @@ fn fixupRelocs(emit: *Emit) InnerError!void {
185}185}
186186
187fn mirBrk(emit: *Emit) InnerError!void {187fn mirBrk(emit: *Emit) InnerError!void {
188 const encoder = try Encoder.init(emit.code, 1);188 return lowerToZoEnc(.brk, emit.code);
189 encoder.opcode_1byte(0xcc);
190}189}
191190
192fn mirNop(emit: *Emit) InnerError!void {191fn mirNop(emit: *Emit) InnerError!void {
193 const encoder = try Encoder.init(emit.code, 1);192 return lowerToZoEnc(.nop, emit.code);
194 encoder.opcode_1byte(0x90);
195}193}
196194
197fn mirSyscall(emit: *Emit) InnerError!void {195fn mirSyscall(emit: *Emit) InnerError!void {
...@@ -436,7 +434,6 @@ fn mirRet(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -436,7 +434,6 @@ fn mirRet(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
436 const tag = emit.mir.instructions.items(.tag)[inst];434 const tag = emit.mir.instructions.items(.tag)[inst];
437 assert(tag == .ret);435 assert(tag == .ret);
438 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);436 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
439 const encoder = try Encoder.init(emit.code, 3);
440 switch (ops.flags) {437 switch (ops.flags) {
441 0b00 => {438 0b00 => {
442 // RETF imm16439 // RETF imm16
...@@ -444,14 +441,14 @@ fn mirRet(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -444,14 +441,14 @@ fn mirRet(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
444 const imm = emit.mir.instructions.items(.data)[inst].imm;441 const imm = emit.mir.instructions.items(.data)[inst].imm;
445 return lowerToIEnc(.ret_far, imm, emit.code);442 return lowerToIEnc(.ret_far, imm, emit.code);
446 },443 },
447 0b01 => encoder.opcode_1byte(0xcb), // RETF444 0b01 => return lowerToZoEnc(.ret_far, emit.code),
448 0b10 => {445 0b10 => {
449 // RET imm16446 // RET imm16
450 // I447 // I
451 const imm = emit.mir.instructions.items(.data)[inst].imm;448 const imm = emit.mir.instructions.items(.data)[inst].imm;
452 return lowerToIEnc(.ret_near, imm, emit.code);449 return lowerToIEnc(.ret_near, imm, emit.code);
453 },450 },
454 0b11 => encoder.opcode_1byte(0xc3), // RET451 0b11 => return lowerToZoEnc(.ret_near, emit.code),
455 }452 }
456}453}
457454
...@@ -471,11 +468,16 @@ const Tag = enum {...@@ -471,11 +468,16 @@ const Tag = enum {
471 push,468 push,
472 pop,469 pop,
473 @"test",470 @"test",
471 brk,
472 nop,
474 ret_near,473 ret_near,
475 ret_far,474 ret_far,
476};475};
477476
478const Encoding = enum {477const Encoding = enum {
478 /// OP
479 zo,
480
479 /// OP rel32481 /// OP rel32
480 d,482 d,
481483
...@@ -509,6 +511,13 @@ const Encoding = enum {...@@ -509,6 +511,13 @@ const Encoding = enum {
509511
510inline fn getOpCode(tag: Tag, enc: Encoding) ?u8 {512inline fn getOpCode(tag: Tag, enc: Encoding) ?u8 {
511 switch (enc) {513 switch (enc) {
514 .zo => return switch (tag) {
515 .ret_near => 0xc3,
516 .ret_far => 0xcb,
517 .brk => 0xcc,
518 .nop => 0x90,
519 else => null,
520 },
512 .d => return switch (tag) {521 .d => return switch (tag) {
513 .jmp_near => 0xe9,522 .jmp_near => 0xe9,
514 .call_near => 0xe8,523 .call_near => 0xe8,
...@@ -638,6 +647,12 @@ const RegisterOrMemory = union(enum) {...@@ -638,6 +647,12 @@ const RegisterOrMemory = union(enum) {
638 }647 }
639};648};
640649
650fn lowerToZoEnc(tag: Tag, code: *std.ArrayList(u8)) InnerError!void {
651 const opc = getOpCode(tag, .zo).?;
652 const encoder = try Encoder.init(code, 1);
653 encoder.opcode_1byte(opc);
654}
655
641fn lowerToIEnc(tag: Tag, imm: i32, code: *std.ArrayList(u8)) InnerError!void {656fn lowerToIEnc(tag: Tag, imm: i32, code: *std.ArrayList(u8)) InnerError!void {
642 var opc = getOpCode(tag, .i).?;657 var opc = getOpCode(tag, .i).?;
643 if (tag == .ret_far or tag == .ret_near) {658 if (tag == .ret_far or tag == .ret_near) {