@@ -919,32 +919,29 @@ let complex_im c dbg =
919
919
920
920
(* Unit *)
921
921
922
- let return_unit dbg c = Csequence (c, Cconst_int (1 , dbg))
922
+ let return_unit dbg c =
923
+ match c with
924
+ | Csequence (_ , Cconst_int (1 , _ )) as c -> c
925
+ | c -> Csequence (c, Cconst_int (1 , dbg))
926
+
927
+ let memory_chunk_width_in_bytes : memory_chunk -> int = function
928
+ | Byte_unsigned | Byte_signed -> 1
929
+ | Sixteen_unsigned | Sixteen_signed -> 2
930
+ | Thirtytwo_unsigned | Thirtytwo_signed -> 4
931
+ | Single { reg = Float64 | Float32 } -> 4
932
+ | Word_int -> size_int
933
+ | Word_val -> size_addr
934
+ | Double -> size_float
935
+ | Onetwentyeight_unaligned | Onetwentyeight_aligned -> size_vec128
923
936
924
937
let strided_field_address ptr ~index ~stride dbg =
925
938
if index * stride = 0
926
939
then ptr
927
940
else Cop (Cadda , [ptr; Cconst_int (index * stride, dbg)], dbg)
928
941
929
942
let field_address ?(memory_chunk = Word_val ) ptr n dbg =
930
- if n = 0
931
- then ptr
932
- else
933
- let field_size_in_bytes =
934
- match memory_chunk with
935
- | Byte_unsigned | Byte_signed -> 1
936
- | Sixteen_unsigned | Sixteen_signed -> 2
937
- | Thirtytwo_unsigned | Thirtytwo_signed -> 4
938
- | Single { reg = Float64 | Float32 } ->
939
- assert (size_float = 8 );
940
- (* unclear what to do if this is false *)
941
- size_float / 2
942
- | Word_int -> size_int
943
- | Word_val -> size_addr
944
- | Double -> size_float
945
- | Onetwentyeight_unaligned | Onetwentyeight_aligned -> size_vec128
946
- in
947
- Cop (Cadda , [ptr; Cconst_int (n * field_size_in_bytes, dbg)], dbg)
943
+ strided_field_address ptr dbg ~index: n
944
+ ~stride: (memory_chunk_width_in_bytes memory_chunk)
948
945
949
946
let get_field_gen_given_memory_chunk memory_chunk mutability ptr n dbg =
950
947
Cop
@@ -1405,147 +1402,50 @@ let unboxed_int64_or_nativeint_array_set ~has_custom_ops arr ~index ~new_value
1405
1402
in
1406
1403
int_array_set arr index new_value dbg)))
1407
1404
1408
- (* Get the field of a block given a possibly inconstant index *)
1405
+ let get_field_unboxed ~dbg memory_chunk mutability block ~index_in_words =
1406
+ if Arch. big_endian && memory_chunk_width_in_bytes memory_chunk <> size_addr
1407
+ then
1408
+ (* CR layouts v5.1: Properly support big-endian. *)
1409
+ Misc. fatal_error
1410
+ " Unboxed non-word size integer fields are only supported on \
1411
+ little-endian architectures" ;
1412
+ (* CR layouts v5.1: We'll need to vary log2_size_addr among other things to
1413
+ efficiently pack small integers *)
1414
+ let field_address =
1415
+ assert (size_float = size_addr);
1416
+ array_indexing log2_size_addr block index_in_words dbg
1417
+ in
1418
+ Cop
1419
+ (Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
1409
1420
1410
1421
let get_field_computed imm_or_ptr mutability ~block ~index dbg =
1411
1422
let memory_chunk =
1412
1423
match imm_or_ptr with
1413
1424
| Lambda. Immediate -> Word_int
1414
1425
| Lambda. Pointer -> Word_val
1415
1426
in
1416
- let field_address = array_indexing log2_size_addr block index dbg in
1417
- Cop
1418
- (Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
1419
-
1420
- (* Getters for unboxed int fields *)
1421
-
1422
- let get_field_unboxed_int32 mutability ~block ~index dbg =
1423
- let memory_chunk = Thirtytwo_signed in
1424
- (* CR layouts v5.1: Properly support big-endian. *)
1425
- if Arch. big_endian
1426
- then
1427
- Misc. fatal_error
1428
- " Unboxed int32 fields only supported on little-endian architectures" ;
1429
- (* CR layouts v5.1: We'll need to vary log2_size_addr to efficiently pack
1430
- * int32s *)
1431
- let field_address = array_indexing log2_size_addr block index dbg in
1432
- Cop
1433
- (Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
1434
-
1435
- let get_field_unboxed_int64_or_nativeint mutability ~block ~index dbg =
1436
- let memory_chunk = Word_int in
1437
- let field_address = array_indexing log2_size_addr block index dbg in
1438
- Cop
1439
- (Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
1440
-
1441
- (* Setters for unboxed int fields *)
1442
-
1443
- let setfield_unboxed_int32 arr ofs newval dbg =
1444
- (* CR layouts v5.1: Properly support big-endian. *)
1445
- if Arch. big_endian
1446
- then
1447
- Misc. fatal_error
1448
- " Unboxed int32 fields only supported on little-endian architectures" ;
1449
- (* CR layouts v5.1: We will need to vary log2_size_addr when int32 fields are
1450
- efficiently packed. *)
1451
- return_unit dbg
1452
- (Cop
1453
- ( Cstore (Thirtytwo_signed , Assignment ),
1454
- [array_indexing log2_size_addr arr ofs dbg; newval],
1455
- dbg ))
1456
-
1457
- let setfield_unboxed_int64_or_nativeint arr ofs newval dbg =
1458
- return_unit dbg
1459
- (Cop
1460
- ( Cstore (Word_int , Assignment ),
1461
- [array_indexing log2_size_addr arr ofs dbg; newval],
1462
- dbg ))
1463
-
1464
- (* Getters and setters for unboxed float32 fields *)
1465
-
1466
- let get_field_unboxed_float32 mutability ~block ~index dbg =
1467
- (* CR layouts v5.1: Properly support big-endian. *)
1468
- if Arch. big_endian
1469
- then
1470
- Misc. fatal_error
1471
- " Unboxed float32 fields only supported on little-endian architectures" ;
1472
- let memory_chunk = Single { reg = Float32 } in
1473
- (* CR layouts v5.1: We'll need to vary log2_size_addr to efficiently pack
1474
- * float32s *)
1475
- let field_address = array_indexing log2_size_addr block index dbg in
1476
- Cop
1477
- (Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
1478
-
1479
- let setfield_unboxed_float32 arr ofs newval dbg =
1480
- (* CR layouts v5.1: Properly support big-endian. *)
1481
- if Arch. big_endian
1482
- then
1483
- Misc. fatal_error
1484
- " Unboxed float32 fields only supported on little-endian architectures" ;
1485
- (* CR layouts v5.1: We will need to vary log2_size_addr when float32 fields
1486
- are efficiently packed. *)
1487
- return_unit dbg
1488
- (Cop
1489
- ( Cstore (Single { reg = Float32 }, Assignment ),
1490
- [array_indexing log2_size_addr arr ofs dbg; newval],
1491
- dbg ))
1492
-
1493
- (* Getters and setters for unboxed vec128 fields *)
1494
-
1495
- let get_field_unboxed_vec128 mutability ~block ~index_in_words dbg =
1496
- (* CR layouts v5.1: Properly support big-endian. *)
1497
- if Arch. big_endian
1498
- then
1499
- Misc. fatal_error
1500
- " Unboxed vec128 fields only supported on little-endian architectures" ;
1501
- let memory_chunk = Onetwentyeight_unaligned in
1502
- let field_address = array_indexing log2_size_addr block index_in_words dbg in
1503
- Cop
1504
- (Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
1505
-
1506
- let setfield_unboxed_vec128 arr ~index_in_words newval dbg =
1507
- (* CR layouts v5.1: Properly support big-endian. *)
1508
- if Arch. big_endian
1509
- then
1510
- Misc. fatal_error
1511
- " Unboxed vec128 fields only supported on little-endian architectures" ;
1512
- let field_address = array_indexing log2_size_addr arr index_in_words dbg in
1513
- return_unit dbg
1514
- (Cop
1515
- ( Cstore (Onetwentyeight_unaligned , Assignment ),
1516
- [field_address; newval],
1517
- dbg ))
1518
-
1519
- let get_field_unboxed ~dbg memory_chunk mutability block ~index_in_words =
1520
- match (memory_chunk : memory_chunk ) with
1521
- | Single { reg = Float32 } ->
1522
- get_field_unboxed_float32 mutability ~block ~index: index_in_words dbg
1523
- | Double ->
1524
- unboxed_float_array_ref mutability ~block ~index: index_in_words dbg
1525
- | Onetwentyeight_unaligned | Onetwentyeight_aligned ->
1526
- get_field_unboxed_vec128 mutability ~block ~index_in_words dbg
1527
- | Thirtytwo_signed ->
1528
- get_field_unboxed_int32 mutability ~block ~index: index_in_words dbg
1529
- | Word_int ->
1530
- get_field_unboxed_int64_or_nativeint mutability ~block ~index: index_in_words
1531
- dbg
1532
- | Word_val ->
1533
- Misc. fatal_error " cannot use get_field_unboxed with a heap block"
1534
- | _ -> Misc. fatal_error " get_field_unboxed: unexpected memory chunk"
1427
+ get_field_unboxed ~dbg memory_chunk mutability block ~index_in_words: index
1535
1428
1536
1429
let set_field_unboxed ~dbg memory_chunk block ~index_in_words newval =
1537
- match (memory_chunk : memory_chunk ) with
1538
- | Single { reg = Float32 } ->
1539
- setfield_unboxed_float32 block index_in_words newval dbg
1540
- | Double -> float_array_set block index_in_words newval dbg
1541
- | Onetwentyeight_unaligned | Onetwentyeight_aligned ->
1542
- setfield_unboxed_vec128 block ~index_in_words newval dbg
1543
- | Thirtytwo_signed -> setfield_unboxed_int32 block index_in_words newval dbg
1544
- | Word_int ->
1545
- setfield_unboxed_int64_or_nativeint block index_in_words newval dbg
1430
+ match memory_chunk with
1546
1431
| Word_val ->
1547
- Misc. fatal_error " cannot use set_field_unboxed with a heap block"
1548
- | _ -> Misc. fatal_error " set_field_unboxed : unexpected memory chunk"
1432
+ Misc. fatal_error " Attempted to set a value via [setfield_unboxed]"
1433
+ | memory_chunk ->
1434
+ let size_in_bytes = memory_chunk_width_in_bytes memory_chunk in
1435
+ (* CR layouts v5.1: Properly support big-endian. *)
1436
+ if Arch. big_endian && size_in_bytes <> size_addr
1437
+ then
1438
+ Misc. fatal_error
1439
+ " Unboxed non-word-size fields are only supported on little-endian \
1440
+ architectures" ;
1441
+ (* CR layouts v5.1: We will need to vary log2_size_addr, among other things,
1442
+ when small fields are efficiently packed. *)
1443
+ let field_address =
1444
+ array_indexing log2_size_addr block index_in_words dbg
1445
+ in
1446
+ let newval = if size_in_bytes = 4 then low_32 dbg newval else newval in
1447
+ return_unit dbg
1448
+ (Cop (Cstore (memory_chunk, Assignment ), [field_address; newval], dbg))
1549
1449
1550
1450
(* String length *)
1551
1451
0 commit comments