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