@@ -1757,12 +1757,45 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
17571757 args,
17581758 ..
17591759 } => {
1760- let arith_ty = bin. context . custom_width_int_type ( 512 ) ;
1761- let res_ty = bin. context . custom_width_int_type ( 256 ) ;
1762-
17631760 let x = expression ( target, bin, & args[ 0 ] , vartab, function) . into_int_value ( ) ;
17641761 let y = expression ( target, bin, & args[ 1 ] , vartab, function) . into_int_value ( ) ;
17651762 let k = expression ( target, bin, & args[ 2 ] , vartab, function) . into_int_value ( ) ;
1763+
1764+ if bin. ns . target == Target :: Stylus {
1765+ let x_unswapped_ptr =
1766+ bin. build_alloca ( function, bin. value_type ( ) , "x_unswapped_ptr" ) ;
1767+ let y_unswapped_ptr =
1768+ bin. build_alloca ( function, bin. value_type ( ) , "y_unswapped_ptr" ) ;
1769+ let k_unswapped_ptr =
1770+ bin. build_alloca ( function, bin. value_type ( ) , "k_unswapped_ptr" ) ;
1771+ let x_swapped_ptr = bin. build_alloca ( function, bin. value_type ( ) , "x_swapped_ptr" ) ;
1772+ let y_swapped_ptr = bin. build_alloca ( function, bin. value_type ( ) , "y_swapped_ptr" ) ;
1773+ let k_swapped_ptr = bin. build_alloca ( function, bin. value_type ( ) , "k_swapped_ptr" ) ;
1774+ bin. builder . build_store ( x_unswapped_ptr, x) . unwrap ( ) ;
1775+ bin. builder . build_store ( y_unswapped_ptr, y) . unwrap ( ) ;
1776+ bin. builder . build_store ( k_unswapped_ptr, k) . unwrap ( ) ;
1777+ byte_swap_value ( bin, & Type :: Uint ( 256 ) , x_unswapped_ptr, x_swapped_ptr, true ) ;
1778+ byte_swap_value ( bin, & Type :: Uint ( 256 ) , y_unswapped_ptr, y_swapped_ptr, true ) ;
1779+ byte_swap_value ( bin, & Type :: Uint ( 256 ) , k_unswapped_ptr, k_swapped_ptr, true ) ;
1780+ call ! (
1781+ "math_add_mod" ,
1782+ & [
1783+ x_swapped_ptr. into( ) ,
1784+ y_swapped_ptr. into( ) ,
1785+ k_swapped_ptr. into( )
1786+ ]
1787+ ) ;
1788+ let sum_ptr = bin. build_alloca ( function, bin. value_type ( ) , "sum_ptr" ) ;
1789+ byte_swap_value ( bin, & Type :: Uint ( 256 ) , x_swapped_ptr, sum_ptr, false ) ;
1790+ return bin
1791+ . builder
1792+ . build_load ( bin. value_type ( ) , sum_ptr, "sum" )
1793+ . unwrap ( ) ;
1794+ }
1795+
1796+ let arith_ty = bin. context . custom_width_int_type ( 512 ) ;
1797+ let res_ty = bin. context . custom_width_int_type ( 256 ) ;
1798+
17661799 let dividend = bin
17671800 . builder
17681801 . build_int_add (
@@ -1855,11 +1888,45 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
18551888 args,
18561889 ..
18571890 } => {
1891+ let x = expression ( target, bin, & args[ 0 ] , vartab, function) . into_int_value ( ) ;
1892+ let y = expression ( target, bin, & args[ 1 ] , vartab, function) . into_int_value ( ) ;
1893+ let k = expression ( target, bin, & args[ 2 ] , vartab, function) . into_int_value ( ) ;
1894+
1895+ if bin. ns . target == Target :: Stylus {
1896+ let x_unswapped_ptr =
1897+ bin. build_alloca ( function, bin. value_type ( ) , "x_unswapped_ptr" ) ;
1898+ let y_unswapped_ptr =
1899+ bin. build_alloca ( function, bin. value_type ( ) , "y_unswapped_ptr" ) ;
1900+ let k_unswapped_ptr =
1901+ bin. build_alloca ( function, bin. value_type ( ) , "k_unswapped_ptr" ) ;
1902+ let x_swapped_ptr = bin. build_alloca ( function, bin. value_type ( ) , "x_swapped_ptr" ) ;
1903+ let y_swapped_ptr = bin. build_alloca ( function, bin. value_type ( ) , "y_swapped_ptr" ) ;
1904+ let k_swapped_ptr = bin. build_alloca ( function, bin. value_type ( ) , "k_swapped_ptr" ) ;
1905+ bin. builder . build_store ( x_unswapped_ptr, x) . unwrap ( ) ;
1906+ bin. builder . build_store ( y_unswapped_ptr, y) . unwrap ( ) ;
1907+ bin. builder . build_store ( k_unswapped_ptr, k) . unwrap ( ) ;
1908+ byte_swap_value ( bin, & Type :: Uint ( 256 ) , x_unswapped_ptr, x_swapped_ptr, true ) ;
1909+ byte_swap_value ( bin, & Type :: Uint ( 256 ) , y_unswapped_ptr, y_swapped_ptr, true ) ;
1910+ byte_swap_value ( bin, & Type :: Uint ( 256 ) , k_unswapped_ptr, k_swapped_ptr, true ) ;
1911+ call ! (
1912+ "math_mul_mod" ,
1913+ & [
1914+ x_swapped_ptr. into( ) ,
1915+ y_swapped_ptr. into( ) ,
1916+ k_swapped_ptr. into( )
1917+ ]
1918+ ) ;
1919+ let product_ptr = bin. build_alloca ( function, bin. value_type ( ) , "product_ptr" ) ;
1920+ byte_swap_value ( bin, & Type :: Uint ( 256 ) , x_swapped_ptr, product_ptr, false ) ;
1921+ return bin
1922+ . builder
1923+ . build_load ( bin. value_type ( ) , product_ptr, "product" )
1924+ . unwrap ( ) ;
1925+ }
1926+
18581927 let arith_ty = bin. context . custom_width_int_type ( 512 ) ;
18591928 let res_ty = bin. context . custom_width_int_type ( 256 ) ;
18601929
1861- let x = expression ( target, bin, & args[ 0 ] , vartab, function) . into_int_value ( ) ;
1862- let y = expression ( target, bin, & args[ 1 ] , vartab, function) . into_int_value ( ) ;
18631930 let x_m = bin. build_alloca ( function, arith_ty, "x_m" ) ;
18641931 let y_m = bin. build_alloca ( function, arith_ty, "x_y" ) ;
18651932 let x_times_y_m = bin. build_alloca ( function, arith_ty, "x_times_y_m" ) ;
@@ -1893,7 +1960,6 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
18931960 "" ,
18941961 )
18951962 . unwrap ( ) ;
1896- let k = expression ( target, bin, & args[ 2 ] , vartab, function) . into_int_value ( ) ;
18971963 let dividend = bin
18981964 . builder
18991965 . build_load ( arith_ty, x_times_y_m, "x_t_y" )
@@ -2138,7 +2204,7 @@ pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
21382204
21392205 Expression :: ByteSwap { expr, le_to_be } => {
21402206 let ty = expr. ty ( ) ;
2141- bytes_swap ( target, bin, & ty, expr, * le_to_be, vartab, function)
2207+ byte_swap_expression ( target, bin, & ty, expr, * le_to_be, vartab, function)
21422208 }
21432209
21442210 Expression :: RationalNumberLiteral { .. }
@@ -2696,7 +2762,7 @@ fn basic_value_to_slice<'a>(
26962762
26972763// smoelius: I think this type-walking must be done during the emit phase and not during the codegen
26982764// phase. For example, the bounds on a dynamic array cannot be known. Hence, a loop must be emitted.
2699- fn bytes_swap < ' a , T : TargetRuntime < ' a > + ?Sized > (
2765+ fn byte_swap_expression < ' a , T : TargetRuntime < ' a > + ?Sized > (
27002766 target : & T ,
27012767 bin : & Binary < ' a > ,
27022768 ty : & Type ,
@@ -2723,31 +2789,41 @@ fn bytes_swap<'a, T: TargetRuntime<'a> + ?Sized>(
27232789 "dest" ,
27242790 ) ;
27252791
2726- let name = if le_to_be { "__leNtobeN" } else { "__beNtoleN" } ;
2727-
2728- bin. builder
2729- . build_call (
2730- bin. module . get_function ( name) . unwrap ( ) ,
2731- & [
2732- src. into ( ) ,
2733- dest. into ( ) ,
2734- bin. context
2735- . i32_type ( )
2736- . const_int ( ( ty. get_type_size ( ) / 8 ) as u64 , false )
2737- . into ( ) ,
2738- ] ,
2739- name,
2740- )
2741- . unwrap ( ) ;
2792+ byte_swap_value ( bin, ty, src, dest, le_to_be) ;
27422793
27432794 bin. builder
27442795 . build_load ( llvm_ty, dest, "swapped bytes" )
27452796 . unwrap ( )
27462797 }
27472798 Type :: UserType ( no) => {
27482799 let ty = & bin. ns . user_types [ * no] . ty ;
2749- bytes_swap ( target, bin, ty, expr, le_to_be, vartab, function)
2800+ byte_swap_expression ( target, bin, ty, expr, le_to_be, vartab, function)
27502801 }
27512802 _ => unimplemented ! ( "{ty:?}" ) ,
27522803 }
27532804}
2805+
2806+ fn byte_swap_value (
2807+ bin : & Binary < ' _ > ,
2808+ ty : & Type ,
2809+ from : PointerValue < ' _ > ,
2810+ to : PointerValue < ' _ > ,
2811+ le_to_be : bool ,
2812+ ) {
2813+ let name = if le_to_be { "__leNtobeN" } else { "__beNtoleN" } ;
2814+
2815+ bin. builder
2816+ . build_call (
2817+ bin. module . get_function ( name) . unwrap ( ) ,
2818+ & [
2819+ from. into ( ) ,
2820+ to. into ( ) ,
2821+ bin. context
2822+ . i32_type ( )
2823+ . const_int ( ( ty. get_type_size ( ) / 8 ) as u64 , false )
2824+ . into ( ) ,
2825+ ] ,
2826+ name,
2827+ )
2828+ . unwrap ( ) ;
2829+ }
0 commit comments