@@ -206,19 +206,22 @@ pub const Instruction = struct {
206
206
};
207
207
}
208
208
209
- pub fn isBaseExtended (op : Operand ) bool {
209
+ pub fn baseExtEnc (op : Operand ) u2 {
210
210
return switch (op ) {
211
- .none , .imm = > false ,
212
- .reg = > | reg | reg .isExtended (),
213
- .mem = > | mem | mem .base ().isExtended (),
211
+ .none , .imm = > 0b00 ,
212
+ .reg = > | reg | @truncate (reg .enc () >> 3 ),
213
+ .mem = > | mem | switch (mem .base ()) {
214
+ .none , .frame , .table , .reloc , .rip_inst = > 0b00 , // rsp, rbp, and rip are not extended
215
+ .reg = > | reg | @truncate (reg .enc () >> 3 ),
216
+ },
214
217
.bytes = > unreachable ,
215
218
};
216
219
}
217
220
218
- pub fn isIndexExtended (op : Operand ) bool {
221
+ pub fn indexExtEnc (op : Operand ) u2 {
219
222
return switch (op ) {
220
- .none , .reg , .imm = > false ,
221
- .mem = > | mem | if (mem .scaleIndex ()) | si | si .index .isExtended () else false ,
223
+ .none , .reg , .imm = > 0b00 ,
224
+ .mem = > | mem | if (mem .scaleIndex ()) | si | @truncate ( si .index .enc () >> 3 ) else 0b00 ,
222
225
.bytes = > unreachable ,
223
226
};
224
227
}
@@ -422,14 +425,14 @@ pub const Instruction = struct {
422
425
};
423
426
switch (mem_op ) {
424
427
.reg = > | reg | {
425
- const rm = switch (data .op_en ) {
428
+ const rm : u3 = switch (data .op_en ) {
426
429
.ia , .m , .mi , .m1 , .mc , .vm , .vmi = > enc .modRmExt (),
427
- .mr , .mri , .mrc = > inst .ops [1 ].reg .lowEnc ( ),
428
- .rm , .rmi , .rm0 , .rvm , .rvmr , .rvmi , .rmv = > inst .ops [0 ].reg .lowEnc ( ),
429
- .mvr = > inst .ops [2 ].reg .lowEnc ( ),
430
+ .mr , .mri , .mrc = > @truncate ( inst .ops [1 ].reg .enc () ),
431
+ .rm , .rmi , .rm0 , .rvm , .rvmr , .rvmi , .rmv = > @truncate ( inst .ops [0 ].reg .enc () ),
432
+ .mvr = > @truncate ( inst .ops [2 ].reg .enc () ),
430
433
else = > unreachable ,
431
434
};
432
- try encoder .modRm_direct (rm , reg .lowEnc ( ));
435
+ try encoder .modRm_direct (rm , @truncate ( reg .enc () ));
433
436
},
434
437
.mem = > | mem | {
435
438
const op = switch (data .op_en ) {
@@ -448,7 +451,7 @@ pub const Instruction = struct {
448
451
.ia = > try encodeImm (inst .ops [0 ].imm , data .ops [0 ], encoder ),
449
452
.mi = > try encodeImm (inst .ops [1 ].imm , data .ops [1 ], encoder ),
450
453
.rmi , .mri , .vmi = > try encodeImm (inst .ops [2 ].imm , data .ops [2 ], encoder ),
451
- .rvmr = > try encoder .imm8 (@as (u8 , inst .ops [3 ].reg .enc ()) << 4 ),
454
+ .rvmr = > try encoder .imm8 (@as (u8 , @as ( u4 , @intCast ( inst .ops [3 ].reg .enc ()) )) << 4 ),
452
455
.rvmi = > try encodeImm (inst .ops [3 ].imm , data .ops [3 ], encoder ),
453
456
else = > {},
454
457
}
@@ -462,8 +465,8 @@ pub const Instruction = struct {
462
465
const final = opcode .len - 1 ;
463
466
for (opcode [first .. final ]) | byte | try encoder .opcode_1byte (byte );
464
467
switch (inst .encoding .data .op_en ) {
465
- .o , .oz , .oi = > try encoder .opcode_withReg (opcode [final ], inst .ops [0 ].reg .lowEnc ( )),
466
- .zo = > try encoder .opcode_withReg (opcode [final ], inst .ops [1 ].reg .lowEnc ( )),
468
+ .o , .oz , .oi = > try encoder .opcode_withReg (opcode [final ], @truncate ( inst .ops [0 ].reg .enc () )),
469
+ .zo = > try encoder .opcode_withReg (opcode [final ], @truncate ( inst .ops [1 ].reg .enc () )),
467
470
else = > try encoder .opcode_1byte (opcode [final ]),
468
471
}
469
472
}
@@ -533,23 +536,29 @@ pub const Instruction = struct {
533
536
534
537
switch (op_en ) {
535
538
.z , .i , .zi , .ii , .ia , .fd , .td , .d = > {},
536
- .o , .oz , .oi = > rex .b = inst .ops [0 ].reg .isExtended () ,
537
- .zo = > rex .b = inst .ops [1 ].reg .isExtended () ,
539
+ .o , .oz , .oi = > rex .b = inst .ops [0 ].reg .enc () & 0b01000 != 0 ,
540
+ .zo = > rex .b = inst .ops [1 ].reg .enc () & 0b01000 != 0 ,
538
541
.m , .mi , .m1 , .mc , .mr , .rm , .rmi , .mri , .mrc , .rm0 , .rmv = > {
539
542
const r_op = switch (op_en ) {
540
543
.rm , .rmi , .rm0 , .rmv = > inst .ops [0 ],
541
544
.mr , .mri , .mrc = > inst .ops [1 ],
542
545
else = > .none ,
543
546
};
544
- rex .r = r_op .isBaseExtended ();
547
+ const r_op_base_ext_enc = r_op .baseExtEnc ();
548
+ rex .r = r_op_base_ext_enc & 0b01 != 0 ;
549
+ assert (r_op_base_ext_enc & 0b10 == 0 );
545
550
546
551
const b_x_op = switch (op_en ) {
547
552
.rm , .rmi , .rm0 = > inst .ops [1 ],
548
553
.m , .mi , .m1 , .mc , .mr , .mri , .mrc = > inst .ops [0 ],
549
554
else = > unreachable ,
550
555
};
551
- rex .b = b_x_op .isBaseExtended ();
552
- rex .x = b_x_op .isIndexExtended ();
556
+ const b_x_op_base_ext_enc = b_x_op .baseExtEnc ();
557
+ rex .b = b_x_op_base_ext_enc & 0b01 != 0 ;
558
+ assert (b_x_op_base_ext_enc & 0b10 == 0 );
559
+ const b_x_op_index_ext_enc = b_x_op .indexExtEnc ();
560
+ rex .x = b_x_op_index_ext_enc & 0b01 != 0 ;
561
+ assert (b_x_op_index_ext_enc & 0b10 == 0 );
553
562
},
554
563
.vm , .vmi , .rvm , .rvmr , .rvmi , .mvr = > unreachable ,
555
564
}
@@ -576,16 +585,22 @@ pub const Instruction = struct {
576
585
.m , .mi , .m1 , .mc , .vm , .vmi = > .none ,
577
586
else = > unreachable ,
578
587
};
579
- vex .r = r_op .isBaseExtended ();
588
+ const r_op_base_ext_enc = r_op .baseExtEnc ();
589
+ vex .r = r_op_base_ext_enc & 0b01 != 0 ;
590
+ assert (r_op_base_ext_enc & 0b10 == 0 );
580
591
581
592
const b_x_op = switch (op_en ) {
582
593
.rm , .rmi , .rm0 , .vm , .vmi , .rmv = > inst .ops [1 ],
583
594
.m , .mi , .m1 , .mc , .mr , .mri , .mrc , .mvr = > inst .ops [0 ],
584
595
.rvm , .rvmr , .rvmi = > inst .ops [2 ],
585
596
else = > unreachable ,
586
597
};
587
- vex .b = b_x_op .isBaseExtended ();
588
- vex .x = b_x_op .isIndexExtended ();
598
+ const b_x_op_base_ext_enc = b_x_op .baseExtEnc ();
599
+ vex .b = b_x_op_base_ext_enc & 0b01 != 0 ;
600
+ assert (b_x_op_base_ext_enc & 0b10 == 0 );
601
+ const b_x_op_index_ext_enc = b_x_op .indexExtEnc ();
602
+ vex .x = b_x_op_index_ext_enc & 0b01 != 0 ;
603
+ assert (b_x_op_index_ext_enc & 0b10 == 0 );
589
604
},
590
605
}
591
606
@@ -622,8 +637,8 @@ pub const Instruction = struct {
622
637
}
623
638
624
639
fn encodeMemory (encoding : Encoding , mem : Memory , operand : Operand , encoder : anytype ) ! void {
625
- const operand_enc = switch (operand ) {
626
- .reg = > | reg | reg .lowEnc ( ),
640
+ const operand_enc : u3 = switch (operand ) {
641
+ .reg = > | reg | @truncate ( reg .enc () ),
627
642
.none = > encoding .modRmExt (),
628
643
else = > unreachable ,
629
644
};
@@ -635,7 +650,7 @@ pub const Instruction = struct {
635
650
try encoder .modRm_SIBDisp0 (operand_enc );
636
651
if (mem .scaleIndex ()) | si | {
637
652
const scale = math .log2_int (u4 , si .scale );
638
- try encoder .sib_scaleIndexDisp32 (scale , si .index .lowEnc ( ));
653
+ try encoder .sib_scaleIndexDisp32 (scale , @truncate ( si .index .enc () ));
639
654
} else {
640
655
try encoder .sib_disp32 ();
641
656
}
@@ -647,29 +662,29 @@ pub const Instruction = struct {
647
662
try encoder .modRm_SIBDisp0 (operand_enc );
648
663
if (mem .scaleIndex ()) | si | {
649
664
const scale = math .log2_int (u4 , si .scale );
650
- try encoder .sib_scaleIndexDisp32 (scale , si .index .lowEnc ( ));
665
+ try encoder .sib_scaleIndexDisp32 (scale , @truncate ( si .index .enc () ));
651
666
} else {
652
667
try encoder .sib_disp32 ();
653
668
}
654
669
try encoder .disp32 (sib .disp );
655
670
},
656
671
.general_purpose = > {
657
- const dst = base .lowEnc ( );
672
+ const dst : u3 = @truncate ( base .enc () );
658
673
const src = operand_enc ;
659
674
if (dst == 4 or mem .scaleIndex () != null ) {
660
675
if (sib .disp == 0 and dst != 5 ) {
661
676
try encoder .modRm_SIBDisp0 (src );
662
677
if (mem .scaleIndex ()) | si | {
663
678
const scale = math .log2_int (u4 , si .scale );
664
- try encoder .sib_scaleIndexBase (scale , si .index .lowEnc ( ), dst );
679
+ try encoder .sib_scaleIndexBase (scale , @truncate ( si .index .enc () ), dst );
665
680
} else {
666
681
try encoder .sib_base (dst );
667
682
}
668
683
} else if (math .cast (i8 , sib .disp )) | _ | {
669
684
try encoder .modRm_SIBDisp8 (src );
670
685
if (mem .scaleIndex ()) | si | {
671
686
const scale = math .log2_int (u4 , si .scale );
672
- try encoder .sib_scaleIndexBaseDisp8 (scale , si .index .lowEnc ( ), dst );
687
+ try encoder .sib_scaleIndexBaseDisp8 (scale , @truncate ( si .index .enc () ), dst );
673
688
} else {
674
689
try encoder .sib_baseDisp8 (dst );
675
690
}
@@ -678,7 +693,7 @@ pub const Instruction = struct {
678
693
try encoder .modRm_SIBDisp32 (src );
679
694
if (mem .scaleIndex ()) | si | {
680
695
const scale = math .log2_int (u4 , si .scale );
681
- try encoder .sib_scaleIndexBaseDisp32 (scale , si .index .lowEnc ( ), dst );
696
+ try encoder .sib_scaleIndexBaseDisp32 (scale , @truncate ( si .index .enc () ), dst );
682
697
} else {
683
698
try encoder .sib_baseDisp32 (dst );
684
699
}
@@ -867,15 +882,15 @@ fn Encoder(comptime T: type, comptime opts: Options) type {
867
882
868
883
try self .writer .writeByte (
869
884
@as (u8 , @intFromBool (fields .w )) << 7 |
870
- @as (u8 , ~ fields .v .enc ()) << 3 |
885
+ @as (u8 , ~ @as ( u4 , @intCast ( fields .v .enc ()) )) << 3 |
871
886
@as (u8 , @intFromBool (fields .l )) << 2 |
872
887
@as (u8 , @intFromEnum (fields .p )) << 0 ,
873
888
);
874
889
} else {
875
890
try self .writer .writeByte (0b1100_0101 );
876
891
try self .writer .writeByte (
877
892
@as (u8 , ~ @intFromBool (fields .r )) << 7 |
878
- @as (u8 , ~ fields .v .enc ()) << 3 |
893
+ @as (u8 , ~ @as ( u4 , @intCast ( fields .v .enc ()) )) << 3 |
879
894
@as (u8 , @intFromBool (fields .l )) << 2 |
880
895
@as (u8 , @intFromEnum (fields .p )) << 0 ,
881
896
);
0 commit comments