@@ -176,7 +176,10 @@ initDefs tgt =
176176 , exfun "__gmpz_init" VoidType [pmpz] False
177177 , exfun "__gmpz_init_set_str" (IntegerType 32) [pmpz, ptrI8, IntegerType 32] False
178178 , exfun "__gmpz_get_str" ptrI8 [ptrI8, IntegerType 32, pmpz] False
179+ , exfun "__gmpz_get_ui" intPtr [pmpz] False
179180 , exfun "__gmpz_cmp" (IntegerType 32) [pmpz, pmpz] False
181+ , exfun "__gmpz_fdiv_q_2exp" VoidType [pmpz, pmpz, intPtr] False
182+ , exfun "__gmpz_mul_2exp" VoidType [pmpz, pmpz, intPtr] False
180183 , exfun "mpz_get_ull" (IntegerType 64) [pmpz] False
181184 , exfun "mpz_init_set_ull" VoidType [pmpz, IntegerType 64] False
182185 , exfun "mpz_init_set_sll" VoidType [pmpz, IntegerType 64] False
@@ -867,6 +870,8 @@ cgOp (LAnd ITBig) [x,y] = mpzBin "and" x y
867870cgOp (LOr ITBig) [x,y] = mpzBin "ior" x y
868871cgOp (LXOr ITBig) [x,y] = mpzBin "xor" x y
869872cgOp (LCompl ITBig) [x] = mpzUn "com" x
873+cgOp (LSHL ITBig) [x,y] = mpzBit "mul_2exp" x y
874+cgOp (LASHR ITBig) [x,y] = mpzBit "fdiv_q_2exp" x y
870875
871876cgOp (LTrunc ITNative (ITFixed to)) [x]
872877 | 32 >= nativeTyWidth to = iCoerce Trunc IT32 to x
@@ -1106,6 +1111,16 @@ mpzBin name x y = do
11061111 inst' $ simpleCall ("__gmpz_" ++ name) [nz, nx, ny]
11071112 box (FArith (ATInt ITBig)) nz
11081113
1114+mpzBit :: String -> Operand -> Operand -> Codegen Operand
1115+mpzBit name x y = do
1116+ nx <- unbox (FArith (ATInt ITBig)) x
1117+ ny <- unbox (FArith (ATInt ITBig)) y
1118+ bitcnt <- inst $ simpleCall "__gmpz_get_ui" [ny]
1119+ nz <- alloc mpzTy
1120+ inst' $ simpleCall "__gmpz_init" [nz]
1121+ inst' $ simpleCall ("__gmpz_" ++ name) [nz, nx, bitcnt]
1122+ box (FArith (ATInt ITBig)) nz
1123+
11091124mpzUn :: String -> Operand -> Codegen Operand
11101125mpzUn name x = do
11111126 nx <- unbox (FArith (ATInt ITBig)) x