Skip to content

Commit 8a8a742

Browse files
committed
beta-min: added all instruction (in one day :D)
1 parent bfda95f commit 8a8a742

11 files changed

Lines changed: 1102 additions & 54 deletions

File tree

roadmap.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,16 @@ Goal: implement support for Intel APX
108108

109109
Goal: support for smaller x86-64 ISA extensions (around 284 new mnemonics)
110110

111-
- [ ] missing x86-64 instructions
112-
- [ ] move to rc
111+
- [x] missing x86-64 instructions
112+
- [x] move to rc
113113

114114
## rc
115115

116116
Goal: extensive testing, polish and optimizations of assembler, less updates/commits
117117

118118
- [ ] Support for 16-bit addressing
119+
- [ ] Full migration to `CheckAPI`
120+
- [ ] Add tests without need for `nasm` and `sxd` (only `cargo test`)
119121
- [ ] Add `type` directive for `section`s (allows to have `.bss` sections)
120122
- [ ] Allow for `protected public function label_name:`
121123
- [ ] Support for `offset` (aka `ORG`) directive

src/conf.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,4 @@ pub const PREFIX_REF: char = '@';
4545
// metadata for help
4646

4747
pub const BIN: &str = "pasm";
48-
pub const VER: &str = "25.07-beta-intel-apx";
48+
pub const VER: &str = "25.07-rc";

src/core/comp.rs

Lines changed: 697 additions & 5 deletions
Large diffs are not rendered by default.

src/core/rex.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,15 @@ pub fn needs_rex(ins: &Instruction, dst: &Option<Operand>, src: &Option<Operand>
3030
(Size::Qword, Size::Qword) | (Size::Qword, _) | (_, Size::Qword) => {}
3131
_ => return false,
3232
}
33+
3334
match &ins.mnemonic {
3435
Mnemonic::XADD
36+
| Mnemonic::MOVSXD
37+
| Mnemonic::MOVSX
38+
| Mnemonic::INCSSPQ
39+
| Mnemonic::WRSSQ
40+
| Mnemonic::RDFSBASE
41+
| Mnemonic::RDGSBASE
3542
| Mnemonic::XRSTOR
3643
| Mnemonic::XRSTOR64
3744
| Mnemonic::XRSTORS

src/pre/chk.rs

Lines changed: 273 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ fn check_ins32bit(ins: &Instruction) -> Result<(), Error> {
5959
);
6060
return Err(er);
6161
} else if ins.needs_apx_extension() {
62-
todo!("TODO: ");
62+
return Err(Error::new(
63+
"you tried to use instruction that requires APX extension, but bits != 64",
64+
10,
65+
));
6366
}
6467
match ins.mnemonic {
6568
JCXZ | JECXZ => ot_chk(ins, &[(&[I8], Optional::Needed)], &[], &[]),
@@ -447,20 +450,123 @@ fn check_ins32bit(ins: &Instruction) -> Result<(), Error> {
447450
&[(M32, M32), (R32, R32), (MMX, MMX), (XMM, MMX), (MMX, XMM)],
448451
&[],
449452
),
450-
Mnemonic::MOVQ | MOVSTRQ | SCASQ | STOSQ => {
453+
Mnemonic::MOVQ | Mnemonic::PUSHAQ | MOVSTRQ | SCASQ | STOSQ | Mnemonic::POPAQ | INCSSPQ => {
451454
let er = Error::new(
452455
"you tried to use instruction that is invalid when bits != 64",
453456
10,
454457
);
455458
Err(er)
456459
}
460+
Mnemonic::PTWRITE => {
461+
use chkn::*;
462+
CheckAPI::<1>::new().push(&[R32, M32], true).check(ins)
463+
}
464+
Mnemonic::WBNOINVD | Mnemonic::PCONFIG => {
465+
use chkn::*;
466+
CheckAPI::<0>::new().check(ins)
467+
}
468+
Mnemonic::MOVSX => {
469+
use chkn::*;
470+
CheckAPI::<2>::new()
471+
.push(&[R16, R32], true)
472+
.push(&[R8, R16, M8, M16], true)
473+
.set_mode(CheckMode::NOSIZE)
474+
.check(ins)
475+
}
457476
_ => shr_chk(ins),
458477
}
459478
}
460479

