Conditional Memory

From Msim

Jump to: navigation, search

This page refers to support for the Conditional Memory access and Register Locked instructions.
See Alpha Architecture Handbook: 4-9 to 4-14 (pages 65-70)

Contents

STQ_C and STL_C

Register Sources

These now require an integer physical register.
In regrename.c::getregset(...):

case STW:
case STB:
case STQ_U:
case STL:
case STQ:
case STL_C:
case STQ_C:
 my_regs->src1 = REG_INT;
 my_regs->src2 = REG_INT;
 my_regs->dest = REG_NONE;
 my_regs->store = 1;
 break;

Is now:

case STW:
case STB:
case STQ_U:
case STL:
case STQ:
 my_regs->src1 = REG_INT;
 my_regs->src2 = REG_INT;
 my_regs->dest = REG_NONE;
 my_regs->store = 1;
 break;

case STL_C:
case STQ_C:
 my_regs->src1 = REG_INT;
 my_regs->src2 = REG_INT;
 my_regs->dest = REG_INT;
 my_regs->store = 1;
 break;

Instruction Definition

In machine.def, STQ_C and STL_C need to indicate they use a destination register and they need to check the lock_flag.

STL_C

#define STL_C_IMPL                                        \
{                                                         \
 word_t _src;                                             \
 enum md_fault_type _fault;                               \
                                                          \
 _src = (word_t)(GPR(RA) & ULL(0xffffffff));              \
                                                          \
 WRITE_WORD(_src, GPR(RB) + SEXT(OFS), _fault);           \
 if(_fault != md_fault_none)                              \
  DECLARE_FAULT(_fault);                                  \
  SET_GPR(RA, 1);                                         \
}
DEFINST(STL_C,           0x2e,
 "stl_c (unimpl)",       "a,o(b)",
 WrPort,                 F_MEM|F_STORE|F_DISP,
 DNA, DNA,               DGPR(RA), DGPR(RB), DNA)

Is now:

#define STL_C_IMPL                                                                               \
{                                                                                                \
 enum md_fault_type _fault;                                                                      \
                                                                                                 \
 word_t _src = (word_t)(GPR(RA) & ULL(0xffffffff));                                              \
 SET_GPR(RA, 0);                                                                                 \
 if(cores[core_num].lock_flag && (GPR(RB)+SEXT(OFS))==cores[core_num].locked_physical_address)   \
 {                                                                                               \
  WRITE_WORD(_src, GPR(RB) + SEXT(OFS), _fault);                                                 \
  if(_fault != md_fault_none)                                                                    \
   DECLARE_FAULT(_fault);                                                                        \
  SET_GPR(RA, 1);                                                                                \
 }                                                                                               \
 else                                                                                            \
 {                                                                                               \
  SET_GPR(RA, 0);                                                                                \
 }                                                                                               \
 cores[core_num].lock_flag = 0;                                                                  \
}
DEFINST(STL_C,           0x2e,
 "stl_c (unimpl)",       "a,o(b)",
 WrPort,                 F_MEM|F_STORE|F_DISP,
 DGPR(RA), DNA,          DGPR(RA), DGPR(RB), DNA)


STL_Q

#define STQ_C_IMPL                                       \
{                                                        \
 enum md_fault_type _fault;                              \
                                                         \
 WRITE_QWORD(GPR(RA), GPR(RB) + SEXT(OFS), _fault);      \
 if(_fault != md_fault_none)                             \
  DECLARE_FAULT(_fault);                                 \
 SET_GPR(RA, 1);                                         \
}
DEFINST(STQ_C,           0x2f,
 "stq_c (unimpl)",       "a,o(b)",
 WrPort,                 F_MEM|F_STORE|F_DISP,
 DNA, DNA,               DGPR(RA), DGPR(RB), DNA)

Is now:

