1use crate::cpu::arith::{cmp16, cmp32, cmp8};
13use crate::cpu::cpu::{
14 get_seg, io_port_read16, io_port_read32, io_port_read8, io_port_write16, io_port_write32,
15 io_port_write8, read_reg16, read_reg32, safe_read16, safe_read32s, safe_read8, safe_write16,
16 safe_write32, safe_write8, set_reg_asize, test_privileges_for_io, translate_address_read,
17 translate_address_write_and_can_skip_dirty, writable_or_pagefault, write_reg16, write_reg32,
18 write_reg8, AL, AX, DX, EAX, ECX, EDI, ES, ESI, FLAG_DIRECTION,
19};
20use crate::cpu::global_pointers::{flags, instruction_pointer, previous_ip};
21use crate::cpu::memory;
22use crate::jit;
23use crate::page::Page;
24
25fn count_until_end_of_page(direction: i32, size: i32, addr: u32) -> u32 {
26 (if direction == 1 {
27 (0x1000 - (addr & 0xFFF)) / size as u32
28 } else {
29 (addr & 0xFFF) / size as u32 + 1
30 }) as u32
31}
32
33#[derive(Copy, Clone, PartialEq)]
34enum Instruction {
35 Movs,
36 Lods,
37 Stos,
38 Scas,
39 Cmps,
40 Ins,
41 Outs,
42}
43#[derive(PartialEq)]
44enum Size {
45 B,
46 W,
47 D,
48}
49#[derive(Copy, Clone)]
50enum Rep {
51 None,
52 Z,
53 NZ,
54}
55
56#[inline(always)]
59unsafe fn string_instruction(
60 is_asize_32: bool,
61 ds_or_prefix: i32,
62 instruction: Instruction,
63 size: Size,
64 rep: Rep,
65) {
66 let asize_mask = if is_asize_32 { -1 } else { 0xFFFF };
67
68 let direction = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };
69
70 let mut count = match rep {
71 Rep::Z | Rep::NZ => {
72 let c = (read_reg32(ECX) & asize_mask) as u32;
73 if c == 0 {
74 return;
75 };
76 c
77 }
78 Rep::None => 0,
79 };
80
81 let es = match instruction {
82 Instruction::Movs
83 | Instruction::Cmps
84 | Instruction::Stos
85 | Instruction::Scas
86 | Instruction::Ins => return_on_pagefault!(get_seg(ES)),
87 _ => 0,
88 };
89 let ds = match instruction {
90 Instruction::Movs
91 | Instruction::Cmps
92 | Instruction::Lods
93 | Instruction::Scas
94 | Instruction::Outs => return_on_pagefault!(get_seg(ds_or_prefix)),
95 _ => 0,
96 };
97
98 let size_bytes = match size {
99 Size::B => 1,
100 Size::W => 2,
101 Size::D => 4,
102 };
103 let size_mask = match size {
104 Size::B => 0xFF,
105 Size::W => 0xFFFF,
106 Size::D => -1,
107 };
108
109 let increment = direction * size_bytes;
110
111 let data = match instruction {
112 Instruction::Stos | Instruction::Scas => read_reg32(EAX),
113 _ => 0,
114 };
115
116 let mut src = match instruction {
117 Instruction::Movs | Instruction::Cmps | Instruction::Lods | Instruction::Outs => {
118 read_reg32(ESI) & asize_mask
119 }
120 _ => 0,
121 };
122 let mut dst = match instruction {
123 Instruction::Movs
124 | Instruction::Cmps
125 | Instruction::Stos
126 | Instruction::Scas
127 | Instruction::Ins => read_reg32(EDI) & asize_mask,
128 _ => 0,
129 };
130
131 let port = match instruction {
132 Instruction::Ins | Instruction::Outs => {
133 let port = read_reg16(DX);
134 if !test_privileges_for_io(port, size_bytes) {
135 return;
136 }
137 port
138 }
139 _ => 0,
140 };
141
142 let is_aligned = (ds + src) & (size_bytes - 1) == 0 && (es + dst) & (size_bytes - 1) == 0;
143
144 let mut rep_fast = (instruction == Instruction::Movs || is_aligned)
146 && is_asize_32 && match rep {
148 Rep::NZ | Rep::Z => true,
149 Rep::None => false,
150 };
151
152 let mut phys_dst = 0;
153 let mut phys_src = 0;
154 let mut skip_dirty_page = false;
155
156 let mut movs_into_svga_lfb = false;
157 let mut movs_reenter_fast_path = false;
158
159 let count_until_end_of_page = if rep_fast {
160 match instruction {
161 Instruction::Movs => {
162 let (addr, skip) =
163 return_on_pagefault!(translate_address_write_and_can_skip_dirty(es + dst));
164 movs_into_svga_lfb = memory::in_svga_lfb(addr);
165 rep_fast = rep_fast && (!memory::in_mapped_range(addr) || movs_into_svga_lfb);
166 phys_dst = addr;
167 skip_dirty_page = skip;
168 }
169 Instruction::Stos | Instruction::Ins => {
170 let (addr, skip) =
171 return_on_pagefault!(translate_address_write_and_can_skip_dirty(es + dst));
172 rep_fast = rep_fast && !memory::in_mapped_range(addr);
173 phys_dst = addr;
174 skip_dirty_page = skip;
175 }
176 Instruction::Cmps | Instruction::Scas => {
177 let addr = return_on_pagefault!(translate_address_read(es + dst));
178 rep_fast = rep_fast && !memory::in_mapped_range(addr);
179 phys_dst = addr;
180 skip_dirty_page = true;
181 }
182 _ => {}
183 };
184
185 match instruction {
186 Instruction::Movs | Instruction::Cmps | Instruction::Lods | Instruction::Outs => {
187 let addr = return_on_pagefault!(translate_address_read(ds + src));
188 rep_fast = rep_fast && !memory::in_mapped_range(addr);
189 phys_src = addr;
190 }
191 _ => {}
192 };
193
194 let count_until_end_of_page = u32::min(
195 count,
196 match instruction {
197 Instruction::Movs | Instruction::Cmps => u32::min(
198 count_until_end_of_page(direction, size_bytes, phys_src),
199 count_until_end_of_page(direction, size_bytes, phys_dst),
200 ),
201 Instruction::Stos | Instruction::Ins | Instruction::Scas => {
202 count_until_end_of_page(direction, size_bytes, phys_dst)
203 }
204 Instruction::Lods | Instruction::Outs => {
205 count_until_end_of_page(direction, size_bytes, phys_src)
206 }
207 },
208 );
209
210 match instruction {
211 Instruction::Movs => {
212 let c = count_until_end_of_page * size_bytes as u32;
213
214 let overlap_interferes = if phys_src < phys_dst {
215 phys_dst - phys_src < c && direction == 1
217 } else if phys_src > phys_dst {
218 phys_src - phys_dst < c && direction == -1
220 } else {
221 false
222 };
223 rep_fast = rep_fast && !overlap_interferes;
224
225 movs_reenter_fast_path = rep_fast;
228 rep_fast = rep_fast
229 && (phys_src & 0xFFF <= 0x1000 - size_bytes as u32)
230 && (phys_dst & 0xFFF <= 0x1000 - size_bytes as u32);
231 }
232 _ => {}
233 }
234
235 count_until_end_of_page
236 } else {
237 0 };
239
240 if rep_fast {
241 dbg_assert!(count_until_end_of_page > 0);
242
243 if !skip_dirty_page {
244 jit::jit_dirty_page(Page::page_of(phys_dst));
245 }
246
247 let mut rep_cmp_finished = false;
248
249 let mut i = 0;
250 while i < count_until_end_of_page {
251 i += 1;
252
253 let src_val = match instruction {
254 Instruction::Movs | Instruction::Cmps | Instruction::Lods | Instruction::Outs => {
255 match size {
256 Size::B => memory::read8_no_mmap_check(phys_src),
257 Size::W => memory::read16_no_mmap_check(phys_src),
258 Size::D => memory::read32_no_mmap_check(phys_src),
259 }
260 }
261 Instruction::Scas | Instruction::Stos => data & size_mask,
262 Instruction::Ins => match size {
263 Size::B => io_port_read8(port),
264 Size::W => io_port_read16(port),
265 Size::D => io_port_read32(port),
266 },
267 };
268
269 let mut dst_val = 0;
270
271 match instruction {
272 Instruction::Cmps | Instruction::Scas => match size {
273 Size::B => dst_val = memory::read8_no_mmap_check(phys_dst),
274 Size::W => dst_val = memory::read16_no_mmap_check(phys_dst),
275 Size::D => dst_val = memory::read32_no_mmap_check(phys_dst),
276 },
277 Instruction::Outs => match size {
278 Size::B => io_port_write8(port, src_val),
279 Size::W => io_port_write16(port, src_val),
280 Size::D => io_port_write32(port, src_val),
281 },
282 Instruction::Lods => match size {
283 Size::B => write_reg8(AL, src_val),
284 Size::W => write_reg16(AX, src_val),
285 Size::D => write_reg32(EAX, src_val),
286 },
287 Instruction::Ins => match size {
288 Size::B => memory::write8_no_mmap_or_dirty_check(phys_dst, src_val),
289 Size::W => memory::write16_no_mmap_or_dirty_check(phys_dst, src_val),
290 Size::D => memory::write32_no_mmap_or_dirty_check(phys_dst, src_val),
291 },
292 Instruction::Movs => {
293 if direction == -1 {
294 phys_src -= (count_until_end_of_page - 1) * size_bytes as u32;
295 phys_dst -= (count_until_end_of_page - 1) * size_bytes as u32;
296 }
297 if movs_into_svga_lfb {
298 memory::memcpy_into_svga_lfb(
299 phys_src,
300 phys_dst,
301 count_until_end_of_page * size_bytes as u32,
302 );
303 } else {
304 memory::memcpy_no_mmap_or_dirty_check(
305 phys_src,
306 phys_dst,
307 count_until_end_of_page * size_bytes as u32,
308 );
309 }
310 i = count_until_end_of_page;
311 break;
312 }
313 Instruction::Stos => match size {
314 Size::B => {
315 if direction == -1 {
316 phys_dst -= count_until_end_of_page - 1
317 }
318 memory::memset_no_mmap_or_dirty_check(
319 phys_dst,
320 src_val as u8,
321 count_until_end_of_page,
322 );
323 i = count_until_end_of_page;
324 break;
325 }
326 Size::W => memory::write16_no_mmap_or_dirty_check(phys_dst, src_val),
327 Size::D => memory::write32_no_mmap_or_dirty_check(phys_dst, src_val),
328 },
329 };
330
331 match instruction {
332 Instruction::Movs
333 | Instruction::Cmps
334 | Instruction::Stos
335 | Instruction::Scas
336 | Instruction::Ins => {
337 phys_dst += increment as u32;
338 }
339 _ => {}
340 }
341 match instruction {
342 Instruction::Movs | Instruction::Cmps | Instruction::Lods | Instruction::Outs => {
343 phys_src += increment as u32;
344 }
345 _ => {}
346 };
347
348 match instruction {
349 Instruction::Scas | Instruction::Cmps => {
350 let rep_cmp = match rep {
351 Rep::Z => src_val == dst_val,
352 Rep::NZ => src_val != dst_val,
353 Rep::None => {
354 dbg_assert!(false);
355 true
356 }
357 };
358 if !rep_cmp || count == i {
359 match size {
360 Size::B => cmp8(src_val, dst_val),
361 Size::W => cmp16(src_val, dst_val),
362 Size::D => cmp32(src_val, dst_val),
363 };
364 rep_cmp_finished = true;
365 break;
366 }
367 }
368 _ => {}
369 }
370 }
371
372 dbg_assert!(i <= count);
373 count -= i;
374
375 if !rep_cmp_finished && count != 0 {
376 *instruction_pointer = *previous_ip;
378 }
379
380 src += i as i32 * increment;
381 dst += i as i32 * increment;
382 } else {
383 loop {
384 match instruction {
385 Instruction::Ins => {
386 break_on_pagefault!(writable_or_pagefault(es + dst, size_bytes));
389 }
390 _ => {}
391 };
392 let src_val = match instruction {
393 Instruction::Movs | Instruction::Cmps | Instruction::Lods | Instruction::Outs => {
394 break_on_pagefault!(match size {
395 Size::B => safe_read8(ds + src),
396 Size::W => safe_read16(ds + src),
397 Size::D => safe_read32s(ds + src),
398 })
399 }
400 Instruction::Scas | Instruction::Stos => data & size_mask,
401 Instruction::Ins => match size {
402 Size::B => io_port_read8(port),
403 Size::W => io_port_read16(port),
404 Size::D => io_port_read32(port),
405 },
406 };
407
408 let mut dst_val = 0;
409
410 match instruction {
411 Instruction::Cmps | Instruction::Scas => match size {
412 Size::B => dst_val = break_on_pagefault!(safe_read8(es + dst)),
413 Size::W => dst_val = break_on_pagefault!(safe_read16(es + dst)),
414 Size::D => dst_val = break_on_pagefault!(safe_read32s(es + dst)),
415 },
416 Instruction::Outs => match size {
417 Size::B => io_port_write8(port, src_val),
418 Size::W => io_port_write16(port, src_val),
419 Size::D => io_port_write32(port, src_val),
420 },
421 Instruction::Lods => match size {
422 Size::B => write_reg8(AL, src_val),
423 Size::W => write_reg16(AX, src_val),
424 Size::D => write_reg32(EAX, src_val),
425 },
426 Instruction::Movs | Instruction::Stos | Instruction::Ins => match size {
427 Size::B => break_on_pagefault!(safe_write8(es + dst, src_val)),
428 Size::W => break_on_pagefault!(safe_write16(es + dst, src_val)),
429 Size::D => break_on_pagefault!(safe_write32(es + dst, src_val)),
430 },
431 };
432
433 match instruction {
434 Instruction::Movs
435 | Instruction::Cmps
436 | Instruction::Stos
437 | Instruction::Scas
438 | Instruction::Ins => dst = dst + increment & asize_mask,
439 _ => {}
440 }
441 match instruction {
442 Instruction::Movs | Instruction::Cmps | Instruction::Lods | Instruction::Outs => {
443 src = src + increment & asize_mask
444 }
445 _ => {}
446 };
447
448 count -= 1;
449
450 let finished = match rep {
451 Rep::Z | Rep::NZ => match (rep, instruction) {
452 (Rep::Z, Instruction::Cmps) => src_val != dst_val || count == 0,
453 (Rep::Z, Instruction::Scas) => src_val != dst_val || count == 0,
454 (Rep::NZ, Instruction::Cmps) => src_val == dst_val || count == 0,
455 (Rep::NZ, Instruction::Scas) => src_val == dst_val || count == 0,
456 (Rep::NZ | Rep::Z, Instruction::Movs) => {
457 if count == 0 {
458 true
459 } else if movs_reenter_fast_path {
460 *instruction_pointer = *previous_ip;
461 true
462 } else {
463 false
464 }
465 }
466 _ => count == 0,
467 },
468 Rep::None => true,
469 };
470
471 if finished {
472 match instruction {
473 Instruction::Scas | Instruction::Cmps => match size {
474 Size::B => cmp8(src_val, dst_val),
475 Size::W => cmp16(src_val, dst_val),
476 Size::D => cmp32(src_val, dst_val),
477 },
478 _ => {}
479 }
480 break;
481 }
482 }
483 }
484
485 match instruction {
486 Instruction::Movs
487 | Instruction::Cmps
488 | Instruction::Stos
489 | Instruction::Scas
490 | Instruction::Ins => set_reg_asize(is_asize_32, EDI, dst),
491 _ => {}
492 }
493 match instruction {
494 Instruction::Movs | Instruction::Cmps | Instruction::Lods | Instruction::Outs => {
495 set_reg_asize(is_asize_32, ESI, src)
496 }
497 _ => {}
498 };
499
500 match rep {
501 Rep::Z | Rep::NZ => {
502 set_reg_asize(is_asize_32, ECX, count as i32);
503 }
504 Rep::None => {}
505 }
506}
507
508#[no_mangle]
509pub unsafe fn movsb_rep(is_asize_32: bool, seg: i32) {
510 string_instruction(is_asize_32, seg, Instruction::Movs, Size::B, Rep::Z)
511}
512#[no_mangle]
513pub unsafe fn movsw_rep(is_asize_32: bool, seg: i32) {
514 string_instruction(is_asize_32, seg, Instruction::Movs, Size::W, Rep::Z)
515}
516#[no_mangle]
517pub unsafe fn movsd_rep(is_asize_32: bool, seg: i32) {
518 string_instruction(is_asize_32, seg, Instruction::Movs, Size::D, Rep::Z)
519}
520pub unsafe fn movsb_no_rep(is_asize_32: bool, seg: i32) {
521 string_instruction(is_asize_32, seg, Instruction::Movs, Size::B, Rep::None)
522}
523pub unsafe fn movsw_no_rep(is_asize_32: bool, seg: i32) {
524 string_instruction(is_asize_32, seg, Instruction::Movs, Size::W, Rep::None)
525}
526pub unsafe fn movsd_no_rep(is_asize_32: bool, seg: i32) {
527 string_instruction(is_asize_32, seg, Instruction::Movs, Size::D, Rep::None)
528}
529
530#[no_mangle]
531pub unsafe fn lodsb_rep(is_asize_32: bool, seg: i32) {
532 string_instruction(is_asize_32, seg, Instruction::Lods, Size::B, Rep::Z)
533}
534#[no_mangle]
535pub unsafe fn lodsw_rep(is_asize_32: bool, seg: i32) {
536 string_instruction(is_asize_32, seg, Instruction::Lods, Size::W, Rep::Z)
537}
538#[no_mangle]
539pub unsafe fn lodsd_rep(is_asize_32: bool, seg: i32) {
540 string_instruction(is_asize_32, seg, Instruction::Lods, Size::D, Rep::Z)
541}
542pub unsafe fn lodsb_no_rep(is_asize_32: bool, seg: i32) {
543 string_instruction(is_asize_32, seg, Instruction::Lods, Size::B, Rep::None)
544}
545pub unsafe fn lodsw_no_rep(is_asize_32: bool, seg: i32) {
546 string_instruction(is_asize_32, seg, Instruction::Lods, Size::W, Rep::None)
547}
548pub unsafe fn lodsd_no_rep(is_asize_32: bool, seg: i32) {
549 string_instruction(is_asize_32, seg, Instruction::Lods, Size::D, Rep::None)
550}
551
552#[no_mangle]
553pub unsafe fn stosb_rep(is_asize_32: bool) {
554 string_instruction(is_asize_32, 0, Instruction::Stos, Size::B, Rep::Z)
555}
556#[no_mangle]
557pub unsafe fn stosw_rep(is_asize_32: bool) {
558 string_instruction(is_asize_32, 0, Instruction::Stos, Size::W, Rep::Z)
559}
560#[no_mangle]
561pub unsafe fn stosd_rep(is_asize_32: bool) {
562 string_instruction(is_asize_32, 0, Instruction::Stos, Size::D, Rep::Z)
563}
564pub unsafe fn stosb_no_rep(is_asize_32: bool) {
565 string_instruction(is_asize_32, 0, Instruction::Stos, Size::B, Rep::None)
566}
567pub unsafe fn stosw_no_rep(is_asize_32: bool) {
568 string_instruction(is_asize_32, 0, Instruction::Stos, Size::W, Rep::None)
569}
570pub unsafe fn stosd_no_rep(is_asize_32: bool) {
571 string_instruction(is_asize_32, 0, Instruction::Stos, Size::D, Rep::None)
572}
573
574#[no_mangle]
575pub unsafe fn cmpsb_repz(is_asize_32: bool, seg: i32) {
576 string_instruction(is_asize_32, seg, Instruction::Cmps, Size::B, Rep::Z)
577}
578#[no_mangle]
579pub unsafe fn cmpsw_repz(is_asize_32: bool, seg: i32) {
580 string_instruction(is_asize_32, seg, Instruction::Cmps, Size::W, Rep::Z)
581}
582#[no_mangle]
583pub unsafe fn cmpsd_repz(is_asize_32: bool, seg: i32) {
584 string_instruction(is_asize_32, seg, Instruction::Cmps, Size::D, Rep::Z)
585}
586#[no_mangle]
587pub unsafe fn cmpsb_repnz(is_asize_32: bool, seg: i32) {
588 string_instruction(is_asize_32, seg, Instruction::Cmps, Size::B, Rep::NZ)
589}
590#[no_mangle]
591pub unsafe fn cmpsw_repnz(is_asize_32: bool, seg: i32) {
592 string_instruction(is_asize_32, seg, Instruction::Cmps, Size::W, Rep::NZ)
593}
594#[no_mangle]
595pub unsafe fn cmpsd_repnz(is_asize_32: bool, seg: i32) {
596 string_instruction(is_asize_32, seg, Instruction::Cmps, Size::D, Rep::NZ)
597}
598#[no_mangle]
599pub unsafe fn cmpsb_no_rep(is_asize_32: bool, seg: i32) {
600 string_instruction(is_asize_32, seg, Instruction::Cmps, Size::B, Rep::None)
601}
602#[no_mangle]
603pub unsafe fn cmpsw_no_rep(is_asize_32: bool, seg: i32) {
604 string_instruction(is_asize_32, seg, Instruction::Cmps, Size::W, Rep::None)
605}
606#[no_mangle]
607pub unsafe fn cmpsd_no_rep(is_asize_32: bool, seg: i32) {
608 string_instruction(is_asize_32, seg, Instruction::Cmps, Size::D, Rep::None)
609}
610
611#[no_mangle]
612pub unsafe fn scasb_repz(is_asize_32: bool) {
613 string_instruction(is_asize_32, 0, Instruction::Scas, Size::B, Rep::Z)
614}
615#[no_mangle]
616pub unsafe fn scasw_repz(is_asize_32: bool) {
617 string_instruction(is_asize_32, 0, Instruction::Scas, Size::W, Rep::Z)
618}
619#[no_mangle]
620pub unsafe fn scasd_repz(is_asize_32: bool) {
621 string_instruction(is_asize_32, 0, Instruction::Scas, Size::D, Rep::Z)
622}
623#[no_mangle]
624pub unsafe fn scasb_repnz(is_asize_32: bool) {
625 string_instruction(is_asize_32, 0, Instruction::Scas, Size::B, Rep::NZ)
626}
627#[no_mangle]
628pub unsafe fn scasw_repnz(is_asize_32: bool) {
629 string_instruction(is_asize_32, 0, Instruction::Scas, Size::W, Rep::NZ)
630}
631#[no_mangle]
632pub unsafe fn scasd_repnz(is_asize_32: bool) {
633 string_instruction(is_asize_32, 0, Instruction::Scas, Size::D, Rep::NZ)
634}
635pub unsafe fn scasb_no_rep(is_asize_32: bool) {
636 string_instruction(is_asize_32, 0, Instruction::Scas, Size::B, Rep::None)
637}
638pub unsafe fn scasw_no_rep(is_asize_32: bool) {
639 string_instruction(is_asize_32, 0, Instruction::Scas, Size::W, Rep::None)
640}
641pub unsafe fn scasd_no_rep(is_asize_32: bool) {
642 string_instruction(is_asize_32, 0, Instruction::Scas, Size::D, Rep::None)
643}
644
645#[no_mangle]
646pub unsafe fn outsb_rep(is_asize_32: bool, seg: i32) {
647 string_instruction(is_asize_32, seg, Instruction::Outs, Size::B, Rep::Z)
648}
649#[no_mangle]
650pub unsafe fn outsw_rep(is_asize_32: bool, seg: i32) {
651 string_instruction(is_asize_32, seg, Instruction::Outs, Size::W, Rep::Z)
652}
653#[no_mangle]
654pub unsafe fn outsd_rep(is_asize_32: bool, seg: i32) {
655 string_instruction(is_asize_32, seg, Instruction::Outs, Size::D, Rep::Z)
656}
657#[no_mangle]
658pub unsafe fn outsb_no_rep(is_asize_32: bool, seg: i32) {
659 string_instruction(is_asize_32, seg, Instruction::Outs, Size::B, Rep::None)
660}
661#[no_mangle]
662pub unsafe fn outsw_no_rep(is_asize_32: bool, seg: i32) {
663 string_instruction(is_asize_32, seg, Instruction::Outs, Size::W, Rep::None)
664}
665#[no_mangle]
666pub unsafe fn outsd_no_rep(is_asize_32: bool, seg: i32) {
667 string_instruction(is_asize_32, seg, Instruction::Outs, Size::D, Rep::None)
668}
669
670#[no_mangle]
671pub unsafe fn insb_rep(is_asize_32: bool) {
672 string_instruction(is_asize_32, 0, Instruction::Ins, Size::B, Rep::Z)
673}
674#[no_mangle]
675pub unsafe fn insw_rep(is_asize_32: bool) {
676 string_instruction(is_asize_32, 0, Instruction::Ins, Size::W, Rep::Z)
677}
678#[no_mangle]
679pub unsafe fn insd_rep(is_asize_32: bool) {
680 string_instruction(is_asize_32, 0, Instruction::Ins, Size::D, Rep::Z)
681}
682#[no_mangle]
683pub unsafe fn insb_no_rep(is_asize_32: bool) {
684 string_instruction(is_asize_32, 0, Instruction::Ins, Size::B, Rep::None)
685}
686#[no_mangle]
687pub unsafe fn insw_no_rep(is_asize_32: bool) {
688 string_instruction(is_asize_32, 0, Instruction::Ins, Size::W, Rep::None)
689}
690#[no_mangle]
691pub unsafe fn insd_no_rep(is_asize_32: bool) {
692 string_instruction(is_asize_32, 0, Instruction::Ins, Size::D, Rep::None)
693}