tum-ei-eda / M2-ISA-R

CoreDSL2 Parser with backend to generate simulation code for the ETISS instruction set simulator
https://tum-ei-eda.github.io/M2-ISA-R/
Apache License 2.0
5 stars 6 forks source link

slicing is not working correctly for extern variables #11

Closed togulcan closed 2 years ago

togulcan commented 2 years ago

Hello

I just realized the following code:

architectural_state { 
  extern unsigned<8> ITSTATE;
}
bool it_passed(){
  unsigned<4> cond = 0;

  if(ITSTATE[3:0] != 0)
    cond = ITSTATE[7:4];
  else if(ITSTATE==0)
    cond = 14;
  bool result = condition_passed(cond);

  ///// advance IT
  if (ITSTATE[2:0]== 0) ITSTATE=0;
  else states = ITSTATE[7:5] :: (unsigned<6>) LSL(ITSTATE[4:0], 1);

  return result;
}

is producing the following code:

// in ARMv7M.h file
etiss_uint8 ITSTATE; 
static inline etiss_uint8 it_passed (ETISS_CPU * const cpu, ETISS_System* const system, void* const* const plugin_pointers)
{
  etiss_uint8 cond = (0U) & 0xf;

  if (((ARMv7M*)cpu)->ITSTATE[3U] & 1U)
    cond = (((ARMv7M*)cpu)->ITSTATE[7U]) & 0xf;
  else 
    if (((ARMv7M*)cpu)->ITSTATE == 0U) 
      cond = (14U) & 0xf;

  etiss_uint8 result = (condition_passed(cpu, system, plugin_pointers, cond)) & 0x1;

  if (((ARMv7M*)cpu)->ITSTATE[2U] == 0U)
    ((ARMv7M*)cpu)->ITSTATE = 0U;
  else
    ((ARMv7M*)cpu)->ITSTATE = (((((ARMv7M*)cpu)->ITSTATE[7U])<< 6) | ((etiss_uint8)((LSL(((ARMv7M*)cpu)->ITSTATE[4U], 1U) & 0x3f))));

  return result;}

where you might have already seen the resulting indexes of ITSTATE after slicing are completely wrong.

However when I create a local copy of the extern variable ITSTATE as follows:

architectural_state { 
  extern unsigned<8> ITSTATE;
}

bool it_passed(){
  unsigned<4> cond = 0;
  unsigned<8> states = ITSTATE;      /// local copy of the same type

  if(states[3:0] & 0xf  != 0)
    cond = states[7:4];
  else if(states == 0)
    cond = 14;

  bool result = condition_passed(cond);
  ///// advance IT
  if (states[2:0] == 0) states = 0;
  else states = states[7:5] :: (unsigned<6>)LSL(states[4:0], 1);

  ITSTATE = states; // put the result back
  return result;
}

The following true expected code is generated.

static inline etiss_uint8 it_passed (ETISS_CPU * const cpu, ETISS_System* const system, void *const * const plugin_pointers){
  etiss_uint8 cond = (0U) & 0xf;
  etiss_uint8 states = ((ARMv7M*)cpu)->ITSTATE; 
  if ((((states) >> (0U)) & 15) & 1U)
    cond = ((((states) >> (4U)) & 15)) & 0xf;
  else
    if (states == 0U)
      cond = (14U) & 0xf;

  etiss_uint8 result = (condition_passed(cpu, system, plugin_pointers, cond)) & 0x1;

  if ((((states) >> (0U)) & 7) == 0U)
    states = 0U;
  else 
    states = ((((((states) >> (5U)) & 7)) << 6) | ((etiss_uint8)((LSL((((states)>> (0U)) & 31), 1U) & 0x3f))));

  ((ARMv7M*)cpu)->ITSTATE = states;

  return result;}

But why this is happening in the first place even though states and ITSTATE are of the same type of etiss_uint8? Is there something wrong with extern variables?

Thanks

wysiwyng commented 2 years ago

Not directly a problem with extern architecture states, but rather with the mechanism how slice expressions are parsed. To the parser, slicing and indexing looks the same: MEM[23] looks the same asITSTATE[3], butMEMis an array whereasITSTATE` is a scalar. Therefore indexing and slicing expressions are dependent on the context. I fixed this in e83d31621d4d8e94b4e34b723c042e6455570847, please check if this solves the issue.

wysiwyng commented 2 years ago

One comment: ITSTATE is more of a register than an extern type. extern declared entities usually refer to memory banks of some form.

togulcan commented 2 years ago

Yes, it is solved!! Many thanks. I will pay attention to the declaration as a register as well, thanks!