@@ -374,13 +374,93 @@ let caml_format_int fmt i =
374
374
let f = parse_format fmt in
375
375
aux f i
376
376
377
+ (* This can handle unsigned integer (-1L) and print it as "%Lu" which
378
+ will overflow signed integer in general
379
+ *)
380
+ let dec_of_pos_int64 x =
381
+
382
+
383
+ (if x < 0L then
384
+
385
+ let wbase = 10L in
386
+ let cvtbl = " 0123456789" in
387
+ let y = Caml_int64. discard_sign x in
388
+ (* 2 ^ 63 + y `div_mod` 10 *)
389
+
390
+ let quotient_l = 922337203685477580L (* 2 ^ 63 / 10 *)
391
+ (* {lo = -858993460n; hi = 214748364n} *)
392
+ (* TODO: int64 constant folding so that we can do idiomatic code
393
+ 2 ^ 63 / 10 *) in
394
+ let modulus_l = 8L in
395
+ (* let c, d = Caml_int64.div_mod (Caml_int64.add y modulus_l) wbase in
396
+ we can not do the code above, it can overflow when y is really large
397
+ *)
398
+ let c, d = Caml_int64. div_mod y wbase in
399
+ let e ,f = Caml_int64. div_mod (Caml_int64_extern. add modulus_l d) wbase in
400
+ let quotient =
401
+ (Caml_int64_extern. add (Caml_int64_extern. add quotient_l c )
402
+ e) in
403
+ Caml_int64. to_string quotient ^
404
+ (Caml_string_extern. get_string_unsafe
405
+ cvtbl (Caml_int64_extern. to_int f))
406
+ else
407
+ Caml_int64. to_string x)
408
+
409
+ let oct_of_int64 x =
410
+ let s = ref " " in
411
+ let wbase = 8L in
412
+ let cvtbl = " 01234567" in
413
+ (if x < 0L then
414
+ begin
415
+ let y = Caml_int64. discard_sign x in
416
+ (* 2 ^ 63 + y `div_mod` 8 *)
417
+ let quotient_l = 1152921504606846976L
418
+ (* {lo = 0n; hi = 268435456n } *) (* 2 ^ 31 / 8 *)
419
+ in
420
+
421
+ (* let c, d = Caml_int64.div_mod (Caml_int64.add y modulus_l) wbase in
422
+ we can not do the code above, it can overflow when y is really large
423
+ *)
424
+ let c, d = Caml_int64. div_mod y wbase in
425
+
426
+ let quotient =
427
+ ref (Caml_int64_extern. add quotient_l c ) in
428
+ let modulus = ref d in
429
+ s .contents< -
430
+ Caml_string_extern. get_string_unsafe
431
+ cvtbl (Caml_int64_extern. to_int modulus.contents) ^ s.contents ;
432
+
433
+ while quotient.contents <> 0L do
434
+ let a, b = Caml_int64. div_mod quotient.contents wbase in
435
+ quotient .contents< - a;
436
+ modulus .contents< - b;
437
+ s .contents< - Caml_string_extern. get_string_unsafe cvtbl (Caml_int64_extern. to_int modulus.contents) ^ s.contents ;
438
+ done ;
439
+ end
440
+ else
441
+ let a, b = Caml_int64. div_mod x wbase in
442
+ let quotient = ref a in
443
+ let modulus = ref b in
444
+ s .contents< -
445
+ Caml_string_extern. get_string_unsafe
446
+ cvtbl (Caml_int64_extern. to_int modulus.contents) ^ s.contents ;
447
+
448
+ while quotient.contents <> 0L do
449
+ let a, b = Caml_int64. div_mod (quotient.contents) wbase in
450
+ quotient .contents< - a;
451
+ modulus .contents< - b;
452
+ s .contents< - Caml_string_extern. get_string_unsafe cvtbl (Caml_int64_extern. to_int modulus.contents) ^ s.contents ;
453
+ done ); s.contents
454
+
455
+
377
456
(* FIXME: improve codegen for such cases
378
457
let div_mod (x : int64) (y : int64) : int64 * int64 =
379
458
let a, b = Caml_int64.(div_mod (unsafe_of_int64 x) (unsafe_of_int64 y)) in
380
459
Caml_int64.unsafe_to_int64 a , Caml_int64.unsafe_to_int64 b
381
460
*)
382
461
let caml_int64_format fmt x =
383
- let module String = Caml_string_extern in
462
+ if fmt = " %d" then Caml_int64. to_string x
463
+ else
384
464
let f = parse_format fmt in
385
465
let x =
386
466
if f.signedconv && x < 0L then
@@ -389,114 +469,26 @@ let caml_int64_format fmt x =
389
469
Caml_int64_extern. neg x
390
470
end
391
471
else x in
392
- let s = ref " " in
472
+ let s =
393
473
394
474
begin match f.base with
395
475
| Hex ->
396
- s .contents < - Caml_int64. to_hex x ^ s.contents
476
+ Caml_int64. to_hex x
397
477
| Oct ->
398
- let wbase = 8L in
399
- let cvtbl = " 01234567" in
400
-
401
- if x < 0L then
402
- begin
403
- let y = Caml_int64. discard_sign x in
404
- (* 2 ^ 63 + y `div_mod` 8 *)
405
- let quotient_l = 1152921504606846976L
406
- (* {lo = 0n; hi = 268435456n } *) (* 2 ^ 31 / 8 *)
407
- in
408
-
409
- (* let c, d = Caml_int64.div_mod (Caml_int64.add y modulus_l) wbase in
410
- we can not do the code above, it can overflow when y is really large
411
- *)
412
- let c, d = Caml_int64. div_mod y wbase in
413
-
414
- let quotient =
415
- ref (Caml_int64_extern. add quotient_l c ) in
416
- let modulus = ref d in
417
- s .contents< -
418
- Caml_string_extern. of_char
419
- cvtbl.[ Caml_int64_extern. to_int modulus.contents] ^ s.contents ;
420
-
421
- while quotient.contents <> 0L do
422
- let a, b = Caml_int64. div_mod quotient.contents wbase in
423
- quotient .contents< - a;
424
- modulus .contents< - b;
425
- s .contents< - Caml_string_extern. of_char cvtbl.[Caml_int64_extern. to_int modulus.contents] ^ s.contents ;
426
- done ;
427
- end
428
- else
429
- let a, b = Caml_int64. div_mod x wbase in
430
- let quotient = ref a in
431
- let modulus = ref b in
432
- s .contents< -
433
- Caml_string_extern. of_char
434
- cvtbl.[ Caml_int64_extern. to_int modulus.contents] ^ s.contents ;
435
-
436
- while quotient.contents <> 0L do
437
- let a, b = Caml_int64. div_mod (quotient.contents) wbase in
438
- quotient .contents< - a;
439
- modulus .contents< - b;
440
- s .contents< - Caml_string_extern. of_char cvtbl.[Caml_int64_extern. to_int modulus.contents] ^ s.contents ;
441
- done
442
-
478
+ oct_of_int64 x
443
479
| Dec ->
444
- let wbase = 10L in
445
- let cvtbl = " 0123456789" in
446
-
447
- if x < 0L then
448
- let y = Caml_int64. discard_sign x in
449
- (* 2 ^ 63 + y `div_mod` 10 *)
450
-
451
- let quotient_l = 922337203685477580L (* 2 ^ 63 / 10 *)
452
- (* {lo = -858993460n; hi = 214748364n} *)
453
- (* TODO: int64 constant folding so that we can do idiomatic code
454
- 2 ^ 63 / 10 *) in
455
- let modulus_l = 8L in
456
- (* let c, d = Caml_int64.div_mod (Caml_int64.add y modulus_l) wbase in
457
- we can not do the code above, it can overflow when y is really large
458
- *)
459
- let c, d = Caml_int64. div_mod y wbase in
460
- let e ,f = Caml_int64. div_mod (Caml_int64_extern. add modulus_l d) wbase in
461
- let quotient =
462
- ref (Caml_int64_extern. add (Caml_int64_extern. add quotient_l c )
463
- e) in
464
- let modulus = ref f in
465
- s .contents< -
466
- Caml_string_extern. of_char
467
- cvtbl.[Caml_int64_extern. to_int modulus.contents] ^ s.contents ;
468
-
469
- while quotient.contents <> 0L do
470
- let a, b = Caml_int64. div_mod (quotient.contents) wbase in
471
- quotient .contents< - a;
472
- modulus .contents< - b;
473
- s .contents< - Caml_string_extern. of_char cvtbl.[Caml_int64_extern. to_int modulus.contents] ^ s.contents ;
474
- done ;
475
-
476
- else
477
- let a, b = Caml_int64. div_mod x wbase in
478
- let quotient = ref a in
479
- let modulus = ref b in
480
- s .contents< -
481
- Caml_string_extern. of_char
482
- cvtbl.[ Caml_int64_extern. to_int modulus.contents] ^ s.contents ;
483
-
484
- while quotient.contents <> 0L do
485
- let a, b = Caml_int64. div_mod (quotient.contents) wbase in
486
- quotient .contents< - a;
487
- modulus .contents< - b;
488
- s .contents< - Caml_string_extern. of_char cvtbl.[Caml_int64_extern. to_int modulus.contents] ^ s.contents ;
489
- done ;
490
- end ;
480
+ dec_of_pos_int64 x
481
+ end in
482
+ let fill_s =
491
483
if f.prec > = 0 then
492
484
begin
493
485
f.filter < - " " ;
494
- let n = f.prec - Caml_string_extern. length s.contents in
486
+ let n = f.prec - Caml_string_extern. length s in
495
487
if n > 0 then
496
- s .contents < - repeat n " 0" ^ s.contents
497
- end ;
488
+ repeat n " 0" ^ s else s
489
+ end else s in
498
490
499
- finish_formatting f s.contents
491
+ finish_formatting f fill_s
500
492
501
493
let caml_format_float fmt x =
502
494
let module String = Caml_string_extern in
0 commit comments