| ... | @@ -185,13 +185,11 @@ fn fixupRelocs(emit: *Emit) InnerError!void { | ... | @@ -185,13 +185,11 @@ fn fixupRelocs(emit: *Emit) InnerError!void { |
| 185 | } | 185 | } |
| 186 | | 186 | |
| 187 | fn mirBrk(emit: *Emit) InnerError!void { | 187 | fn 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 | } |
| 191 | | 190 | |
| 192 | fn mirNop(emit: *Emit) InnerError!void { | 191 | fn 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 | } |
| 196 | | 194 | |
| 197 | fn mirSyscall(emit: *Emit) InnerError!void { | 195 | fn 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 imm16 | 439 | // 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), // RETF | 444 | 0b01 => return lowerToZoEnc(.ret_far, emit.code), |
| 448 | 0b10 => { | 445 | 0b10 => { |
| 449 | // RET imm16 | 446 | // RET imm16 |
| 450 | // I | 447 | // 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), // RET | 451 | 0b11 => return lowerToZoEnc(.ret_near, emit.code), |
| 455 | } | 452 | } |
| 456 | } | 453 | } |
| 457 | | 454 | |
| ... | @@ -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 | }; |
| 477 | | 476 | |
| 478 | const Encoding = enum { | 477 | const Encoding = enum { |
| | 478 | /// OP |
| | 479 | zo, |
| | 480 | |
| 479 | /// OP rel32 | 481 | /// OP rel32 |
| 480 | d, | 482 | d, |
| 481 | | 483 | |
| ... | @@ -509,6 +511,13 @@ const Encoding = enum { | ... | @@ -509,6 +511,13 @@ const Encoding = enum { |
| 509 | | 511 | |
| 510 | inline fn getOpCode(tag: Tag, enc: Encoding) ?u8 { | 512 | inline 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 | }; |
| 640 | | 649 | |
| | 650 | fn 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 | |
| 641 | fn lowerToIEnc(tag: Tag, imm: i32, code: *std.ArrayList(u8)) InnerError!void { | 656 | fn 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) { |