authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-23 00:36:44+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-23 00:43:38+01:00
log1167e248ef8ab94aac3c4218574a09ba9346d34f
tree180b7188d0b3de1581370698a626e8ee2612f3ef
parent362eccf539db6bb89e222916f3c4a45b0eb2bece

stage2: add lowering of D encoding

Example of such encoding includes a near/far call and jmp instructions.

1 files changed, 118 insertions(+), 110 deletions(-)

src/arch/x86_64/Emit.zig+118-110
...@@ -66,40 +66,45 @@ pub fn emitMir(emit: *Emit) InnerError!void {...@@ -66,40 +66,45 @@ pub fn emitMir(emit: *Emit) InnerError!void {
66 const inst = @intCast(u32, index);66 const inst = @intCast(u32, index);
67 try emit.code_offset_mapping.putNoClobber(emit.bin_file.allocator, inst, emit.code.items.len);67 try emit.code_offset_mapping.putNoClobber(emit.bin_file.allocator, inst, emit.code.items.len);
68 switch (tag) {68 switch (tag) {
69 .adc, .add, .sub, .xor, .@"and", .@"or", .sbb, .cmp, .mov => try emit.mirArith(tag, inst),69 .adc => try emit.mirArith(.adc, inst),
7070 .add => try emit.mirArith(.add, inst),
71 .adc_scale_src,71 .sub => try emit.mirArith(.sub, inst),
72 .add_scale_src,72 .xor => try emit.mirArith(.xor, inst),
73 .sub_scale_src,73 .@"and" => try emit.mirArith(.@"and", inst),
74 .xor_scale_src,74 .@"or" => try emit.mirArith(.@"or", inst),
75 .and_scale_src,75 .sbb => try emit.mirArith(.sbb, inst),
76 .or_scale_src,76 .cmp => try emit.mirArith(.cmp, inst),
77 .sbb_scale_src,77 .mov => try emit.mirArith(.mov, inst),
78 .cmp_scale_src,78
79 .mov_scale_src,79 .adc_scale_src => try emit.mirArithScaleSrc(.adc, inst),
80 => try emit.mirArithScaleSrc(tag, inst),80 .add_scale_src => try emit.mirArithScaleSrc(.add, inst),
8181 .sub_scale_src => try emit.mirArithScaleSrc(.sub, inst),
82 .adc_scale_dst,82 .xor_scale_src => try emit.mirArithScaleSrc(.xor, inst),
83 .add_scale_dst,83 .and_scale_src => try emit.mirArithScaleSrc(.@"and", inst),
84 .sub_scale_dst,84 .or_scale_src => try emit.mirArithScaleSrc(.@"or", inst),
85 .xor_scale_dst,85 .sbb_scale_src => try emit.mirArithScaleSrc(.sbb, inst),
86 .and_scale_dst,86 .cmp_scale_src => try emit.mirArithScaleSrc(.cmp, inst),
87 .or_scale_dst,87 .mov_scale_src => try emit.mirArithScaleSrc(.mov, inst),
88 .sbb_scale_dst,88
89 .cmp_scale_dst,89 .adc_scale_dst => try emit.mirArithScaleDst(.adc, inst),
90 .mov_scale_dst,90 .add_scale_dst => try emit.mirArithScaleDst(.add, inst),
91 => try emit.mirArithScaleDst(tag, inst),91 .sub_scale_dst => try emit.mirArithScaleDst(.sub, inst),
9292 .xor_scale_dst => try emit.mirArithScaleDst(.xor, inst),
93 .adc_scale_imm,93 .and_scale_dst => try emit.mirArithScaleDst(.@"and", inst),
94 .add_scale_imm,94 .or_scale_dst => try emit.mirArithScaleDst(.@"or", inst),
95 .sub_scale_imm,95 .sbb_scale_dst => try emit.mirArithScaleDst(.sbb, inst),
96 .xor_scale_imm,96 .cmp_scale_dst => try emit.mirArithScaleDst(.cmp, inst),
97 .and_scale_imm,97 .mov_scale_dst => try emit.mirArithScaleDst(.mov, inst),
98 .or_scale_imm,98
99 .sbb_scale_imm,99 .adc_scale_imm => try emit.mirArithScaleImm(.adc, inst),
100 .cmp_scale_imm,100 .add_scale_imm => try emit.mirArithScaleImm(.add, inst),
101 .mov_scale_imm,101 .sub_scale_imm => try emit.mirArithScaleImm(.sub, inst),
102 => try emit.mirArithScaleImm(tag, inst),102 .xor_scale_imm => try emit.mirArithScaleImm(.xor, inst),
103 .and_scale_imm => try emit.mirArithScaleImm(.@"and", inst),
104 .or_scale_imm => try emit.mirArithScaleImm(.@"or", inst),
105 .sbb_scale_imm => try emit.mirArithScaleImm(.sbb, inst),
106 .cmp_scale_imm => try emit.mirArithScaleImm(.cmp, inst),
107 .mov_scale_imm => try emit.mirArithScaleImm(.mov, inst),
103108
104 .movabs => try emit.mirMovabs(inst),109 .movabs => try emit.mirMovabs(inst),
105110
...@@ -110,7 +115,8 @@ pub fn emitMir(emit: *Emit) InnerError!void {...@@ -110,7 +115,8 @@ pub fn emitMir(emit: *Emit) InnerError!void {
110115
111 .push, .pop => try emit.mirPushPop(tag, inst),116 .push, .pop => try emit.mirPushPop(tag, inst),
112117
113 .jmp, .call => try emit.mirJmpCall(tag, inst),118 .jmp => try emit.mirJmpCall(.jmp_near, inst),
119 .call => try emit.mirJmpCall(.call_near, inst),
114120
115 .cond_jmp_greater_less,121 .cond_jmp_greater_less,
116 .cond_jmp_above_below,122 .cond_jmp_above_below,
...@@ -283,31 +289,24 @@ fn mirPushPopRegsFromCalleePreservedRegs(emit: *Emit, tag: Mir.Inst.Tag, inst: M...@@ -283,31 +289,24 @@ fn mirPushPopRegsFromCalleePreservedRegs(emit: *Emit, tag: Mir.Inst.Tag, inst: M
283 }289 }
284}290}
285291
286fn mirJmpCall(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void {292fn mirJmpCall(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void {
287 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);293 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
288 const flag = @truncate(u1, ops.flags);294 const flag = @truncate(u1, ops.flags);
289 if (flag == 0) {295 if (flag == 0) {
290 const target = emit.mir.instructions.items(.data)[inst].inst;296 const target = emit.mir.instructions.items(.data)[inst].inst;
291 const opc: u8 = switch (tag) {
292 .jmp => 0xe9,
293 .call => 0xe8,
294 else => unreachable,
295 };
296 const source = emit.code.items.len;297 const source = emit.code.items.len;
297 const encoder = try Encoder.init(emit.code, 5);298 try lowerToDEnc(tag, 0, emit.code);
298 encoder.opcode_1byte(opc);
299 try emit.relocs.append(emit.bin_file.allocator, .{299 try emit.relocs.append(emit.bin_file.allocator, .{
300 .source = source,300 .source = source,
301 .target = target,301 .target = target,
302 .offset = emit.code.items.len,302 .offset = emit.code.items.len - 4,
303 .length = 5,303 .length = 5,
304 });304 });
305 encoder.imm32(0x0);
306 return;305 return;
307 }306 }
308 const modrm_ext: u3 = switch (tag) {307 const modrm_ext: u3 = switch (tag) {
309 .jmp => 0x4,308 .jmp_near => 0x4,
310 .call => 0x2,309 .call_near => 0x2,
311 else => unreachable,310 else => unreachable,
312 };311 };
313 if (ops.reg1 == .none) {312 if (ops.reg1 == .none) {
...@@ -532,7 +531,28 @@ fn mirRet(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -532,7 +531,28 @@ fn mirRet(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
532 }531 }
533}532}
534533
534const Tag = enum {
535 adc,
536 add,
537 sub,
538 xor,
539 @"and",
540 @"or",
541 sbb,
542 cmp,
543 mov,
544 lea,
545 jmp_near,
546 call_near,
547};
548
535const Encoding = enum {549const Encoding = enum {
550 /// OP rel32
551 d,
552
553 /// OP r/m64
554 m,
555
536 /// OP r/m64, imm32556 /// OP r/m64, imm32
537 mi,557 mi,
538558
...@@ -552,12 +572,21 @@ const Encoding = enum {...@@ -552,12 +572,21 @@ const Encoding = enum {
552 td,572 td,
553};573};
554574
555inline fn getOpCode(tag: Mir.Inst.Tag, enc: Encoding) u8 {575inline fn getOpCode(tag: Tag, enc: Encoding) ?u8 {
556 switch (enc) {576 switch (enc) {
577 .d => return switch (tag) {
578 .jmp_near => 0xe9,
579 .call_near => 0xe8,
580 else => null,
581 },
582 .m => return switch (tag) {
583 .jmp_near, .call_near => 0xff,
584 else => null,
585 },
557 .mi => return switch (tag) {586 .mi => return switch (tag) {
558 .adc, .add, .sub, .xor, .@"and", .@"or", .sbb, .cmp => 0x81,587 .adc, .add, .sub, .xor, .@"and", .@"or", .sbb, .cmp => 0x81,
559 .mov => 0xc7,588 .mov => 0xc7,
560 else => unreachable,589 else => null,
561 },590 },
562 .mr => return switch (tag) {591 .mr => return switch (tag) {
563 .adc => 0x11,592 .adc => 0x11,
...@@ -569,7 +598,7 @@ inline fn getOpCode(tag: Mir.Inst.Tag, enc: Encoding) u8 {...@@ -569,7 +598,7 @@ inline fn getOpCode(tag: Mir.Inst.Tag, enc: Encoding) u8 {
569 .sbb => 0x19,598 .sbb => 0x19,
570 .cmp => 0x39,599 .cmp => 0x39,
571 .mov => 0x89,600 .mov => 0x89,
572 else => unreachable,601 else => null,
573 },602 },
574 .rm => return switch (tag) {603 .rm => return switch (tag) {
575 .adc => 0x13,604 .adc => 0x13,
...@@ -582,24 +611,24 @@ inline fn getOpCode(tag: Mir.Inst.Tag, enc: Encoding) u8 {...@@ -582,24 +611,24 @@ inline fn getOpCode(tag: Mir.Inst.Tag, enc: Encoding) u8 {
582 .cmp => 0x3b,611 .cmp => 0x3b,
583 .mov => 0x8b,612 .mov => 0x8b,
584 .lea => 0x8d,613 .lea => 0x8d,
585 else => unreachable,614 else => null,
586 },615 },
587 .oi => return switch (tag) {616 .oi => return switch (tag) {
588 .mov => 0xb8,617 .mov => 0xb8,
589 else => unreachable,618 else => null,
590 },619 },
591 .fd => return switch (tag) {620 .fd => return switch (tag) {
592 .mov => 0xa1,621 .mov => 0xa1,
593 else => unreachable,622 else => null,
594 },623 },
595 .td => return switch (tag) {624 .td => return switch (tag) {
596 .mov => 0xa3,625 .mov => 0xa3,
597 else => unreachable,626 else => null,
598 },627 },
599 }628 }
600}629}
601630
602inline fn getMiModRmExt(tag: Mir.Inst.Tag) u3 {631inline fn getModRmExt(tag: Tag) u3 {
603 return switch (tag) {632 return switch (tag) {
604 .adc => 0x2,633 .adc => 0x2,
605 .add => 0x0,634 .add => 0x0,
...@@ -610,6 +639,7 @@ inline fn getMiModRmExt(tag: Mir.Inst.Tag) u3 {...@@ -610,6 +639,7 @@ inline fn getMiModRmExt(tag: Mir.Inst.Tag) u3 {
610 .sbb => 0x3,639 .sbb => 0x3,
611 .cmp => 0x7,640 .cmp => 0x7,
612 .mov => 0x0,641 .mov => 0x0,
642 .call_near => 0x2,
613 else => unreachable,643 else => unreachable,
614 };644 };
615}645}
...@@ -655,34 +685,25 @@ const RegisterOrMemory = union(enum) {...@@ -655,34 +685,25 @@ const RegisterOrMemory = union(enum) {
655 }685 }
656};686};
657687
658fn lowerToTdEnc(688fn lowerToDEnc(tag: Tag, imm: i32, code: *std.ArrayList(u8)) InnerError!void {
659 tag: Mir.Inst.Tag,689 const opc = getOpCode(tag, .d).?;
660 moffs: i64,690 const encoder = try Encoder.init(code, 5);
661 reg: Register,691 encoder.opcode_1byte(opc);
662 code: *std.ArrayList(u8),692 encoder.imm32(imm);
663) InnerError!void {693}
694
695fn lowerToTdEnc(tag: Tag, moffs: i64, reg: Register, code: *std.ArrayList(u8)) InnerError!void {
664 return lowerToTdFdEnc(tag, reg, moffs, code, true);696 return lowerToTdFdEnc(tag, reg, moffs, code, true);
665}697}
666698
667fn lowerToFdEnc(699fn lowerToFdEnc(tag: Tag, reg: Register, moffs: i64, code: *std.ArrayList(u8)) InnerError!void {
668 tag: Mir.Inst.Tag,
669 reg: Register,
670 moffs: i64,
671 code: *std.ArrayList(u8),
672) InnerError!void {
673 return lowerToTdFdEnc(tag, reg, moffs, code, false);700 return lowerToTdFdEnc(tag, reg, moffs, code, false);
674}701}
675702
676fn lowerToTdFdEnc(703fn lowerToTdFdEnc(tag: Tag, reg: Register, moffs: i64, code: *std.ArrayList(u8), td: bool) InnerError!void {
677 tag: Mir.Inst.Tag,
678 reg: Register,
679 moffs: i64,
680 code: *std.ArrayList(u8),
681 td: bool,
682) InnerError!void {
683 if (reg.lowId() != Register.rax.lowId()) return error.EmitFail;704 if (reg.lowId() != Register.rax.lowId()) return error.EmitFail;
684 if (reg.size() != immOpSize(moffs)) return error.EmitFail;705 if (reg.size() != immOpSize(moffs)) return error.EmitFail;
685 var opc = if (td) getOpCode(tag, .td) else getOpCode(tag, .fd);706 var opc = if (td) getOpCode(tag, .td).? else getOpCode(tag, .fd).?;
686 if (reg.size() == 8) {707 if (reg.size() == 8) {
687 opc -= 1;708 opc -= 1;
688 }709 }
...@@ -714,13 +735,8 @@ fn lowerToTdFdEnc(...@@ -714,13 +735,8 @@ fn lowerToTdFdEnc(
714 }735 }
715}736}
716737
717fn lowerToOiEnc(738fn lowerToOiEnc(tag: Tag, reg: Register, imm: i64, code: *std.ArrayList(u8)) InnerError!void {
718 tag: Mir.Inst.Tag,739 var opc = getOpCode(tag, .oi).?;
719 reg: Register,
720 imm: i64,
721 code: *std.ArrayList(u8),
722) InnerError!void {
723 var opc = getOpCode(tag, .oi);
724 if (reg.size() != immOpSize(imm)) return error.EmitFail;740 if (reg.size() != immOpSize(imm)) return error.EmitFail;
725 if (reg.size() == 8) {741 if (reg.size() == 8) {
726 opc -= 8;742 opc -= 8;
...@@ -754,14 +770,9 @@ fn lowerToOiEnc(...@@ -754,14 +770,9 @@ fn lowerToOiEnc(
754 }770 }
755}771}
756772
757fn lowerToMiEnc(773fn lowerToMiEnc(tag: Tag, reg_or_mem: RegisterOrMemory, imm: i32, code: *std.ArrayList(u8)) InnerError!void {
758 tag: Mir.Inst.Tag,774 var opc = getOpCode(tag, .mi).?;
759 reg_or_mem: RegisterOrMemory,775 const modrm_ext = getModRmExt(tag);
760 imm: i32,
761 code: *std.ArrayList(u8),
762) InnerError!void {
763 var opc = getOpCode(tag, .mi);
764 const modrm_ext = getMiModRmExt(tag);
765 switch (reg_or_mem) {776 switch (reg_or_mem) {
766 .register => |dst_reg| {777 .register => |dst_reg| {
767 if (dst_reg.size() == 8) {778 if (dst_reg.size() == 8) {
...@@ -839,12 +850,12 @@ fn lowerToMiEnc(...@@ -839,12 +850,12 @@ fn lowerToMiEnc(
839}850}
840851
841fn lowerToRmEnc(852fn lowerToRmEnc(
842 tag: Mir.Inst.Tag,853 tag: Tag,
843 reg: Register,854 reg: Register,
844 reg_or_mem: RegisterOrMemory,855 reg_or_mem: RegisterOrMemory,
845 code: *std.ArrayList(u8),856 code: *std.ArrayList(u8),
846) InnerError!void {857) InnerError!void {
847 var opc = getOpCode(tag, .rm);858 var opc = getOpCode(tag, .rm).?;
848 if (reg.size() == 8) {859 if (reg.size() == 8) {
849 opc -= 1;860 opc -= 1;
850 }861 }
...@@ -909,7 +920,7 @@ fn lowerToRmEnc(...@@ -909,7 +920,7 @@ fn lowerToRmEnc(
909}920}
910921
911fn lowerToMrEnc(922fn lowerToMrEnc(
912 tag: Mir.Inst.Tag,923 tag: Tag,
913 reg_or_mem: RegisterOrMemory,924 reg_or_mem: RegisterOrMemory,
914 reg: Register,925 reg: Register,
915 code: *std.ArrayList(u8),926 code: *std.ArrayList(u8),
...@@ -920,7 +931,7 @@ fn lowerToMrEnc(...@@ -920,7 +931,7 @@ fn lowerToMrEnc(
920 // * reg is 32bit - dword ptr931 // * reg is 32bit - dword ptr
921 // * reg is 16bit - word ptr932 // * reg is 16bit - word ptr
922 // * reg is 8bit - byte ptr933 // * reg is 8bit - byte ptr
923 var opc = getOpCode(tag, .mr);934 var opc = getOpCode(tag, .mr).?;
924 if (reg.size() == 8) {935 if (reg.size() == 8) {
925 opc -= 1;936 opc -= 1;
926 }937 }
...@@ -982,7 +993,7 @@ fn lowerToMrEnc(...@@ -982,7 +993,7 @@ fn lowerToMrEnc(
982 }993 }
983}994}
984995
985fn mirArith(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void {996fn mirArith(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void {
986 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);997 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
987 switch (ops.flags) {998 switch (ops.flags) {
988 0b00 => {999 0b00 => {
...@@ -1053,11 +1064,11 @@ fn immOpSize(imm: i64) u8 {...@@ -1053,11 +1064,11 @@ fn immOpSize(imm: i64) u8 {
1053 return 64;1064 return 64;
1054}1065}
10551066
1056fn mirArithScaleSrc(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void {1067fn mirArithScaleSrc(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void {
1057 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);1068 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
1058 const scale = ops.flags;1069 const scale = ops.flags;
1059 // OP reg1, [reg2 + scale*rcx + imm32]1070 // OP reg1, [reg2 + scale*rcx + imm32]
1060 var opc = getOpCode(tag, .rm);1071 var opc = getOpCode(tag, .rm).?;
1061 if (ops.reg1.size() == 8) {1072 if (ops.reg1.size() == 8) {
1062 opc -= 1;1073 opc -= 1;
1063 }1074 }
...@@ -1080,15 +1091,15 @@ fn mirArithScaleSrc(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE...@@ -1080,15 +1091,15 @@ fn mirArithScaleSrc(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE
1080 }1091 }
1081}1092}
10821093
1083fn mirArithScaleDst(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void {1094fn mirArithScaleDst(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void {
1084 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);1095 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
1085 const scale = ops.flags;1096 const scale = ops.flags;
1086 const imm = emit.mir.instructions.items(.data)[inst].imm;1097 const imm = emit.mir.instructions.items(.data)[inst].imm;
10871098
1088 if (ops.reg2 == .none) {1099 if (ops.reg2 == .none) {
1089 // OP [reg1 + scale*rax + 0], imm321100 // OP [reg1 + scale*rax + 0], imm32
1090 var opc = getOpCode(tag, .mi);1101 var opc = getOpCode(tag, .mi).?;
1091 const modrm_ext = getMiModRmExt(tag);1102 const modrm_ext = getModRmExt(tag);
1092 if (ops.reg1.size() == 8) {1103 if (ops.reg1.size() == 8) {
1093 opc -= 1;1104 opc -= 1;
1094 }1105 }
...@@ -1111,7 +1122,7 @@ fn mirArithScaleDst(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE...@@ -1111,7 +1122,7 @@ fn mirArithScaleDst(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE
1111 }1122 }
11121123
1113 // OP [reg1 + scale*rax + imm32], reg21124 // OP [reg1 + scale*rax + imm32], reg2
1114 var opc = getOpCode(tag, .mr);1125 var opc = getOpCode(tag, .mr).?;
1115 if (ops.reg1.size() == 8) {1126 if (ops.reg1.size() == 8) {
1116 opc -= 1;1127 opc -= 1;
1117 }1128 }
...@@ -1133,16 +1144,16 @@ fn mirArithScaleDst(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE...@@ -1133,16 +1144,16 @@ fn mirArithScaleDst(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE
1133 }1144 }
1134}1145}
11351146
1136fn mirArithScaleImm(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void {1147fn mirArithScaleImm(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void {
1137 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);1148 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
1138 const scale = ops.flags;1149 const scale = ops.flags;
1139 const payload = emit.mir.instructions.items(.data)[inst].payload;1150 const payload = emit.mir.instructions.items(.data)[inst].payload;
1140 const imm_pair = emit.mir.extraData(Mir.ImmPair, payload).data;1151 const imm_pair = emit.mir.extraData(Mir.ImmPair, payload).data;
1141 var opc = getOpCode(tag, .mi);1152 var opc = getOpCode(tag, .mi).?;
1142 if (ops.reg1.size() == 8) {1153 if (ops.reg1.size() == 8) {
1143 opc -= 1;1154 opc -= 1;
1144 }1155 }
1145 const modrm_ext = getMiModRmExt(tag);1156 const modrm_ext = getModRmExt(tag);
1146 const encoder = try Encoder.init(emit.code, 2);1157 const encoder = try Encoder.init(emit.code, 2);
1147 encoder.rex(.{1158 encoder.rex(.{
1148 .w = ops.reg1.size() == 64,1159 .w = ops.reg1.size() == 64,
...@@ -1230,7 +1241,7 @@ fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -1230,7 +1241,7 @@ fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
1230 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);1241 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
1231 assert(ops.flags == 0b01);1242 assert(ops.flags == 0b01);
1232 const imm = emit.mir.instructions.items(.data)[inst].imm;1243 const imm = emit.mir.instructions.items(.data)[inst].imm;
1233 return lowerToRmEnc(tag, ops.reg1, RegisterOrMemory.mem(ops.reg2, imm), emit.code);1244 return lowerToRmEnc(.lea, ops.reg1, RegisterOrMemory.mem(ops.reg2, imm), emit.code);
1234}1245}
12351246
1236fn mirLeaRip(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {1247fn mirLeaRip(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
...@@ -1272,12 +1283,9 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -1272,12 +1283,9 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
1272 assert(tag == .call_extern);1283 assert(tag == .call_extern);
1273 const n_strx = emit.mir.instructions.items(.data)[inst].extern_fn;1284 const n_strx = emit.mir.instructions.items(.data)[inst].extern_fn;
1274 const offset = blk: {1285 const offset = blk: {
1275 const offset = @intCast(u32, emit.code.items.len + 1);
1276 // callq1286 // callq
1277 const encoder = try Encoder.init(emit.code, 5);1287 try lowerToDEnc(.call_near, 0, emit.code);
1278 encoder.opcode_1byte(0xe8);1288 break :blk @intCast(u32, emit.code.items.len) - 4;
1279 encoder.imm32(0x0);
1280 break :blk offset;
1281 };1289 };
1282 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {1290 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
1283 // Add relocation to the decl.1291 // Add relocation to the decl.