authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-08-13 17:42:11+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-09-09 19:17:13+02:00
log28cc3639476fae72bae3836e8776966386915142
tree4abac414a331012b87b2ac1de2bf0736e62b5e2b
parent9e070b653c89a9216f9dd9f78ed7c78c11460ac7
signaturelock-open Commit is signed but in an unrecognized format.

stage2 ARM: improve Mir representation of mov and cmp


3 files changed, 82 insertions(+), 61 deletions(-)

src/arch/arm/CodeGen.zig+32-49
......@@ -438,9 +438,8 @@ fn gen(self: *Self) !void {
438438 // mov fp, sp
439439 _ = try self.addInst(.{
440440 .tag = .mov,
441 .data = .{ .rr_op = .{
441 .data = .{ .r_op_mov = .{
442442 .rd = .fp,
443 .rn = .r0,
444443 .op = Instruction.Operand.reg(.sp, Instruction.Operand.Shift.none),
445444 } },
446445 });
......@@ -531,9 +530,8 @@ fn gen(self: *Self) !void {
531530 // mov sp, fp
532531 _ = try self.addInst(.{
533532 .tag = .mov,
534 .data = .{ .rr_op = .{
533 .data = .{ .r_op_mov = .{
535534 .rd = .sp,
536 .rn = .r0,
537535 .op = Instruction.Operand.reg(.fp, Instruction.Operand.Shift.none),
538536 } },
539537 });
......@@ -1240,9 +1238,8 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
12401238
12411239 _ = try self.addInst(.{
12421240 .tag = .mvn,
1243 .data = .{ .rr_op = .{
1241 .data = .{ .r_op_mov = .{
12441242 .rd = dest_reg,
1245 .rn = undefined,
12461243 .op = Instruction.Operand.reg(op_reg, Instruction.Operand.Shift.none),
12471244 } },
12481245 });
......@@ -1337,9 +1334,8 @@ fn minMax(
13371334 _ = try self.addInst(.{
13381335 .tag = .mov,
13391336 .cond = cond_choose_lhs,
1340 .data = .{ .rr_op = .{
1337 .data = .{ .r_op_mov = .{
13411338 .rd = dest_reg,
1342 .rn = .r0,
13431339 .op = Instruction.Operand.reg(lhs_reg, Instruction.Operand.Shift.none),
13441340 } },
13451341 });
......@@ -1348,9 +1344,8 @@ fn minMax(
13481344 _ = try self.addInst(.{
13491345 .tag = .mov,
13501346 .cond = cond_choose_rhs,
1351 .data = .{ .rr_op = .{
1347 .data = .{ .r_op_mov = .{
13521348 .rd = dest_reg,
1353 .rn = .r0,
13541349 .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none),
13551350 } },
13561351 });
......@@ -1682,9 +1677,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
16821677 // mov rdlo, #0
16831678 _ = try self.addInst(.{
16841679 .tag = .mov,
1685 .data = .{ .rr_op = .{
1680 .data = .{ .r_op_mov = .{
16861681 .rd = rdlo,
1687 .rn = .r0,
16881682 .op = Instruction.Operand.fromU32(0).?,
16891683 } },
16901684 });
......@@ -1693,9 +1687,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
16931687 _ = try self.addInst(.{
16941688 .tag = .mov,
16951689 .cond = .ne,
1696 .data = .{ .rr_op = .{
1690 .data = .{ .r_op_mov = .{
16971691 .rd = rdlo,
1698 .rn = .r0,
16991692 .op = Instruction.Operand.fromU32(1).?,
17001693 } },
17011694 });
......@@ -1707,9 +1700,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
17071700 _ = try self.addInst(.{
17081701 .tag = .mov,
17091702 .cond = .ne,
1710 .data = .{ .rr_op = .{
1703 .data = .{ .r_op_mov = .{
17111704 .rd = rdlo,
1712 .rn = .r0,
17131705 .op = Instruction.Operand.fromU32(1).?,
17141706 } },
17151707 });
......@@ -2670,7 +2662,7 @@ fn binOpRegister(
26702662 defer if (new_rhs_lock) |reg| self.register_manager.unlockReg(reg);
26712663
26722664 const dest_reg = switch (mir_tag) {
2673 .cmp => .r0, // cmp has no destination regardless
2665 .cmp => undefined, // cmp has no destination regardless
26742666 else => if (metadata) |md| blk: {
26752667 if (lhs_is_register and self.reuseOperand(md.inst, md.lhs, 0, lhs)) {
26762668 break :blk lhs_reg;
......@@ -2690,7 +2682,6 @@ fn binOpRegister(
26902682 .adds,
26912683 .sub,
26922684 .subs,
2693 .cmp,
26942685 .@"and",
26952686 .orr,
26962687 .eor,
......@@ -2699,6 +2690,10 @@ fn binOpRegister(
26992690 .rn = lhs_reg,
27002691 .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none),
27012692 } },
2693 .cmp => .{ .r_op_cmp = .{
2694 .rn = lhs_reg,
2695 .op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none),
2696 } },
27022697 .lsl,
27032698 .asr,
27042699 .lsr,
......@@ -2767,7 +2762,7 @@ fn binOpImmediate(
27672762 defer if (new_lhs_lock) |reg| self.register_manager.unlockReg(reg);
27682763
27692764 const dest_reg = switch (mir_tag) {
2770 .cmp => .r0, // cmp has no destination reg
2765 .cmp => undefined, // cmp has no destination reg
27712766 else => if (metadata) |md| blk: {
27722767 if (lhs_is_register and self.reuseOperand(
27732768 md.inst,
......@@ -2789,7 +2784,6 @@ fn binOpImmediate(
27892784 .adds,
27902785 .sub,
27912786 .subs,
2792 .cmp,
27932787 .@"and",
27942788 .orr,
27952789 .eor,
......@@ -2798,6 +2792,10 @@ fn binOpImmediate(
27982792 .rn = lhs_reg,
27992793 .op = Instruction.Operand.fromU32(rhs.immediate).?,
28002794 } },
2795 .cmp => .{ .r_op_cmp = .{
2796 .rn = lhs_reg,
2797 .op = Instruction.Operand.fromU32(rhs.immediate).?,
2798 } },
28012799 .lsl,
28022800 .asr,
28032801 .lsr,
......@@ -3312,9 +3310,8 @@ fn genInlineMemcpy(
33123310 // mov count, #0
33133311 _ = try self.addInst(.{
33143312 .tag = .mov,
3315 .data = .{ .rr_op = .{
3313 .data = .{ .r_op_mov = .{
33163314 .rd = count,
3317 .rn = .r0,
33183315 .op = Instruction.Operand.imm(0, 0),
33193316 } },
33203317 });
......@@ -3323,8 +3320,7 @@ fn genInlineMemcpy(
33233320 // cmp count, len
33243321 _ = try self.addInst(.{
33253322 .tag = .cmp,
3326 .data = .{ .rr_op = .{
3327 .rd = .r0,
3323 .data = .{ .r_op_cmp = .{
33283324 .rn = count,
33293325 .op = Instruction.Operand.reg(len, Instruction.Operand.Shift.none),
33303326 } },
......@@ -3418,9 +3414,8 @@ fn genInlineMemsetCode(
34183414 // mov count, #0
34193415 _ = try self.addInst(.{
34203416 .tag = .mov,
3421 .data = .{ .rr_op = .{
3417 .data = .{ .r_op_mov = .{
34223418 .rd = count,
3423 .rn = .r0,
34243419 .op = Instruction.Operand.imm(0, 0),
34253420 } },
34263421 });
......@@ -3429,8 +3424,7 @@ fn genInlineMemsetCode(
34293424 // cmp count, len
34303425 _ = try self.addInst(.{
34313426 .tag = .cmp,
3432 .data = .{ .rr_op = .{
3433 .rd = .r0,
3427 .data = .{ .r_op_cmp = .{
34343428 .rn = count,
34353429 .op = Instruction.Operand.reg(len, Instruction.Operand.Shift.none),
34363430 } },
......@@ -4020,9 +4014,7 @@ fn condBr(self: *Self, condition: MCValue) !Mir.Inst.Index {
40204014 // bne ...
40214015 _ = try self.addInst(.{
40224016 .tag = .cmp,
4023 .cond = .al,
4024 .data = .{ .rr_op = .{
4025 .rd = .r0,
4017 .data = .{ .r_op_cmp = .{
40264018 .rn = reg,
40274019 .op = Instruction.Operand.imm(1, 0),
40284020 } },
......@@ -4196,8 +4188,7 @@ fn isNull(self: *Self, ty: Type, operand: MCValue) !MCValue {
41964188
41974189 _ = try self.addInst(.{
41984190 .tag = .cmp,
4199 .data = .{ .rr_op = .{
4200 .rd = undefined,
4191 .data = .{ .r_op_cmp = .{
42014192 .rn = reg_mcv.register,
42024193 .op = Instruction.Operand.fromU32(0).?,
42034194 } },
......@@ -4832,9 +4823,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
48324823 .register_v_flag => .vs,
48334824 else => unreachable,
48344825 },
4835 .data = .{ .rr_op = .{
4826 .data = .{ .r_op_mov = .{
48364827 .rd = cond_reg,
4837 .rn = .r0,
48384828 .op = Instruction.Operand.fromU32(1).?,
48394829 } },
48404830 });
......@@ -4935,9 +4925,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
49354925 // mov reg, 0
49364926 _ = try self.addInst(.{
49374927 .tag = .mov,
4938 .data = .{ .rr_op = .{
4928 .data = .{ .r_op_mov = .{
49394929 .rd = reg,
4940 .rn = .r0,
49414930 .op = zero,
49424931 } },
49434932 });
......@@ -4946,9 +4935,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
49464935 _ = try self.addInst(.{
49474936 .tag = .mov,
49484937 .cond = condition,
4949 .data = .{ .rr_op = .{
4938 .data = .{ .r_op_mov = .{
49504939 .rd = reg,
4951 .rn = .r0,
49524940 .op = one,
49534941 } },
49544942 });
......@@ -4957,18 +4945,16 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
49574945 if (Instruction.Operand.fromU32(x)) |op| {
49584946 _ = try self.addInst(.{
49594947 .tag = .mov,
4960 .data = .{ .rr_op = .{
4948 .data = .{ .r_op_mov = .{
49614949 .rd = reg,
4962 .rn = .r0,
49634950 .op = op,
49644951 } },
49654952 });
49664953 } else if (Instruction.Operand.fromU32(~x)) |op| {
49674954 _ = try self.addInst(.{
49684955 .tag = .mvn,
4969 .data = .{ .rr_op = .{
4956 .data = .{ .r_op_mov = .{
49704957 .rd = reg,
4971 .rn = .r0,
49724958 .op = op,
49734959 } },
49744960 });
......@@ -4984,9 +4970,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
49844970 } else {
49854971 _ = try self.addInst(.{
49864972 .tag = .mov,
4987 .data = .{ .rr_op = .{
4973 .data = .{ .r_op_mov = .{
49884974 .rd = reg,
4989 .rn = .r0,
49904975 .op = Instruction.Operand.imm(@truncate(u8, x), 0),
49914976 } },
49924977 });
......@@ -5028,9 +5013,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
50285013 // orr reg, reg, #0xdd, 8
50295014 _ = try self.addInst(.{
50305015 .tag = .mov,
5031 .data = .{ .rr_op = .{
5016 .data = .{ .r_op_mov = .{
50325017 .rd = reg,
5033 .rn = .r0,
50345018 .op = Instruction.Operand.imm(@truncate(u8, x), 0),
50355019 } },
50365020 });
......@@ -5069,9 +5053,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
50695053 // mov reg, src_reg
50705054 _ = try self.addInst(.{
50715055 .tag = .mov,
5072 .data = .{ .rr_op = .{
5056 .data = .{ .r_op_mov = .{
50735057 .rd = reg,
5074 .rn = .r0,
50755058 .op = Instruction.Operand.reg(src_reg, Instruction.Operand.Shift.none),
50765059 } },
50775060 });
src/arch/arm/Emit.zig+36-12
......@@ -385,20 +385,44 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
385385fn mirDataProcessing(emit: *Emit, inst: Mir.Inst.Index) !void {
386386 const tag = emit.mir.instructions.items(.tag)[inst];
387387 const cond = emit.mir.instructions.items(.cond)[inst];
388 const rr_op = emit.mir.instructions.items(.data)[inst].rr_op;
389388
390389 switch (tag) {
391 .add => try emit.writeInstruction(Instruction.add(cond, rr_op.rd, rr_op.rn, rr_op.op)),
392 .adds => try emit.writeInstruction(Instruction.adds(cond, rr_op.rd, rr_op.rn, rr_op.op)),
393 .@"and" => try emit.writeInstruction(Instruction.@"and"(cond, rr_op.rd, rr_op.rn, rr_op.op)),
394 .cmp => try emit.writeInstruction(Instruction.cmp(cond, rr_op.rn, rr_op.op)),
395 .eor => try emit.writeInstruction(Instruction.eor(cond, rr_op.rd, rr_op.rn, rr_op.op)),
396 .mov => try emit.writeInstruction(Instruction.mov(cond, rr_op.rd, rr_op.op)),
397 .mvn => try emit.writeInstruction(Instruction.mvn(cond, rr_op.rd, rr_op.op)),
398 .orr => try emit.writeInstruction(Instruction.orr(cond, rr_op.rd, rr_op.rn, rr_op.op)),
399 .rsb => try emit.writeInstruction(Instruction.rsb(cond, rr_op.rd, rr_op.rn, rr_op.op)),
400 .sub => try emit.writeInstruction(Instruction.sub(cond, rr_op.rd, rr_op.rn, rr_op.op)),
401 .subs => try emit.writeInstruction(Instruction.subs(cond, rr_op.rd, rr_op.rn, rr_op.op)),
390 .add,
391 .adds,
392 .@"and",
393 .eor,
394 .orr,
395 .rsb,
396 .sub,
397 .subs,
398 => {
399 const rr_op = emit.mir.instructions.items(.data)[inst].rr_op;
400 switch (tag) {
401 .add => try emit.writeInstruction(Instruction.add(cond, rr_op.rd, rr_op.rn, rr_op.op)),
402 .adds => try emit.writeInstruction(Instruction.adds(cond, rr_op.rd, rr_op.rn, rr_op.op)),
403 .@"and" => try emit.writeInstruction(Instruction.@"and"(cond, rr_op.rd, rr_op.rn, rr_op.op)),
404 .eor => try emit.writeInstruction(Instruction.eor(cond, rr_op.rd, rr_op.rn, rr_op.op)),
405 .orr => try emit.writeInstruction(Instruction.orr(cond, rr_op.rd, rr_op.rn, rr_op.op)),
406 .rsb => try emit.writeInstruction(Instruction.rsb(cond, rr_op.rd, rr_op.rn, rr_op.op)),
407 .sub => try emit.writeInstruction(Instruction.sub(cond, rr_op.rd, rr_op.rn, rr_op.op)),
408 .subs => try emit.writeInstruction(Instruction.subs(cond, rr_op.rd, rr_op.rn, rr_op.op)),
409 else => unreachable,
410 }
411 },
412 .cmp => {
413 const r_op_cmp = emit.mir.instructions.items(.data)[inst].r_op_cmp;
414 try emit.writeInstruction(Instruction.cmp(cond, r_op_cmp.rn, r_op_cmp.op));
415 },
416 .mov,
417 .mvn,
418 => {
419 const r_op_mov = emit.mir.instructions.items(.data)[inst].r_op_mov;
420 switch (tag) {
421 .mov => try emit.writeInstruction(Instruction.mov(cond, r_op_mov.rd, r_op_mov.op)),
422 .mvn => try emit.writeInstruction(Instruction.mvn(cond, r_op_mov.rd, r_op_mov.op)),
423 else => unreachable,
424 }
425 },
402426 else => unreachable,
403427 }
404428}
src/arch/arm/Mir.zig+14
......@@ -166,6 +166,20 @@ pub const Inst = struct {
166166 rd: Register,
167167 imm16: u16,
168168 },
169 /// A register and an operand
170 ///
171 /// Used by mov and mvn
172 r_op_mov: struct {
173 rd: Register,
174 op: bits.Instruction.Operand,
175 },
176 /// A register and an operand
177 ///
178 /// Used by cmp
179 r_op_cmp: struct {
180 rn: Register,
181 op: bits.Instruction.Operand,
182 },
169183 /// Two registers and a shift amount
170184 ///
171185 /// Used by e.g. lsl