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