@@ -244,6 +244,48 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
244244 let left = expression ( target, bin, left, vartab, function) . into_int_value ( ) ;
245245 let right = expression ( target, bin, right, vartab, function) . into_int_value ( ) ;
246246
247+ // smoelius: If the target is Stylus and `left` and `right` are both `uint256`s, we can
248+ // use the `math_div` import.
249+ if bin. ns . target == Target :: Stylus
250+ && left. get_type ( ) . get_bit_width ( ) == 256
251+ && right. get_type ( ) . get_bit_width ( ) == 256
252+ {
253+ let left_unswapped_ptr =
254+ bin. build_alloca ( function, bin. value_type ( ) , "left_unswapped_ptr" ) ;
255+ let right_unswapped_ptr =
256+ bin. build_alloca ( function, bin. value_type ( ) , "right_unswapped_ptr" ) ;
257+ let left_swapped_ptr =
258+ bin. build_alloca ( function, bin. value_type ( ) , "left_swapped_ptr" ) ;
259+ let right_swapped_ptr =
260+ bin. build_alloca ( function, bin. value_type ( ) , "right_swapped_ptr" ) ;
261+ bin. builder . build_store ( left_unswapped_ptr, left) . unwrap ( ) ;
262+ bin. builder . build_store ( right_unswapped_ptr, right) . unwrap ( ) ;
263+ byte_swap_value (
264+ bin,
265+ & Type :: Uint ( 256 ) ,
266+ left_unswapped_ptr,
267+ left_swapped_ptr,
268+ true ,
269+ ) ;
270+ byte_swap_value (
271+ bin,
272+ & Type :: Uint ( 256 ) ,
273+ right_unswapped_ptr,
274+ right_swapped_ptr,
275+ true ,
276+ ) ;
277+ call ! (
278+ "math_div" ,
279+ & [ left_swapped_ptr. into( ) , right_swapped_ptr. into( ) , ]
280+ ) ;
281+ let quotient_ptr = bin. build_alloca ( function, bin. value_type ( ) , "quotient_ptr" ) ;
282+ byte_swap_value ( bin, & Type :: Uint ( 256 ) , left_swapped_ptr, quotient_ptr, false ) ;
283+ return bin
284+ . builder
285+ . build_load ( bin. value_type ( ) , quotient_ptr, "quotient" )
286+ . unwrap ( ) ;
287+ }
288+
247289 let bits = left. get_type ( ) . get_bit_width ( ) ;
248290
249291 if bits > 64 {
@@ -513,6 +555,54 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
513555 let left = expression ( target, bin, left, vartab, function) . into_int_value ( ) ;
514556 let right = expression ( target, bin, right, vartab, function) . into_int_value ( ) ;
515557
558+ // smoelius: If the target is Stylus and `left` and `right` are both `uint256`s, we can
559+ // use the `math_mod` import.
560+ if bin. ns . target == Target :: Stylus
561+ && left. get_type ( ) . get_bit_width ( ) == 256
562+ && right. get_type ( ) . get_bit_width ( ) == 256
563+ {
564+ let left_unswapped_ptr =
565+ bin. build_alloca ( function, bin. value_type ( ) , "left_unswapped_ptr" ) ;
566+ let right_unswapped_ptr =
567+ bin. build_alloca ( function, bin. value_type ( ) , "right_unswapped_ptr" ) ;
568+ let left_swapped_ptr =
569+ bin. build_alloca ( function, bin. value_type ( ) , "left_swapped_ptr" ) ;
570+ let right_swapped_ptr =
571+ bin. build_alloca ( function, bin. value_type ( ) , "right_swapped_ptr" ) ;
572+ bin. builder . build_store ( left_unswapped_ptr, left) . unwrap ( ) ;
573+ bin. builder . build_store ( right_unswapped_ptr, right) . unwrap ( ) ;
574+ byte_swap_value (
575+ bin,
576+ & Type :: Uint ( 256 ) ,
577+ left_unswapped_ptr,
578+ left_swapped_ptr,
579+ true ,
580+ ) ;
581+ byte_swap_value (
582+ bin,
583+ & Type :: Uint ( 256 ) ,
584+ right_unswapped_ptr,
585+ right_swapped_ptr,
586+ true ,
587+ ) ;
588+ call ! (
589+ "math_mod" ,
590+ & [ left_swapped_ptr. into( ) , right_swapped_ptr. into( ) , ]
591+ ) ;
592+ let remainder_ptr = bin. build_alloca ( function, bin. value_type ( ) , "remainder_ptr" ) ;
593+ byte_swap_value (
594+ bin,
595+ & Type :: Uint ( 256 ) ,
596+ left_swapped_ptr,
597+ remainder_ptr,
598+ false ,
599+ ) ;
600+ return bin
601+ . builder
602+ . build_load ( bin. value_type ( ) , remainder_ptr, "remainder" )
603+ . unwrap ( ) ;
604+ }
605+
516606 let bits = left. get_type ( ) . get_bit_width ( ) ;
517607
518608 if bits > 64 {
@@ -782,6 +872,48 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
782872 let left = expression ( target, bin, l, vartab, function) ;
783873 let right = expression ( target, bin, r, vartab, function) ;
784874
875+ // smoelius: If the target is Stylus and `left` and `right` are both `uint256`s, we can
876+ // use the `math_pow` import.
877+ if bin. ns . target == Target :: Stylus
878+ && left. into_int_value ( ) . get_type ( ) . get_bit_width ( ) == 256
879+ && right. into_int_value ( ) . get_type ( ) . get_bit_width ( ) == 256
880+ {
881+ let left_unswapped_ptr =
882+ bin. build_alloca ( function, bin. value_type ( ) , "left_unswapped_ptr" ) ;
883+ let right_unswapped_ptr =
884+ bin. build_alloca ( function, bin. value_type ( ) , "right_unswapped_ptr" ) ;
885+ let left_swapped_ptr =
886+ bin. build_alloca ( function, bin. value_type ( ) , "left_swapped_ptr" ) ;
887+ let right_swapped_ptr =
888+ bin. build_alloca ( function, bin. value_type ( ) , "right_swapped_ptr" ) ;
889+ bin. builder . build_store ( left_unswapped_ptr, left) . unwrap ( ) ;
890+ bin. builder . build_store ( right_unswapped_ptr, right) . unwrap ( ) ;
891+ byte_swap_value (
892+ bin,
893+ & Type :: Uint ( 256 ) ,
894+ left_unswapped_ptr,
895+ left_swapped_ptr,
896+ true ,
897+ ) ;
898+ byte_swap_value (
899+ bin,
900+ & Type :: Uint ( 256 ) ,
901+ right_unswapped_ptr,
902+ right_swapped_ptr,
903+ true ,
904+ ) ;
905+ call ! (
906+ "math_pow" ,
907+ & [ left_swapped_ptr. into( ) , right_swapped_ptr. into( ) , ]
908+ ) ;
909+ let power_ptr = bin. build_alloca ( function, bin. value_type ( ) , "power_ptr" ) ;
910+ byte_swap_value ( bin, & Type :: Uint ( 256 ) , left_swapped_ptr, power_ptr, false ) ;
911+ return bin
912+ . builder
913+ . build_load ( bin. value_type ( ) , power_ptr, "power" )
914+ . unwrap ( ) ;
915+ }
916+
785917 let bits = left. into_int_value ( ) . get_type ( ) . get_bit_width ( ) ;
786918 let o = bin. build_alloca ( function, left. get_type ( ) , "" ) ;
787919 let f = power (
0 commit comments