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