aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/runtime.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/runtime.c')
-rw-r--r--src/pkg/runtime/runtime.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/pkg/runtime/runtime.c b/src/pkg/runtime/runtime.c
index 9b5f6c8ca3..03a9daf4c2 100644
--- a/src/pkg/runtime/runtime.c
+++ b/src/pkg/runtime/runtime.c
@@ -220,6 +220,9 @@ runtime·check(void)
if(offsetof(struct y1, y) != 1) runtime·throw("bad offsetof y1.y");
if(sizeof(struct y1) != 2) runtime·throw("bad sizeof y1");
+ if(runtime·timediv(12345LL*1000000000+54321, 1000000000, &e) != 12345 || e != 54321)
+ runtime·throw("bad timediv");
+
uint32 z;
z = 1;
if(!runtime·cas(&z, 1, 2))
@@ -407,3 +410,30 @@ runtime·parsedebugvars(void)
p++;
}
}
+
+// Poor mans 64-bit division.
+// This is a very special function, do not use it if you are not sure what you are doing.
+// int64 division is lowered into _divv() call on 386, which does not fit into nosplit functions.
+// Handles overflow in a time-specific manner.
+#pragma textflag 7
+int32
+runtime·timediv(int64 v, int32 div, int32 *rem)
+{
+ int32 res, bit;
+
+ if(v >= div*0x7fffffffLL) {
+ if(rem != nil)
+ *rem = 0;
+ return 0x7fffffff;
+ }
+ res = 0;
+ for(bit = 0x40000000; bit != 0; bit >>= 1) {
+ if(v >= (int64)bit*div) {
+ v -= (int64)bit*div;
+ res += bit;
+ }
+ }
+ if(rem != nil)
+ *rem = v;
+ return res;
+}