| ... | ... | @@ -113,7 +113,8 @@ pub fn emitMir(emit: *Emit) InnerError!void { |
| 113 | 113 | |
| 114 | 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 | 119 | .jmp => try emit.mirJmpCall(.jmp_near, inst), |
| 119 | 120 | .call => try emit.mirJmpCall(.call_near, inst), |
| ... | ... | @@ -198,7 +199,7 @@ fn mirSyscall(emit: *Emit) InnerError!void { |
| 198 | 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 | 203 | const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]); |
| 203 | 204 | switch (ops.flags) { |
| 204 | 205 | 0b00 => { |
| ... | ... | @@ -217,25 +218,7 @@ fn mirPushPop(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!v |
| 217 | 218 | 0b01 => { |
| 218 | 219 | // PUSH/POP r/m64 |
| 219 | 220 | const imm = emit.mir.instructions.items(.data)[inst].imm; |
| 220 | | const opc: u8 = switch (tag) { |
| 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 | | } |
| 221 | return lowerToMEnc(tag, RegisterOrMemory.mem(ops.reg1, imm), emit.code); |
| 239 | 222 | }, |
| 240 | 223 | 0b10 => { |
| 241 | 224 | // PUSH imm32 |
| ... | ... | @@ -255,7 +238,7 @@ fn mirPushPop(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!v |
| 255 | 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 | 242 | const callee_preserved_regs = bits.callee_preserved_regs; |
| 260 | 243 | // PUSH/POP reg |
| 261 | 244 | const opc: u8 = switch (tag) { |
| ... | ... | @@ -532,6 +515,8 @@ const Tag = enum { |
| 532 | 515 | lea, |
| 533 | 516 | jmp_near, |
| 534 | 517 | call_near, |
| 518 | push, |
| 519 | pop, |
| 535 | 520 | }; |
| 536 | 521 | |
| 537 | 522 | const Encoding = enum { |
| ... | ... | @@ -568,7 +553,8 @@ inline fn getOpCode(tag: Tag, enc: Encoding) ?u8 { |
| 568 | 553 | else => null, |
| 569 | 554 | }, |
| 570 | 555 | .m => return switch (tag) { |
| 571 | | .jmp_near, .call_near => 0xff, |
| 556 | .jmp_near, .call_near, .push => 0xff, |
| 557 | .pop => 0x8f, |
| 572 | 558 | else => null, |
| 573 | 559 | }, |
| 574 | 560 | .mi => return switch (tag) { |
| ... | ... | @@ -629,6 +615,8 @@ inline fn getModRmExt(tag: Tag) ?u3 { |
| 629 | 615 | .mov => 0x0, |
| 630 | 616 | .jmp_near => 0x4, |
| 631 | 617 | .call_near => 0x2, |
| 618 | .push => 0x6, |
| 619 | .pop => 0x0, |
| 632 | 620 | else => null, |
| 633 | 621 | }; |
| 634 | 622 | } |