aboutsummaryrefslogtreecommitdiff
path: root/src/lj_carith.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_carith.c')
-rw-r--r--src/lj_carith.c55
1 files changed, 35 insertions, 20 deletions
diff --git a/src/lj_carith.c b/src/lj_carith.c
index 134a61fb..bba9f6b9 100644
--- a/src/lj_carith.c
+++ b/src/lj_carith.c
@@ -148,21 +148,6 @@ static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
148 setboolV(L->top-1, 148 setboolV(L->top-1,
149 id == CTID_INT64 ? ((int64_t)u0 <= (int64_t)u1) : (u0 <= u1)); 149 id == CTID_INT64 ? ((int64_t)u0 <= (int64_t)u1) : (u0 <= u1));
150 return 1; 150 return 1;
151 case MM_div: case MM_mod:
152 if (u1 == 0) { /* Division by zero. */
153 if (u0 == 0)
154 setnanV(L->top-1);
155 else if (id == CTID_INT64 && (int64_t)u0 < 0)
156 setminfV(L->top-1);
157 else
158 setpinfV(L->top-1);
159 return 1;
160 } else if (id == CTID_INT64 && (int64_t)u1 == -1 &&
161 u0 == U64x(80000000,00000000)) { /* MIN64 / -1. */
162 if (mm == MM_div) id = CTID_UINT64; else u0 = 0;
163 mm = MM_unm; /* Result is 0x8000000000000000ULL or 0LL. */
164 }
165 break;
166 default: break; 151 default: break;
167 } 152 }
168 cd = lj_cdata_new(cts, id, 8); 153 cd = lj_cdata_new(cts, id, 8);
@@ -174,15 +159,15 @@ static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
174 case MM_mul: *up = u0 * u1; break; 159 case MM_mul: *up = u0 * u1; break;
175 case MM_div: 160 case MM_div:
176 if (id == CTID_INT64) 161 if (id == CTID_INT64)
177 *up = (uint64_t)((int64_t)u0 / (int64_t)u1); 162 *up = (uint64_t)lj_carith_divi64((int64_t)u0, (int64_t)u1);
178 else 163 else
179 *up = u0 / u1; 164 *up = lj_carith_divu64(u0, u1);
180 break; 165 break;
181 case MM_mod: 166 case MM_mod:
182 if (id == CTID_INT64) 167 if (id == CTID_INT64)
183 *up = (uint64_t)((int64_t)u0 % (int64_t)u1); 168 *up = (uint64_t)lj_carith_modi64((int64_t)u0, (int64_t)u1);
184 else 169 else
185 *up = u0 % u1; 170 *up = lj_carith_modu64(u0, u1);
186 break; 171 break;
187 case MM_pow: 172 case MM_pow:
188 if (id == CTID_INT64) 173 if (id == CTID_INT64)
@@ -231,13 +216,43 @@ int lj_carith_op(lua_State *L, MMS mm)
231/* -- 64 bit integer arithmetic helpers ----------------------------------- */ 216/* -- 64 bit integer arithmetic helpers ----------------------------------- */
232 217
233#if LJ_32 218#if LJ_32
234/* Signed/unsigned 64 bit multiply. */ 219/* Signed/unsigned 64 bit multiplication. */
235int64_t lj_carith_mul64(int64_t a, int64_t b) 220int64_t lj_carith_mul64(int64_t a, int64_t b)
236{ 221{
237 return a * b; 222 return a * b;
238} 223}
239#endif 224#endif
240 225
226/* Unsigned 64 bit division. */
227uint64_t lj_carith_divu64(uint64_t a, uint64_t b)
228{
229 if (b == 0) return U64x(80000000,00000000);
230 return a / b;
231}
232
233/* Signed 64 bit division. */
234int64_t lj_carith_divi64(int64_t a, int64_t b)
235{
236 if (b == 0 || (a == (int64_t)U64x(80000000,00000000) && b == -1))
237 return U64x(80000000,00000000);
238 return a / b;
239}
240
241/* Unsigned 64 bit modulo. */
242uint64_t lj_carith_modu64(uint64_t a, uint64_t b)
243{
244 if (b == 0) return U64x(80000000,00000000);
245 return a % b;
246}
247
248/* Signed 64 bit modulo. */
249int64_t lj_carith_modi64(int64_t a, int64_t b)
250{
251 if (b == 0) return U64x(80000000,00000000);
252 if (a == (int64_t)U64x(80000000,00000000) && b == -1) return 0;
253 return a % b;
254}
255
241/* Unsigned 64 bit x^k. */ 256/* Unsigned 64 bit x^k. */
242uint64_t lj_carith_powu64(uint64_t x, uint64_t k) 257uint64_t lj_carith_powu64(uint64_t x, uint64_t k)
243{ 258{