| ... | @@ -113,7 +113,8 @@ pub fn emitMir(emit: *Emit) InnerError!void { | ... | @@ -113,7 +113,8 @@ pub fn emitMir(emit: *Emit) InnerError!void { |
| 113 | | 113 | |
| 114 | .imul_complex => try emit.mirIMulComplex(inst), | 114 | .imul_complex => try emit.mirIMulComplex(inst), |
| 115 | | 115 | |
| 116 | .push, .pop => try emit.mirPushPop(tag, inst), | 116 | .push => try emit.mirPushPop(.push, inst), |
| | 117 | .pop => try emit.mirPushPop(.pop, inst), |
| 117 | | 118 | |
| 118 | .jmp => try emit.mirJmpCall(.jmp_near, inst), | 119 | .jmp => try emit.mirJmpCall(.jmp_near, inst), |
| 119 | .call => try emit.mirJmpCall(.call_near, inst), | 120 | .call => try emit.mirJmpCall(.call_near, inst), |
| ... | @@ -198,7 +199,7 @@ fn mirSyscall(emit: *Emit) InnerError!void { | ... | @@ -198,7 +199,7 @@ fn mirSyscall(emit: *Emit) InnerError!void { |
| 198 | encoder.opcode_2byte(0x0f, 0x05); | 199 | encoder.opcode_2byte(0x0f, 0x05); |
| 199 | } | 200 | } |
| 200 | | 201 | |
| 201 | fn mirPushPop(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void { | 202 | fn mirPushPop(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void { |
| 202 | const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]); | 203 | const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]); |
| 203 | switch (ops.flags) { | 204 | switch (ops.flags) { |
| 204 | 0b00 => { | 205 | 0b00 => { |
| ... | @@ -217,25 +218,7 @@ fn mirPushPop(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!v | ... | @@ -217,25 +218,7 @@ fn mirPushPop(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!v |
| 217 | 0b01 => { | 218 | 0b01 => { |
| 218 | // PUSH/POP r/m64 | 219 | // PUSH/POP r/m64 |
| 219 | const imm = emit.mir.instructions.items(.data)[inst].imm; | 220 | const imm = emit.mir.instructions.items(.data)[inst].imm; |
| 220 | const opc: u8 = switch (tag) { | 221 | return lowerToMEnc(tag, RegisterOrMemory.mem(ops.reg1, imm), emit.code); |
| 221 | .push => 0xff, | | |
| 222 | .pop => 0x8f, | | |
| 223 | else => unreachable, | | |
| 224 | }; | | |
| 225 | const modrm_ext: u3 = switch (tag) { | | |
| 226 | .push => 0x6, | | |
| 227 | .pop => 0x0, | | |
| 228 | else => unreachable, | | |
| 229 | }; | | |
| 230 | const encoder = try Encoder.init(emit.code, 6); | | |
| 231 | encoder.opcode_1byte(opc); | | |
| 232 | if (math.cast(i8, imm)) |imm_i8| { | | |
| 233 | encoder.modRm_indirectDisp8(modrm_ext, ops.reg1.lowId()); | | |
| 234 | encoder.imm8(@intCast(i8, imm_i8)); | | |
| 235 | } else |_| { | | |
| 236 | encoder.modRm_indirectDisp32(modrm_ext, ops.reg1.lowId()); | | |
| 237 | encoder.imm32(imm); | | |
| 238 | } | | |
| 239 | }, | 222 | }, |
| 240 | 0b10 => { | 223 | 0b10 => { |
| 241 | // PUSH imm32 | 224 | // PUSH imm32 |
| ... | @@ -255,7 +238,7 @@ fn mirPushPop(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!v | ... | @@ -255,7 +238,7 @@ fn mirPushPop(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!v |
| 255 | 0b11 => unreachable, | 238 | 0b11 => unreachable, |
| 256 | } | 239 | } |
| 257 | } | 240 | } |
| 258 | fn mirPushPopRegsFromCalleePreservedRegs(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void { | 241 | fn mirPushPopRegsFromCalleePreservedRegs(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void { |
| 259 | const callee_preserved_regs = bits.callee_preserved_regs; | 242 | const callee_preserved_regs = bits.callee_preserved_regs; |
| 260 | // PUSH/POP reg | 243 | // PUSH/POP reg |
| 261 | const opc: u8 = switch (tag) { | 244 | const opc: u8 = switch (tag) { |
| ... | @@ -532,6 +515,8 @@ const Tag = enum { | ... | @@ -532,6 +515,8 @@ const Tag = enum { |
| 532 | lea, | 515 | lea, |
| 533 | jmp_near, | 516 | jmp_near, |
| 534 | call_near, | 517 | call_near, |
| | 518 | push, |
| | 519 | pop, |
| 535 | }; | 520 | }; |
| 536 | | 521 | |
| 537 | const Encoding = enum { | 522 | const Encoding = enum { |
| ... | @@ -568,7 +553,8 @@ inline fn getOpCode(tag: Tag, enc: Encoding) ?u8 { | ... | @@ -568,7 +553,8 @@ inline fn getOpCode(tag: Tag, enc: Encoding) ?u8 { |
| 568 | else => null, | 553 | else => null, |
| 569 | }, | 554 | }, |
| 570 | .m => return switch (tag) { | 555 | .m => return switch (tag) { |
| 571 | .jmp_near, .call_near => 0xff, | 556 | .jmp_near, .call_near, .push => 0xff, |
| | 557 | .pop => 0x8f, |
| 572 | else => null, | 558 | else => null, |
| 573 | }, | 559 | }, |
| 574 | .mi => return switch (tag) { | 560 | .mi => return switch (tag) { |
| ... | @@ -629,6 +615,8 @@ inline fn getModRmExt(tag: Tag) ?u3 { | ... | @@ -629,6 +615,8 @@ inline fn getModRmExt(tag: Tag) ?u3 { |
| 629 | .mov => 0x0, | 615 | .mov => 0x0, |
| 630 | .jmp_near => 0x4, | 616 | .jmp_near => 0x4, |
| 631 | .call_near => 0x2, | 617 | .call_near => 0x2, |
| | 618 | .push => 0x6, |
| | 619 | .pop => 0x0, |
| 632 | else => null, | 620 | else => null, |
| 633 | }; | 621 | }; |
| 634 | } | 622 | } |