| author | |
| committer | |
| log | 7221cd8ec90b5f206cf0b2979ba165719e5a2f23 |
| tree | 5bedc30933986fb1e8216769657a4068c1b75e28 |
| parent | f61a70e812b0301f4e54e38ff4ce2b041f395e8d |
3 files changed, 94 insertions(+), 165 deletions(-)
src/arch/x86_64/CodeGen.zig+31-60| ... | @@ -400,6 +400,29 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { | ... | @@ -400,6 +400,29 @@ fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 400 | return result; | 400 | return result; |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | fn asmSetCCRegister(self: *Self, reg: Register, cc: bits.Condition) !void { | ||
| 404 | _ = try self.addInst(.{ | ||
| 405 | .tag = .setcc, | ||
| 406 | .ops = .r_c, | ||
| 407 | .data = .{ .r_c = .{ | ||
| 408 | .r1 = reg, | ||
| 409 | .cc = cc, | ||
| 410 | } }, | ||
| 411 | }); | ||
| 412 | } | ||
| 413 | |||
| 414 | fn asmCmovCCRegisterRegister(self: *Self, reg1: Register, reg2: Register, cc: bits.Condition) !void { | ||
| 415 | _ = try self.addInst(.{ | ||
| 416 | .tag = .cmovcc, | ||
| 417 | .ops = .rr_c, | ||
| 418 | .data = .{ .rr_c = .{ | ||
| 419 | .r1 = reg1, | ||
| 420 | .r2 = reg2, | ||
| 421 | .cc = cc, | ||
| 422 | } }, | ||
| 423 | }); | ||
| 424 | } | ||
| 425 | |||
| 403 | fn asmNone(self: *Self, tag: Mir.Inst.Tag) !void { | 426 | fn asmNone(self: *Self, tag: Mir.Inst.Tag) !void { |
| 404 | _ = try self.addInst(.{ | 427 | _ = try self.addInst(.{ |
| 405 | .tag = tag, | 428 | .tag = tag, |
| ... | @@ -1346,15 +1369,7 @@ fn airMin(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1346,15 +1369,7 @@ fn airMin(self: *Self, inst: Air.Inst.Index) !void { |
| 1346 | .unsigned => .b, | 1369 | .unsigned => .b, |
| 1347 | .signed => .l, | 1370 | .signed => .l, |
| 1348 | }; | 1371 | }; |
| 1349 | _ = cc; | 1372 | try self.asmCmovCCRegisterRegister(dst_mcv.register, lhs_reg, cc); |
| 1350 | // _ = try self.addInst(.{ | ||
| 1351 | // .tag = .cond_mov, | ||
| 1352 | // .ops = Mir.Inst.Ops.encode(.{ | ||
| 1353 | // .reg1 = dst_mcv.register, | ||
| 1354 | // .reg2 = lhs_reg, | ||
| 1355 | // }), | ||
| 1356 | // .data = .{ .cc = cc }, | ||
| 1357 | // }); | ||
| 1358 | 1373 | ||
| 1359 | break :result dst_mcv; | 1374 | break :result dst_mcv; |
| 1360 | }; | 1375 | }; |
| ... | @@ -1554,14 +1569,7 @@ fn genSetStackTruncatedOverflowCompare( | ... | @@ -1554,14 +1569,7 @@ fn genSetStackTruncatedOverflowCompare( |
| 1554 | .signed => .o, | 1569 | .signed => .o, |
| 1555 | .unsigned => .c, | 1570 | .unsigned => .c, |
| 1556 | }; | 1571 | }; |
| 1557 | _ = cc; | 1572 | try self.asmSetCCRegister(overflow_reg.to8(), cc); |
| 1558 | // _ = try self.addInst(.{ | ||
| 1559 | // .tag = .cond_set_byte, | ||
| 1560 | // .ops = Mir.Inst.Ops.encode(.{ | ||
| 1561 | // .reg1 = overflow_reg.to8(), | ||
| 1562 | // }), | ||
| 1563 | // .data = .{ .cc = cc }, | ||
| 1564 | // }); | ||
| 1565 | 1573 | ||
| 1566 | const scratch_reg = temp_regs[1]; | 1574 | const scratch_reg = temp_regs[1]; |
| 1567 | try self.genSetReg(extended_ty, scratch_reg, .{ .register = reg }); | 1575 | try self.genSetReg(extended_ty, scratch_reg, .{ .register = reg }); |
| ... | @@ -1574,12 +1582,7 @@ fn genSetStackTruncatedOverflowCompare( | ... | @@ -1574,12 +1582,7 @@ fn genSetStackTruncatedOverflowCompare( |
| 1574 | ); | 1582 | ); |
| 1575 | 1583 | ||
| 1576 | const eq_reg = temp_regs[2]; | 1584 | const eq_reg = temp_regs[2]; |
| 1577 | // _ = try self.addInst(.{ | 1585 | try self.asmSetCCRegister(eq_reg.to8(), .ne); |
| 1578 | // .tag = .cond_set_byte, | ||
| 1579 | // .ops = Mir.Inst.Ops.encode(.{ .reg1 = eq_reg.to8() }), | ||
| 1580 | // .data = .{ .cc = .ne }, | ||
| 1581 | // }); | ||
| 1582 | |||
| 1583 | try self.genBinOpMir( | 1586 | try self.genBinOpMir( |
| 1584 | .@"or", | 1587 | .@"or", |
| 1585 | Type.u8, | 1588 | Type.u8, |
| ... | @@ -1829,14 +1832,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa | ... | @@ -1829,14 +1832,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa |
| 1829 | // }), | 1832 | // }), |
| 1830 | // .data = undefined, | 1833 | // .data = undefined, |
| 1831 | // }); | 1834 | // }); |
| 1832 | // _ = try self.addInst(.{ | 1835 | try self.asmCmovCCRegisterRegister(divisor.to64(), .rdx, .e); |
| 1833 | // .tag = .cond_mov, | ||
| 1834 | // .ops = Mir.Inst.Ops.encode(.{ | ||
| 1835 | // .reg1 = divisor.to64(), | ||
| 1836 | // .reg2 = .rdx, | ||
| 1837 | // }), | ||
| 1838 | // .data = .{ .cc = .e }, | ||
| 1839 | // }); | ||
| 1840 | try self.genBinOpMir(.add, Type.isize, .{ .register = divisor }, .{ .register = .rax }); | 1836 | try self.genBinOpMir(.add, Type.isize, .{ .register = divisor }, .{ .register = .rax }); |
| 1841 | return MCValue{ .register = divisor }; | 1837 | return MCValue{ .register = divisor }; |
| 1842 | } | 1838 | } |
| ... | @@ -2881,13 +2877,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2881,13 +2877,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2881 | const overflow_bit_ty = value_ty.structFieldType(1); | 2877 | const overflow_bit_ty = value_ty.structFieldType(1); |
| 2882 | const overflow_bit_offset = value_ty.structFieldOffset(1, self.target.*); | 2878 | const overflow_bit_offset = value_ty.structFieldOffset(1, self.target.*); |
| 2883 | const tmp_reg = try self.register_manager.allocReg(null, gp); | 2879 | const tmp_reg = try self.register_manager.allocReg(null, gp); |
| 2884 | // _ = try self.addInst(.{ | 2880 | try self.asmSetCCRegister(tmp_reg.to8(), ro.eflags); |
| 2885 | // .tag = .cond_set_byte, | ||
| 2886 | // .ops = Mir.Inst.Ops.encode(.{ | ||
| 2887 | // .reg1 = tmp_reg.to8(), | ||
| 2888 | // }), | ||
| 2889 | // .data = .{ .cc = ro.eflags }, | ||
| 2890 | // }); | ||
| 2891 | try self.genInlineMemcpyRegisterRegister( | 2881 | try self.genInlineMemcpyRegisterRegister( |
| 2892 | overflow_bit_ty, | 2882 | overflow_bit_ty, |
| 2893 | reg, | 2883 | reg, |
| ... | @@ -3185,13 +3175,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3185,13 +3175,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3185 | defer self.register_manager.unlockReg(reg_lock); | 3175 | defer self.register_manager.unlockReg(reg_lock); |
| 3186 | 3176 | ||
| 3187 | const dst_reg = try self.register_manager.allocReg(inst, gp); | 3177 | const dst_reg = try self.register_manager.allocReg(inst, gp); |
| 3188 | // _ = try self.addInst(.{ | 3178 | try self.asmSetCCRegister(dst_reg.to8(), ro.eflags); |
| 3189 | // .tag = .cond_set_byte, | ||
| 3190 | // .ops = Mir.Inst.Ops.encode(.{ | ||
| 3191 | // .reg1 = dst_reg.to8(), | ||
| 3192 | // }), | ||
| 3193 | // .data = .{ .cc = ro.eflags }, | ||
| 3194 | // }); | ||
| 3195 | break :result MCValue{ .register = dst_reg.to8() }; | 3179 | break :result MCValue{ .register = dst_reg.to8() }; |
| 3196 | }, | 3180 | }, |
| 3197 | else => unreachable, | 3181 | else => unreachable, |
| ... | @@ -5577,13 +5561,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -5577,13 +5561,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5577 | const overflow_bit_ty = ty.structFieldType(1); | 5561 | const overflow_bit_ty = ty.structFieldType(1); |
| 5578 | const overflow_bit_offset = ty.structFieldOffset(1, self.target.*); | 5562 | const overflow_bit_offset = ty.structFieldOffset(1, self.target.*); |
| 5579 | const tmp_reg = try self.register_manager.allocReg(null, gp); | 5563 | const tmp_reg = try self.register_manager.allocReg(null, gp); |
| 5580 | // _ = try self.addInst(.{ | 5564 | try self.asmSetCCRegister(tmp_reg.to8(), ro.eflags); |
| 5581 | // .tag = .cond_set_byte, | ||
| 5582 | // .ops = Mir.Inst.Ops.encode(.{ | ||
| 5583 | // .reg1 = tmp_reg.to8(), | ||
| 5584 | // }), | ||
| 5585 | // .data = .{ .cc = ro.eflags }, | ||
| 5586 | // }); | ||
| 5587 | 5565 | ||
| 5588 | return self.genSetStack( | 5566 | return self.genSetStack( |
| 5589 | overflow_bit_ty, | 5567 | overflow_bit_ty, |
| ... | @@ -6114,14 +6092,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -6114,14 +6092,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6114 | } | 6092 | } |
| 6115 | }, | 6093 | }, |
| 6116 | .eflags => |cc| { | 6094 | .eflags => |cc| { |
| 6117 | _ = cc; | 6095 | return self.asmSetCCRegister(reg.to8(), cc); |
| 6118 | // _ = try self.addInst(.{ | ||
| 6119 | // .tag = .cond_set_byte, | ||
| 6120 | // .ops = Mir.Inst.Ops.encode(.{ | ||
| 6121 | // .reg1 = reg.to8(), | ||
| 6122 | // }), | ||
| 6123 | // .data = .{ .cc = cc }, | ||
| 6124 | // }); | ||
| 6125 | }, | 6096 | }, |
| 6126 | .immediate => |x| { | 6097 | .immediate => |x| { |
| 6127 | if (x == 0) { | 6098 | if (x == 0) { |
src/arch/x86_64/Emit.zig+43-103| ... | @@ -118,6 +118,9 @@ pub fn lowerMir(emit: *Emit) InnerError!void { | ... | @@ -118,6 +118,9 @@ pub fn lowerMir(emit: *Emit) InnerError!void { |
| 118 | => try emit.mirEncodeGeneric(tag, inst), | 118 | => try emit.mirEncodeGeneric(tag, inst), |
| 119 | 119 | ||
| 120 | // Pseudo-instructions | 120 | // Pseudo-instructions |
| 121 | .cmovcc => try emit.mirCmovCC(inst), | ||
| 122 | .setcc => try emit.mirSetCC(inst), | ||
| 123 | |||
| 121 | .dbg_line => try emit.mirDbgLine(inst), | 124 | .dbg_line => try emit.mirDbgLine(inst), |
| 122 | .dbg_prologue_end => try emit.mirDbgPrologueEnd(inst), | 125 | .dbg_prologue_end => try emit.mirDbgPrologueEnd(inst), |
| 123 | .dbg_epilogue_begin => try emit.mirDbgEpilogueBegin(inst), | 126 | .dbg_epilogue_begin => try emit.mirDbgEpilogueBegin(inst), |
| ... | @@ -200,9 +203,11 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE | ... | @@ -200,9 +203,11 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE |
| 200 | .{ .imm = Immediate.u(data.ri_u.imm) }, | 203 | .{ .imm = Immediate.u(data.ri_u.imm) }, |
| 201 | }, | 204 | }, |
| 202 | .ri64 => { | 205 | .ri64 => { |
| 203 | operands[0] = .{ .reg = data.rx.r1 }; | ||
| 204 | const imm64 = emit.mir.extraData(Mir.Imm64, data.rx.payload).data; | 206 | const imm64 = emit.mir.extraData(Mir.Imm64, data.rx.payload).data; |
| 205 | operands[1] = .{ .imm = Immediate.u(Mir.Imm64.decode(imm64)) }; | 207 | operands[0..2].* = .{ |
| 208 | .{ .reg = data.rx.r1 }, | ||
| 209 | .{ .imm = Immediate.u(Mir.Imm64.decode(imm64)) }, | ||
| 210 | }; | ||
| 206 | }, | 211 | }, |
| 207 | else => unreachable, | 212 | else => unreachable, |
| 208 | } | 213 | } |
| ... | @@ -215,6 +220,42 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE | ... | @@ -215,6 +220,42 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE |
| 215 | }); | 220 | }); |
| 216 | } | 221 | } |
| 217 | 222 | ||
| 223 | fn mnemonicFromCC(comptime basename: []const u8, cc: bits.Condition) Instruction.Mnemonic { | ||
| 224 | inline for (@typeInfo(bits.Condition).Enum.fields) |field| { | ||
| 225 | if (mem.eql(u8, field.name, @tagName(cc))) | ||
| 226 | return @field(Instruction.Mnemonic, basename ++ field.name); | ||
| 227 | } else unreachable; | ||
| 228 | } | ||
| 229 | |||
| 230 | fn mirCmovCC(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { | ||
| 231 | const ops = emit.mir.instructions.items(.ops)[inst]; | ||
| 232 | switch (ops) { | ||
| 233 | .rr_c => { | ||
| 234 | const data = emit.mir.instructions.items(.data)[inst].rr_c; | ||
| 235 | const mnemonic = mnemonicFromCC("cmov", data.cc); | ||
| 236 | return emit.encode(mnemonic, .{ | ||
| 237 | .op1 = .{ .reg = data.r1 }, | ||
| 238 | .op2 = .{ .reg = data.r2 }, | ||
| 239 | }); | ||
| 240 | }, | ||
| 241 | else => unreachable, // TODO | ||
| 242 | } | ||
| 243 | } | ||
| 244 | |||
| 245 | fn mirSetCC(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { | ||
| 246 | const ops = emit.mir.instructions.items(.ops)[inst]; | ||
| 247 | switch (ops) { | ||
| 248 | .r_c => { | ||
| 249 | const data = emit.mir.instructions.items(.data)[inst].r_c; | ||
| 250 | const mnemonic = mnemonicFromCC("set", data.cc); | ||
| 251 | return emit.encode(mnemonic, .{ | ||
| 252 | .op1 = .{ .reg = data.r1 }, | ||
| 253 | }); | ||
| 254 | }, | ||
| 255 | else => unreachable, // TODO | ||
| 256 | } | ||
| 257 | } | ||
| 258 | |||
| 218 | fn mirPushPopRegisterList(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void { | 259 | fn mirPushPopRegisterList(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void { |
| 219 | const payload = emit.mir.instructions.items(.data)[inst].payload; | 260 | const payload = emit.mir.instructions.items(.data)[inst].payload; |
| 220 | const save_reg_list = emit.mir.extraData(Mir.SaveRegisterList, payload).data; | 261 | const save_reg_list = emit.mir.extraData(Mir.SaveRegisterList, payload).data; |
| ... | @@ -333,107 +374,6 @@ fn mirPushPopRegisterList(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) | ... | @@ -333,107 +374,6 @@ fn mirPushPopRegisterList(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) |
| 333 | // }); | 374 | // }); |
| 334 | // } | 375 | // } |
| 335 | 376 | ||
| 336 | // fn mirCondSetByte(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { | ||
| 337 | // const tag = emit.mir.instructions.items(.tag)[inst]; | ||
| 338 | // assert(tag == .cond_set_byte); | ||
| 339 | // const ops = emit.mir.instructions.items(.ops)[inst].decode(); | ||
| 340 | // const cc = emit.mir.instructions.items(.data)[inst].cc; | ||
| 341 | // const mnemonic: Instruction.Mnemonic = switch (cc) { | ||
| 342 | // .a => .seta, | ||
| 343 | // .ae => .setae, | ||
| 344 | // .b => .setb, | ||
| 345 | // .be => .setbe, | ||
| 346 | // .c => .setc, | ||
| 347 | // .e => .sete, | ||
| 348 | // .g => .setg, | ||
| 349 | // .ge => .setge, | ||
| 350 | // .l => .setl, | ||
| 351 | // .le => .setle, | ||
| 352 | // .na => .setna, | ||
| 353 | // .nae => .setnae, | ||
| 354 | // .nb => .setnb, | ||
| 355 | // .nbe => .setnbe, | ||
| 356 | // .nc => .setnc, | ||
| 357 | // .ne => .setne, | ||
| 358 | // .ng => .setng, | ||
| 359 | // .nge => .setnge, | ||
| 360 | // .nl => .setnl, | ||
| 361 | // .nle => .setnle, | ||
| 362 | // .no => .setno, | ||
| 363 | // .np => .setnp, | ||
| 364 | // .ns => .setns, | ||
| 365 | // .nz => .setnz, | ||
| 366 | // .o => .seto, | ||
| 367 | // .p => .setp, | ||
| 368 | // .pe => .setpe, | ||
| 369 | // .po => .setpo, | ||
| 370 | // .s => .sets, | ||
| 371 | // .z => .setz, | ||
| 372 | // }; | ||
| 373 | // return emit.encode(mnemonic, .{ .op1 = .{ .reg = ops.reg1 } }); | ||
| 374 | // } | ||
| 375 | |||
| 376 | // fn mirCondMov(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { | ||
| 377 | // const tag = emit.mir.instructions.items(.tag)[inst]; | ||
| 378 | // assert(tag == .cond_mov); | ||
| 379 | // const ops = emit.mir.instructions.items(.ops)[inst].decode(); | ||
| 380 | // const cc = emit.mir.instructions.items(.data)[inst].cc; | ||
| 381 | // const mnemonic: Instruction.Mnemonic = switch (cc) { | ||
| 382 | // .a => .cmova, | ||
| 383 | // .ae => .cmovae, | ||
| 384 | // .b => .cmovb, | ||
| 385 | // .be => .cmovbe, | ||
| 386 | // .c => .cmovc, | ||
| 387 | // .e => .cmove, | ||
| 388 | // .g => .cmovg, | ||
| 389 | // .ge => .cmovge, | ||
| 390 | // .l => .cmovl, | ||
| 391 | // .le => .cmovle, | ||
| 392 | // .na => .cmovna, | ||
| 393 | // .nae => .cmovnae, | ||
| 394 | // .nb => .cmovnb, | ||
| 395 | // .nbe => .cmovnbe, | ||
| 396 | // .nc => .cmovnc, | ||
| 397 | // .ne => .cmovne, | ||
| 398 | // .ng => .cmovng, | ||
| 399 | // .nge => .cmovnge, | ||
| 400 | // .nl => .cmovnl, | ||
| 401 | // .nle => .cmovnle, | ||
| 402 | // .no => .cmovno, | ||
| 403 | // .np => .cmovnp, | ||
| 404 | // .ns => .cmovns, | ||
| 405 | // .nz => .cmovnz, | ||
| 406 | // .o => .cmovo, | ||
| 407 | // .p => .cmovp, | ||
| 408 | // .pe => .cmovpe, | ||
| 409 | // .po => .cmovpo, | ||
| 410 | // .s => .cmovs, | ||
| 411 | // .z => .cmovz, | ||
| 412 | // }; | ||
| 413 | // const op1: Instruction.Operand = .{ .reg = ops.reg1 }; | ||
| 414 | |||
| 415 | // if (ops.flags == 0b00) { | ||
| 416 | // return emit.encode(mnemonic, .{ | ||
| 417 | // .op1 = op1, | ||
| 418 | // .op2 = .{ .reg = ops.reg2 }, | ||
| 419 | // }); | ||
| 420 | // } | ||
| 421 | // const disp = emit.mir.instructions.items(.data)[inst].disp; | ||
| 422 | // const ptr_size: Memory.PtrSize = switch (ops.flags) { | ||
| 423 | // 0b00 => unreachable, | ||
| 424 | // 0b01 => .word, | ||
| 425 | // 0b10 => .dword, | ||
| 426 | // 0b11 => .qword, | ||
| 427 | // }; | ||
| 428 | // return emit.encode(mnemonic, .{ | ||
| 429 | // .op1 = op1, | ||
| 430 | // .op2 = .{ .mem = Memory.sib(ptr_size, .{ | ||
| 431 | // .base = ops.reg2, | ||
| 432 | // .disp = disp, | ||
| 433 | // }) }, | ||
| 434 | // }); | ||
| 435 | // } | ||
| 436 | |||
| 437 | // fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { | 377 | // fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| 438 | // const tag = emit.mir.instructions.items(.tag)[inst]; | 378 | // const tag = emit.mir.instructions.items(.tag)[inst]; |
| 439 | // assert(tag == .lea); | 379 | // assert(tag == .lea); |
src/arch/x86_64/Mir.zig+20-2| ... | @@ -56,8 +56,6 @@ pub const Inst = struct { | ... | @@ -56,8 +56,6 @@ pub const Inst = struct { |
| 56 | cqo, | 56 | cqo, |
| 57 | /// Logical compare | 57 | /// Logical compare |
| 58 | cmp, | 58 | cmp, |
| 59 | /// Conditional move | ||
| 60 | cmovcc, | ||
| 61 | /// Unsigned division | 59 | /// Unsigned division |
| 62 | div, | 60 | div, |
| 63 | /// Store integer with truncation | 61 | /// Store integer with truncation |
| ... | @@ -134,6 +132,9 @@ pub const Inst = struct { | ... | @@ -134,6 +132,9 @@ pub const Inst = struct { |
| 134 | /// Unordered compare scalar double-precision floating-point values | 132 | /// Unordered compare scalar double-precision floating-point values |
| 135 | ucomisd, | 133 | ucomisd, |
| 136 | 134 | ||
| 135 | /// Conditional move | ||
| 136 | cmovcc, | ||
| 137 | |||
| 137 | /// End of prologue | 138 | /// End of prologue |
| 138 | dbg_prologue_end, | 139 | dbg_prologue_end, |
| 139 | /// Start of epilogue | 140 | /// Start of epilogue |
| ... | @@ -161,6 +162,12 @@ pub const Inst = struct { | ... | @@ -161,6 +162,12 @@ pub const Inst = struct { |
| 161 | /// Register, register, register operands. | 162 | /// Register, register, register operands. |
| 162 | /// Uses `rrr` payload. | 163 | /// Uses `rrr` payload. |
| 163 | rrr, | 164 | rrr, |
| 165 | /// Register with condition code (CC). | ||
| 166 | /// Uses `r_c` payload. | ||
| 167 | r_c, | ||
| 168 | /// Register, register with condition code (CC). | ||
| 169 | /// Uses `rr_c` payload. | ||
| 170 | rr_c, | ||
| 164 | /// Register, immediate (sign-extended) operands. | 171 | /// Register, immediate (sign-extended) operands. |
| 165 | /// Uses `ri_s` payload. | 172 | /// Uses `ri_s` payload. |
| 166 | ri_s, | 173 | ri_s, |
| ... | @@ -241,6 +248,17 @@ pub const Inst = struct { | ... | @@ -241,6 +248,17 @@ pub const Inst = struct { |
| 241 | r2: Register, | 248 | r2: Register, |
| 242 | r3: Register, | 249 | r3: Register, |
| 243 | }, | 250 | }, |
| 251 | /// Register with condition code (CC). | ||
| 252 | r_c: struct { | ||
| 253 | r1: Register, | ||
| 254 | cc: bits.Condition, | ||
| 255 | }, | ||
| 256 | /// Register, register with condition code (CC). | ||
| 257 | rr_c: struct { | ||
| 258 | r1: Register, | ||
| 259 | r2: Register, | ||
| 260 | cc: bits.Condition, | ||
| 261 | }, | ||
| 244 | /// Register, signed immediate. | 262 | /// Register, signed immediate. |
| 245 | ri_s: struct { | 263 | ri_s: struct { |
| 246 | r1: Register, | 264 | r1: Register, |