2 CarryFlags, ConditionRegister, InstructionInput, InstructionOutput, InstructionResult,
3 MissingInstructionInput, OverflowFlags,
5 use std::convert::TryFrom;
8 mut overflow: OverflowFlags,
9 inputs: InstructionInput,
10 ) -> Result<OverflowFlags, MissingInstructionInput> {
11 if inputs.try_get_overflow()?.so {
17 macro_rules! create_instr_variants_ov_cr {
18 ($fn:ident, $fno:ident, $fn_:ident, $fno_:ident, $iwidth:ident) => {
19 pub fn $fn(mut inputs: InstructionInput) -> InstructionResult {
20 inputs.overflow = Some(OverflowFlags::default());
21 Ok(InstructionOutput {
26 pub fn $fn_(inputs: InstructionInput) -> InstructionResult {
27 let mut retval = $fno_(inputs)?;
28 let mut cr0 = retval.cr0.as_mut().expect("expected cr0 to be set");
29 cr0.so = inputs.try_get_overflow()?.so;
30 retval.overflow = None;
33 pub fn $fno_(inputs: InstructionInput) -> InstructionResult {
34 let mut retval = $fno(inputs)?;
35 let result = retval.rt.expect("expected rt to be set");
36 let so = retval.overflow.expect("expected overflow to be set").so;
37 let cr0 = ConditionRegister::from_signed_int(result as $iwidth, so);
38 retval.cr0 = Some(cr0);
44 macro_rules! create_instr_variants_cr {
45 ($fn:ident, $fn_:ident, $iwidth:ident) => {
46 pub fn $fn_(inputs: InstructionInput) -> InstructionResult {
47 let mut retval = $fn(inputs)?;
48 let result = retval.rt.expect("expected rt to be set");
49 let cr0 = ConditionRegister::from_signed_int(
51 inputs.try_get_overflow()?.so,
53 retval.cr0 = Some(cr0);
59 pub fn addi(inputs: InstructionInput) -> InstructionResult {
60 let ra = inputs.try_get_ra()? as i64;
61 let immediate = inputs.try_get_immediate_s16()? as i64;
62 let result = ra.wrapping_add(immediate) as u64;
63 Ok(InstructionOutput {
65 ..InstructionOutput::default()
69 pub fn addis(inputs: InstructionInput) -> InstructionResult {
70 let ra = inputs.try_get_ra()? as i64;
71 let immediate = inputs.try_get_immediate_s16()? as i64;
72 let result = ra.wrapping_add(immediate << 16) as u64;
73 Ok(InstructionOutput {
75 ..InstructionOutput::default()
79 create_instr_variants_ov_cr!(add, addo, add_, addo_, i64);
81 pub fn addo(inputs: InstructionInput) -> InstructionResult {
82 let ra = inputs.try_get_ra()? as i64;
83 let rb = inputs.try_get_rb()? as i64;
84 let (result, ov) = ra.overflowing_add(rb);
85 let result = result as u64;
86 let ov32 = (ra as i32).overflowing_add(rb as i32).1;
87 Ok(InstructionOutput {
89 overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
90 ..InstructionOutput::default()
94 create_instr_variants_cr!(addic, addic_, i64);
96 pub fn addic(inputs: InstructionInput) -> InstructionResult {
97 let ra = inputs.try_get_ra()? as i64;
98 let immediate = inputs.try_get_immediate_s16()? as i64;
99 let result = ra.wrapping_add(immediate) as u64;
100 let ca = (ra as u64).overflowing_add(immediate as u64).1;
101 let ca32 = (ra as u32).overflowing_add(immediate as u32).1;
102 Ok(InstructionOutput {
104 carry: Some(CarryFlags { ca, ca32 }),
105 ..InstructionOutput::default()
109 create_instr_variants_ov_cr!(subf, subfo, subf_, subfo_, i64);
111 pub fn subfo(inputs: InstructionInput) -> InstructionResult {
112 let ra = inputs.try_get_ra()? as i64;
113 let rb = inputs.try_get_rb()? as i64;
114 let (result, ov) = rb.overflowing_sub(ra);
115 let result = result as u64;
116 let ov32 = (rb as i32).overflowing_sub(ra as i32).1;
117 Ok(InstructionOutput {
119 overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
120 ..InstructionOutput::default()
124 create_instr_variants_ov_cr!(addc, addco, addc_, addco_, i64);
126 pub fn addco(inputs: InstructionInput) -> InstructionResult {
127 let ra = inputs.try_get_ra()? as i64;
128 let rb = inputs.try_get_rb()? as i64;
129 let (result, ov) = ra.overflowing_add(rb);
130 let result = result as u64;
131 let ov32 = (ra as i32).overflowing_add(rb as i32).1;
132 let ca = (ra as u64).overflowing_add(rb as u64).1;
133 let ca32 = (ra as u32).overflowing_add(rb as u32).1;
134 Ok(InstructionOutput {
136 overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
137 carry: Some(CarryFlags { ca, ca32 }),
138 ..InstructionOutput::default()
142 create_instr_variants_ov_cr!(subfc, subfco, subfc_, subfco_, i64);
144 pub fn subfco(inputs: InstructionInput) -> InstructionResult {
145 let ra = inputs.try_get_ra()? as i64;
146 let rb = inputs.try_get_rb()? as i64;
147 let (result, ov) = rb.overflowing_sub(ra);
148 let result = result as u64;
149 let ov32 = (rb as i32).overflowing_sub(ra as i32).1;
150 let ca = !(rb as u64).overflowing_sub(ra as u64).1;
151 let ca32 = !(rb as u32).overflowing_sub(ra as u32).1;
152 Ok(InstructionOutput {
154 overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
155 carry: Some(CarryFlags { ca, ca32 }),
156 ..InstructionOutput::default()
160 create_instr_variants_ov_cr!(adde, addeo, adde_, addeo_, i64);
162 pub fn addeo(inputs: InstructionInput) -> InstructionResult {
163 let ra: u64 = inputs.try_get_ra()?;
164 let rb: u64 = inputs.try_get_rb()?;
165 let carry_in = inputs.try_get_carry()?.ca;
166 let result_i128 = ra as i64 as i128 + rb as i64 as i128 + carry_in as i128;
167 let result_u128 = ra as u128 + rb as u128 + carry_in as u128;
168 let result32_i128 = ra as i32 as i128 + rb as i32 as i128 + carry_in as i128;
169 let result32_u128 = ra as u32 as u128 + rb as u32 as u128 + carry_in as u128;
170 let result = result_u128 as u64;
171 let ov = i64::try_from(result_i128).is_err();
172 let ov32 = i32::try_from(result32_i128).is_err();
173 let ca = u64::try_from(result_u128).is_err();
174 let ca32 = u32::try_from(result32_u128).is_err();
175 Ok(InstructionOutput {
177 overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
178 carry: Some(CarryFlags { ca, ca32 }),
179 ..InstructionOutput::default()
183 create_instr_variants_ov_cr!(subfe, subfeo, subfe_, subfeo_, i64);
185 pub fn subfeo(inputs: InstructionInput) -> InstructionResult {
186 let ra: u64 = inputs.try_get_ra()?;
187 let rb: u64 = inputs.try_get_rb()?;
188 let carry_in = inputs.try_get_carry()?.ca;
190 let result_i128 = not_ra as i64 as i128 + rb as i64 as i128 + carry_in as i128;
191 let result_u128 = not_ra as u128 + rb as u128 + carry_in as u128;
192 let result32_i128 = not_ra as i32 as i128 + rb as i32 as i128 + carry_in as i128;
193 let result32_u128 = not_ra as u32 as u128 + rb as u32 as u128 + carry_in as u128;
194 let result = result_u128 as u64;
195 let ov = i64::try_from(result_i128).is_err();
196 let ov32 = i32::try_from(result32_i128).is_err();
197 let ca = u64::try_from(result_u128).is_err();
198 let ca32 = u32::try_from(result32_u128).is_err();
199 Ok(InstructionOutput {
201 overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
202 carry: Some(CarryFlags { ca, ca32 }),
203 ..InstructionOutput::default()
207 create_instr_variants_ov_cr!(addme, addmeo, addme_, addmeo_, i64);
209 pub fn addmeo(inputs: InstructionInput) -> InstructionResult {
210 let ra: u64 = inputs.try_get_ra()?;
212 let carry_in = inputs.try_get_carry()?.ca;
213 let result_i128 = ra as i64 as i128 + rb as i64 as i128 + carry_in as i128;
214 let result_u128 = ra as u128 + rb as u128 + carry_in as u128;
215 let result32_i128 = ra as i32 as i128 + rb as i32 as i128 + carry_in as i128;
216 let result32_u128 = ra as u32 as u128 + rb as u32 as u128 + carry_in as u128;
217 let result = result_u128 as u64;
218 let ov = i64::try_from(result_i128).is_err();
219 let ov32 = i32::try_from(result32_i128).is_err();
220 let ca = u64::try_from(result_u128).is_err();
221 let ca32 = u32::try_from(result32_u128).is_err();
222 Ok(InstructionOutput {
224 overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
225 carry: Some(CarryFlags { ca, ca32 }),
226 ..InstructionOutput::default()
230 create_instr_variants_ov_cr!(subfme, subfmeo, subfme_, subfmeo_, i64);
232 pub fn subfmeo(inputs: InstructionInput) -> InstructionResult {
233 let ra: u64 = inputs.try_get_ra()?;
235 let carry_in = inputs.try_get_carry()?.ca;
237 let result_i128 = not_ra as i64 as i128 + rb as i64 as i128 + carry_in as i128;
238 let result_u128 = not_ra as u128 + rb as u128 + carry_in as u128;
239 let result32_i128 = not_ra as i32 as i128 + rb as i32 as i128 + carry_in as i128;
240 let result32_u128 = not_ra as u32 as u128 + rb as u32 as u128 + carry_in as u128;
241 let result = result_u128 as u64;
242 let ov = i64::try_from(result_i128).is_err();
243 let ov32 = i32::try_from(result32_i128).is_err();
244 let ca = u64::try_from(result_u128).is_err();
245 let ca32 = u32::try_from(result32_u128).is_err();
246 Ok(InstructionOutput {
248 overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
249 carry: Some(CarryFlags { ca, ca32 }),
250 ..InstructionOutput::default()
254 create_instr_variants_ov_cr!(addze, addzeo, addze_, addzeo_, i64);
256 pub fn addzeo(inputs: InstructionInput) -> InstructionResult {
257 let ra: u64 = inputs.try_get_ra()?;
258 let carry_in = inputs.try_get_carry()?.ca;
259 let result_i128 = ra as i64 as i128 + carry_in as i128;
260 let result_u128 = ra as u128 + carry_in as u128;
261 let result32_i128 = ra as i32 as i128 + carry_in as i128;
262 let result32_u128 = ra as u32 as u128 + carry_in as u128;
263 let result = result_u128 as u64;
264 let ov = i64::try_from(result_i128).is_err();
265 let ov32 = i32::try_from(result32_i128).is_err();
266 let ca = u64::try_from(result_u128).is_err();
267 let ca32 = u32::try_from(result32_u128).is_err();
268 Ok(InstructionOutput {
270 overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
271 carry: Some(CarryFlags { ca, ca32 }),
272 ..InstructionOutput::default()
276 create_instr_variants_ov_cr!(subfze, subfzeo, subfze_, subfzeo_, i64);
278 pub fn subfzeo(inputs: InstructionInput) -> InstructionResult {
279 let ra: u64 = inputs.try_get_ra()?;
280 let carry_in = inputs.try_get_carry()?.ca;
282 let result_i128 = not_ra as i64 as i128 + carry_in as i128;
283 let result_u128 = not_ra as u128 + carry_in as u128;
284 let result32_i128 = not_ra as i32 as i128 + carry_in as i128;
285 let result32_u128 = not_ra as u32 as u128 + carry_in as u128;
286 let result = result_u128 as u64;
287 let ov = i64::try_from(result_i128).is_err();
288 let ov32 = i32::try_from(result32_i128).is_err();
289 let ca = u64::try_from(result_u128).is_err();
290 let ca32 = u32::try_from(result32_u128).is_err();
291 Ok(InstructionOutput {
293 overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
294 carry: Some(CarryFlags { ca, ca32 }),
295 ..InstructionOutput::default()
299 pub fn addex(inputs: InstructionInput) -> InstructionResult {
300 let ra: u64 = inputs.try_get_ra()?;
301 let rb: u64 = inputs.try_get_rb()?;
304 } = inputs.try_get_overflow()?;
305 let result_u128 = ra as u128 + rb as u128 + carry_in as u128;
306 let result32_u128 = ra as u32 as u128 + rb as u32 as u128 + carry_in as u128;
307 let result = result_u128 as u64;
308 let carry = u64::try_from(result_u128).is_err();
309 let carry32 = u32::try_from(result32_u128).is_err();
310 Ok(InstructionOutput {
312 // doesn't change `so` on purpose
313 overflow: Some(OverflowFlags {
318 ..InstructionOutput::default()
322 create_instr_variants_ov_cr!(neg, nego, neg_, nego_, i64);
324 pub fn nego(inputs: InstructionInput) -> InstructionResult {
325 let ra = inputs.try_get_ra()? as i64;
326 let result = ra.wrapping_neg() as u64;
327 let ov = ra.checked_neg().is_none();
328 let ov32 = (ra as i32).checked_neg().is_none();
329 Ok(InstructionOutput {
331 overflow: Some(propagate_so(OverflowFlags { so: ov, ov, ov32 }, inputs)?),
332 ..InstructionOutput::default()
336 create_instr_variants_ov_cr!(divde, divdeo, divde_, divdeo_, i64);
338 pub fn divdeo(inputs: InstructionInput) -> InstructionResult {
339 let dividend = i128::from(inputs.try_get_ra()? as i64) << 64;
340 let divisor = i128::from(inputs.try_get_rb()? as i64);
343 if divisor == 0 || (divisor == -1 && dividend == i128::min_value()) {
347 let result128 = dividend / divisor;
348 if result128 as i64 as i128 != result128 {
352 result = result128 as u64;
356 Ok(InstructionOutput {
358 overflow: Some(propagate_so(
359 OverflowFlags::from_overflow(overflow),
362 ..InstructionOutput::default()
366 create_instr_variants_ov_cr!(divdeu, divdeuo, divdeu_, divdeuo_, i64);
368 pub fn divdeuo(inputs: InstructionInput) -> InstructionResult {
369 let dividend = u128::from(inputs.try_get_ra()?) << 64;
370 let divisor = u128::from(inputs.try_get_rb()?);
377 let resultu128 = dividend / divisor;
378 if resultu128 > u128::from(u64::max_value()) {
382 result = resultu128 as u64;
386 Ok(InstructionOutput {
388 overflow: Some(propagate_so(
389 OverflowFlags::from_overflow(overflow),
392 ..InstructionOutput::default()
396 create_instr_variants_ov_cr!(divd, divdo, divd_, divdo_, i64);
398 pub fn divdo(inputs: InstructionInput) -> InstructionResult {
399 let dividend = inputs.try_get_ra()? as i64;
400 let divisor = inputs.try_get_rb()? as i64;
403 if divisor == 0 || (divisor == -1 && dividend == i64::min_value()) {
407 result = (dividend / divisor) as u64;
410 Ok(InstructionOutput {
412 overflow: Some(propagate_so(
413 OverflowFlags::from_overflow(overflow),
416 ..InstructionOutput::default()
420 create_instr_variants_ov_cr!(divdu, divduo, divdu_, divduo_, i64);
422 pub fn divduo(inputs: InstructionInput) -> InstructionResult {
423 let dividend: u64 = inputs.try_get_ra()?;
424 let divisor: u64 = inputs.try_get_rb()?;
431 result = dividend / divisor;
434 Ok(InstructionOutput {
436 overflow: Some(propagate_so(
437 OverflowFlags::from_overflow(overflow),
440 ..InstructionOutput::default()
444 // ISA doesn't define compare results -- POWER9 apparently uses i64 instead of i32
445 create_instr_variants_ov_cr!(divwe, divweo, divwe_, divweo_, i64);
447 pub fn divweo(inputs: InstructionInput) -> InstructionResult {
448 let dividend = i64::from(inputs.try_get_ra()? as i32) << 32;
449 let divisor = i64::from(inputs.try_get_rb()? as i32);
452 if divisor == 0 || (divisor == -1 && dividend == i64::min_value()) {
456 let result64 = dividend / divisor;
457 if result64 as i32 as i64 != result64 {
461 result = result64 as u32 as u64;
465 Ok(InstructionOutput {
467 overflow: Some(propagate_so(
468 OverflowFlags::from_overflow(overflow),
471 ..InstructionOutput::default()
475 // ISA doesn't define compare results -- POWER9 apparently uses i64 instead of i32
476 create_instr_variants_ov_cr!(divweu, divweuo, divweu_, divweuo_, i64);
478 pub fn divweuo(inputs: InstructionInput) -> InstructionResult {
479 let dividend = u64::from(inputs.try_get_ra()? as u32) << 32;
480 let divisor = u64::from(inputs.try_get_rb()? as u32);
487 let resultu64 = dividend / divisor;
488 if resultu64 > u64::from(u32::max_value()) {
492 result = resultu64 as u32 as u64;
496 Ok(InstructionOutput {
498 overflow: Some(propagate_so(
499 OverflowFlags::from_overflow(overflow),
502 ..InstructionOutput::default()
506 // ISA doesn't define compare results -- POWER9 apparently uses i64 instead of i32
507 create_instr_variants_ov_cr!(divw, divwo, divw_, divwo_, i64);
509 pub fn divwo(inputs: InstructionInput) -> InstructionResult {
510 let dividend = inputs.try_get_ra()? as i32;
511 let divisor = inputs.try_get_rb()? as i32;
514 if divisor == 0 || (divisor == -1 && dividend == i32::min_value()) {
518 result = (dividend / divisor) as u32 as u64;
521 Ok(InstructionOutput {
523 overflow: Some(propagate_so(
524 OverflowFlags::from_overflow(overflow),
527 ..InstructionOutput::default()
531 // ISA doesn't define compare results -- POWER9 apparently uses i64 instead of i32
532 create_instr_variants_ov_cr!(divwu, divwuo, divwu_, divwuo_, i64);
534 pub fn divwuo(inputs: InstructionInput) -> InstructionResult {
535 let dividend = inputs.try_get_ra()? as u32;
536 let divisor = inputs.try_get_rb()? as u32;
543 result = (dividend / divisor) as u64;
546 Ok(InstructionOutput {
548 overflow: Some(propagate_so(
549 OverflowFlags::from_overflow(overflow),
552 ..InstructionOutput::default()
556 pub fn modsd(inputs: InstructionInput) -> InstructionResult {
557 let dividend = inputs.try_get_ra()? as i64;
558 let divisor = inputs.try_get_rb()? as i64;
560 if divisor == 0 || (divisor == -1 && dividend == i64::min_value()) {
563 result = (dividend % divisor) as u64;
565 Ok(InstructionOutput {
567 ..InstructionOutput::default()
571 pub fn modud(inputs: InstructionInput) -> InstructionResult {
572 let dividend: u64 = inputs.try_get_ra()?;
573 let divisor: u64 = inputs.try_get_rb()?;
578 result = dividend % divisor;
580 Ok(InstructionOutput {
582 ..InstructionOutput::default()
586 pub fn modsw(inputs: InstructionInput) -> InstructionResult {
587 let dividend = inputs.try_get_ra()? as i32;
588 let divisor = inputs.try_get_rb()? as i32;
590 if divisor == 0 || (divisor == -1 && dividend == i32::min_value()) {
593 result = (dividend % divisor) as u64;
595 Ok(InstructionOutput {
597 ..InstructionOutput::default()
601 pub fn moduw(inputs: InstructionInput) -> InstructionResult {
602 let dividend = inputs.try_get_ra()? as u32;
603 let divisor = inputs.try_get_rb()? as u32;
608 result = (dividend % divisor) as u64;
610 Ok(InstructionOutput {
612 ..InstructionOutput::default()
616 create_instr_variants_ov_cr!(mullw, mullwo, mullw_, mullwo_, i64);
618 pub fn mullwo(inputs: InstructionInput) -> InstructionResult {
619 let ra = inputs.try_get_ra()? as i32 as i64;
620 let rb = inputs.try_get_rb()? as i32 as i64;
621 let result = ra.wrapping_mul(rb) as u64;
622 let overflow = result as i32 as i64 != result as i64;
623 Ok(InstructionOutput {
625 overflow: Some(propagate_so(
626 OverflowFlags::from_overflow(overflow),
629 ..InstructionOutput::default()
633 create_instr_variants_cr!(mulhw, mulhw_, i32);
635 pub fn mulhw(inputs: InstructionInput) -> InstructionResult {
636 let ra = inputs.try_get_ra()? as i32 as i64;
637 let rb = inputs.try_get_rb()? as i32 as i64;
638 let result = (ra * rb) >> 32;
639 let mut result = result as u32 as u64;
640 result |= result << 32;
641 Ok(InstructionOutput {
643 ..InstructionOutput::default()
647 create_instr_variants_cr!(mulhwu, mulhwu_, i32);
649 pub fn mulhwu(inputs: InstructionInput) -> InstructionResult {
650 let ra = inputs.try_get_ra()? as u32 as u64;
651 let rb = inputs.try_get_rb()? as u32 as u64;
652 let result = (ra * rb) >> 32;
653 let mut result = result as u32 as u64;
654 result |= result << 32;
655 Ok(InstructionOutput {
657 ..InstructionOutput::default()
661 create_instr_variants_ov_cr!(mulld, mulldo, mulld_, mulldo_, i64);
663 pub fn mulldo(inputs: InstructionInput) -> InstructionResult {
664 let ra = inputs.try_get_ra()? as i64;
665 let rb = inputs.try_get_rb()? as i64;
666 let result = ra.wrapping_mul(rb) as u64;
667 let overflow = ra.checked_mul(rb).is_none();
668 Ok(InstructionOutput {
670 overflow: Some(propagate_so(
671 OverflowFlags::from_overflow(overflow),
674 ..InstructionOutput::default()
678 create_instr_variants_cr!(mulhd, mulhd_, i64);
680 pub fn mulhd(inputs: InstructionInput) -> InstructionResult {
681 let ra = inputs.try_get_ra()? as i64 as i128;
682 let rb = inputs.try_get_rb()? as i64 as i128;
683 let result = ((ra * rb) >> 64) as i64;
684 let result = result as u64;
685 Ok(InstructionOutput {
687 ..InstructionOutput::default()
691 create_instr_variants_cr!(mulhdu, mulhdu_, i64);
693 pub fn mulhdu(inputs: InstructionInput) -> InstructionResult {
694 let ra = inputs.try_get_ra()? as u128;
695 let rb = inputs.try_get_rb()? as u128;
696 let result = ((ra * rb) >> 64) as u64;
697 Ok(InstructionOutput {
699 ..InstructionOutput::default()
703 pub fn maddhd(inputs: InstructionInput) -> InstructionResult {
704 let ra = inputs.try_get_ra()? as i64 as i128;
705 let rb = inputs.try_get_rb()? as i64 as i128;
706 let rc = inputs.try_get_rc()? as i64 as i128;
707 let result = ((ra * rb + rc) >> 64) as u64;
708 Ok(InstructionOutput {
710 ..InstructionOutput::default()
714 pub fn maddhdu(inputs: InstructionInput) -> InstructionResult {
715 let ra = inputs.try_get_ra()? as u128;
716 let rb = inputs.try_get_rb()? as u128;
717 let rc = inputs.try_get_rc()? as u128;
718 let result = ((ra * rb + rc) >> 64) as u64;
719 Ok(InstructionOutput {
721 ..InstructionOutput::default()
725 pub fn maddld(inputs: InstructionInput) -> InstructionResult {
726 let ra = inputs.try_get_ra()? as i64;
727 let rb = inputs.try_get_rb()? as i64;
728 let rc = inputs.try_get_rc()? as i64;
729 let result = ra.wrapping_mul(rb).wrapping_add(rc) as u64;
730 Ok(InstructionOutput {
732 ..InstructionOutput::default()