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