461480
fn check_ins64bit(ins: &Instruction) -> Result<(), Error> {
462481
use Mnemonic::*;
463482
match ins.mnemonic {
483+
Mnemonic::RDMSRLIST
484+
| Mnemonic::PBNDKB
485+
| Mnemonic::WRMSRLIST
486+
| Mnemonic::WBNOINVD
487+
| Mnemonic::PCONFIG
488+
| Mnemonic::POPAQ => {
489+
use chkn::*;
490+
CheckAPI::<0>::new().check(ins)
491+
}
492+
AWRSSQ | AWRUSSQ => {
493+
use chkn::*;
494+
CheckAPI::<2>::new()
495+
.push(&[M64], true)
496+
.push(&[R64], true)
497+
.apx(APXVariant::LegacyExtension, false)
498+
.check(ins)
499+
}
500+
AWRSSD | AWRUSSD => {
501+
use chkn::*;
502+
CheckAPI::<2>::new()
503+
.push(&[M32], true)
504+
.push(&[R32], true)
505+
.apx(APXVariant::LegacyExtension, false)
506+
.check(ins)
507+
}
508+
Mnemonic::PREFETCHIT0 | Mnemonic::PREFETCHIT1 => {
509+
use chkn::*;
510+
CheckAPI::<1>::new().push(&[M8], true).check(ins)
511+
}
512+
Mnemonic::PTWRITE => {
513+
use chkn::*;
514+
CheckAPI::<1>::new()
515+
.push(&[R32, R64, M32, M64], true)
516+
.check(ins)
517+
}
518+
Mnemonic::ENQCMDS | Mnemonic::MOVDIR64B | Mnemonic::ENQCMD | Mnemonic::AENQCMD => {
519+
use chkn::*;
520+
CheckAPI::<2>::new()
521+
.push(&[R16, R32, R64], true)
522+
.push(&[M512], true)
523+
.check(ins)
524+
}
525+
Mnemonic::RDFSBASE | Mnemonic::RDGSBASE => {
526+
use chkn::*;
527+
CheckAPI::<1>::new().push(&[R32, R64], true).check(ins)
528+
}
529+
Mnemonic::MOVSX => {
530+
use chkn::*;
531+
CheckAPI::<2>::new()
532+
.push(&[R16, R32, R64], true)
533+
.push(&[R8, R16, M8, M16], true)
534+
.set_mode(CheckMode::NOSIZE)
535+
.check(ins)
536+
}
537+
Mnemonic::MOVSXD => {
538+
use chkn::*;
539+
CheckAPI::<2>::new()
540+
.push(&[R16, R32, R64], true)
541+
.push(&[R16, R32, M16, M32], true)
542+
.set_mode(CheckMode::NOSIZE)
543+
.check(ins)
544+
}
545+
546+
ACMPBXADD | ACMPBEXADD | ACMPLXADD | ACMPLEXADD | ACMPNBXADD | ACMPZXADD | ACMPNBEXADD
547+
| ACMPNLXADD | ACMPNLEXADD | ACMPNOXADD | ACMPNSXADD | ACMPNZXADD | ACMPOXADD
548+
| ACMPSXADD | ACMPNAXADD | ACMPAXADD | ACMPNAEXADD | ACMPAEXADD | ACMPEXADD
549+
| ACMPNEXADD | ACMPGEXADD | ACMPGXADD | ACMPNGXADD | ACMPNGEXADD => {
550+
use chkn::*;
551+
CheckAPI::<3>::new()
552+
.push(&[M32, M64], true)
553+
.push(&[R32, R64], true)
554+
.push(&[R32, R64], true)
555+
.apx(APXVariant::VexExtension, false)
556+
.check(ins)
557+
}
558+
CMPBXADD | CMPBEXADD | CMPLXADD | CMPLEXADD | CMPNBXADD | CMPZXADD | CMPNBEXADD
559+
| CMPNLXADD | CMPNLEXADD | CMPNOXADD | CMPNSXADD | CMPNZXADD | CMPOXADD | CMPSXADD
560+
| CMPNAXADD | CMPAXADD | CMPNAEXADD | CMPAEXADD | CMPEXADD | CMPNEXADD | CMPGEXADD
561+
| CMPGXADD | CMPNGXADD | CMPNGEXADD | CMPCXADD | CMPNCXADD => {
562+
use chkn::*;
563+
CheckAPI::<3>::new()
564+
.push(&[M32, M64], true)
565+
.push(&[R32, R64], true)
566+
.push(&[R32, R64], true)
567+
.check(ins)
568+
}
569+
464570
// APX
465571
Mnemonic::PUSHP => {
466572
use chkn::*;
@@ -1130,14 +1236,173 @@ fn check_ins64bit(ins: &Instruction) -> Result<(), Error> {
11301236
&[],
11311237
&[LOCK],
11321238
),
1239+
WRSSQ | WRUSSQ => {
1240+
use chkn::*;
1241+
CheckAPI::<2>::new()
1242+
.push(&[M64], true)
1243+
.push(&[R64], true)
1244+
.check(ins)
1245+
}
1246+
INCSSPQ => {
1247+
use chkn::*;
1248+
CheckAPI::<1>::new().push(&[R64], true).check(ins)
1249+
}
11331250
_ => shr_chk(ins),
11341251
}
11351252
}
11361253

11371254
pub fn shr_chk(ins: &Instruction) -> Result<(), Error> {
11381255
use Mnemonic::*;
11391256
match ins.mnemonic {
1140-
LGDT | LIDT => ot_chk(ins, &[(&[M16], Optional::Needed)], &[], &[]),
1257+
INVLPGA | VMRUN | VMLOAD | VMSAVE | STGI | CLGI | VMMCALL | SKINIT | VMGEXIT | PSMASH
1258+
| RMPUPDATE | PVALIDATE | RMPADJUST | RMPQUERY | RMPREAD | VMXOFF | VMLAUNCH | VMRESUME
1259+
| VMCALL | VMFUNC | SEAMOPS | SEAMRET | SEAMCALL | TDCALL | FNINIT | FINIT | FNCLEX
1260+
| FCLEX | FNDISI | FDISI | FENI | FNENI | FLDZ | FLD1 | FLDPI | FLDL2T | FLDL2E
1261+
| FLDLG2 | FLDLN2 | FCOMPP | FCHS | FABS | FTST | FXAM | FXTRACT | FRNDINT | FPREM
1262+
| FSQRT | FSCALE | F2XM1 | FYL2X | FPTAN | FYL2XP1 | FDECSTP | FINCSTP | FNSETPM
1263+
| FSETPM | FNSTSWAX | FSTSWAX | FUCOMPP | FPREM1 | FSINCOS | FSIN | FCOS | ENCLV
1264+
| ENCLS | ENCLU | SAVEPREVSSP | FPATAN => {
1265+
use chkn::*;
1266+
CheckAPI::<0>::new().check(ins)
1267+
}
1268+
FCMOVB | FCMOVE | FCMOVBE | FCMOVU | FCMOVNB | FCMOVNE | FCMOVNBE | FCMOVNU | FADDP
1269+
| FMULP | FSUBRP | FFREE | FSUBP | FDIVP | FDIVRP | FCOMP | FCOMI | FCOMIP | FUCOMI
1270+
| FUCOMIP => {
1271+
use chkn::*;
1272+
CheckAPI::<1>::new().push(&[ST], true).check(ins)
1273+
}
1274+
FIADD | FIMUL | FISUBR | FISUB | FIDIV | FIDIVR | FICOMP | FICOM => {
1275+
use chkn::*;
1276+
CheckAPI::<1>::new().push(&[M32, M64], true).check(ins)
1277+
}
1278+
FADD | FMUL | FSUBR | FSUB | FDIV | FDIVR => {
1279+
use chkn::*;
1280+
CheckAPI::<2>::new()
1281+
.push(&[M32, M64, ST], true)
1282+
.push(&[ST], false)
1283+
.forbidden(&[[MA, ST]])
1284+
.check(ins)
1285+
}
1286+
CLRSSBSY => {
1287+
use chkn::*;
1288+
CheckAPI::<1>::new().push(&[M64], true).check(ins)
1289+
}
1290+
WRSSD | WRUSSD => {
1291+
use chkn::*;
1292+
CheckAPI::<2>::new()
1293+
.push(&[M32], true)
1294+
.push(&[R32], true)
1295+
.check(ins)
1296+
}
1297+
FILD | FISTP => {
1298+
use chkn::*;
1299+
CheckAPI::<1>::new().push(&[M16, M32, M64], true).check(ins)
1300+
}
1301+
FIST => {
1302+
use chkn::*;
1303+
CheckAPI::<1>::new().push(&[M16, M32], true).check(ins)
1304+
}
1305+
FBLD | FBSTP => {
1306+
use chkn::*;
1307+
CheckAPI::<1>::new().push(&[M80], true).check(ins)
1308+
}
1309+
FXCH | FUCOM | FUCOMP => {
1310+
use chkn::*;
1311+
CheckAPI::<1>::new().push(&[ST], true).check(ins)
1312+
}
1313+
FST | FCOM => {
1314+
use chkn::*;
1315+
CheckAPI::<1>::new().push(&[M32, M64, ST], true).check(ins)
1316+
}
1317+
FLD | FSTP => {
1318+
use chkn::*;
1319+
CheckAPI::<1>::new()
1320+
.push(&[M32, M64, M80, ST], true)
1321+
.check(ins)
1322+
}
1323+
FNSTCW | FSTCW | FNSTSW | FSTSW | FLDCW | FLDENV | FNSTENV | FNSAVE | FSAVE | FSTENV
1324+
| FRSTOR | FXSAVE | FXRSTOR | FXSAVE64 | FXRSTOR64 => {
1325+
use chkn::*;
1326+
CheckAPI::<1>::new().push(&[MA], true).check(ins)
1327+
}
1328+
INVEPT | INVVPID => {
1329+
use chkn::*;
1330+
CheckAPI::<2>::new()
1331+
.push(&[R16, R32, R64], true)
1332+
.push(&[M128], true)
1333+
.check(ins)
1334+
}
1335+
AESENC256KL | AESDEC256KL => {
1336+
use chkn::*;
1337+
CheckAPI::<2>::new()
1338+
.push(&[XMM], true)
1339+
.push(&[M512], true)
1340+
.set_mode(CheckMode::NOSIZE)
1341+
.check(ins)
1342+
}
1343+
AESENCWIDE128KL | AESDECWIDE128KL => {
1344+
use chkn::*;
1345+
CheckAPI::<1>::new()
1346+
.push(&[MA], true)
1347+
.set_mode(CheckMode::NOSIZE)
1348+
.check(ins)
1349+
}
1350+
AESENC128KL | AESDEC128KL => {
1351+
use chkn::*;
1352+
CheckAPI::<2>::new()
1353+
.push(&[XMM], true)
1354+
.push(&[MA], true)
1355+
.set_mode(CheckMode::NOSIZE)
1356+
.check(ins)
1357+
}
1358+
ENCODEKEY128 | ENCODEKEY256 => {
1359+
use chkn::*;
1360+
CheckAPI::<2>::new()
1361+
.push(&[R32], true)
1362+
.push(&[R32], true)
1363+
.check(ins)
1364+
}
1365+
LOADIWKEY => {
1366+
use chkn::*;
1367+
CheckAPI::<2>::new()
1368+
.push(&[XMM], true)
1369+
.push(&[XMM], true)
1370+
.check(ins)
1371+
}
1372+
INCSSPD => {
1373+
use chkn::*;
1374+
CheckAPI::<1>::new().push(&[R32], true).check(ins)
1375+
}
1376+
VMWRITE => {
1377+
use chkn::*;
1378+
CheckAPI::<2>::new()
1379+
.push(&[R64], true)
1380+
.push(&[R64, M64], true)
1381+
.check(ins)
1382+
}
1383+
VMREAD => {
1384+
use chkn::*;
1385+
CheckAPI::<2>::new()
1386+
.push(&[R64, M64], true)
1387+
.push(&[R64], true)
1388+
.check(ins)
1389+
}
1390+
VMXON | VMPTRLD | VMPTRST | VMCLEAR => {
1391+
use chkn::*;
1392+
CheckAPI::<1>::new().push(&[M64], true).check(ins)
1393+
}
1394+
1395+
LGDT | LIDT | Mnemonic::SGDT | Mnemonic::SIDT => {
1396+
ot_chk(ins, &[(&[M16], Optional::Needed)], &[], &[])
1397+
}
1398+
1399+
LFS | LGS => {
1400+
use chkn::*;
1401+
CheckAPI::<2>::new()
1402+
.push(&[R16, R32], true)
1403+
.push(&[M16, M32], true)
1404+
.check(ins)
1405+
}
11411406

11421407
OUT => ot_chk(
11431408
ins,
@@ -1172,7 +1437,7 @@ pub fn shr_chk(ins: &Instruction) -> Result<(), Error> {
11721437
),
11731438

11741439
LTR => ot_chk(ins, &[(&[R16, M16], Optional::Needed)], &[], &[]),
1175-
PREFETCHW | PREFETCH0 | PREFETCH1 | PREFETCH2 | PREFETCHA => {
1440+
PREFETCHW | PREFETCH0 | PREFETCHIT0 | PREFETCHIT1 | PREFETCH1 | PREFETCH2 | PREFETCHA => {
11761441
ot_chk(ins, &[(&[M8], Optional::Needed)], &[], &[])
11771442
}
11781443
LSL => ot_chk(
@@ -1187,7 +1452,8 @@ pub fn shr_chk(ins: &Instruction) -> Result<(), Error> {
11871452
OUTSB | OUTSW | OUTSD | STOSB | STOSW | STOSD | STOSQ => ot_chk(ins, &[], &[], &[REP]),
11881453

11891454
SFENCE | STAC | STC | STD | STI | STUI | SYSENTER | SYSEXIT | SYSRET | TESTUI | UD2
1190-
| UIRET | WAIT | FWAIT | WBINVD | WRMSR | WRPKRU => ot_chk(ins, &[], &[], &[]),
1455+
| POPAW | POPAD | POPAQ | PUSHAW | PUSHAD | PUSHAQ | UIRET | WAIT | FWAIT | WBINVD
1456+
| WRMSR | WRPKRU => ot_chk(ins, &[], &[], &[]),
11911457
TPAUSE | UMWAIT => ot_chk(
11921458
ins,
11931459
&[
@@ -1274,7 +1540,7 @@ pub fn shr_chk(ins: &Instruction) -> Result<(), Error> {
12741540
&[],
12751541
&[],
12761542
),
1277-
LLDT | LMSW => ot_chk(ins, &[(&[R16, M16], Optional::Needed)], &[], &[]),
1543+
LLDT | SLDT | LMSW => ot_chk(ins, &[(&[R16, M16], Optional::Needed)], &[], &[]),
12781544

12791545
RDMSR | RDPKRU | RDPMC | RDTSC | RDTSCP | RSM | SAHF | SERIALIZE | SETSSBY => {
12801546
ot_chk(ins, &[], &[], &[])
@@ -1293,7 +1559,7 @@ pub fn shr_chk(ins: &Instruction) -> Result<(), Error> {
12931559
// norm-part6
12941560
XABORT => ot_chk(ins, &[(&[I8], Optional::Needed)], &[], &[]),
12951561
XACQUIRE | XRELEASE | XEND | XGETBV | XLAT | XLATB | XLATB64 | XRESLDTRK | XSETBV
1296-
| XSUSLDTRK | XTEST => ot_chk(ins, &[], &[], &[]),
1562+
| NOPL | SWAPGS | XSUSLDTRK | XTEST => ot_chk(ins, &[], &[], &[]),
12971563

12981564
XBEGIN => ot_chk(ins, &[(&[I32, I16], Optional::Needed)], &[], &[]),
12991565
XRSTOR | XRSTORS | XRSTORS64 | XSAVE | XSAVE64 | XSAVEC | XSAVEC64 | XSAVEOPT

0 commit comments

Comments
 (0)