Index: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Load_store_unit/src/Load_store_unit_function_speculative_load_commit_transition.cpp
===================================================================
--- trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Load_store_unit/src/Load_store_unit_function_speculative_load_commit_transition.cpp	(revision 101)
+++ trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Load_store_unit/src/Load_store_unit_function_speculative_load_commit_transition.cpp	(revision 104)
@@ -57,7 +57,9 @@
 	for (uint32_t i=0, nb_check=0; (nb_check<_param->_nb_port_check) and (i<_param->_size_load_queue); i++)
 	  {
+            // Get an index from load queue
 	    uint32_t index_load = (i + reg_LOAD_QUEUE_CHECK_PRIORITY)%_param->_size_load_queue;
-	    
-	    if (((_load_queue[index_load]._state == LOAD_QUEUE_WAIT_CHECK)   or
+
+            // Test if this load must ckecked store queue
+	    if (((_load_queue[index_load]._state == LOAD_QUEUE_WAIT_CHECK) or
 		 (_load_queue[index_load]._state == LOAD_QUEUE_COMMIT_CHECK) or
 		 (_load_queue[index_load]._state == LOAD_QUEUE_CHECK)) and
@@ -69,6 +71,6 @@
 
 		// find a entry that it need a check
-
 		Tlsq_ptr_t index_store  = _load_queue[index_load]._store_queue_ptr_write;
+                // Init variable
 		bool       end_check    = false;
 		bool       change_state = false;
@@ -95,4 +97,5 @@
 		    log_printf(TRACE,Load_store_unit,FUNCTION,"      * index_store : %d",index_store);
 		    
+                    // switch on store_queue state
 		    switch (_store_queue[index_store]._state)
 		      {
@@ -107,5 +110,5 @@
 			  bool test_thread_id = true;
 			  
-			  // Test thread id.
+			  // Test thread id
 			  if (_param->_have_port_context_id)
 			    test_thread_id &= (_load_queue[index_load]._context_id    == _store_queue[index_store]._context_id);
@@ -117,6 +120,7 @@
 			  if (test_thread_id)
 			    {
+			      // the load and store are in the same thread. Now, we must test address.
+
 			      log_printf(TRACE,Load_store_unit,FUNCTION,"        * load and store is the same thread.");
-			      // the load and store are in the same thread. Now, we must test address.
 			      Tdcache_address_t load_addr  = _load_queue [index_load ]._address;
 			      Tdcache_address_t store_addr = _store_queue[index_store]._address;
@@ -126,5 +130,5 @@
 			      log_printf(TRACE,Load_store_unit,FUNCTION,"          * load_addr  & mask_address_msb : %.8x.",load_addr  & _param->_mask_address_msb);
 			      log_printf(TRACE,Load_store_unit,FUNCTION,"          * store_addr & mask_address_msb : %.8x.",store_addr & _param->_mask_address_msb);
-			      // Test if the both address target the same word
+			      // Test if the both address target the same "word"
 			      if ((load_addr  & _param->_mask_address_msb) == 
 				  (store_addr & _param->_mask_address_msb))
@@ -143,11 +147,17 @@
 				  // the only case is (4)
 				  
+                                  // Read data
 				  Tgeneral_data_t load_data  = _load_queue [index_load ]._rdata  ;
 				  Tgeneral_data_t store_data = _store_queue[index_store]._wdata  ;
 				  
-				  log_printf(TRACE,Load_store_unit,FUNCTION,"              * load_data  (init) : %.8x",load_data);
-				  log_printf(TRACE,Load_store_unit,FUNCTION,"              * store_data (init) : %.8x",store_data);
+				  log_printf(TRACE,Load_store_unit,FUNCTION,"            * load_data  (before): 0x%.8x",load_data);
+				  log_printf(TRACE,Load_store_unit,FUNCTION,"            * store_data (before): 0x%.8x",store_data);
+
+                                  uint32_t store_nb_byte     = (1<<memory_access(_store_queue[index_store]._operation));
+
+                                  // Take interval to the store
 				  uint32_t store_num_byte_min = (store_addr & _param->_mask_address_lsb);
-				  uint32_t store_num_byte_max = store_num_byte_min+(1<<memory_access(_store_queue[index_store]._operation));
+				  uint32_t store_num_byte_max = store_num_byte_min+store_nb_byte;
+
 				  log_printf(TRACE,Load_store_unit,FUNCTION,"            * store_num_byte_min : %d",store_num_byte_min);
 				  log_printf(TRACE,Load_store_unit,FUNCTION,"            * store_num_byte_max : %d",store_num_byte_max);
@@ -155,26 +165,108 @@
 				  log_printf(TRACE,Load_store_unit,FUNCTION,"            * check_hit_byte     : %x",_load_queue[index_load]._check_hit_byte);
 				  // The bypass is checked byte per byte
-				  for (uint32_t byte=store_num_byte_min; byte<store_num_byte_max; byte ++)
+                                  // Is same endianness : because to change endianness, we must write in special register. Also the pipeline is flushed.
+                                  bool is_big_endian = true;
+
+				  for (uint32_t num_store_byte=store_num_byte_min; num_store_byte<store_num_byte_max; num_store_byte ++)
 				    {
-				      uint32_t mask  = 1<<byte;
-				      uint32_t index = byte<<3;
-				      log_printf(TRACE,Load_store_unit,FUNCTION,"              * byte  : %d",byte);
-				      log_printf(TRACE,Load_store_unit,FUNCTION,"              * mask  : %d",mask);
-				      log_printf(TRACE,Load_store_unit,FUNCTION,"              * index : %d",index);
-				      // Accept the bypass if they had not a previous bypass with an another store 
+                                      // Make a mask
+                                      uint32_t num_load_byte;
+
+                                      if (is_big_endian)
+                                        {
+                                          // sd 0 : 0 1 2 3 4 5 6 7
+                                          // ld 0 : 0 1 2 3 4 5 6 7 >>  0 
+                                          // lw 0 :         0 1 2 3 >>  0 -4
+                                          // lw 4 : 4 5 6 7         >> 32 +4
+                                          // lh 0 :             0 1 >>  0 -6
+                                          // lh 2 :         2 3     >> 16 -2
+                                          // lh 4 :     4 5         >> 32 +2
+                                          // lh 6 : 6 7             >> 48 +6
+                                          // lb 0 :               0 >>  0 -7
+                                          // lb 1 :             1   >>  8 -5
+                                          // lb 2 :           2     >> 16 -3
+                                          // lb 3 :         3       >> 24 -1
+                                          // lb 4 :       4         >> 32 +1
+                                          // lb 5 :     5           >> 40 +3
+                                          // lb 6 :   6             >> 48 +5
+                                          // lb 7 : 7               >> 56 +7
+
+                                          // diff : (store_nb_byte + load_nb_byte) - 2*nb_load_byte*((num_store_byte+1)
+
+                                          // store duplicate = all store access can be see as full size_data store
+                                          uint32_t load_nb_byte = (1<<memory_access(_load_queue [index_load ]._operation));
+
+//                                           log_printf(TRACE,Load_store_unit,FUNCTION,"                * num_store_byte       : %d",num_store_byte);
+//                                           log_printf(TRACE,Load_store_unit,FUNCTION,"                * size_general_data>>3 : %d",(_param->_size_general_data>>3));
+//                                           log_printf(TRACE,Load_store_unit,FUNCTION,"                * load_nb_byte         : %d",load_nb_byte);
+//                                           log_printf(TRACE,Load_store_unit,FUNCTION,"                * x = ((_param->_size_general_data>>3)+load_nb_byte-2*load_nb_byte*(num_store_byte/load_nb_byte+1)) = %d+%d-%d*%d = %d"
+//                                                      , (_param->_size_general_data>>3)
+//                                                      , load_nb_byte
+//                                                      , 2*load_nb_byte
+//                                                      ,((num_store_byte/load_nb_byte)+1)
+//                                                      ,((_param->_size_general_data>>3)+load_nb_byte-2*load_nb_byte*((num_store_byte/load_nb_byte)+1)));
+                                          
+
+                                          num_load_byte =num_store_byte+((_param->_size_general_data>>3)+load_nb_byte-2*load_nb_byte*((num_store_byte/load_nb_byte)+1));
+                                        }
+                                      else
+                                        {
+                                          // sd 0 : 0 1 2 3 4 5 6 7
+                                          // ld 0 : 0 1 2 3 4 5 6 7 >>  0
+                                          // lw 0 :         4 5 6 7 >>  0
+                                          // lw 4 : 0 1 2 3         >> 32
+                                          // lh 0 :             6 7 >>  0
+                                          // lh 2 :         4 5     >> 16
+                                          // lh 4 :     2 3         >> 32
+                                          // lh 6 : 0 1             >> 48
+                                          // lb 0 :               7 >>  0
+                                          // lb 1 :             6   >>  8
+                                          // lb 2 :           5     >> 16
+                                          // lb 3 :         4       >> 24
+                                          // lb 4 :       3         >> 32
+                                          // lb 5 :     2           >> 40
+                                          // lb 6 :   1             >> 48
+                                          // lb 7 : 0               >> 56
+                                          
+                                          num_load_byte = num_store_byte;
+                                        }
+                                      
+				      uint32_t mask  = 1<<num_load_byte;
+
+				      log_printf(TRACE,Load_store_unit,FUNCTION,"              * num_store_byte : %d",num_store_byte);
+				      log_printf(TRACE,Load_store_unit,FUNCTION,"              * num_load_byte  : %d",num_load_byte);
+				      log_printf(TRACE,Load_store_unit,FUNCTION,"              * mask           : %d",mask);
+
+				      // Accept the bypass if :
+                                      //   * they have not a previous bypass with an another store
+                                      //   * it's a valid request of load
 				      if ((_load_queue[index_load]._check_hit_byte&mask)==0)
 					{
+                                          // Note : Store is duplicate = all store access can be see as full size_data store
+
+                                          uint32_t num_store_bit_min = num_store_byte<<3; //*8
+//                                         uint32_t num_store_bit_max = num_store_bit_min+8-1;
+                                          uint32_t num_load_bit_min  = num_load_byte <<3; //*8
+                                          uint32_t num_load_bit_max  = num_load_bit_min+8-1;
+
 					  log_printf(TRACE,Load_store_unit,FUNCTION,"              * bypass !!!");
-					  log_printf(TRACE,Load_store_unit,FUNCTION,"                * rdata_old : %.8x", load_data);
-					  load_data = insert<Tdcache_data_t>(load_data, store_data, index+8-1, index);
+//                                        log_printf(TRACE,Load_store_unit,FUNCTION,"              * interval store : [%d:%d]",num_store_bit_max,num_store_bit_min);
+                                          log_printf(TRACE,Load_store_unit,FUNCTION,"              * interval store : [..:%d]",num_store_bit_min);
+                                          log_printf(TRACE,Load_store_unit,FUNCTION,"              * interval load  : [%d:%d]",num_load_bit_max,num_load_bit_min);
+					  log_printf(TRACE,Load_store_unit,FUNCTION,"                * rdata_old : 0x%.8x", load_data);
+
+					  load_data = ((((store_data>>num_store_bit_min) & 0xff) << num_load_bit_min) |
+                                                       mask_not<Tdcache_data_t>(load_data,num_load_bit_max,num_load_bit_min));
+
 					  _load_queue[index_load]._check_hit_byte |= mask;
 					  _load_queue[index_load]._check_hit       = 1;
 					  change_state = true;
 
-					  log_printf(TRACE,Load_store_unit,FUNCTION,"                * rdata_new : %.8x", load_data);
+					  log_printf(TRACE,Load_store_unit,FUNCTION,"                * rdata_new : 0x%.8x", load_data);
 					}
 				    }
 
 				  _load_queue[index_load]._rdata = load_data;
+				  log_printf(TRACE,Load_store_unit,FUNCTION,"            * load_data  (after) : 0x%.8x",load_data);
 
 				  log_printf(TRACE,Load_store_unit,FUNCTION,"            * check_hit          : %x",_load_queue[index_load]._check_hit);
@@ -182,6 +274,7 @@
 
 				  log_printf(TRACE,Load_store_unit,FUNCTION,"            * mask_end_check     : %x",(-1& _param->_mask_address_lsb));
+				  log_printf(TRACE,Load_store_unit,FUNCTION,"            * mask_check_hit_byte: %x",_param->_mask_check_hit_byte);
 				  // The check is finish if all bit is set
-				  end_check = (_load_queue[index_load]._check_hit_byte == MASK_CHECK_BYTE_HIT);
+				  end_check = (_load_queue[index_load]._check_hit_byte == _param->_mask_check_hit_byte);
 				}
 			    }
@@ -387,5 +480,5 @@
 
 		    // reordering data
-		    _store_queue [index]._wdata                = duplicate<Tgeneral_data_t>(_param->_size_general_data,PORT_READ(in_MEMORY_IN_DATA_RB[internal_MEMORY_IN_PORT]), memory_size(operation), 0);
+		    _store_queue [index]._wdata                = duplicate<Tgeneral_data_t>(_param->_size_general_data,PORT_READ(in_MEMORY_IN_DATA_RB[internal_MEMORY_IN_PORT]), memory_size(operation), 0); 
 //                  _store_queue [index]._num_reg_rd           = PORT_READ(in_MEMORY_IN_NUM_REG_RD  [internal_MEMORY_IN_PORT]);
 		  }
@@ -500,5 +593,5 @@
             (PORT_READ(in_DCACHE_REQ_ACK[0]) == 1))
           {
-	    log_printf(TRACE,Load_store_unit,FUNCTION,"  * DCACHE_REQ[0]");
+	    log_printf(TRACE,Load_store_unit,FUNCTION,"  * DCACHE_REQ [0]");
 
 	    switch (internal_DCACHE_REQ_SELECT_QUEUE)
@@ -542,5 +635,4 @@
 	    bool         have_exception = (exception != EXCEPTION_MEMORY_NONE);
 	    
-	    
 	    if (have_exception)
 	      _load_queue [ptr_write]._state = LOAD_QUEUE_COMMIT;
@@ -570,23 +662,30 @@
 	    Tdcache_address_t address        = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._address;
 	    Tdcache_address_t address_lsb    = (address & _param->_mask_address_lsb);
-	    Tdcache_address_t check_hit_byte = gen_mask_not<Tdcache_address_t>(address_lsb+memory_access(operation)+1,address_lsb);
-	    _load_queue [ptr_write]._context_id        = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._context_id           ;
-	    _load_queue [ptr_write]._front_end_id      = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._front_end_id         ;
-	    _load_queue [ptr_write]._ooo_engine_id     = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._ooo_engine_id        ;
-	    _load_queue [ptr_write]._packet_id         = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._packet_id            ;
-	    _load_queue [ptr_write]._operation         = operation;
+	    Tdcache_address_t check_hit_byte = gen_mask_not<Tdcache_address_t>(address_lsb+(memory_size(operation)>>3)-1,address_lsb) & _param->_mask_check_hit_byte;
+
+	    log_printf(TRACE,Load_store_unit,FUNCTION,"    * address                 : 0x%.8x", address);
+	    log_printf(TRACE,Load_store_unit,FUNCTION,"    * address_lsb             : 0x%.8x", address_lsb);
+	    log_printf(TRACE,Load_store_unit,FUNCTION,"    * operation               : %d", operation);
+	    log_printf(TRACE,Load_store_unit,FUNCTION,"    * memory_size             : %d", memory_size(operation));
+	    log_printf(TRACE,Load_store_unit,FUNCTION,"    * check_hit_byte          : 0x%x", check_hit_byte);
+
+	    _load_queue [ptr_write]._context_id            = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._context_id;
+	    _load_queue [ptr_write]._front_end_id          = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._front_end_id;
+	    _load_queue [ptr_write]._ooo_engine_id         = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._ooo_engine_id;
+	    _load_queue [ptr_write]._packet_id             = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._packet_id;
+	    _load_queue [ptr_write]._operation             = operation;
 	    _load_queue [ptr_write]._store_queue_ptr_write = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._store_queue_ptr_write;
-	    _load_queue [ptr_write]._address           = address;
-	    _load_queue [ptr_write]._check_hit_byte    = check_hit_byte;
-	    _load_queue [ptr_write]._check_hit         = 0;
-	    _load_queue [ptr_write]._shift             = address<<3;
-	    _load_queue [ptr_write]._is_load_signed    = is_operation_memory_load_signed(operation);
-	    _load_queue [ptr_write]._access_size       = memory_size(operation);
+	    _load_queue [ptr_write]._address               = address;
+	    _load_queue [ptr_write]._check_hit_byte        = check_hit_byte;
+	    _load_queue [ptr_write]._check_hit             = 0;
+	    _load_queue [ptr_write]._shift                 = address_lsb<<3;// *8
+	    _load_queue [ptr_write]._is_load_signed        = is_operation_memory_load_signed(operation);
+	    _load_queue [ptr_write]._access_size           = memory_size(operation);
 	    // NOTE : if have an exception, must write in register, because a depend instruction wait the load data.
-	    _load_queue [ptr_write]._write_rd          = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._write_rd             ;
+	    _load_queue [ptr_write]._write_rd              = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._write_rd             ;
 	    
-	    _load_queue [ptr_write]._num_reg_rd        = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._num_reg_rd           ;
-	    _load_queue [ptr_write]._exception         = exception;
-	    _load_queue [ptr_write]._rdata             = address; // to the exception
+	    _load_queue [ptr_write]._num_reg_rd            = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._num_reg_rd           ;
+	    _load_queue [ptr_write]._exception             = exception;
+	    _load_queue [ptr_write]._rdata                 = address; // to the exception
 	    
 	    log_printf(TRACE,Load_store_unit,FUNCTION,"    * speculative_access_queue");
@@ -628,5 +727,20 @@
 #endif
 
-                _load_queue [packet_id]._rdata = rdata;
+                Tdcache_data_t data = _load_queue [packet_id]._rdata;
+
+                log_printf(TRACE,Load_store_unit,FUNCTION,"    * data construction");
+                log_printf(TRACE,Load_store_unit,FUNCTION,"      * data from cache     : 0x%.8x",rdata);
+                log_printf(TRACE,Load_store_unit,FUNCTION,"      * data (before)       : 0x%.8x", data);
+                log_printf(TRACE,Load_store_unit,FUNCTION,"      * check_hit_byte      : 0x%x"  ,_load_queue [packet_id]._check_hit_byte);
+                for (uint32_t i=0;i<(_param->_size_general_data>>3)/*8*/; ++i)
+                  // Test if this byte has been checked
+                  if ((_load_queue [packet_id]._check_hit_byte & (1<<i)) == 0)
+                    {
+                      log_printf(TRACE,Load_store_unit,FUNCTION,"      * no previous check ]%d:%d]",(i+1)<<3,i<<3);
+                      data = insert<Tdcache_data_t>(data,rdata,((i+1)<<3)-1,i<<3);
+                    }
+                log_printf(TRACE,Load_store_unit,FUNCTION,"      * data (after)        : 0x%.8x", data);
+                
+                _load_queue [packet_id]._rdata = data;
 		
 		if (error != DCACHE_ERROR_NONE)
