| author | |
| committer | |
| log | 71c5eebd32d44ca01fedcb48674c5e7185f10289 |
| tree | 2f58bd79d159f7c8952af53fe68e78e17e312003 |
| parent | 4a40c0a80c8f7014097f3ac6f523c7e21cda80a9 |
* variant `0b11` when both `reg1 != .none` and `reg2 != .none` is
identical to `0b00` therefore it can safely be removed
* fix proper destination register size calculation when setting register from
another source register3 files changed, 3 insertions(+), 14 deletions(-)
src/arch/x86_64/CodeGen.zig+1-2| ... | @@ -2968,9 +2968,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -2968,9 +2968,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 2968 | _ = try self.addInst(.{ | 2968 | _ = try self.addInst(.{ |
| 2969 | .tag = .mov, | 2969 | .tag = .mov, |
| 2970 | .ops = (Mir.Ops{ | 2970 | .ops = (Mir.Ops{ |
| 2971 | .reg1 = reg, | 2971 | .reg1 = registerAlias(reg, @divExact(src_reg.size(), 8)), |
| 2972 | .reg2 = src_reg, | 2972 | .reg2 = src_reg, |
| 2973 | .flags = 0b11, | ||
| 2974 | }).encode(), | 2973 | }).encode(), |
| 2975 | .data = undefined, | 2974 | .data = undefined, |
| 2976 | }); | 2975 | }); |
src/arch/x86_64/Emit.zig+1-11| ... | @@ -1119,17 +1119,7 @@ fn mirMovImpl( | ... | @@ -1119,17 +1119,7 @@ fn mirMovImpl( |
| 1119 | encoder.imm32(imm_op); | 1119 | encoder.imm32(imm_op); |
| 1120 | break :blk; | 1120 | break :blk; |
| 1121 | } | 1121 | } |
| 1122 | // mov reg1, reg2 | 1122 | return EmitResult.err(allocator, src_loc, "TODO unused variant: mov reg1, reg2, 0b11", .{}); |
| 1123 | // RM | ||
| 1124 | const opc: u8 = if (ops.reg1.size() == 8) 0x8a else 0x8b; | ||
| 1125 | const encoder = try Encoder.init(code, 3); | ||
| 1126 | encoder.rex(.{ | ||
| 1127 | .w = ops.reg1.size() == 64 and ops.reg2.size() == 64, | ||
| 1128 | .r = ops.reg1.isExtended(), | ||
| 1129 | .b = ops.reg2.isExtended(), | ||
| 1130 | }); | ||
| 1131 | encoder.opcode_1byte(opc); | ||
| 1132 | encoder.modRm_direct(ops.reg1.lowId(), ops.reg2.lowId()); | ||
| 1133 | }, | 1123 | }, |
| 1134 | } | 1124 | } |
| 1135 | return EmitResult.ok(); | 1125 | return EmitResult.ok(); |
src/arch/x86_64/Mir.zig+1-1| ... | @@ -145,7 +145,7 @@ pub const Inst = struct { | ... | @@ -145,7 +145,7 @@ pub const Inst = struct { |
| 145 | /// 0b10 [reg1 + imm32], reg2 | 145 | /// 0b10 [reg1 + imm32], reg2 |
| 146 | /// 0b10 [reg1 + 0], imm32 | 146 | /// 0b10 [reg1 + 0], imm32 |
| 147 | /// 0b11 [reg1 + imm32], imm32 | 147 | /// 0b11 [reg1 + imm32], imm32 |
| 148 | /// 0b11 reg1, reg2 (RM) | 148 | /// 0b11 AVAILABLE |
| 149 | /// Notes: | 149 | /// Notes: |
| 150 | /// * If reg2 is `none` then it means Data field `imm` is used as the immediate. | 150 | /// * If reg2 is `none` then it means Data field `imm` is used as the immediate. |
| 151 | /// * When two imm32 values are required, Data field `payload` points at `ImmPair`. | 151 | /// * When two imm32 values are required, Data field `payload` points at `ImmPair`. |