#define STQ_C_IMPL                                                                               \
{                                                                                                \
 enum md_fault_type _fault;                                                                      \
                                                                                                 \
 if(cores[core_num].lock_flag && (GPR(RB)+SEXT(OFS))==cores[core_num].locked_physical_address)   \
 {                                                                                               \
  WRITE_QWORD(GPR(RA), GPR(RB) + SEXT(OFS), _fault);                                             \
  if(_fault != md_fault_none)                                                                    \
   DECLARE_FAULT(_fault);                                                                        \
  SET_GPR(RA, 1);                                                                                \
 }                                                                                               \
 else                                                                                            \
 {                                                                                               \
  SET_GPR(RA, 0);                                                                                \
 }                                                                                               \
 cores[core_num].lock_flag = 0;                                                                  \
}
DEFINST(STQ_C,           0x2f,
 "stq_c (unimpl)",       "a,o(b)",
 WrPort,                 F_MEM|F_STORE|F_DISP,
 DGPR(RA), DNA,          DGPR(RA), DGPR(RB), DNA)

Branch Misprediction

The use of a physical register eliminates the special case used in cmp.c::rollbackTo(...) and cmp.c::flush_context(...):
The following code is no longer needed:

//STQ_C and STL_C do not have a physical register but need to rollback RA
if(target.ROB[ROB_index].op == STQ_C || target.ROB[ROB_index].op == STL_C)
{
 int index = target.ROB[ROB_index].regs_index;
 target.regs.regs_R[index] = target.ROB[ROB_index].regs_R;
}

Also, in sim-outorder, special case code in no longer needed in register_rename(...):
The following code is no longer needed:

//Rollback support
//STQ_C and STL_C do not have an output register but technically, it overwrites RA with "lock_flag"
if(op == STQ_C || op == STL_C)
{
 rs->regs_index = Rlist[0];
 rs->regs_R = regs_R[0];
}

Core Support

The core is required to support the lock_flag as well as retain the locked_physical_address.
These values are added to cmp.c and cmp.h.

cmp.h

Before private in core_t:

//Lock Registers:
bool lock_flag;
md_addr_t locked_physical_address;

cmp.c

As part of initialization: New code in bold (be aware of the comma on the first line)

comb_nelt(1),ccomb_nelt(1),btb_nelt(2),cbtb_nelt(2),
lock_flag(FALSE),locked_physical_address(0)

The comma doesn't show well... in this example, the second line is the new code.

comb_nelt(1),ccomb_nelt(1),btb_nelt(2),cbtb_nelt(2)
,lock_flag(FALSE),locked_physical_address(0)

LDQ_L and LDL_L

These instructions must be updated in machine.def to support modifying lock_flag and locked_physical_address. Behavior is unclear in light of mispredicting branches and may need further examination.

LDQ_L

The code is shown here, bold code is the new code, some reorganization was done but is trivial

#define LDQ_L_IMPL                                               \
{                                                                \
 enum md_fault_type _fault;                                      \
                                                                 \
 qword_t _result = READ_QWORD(GPR(RB) + SEXT(OFS), _fault);      \
 if(_fault != md_fault_none)                                     \
  DECLARE_FAULT(_fault);                                         \
                                                                 \
 cores[core_num].lock_flag = 1;                                  \
 cores[core_num].locked_physical_address = GPR(RB) + SEXT(OFS);  \
 SET_GPR(RA, _result);                                           \
}

LDL_L

The code is shown here, bold code is the new code, some reorganization was done but is trivial

#define LDQ_L_IMPL                                               \
{                                                                \
 enum md_fault_type _fault;                                      \
                                                                 \
 word_t _result = READ_WORD(GPR(RB) + SEXT(OFS), _fault);        \
 if(_fault != md_fault_none)                                     \
  DECLARE_FAULT(_fault);                                         \
                                                                 \
 cores[core_num].lock_flag = 1;                                  \
 cores[core_num].locked_physical_address = GPR(RB) + SEXT(OFS);  \
 SET_GPR(RA, (sqword_t)((sword_t)_result));                      \
}


Execution Handling

In the fastfwd stage of the simulation, we must define core_num since it is used in machine.def to identify which lock flags to use.
In sim-outorder.c::sim_main(...):

//execute the instruction
switch(op)

Should be:

int core_num = contexts[current_context].core_id;
//execute the instruction
switch(op)
Personal tools