21 #ifndef __SYSTEMC_EXT_TLM_CORE_2_GENERIC_PAYLOAD_ENDIAN_CONV_HH__
22 #define __SYSTEMC_EXT_TLM_CORE_2_GENERIC_PAYLOAD_ENDIAN_CONV_HH__
147 class tlm_endian_context;
149 class tlm_endian_context_pool
152 tlm_endian_context *
first;
155 inline tlm_endian_context *
pop();
156 inline void push(tlm_endian_context *
c);
162 class tlm_endian_context :
public tlm_extension<tlm_endian_context>
213 tlm_extension_base *
clone()
const {
return 0; }
214 void copy_from(tlm_extension_base
const &) {
return; }
261 return new tlm_endian_context;
262 tlm_endian_context *
r =
first;
285 unsigned char *tmp = (
unsigned char *)(&
d);
286 for (ptrdiff_t
i = 0;
i !=
sizeof(D);
i++)
294 operator bool()
const {
return b; }
307 copy_db0(
unsigned char *src1,
unsigned char *src2,
308 unsigned char *dest1,
unsigned char *dest2)
316 unsigned char *dest1,
unsigned char *dest2)
324 unsigned char * ,
unsigned char *dest2)
330 copy_b0(
unsigned char * ,
unsigned char *src2,
331 unsigned char * ,
unsigned char *dest2)
337 copy_dbyb0(
unsigned char *src1,
unsigned char * ,
338 unsigned char *dest1,
unsigned char *dest2)
346 void COPY(
unsigned char *he_d,
unsigned char *he_b,
347 unsigned char *ie_d,
unsigned char *ie_b)>
349 loop_generic0(
int new_len,
int new_stream_width,
int orig_stream_width,
352 unsigned char *ie_data,
unsigned char *ie_be,
353 unsigned char *he_data,
unsigned char *he_be)
355 for (
int orig_sword = 0, new_sword = 0; new_sword < new_len;
356 new_sword += new_stream_width, orig_sword += orig_stream_width) {
358 for (
int orig_dword = orig_sword;
359 orig_dword < orig_sword + orig_stream_width;
360 orig_dword +=
sizeof(D)) {
361 for (
int curr_byte = orig_dword +
sizeof(D) - 1;
362 curr_byte >= orig_dword; curr_byte--) {
363 ptrdiff_t he_index = ((ie_addr++) ^ (sizeof_databus - 1)) -
364 new_start_address + new_sword;
365 COPY(ie_data + curr_byte,
367 ie_be + (curr_byte % be_length),
368 he_data + he_index, he_be + he_index);
379 template <
class DATAWORD>
382 unsigned int sizeof_databus)
384 if (txn->is_read()) {
385 tlm_endian_context *tc =
386 txn->template get_extension<tlm_endian_context>();
387 loop_generic0<DATAWORD, ©_dbyb0>(txn->get_data_length(),
388 txn->get_streaming_width(), tc->stream_width, sizeof_databus,
389 tc->address, tc->new_address, txn->get_data_length(),
390 tc->data_ptr, 0, txn->get_data_ptr(),
391 txn->get_byte_enable_ptr());
398 template <
class DATAWORD>
401 unsigned int sizeof_databus)
404 tc->from_f = &(tlm_from_hostendian_generic<DATAWORD>);
405 tc->sizeof_databus = sizeof_databus;
413 int nr_stream_words =
length / s_width;
418 ~(sizeof_databus - 1));
420 int new_stream_width = end_address - new_address + sizeof_databus;
421 int new_length = new_stream_width * nr_stream_words;
426 tc->new_address = new_address;
427 tc->stream_width = s_width;
433 tc->establish_dbuf(new_length);
435 tc->establish_bebuf(new_length);
445 loop_generic0<DATAWORD, ©_dbtrue0>(
446 new_length, new_stream_width, s_width, sizeof_databus,
447 tc->address, new_address, new_length, tc->data_ptr, 0,
450 loop_generic0<DATAWORD, ©_db0>(new_length, new_stream_width,
451 s_width, sizeof_databus, tc->address, new_address,
452 orig_be_length, tc->data_ptr, orig_be,
458 loop_generic0<DATAWORD, ©_btrue0>(new_length,
459 new_stream_width, s_width, sizeof_databus, tc->address,
460 new_address, new_length, tc->data_ptr, 0,
463 loop_generic0<DATAWORD, ©_b0>(new_length, new_stream_width,
464 s_width, sizeof_databus, tc->address, new_address,
465 orig_be_length, tc->data_ptr, orig_be,
478 copy_d1(
unsigned char *src1,
unsigned char *src2,
479 unsigned char *dest1,
unsigned char *dest2)
481 *((D *)dest1) = *((D *)src1);
487 copy_db1(
unsigned char *src1,
unsigned char *src2,
488 unsigned char *dest1,
unsigned char *dest2)
490 *((D *)dest1) = *((D *)src1);
491 *((D *)dest2) = *((D *)src2);
496 true_b1(
unsigned char *src1,
unsigned char *src2,
497 unsigned char *dest1,
unsigned char *dest2)
504 copy_b1(
unsigned char *src1,
unsigned char *src2,
505 unsigned char *dest1,
unsigned char *dest2)
507 *((D *)dest2) = *((D *)src2);
512 copy_dbyb1(
unsigned char *src1,
unsigned char *src2,
513 unsigned char *dest1,
unsigned char *dest2)
516 *((D *)src1) = *((D *)dest1);
522 unsigned char *dest1,
unsigned char *dest2)
524 *((D *)src1) = *((D *)dest1);
536 no_b1(
unsigned char *dest1)
540 void COPY(
unsigned char *src1,
unsigned char *src2,
541 unsigned char *dest1,
unsigned char *dest2),
542 void COPYuchar(
unsigned char *src1,
unsigned char *src2,
543 unsigned char *dest1,
unsigned char *dest2),
544 void FILLFALSE(
unsigned char *dest1),
545 void FILLFALSEuchar(
unsigned char *dest1)>
547 loop_word1(
int bytes_left,
int len0,
int lenN,
int sizeof_databus,
548 unsigned char *start,
unsigned char *end,
549 unsigned char *src,
unsigned char *bsrc,
550 unsigned char *dest,
unsigned char *bdest)
552 ptrdiff_t d2b_src = bsrc - src;
553 ptrdiff_t d2b_dest = bdest - dest;
554 unsigned char *original_dest = dest;
558 if ((src >= start) && (src < end)) {
559 for (
int i = 0;
i <
len0;
i++) {
560 COPYuchar(src, src + d2b_src, dest, dest + d2b_dest);
566 return int(dest - original_dest);
568 for (
int i = 0;
i <
len0;
i++) {
569 FILLFALSEuchar(dest + d2b_dest);
574 src -= 2 *
sizeof(D);
577 for (
unsigned int i = 1;
i < sizeof_databus /
sizeof(D);
i++) {
578 if ((src >= start) && (src < end)) {
579 COPY(src, src + d2b_src, dest, dest + d2b_dest);
580 bytes_left -=
sizeof(D);
582 FILLFALSE(dest + d2b_dest);
586 return int(dest - original_dest);
591 if ((src >= start) && (src < end)) {
592 for (
int i = 0;
i < lenN;
i++) {
593 COPYuchar(src, src + d2b_src, dest, dest + d2b_dest);
599 return int(dest - original_dest);
601 for (
int i = 0;
i < lenN;
i++) {
602 FILLFALSEuchar(dest + d2b_dest);
607 src += 2 * sizeof_databus;
616 template <
class DATAWORD>
620 if (txn->is_read()) {
621 tlm_endian_context *tc =
622 txn->template get_extension<tlm_endian_context>();
624 int d_mask =
sizeof(DATAWORD) - 1;
625 int a_offset =
static_cast<int>(tc->address & b_mask);
626 int len0 = (sizeof_databus - a_offset) & d_mask;
627 int lenN =
sizeof(DATAWORD) -
len0;
628 unsigned char *d_start = tc->data_ptr;
629 unsigned char *d_end =
630 ptrdiff_t(tc->length) + d_start;
632 ptrdiff_t(((sizeof_databus - a_offset) & ~d_mask) + lenN) +
636 if (tc->byte_enable == 0) {
637 loop_word1<DATAWORD, ©_dbytrue1<DATAWORD>,
638 ©_dbytrue1<unsigned char>, &no_b1<DATAWORD>,
639 &no_b1<unsigned char>>(
640 tc->length,
len0, lenN, sizeof_databus,
641 d_start, d_end,
d, 0, txn->get_data_ptr(), 0);
643 loop_word1<DATAWORD, ©_dbyb1<DATAWORD>,
644 ©_dbyb1<unsigned char>, &no_b1<DATAWORD>,
645 &no_b1<unsigned char>>(
646 tc->length,
len0, lenN, sizeof_databus,
648 tc->byte_enable - d_start +
d,
649 txn->get_data_ptr(), 0);
659 template <
class DATAWORD>
664 tc->from_f = &(tlm_from_hostendian_word<DATAWORD>);
665 tc->sizeof_databus = sizeof_databus;
668 int d_mask =
sizeof(DATAWORD) - 1;
670 int a_offset =
static_cast<int>(txn->get_address() & b_mask);
671 int len0 = (sizeof_databus - a_offset) & d_mask;
672 int lenN =
sizeof(DATAWORD) -
len0;
673 unsigned char *d_start = txn->get_data_ptr();
674 unsigned char *d_end =
675 ptrdiff_t(txn->get_data_length()) + d_start;
678 ptrdiff_t(((sizeof_databus - a_offset) & ~d_mask) + lenN) + d_start;
682 int long_enough = txn->get_data_length() + 2 * sizeof_databus;
683 tc->establish_dbuf(long_enough);
684 unsigned char *new_data = tc->new_dbuf;
685 tc->establish_bebuf(long_enough);
686 unsigned char *new_be = tc->new_bebuf;
688 if (txn->is_read()) {
689 tc->data_ptr = d_start;
690 tc->address = txn->get_address();
691 tc->byte_enable = txn->get_byte_enable_ptr();
692 tc->length = txn->get_data_length();
693 if (txn->get_byte_enable_ptr() == 0) {
695 txn->set_data_length(
697 &true_b1<unsigned char>, &false_b1<DATAWORD>,
698 &false_b1<unsigned char>>(
699 txn->get_data_length(),
len0, lenN,
700 sizeof_databus, d_start, d_end,
d, 0,
704 txn->set_data_length(
706 ©_b1<unsigned char>, &false_b1<DATAWORD>,
707 &false_b1<unsigned char>>(
708 txn->get_data_length(),
len0, lenN,
709 sizeof_databus, d_start, d_end,
d,
710 txn->get_byte_enable_ptr() - d_start +
d,
715 if (txn->get_byte_enable_ptr() == 0) {
718 txn->set_data_length(
720 ©_d1<unsigned char>, &false_b1<DATAWORD>,
721 &false_b1<unsigned char>>(
722 txn->get_data_length(),
len0, lenN,
723 sizeof_databus, d_start, d_end,
d, 0,
727 txn->set_data_length(
729 ©_db1<unsigned char>, &false_b1<DATAWORD>,
730 &false_b1<unsigned char>>(
731 txn->get_data_length(),
len0, lenN,
732 sizeof_databus, d_start, d_end,
d,
733 txn->get_byte_enable_ptr() - d_start +
d,
737 txn->set_byte_enable_length(txn->get_data_length());
738 txn->set_streaming_width(txn->get_data_length());
739 txn->set_data_ptr(new_data);
740 txn->set_byte_enable_ptr(new_be);
741 txn->set_address(a_aligned);
751 inline void copy_d2(D *src1, D *src2, D *dest1, D *dest2) { *dest1 = *src1; }
755 copy_db2(D *src1, D *src2, D *dest1, D *dest2)
763 copy_dbyb2(D *src1, D *src2, D *dest1, D *dest2)
765 if (tlm_bool<D>(*src2))
769 template <
class D,
void COPY(D *src1, D *src2, D *dest1, D *dest2)>
771 loop_aligned2(D *src1, D *src2, D *dest1, D *dest2,
int words,
775 ptrdiff_t src1to2 = (
char *)src2 - (
char *)src1;
777 ptrdiff_t dest1to2 = (
char *)dest2 - (
char *)dest1;
779 D *done = src1 + ptrdiff_t(words);
781 src1 += ptrdiff_t(words_per_bus - 1);
784 COPY(src1, (D *)(src1to2 + (
char *)src1), dest1,
785 (D *)(dest1to2 + (
char *)dest1));
787 if ((--src1) < bus_start) {
788 bus_start += ptrdiff_t(words_per_bus);
789 if (bus_start == done)
791 src1 = bus_start + ptrdiff_t(words_per_bus - 1);
801 template <
class DATAWORD>
804 tlm_generic_payload *txn,
unsigned int sizeof_databus)
806 int words_per_bus = sizeof_databus /
sizeof(DATAWORD);
807 if (words_per_bus == 1)
809 int words = (txn->get_data_length()) /
sizeof(DATAWORD);
810 tlm_endian_context *tc = txn->template get_extension<tlm_endian_context>();
812 if (txn->get_byte_enable_ptr() == 0) {
814 if (txn->is_read()) {
816 loop_aligned2<DATAWORD, ©_d2<DATAWORD>>(
817 (DATAWORD *)(txn->get_data_ptr()), 0,
818 (DATAWORD *)(tc->data_ptr), 0, words, words_per_bus);
822 if (txn->is_read()) {
824 loop_aligned2<DATAWORD, ©_dbyb2<DATAWORD>>(
825 (DATAWORD *)(txn->get_data_ptr()),
826 (DATAWORD *)(txn->get_byte_enable_ptr()),
827 (DATAWORD *)(tc->data_ptr), 0, words, words_per_bus);
837 template <
class DATAWORD>
840 tlm_generic_payload *txn,
unsigned int sizeof_databus)
843 tc->from_f = &(tlm_from_hostendian_aligned<DATAWORD>);
844 tc->sizeof_databus = sizeof_databus;
846 int words_per_bus = sizeof_databus /
sizeof(DATAWORD);
847 if (words_per_bus == 1)
849 int words = (txn->get_data_length()) /
sizeof(DATAWORD);
851 DATAWORD *original_be = (DATAWORD *)(txn->get_byte_enable_ptr());
852 DATAWORD *original_data = (DATAWORD *)(txn->get_data_ptr());
855 tc->establish_dbuf(txn->get_data_length());
856 txn->set_data_ptr(tc->new_dbuf);
858 if (original_be == 0) {
860 if (txn->is_write()) {
862 loop_aligned2<DATAWORD, ©_d2<DATAWORD>>(
863 original_data, 0, (DATAWORD *)(txn->get_data_ptr()), 0,
864 words, words_per_bus);
867 tc->data_ptr = (
unsigned char *)original_data;
872 tc->establish_bebuf(txn->get_data_length());
873 txn->set_byte_enable_ptr(tc->new_bebuf);
874 txn->set_byte_enable_length(txn->get_data_length());
876 if (txn->is_write()) {
878 loop_aligned2<DATAWORD, ©_db2<DATAWORD>>(
879 original_data, original_be,
880 (DATAWORD *)(txn->get_data_ptr()),
881 (DATAWORD *)(txn->get_byte_enable_ptr()),
882 words, words_per_bus);
885 tc->data_ptr = (
unsigned char *)original_data;
887 loop_aligned2<DATAWORD, ©_d2<DATAWORD>>(
888 original_be, 0, (DATAWORD *)(txn->get_byte_enable_ptr()),
889 0, words, words_per_bus);
900 template <
class DATAWORD>
903 tlm_generic_payload *txn,
unsigned int sizeof_databus)
911 template <
class DATAWORD>
916 tc->from_f = &(tlm_from_hostendian_single<DATAWORD>);
917 tc->sizeof_databus = sizeof_databus;
922 txn->set_address((
a & ~
mask) |
923 (sizeof_databus - (
a &
mask) -
sizeof(DATAWORD)));
935 tlm_endian_context *tc = txn->get_extension<tlm_endian_context>();
936 (*(tc->from_f))(txn, tc->sizeof_databus);