| ... | ... | @@ -453,7 +453,8 @@ pub const Op = enum { |
| 453 | 453 | pub fn bitSize(op: Op) u64 { |
| 454 | 454 | return switch (op) { |
| 455 | 455 | .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable, |
| 456 | | .unity, .imm8, .imm8s, .al, .cl, .r8, .m8, .rm8, .rel8 => 8, |
| 456 | .unity => 1, |
| 457 | .imm8, .imm8s, .al, .cl, .r8, .m8, .rm8, .rel8 => 8, |
| 457 | 458 | .imm16, .imm16s, .ax, .r16, .m16, .rm16, .rel16 => 16, |
| 458 | 459 | .imm32, .imm32s, .eax, .r32, .m32, .rm32, .rel32, .xmm_m32 => 32, |
| 459 | 460 | .imm64, .rax, .r64, .m64, .rm64, .xmm_m64 => 64, |
| ... | ... | @@ -462,6 +463,18 @@ pub const Op = enum { |
| 462 | 463 | }; |
| 463 | 464 | } |
| 464 | 465 | |
| 466 | pub fn isSigned(op: Op) bool { |
| 467 | return switch (op) { |
| 468 | .unity, .imm8, .imm16, .imm32, .imm64 => false, |
| 469 | .imm8s, .imm16s, .imm32s => true, |
| 470 | else => unreachable, |
| 471 | }; |
| 472 | } |
| 473 | |
| 474 | pub fn isUnsigned(op: Op) bool { |
| 475 | return !op.isSigned(); |
| 476 | } |
| 477 | |
| 465 | 478 | pub fn isRegister(op: Op) bool { |
| 466 | 479 | // zig fmt: off |
| 467 | 480 | return switch (op) { |
| ... | ... | @@ -516,8 +529,7 @@ pub const Op = enum { |
| 516 | 529 | }; |
| 517 | 530 | } |
| 518 | 531 | |
| 519 | | /// Given an operand `op` checks if `target` is a subset for the purposes |
| 520 | | /// of the encoding. |
| 532 | /// Given an operand `op` checks if `target` is a subset for the purposes of the encoding. |
| 521 | 533 | pub fn isSubset(op: Op, target: Op, mode: Mode) bool { |
| 522 | 534 | switch (op) { |
| 523 | 535 | .m, .o16, .o32, .o64 => unreachable, |
| ... | ... | @@ -544,36 +556,19 @@ pub const Op = enum { |
| 544 | 556 | } |
| 545 | 557 | if (op.isImmediate() and target.isImmediate()) { |
| 546 | 558 | switch (target) { |
| 547 | | .imm64 => switch (op) { |
| 548 | | .unity, .imm8s, .imm8, .imm16s, .imm16, .imm32s, .imm32, .imm64 => return true, |
| 549 | | else => return op == target, |
| 550 | | }, |
| 551 | | .imm32s, .rel32 => switch (op) { |
| 552 | | .unity, .imm8s, .imm8, .imm16s, .imm16, .imm32s => return true, |
| 553 | | else => return op == target, |
| 554 | | }, |
| 555 | | .imm32 => switch (op) { |
| 556 | | .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s => return true, |
| 557 | | else => return op == target, |
| 558 | | }, |
| 559 | | .imm16s, .rel16 => switch (op) { |
| 560 | | .unity, .imm8s, .imm8, .imm16s => return true, |
| 561 | | else => return op == target, |
| 562 | | }, |
| 563 | | .imm16 => switch (op) { |
| 564 | | .unity, .imm8, .imm8s, .imm16, .imm16s => return true, |
| 565 | | else => return op == target, |
| 566 | | }, |
| 567 | | .imm8s, .rel8 => switch (op) { |
| 568 | | .unity, .imm8s => return true, |
| 569 | | else => return op == target, |
| 570 | | }, |
| 571 | | .imm8 => switch (op) { |
| 572 | | .unity, .imm8, .imm8s => return true, |
| 573 | | else => return op == target, |
| 574 | | }, |
| 575 | | else => return op == target, |
| 559 | .imm64 => if (op.bitSize() <= 64) return true, |
| 560 | .imm32s, .rel32 => if (op.bitSize() < 32 or (op.bitSize() == 32 and op.isSigned())) |
| 561 | return true, |
| 562 | .imm32 => if (op.bitSize() <= 32) return true, |
| 563 | .imm16s, .rel16 => if (op.bitSize() < 16 or (op.bitSize() == 16 and op.isSigned())) |
| 564 | return true, |
| 565 | .imm16 => if (op.bitSize() <= 16) return true, |
| 566 | .imm8s, .rel8 => if (op.bitSize() < 8 or (op.bitSize() == 8 and op.isSigned())) |
| 567 | return true, |
| 568 | .imm8 => if (op.bitSize() <= 8) return true, |
| 569 | else => {}, |
| 576 | 570 | } |
| 571 | return op == target; |
| 577 | 572 | } |
| 578 | 573 | return false; |
| 579 | 574 | }, |