1use {
4 crate::{approximations::sqrt, instruction::MathInstruction, precise_number::PreciseNumber},
5 borsh::BorshDeserialize,
6 gemachain_program::{
7 account_info::AccountInfo, entrypoint::ProgramResult, log::gema_log_compute_units, msg,
8 pubkey::Pubkey,
9 },
10};
11
12#[inline(never)]
14fn u64_multiply(multiplicand: u64, multiplier: u64) -> u64 {
15 multiplicand * multiplier
16}
17
18#[inline(never)]
20fn u64_divide(dividend: u64, divisor: u64) -> u64 {
21 dividend / divisor
22}
23
24#[inline(never)]
26fn f32_multiply(multiplicand: f32, multiplier: f32) -> f32 {
27 multiplicand * multiplier
28}
29
30#[inline(never)]
32fn f32_divide(dividend: f32, divisor: f32) -> f32 {
33 dividend / divisor
34}
35
36pub fn process_instruction(
38 _program_id: &Pubkey,
39 _accounts: &[AccountInfo],
40 input: &[u8],
41) -> ProgramResult {
42 let instruction = MathInstruction::try_from_slice(input).unwrap();
43 match instruction {
44 MathInstruction::PreciseSquareRoot { radicand } => {
45 msg!("Calculating square root using PreciseNumber");
46 let radicand = PreciseNumber::new(radicand as u128).unwrap();
47 gema_log_compute_units();
48 let result = radicand.sqrt().unwrap().to_imprecise().unwrap() as u64;
49 gema_log_compute_units();
50 msg!("{}", result);
51 Ok(())
52 }
53 MathInstruction::SquareRootU64 { radicand } => {
54 msg!("Calculating u64 square root");
55 gema_log_compute_units();
56 let result = sqrt(radicand).unwrap();
57 gema_log_compute_units();
58 msg!("{}", result);
59 Ok(())
60 }
61 MathInstruction::SquareRootU128 { radicand } => {
62 msg!("Calculating u128 square root");
63 gema_log_compute_units();
64 let result = sqrt(radicand).unwrap();
65 gema_log_compute_units();
66 msg!("{}", result);
67 Ok(())
68 }
69 MathInstruction::U64Multiply {
70 multiplicand,
71 multiplier,
72 } => {
73 msg!("Calculating U64 Multiply");
74 gema_log_compute_units();
75 let result = u64_multiply(multiplicand, multiplier);
76 gema_log_compute_units();
77 msg!("{}", result);
78 Ok(())
79 }
80 MathInstruction::U64Divide { dividend, divisor } => {
81 msg!("Calculating U64 Divide");
82 gema_log_compute_units();
83 let result = u64_divide(dividend, divisor);
84 gema_log_compute_units();
85 msg!("{}", result);
86 Ok(())
87 }
88 MathInstruction::F32Multiply {
89 multiplicand,
90 multiplier,
91 } => {
92 msg!("Calculating f32 Multiply");
93 gema_log_compute_units();
94 let result = f32_multiply(multiplicand, multiplier);
95 gema_log_compute_units();
96 msg!("{}", result as u64);
97 Ok(())
98 }
99 MathInstruction::F32Divide { dividend, divisor } => {
100 msg!("Calculating f32 Divide");
101 gema_log_compute_units();
102 let result = f32_divide(dividend, divisor);
103 gema_log_compute_units();
104 msg!("{}", result as u64);
105 Ok(())
106 }
107 MathInstruction::Noop => {
108 msg!("Do nothing");
109 msg!("{}", 0_u64);
110 Ok(())
111 }
112 }
113}